Redesign doc service UX for scale + add group-based document sharing
- Three-column layout: Sidebar + SourcePanel (views + searchable category tree) + main - DocumentSlideOver (480px right panel): inline editing, type picker, AI suggestion confirm/reject, categories combobox, tags editor, sharing section, raw text, re-analyse/delete actions - ManageCategoriesDialog: inline rename, delete with confirm, search filter - DocumentsPage rewrite: filter chip system, multi-file upload queue, drag-and-drop overlay, bulk actions bar (share/delete), smart TanStack Query polling, URL-driven view state - Sidebar simplified: per-category NavLinks removed; Documents = single NavLink under Apps - Backend: document_shares table (migration 0004), share CRUD endpoints, shared-with-me view, N+1-safe share_count via GROUP BY, recipient download access, X-User-Groups header enforcement - Gateway proxy: injects X-User-Groups header into all document + category proxy requests - Backend users: GET /api/users/me/groups endpoint for share picker combobox - CLAUDE.md, STATUS.md files, and changelog updated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -111,6 +111,20 @@ export interface DocumentOut {
|
||||
watch_path: string | null;
|
||||
suggested_folder: string | null;
|
||||
suggested_filename: string | null;
|
||||
share_count: number;
|
||||
}
|
||||
|
||||
export interface SharedDocumentOut extends DocumentOut {
|
||||
shared_by_user_id: string;
|
||||
shared_via_group_id: string;
|
||||
}
|
||||
|
||||
export interface DocumentShareOut {
|
||||
id: string;
|
||||
document_id: string;
|
||||
group_id: string;
|
||||
shared_by_user_id: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface DocumentPage {
|
||||
@@ -142,6 +156,18 @@ export interface DocumentStatusOut {
|
||||
export const listDocuments = (params: DocumentListParams = {}) =>
|
||||
api.get<DocumentPage>("/documents", { params }).then((r) => r.data);
|
||||
|
||||
export const listSharedWithMe = (params: DocumentListParams = {}) =>
|
||||
api.get<DocumentPage>("/documents/shared-with-me", { params }).then((r) => r.data);
|
||||
|
||||
export const getDocumentShares = (docId: string) =>
|
||||
api.get<DocumentShareOut[]>(`/documents/${docId}/shares`).then((r) => r.data);
|
||||
|
||||
export const addDocumentShare = (docId: string, groupId: string) =>
|
||||
api.post<DocumentShareOut>(`/documents/${docId}/shares`, { group_id: groupId }).then((r) => r.data);
|
||||
|
||||
export const removeDocumentShare = (docId: string, groupId: string) =>
|
||||
api.delete(`/documents/${docId}/shares/${groupId}`);
|
||||
|
||||
export const getDocument = (id: string) =>
|
||||
api.get<DocumentOut>(`/documents/${id}`).then((r) => r.data);
|
||||
|
||||
@@ -289,6 +315,16 @@ export const updateDocumentLimits = (max_pdf_mb: number) =>
|
||||
export const getDocumentLimits = () =>
|
||||
api.get<Record<string, unknown>>("/settings/documents/limits").then((r) => r.data);
|
||||
|
||||
// --- User groups (current user's own memberships) ---
|
||||
export interface UserGroupOut {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string | null;
|
||||
}
|
||||
|
||||
export const getMyGroups = () =>
|
||||
api.get<UserGroupOut[]>("/users/me/groups").then((r) => r.data);
|
||||
|
||||
// --- Groups (admin only) ---
|
||||
export interface GroupOut {
|
||||
id: string;
|
||||
|
||||
Reference in New Issue
Block a user