Skip to content

feat: complete user permissions management system#24

Merged
asithade merged 5 commits intomainfrom
feat/self-permissioning
Aug 7, 2025
Merged

feat: complete user permissions management system#24
asithade merged 5 commits intomainfrom
feat/self-permissioning

Conversation

@asithade
Copy link
Contributor

@asithade asithade commented Aug 5, 2025

Summary

  • Complete CRUD operations for user permissions management
  • Create, edit, and remove users with project or committee-specific permissions
  • Permissions matrix component explaining different permission levels
  • Committee names pipe for better template performance

Features

  • Create Users: Add new users with project or committee-specific permissions
  • Edit Users: Update existing user permissions while preserving user data
  • Remove Users: Remove user permissions from projects (preserves user records)
  • Permission Matrix: Clear documentation of different permission levels and scopes

Technical Implementation

  • Backend API endpoints for all CRUD operations with proper error handling
  • Frontend components: user form, permissions table, and matrix documentation
  • Permission system supporting both project-level and committee-specific scopes
  • Comprehensive form validation and user feedback

🤖 Generated with Claude Code

- Convert getCommitteeNames function to committee-names.pipe for better performance
- Add permissions matrix component explaining different permission levels and scopes
- Implement edit user functionality with proper form initialization and validation
- Add comprehensive remove user functionality that preserves user records
- Fix backend API to handle permission updates with proper 404 handling
- Move committee names pipe to shared pipes folder for reusability
- Update permission service methods to match backend API contracts
- Ensure proper error handling for all CRUD operations on user permissions

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <asithade@gmail.com>
Copilot AI review requested due to automatic review settings August 5, 2025 23:47
@asithade asithade requested a review from jordane as a code owner August 5, 2025 23:47
@coderabbitai
Copy link

coderabbitai bot commented Aug 5, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This update introduces a comprehensive refactor and expansion of the user permissions system in the project. It replaces the previous role-based model with explicit project and committee-level permissions, adds new Angular components for permission management, updates backend services and API routes to support granular permission operations, and enhances UI components for improved user experience and configurability.

Changes

Cohort / File(s) Change Summary
Permissions Model Refactor
packages/shared/src/interfaces/permissions.interface.ts
Replaces role-based interfaces with explicit project/committee permission types, updates mailing list model, introduces request/summary interfaces, and adds a permission matrix item interface.
Backend Service & API Expansion
apps/lfx-pcc/src/server/services/supabase.service.ts, apps/lfx-pcc/src/server/routes/permissions.ts
Refactors permission fetching to explicit project/committee queries, adds create/update/delete user permission methods and corresponding API endpoints with validation and error handling.
Angular Permissions Service Update
apps/lfx-pcc/src/app/shared/services/permissions.service.ts
Updates service methods to use new permission summary/request interfaces and adjusts HTTP method signatures for new backend contract.
User Service Enhancement
apps/lfx-pcc/src/app/shared/services/user.service.ts
Adds HTTP client injection and a method to create users with permissions via the new API endpoint.
Permissions Table Refactor
apps/lfx-pcc/src/app/modules/project/settings/components/user-permissions-table/user-permissions-table.component.ts, apps/lfx-pcc/src/app/modules/project/settings/components/user-permissions-table/user-permissions-table.component.html
Refactors data flow to use input-driven user summaries, introduces user action menus, confirmation dialogs, and updates UI to match new permission model.
Settings Dashboard Integration
apps/lfx-pcc/src/app/modules/project/settings/settings-dashboard/settings-dashboard.component.ts, apps/lfx-pcc/src/app/modules/project/settings/settings-dashboard/settings-dashboard.component.html
Integrates new permission matrix and user form components, uses signals for reactive user data, and updates menu actions for user addition.
Permissions Matrix Feature
apps/lfx-pcc/src/app/modules/project/settings/components/permissions-matrix/permissions-matrix.component.ts, apps/lfx-pcc/src/app/modules/project/settings/components/permissions-matrix/permissions-matrix.component.html
Adds new standalone component and template to display a permission matrix guide for users.
User Form Feature
apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.ts, apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.html
Adds a standalone user form component for creating or editing users and permissions, with reactive validation and committee selection.
Multi-Select Component Enhancement
apps/lfx-pcc/src/app/shared/components/multi-select/multi-select.component.ts, apps/lfx-pcc/src/app/shared/components/multi-select/multi-select.component.html
Adds configurable size and style class inputs, updates template for dynamic class/size, and maintains full-width styling.
Button Component Enhancement
apps/lfx-pcc/src/app/shared/components/button/button.component.html
Adds new input bindings for accessibility and styling on the button component.
Committee Names Pipe Update
apps/lfx-pcc/src/app/shared/pipes/committee-names.pipe.ts
Updates pipe to handle new committee permission object structure and improves null/empty guard logic.
UI Styling Adjustments
apps/lfx-pcc/src/app/app.component.scss, apps/lfx-pcc/src/styles.scss
Expands CSS selectors for consistent text sizing in select/multiselect overlays and adds custom font size variables for multiselects.
Committee Components Refactor
apps/lfx-pcc/src/app/modules/project/committees/committee-dashboard/committee-dashboard.component.ts, apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.ts, apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.html, apps/lfx-pcc/src/app/modules/project/committees/components/committee-members/committee-members.component.ts, apps/lfx-pcc/src/app/modules/project/committees/components/committee-members/committee-members.component.html
Converts committee data loading to reactive streams with refresh subjects, moves members and loading state to inputs, updates component templates and logic to support external data inputs, and removes redundant UI fallback for empty members.
Committee Form Event Handler Rename
apps/lfx-pcc/src/app/modules/project/committees/components/committee-form/committee-form.component.ts, apps/lfx-pcc/src/app/modules/project/committees/components/committee-form/committee-form.component.html
Renames event handler methods to use consistent "on" prefix and updates template bindings accordingly.
Meeting Components Refresh Refactor
apps/lfx-pcc/src/app/modules/project/meetings/meeting-dashboard/meeting-dashboard.component.ts, apps/lfx-pcc/src/app/modules/project/meetings/components/meeting-form/meeting-form.component.html, apps/lfx-pcc/src/app/modules/project/meetings/components/participant-form/participant-form.component.html
Introduces reactive refresh subjects for meeting data, removes redundant click handlers on submit buttons relying on form submit events.
General Form Submit Button Cleanup
apps/lfx-pcc/src/app/modules/project/committees/components/member-form/member-form.component.html
Removes explicit click event binding on submit button, relying on form submit event instead.

