diff --git a/web-admin/src/features/edit-session/EditSessionViewAs.svelte b/web-admin/src/features/edit-session/EditSessionViewAs.svelte new file mode 100644 index 00000000000..35aacbca5f1 --- /dev/null +++ b/web-admin/src/features/edit-session/EditSessionViewAs.svelte @@ -0,0 +1,85 @@ + + +{#if hasSecurityPolicy} + +{/if} diff --git a/web-admin/src/features/edit-session/updateEditSessionDevJWT.ts b/web-admin/src/features/edit-session/updateEditSessionDevJWT.ts new file mode 100644 index 00000000000..62a92c675ef --- /dev/null +++ b/web-admin/src/features/edit-session/updateEditSessionDevJWT.ts @@ -0,0 +1,56 @@ +import { + selectedMockUserJWT, + selectedMockUserStore, +} from "@rilldata/web-common/features/dashboards/granular-access-policies/stores"; +import type { MockUser } from "@rilldata/web-common/features/dashboards/granular-access-policies/useMockUsers"; +import { + invalidateAllMetricsViews, + invalidateCanvasQueries, +} from "@rilldata/web-common/runtime-client/invalidation"; +import type { RuntimeClient } from "@rilldata/web-common/runtime-client/v2"; +import type { QueryClient } from "@tanstack/svelte-query"; +import { adminServiceGetDeployment } from "@rilldata/web-admin/client"; +import { getDomain } from "@rilldata/web-admin/features/projects/user-management/selectors.ts"; + +export function createUpdateEditSessionDevJWT( + deploymentId: string, + editSessionJwt: string, +) { + return async ( + queryClient: QueryClient, + client: RuntimeClient, + mockUser: MockUser | null, + ) => { + selectedMockUserStore.set(mockUser); + + if (mockUser === null) { + selectedMockUserJWT.set(null); + client.updateJwt(editSessionJwt, "user"); + } else { + try { + const { name, email, groups, admin, ...customAttributes } = mockUser; + + const { accessToken } = await adminServiceGetDeployment(deploymentId, { + attributes: { + email, + ...(email ? { domain: getDomain(email) } : {}), + name: name || "Mock User", + admin: !!admin, + groups: groups || [], + ...customAttributes, + }, + }); + + if (!accessToken) throw new Error("No JWT returned"); + + selectedMockUserJWT.set(accessToken); + client.updateJwt(accessToken, "mock"); + } catch { + // no-op + } + } + + await invalidateAllMetricsViews(queryClient, client.instanceId); + return invalidateCanvasQueries(queryClient, client.instanceId); + }; +} diff --git a/web-admin/src/features/projects/header/ProjectHeader.svelte b/web-admin/src/features/projects/header/ProjectHeader.svelte index 1f35ee90745..924670dcecb 100644 --- a/web-admin/src/features/projects/header/ProjectHeader.svelte +++ b/web-admin/src/features/projects/header/ProjectHeader.svelte @@ -54,6 +54,7 @@ import { useReports } from "../../scheduled-reports/selectors"; import SharePersonalFile from "web-admin/src/features/personal-files/SharePersonalFile.svelte"; import VisualizationsBreadcrumbDropdown from "./VisualizationsBreadcrumbDropdown.svelte"; + import EditSessionViewAs from "@rilldata/web-admin/features/edit-session/EditSessionViewAs.svelte"; export let organization: string; export let project: string; @@ -65,6 +66,8 @@ export let planDisplayName: string | undefined; export let organizationLogoUrl: string | undefined; export let editContext: boolean = false; + export let editSessionDeploymentId: string | undefined = undefined; + export let editSessionJwt: string | undefined = undefined; const user = createAdminServiceGetCurrentUser(); const runtimeClient = useRuntimeClient(); @@ -216,6 +219,12 @@
{#if editContext} + {#if editSessionDeploymentId && editSessionJwt} + + {/if} {#if $developerChat && !onEditDashboardPreview} {/if} diff --git a/web-admin/src/features/projects/user-management/selectors.ts b/web-admin/src/features/projects/user-management/selectors.ts index 7130b2bdbb1..cb3e90cba89 100644 --- a/web-admin/src/features/projects/user-management/selectors.ts +++ b/web-admin/src/features/projects/user-management/selectors.ts @@ -27,7 +27,7 @@ export function emailIsPublic(email: string) { return RillPublicEmailDomains.includes(domain); } -function getDomain(email: string) { +export function getDomain(email: string) { const domainParts = email.split("@"); return domainParts.length ? domainParts[domainParts.length - 1] : ""; } diff --git a/web-admin/src/routes/[organization]/[project]/-/edit/+layout.svelte b/web-admin/src/routes/[organization]/[project]/-/edit/+layout.svelte index b9ef1836869..0fe886e06a8 100644 --- a/web-admin/src/routes/[organization]/[project]/-/edit/+layout.svelte +++ b/web-admin/src/routes/[organization]/[project]/-/edit/+layout.svelte @@ -192,6 +192,8 @@ {planDisplayName} {organizationLogoUrl} editContext={true} + editSessionDeploymentId={deployment.id} + editSessionJwt={jwt} /> @@ -45,7 +51,7 @@ active={viewAsMenuOpen} removeTooltipText={m.dashboard_clear_view()} onRemove={() => { - updateDevJWT(queryClient, client, null); + devJTWUpdater(queryClient, client, null); }} >
@@ -68,7 +74,7 @@ {#each $mockUsers.data as user (user?.email)} { - updateDevJWT(queryClient, client, user); + devJTWUpdater(queryClient, client, user); }} class="flex gap-x-2 items-center" >