diff --git a/web-admin/src/features/navigation/nav-utils.ts b/web-admin/src/features/navigation/nav-utils.ts index 52f283f4472..42e0db4d0fb 100644 --- a/web-admin/src/features/navigation/nav-utils.ts +++ b/web-admin/src/features/navigation/nav-utils.ts @@ -38,7 +38,11 @@ export function isMetricsExplorerPage(page: Page): boolean { } export function isCanvasDashboardPage(page: Page): boolean { - return page.route.id === "/[organization]/[project]/canvas/[dashboard]"; + return ( + page.route.id === "/[organization]/[project]/canvas/[dashboard]" || + page.route.id === + "/[organization]/[project]/-/share/[token]/canvas/[dashboard]" + ); } /** diff --git a/web-admin/src/features/projects/ProjectHeader.svelte b/web-admin/src/features/projects/ProjectHeader.svelte index 93ac6c359f5..b8cefac25b2 100644 --- a/web-admin/src/features/projects/ProjectHeader.svelte +++ b/web-admin/src/features/projects/ProjectHeader.svelte @@ -7,10 +7,11 @@ import { createAdminServiceGetProjectWithBearerToken } from "@rilldata/web-admin/features/public-urls/get-project-with-bearer-token"; import Breadcrumbs from "@rilldata/web-common/components/navigation/breadcrumbs/Breadcrumbs.svelte"; import type { PathOption } from "@rilldata/web-common/components/navigation/breadcrumbs/types"; - import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors"; + import { useCanvas } from "@rilldata/web-common/features/canvas/selector"; import ChatToggle from "@rilldata/web-common/features/chat/layouts/sidebar/ChatToggle.svelte"; import GlobalDimensionSearch from "@rilldata/web-common/features/dashboards/dimension-search/GlobalDimensionSearch.svelte"; import StateManagersProvider from "@rilldata/web-common/features/dashboards/state-managers/StateManagersProvider.svelte"; + import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors"; import { useExplore } from "@rilldata/web-common/features/explores/selectors"; import { featureFlags } from "@rilldata/web-common/features/feature-flags"; import Header from "@rilldata/web-common/layout/header/Header.svelte"; @@ -21,10 +22,6 @@ createAdminServiceGetCurrentUser, createAdminServiceGetDeploymentCredentials, } from "../../client"; - import { - useBreadcrumbOrgPaths, - useBreadcrumbProjectPaths, - } from "../navigation/breadcrumb-selectors"; import ViewAsUserChip from "../../features/view-as-user/ViewAsUserChip.svelte"; import { viewAsUserStore } from "../../features/view-as-user/viewAsUserStore"; import CreateAlert from "../alerts/CreateAlert.svelte"; @@ -33,14 +30,18 @@ import SignIn from "../authentication/SignIn.svelte"; import LastRefreshedDate from "../dashboards/listing/LastRefreshedDate.svelte"; import { useDashboards } from "../dashboards/listing/selectors"; - import PageTitle from "../public-urls/PageTitle.svelte"; - import { useReports } from "../scheduled-reports/selectors"; + import { + useBreadcrumbOrgPaths, + useBreadcrumbProjectPaths, + } from "../navigation/breadcrumb-selectors"; import { isCanvasDashboardPage, isMetricsExplorerPage, isProjectPage, isPublicURLPage, } from "../navigation/nav-utils"; + import PageTitle from "../public-urls/PageTitle.svelte"; + import { useReports } from "../scheduled-reports/selectors"; export let organization: string; export let project: string; @@ -184,9 +185,18 @@ $: isDashboardValid = !!exploreSpec; $: hasUserAccess = $user.isSuccess && $user.data.user && !onPublicURLPage; - $: publicURLDashboardTitle = - $exploreQuery.data?.explore?.explore?.state?.validSpec?.displayName || - dashboard; + $: canvasQuery = useCanvas(runtimeClient, dashboard, { + enabled: + !!runtimeClient.instanceId && + !!dashboard && + !!onCanvasDashboardPage && + !!onPublicURLPage, + }); + + $: publicURLDashboardTitle = onCanvasDashboardPage + ? $canvasQuery.data?.canvas?.displayName || dashboard + : $exploreQuery.data?.explore?.explore?.state?.validSpec?.displayName || + dashboard; $: currentPath = [organization, project, dashboard, report || alert]; @@ -252,7 +262,9 @@ {/if} - + {/if} {#if $user.isSuccess} diff --git a/web-admin/src/features/public-urls/CanvasFiltersSection.svelte b/web-admin/src/features/public-urls/CanvasFiltersSection.svelte new file mode 100644 index 00000000000..4560b523736 --- /dev/null +++ b/web-admin/src/features/public-urls/CanvasFiltersSection.svelte @@ -0,0 +1,98 @@ + + +{#if hasSomeFilter} +
+ +
+

+ The following filters will be locked and hidden: +

+ {#if canvasAppliedFiltersStore} +
+ +
+ {/if} +
+{/if} diff --git a/web-admin/src/features/public-urls/CreatePublicURLForm.svelte b/web-admin/src/features/public-urls/CreatePublicURLForm.svelte index 6959c4ca998..68c03414044 100644 --- a/web-admin/src/features/public-urls/CreatePublicURLForm.svelte +++ b/web-admin/src/features/public-urls/CreatePublicURLForm.svelte @@ -3,7 +3,9 @@ import { createAdminServiceIssueMagicAuthToken, getAdminServiceListMagicAuthTokensQueryKey, + type AdminServiceIssueMagicAuthTokenBody, } from "@rilldata/web-admin/client"; + import { isCanvasDashboardPage } from "@rilldata/web-admin/features/navigation/nav-utils"; import { Button, IconButton } from "@rilldata/web-common/components/button"; import Calendar from "@rilldata/web-common/components/date-picker/Calendar.svelte"; import Input from "@rilldata/web-common/components/forms/Input.svelte"; @@ -15,11 +17,6 @@ PopoverContent, PopoverTrigger, } from "@rilldata/web-common/components/popover"; - import ExploreFilterChipsReadOnly from "@rilldata/web-common/features/dashboards/filters/ExploreFilterChipsReadOnly.svelte"; - import { mergeDimensionAndMeasureFilters } from "@rilldata/web-common/features/dashboards/filters/measure-filters/measure-filter-utils.ts"; - import { getStateManagers } from "@rilldata/web-common/features/dashboards/state-managers/state-managers"; - import { useTimeControlStore } from "@rilldata/web-common/features/dashboards/time-controls/time-control-store"; - import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors"; import { copyToClipboard } from "@rilldata/web-common/lib/actions/copy-to-clipboard"; import type { HTTPError } from "@rilldata/web-common/lib/errors"; import { useQueryClient } from "@tanstack/svelte-query"; @@ -28,56 +25,39 @@ import { defaults, superForm } from "sveltekit-superforms"; import { yup } from "sveltekit-superforms/adapters"; import { object, string } from "yup"; - import { - convertDateToMinutes, - getExploreFields, - getSanitizedExploreStateParam, - hasDashboardDimensionThresholdFilter, - hasDashboardWhereFilter, - } from "./form-utils"; + import CanvasFiltersSection from "./CanvasFiltersSection.svelte"; + import ExploreFiltersSection from "./ExploreFiltersSection.svelte"; + import { convertDateToMinutes } from "./form-utils"; const queryClient = useQueryClient(); - const StateManagers = getStateManagers(); - - const { - dashboardStore, - metricsViewName, - selectors: { - measures: { visibleMeasures }, - dimensions: { visibleDimensions }, - }, - validSpecStore, - } = StateManagers; $: ({ organization, project, dashboard } = $page.params); - - const timeControlStore = useTimeControlStore(StateManagers); + $: isCanvas = isCanvasDashboardPage($page); $: isTitleEmpty = $form.title.trim() === ""; - $: exploreFields = getExploreFields( - $dashboardStore, - $visibleDimensions, - $visibleMeasures, - ); - - $: sanitizedState = getSanitizedExploreStateParam( - $dashboardStore, - exploreFields, - $validSpecStore.data?.explore, - ); - - $: hasWhereFilter = hasDashboardWhereFilter($dashboardStore); - $: hasDimensionThresholdFilter = - hasDashboardDimensionThresholdFilter($dashboardStore); - $: hasSomeFilter = hasWhereFilter || hasDimensionThresholdFilter; - let url: string | null = null; let setExpiration = false; let apiError: string; let popoverOpen = false; let copied = false; + // These will be set by the child components via callbacks + let hasSomeFilter = false; + let dashboardDataProvider: + | (() => Partial) + | null = null; + + function handleFilterStateChange(hasFilters: boolean) { + hasSomeFilter = hasFilters; + } + + function handleProvideFilters( + provider: () => Partial, + ) { + dashboardDataProvider = provider; + } + const formId = "create-public-url-form"; const initialValues = { @@ -101,29 +81,21 @@ const values = form.data; try { - const filter = hasSomeFilter - ? mergeDimensionAndMeasureFilters( - $dashboardStore.whereFilter, - $dashboardStore.dimensionThresholdFilters, - ) - : undefined; - // TODO : add a check upstream to make sure if filter exists, metricsViewName is defined - const metricsViewFilters = filter - ? { [$metricsViewName]: filter } - : undefined; + if (!dashboardDataProvider) { + throw new Error("Dashboard data provider not initialized"); + } + + const dashboardData = dashboardDataProvider(); const { url: _url } = await $issueMagicAuthToken.mutateAsync({ org: organization, project, data: { - resourceType: ResourceKind.Explore as string, + ...dashboardData, resourceName: dashboard, - metricsViewFilters, - fields: exploreFields, ttlMinutes: setExpiration ? convertDateToMinutes(values.expiresAt).toString() : undefined, - state: sanitizedState ? sanitizedState : undefined, displayName: values.title, }, }); @@ -174,53 +146,52 @@ Create a shareable public URL for this view. - {#if !url} -
- -
+
+ +
-
-
- - -
- {#if setExpiration} -
- - - - - - - - - { - $form.expiresAt = date.toISO(); - popoverOpen = false; - }} - /> - - -
- {/if} +
+
+ +
+ {#if setExpiration} +
+ + + + + + + + + { + $form.expiresAt = date.toISO(); + popoverOpen = false; + }} + /> + + +
+ {/if} +
- - + - {#if hasSomeFilter} -
- -
-

- The following filters will be locked and hidden: -

-
- -
-
- -

- Measures and dimensions will be limited to current visible set. -

- {/if} + {#if isCanvas} + + {:else} + {/if}