diff --git a/web-common/src/features/charts/ChartAssets.svelte b/web-common/src/features/charts/ChartAssets.svelte index 00957f53735..fae330b2dee 100644 --- a/web-common/src/features/charts/ChartAssets.svelte +++ b/web-common/src/features/charts/ChartAssets.svelte @@ -31,13 +31,14 @@
    {#if $chartFileNames?.data} {#each $chartFileNames.data as chartName (chartName)} + {@const open = $page.url.pathname === `/chart/${chartName}`}
  1. - +
  2. {/each} diff --git a/web-common/src/features/charts/ChartMenuItems.svelte b/web-common/src/features/charts/ChartMenuItems.svelte index 7128ed12085..d0f29404bc3 100644 --- a/web-common/src/features/charts/ChartMenuItems.svelte +++ b/web-common/src/features/charts/ChartMenuItems.svelte @@ -5,18 +5,23 @@ import { deleteFileArtifact } from "../entity-management/actions"; import { EntityType } from "../entity-management/types"; import { useChartRoutes } from "./selectors"; + import { getNextRoute } from "../models/utils/navigate-to-next"; + import { goto } from "$app/navigation"; export let chartName: string; + export let open: boolean; - $: chartRoutes = useChartRoutes($runtime.instanceId); + $: chartRoutesQuery = useChartRoutes($runtime.instanceId); + $: chartRoutes = $chartRoutesQuery.data ?? []; async function handleDeleteChart() { await deleteFileArtifact( $runtime.instanceId, getFileAPIPathFromNameAndType(chartName, EntityType.Chart), EntityType.Chart, - $chartRoutes.data ?? [], ); + + if (open) await goto(getNextRoute(chartRoutes)); } diff --git a/web-common/src/features/custom-dashboards/CustomDashboardAssets.svelte b/web-common/src/features/custom-dashboards/CustomDashboardAssets.svelte index a75c04a8edd..25562d5f282 100644 --- a/web-common/src/features/custom-dashboards/CustomDashboardAssets.svelte +++ b/web-common/src/features/custom-dashboards/CustomDashboardAssets.svelte @@ -38,14 +38,16 @@
      {#if $customDashboardFileNames?.data} {#each $customDashboardFileNames.data as customDashboardName (customDashboardName)} + {@const open = + $page.url.pathname === `/custom-dashboard/${customDashboardName}`}
    1. diff --git a/web-common/src/features/custom-dashboards/CustomDashboardMenuItems.svelte b/web-common/src/features/custom-dashboards/CustomDashboardMenuItems.svelte index 7bc0563639d..5df198576d2 100644 --- a/web-common/src/features/custom-dashboards/CustomDashboardMenuItems.svelte +++ b/web-common/src/features/custom-dashboards/CustomDashboardMenuItems.svelte @@ -5,18 +5,30 @@ import { EntityType } from "../entity-management/types"; import { useCustomDashboardRoutes } from "./selectors"; import * as DropdownMenu from "@rilldata/web-common/components/dropdown-menu/"; + import { goto } from "$app/navigation"; + import { getNextRoute } from "../models/utils/navigate-to-next"; export let customDashboardName: string; + export let open: boolean; - $: customDashboardRoutes = useCustomDashboardRoutes($runtime.instanceId); + $: customDashboardRoutesQuery = useCustomDashboardRoutes($runtime.instanceId); + $: customDashboardRoutes = $customDashboardRoutesQuery.data ?? []; async function handleDeleteCustomDashboard() { - await deleteFileArtifact( - $runtime.instanceId, - getFileAPIPathFromNameAndType(customDashboardName, EntityType.Dashboard), - EntityType.Dashboard, - $customDashboardRoutes.data ?? [], - ); + try { + await deleteFileArtifact( + $runtime.instanceId, + getFileAPIPathFromNameAndType( + customDashboardName, + EntityType.Dashboard, + ), + EntityType.Dashboard, + ); + + if (open) await goto(getNextRoute(customDashboardRoutes)); + } catch (error) { + console.error(error); + } } diff --git a/web-common/src/features/dashboards/DashboardAssets.svelte b/web-common/src/features/dashboards/DashboardAssets.svelte index 226402ecf91..c125b22b270 100644 --- a/web-common/src/features/dashboards/DashboardAssets.svelte +++ b/web-common/src/features/dashboards/DashboardAssets.svelte @@ -84,15 +84,18 @@
        {#if $dashboardNames.data} {#each $dashboardNames.data as dashboardName (dashboardName)} + {@const open = + $page.url.pathname === `/dashboard/${dashboardName}` || + $page.url.pathname === `/dashboard/${dashboardName}/edit`}
      1. openRenameMetricsDefModal(dashboardName)} diff --git a/web-common/src/features/dashboards/DashboardMenuItems.svelte b/web-common/src/features/dashboards/DashboardMenuItems.svelte index 83bb441614f..e8447916718 100644 --- a/web-common/src/features/dashboards/DashboardMenuItems.svelte +++ b/web-common/src/features/dashboards/DashboardMenuItems.svelte @@ -3,7 +3,7 @@ import Explore from "@rilldata/web-common/components/icons/Explore.svelte"; import { useDashboard, - useDashboardFileNames, + useDashboardRoutes, } from "@rilldata/web-common/features/dashboards/selectors"; import { deleteFileArtifact } from "@rilldata/web-common/features/entity-management/actions"; import { getFileAPIPathFromNameAndType } from "@rilldata/web-common/features/entity-management/entity-mappers"; @@ -28,8 +28,10 @@ import { useQueryClient } from "@tanstack/svelte-query"; import { WandIcon } from "lucide-svelte"; import { createEventDispatcher } from "svelte"; + import { getNextRoute } from "../models/utils/navigate-to-next"; export let metricsViewName: string; + export let open: boolean; $: filePath = getFileAPIPathFromNameAndType( metricsViewName, @@ -42,9 +44,10 @@ const { customDashboards } = featureFlags; $: instanceId = $runtime.instanceId; - $: dashboardNames = useDashboardFileNames(instanceId); $: dashboardQuery = useDashboard(instanceId, metricsViewName); $: hasErrors = fileArtifact.getHasErrors(queryClient, instanceId); + $: dashboardRoutesQuery = useDashboardRoutes(instanceId); + $: dashboardRoutes = $dashboardRoutesQuery.data ?? []; /** * Get the name of the dashboard's underlying model (if any). @@ -82,12 +85,17 @@ }; const deleteMetricsDef = async () => { - await deleteFileArtifact( - instanceId, - filePath, - EntityType.MetricsDefinition, - $dashboardNames?.data ?? [], - ); + try { + await deleteFileArtifact( + instanceId, + filePath, + EntityType.MetricsDefinition, + ); + + if (open) await goto(getNextRoute(dashboardRoutes)); + } catch (e) { + console.error(e); + } }; diff --git a/web-common/src/features/entity-management/actions.ts b/web-common/src/features/entity-management/actions.ts index 45309f16bda..723b79c2de5 100644 --- a/web-common/src/features/entity-management/actions.ts +++ b/web-common/src/features/entity-management/actions.ts @@ -1,15 +1,11 @@ -import { goto } from "$app/navigation"; import { notifications } from "@rilldata/web-common/components/notifications"; import { extractFileName } from "@rilldata/web-common/features/sources/extract-file-name"; -import { appScreen } from "@rilldata/web-common/layout/app-store"; import { runtimeServiceDeleteFile, runtimeServiceRenameFile, } from "@rilldata/web-common/runtime-client"; import { httpRequestQueue } from "@rilldata/web-common/runtime-client/http-client"; -import { get } from "svelte/store"; import { getLabel, removeLeadingSlash } from "./entity-mappers"; -import { getNextEntityName } from "./name-utils"; import type { EntityType } from "./types"; export async function renameFileArtifact( @@ -36,7 +32,6 @@ export async function deleteFileArtifact( instanceId: string, filePath: string, type: EntityType, - allPaths: Array, showNotification = true, ) { const name = extractFileName(filePath); @@ -47,10 +42,6 @@ export async function deleteFileArtifact( if (showNotification) { notifications.send({ message: `Deleted ${getLabel(type)} ${name}` }); } - - if (get(appScreen)?.name === name) { - await goto(getNextEntityName(allPaths, name)); - } } catch (err) { console.error(err); } diff --git a/web-common/src/features/entity-management/name-utils.ts b/web-common/src/features/entity-management/name-utils.ts index 19cae9b2d52..8573750f52c 100644 --- a/web-common/src/features/entity-management/name-utils.ts +++ b/web-common/src/features/entity-management/name-utils.ts @@ -29,18 +29,6 @@ export function getName(name: string, others: string[]): string { return result; } -export function getNextEntityName( - entityNames: Array, - entityName: string, -): string { - const idx = entityNames.indexOf(entityName); - if (idx <= 0) { - return entityNames[idx + 1]; - } else { - return entityNames[idx - 1]; - } -} - export function isDuplicateName( name: string, fromName: string, diff --git a/web-common/src/features/models/navigation/ModelAssets.svelte b/web-common/src/features/models/navigation/ModelAssets.svelte index 0cb1fdc12f8..7e69322434f 100644 --- a/web-common/src/features/models/navigation/ModelAssets.svelte +++ b/web-common/src/features/models/navigation/ModelAssets.svelte @@ -61,12 +61,13 @@ {#if showModels}
          {#each modelNames as modelName (modelName)} + {@const open = $page.url.pathname === `/model/${modelName}`}
        1. @@ -75,6 +76,7 @@ { diff --git a/web-common/src/features/models/navigation/ModelMenuItems.svelte b/web-common/src/features/models/navigation/ModelMenuItems.svelte index 9ad0c73b9c2..fea4422decc 100644 --- a/web-common/src/features/models/navigation/ModelMenuItems.svelte +++ b/web-common/src/features/models/navigation/ModelMenuItems.svelte @@ -21,8 +21,11 @@ import { deleteFileArtifact } from "../../entity-management/actions"; import { useCreateDashboardFromTableUIAction } from "../../metrics-views/ai-generation/generateMetricsView"; import { useModel, useModelRoutes } from "../selectors"; + import { goto } from "$app/navigation"; + import { getNextRoute } from "../utils/navigate-to-next"; export let modelName: string; + export let open: boolean; $: modelPath = getFilePathFromNameAndType(modelName, EntityType.Model); $: fileArtifact = fileArtifacts.getFileArtifact(modelPath); @@ -32,7 +35,8 @@ const { customDashboards } = featureFlags; - $: modelRoutes = useModelRoutes($runtime.instanceId); + $: modelRoutesQuery = useModelRoutes($runtime.instanceId); + $: modelRoutes = $modelRoutesQuery.data ?? []; $: modelHasError = fileArtifact.getHasErrors( queryClient, $runtime.instanceId, @@ -55,13 +59,16 @@ ); const handleDeleteModel = async (modelName: string) => { - if ($modelRoutes.data) { + try { await deleteFileArtifact( $runtime.instanceId, getFileAPIPathFromNameAndType(modelName, EntityType.Model), - EntityType.Model, - $modelRoutes.data, + EntityType.MetricsDefinition, ); + + if (open) await goto(getNextRoute(modelRoutes)); + } catch (e) { + console.error(e); } }; diff --git a/web-common/src/features/models/utils/navigate-to-next.ts b/web-common/src/features/models/utils/navigate-to-next.ts new file mode 100644 index 00000000000..47845b8d5c5 --- /dev/null +++ b/web-common/src/features/models/utils/navigate-to-next.ts @@ -0,0 +1,17 @@ +import { page } from "$app/stores"; +import { get } from "svelte/store"; + +export function getNextRoute(assetRoutes: string[]) { + const currentPage = get(page); + const currentPageIndex = assetRoutes.indexOf(currentPage.url.pathname); + + if (assetRoutes.length <= 1 || currentPageIndex === -1) { + return "/"; + } + + if (currentPageIndex === assetRoutes.length - 1) { + return assetRoutes[0]; + } + + return assetRoutes[currentPageIndex + 1]; +} diff --git a/web-common/src/features/sources/navigation/SourceAssets.svelte b/web-common/src/features/sources/navigation/SourceAssets.svelte index 6c4e7674c77..09ace298472 100644 --- a/web-common/src/features/sources/navigation/SourceAssets.svelte +++ b/web-common/src/features/sources/navigation/SourceAssets.svelte @@ -77,6 +77,7 @@
            {#if $sourceNames?.data} {#each $sourceNames.data as sourceName (sourceName)} + {@const open = $page.url.pathname === `/source/${sourceName}`}
          1. queryHandler(sourceName)} >
            @@ -96,6 +97,7 @@ { diff --git a/web-common/src/features/sources/navigation/SourceMenuItems.svelte b/web-common/src/features/sources/navigation/SourceMenuItems.svelte index b4f99c77e41..196bd26c735 100644 --- a/web-common/src/features/sources/navigation/SourceMenuItems.svelte +++ b/web-common/src/features/sources/navigation/SourceMenuItems.svelte @@ -39,8 +39,11 @@ refreshSource, replaceSourceWithUploadedFile, } from "../refreshSource"; + import { goto } from "$app/navigation"; + import { getNextRoute } from "../../models/utils/navigate-to-next"; export let sourceName: string; + export let open: boolean; $: filePath = getFilePathFromNameAndType(sourceName, EntityType.Table); $: fileArtifact = fileArtifacts.getFileArtifact(filePath); @@ -67,7 +70,8 @@ $: sourceFromYaml = useSourceFromYaml($runtime.instanceId, filePath); - $: sourceRoutes = useSourceRoutes($runtime.instanceId); + $: sourceRoutesQuery = useSourceRoutes($runtime.instanceId); + $: sourceRoutes = $sourceRoutesQuery.data ?? []; $: modelNames = useModelFileNames($runtime.instanceId); $: createDashboardFromTable = useCreateDashboardFromTableUIAction( @@ -81,12 +85,13 @@ ); const handleDeleteSource = async () => { - await deleteFileArtifact( - runtimeInstanceId, - filePath, - EntityType.Table, - $sourceRoutes.data ?? [], - ); + try { + await deleteFileArtifact(runtimeInstanceId, filePath, EntityType.Table); + + if (open) await goto(getNextRoute(sourceRoutes)); + } catch (e) { + console.error(e); + } }; const handleCreateModel = async () => {