Sequence Diagram(s)

User Permission Management Flow

sequenceDiagram
    participant User
    participant SettingsDashboardComponent
    participant UserPermissionsTableComponent
    participant UserFormComponent
    participant PermissionsService
    participant UserService
    participant BackendAPI
    participant SupabaseService

    User->>SettingsDashboardComponent: Click "Add User"
    SettingsDashboardComponent->>UserFormComponent: Open dialog
    UserFormComponent->>UserService: createUserWithPermissions(request)
    UserService->>BackendAPI: POST /api/projects/:projectId/permissions
    BackendAPI->>SupabaseService: createUserWithPermissions(request)
    SupabaseService-->>BackendAPI: User created and permissions assigned
    BackendAPI-->>UserService: Success response
    UserService-->>UserFormComponent: User created
    UserFormComponent-->>SettingsDashboardComponent: Close dialog, trigger refresh
    SettingsDashboardComponent->>PermissionsService: getProjectPermissions(projectId)
    PermissionsService->>BackendAPI: GET /api/projects/:projectId/permissions
    BackendAPI->>SupabaseService: getProjectPermissions(projectId)
    SupabaseService-->>BackendAPI: UserPermissionSummary[]
    BackendAPI-->>PermissionsService: UserPermissionSummary[]
    PermissionsService-->>SettingsDashboardComponent: UserPermissionSummary[]
    SettingsDashboardComponent-->>UserPermissionsTableComponent: Update users input
Loading

User Permission Removal Flow

sequenceDiagram
    participant User
    participant UserPermissionsTableComponent
    participant PermissionsService
    participant BackendAPI
    participant SupabaseService

    User->>UserPermissionsTableComponent: Select "Remove" for user
    UserPermissionsTableComponent->>User: Show confirmation dialog
    User->>UserPermissionsTableComponent: Confirm removal
    UserPermissionsTableComponent->>PermissionsService: removeUserFromProject(projectId, userId)
    PermissionsService->>BackendAPI: DELETE /api/projects/:projectId/permissions/:userId
    BackendAPI->>SupabaseService: removeUserFromProject(userId, projectId)
    SupabaseService-->>BackendAPI: Success (204 No Content)
    BackendAPI-->>PermissionsService: Success
    PermissionsService-->>UserPermissionsTableComponent: Success
    UserPermissionsTableComponent-->>SettingsDashboardComponent: Emit refresh
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3cdb5b6 and de254ca.

📒 Files selected for processing (1)
  • apps/lfx-pcc/src/server/server.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • apps/lfx-pcc/src/server/server.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Code Quality Checks
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/self-permissioning

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

This comment was marked as outdated.

Signed-off-by: Asitha de Silva <asithade@gmail.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🔭 Outside diff range comments (1)
apps/lfx-pcc/src/app/modules/project/settings/components/user-permissions-table/user-permissions-table.component.html (1)

114-136: Eliminate duplicate empty state rendering

The empty state message is duplicated in both the emptymessage template and the else block. Consider extracting this into a reusable component or template reference.

Create a template reference to avoid duplication:

+<ng-template #emptyStateTemplate>
+  <div class="text-center py-8 text-gray-500">
+    <i class="fa-light fa-users text-4xl text-gray-400 mb-4"></i>
+    <h3 class="text-lg font-medium text-gray-900 mb-2">No User Permissions</h3>
+    <p class="text-gray-600">No users have been assigned permissions to this project yet.</p>
+  </div>
+</ng-template>

 <ng-template #emptymessage>
   <tr>
     <td colspan="6" class="text-center py-8">
-      <div class="text-center py-8 text-gray-500">
-        <i class="fa-light fa-users text-4xl text-gray-400 mb-4"></i>
-        <h3 class="text-lg font-medium text-gray-900 mb-2">No User Permissions</h3>
-        <p class="text-gray-600">No users have been assigned permissions to this project yet.</p>
-      </div>
+      <ng-container *ngTemplateOutlet="emptyStateTemplate"></ng-container>
     </td>
   </tr>
 </ng-template>

 } @else {
   <div class="flex justify-center items-center h-full">
-    <div class="text-center py-8">
-      <i class="fa-light fa-users text-4xl text-gray-400 mb-4"></i>
-      <h3 class="text-lg font-medium text-gray-900 mb-2">No User Permissions</h3>
-      <p class="text-gray-600">No users have been assigned permissions to this project yet.</p>
-    </div>
+    <ng-container *ngTemplateOutlet="emptyStateTemplate"></ng-container>
   </div>
 }
