From e97b5583a6355b19c1b9be811cf455c57705af28 Mon Sep 17 00:00:00 2001 From: Nishant Bangarwa Date: Tue, 30 Jun 2026 02:45:56 +0530 Subject: [PATCH 1/2] fix canvas names with dots --- .../entity-management/entity-mappers.spec.ts | 18 ++++++++++++++++++ .../entity-management/entity-mappers.ts | 15 +++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/web-common/src/features/entity-management/entity-mappers.spec.ts b/web-common/src/features/entity-management/entity-mappers.spec.ts index 4b26370c8656..c557979b8db7 100644 --- a/web-common/src/features/entity-management/entity-mappers.spec.ts +++ b/web-common/src/features/entity-management/entity-mappers.spec.ts @@ -19,6 +19,24 @@ describe("entity-mappers", () => { expect(getNameFromFile("/path/to/data/adbids.csv.tgz")).toBe("adbids"); }); + it("keeps dots in YAML resource names", () => { + expect(getNameFromFile("/dashboards/dashboard.canvas.yaml")).toBe( + "dashboard.canvas", + ); + }); + + it("keeps dots in YML resource names", () => { + expect(getNameFromFile("/dashboards/dashboard.canvas.yml")).toBe( + "dashboard.canvas", + ); + }); + + it("keeps dots in SQL resource names", () => { + expect(getNameFromFile("/models/orders.latest.sql")).toBe( + "orders.latest", + ); + }); + it("no folder", () => { expect(getNameFromFile("adbids.csv")).toBe("adbids"); }); diff --git a/web-common/src/features/entity-management/entity-mappers.ts b/web-common/src/features/entity-management/entity-mappers.ts index 57bfcd968df5..b3976c660ef7 100644 --- a/web-common/src/features/entity-management/entity-mappers.ts +++ b/web-common/src/features/entity-management/entity-mappers.ts @@ -64,9 +64,20 @@ export function getFileAPIPathFromNameAndType( } export function getNameFromFile(fileName: string): string { - // TODO: do we need a library here? const splits = fileName.split("/"); - const extensionSplits = splits[splits.length - 1]?.split("."); + const basename = splits[splits.length - 1] ?? ""; + + // Rill resource names are inferred by removing only the final resource file + // extension, so dotted names like `dashboard.canvas.yaml` stay intact. + for (const extension of [".yaml", ".yml", ".sql"]) { + if (basename.endsWith(extension)) { + return basename.slice(0, -extension.length); + } + } + + // Non-resource data files keep the legacy behavior of removing compound + // extensions, e.g. `adbids.csv.tgz` -> `adbids`. + const extensionSplits = basename.split("."); return extensionSplits[0]; } From bbaa2747f8acb660b593f6f2d82208b58e6c60c8 Mon Sep 17 00:00:00 2001 From: Nishant Bangarwa Date: Tue, 30 Jun 2026 13:10:14 +0530 Subject: [PATCH 2/2] fix dotted resource extension inference --- .../src/features/entity-management/entity-mappers.ts | 3 ++- .../features/entity-management/file-path-utils.ts | 12 ++++++++++-- .../entity-management/infer-resource-kind.spec.ts | 12 ++++++++++++ .../src/features/sources/extract-table-name.spec.ts | 3 +++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/web-common/src/features/entity-management/entity-mappers.ts b/web-common/src/features/entity-management/entity-mappers.ts index b3976c660ef7..a71a4eab0b2f 100644 --- a/web-common/src/features/entity-management/entity-mappers.ts +++ b/web-common/src/features/entity-management/entity-mappers.ts @@ -1,5 +1,6 @@ import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors"; import { EntityType } from "@rilldata/web-common/features/entity-management/types"; +import { RESOURCE_FILE_EXTENSIONS } from "./file-path-utils"; export function getFilePathFromPagePath(path: string): string { const pathSplits = path.split("/"); @@ -69,7 +70,7 @@ export function getNameFromFile(fileName: string): string { // Rill resource names are inferred by removing only the final resource file // extension, so dotted names like `dashboard.canvas.yaml` stay intact. - for (const extension of [".yaml", ".yml", ".sql"]) { + for (const extension of RESOURCE_FILE_EXTENSIONS) { if (basename.endsWith(extension)) { return basename.slice(0, -extension.length); } diff --git a/web-common/src/features/entity-management/file-path-utils.ts b/web-common/src/features/entity-management/file-path-utils.ts index 9f8924e66ab1..ac566322cedd 100644 --- a/web-common/src/features/entity-management/file-path-utils.ts +++ b/web-common/src/features/entity-management/file-path-utils.ts @@ -1,5 +1,7 @@ const FILE_PATH_SPLIT_REGEX = /\//; +export const RESOURCE_FILE_EXTENSIONS = [".yaml", ".yml", ".sql"] as const; + export function extractFileName(filePath: string): string { let fileName = filePath.split(FILE_PATH_SPLIT_REGEX).slice(-1)[0]; const lastIndexOfDot = fileName.lastIndexOf("."); @@ -17,8 +19,14 @@ export function extractFileName(filePath: string): string { export function extractFileExtension(filePath: string): string { const fileName = filePath.split(FILE_PATH_SPLIT_REGEX).slice(-1)[0]; - const lastIndexOfDot = fileName.indexOf("."); - return lastIndexOfDot >= 0 ? fileName.substring(lastIndexOfDot) : ""; + + const resourceExtension = RESOURCE_FILE_EXTENSIONS.find((extension) => + fileName.endsWith(extension), + ); + if (resourceExtension) return resourceExtension; + + const firstIndexOfDot = fileName.indexOf("."); + return firstIndexOfDot >= 0 ? fileName.substring(firstIndexOfDot) : ""; } export function splitFolderAndFileName( diff --git a/web-common/src/features/entity-management/infer-resource-kind.spec.ts b/web-common/src/features/entity-management/infer-resource-kind.spec.ts index 11c23526d3fc..d7b23f11e66c 100644 --- a/web-common/src/features/entity-management/infer-resource-kind.spec.ts +++ b/web-common/src/features/entity-management/infer-resource-kind.spec.ts @@ -48,6 +48,18 @@ describe("inferResourceName", () => { `rows:\n type: invalid\ntype: canvas`, ResourceKind.Canvas, ], + [ + "implicit kind for dotted yaml", + "dashboards/dashboard.canvas.yaml", + `type: canvas\nrows: []`, + ResourceKind.Canvas, + ], + [ + "implicit kind for dotted sql", + "models/orders.latest.sql", + `select * from orders`, + ResourceKind.Model, + ], ]; testCases.forEach(([title, path, contents, expected]) => { diff --git a/web-common/src/features/sources/extract-table-name.spec.ts b/web-common/src/features/sources/extract-table-name.spec.ts index dffbceee866f..beda8a9ff27b 100644 --- a/web-common/src/features/sources/extract-table-name.spec.ts +++ b/web-common/src/features/sources/extract-table-name.spec.ts @@ -36,6 +36,9 @@ const TestCases = [ "table_v1_parquet", ".v1.parquet.gz", ), + ...generateTestCases("dashboard.canvas.yaml", "dashboard_canvas", ".yaml"), + ...generateTestCases("dashboard.canvas.yml", "dashboard_canvas", ".yml"), + ...generateTestCases("orders.latest.sql", "orders_latest", ".sql"), ]; describe("extract-table-name", () => {