From 1f6aec54702b0b8255a084ae597b0202ef8322eb Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Tue, 1 Sep 2026 03:39:06 +0200 Subject: [PATCH] fix(raw apps): show the schemas the picked role can reach --- .../raw_apps/RawAppTemplatePicker.svelte | 27 +++++++++++-- .../raw_apps/datatableUtils.svelte.ts | 40 +++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/frontend/src/lib/components/raw_apps/RawAppTemplatePicker.svelte b/frontend/src/lib/components/raw_apps/RawAppTemplatePicker.svelte index 293895e351..bafa276697 100644 --- a/frontend/src/lib/components/raw_apps/RawAppTemplatePicker.svelte +++ b/frontend/src/lib/components/raw_apps/RawAppTemplatePicker.svelte @@ -21,9 +21,9 @@ import type { Runnable } from './rawAppPolicy' import { type DataTableRef, type RawAppData, formatDataTableRef } from './dataTableRefUtils' import { + createDatatableAccessResource, createDatatablesResource, createRolesResource, - createSchemasResource, rolesWorthPicking, toDatatableItems, toSchemaItems @@ -70,8 +70,10 @@ let opWs = $derived(getOpWs?.() ?? $workspaceStore) const datatables = createDatatablesResource(() => opWs) - const schemas = createSchemasResource( + // What the picked role can reach, which is not what the data table holds. + const access = createDatatableAccessResource( () => selectedDatatable, + () => (showRolePicker ? selectedRole : undefined), () => opWs ) const roles = createRolesResource( @@ -95,7 +97,14 @@ }) const availableDatatables = $derived(datatables.current) - const availableSchemas = $derived(schemas.current) + const availableSchemas = $derived(access.current.schemas) + const canCreateSchema = $derived(access.current.canCreateSchema) + + // A role that cannot create schemas has nothing to name, so the mode goes + // back to the one every role has. + $effect(() => { + if (schemaMode === 'new' && !canCreateSchema) schemaMode = 'none' + }) let hasAutoSelected = false $effect(() => { @@ -316,7 +325,17 @@ {#snippet children({ item })} - + string | undefined, + getRole: () => string | undefined, + getWorkspace: () => string | undefined = () => get(workspaceStore) +) { + return resource( + () => [getDatatable() ?? '', getRole() ?? '', getWorkspace() ?? ''] as const, + async ([datatable, role, workspace]): Promise<{ + schemas: string[] + canCreateSchema: boolean + }> => { + if (!datatable || !workspace) return { schemas: [], canCreateSchema: false } + try { + const tables = await WorkspaceService.listDataTableTables({ + workspace, + roleFor: datatable, + role: role || undefined + }) + const entry = tables.find((t) => t.datatable_name === datatable) + return { + schemas: Object.keys(entry?.schemas ?? {}).sort(), + canCreateSchema: !!entry?.can_create_schema + } + } catch (e) { + console.error('Failed to load datatable access:', e) + return { schemas: [], canCreateSchema: false } + } + }, + { initialValue: { schemas: [], canCreateSchema: false } } + ) +} + /** * Whether naming a role says anything here: a data table without permissions has * none to pick, and one whose single role is the implicit `admin` has no choice