@atlashub/smartstack 3.21.0 → 3.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/dist/chunks/{AgentSkillsPage-7si3Ng8e.js → AgentSkillsPage-BWQSCYl-.js} +2 -2
  2. package/dist/chunks/{AgentSkillsPage-7si3Ng8e.js.map → AgentSkillsPage-BWQSCYl-.js.map} +1 -1
  3. package/dist/chunks/{AgentSkillsPage-D0cD1QdM.js → AgentSkillsPage-IQcMnBaD.js} +2 -2
  4. package/dist/chunks/{AgentSkillsPage-D0cD1QdM.js.map → AgentSkillsPage-IQcMnBaD.js.map} +1 -1
  5. package/dist/chunks/{AgentWorkloadPage-H_7ze33H.js → AgentWorkloadPage-DqrjkvWL.js} +2 -2
  6. package/dist/chunks/{AgentWorkloadPage-H_7ze33H.js.map → AgentWorkloadPage-DqrjkvWL.js.map} +1 -1
  7. package/dist/chunks/{AgentWorkloadPage-D4d86cdV.js → AgentWorkloadPage-w-HiyFYP.js} +2 -2
  8. package/dist/chunks/{AgentWorkloadPage-D4d86cdV.js.map → AgentWorkloadPage-w-HiyFYP.js.map} +1 -1
  9. package/dist/chunks/{ApiCatalogDetailPage-2ktkRrCb.js → ApiCatalogDetailPage-D3L8Yf4G.js} +3 -3
  10. package/dist/chunks/{ApiCatalogDetailPage-2ktkRrCb.js.map → ApiCatalogDetailPage-D3L8Yf4G.js.map} +1 -1
  11. package/dist/chunks/{ApiCatalogDetailPage-BQ53xuwD.js → ApiCatalogDetailPage-MPT3Kz6H.js} +2 -2
  12. package/dist/chunks/{ApiCatalogDetailPage-BQ53xuwD.js.map → ApiCatalogDetailPage-MPT3Kz6H.js.map} +1 -1
  13. package/dist/chunks/{ApiCatalogPage-BEqTDJz8.js → ApiCatalogPage-D4Hg3uiS.js} +2 -2
  14. package/dist/chunks/{ApiCatalogPage-BEqTDJz8.js.map → ApiCatalogPage-D4Hg3uiS.js.map} +1 -1
  15. package/dist/chunks/{ApiCatalogPage-BBkWSLI8.js → ApiCatalogPage-DRg5Cz0r.js} +2 -2
  16. package/dist/chunks/{ApiCatalogPage-BBkWSLI8.js.map → ApiCatalogPage-DRg5Cz0r.js.map} +1 -1
  17. package/dist/chunks/{ApplicationDetailPage-BYJ2YMPq.js → ApplicationDetailPage-Caizuyn2.js} +2 -2
  18. package/dist/chunks/{ApplicationDetailPage-BYJ2YMPq.js.map → ApplicationDetailPage-Caizuyn2.js.map} +1 -1
  19. package/dist/chunks/{ApplicationDetailPage-D8-bf1as.js → ApplicationDetailPage-CuCW6aMB.js} +4 -4
  20. package/dist/chunks/{ApplicationDetailPage-D8-bf1as.js.map → ApplicationDetailPage-CuCW6aMB.js.map} +1 -1
  21. package/dist/chunks/{ApplicationsDashboardPage-BBlLms2r.js → ApplicationsDashboardPage-B2MW8-Kc.js} +2 -2
  22. package/dist/chunks/{ApplicationsDashboardPage-BBlLms2r.js.map → ApplicationsDashboardPage-B2MW8-Kc.js.map} +1 -1
  23. package/dist/chunks/{ApplicationsDashboardPage-DTWZxJJM.js → ApplicationsDashboardPage-BDIjFIYZ.js} +3 -3
  24. package/dist/chunks/{ApplicationsDashboardPage-DTWZxJJM.js.map → ApplicationsDashboardPage-BDIjFIYZ.js.map} +1 -1
  25. package/dist/chunks/{ApplicationsGridPage-BQaMsK1K.js → ApplicationsGridPage-DV-FihKj.js} +2 -2
  26. package/dist/chunks/{ApplicationsGridPage-BQaMsK1K.js.map → ApplicationsGridPage-DV-FihKj.js.map} +1 -1
  27. package/dist/chunks/{ApplicationsGridPage-DbVcvezt.js → ApplicationsGridPage-DXsTfXPI.js} +2 -2
  28. package/dist/chunks/{ApplicationsGridPage-DbVcvezt.js.map → ApplicationsGridPage-DXsTfXPI.js.map} +1 -1
  29. package/dist/chunks/{ApplicationsListPage-DYKM2Yeo.js → ApplicationsListPage--CGkyBuJ.js} +2 -2
  30. package/dist/chunks/{ApplicationsListPage-DYKM2Yeo.js.map → ApplicationsListPage--CGkyBuJ.js.map} +1 -1
  31. package/dist/chunks/{ApplicationsListPage-C91v2rZt.js → ApplicationsListPage-JUX823bh.js} +2 -2
  32. package/dist/chunks/{ApplicationsListPage-C91v2rZt.js.map → ApplicationsListPage-JUX823bh.js.map} +1 -1
  33. package/dist/chunks/{ApplicationsPage-BCbgotIx.js → ApplicationsPage-6zgFye6w.js} +2 -2
  34. package/dist/chunks/{ApplicationsPage-BCbgotIx.js.map → ApplicationsPage-6zgFye6w.js.map} +1 -1
  35. package/dist/chunks/{ApplicationsPage-CW3-Hjlu.js → ApplicationsPage-CQPuuiO6.js} +4 -4
  36. package/dist/chunks/{ApplicationsPage-CW3-Hjlu.js.map → ApplicationsPage-CQPuuiO6.js.map} +1 -1
  37. package/dist/chunks/{AssignmentRulesPage-D8vfGDBN.js → AssignmentRulesPage-CFffeEbo.js} +2 -2
  38. package/dist/chunks/{AssignmentRulesPage-D8vfGDBN.js.map → AssignmentRulesPage-CFffeEbo.js.map} +1 -1
  39. package/dist/chunks/{AssignmentRulesPage-CxktlEMB.js → AssignmentRulesPage-D78UeUId.js} +2 -2
  40. package/dist/chunks/{AssignmentRulesPage-CxktlEMB.js.map → AssignmentRulesPage-D78UeUId.js.map} +1 -1
  41. package/dist/chunks/{AssignmentsPage-DmfBYQAD.js → AssignmentsPage-Cww2ifZF.js} +2 -2
  42. package/dist/chunks/{AssignmentsPage-DmfBYQAD.js.map → AssignmentsPage-Cww2ifZF.js.map} +1 -1
  43. package/dist/chunks/{AssignmentsPage-sRCCBmRc.js → AssignmentsPage-DE_QS2LO.js} +2 -2
  44. package/dist/chunks/{AssignmentsPage-sRCCBmRc.js.map → AssignmentsPage-DE_QS2LO.js.map} +1 -1
  45. package/dist/chunks/{AuthCallbackPage-C7XiZxKb.js → AuthCallbackPage-CA2nO6DG.js} +2 -2
  46. package/dist/chunks/{AuthCallbackPage-C7XiZxKb.js.map → AuthCallbackPage-CA2nO6DG.js.map} +1 -1
  47. package/dist/chunks/{AuthCallbackPage-BCe_bwJM.js → AuthCallbackPage-CDUAoX-N.js} +2 -2
  48. package/dist/chunks/{AuthCallbackPage-BCe_bwJM.js.map → AuthCallbackPage-CDUAoX-N.js.map} +1 -1
  49. package/dist/chunks/{ConfirmEmailPage-BUfGSqxF.js → ConfirmEmailPage-BqsILAYH.js} +2 -2
  50. package/dist/chunks/{ConfirmEmailPage-BUfGSqxF.js.map → ConfirmEmailPage-BqsILAYH.js.map} +1 -1
  51. package/dist/chunks/{ConfirmEmailPage-Buj4x-rx.js → ConfirmEmailPage-INeHCuMB.js} +2 -2
  52. package/dist/chunks/{ConfirmEmailPage-Buj4x-rx.js.map → ConfirmEmailPage-INeHCuMB.js.map} +1 -1
  53. package/dist/chunks/{CreateSupportTicketPage-CKDX_HQm.js → CreateSupportTicketPage-BWeuV2aU.js} +2 -2
  54. package/dist/chunks/{CreateSupportTicketPage-CKDX_HQm.js.map → CreateSupportTicketPage-BWeuV2aU.js.map} +1 -1
  55. package/dist/chunks/{CreateSupportTicketPage-0LgY-_pu.js → CreateSupportTicketPage-OBwF4v7b.js} +2 -2
  56. package/dist/chunks/{CreateSupportTicketPage-0LgY-_pu.js.map → CreateSupportTicketPage-OBwF4v7b.js.map} +1 -1
  57. package/dist/chunks/{DashboardPage-CUZ80NGV.js → DashboardPage-CKHqWrdS.js} +3 -3
  58. package/dist/chunks/{DashboardPage-CUZ80NGV.js.map → DashboardPage-CKHqWrdS.js.map} +1 -1
  59. package/dist/chunks/{DashboardPage-CaNOAstg.js → DashboardPage-COmc9b__.js} +3 -3
  60. package/dist/chunks/{DashboardPage-CaNOAstg.js.map → DashboardPage-COmc9b__.js.map} +1 -1
  61. package/dist/chunks/{DashboardPage-B48_rQFi.js → DashboardPage-CfKZHiSj.js} +2 -2
  62. package/dist/chunks/{DashboardPage-B48_rQFi.js.map → DashboardPage-CfKZHiSj.js.map} +1 -1
  63. package/dist/chunks/{DashboardPage-CUZV1J9t.js → DashboardPage-CwEZZ3jx.js} +2 -2
  64. package/dist/chunks/{DashboardPage-CUZV1J9t.js.map → DashboardPage-CwEZZ3jx.js.map} +1 -1
  65. package/dist/chunks/{EscalationConfigPage-CdzAbnGy.js → EscalationConfigPage--7lgZ0kJ.js} +2 -2
  66. package/dist/chunks/{EscalationConfigPage-CdzAbnGy.js.map → EscalationConfigPage--7lgZ0kJ.js.map} +1 -1
  67. package/dist/chunks/{EscalationConfigPage-CYGIl_e6.js → EscalationConfigPage-DPyiBcqV.js} +2 -2
  68. package/dist/chunks/{EscalationConfigPage-CYGIl_e6.js.map → EscalationConfigPage-DPyiBcqV.js.map} +1 -1
  69. package/dist/chunks/{ForceChangePasswordPage-lRpkwcX7.js → ForceChangePasswordPage-BE-6umub.js} +2 -2
  70. package/dist/chunks/{ForceChangePasswordPage-lRpkwcX7.js.map → ForceChangePasswordPage-BE-6umub.js.map} +1 -1
  71. package/dist/chunks/{ForceChangePasswordPage-CvmYAV3r.js → ForceChangePasswordPage-CnsYoWmV.js} +2 -2
  72. package/dist/chunks/{ForceChangePasswordPage-CvmYAV3r.js.map → ForceChangePasswordPage-CnsYoWmV.js.map} +1 -1
  73. package/dist/chunks/{ForgotPasswordPage-0u49E4Pw.js → ForgotPasswordPage-CSq4DnFF.js} +2 -2
  74. package/dist/chunks/{ForgotPasswordPage-0u49E4Pw.js.map → ForgotPasswordPage-CSq4DnFF.js.map} +1 -1
  75. package/dist/chunks/{ForgotPasswordPage-CxQUqKOm.js → ForgotPasswordPage-DZLVolAC.js} +2 -2
  76. package/dist/chunks/{ForgotPasswordPage-CxQUqKOm.js.map → ForgotPasswordPage-DZLVolAC.js.map} +1 -1
  77. package/dist/chunks/{GroupDetailPage-DFBvVO1S.js → GroupDetailPage-Bf9Wb_2j.js} +5 -5
  78. package/dist/chunks/{GroupDetailPage-DFBvVO1S.js.map → GroupDetailPage-Bf9Wb_2j.js.map} +1 -1
  79. package/dist/chunks/{GroupDetailPage-B2FkKrGG.js → GroupDetailPage-R-hf3rJ7.js} +2 -2
  80. package/dist/chunks/{GroupDetailPage-B2FkKrGG.js.map → GroupDetailPage-R-hf3rJ7.js.map} +1 -1
  81. package/dist/chunks/{MyAccessRequestsPage-C9IX4c0K.js → MyAccessRequestsPage-BIisvWM6.js} +2 -2
  82. package/dist/chunks/{MyAccessRequestsPage-C9IX4c0K.js.map → MyAccessRequestsPage-BIisvWM6.js.map} +1 -1
  83. package/dist/chunks/{MyAccessRequestsPage-D6pVULNM.js → MyAccessRequestsPage-BLSV7Tbx.js} +2 -2
  84. package/dist/chunks/{MyAccessRequestsPage-D6pVULNM.js.map → MyAccessRequestsPage-BLSV7Tbx.js.map} +1 -1
  85. package/dist/chunks/{MyTenantsPage-BEcYYdGR.js → MyTenantsPage-D-7k9CP1.js} +3 -3
  86. package/dist/chunks/{MyTenantsPage-BEcYYdGR.js.map → MyTenantsPage-D-7k9CP1.js.map} +1 -1
  87. package/dist/chunks/{MyTenantsPage-D9f85zjF.js → MyTenantsPage-DqGW6aDt.js} +2 -2
  88. package/dist/chunks/{MyTenantsPage-D9f85zjF.js.map → MyTenantsPage-DqGW6aDt.js.map} +1 -1
  89. package/dist/chunks/{MyTicketsPage-DJR8h6y1.js → MyTicketsPage--DgDsnZA.js} +2 -2
  90. package/dist/chunks/{MyTicketsPage-DJR8h6y1.js.map → MyTicketsPage--DgDsnZA.js.map} +1 -1
  91. package/dist/chunks/{MyTicketsPage-DiOUExKJ.js → MyTicketsPage-CqJ3Aqob.js} +2 -2
  92. package/dist/chunks/{MyTicketsPage-DiOUExKJ.js.map → MyTicketsPage-CqJ3Aqob.js.map} +1 -1
  93. package/dist/chunks/{NavigationAppsPage-CeHbxfZw.js → NavigationAppsPage-Bebis_RT.js} +2 -2
  94. package/dist/chunks/{NavigationAppsPage-CeHbxfZw.js.map → NavigationAppsPage-Bebis_RT.js.map} +1 -1
  95. package/dist/chunks/{NavigationAppsPage-If7tmCFY.js → NavigationAppsPage-THNPOAjv.js} +2 -2
  96. package/dist/chunks/{NavigationAppsPage-If7tmCFY.js.map → NavigationAppsPage-THNPOAjv.js.map} +1 -1
  97. package/dist/chunks/{NotificationsPage-C29Lln5o.js → NotificationsPage-CAbNW_Cn.js} +2 -2
  98. package/dist/chunks/{NotificationsPage-C29Lln5o.js.map → NotificationsPage-CAbNW_Cn.js.map} +1 -1
  99. package/dist/chunks/{NotificationsPage-BiaLRb0s.js → NotificationsPage-DxwizUhL.js} +2 -2
  100. package/dist/chunks/{NotificationsPage-BiaLRb0s.js.map → NotificationsPage-DxwizUhL.js.map} +1 -1
  101. package/dist/chunks/{OnboardingWizardPage-DQrBKNBq.js → OnboardingWizardPage-C6HlbJ3K.js} +2 -2
  102. package/dist/chunks/{OnboardingWizardPage-DQrBKNBq.js.map → OnboardingWizardPage-C6HlbJ3K.js.map} +1 -1
  103. package/dist/chunks/{OnboardingWizardPage-BQah4cI8.js → OnboardingWizardPage-CyC2zONO.js} +2 -2
  104. package/dist/chunks/{OnboardingWizardPage-BQah4cI8.js.map → OnboardingWizardPage-CyC2zONO.js.map} +1 -1
  105. package/dist/chunks/{PermissionDetailPage-Ckjdjvf9.js → PermissionDetailPage-BDHiNgky.js} +2 -2
  106. package/dist/chunks/{PermissionDetailPage-Ckjdjvf9.js.map → PermissionDetailPage-BDHiNgky.js.map} +1 -1
  107. package/dist/chunks/{PermissionDetailPage-Dh8v7mGj.js → PermissionDetailPage-C5K17ydY.js} +2 -2
  108. package/dist/chunks/{PermissionDetailPage-Dh8v7mGj.js.map → PermissionDetailPage-C5K17ydY.js.map} +1 -1
  109. package/dist/chunks/{PermissionsPage-l0PnY-EE.js → PermissionsPage-COI5LJPo.js} +2 -2
  110. package/dist/chunks/{PermissionsPage-l0PnY-EE.js.map → PermissionsPage-COI5LJPo.js.map} +1 -1
  111. package/dist/chunks/{PermissionsPage-DLy9U3P3.js → PermissionsPage-CkOwH2_d.js} +2 -2
  112. package/dist/chunks/{PermissionsPage-DLy9U3P3.js.map → PermissionsPage-CkOwH2_d.js.map} +1 -1
  113. package/dist/chunks/{PortalDashboardPage-DFBx38-x.js → PortalDashboardPage-CoEC4CmC.js} +2 -2
  114. package/dist/chunks/{PortalDashboardPage-DFBx38-x.js.map → PortalDashboardPage-CoEC4CmC.js.map} +1 -1
  115. package/dist/chunks/{PortalDashboardPage-rQYhrX0q.js → PortalDashboardPage-DrYymEf-.js} +2 -2
  116. package/dist/chunks/{PortalDashboardPage-rQYhrX0q.js.map → PortalDashboardPage-DrYymEf-.js.map} +1 -1
  117. package/dist/chunks/{PreferencesPage-BBu8yZQB.js → PreferencesPage-CJRaU3ba.js} +2 -2
  118. package/dist/chunks/{PreferencesPage-BBu8yZQB.js.map → PreferencesPage-CJRaU3ba.js.map} +1 -1
  119. package/dist/chunks/{PreferencesPage-B81MsNV1.js → PreferencesPage-Cqr9mAab.js} +2 -2
  120. package/dist/chunks/{PreferencesPage-B81MsNV1.js.map → PreferencesPage-Cqr9mAab.js.map} +1 -1
  121. package/dist/chunks/{ProfilePage-DDrl10zj.js → ProfilePage-BZVpg6-l.js} +2 -2
  122. package/dist/chunks/{ProfilePage-DDrl10zj.js.map → ProfilePage-BZVpg6-l.js.map} +1 -1
  123. package/dist/chunks/{ProfilePage-DPoXwdnc.js → ProfilePage-Cu_FITeL.js} +2 -2
  124. package/dist/chunks/{ProfilePage-DPoXwdnc.js.map → ProfilePage-Cu_FITeL.js.map} +1 -1
  125. package/dist/chunks/{ReferencesManagementPage-eFsKjIEK.js → ReferencesManagementPage-DUlVk9Ps.js} +3 -3
  126. package/dist/chunks/{ReferencesManagementPage-eFsKjIEK.js.map → ReferencesManagementPage-DUlVk9Ps.js.map} +1 -1
  127. package/dist/chunks/{ReferencesManagementPage-DhVsuElE.js → ReferencesManagementPage-ZCuYtqd7.js} +2 -2
  128. package/dist/chunks/{ReferencesManagementPage-DhVsuElE.js.map → ReferencesManagementPage-ZCuYtqd7.js.map} +1 -1
  129. package/dist/chunks/{RegisterPage-CiQib3-6.js → RegisterPage-C4xmVwh9.js} +2 -2
  130. package/dist/chunks/{RegisterPage-CiQib3-6.js.map → RegisterPage-C4xmVwh9.js.map} +1 -1
  131. package/dist/chunks/{RegisterPage-bXCcJD88.js → RegisterPage-DGyzoIHT.js} +2 -2
  132. package/dist/chunks/{RegisterPage-bXCcJD88.js.map → RegisterPage-DGyzoIHT.js.map} +1 -1
  133. package/dist/chunks/{ResetPasswordPage-Dqiahhnj.js → ResetPasswordPage-DqDD6VPR.js} +2 -2
  134. package/dist/chunks/{ResetPasswordPage-Dqiahhnj.js.map → ResetPasswordPage-DqDD6VPR.js.map} +1 -1
  135. package/dist/chunks/{ResetPasswordPage-CubPG3yv.js → ResetPasswordPage-Glu-aeqv.js} +2 -2
  136. package/dist/chunks/{ResetPasswordPage-CubPG3yv.js.map → ResetPasswordPage-Glu-aeqv.js.map} +1 -1
  137. package/dist/chunks/{ResolutionModal-Bg7XZmR1.js → ResolutionModal-CxjANAOP.js} +2 -2
  138. package/dist/chunks/{ResolutionModal-Bg7XZmR1.js.map → ResolutionModal-CxjANAOP.js.map} +1 -1
  139. package/dist/chunks/{ResolutionModal-DqRk_T0n.js → ResolutionModal-Duat18qV.js} +2 -2
  140. package/dist/chunks/{ResolutionModal-DqRk_T0n.js.map → ResolutionModal-Duat18qV.js.map} +1 -1
  141. package/dist/chunks/{RoleDetailPage-Blau6_4c.js → RoleDetailPage-BQffUSnt.js} +3 -3
  142. package/dist/chunks/{RoleDetailPage-Blau6_4c.js.map → RoleDetailPage-BQffUSnt.js.map} +1 -1
  143. package/dist/chunks/{RoleDetailPage-CiRVxxIP.js → RoleDetailPage-JTm5lD1_.js} +2 -2
  144. package/dist/chunks/{RoleDetailPage-CiRVxxIP.js.map → RoleDetailPage-JTm5lD1_.js.map} +1 -1
  145. package/dist/chunks/{RolesPage-Pm-RN3lP.js → RolesPage-B9rRzciI.js} +2 -2
  146. package/dist/chunks/{RolesPage-Pm-RN3lP.js.map → RolesPage-B9rRzciI.js.map} +1 -1
  147. package/dist/chunks/{RolesPage-Cb8joqdJ.js → RolesPage-BN8_zMOC.js} +2 -2
  148. package/dist/chunks/{RolesPage-Cb8joqdJ.js.map → RolesPage-BN8_zMOC.js.map} +1 -1
  149. package/dist/chunks/{SlaConfigPage-B86McKM6.js → SlaConfigPage-B7kZNig4.js} +2 -2
  150. package/dist/chunks/{SlaConfigPage-B86McKM6.js.map → SlaConfigPage-B7kZNig4.js.map} +1 -1
  151. package/dist/chunks/{SlaConfigPage-BY7gvYU6.js → SlaConfigPage-okvZfA_K.js} +2 -2
  152. package/dist/chunks/{SlaConfigPage-BY7gvYU6.js.map → SlaConfigPage-okvZfA_K.js.map} +1 -1
  153. package/dist/chunks/{SupportPermissionsPage-BYxcLMSd.js → SupportPermissionsPage-DGAPqJbl.js} +2 -2
  154. package/dist/chunks/{SupportPermissionsPage-BYxcLMSd.js.map → SupportPermissionsPage-DGAPqJbl.js.map} +1 -1
  155. package/dist/chunks/{SupportPermissionsPage-MXqXNJIZ.js → SupportPermissionsPage-Dg_wLOme.js} +2 -2
  156. package/dist/chunks/{SupportPermissionsPage-MXqXNJIZ.js.map → SupportPermissionsPage-Dg_wLOme.js.map} +1 -1
  157. package/dist/chunks/{TemplatesPage-BDguJ401.js → TemplatesPage-DT9fhlAU.js} +2 -2
  158. package/dist/chunks/{TemplatesPage-BDguJ401.js.map → TemplatesPage-DT9fhlAU.js.map} +1 -1
  159. package/dist/chunks/{TemplatesPage-DdnGgioU.js → TemplatesPage-DiEk538p.js} +2 -2
  160. package/dist/chunks/{TemplatesPage-DdnGgioU.js.map → TemplatesPage-DiEk538p.js.map} +1 -1
  161. package/dist/chunks/{TenantCard-ffwWsgFQ.js → TenantCard-BbSYk9_Z.js} +2 -2
  162. package/dist/chunks/{TenantCard-ffwWsgFQ.js.map → TenantCard-BbSYk9_Z.js.map} +1 -1
  163. package/dist/chunks/{TenantCard-CUjb6og9.js → TenantCard-CEkiKxcZ.js} +2 -2
  164. package/dist/chunks/{TenantCard-CUjb6og9.js.map → TenantCard-CEkiKxcZ.js.map} +1 -1
  165. package/dist/chunks/{TenantScopeSelector-Dz7i1I43.js → TenantScopeSelector-BWfYxvEa.js} +2 -2
  166. package/dist/chunks/{TenantScopeSelector-Dz7i1I43.js.map → TenantScopeSelector-BWfYxvEa.js.map} +1 -1
  167. package/dist/chunks/{TenantScopeSelector-Cym_Zyps.js → TenantScopeSelector-D-BKgQPV.js} +2 -2
  168. package/dist/chunks/{TenantScopeSelector-Cym_Zyps.js.map → TenantScopeSelector-D-BKgQPV.js.map} +1 -1
  169. package/dist/chunks/{TicketDetailPage-GOh9GX7E.js → TicketDetailPage-C1mNS9Up.js} +2 -2
  170. package/dist/chunks/{TicketDetailPage-GOh9GX7E.js.map → TicketDetailPage-C1mNS9Up.js.map} +1 -1
  171. package/dist/chunks/{TicketDetailPage-Du8WMyqf.js → TicketDetailPage-ieVDRh42.js} +2 -2
  172. package/dist/chunks/{TicketDetailPage-Du8WMyqf.js.map → TicketDetailPage-ieVDRh42.js.map} +1 -1
  173. package/dist/chunks/{TicketsPage-Bqd6moQy.js → TicketsPage-CnuWsnIW.js} +2 -2
  174. package/dist/chunks/{TicketsPage-Bqd6moQy.js.map → TicketsPage-CnuWsnIW.js.map} +1 -1
  175. package/dist/chunks/{TicketsPage-WdU4Bb7M.js → TicketsPage-jjyY15_D.js} +2 -2
  176. package/dist/chunks/{TicketsPage-WdU4Bb7M.js.map → TicketsPage-jjyY15_D.js.map} +1 -1
  177. package/dist/chunks/{UserCreateTicketPage-Cm1emgwR.js → UserCreateTicketPage-B8Tvf-ag.js} +2 -2
  178. package/dist/chunks/{UserCreateTicketPage-Cm1emgwR.js.map → UserCreateTicketPage-B8Tvf-ag.js.map} +1 -1
  179. package/dist/chunks/{UserCreateTicketPage-BPw-5Y_D.js → UserCreateTicketPage-DnOsDlfO.js} +2 -2
  180. package/dist/chunks/{UserCreateTicketPage-BPw-5Y_D.js.map → UserCreateTicketPage-DnOsDlfO.js.map} +1 -1
  181. package/dist/chunks/{UserDashboardPage-BP5WeXPS.js → UserDashboardPage-BrtkJ-NB.js} +2 -2
  182. package/dist/chunks/{UserDashboardPage-BP5WeXPS.js.map → UserDashboardPage-BrtkJ-NB.js.map} +1 -1
  183. package/dist/chunks/{UserDashboardPage-B53C8fUq.js → UserDashboardPage-KLB5CQP5.js} +2 -2
  184. package/dist/chunks/{UserDashboardPage-B53C8fUq.js.map → UserDashboardPage-KLB5CQP5.js.map} +1 -1
  185. package/dist/chunks/{UserDetailPage-B110bmGX.js → UserDetailPage-U7smBQoF.js} +5 -5
  186. package/dist/chunks/{UserDetailPage-B110bmGX.js.map → UserDetailPage-U7smBQoF.js.map} +1 -1
  187. package/dist/chunks/{UserDetailPage-CV2VCE46.js → UserDetailPage-_J6lcKAU.js} +2 -2
  188. package/dist/chunks/{UserDetailPage-CV2VCE46.js.map → UserDetailPage-_J6lcKAU.js.map} +1 -1
  189. package/dist/chunks/{UserTicketDetailPage-CCNJON1V.js → UserTicketDetailPage-CWoYQgH-.js} +2 -2
  190. package/dist/chunks/{UserTicketDetailPage-CCNJON1V.js.map → UserTicketDetailPage-CWoYQgH-.js.map} +1 -1
  191. package/dist/chunks/{UserTicketDetailPage-V0mLXrox.js → UserTicketDetailPage-DkufSlvZ.js} +2 -2
  192. package/dist/chunks/{UserTicketDetailPage-V0mLXrox.js.map → UserTicketDetailPage-DkufSlvZ.js.map} +1 -1
  193. package/dist/chunks/{UsersGroupsPage-CmdaU-z-.js → UsersGroupsPage-C38s2-Rq.js} +3 -3
  194. package/dist/chunks/{UsersGroupsPage-CmdaU-z-.js.map → UsersGroupsPage-C38s2-Rq.js.map} +1 -1
  195. package/dist/chunks/{UsersGroupsPage-BgfAMgEP.js → UsersGroupsPage-Dq3rAteo.js} +2 -2
  196. package/dist/chunks/{UsersGroupsPage-BgfAMgEP.js.map → UsersGroupsPage-Dq3rAteo.js.map} +1 -1
  197. package/dist/chunks/{UsersPage-Bg7033pp.js → UsersPage-B5C5KEUR.js} +2 -2
  198. package/dist/chunks/{UsersPage-Bg7033pp.js.map → UsersPage-B5C5KEUR.js.map} +1 -1
  199. package/dist/chunks/{UsersPage-TYAfwPY1.js → UsersPage-CXC9Hvq6.js} +2 -2
  200. package/dist/chunks/{UsersPage-TYAfwPY1.js.map → UsersPage-CXC9Hvq6.js.map} +1 -1
  201. package/dist/chunks/{accessRequestsApi-DZeDvzwv.js → accessRequestsApi-B-4TJ5_U.js} +2 -2
  202. package/dist/chunks/{accessRequestsApi-DZeDvzwv.js.map → accessRequestsApi-B-4TJ5_U.js.map} +1 -1
  203. package/dist/chunks/{accessRequestsApi-ZXFPCid2.js → accessRequestsApi-DZSfThpd.js} +2 -2
  204. package/dist/chunks/{accessRequestsApi-ZXFPCid2.js.map → accessRequestsApi-DZSfThpd.js.map} +1 -1
  205. package/dist/chunks/{aiApi-CsH8DXgs.js → aiApi-B20Teu2v.js} +2 -2
  206. package/dist/chunks/{aiApi-CsH8DXgs.js.map → aiApi-B20Teu2v.js.map} +1 -1
  207. package/dist/chunks/{aiApi-CVPzFTXa.js → aiApi-DMGz-RPM.js} +2 -2
  208. package/dist/chunks/{aiApi-CVPzFTXa.js.map → aiApi-DMGz-RPM.js.map} +1 -1
  209. package/dist/chunks/{applicationAnalyticsApi-B8AhFYLr.js → applicationAnalyticsApi-Bwa75Fzd.js} +2 -2
  210. package/dist/chunks/{applicationAnalyticsApi-B8AhFYLr.js.map → applicationAnalyticsApi-Bwa75Fzd.js.map} +1 -1
  211. package/dist/chunks/{applicationAnalyticsApi-Ce_1qOk-.js → applicationAnalyticsApi-CLBqRPfN.js} +2 -2
  212. package/dist/chunks/{applicationAnalyticsApi-Ce_1qOk-.js.map → applicationAnalyticsApi-CLBqRPfN.js.map} +1 -1
  213. package/dist/chunks/{groupsApi-BgCk2fsp.js → groupsApi-QzXI-5xu.js} +2 -2
  214. package/dist/chunks/{groupsApi-BgCk2fsp.js.map → groupsApi-QzXI-5xu.js.map} +1 -1
  215. package/dist/chunks/{groupsApi-BIbG665N.js → groupsApi-hB9kSWEd.js} +2 -2
  216. package/dist/chunks/{groupsApi-BIbG665N.js.map → groupsApi-hB9kSWEd.js.map} +1 -1
  217. package/dist/chunks/{index-Cb3LotuT.js → index--NGcBYUu.js} +3 -3
  218. package/dist/chunks/{index-Cb3LotuT.js.map → index--NGcBYUu.js.map} +1 -1
  219. package/dist/chunks/{index-C33zcyF4.js → index--aPwOFjF.js} +2 -2
  220. package/dist/chunks/{index-C33zcyF4.js.map → index--aPwOFjF.js.map} +1 -1
  221. package/dist/chunks/{index-sMr9qND_.js → index-0VrOtwP0.js} +2 -2
  222. package/dist/chunks/{index-sMr9qND_.js.map → index-0VrOtwP0.js.map} +1 -1
  223. package/dist/chunks/{index-DDKetfKq.js → index-37U271aw.js} +2 -2
  224. package/dist/chunks/{index-DDKetfKq.js.map → index-37U271aw.js.map} +1 -1
  225. package/dist/chunks/{index-B9fS7ir6.js → index-B7qZTuQ-.js} +2 -2
  226. package/dist/chunks/{index-B9fS7ir6.js.map → index-B7qZTuQ-.js.map} +1 -1
  227. package/dist/chunks/{index-CdjBY7L8.js → index-Bedzmqr-.js} +2 -2
  228. package/dist/chunks/{index-CdjBY7L8.js.map → index-Bedzmqr-.js.map} +1 -1
  229. package/dist/chunks/{index-CHG_O1fS.js → index-Betxo5g5.js} +2 -2
  230. package/dist/chunks/{index-CHG_O1fS.js.map → index-Betxo5g5.js.map} +1 -1
  231. package/dist/chunks/{index-jiGu-H8x.js → index-BmaJz475.js} +2 -2
  232. package/dist/chunks/{index-jiGu-H8x.js.map → index-BmaJz475.js.map} +1 -1
  233. package/dist/chunks/{index-C53JoVNk.js → index-Buhqag3v.js} +2 -2
  234. package/dist/chunks/{index-C53JoVNk.js.map → index-Buhqag3v.js.map} +1 -1
  235. package/dist/chunks/{index-DO0Rw7hX.js → index-C3VxlfKq.js} +2 -2
  236. package/dist/chunks/{index-DO0Rw7hX.js.map → index-C3VxlfKq.js.map} +1 -1
  237. package/dist/chunks/{index-CSQ60fpG.js → index-CgpRo8Oe.js} +2 -2
  238. package/dist/chunks/{index-CSQ60fpG.js.map → index-CgpRo8Oe.js.map} +1 -1
  239. package/dist/chunks/{index-B-e-ELsf.js → index-DOY0w8Iu.js} +8 -8
  240. package/dist/chunks/{index-B-e-ELsf.js.map → index-DOY0w8Iu.js.map} +1 -1
  241. package/dist/chunks/{index-D2REDIRX.js → index-DwuvIOrQ.js} +2 -2
  242. package/dist/chunks/{index-D2REDIRX.js.map → index-DwuvIOrQ.js.map} +1 -1
  243. package/dist/chunks/{index-DCcl7Qof.js → index-DzedSLdI.js} +2 -2
  244. package/dist/chunks/{index-DCcl7Qof.js.map → index-DzedSLdI.js.map} +1 -1
  245. package/dist/chunks/{index-2wUhd9Lu.js → index-IgLVXPg8.js} +10 -10
  246. package/dist/chunks/index-IgLVXPg8.js.map +1 -0
  247. package/dist/chunks/{index-CwSaRXXg.js → index-lpIzhufD.js} +1916 -1900
  248. package/dist/chunks/index-lpIzhufD.js.map +1 -0
  249. package/dist/chunks/{index-Cuwn2q-f.js → index-mLUKwbGl.js} +4 -4
  250. package/dist/chunks/{index-Cuwn2q-f.js.map → index-mLUKwbGl.js.map} +1 -1
  251. package/dist/chunks/{index-B0mk2tNY.js → index-tO6MMIFB.js} +2 -2
  252. package/dist/chunks/{index-B0mk2tNY.js.map → index-tO6MMIFB.js.map} +1 -1
  253. package/dist/chunks/{tenantIconMap-BpNANQ5s.js → tenantIconMap-BQD9byc8.js} +2 -2
  254. package/dist/chunks/{tenantIconMap-BpNANQ5s.js.map → tenantIconMap-BQD9byc8.js.map} +1 -1
  255. package/dist/chunks/{tenantIconMap-DtdUgvJO.js → tenantIconMap-CTMuSt18.js} +2 -2
  256. package/dist/chunks/{tenantIconMap-DtdUgvJO.js.map → tenantIconMap-CTMuSt18.js.map} +1 -1
  257. package/dist/chunks/{ticketingApi-Bu4rKwLl.js → ticketingApi-BNIdox5t.js} +2 -2
  258. package/dist/chunks/{ticketingApi-Bu4rKwLl.js.map → ticketingApi-BNIdox5t.js.map} +1 -1
  259. package/dist/chunks/{ticketingApi-r4Avm9iS.js → ticketingApi-J0vC_t7r.js} +2 -2
  260. package/dist/chunks/{ticketingApi-r4Avm9iS.js.map → ticketingApi-J0vC_t7r.js.map} +1 -1
  261. package/dist/chunks/{useAccessRequests-B9bF4swg.js → useAccessRequests-DCNNLnxk.js} +3 -3
  262. package/dist/chunks/{useAccessRequests-B9bF4swg.js.map → useAccessRequests-DCNNLnxk.js.map} +1 -1
  263. package/dist/chunks/{useAccessRequests-JyPUX3Om.js → useAccessRequests-DT7X4FAK.js} +2 -2
  264. package/dist/chunks/{useAccessRequests-JyPUX3Om.js.map → useAccessRequests-DT7X4FAK.js.map} +1 -1
  265. package/dist/chunks/{useUserAccessRequests-DjPQenC2.js → useUserAccessRequests-BYbmG4c7.js} +2 -2
  266. package/dist/chunks/{useUserAccessRequests-DjPQenC2.js.map → useUserAccessRequests-BYbmG4c7.js.map} +1 -1
  267. package/dist/chunks/{useUserAccessRequests-BB6FHW14.js → useUserAccessRequests-CylKxRN6.js} +2 -2
  268. package/dist/chunks/{useUserAccessRequests-BB6FHW14.js.map → useUserAccessRequests-CylKxRN6.js.map} +1 -1
  269. package/dist/hooks/useCollapsibleState.d.ts +5 -2
  270. package/dist/hooks/useCollapsibleState.d.ts.map +1 -1
  271. package/dist/i18n/config.d.ts +1 -0
  272. package/dist/i18n/config.d.ts.map +1 -1
  273. package/dist/main.d.ts +0 -1
  274. package/dist/main.d.ts.map +1 -1
  275. package/dist/smartstack.cjs +1 -1
  276. package/dist/smartstack.js +1 -1
  277. package/dist/utils/permissions.d.ts.map +1 -1
  278. package/package.json +1 -1
  279. package/dist/chunks/index-2wUhd9Lu.js.map +0 -1
  280. package/dist/chunks/index-CwSaRXXg.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"RoleDetailPage-CiRVxxIP.js","sources":["../../src/components/platform/administration/permissions/RolePermissionMatrix.tsx","../../src/pages/platform/administration/permissions/RoleDetailPage.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\r\nimport React, { useState, useMemo, useCallback, createRef } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, AlertCircle, ChevronDown, ChevronRight, FolderOpen, Box, FileText, Database, Check, Star, Eye, Ban, Save, X, Plus, Edit, Trash2, UserPlus, Play, Shield } from 'lucide-react';\r\nimport { usePermissionMatrix } from '@/hooks/usePermissionMatrix';\r\nimport { useCollapsibleState } from '@/hooks/useCollapsibleState';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { hasFullAccess } from '@/utils/permissions';\r\nimport { groupByApplicationWithSections, calculatePermissionStatus, calculateModuleWithSectionsStatus, getPermissionCellBackground } from '@/utils/permissionUtils';\r\nimport { PermissionStatusIndicator } from './PermissionStatusIndicator';\r\nimport { PermissionPopover } from '../PermissionPopover';\r\nimport type { ResourceNode, PermissionStatus, ModuleWithSections } from './types';\r\n\r\ninterface RolePermissionMatrixProps {\r\n readonly roleId: string;\r\n}\r\n\r\n// Action icons and colors (same as PermissionCellPopover)\r\nconst ACTION_ICONS: Record<string, React.ReactNode> = {\r\n '*': <Shield className=\"h-3 w-3\" />,\r\n read: <Eye className=\"h-3 w-3\" />,\r\n create: <Plus className=\"h-3 w-3\" />,\r\n update: <Edit className=\"h-3 w-3\" />,\r\n delete: <Trash2 className=\"h-3 w-3\" />,\r\n assign: <UserPlus className=\"h-3 w-3\" />,\r\n execute: <Play className=\"h-3 w-3\" />,\r\n};\r\n\r\nconst ACTION_COLORS: Record<string, string> = {\r\n '*': 'bg-[var(--accent-bg)] text-[var(--accent-text)] border-[var(--accent-border)]',\r\n read: 'bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]',\r\n create: 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]',\r\n update: 'bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]',\r\n delete: 'bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]',\r\n assign: 'bg-[var(--accent-bg)] text-[var(--accent-text)] border-[var(--accent-border)]',\r\n execute: 'bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]',\r\n};\r\n\r\n// Pure function to apply application/module filter\r\nfunction applyApplicationModuleFilterHelper(\r\n grouped: ReturnType<typeof groupByApplicationWithSections>,\r\n applicationFilter: string,\r\n moduleFilter: string\r\n) {\r\n return grouped\r\n .filter(app => applicationFilter === 'all' || app.application === applicationFilter)\r\n .map(app => ({\r\n ...app,\r\n modules: app.modules.filter(m => moduleFilter === 'all' || m.module.moduleLabel === moduleFilter)\r\n }))\r\n .filter(app => app.modules.length > 0);\r\n}\r\n\r\n// Pure function to apply status filter\r\nfunction applyStatusFilterHelper(\r\n grouped: ReturnType<typeof groupByApplicationWithSections>,\r\n statusFilters: Set<PermissionStatus>,\r\n getModuleStatus: (m: ModuleWithSections) => { status: PermissionStatus; grantedCount: number; totalCount: number }\r\n) {\r\n return grouped.map(app => ({\r\n ...app,\r\n modules: app.modules.filter(m => {\r\n const { status } = getModuleStatus(m);\r\n return statusFilters.has(status);\r\n })\r\n })).filter(app => app.modules.length > 0);\r\n}\r\n\r\n// Sub-component for rendering section and resource rows\r\ninterface SectionResourceRowsProps {\r\n readonly section: ResourceNode;\r\n readonly resources: ResourceNode[];\r\n readonly moduleIndex: number;\r\n readonly sectionIndex: number;\r\n readonly collapsedSections: Set<string>;\r\n readonly renderResourceRow: (resource: ResourceNode, rowIndex: number, level: 'module' | 'section' | 'resource', hasChildren: boolean, isCollapsed: boolean) => React.ReactNode;\r\n}\r\n\r\nfunction SectionResourceRows({\r\n section,\r\n resources,\r\n moduleIndex,\r\n sectionIndex,\r\n collapsedSections,\r\n renderResourceRow,\r\n}: SectionResourceRowsProps) {\r\n const hasResources = resources.length > 0;\r\n const isSectionCollapsed = collapsedSections.has(section.id);\r\n\r\n return (\r\n <React.Fragment key={section.id}>\r\n {/* Section Row */}\r\n {renderResourceRow(section, moduleIndex + sectionIndex + 1, 'section', hasResources, isSectionCollapsed)}\r\n\r\n {/* Resource Rows (if section has resources and is not collapsed) */}\r\n {hasResources && !isSectionCollapsed && resources.map((resource, resourceIndex) =>\r\n renderResourceRow(resource, moduleIndex + sectionIndex + resourceIndex + 2, 'resource', false, false)\r\n )}\r\n </React.Fragment>\r\n );\r\n}\r\n\r\nexport function RolePermissionMatrix({ roleId }: RolePermissionMatrixProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { user } = useAuth();\r\n\r\n const { collapsedApps, toggleApp } = useCollapsibleState();\r\n const [collapsedModules, setCollapsedModules] = useState<Set<string>>(new Set());\r\n const [collapsedSections, setCollapsedSections] = useState<Set<string>>(new Set());\r\n const [statusFilters, setStatusFilters] = useState<Set<PermissionStatus>>(new Set());\r\n const [openPopover, setOpenPopover] = useState<string | null>(null);\r\n\r\n // Filter states\r\n const [applicationFilter, setApplicationFilter] = useState<string>('all');\r\n const [moduleFilter, setModuleFilter] = useState<string>('all');\r\n\r\n // Super Admin can edit system roles\r\n const canEditSystemRoles = useMemo(() => {\r\n if (!user) return false;\r\n return hasFullAccess(user.permissions);\r\n }, [user]);\r\n\r\n const {\r\n loading,\r\n error,\r\n roles,\r\n filteredResources,\r\n hasChanges,\r\n saving,\r\n saveSuccess,\r\n saveError,\r\n togglePermission,\r\n saveChanges,\r\n resetChanges,\r\n getPermissionInheritance,\r\n } = usePermissionMatrix({ canEditSystemRoles });\r\n\r\n // Find the specific role\r\n const role = useMemo(() => {\r\n return roles.find(r => r.id === roleId);\r\n }, [roles, roleId]);\r\n\r\n // Check if role is editable\r\n const isRoleEditable = useMemo(() => {\r\n if (!role) return false;\r\n if (role.isSystem && !canEditSystemRoles) return false;\r\n return true;\r\n }, [role, canEditSystemRoles]);\r\n\r\n const toggleStatusFilter = (status: PermissionStatus) => {\r\n setStatusFilters(prev => {\r\n const next = new Set(prev);\r\n if (next.has(status)) {\r\n next.delete(status);\r\n } else {\r\n next.add(status);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n const toggleModule = (moduleId: string) => {\r\n setCollapsedModules(prev => {\r\n const next = new Set(prev);\r\n if (next.has(moduleId)) {\r\n next.delete(moduleId);\r\n } else {\r\n next.add(moduleId);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n const toggleSection = (sectionId: string) => {\r\n setCollapsedSections(prev => {\r\n const next = new Set(prev);\r\n if (next.has(sectionId)) {\r\n next.delete(sectionId);\r\n } else {\r\n next.add(sectionId);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n // Build filter options from resources\r\n const filterOptions = useMemo(() => {\r\n const applications: { app: string; label: string }[] = [];\r\n const modules: { app: string; module: string; label: string }[] = [];\r\n\r\n filteredResources.forEach(resource => {\r\n if (resource.level === 'module') {\r\n const appKey = resource.applicationLabel;\r\n if (!applications.find(a => a.app === appKey)) {\r\n applications.push({\r\n app: resource.applicationLabel,\r\n label: resource.applicationLabel\r\n });\r\n }\r\n\r\n modules.push({\r\n app: resource.applicationLabel,\r\n module: resource.moduleLabel,\r\n label: resource.moduleLabel\r\n });\r\n }\r\n });\r\n\r\n return {\r\n applications: applications.sort((a, b) => a.label.localeCompare(b.label)),\r\n modules: modules.sort((a, b) => a.label.localeCompare(b.label))\r\n };\r\n }, [filteredResources]);\r\n\r\n // Handle permission toggle\r\n const handleTogglePermission = useCallback((permissionId: string) => {\r\n if (!role || !isRoleEditable) return;\r\n togglePermission(role.id, permissionId);\r\n }, [role, isRoleEditable, togglePermission]);\r\n\r\n // Check if a permission is granted\r\n const isPermissionGrantedFn = useCallback((permissionId: string): boolean => {\r\n if (!role) return false;\r\n const info = getPermissionInheritance(role.id, permissionId);\r\n return info.isDirect || info.isInherited;\r\n }, [role, getPermissionInheritance]);\r\n\r\n // Calculate permission status for this role on a module (including sections)\r\n const getModuleStatus = useCallback((moduleWithSections: ModuleWithSections): { status: PermissionStatus; grantedCount: number; totalCount: number } => {\r\n return calculateModuleWithSectionsStatus(\r\n moduleWithSections.module,\r\n moduleWithSections.sections,\r\n isPermissionGrantedFn\r\n );\r\n }, [isPermissionGrantedFn]);\r\n\r\n // Calculate permission status for a single resource\r\n const getResourceStatus = useCallback((resource: ResourceNode): { status: PermissionStatus; grantedCount: number } => {\r\n return calculatePermissionStatus(resource, isPermissionGrantedFn);\r\n }, [isPermissionGrantedFn]);\r\n\r\n // Get granted permissions for a resource\r\n const getGrantedPermissions = useCallback((resource: ResourceNode): string[] => {\r\n if (!role) return [];\r\n\r\n return resource.permissions\r\n .filter(p => {\r\n const info = getPermissionInheritance(role.id, p.id);\r\n return info.isDirect || info.isInherited;\r\n })\r\n .map(p => p.action);\r\n }, [role, getPermissionInheritance]);\r\n\r\n\r\n const applyApplicationModuleFilter = useCallback((grouped: ReturnType<typeof groupByApplicationWithSections>) => {\r\n return applyApplicationModuleFilterHelper(grouped, applicationFilter, moduleFilter);\r\n }, [applicationFilter, moduleFilter]);\r\n\r\n const applyStatusFilter = useCallback((grouped: ReturnType<typeof groupByApplicationWithSections>) => {\r\n if (statusFilters.size === 0) return grouped;\r\n return applyStatusFilterHelper(grouped, statusFilters, getModuleStatus);\r\n }, [statusFilters, getModuleStatus]);\r\n\r\n const groupedResources = useMemo(() => {\r\n let grouped = groupByApplicationWithSections(filteredResources);\r\n grouped = applyApplicationModuleFilter(grouped);\r\n grouped = applyStatusFilter(grouped);\r\n return grouped;\r\n }, [filteredResources, applyApplicationModuleFilter, applyStatusFilter]);\r\n\r\n // Get total module count for stats\r\n const totalModuleCount = useMemo(() => {\r\n return groupedResources.reduce((sum, app) =>\r\n sum + app.modules.length, 0);\r\n }, [groupedResources]);\r\n\r\n const handleToggleCollapse = useCallback((resourceId: string, level: 'module' | 'section' | 'resource') => {\r\n if (level === 'module') {\r\n toggleModule(resourceId);\r\n } else if (level === 'section') {\r\n toggleSection(resourceId);\r\n }\r\n }, [toggleModule, toggleSection]);\r\n\r\n const handleCellClick = (resourceId: string) => {\r\n if (openPopover === resourceId) {\r\n setOpenPopover(null);\r\n } else {\r\n setOpenPopover(resourceId);\r\n }\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <div className=\"text-center\">\r\n <Loader2 className=\"h-8 w-8 animate-spin text-[var(--color-accent-500)] mx-auto mb-4\" />\r\n <p className=\"text-[var(--text-secondary)]\">{t('userPermissions.loading')}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2\">\r\n <AlertCircle className=\"h-5 w-5 text-[var(--error-text)]\" />\r\n <p className=\"text-[var(--error-text)]\">{error}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!role) {\r\n return (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('roleDetail.notFound')}\r\n </div>\r\n );\r\n }\r\n\r\n const getRoleResourceIcon = (level: 'module' | 'section' | 'resource') => {\r\n if (level === 'resource') return <Database className=\"h-3.5 w-3.5 text-[var(--text-muted)]\" />;\r\n if (level === 'section') return <FileText className=\"h-3.5 w-3.5 text-[var(--text-muted)]\" />;\r\n return <Box className=\"h-3.5 w-3.5 text-[var(--text-secondary)]\" />;\r\n };\r\n\r\n const getRoleResourceLabelClass = (level: 'module' | 'section' | 'resource'): string => {\r\n if (level === 'resource') return 'text-[var(--text-muted)] italic';\r\n if (level === 'section') return 'text-[var(--text-secondary)]';\r\n return 'font-medium text-[var(--text-primary)]';\r\n };\r\n\r\n const getRolePaddingClass = (level: 'module' | 'section' | 'resource'): string => {\r\n if (level === 'resource') return 'pl-28';\r\n if (level === 'section') return 'pl-22';\r\n return 'pl-16';\r\n };\r\n\r\n const renderToggleButton = (hasChildren: boolean, resourceId: string, level: 'module' | 'section' | 'resource', isCollapsed: boolean) => {\r\n if (!hasChildren) return null;\r\n return (\r\n <button\r\n onClick={() => handleToggleCollapse(resourceId, level)}\r\n className=\"p-0.5 hover:bg-[var(--bg-hover)] rounded\"\r\n >\r\n {isCollapsed ? (\r\n <ChevronRight className=\"h-3 w-3 text-[var(--text-muted)]\" />\r\n ) : (\r\n <ChevronDown className=\"h-3 w-3 text-[var(--text-muted)]\" />\r\n )}\r\n </button>\r\n );\r\n };\r\n\r\n const renderPermissionBadges = (grantedPermissions: string[]) => {\r\n if (grantedPermissions.length === 0) {\r\n return (\r\n <span className=\"text-xs text-[var(--text-muted)] italic\">\r\n {t('assignments.noPermissions')}\r\n </span>\r\n );\r\n }\r\n return grantedPermissions.map((action) => {\r\n const actionColor = ACTION_COLORS[action] || 'bg-[var(--bg-secondary)] text-[var(--text-secondary)] border-[var(--border-color)]';\r\n const icon = ACTION_ICONS[action] || <Eye className=\"h-3 w-3\" />;\r\n return (\r\n <div\r\n key={action}\r\n className={`inline-flex items-center gap-1.5 px-2 py-0.5 rounded-[var(--radius-badge)] border text-xs font-medium ${actionColor}`}\r\n title={t(`assignments.actions.${action === '*' ? 'all' : action}.description`)}\r\n >\r\n {icon}\r\n <span className=\"capitalize\">\r\n {t(`assignments.actions.${action === '*' ? 'all' : action}.label`)}\r\n </span>\r\n </div>\r\n );\r\n });\r\n };\r\n\r\n const renderResourceRow = (\r\n resource: ResourceNode,\r\n rowIndex: number,\r\n level: 'module' | 'section' | 'resource',\r\n hasChildren: boolean = false,\r\n isCollapsed: boolean = false\r\n ) => {\r\n const { status, grantedCount } = getResourceStatus(resource);\r\n const isPopoverOpen = openPopover === resource.id;\r\n const buttonRef = createRef<HTMLButtonElement>();\r\n const cellBg = getPermissionCellBackground(status);\r\n const grantedPermissions = getGrantedPermissions(resource);\r\n const paddingLeft = getRolePaddingClass(level);\r\n const rowBgClass = rowIndex % 2 === 0 ? 'item-light' : 'item-medium';\r\n\r\n return (\r\n <tr\r\n key={resource.id}\r\n className={`hover:bg-[var(--bg-hover)] ${rowBgClass}`}\r\n >\r\n <td\r\n className={`sticky left-0 z-10 ${rowBgClass} px-3 py-2 ${paddingLeft}`}\r\n style={{ width: '280px', minWidth: '280px', maxWidth: '280px' }}\r\n >\r\n <div className=\"flex items-center gap-2\">\r\n {renderToggleButton(hasChildren, resource.id, level, isCollapsed)}\r\n {getRoleResourceIcon(level)}\r\n <span className={`text-sm ${getRoleResourceLabelClass(level)}`}>\r\n {resource.moduleLabel}\r\n </span>\r\n <span className=\"text-xs text-[var(--text-muted)]\">\r\n ({resource.permissions.length})\r\n </span>\r\n </div>\r\n </td>\r\n\r\n <td\r\n className={`px-0 py-1 text-center relative ${cellBg}`}\r\n style={{ width: '60px', minWidth: '60px', maxWidth: '60px' }}\r\n >\r\n <button\r\n ref={buttonRef}\r\n type=\"button\"\r\n onClick={() => isRoleEditable && handleCellClick(resource.id)}\r\n disabled={!isRoleEditable}\r\n className={`w-full h-full min-h-[36px] flex items-center justify-center rounded transition-colors ${\r\n !isRoleEditable\r\n ? 'cursor-not-allowed opacity-50'\r\n : 'hover:opacity-80'\r\n } ${\r\n isPopoverOpen ? 'ring-2 ring-[var(--color-accent-500)]' : ''\r\n }`}\r\n title={\r\n !isRoleEditable\r\n ? `${role.name} - ${t('assignments.systemRoleReadOnly')}`\r\n : `${role.name} - ${resource.moduleLabel}: ${grantedCount}/${resource.permissions.length}`\r\n }\r\n >\r\n <PermissionStatusIndicator\r\n status={status}\r\n grantedCount={grantedCount}\r\n totalCount={resource.permissions.length}\r\n />\r\n </button>\r\n {isPopoverOpen && isRoleEditable && (\r\n <PermissionPopover\r\n mode=\"editable\"\r\n role={role}\r\n resource={resource}\r\n onTogglePermission={handleTogglePermission}\r\n onClose={() => setOpenPopover(null)}\r\n getPermissionInheritance={(_, permId) => getPermissionInheritance(role.id, permId)}\r\n />\r\n )}\r\n </td>\r\n\r\n <td className=\"px-3 py-2\">\r\n <div className=\"flex flex-wrap gap-1.5\">\r\n {renderPermissionBadges(grantedPermissions)}\r\n </div>\r\n </td>\r\n </tr>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Fixed height container for save banner to prevent layout shift */}\r\n <div className=\"min-h-[52px]\">\r\n {saveSuccess && (\r\n <div className=\"flex items-center justify-between p-3 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <div className=\"flex items-center gap-2\">\r\n <Check className=\"h-4 w-4 text-[var(--success-text)]\" />\r\n <p className=\"text-sm text-[var(--success-text)] font-medium\">\r\n {t('common.savedSuccessfully', 'Sauvegardé avec succès !')}\r\n </p>\r\n </div>\r\n </div>\r\n )}\r\n {!saveSuccess && saving && (\r\n <div className=\"flex items-center justify-between p-3 rounded-[var(--radius-card)] bg-[var(--info-bg)] border border-[var(--info-border)]\">\r\n <div className=\"flex items-center gap-2\">\r\n <Loader2 className=\"h-4 w-4 animate-spin text-[var(--info-text)]\" />\r\n <p className=\"text-sm text-[var(--info-text)] font-medium\">\r\n {t('common.saving', 'Sauvegarde en cours...')}\r\n </p>\r\n </div>\r\n </div>\r\n )}\r\n {!saveSuccess && !saving && hasChanges && (\r\n <div className=\"flex items-center justify-between p-3 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <p className=\"text-sm text-[var(--warning-text)]\">\r\n {t('assignments.unsavedChanges', 'You have unsaved changes')}\r\n </p>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={resetChanges}\r\n disabled={saving}\r\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-[var(--radius-button)] bg-[var(--bg-secondary)] border border-[var(--border-color)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] disabled:opacity-50\"\r\n >\r\n <X className=\"h-4 w-4\" />\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n onClick={saveChanges}\r\n disabled={saving}\r\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Save className=\"h-4 w-4\" />}\r\n {t('common.save')}\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n {!saveSuccess && !saving && !hasChanges && (\r\n <div className=\"h-[52px]\" />\r\n )}\r\n </div>\r\n\r\n {/* Save error */}\r\n {saveError && (\r\n <div className=\"p-3 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2\">\r\n <AlertCircle className=\"h-4 w-4 text-[var(--error-text)]\" />\r\n <p className=\"text-sm text-[var(--error-text)]\">{saveError}</p>\r\n </div>\r\n </div>\r\n )}\r\n\r\n\r\n {/* Filter Dropdowns */}\r\n <div className=\"flex flex-wrap items-center gap-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <label className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('userPermissions.filters.application')}:\r\n </label>\r\n <select\r\n value={applicationFilter}\r\n onChange={(e) => {\r\n setApplicationFilter(e.target.value);\r\n setModuleFilter('all');\r\n }}\r\n className=\"px-3 py-1.5 text-sm bg-[var(--bg-secondary)] border border-[var(--border-color)] rounded-[var(--radius-input)] text-[var(--text-primary)] focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value=\"all\">{t('userPermissions.filters.allApplications')}</option>\r\n {filterOptions.applications\r\n .map(app => (\r\n <option key={app.app} value={app.app}>{app.label}</option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n <div className=\"flex items-center gap-2\">\r\n <label className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('userPermissions.filters.module')}:\r\n </label>\r\n <select\r\n value={moduleFilter}\r\n onChange={(e) => setModuleFilter(e.target.value)}\r\n className=\"px-3 py-1.5 text-sm bg-[var(--bg-secondary)] border border-[var(--border-color)] rounded-[var(--radius-input)] text-[var(--text-primary)] focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value=\"all\">{t('userPermissions.filters.allModules')}</option>\r\n {filterOptions.modules\r\n .filter(mod =>\r\n (applicationFilter === 'all' || mod.app === applicationFilter)\r\n )\r\n .map(mod => (\r\n <option key={`${mod.app}:${mod.module}`} value={mod.module}>{mod.label}</option>\r\n ))}\r\n </select>\r\n </div>\r\n </div>\r\n\r\n {/* Status Filter Buttons - Using CSS variables for colors */}\r\n <div className=\"flex flex-wrap items-center gap-3\">\r\n <span className=\"text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('userPermissions.filterByStatus')}:\r\n </span>\r\n <div className=\"flex flex-wrap gap-2\">\r\n <button\r\n onClick={() => toggleStatusFilter('all')}\r\n className={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border transition-colors ${\r\n statusFilters.has('all')\r\n ? 'bg-[var(--success-bg)] border-[var(--success-border)] text-[var(--success-text)]'\r\n : 'bg-[var(--bg-tertiary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--success-border)]'\r\n }`}\r\n >\r\n <Check className={`h-3.5 w-3.5 ${statusFilters.has('all') ? '' : 'text-[var(--success-dot)]'}`} />\r\n {t('assignments.complete')}\r\n </button>\r\n <button\r\n onClick={() => toggleStatusFilter('some')}\r\n className={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border transition-colors ${\r\n statusFilters.has('some')\r\n ? 'bg-[var(--warning-bg)] border-[var(--warning-border)] text-[var(--warning-text)]'\r\n : 'bg-[var(--bg-tertiary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--warning-border)]'\r\n }`}\r\n >\r\n <Star className={`h-3.5 w-3.5 ${statusFilters.has('some') ? '' : 'text-[var(--warning-dot)]'}`} />\r\n {t('assignments.partial')}\r\n </button>\r\n <button\r\n onClick={() => toggleStatusFilter('read-only')}\r\n className={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border transition-colors ${\r\n statusFilters.has('read-only')\r\n ? 'bg-[var(--info-bg)] border-[var(--info-border)] text-[var(--info-text)]'\r\n : 'bg-[var(--bg-tertiary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--info-border)]'\r\n }`}\r\n >\r\n <Eye className={`h-3.5 w-3.5 ${statusFilters.has('read-only') ? '' : 'text-[var(--info-dot)]'}`} />\r\n {t('assignments.readOnly')}\r\n </button>\r\n <button\r\n onClick={() => toggleStatusFilter('none')}\r\n className={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border transition-colors ${\r\n statusFilters.has('none')\r\n ? 'bg-[var(--error-bg)] border-[var(--error-border)] text-[var(--error-text)]'\r\n : 'bg-[var(--bg-tertiary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--error-border)]'\r\n }`}\r\n >\r\n <Ban className={`h-3.5 w-3.5 ${statusFilters.has('none') ? '' : 'text-[var(--text-muted)]'}`} />\r\n {t('assignments.none')}\r\n </button>\r\n </div>\r\n {statusFilters.size > 0 && (\r\n <button\r\n onClick={() => setStatusFilters(new Set())}\r\n className=\"text-xs text-[var(--color-accent-500)] hover:text-[var(--color-accent-600)] underline\"\r\n >\r\n {t('assignments.clearFilters')}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* Stats */}\r\n <div className=\"flex items-center gap-3\">\r\n <span className=\"px-2.5 py-1 text-xs font-semibold rounded-full bg-[var(--bg-tertiary)] text-[var(--text-secondary)]\">\r\n {totalModuleCount} {t('assignments.modules')}\r\n </span>\r\n </div>\r\n\r\n {/* Permission Matrix Table - Same style as PermissionMatrixTable */}\r\n <div className=\"overflow-x-auto overflow-y-visible\">\r\n <table className=\"border-collapse\" style={{ width: 'auto' }}>\r\n <thead className=\"item-medium border-b border-[var(--item-color-border)]\">\r\n <tr>\r\n <th\r\n scope=\"col\"\r\n className=\"sticky left-0 z-20 item-medium px-3 text-left text-xs font-medium text-[var(--text-secondary)] uppercase tracking-wider\"\r\n style={{ width: '280px', minWidth: '280px', maxWidth: '280px', height: '48px', verticalAlign: 'middle' }}\r\n >\r\n {t('assignments.resource')}\r\n </th>\r\n <th\r\n scope=\"col\"\r\n className=\"px-2 text-center text-xs font-medium text-[var(--text-secondary)] uppercase tracking-wider\"\r\n style={{ width: '60px', minWidth: '60px', maxWidth: '60px', height: '48px', verticalAlign: 'middle' }}\r\n >\r\n {t('userPermissions.status')}\r\n </th>\r\n <th\r\n scope=\"col\"\r\n className=\"px-3 text-left text-xs font-medium text-[var(--text-secondary)] uppercase tracking-wider\"\r\n style={{ height: '48px', verticalAlign: 'middle' }}\r\n >\r\n {t('assignments.permissions')}\r\n </th>\r\n </tr>\r\n </thead>\r\n <tbody className=\"divide-y divide-[var(--item-color-border)]\">\r\n {groupedResources.map((appGroup) => {\r\n const appKey = appGroup.application;\r\n const isAppCollapsed = collapsedApps.has(appKey);\r\n\r\n return (\r\n <React.Fragment key={appKey}>\r\n {/* Application Header Row */}\r\n <tr className=\"bg-[var(--bg-tertiary)]\">\r\n <td\r\n className=\"sticky left-0 z-10 px-3 py-2 bg-[var(--bg-tertiary)]\"\r\n style={{ width: '280px', minWidth: '280px', maxWidth: '280px' }}\r\n >\r\n <button\r\n onClick={() => toggleApp(appKey)}\r\n className=\"flex items-center gap-3 w-full text-left hover:opacity-80\"\r\n >\r\n {isAppCollapsed ? (\r\n <ChevronRight className=\"h-4 w-4 text-[var(--text-secondary)]\" />\r\n ) : (\r\n <ChevronDown className=\"h-4 w-4 text-[var(--text-secondary)]\" />\r\n )}\r\n <FolderOpen className=\"h-4 w-4 text-[var(--text-secondary)]\" />\r\n <span className=\"text-sm font-semibold text-[var(--text-primary)]\">\r\n {appGroup.application}\r\n </span>\r\n <span className=\"text-xs text-[var(--text-muted)] ml-auto\">\r\n {appGroup.modules.length} module{appGroup.modules.length > 1 ? 's' : ''}\r\n </span>\r\n </button>\r\n </td>\r\n <td className=\"px-0 py-2\" />\r\n <td className=\"px-0 py-2\" />\r\n </tr>\r\n\r\n {/* Module, Section and Resource Rows */}\r\n {!isAppCollapsed && appGroup.modules.map((moduleWithSections, moduleIndex) => {\r\n const { module, sections } = moduleWithSections;\r\n const hasSections = sections.length > 0;\r\n const isModuleCollapsed = collapsedModules.has(module.id);\r\n\r\n return (\r\n <React.Fragment key={module.id}>\r\n {/* Module Row */}\r\n {renderResourceRow(module, moduleIndex, 'module', hasSections, isModuleCollapsed)}\r\n\r\n {/* Section and Resource Rows (if module has sections and is not collapsed) */}\r\n {hasSections && !isModuleCollapsed && sections.map((sectionWithResources, sectionIndex) => {\r\n const { section, resources } = sectionWithResources;\r\n\r\n return (\r\n <SectionResourceRows\r\n key={section.id}\r\n section={section}\r\n resources={resources}\r\n moduleIndex={moduleIndex}\r\n sectionIndex={sectionIndex}\r\n collapsedSections={collapsedSections}\r\n renderResourceRow={renderResourceRow}\r\n />\r\n );\r\n })}\r\n </React.Fragment>\r\n );\r\n })}\r\n </React.Fragment>\r\n );\r\n })}\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n {totalModuleCount === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('assignments.noResources')}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useParams, useNavigate, Link } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n ArrowLeft,\r\n Shield,\r\n Users,\r\n Settings,\r\n Loader2,\r\n Save,\r\n Lock,\r\n AlertTriangle,\r\n CheckCircle,\r\n Languages,\r\n Plus,\r\n Trash2,\r\n Edit2,\r\n X,\r\n UsersRound,\r\n Search\r\n} from 'lucide-react';\r\nimport {\r\n adminApi,\r\n type RoleDetailDto,\r\n type RoleListDto,\r\n type UpdateRoleRequest,\r\n type RoleTranslationDto,\r\n type UpdateRoleTranslationRequest,\r\n type RoleCategory,\r\n type UserListDto\r\n} from '@/services/api/adminApi';\r\nimport { groupsApi, type GroupListDto } from '@/services/api/groupsApi';\r\nimport { RolePermissionMatrix } from '@/components/platform/administration/permissions/RolePermissionMatrix';\r\n\r\ntype TabId = 'info' | 'permissions' | 'users' | 'groups' | 'translations';\r\n\r\nconst SUPPORTED_LANGUAGES = [\r\n { code: 'fr', label: 'Français' },\r\n { code: 'en', label: 'English' },\r\n { code: 'it', label: 'Italiano' },\r\n { code: 'de', label: 'Deutsch' }\r\n];\r\n\r\nexport function RoleDetailPage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { id: roleId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n\r\n const [role, setRole] = useState<RoleDetailDto | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [saving, setSaving] = useState(false);\r\n const [activeTab, setActiveTab] = useState<TabId>('info');\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n\r\n const [formData, setFormData] = useState({\r\n name: '',\r\n shortName: '',\r\n category: 'Custom' as RoleCategory,\r\n description: '',\r\n parentRoleId: null as string | null\r\n });\r\n const [availableRoles, setAvailableRoles] = useState<RoleListDto[]>([]);\r\n\r\n const ROLE_CATEGORIES: RoleCategory[] = ['Global', 'Admin', 'Manager', 'Contributor', 'Viewer', 'Custom'];\r\n\r\n // Translation state\r\n const [translations, setTranslations] = useState<RoleTranslationDto[]>([]);\r\n const [loadingTranslations, setLoadingTranslations] = useState(false);\r\n const [editingTranslation, setEditingTranslation] = useState<string | null>(null);\r\n const [translationForm, setTranslationForm] = useState<UpdateRoleTranslationRequest>({\r\n name: '',\r\n shortName: '',\r\n description: ''\r\n });\r\n const [savingTranslation, setSavingTranslation] = useState(false);\r\n const [showAddTranslation, setShowAddTranslation] = useState(false);\r\n const [newTranslationLang, setNewTranslationLang] = useState('');\r\n\r\n // User assignment state\r\n const [addingUser, setAddingUser] = useState(false);\r\n const [availableUsers, setAvailableUsers] = useState<UserListDto[]>([]);\r\n const [loadingUsers, setLoadingUsers] = useState(false);\r\n const [userSearchTerm, setUserSearchTerm] = useState('');\r\n const [selectedUserId, setSelectedUserId] = useState<string | null>(null);\r\n const [assigningUser, setAssigningUser] = useState(false);\r\n const [removingUserId, setRemovingUserId] = useState<string | null>(null);\r\n\r\n // Group assignment state\r\n const [addingGroup, setAddingGroup] = useState(false);\r\n const [availableGroups, setAvailableGroups] = useState<GroupListDto[]>([]);\r\n const [loadingGroups, setLoadingGroups] = useState(false);\r\n const [groupSearchTerm, setGroupSearchTerm] = useState('');\r\n const [selectedGroupId, setSelectedGroupId] = useState<string | null>(null);\r\n const [assigningGroup, setAssigningGroup] = useState(false);\r\n const [removingGroupId, setRemovingGroupId] = useState<string | null>(null);\r\n\r\n const loadRole = useCallback(async () => {\r\n if (!roleId) return;\r\n try {\r\n setLoading(true);\r\n const [roleData, rolesData] = await Promise.all([\r\n adminApi.roles.getById(roleId),\r\n adminApi.roles.getAll()\r\n ]);\r\n setRole(roleData);\r\n // Filter out current role from available parent roles\r\n setAvailableRoles(rolesData.filter(r => r.id !== roleId));\r\n setFormData({\r\n name: roleData.name,\r\n shortName: roleData.shortName,\r\n category: roleData.category,\r\n description: roleData.description || '',\r\n parentRoleId: roleData.parentRoleId\r\n });\r\n } catch (err) {\r\n console.error('Failed to load role:', err);\r\n setError(t('roleDetail.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [roleId, t]);\r\n\r\n useEffect(() => {\r\n loadRole();\r\n }, [loadRole]);\r\n\r\n const handleSaveInfo = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (!roleId || !role) return;\r\n\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n\r\n try {\r\n const updateData: UpdateRoleRequest = {\r\n name: formData.name,\r\n shortName: formData.shortName,\r\n category: formData.category,\r\n description: formData.description || undefined,\r\n parentRoleId: formData.parentRoleId || undefined\r\n };\r\n await adminApi.roles.update(roleId, updateData);\r\n setSuccess(t('roleDetail.success.saved'));\r\n loadRole();\r\n } catch (err: unknown) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.saveFailed'));\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n // Translation functions\r\n const loadTranslations = useCallback(async () => {\r\n if (!roleId) return;\r\n setLoadingTranslations(true);\r\n try {\r\n const data = await adminApi.roles.getTranslations(roleId);\r\n setTranslations(data);\r\n } catch (err) {\r\n console.error('Failed to load translations:', err);\r\n } finally {\r\n setLoadingTranslations(false);\r\n }\r\n }, [roleId]);\r\n\r\n useEffect(() => {\r\n if (activeTab === 'translations' && translations.length === 0) {\r\n loadTranslations();\r\n }\r\n }, [activeTab, translations.length, loadTranslations]);\r\n\r\n const startEditTranslation = (trans: RoleTranslationDto) => {\r\n setEditingTranslation(trans.languageCode);\r\n setTranslationForm({\r\n name: trans.name,\r\n shortName: trans.shortName,\r\n description: trans.description || ''\r\n });\r\n };\r\n\r\n const cancelEditTranslation = () => {\r\n setEditingTranslation(null);\r\n setShowAddTranslation(false);\r\n setTranslationForm({ name: '', shortName: '', description: '' });\r\n setNewTranslationLang('');\r\n };\r\n\r\n const handleSaveTranslation = async (languageCode: string) => {\r\n if (!roleId) return;\r\n setSavingTranslation(true);\r\n setError(null);\r\n try {\r\n await adminApi.roles.upsertTranslation(roleId, languageCode, translationForm);\r\n setSuccess(t('roleDetail.translations.saved'));\r\n setEditingTranslation(null);\r\n setShowAddTranslation(false);\r\n setNewTranslationLang('');\r\n loadTranslations();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.saveFailed'));\r\n } finally {\r\n setSavingTranslation(false);\r\n }\r\n };\r\n\r\n const handleDeleteTranslation = async (languageCode: string) => {\r\n if (!roleId) return;\r\n if (!confirm(t('roleDetail.translations.confirmDelete'))) return;\r\n try {\r\n await adminApi.roles.deleteTranslation(roleId, languageCode);\r\n setSuccess(t('roleDetail.translations.deleted'));\r\n loadTranslations();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.saveFailed'));\r\n }\r\n };\r\n\r\n const availableLanguages = SUPPORTED_LANGUAGES.filter(\r\n lang => !translations.some(t => t.languageCode === lang.code)\r\n );\r\n\r\n // User assignment functions\r\n const openAddUser = async () => {\r\n setAddingUser(true);\r\n setSelectedUserId(null);\r\n setUserSearchTerm('');\r\n setLoadingUsers(true);\r\n try {\r\n const data = await adminApi.users.getAll({ globalScope: true });\r\n setAvailableUsers(data.items);\r\n } catch (err) {\r\n console.error('Failed to load users:', err);\r\n } finally {\r\n setLoadingUsers(false);\r\n }\r\n };\r\n\r\n const handleAssignUser = async () => {\r\n if (!roleId || !selectedUserId) return;\r\n setAssigningUser(true);\r\n try {\r\n await adminApi.roles.assignUser(roleId, selectedUserId);\r\n setAddingUser(false);\r\n setSelectedUserId(null);\r\n setSuccess(t('roleDetail.users.assigned'));\r\n loadRole();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.assignFailed'));\r\n } finally {\r\n setAssigningUser(false);\r\n }\r\n };\r\n\r\n const handleRemoveUser = async (userId: string) => {\r\n if (!roleId) return;\r\n if (!confirm(t('roleDetail.users.confirmRemove'))) return;\r\n setRemovingUserId(userId);\r\n try {\r\n await adminApi.roles.removeUser(roleId, userId);\r\n setSuccess(t('roleDetail.users.removed'));\r\n loadRole();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.removeFailed'));\r\n } finally {\r\n setRemovingUserId(null);\r\n }\r\n };\r\n\r\n // Group assignment functions\r\n const openAddGroup = async () => {\r\n setAddingGroup(true);\r\n setSelectedGroupId(null);\r\n setGroupSearchTerm('');\r\n setLoadingGroups(true);\r\n try {\r\n const data = await groupsApi.getAll();\r\n setAvailableGroups(data);\r\n } catch (err) {\r\n console.error('Failed to load groups:', err);\r\n } finally {\r\n setLoadingGroups(false);\r\n }\r\n };\r\n\r\n const handleAssignGroup = async () => {\r\n if (!roleId || !selectedGroupId) return;\r\n setAssigningGroup(true);\r\n try {\r\n await adminApi.roles.assignGroup(roleId, selectedGroupId);\r\n setAddingGroup(false);\r\n setSelectedGroupId(null);\r\n setSuccess(t('roleDetail.groups.assigned'));\r\n loadRole();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.assignFailed'));\r\n } finally {\r\n setAssigningGroup(false);\r\n }\r\n };\r\n\r\n const handleRemoveGroup = async (groupId: string) => {\r\n if (!roleId) return;\r\n if (!confirm(t('roleDetail.groups.confirmRemove'))) return;\r\n setRemovingGroupId(groupId);\r\n try {\r\n await adminApi.roles.removeGroup(roleId, groupId);\r\n setSuccess(t('roleDetail.groups.removed'));\r\n loadRole();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.removeFailed'));\r\n } finally {\r\n setRemovingGroupId(null);\r\n }\r\n };\r\n\r\n const tabs: { id: TabId; label: string; icon: React.ReactNode }[] = [\r\n { id: 'info', label: t('roleDetail.tabs.info'), icon: <Settings className=\"w-4 h-4\" /> },\r\n { id: 'permissions', label: t('roleDetail.tabs.permissions'), icon: <Shield className=\"w-4 h-4\" /> },\r\n { id: 'users', label: t('roleDetail.tabs.users'), icon: <Users className=\"w-4 h-4\" /> },\r\n { id: 'groups', label: t('roleDetail.tabs.groups'), icon: <UsersRound className=\"w-4 h-4\" /> },\r\n { id: 'translations', label: t('roleDetail.tabs.translations'), icon: <Languages className=\"w-4 h-4\" /> }\r\n ];\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center h-64\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (!role) {\r\n return (\r\n <div className=\"text-center py-12\">\r\n <p className=\"text-[var(--text-secondary)]\">{t('roleDetail.notFound')}</p>\r\n <button\r\n onClick={() => navigate('/administration/permissions/roles')}\r\n className=\"mt-4 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white\"\r\n >\r\n {t('roleDetail.backToList')}\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('roles.title', 'Roles'), href: '/administration/permissions/roles' },\r\n { label: role?.name || 'Detail' }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/administration/permissions/roles')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-3\">\r\n <h1 className=\"text-xl sm:text-2xl font-bold text-[var(--text-primary)]\">{role.name}</h1>\r\n {role.isSystem && (\r\n <span className=\"flex items-center gap-1 px-2 py-1 rounded-[var(--radius-badge)] text-xs bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)]\">\r\n <Lock className=\"w-3 h-3\" />\r\n {t('roles.system')}\r\n </span>\r\n )}\r\n </div>\r\n {role.description && (\r\n <p className=\"text-sm sm:text-base text-[var(--text-secondary)] mt-1\">{role.description}</p>\r\n )}\r\n </div>\r\n <div className=\"flex items-center gap-4 text-sm text-[var(--text-secondary)]\">\r\n <div className=\"flex items-center gap-1\">\r\n <Users className=\"w-4 h-4\" />\r\n <span>{role.users.length} {t('roleDetail.usersCount')}</span>\r\n </div>\r\n <div className=\"flex items-center gap-1\">\r\n <UsersRound className=\"w-4 h-4\" />\r\n <span>{role.groups?.length || 0} {t('roleDetail.groupsCount')}</span>\r\n </div>\r\n <div className=\"flex items-center gap-1\">\r\n <Shield className=\"w-4 h-4\" />\r\n <span>{role.permissions.length} {t('roles.permissions')}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Alerts */}\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)] text-[var(--error-text)] flex items-center gap-2\">\r\n <AlertTriangle className=\"w-5 h-5 flex-shrink-0\" />\r\n {error}\r\n </div>\r\n )}\r\n {success && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)] text-[var(--success-text)] flex items-center gap-2\">\r\n <CheckCircle className=\"w-5 h-5 flex-shrink-0\" />\r\n {success}\r\n </div>\r\n )}\r\n\r\n\r\n {/* Tabs */}\r\n <div className=\"flex gap-1 p-1 bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n {tabs.map(tab => (\r\n <button\r\n key={tab.id}\r\n onClick={() => setActiveTab(tab.id)}\r\n className={`flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium transition-colors ${\r\n activeTab === tab.id\r\n ? 'bg-[var(--color-accent-600)] text-white'\r\n : 'text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n {tab.icon}\r\n <span className=\"hidden sm:inline\">{tab.label}</span>\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* Tab Content */}\r\n <div className=\"bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-4 sm:p-6\">\r\n {/* Info Tab */}\r\n {activeTab === 'info' && (\r\n <form onSubmit={handleSaveInfo} className=\"space-y-6 max-w-2xl\">\r\n {/* ID (read-only) */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.info.id')}\r\n </label>\r\n <div className=\"px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-tertiary)] text-[var(--text-secondary)] font-mono text-sm\">\r\n {role.id}\r\n </div>\r\n </div>\r\n\r\n {/* Name */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roles.form.name')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n required\r\n value={formData.name}\r\n onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n\r\n {/* Short Name */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.info.shortName')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n required\r\n value={formData.shortName}\r\n onChange={e => setFormData(prev => ({ ...prev, shortName: e.target.value }))}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <p className=\"mt-1 text-xs text-[var(--text-tertiary)]\">\r\n {t('roleDetail.info.shortNameHelp')}\r\n </p>\r\n </div>\r\n\r\n {/* Category */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.info.category')} *\r\n </label>\r\n <select\r\n value={formData.category}\r\n onChange={e => setFormData(prev => ({ ...prev, category: e.target.value as RoleCategory }))}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n {ROLE_CATEGORIES.map(cat => (\r\n <option key={cat} value={cat}>\r\n {t(`roleDetail.categories.${cat.toLowerCase()}`)}\r\n </option>\r\n ))}\r\n </select>\r\n <p className=\"mt-1 text-xs text-[var(--text-tertiary)]\">\r\n {t('roleDetail.info.categoryHelp')}\r\n </p>\r\n </div>\r\n\r\n {/* Parent Role */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.info.parentRole')}\r\n </label>\r\n <select\r\n value={formData.parentRoleId || ''}\r\n onChange={e => setFormData(prev => ({ ...prev, parentRoleId: e.target.value || null }))}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value=\"\">{t('roleDetail.info.noParent')}</option>\r\n {availableRoles.map(r => (\r\n <option key={r.id} value={r.id}>\r\n {r.name} ({t(`roleDetail.categories.${r.category.toLowerCase()}`)})\r\n </option>\r\n ))}\r\n </select>\r\n <p className=\"mt-1 text-xs text-[var(--text-tertiary)]\">\r\n {t('roleDetail.info.parentRoleHelp')}\r\n </p>\r\n </div>\r\n\r\n {/* Description */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roles.form.description')}\r\n </label>\r\n <textarea\r\n value={formData.description}\r\n onChange={e => setFormData(prev => ({ ...prev, description: e.target.value }))}\r\n rows={3}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] resize-none\"\r\n />\r\n </div>\r\n\r\n {/* System Role Badge */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.info.systemRole')}\r\n </label>\r\n <div className=\"flex items-center gap-2\">\r\n {role.isSystem ? (\r\n <span className=\"flex items-center gap-1.5 px-3 py-1.5 rounded-[var(--radius-badge)] text-sm bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)]\">\r\n <Lock className=\"w-4 h-4\" />\r\n {t('roleDetail.info.isSystemRole')}\r\n </span>\r\n ) : (\r\n <span className=\"flex items-center gap-1.5 px-3 py-1.5 rounded-[var(--radius-badge)] text-sm bg-[var(--bg-tertiary)] text-[var(--text-secondary)]\">\r\n {t('roleDetail.info.isCustomRole')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Metadata */}\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4 pt-4 border-t border-[var(--border-color)]\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.createdAt')}\r\n </label>\r\n <div className=\"text-sm text-[var(--text-primary)]\">\r\n {new Date(role.createdAt).toLocaleString()}\r\n </div>\r\n </div>\r\n {role.updatedAt && (\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.updatedAt')}\r\n </label>\r\n <div className=\"text-sm text-[var(--text-primary)]\">\r\n {new Date(role.updatedAt).toLocaleString()}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex justify-end pt-4\">\r\n <button\r\n type=\"submit\"\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white font-medium transition-colors disabled:opacity-50\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('common.save')}\r\n </button>\r\n </div>\r\n </form>\r\n )}\r\n\r\n {/* Permissions Tab - Matrix View */}\r\n {activeTab === 'permissions' && roleId && (\r\n <RolePermissionMatrix roleId={roleId} />\r\n )}\r\n\r\n {/* Groups Tab */}\r\n {activeTab === 'groups' && (\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('roleDetail.groups.title')} ({role.groups?.length || 0})\r\n </h3>\r\n <button\r\n onClick={openAddGroup}\r\n className=\"flex items-center gap-2 px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white text-sm font-medium transition-colors\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('roleDetail.groups.add')}\r\n </button>\r\n </div>\r\n\r\n {(!role.groups || role.groups.length === 0) ? (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('roleDetail.groups.noGroups')}\r\n </div>\r\n ) : (\r\n <div className=\"grid gap-3\">\r\n {role.groups.map(group => (\r\n <div\r\n key={group.id}\r\n className=\"flex items-center gap-4 p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\"\r\n >\r\n <Link\r\n to={`/administration/users/groups/${group.id}`}\r\n className=\"flex items-center gap-4 flex-1 min-w-0 hover:opacity-80 transition-opacity\"\r\n >\r\n <div className=\"w-10 h-10 rounded-full bg-[var(--color-accent-100)] flex items-center justify-center\">\r\n <UsersRound className=\"w-5 h-5 text-[var(--color-accent-700)]\" />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"font-medium text-[var(--text-primary)] truncate\">{group.name}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)] truncate\">\r\n {group.membersCount} {t('roleDetail.groups.members')}\r\n {group.description && ` · ${group.description}`}\r\n </div>\r\n </div>\r\n </Link>\r\n <button\r\n onClick={() => handleRemoveGroup(group.id)}\r\n disabled={removingGroupId === group.id}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] text-[var(--text-secondary)] hover:text-[var(--error-text)] transition-colors disabled:opacity-50\"\r\n title={t('roleDetail.groups.remove')}\r\n >\r\n {removingGroupId === group.id ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Trash2 className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Add Group Modal */}\r\n {addingGroup && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] w-full max-w-md p-6 m-4 max-h-[90vh] overflow-y-auto\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('roleDetail.groups.addTitle')}\r\n </h2>\r\n <button\r\n onClick={() => setAddingGroup(false)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n value={groupSearchTerm}\r\n onChange={(e) => setGroupSearchTerm(e.target.value)}\r\n className=\"w-full pl-10 pr-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n placeholder={t('roleDetail.groups.searchPlaceholder')}\r\n />\r\n </div>\r\n </div>\r\n\r\n {loadingGroups ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n ) : (\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto\">\r\n {availableGroups\r\n .filter(g =>\r\n !role.groups?.some(rg => rg.id === g.id) &&\r\n (groupSearchTerm === '' ||\r\n g.name.toLowerCase().includes(groupSearchTerm.toLowerCase()) ||\r\n (g.description || '').toLowerCase().includes(groupSearchTerm.toLowerCase()))\r\n )\r\n .map(group => (\r\n <label\r\n key={group.id}\r\n className={`flex items-center gap-3 cursor-pointer p-3 rounded-[var(--radius-button)] transition-colors ${\r\n selectedGroupId === group.id\r\n ? 'bg-[var(--color-accent-500)]/10 border border-[var(--color-accent-500)]'\r\n : 'hover:bg-[var(--bg-hover)] border border-transparent'\r\n }`}\r\n htmlFor={`group-${group.id}`}\r\n >\r\n <input\r\n id={`group-${group.id}`}\r\n type=\"radio\"\r\n name=\"selectedGroup\"\r\n checked={selectedGroupId === group.id}\r\n onChange={() => setSelectedGroupId(group.id)}\r\n className=\"w-4 h-4 text-[var(--color-accent-600)] focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <div className=\"flex-1 min-w-0\">\r\n <span className=\"text-[var(--text-primary)] font-medium\">{group.name}</span>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">\r\n {group.memberCount} {t('roleDetail.groups.members')}\r\n {group.description && ` · ${group.description}`}\r\n </p>\r\n </div>\r\n </label>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex justify-end gap-3 mt-6\">\r\n <button\r\n onClick={() => setAddingGroup(false)}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] text-[var(--text-primary)] font-medium transition-colors\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n onClick={handleAssignGroup}\r\n disabled={!selectedGroupId || assigningGroup}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white font-medium transition-colors disabled:opacity-50\"\r\n >\r\n {assigningGroup && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {t('common.add')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Users Tab */}\r\n {activeTab === 'users' && (\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('roleDetail.users.title')} ({role.users.length})\r\n </h3>\r\n <button\r\n onClick={openAddUser}\r\n className=\"flex items-center gap-2 px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white text-sm font-medium transition-colors\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('roleDetail.users.add')}\r\n </button>\r\n </div>\r\n\r\n {role.users.length === 0 ? (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('roleDetail.users.noUsers')}\r\n </div>\r\n ) : (\r\n <div className=\"grid gap-3\">\r\n {role.users.map(user => (\r\n <div\r\n key={user.id}\r\n className=\"flex items-center gap-4 p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\"\r\n >\r\n <Link\r\n to={`/administration/users/${user.id}`}\r\n className=\"flex items-center gap-4 flex-1 min-w-0 hover:opacity-80 transition-opacity\"\r\n >\r\n <div className=\"w-10 h-10 rounded-full bg-[var(--color-accent-100)] flex items-center justify-center\">\r\n <span className=\"text-sm font-medium text-[var(--color-accent-700)]\">\r\n {user.fullName.split(' ').map(n => n.at(0)).join('').toUpperCase().slice(0, 2)}\r\n </span>\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"font-medium text-[var(--text-primary)] truncate\">{user.fullName}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)] truncate\">{user.email}</div>\r\n </div>\r\n </Link>\r\n <button\r\n onClick={() => handleRemoveUser(user.id)}\r\n disabled={removingUserId === user.id}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] text-[var(--text-secondary)] hover:text-[var(--error-text)] transition-colors disabled:opacity-50\"\r\n title={t('roleDetail.users.remove')}\r\n >\r\n {removingUserId === user.id ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Trash2 className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Add User Modal */}\r\n {addingUser && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] w-full max-w-md p-6 m-4 max-h-[90vh] overflow-y-auto\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('roleDetail.users.addTitle')}\r\n </h2>\r\n <button\r\n onClick={() => setAddingUser(false)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n value={userSearchTerm}\r\n onChange={(e) => setUserSearchTerm(e.target.value)}\r\n className=\"w-full pl-10 pr-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n placeholder={t('roleDetail.users.searchPlaceholder')}\r\n />\r\n </div>\r\n </div>\r\n\r\n {loadingUsers ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n ) : (\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto\">\r\n {availableUsers\r\n .filter(u =>\r\n !role.users.some(ru => ru.id === u.id) &&\r\n (userSearchTerm === '' ||\r\n u.fullName.toLowerCase().includes(userSearchTerm.toLowerCase()) ||\r\n u.email.toLowerCase().includes(userSearchTerm.toLowerCase()))\r\n )\r\n .map(user => (\r\n <label\r\n key={user.id}\r\n className={`flex items-center gap-3 cursor-pointer p-3 rounded-[var(--radius-button)] transition-colors ${\r\n selectedUserId === user.id\r\n ? 'bg-[var(--color-accent-500)]/10 border border-[var(--color-accent-500)]'\r\n : 'hover:bg-[var(--bg-hover)] border border-transparent'\r\n }`}\r\n htmlFor={`user-${user.id}`}\r\n >\r\n <input\r\n id={`user-${user.id}`}\r\n type=\"radio\"\r\n name=\"selectedUser\"\r\n checked={selectedUserId === user.id}\r\n onChange={() => setSelectedUserId(user.id)}\r\n className=\"w-4 h-4 text-[var(--color-accent-600)] focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <div className=\"flex-1 min-w-0\">\r\n <span className=\"text-[var(--text-primary)] font-medium\">{user.fullName}</span>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{user.email}</p>\r\n </div>\r\n </label>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex justify-end gap-3 mt-6\">\r\n <button\r\n onClick={() => setAddingUser(false)}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] text-[var(--text-primary)] font-medium transition-colors\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n onClick={handleAssignUser}\r\n disabled={!selectedUserId || assigningUser}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white font-medium transition-colors disabled:opacity-50\"\r\n >\r\n {assigningUser && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {t('common.add')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Translations Tab */}\r\n {activeTab === 'translations' && (\r\n <div className=\"space-y-6\">\r\n <div className=\"flex items-center justify-between\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('roleDetail.translations.title')} ({translations.length})\r\n </h3>\r\n {availableLanguages.length > 0 && (\r\n <button\r\n onClick={() => setShowAddTranslation(true)}\r\n className=\"flex items-center gap-2 px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white text-sm font-medium transition-colors\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('roleDetail.translations.add')}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* Add new translation form */}\r\n {showAddTranslation && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--color-accent-500)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h4 className=\"font-medium text-[var(--text-primary)]\">\r\n {t('roleDetail.translations.addNew')}\r\n </h4>\r\n <button\r\n onClick={cancelEditTranslation}\r\n className=\"p-1 rounded hover:bg-[var(--bg-hover)]\"\r\n >\r\n <X className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n </button>\r\n </div>\r\n <div className=\"grid gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.language')}\r\n </label>\r\n <select\r\n value={newTranslationLang}\r\n onChange={e => setNewTranslationLang(e.target.value)}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)]\"\r\n >\r\n <option value=\"\">{t('roleDetail.translations.selectLanguage')}</option>\r\n {availableLanguages.map(lang => (\r\n <option key={lang.code} value={lang.code}>{lang.label}</option>\r\n ))}\r\n </select>\r\n </div>\r\n {newTranslationLang && (\r\n <>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.name')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={translationForm.name}\r\n onChange={e => setTranslationForm(prev => ({ ...prev, name: e.target.value }))}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.shortName')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={translationForm.shortName}\r\n onChange={e => setTranslationForm(prev => ({ ...prev, shortName: e.target.value }))}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.description')}\r\n </label>\r\n <textarea\r\n value={translationForm.description || ''}\r\n onChange={e => setTranslationForm(prev => ({ ...prev, description: e.target.value }))}\r\n rows={2}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] resize-none\"\r\n />\r\n </div>\r\n <div className=\"flex justify-end gap-2\">\r\n <button\r\n onClick={cancelEditTranslation}\r\n className=\"px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] text-[var(--text-primary)] text-sm font-medium\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n onClick={() => handleSaveTranslation(newTranslationLang)}\r\n disabled={savingTranslation || !translationForm.name || !translationForm.shortName}\r\n className=\"flex items-center gap-2 px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white text-sm font-medium disabled:opacity-50\"\r\n >\r\n {savingTranslation && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {t('common.save')}\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {loadingTranslations && (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n )}\r\n {!loadingTranslations && translations.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('roleDetail.translations.noTranslations')}\r\n </div>\r\n )}\r\n {!loadingTranslations && translations.length > 0 && (\r\n <div className=\"space-y-3\">\r\n {translations.map(trans => {\r\n const langInfo = SUPPORTED_LANGUAGES.find(l => l.code === trans.languageCode);\r\n const isEditing = editingTranslation === trans.languageCode;\r\n\r\n return (\r\n <div\r\n key={trans.languageCode}\r\n className={`p-4 rounded-[var(--radius-card)] border ${\r\n isEditing\r\n ? 'bg-[var(--bg-primary)] border-[var(--color-accent-500)]'\r\n : 'bg-[var(--bg-primary)] border-[var(--border-color)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center justify-between mb-2\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"px-2 py-0.5 text-xs font-medium rounded bg-[var(--bg-tertiary)] text-[var(--text-secondary)] uppercase\">\r\n {trans.languageCode}\r\n </span>\r\n <span className=\"text-sm text-[var(--text-secondary)]\">\r\n {langInfo?.label || trans.languageCode}\r\n </span>\r\n </div>\r\n {!isEditing && (\r\n <div className=\"flex items-center gap-1\">\r\n <button\r\n onClick={() => startEditTranslation(trans)}\r\n className=\"p-1.5 rounded hover:bg-[var(--bg-hover)] text-[var(--text-secondary)] hover:text-[var(--color-accent-600)]\"\r\n title={t('common.edit')}\r\n >\r\n <Edit2 className=\"w-4 h-4\" />\r\n </button>\r\n <button\r\n onClick={() => handleDeleteTranslation(trans.languageCode)}\r\n className=\"p-1.5 rounded hover:bg-[var(--bg-hover)] text-[var(--text-secondary)] hover:text-[var(--error-text)]\"\r\n title={t('common.delete')}\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {isEditing ? (\r\n <div className=\"grid gap-3 mt-3\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.name')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={translationForm.name}\r\n onChange={e => setTranslationForm(prev => ({ ...prev, name: e.target.value }))}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.shortName')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={translationForm.shortName}\r\n onChange={e => setTranslationForm(prev => ({ ...prev, shortName: e.target.value }))}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.description')}\r\n </label>\r\n <textarea\r\n value={translationForm.description || ''}\r\n onChange={e => setTranslationForm(prev => ({ ...prev, description: e.target.value }))}\r\n rows={2}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] resize-none\"\r\n />\r\n </div>\r\n <div className=\"flex justify-end gap-2\">\r\n <button\r\n onClick={cancelEditTranslation}\r\n className=\"px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] text-[var(--text-primary)] text-sm font-medium\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n onClick={() => handleSaveTranslation(trans.languageCode)}\r\n disabled={savingTranslation || !translationForm.name || !translationForm.shortName}\r\n className=\"flex items-center gap-2 px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white text-sm font-medium disabled:opacity-50\"\r\n >\r\n {savingTranslation && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {t('common.save')}\r\n </button>\r\n </div>\r\n </div>\r\n ) : (\r\n <div className=\"grid gap-1\">\r\n <div className=\"font-medium text-[var(--text-primary)]\">{trans.name}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('roleDetail.translations.shortName')}: {trans.shortName}\r\n </div>\r\n {trans.description && (\r\n <div className=\"text-sm text-[var(--text-tertiary)] mt-1\">{trans.description}</div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"names":["ACTION_ICONS","jsx","Shield","Eye","Plus","Edit","Trash2","UserPlus","Play","ACTION_COLORS","applyApplicationModuleFilterHelper","grouped","applicationFilter","moduleFilter","app","m","applyStatusFilterHelper","statusFilters","getModuleStatus","status","SectionResourceRows","section","resources","moduleIndex","sectionIndex","collapsedSections","renderResourceRow","hasResources","isSectionCollapsed","jsxs","React","resource","resourceIndex","RolePermissionMatrix","roleId","t","useTranslation","user","useAuth","collapsedApps","toggleApp","useCollapsibleState","collapsedModules","setCollapsedModules","useState","setCollapsedSections","setStatusFilters","openPopover","setOpenPopover","setApplicationFilter","setModuleFilter","canEditSystemRoles","useMemo","hasFullAccess","loading","error","roles","filteredResources","hasChanges","saving","saveSuccess","saveError","togglePermission","saveChanges","resetChanges","getPermissionInheritance","usePermissionMatrix","role","r","isRoleEditable","toggleStatusFilter","prev","next","toggleModule","moduleId","toggleSection","sectionId","filterOptions","applications","modules","appKey","a","b","handleTogglePermission","useCallback","permissionId","isPermissionGrantedFn","info","moduleWithSections","calculateModuleWithSectionsStatus","getResourceStatus","calculatePermissionStatus","getGrantedPermissions","p","applyApplicationModuleFilter","applyStatusFilter","groupedResources","groupByApplicationWithSections","totalModuleCount","sum","handleToggleCollapse","resourceId","level","handleCellClick","Loader2","AlertCircle","getRoleResourceIcon","Database","FileText","Box","getRoleResourceLabelClass","getRolePaddingClass","renderToggleButton","hasChildren","isCollapsed","ChevronRight","ChevronDown","renderPermissionBadges","grantedPermissions","action","actionColor","icon","rowIndex","grantedCount","isPopoverOpen","buttonRef","createRef","cellBg","getPermissionCellBackground","paddingLeft","rowBgClass","PermissionStatusIndicator","PermissionPopover","_","permId","Check","X","Save","e","mod","Star","Ban","appGroup","isAppCollapsed","FolderOpen","module","sections","hasSections","isModuleCollapsed","sectionWithResources","SUPPORTED_LANGUAGES","RoleDetailPage","useParams","navigate","useNavigate","setRole","setLoading","setSaving","activeTab","setActiveTab","setError","success","setSuccess","formData","setFormData","availableRoles","setAvailableRoles","ROLE_CATEGORIES","translations","setTranslations","loadingTranslations","setLoadingTranslations","editingTranslation","setEditingTranslation","translationForm","setTranslationForm","savingTranslation","setSavingTranslation","showAddTranslation","setShowAddTranslation","newTranslationLang","setNewTranslationLang","addingUser","setAddingUser","availableUsers","setAvailableUsers","loadingUsers","setLoadingUsers","userSearchTerm","setUserSearchTerm","selectedUserId","setSelectedUserId","assigningUser","setAssigningUser","removingUserId","setRemovingUserId","addingGroup","setAddingGroup","availableGroups","setAvailableGroups","loadingGroups","setLoadingGroups","groupSearchTerm","setGroupSearchTerm","selectedGroupId","setSelectedGroupId","assigningGroup","setAssigningGroup","removingGroupId","setRemovingGroupId","loadRole","roleData","rolesData","adminApi","err","useEffect","handleSaveInfo","updateData","loadTranslations","data","startEditTranslation","trans","cancelEditTranslation","handleSaveTranslation","languageCode","handleDeleteTranslation","availableLanguages","lang","openAddUser","handleAssignUser","handleRemoveUser","userId","openAddGroup","groupsApi","handleAssignGroup","handleRemoveGroup","groupId","tabs","Settings","Users","UsersRound","Languages","Breadcrumb","ArrowLeft","Lock","AlertTriangle","CheckCircle","tab","cat","group","Link","Search","g","rg","n","u","ru","Fragment","langInfo","l","isEditing","Edit2"],"mappings":"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"}
1
+ {"version":3,"file":"RoleDetailPage-JTm5lD1_.js","sources":["../../src/components/platform/administration/permissions/RolePermissionMatrix.tsx","../../src/pages/platform/administration/permissions/RoleDetailPage.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\r\nimport React, { useState, useMemo, useCallback, createRef } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, AlertCircle, ChevronDown, ChevronRight, FolderOpen, Box, FileText, Database, Check, Star, Eye, Ban, Save, X, Plus, Edit, Trash2, UserPlus, Play, Shield } from 'lucide-react';\r\nimport { usePermissionMatrix } from '@/hooks/usePermissionMatrix';\r\nimport { useCollapsibleState } from '@/hooks/useCollapsibleState';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { hasFullAccess } from '@/utils/permissions';\r\nimport { groupByApplicationWithSections, calculatePermissionStatus, calculateModuleWithSectionsStatus, getPermissionCellBackground } from '@/utils/permissionUtils';\r\nimport { PermissionStatusIndicator } from './PermissionStatusIndicator';\r\nimport { PermissionPopover } from '../PermissionPopover';\r\nimport type { ResourceNode, PermissionStatus, ModuleWithSections } from './types';\r\n\r\ninterface RolePermissionMatrixProps {\r\n readonly roleId: string;\r\n}\r\n\r\n// Action icons and colors (same as PermissionCellPopover)\r\nconst ACTION_ICONS: Record<string, React.ReactNode> = {\r\n '*': <Shield className=\"h-3 w-3\" />,\r\n read: <Eye className=\"h-3 w-3\" />,\r\n create: <Plus className=\"h-3 w-3\" />,\r\n update: <Edit className=\"h-3 w-3\" />,\r\n delete: <Trash2 className=\"h-3 w-3\" />,\r\n assign: <UserPlus className=\"h-3 w-3\" />,\r\n execute: <Play className=\"h-3 w-3\" />,\r\n};\r\n\r\nconst ACTION_COLORS: Record<string, string> = {\r\n '*': 'bg-[var(--accent-bg)] text-[var(--accent-text)] border-[var(--accent-border)]',\r\n read: 'bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]',\r\n create: 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]',\r\n update: 'bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]',\r\n delete: 'bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]',\r\n assign: 'bg-[var(--accent-bg)] text-[var(--accent-text)] border-[var(--accent-border)]',\r\n execute: 'bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]',\r\n};\r\n\r\n// Pure function to apply application/module filter\r\nfunction applyApplicationModuleFilterHelper(\r\n grouped: ReturnType<typeof groupByApplicationWithSections>,\r\n applicationFilter: string,\r\n moduleFilter: string\r\n) {\r\n return grouped\r\n .filter(app => applicationFilter === 'all' || app.application === applicationFilter)\r\n .map(app => ({\r\n ...app,\r\n modules: app.modules.filter(m => moduleFilter === 'all' || m.module.moduleLabel === moduleFilter)\r\n }))\r\n .filter(app => app.modules.length > 0);\r\n}\r\n\r\n// Pure function to apply status filter\r\nfunction applyStatusFilterHelper(\r\n grouped: ReturnType<typeof groupByApplicationWithSections>,\r\n statusFilters: Set<PermissionStatus>,\r\n getModuleStatus: (m: ModuleWithSections) => { status: PermissionStatus; grantedCount: number; totalCount: number }\r\n) {\r\n return grouped.map(app => ({\r\n ...app,\r\n modules: app.modules.filter(m => {\r\n const { status } = getModuleStatus(m);\r\n return statusFilters.has(status);\r\n })\r\n })).filter(app => app.modules.length > 0);\r\n}\r\n\r\n// Sub-component for rendering section and resource rows\r\ninterface SectionResourceRowsProps {\r\n readonly section: ResourceNode;\r\n readonly resources: ResourceNode[];\r\n readonly moduleIndex: number;\r\n readonly sectionIndex: number;\r\n readonly collapsedSections: Set<string>;\r\n readonly renderResourceRow: (resource: ResourceNode, rowIndex: number, level: 'module' | 'section' | 'resource', hasChildren: boolean, isCollapsed: boolean) => React.ReactNode;\r\n}\r\n\r\nfunction SectionResourceRows({\r\n section,\r\n resources,\r\n moduleIndex,\r\n sectionIndex,\r\n collapsedSections,\r\n renderResourceRow,\r\n}: SectionResourceRowsProps) {\r\n const hasResources = resources.length > 0;\r\n const isSectionCollapsed = collapsedSections.has(section.id);\r\n\r\n return (\r\n <React.Fragment key={section.id}>\r\n {/* Section Row */}\r\n {renderResourceRow(section, moduleIndex + sectionIndex + 1, 'section', hasResources, isSectionCollapsed)}\r\n\r\n {/* Resource Rows (if section has resources and is not collapsed) */}\r\n {hasResources && !isSectionCollapsed && resources.map((resource, resourceIndex) =>\r\n renderResourceRow(resource, moduleIndex + sectionIndex + resourceIndex + 2, 'resource', false, false)\r\n )}\r\n </React.Fragment>\r\n );\r\n}\r\n\r\nexport function RolePermissionMatrix({ roleId }: RolePermissionMatrixProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { user } = useAuth();\r\n\r\n const { collapsedApps, toggleApp } = useCollapsibleState();\r\n const [collapsedModules, setCollapsedModules] = useState<Set<string>>(new Set());\r\n const [collapsedSections, setCollapsedSections] = useState<Set<string>>(new Set());\r\n const [statusFilters, setStatusFilters] = useState<Set<PermissionStatus>>(new Set());\r\n const [openPopover, setOpenPopover] = useState<string | null>(null);\r\n\r\n // Filter states\r\n const [applicationFilter, setApplicationFilter] = useState<string>('all');\r\n const [moduleFilter, setModuleFilter] = useState<string>('all');\r\n\r\n // Super Admin can edit system roles\r\n const canEditSystemRoles = useMemo(() => {\r\n if (!user) return false;\r\n return hasFullAccess(user.permissions);\r\n }, [user]);\r\n\r\n const {\r\n loading,\r\n error,\r\n roles,\r\n filteredResources,\r\n hasChanges,\r\n saving,\r\n saveSuccess,\r\n saveError,\r\n togglePermission,\r\n saveChanges,\r\n resetChanges,\r\n getPermissionInheritance,\r\n } = usePermissionMatrix({ canEditSystemRoles });\r\n\r\n // Find the specific role\r\n const role = useMemo(() => {\r\n return roles.find(r => r.id === roleId);\r\n }, [roles, roleId]);\r\n\r\n // Check if role is editable\r\n const isRoleEditable = useMemo(() => {\r\n if (!role) return false;\r\n if (role.isSystem && !canEditSystemRoles) return false;\r\n return true;\r\n }, [role, canEditSystemRoles]);\r\n\r\n const toggleStatusFilter = (status: PermissionStatus) => {\r\n setStatusFilters(prev => {\r\n const next = new Set(prev);\r\n if (next.has(status)) {\r\n next.delete(status);\r\n } else {\r\n next.add(status);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n const toggleModule = (moduleId: string) => {\r\n setCollapsedModules(prev => {\r\n const next = new Set(prev);\r\n if (next.has(moduleId)) {\r\n next.delete(moduleId);\r\n } else {\r\n next.add(moduleId);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n const toggleSection = (sectionId: string) => {\r\n setCollapsedSections(prev => {\r\n const next = new Set(prev);\r\n if (next.has(sectionId)) {\r\n next.delete(sectionId);\r\n } else {\r\n next.add(sectionId);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n // Build filter options from resources\r\n const filterOptions = useMemo(() => {\r\n const applications: { app: string; label: string }[] = [];\r\n const modules: { app: string; module: string; label: string }[] = [];\r\n\r\n filteredResources.forEach(resource => {\r\n if (resource.level === 'module') {\r\n const appKey = resource.applicationLabel;\r\n if (!applications.find(a => a.app === appKey)) {\r\n applications.push({\r\n app: resource.applicationLabel,\r\n label: resource.applicationLabel\r\n });\r\n }\r\n\r\n modules.push({\r\n app: resource.applicationLabel,\r\n module: resource.moduleLabel,\r\n label: resource.moduleLabel\r\n });\r\n }\r\n });\r\n\r\n return {\r\n applications: applications.sort((a, b) => a.label.localeCompare(b.label)),\r\n modules: modules.sort((a, b) => a.label.localeCompare(b.label))\r\n };\r\n }, [filteredResources]);\r\n\r\n // Handle permission toggle\r\n const handleTogglePermission = useCallback((permissionId: string) => {\r\n if (!role || !isRoleEditable) return;\r\n togglePermission(role.id, permissionId);\r\n }, [role, isRoleEditable, togglePermission]);\r\n\r\n // Check if a permission is granted\r\n const isPermissionGrantedFn = useCallback((permissionId: string): boolean => {\r\n if (!role) return false;\r\n const info = getPermissionInheritance(role.id, permissionId);\r\n return info.isDirect || info.isInherited;\r\n }, [role, getPermissionInheritance]);\r\n\r\n // Calculate permission status for this role on a module (including sections)\r\n const getModuleStatus = useCallback((moduleWithSections: ModuleWithSections): { status: PermissionStatus; grantedCount: number; totalCount: number } => {\r\n return calculateModuleWithSectionsStatus(\r\n moduleWithSections.module,\r\n moduleWithSections.sections,\r\n isPermissionGrantedFn\r\n );\r\n }, [isPermissionGrantedFn]);\r\n\r\n // Calculate permission status for a single resource\r\n const getResourceStatus = useCallback((resource: ResourceNode): { status: PermissionStatus; grantedCount: number } => {\r\n return calculatePermissionStatus(resource, isPermissionGrantedFn);\r\n }, [isPermissionGrantedFn]);\r\n\r\n // Get granted permissions for a resource\r\n const getGrantedPermissions = useCallback((resource: ResourceNode): string[] => {\r\n if (!role) return [];\r\n\r\n return resource.permissions\r\n .filter(p => {\r\n const info = getPermissionInheritance(role.id, p.id);\r\n return info.isDirect || info.isInherited;\r\n })\r\n .map(p => p.action);\r\n }, [role, getPermissionInheritance]);\r\n\r\n\r\n const applyApplicationModuleFilter = useCallback((grouped: ReturnType<typeof groupByApplicationWithSections>) => {\r\n return applyApplicationModuleFilterHelper(grouped, applicationFilter, moduleFilter);\r\n }, [applicationFilter, moduleFilter]);\r\n\r\n const applyStatusFilter = useCallback((grouped: ReturnType<typeof groupByApplicationWithSections>) => {\r\n if (statusFilters.size === 0) return grouped;\r\n return applyStatusFilterHelper(grouped, statusFilters, getModuleStatus);\r\n }, [statusFilters, getModuleStatus]);\r\n\r\n const groupedResources = useMemo(() => {\r\n let grouped = groupByApplicationWithSections(filteredResources);\r\n grouped = applyApplicationModuleFilter(grouped);\r\n grouped = applyStatusFilter(grouped);\r\n return grouped;\r\n }, [filteredResources, applyApplicationModuleFilter, applyStatusFilter]);\r\n\r\n // Get total module count for stats\r\n const totalModuleCount = useMemo(() => {\r\n return groupedResources.reduce((sum, app) =>\r\n sum + app.modules.length, 0);\r\n }, [groupedResources]);\r\n\r\n const handleToggleCollapse = useCallback((resourceId: string, level: 'module' | 'section' | 'resource') => {\r\n if (level === 'module') {\r\n toggleModule(resourceId);\r\n } else if (level === 'section') {\r\n toggleSection(resourceId);\r\n }\r\n }, [toggleModule, toggleSection]);\r\n\r\n const handleCellClick = (resourceId: string) => {\r\n if (openPopover === resourceId) {\r\n setOpenPopover(null);\r\n } else {\r\n setOpenPopover(resourceId);\r\n }\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <div className=\"text-center\">\r\n <Loader2 className=\"h-8 w-8 animate-spin text-[var(--color-accent-500)] mx-auto mb-4\" />\r\n <p className=\"text-[var(--text-secondary)]\">{t('userPermissions.loading')}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2\">\r\n <AlertCircle className=\"h-5 w-5 text-[var(--error-text)]\" />\r\n <p className=\"text-[var(--error-text)]\">{error}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!role) {\r\n return (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('roleDetail.notFound')}\r\n </div>\r\n );\r\n }\r\n\r\n const getRoleResourceIcon = (level: 'module' | 'section' | 'resource') => {\r\n if (level === 'resource') return <Database className=\"h-3.5 w-3.5 text-[var(--text-muted)]\" />;\r\n if (level === 'section') return <FileText className=\"h-3.5 w-3.5 text-[var(--text-muted)]\" />;\r\n return <Box className=\"h-3.5 w-3.5 text-[var(--text-secondary)]\" />;\r\n };\r\n\r\n const getRoleResourceLabelClass = (level: 'module' | 'section' | 'resource'): string => {\r\n if (level === 'resource') return 'text-[var(--text-muted)] italic';\r\n if (level === 'section') return 'text-[var(--text-secondary)]';\r\n return 'font-medium text-[var(--text-primary)]';\r\n };\r\n\r\n const getRolePaddingClass = (level: 'module' | 'section' | 'resource'): string => {\r\n if (level === 'resource') return 'pl-28';\r\n if (level === 'section') return 'pl-22';\r\n return 'pl-16';\r\n };\r\n\r\n const renderToggleButton = (hasChildren: boolean, resourceId: string, level: 'module' | 'section' | 'resource', isCollapsed: boolean) => {\r\n if (!hasChildren) return null;\r\n return (\r\n <button\r\n onClick={() => handleToggleCollapse(resourceId, level)}\r\n className=\"p-0.5 hover:bg-[var(--bg-hover)] rounded\"\r\n >\r\n {isCollapsed ? (\r\n <ChevronRight className=\"h-3 w-3 text-[var(--text-muted)]\" />\r\n ) : (\r\n <ChevronDown className=\"h-3 w-3 text-[var(--text-muted)]\" />\r\n )}\r\n </button>\r\n );\r\n };\r\n\r\n const renderPermissionBadges = (grantedPermissions: string[]) => {\r\n if (grantedPermissions.length === 0) {\r\n return (\r\n <span className=\"text-xs text-[var(--text-muted)] italic\">\r\n {t('assignments.noPermissions')}\r\n </span>\r\n );\r\n }\r\n return grantedPermissions.map((action) => {\r\n const actionColor = ACTION_COLORS[action] || 'bg-[var(--bg-secondary)] text-[var(--text-secondary)] border-[var(--border-color)]';\r\n const icon = ACTION_ICONS[action] || <Eye className=\"h-3 w-3\" />;\r\n return (\r\n <div\r\n key={action}\r\n className={`inline-flex items-center gap-1.5 px-2 py-0.5 rounded-[var(--radius-badge)] border text-xs font-medium ${actionColor}`}\r\n title={t(`assignments.actions.${action === '*' ? 'all' : action}.description`)}\r\n >\r\n {icon}\r\n <span className=\"capitalize\">\r\n {t(`assignments.actions.${action === '*' ? 'all' : action}.label`)}\r\n </span>\r\n </div>\r\n );\r\n });\r\n };\r\n\r\n const renderResourceRow = (\r\n resource: ResourceNode,\r\n rowIndex: number,\r\n level: 'module' | 'section' | 'resource',\r\n hasChildren: boolean = false,\r\n isCollapsed: boolean = false\r\n ) => {\r\n const { status, grantedCount } = getResourceStatus(resource);\r\n const isPopoverOpen = openPopover === resource.id;\r\n const buttonRef = createRef<HTMLButtonElement>();\r\n const cellBg = getPermissionCellBackground(status);\r\n const grantedPermissions = getGrantedPermissions(resource);\r\n const paddingLeft = getRolePaddingClass(level);\r\n const rowBgClass = rowIndex % 2 === 0 ? 'item-light' : 'item-medium';\r\n\r\n return (\r\n <tr\r\n key={resource.id}\r\n className={`hover:bg-[var(--bg-hover)] ${rowBgClass}`}\r\n >\r\n <td\r\n className={`sticky left-0 z-10 ${rowBgClass} px-3 py-2 ${paddingLeft}`}\r\n style={{ width: '280px', minWidth: '280px', maxWidth: '280px' }}\r\n >\r\n <div className=\"flex items-center gap-2\">\r\n {renderToggleButton(hasChildren, resource.id, level, isCollapsed)}\r\n {getRoleResourceIcon(level)}\r\n <span className={`text-sm ${getRoleResourceLabelClass(level)}`}>\r\n {resource.moduleLabel}\r\n </span>\r\n <span className=\"text-xs text-[var(--text-muted)]\">\r\n ({resource.permissions.length})\r\n </span>\r\n </div>\r\n </td>\r\n\r\n <td\r\n className={`px-0 py-1 text-center relative ${cellBg}`}\r\n style={{ width: '60px', minWidth: '60px', maxWidth: '60px' }}\r\n >\r\n <button\r\n ref={buttonRef}\r\n type=\"button\"\r\n onClick={() => isRoleEditable && handleCellClick(resource.id)}\r\n disabled={!isRoleEditable}\r\n className={`w-full h-full min-h-[36px] flex items-center justify-center rounded transition-colors ${\r\n !isRoleEditable\r\n ? 'cursor-not-allowed opacity-50'\r\n : 'hover:opacity-80'\r\n } ${\r\n isPopoverOpen ? 'ring-2 ring-[var(--color-accent-500)]' : ''\r\n }`}\r\n title={\r\n !isRoleEditable\r\n ? `${role.name} - ${t('assignments.systemRoleReadOnly')}`\r\n : `${role.name} - ${resource.moduleLabel}: ${grantedCount}/${resource.permissions.length}`\r\n }\r\n >\r\n <PermissionStatusIndicator\r\n status={status}\r\n grantedCount={grantedCount}\r\n totalCount={resource.permissions.length}\r\n />\r\n </button>\r\n {isPopoverOpen && isRoleEditable && (\r\n <PermissionPopover\r\n mode=\"editable\"\r\n role={role}\r\n resource={resource}\r\n onTogglePermission={handleTogglePermission}\r\n onClose={() => setOpenPopover(null)}\r\n getPermissionInheritance={(_, permId) => getPermissionInheritance(role.id, permId)}\r\n />\r\n )}\r\n </td>\r\n\r\n <td className=\"px-3 py-2\">\r\n <div className=\"flex flex-wrap gap-1.5\">\r\n {renderPermissionBadges(grantedPermissions)}\r\n </div>\r\n </td>\r\n </tr>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Fixed height container for save banner to prevent layout shift */}\r\n <div className=\"min-h-[52px]\">\r\n {saveSuccess && (\r\n <div className=\"flex items-center justify-between p-3 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <div className=\"flex items-center gap-2\">\r\n <Check className=\"h-4 w-4 text-[var(--success-text)]\" />\r\n <p className=\"text-sm text-[var(--success-text)] font-medium\">\r\n {t('common.savedSuccessfully', 'Sauvegardé avec succès !')}\r\n </p>\r\n </div>\r\n </div>\r\n )}\r\n {!saveSuccess && saving && (\r\n <div className=\"flex items-center justify-between p-3 rounded-[var(--radius-card)] bg-[var(--info-bg)] border border-[var(--info-border)]\">\r\n <div className=\"flex items-center gap-2\">\r\n <Loader2 className=\"h-4 w-4 animate-spin text-[var(--info-text)]\" />\r\n <p className=\"text-sm text-[var(--info-text)] font-medium\">\r\n {t('common.saving', 'Sauvegarde en cours...')}\r\n </p>\r\n </div>\r\n </div>\r\n )}\r\n {!saveSuccess && !saving && hasChanges && (\r\n <div className=\"flex items-center justify-between p-3 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <p className=\"text-sm text-[var(--warning-text)]\">\r\n {t('assignments.unsavedChanges', 'You have unsaved changes')}\r\n </p>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={resetChanges}\r\n disabled={saving}\r\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-[var(--radius-button)] bg-[var(--bg-secondary)] border border-[var(--border-color)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] disabled:opacity-50\"\r\n >\r\n <X className=\"h-4 w-4\" />\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n onClick={saveChanges}\r\n disabled={saving}\r\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Save className=\"h-4 w-4\" />}\r\n {t('common.save')}\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n {!saveSuccess && !saving && !hasChanges && (\r\n <div className=\"h-[52px]\" />\r\n )}\r\n </div>\r\n\r\n {/* Save error */}\r\n {saveError && (\r\n <div className=\"p-3 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <div className=\"flex items-center gap-2\">\r\n <AlertCircle className=\"h-4 w-4 text-[var(--error-text)]\" />\r\n <p className=\"text-sm text-[var(--error-text)]\">{saveError}</p>\r\n </div>\r\n </div>\r\n )}\r\n\r\n\r\n {/* Filter Dropdowns */}\r\n <div className=\"flex flex-wrap items-center gap-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <label className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('userPermissions.filters.application')}:\r\n </label>\r\n <select\r\n value={applicationFilter}\r\n onChange={(e) => {\r\n setApplicationFilter(e.target.value);\r\n setModuleFilter('all');\r\n }}\r\n className=\"px-3 py-1.5 text-sm bg-[var(--bg-secondary)] border border-[var(--border-color)] rounded-[var(--radius-input)] text-[var(--text-primary)] focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value=\"all\">{t('userPermissions.filters.allApplications')}</option>\r\n {filterOptions.applications\r\n .map(app => (\r\n <option key={app.app} value={app.app}>{app.label}</option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n <div className=\"flex items-center gap-2\">\r\n <label className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('userPermissions.filters.module')}:\r\n </label>\r\n <select\r\n value={moduleFilter}\r\n onChange={(e) => setModuleFilter(e.target.value)}\r\n className=\"px-3 py-1.5 text-sm bg-[var(--bg-secondary)] border border-[var(--border-color)] rounded-[var(--radius-input)] text-[var(--text-primary)] focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value=\"all\">{t('userPermissions.filters.allModules')}</option>\r\n {filterOptions.modules\r\n .filter(mod =>\r\n (applicationFilter === 'all' || mod.app === applicationFilter)\r\n )\r\n .map(mod => (\r\n <option key={`${mod.app}:${mod.module}`} value={mod.module}>{mod.label}</option>\r\n ))}\r\n </select>\r\n </div>\r\n </div>\r\n\r\n {/* Status Filter Buttons - Using CSS variables for colors */}\r\n <div className=\"flex flex-wrap items-center gap-3\">\r\n <span className=\"text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('userPermissions.filterByStatus')}:\r\n </span>\r\n <div className=\"flex flex-wrap gap-2\">\r\n <button\r\n onClick={() => toggleStatusFilter('all')}\r\n className={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border transition-colors ${\r\n statusFilters.has('all')\r\n ? 'bg-[var(--success-bg)] border-[var(--success-border)] text-[var(--success-text)]'\r\n : 'bg-[var(--bg-tertiary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--success-border)]'\r\n }`}\r\n >\r\n <Check className={`h-3.5 w-3.5 ${statusFilters.has('all') ? '' : 'text-[var(--success-dot)]'}`} />\r\n {t('assignments.complete')}\r\n </button>\r\n <button\r\n onClick={() => toggleStatusFilter('some')}\r\n className={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border transition-colors ${\r\n statusFilters.has('some')\r\n ? 'bg-[var(--warning-bg)] border-[var(--warning-border)] text-[var(--warning-text)]'\r\n : 'bg-[var(--bg-tertiary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--warning-border)]'\r\n }`}\r\n >\r\n <Star className={`h-3.5 w-3.5 ${statusFilters.has('some') ? '' : 'text-[var(--warning-dot)]'}`} />\r\n {t('assignments.partial')}\r\n </button>\r\n <button\r\n onClick={() => toggleStatusFilter('read-only')}\r\n className={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border transition-colors ${\r\n statusFilters.has('read-only')\r\n ? 'bg-[var(--info-bg)] border-[var(--info-border)] text-[var(--info-text)]'\r\n : 'bg-[var(--bg-tertiary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--info-border)]'\r\n }`}\r\n >\r\n <Eye className={`h-3.5 w-3.5 ${statusFilters.has('read-only') ? '' : 'text-[var(--info-dot)]'}`} />\r\n {t('assignments.readOnly')}\r\n </button>\r\n <button\r\n onClick={() => toggleStatusFilter('none')}\r\n className={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border transition-colors ${\r\n statusFilters.has('none')\r\n ? 'bg-[var(--error-bg)] border-[var(--error-border)] text-[var(--error-text)]'\r\n : 'bg-[var(--bg-tertiary)] border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--error-border)]'\r\n }`}\r\n >\r\n <Ban className={`h-3.5 w-3.5 ${statusFilters.has('none') ? '' : 'text-[var(--text-muted)]'}`} />\r\n {t('assignments.none')}\r\n </button>\r\n </div>\r\n {statusFilters.size > 0 && (\r\n <button\r\n onClick={() => setStatusFilters(new Set())}\r\n className=\"text-xs text-[var(--color-accent-500)] hover:text-[var(--color-accent-600)] underline\"\r\n >\r\n {t('assignments.clearFilters')}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* Stats */}\r\n <div className=\"flex items-center gap-3\">\r\n <span className=\"px-2.5 py-1 text-xs font-semibold rounded-full bg-[var(--bg-tertiary)] text-[var(--text-secondary)]\">\r\n {totalModuleCount} {t('assignments.modules')}\r\n </span>\r\n </div>\r\n\r\n {/* Permission Matrix Table - Same style as PermissionMatrixTable */}\r\n <div className=\"overflow-x-auto overflow-y-visible\">\r\n <table className=\"border-collapse\" style={{ width: 'auto' }}>\r\n <thead className=\"item-medium border-b border-[var(--item-color-border)]\">\r\n <tr>\r\n <th\r\n scope=\"col\"\r\n className=\"sticky left-0 z-20 item-medium px-3 text-left text-xs font-medium text-[var(--text-secondary)] uppercase tracking-wider\"\r\n style={{ width: '280px', minWidth: '280px', maxWidth: '280px', height: '48px', verticalAlign: 'middle' }}\r\n >\r\n {t('assignments.resource')}\r\n </th>\r\n <th\r\n scope=\"col\"\r\n className=\"px-2 text-center text-xs font-medium text-[var(--text-secondary)] uppercase tracking-wider\"\r\n style={{ width: '60px', minWidth: '60px', maxWidth: '60px', height: '48px', verticalAlign: 'middle' }}\r\n >\r\n {t('userPermissions.status')}\r\n </th>\r\n <th\r\n scope=\"col\"\r\n className=\"px-3 text-left text-xs font-medium text-[var(--text-secondary)] uppercase tracking-wider\"\r\n style={{ height: '48px', verticalAlign: 'middle' }}\r\n >\r\n {t('assignments.permissions')}\r\n </th>\r\n </tr>\r\n </thead>\r\n <tbody className=\"divide-y divide-[var(--item-color-border)]\">\r\n {groupedResources.map((appGroup) => {\r\n const appKey = appGroup.application;\r\n const isAppCollapsed = collapsedApps.has(appKey);\r\n\r\n return (\r\n <React.Fragment key={appKey}>\r\n {/* Application Header Row */}\r\n <tr className=\"bg-[var(--bg-tertiary)]\">\r\n <td\r\n className=\"sticky left-0 z-10 px-3 py-2 bg-[var(--bg-tertiary)]\"\r\n style={{ width: '280px', minWidth: '280px', maxWidth: '280px' }}\r\n >\r\n <button\r\n onClick={() => toggleApp(appKey)}\r\n className=\"flex items-center gap-3 w-full text-left hover:opacity-80\"\r\n >\r\n {isAppCollapsed ? (\r\n <ChevronRight className=\"h-4 w-4 text-[var(--text-secondary)]\" />\r\n ) : (\r\n <ChevronDown className=\"h-4 w-4 text-[var(--text-secondary)]\" />\r\n )}\r\n <FolderOpen className=\"h-4 w-4 text-[var(--text-secondary)]\" />\r\n <span className=\"text-sm font-semibold text-[var(--text-primary)]\">\r\n {appGroup.application}\r\n </span>\r\n <span className=\"text-xs text-[var(--text-muted)] ml-auto\">\r\n {appGroup.modules.length} module{appGroup.modules.length > 1 ? 's' : ''}\r\n </span>\r\n </button>\r\n </td>\r\n <td className=\"px-0 py-2\" />\r\n <td className=\"px-0 py-2\" />\r\n </tr>\r\n\r\n {/* Module, Section and Resource Rows */}\r\n {!isAppCollapsed && appGroup.modules.map((moduleWithSections, moduleIndex) => {\r\n const { module, sections } = moduleWithSections;\r\n const hasSections = sections.length > 0;\r\n const isModuleCollapsed = collapsedModules.has(module.id);\r\n\r\n return (\r\n <React.Fragment key={module.id}>\r\n {/* Module Row */}\r\n {renderResourceRow(module, moduleIndex, 'module', hasSections, isModuleCollapsed)}\r\n\r\n {/* Section and Resource Rows (if module has sections and is not collapsed) */}\r\n {hasSections && !isModuleCollapsed && sections.map((sectionWithResources, sectionIndex) => {\r\n const { section, resources } = sectionWithResources;\r\n\r\n return (\r\n <SectionResourceRows\r\n key={section.id}\r\n section={section}\r\n resources={resources}\r\n moduleIndex={moduleIndex}\r\n sectionIndex={sectionIndex}\r\n collapsedSections={collapsedSections}\r\n renderResourceRow={renderResourceRow}\r\n />\r\n );\r\n })}\r\n </React.Fragment>\r\n );\r\n })}\r\n </React.Fragment>\r\n );\r\n })}\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n {totalModuleCount === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('assignments.noResources')}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useParams, useNavigate, Link } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n ArrowLeft,\r\n Shield,\r\n Users,\r\n Settings,\r\n Loader2,\r\n Save,\r\n Lock,\r\n AlertTriangle,\r\n CheckCircle,\r\n Languages,\r\n Plus,\r\n Trash2,\r\n Edit2,\r\n X,\r\n UsersRound,\r\n Search\r\n} from 'lucide-react';\r\nimport {\r\n adminApi,\r\n type RoleDetailDto,\r\n type RoleListDto,\r\n type UpdateRoleRequest,\r\n type RoleTranslationDto,\r\n type UpdateRoleTranslationRequest,\r\n type RoleCategory,\r\n type UserListDto\r\n} from '@/services/api/adminApi';\r\nimport { groupsApi, type GroupListDto } from '@/services/api/groupsApi';\r\nimport { RolePermissionMatrix } from '@/components/platform/administration/permissions/RolePermissionMatrix';\r\n\r\ntype TabId = 'info' | 'permissions' | 'users' | 'groups' | 'translations';\r\n\r\nconst SUPPORTED_LANGUAGES = [\r\n { code: 'fr', label: 'Français' },\r\n { code: 'en', label: 'English' },\r\n { code: 'it', label: 'Italiano' },\r\n { code: 'de', label: 'Deutsch' }\r\n];\r\n\r\nexport function RoleDetailPage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { id: roleId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n\r\n const [role, setRole] = useState<RoleDetailDto | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [saving, setSaving] = useState(false);\r\n const [activeTab, setActiveTab] = useState<TabId>('info');\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n\r\n const [formData, setFormData] = useState({\r\n name: '',\r\n shortName: '',\r\n category: 'Custom' as RoleCategory,\r\n description: '',\r\n parentRoleId: null as string | null\r\n });\r\n const [availableRoles, setAvailableRoles] = useState<RoleListDto[]>([]);\r\n\r\n const ROLE_CATEGORIES: RoleCategory[] = ['Global', 'Admin', 'Manager', 'Contributor', 'Viewer', 'Custom'];\r\n\r\n // Translation state\r\n const [translations, setTranslations] = useState<RoleTranslationDto[]>([]);\r\n const [loadingTranslations, setLoadingTranslations] = useState(false);\r\n const [editingTranslation, setEditingTranslation] = useState<string | null>(null);\r\n const [translationForm, setTranslationForm] = useState<UpdateRoleTranslationRequest>({\r\n name: '',\r\n shortName: '',\r\n description: ''\r\n });\r\n const [savingTranslation, setSavingTranslation] = useState(false);\r\n const [showAddTranslation, setShowAddTranslation] = useState(false);\r\n const [newTranslationLang, setNewTranslationLang] = useState('');\r\n\r\n // User assignment state\r\n const [addingUser, setAddingUser] = useState(false);\r\n const [availableUsers, setAvailableUsers] = useState<UserListDto[]>([]);\r\n const [loadingUsers, setLoadingUsers] = useState(false);\r\n const [userSearchTerm, setUserSearchTerm] = useState('');\r\n const [selectedUserId, setSelectedUserId] = useState<string | null>(null);\r\n const [assigningUser, setAssigningUser] = useState(false);\r\n const [removingUserId, setRemovingUserId] = useState<string | null>(null);\r\n\r\n // Group assignment state\r\n const [addingGroup, setAddingGroup] = useState(false);\r\n const [availableGroups, setAvailableGroups] = useState<GroupListDto[]>([]);\r\n const [loadingGroups, setLoadingGroups] = useState(false);\r\n const [groupSearchTerm, setGroupSearchTerm] = useState('');\r\n const [selectedGroupId, setSelectedGroupId] = useState<string | null>(null);\r\n const [assigningGroup, setAssigningGroup] = useState(false);\r\n const [removingGroupId, setRemovingGroupId] = useState<string | null>(null);\r\n\r\n const loadRole = useCallback(async () => {\r\n if (!roleId) return;\r\n try {\r\n setLoading(true);\r\n const [roleData, rolesData] = await Promise.all([\r\n adminApi.roles.getById(roleId),\r\n adminApi.roles.getAll()\r\n ]);\r\n setRole(roleData);\r\n // Filter out current role from available parent roles\r\n setAvailableRoles(rolesData.filter(r => r.id !== roleId));\r\n setFormData({\r\n name: roleData.name,\r\n shortName: roleData.shortName,\r\n category: roleData.category,\r\n description: roleData.description || '',\r\n parentRoleId: roleData.parentRoleId\r\n });\r\n } catch (err) {\r\n console.error('Failed to load role:', err);\r\n setError(t('roleDetail.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [roleId, t]);\r\n\r\n useEffect(() => {\r\n loadRole();\r\n }, [loadRole]);\r\n\r\n const handleSaveInfo = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (!roleId || !role) return;\r\n\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n\r\n try {\r\n const updateData: UpdateRoleRequest = {\r\n name: formData.name,\r\n shortName: formData.shortName,\r\n category: formData.category,\r\n description: formData.description || undefined,\r\n parentRoleId: formData.parentRoleId || undefined\r\n };\r\n await adminApi.roles.update(roleId, updateData);\r\n setSuccess(t('roleDetail.success.saved'));\r\n loadRole();\r\n } catch (err: unknown) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.saveFailed'));\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n // Translation functions\r\n const loadTranslations = useCallback(async () => {\r\n if (!roleId) return;\r\n setLoadingTranslations(true);\r\n try {\r\n const data = await adminApi.roles.getTranslations(roleId);\r\n setTranslations(data);\r\n } catch (err) {\r\n console.error('Failed to load translations:', err);\r\n } finally {\r\n setLoadingTranslations(false);\r\n }\r\n }, [roleId]);\r\n\r\n useEffect(() => {\r\n if (activeTab === 'translations' && translations.length === 0) {\r\n loadTranslations();\r\n }\r\n }, [activeTab, translations.length, loadTranslations]);\r\n\r\n const startEditTranslation = (trans: RoleTranslationDto) => {\r\n setEditingTranslation(trans.languageCode);\r\n setTranslationForm({\r\n name: trans.name,\r\n shortName: trans.shortName,\r\n description: trans.description || ''\r\n });\r\n };\r\n\r\n const cancelEditTranslation = () => {\r\n setEditingTranslation(null);\r\n setShowAddTranslation(false);\r\n setTranslationForm({ name: '', shortName: '', description: '' });\r\n setNewTranslationLang('');\r\n };\r\n\r\n const handleSaveTranslation = async (languageCode: string) => {\r\n if (!roleId) return;\r\n setSavingTranslation(true);\r\n setError(null);\r\n try {\r\n await adminApi.roles.upsertTranslation(roleId, languageCode, translationForm);\r\n setSuccess(t('roleDetail.translations.saved'));\r\n setEditingTranslation(null);\r\n setShowAddTranslation(false);\r\n setNewTranslationLang('');\r\n loadTranslations();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.saveFailed'));\r\n } finally {\r\n setSavingTranslation(false);\r\n }\r\n };\r\n\r\n const handleDeleteTranslation = async (languageCode: string) => {\r\n if (!roleId) return;\r\n if (!confirm(t('roleDetail.translations.confirmDelete'))) return;\r\n try {\r\n await adminApi.roles.deleteTranslation(roleId, languageCode);\r\n setSuccess(t('roleDetail.translations.deleted'));\r\n loadTranslations();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.saveFailed'));\r\n }\r\n };\r\n\r\n const availableLanguages = SUPPORTED_LANGUAGES.filter(\r\n lang => !translations.some(t => t.languageCode === lang.code)\r\n );\r\n\r\n // User assignment functions\r\n const openAddUser = async () => {\r\n setAddingUser(true);\r\n setSelectedUserId(null);\r\n setUserSearchTerm('');\r\n setLoadingUsers(true);\r\n try {\r\n const data = await adminApi.users.getAll({ globalScope: true });\r\n setAvailableUsers(data.items);\r\n } catch (err) {\r\n console.error('Failed to load users:', err);\r\n } finally {\r\n setLoadingUsers(false);\r\n }\r\n };\r\n\r\n const handleAssignUser = async () => {\r\n if (!roleId || !selectedUserId) return;\r\n setAssigningUser(true);\r\n try {\r\n await adminApi.roles.assignUser(roleId, selectedUserId);\r\n setAddingUser(false);\r\n setSelectedUserId(null);\r\n setSuccess(t('roleDetail.users.assigned'));\r\n loadRole();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.assignFailed'));\r\n } finally {\r\n setAssigningUser(false);\r\n }\r\n };\r\n\r\n const handleRemoveUser = async (userId: string) => {\r\n if (!roleId) return;\r\n if (!confirm(t('roleDetail.users.confirmRemove'))) return;\r\n setRemovingUserId(userId);\r\n try {\r\n await adminApi.roles.removeUser(roleId, userId);\r\n setSuccess(t('roleDetail.users.removed'));\r\n loadRole();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.removeFailed'));\r\n } finally {\r\n setRemovingUserId(null);\r\n }\r\n };\r\n\r\n // Group assignment functions\r\n const openAddGroup = async () => {\r\n setAddingGroup(true);\r\n setSelectedGroupId(null);\r\n setGroupSearchTerm('');\r\n setLoadingGroups(true);\r\n try {\r\n const data = await groupsApi.getAll();\r\n setAvailableGroups(data);\r\n } catch (err) {\r\n console.error('Failed to load groups:', err);\r\n } finally {\r\n setLoadingGroups(false);\r\n }\r\n };\r\n\r\n const handleAssignGroup = async () => {\r\n if (!roleId || !selectedGroupId) return;\r\n setAssigningGroup(true);\r\n try {\r\n await adminApi.roles.assignGroup(roleId, selectedGroupId);\r\n setAddingGroup(false);\r\n setSelectedGroupId(null);\r\n setSuccess(t('roleDetail.groups.assigned'));\r\n loadRole();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.assignFailed'));\r\n } finally {\r\n setAssigningGroup(false);\r\n }\r\n };\r\n\r\n const handleRemoveGroup = async (groupId: string) => {\r\n if (!roleId) return;\r\n if (!confirm(t('roleDetail.groups.confirmRemove'))) return;\r\n setRemovingGroupId(groupId);\r\n try {\r\n await adminApi.roles.removeGroup(roleId, groupId);\r\n setSuccess(t('roleDetail.groups.removed'));\r\n loadRole();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('roleDetail.errors.removeFailed'));\r\n } finally {\r\n setRemovingGroupId(null);\r\n }\r\n };\r\n\r\n const tabs: { id: TabId; label: string; icon: React.ReactNode }[] = [\r\n { id: 'info', label: t('roleDetail.tabs.info'), icon: <Settings className=\"w-4 h-4\" /> },\r\n { id: 'permissions', label: t('roleDetail.tabs.permissions'), icon: <Shield className=\"w-4 h-4\" /> },\r\n { id: 'users', label: t('roleDetail.tabs.users'), icon: <Users className=\"w-4 h-4\" /> },\r\n { id: 'groups', label: t('roleDetail.tabs.groups'), icon: <UsersRound className=\"w-4 h-4\" /> },\r\n { id: 'translations', label: t('roleDetail.tabs.translations'), icon: <Languages className=\"w-4 h-4\" /> }\r\n ];\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center h-64\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (!role) {\r\n return (\r\n <div className=\"text-center py-12\">\r\n <p className=\"text-[var(--text-secondary)]\">{t('roleDetail.notFound')}</p>\r\n <button\r\n onClick={() => navigate('/administration/permissions/roles')}\r\n className=\"mt-4 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white\"\r\n >\r\n {t('roleDetail.backToList')}\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('header.title'), href: '/administration' },\r\n { label: t('roles.title', 'Roles'), href: '/administration/permissions/roles' },\r\n { label: role?.name || 'Detail' }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/administration/permissions/roles')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-3\">\r\n <h1 className=\"text-xl sm:text-2xl font-bold text-[var(--text-primary)]\">{role.name}</h1>\r\n {role.isSystem && (\r\n <span className=\"flex items-center gap-1 px-2 py-1 rounded-[var(--radius-badge)] text-xs bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)]\">\r\n <Lock className=\"w-3 h-3\" />\r\n {t('roles.system')}\r\n </span>\r\n )}\r\n </div>\r\n {role.description && (\r\n <p className=\"text-sm sm:text-base text-[var(--text-secondary)] mt-1\">{role.description}</p>\r\n )}\r\n </div>\r\n <div className=\"flex items-center gap-4 text-sm text-[var(--text-secondary)]\">\r\n <div className=\"flex items-center gap-1\">\r\n <Users className=\"w-4 h-4\" />\r\n <span>{role.users.length} {t('roleDetail.usersCount')}</span>\r\n </div>\r\n <div className=\"flex items-center gap-1\">\r\n <UsersRound className=\"w-4 h-4\" />\r\n <span>{role.groups?.length || 0} {t('roleDetail.groupsCount')}</span>\r\n </div>\r\n <div className=\"flex items-center gap-1\">\r\n <Shield className=\"w-4 h-4\" />\r\n <span>{role.permissions.length} {t('roles.permissions')}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Alerts */}\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)] text-[var(--error-text)] flex items-center gap-2\">\r\n <AlertTriangle className=\"w-5 h-5 flex-shrink-0\" />\r\n {error}\r\n </div>\r\n )}\r\n {success && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)] text-[var(--success-text)] flex items-center gap-2\">\r\n <CheckCircle className=\"w-5 h-5 flex-shrink-0\" />\r\n {success}\r\n </div>\r\n )}\r\n\r\n\r\n {/* Tabs */}\r\n <div className=\"flex gap-1 p-1 bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)]\">\r\n {tabs.map(tab => (\r\n <button\r\n key={tab.id}\r\n onClick={() => setActiveTab(tab.id)}\r\n className={`flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium transition-colors ${\r\n activeTab === tab.id\r\n ? 'bg-[var(--color-accent-600)] text-white'\r\n : 'text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n {tab.icon}\r\n <span className=\"hidden sm:inline\">{tab.label}</span>\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* Tab Content */}\r\n <div className=\"bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-4 sm:p-6\">\r\n {/* Info Tab */}\r\n {activeTab === 'info' && (\r\n <form onSubmit={handleSaveInfo} className=\"space-y-6 max-w-2xl\">\r\n {/* ID (read-only) */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.info.id')}\r\n </label>\r\n <div className=\"px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-tertiary)] text-[var(--text-secondary)] font-mono text-sm\">\r\n {role.id}\r\n </div>\r\n </div>\r\n\r\n {/* Name */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roles.form.name')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n required\r\n value={formData.name}\r\n onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n\r\n {/* Short Name */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.info.shortName')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n required\r\n value={formData.shortName}\r\n onChange={e => setFormData(prev => ({ ...prev, shortName: e.target.value }))}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <p className=\"mt-1 text-xs text-[var(--text-tertiary)]\">\r\n {t('roleDetail.info.shortNameHelp')}\r\n </p>\r\n </div>\r\n\r\n {/* Category */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.info.category')} *\r\n </label>\r\n <select\r\n value={formData.category}\r\n onChange={e => setFormData(prev => ({ ...prev, category: e.target.value as RoleCategory }))}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n {ROLE_CATEGORIES.map(cat => (\r\n <option key={cat} value={cat}>\r\n {t(`roleDetail.categories.${cat.toLowerCase()}`)}\r\n </option>\r\n ))}\r\n </select>\r\n <p className=\"mt-1 text-xs text-[var(--text-tertiary)]\">\r\n {t('roleDetail.info.categoryHelp')}\r\n </p>\r\n </div>\r\n\r\n {/* Parent Role */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.info.parentRole')}\r\n </label>\r\n <select\r\n value={formData.parentRoleId || ''}\r\n onChange={e => setFormData(prev => ({ ...prev, parentRoleId: e.target.value || null }))}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n >\r\n <option value=\"\">{t('roleDetail.info.noParent')}</option>\r\n {availableRoles.map(r => (\r\n <option key={r.id} value={r.id}>\r\n {r.name} ({t(`roleDetail.categories.${r.category.toLowerCase()}`)})\r\n </option>\r\n ))}\r\n </select>\r\n <p className=\"mt-1 text-xs text-[var(--text-tertiary)]\">\r\n {t('roleDetail.info.parentRoleHelp')}\r\n </p>\r\n </div>\r\n\r\n {/* Description */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roles.form.description')}\r\n </label>\r\n <textarea\r\n value={formData.description}\r\n onChange={e => setFormData(prev => ({ ...prev, description: e.target.value }))}\r\n rows={3}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] resize-none\"\r\n />\r\n </div>\r\n\r\n {/* System Role Badge */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.info.systemRole')}\r\n </label>\r\n <div className=\"flex items-center gap-2\">\r\n {role.isSystem ? (\r\n <span className=\"flex items-center gap-1.5 px-3 py-1.5 rounded-[var(--radius-badge)] text-sm bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)]\">\r\n <Lock className=\"w-4 h-4\" />\r\n {t('roleDetail.info.isSystemRole')}\r\n </span>\r\n ) : (\r\n <span className=\"flex items-center gap-1.5 px-3 py-1.5 rounded-[var(--radius-badge)] text-sm bg-[var(--bg-tertiary)] text-[var(--text-secondary)]\">\r\n {t('roleDetail.info.isCustomRole')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Metadata */}\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4 pt-4 border-t border-[var(--border-color)]\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.createdAt')}\r\n </label>\r\n <div className=\"text-sm text-[var(--text-primary)]\">\r\n {new Date(role.createdAt).toLocaleString()}\r\n </div>\r\n </div>\r\n {role.updatedAt && (\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.updatedAt')}\r\n </label>\r\n <div className=\"text-sm text-[var(--text-primary)]\">\r\n {new Date(role.updatedAt).toLocaleString()}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex justify-end pt-4\">\r\n <button\r\n type=\"submit\"\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white font-medium transition-colors disabled:opacity-50\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('common.save')}\r\n </button>\r\n </div>\r\n </form>\r\n )}\r\n\r\n {/* Permissions Tab - Matrix View */}\r\n {activeTab === 'permissions' && roleId && (\r\n <RolePermissionMatrix roleId={roleId} />\r\n )}\r\n\r\n {/* Groups Tab */}\r\n {activeTab === 'groups' && (\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('roleDetail.groups.title')} ({role.groups?.length || 0})\r\n </h3>\r\n <button\r\n onClick={openAddGroup}\r\n className=\"flex items-center gap-2 px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white text-sm font-medium transition-colors\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('roleDetail.groups.add')}\r\n </button>\r\n </div>\r\n\r\n {(!role.groups || role.groups.length === 0) ? (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('roleDetail.groups.noGroups')}\r\n </div>\r\n ) : (\r\n <div className=\"grid gap-3\">\r\n {role.groups.map(group => (\r\n <div\r\n key={group.id}\r\n className=\"flex items-center gap-4 p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\"\r\n >\r\n <Link\r\n to={`/administration/users/groups/${group.id}`}\r\n className=\"flex items-center gap-4 flex-1 min-w-0 hover:opacity-80 transition-opacity\"\r\n >\r\n <div className=\"w-10 h-10 rounded-full bg-[var(--color-accent-100)] flex items-center justify-center\">\r\n <UsersRound className=\"w-5 h-5 text-[var(--color-accent-700)]\" />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"font-medium text-[var(--text-primary)] truncate\">{group.name}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)] truncate\">\r\n {group.membersCount} {t('roleDetail.groups.members')}\r\n {group.description && ` · ${group.description}`}\r\n </div>\r\n </div>\r\n </Link>\r\n <button\r\n onClick={() => handleRemoveGroup(group.id)}\r\n disabled={removingGroupId === group.id}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] text-[var(--text-secondary)] hover:text-[var(--error-text)] transition-colors disabled:opacity-50\"\r\n title={t('roleDetail.groups.remove')}\r\n >\r\n {removingGroupId === group.id ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Trash2 className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Add Group Modal */}\r\n {addingGroup && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] w-full max-w-md p-6 m-4 max-h-[90vh] overflow-y-auto\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('roleDetail.groups.addTitle')}\r\n </h2>\r\n <button\r\n onClick={() => setAddingGroup(false)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n value={groupSearchTerm}\r\n onChange={(e) => setGroupSearchTerm(e.target.value)}\r\n className=\"w-full pl-10 pr-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n placeholder={t('roleDetail.groups.searchPlaceholder')}\r\n />\r\n </div>\r\n </div>\r\n\r\n {loadingGroups ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n ) : (\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto\">\r\n {availableGroups\r\n .filter(g =>\r\n !role.groups?.some(rg => rg.id === g.id) &&\r\n (groupSearchTerm === '' ||\r\n g.name.toLowerCase().includes(groupSearchTerm.toLowerCase()) ||\r\n (g.description || '').toLowerCase().includes(groupSearchTerm.toLowerCase()))\r\n )\r\n .map(group => (\r\n <label\r\n key={group.id}\r\n className={`flex items-center gap-3 cursor-pointer p-3 rounded-[var(--radius-button)] transition-colors ${\r\n selectedGroupId === group.id\r\n ? 'bg-[var(--color-accent-500)]/10 border border-[var(--color-accent-500)]'\r\n : 'hover:bg-[var(--bg-hover)] border border-transparent'\r\n }`}\r\n htmlFor={`group-${group.id}`}\r\n >\r\n <input\r\n id={`group-${group.id}`}\r\n type=\"radio\"\r\n name=\"selectedGroup\"\r\n checked={selectedGroupId === group.id}\r\n onChange={() => setSelectedGroupId(group.id)}\r\n className=\"w-4 h-4 text-[var(--color-accent-600)] focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <div className=\"flex-1 min-w-0\">\r\n <span className=\"text-[var(--text-primary)] font-medium\">{group.name}</span>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">\r\n {group.memberCount} {t('roleDetail.groups.members')}\r\n {group.description && ` · ${group.description}`}\r\n </p>\r\n </div>\r\n </label>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex justify-end gap-3 mt-6\">\r\n <button\r\n onClick={() => setAddingGroup(false)}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] text-[var(--text-primary)] font-medium transition-colors\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n onClick={handleAssignGroup}\r\n disabled={!selectedGroupId || assigningGroup}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white font-medium transition-colors disabled:opacity-50\"\r\n >\r\n {assigningGroup && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {t('common.add')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Users Tab */}\r\n {activeTab === 'users' && (\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('roleDetail.users.title')} ({role.users.length})\r\n </h3>\r\n <button\r\n onClick={openAddUser}\r\n className=\"flex items-center gap-2 px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white text-sm font-medium transition-colors\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('roleDetail.users.add')}\r\n </button>\r\n </div>\r\n\r\n {role.users.length === 0 ? (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('roleDetail.users.noUsers')}\r\n </div>\r\n ) : (\r\n <div className=\"grid gap-3\">\r\n {role.users.map(user => (\r\n <div\r\n key={user.id}\r\n className=\"flex items-center gap-4 p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\"\r\n >\r\n <Link\r\n to={`/administration/users/${user.id}`}\r\n className=\"flex items-center gap-4 flex-1 min-w-0 hover:opacity-80 transition-opacity\"\r\n >\r\n <div className=\"w-10 h-10 rounded-full bg-[var(--color-accent-100)] flex items-center justify-center\">\r\n <span className=\"text-sm font-medium text-[var(--color-accent-700)]\">\r\n {user.fullName.split(' ').map(n => n.at(0)).join('').toUpperCase().slice(0, 2)}\r\n </span>\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"font-medium text-[var(--text-primary)] truncate\">{user.fullName}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)] truncate\">{user.email}</div>\r\n </div>\r\n </Link>\r\n <button\r\n onClick={() => handleRemoveUser(user.id)}\r\n disabled={removingUserId === user.id}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] text-[var(--text-secondary)] hover:text-[var(--error-text)] transition-colors disabled:opacity-50\"\r\n title={t('roleDetail.users.remove')}\r\n >\r\n {removingUserId === user.id ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Trash2 className=\"w-4 h-4\" />\r\n )}\r\n </button>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Add User Modal */}\r\n {addingUser && (\r\n <div className=\"fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50\">\r\n <div className=\"bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] w-full max-w-md p-6 m-4 max-h-[90vh] overflow-y-auto\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {t('roleDetail.users.addTitle')}\r\n </h2>\r\n <button\r\n onClick={() => setAddingUser(false)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <X className=\"w-5 h-5 text-[var(--text-tertiary)]\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n value={userSearchTerm}\r\n onChange={(e) => setUserSearchTerm(e.target.value)}\r\n className=\"w-full pl-10 pr-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n placeholder={t('roleDetail.users.searchPlaceholder')}\r\n />\r\n </div>\r\n </div>\r\n\r\n {loadingUsers ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n ) : (\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto\">\r\n {availableUsers\r\n .filter(u =>\r\n !role.users.some(ru => ru.id === u.id) &&\r\n (userSearchTerm === '' ||\r\n u.fullName.toLowerCase().includes(userSearchTerm.toLowerCase()) ||\r\n u.email.toLowerCase().includes(userSearchTerm.toLowerCase()))\r\n )\r\n .map(user => (\r\n <label\r\n key={user.id}\r\n className={`flex items-center gap-3 cursor-pointer p-3 rounded-[var(--radius-button)] transition-colors ${\r\n selectedUserId === user.id\r\n ? 'bg-[var(--color-accent-500)]/10 border border-[var(--color-accent-500)]'\r\n : 'hover:bg-[var(--bg-hover)] border border-transparent'\r\n }`}\r\n htmlFor={`user-${user.id}`}\r\n >\r\n <input\r\n id={`user-${user.id}`}\r\n type=\"radio\"\r\n name=\"selectedUser\"\r\n checked={selectedUserId === user.id}\r\n onChange={() => setSelectedUserId(user.id)}\r\n className=\"w-4 h-4 text-[var(--color-accent-600)] focus:ring-[var(--color-accent-500)]\"\r\n />\r\n <div className=\"flex-1 min-w-0\">\r\n <span className=\"text-[var(--text-primary)] font-medium\">{user.fullName}</span>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{user.email}</p>\r\n </div>\r\n </label>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className=\"flex justify-end gap-3 mt-6\">\r\n <button\r\n onClick={() => setAddingUser(false)}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] text-[var(--text-primary)] font-medium transition-colors\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n onClick={handleAssignUser}\r\n disabled={!selectedUserId || assigningUser}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white font-medium transition-colors disabled:opacity-50\"\r\n >\r\n {assigningUser && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {t('common.add')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Translations Tab */}\r\n {activeTab === 'translations' && (\r\n <div className=\"space-y-6\">\r\n <div className=\"flex items-center justify-between\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('roleDetail.translations.title')} ({translations.length})\r\n </h3>\r\n {availableLanguages.length > 0 && (\r\n <button\r\n onClick={() => setShowAddTranslation(true)}\r\n className=\"flex items-center gap-2 px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white text-sm font-medium transition-colors\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('roleDetail.translations.add')}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* Add new translation form */}\r\n {showAddTranslation && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--color-accent-500)]\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h4 className=\"font-medium text-[var(--text-primary)]\">\r\n {t('roleDetail.translations.addNew')}\r\n </h4>\r\n <button\r\n onClick={cancelEditTranslation}\r\n className=\"p-1 rounded hover:bg-[var(--bg-hover)]\"\r\n >\r\n <X className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n </button>\r\n </div>\r\n <div className=\"grid gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.language')}\r\n </label>\r\n <select\r\n value={newTranslationLang}\r\n onChange={e => setNewTranslationLang(e.target.value)}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)]\"\r\n >\r\n <option value=\"\">{t('roleDetail.translations.selectLanguage')}</option>\r\n {availableLanguages.map(lang => (\r\n <option key={lang.code} value={lang.code}>{lang.label}</option>\r\n ))}\r\n </select>\r\n </div>\r\n {newTranslationLang && (\r\n <>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.name')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={translationForm.name}\r\n onChange={e => setTranslationForm(prev => ({ ...prev, name: e.target.value }))}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.shortName')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={translationForm.shortName}\r\n onChange={e => setTranslationForm(prev => ({ ...prev, shortName: e.target.value }))}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.description')}\r\n </label>\r\n <textarea\r\n value={translationForm.description || ''}\r\n onChange={e => setTranslationForm(prev => ({ ...prev, description: e.target.value }))}\r\n rows={2}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] resize-none\"\r\n />\r\n </div>\r\n <div className=\"flex justify-end gap-2\">\r\n <button\r\n onClick={cancelEditTranslation}\r\n className=\"px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] text-[var(--text-primary)] text-sm font-medium\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n onClick={() => handleSaveTranslation(newTranslationLang)}\r\n disabled={savingTranslation || !translationForm.name || !translationForm.shortName}\r\n className=\"flex items-center gap-2 px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white text-sm font-medium disabled:opacity-50\"\r\n >\r\n {savingTranslation && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {t('common.save')}\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {loadingTranslations && (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n )}\r\n {!loadingTranslations && translations.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {t('roleDetail.translations.noTranslations')}\r\n </div>\r\n )}\r\n {!loadingTranslations && translations.length > 0 && (\r\n <div className=\"space-y-3\">\r\n {translations.map(trans => {\r\n const langInfo = SUPPORTED_LANGUAGES.find(l => l.code === trans.languageCode);\r\n const isEditing = editingTranslation === trans.languageCode;\r\n\r\n return (\r\n <div\r\n key={trans.languageCode}\r\n className={`p-4 rounded-[var(--radius-card)] border ${\r\n isEditing\r\n ? 'bg-[var(--bg-primary)] border-[var(--color-accent-500)]'\r\n : 'bg-[var(--bg-primary)] border-[var(--border-color)]'\r\n }`}\r\n >\r\n <div className=\"flex items-center justify-between mb-2\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"px-2 py-0.5 text-xs font-medium rounded bg-[var(--bg-tertiary)] text-[var(--text-secondary)] uppercase\">\r\n {trans.languageCode}\r\n </span>\r\n <span className=\"text-sm text-[var(--text-secondary)]\">\r\n {langInfo?.label || trans.languageCode}\r\n </span>\r\n </div>\r\n {!isEditing && (\r\n <div className=\"flex items-center gap-1\">\r\n <button\r\n onClick={() => startEditTranslation(trans)}\r\n className=\"p-1.5 rounded hover:bg-[var(--bg-hover)] text-[var(--text-secondary)] hover:text-[var(--color-accent-600)]\"\r\n title={t('common.edit')}\r\n >\r\n <Edit2 className=\"w-4 h-4\" />\r\n </button>\r\n <button\r\n onClick={() => handleDeleteTranslation(trans.languageCode)}\r\n className=\"p-1.5 rounded hover:bg-[var(--bg-hover)] text-[var(--text-secondary)] hover:text-[var(--error-text)]\"\r\n title={t('common.delete')}\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {isEditing ? (\r\n <div className=\"grid gap-3 mt-3\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.name')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={translationForm.name}\r\n onChange={e => setTranslationForm(prev => ({ ...prev, name: e.target.value }))}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.shortName')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={translationForm.shortName}\r\n onChange={e => setTranslationForm(prev => ({ ...prev, shortName: e.target.value }))}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roleDetail.translations.description')}\r\n </label>\r\n <textarea\r\n value={translationForm.description || ''}\r\n onChange={e => setTranslationForm(prev => ({ ...prev, description: e.target.value }))}\r\n rows={2}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] resize-none\"\r\n />\r\n </div>\r\n <div className=\"flex justify-end gap-2\">\r\n <button\r\n onClick={cancelEditTranslation}\r\n className=\"px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] text-[var(--text-primary)] text-sm font-medium\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n onClick={() => handleSaveTranslation(trans.languageCode)}\r\n disabled={savingTranslation || !translationForm.name || !translationForm.shortName}\r\n className=\"flex items-center gap-2 px-3 py-1.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white text-sm font-medium disabled:opacity-50\"\r\n >\r\n {savingTranslation && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {t('common.save')}\r\n </button>\r\n </div>\r\n </div>\r\n ) : (\r\n <div className=\"grid gap-1\">\r\n <div className=\"font-medium text-[var(--text-primary)]\">{trans.name}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('roleDetail.translations.shortName')}: {trans.shortName}\r\n </div>\r\n {trans.description && (\r\n <div className=\"text-sm text-[var(--text-tertiary)] mt-1\">{trans.description}</div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"names":["ACTION_ICONS","jsx","Shield","Eye","Plus","Edit","Trash2","UserPlus","Play","ACTION_COLORS","applyApplicationModuleFilterHelper","grouped","applicationFilter","moduleFilter","app","m","applyStatusFilterHelper","statusFilters","getModuleStatus","status","SectionResourceRows","section","resources","moduleIndex","sectionIndex","collapsedSections","renderResourceRow","hasResources","isSectionCollapsed","jsxs","React","resource","resourceIndex","RolePermissionMatrix","roleId","t","useTranslation","user","useAuth","collapsedApps","toggleApp","useCollapsibleState","collapsedModules","setCollapsedModules","useState","setCollapsedSections","setStatusFilters","openPopover","setOpenPopover","setApplicationFilter","setModuleFilter","canEditSystemRoles","useMemo","hasFullAccess","loading","error","roles","filteredResources","hasChanges","saving","saveSuccess","saveError","togglePermission","saveChanges","resetChanges","getPermissionInheritance","usePermissionMatrix","role","r","isRoleEditable","toggleStatusFilter","prev","next","toggleModule","moduleId","toggleSection","sectionId","filterOptions","applications","modules","appKey","a","b","handleTogglePermission","useCallback","permissionId","isPermissionGrantedFn","info","moduleWithSections","calculateModuleWithSectionsStatus","getResourceStatus","calculatePermissionStatus","getGrantedPermissions","p","applyApplicationModuleFilter","applyStatusFilter","groupedResources","groupByApplicationWithSections","totalModuleCount","sum","handleToggleCollapse","resourceId","level","handleCellClick","Loader2","AlertCircle","getRoleResourceIcon","Database","FileText","Box","getRoleResourceLabelClass","getRolePaddingClass","renderToggleButton","hasChildren","isCollapsed","ChevronRight","ChevronDown","renderPermissionBadges","grantedPermissions","action","actionColor","icon","rowIndex","grantedCount","isPopoverOpen","buttonRef","createRef","cellBg","getPermissionCellBackground","paddingLeft","rowBgClass","PermissionStatusIndicator","PermissionPopover","_","permId","Check","X","Save","e","mod","Star","Ban","appGroup","isAppCollapsed","FolderOpen","module","sections","hasSections","isModuleCollapsed","sectionWithResources","SUPPORTED_LANGUAGES","RoleDetailPage","useParams","navigate","useNavigate","setRole","setLoading","setSaving","activeTab","setActiveTab","setError","success","setSuccess","formData","setFormData","availableRoles","setAvailableRoles","ROLE_CATEGORIES","translations","setTranslations","loadingTranslations","setLoadingTranslations","editingTranslation","setEditingTranslation","translationForm","setTranslationForm","savingTranslation","setSavingTranslation","showAddTranslation","setShowAddTranslation","newTranslationLang","setNewTranslationLang","addingUser","setAddingUser","availableUsers","setAvailableUsers","loadingUsers","setLoadingUsers","userSearchTerm","setUserSearchTerm","selectedUserId","setSelectedUserId","assigningUser","setAssigningUser","removingUserId","setRemovingUserId","addingGroup","setAddingGroup","availableGroups","setAvailableGroups","loadingGroups","setLoadingGroups","groupSearchTerm","setGroupSearchTerm","selectedGroupId","setSelectedGroupId","assigningGroup","setAssigningGroup","removingGroupId","setRemovingGroupId","loadRole","roleData","rolesData","adminApi","err","useEffect","handleSaveInfo","updateData","loadTranslations","data","startEditTranslation","trans","cancelEditTranslation","handleSaveTranslation","languageCode","handleDeleteTranslation","availableLanguages","lang","openAddUser","handleAssignUser","handleRemoveUser","userId","openAddGroup","groupsApi","handleAssignGroup","handleRemoveGroup","groupId","tabs","Settings","Users","UsersRound","Languages","Breadcrumb","ArrowLeft","Lock","AlertTriangle","CheckCircle","tab","cat","group","Link","Search","g","rg","n","u","ru","Fragment","langInfo","l","isEditing","Edit2"],"mappings":"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"}