🧹 Nitpick comments (8)
apps/lfx-pcc/src/app/app.component.scss (1)

33-38: Selector duplication – consider flattening to keep CSS concise
p-select-overlay and p-multiselect-overlay share identical nested rules. You could merge them to reduce specificity and maintenance overhead without changing behaviour.

-.p-select-overlay,
-.p-multiselect-overlay {
-  .p-select-list-container,
-  .p-multiselect-list-container {
-    .p-select-option,
-    .p-multiselect-option {
-      @apply text-sm;
-    }
-  }
-}
+.p-select-overlay .p-select-list-container .p-select-option,
+.p-multiselect-overlay .p-multiselect-list-container .p-multiselect-option {
+  @apply text-sm;
+}
apps/lfx-pcc/src/app/modules/project/settings/settings-dashboard/settings-dashboard.component.html (1)

5-16: Repeated function invocations in high-frequency template
users(), loading() and refreshUsers() are signal/function calls executed on each CD pass. Cache their values into readonly signals or variables and bind to those, or convert to async pipes, to avoid performance degradation when the dashboard displays large tables.

apps/lfx-pcc/src/app/modules/project/settings/components/permissions-matrix/permissions-matrix.component.html (1)

14-33: LGTM! Well-structured permission matrix display with minor styling suggestion.

The template effectively displays the permission matrix using modern Angular control flow. The structure is semantic and user-friendly.

Consider these minor improvements for better maintainability:

- <span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium" [class]="item.badge.bgColor + ' ' + item.badge.color">
+ <span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium" [ngClass]="[item.badge.bgColor, item.badge.color]">

- <i class="fa-light fa-check text-green-500 mr-1 mt-0.5" style="font-size: 10px"></i>
+ <i class="fa-light fa-check text-green-500 mr-1 mt-0.5 text-[10px]"></i>

This uses [ngClass] for cleaner class binding and Tailwind utilities instead of inline styles.

apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.ts (1)

67-133: Consider using a logging service instead of console.error

The form submission logic is well-implemented, but consider replacing console.error with a proper logging service for production environments.

Replace console.error with a logging service:

      error: (error) => {
-       console.error('Error saving user:', error);
+       // Consider injecting and using a logging service
+       // this.loggingService.error('Error saving user:', error);
        this.messageService.add({
          severity: 'error',
          summary: 'Error',
          detail: `Failed to ${this.isEditing() ? 'update' : 'create'} user. Please try again.`,
        });
        this.submitting.set(false);
      },
apps/lfx-pcc/src/server/routes/permissions.ts (4)

33-34: Use consistent property access notation

For consistency with line 18, use dot notation instead of bracket notation when accessing req.params.projectId.

-    req.log.error({ error, projectId: req.params['projectId'] }, 'Error fetching project permissions');
+    req.log.error({ error, projectId: req.params.projectId }, 'Error fetching project permissions');

78-79: Use consistent property access notation

-    req.log.error({ error, projectId: req.params['projectId'] }, 'Error creating user with permissions');
+    req.log.error({ error, projectId: req.params.projectId }, 'Error creating user with permissions');

127-128: Use consistent property access notation

-    req.log.error({ error, projectId: req.params['projectId'], userId: req.params['userId'] }, 'Error updating user permissions');
+    req.log.error({ error, projectId: req.params.projectId, userId: req.params.userId }, 'Error updating user permissions');

153-154: Use consistent property access notation

-    req.log.error({ error, projectId: req.params['projectId'], userId: req.params['userId'] }, 'Error removing user permissions');
+    req.log.error({ error, projectId: req.params.projectId, userId: req.params.userId }, 'Error removing user permissions');
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 71d3d78 and 36b0b58.

📒 Files selected for processing (19)
  • apps/lfx-pcc/src/app/app.component.scss (1 hunks)
  • apps/lfx-pcc/src/app/modules/project/settings/components/permissions-matrix/permissions-matrix.component.html (1 hunks)
  • apps/lfx-pcc/src/app/modules/project/settings/components/permissions-matrix/permissions-matrix.component.ts (1 hunks)
  • apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.html (1 hunks)
  • apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.ts (1 hunks)
  • apps/lfx-pcc/src/app/modules/project/settings/components/user-permissions-table/user-permissions-table.component.html (4 hunks)
  • apps/lfx-pcc/src/app/modules/project/settings/components/user-permissions-table/user-permissions-table.component.ts (1 hunks)
  • apps/lfx-pcc/src/app/modules/project/settings/settings-dashboard/settings-dashboard.component.html (1 hunks)
  • apps/lfx-pcc/src/app/modules/project/settings/settings-dashboard/settings-dashboard.component.ts (1 hunks)
  • apps/lfx-pcc/src/app/shared/components/button/button.component.html (1 hunks)
  • apps/lfx-pcc/src/app/shared/components/multi-select/multi-select.component.html (1 hunks)
  • apps/lfx-pcc/src/app/shared/components/multi-select/multi-select.component.ts (1 hunks)
  • apps/lfx-pcc/src/app/shared/pipes/committee-names.pipe.ts (1 hunks)
  • apps/lfx-pcc/src/app/shared/services/permissions.service.ts (2 hunks)
  • apps/lfx-pcc/src/app/shared/services/user.service.ts (1 hunks)
  • apps/lfx-pcc/src/server/routes/permissions.ts (2 hunks)
  • apps/lfx-pcc/src/server/services/supabase.service.ts (4 hunks)
  • apps/lfx-pcc/src/styles.scss (1 hunks)
  • packages/shared/src/interfaces/permissions.interface.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (7)
