Skip to content

2nd Task list No. 3 - Inna #4151

Description

@MuhammadKhalilzadeh

Inna — Next Sprint Frontend ➕ Backend ➕ UI/UX Checklist

Focus: design-system consistency, accessibility, and user experience — but with real backend work so you can own features end-to-end. Each task pairs a frontend UI deliverable with a backend API, validation, or data change.


  • 1. Unify empty, loading, and error states across primary list views

    ModelInventory, Vendors, Policies, Tasks, and TrainingRegistar currently render their own ad-hoc "No data" text, CircularProgress spinners, or blank screens. Audit these pages and replace every bespoke state with the approved EmptyIllustration, skeleton, and error-alert patterns from the StyleGuide. Introduce a lightweight ListStateWrapper component if needed so future list views get the same treatment for free.

    On the backend, ensure the endpoints feeding these pages return consistent empty lists ([]) and standardized 500 envelopes rather than null or raw error strings. Update any repository that returns null for an empty result to return an empty array, because the new wrapper expects array-shaped data.

    Acceptance: Every primary list view uses the approved patterns; backend returns arrays for empty results; StyleGuide screenshots match production; no layout shift between loading and populated states.

  • 2. Add input validation to the approval-request and automations controllers

    approvalRequest.ctrl.ts and automations.ctrl.ts parse request bodies manually and lack route-level validation. Add express-validator chains for create/update payloads and path parameters, and route them through a shared validation-error handler. Pay special attention to the JSON.parse(req.body.params || "{}") pattern in automations, which can throw inside a transaction.

    On the frontend, the approval-request detail panel and automation editor should display field-level errors returned by the backend and disable submit until required fields are valid. Use the existing Field and Select components and ensure error text meets contrast requirements.

    Acceptance: Both controllers reject malformed payloads with a consistent 400 shape; frontend forms show inline errors; no raw JSON.parse remains unguarded; existing tests pass.

  • 3. Mobile responsive audit for EvalsDashboard and PolicyEditor

    EvalsDashboard/NewExperimentModal.tsx, EvalsDashboard/ProjectDatasets.tsx, PolicyEditorPage.tsx, and ProjectView/CEMarking/index.tsx overflow or clip on 375 px and 768 px viewports. Fix horizontal scroll, clipped dropdowns, and tables that do not fit. Use MUI useMediaQuery, responsive tables with horizontal scroll containers, and breakpoint-aware Grid/Stack instead of fixed widths.

    On the backend, add optional ?viewport=compact query parameters to the EvalServer experiments list and the policy metadata endpoints so mobile clients can request a lighter payload with fewer fields. Use the existing pagination helpers and return only the fields the compact UI needs.

    Acceptance: Pages render without horizontal scroll on target viewports; dropdowns and buttons remain usable; backend compact endpoints are tested; responsive screenshots added to PRs.

  • 4. Implement a user date-format preference that flows from backend to UI

    Dates are formatted in 105 frontend files using date-fns, dayjs, toLocaleDateString, or isoDateToString, and the user’s date_format preference is not consistently respected. Create a central useFormattedDate(date, options) hook in Clients/src/application/hooks that reads the preference from the authenticated user state and applies the chosen format. Replace the top 20 raw new Date(...).toLocale* occurrences in presentation/.

    On the backend, expose PATCH /api/users/me/preferences to persist date_format (and language) and include the saved values in the JWT payload or a small GET /api/users/me/preferences endpoint. Validate the allowed format strings so only known patterns are accepted.

    Acceptance: All major table and detail views respect the preference; backend endpoint validates and persists the choice; hook has unit tests; no raw toLocaleDateString remains in migrated files.

  • 5. Accessibility pass on icon-only controls and form inputs

    151 frontend files use <IconButton> without a visible label or aria-label, and many form inputs lack associated labels or aria-describedby links to helper text. Add a required ariaLabel prop to the project’s IconButton wrapper (or enforce it via TypeScript) and fix the top 20 most-used icon-only buttons across CommandPalette, PageHeader, ModelInventory, tables, and drawers. Update the Field component to set aria-invalid={!!error} and aria-errormessage={errorTextId} when an error exists.

    On the backend, the public intake form and share-link views are also rendered server-side or as static HTML. Add semantic landmarks (<main>, <nav>, valid heading order) and ensure required inputs have associated <label> elements in those server-rendered templates.

    Acceptance: axe-core scan shows zero critical/serious issues on Dashboard, Tasks, and ModelInventory; icon buttons have accessible names; Field wires ARIA correctly; public forms pass a semantic HTML check.

  • 6. Keyboard navigation and focus traps for overlays

    CommandPalette, AdvisorChat, all Drawer dialogs, ImageLightbox, and modal forms currently have limited keyboard support. Ensure Esc closes each overlay, focus moves inside when opened, tab cycles within the overlay, and focus returns to the trigger element on close. Use MUI’s FocusTrap or a small custom focus-trap hook, and add aria-modal where appropriate.

    On the backend, the commands exposed by the advisor API drive the CommandPalette options. Add a small integration test that verifies the advisor command list endpoint returns stable IDs and labels so the keyboard navigation tests in the frontend can rely on predictable data.

    Acceptance: Keyboard-only navigation succeeds for open/close and form submission on three major overlays; focus returns to trigger; advisor command endpoint test passes; no focusable elements leak outside the overlay.

  • 7. Refactor ScanDetailsPage into co-located sub-components

    Clients/src/presentation/pages/AIDetection/ScanDetailsPage.tsx is over 4,000 lines and mixes data fetching, tabs, findings tables, graphs, suppression dialogs, risk scoring, and export logic. Extract ScanHeader, FindingTabs, SecurityFindingsTable, AIBOMExportPanel, and a useScanDetails hook as co-located sub-components. Keep each sub-component under 250 lines and move data fetching entirely into the hook.

    On the backend, the scan detail endpoint currently returns a deeply nested payload. Add explicit TypeScript DTOs (or generate them from the backend response shape) and share them with the frontend so the new hook and table components are fully typed. Remove any any[] casts in the scan detail data flow.

    Acceptance: Page file shrinks by at least 35%; sub-components render and export correctly; DTOs are typed end-to-end; no any remains in scan detail state.

  • 8. Add a shared StatusBadge component and migrate chip/badge variants

    The codebase has many overlapping badge-like components: Chip.tsx, CategoryChip, DaysChip, TagChip, FrameworkChip, CrossMappingBadge, MappingStrengthBadge, and statusColors.ts. Consolidate them into a single StatusBadge design-system component under Clients/src/presentation/components/StatusBadge with props for variant (risk, status, severity, boolean), size, and uppercase override.

    On the backend, the enums that drive these badges (ReviewStatus, RiskLevel, Severity, etc.) are currently only enforced in TypeScript. Add PostgreSQL CHECK constraints or native enums in migrations for the most common statuses so the database cannot store invalid badge keys.

    Acceptance: New StatusBadge component replaces at least six legacy variants; StyleGuide has a runnable showcase; database constraints exist for the migrated enums; no inline chip styling remains in migrated files.

  • 9. Reduce i18n translation dictionary bloat and split by module

    Clients/src/i18n/translations.ts is ~1.9 MB with 6,675 keys in a single file, increasing bundle size and merge-conflict risk. Split it into module-based files (e.g., common.ts, dashboard.ts, modelInventory.ts, tasks.ts) and lazy-load dictionaries by module so only the keys needed for the current route are fetched. Identify unused keys with the existing npm run i18n:audit:strict script and remove them.

    On the backend, the invitation email utility in Servers/utils/inviteEmail.utils.ts has a TODO to use the recipient’s stored language preference. Wire up that preference lookup and send the invitation email in the recipient’s language, using the same translation keys the frontend uses for consistency.

    Acceptance: Translation file is split into modules; unused keys removed; strict i18n audit passes; invitation emails respect recipient language preference.

  • 10. Document theme tokens in the StyleGuide and migrate top hardcoded values

    Audit Clients/src/presentation/ for the top 20 repeated hardcoded colors and spacing values in inline sx and styled-components. Move them into the MUI theme palette or a shared theme.tokens.ts file. Add a new "Tokens" section to the StyleGuide that documents each token, shows usage examples, and warns against adding new literals.

    On the backend, the email templates and PDF report generators also embed hardcoded colors that drift from the frontend theme. Create a shared JSON color manifest under shared/design-tokens/colors.json and consume it from both the frontend theme and the backend template/rendering utilities. This is the first step toward a single source of truth for brand colors.

    Acceptance: Top 20 repeated literals are theme-derived; StyleGuide has a Tokens section; backend email/PDF utilities read from the shared manifest; no new hardcoded colors pass ESLint.

Metadata

Metadata

Assignees

Labels

UI/UX DesignRelated to User Interface DesignbackendBackend related tasks/issuesenhancementNew feature or requestfrontendFrontend related tasks/issuesintegrations

Type

Fields

No fields configured for Task.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions