diff --git a/apps/frontend/src/lib/components/blocks/forms/form-display.svelte b/apps/frontend/src/lib/components/blocks/forms/form-display.svelte index 56d07a21e..fb9a3885e 100644 --- a/apps/frontend/src/lib/components/blocks/forms/form-display.svelte +++ b/apps/frontend/src/lib/components/blocks/forms/form-display.svelte @@ -13,7 +13,6 @@ import { queryParam } from "sveltekit-search-params" import { Input } from "$lib/components/ui/input" import { Label } from "$lib/components/ui/label" - import ScrollArea from "$lib/components/ui/scroll-area/scroll-area.svelte" import autoAnimate from "@formkit/auto-animate" import Button from "$lib/components/ui/button/button.svelte" import { PlusIcon, GripVerticalIcon } from "lucide-svelte" @@ -22,6 +21,8 @@ import { getFormBgColor } from "./form-bg-color" import { invalidate } from "$app/navigation" + export let readonly = false + const selectedFieldId = queryParam("formField") const table = getTable() @@ -84,13 +85,21 @@ { setForm() isEditingFormName = false }} /> {:else} -

(isEditingFormName = true)}> +

{ + if (!readonly) { + isEditingFormName = true + } + }} + > {form.name}

{/if} @@ -98,9 +107,9 @@ {#if form.description || isAddingDescription}
- +
- {:else} + {:else if !readonly} {/if} @@ -167,6 +183,7 @@ + import { getTable } from "$lib/store/table.store" + import { formId } from "$lib/store/tab.store" + import FormDisplay from "$lib/components/blocks/forms/form-display.svelte" + + const table = getTable() + + $: form = $formId ? $table.forms?.getFormById($formId) : $table.forms?.forms[0] + + +{#if form} + +{/if} diff --git a/apps/frontend/src/lib/components/blocks/forms/forms-readonly.svelte b/apps/frontend/src/lib/components/blocks/forms/forms-readonly.svelte new file mode 100644 index 000000000..e102c9740 --- /dev/null +++ b/apps/frontend/src/lib/components/blocks/forms/forms-readonly.svelte @@ -0,0 +1,37 @@ + + +
+ + +
    + {#each forms as form} + {@const active = $formId === form.id || (!$formId && form.id === forms[0].id)} + + {/each} +
+
+ + + + +
+
diff --git a/apps/frontend/src/lib/components/blocks/forms/forms.svelte b/apps/frontend/src/lib/components/blocks/forms/forms.svelte index 6fbbf8ea2..803c76fbc 100644 --- a/apps/frontend/src/lib/components/blocks/forms/forms.svelte +++ b/apps/frontend/src/lib/components/blocks/forms/forms.svelte @@ -2,13 +2,19 @@ import { getTable } from "$lib/store/table.store" import EmptyForms from "./empty-forms.svelte" import FormEditor from "./form-editor.svelte" + import FormsReadonly from "./forms-readonly.svelte" + import { hasPermission } from "$lib/store/space-member.store" const table = getTable() $: forms = $table.forms + + export let readonly = false {#if !forms?.value.length} +{:else if readonly || !$hasPermission("form:update")} + {:else} {/if} diff --git a/apps/frontend/src/lib/store/tab.store.ts b/apps/frontend/src/lib/store/tab.store.ts index 2e27d5fd9..f924a0aea 100644 --- a/apps/frontend/src/lib/store/tab.store.ts +++ b/apps/frontend/src/lib/store/tab.store.ts @@ -3,6 +3,7 @@ import { queryParam, ssp } from "sveltekit-search-params" export const tab = queryParam("tab", ssp.string()) +export const isDataTab = derived(tab, ($tab) => $tab === "data" || !$tab) export const isFormTab = derived(tab, ($tab) => $tab === "form") export const isAuthTab = derived(tab, ($tab) => $tab === "auth") export const isDeveloperTab = derived(tab, ($tab) => $tab === "developer") diff --git a/apps/frontend/src/routes/(authed)/(space)/t/[tableId]/[[viewId]]/+page.svelte b/apps/frontend/src/routes/(authed)/(space)/t/[tableId]/[[viewId]]/+page.svelte index 76befc344..339f0ac7a 100644 --- a/apps/frontend/src/routes/(authed)/(space)/t/[tableId]/[[viewId]]/+page.svelte +++ b/apps/frontend/src/routes/(authed)/(space)/t/[tableId]/[[viewId]]/+page.svelte @@ -7,9 +7,8 @@ import TableHeader from "$lib/components/blocks/table-header/table-header.svelte" import Forms from "$lib/components/blocks/forms/forms.svelte" import Auth from "$lib/components/blocks/auth/auth.svelte" - import RecordDetailSheet from "$lib/components/blocks/record-detail/record-detail-sheet.svelte" import Developer from "$lib/components/blocks/developer/developer.svelte" - import { tab } from "$lib/store/tab.store" + import { isFormTab, isAuthTab, isDataTab } from "$lib/store/tab.store" import { CREATE_RECORD_MODAL, toggleModal } from "$lib/store/modal.store" import UpdateViewDialog from "$lib/components/blocks/view/update-view-dialog.svelte" import DuplicateViewDialog from "$lib/components/blocks/view/duplicate-view-dialog.svelte" @@ -36,11 +35,11 @@ {#key $table.id.value}
- {#if !$tab || $tab === "data"} + {#if $isDataTab} - {:else if $tab === "form"} + {:else if $isFormTab} - {:else if $tab === "auth"} + {:else if $isAuthTab} {:else} diff --git a/packages/authz/src/space-member/space-action.ts b/packages/authz/src/space-member/space-action.ts index 20da3269b..fff1a78dd 100644 --- a/packages/authz/src/space-member/space-action.ts +++ b/packages/authz/src/space-member/space-action.ts @@ -18,6 +18,12 @@ export const spaceActions = z.enum([ "table:list", "table:delete", + "form:create", + "form:update", + "form:list", + "form:delete", + "form:read", + "field:create", "field:update", "field:delete", diff --git a/packages/authz/src/space-member/space-permission.ts b/packages/authz/src/space-member/space-permission.ts index 4242fa10d..2002504d8 100644 --- a/packages/authz/src/space-member/space-permission.ts +++ b/packages/authz/src/space-member/space-permission.ts @@ -20,6 +20,12 @@ export const spacePermission: Record { yield* this.props } + get forms() { + return this.props + } + $setForm(dto: IFormDTO): WithFormSpecification { const previous = this.props.find((form) => form.id === dto.id)?.toJSON() return new WithFormSpecification(previous, FormVO.fromJSON(dto))