New specs: archer-template-library, ccp-metrics-view-restructure, compliance-list-stale-after-sidebar-edit, compliance-metric-estimated-resolution-date, compliance-remediation-display-fix, flexible-jira-ticket-creation, forecast-burndown-chart, granite-loader-export, ivanti-queue-clear-completed-fix, multi-item-jira-ticket, queue-collapsible-sections, vendor-issue-type-dropdown New steering: archer-template-gen.md Updated: migration-registration-check hook, remediation-plan-history spec, gitlab-workflow, tech, versioning steering files
6.2 KiB
Implementation Plan: Queue Collapsible Sections
Overview
Add collapsible, grouped sections to the IvantiTodoQueuePage. Items are organized into a hybrid layout: an "Inventory" section (CARD, GRANITE, DECOM workflow types) at the top, followed by vendor-grouped sections for FP and Archer items. Each section has a clickable header that toggles visibility. This is a frontend-only change to a single file with property-based tests for the grouping logic.
Tasks
-
1. Add section header styles and icon imports
-
1.1 Add ChevronDown and ChevronRight to the lucide-react import statement
- Add
ChevronDown, ChevronRightto the existing import fromlucide-react - Requirements: 5.2
- Add
-
1.2 Add section header style entries to the STYLES constant
- Add
sectionHeaderInventory,sectionHeaderVendor, andsectionCountstyle objects to the existingSTYLESconstant - Use green accent (
#10B981) for Inventory header, neutral (#94A3B8) for vendor headers - Include
cursor: 'pointer',userSelect: 'none', monospace font, uppercase text - Requirements: 3.3, 3.4, 3.5, 5.1, 5.3
- Add
-
-
2. Implement grouping computation and collapse state
-
2.1 Add the
groupedSectionsuseMemo hook- Add a
useMemothat transformsvisibleItemsinto an array of section objects{ key, label, type, items } - Items with workflow_type CARD, GRANITE, or DECOM go into the Inventory section
- Remaining items are grouped by vendor field (null/empty vendor → "Unknown")
- Inventory section appears first (if non-empty), vendor sections sorted alphabetically
- Sections with zero items are omitted
- Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7
- Add a
-
2.2 Add collapse state and toggle handler
- Add
const [collapsedSections, setCollapsedSections] = useState({})for collapse tracking - Add
toggleSectioncallback that flips the boolean for a given section key - All sections default to expanded (empty object → falsy lookup)
- Requirements: 2.2, 2.7
- Add
-
-
3. Refactor render to use grouped sections with collapsible headers
-
3.1 Replace flat
visibleItems.map(...)with grouped section rendering- Map over
groupedSectionsinstead ofvisibleItemsdirectly - For each section, render a clickable Section Header with chevron icon, label, and item count
- Conditionally render section body (item rows) only when section is not collapsed
- Preserve existing queue item row rendering logic inside each section body
- Add
role="button",tabIndex={0},aria-expanded,aria-labelto section headers for accessibility - Requirements: 2.1, 2.3, 2.4, 2.5, 2.6, 3.1, 3.2
- Map over
-
3.2 Verify cross-section selection still works correctly
- Ensure Select All checkbox still toggles all
visibleItemsacross all sections regardless of collapse state - Ensure selection count reflects total selected items across all sections
- Ensure floating action bar operates on all selected items regardless of collapse state
- Ensure collapsing a section does not clear or modify
selectedIds - Requirements: 4.1, 4.2, 4.3, 4.4, 4.5, 4.6
- Ensure Select All checkbox still toggles all
-
3.3 Verify existing functionality is preserved
- Ticket link badges continue to display on items with associated Jira tickets
- Consolidation modal continues to function with selected items
- Floating action bar appears when items are selected
- Completed items count still displays at the bottom
- Empty state renders without section headers when no visible items exist
- Requirements: 5.4, 5.5, 5.6, 5.7, 5.8
-
-
4. Checkpoint - Ensure frontend builds successfully
- Ensure all tests pass, ask the user if questions arise.
-
5. Write property-based tests for grouping logic
-
* 5.1 Write property test: Grouping Correctness
- Property 1: Grouping Correctness
- Every item with workflow_type CARD, GRANITE, or DECOM appears in the Inventory section; every FP/Archer item appears in the vendor section matching its vendor field (or "Unknown" if null/empty); no item appears in more than one section
- Extract the grouping logic into a testable pure function or test it inline
- Validates: Requirements 1.1, 1.2, 1.5
-
* 5.2 Write property test: Section Ordering
- Property 2: Section Ordering
- Inventory section (if present) is always first; vendor sections are sorted alphabetically by label
- Validates: Requirements 1.3, 1.4
-
* 5.3 Write property test: Empty Section Omission
- Property 3: Empty Section Omission
- No section in the output has zero items; if no inventory-type items exist, no Inventory section appears
- Validates: Requirements 1.6, 1.7
-
* 5.4 Write property test: Section Header Count Accuracy
- Property 4: Section Header Count Accuracy
- For every section, the items array length equals the count that would be displayed in the header
- Validates: Requirements 3.1, 3.2
-
* 5.5 Write property test: Selection Independence from Collapse State
- Property 5: Selection Independence from Collapse State
- Toggling collapse state does not alter the set of selected item IDs; Select All always covers all visible items regardless of collapse
- Validates: Requirements 4.2, 4.4, 4.5
-
-
6. Final checkpoint - Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.
Notes
- Tasks marked with
*are optional and can be skipped for faster MVP - This is a frontend-only change to a single file:
frontend/src/components/pages/IvantiTodoQueuePage.js - Property tests should use
fast-check(already a project dependency) and extract the grouping logic as a pure function for testability - The selection logic (
selectedIds,toggleSelectAll,allVisibleSelected) operates onvisibleItemswhich is independent of collapse state — no changes needed to selection logic - The collapse state is purely visual — it controls rendering, not data
Task Dependency Graph
{
"waves": [
{ "id": 0, "tasks": ["1.1", "1.2"] },
{ "id": 1, "tasks": ["2.1", "2.2"] },
{ "id": 2, "tasks": ["3.1"] },
{ "id": 3, "tasks": ["3.2", "3.3"] },
{ "id": 4, "tasks": ["5.1", "5.2", "5.3", "5.4", "5.5"] }
]
}