apps/lfx-pcc/src/app/shared/pipes/committee-names.pipe.ts (1)
packages/shared/src/interfaces/committee.interface.ts (1)
  • Committee (4-27)
apps/lfx-pcc/src/app/shared/services/user.service.ts (3)
apps/lfx-pcc/src/app/shared/services/permissions.service.ts (1)
  • Injectable (9-34)
packages/shared/src/interfaces/auth.ts (1)
  • User (4-21)
packages/shared/src/interfaces/permissions.interface.ts (1)
  • CreateUserPermissionRequest (50-59)
apps/lfx-pcc/src/app/modules/project/settings/components/permissions-matrix/permissions-matrix.component.ts (3)
apps/lfx-pcc/src/app/modules/project/settings/settings-dashboard/settings-dashboard.component.ts (1)
  • Component (20-77)
apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.ts (1)
  • Component (20-204)
packages/shared/src/interfaces/permissions.interface.ts (1)
  • PermissionMatrixItem (69-78)
apps/lfx-pcc/src/app/modules/project/settings/settings-dashboard/settings-dashboard.component.ts (3)
apps/lfx-pcc/src/app/modules/project/settings/components/user-permissions-table/user-permissions-table.component.ts (1)
  • Component (22-166)
apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.ts (1)
  • Component (20-204)
packages/shared/src/interfaces/permissions.interface.ts (1)
  • UserPermissionSummary (37-48)
apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.ts (4)
apps/lfx-pcc/src/app/modules/project/settings/settings-dashboard/settings-dashboard.component.ts (1)
  • Component (20-77)
apps/lfx-pcc/src/app/modules/project/settings/components/user-permissions-table/user-permissions-table.component.ts (1)
  • Component (22-166)
apps/lfx-pcc/src/app/shared/components/multi-select/multi-select.component.ts (1)
  • Component (9-29)
packages/shared/src/interfaces/permissions.interface.ts (3)
  • PermissionScope (8-8)
  • PermissionLevel (7-7)
  • CreateUserPermissionRequest (50-59)
apps/lfx-pcc/src/server/routes/permissions.ts (1)
packages/shared/src/interfaces/permissions.interface.ts (2)
  • CreateUserPermissionRequest (50-59)
  • UpdateUserPermissionRequest (61-67)
apps/lfx-pcc/src/app/shared/services/permissions.service.ts (1)
packages/shared/src/interfaces/permissions.interface.ts (2)
  • UserPermissionSummary (37-48)
  • UpdateUserPermissionRequest (61-67)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Code Quality Checks
🔇 Additional comments (23)
apps/lfx-pcc/src/styles.scss (1)

42-43: Verify variables are actually consumed
--p-multiselect-sm-font-size and --p-multiselect-md-font-size are declared but I don’t see corresponding usages in the changed SCSS. Make sure PrimeNG is configured to read these variables; otherwise they become dead code.

apps/lfx-pcc/src/app/shared/services/user.service.ts (1)

4-7: LGTM! Clean dependency injection and imports.

The HttpClient injection using Angular's inject() function and the import of CreateUserPermissionRequest interface are properly implemented and align with the new permissions system.

apps/lfx-pcc/src/app/shared/components/multi-select/multi-select.component.ts (1)

27-28: LGTM! Good enhancement for component configurability.

The addition of size and styleClass input properties enhances the component's flexibility. The union type constraint for size and sensible default values are well-implemented.

apps/lfx-pcc/src/app/shared/pipes/committee-names.pipe.ts (2)

5-5: LGTM! Appropriate import for the new data structure.

The import of the Committee interface aligns with the updated permission model where committee information is now nested within permission objects.


12-17: LGTM! Well-implemented refactor to handle new permission structure.

The changes correctly adapt the pipe to work with the new permission data structure:

  • The guard clause provides good defensive programming
  • The parameter type accurately reflects the new nested committee structure
  • The mapping logic correctly extracts committee names from cp.committee.name

This aligns well with the refactored permission interfaces mentioned in the AI summary.

apps/lfx-pcc/src/app/modules/project/settings/components/permissions-matrix/permissions-matrix.component.ts (2)

4-13: LGTM! Clean component structure and imports.

The component setup follows Angular best practices with proper standalone configuration and appropriate imports for CardComponent and PermissionMatrixItem interface.


15-66: PermissionMatrix display labels are independent of PermissionLevel enum

The permissionMatrix in PermissionsMatrixComponent uses user-facing labels (“View”/“Manage”) purely for display. Its level field is typed as a plain string, so it isn’t bound to the 'read' | 'write' values of the PermissionLevel type used elsewhere (e.g., in the user-form). No change is needed unless you intend to drive this matrix dynamically from the enum values themselves.

