Skip to content

chore: restructure and test groups #1894

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

riccardo-forina
Copy link
Contributor

@riccardo-forina riccardo-forina commented Aug 5, 2025

Description

description text...

RHCLOUDXXXX


Screenshots

Before:

After:


Checklist ☑️

  • PR only fixes one issue or story
  • Change reviewed for extraneous code
  • UI best practices adhered to
  • Commits squashed and meaningfully named
  • All PR checks pass locally (build, lint, test, E2E)

  • (Optional) QE: Needs QE attention (OUIA changed, perceived impact to tests, no test coverage)
  • (Optional) QE: Has been mentioned
  • (Optional) UX: Needs UX attention (end user UX modified, missing designs)
  • (Optional) UX: Has been mentioned

Summary by Sourcery

Restructure the groups feature by introducing a new DataView-based implementation and refactoring table and modal logic into modular components. Enhance Storybook coverage with interactive tests, update routing to support the legacy component, and adjust default group fetching to respect admin permissions.

New Features:

  • Implement new DataView-based Groups component with filtering, sorting, bulk actions, and expand/collapse functionality
  • Extract table rendering into reusable GroupsTable, RolesTable, MembersTable, and action menu components
  • Add EditGroupModal and RemoveGroupModal components for group CRUD operations
  • Create comprehensive Storybook stories with interactive MSW-based tests covering listing, filtering, sorting, expansion, bulk actions, routing, and modals

Bug Fixes:

  • Limit default admin and system group fetches to only run for admin users

Enhancements:

  • Restructure feature folder to separate legacy and new implementations
  • Update routing to lazily import the legacy groups component
  • Consolidate modal form template by removing redundant role attribute

Tests:

  • Integrate Storybook play functions using MSW to simulate API calls and verify UI behaviors across various scenarios

Copy link
Contributor

sourcery-ai bot commented Aug 5, 2025

Reviewer's Guide

This PR restructures the groups feature by separating the legacy implementation from a new DataView-based UI: it renames and guards the legacy component, introduces a modern Groups container with DataViewToolbar and debounced fetch logic, extracts a dedicated GroupsTable component with expandable rows and selection, adds new action and modal components (GroupActionsMenu, EditGroupModal, RemoveGroupModal, EmptyGroupsState) with corresponding TypeScript types, updates routing to reference the legacy entrypoint, tweaks ModalFormTemplate by removing an extraneous role attribute, and enriches Storybook with comprehensive stories for both legacy and new components.

Class diagram for new Groups feature structure

classDiagram
  class Groups {
    +useContext(PermissionsContext)
    +useSelector(RBACStore)
    +useDataViewFilters()
    +fetchData()
    +handleRowSelection()
    +handleExpansion()
    +handleSort()
    +handleCreateGroup()
    +handleEditGroup()
    +handleDeleteGroups()
  }
  class GroupsTable {
    +groups: Group[]
    +isLoading: boolean
    +isAdmin: boolean
    +selectedRows: Group[]
    +expandedCells: ExpandedCells
    +sortByState: SortByState
    +onRowSelection()
    +onExpansion()
    +onSort()
    +onEditGroup()
    +onDeleteGroups()
  }
  class GroupActionsMenu {
    +selectedRows: Group[]
    +onCreateGroup()
    +onEditGroup()
    +onDeleteGroups()
  }
  class EditGroupModal {
    +group: Group
    +isOpen: boolean
    +onClose()
    +onSubmit()
    +isSubmitting: boolean
  }
  class RemoveGroupModal {
    +groups: Group[]
    +isOpen: boolean
    +onClose()
    +onConfirm()
    +isRemoving: boolean
    +isLoading: boolean
  }
  class Group {
    +uuid: string
    +name: string
    +description: string
    +principalCount: number | string
    +roleCount: number
    +policyCount: number
    +platform_default: boolean
    +admin_default: boolean
    +system: boolean
    +created: string
    +modified: string
    +roles: RoleWithAccess[]
    +isLoadingRoles: boolean
    +members: PrincipalIn[]
    +isLoadingMembers: boolean
  }
  Groups --> GroupsTable
  GroupsTable --> GroupActionsMenu
  GroupsTable --> Group
  Groups --> EditGroupModal
  Groups --> RemoveGroupModal
  EditGroupModal --> Group
  RemoveGroupModal --> Group
