diff --git a/web-common/src/features/charts/ChartMenuItems.svelte b/web-common/src/features/charts/ChartMenuItems.svelte
index 88d38aaf4ef..7128ed12085 100644
--- a/web-common/src/features/charts/ChartMenuItems.svelte
+++ b/web-common/src/features/charts/ChartMenuItems.svelte
@@ -1,20 +1,21 @@
diff --git a/web-common/src/features/charts/selectors.ts b/web-common/src/features/charts/selectors.ts
index 7668eb0a49c..3b1dfcea474 100644
--- a/web-common/src/features/charts/selectors.ts
+++ b/web-common/src/features/charts/selectors.ts
@@ -1,13 +1,21 @@
+import { getRouteFromName } from "@rilldata/web-common/features/entity-management/entity-mappers";
import {
ResourceKind,
useResource,
} from "@rilldata/web-common/features/entity-management/resource-selectors";
+import { EntityType } from "@rilldata/web-common/features/entity-management/types";
import { useMainEntityFiles } from "../entity-management/file-selectors";
export function useChartFileNames(instanceId: string) {
return useMainEntityFiles(instanceId, "charts");
}
+export function useChartRoutes(instanceId: string) {
+ return useMainEntityFiles(instanceId, "charts", (name) =>
+ getRouteFromName(name, EntityType.Chart),
+ );
+}
+
export const useChart = (instanceId: string, chartName: string) => {
return useResource(instanceId, chartName, ResourceKind.Chart);
};
diff --git a/web-common/src/features/custom-dashboards/CustomDashboardMenuItems.svelte b/web-common/src/features/custom-dashboards/CustomDashboardMenuItems.svelte
index 8b6b57e2a8f..7bc0563639d 100644
--- a/web-common/src/features/custom-dashboards/CustomDashboardMenuItems.svelte
+++ b/web-common/src/features/custom-dashboards/CustomDashboardMenuItems.svelte
@@ -1,22 +1,21 @@
diff --git a/web-common/src/features/custom-dashboards/selectors.ts b/web-common/src/features/custom-dashboards/selectors.ts
index ee8c27cd88c..931691b7a5f 100644
--- a/web-common/src/features/custom-dashboards/selectors.ts
+++ b/web-common/src/features/custom-dashboards/selectors.ts
@@ -1,5 +1,13 @@
+import { getRouteFromName } from "@rilldata/web-common/features/entity-management/entity-mappers";
+import { EntityType } from "@rilldata/web-common/features/entity-management/types";
import { useMainEntityFiles } from "../entity-management/file-selectors";
export function useCustomDashboardFileNames(instanceId: string) {
return useMainEntityFiles(instanceId, "custom-dashboards");
}
+
+export function useCustomDashboardRoutes(instanceId: string) {
+ return useMainEntityFiles(instanceId, "custom-dashboards", (name) =>
+ getRouteFromName(name, EntityType.Dashboard),
+ );
+}
diff --git a/web-common/src/features/dashboards/DashboardAssets.svelte b/web-common/src/features/dashboards/DashboardAssets.svelte
index c8669b78101..6985c92032f 100644
--- a/web-common/src/features/dashboards/DashboardAssets.svelte
+++ b/web-common/src/features/dashboards/DashboardAssets.svelte
@@ -7,6 +7,7 @@
import Model from "@rilldata/web-common/components/icons/Model.svelte";
import {
useDashboardFileNames,
+ useDashboardRoutes,
useValidDashboards,
} from "@rilldata/web-common/features/dashboards/selectors";
import { deleteFileArtifact } from "@rilldata/web-common/features/entity-management/actions";
@@ -53,6 +54,7 @@
$: sourceNames = useSourceFileNames(instanceId);
$: modelNames = useModelFileNames(instanceId);
$: dashboardNames = useDashboardFileNames(instanceId);
+ $: dashboardRoutes = useDashboardRoutes(instanceId);
$: dashboards = useValidDashboards(instanceId);
const MetricsSourceSelectionError = (
@@ -168,9 +170,12 @@
);
await deleteFileArtifact(
instanceId,
- dashboardName,
+ getFileAPIPathFromNameAndType(
+ dashboardName,
+ EntityType.MetricsDefinition,
+ ),
EntityType.MetricsDefinition,
- $dashboardNames?.data ?? [],
+ $dashboardRoutes?.data ?? [],
);
// redirect to model when metric is deleted
diff --git a/web-common/src/features/dashboards/selectors.ts b/web-common/src/features/dashboards/selectors.ts
index 8fa0590c9b1..217de3d4952 100644
--- a/web-common/src/features/dashboards/selectors.ts
+++ b/web-common/src/features/dashboards/selectors.ts
@@ -1,4 +1,5 @@
import { filterExpressions } from "@rilldata/web-common/features/dashboards/stores/filter-utils";
+import { getRouteFromName } from "@rilldata/web-common/features/entity-management/entity-mappers";
import { useMainEntityFiles } from "@rilldata/web-common/features/entity-management/file-selectors";
import {
ResourceKind,
@@ -6,6 +7,7 @@ import {
useFilteredResources,
useResource,
} from "@rilldata/web-common/features/entity-management/resource-selectors";
+import { EntityType } from "@rilldata/web-common/features/entity-management/types";
import {
V1Expression,
V1MetricsViewSpec,
@@ -26,6 +28,12 @@ export function useDashboardFileNames(instanceId: string) {
return useMainEntityFiles(instanceId, "dashboards");
}
+export function useDashboardRoutes(instanceId: string) {
+ return useMainEntityFiles(instanceId, "dashboards", (name) =>
+ getRouteFromName(name, EntityType.MetricsDefinition),
+ );
+}
+
export function useDashboard(instanceId: string, metricViewName: string) {
return useResource(instanceId, metricViewName, ResourceKind.MetricsView);
}
diff --git a/web-common/src/features/entity-management/RenameAssetModal.svelte b/web-common/src/features/entity-management/RenameAssetModal.svelte
index 1af900e0285..48854c97c44 100644
--- a/web-common/src/features/entity-management/RenameAssetModal.svelte
+++ b/web-common/src/features/entity-management/RenameAssetModal.svelte
@@ -9,7 +9,11 @@
import * as yup from "yup";
import { runtime } from "../../runtime-client/runtime-store";
import { renameFileArtifact } from "./actions";
- import { getLabel, getRouteFromName } from "./entity-mappers";
+ import {
+ getFileAPIPathFromNameAndType,
+ getLabel,
+ getRouteFromName,
+ } from "./entity-mappers";
import {
INVALID_NAME_MESSAGE,
VALID_NAME_PATTERN,
@@ -50,8 +54,8 @@
try {
await renameFileArtifact(
runtimeInstanceId,
- currentAssetName,
- values.newName,
+ getFileAPIPathFromNameAndType(currentAssetName, entityType),
+ getFileAPIPathFromNameAndType(values.newName, entityType),
entityType,
);
goto(getRouteFromName(values.newName, entityType), {
diff --git a/web-common/src/features/entity-management/actions.ts b/web-common/src/features/entity-management/actions.ts
index d57d1f51251..45309f16bda 100644
--- a/web-common/src/features/entity-management/actions.ts
+++ b/web-common/src/features/entity-management/actions.ts
@@ -1,5 +1,6 @@
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,
@@ -7,26 +8,24 @@ import {
} from "@rilldata/web-common/runtime-client";
import { httpRequestQueue } from "@rilldata/web-common/runtime-client/http-client";
import { get } from "svelte/store";
-import {
- getFileAPIPathFromNameAndType,
- getLabel,
- getRouteFromName,
- removeLeadingSlash,
-} from "./entity-mappers";
+import { getLabel, removeLeadingSlash } from "./entity-mappers";
import { getNextEntityName } from "./name-utils";
import type { EntityType } from "./types";
export async function renameFileArtifact(
instanceId: string,
- fromName: string,
- toName: string,
+ fromPath: string,
+ toPath: string,
type: EntityType,
) {
await runtimeServiceRenameFile(instanceId, {
- fromPath: getFileAPIPathFromNameAndType(fromName, type),
- toPath: getFileAPIPathFromNameAndType(toName, type),
+ fromPath,
+ toPath,
});
+ const fromName = extractFileName(fromPath);
+ const toName = extractFileName(toPath);
+
httpRequestQueue.removeByName(fromName);
notifications.send({
message: `Renamed ${getLabel(type)} ${fromName} to ${toName}`,
@@ -35,14 +34,14 @@ export async function renameFileArtifact(
export async function deleteFileArtifact(
instanceId: string,
- name: string,
+ filePath: string,
type: EntityType,
- names: Array,
+ allPaths: Array,
showNotification = true,
) {
- const path = getFileAPIPathFromNameAndType(name, type);
+ const name = extractFileName(filePath);
try {
- await runtimeServiceDeleteFile(instanceId, removeLeadingSlash(path));
+ await runtimeServiceDeleteFile(instanceId, removeLeadingSlash(filePath));
httpRequestQueue.removeByName(name);
if (showNotification) {
@@ -50,9 +49,7 @@ export async function deleteFileArtifact(
}
if (get(appScreen)?.name === name) {
- const route = getRouteFromName(getNextEntityName(names, name), type);
-
- await goto(route);
+ await goto(getNextEntityName(allPaths, name));
}
} catch (err) {
console.error(err);
diff --git a/web-common/src/features/entity-management/file-selectors.ts b/web-common/src/features/entity-management/file-selectors.ts
index 3ef9916b5ed..08829f50b7b 100644
--- a/web-common/src/features/entity-management/file-selectors.ts
+++ b/web-common/src/features/entity-management/file-selectors.ts
@@ -7,6 +7,7 @@ import { createRuntimeServiceListFiles } from "@rilldata/web-common/runtime-clie
export function useMainEntityFiles(
instanceId: string,
prefix: "sources" | "models" | "dashboards" | "charts" | "custom-dashboards",
+ transform = (name: string) => name,
) {
let extension: string;
switch (prefix) {
@@ -40,7 +41,9 @@ export function useMainEntityFiles(
})
.map((filePath) => {
// Remove the directory and extension from the filePath to get the file name
- return filePath.replace(`/${prefix}/`, "").replace(extension, "");
+ return transform(
+ filePath.replace(`/${prefix}/`, "").replace(extension, ""),
+ );
})
// Sort the file names alphabetically in a case-insensitive manner
.sort((fileNameA, fileNameB) =>
diff --git a/web-common/src/features/metrics-views/workspace/MetricsWorkspaceHeader.svelte b/web-common/src/features/metrics-views/workspace/MetricsWorkspaceHeader.svelte
index 0c6f43b40bf..2f353ed19b8 100644
--- a/web-common/src/features/metrics-views/workspace/MetricsWorkspaceHeader.svelte
+++ b/web-common/src/features/metrics-views/workspace/MetricsWorkspaceHeader.svelte
@@ -2,6 +2,7 @@
import { goto } from "$app/navigation";
import { notifications } from "@rilldata/web-common/components/notifications";
import { renameFileArtifact } from "@rilldata/web-common/features/entity-management/actions";
+ import { getFileAPIPathFromNameAndType } from "@rilldata/web-common/features/entity-management/entity-mappers";
import {
INVALID_NAME_MESSAGE,
VALID_NAME_PATTERN,
@@ -39,7 +40,12 @@
try {
const toName = e.target.value;
const type = EntityType.MetricsDefinition;
- await renameFileArtifact(runtimeInstanceId, metricsDefName, toName, type);
+ await renameFileArtifact(
+ runtimeInstanceId,
+ getFileAPIPathFromNameAndType(metricsDefName, type),
+ getFileAPIPathFromNameAndType(toName, type),
+ type,
+ );
goto(`/dashboard/${toName}/edit`, { replaceState: true });
} catch (err) {
console.error(err.response.data.message);
diff --git a/web-common/src/features/models/navigation/ModelMenuItems.svelte b/web-common/src/features/models/navigation/ModelMenuItems.svelte
index 2d3ff0cde9b..d3cc263f881 100644
--- a/web-common/src/features/models/navigation/ModelMenuItems.svelte
+++ b/web-common/src/features/models/navigation/ModelMenuItems.svelte
@@ -2,7 +2,10 @@
import Cancel from "@rilldata/web-common/components/icons/Cancel.svelte";
import EditIcon from "@rilldata/web-common/components/icons/EditIcon.svelte";
import Explore from "@rilldata/web-common/components/icons/Explore.svelte";
- import { getFilePathFromNameAndType } from "@rilldata/web-common/features/entity-management/entity-mappers";
+ import {
+ getFileAPIPathFromNameAndType,
+ getFilePathFromNameAndType,
+ } from "@rilldata/web-common/features/entity-management/entity-mappers";
import { getFileHasErrors } from "@rilldata/web-common/features/entity-management/resources-store";
import { EntityType } from "@rilldata/web-common/features/entity-management/types";
import { BehaviourEventMedium } from "@rilldata/web-common/metrics/service/BehaviourEventTypes";
@@ -14,7 +17,7 @@
import { runtime } from "../../../runtime-client/runtime-store";
import { deleteFileArtifact } from "../../entity-management/actions";
import { useCreateDashboardFromTableUIAction } from "../../metrics-views/ai-generation/generateMetricsView";
- import { useModel, useModelFileNames } from "../selectors";
+ import { useModel, useModelRoutes } from "../selectors";
import NavigationMenuItem from "@rilldata/web-common/layout/navigation/NavigationMenuItem.svelte";
import NavigationMenuSeparator from "@rilldata/web-common/layout/navigation/NavigationMenuSeparator.svelte";
@@ -25,7 +28,7 @@
const queryClient = useQueryClient();
const dispatch = createEventDispatcher();
- $: modelNames = useModelFileNames($runtime.instanceId);
+ $: modelRoutes = useModelRoutes($runtime.instanceId);
$: modelHasError = getFileHasErrors(
queryClient,
$runtime.instanceId,
@@ -45,12 +48,12 @@
);
const handleDeleteModel = async (modelName: string) => {
- if ($modelNames.data) {
+ if ($modelRoutes.data) {
await deleteFileArtifact(
$runtime.instanceId,
- modelName,
+ getFileAPIPathFromNameAndType(modelName, EntityType.Model),
EntityType.Model,
- $modelNames.data,
+ $modelRoutes.data,
);
}
};
diff --git a/web-common/src/features/models/selectors.ts b/web-common/src/features/models/selectors.ts
index 46295288fc4..aca313741e5 100644
--- a/web-common/src/features/models/selectors.ts
+++ b/web-common/src/features/models/selectors.ts
@@ -1,3 +1,4 @@
+import { getRouteFromName } from "@rilldata/web-common/features/entity-management/entity-mappers";
import { useMainEntityFiles } from "@rilldata/web-common/features/entity-management/file-selectors";
import {
ResourceKind,
@@ -5,6 +6,7 @@ import {
useFilteredResources,
useResource,
} from "@rilldata/web-common/features/entity-management/resource-selectors";
+import { EntityType } from "@rilldata/web-common/features/entity-management/types";
import {
V1ListFilesResponse,
createRuntimeServiceGetFile,
@@ -31,6 +33,12 @@ export function useModelFileNames(instanceId: string) {
return useMainEntityFiles(instanceId, "models");
}
+export function useModelRoutes(instanceId: string) {
+ return useMainEntityFiles(instanceId, "models", (name) =>
+ getRouteFromName(name, EntityType.Model),
+ );
+}
+
export function useModel(instanceId: string, name: string) {
return useResource(instanceId, name, ResourceKind.Model);
}
diff --git a/web-common/src/features/models/workspace/ModelWorkspaceHeader.svelte b/web-common/src/features/models/workspace/ModelWorkspaceHeader.svelte
index 0434792ab53..e825670d955 100644
--- a/web-common/src/features/models/workspace/ModelWorkspaceHeader.svelte
+++ b/web-common/src/features/models/workspace/ModelWorkspaceHeader.svelte
@@ -14,6 +14,7 @@
import { useGetDashboardsForModel } from "../../dashboards/selectors";
import { renameFileArtifact } from "../../entity-management/actions";
import {
+ getFileAPIPathFromNameAndType,
getFilePathFromNameAndType,
getRouteFromName,
} from "../../entity-management/entity-mappers";
@@ -86,8 +87,8 @@
const entityType = EntityType.Model;
await renameFileArtifact(
runtimeInstanceId,
- modelName,
- toName,
+ getFileAPIPathFromNameAndType(modelName, entityType),
+ getFileAPIPathFromNameAndType(toName, entityType),
entityType,
);
await goto(getRouteFromName(toName, entityType), {
@@ -114,7 +115,7 @@
-
+
{@const collapse = width < 800}
{
describe("should extract and sanitise table name", () => {
for (const variation of TestCases) {
it(variation.title, () => {
- expect(sanitizeEntityName(extractTableName(variation.path))).toBe(
+ expect(sanitizeEntityName(extractFileName(variation.path))).toBe(
variation.expectedFileName,
);
});
diff --git a/web-common/src/features/sources/modal/file-upload.ts b/web-common/src/features/sources/modal/file-upload.ts
index 735513178db..3312a0b679b 100644
--- a/web-common/src/features/sources/modal/file-upload.ts
+++ b/web-common/src/features/sources/modal/file-upload.ts
@@ -11,7 +11,7 @@ import {
} from "@rilldata/web-common/features/sources/modal/possible-file-extensions";
import { importOverlayVisible } from "@rilldata/web-common/layout/overlay-store";
import { runtimeServiceFileUpload } from "@rilldata/web-common/runtime-client/manual-clients";
-import { getTableNameFromFile } from "../extract-table-name";
+import { getTableNameFromFile } from "web-common/src/features/sources/extract-file-name";
import {
DuplicateActions,
duplicateSourceAction,
diff --git a/web-common/src/features/sources/navigation/SourceMenuItems.svelte b/web-common/src/features/sources/navigation/SourceMenuItems.svelte
index 54c7cb029ad..2ed7713eb86 100644
--- a/web-common/src/features/sources/navigation/SourceMenuItems.svelte
+++ b/web-common/src/features/sources/navigation/SourceMenuItems.svelte
@@ -5,14 +5,17 @@
import Import from "@rilldata/web-common/components/icons/Import.svelte";
import Model from "@rilldata/web-common/components/icons/Model.svelte";
import RefreshIcon from "@rilldata/web-common/components/icons/RefreshIcon.svelte";
- import { getFilePathFromNameAndType } from "@rilldata/web-common/features/entity-management/entity-mappers";
+ import {
+ getFileAPIPathFromNameAndType,
+ getFilePathFromNameAndType,
+ } from "@rilldata/web-common/features/entity-management/entity-mappers";
import { getFileHasErrors } from "@rilldata/web-common/features/entity-management/resources-store";
import { useModelFileNames } from "@rilldata/web-common/features/models/selectors";
import {
useIsLocalFileConnector,
useSource,
- useSourceFileNames,
useSourceFromYaml,
+ useSourceRoutes,
} from "@rilldata/web-common/features/sources/selectors";
import { appScreen } from "@rilldata/web-common/layout/app-store";
import { overlay } from "@rilldata/web-common/layout/overlay-store";
@@ -66,7 +69,7 @@
$: sourceFromYaml = useSourceFromYaml($runtime.instanceId, filePath);
- $: sourceNames = useSourceFileNames($runtime.instanceId);
+ $: sourceRoutes = useSourceRoutes($runtime.instanceId);
$: modelNames = useModelFileNames($runtime.instanceId);
$: createDashboardFromTable = useCreateDashboardFromTableUIAction(
@@ -79,9 +82,9 @@
const handleDeleteSource = async (tableName: string) => {
await deleteFileArtifact(
runtimeInstanceId,
- tableName,
+ getFileAPIPathFromNameAndType(tableName, EntityType.Table),
EntityType.Table,
- $sourceNames.data ?? [],
+ $sourceRoutes.data ?? [],
);
};
diff --git a/web-common/src/features/sources/selectors.ts b/web-common/src/features/sources/selectors.ts
index b6ec232199a..962ddd8f9d1 100644
--- a/web-common/src/features/sources/selectors.ts
+++ b/web-common/src/features/sources/selectors.ts
@@ -13,7 +13,10 @@ import {
import type { CreateQueryResult, QueryClient } from "@tanstack/svelte-query";
import { Readable, derived } from "svelte/store";
import { parse } from "yaml";
-import { getFilePathFromNameAndType } from "../entity-management/entity-mappers";
+import {
+ getFilePathFromNameAndType,
+ getRouteFromName,
+} from "../entity-management/entity-mappers";
import { EntityType } from "../entity-management/types";
export type SourceFromYaml = {
@@ -34,6 +37,12 @@ export function useSourceFileNames(instanceId: string) {
return useMainEntityFiles(instanceId, "sources");
}
+export function useSourceRoutes(instanceId: string) {
+ return useMainEntityFiles(instanceId, "sources", (name) =>
+ getRouteFromName(name, EntityType.Table),
+ );
+}
+
export function useSource(instanceId: string, name: string) {
return useResource(instanceId, name, ResourceKind.Source);
}
diff --git a/web-common/src/features/sources/sourceUtils.ts b/web-common/src/features/sources/sourceUtils.ts
index 915616d92e2..954e9b89108 100644
--- a/web-common/src/features/sources/sourceUtils.ts
+++ b/web-common/src/features/sources/sourceUtils.ts
@@ -4,7 +4,10 @@ import type {
} from "@rilldata/web-common/runtime-client";
import { getFilePathFromNameAndType } from "../entity-management/entity-mappers";
import { EntityType } from "../entity-management/types";
-import { extractFileExtension, sanitizeEntityName } from "./extract-table-name";
+import {
+ extractFileExtension,
+ sanitizeEntityName,
+} from "@rilldata/web-common/features/sources/extract-file-name";
export function compileCreateSourceYAML(
values: Record,
diff --git a/web-common/src/features/sources/workspace/SourceWorkspaceHeader.svelte b/web-common/src/features/sources/workspace/SourceWorkspaceHeader.svelte
index 3fa05b0f4b3..ba6b241ba87 100644
--- a/web-common/src/features/sources/workspace/SourceWorkspaceHeader.svelte
+++ b/web-common/src/features/sources/workspace/SourceWorkspaceHeader.svelte
@@ -103,8 +103,8 @@
const entityType = EntityType.Table;
await renameFileArtifact(
runtimeInstanceId,
- sourceName,
- toName,
+ getFilePathFromNameAndType(sourceName, entityType),
+ getFilePathFromNameAndType(toName, entityType),
entityType,
);
goto(getRouteFromName(toName, entityType), {
@@ -205,7 +205,7 @@
{/if}
-
+