diff --git a/web-admin/src/features/alerts/selectors.ts b/web-admin/src/features/alerts/selectors.ts index 7115eec5a30..cbaccf21543 100644 --- a/web-admin/src/features/alerts/selectors.ts +++ b/web-admin/src/features/alerts/selectors.ts @@ -9,7 +9,7 @@ import { createRuntimeServiceListResources, type V1AlertSpec, } from "@rilldata/web-common/runtime-client"; -import { createSmartRefetchInterval } from "@rilldata/web-admin/lib/refetch-interval-store"; +import { smartRefetchIntervalFunc } from "@rilldata/web-admin/lib/refetch-interval-store"; import { derived, type Readable, readable } from "svelte/store"; export function useAlerts(instanceId: string, enabled = true) { @@ -22,7 +22,7 @@ export function useAlerts(instanceId: string, enabled = true) { query: { enabled: enabled && !!instanceId, refetchOnMount: true, - refetchInterval: createSmartRefetchInterval, + refetchInterval: smartRefetchIntervalFunc, }, }, ); diff --git a/web-admin/src/features/dashboards/listing/deploying-dashboards.ts b/web-admin/src/features/dashboards/listing/deploying-dashboards.ts index 928609a0a0c..0d329f5dfc2 100644 --- a/web-admin/src/features/dashboards/listing/deploying-dashboards.ts +++ b/web-admin/src/features/dashboards/listing/deploying-dashboards.ts @@ -1,4 +1,3 @@ -import { isResourceReconciling } from "@rilldata/web-admin/lib/refetch-interval-store.ts"; import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors.ts"; import { createRuntimeServiceListResources, @@ -6,84 +5,82 @@ import { type V1Resource, } from "@rilldata/web-common/runtime-client"; import type { CreateQueryResult } from "@tanstack/svelte-query"; +import { + isResourceReconciling, + smartRefetchIntervalFunc, +} from "@rilldata/web-admin/lib/refetch-interval-store.ts"; export function useDeployingDashboards( instanceId: string, orgName: string, projName: string, - deploying: boolean, deployingDashboard: string | null, ): CreateQueryResult<{ - redirectToDashboardPath: string | null; - dashboardsReconciling: boolean; + redirectPath: string | null; dashboardsErrored: boolean; }> { return createRuntimeServiceListResources(instanceId, undefined, { query: { select: (data) => { - if (!deploying) { + const resources = data.resources ?? []; + const dashboards = resources.filter(isDashboard); + + const reconciling = getDashboardsReconciling( + dashboards, + deployingDashboard, + ); + if (reconciling) { return { - redirectToDashboardPath: null, - dashboardsReconciling: false, + redirectPath: null, dashboardsErrored: false, }; } - const resources = data.resources ?? []; - const dashboards = resources.filter(isDashboard); - const dashboard = getDashboard(dashboards, deployingDashboard) ?? null; - const hasValidDashboard = dashboard - ? isValidDashboard(dashboard) - : false; + const dashboardsErrored = getDashboardsErrored( + dashboards, + deployingDashboard, + ); + if (dashboardsErrored) { + const dashboardsErrored = getDashboardsErrored( + dashboards, + deployingDashboard, + ); + return { + // Redirect to status page is dashboards errored + redirectPath: dashboardsErrored + ? `/${orgName}/${projName}/-/status` + : null, + dashboardsErrored, + }; + } - if (!hasValidDashboard || !dashboard?.meta?.name?.name) { + const dashboard = dashboards.find( + (res) => res.meta?.name?.name === deployingDashboard, + ); + + // Redirect to home page if no specific dashboard was deployed + if (!deployingDashboard || !dashboard?.meta?.name) { return { - redirectToDashboardPath: null, - dashboardsReconciling: getDashboardsReconciling( - dashboards, - deployingDashboard, - ), - dashboardsErrored: getDashboardsErrored( - dashboards, - deployingDashboard, - ), + redirectPath: `/${orgName}/${projName}`, + dashboardsErrored: false, }; } const resourceRoute = - dashboard.meta?.name?.kind === ResourceKind.Explore + dashboard.meta.name.kind === ResourceKind.Explore ? "explore" : "canvas"; - const redirectToDashboardPath = `/${orgName}/${projName}/${resourceRoute}/${dashboard.meta.name.name}`; - + const redirectPath = `/${orgName}/${projName}/${resourceRoute}/${dashboard.meta.name.name}`; return { - redirectToDashboardPath, - dashboardsReconciling: false, + redirectPath, dashboardsErrored: false, }; }, + refetchInterval: smartRefetchIntervalFunc, }, }); } -function getDashboard( - dashboards: V1Resource[], - dashboardName: string | null, -): V1Resource | undefined { - let dashboard: V1Resource | undefined; - if (dashboardName) { - dashboard = dashboards.find( - (res) => res.meta?.name?.name === dashboardName, - ); - } else { - dashboard = - dashboards.find((res) => res.canvas?.state?.validSpec) ?? - dashboards.find((res) => res.explore?.state?.validSpec); - } - - return dashboard; -} - function getDashboardsReconciling( dashboards: V1Resource[], dashboardName: string | null, @@ -116,10 +113,6 @@ function isDashboard(res: V1Resource) { return res.canvas || res.explore; } -function isValidDashboard(res: V1Resource) { - return Boolean(res.canvas?.state?.validSpec || res.explore?.state?.validSpec); -} - function hasErrored(res: V1Resource) { return ( res.meta?.reconcileStatus === V1ReconcileStatus.RECONCILE_STATUS_IDLE && diff --git a/web-admin/src/features/dashboards/listing/selectors.ts b/web-admin/src/features/dashboards/listing/selectors.ts index 7f28a786b57..fa3d3e9803f 100644 --- a/web-admin/src/features/dashboards/listing/selectors.ts +++ b/web-admin/src/features/dashboards/listing/selectors.ts @@ -4,7 +4,7 @@ import type { V1Resource } from "@rilldata/web-common/runtime-client"; import { createRuntimeServiceListResources } from "@rilldata/web-common/runtime-client"; import type { CreateQueryResult } from "@tanstack/svelte-query"; import { derived } from "svelte/store"; -import { createSmartRefetchInterval } from "@rilldata/web-admin/lib/refetch-interval-store"; +import { smartRefetchIntervalFunc } from "@rilldata/web-admin/lib/refetch-interval-store"; export function useDashboardsLastUpdated( instanceId: string, @@ -42,7 +42,7 @@ export function useDashboards( select: (data) => { return data.resources.filter((res) => res.canvas || res.explore); }, - refetchInterval: createSmartRefetchInterval, + refetchInterval: smartRefetchIntervalFunc, }, }); } diff --git a/web-admin/src/features/projects/status/selectors.ts b/web-admin/src/features/projects/status/selectors.ts index d226fb687fd..9724d55bf55 100644 --- a/web-admin/src/features/projects/status/selectors.ts +++ b/web-admin/src/features/projects/status/selectors.ts @@ -7,7 +7,7 @@ import { type V1ListResourcesResponse, } from "@rilldata/web-common/runtime-client"; import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors"; -import { createSmartRefetchInterval } from "@rilldata/web-admin/lib/refetch-interval-store"; +import { smartRefetchIntervalFunc } from "@rilldata/web-admin/lib/refetch-interval-store"; export function useProjectDeployment(orgName: string, projName: string) { return createAdminServiceGetProject( @@ -42,7 +42,7 @@ export function useResources(instanceId: string) { resources: filtered, }; }, - refetchInterval: createSmartRefetchInterval, + refetchInterval: smartRefetchIntervalFunc, }, }, ); diff --git a/web-admin/src/features/scheduled-reports/selectors.ts b/web-admin/src/features/scheduled-reports/selectors.ts index 2fd13655fdb..eccb3973b4a 100644 --- a/web-admin/src/features/scheduled-reports/selectors.ts +++ b/web-admin/src/features/scheduled-reports/selectors.ts @@ -5,7 +5,7 @@ import { createRuntimeServiceGetResource, createRuntimeServiceListResources, } from "@rilldata/web-common/runtime-client"; -import { createSmartRefetchInterval } from "@rilldata/web-admin/lib/refetch-interval-store"; +import { smartRefetchIntervalFunc } from "@rilldata/web-admin/lib/refetch-interval-store"; export function useReports(instanceId: string, enabled = true) { return createRuntimeServiceListResources( @@ -17,7 +17,7 @@ export function useReports(instanceId: string, enabled = true) { query: { enabled: enabled && !!instanceId, refetchOnMount: true, - refetchInterval: createSmartRefetchInterval, + refetchInterval: smartRefetchIntervalFunc, }, }, ); diff --git a/web-admin/src/lib/refetch-interval-store.ts b/web-admin/src/lib/refetch-interval-store.ts index 701e889b6ee..3fd716506f1 100644 --- a/web-admin/src/lib/refetch-interval-store.ts +++ b/web-admin/src/lib/refetch-interval-store.ts @@ -64,13 +64,13 @@ const queryRefetchStateMap = new WeakMap< >(); /** - * Creates a smart refetch interval function that uses a WeakMap to store state. + * A smart refetch interval function that uses a WeakMap to store state. * This approach keeps refetch state per query without mutating the query object. * * @param query The TanStack query object * @returns The refetch interval (number in ms or false to disable) */ -export function createSmartRefetchInterval( +export function smartRefetchIntervalFunc( query: Query< V1ListResourcesResponse, HTTPError, diff --git a/web-admin/src/routes/[organization]/[project]/-/dashboards/+page.svelte b/web-admin/src/routes/[organization]/[project]/-/dashboards/+page.svelte index 5b1ecb27568..93c430bbe3e 100644 --- a/web-admin/src/routes/[organization]/[project]/-/dashboards/+page.svelte +++ b/web-admin/src/routes/[organization]/[project]/-/dashboards/+page.svelte @@ -1,61 +1,19 @@ {project} overview - Rill -{#if showError} - -{:else if showSpinner} - -{:else} - -
- -
-
-{/if} + +
+ +
+
diff --git a/web-admin/src/routes/[organization]/[project]/-/deploy-landing-page/+page.svelte b/web-admin/src/routes/[organization]/[project]/-/deploy-landing-page/+page.svelte new file mode 100644 index 00000000000..cbc16df27b1 --- /dev/null +++ b/web-admin/src/routes/[organization]/[project]/-/deploy-landing-page/+page.svelte @@ -0,0 +1,35 @@ + + + diff --git a/web-admin/src/routes/[organization]/[project]/-/dashboards/+page.ts b/web-admin/src/routes/[organization]/[project]/-/deploy-landing-page/+page.ts similarity index 80% rename from web-admin/src/routes/[organization]/[project]/-/dashboards/+page.ts rename to web-admin/src/routes/[organization]/[project]/-/deploy-landing-page/+page.ts index 2075a09ff34..2a2be6254f0 100644 --- a/web-admin/src/routes/[organization]/[project]/-/dashboards/+page.ts +++ b/web-admin/src/routes/[organization]/[project]/-/deploy-landing-page/+page.ts @@ -1,11 +1,9 @@ import { DeployingDashboardUrlParam } from "@rilldata/web-common/features/project/deploy/utils.ts"; export const load = ({ url: { searchParams } }) => { - const deploying = searchParams.has("deploying"); const deployingDashboard = searchParams.get(DeployingDashboardUrlParam); return { - deploying, deployingDashboard, }; }; diff --git a/web-admin/src/routes/[organization]/[project]/-/invite/+page.svelte b/web-admin/src/routes/[organization]/[project]/-/invite/+page.svelte index 3924ff89bfc..6f5f5f54241 100644 --- a/web-admin/src/routes/[organization]/[project]/-/invite/+page.svelte +++ b/web-admin/src/routes/[organization]/[project]/-/invite/+page.svelte @@ -68,8 +68,8 @@ function getDeployLandingPage() { const u = new URL($page.url); - u.pathname = `/${organization}/${project}/-/dashboards`; - u.searchParams.set("deploying", "true"); + u.pathname = `/${organization}/${project}/-/deploy-landing-page`; + console.log("Redirecting to deploy landing page: ", u.toString()); return u.toString(); } diff --git a/web-common/src/features/dashboards/workspace/DeployProjectCTA.svelte b/web-common/src/features/dashboards/workspace/DeployProjectCTA.svelte index 9193e40392d..4d86f6cfa2e 100644 --- a/web-common/src/features/dashboards/workspace/DeployProjectCTA.svelte +++ b/web-common/src/features/dashboards/workspace/DeployProjectCTA.svelte @@ -66,6 +66,7 @@ $: redirectPageUrl = copyWithAdditionalArguments($page.url, { deploy: "true", }); + $: console.log("Deploy route:", $deployPageUrl); async function onDeploy(resumingDeploy = false) { await waitUntil(() => !get(deploymentState).loading); diff --git a/web-common/src/features/entity-management/file-artifacts.ts b/web-common/src/features/entity-management/file-artifacts.ts index 0be89adcdc1..df6b8e2f314 100644 --- a/web-common/src/features/entity-management/file-artifacts.ts +++ b/web-common/src/features/entity-management/file-artifacts.ts @@ -8,8 +8,9 @@ import { type V1ResourceName, } from "@rilldata/web-common/runtime-client"; import type { QueryClient } from "@tanstack/svelte-query"; -import { derived, get, writable } from "svelte/store"; +import { derived, get, writable, type Readable } from "svelte/store"; import { FileArtifact } from "./file-artifact"; +import { page } from "$app/stores"; class UnsavedFilesStore { private unsavedFiles = writable(new Set()); @@ -171,6 +172,14 @@ export class FileArtifacts { } return null; } + + public createCurrentResourceStore(): Readable { + return derived(page, (pageState, set) => { + const filePath = pageState.url.pathname.replace("/files", ""); + const fileArtifact = this.getFileArtifact(filePath); + return fileArtifact.resourceName.subscribe(set); + }); + } } export const fileArtifacts = new FileArtifacts(); diff --git a/web-common/src/features/project/deploy/UpdateProjectPopup.svelte b/web-common/src/features/project/deploy/UpdateProjectPopup.svelte index 5a2a977c7fd..3974628cc78 100644 --- a/web-common/src/features/project/deploy/UpdateProjectPopup.svelte +++ b/web-common/src/features/project/deploy/UpdateProjectPopup.svelte @@ -1,4 +1,5 @@