Likely an incorrect or invalid review comment.

apps/lfx-pcc/src/app/modules/project/settings/components/permissions-matrix/permissions-matrix.component.html (1)

3-11: LGTM! Clear informational structure.

The card header and key information section effectively orient users about the permission system differences between project and committee scopes.

apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.html (3)

1-59: Well-structured form with proper validation

The basic information section is well-implemented with:

  • Clear field labeling and required field indicators
  • Proper reactive form bindings
  • Appropriate validation feedback using Angular's new control flow syntax

61-94: Permission settings properly implemented

Good use of:

  • Dynamic radio button generation with track functions for performance
  • Clear labeling for permission scope and level options
  • Proper form control bindings

95-131: Excellent conditional rendering and user feedback

The committee selection and permission summary section effectively:

  • Shows committee selection only when relevant
  • Provides clear permission summary for user understanding
  • Uses appendTo="body" for the multi-select to avoid potential z-index issues
apps/lfx-pcc/src/app/modules/project/settings/components/user-permissions-table/user-permissions-table.component.html (2)

1-37: Clean table structure with loading state

The table setup is well-implemented with:

  • Clear loading indicator
  • Proper pagination configuration
  • Well-organized column headers

38-112: Comprehensive permission display with good UX

Excellent implementation of:

  • Visual distinction using colored badges for permission scopes
  • Clear access level indicators (Manage/View)
  • Contextual details based on permission type
  • Individual loading states for user actions
apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.ts (1)

1-45: Well-structured component with modern Angular patterns

Excellent use of:

  • Standalone component architecture
  • Signals for reactive state management
  • Computed properties for derived values
  • Proper dependency injection
apps/lfx-pcc/src/app/modules/project/settings/settings-dashboard/settings-dashboard.component.ts (1)

57-76: Clean dialog management implementation

The dialog handling is well-implemented with:

  • Proper configuration for modal behavior
  • Appropriate use of RxJS operators
  • Clear separation of concerns
apps/lfx-pcc/src/app/shared/services/permissions.service.ts (1)

15-34: Service implementation follows Angular best practices

The permissions service is well-structured with:

  • Proper use of HttpClient and Observables
  • RESTful API endpoint conventions
  • Clear method signatures with appropriate types
apps/lfx-pcc/src/server/services/supabase.service.ts (5)

809-845: LGTM!

The implementation correctly removes both project and committee permissions with appropriate error handling for 404 responses.


848-913: LGTM!

Well-implemented user creation with proper email existence check, URL encoding, and permission assignment based on scope.


915-938: LGTM!

Clean implementation of permission updates with proper removal of existing permissions before adding new ones.


982-994: LGTM!

Clean helper method for project permission creation.


996-1008: LGTM!

Clean helper method for committee permission creation.

packages/shared/src/interfaces/permissions.interface.ts (1)

7-78: LGTM!

Well-structured interfaces with clear type definitions and appropriate optional fields. The permission model is comprehensive and consistent.

apps/lfx-pcc/src/app/modules/project/settings/components/user-permissions-table/user-permissions-table.component.ts (1)

28-166: LGTM!

Well-implemented Angular component with:

  • Proper use of signals for state management
  • Memory leak prevention with take(1) operator
  • Comprehensive error handling with user-friendly messages
  • Clean separation of concerns using input/output patterns

@github-actions
Copy link

github-actions bot commented Aug 5, 2025

❌ E2E Tests Failed

Browser: chromium
Status: failed

Some E2E tests failed. Check the test report for details.

Test Configuration

Signed-off-by: Asitha de Silva <asithade@gmail.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.ts (3)

125-125: Replace console.error with proper logging service

Console.error should be replaced with proper logging using a logging service for consistency with the rest of the application.


141-151: Add dynamic validation for committee_ids

When permission scope is 'committee', the committee_ids field should be required. The current implementation lacks this dynamic validation that was previously suggested.


153-168: Add null safety for project ID

The project ID is cast to string without checking if the project exists, which could cause runtime errors. This issue was previously identified but not addressed.

🧹 Nitpick comments (2)
apps/lfx-pcc/src/app/modules/project/settings/settings-dashboard/settings-dashboard.component.ts (1)

33-33: Improve BehaviorSubject initialization

The BehaviorSubject is initialized with undefined which is unconventional. Consider using void 0 for better practice.

-  public refresh: BehaviorSubject<void> = new BehaviorSubject<void>(undefined);
+  public refresh: BehaviorSubject<void> = new BehaviorSubject<void>(void 0);
apps/lfx-pcc/src/server/services/supabase.service.ts (1)

472-494: Consider optimizing the permission aggregation logic

