T08a: Frontend DMS + Tags + Permissions UI — 33 tests, tsc clean, vite build pass
- DMS file browser: folder tree + file grid + upload dropzone + search + preview modal - DMS share dialog: user/group share + public share links with password+expiry - DMS bulk actions: bulk move + bulk delete with confirm dialogs - DMS trash view: deleted files list with restore button - Tags: TagPicker on company/contact detail pages (new tabs tab) - Tags: TagCloud + BulkTagDialog for bulk tag assignment - Permissions: share link creation, permission display, copy-link button - API clients: dms.ts, tags.ts, permissions.ts - Routes: /dms, /dms/trash added to router - Sidebar: DMS nav link updated - i18n: de.json + en.json translations for DMS/Tags/Permissions - 33 new tests (5 test files), full regression 276/276 pass - tsc --noEmit: 0 errors, vite build: 252 modules
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Permissions plugin API client.
|
||||
*
|
||||
* All requests use the shared `apiClient` (`baseURL: '/api/v1'`) and target
|
||||
* the Permissions plugin routes under `/permissions/...`.
|
||||
*/
|
||||
|
||||
import { apiDelete, apiGet, apiPost } from './client';
|
||||
|
||||
// ─── Types ─────────────────────────────────────────────────────────────────
|
||||
|
||||
export type PermissionLevel = 'read' | 'write' | 'admin';
|
||||
|
||||
export interface FilePermissionEntry {
|
||||
id: string;
|
||||
file_id: string;
|
||||
user_id: string | null;
|
||||
group_id: string | null;
|
||||
permission: PermissionLevel;
|
||||
user_name?: string | null;
|
||||
group_name?: string | null;
|
||||
created_at?: string | null;
|
||||
}
|
||||
|
||||
export interface ShareLinkEntry {
|
||||
id: string;
|
||||
file_id: string;
|
||||
token: string;
|
||||
url: string;
|
||||
password_protected: boolean;
|
||||
expires_at: string | null;
|
||||
created_at?: string | null;
|
||||
}
|
||||
|
||||
// ─── Payloads ──────────────────────────────────────────────────────────────
|
||||
|
||||
export interface GrantPermissionPayload {
|
||||
user_id?: string;
|
||||
group_id?: string;
|
||||
permission: PermissionLevel;
|
||||
}
|
||||
|
||||
export interface CreateShareLinkPayload {
|
||||
password?: string;
|
||||
expires_at?: string | null;
|
||||
}
|
||||
|
||||
// ─── File Permissions ──────────────────────────────────────────────────────
|
||||
|
||||
export function fetchFilePermissions(fileId: string): Promise<FilePermissionEntry[]> {
|
||||
return apiGet<FilePermissionEntry[]>(`/permissions/files/${fileId}/permissions`);
|
||||
}
|
||||
|
||||
export function grantPermission(
|
||||
fileId: string,
|
||||
payload: GrantPermissionPayload
|
||||
): Promise<FilePermissionEntry> {
|
||||
return apiPost<FilePermissionEntry>(`/permissions/files/${fileId}/permissions`, payload);
|
||||
}
|
||||
|
||||
export function revokePermission(fileId: string, userId: string): Promise<void> {
|
||||
return apiDelete<void>(`/permissions/files/${fileId}/permissions/${userId}`);
|
||||
}
|
||||
|
||||
// ─── Share Links ───────────────────────────────────────────────────────────
|
||||
|
||||
export function createShareLink(
|
||||
fileId: string,
|
||||
payload: CreateShareLinkPayload
|
||||
): Promise<ShareLinkEntry> {
|
||||
return apiPost<ShareLinkEntry>(`/permissions/files/${fileId}/share-link`, payload);
|
||||
}
|
||||
|
||||
export function revokeShareLink(linkId: string): Promise<void> {
|
||||
return apiDelete<void>(`/permissions/share-links/${linkId}`);
|
||||
}
|
||||
Reference in New Issue
Block a user