# File Page Requirements This document contains the complete frontend requirements for all file management pages and components. All UI components are dynamically generated from backend metadata—no hardcoding required. ## Table of Contents 1. [Overview](#overview) 2. [Page Structure and Layout](#page-structure-and-layout) 3. [User Interactions and Functionality](#user-interactions-and-functionality) 4. [Backend Routes and API Integration](#backend-routes-and-api-integration) 5. [Field and Attribute Reference](#field-and-attribute-reference) 6. [Dynamic Rendering Guidelines](#dynamic-rendering-guidelines) --- ## Overview The file management page enables users to manage files within their mandate. The frontend consists of a single page (`/files`) with different views/states: - **List View** - Browse, search, filter, and sort files (all information displayed in table) - **Edit View** - Edit file properties in popup/modal - **Upload View** - Upload new files All views use backend-driven UI generation, meaning field definitions, labels, validation rules, and UI structure come entirely from backend metadata through the `/api/attributes/FileItem` endpoint. Views are managed through component state and routing within the same page, not as separate routes. --- ## Page Structure and Layout ### File Management Page (`/files`) The file management page uses different views/states to handle different user interactions. Views are managed through component state and routing within the same page component. ### List View **State:** `view === 'list'` or `selectedFileId === null` **What the user sees:** - **Main Content Area:** - Table or card grid displaying all files in the mandate - Each file row/card shows: file name, MIME type, file size, creation date, mandate ID - **Action buttons column** in table (rendered on first load): - "Edit" button - opens popup/modal edit form for file name - "Delete" button - shows confirmation dialog and deletes file - "Download" button - downloads file to user's device - "Add to Prompt" button - navigates to `/chat-playground` with file attached - All necessary file information displayed in table (no detail view needed) - **Search and Filter Controls:** - General search input box (searches across all text fields) - Field-specific filter controls (one filter per visible field) - Active filter indicators (chips/badges showing applied filters) - "Clear all filters" button when filters are active - **Sorting Controls:** - Clickable column headers with sort indicators (up/down arrows) - Visual indication of current sort field and direction - Support for multi-level sorting - **Pagination Controls:** - Page information display ("Page X of Y", "Showing 1-20 of 45 files") - Previous/Next page buttons - Page number buttons - Page size selector (10, 20, 50, 100 items per page) - **Action Buttons:** - "Upload File" button - opens file upload dialog ### Edit View (Popup/Modal) **State:** `view === 'edit'` and `selectedFileId !== null` (popup/modal overlay) **What the user sees:** - **Edit Form in Popup/Modal:** - Dynamic form with editable file fields only (typically fileName) - Field labels with required indicators (asterisk for required fields) - Help text/tooltips from field descriptions - Input validation errors displayed inline - Form pre-populated with current file values - Save and Cancel buttons in modal footer - On save: Updates file name, closes modal, refreshes table - On cancel: Closes modal without saving ### Upload View **State:** `view === 'upload'` or upload dialog open **What the user sees:** - **Upload Dialog/Form:** - File input/picker for selecting files - Drag-and-drop area with visual feedback - Selected files list with preview - Upload progress indicator - Duplicate file handling information - **Action Buttons:** - Upload button (starts upload) - Cancel button (closes upload dialog) - **Confirmation Dialogs:** - Delete confirmation dialog (on file detail page) --- ## User Interactions and Functionality ### Browsing and Discovery **Search Functionality:** - User types in general search box - Frontend debounces input (300-500ms delay) - Search applies across all text fields in file objects - Results update automatically - Page resets to page 1 when search changes **Field Filtering:** - User selects field to filter by - Frontend shows appropriate filter UI based on field type: - Text fields → Text input with operator selection (contains, equals, startsWith, endsWith) - Integer fields → Number input with comparison operators (gt, gte, lt, lte) or range inputs - Timestamp fields → Date picker with comparison operators or date range picker - Select fields → Dropdown with options from backend metadata - User applies filter → Filter appears as active chip/badge - User can remove individual filters - Multiple filters work together (AND logic) - Page resets to page 1 when filters change **Sorting:** - User clicks column header - Sort direction toggles (asc → desc → remove) - Multiple columns can be sorted (multi-level sorting) - Sort indicators show on column headers - All filters and search preserved when sorting **Pagination:** - User clicks page number or navigation button - Page updates and data refetches - All filters, search, and sort preserved - User changes page size → Page resets to 1, data refetches **View Switching:** - All file information displayed in table (no detail view navigation needed) ### Uploading Files **Upload Interaction:** - User clicks "Upload File" button → Opens upload dialog/form - OR user drags and drops file(s) onto upload area - Drag and drop area highlights when files are dragged over - User selects file(s) from device picker OR drops file(s) on upload area - File upload starts immediately (no size validation) - User clicks Cancel → Closes upload dialog, no action **Drag and Drop Support:** - Upload area supports drag and drop functionality - Visual feedback when files are dragged over (highlight drop zone) - Multiple files can be dropped at once - Files are accepted and uploaded immediately upon drop **Upload Submission:** - File sent as multipart/form-data - Optional `workflowId` parameter can be included - No file size validation (all file sizes accepted) - Success → File appears in list, show success message with duplicate info if applicable - Error handling: - 403 (permission denied) → Show permission error - 400 (validation errors) → Display backend validation errors - Other errors → Show generic error message **Duplicate Handling:** - Backend returns duplicate information in response - Frontend displays appropriate message: - Exact duplicate → "File already exists with identical content. Reusing existing file." - Name conflict → "File already exists with different content. Uploaded as '[new name]'." - New file → "File uploaded successfully" ### Editing Files **Edit Interaction:** - User clicks "Edit" button in table row → Opens popup/modal edit form - Form pre-populated with current file values - User modifies file name in form - Client-side validation shows errors immediately - User clicks Save → Form validates and submits - User clicks Cancel → Closes modal without saving **Form Validation:** - Required field validation (shows error if empty) - Type validation (e.g., text fields must be valid text) - Validation errors displayed inline below fields **Form Submission:** - Only changed fields sent (or all form data) - Success → Close popup/modal, refresh table, show success message - Error handling: - 403 (permission denied) → Show permission error in modal - 400 (validation errors) → Display backend validation errors in modal - Other errors → Show generic error message in modal ### Downloading Files **Download Action:** - User clicks "Download" button in table - Frontend shows loading state - Frontend calls `GET /api/files/{fileId}/download` - Browser triggers download with proper filename - Success → File downloads to user's device - Error handling: - 403 (permission denied) → Show permission error - 404 (not found) → Show not found error - Other errors → Show generic error message **Implementation Notes:** - Download should use proper Content-Disposition header handling - Filename should be properly encoded for Unicode characters ### Adding File to Prompt **Add to Prompt Action:** - User clicks "Add to Prompt" button in table - Frontend fetches file data to get file ID - Frontend navigates to `/chat-playground` page - Frontend pre-selects the file in the file picker/attachments area - Frontend displays file name as context - User can enter prompt text and optionally add more files - User clicks "Start" or "Send" button - Frontend calls `POST /api/chat/playground/start` with file ID in `listFileId` array **Add to Prompt Submission:** - File ID included in `listFileId` array in request body - Prompt text required (user must enter prompt) - Success → Workflow starts with file attached, chat playground updates - Error handling: - 403 (permission denied) → Show permission error - 400 (validation errors) → Display backend validation errors - Other errors → Show generic error message ### Deleting Files **Delete Action:** - User clicks delete button (on detail page or list) - Confirmation dialog appears with file name - Warning about permanent deletion - User confirms → File deleted - User cancels → Dialog closes, no action **Delete Success Handling:** - Success message displayed - Remove file from list or refresh table --- ## Backend Routes and API Integration ### Complete Route Reference All backend routes used by file pages: | Route | Method | Purpose | When Used | Access Control | |-------|--------|---------|-----------|----------------| | `/api/files/list` | GET | Get all files (with pagination) | Initial page load, pagination changes, sort changes, filter changes, search changes | All authenticated users (filtered by mandate) | | `/api/files/{fileId}` | GET | Get file details | Detail page load, edit page load | All authenticated users | | `/api/files/{fileId}` | PUT | Update file | Edit form submission | All authenticated users | | `/api/files/{fileId}` | DELETE | Delete file | User confirms deletion | All authenticated users | | `/api/files/upload` | POST | Upload file | User selects and uploads file | All authenticated users | | `/api/files/{fileId}/download` | GET | Download file | User clicks download button | All authenticated users | | `/api/files/stats` | GET | Get file statistics | Optional: display statistics on page | All authenticated users | | `/api/chat/playground/start` | POST | Start workflow with file | User clicks "Add to Prompt" and starts workflow | All authenticated users | | `/api/attributes/FileItem` | GET | Get field definitions | Page load (once per page) - used to generate all UI components | All authenticated users | ### API Request Patterns **Pagination Request:** ``` GET /api/files/list?pagination={"page":1,"pageSize":20,"sort":[],"filters":null} ``` - `pagination` parameter is JSON-encoded string - If user wants all files: omit `pagination` parameter entirely - Filters structure: `{"search":"query","fieldName":"value",...}` - Optional `mandateId` query parameter to filter by mandate **Upload Request:** ``` POST /api/files/upload Content-Type: multipart/form-data Body: { file: , workflowId: "optional-workflow-id" (optional) } ``` - File sent as multipart/form-data - `workflowId` is optional form field - No file size limits (all sizes accepted) - Handle 403 (permission denied) and 400 (validation errors) - Response includes duplicate information: ```json { "message": "File uploaded successfully", "file": {...}, "duplicateType": "new_file" | "exact_duplicate" | "name_conflict", "originalFileName": "...", "storedFileName": "...", "isDuplicate": false } ``` **Update Request:** ``` PUT /api/files/{fileId} Content-Type: application/json Body: {fieldName: value, ...} ``` - Send only changed fields or all form data - Handle 403 (permission denied) and 400 (validation errors) **Download Request:** ``` GET /api/files/{fileId}/download ``` - Returns file content with Content-Disposition header - Browser automatically triggers download - Filename properly encoded for Unicode characters **Add to Prompt Request:** ``` POST /api/chat/playground/start?workflowMode=Dynamic Content-Type: application/json Body: { "prompt": "User prompt text here...", "listFileId": ["fileId1", "fileId2"], "userLanguage": "en" } ``` - `workflowMode` query parameter is required: "Actionplan", "Dynamic", or "Template" (default: "Dynamic") - `listFileId` array contains file IDs to attach (includes the file from "Add to Prompt" button) - `prompt` field contains user's prompt text - `userLanguage` should match user's preferred language - Handle 403 (permission denied) and 400 (validation errors) **Delete Requests:** ``` DELETE /api/files/{fileId} ``` - Delete operation requires user confirmation - Handle 403 (permission denied) and 404 (not found) gracefully ### Response Handling **Paginated Response:** ```json { "items": [...], "pagination": { "currentPage": 1, "pageSize": 20, "totalItems": 45, "totalPages": 3, "sort": [...], "filters": {...} } } ``` **Error Responses:** - 403 Forbidden → Show permission error message - 404 Not Found → Show "not found" error message - 400 Bad Request → Display validation errors from response - 500 Internal Server Error → Show generic error message --- ## Field and Attribute Reference ### Complete Field List The following is a comprehensive list of all parameters, attributes, and fields that will be displayed for files. All of these are provided by the backend through the `/api/attributes/FileItem` endpoint and should never be hardcoded in the frontend. #### Core File Fields **Identification Fields:** - `id` - Unique file identifier (text, readonly, not required, visible) - `mandateId` - ID of the mandate this file belongs to (text, readonly, not required, visible) **File Properties:** - `fileName` - Name of the file (text, editable, required, visible) - `mimeType` - MIME type of the file (text, readonly, not required, visible) - `fileHash` - Hash of the file (text, readonly, not required, visible) - `fileSize` - Size of the file in bytes (integer, readonly, not required, visible) - `creationDate` - Date when the file was created (timestamp, readonly, not required, visible) ### Pagination Parameters **Request Parameters (`PaginationParams`):** - `page` - Current page number (1-based, minimum 1) - `pageSize` - Number of items per page (minimum 1, maximum 1000) - `sort` - Array of sort field configurations - Each sort field contains: - `field` - Field name to sort by (must match a file field name) - `direction` - Sort direction: "asc" or "desc" - `filters` - Filter criteria dictionary - `search` - General search term (searches across all text fields, case-insensitive) - Field-specific filters: `{fieldName: value}` or `{fieldName: {operator: "operator", value: value}}` - Supported operators: "equals", "contains", "startsWith", "endsWith", "gt", "gte", "lt", "lte", "in", "notIn" **Response Metadata (`PaginationMetadata`):** - `currentPage` - Current page number (1-based) - `pageSize` - Number of items per page - `totalItems` - Total number of items across all pages (after filters applied) - `totalPages` - Total number of pages (calculated from totalItems / pageSize) - `sort` - Current sort configuration applied (array of SortField objects) - `filters` - Current filters applied (mirrors request filters) ### Attribute Definition Structure Each field returned from `/api/attributes/FileItem` contains: - `name` - Field name (e.g., "fileName", "mimeType", "fileSize", "id") - `type` - Field data type (e.g., "text", "integer", "timestamp", "checkbox") - `label` - Localized field label (object with language keys: {"en": "English Label", "fr": "French Label"}) - `description` - Field description text - `required` - Boolean indicating if field is required - `readonly` - Boolean indicating if field is read-only - `editable` - Boolean indicating if field can be edited (inverse of readonly) - `visible` - Boolean indicating if field should be displayed in UI - `options` - Array of options for select fields (each option has `value` and localized `label`) --- ## Dynamic Rendering Guidelines The frontend must render all UI components dynamically based on backend metadata. No field definitions, labels, validation rules, or UI structure should be hardcoded. ### Table Column Generation When rendering the file list table: 1. Fetch attribute definitions from `/api/attributes/FileItem` 2. Filter attributes where `visible: true` to determine which columns to display 3. Use `label` property for column headers (select appropriate language based on user preference) 4. Use `type` property to determine how to format cell values: - `text` fields → Display as plain text - `integer` fields → Display as formatted number (for fileSize, show human-readable format like "1.5 MB") - `timestamp` fields → Format as relative time ("2 hours ago") or absolute date/time based on user preference - `select` fields → Display value using label from options array (match value to option.value, then display option.label) - `checkbox` fields → Display as checkmark icon or "Yes"/"No" text 5. Use `readonly` property to determine if column should be sortable (readonly fields may still be sortable, but editable fields definitely are) 6. Generate click handlers for column headers to update sort parameters and refetch data 7. **Add Actions Column:** - Render action buttons in each table row on first load - Include "Edit" button - opens popup/modal edit form for file name - Include "Delete" button - shows confirmation dialog - Include "Download" button - triggers file download - Include "Add to Prompt" button - navigates to `/chat-playground` with file attached - Buttons should be visible and accessible in each row ### Filter Control Generation When rendering filter controls: 1. Fetch attribute definitions from `/api/attributes/FileItem` 2. Filter attributes where `visible: true` to determine which filters to show 3. For each visible field, generate appropriate filter UI based on `type`: - `text` fields → Text input filter (supports "contains", "equals", "startsWith", "endsWith" operators) - `integer` fields → Number range filter (min/max inputs) or single number input with comparison operators (gt, gte, lt, lte) - `timestamp` fields → Date range picker or single date picker with comparison operators - `select` fields → Dropdown filter with options from `options` array (use localized labels) - `checkbox` fields → Boolean toggle filter (true/false/any) 4. Use `label` property for filter labels (localized) 5. When user applies filter, update `filters` object in pagination parameters and refetch data 6. Display active filters as chips/badges showing field label and value 7. Allow removing individual filters by removing them from `filters` object ### Search Implementation For general search functionality: 1. Display a single search input box (not field-specific) 2. When user types, update `filters.search` in pagination parameters 3. Debounce search input (wait 300-500ms after user stops typing before sending request) 4. Search applies across all text fields in the file object 5. Reset to page 1 when search query changes 6. Combine search with field-specific filters (both are in the `filters` object) ### Form Field Generation When rendering edit forms: 1. Fetch attribute definitions from `/api/attributes/FileItem` 2. Filter attributes where `visible: true` AND `editable: true` to determine which fields to show 3. For each editable field, generate appropriate form input based on `type`: - `text` fields → Text input - `integer` fields → Number input with appropriate min/max constraints - `timestamp` fields → Date/time picker - `select` fields → Dropdown/select input with options from `options` array (use localized labels) - `checkbox` fields → Checkbox input 4. Use `label` property for field labels (localized) 5. Use `required` property to show required indicators (asterisk, etc.) 6. Use `description` property to show help text or tooltips 7. Validate form before submission: - Check all `required: true` fields have values - Validate types (e.g., integer fields must be numbers) - Validate select fields (value must be in options array) 8. On submit, send only changed fields or all form data to update endpoint ### Display Formatting When displaying field values: 1. Use `type` property to determine formatting: - `text` → Display as-is (may need HTML escaping) - `integer` → Format with thousand separators if needed - For `fileSize` field specifically → Format as human-readable (e.g., "1.5 MB", "500 KB", "2.3 GB") - `timestamp` → Format as relative time or absolute date/time - `select` → Look up value in `options` array and display localized label - `checkbox` → Display as checkmark icon or "Yes"/"No" text 2. Handle `null` or `undefined` values gracefully (show "-" or "Not set") 3. Use `readonly` property to determine if field should show edit indicators 4. Special formatting for file fields: - File Size → Always show in human-readable format (bytes → KB → MB → GB) - MIME Type → Display as badge with icon if possible - File Hash → Display as truncated hash (first 8-12 characters) with copy button - Creation Date → Show relative time in list view, absolute date in detail view ### File Size Formatting For the `fileSize` field (integer in bytes), always format as human-readable: ```typescript function formatFileSize(bytes: number): string { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]; } ``` ### Localization All labels and options support multiple languages: 1. Use user's preferred language (from user settings or browser locale) 2. Access localized labels from `label` object: `label[userLanguage]` or `label.en` as fallback 3. For select options, use `option.label[userLanguage]` or `option.label.en` as fallback 4. If label for current language is missing, fall back to English ### Key Principles - Never hardcode field names, labels, types, or validation rules - Always fetch attribute definitions from backend before rendering UI - Use attribute metadata to determine what to display and how to display it - Support all field types dynamically - if backend adds new types, frontend should handle them - Respect `visible`, `editable`, `readonly`, and `required` flags from backend - Use localized labels from backend metadata - Generate filters, forms, and tables entirely from attribute definitions - When backend adds new fields, frontend should automatically display them without code changes - Handle all error cases gracefully (403, 404, 400, 413, 500) - Provide user feedback for all actions (loading states, success messages, error messages) - Format file sizes in human-readable format - Handle file uploads with proper duplicate detection feedback --- ## Summary This document provides complete frontend requirements for all file management pages and components. All requirements follow the principle of **backend-driven UI generation**—no hardcoding of field definitions, labels, or validation rules. The frontend should dynamically generate all UI components from backend metadata provided through the `/api/attributes/FileItem` endpoint. **Key Architecture Pattern:** The file management interface is a single page (`/files`) with different views managed through component state. All interactions happen within the same page component without separate routes. For generic patterns that apply across all entity types (not just files), see the [Dynamic Forms and Pagination documentation](./dynamic-forms-and-pagination.md).