The current implementation correctly handles merging project and committee permissions. However, the logic could be more concise by always initializing the user entry if not present.

 projectPermissions.forEach((perm: { user_id: string; users: User; project_id: string; permission_level: PermissionLevel }) => {
   userPermissionsMap.set(perm.user_id, {
     user: perm.users,
     projectPermission: { level: perm.permission_level, scope: 'project' },
     committeePermissions: [],
   });
 });

 committeePermissions.forEach((perm: { user_id: string; users: User; committee_id: string; permission_level: PermissionLevel; committees: Committee }) => {
-  const user = userPermissionsMap.get(perm.user_id);
-  if (user) {
-    userPermissionsMap.set(perm.user_id, {
-      user: perm.users,
-      projectPermission: user.projectPermission,
-      committeePermissions: [...user.committeePermissions, { committee: perm.committees, level: perm.permission_level, scope: 'committee' }],
-    });
-  } else {
-    userPermissionsMap.set(perm.user_id, {
-      user: perm.users,
-      committeePermissions: [{ committee: perm.committees, level: perm.permission_level, scope: 'committee' }],
-    });
-  }
+  const existingUser = userPermissionsMap.get(perm.user_id);
+  const committeePermission = { committee: perm.committees, level: perm.permission_level, scope: 'committee' as const };
+  
+  userPermissionsMap.set(perm.user_id, {
+    user: perm.users,
+    projectPermission: existingUser?.projectPermission,
+    committeePermissions: existingUser ? [...existingUser.committeePermissions, committeePermission] : [committeePermission],
+  });
 });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 36b0b58 and 141c08c.

📒 Files selected for processing (7)
  • apps/lfx-pcc/src/app/modules/project/settings/components/permissions-matrix/permissions-matrix.component.ts (1 hunks)
  • apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.html (1 hunks)
  • apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.ts (1 hunks)
  • apps/lfx-pcc/src/app/modules/project/settings/settings-dashboard/settings-dashboard.component.ts (1 hunks)
  • apps/lfx-pcc/src/app/shared/services/permissions.service.ts (2 hunks)
  • apps/lfx-pcc/src/app/shared/services/user.service.ts (1 hunks)
  • apps/lfx-pcc/src/server/services/supabase.service.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.html
  • apps/lfx-pcc/src/app/shared/services/user.service.ts
  • apps/lfx-pcc/src/app/modules/project/settings/components/permissions-matrix/permissions-matrix.component.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/lfx-pcc/src/app/shared/services/permissions.service.ts (1)
packages/shared/src/interfaces/permissions.interface.ts (2)
  • UserPermissionSummary (37-48)
  • UpdateUserPermissionRequest (61-67)
apps/lfx-pcc/src/server/services/supabase.service.ts (3)
packages/shared/src/interfaces/permissions.interface.ts (6)
  • UserPermissionSummary (37-48)
  • PermissionLevel (7-7)
  • CreateUserPermissionRequest (50-59)
  • UpdateUserPermissionRequest (61-67)
  • ProjectPermission (10-17)
  • CommitteePermission (19-27)
packages/shared/src/interfaces/auth.ts (1)
  • User (4-21)
