frontend_nyla/.cursor/plans/implement_rbac_roles_page_8dd9fac6.plan.md

7.3 KiB

Implement RBAC Roles Page

Overview

Implement the RBAC roles admin page following the exact pattern used in mandates.ts. This includes creating the API file, custom hook for state management, updating the page configuration with CreateButton header button, and adding translations in all three languages (German, English, French).

Files to Create/Modify

1. Create API File: frontend_nyla/src/api/roleApi.ts

  • Follow the pattern from mandateApi.ts
  • Implement all required endpoints:
    • fetchRoles() - GET /api/rbac/roles (with pagination support)
    • fetchRoleById() - GET /api/rbac/roles/{roleId}
    • fetchRoleOptions() - GET /api/rbac/roles/options
    • createRole() - POST /api/rbac/roles
    • updateRole() - PUT /api/rbac/roles/{roleId}
    • deleteRole() - DELETE /api/rbac/roles/{roleId}
  • Include TypeScript types: Role, RoleUpdateData, PaginationParams, PaginatedResponse

2. Create Hook: frontend_nyla/src/hooks/useAdminRbacRoles.ts

  • Follow the exact pattern from useAdminMandates.ts
  • Create two hooks:
    • useRbacRoles() - Main hook for data fetching and state management
      • Fetch roles with pagination support
      • Fetch attributes from /api/attributes/Role using fetchAttributes(request, 'Role')
      • Fetch permissions using checkPermission('DATA', 'Role')
      • Implement generateEditFieldsFromAttributes() using attributeTypeMapper utilities
      • Implement generateCreateFieldsFromAttributes() using attributeTypeMapper utilities
      • Implement ensureAttributesLoaded() for EditActionButton
      • Implement optimistic updates (removeOptimistically, updateOptimistically)
      • Return pagination info, attributes, permissions, and all required functions
    • useRbacRoleOperations() - Operations hook for CRUD
      • handleRoleDelete() - Delete with loading state tracking
      • handleRoleCreate() - Create with error handling
      • handleRoleUpdate() - Update with error handling
      • Track loading states in Sets (deletingRoles, editingRoles, creatingRole)
      • Return error states (deleteError, createError, updateError)

3. Update Page Configuration: frontend_nyla/src/core/PageManager/data/pages/admin/rbac-role.ts

  • Follow the exact structure from mandates.ts
  • Import FaPlus from react-icons/fa for the create button icon
  • Create createRbacRolesHook() factory function that:
    • Uses useRbacRoles() and useRbacRoleOperations()
    • Converts attributes to columns using attributesToColumns() helper
    • Implements handleDeleteSingle and handleDeleteMultiple callbacks
    • Returns all required data for FormGeneratorTable
  • Update rbacRolePageData:
    • Add header button with FaPlus icon for creating roles (following mandates.ts pattern):
      headerButtons: [
          {
              id: 'add-role',
              label: 'admin.rbac-role.new_button',
              variant: 'primary',
              size: 'md',
              icon: FaPlus,
              formConfig: {
                  fields: [], // Empty array - fields will be generated dynamically from attributes
                  popupTitle: 'admin.rbac-role.modal.create.title',
                  popupSize: 'medium',
                  createOperationName: 'handleRoleCreate',
                  successMessage: 'admin.rbac-role.create.success',
                  errorMessage: 'admin.rbac-role.create.error'
              }
          }
      ]
      
    • Add table content section with:
      • hookFactory: createRbacRolesHook
      • Action buttons: edit and delete (following mandates pattern)
      • Configure edit button with fetchItemFunctionName: 'fetchRoleById'
      • Configure delete button with proper operation names
      • Add permission-based disabled logic
    • Keep existing privilege checker (sysadmin only)

4. Update Translations: All three locale files

  • German (frontend_nyla/src/locales/de.ts): Add missing translations after line 756:

    • 'admin.rbac-role.new_button': 'Rolle hinzufügen'
    • 'admin.rbac-role.action.edit': 'Bearbeiten'
    • 'admin.rbac-role.action.delete': 'Löschen'
    • 'admin.rbac-role.modal.create.title': 'Neue Rolle erstellen'
    • 'admin.rbac-role.create.success': 'Rolle erfolgreich erstellt'
    • 'admin.rbac-role.create.error': 'Fehler beim Erstellen der Rolle'
  • English (frontend_nyla/src/locales/en.ts): Add missing translations after line 756:

    • 'admin.rbac-role.new_button': 'Add Role'
    • 'admin.rbac-role.action.edit': 'Edit'
    • 'admin.rbac-role.action.delete': 'Delete'
    • 'admin.rbac-role.modal.create.title': 'Create New Role'
    • 'admin.rbac-role.create.success': 'Role created successfully'
    • 'admin.rbac-role.create.error': 'Error creating role'
  • French (frontend_nyla/src/locales/fr.ts): Add missing translations after line 756:

    • 'admin.rbac-role.new_button': 'Ajouter un rôle'
    • 'admin.rbac-role.action.edit': 'Modifier'
    • 'admin.rbac-role.action.delete': 'Supprimer'
    • 'admin.rbac-role.modal.create.title': 'Créer un nouveau rôle'
    • 'admin.rbac-role.create.success': 'Rôle créé avec succès'
    • 'admin.rbac-role.create.error': 'Erreur lors de la création du rôle'

Implementation Details

API File Structure

  • Use ApiRequestFunction type from useApi
  • Support pagination parameters (page, pageSize, sort, filters, search)
  • Handle both paginated and non-paginated responses
  • Use /api/rbac/roles as base URL
  • Use /api/attributes/Role for attributes endpoint

Hook Pattern

  • Use useApiRequest hook for API calls
  • Use usePermissions hook for permission checking
  • Use getUserDataCache() to check authentication before fetching
  • Implement attribute type mapping using utilities from attributeTypeMapper.ts:
    • isCheckboxType(), isSelectType(), isMultiselectType(), isDateTimeType(), isTextareaType()
  • Filter out non-editable fields (id, readonly fields, etc.)
  • Handle options arrays and option references

Page Configuration Pattern

  • Use attributesToColumns() helper to convert attributes to column config
  • Disable filtering for date/timestamp fields using isDateTimeType()
  • Configure action buttons with proper field mappings and operation names
  • Use permission-based disabled logic for buttons
  • Set entityType: 'Role' for EditActionButton
  • Add header button using CreateButton component pattern (via formConfig in headerButtons)

Key Dependencies

  • useApiRequest from hooks/useApi
  • usePermissions from hooks/usePermissions
  • fetchAttributes from api/attributesApi
  • attributeTypeMapper utilities from utils/attributeTypeMapper
  • FormGeneratorTable component
  • EditActionButton and DeleteActionButton components
  • CreateButton component (rendered via PageRenderer from headerButtons formConfig)
  • FaPlus icon from react-icons/fa

Testing Considerations

  • Verify all API endpoints are called correctly
  • Ensure attributes are fetched from /api/attributes/Role
  • Verify permission checks work correctly
  • Test create, edit, delete operations
  • Verify optimistic updates work
  • Check that date/timestamp fields are not filterable
  • Verify CreateButton appears in header and opens create modal
  • Verify translations work in all three languages