From 0faedba4959b26e357bc09266c47eaaeda91bbf4 Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Fri, 4 Sep 2026 23:01:06 +0200 Subject: [PATCH] feat(datatables): a shared data table is listed in the settings, read only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A fork could use its parent's data table but had nowhere to see that it had one: the settings form reads the config, and the pointer lives outside `datatables`. It is now a row of its own, naming the workspace it belongs to, with no name to edit, no database to repoint and no delete — it is configured, and its permissions administered, where it lives. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01S5arH3G2Sa1Qqm32veJQ1n --- backend/windmill-api/openapi.yaml | 13 ++++++++ .../DataTableSettings.svelte | 31 +++++++++++++++++-- .../(logged)/workspace_settings/+page.svelte | 2 +- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index 92efcfab57..f5e681bc49 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -33920,6 +33920,19 @@ components: type: object description: Schema snapshot at fork time additionalProperties: true + shared_datatables: + type: object + description: >- + Data tables of other workspaces that this one uses. Read-only here: + they are configured, and their permissions administered, in the + workspace named by `from`. + additionalProperties: + type: object + required: [from] + properties: + from: + type: string + description: The workspace this data table belongs to DatatableMigration: type: object required: [datatable, timestamp, name, code_up] diff --git a/frontend/src/lib/components/workspaceSettings/DataTableSettings.svelte b/frontend/src/lib/components/workspaceSettings/DataTableSettings.svelte index 435b1723ef..26b7026750 100644 --- a/frontend/src/lib/components/workspaceSettings/DataTableSettings.svelte +++ b/frontend/src/lib/components/workspaceSettings/DataTableSettings.svelte @@ -13,12 +13,16 @@ resource_path?: string | undefined } }[] + /// Data tables of other workspaces that this one uses. Not this form's to + /// edit — they are configured, and their permissions administered, where + /// they live — so they are listed and left out of what it saves. + sharedDataTables: { name: string; from: string }[] } export function convertDataTableSettingsFromBackend( settings: GetSettingsResponse['datatable'] ): DataTableSettingsType { - const s: DataTableSettingsType = { dataTables: [] } + const s: DataTableSettingsType = { dataTables: [], sharedDataTables: [] } if (settings?.datatables) { for (const [name, rest] of Object.entries(settings.datatables)) { s.dataTables.push({ @@ -28,6 +32,9 @@ }) } } + for (const [name, entry] of Object.entries(settings?.shared_datatables ?? {})) { + s.sharedDataTables.push({ name, from: entry.from }) + } return s } export function convertDataTableSettingsToBackend( @@ -316,7 +323,7 @@ - {#if tempSettings.dataTables.length == 0} + {#if tempSettings.dataTables.length == 0 && tempSettings.sharedDataTables.length == 0} {#if wizardEnabled} @@ -492,6 +499,26 @@ {/each} + {#each tempSettings.sharedDataTables as shared (shared.name)} + + + {shared.name} + + + + Shared from {shared.from} + + + This data table belongs to {shared.from}. Everyone here reaches it with the roles + that workspace gives them, and it is configured there. + + + + + + + + {/each} {#if !wizardEnabled || tempSettings.dataTables.length > 0} diff --git a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte index 8dd2937273..c024d6517a 100644 --- a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte @@ -252,7 +252,7 @@ volumeStorage: undefined }) - let dataTableSettings: DataTableSettingsType = $state({ dataTables: [] }) + let dataTableSettings: DataTableSettingsType = $state({ dataTables: [], sharedDataTables: [] }) let dataTableSettingsComponent: DataTableSettings | undefined = $state(undefined) let dbtSettings: DbtSettingsType = $state({ warehouses: [] })