packages/shared/src/interfaces/committee.interface.ts (1)
  • Committee (4-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Code Quality Checks
🔇 Additional comments (3)
apps/lfx-pcc/src/app/modules/project/settings/components/user-form/user-form.component.ts (1)

185-185: Good: Proper typing used for committee permissions

The code correctly uses typed access to committeePermissions without type assertions, addressing the previous concern about type safety.

apps/lfx-pcc/src/app/shared/services/permissions.service.ts (1)

1-29: Good: Service properly refactored

The service has been properly refactored with the removal of the unused addUserPermissions method that was previously flagged. The remaining methods use appropriate types and follow a clean API design.

apps/lfx-pcc/src/server/services/supabase.service.ts (1)

799-835: Good: Proper error handling for permission removal

The implementation correctly handles 404 responses when removing permissions, which is appropriate since the permissions might not exist. This defensive approach prevents unnecessary errors.

@asithade asithade requested a review from Copilot August 6, 2025 17:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements a complete user permissions management system with CRUD operations, replacing the previous role-based system with a simplified permission structure based on scope (project vs committee) and access level (read vs write).

  • Replaces complex role-based permissions with a simplified scope/level system
  • Adds comprehensive user management functionality including create, edit, and delete operations
  • Implements a permission matrix component to document different permission levels

Reviewed Changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/shared/src/interfaces/permissions.interface.ts Refactors permission interfaces from role-based to scope/level system
apps/lfx-pcc/src/server/services/supabase.service.ts Updates backend service to support new permission system with CRUD operations
apps/lfx-pcc/src/server/routes/permissions.ts Adds REST API endpoints for user permission management
apps/lfx-pcc/src/app/shared/services/*.ts Updates frontend services to work with new permission system
apps/lfx-pcc/src/app/modules/project/settings/components/* Implements user form, permissions table, and matrix documentation components
apps/lfx-pcc/src/app/modules/project/settings/settings-dashboard/* Updates dashboard to integrate new user management functionality
Various styling and component files Adds styling support and enhances existing components for the new UI

Signed-off-by: Asitha de Silva <asithade@gmail.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 141c08c and 3cdb5b6.

📒 Files selected for processing (11)
  • apps/lfx-pcc/src/app/modules/project/committees/committee-dashboard/committee-dashboard.component.ts (5 hunks)
  • apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.html (1 hunks)
  • apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.ts (4 hunks)
  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-form/committee-form.component.html (2 hunks)
  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-form/committee-form.component.ts (5 hunks)
  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-members/committee-members.component.html (0 hunks)
  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-members/committee-members.component.ts (4 hunks)
  • apps/lfx-pcc/src/app/modules/project/committees/components/member-form/member-form.component.html (1 hunks)
  • apps/lfx-pcc/src/app/modules/project/meetings/components/meeting-form/meeting-form.component.html (1 hunks)
  • apps/lfx-pcc/src/app/modules/project/meetings/components/participant-form/participant-form.component.html (0 hunks)
  • apps/lfx-pcc/src/app/modules/project/meetings/meeting-dashboard/meeting-dashboard.component.ts (6 hunks)
💤 Files with no reviewable changes (2)
  • apps/lfx-pcc/src/app/modules/project/meetings/components/participant-form/participant-form.component.html
  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-members/committee-members.component.html
✅ Files skipped from review due to trivial changes (1)
  • apps/lfx-pcc/src/app/modules/project/committees/components/member-form/member-form.component.html
🧰 Additional context used
📓 Path-based instructions (4)
apps/**/src/**/*.html

📄 CodeRabbit Inference Engine (CLAUDE.md)

apps/**/src/**/*.html: Always add data-testid attributes when creating new components for reliable test targeting
Use data-testid naming convention - '[section]-[component]-[element]' for hierarchical structure

Files:

  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-form/committee-form.component.html
  • apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.html
  • apps/lfx-pcc/src/app/modules/project/meetings/components/meeting-form/meeting-form.component.html
{apps,packages}/**/*.{ts,tsx,js,jsx,css,scss}

📄 CodeRabbit Inference Engine (CLAUDE.md)

License headers are required on all source files

Files:

  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-members/committee-members.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-form/committee-form.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/committee-dashboard/committee-dashboard.component.ts
  • apps/lfx-pcc/src/app/modules/project/meetings/meeting-dashboard/meeting-dashboard.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.ts
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

Use TypeScript interfaces instead of union types for better maintainability

Files:

  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-members/committee-members.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-form/committee-form.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/committee-dashboard/committee-dashboard.component.ts
  • apps/lfx-pcc/src/app/modules/project/meetings/meeting-dashboard/meeting-dashboard.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-members/committee-members.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-form/committee-form.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/committee-dashboard/committee-dashboard.component.ts
  • apps/lfx-pcc/src/app/modules/project/meetings/meeting-dashboard/meeting-dashboard.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.ts
🧠 Learnings (4)
📚 Learning: 2025-08-06T00:40:54.228Z
Learnt from: asithade
PR: linuxfoundation/lfx-v2-pcc-ui#24
File: apps/lfx-pcc/src/app/shared/components/multi-select/multi-select.component.html:16-18
Timestamp: 2025-08-06T00:40:54.228Z
Learning: In Angular applications, when reviewing template code that uses parentheses syntax like `size()` or `styleClass()`, these may be Angular signals rather than regular methods. Angular signals are memoized and only re-compute when their dependencies change, unlike regular methods which execute on every change detection cycle. Therefore, the performance concerns about avoiding method calls in templates don't apply to signals.

Applied to files:

  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-members/committee-members.component.ts
  • apps/lfx-pcc/src/app/modules/project/meetings/meeting-dashboard/meeting-dashboard.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.ts
📚 Learning: 2025-08-07T16:35:57.349Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.349Z
Learning: All PrimeNG components are wrapped in LFX components for UI library independence

Applied to files:

  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-members/committee-members.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/committee-dashboard/committee-dashboard.component.ts
  • apps/lfx-pcc/src/app/modules/project/meetings/meeting-dashboard/meeting-dashboard.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.ts
📚 Learning: 2025-08-07T16:35:57.349Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.349Z
Learning: Always reference PrimeNG's component interface when trying to define types

Applied to files:

  • apps/lfx-pcc/src/app/modules/project/committees/components/committee-members/committee-members.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/committee-dashboard/committee-dashboard.component.ts
  • apps/lfx-pcc/src/app/modules/project/meetings/meeting-dashboard/meeting-dashboard.component.ts
  • apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.ts
📚 Learning: 2025-08-07T16:35:57.348Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-pcc-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-07T16:35:57.348Z
Learning: Applies to packages/shared/src/{interfaces,constants,enums}/**/*.{ts,tsx} : All shared types, interfaces, and constants are centralized in lfx-pcc/shared package

Applied to files:

  • apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.ts
🧬 Code Graph Analysis (2)
apps/lfx-pcc/src/app/modules/project/committees/components/committee-members/committee-members.component.ts (1)
packages/shared/src/interfaces/member.interface.ts (1)
  • CommitteeMember (4-22)
apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.ts (2)
packages/shared/src/interfaces/committee.interface.ts (1)
  • Committee (4-27)
packages/shared/src/interfaces/member.interface.ts (1)
  • CommitteeMember (4-22)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Code Quality Checks
🔇 Additional comments (25)
apps/lfx-pcc/src/app/modules/project/meetings/components/meeting-form/meeting-form.component.html (1)

313-313: LGTM! Improved form submission handling.

Removing the explicit (onClick) handler on the submit button is a good practice. The form submission is now handled consistently through the (ngSubmit) event on the form element, which ensures proper form validation and follows standard HTML form semantics.

apps/lfx-pcc/src/app/modules/project/committees/components/committee-form/committee-form.component.html (3)

4-4: LGTM! Consistent event handler naming.

Updating the form submission handler from handleSubmit() to onSubmit() improves consistency with the standardized "on" prefix naming convention used across other form components in the project.


118-118: LGTM! Consistent event handler naming.

Updating the cancel button handler from handleCancel() to onCancel() aligns with the standardized naming convention.


124-124: LGTM! Improved form submission handling.

The submit button now relies on the form's (ngSubmit) event rather than a redundant click handler, which is a best practice for form handling and ensures proper validation flow.

apps/lfx-pcc/src/app/modules/project/committees/components/committee-form/committee-form.component.ts (5)

54-54: LGTM! Consistent event handler naming.

Renaming handleSubmit() to onSubmit() follows the standardized "on" prefix convention used across other form components in the project, improving code consistency.


69-69: LGTM! Internal method calls updated correctly.

All internal calls to the renamed success and error handlers have been properly updated to use the new method names, maintaining functionality while following the new naming convention.

Also applies to: 73-73, 81-81, 85-85


95-95: LGTM! Consistent event handler naming.

Renaming handleCancel() to onCancel() aligns with the standardized naming convention and matches the template binding update.


130-130: LGTM! Consistent method naming.

Renaming handleSuccess() to onSuccess() follows the established naming pattern for event handlers and callbacks.


152-152: LGTM! Consistent method naming.

Renaming handleError() to onError() completes the standardization of method naming throughout the component.

apps/lfx-pcc/src/app/modules/project/committees/committee-dashboard/committee-dashboard.component.ts (6)

1-2: License header compliance verified.

The required license header is properly included as specified in the coding guidelines.


22-23: Imports properly updated for reactive pattern.

The addition of BehaviorSubject and switchMap imports supports the new reactive refresh mechanism correctly.


72-74: Property declarations follow good practices.

The refresh property is correctly typed as BehaviorSubject<void> and the reordering of searchTerm and dialogRef maintains consistency. The public access modifier on refresh is appropriate for the component's needs.


84-84: BehaviorSubject initialization is correct.

The refresh subject is properly initialized with undefined as the initial value, which is appropriate for triggering refresh actions.


194-194: Simplified refresh mechanism improves maintainability.

The refactored refreshCommittees() method now correctly uses the reactive pattern by emitting on the refresh subject instead of complex router navigation. This is cleaner and more efficient.


228-238: Reactive data loading pattern implemented correctly.

The initializeCommittees() method properly implements the reactive pattern:

  • Uses refresh.pipe() to trigger data fetching
  • tap() sets loading state correctly
  • switchMap() ensures previous requests are cancelled
  • Handles the case when no project is available by returning empty array
  • Loading state management is consistent

This pattern aligns well with the broader architectural improvements mentioned in the AI summary.

apps/lfx-pcc/src/app/modules/project/meetings/meeting-dashboard/meeting-dashboard.component.ts (8)

1-2: License header compliance verified.

The required license header is properly included as specified in the coding guidelines.


5-5: Import cleanup noted.

The Injector import is retained even though the AI summary mentions runInInjectionContext was removed. This suggests Injector might still be needed elsewhere in the component.


22-23: Reactive pattern imports added correctly.

The addition of BehaviorSubject and switchMap imports supports the new reactive refresh mechanism. These align with the same pattern used in the CommitteeDashboardComponent.


75-75: Refresh subject property properly declared.

The refresh property is correctly typed as BehaviorSubject<void> and marked as public, consistent with the pattern established in other dashboard components.


83-83: BehaviorSubject initialization is consistent.

The refresh subject is properly initialized with undefined, matching the pattern used in the CommitteeDashboardComponent.


161-161: Simplified refresh mechanism implemented correctly.

The refreshMeetings() method now uses the reactive pattern by emitting on the refresh subject. This is much cleaner than the previous runInInjectionContext approach mentioned in the AI summary.


197-208: Reactive meetings data loading implemented correctly.

The initializeMeetings() method properly implements the reactive pattern:

  • Uses refresh.pipe(switchMap(...)) to trigger data fetching
  • tap() correctly sets meetingsLoading to false after fetch
  • Handles null project case by returning empty array
  • Maintains proper signal initialization with empty array default

The pattern is consistent with the CommitteeDashboardComponent implementation.


210-221: Reactive past meetings data loading implemented correctly.

The initializePastMeetings() method follows the same correct pattern:

  • Uses refresh.pipe(switchMap(...)) for reactive data fetching
  • tap() sets pastMeetingsLoading to false appropriately
  • Consistent error handling and initialization approach
  • Matches the pattern established in the meetings initialization

Both meeting data initialization methods now use the same reactive architecture for consistency.

apps/lfx-pcc/src/app/modules/project/committees/components/committee-members/committee-members.component.ts (1)

5-106: LGTM! Good refactoring to improve separation of concerns

The component has been successfully refactored to receive members and loading state as inputs rather than managing them internally. This improves:

  • Separation of concerns by moving data fetching to the parent component
  • Reusability by making the component more flexible
  • Testability by reducing dependencies

The removal of the unused finalize operator import is also appropriate.

apps/lfx-pcc/src/app/modules/project/committees/committee-view/committee-view.component.ts (1)

63-93: LGTM! Clean reactive refresh pattern

The refresh mechanism using BehaviorSubject combined with combineLatest is a good reactive pattern that allows data to be refreshed on demand without route navigation.

@asithade asithade requested a review from dealako August 7, 2025 16:43
Signed-off-by: Asitha de Silva <asithade@gmail.com>
@asithade asithade merged commit 675a00b into main Aug 7, 2025
5 checks passed
@asithade asithade deleted the feat/self-permissioning branch August 7, 2025 16: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.

3 participants