Skip to content
Open
12 changes: 12 additions & 0 deletions web-admin/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ const config: PlaywrightTestConfig = {
storageState: ADMIN_STORAGE_STATE,
},
},
{
// Responsive smoke checks run on an emulated phone against the same
// seeded stack. Limited to mobile-smoke so the desktop suites aren't
// re-run here.
name: "mobile",
dependencies: process.env.E2E_NO_SETUP_OR_TEARDOWN ? [] : ["setup"],
testMatch: "mobile-smoke.spec.ts",
use: {
...devices["iPhone 13"],
storageState: ADMIN_STORAGE_STATE,
},
},
],
};

Expand Down
6 changes: 4 additions & 2 deletions web-admin/src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@
crossorigin
/>
<meta charset="utf-8" />
<!-- Set the mobile viewport width -->
<!-- maximum-scale suppresses the iOS auto-zoom on sub-16px inputs; since
iOS 10 Safari ignores it for user-initiated pinch zoom, so it does
not restrict accessibility. -->
<meta
name="viewport"
content="width=1024, initial-scale=1.0, user-scalable=yes"
content="width=device-width, initial-scale=1, maximum-scale=1"
/>
<!-- Set the og image for thumbnail previews -->
<meta
Expand Down
6 changes: 6 additions & 0 deletions web-admin/src/components/nav/Tab.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
position.set(left);
}

// When the tab row overflows (narrow viewports), keep the selected tab
// visible; "nearest" makes this a no-op when it already is.
$: if (selected && element) {
element.scrollIntoView({ block: "nearest", inline: "nearest" });
}

