Skip to content

Fix/access profiles layout#50

Open
seiggy wants to merge 6 commits into
mainfrom
fix/access-profiles-layout
Open

Fix/access profiles layout#50
seiggy wants to merge 6 commits into
mainfrom
fix/access-profiles-layout

Conversation

@seiggy

@seiggy seiggy commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

This pull request completes a major refactor and test coverage initiative for the Access Profiles /access admin page in the frontend (src/aipolicyengine-ui). The main changes include: (1) moving all filter state and logic out of the ProfileGrid component into the AccessProfiles page to enforce a clean container/presentation separation, (2) extracting all filter logic into a dedicated, pure-function module (filtering.ts) for testability, (3) establishing Vitest as the standard frontend test framework and adding comprehensive unit tests for the filter logic, and (4) fixing layout and accessibility issues with sticky positioning and ARIA attributes. These changes improve maintainability, enable future features, and ensure robust test coverage.

Access Profiles UI Refactor and Test Foundation

Separation of Concerns & Architecture

  • Moved all filter state (searchQuery, overrideFilter) and filter logic (search/filter helpers, filtered section computation) from ProfileGrid.tsx up to AccessProfiles.tsx, following the container/presentation pattern. Now, the page owns all state and data transformation, while the grid component is responsible only for rendering. [1] [2]
  • Extracted all filter logic into a new pure-function module filtering.ts, exporting cellMatchesSearch, cellMatchesOverride, and selectFilteredView for use in the page and for unit testing.

Testing Infrastructure & Coverage

  • Established Vitest as the standard frontend test framework (Vite-native, fast, React 19 compatible). Added 35 passing unit tests for all filter logic in filtering.test.ts, covering edge cases and ensuring 100% test coverage of pure functions. [1] [2] [3]
  • Added and documented test fixtures and patterns for future component and integration tests.

Layout & Accessibility Improvements

  • Fixed sticky positioning offsets and height calculations for the client list and search bar to align exactly with the header, ensuring a consistent and accessible layout across breakpoints.
  • Added ARIA labels to search inputs and filter controls, improved semantic markup for filter button groups, and verified responsive behavior and accessibility compliance.

Cross-Team & Process Outcomes

  • All architectural, accessibility, and testing gates approved by relevant reviewers (McNulty, Bunk, Zack). The codebase now follows a consistent pattern for state, logic, and rendering separation, with robust test foundations for future frontend work. [1] [2] [3]

Key Files Changed

  • src/aipolicyengine-ui/src/pages/AccessProfiles.tsx — Now owns all filter state, logic, and passes pre-filtered data to the grid.
  • src/aipolicyengine-ui/src/components/accessProfiles/ProfileGrid.tsx — Now a pure rendering component, receives all data and callbacks as props.
  • src/aipolicyengine-ui/src/components/accessProfiles/filtering.ts — New pure logic module for all filter operations.
  • src/aipolicyengine-ui/src/components/accessProfiles/filtering.test.ts — New Vitest unit tests for filter logic.
  • Layout and accessibility fixes in ClientList.tsx and related files.

These changes significantly improve maintainability, testability, and accessibility of the Access Profiles admin UI, and establish a foundation for future frontend

seiggy and others added 6 commits June 26, 2026 14:02
- Pin the client list to a sticky left column that scrolls independently
  from the body content (xl breakpoint); the list fills the pinned viewport
  height and scrolls internally.
- Add a sticky search bar to the profile grid to find policies by API,
  operation, plan, method, or path.
- Add an override filter (All scopes / Direct overrides / Inherited only)
  with a match count and clear-filters control.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…lters

- Corrected sticky positions from top-[5.5rem] to top-16 to match h-16 header
- Fixed client list height calc from h-[calc(100vh-7rem)] to h-[calc(100vh-4rem)]
- Added aria-label to search inputs for screen reader support
- Added role="group", aria-label, and aria-pressed to override filter buttons
- All changes maintain responsive behavior and existing functionality

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Refactored per McNulty's architectural review to follow established
container/presentation pattern:

- Moved searchQuery and overrideFilter state from ProfileGrid to AccessProfiles
- Moved cellMatchesSearch and cellMatchesOverride helpers to page level
- Moved filteredSections and visibleScopeCount memos to page computation
- ProfileGrid now receives pre-filtered data and callbacks as props
- All existing filter behaviors preserved (search, override modes, counts)
- No changes to expand/collapse or cascade resolution logic

Pattern now consistent with other admin pages where the page owns data
transformation and components own rendering.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Moved all filter logic from inline page helpers to dedicated
src/components/accessProfiles/filtering.ts module for Bunk's unit tests:

- Created filtering.ts exporting pure, side-effect-free functions
- Exports: OverrideFilter type, OVERRIDE_FILTERS, cellMatchesSearch,
  cellMatchesOverride, AccessApiSection interface, and selectFilteredView
- AccessProfiles.tsx now imports and calls selectFilteredView via useMemo
- ProfileGrid.tsx imports OverrideFilter type and OVERRIDE_FILTERS from module
- All filter logic now trivially unit-testable without mounting components
- Page still owns state (query/overrideFilter), calls pure helpers, passes results

Satisfies McNulty's separation-of-concerns (state in page, logic out of rendering)
and Bunk's testability requirements (pure functions in dedicated module).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ter logic

- Set up Vitest testing framework with @testing-library/react and jsdom
- Add vitest.config.ts with node environment (pure function tests)
- Add npm test scripts (test, test:watch)
- Write 35 unit tests for filtering.ts covering:
  * cellMatchesSearch: empty query, case-insensitive matching across all fields
    (apiDisplayName, apiId, operationDisplayName, operationId, method,
    urlTemplate, planName), null/undefined handling, non-match cases
  * cellMatchesOverride: all/overrides/inherited filter modes
  * selectFilteredView: global visibility, section visibility under each filter
    mode (all/overrides/inherited), visibleScopeCount math for filtered vs
    unfiltered/expanded sections, empty result cases, filtersActive flag logic

All 35 tests pass. Build verified with tsc and vite build.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…e (2026-06-26)

Session: fix/access-profiles-layout — Access Profiles page UX enhancements

Agents & Outcomes:
- Kima (Frontend): Sticky layout, ARIA labels, filter state/logic lift-up to page layer, pure filter module extraction
- McNulty (Arch): Code review gate — REQUEST CHANGES → APPROVED after separation of concerns refactor
- Bunk (QA): Frontend test framework gap identified; Vitest v4 setup + 35 passing tests for filtering.ts

Commits:
- 862fc5d (coordinator, initial): Sticky columns + search/override filter (separation of concerns violation)
- 4212be7 (Kima): Fixed sticky offsets, added ARIA labels
- 603d5ce (Kima): Lifted filter state/logic to AccessProfiles.tsx
- 4fc0a5a (Kima): Extracted pure filter logic to filtering.ts module
- cdebab4 (Bunk): Vitest setup + 35 unit tests

Key Decision: Zack approved frontend testing infrastructure (Vitest adopted as standard for aipolicyengine-ui)

Files:
- .squad/orchestration-log/20260626T183645Z-{kima,mcnulty,bunk}.md — agent completion logs
- .squad/log/20260626T183645Z-access-profiles-ux.md — session summary
- .squad/decisions.md — merged inbox decisions, archived old entries to decisions-archive-20260626.md
- .squad/agents/{kima,bunk,mcnulty}/history.md — cross-agent context notes (Vitest standard, separation of concerns pattern)

Validation: tsc/eslint/build green; 35 tests pass; Quality gates closed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@seiggy
seiggy requested a review from a team June 26, 2026 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant