feat(ui): hide write UI from users without WRITE_ALL permission

Wrap write-only elements with {#if data.canWrite} in:
- Home page: Neues Dokument link
- Persons list: Neue Person link
- Document detail: Bearbeiten button
- Person detail: edit button, edit form, merge section

Refs #17
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-03-20 09:47:45 +01:00
parent 03a1a86cdb
commit fde75f3fcf
5 changed files with 12 additions and 1 deletions

View File

@@ -191,6 +191,7 @@ $effect(() => {
<!-- DOCUMENT LIST HEADER -->
<div class="mb-2 flex justify-end">
{#if data.canWrite}
<a
href="/documents/new"
class="inline-flex items-center gap-1 text-sm font-medium text-brand-navy/60 transition-colors hover:text-brand-navy"
@@ -198,6 +199,7 @@ $effect(() => {
<img src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Add/Add-General-MD.svg" alt="" aria-hidden="true" class="h-4 w-4" />
{m.docs_btn_new()}
</a>
{/if}
</div>
<!-- DOCUMENT LIST -->

View File

@@ -74,6 +74,7 @@
</div>
<div class="flex items-center gap-3 flex-shrink-0 ml-4 font-sans">
{#if data.canWrite}
<a
href="/documents/{doc.id}/edit"
class="text-brand-navy bg-transparent border border-brand-navy hover:bg-brand-navy hover:text-white px-4 py-2 rounded text-sm font-medium transition flex items-center gap-2"
@@ -81,6 +82,7 @@
<img src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Edit-Content-MD.svg" alt="" aria-hidden="true" class="w-4 h-4" />
{m.btn_edit()}
</a>
{/if}
{#if doc.filePath}
<a

View File

@@ -17,6 +17,7 @@ vi.stubGlobal(
const emptyData = {
user: undefined,
canWrite: true,
filters: { q: '', from: '', to: '', senderId: '', receiverId: '', tags: [] },
documents: [],
initialValues: { senderName: '', receiverName: '' },

View File

@@ -25,6 +25,7 @@ function handleSearch(e: Event) {
<p class="mt-2 max-w-xl font-sans text-sm text-brand-navy/60">
{m.persons_subtitle()}
</p>
{#if data.canWrite}
<a
href="/persons/new"
class="mt-3 inline-flex items-center gap-1 text-sm font-medium text-brand-navy/60 transition-colors hover:text-brand-navy"
@@ -32,6 +33,7 @@ function handleSearch(e: Event) {
<img src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Add/Add-General-MD.svg" alt="" aria-hidden="true" class="h-4 w-4" />
{m.persons_btn_new()}
</a>
{/if}
</div>
<!-- Search Input -->

View File

@@ -81,7 +81,7 @@
<div class="h-2 bg-brand-navy w-full"></div>
<div class="p-8 md:p-10">
{#if editMode}
{#if editMode && data.canWrite}
<!-- Edit Form -->
<form method="POST" action="?/update" use:enhance>
<div class="flex flex-col gap-6">
@@ -191,10 +191,12 @@
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"/></svg>
{m.person_btn_conversations()}
</a>
{#if data.canWrite}
<button onclick={() => (editMode = true)} class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-bold uppercase tracking-widest border border-gray-300 text-gray-500 rounded hover:border-brand-navy hover:text-brand-navy transition-colors">
<img src="/degruyter-icons/Simple/Small-16px/SVG/Action/Edit-Content-SM.svg" alt="" aria-hidden="true" class="w-3.5 h-3.5" />
{m.btn_edit()}
</button>
{/if}
</div>
</div>
@@ -236,6 +238,7 @@
</div>
<!-- Merge Section -->
{#if data.canWrite}
{#key person.id}
<div class="bg-white shadow-sm border border-brand-sand rounded-sm overflow-hidden mb-10">
<div class="p-6 md:p-8">
@@ -298,6 +301,7 @@
</div>
</div>
{/key}
{/if}
<!-- Co-Correspondents Section -->
{#if coCorrespondents().length > 0}