124 lines
6.0 KiB
Markdown
124 lines
6.0 KiB
Markdown
|
|
# T08a: Frontend DMS + Tags + Permissions UI — Implementation Briefing
|
|||
|
|
|
|||
|
|
## Task
|
|||
|
|
Implement frontend UI for DMS plugin (file browser, upload, preview, share, trash), Tags UI (assign, bulk, tag cloud), and Permissions UI (share links, permission display).
|
|||
|
|
|
|||
|
|
## Requirements
|
|||
|
|
- F-DMS-01–07: DMS file browser, folder tree, upload, preview, share, trash, search
|
|||
|
|
- F-FILEUI-01–06: File UI components (dropzone, preview modal, share dialog, bulk actions, trash view)
|
|||
|
|
- F-TAG-01–04: Tags UI (assign, bulk assign, tag cloud, tag picker)
|
|||
|
|
- F-PERM-03–05: Permissions UI (share links, permission display)
|
|||
|
|
- F-LINK-01–05: Entity links UI
|
|||
|
|
|
|||
|
|
## Acceptance Criteria (12 ACs)
|
|||
|
|
1. DMS route /dms renders file browser with folder tree + file grid
|
|||
|
|
2. DMS upload: drag file to dropzone → upload progress → file appears in list
|
|||
|
|
3. DMS file preview modal opens with PDF.js for PDF files
|
|||
|
|
4. DMS share dialog: select user/group, set permission, share created
|
|||
|
|
5. DMS public share link: copy button generates URL, optional password+expiry fields
|
|||
|
|
6. DMS bulk select → bulk-move or bulk-delete actions appear
|
|||
|
|
7. DMS trash view: deleted files list, restore button per file
|
|||
|
|
8. Mail: shared mailbox selector (DO NOT IMPLEMENT — belongs to T08c)
|
|||
|
|
9. Tags: tag picker on company/contact detail → assign/unassign
|
|||
|
|
10. Tags: bulk select entities → bulk-tag dialog
|
|||
|
|
11. Plugin deactivate → plugin route+menu-item disappear from SPA
|
|||
|
|
12. Plugin activate → plugin route+menu-item appear in SPA
|
|||
|
|
|
|||
|
|
## Backend API Endpoints (already implemented)
|
|||
|
|
### DMS (/api/v1/dms)
|
|||
|
|
- GET /folders — list folder tree
|
|||
|
|
- POST /folders — create folder
|
|||
|
|
- PATCH /folders/{id} — rename/move folder
|
|||
|
|
- DELETE /folders/{id} — delete folder
|
|||
|
|
- POST /files/upload — upload file (multipart)
|
|||
|
|
- GET /files/{id} — get file detail
|
|||
|
|
- PATCH /files/{id} — update file (rename/move)
|
|||
|
|
- DELETE /files/{id} — soft-delete file
|
|||
|
|
- POST /files/{id}/restore — restore from trash
|
|||
|
|
- GET /files/{id}/preview — stream file for preview
|
|||
|
|
- POST /files/{id}/edit-session — create OnlyOffice edit session
|
|||
|
|
- POST /files/{id}/share — share file with user/group
|
|||
|
|
- DELETE /files/{id}/share — remove share
|
|||
|
|
- GET /search?q=text — search files
|
|||
|
|
- GET /shared-with-me — files shared with current user
|
|||
|
|
- POST /files/bulk-move — bulk move files
|
|||
|
|
- POST /files/bulk-delete — bulk delete files
|
|||
|
|
|
|||
|
|
### Tags (/api/v1/tags)
|
|||
|
|
- GET / — list tags
|
|||
|
|
- POST / — create tag
|
|||
|
|
- PATCH /{id} — update tag
|
|||
|
|
- DELETE /{id} — delete tag
|
|||
|
|
- POST /assign — assign tag to entity
|
|||
|
|
- DELETE /assign — unassign tag
|
|||
|
|
- POST /bulk-assign — bulk assign tags
|
|||
|
|
- GET /{id}/entities — list entities for tag
|
|||
|
|
|
|||
|
|
### Permissions (/api/v1/permissions)
|
|||
|
|
- GET /files/{id}/permissions — list permissions
|
|||
|
|
- POST /files/{id}/permissions — grant permission
|
|||
|
|
- DELETE /files/{id}/permissions/{user_id} — revoke permission
|
|||
|
|
- POST /files/{id}/share-link — create public share link
|
|||
|
|
- DELETE /share-links/{id} — revoke share link
|
|||
|
|
|
|||
|
|
## Frontend Architecture (follow existing patterns)
|
|||
|
|
- **Framework:** React + TypeScript + Vite
|
|||
|
|
- **Routing:** react-router-dom (createBrowserRouter, see src/routes/index.tsx)
|
|||
|
|
- **State:** TanStack Query (useQuery/useMutation)
|
|||
|
|
- **HTTP:** axios via src/api/client.ts (apiClient, baseURL /api/v1)
|
|||
|
|
- **API pattern:** See src/api/calendar.ts for plugin API client example
|
|||
|
|
- **UI components:** src/components/ui/ (Button, Card, Input, Modal, Table, Badge, ConfirmDialog, EmptyState, Pagination, Select, Skeleton, Toast)
|
|||
|
|
- **Shared components:** src/components/shared/ (DataGrid, SearchDropdown, Tabs, ActivityFeed)
|
|||
|
|
- **Store:** src/store/ (authStore, uiStore)
|
|||
|
|
- **Layout:** src/components/layout/AppShell (sidebar + main area)
|
|||
|
|
- **i18n:** src/i18n/ (add de.json + en.json keys for DMS/Tags)
|
|||
|
|
|
|||
|
|
## Files to Create
|
|||
|
|
- `src/api/dms.ts` — DMS API client (types + functions)
|
|||
|
|
- `src/api/tags.ts` — Tags API client
|
|||
|
|
- `src/api/permissions.ts` — Permissions API client
|
|||
|
|
- `src/pages/Dms.tsx` — DMS file browser page (folder tree + file grid)
|
|||
|
|
- `src/pages/DmsTrash.tsx` — DMS trash view
|
|||
|
|
- `src/components/dms/FolderTree.tsx` — folder tree sidebar
|
|||
|
|
- `src/components/dms/FileGrid.tsx` — file grid with icons
|
|||
|
|
- `src/components/dms/UploadDropzone.tsx` — drag-drop upload
|
|||
|
|
- `src/components/dms/FilePreviewModal.tsx` — file preview modal
|
|||
|
|
- `src/components/dms/ShareDialog.tsx` — share dialog
|
|||
|
|
- `src/components/dms/BulkActions.tsx` — bulk select actions
|
|||
|
|
- `src/components/tags/TagPicker.tsx` — tag assign/unassign picker
|
|||
|
|
- `src/components/tags/TagCloud.tsx` — tag cloud display
|
|||
|
|
- `src/components/tags/BulkTagDialog.tsx` — bulk tag assignment dialog
|
|||
|
|
- `src/__tests__/dms/DmsPage.test.tsx` — DMS page tests
|
|||
|
|
- `src/__tests__/dms/UploadDropzone.test.tsx` — upload tests
|
|||
|
|
- `src/__tests__/tags/TagPicker.test.tsx` — tag picker tests
|
|||
|
|
- `src/__tests__/tags/BulkTagDialog.test.tsx` — bulk tag tests
|
|||
|
|
- `src/__tests__/permissions/ShareDialog.test.tsx` — share dialog tests
|
|||
|
|
|
|||
|
|
## Files to Modify
|
|||
|
|
- `src/routes/index.tsx` — Add /dms, /dms/trash routes
|
|||
|
|
- `src/components/layout/AppShell.tsx` — Add DMS + Tags menu items to sidebar
|
|||
|
|
- `src/pages/CompanyDetail.tsx` — Add TagPicker component
|
|||
|
|
- `src/pages/ContactDetail.tsx` — Add TagPicker component
|
|||
|
|
- `src/i18n/locales/de.json` — Add DMS/Tags translations
|
|||
|
|
- `src/i18n/locales/en.json` — Add DMS/Tags translations
|
|||
|
|
|
|||
|
|
## Test Spec
|
|||
|
|
- Run: `cd /a0/usr/workdir/dev-projects/leocrm/frontend && npx vitest run src/__tests__/dms/ src/__tests__/tags/ src/__tests__/permissions/ --reporter=verbose`
|
|||
|
|
- Coverage: `npx vitest run src/__tests__/dms/ src/__tests__/tags/ --coverage`
|
|||
|
|
- Build: `npx vite build`
|
|||
|
|
- Type check: `npx tsc --noEmit`
|
|||
|
|
- Coverage target: 80%
|
|||
|
|
- Follow existing test pattern from src/__tests__/companies/ or src/__tests__/calendar/
|
|||
|
|
|
|||
|
|
## Forbidden Patterns
|
|||
|
|
- No inline styles — use Tailwind classes
|
|||
|
|
- No any types — use proper TypeScript interfaces
|
|||
|
|
- No direct fetch() — use apiClient from src/api/client.ts
|
|||
|
|
- No hardcoded strings — use i18n (t() function)
|
|||
|
|
- No Lorem Ipsum — use realistic test data
|
|||
|
|
- No missing loading/error/empty states
|
|||
|
|
|
|||
|
|
## Estimated Size
|
|||
|
|
- ~600 lines code (pages + components + API clients)
|
|||
|
|
- ~300+ lines tests
|