function measure() {
if (!element) return;
left = element.offsetLeft;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="bg-black bg-opacity-25 w-full h-full">
<div
class="bg-surface-subtle text-center mx-auto my-40 w-[600px] rounded p-12"
class="bg-surface-subtle text-center mx-auto my-40 w-full sm:w-[600px] rounded p-12"
>
<div
class="flex flex-col items-center justify-center gap-y-4 max-w-[400px] mx-auto"
Expand Down
2 changes: 1 addition & 1 deletion web-admin/src/features/alerts/CreateAlert.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
{/snippet}
</DialogTrigger>
<DialogContent
class="p-0 m-0 w-[802px] max-w-fit rounded-md"
class="p-0 m-0 w-[min(802px,calc(100vw-2rem))] max-w-fit rounded-md"
noClose
onEscapeKeydown={preventClose}
onInteractOutside={preventClose}
Expand Down
2 changes: 1 addition & 1 deletion web-admin/src/features/alerts/EditAlert.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
{/snippet}
</DialogTrigger>
<DialogContent
class="p-0 m-0 w-[802px] max-w-fit"
class="p-0 m-0 w-[min(802px,calc(100vw-2rem))] max-w-fit"
noClose
onEscapeKeydown={preventClose}
onInteractOutside={preventClose}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
<div {...props} class="hidden"></div>
{/snippet}
</Dialog.Trigger>
<Dialog.Content class="w-[520px]" noClose>
<Dialog.Content class="w-[min(520px,calc(100vw-2rem))]" noClose>
<Dialog.Header>
<Dialog.Title>{m.billing_change_billing_contact()}</Dialog.Title>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
<div {...props} class="hidden"></div>
{/snippet}
</AlertDialogTrigger>
<AlertDialogContent class="flex flex-row gap-x-2 min-w-[600px]">
<AlertDialogContent
class="flex flex-row gap-x-2 min-w-[min(600px,calc(100vw-2rem))]"
>
<Champagne size="150px" className="min-w-[150px]" />
<div class="flex flex-col gap-x-2">
<AlertDialogHeader>
Expand Down
2 changes: 1 addition & 1 deletion web-admin/src/features/bookmarks/Bookmarks.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@
</Button>
{/snippet}
</DropdownMenuTrigger>
<DropdownMenuContent class="w-[450px]">
<DropdownMenuContent class="w-[min(450px,calc(100vw-2rem))]">
<DropdownMenuItem onclick={() => (showDialog = true)}>
<div class="flex flex-row gap-x-2 items-center">
<BookmarkPlusIcon size="16px" strokeWidth={1.5} />
Expand Down
4 changes: 3 additions & 1 deletion web-admin/src/features/branches/BranchesSection.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,9 @@
<Tooltip location="bottom" distance={8}>
<span class="readonly-badge">{m.branch_read_only()}</span>
<TooltipContent slot="tooltip-content">
<div class="text-xs max-w-[360px] flex flex-col gap-y-1">
<div
class="text-xs max-w-[min(360px,calc(100vw-2rem))] flex flex-col gap-y-1"
>
<span>{m.branch_not_editable()}</span>
<span>
{m.branch_recreate_with()}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<script lang="ts">
import * as Popover from "@rilldata/web-common/components/popover";
import Tooltip from "@rilldata/web-common/components/tooltip/Tooltip.svelte";
import TooltipContent from "@rilldata/web-common/components/tooltip/TooltipContent.svelte";
import { createRuntimeServiceGetExplore } from "@rilldata/web-common/runtime-client";
import { useRuntimeClient } from "@rilldata/web-common/runtime-client/v2";
import { timeAgo } from "@rilldata/web-common/lib/time/relative-time";
import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import { Clock } from "lucide-svelte";

export let dashboard: string;

Expand All @@ -27,8 +29,23 @@
</script>

{#if data}
<!-- On phones the relative text costs a full header row, so it collapses to
a clock icon; hover tooltips never fire on touch, so the icon opens a
popover on tap instead. -->
<Popover.Root>
<Popover.Trigger
class="sm:hidden p-1 -m-1 flex items-center text-fg-secondary"
aria-label={m.dashboard_last_refreshed_ago({ time: timeAgo(data) })}
>
<Clock size="14px" />
</Popover.Trigger>
<Popover.Content class="flex w-fit flex-col gap-y-0.5 text-xs" padding="2">
<span>{m.dashboard_last_refreshed_ago({ time: timeAgo(data) })}</span>
<span class="text-fg-secondary">{data.toLocaleString()}</span>
</Popover.Content>
</Popover.Root>
<Tooltip distance={8}>
<div class="text-[11px] text-fg-secondary">
<div class="hidden sm:block text-[11px] text-fg-secondary">
{m.dashboard_last_refreshed_ago({ time: timeAgo(data) })}
</div>
<TooltipContent slot="tooltip-content">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import { exportCanvasPdf } from "@rilldata/web-common/features/exports/pdf/export-canvas-pdf";
import type { PdfExportRunOptions } from "@rilldata/web-common/features/exports/pdf/types";
import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import { Share } from "lucide-svelte";

export let createMagicAuthTokens: boolean;
// Provide canvas identifiers to enable the "PDF" tab (canvas dashboards only).
Expand Down Expand Up @@ -56,16 +57,24 @@
<PopoverTrigger>
{#snippet child({ props })}
<Tooltip distance={8} suppress={isOpen}>
<Button {...props} type="secondary" selected={isOpen}
>{m.avatar_share()}</Button
<!-- On phones the label costs too much header width, so the button
collapses to its icon; the aria-label keeps the accessible name. -->
<Button
{...props}
type="secondary"
selected={isOpen}
label={m.avatar_share()}
>
<Share size="16px" class="sm:hidden" />
<span class="hidden sm:inline">{m.avatar_share()}</span>
</Button>
<TooltipContent slot="tooltip-content"
>{m.avatar_share_dashboard()}</TooltipContent
>
</Tooltip>
{/snippet}
</PopoverTrigger>
<PopoverContent align="end" class="w-[402px] p-0">
<PopoverContent align="end" class="w-[min(402px,calc(100vw-2rem))] p-0">
<Tabs>
<TabsList>
<TabsTrigger value="tab1">{m.avatar_copy_url()}</TabsTrigger>
Expand Down
2 changes: 1 addition & 1 deletion web-admin/src/features/embeds/EmbedHeader.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
{#if $isErrorStoreEmpty && shouldRender}
<div class="flex items-center w-full">
{#if navigationEnabled}
<nav class="flex-1">
<nav class="flex-1 min-w-0">
<ol class="flex items-center pl-4">
{#if !onProjectPage}
<div class="flex gap-x-2">
Expand Down
2 changes: 1 addition & 1 deletion web-admin/src/features/organizations/OrgHeader.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
<Breadcrumbs {pathParts} {currentPath} />
{/if}

<div class="flex gap-x-2 items-center ml-auto">
<div class="flex gap-x-2 items-center ml-auto shrink-0">
{#if $user.isSuccess}
{#if $user.data?.user}
<AvatarButton />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
<PopoverContent
align="start"
side="bottom"
class="flex flex-col gap-y-2 w-[400px] p-4"
class="flex flex-col gap-y-2 w-[min(400px,calc(100vw-2rem))] p-4"
>
<div class="text-base font-medium">
{m.settings_upload_org_image_title({ label })}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
{/snippet}
</Dialog.Trigger>
<Dialog.Content
class="translate-y-[-200px] md:w-[425px] w-[425px]"
class="translate-y-[-200px] w-[min(425px,calc(100vw-2rem))]"
onInteractOutside={(e) => {
e.preventDefault();
open = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,16 @@
$: dynamicTableMaxHeight = data.length > 12 ? `calc(100dvh - 300px)` : "auto";
</script>

<InfiniteScrollTable
{data}
{columns}
{hasNextPage}
{isFetchingNextPage}
{onLoadMore}
maxHeight={dynamicTableMaxHeight}
emptyStateMessage={m.groups_table_empty()}
/>
<!-- Wrap in a horizontal scroll container: InfiniteScrollTable's own scroll-container
only handles overflow-y, so wide columns would otherwise overflow the viewport. -->
<div class="overflow-x-auto">
<InfiniteScrollTable
{data}
{columns}
{hasNextPage}
{isFetchingNextPage}
{onLoadMore}
maxHeight={dynamicTableMaxHeight}
emptyStateMessage={m.groups_table_empty()}
/>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,19 @@
};
</script>

<InfiniteScrollTable
data={safeData}
{columns}
hasNextPage={usersQuery.hasNextPage || invitesQuery.hasNextPage}
isFetchingNextPage={usersQuery.isFetchingNextPage ||
invitesQuery.isFetchingNextPage}
onLoadMore={handleLoadMore}
maxHeight={dynamicTableMaxHeight}
emptyStateMessage={m.users_table_empty()}
{headerIcons}
{scrollToTopTrigger}
/>
<!-- Wrap in a horizontal scroll container: InfiniteScrollTable's own scroll-container
only handles overflow-y, so wide columns would otherwise overflow the viewport. -->
<div class="overflow-x-auto">
<InfiniteScrollTable
data={safeData}
{columns}
hasNextPage={usersQuery.hasNextPage || invitesQuery.hasNextPage}
isFetchingNextPage={usersQuery.isFetchingNextPage ||
invitesQuery.isFetchingNextPage}
onLoadMore={handleLoadMore}
maxHeight={dynamicTableMaxHeight}
emptyStateMessage={m.users_table_empty()}
{headerIcons}
{scrollToTopTrigger}
/>
</div>
Loading
Loading