feat(phase2): per-board access control UI

- BoardAccessControl component with user/group autocomplete
- BoardShareDialog modal with copy link, guest toggle, quick add
- Board permissions REST API (GET/POST/DELETE)
- Access indicators on BoardCard (lock, globe, shared icons)
- Guest access toggle in board editor with status preview
- Enhanced PermissionEditor with search autocomplete
- i18n translations for all new strings (EN/RU)
This commit is contained in:
2026-03-24 23:29:19 +03:00
parent 477c0e4d52
commit 5bb4fbcedf
16 changed files with 1166 additions and 57 deletions
+28
View File
@@ -3,8 +3,23 @@
import type { PageData } from './$types.js';
import Board from '$lib/components/board/Board.svelte';
import BoardHeader from '$lib/components/board/BoardHeader.svelte';
import BoardShareDialog from '$lib/components/board/BoardShareDialog.svelte';
let { data }: { data: PageData } = $props();
let showShareDialog = $state(false);
async function handleGuestToggle(value: boolean) {
try {
await fetch(`/api/boards/${data.board.id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ isGuestAccessible: value })
});
} catch (err) {
console.error('Failed to update guest access:', err);
}
}
</script>
<svelte:head>
@@ -19,8 +34,21 @@
icon={data.board.icon}
boardId={data.board.id}
canEdit={data.canEdit}
onShare={() => { showShareDialog = true; }}
/>
<Board sections={data.board.sections} allApps={data.allApps} />
</div>
</div>
{#if showShareDialog && data.canEdit}
<BoardShareDialog
boardId={data.board.id}
boardName={data.board.name}
isGuestAccessible={data.board.isGuestAccessible}
users={data.users ?? []}
groups={data.groups ?? []}
onClose={() => { showShareDialog = false; }}
onGuestToggle={handleGuestToggle}
/>
{/if}