Loading

Class diagram for legacy and new groups entrypoints

classDiagram
  class groups_legacy {
    // Legacy groups implementation
  }
  class Groups {
    // New DataView-based groups implementation
  }
  Routing o-- groups_legacy : now references
  Routing o-- Groups : (not default)
Loading

Class diagram for new Group types

classDiagram
  class Group {
    +uuid: string
    +name: string
    +description?: string
    +principalCount?: number | string
    +roleCount?: number
    +policyCount?: number
    +platform_default?: boolean
    +admin_default?: boolean
    +system?: boolean
    +created?: string
    +modified?: string
    +roles?: RoleWithAccess[]
    +isLoadingRoles?: boolean
    +members?: PrincipalIn[]
    +isLoadingMembers?: boolean
  }
  class GroupsTableProps {
    +groups: Group[]
    +isLoading: boolean
    +isAdmin: boolean
    +selectedRows: Group[]
    +expandedCells: ExpandedCells
    +sortByState: SortByState
    +hasActiveFilters: boolean
    +onRowSelection(newSelection: Group[]): void
    +onExpansion(groupId: string, columnKey: string, isExpanding: boolean): void
    +onSort(event: any, index: number, direction: 'asc' | 'desc'): void
    +onEditGroup(groupId: string): void
    +onDeleteGroups(groupIds: string[]): void
  }
  Group <.. GroupsTableProps : used by
Loading

File-Level Changes

Change Details Files
Rename and guard legacy groups component
  • Rename src/features/groups/groups.js to groups-legacy.js
  • Wrap fetchAdminGroup and fetchSystemGroup calls within an isAdmin check
  • Update routing to lazy-load groups-legacy instead of the original file
src/features/groups/groups-legacy.js
src/Routing.tsx
Introduce new Groups container with DataView
  • Create src/features/groups/Groups.tsx implementing DataViewToolbar with bulk select and filters
  • Integrate debounced fetchData and conditional default-group fetching based on isAdmin
  • Manage sorting, expansion, selection state and navigation via useAppNavigate
src/features/groups/Groups.tsx
Extract GroupsTable component for table rendering
  • Implement expandable rows for roles and members with nested tables
  • Support row selection, sort parameters, and default-group info popover
  • Integrate a row actions dropdown that omits default groups
src/features/groups/components/GroupsTable.tsx
Add action and modal components for group operations
  • Create GroupActionsMenu with create, edit, delete bulk actions
  • Implement EditGroupModal using FormRenderer and async name validator
  • Implement RemoveGroupModal with warning and irreversible-action checkbox
  • Add EmptyGroupsState for filtered and empty scenarios
  • Define TypeScript types for groups feature
src/features/groups/components/GroupActionsMenu.tsx
src/features/groups/components/EditGroupModal.tsx
src/features/groups/components/RemoveGroupModal.tsx
src/features/groups/components/EmptyGroupsState.tsx
src/features/groups/types.ts
Expand Storybook coverage for groups feature
  • Add comprehensive stories for new and legacy Groups components covering loading, user roles, bulk actions, expansions, filtering, sorting, and routing
  • Add component-specific stories for EditGroupModal, RemoveGroupModal
src/features/groups/groups.stories.tsx
src/features/groups/groups-legacy.stories.tsx
src/features/groups/components/EditGroupModal.stories.tsx
src/features/groups/components/RemoveGroupModal.stories.tsx
Fix ModalFormTemplate rendering
  • Remove the role="dialog" prop from PatternFly Modal to avoid invalid attributes
src/components/forms/ModalFormTemplate.tsx

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@riccardo-forina riccardo-forina force-pushed the convert-groups branch 3 times, most recently from 6f349c4 to c47628e Compare August 7, 2025 13:34
this also improves some shared utilities around modals to drop an unnecessary role attribute,
and simplifies the code already committed that was using react-data-view to be easier to read
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