@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":"index-Cb3LotuT.js","sources":["../../src/pages/platform/administration/entra/EntraDashboardPage.tsx","../../src/pages/platform/administration/entra/EntraGroupsPage.tsx","../../src/pages/platform/administration/entra/EntraUsersPage.tsx","../../src/pages/platform/administration/entra/EntraConflictsPage.tsx","../../src/pages/platform/administration/entra/EntraSettingsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { Tooltip } from '@/components/ui/Tooltip';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport {\r\n Cloud,\r\n RefreshCw,\r\n Loader2,\r\n AlertTriangle,\r\n CheckCircle,\r\n XCircle,\r\n Clock,\r\n Users,\r\n Building2,\r\n Link2,\r\n Play,\r\n AlertCircle,\r\n Calendar,\r\n Database,\r\n} from 'lucide-react';\r\nimport {\r\n entraApi,\r\n type EntraSyncStatusDto,\r\n type EntraSyncResultDto,\r\n} from '@/services/api/entraApi';\r\n\r\n// ============================================\r\n// Sync Status Card Component\r\n// ============================================\r\n\r\ninterface SyncStatusCardProps {\r\n readonly resourceType: string;\r\n readonly icon: LucideIcon;\r\n readonly status: string;\r\n readonly lastFullSyncAt: string | null;\r\n readonly lastDeltaSyncAt: string | null;\r\n readonly totalItemsSynced: number;\r\n readonly pendingConflicts: number;\r\n readonly lastError: string | null;\r\n readonly syncing: boolean;\r\n readonly canSync: boolean;\r\n readonly onSync: () => void;\r\n readonly formatDate: (date: string | null) => string;\r\n readonly t: (key: string, options?: Record<string, unknown>) => string;\r\n}\r\n\r\nfunction SyncStatusCard({\r\n resourceType,\r\n icon: Icon,\r\n status,\r\n lastFullSyncAt,\r\n lastDeltaSyncAt,\r\n totalItemsSynced,\r\n pendingConflicts,\r\n lastError,\r\n syncing,\r\n canSync,\r\n onSync,\r\n formatDate,\r\n t,\r\n}: SyncStatusCardProps) {\r\n const getStatusConfig = () => {\r\n switch (status) {\r\n case 'Success':\r\n return {\r\n icon: CheckCircle,\r\n color: 'text-[var(--success-text)]',\r\n bg: 'bg-[var(--success-bg)]',\r\n label: t('common:success'),\r\n };\r\n case 'Failed':\r\n return {\r\n icon: XCircle,\r\n color: 'text-[var(--error-text)]',\r\n bg: 'bg-[var(--error-bg)]',\r\n label: t('common:failed'),\r\n };\r\n case 'Running':\r\n return {\r\n icon: Loader2,\r\n color: 'text-[var(--color-accent-500)]',\r\n bg: 'bg-[var(--color-accent-100)]',\r\n label: t('common:running'),\r\n animate: true,\r\n };\r\n default:\r\n return {\r\n icon: Clock,\r\n color: 'text-[var(--text-tertiary)]',\r\n bg: 'bg-[var(--bg-tertiary)]',\r\n label: t('common:pending'),\r\n };\r\n }\r\n };\r\n\r\n const statusConfig = getStatusConfig();\r\n const StatusIcon = statusConfig.icon;\r\n\r\n return (\r\n <div className=\"h-full flex flex-col rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] overflow-hidden shadow-sm hover:shadow-md transition-shadow\">\r\n {/* Header with gradient */}\r\n <div className=\"px-4 py-3 bg-gradient-to-r from-[var(--color-accent-500)]/10 to-[var(--color-accent-600)]/5 border-b border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-[var(--color-accent-500)]/20\">\r\n <Icon className=\"w-5 h-5 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <h3 className=\"font-semibold text-[var(--text-primary)]\">\r\n {t(`entra:resourceTypes.${resourceType.toLowerCase()}`)}\r\n </h3>\r\n </div>\r\n <div className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium ${statusConfig.bg} ${statusConfig.color}`}>\r\n <StatusIcon className={`w-3.5 h-3.5 ${statusConfig.animate ? 'animate-spin' : ''}`} />\r\n {statusConfig.label}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Stats Grid */}\r\n <div className=\"flex-1 flex flex-col p-4\">\r\n <div className=\"grid grid-cols-3 gap-3 mb-4\">\r\n <div className=\"text-center p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-center gap-1 mb-1\">\r\n <Database className=\"w-3.5 h-3.5 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <p className=\"text-xl font-bold text-[var(--text-primary)]\">{totalItemsSynced.toLocaleString()}</p>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{t('entra:dashboard.itemsSynced')}</p>\r\n </div>\r\n <div className=\"text-center p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-center gap-1 mb-1\">\r\n <Calendar className=\"w-3.5 h-3.5 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] truncate\" title={formatDate(lastFullSyncAt)}>\r\n {lastFullSyncAt ? new Date(lastFullSyncAt).toLocaleDateString('fr-FR', { day: 'numeric', month: 'short' }) : '-'}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{t('entra:dashboard.lastFullSync')}</p>\r\n </div>\r\n <div className=\"text-center p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-center gap-1 mb-1\">\r\n <RefreshCw className=\"w-3.5 h-3.5 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] truncate\" title={formatDate(lastDeltaSyncAt)}>\r\n {lastDeltaSyncAt ? new Date(lastDeltaSyncAt).toLocaleDateString('fr-FR', { day: 'numeric', month: 'short' }) : '-'}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{t('entra:dashboard.lastDeltaSync')}</p>\r\n </div>\r\n </div>\r\n\r\n {/* Pending Conflicts Warning */}\r\n {pendingConflicts > 0 && (\r\n <div className=\"flex items-center gap-2 p-3 mb-4 rounded-lg bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <AlertCircle className=\"w-4 h-4 text-[var(--warning-text)] flex-shrink-0\" />\r\n <span className=\"text-sm text-[var(--warning-text)] font-medium\">\r\n {pendingConflicts} {t('entra:dashboard.pendingConflicts')}\r\n </span>\r\n </div>\r\n )}\r\n\r\n {/* Last Error */}\r\n {lastError && (\r\n <div className=\"p-3 mb-4 rounded-lg bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <p className=\"text-xs text-[var(--error-text)] line-clamp-2\">{lastError}</p>\r\n </div>\r\n )}\r\n\r\n {/* Action Button - Always at bottom */}\r\n <Tooltip\r\n content={!canSync ? t('entra:dashboard.noSyncPermission') : undefined}\r\n position=\"top\"\r\n variant=\"error\"\r\n disabled={canSync}\r\n >\r\n <button\r\n onClick={onSync}\r\n disabled={syncing || !canSync}\r\n className=\"mt-auto w-full inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm\"\r\n >\r\n {syncing ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <RefreshCw className=\"w-4 h-4\" />\r\n )}\r\n {t('entra:dashboard.syncNow')}\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport function EntraDashboardPage(): ReactElement {\r\n const { t } = useTranslation(['entra', 'common']);\r\n const { hasPermission } = useAuth();\r\n const [loading, setLoading] = useState(true);\r\n const [refreshing, setRefreshing] = useState(false);\r\n const [syncStatus, setSyncStatus] = useState<EntraSyncStatusDto[]>([]);\r\n const [error, setError] = useState<string | null>(null);\r\n const [syncing, setSyncing] = useState<string | null>(null);\r\n const [lastSyncResult, setLastSyncResult] = useState<EntraSyncResultDto | null>(null);\r\n\r\n // Permission check for sync operations\r\n const canSync = hasPermission('administration.entra.execute');\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setError(null);\r\n const status = await entraApi.dashboard.getSyncStatus();\r\n setSyncStatus(Array.isArray(status) ? status : []);\r\n } catch (err: unknown) {\r\n console.error('Failed to load Entra dashboard data:', err);\r\n setSyncStatus([]);\r\n const axiosError = err as { response?: { status?: number } };\r\n if (axiosError.response?.status === 401) {\r\n setError(t('common:errors.sessionExpired'));\r\n } else if (axiosError.response?.status === 403) {\r\n setError(t('common:errors.noPermission'));\r\n } else {\r\n setError(t('entra:dashboard.loadError'));\r\n }\r\n } finally {\r\n setLoading(false);\r\n setRefreshing(false);\r\n }\r\n }, [t]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n const handleRefresh = () => {\r\n setRefreshing(true);\r\n loadData();\r\n };\r\n\r\n const handleSync = async (type: 'all' | 'users' | 'groups' | 'memberships') => {\r\n setSyncing(type);\r\n setLastSyncResult(null);\r\n try {\r\n let result: EntraSyncResultDto;\r\n switch (type) {\r\n case 'users':\r\n result = await entraApi.sync.syncUsers();\r\n break;\r\n case 'groups':\r\n result = await entraApi.sync.syncGroups();\r\n break;\r\n case 'memberships':\r\n result = await entraApi.sync.syncMemberships();\r\n break;\r\n default:\r\n result = await entraApi.sync.syncAll();\r\n }\r\n setLastSyncResult(result);\r\n await loadData();\r\n } catch (err: unknown) {\r\n console.error('Sync failed:', err);\r\n const axiosError = err as { response?: { status?: number } };\r\n if (axiosError.response?.status === 403) {\r\n setError(t('entra:dashboard.syncPermissionDenied'));\r\n } else if (axiosError.response?.status === 401) {\r\n setError(t('common:errors.sessionExpired'));\r\n } else {\r\n setError(t('entra:dashboard.syncError'));\r\n }\r\n } finally {\r\n setSyncing(null);\r\n }\r\n };\r\n\r\n const handleForceFullSync = async () => {\r\n if (!confirm(t('entra:dashboard.forceFullSyncConfirm'))) return;\r\n setSyncing('force');\r\n try {\r\n await entraApi.sync.forceFullSync();\r\n await loadData();\r\n } catch (err: unknown) {\r\n console.error('Force full sync failed:', err);\r\n const axiosError = err as { response?: { status?: number } };\r\n if (axiosError.response?.status === 403) {\r\n setError(t('entra:dashboard.syncPermissionDenied'));\r\n } else if (axiosError.response?.status === 401) {\r\n setError(t('common:errors.sessionExpired'));\r\n } else {\r\n setError(t('entra:dashboard.syncError'));\r\n }\r\n } finally {\r\n setSyncing(null);\r\n }\r\n };\r\n\r\n const formatDate = (date: string | null) => {\r\n if (!date) return t('common:never');\r\n return new Intl.DateTimeFormat('fr-FR', {\r\n dateStyle: 'medium',\r\n timeStyle: 'short',\r\n }).format(new Date(date));\r\n };\r\n\r\n const getResourceIcon = (resourceType: string): LucideIcon => {\r\n switch (resourceType) {\r\n case 'Users':\r\n return Users;\r\n case 'Groups':\r\n return Building2;\r\n case 'Memberships':\r\n return Link2;\r\n default:\r\n return Cloud;\r\n }\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\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 const totalPendingConflicts = syncStatus.reduce((sum, s) => sum + s.pendingConflicts, 0);\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('entra.title', 'Microsoft Entra ID'), href: '/administration/entra' },\r\n { label: t('entra.dashboard', 'Dashboard') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--color-accent-500)]/10\">\r\n <Cloud className=\"w-6 h-6 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('entra:dashboard.title')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:dashboard.subtitle')}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={handleRefresh}\r\n disabled={refreshing}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] disabled:opacity-50 transition-colors\"\r\n >\r\n <RefreshCw className={`w-4 h-4 ${refreshing ? 'animate-spin' : ''}`} />\r\n {t('common:refresh')}\r\n </button>\r\n <Tooltip\r\n content={!canSync ? t('entra:dashboard.noSyncPermission') : undefined}\r\n position=\"bottom\"\r\n variant=\"error\"\r\n disabled={canSync}\r\n >\r\n <button\r\n onClick={() => handleSync('all')}\r\n disabled={syncing !== null || !canSync}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {syncing === 'all' ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Play className=\"w-4 h-4\" />\r\n )}\r\n {t('entra:dashboard.syncAll')}\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </div>\r\n\r\n {/* Error */}\r\n {error && (\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 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Pending Conflicts Warning */}\r\n {totalPendingConflicts > 0 && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--warning-text)]\">\r\n <AlertCircle className=\"w-5 h-5\" />\r\n <span>\r\n {t('entra:dashboard.conflictsWarning', { count: totalPendingConflicts })}\r\n </span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Last Sync Result */}\r\n {lastSyncResult && (\r\n <div className={`p-4 rounded-[var(--radius-card)] border ${\r\n lastSyncResult.success\r\n ? 'bg-[var(--success-bg)] border-[var(--success-border)]'\r\n : 'bg-[var(--error-bg)] border-[var(--error-border)]'\r\n }`}>\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n {lastSyncResult.success ? (\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n ) : (\r\n <XCircle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n )}\r\n <span className={lastSyncResult.success ? 'text-[var(--success-text)]' : 'text-[var(--error-text)]'}>\r\n {lastSyncResult.success\r\n ? t('entra:dashboard.syncSuccess')\r\n : t('entra:dashboard.syncFailed')}\r\n </span>\r\n </div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:dashboard.syncStats', {\r\n created: lastSyncResult.created,\r\n updated: lastSyncResult.updated,\r\n deleted: lastSyncResult.deleted,\r\n })}\r\n </div>\r\n </div>\r\n {lastSyncResult.errorMessage && (\r\n <p className=\"mt-2 text-sm text-[var(--error-text)]\">\r\n {lastSyncResult.errorMessage}\r\n </p>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Sync Status Cards */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\r\n {syncStatus.map((status) => (\r\n <SyncStatusCard\r\n key={status.resourceType}\r\n resourceType={status.resourceType}\r\n icon={getResourceIcon(status.resourceType)}\r\n status={status.status}\r\n lastFullSyncAt={status.lastFullSyncAt}\r\n lastDeltaSyncAt={status.lastDeltaSyncAt}\r\n totalItemsSynced={status.totalItemsSynced}\r\n pendingConflicts={status.pendingConflicts}\r\n lastError={status.lastError}\r\n syncing={syncing === status.resourceType.toLowerCase()}\r\n canSync={canSync}\r\n onSync={() => handleSync(status.resourceType.toLowerCase() as 'users' | 'groups' | 'memberships')}\r\n formatDate={formatDate}\r\n t={t}\r\n />\r\n ))}\r\n </div>\r\n\r\n {/* Force Full Sync */}\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h3 className=\"font-semibold text-[var(--text-primary)]\">\r\n {t('entra:dashboard.forceFullSync')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:dashboard.forceFullSyncDescription')}\r\n </p>\r\n </div>\r\n <Tooltip\r\n content={!canSync ? t('entra:dashboard.noSyncPermission') : undefined}\r\n position=\"left\"\r\n variant=\"error\"\r\n disabled={canSync}\r\n >\r\n <button\r\n onClick={handleForceFullSync}\r\n disabled={syncing !== null || !canSync}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--warning-border)] bg-[var(--warning-bg)] text-[var(--warning-text)] hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {syncing === 'force' ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <AlertTriangle className=\"w-4 h-4\" />\r\n )}\r\n {t('entra:dashboard.forceFullSync')}\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Link, useNavigate } from 'react-router-dom';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n Cloud,\r\n RefreshCw,\r\n Loader2,\r\n AlertTriangle,\r\n Search,\r\n Users,\r\n Shield,\r\n Plus,\r\n X,\r\n ChevronDown,\r\n ChevronUp,\r\n LayoutGrid,\r\n List,\r\n Filter,\r\n Building2,\r\n GitBranch,\r\n} from 'lucide-react';\r\nimport {\r\n entraApi,\r\n type EntraGroupDto,\r\n type EntraGroupMemberDto,\r\n} from '@/services/api/entraApi';\r\nimport { adminApi, type RoleListDto } from '@/services/api/adminApi';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\n\r\ntype ViewMode = 'cards' | 'table';\r\ntype GroupTypeFilter = 'all' | 'security' | 'distribution';\r\n\r\ninterface GroupWithMembers extends EntraGroupDto {\r\n membersLoaded?: EntraGroupMemberDto[];\r\n}\r\n\r\nconst getGroupHierarchyDisplay = (group: EntraGroupDto) => {\r\n if (group.parentGroupName) {\r\n return (\r\n <span className=\"flex items-center gap-1 text-xs\">\r\n <GitBranch className=\"w-3 h-3\" />\r\n {group.parentGroupName}\r\n </span>\r\n );\r\n }\r\n if (group.childGroupCount > 0) {\r\n return (\r\n <span className=\"flex items-center gap-1 text-xs text-[var(--text-tertiary)]\">\r\n {group.childGroupCount} child groups\r\n </span>\r\n );\r\n }\r\n return <span className=\"text-xs text-[var(--text-tertiary)]\">-</span>;\r\n};\r\n\r\nexport function EntraGroupsPage(): ReactElement {\r\n const { t } = useTranslation(['entra', 'admin', 'common']);\r\n const { hasPermission } = useAuth();\r\n const { currentTenant, isGlobalView } = useTenant();\r\n const navigate = useNavigate();\r\n const [loading, setLoading] = useState(true);\r\n const [groups, setGroups] = useState<GroupWithMembers[]>([]);\r\n const [roles, setRoles] = useState<RoleListDto[]>([]);\r\n const [error, setError] = useState<string | null>(null);\r\n const [searchQuery, setSearchQuery] = useState('');\r\n const [selectedGroup, setSelectedGroup] = useState<GroupWithMembers | null>(null);\r\n const [showAssignModal, setShowAssignModal] = useState(false);\r\n const [expandedGroupId, setExpandedGroupId] = useState<string | null>(null);\r\n const [members, setMembers] = useState<Record<string, EntraGroupMemberDto[]>>({});\r\n const [loadingMembers, setLoadingMembers] = useState<string | null>(null);\r\n const [viewMode, setViewMode] = useState<ViewMode>('cards');\r\n const [groupTypeFilter, setGroupTypeFilter] = useState<GroupTypeFilter>('all');\r\n const [assigning, setAssigning] = useState(false);\r\n\r\n const canAssign = hasPermission('administration.entra.assign');\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setError(null);\r\n const [groupsData, rolesData] = await Promise.all([\r\n entraApi.groups.getAll(),\r\n adminApi.roles.getAssignable(),\r\n ]);\r\n setGroups(Array.isArray(groupsData) ? groupsData : []);\r\n setRoles(Array.isArray(rolesData) ? rolesData : []);\r\n } catch (err: unknown) {\r\n console.error('Failed to load Entra groups:', err);\r\n setGroups([]);\r\n setRoles([]);\r\n const axiosError = err as { response?: { status?: number; data?: { code?: string } } };\r\n if (axiosError.response?.status === 401) {\r\n setError(t('common:errors.sessionExpired'));\r\n } else if (axiosError.response?.status === 403) {\r\n setError(t('common:errors.noPermission'));\r\n } else if (axiosError.response?.data?.code === 'TENANT_REQUIRED') {\r\n setError(t('entra:groups.tenantRequired'));\r\n } else {\r\n setError(t('entra:groups.loadError'));\r\n }\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [t, currentTenant?.id, isGlobalView]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n const loadMembers = async (groupId: string) => {\r\n if (members[groupId]) {\r\n setExpandedGroupId(expandedGroupId === groupId ? null : groupId);\r\n return;\r\n }\r\n\r\n setLoadingMembers(groupId);\r\n try {\r\n const data = await entraApi.groups.getMembers(groupId);\r\n setMembers(prev => ({ ...prev, [groupId]: data }));\r\n setExpandedGroupId(groupId);\r\n } catch (err) {\r\n console.error('Failed to load members:', err);\r\n setError(t('entra:groups.loadMembersError'));\r\n } finally {\r\n setLoadingMembers(null);\r\n }\r\n };\r\n\r\n const reloadGroupsAndRoles = useCallback(async () => {\r\n const [groupsData, rolesData] = await Promise.all([\r\n entraApi.groups.getAll(),\r\n adminApi.roles.getAssignable(),\r\n ]);\r\n const safeGroupsData = Array.isArray(groupsData) ? groupsData : [];\r\n setGroups(safeGroupsData);\r\n setRoles(Array.isArray(rolesData) ? rolesData : []);\r\n return safeGroupsData;\r\n }, [currentTenant?.id]);\r\n\r\n const handleAssignRole = async (roleId: string, isInheritable: boolean = true) => {\r\n if (!selectedGroup) return;\r\n setAssigning(true);\r\n try {\r\n await entraApi.groups.assignRole(selectedGroup.id, { roleId, isInheritable });\r\n const safeGroupsData = await reloadGroupsAndRoles();\r\n const updatedGroup = safeGroupsData.find(g => g.id === selectedGroup.id);\r\n if (updatedGroup) setSelectedGroup(updatedGroup);\r\n } catch (err) {\r\n console.error('Failed to assign role:', err);\r\n setError(t('entra:groups.assignError'));\r\n } finally {\r\n setAssigning(false);\r\n }\r\n };\r\n\r\n const handleRemoveRole = async (groupId: string, roleId: string) => {\r\n if (!confirm(t('entra:groups.removeRoleConfirm'))) return;\r\n try {\r\n await entraApi.groups.removeRole(groupId, roleId);\r\n await reloadGroupsAndRoles();\r\n if (selectedGroup?.id === groupId) {\r\n const updatedGroups = await entraApi.groups.getAll();\r\n const updatedGroup = updatedGroups.find(g => g.id === groupId);\r\n if (updatedGroup) setSelectedGroup(updatedGroup);\r\n }\r\n } catch (err) {\r\n console.error('Failed to remove role:', err);\r\n setError(t('entra:groups.removeError'));\r\n }\r\n };\r\n\r\n const filteredGroups = groups.filter((g) => {\r\n const matchesSearch =\r\n g.displayName.toLowerCase().includes(searchQuery.toLowerCase()) ||\r\n g.description?.toLowerCase().includes(searchQuery.toLowerCase());\r\n\r\n const matchesType =\r\n groupTypeFilter === 'all' ||\r\n (groupTypeFilter === 'security' && g.isSecurityGroup) ||\r\n (groupTypeFilter === 'distribution' && !g.isSecurityGroup);\r\n\r\n return matchesSearch && matchesType;\r\n });\r\n\r\n const formatDate = (date: string | null) => {\r\n if (!date) return '-';\r\n return new Intl.DateTimeFormat('fr-FR', {\r\n dateStyle: 'medium',\r\n timeStyle: 'short',\r\n }).format(new Date(date));\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\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 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('entra.title', 'Microsoft Entra ID'), href: '/administration/entra' },\r\n { label: t('entra.groups', 'Groups') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-blue-500/10\">\r\n <Cloud className=\"w-6 h-6 text-blue-500\" />\r\n </div>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('entra:groups.title')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:groups.subtitle', { count: groups.length })}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={loadData}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <RefreshCw className=\"w-4 h-4\" />\r\n {t('common:refresh')}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Info banner */}\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-blue-500/10 border border-blue-500/20\">\r\n <div className=\"flex items-start gap-3\">\r\n <Cloud className=\"w-5 h-5 text-blue-500 flex-shrink-0 mt-0.5\" />\r\n <div>\r\n <p className=\"text-sm text-[var(--text-primary)]\">\r\n {t('entra:groups.syncedInfo')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n {t('entra:groups.syncedInfoDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Error */}\r\n {error && (\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 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n <button\r\n onClick={() => setError(null)}\r\n className=\"ml-auto p-1 hover:bg-[var(--error-text)]/10 rounded\"\r\n >\r\n <X className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Search & Filters */}\r\n <div className=\"flex flex-col sm:flex-row gap-4\">\r\n {/* Search */}\r\n <div className=\"relative flex-1\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n placeholder={t('entra:groups.searchPlaceholder')}\r\n value={searchQuery}\r\n onChange={(e) => setSearchQuery(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)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n\r\n {/* Type Filter */}\r\n <div className=\"flex items-center gap-2\">\r\n <Filter className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <select\r\n value={groupTypeFilter}\r\n onChange={(e) => setGroupTypeFilter(e.target.value as GroupTypeFilter)}\r\n className=\"px-3 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=\"all\">{t('admin:groups.allTypes')}</option>\r\n <option value=\"security\">{t('admin:groups.securityGroup')}</option>\r\n <option value=\"distribution\">{t('admin:groups.distributionGroup')}</option>\r\n </select>\r\n </div>\r\n\r\n {/* View Mode Toggle */}\r\n <div className=\"flex items-center gap-1 p-1 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <button\r\n onClick={() => setViewMode('cards')}\r\n className={`p-2 rounded-[var(--radius-button)] transition-colors ${\r\n viewMode === 'cards'\r\n ? 'bg-[var(--color-accent-500)] text-white'\r\n : 'text-[var(--text-tertiary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n title={t('admin:groups.cardView')}\r\n >\r\n <LayoutGrid className=\"w-4 h-4\" />\r\n </button>\r\n <button\r\n onClick={() => setViewMode('table')}\r\n className={`p-2 rounded-[var(--radius-button)] transition-colors ${\r\n viewMode === 'table'\r\n ? 'bg-[var(--color-accent-500)] text-white'\r\n : 'text-[var(--text-tertiary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n title={t('admin:groups.tableView')}\r\n >\r\n <List className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Groups List */}\r\n {filteredGroups.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {searchQuery || groupTypeFilter !== 'all'\r\n ? t('admin:groups.noResults')\r\n : t('entra:groups.noGroups')}\r\n </div>\r\n )}\r\n {filteredGroups.length > 0 && viewMode === 'table' && (\r\n /* Table View */\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] overflow-hidden\">\r\n <table className=\"w-full\">\r\n <thead className=\"bg-[var(--bg-secondary)]\">\r\n <tr>\r\n <th className=\"px-4 py-3 text-left text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('admin:groups.groupName')}\r\n </th>\r\n <th className=\"px-4 py-3 text-left text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('common:type')}\r\n </th>\r\n <th className=\"px-4 py-3 text-left text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('admin:groups.members')}\r\n </th>\r\n <th className=\"px-4 py-3 text-left text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('entra:groups.hierarchy')}\r\n </th>\r\n <th className=\"px-4 py-3 text-left text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('admin:groups.assignedRoles')}\r\n </th>\r\n <th className=\"px-4 py-3 text-left text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('entra:groups.lastSynced')}\r\n </th>\r\n {canAssign && !isGlobalView && (\r\n <th className=\"px-4 py-3 text-right text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('common:actionsColumn')}\r\n </th>\r\n )}\r\n </tr>\r\n </thead>\r\n <tbody className=\"divide-y divide-[var(--border-color)]\">\r\n {filteredGroups.map((group) => (\r\n <tr\r\n key={group.id}\r\n className=\"hover:bg-[var(--bg-hover)] cursor-pointer\"\r\n onClick={() => navigate(`/administration/users/groups/${group.id}`)}\r\n >\r\n <td className=\"px-4 py-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`w-8 h-8 rounded-full flex items-center justify-center ${\r\n group.isSecurityGroup\r\n ? 'bg-blue-500/10 text-blue-500'\r\n : 'bg-purple-500/10 text-purple-500'\r\n }`}>\r\n {group.isSecurityGroup ? (\r\n <Shield className=\"w-4 h-4\" />\r\n ) : (\r\n <Building2 className=\"w-4 h-4\" />\r\n )}\r\n </div>\r\n <div>\r\n <span className=\"font-medium text-[var(--text-primary)]\">{group.displayName}</span>\r\n {group.description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] truncate max-w-xs\">\r\n {group.description}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3\">\r\n <span className={`px-2 py-1 text-xs rounded-[var(--radius-badge)] ${\r\n group.isSecurityGroup\r\n ? 'bg-blue-500/10 text-blue-500'\r\n : 'bg-purple-500/10 text-purple-500'\r\n }`}>\r\n {group.isSecurityGroup ? t('admin:groups.securityGroup') : t('admin:groups.distributionGroup')}\r\n </span>\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)]\">\r\n <span className=\"flex items-center gap-1\">\r\n <Users className=\"w-4 h-4\" />\r\n {group.memberCount}\r\n </span>\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)]\">\r\n {getGroupHierarchyDisplay(group)}\r\n </td>\r\n <td className=\"px-4 py-3\">\r\n <div className=\"flex flex-wrap gap-1\">\r\n {group.assignedRoles.slice(0, 2).map((role) => (\r\n <span\r\n key={role.roleId}\r\n className=\"px-2 py-0.5 text-xs rounded-[var(--radius-badge)] bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]\"\r\n >\r\n {role.roleName}\r\n </span>\r\n ))}\r\n {group.assignedRoles.length > 2 && (\r\n <span className=\"px-2 py-0.5 text-xs rounded-[var(--radius-badge)] bg-[var(--bg-tertiary)] text-[var(--text-tertiary)]\">\r\n +{group.assignedRoles.length - 2}\r\n </span>\r\n )}\r\n {group.inheritedRoles.length > 0 && (\r\n <span className=\"px-2 py-0.5 text-xs rounded-[var(--radius-badge)] bg-green-500/10 text-green-600\" title={t('entra:groups.inheritedRoles')}>\r\n +{group.inheritedRoles.length} {t('entra:groups.inherited')}\r\n </span>\r\n )}\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3 text-xs text-[var(--text-tertiary)]\">\r\n {formatDate(group.lastSyncedAt)}\r\n </td>\r\n {canAssign && !isGlobalView && (\r\n <td className=\"px-4 py-3 text-right\" onClick={(e) => e.stopPropagation()}>\r\n <button\r\n onClick={() => {\r\n setSelectedGroup(group);\r\n setShowAssignModal(true);\r\n }}\r\n className=\"p-2 rounded-[var(--radius-button)] text-[var(--text-tertiary)] hover:text-[var(--color-accent-500)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n title={t('admin:groups.assignRole')}\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n </button>\r\n </td>\r\n )}\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n )}\r\n {filteredGroups.length > 0 && viewMode !== 'table' && (\r\n /* Cards View */\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n {filteredGroups.map((group) => (\r\n <button\r\n type=\"button\"\r\n key={group.id}\r\n className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-secondary)] overflow-hidden cursor-pointer hover:border-[var(--color-accent-500)] transition-colors text-left\"\r\n onClick={() => navigate(`/administration/users/groups/${group.id}`)}\r\n >\r\n {/* Card Header */}\r\n <div className=\"p-4\">\r\n <div className=\"flex items-start justify-between gap-4\">\r\n <div className=\"flex items-start gap-3 min-w-0\">\r\n <div className={`p-2.5 rounded-[var(--radius-button)] flex-shrink-0 ${\r\n group.isSecurityGroup\r\n ? 'bg-blue-500/10 text-blue-500'\r\n : 'bg-purple-500/10 text-purple-500'\r\n }`}>\r\n {group.isSecurityGroup ? (\r\n <Shield className=\"w-5 h-5\" />\r\n ) : (\r\n <Building2 className=\"w-5 h-5\" />\r\n )}\r\n </div>\r\n <div className=\"min-w-0\">\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"font-semibold text-[var(--text-primary)] truncate\">\r\n {group.displayName}\r\n </span>\r\n <span className={`px-2 py-0.5 text-xs rounded-[var(--radius-badge)] ${\r\n group.isSecurityGroup\r\n ? 'bg-blue-500/10 text-blue-500 border border-blue-500/20'\r\n : 'bg-purple-500/10 text-purple-500 border border-purple-500/20'\r\n }`}>\r\n {group.isSecurityGroup ? t('admin:groups.securityGroup') : t('admin:groups.distributionGroup')}\r\n </span>\r\n {!group.isActive && (\r\n <span className=\"px-2 py-0.5 text-xs rounded-[var(--radius-badge)] bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)]\">\r\n {t('common:inactive')}\r\n </span>\r\n )}\r\n </div>\r\n {group.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1 line-clamp-2\">\r\n {group.description}\r\n </p>\r\n )}\r\n <div className=\"flex items-center gap-4 mt-2 text-sm text-[var(--text-tertiary)] flex-wrap\">\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n loadMembers(group.id);\r\n }}\r\n className=\"flex items-center gap-1 hover:text-[var(--color-accent-500)] transition-colors\"\r\n >\r\n <Users className=\"w-4 h-4\" />\r\n {t('admin:groups.memberCount', { count: group.memberCount })}\r\n {loadingMembers === group.id && (\r\n <Loader2 className=\"w-3 h-3 animate-spin ml-1\" />\r\n )}\r\n {loadingMembers !== group.id && expandedGroupId === group.id && (\r\n <ChevronUp className=\"w-3 h-3 ml-1\" />\r\n )}\r\n {loadingMembers !== group.id && expandedGroupId !== group.id && (\r\n <ChevronDown className=\"w-3 h-3 ml-1\" />\r\n )}\r\n </button>\r\n {group.childGroupCount > 0 && (\r\n <span className=\"flex items-center gap-1 text-xs\">\r\n <GitBranch className=\"w-3 h-3\" />\r\n {group.childGroupCount} {t('entra:groups.childGroups')}\r\n </span>\r\n )}\r\n </div>\r\n {group.parentGroupName && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1 flex items-center gap-1\">\r\n <GitBranch className=\"w-3 h-3\" />\r\n {t('entra:groups.parentGroup')}: {group.parentGroupName}\r\n </p>\r\n )}\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1\">\r\n {t('entra:groups.lastSynced')}: {formatDate(group.lastSyncedAt)}\r\n </p>\r\n </div>\r\n </div>\r\n {canAssign && !isGlobalView && (\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n setSelectedGroup(group);\r\n setShowAssignModal(true);\r\n }}\r\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors flex-shrink-0\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('admin:groups.assignRole')}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* Assigned Roles */}\r\n {(group.assignedRoles.length > 0 || group.inheritedRoles.length > 0) && (\r\n <div className=\"mt-4 pt-4 border-t border-[var(--border-color)]\">\r\n {group.assignedRoles.length > 0 && (\r\n <>\r\n <h4 className=\"text-sm font-medium text-[var(--text-primary)] mb-2\">\r\n {t('admin:groups.assignedRoles')}\r\n </h4>\r\n <div className=\"flex flex-wrap gap-2 mb-3\">\r\n {group.assignedRoles.map((role) => (\r\n <div\r\n key={role.roleId}\r\n className=\"inline-flex items-center gap-2 px-3 py-1.5 rounded-[var(--radius-badge)] bg-[var(--bg-primary)] border border-[var(--border-color)] group\"\r\n >\r\n <Shield className=\"w-4 h-4 text-[var(--color-accent-500)]\" />\r\n <span className=\"text-sm text-[var(--text-primary)]\">{role.roleName}</span>\r\n {role.isInheritable && (\r\n <span className=\"text-xs text-green-600\" title={t('entra:groups.inheritableRole')}>\r\n ↓\r\n </span>\r\n )}\r\n {canAssign && (\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n handleRemoveRole(group.id, role.roleId);\r\n }}\r\n className=\"ml-1 p-0.5 rounded opacity-0 group-hover:opacity-100 hover:bg-[var(--error-bg)] text-[var(--text-tertiary)] hover:text-[var(--error-text)] transition-all\"\r\n title={t('common:remove')}\r\n >\r\n <X className=\"w-3 h-3\" />\r\n </button>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n </>\r\n )}\r\n {group.inheritedRoles.length > 0 && (\r\n <>\r\n <h4 className=\"text-xs font-medium text-[var(--text-tertiary)] mb-2 flex items-center gap-1\">\r\n <GitBranch className=\"w-3 h-3\" />\r\n {t('entra:groups.inheritedRoles')}\r\n </h4>\r\n <div className=\"flex flex-wrap gap-2\">\r\n {group.inheritedRoles.map((role) => (\r\n <div\r\n key={`${role.roleId}-${role.sourceGroupId}`}\r\n className=\"inline-flex items-center gap-2 px-2 py-1 rounded-[var(--radius-badge)] bg-green-500/5 border border-green-500/20\"\r\n title={`${t('entra:groups.inheritedFrom')} ${role.sourceGroupName}`}\r\n >\r\n <Shield className=\"w-3 h-3 text-green-600\" />\r\n <span className=\"text-xs text-green-700\">{role.roleName}</span>\r\n <span className=\"text-xs text-green-600/60\">← {role.sourceGroupName}</span>\r\n </div>\r\n ))}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Members Panel */}\r\n {expandedGroupId === group.id && members[group.id] && (\r\n <div className=\"border-t border-[var(--border-color)] bg-[var(--bg-primary)]\" onClick={(e) => e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()} role=\"presentation\">\r\n <div className=\"p-4\">\r\n <h4 className=\"text-sm font-medium text-[var(--text-primary)] mb-3 flex items-center gap-2\">\r\n <Users className=\"w-4 h-4\" />\r\n {t('admin:groups.members')} ({members[group.id].length})\r\n </h4>\r\n {members[group.id].length === 0 ? (\r\n <p className=\"text-sm text-[var(--text-tertiary)]\">\r\n {t('admin:groups.noMembers')}\r\n </p>\r\n ) : (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-2 max-h-64 overflow-y-auto\">\r\n {members[group.id].slice(0, 10).map((member) => (\r\n <Link\r\n key={member.userId}\r\n to={`/administration/users/${member.userId}`}\r\n className=\"flex items-center gap-3 p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <div className=\"w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]\">\r\n {member.fullName.charAt(0).toUpperCase()}\r\n </div>\r\n <div className=\"min-w-0 flex-1\">\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] truncate\">\r\n {member.fullName}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-tertiary)] truncate\">\r\n {member.email}\r\n </p>\r\n </div>\r\n {!member.isDirect && member.sourceGroupName && (\r\n <span className=\"text-xs text-[var(--text-tertiary)] flex items-center gap-1\" title={t('entra:groups.memberFromChildGroup')}>\r\n <GitBranch className=\"w-3 h-3\" />\r\n </span>\r\n )}\r\n </Link>\r\n ))}\r\n </div>\r\n )}\r\n {members[group.id].length > 10 && (\r\n <p className=\"mt-3 text-center text-sm text-[var(--text-tertiary)]\">\r\n {t('admin:groups.showingMembers', {\r\n shown: 10,\r\n total: members[group.id].length,\r\n })}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Assign Role Modal */}\r\n {showAssignModal && selectedGroup && (\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50\">\r\n <div className=\"w-full max-w-md rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)] shadow-xl\">\r\n <div className=\"flex items-center justify-between p-4 border-b border-[var(--border-color)]\">\r\n <h2 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('admin:groups.assignRoleTitle')}\r\n </h2>\r\n <button\r\n onClick={() => {\r\n setShowAssignModal(false);\r\n setSelectedGroup(null);\r\n }}\r\n className=\"p-1 rounded hover:bg-[var(--bg-hover)] text-[var(--text-tertiary)]\"\r\n >\r\n <X className=\"w-5 h-5\" />\r\n </button>\r\n </div>\r\n <div className=\"p-4\">\r\n <p className=\"text-sm text-[var(--text-secondary)] mb-4\">\r\n {t('admin:groups.assignRoleDescription', { group: selectedGroup.displayName })}\r\n </p>\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto\">\r\n {roles\r\n .filter((role) => !selectedGroup.assignedRoles.some(r => r.roleId === role.id))\r\n .map((role) => (\r\n <button\r\n key={role.id}\r\n onClick={() => handleAssignRole(role.id)}\r\n disabled={assigning}\r\n className=\"w-full flex items-center gap-3 p-3 rounded-[var(--radius-button)] border border-[var(--border-color)] hover:border-[var(--color-accent-500)] hover:bg-[var(--bg-hover)] transition-colors text-left disabled:opacity-50\"\r\n >\r\n <Shield className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n <div className=\"flex-1\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">{role.name}</p>\r\n {role.description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{role.description}</p>\r\n )}\r\n </div>\r\n {assigning && (\r\n <Loader2 className=\"w-4 h-4 animate-spin text-[var(--color-accent-500)]\" />\r\n )}\r\n </button>\r\n ))}\r\n {roles.filter((role) => !selectedGroup.assignedRoles.some(r => r.roleId === role.id)).length === 0 && (\r\n <p className=\"text-sm text-[var(--text-tertiary)] text-center py-4\">\r\n {t('admin:groups.allRolesAssigned')}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n </div>\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 { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n Users,\r\n RefreshCw,\r\n AlertTriangle,\r\n CheckCircle,\r\n XCircle,\r\n Mail,\r\n Calendar,\r\n ExternalLink,\r\n} from 'lucide-react';\r\nimport { adminApi, type UserListDto } from '@/services/api/adminApi';\r\nimport { DataTable, type DataTableColumn } from '@/components/ui/DataTable';\r\n\r\nexport function EntraUsersPage(): ReactElement {\r\n const { t } = useTranslation(['entra', 'common']);\r\n const navigate = useNavigate();\r\n const [loading, setLoading] = useState(true);\r\n const [users, setUsers] = useState<UserListDto[]>([]);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n setError(null);\r\n // Only fetch users synced from Entra ID (have entraObjectId)\r\n const response = await adminApi.users.getAll({ pageSize: 1000, entraOnly: true });\r\n setUsers(response?.items ?? []);\r\n } catch (err: unknown) {\r\n console.error('Failed to load users:', err);\r\n const axiosError = err as { response?: { status?: number } };\r\n if (axiosError.response?.status === 401) {\r\n setError(t('common:errors.sessionExpired'));\r\n } else if (axiosError.response?.status === 403) {\r\n setError(t('common:errors.noPermission'));\r\n } else {\r\n setError(t('entra:users.loadError'));\r\n }\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [t]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n const formatDate = (date: string | null) => {\r\n if (!date) return t('common:never');\r\n return new Intl.DateTimeFormat('fr-FR', {\r\n dateStyle: 'medium',\r\n timeStyle: 'short',\r\n }).format(new Date(date));\r\n };\r\n\r\n // Define columns for DataTable\r\n const columns: DataTableColumn<UserListDto>[] = [\r\n {\r\n key: 'fullName',\r\n label: t('entra:users.columns.user'),\r\n sortable: true,\r\n render: (user) => (\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"w-10 h-10 rounded-full bg-[var(--color-primary-100)] dark:bg-[var(--color-primary-900)] flex items-center justify-center flex-shrink-0\">\r\n <span className=\"text-sm font-medium text-[var(--color-primary-600)]\">\r\n {user.fullName?.charAt(0).toUpperCase() || '?'}\r\n </span>\r\n </div>\r\n <span className=\"font-medium text-[var(--text-primary)]\">{user.fullName}</span>\r\n </div>\r\n ),\r\n },\r\n {\r\n key: 'email',\r\n label: t('entra:users.columns.email'),\r\n sortable: true,\r\n render: (user) => (\r\n <div className=\"flex items-center gap-1 text-sm text-[var(--text-secondary)]\">\r\n <Mail className=\"w-4 h-4\" />\r\n {user.email}\r\n </div>\r\n ),\r\n },\r\n {\r\n key: 'isActive',\r\n label: t('entra:users.columns.status'),\r\n sortable: true,\r\n render: (user) =>\r\n user.isActive ? (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-1 text-xs rounded-full bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400\">\r\n <CheckCircle className=\"w-3 h-3\" />\r\n {t('common:active')}\r\n </span>\r\n ) : (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-1 text-xs rounded-full bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400\">\r\n <XCircle className=\"w-3 h-3\" />\r\n {t('common:inactive')}\r\n </span>\r\n ),\r\n },\r\n {\r\n key: 'lastEntraSyncAt',\r\n label: t('entra:users.columns.lastSync'),\r\n sortable: true,\r\n render: (user) => (\r\n <div className=\"flex items-center gap-1 text-sm text-[var(--text-secondary)]\">\r\n <Calendar className=\"w-4 h-4\" />\r\n {formatDate(user.lastEntraSyncAt)}\r\n </div>\r\n ),\r\n },\r\n {\r\n key: 'actions',\r\n label: t('entra:users.columns.actions'),\r\n align: 'right',\r\n render: (user) => (\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n navigate(`/administration/users/${user.id}`);\r\n }}\r\n className=\"inline-flex items-center gap-1 text-sm text-[var(--color-primary-600)] hover:underline\"\r\n >\r\n {t('common:viewDetails')}\r\n <ExternalLink className=\"w-4 h-4\" />\r\n </button>\r\n ),\r\n },\r\n ];\r\n\r\n // Custom search filter for users\r\n const searchFilter = (user: UserListDto, searchTerm: string) => {\r\n const search = searchTerm.toLowerCase();\r\n return (\r\n user.fullName?.toLowerCase().includes(search) ||\r\n user.email?.toLowerCase().includes(search) ||\r\n false\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('entra.title', 'Microsoft Entra ID'), href: '/administration/entra' },\r\n { label: t('entra.users', 'Users') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-[var(--color-primary-100)] dark:bg-[var(--color-primary-900)]\">\r\n <Users className=\"w-6 h-6 text-[var(--color-primary-600)]\" />\r\n </div>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('entra:users.title')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:users.subtitle', { count: users.length })}\r\n </p>\r\n </div>\r\n </div>\r\n <button\r\n onClick={loadData}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg border border-[var(--border-primary)] bg-[var(--bg-primary)] text-[var(--text-primary)] hover:bg-[var(--bg-secondary)]\"\r\n >\r\n <RefreshCw className=\"w-4 h-4\" />\r\n {t('common:refresh')}\r\n </button>\r\n </div>\r\n\r\n {/* Error */}\r\n {error && (\r\n <div className=\"p-4 rounded-lg bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800\">\r\n <div className=\"flex items-center gap-2 text-red-700 dark:text-red-400\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* DataTable */}\r\n <DataTable\r\n data={users}\r\n columns={columns}\r\n loading={loading}\r\n searchable\r\n searchPlaceholder={t('entra:users.searchPlaceholder')}\r\n searchFilter={searchFilter}\r\n pagination={{ pageSize: 20, showSizeSelector: true }}\r\n onRowClick={(user) => navigate(`/administration/users/${user.id}`)}\r\n getRowKey={(user) => user.id}\r\n emptyMessage={t('entra:users.noUsers')}\r\n emptyIcon={<Users className=\"w-12 h-12 mx-auto text-[var(--text-secondary)] opacity-50\" />}\r\n defaultSortKey=\"fullName\"\r\n striped\r\n />\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback, useRef } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n AlertTriangle,\r\n RefreshCw,\r\n Loader2,\r\n CheckCircle,\r\n} from 'lucide-react';\r\nimport {\r\n entraApi,\r\n type EntraSyncConflictDto,\r\n type ResolveConflictRequest,\r\n} from '@/services/api/entraApi';\r\nimport { ConflictCard, ResolutionModal } from '@/components/platform/administration/entra';\r\n\r\n// ============================================\r\n// Main Component\r\n// ============================================\r\n\r\nexport function EntraConflictsPage(): ReactElement {\r\n const { t } = useTranslation(['entra', 'common']);\r\n const [loading, setLoading] = useState(true);\r\n const [conflicts, setConflicts] = useState<EntraSyncConflictDto[]>([]);\r\n const [error, setError] = useState<string | null>(null);\r\n const [selectedConflict, setSelectedConflict] = useState<EntraSyncConflictDto | null>(null);\r\n const [resolving, setResolving] = useState(false);\r\n\r\n // Abort controller ref for preventing race conditions\r\n const abortControllerRef = useRef<AbortController | null>(null);\r\n const isLoadingRef = useRef(false);\r\n\r\n const loadData = useCallback(async () => {\r\n // Prevent concurrent loads\r\n if (isLoadingRef.current) return;\r\n\r\n // Cancel any pending request\r\n if (abortControllerRef.current) {\r\n abortControllerRef.current.abort();\r\n }\r\n\r\n abortControllerRef.current = new AbortController();\r\n isLoadingRef.current = true;\r\n\r\n try {\r\n setError(null);\r\n const data = await entraApi.conflicts.getAll();\r\n setConflicts(Array.isArray(data) ? data : []);\r\n } catch (err: unknown) {\r\n // Ignore abort errors\r\n if (err instanceof Error && err.name === 'AbortError') {\r\n return;\r\n }\r\n // Log error type only, not the full error object (PII protection)\r\n console.error('Failed to load conflicts:', err instanceof Error ? err.message : 'Unknown error');\r\n setConflicts([]);\r\n const axiosError = err as { response?: { status?: number } };\r\n if (axiosError.response?.status === 401) {\r\n setError(t('common:errors.sessionExpired'));\r\n } else if (axiosError.response?.status === 403) {\r\n setError(t('common:errors.noPermission'));\r\n } else {\r\n setError(t('entra:conflicts.loadError'));\r\n }\r\n } finally {\r\n isLoadingRef.current = false;\r\n setLoading(false);\r\n }\r\n }, [t]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n\r\n // Cleanup on unmount\r\n return () => {\r\n if (abortControllerRef.current) {\r\n abortControllerRef.current.abort();\r\n }\r\n };\r\n }, [loadData]);\r\n\r\n const handleResolve = useCallback(async (resolution: ResolveConflictRequest['resolution'], notes?: string) => {\r\n if (!selectedConflict || resolving) return;\r\n\r\n setResolving(true);\r\n try {\r\n await entraApi.conflicts.resolve(selectedConflict.id, {\r\n resolution,\r\n notes: notes || undefined,\r\n });\r\n setSelectedConflict(null);\r\n await loadData();\r\n } catch (err) {\r\n // Log error type only, not the full error object (PII protection)\r\n console.error('Failed to resolve conflict:', err instanceof Error ? err.message : 'Unknown error');\r\n setError(t('entra:conflicts.resolveError'));\r\n } finally {\r\n setResolving(false);\r\n }\r\n }, [selectedConflict, resolving, loadData, t]);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\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 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('entra.title', 'Microsoft Entra ID'), href: '/administration/entra' },\r\n { label: t('entra.conflicts', 'Conflicts') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--color-accent-500)]/10\">\r\n <AlertTriangle className=\"w-6 h-6 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('entra:conflicts.title')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:conflicts.subtitle', { count: conflicts.length })}\r\n </p>\r\n </div>\r\n </div>\r\n <button\r\n onClick={loadData}\r\n disabled={loading}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-tertiary)] transition-colors disabled:opacity-50\"\r\n >\r\n <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />\r\n {t('common:refresh')}\r\n </button>\r\n </div>\r\n\r\n {/* Error */}\r\n {error && (\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 justify-between\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n <button\r\n onClick={() => setError(null)}\r\n className=\"text-[var(--error-text)] hover:opacity-70\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* No Conflicts - Empty State */}\r\n {conflicts.length === 0 ? (\r\n <div className=\"text-center py-16 px-6 rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)]\">\r\n <div className=\"mx-auto w-16 h-16 rounded-full bg-[var(--success-bg)] flex items-center justify-center mb-4\">\r\n <CheckCircle className=\"w-8 h-8 text-[var(--success-text)]\" />\r\n </div>\r\n <h2 className=\"text-xl font-semibold text-[var(--text-primary)] mb-2\">\r\n {t('entra:conflicts.noConflicts')}\r\n </h2>\r\n <p className=\"text-[var(--text-secondary)] max-w-md mx-auto\">\r\n {t('entra:conflicts.noConflictsDescription')}\r\n </p>\r\n </div>\r\n ) : (\r\n /* Conflicts Grid */\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {conflicts.map((conflict) => (\r\n <ConflictCard\r\n key={conflict.id}\r\n conflict={conflict}\r\n onResolve={setSelectedConflict}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Resolve Modal */}\r\n {selectedConflict && (\r\n <ResolutionModal\r\n conflict={selectedConflict}\r\n onClose={() => setSelectedConflict(null)}\r\n onResolve={handleResolve}\r\n resolving={resolving}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback, type ReactNode } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport {\r\n Settings,\r\n Key,\r\n Eye,\r\n EyeOff,\r\n Save,\r\n AlertTriangle,\r\n CheckCircle,\r\n ExternalLink,\r\n Shield,\r\n Clock,\r\n Loader2,\r\n TestTube,\r\n Users,\r\n Layers,\r\n Building2,\r\n Copy,\r\n Check,\r\n GitMerge,\r\n Filter,\r\n} from 'lucide-react';\r\nimport { entraApi } from '@/services/api/entraApi';\r\nimport type { TestConnectionResult, EntraConfigurationDto } from '@/services/api/entraApi';\r\n\r\ninterface EntraCredentials {\r\n tenantId: string;\r\n clientId: string;\r\n clientSecret: string;\r\n}\r\n\r\ninterface SyncSettings {\r\n syncEnabled: boolean;\r\n syncIntervalMinutes: number;\r\n useDeltaSync: boolean;\r\n defaultConflictResolution: 'ManualReview' | 'EntraWins' | 'LocalWins';\r\n autoCreateReferences: boolean;\r\n // User sync filters\r\n syncOnlyActiveUsers: boolean;\r\n syncUserTypes: string; // comma-separated: member, guest, shared, room, equipment\r\n}\r\n\r\n// Available user types for sync\r\n// Note: shared, room, equipment require mailboxSettings which is not available in bulk user listing API\r\nconst USER_TYPES = [\r\n { id: 'member', labelKey: 'userTypes.member', descriptionKey: 'userTypes.memberDescription', supported: true },\r\n { id: 'guest', labelKey: 'userTypes.guest', descriptionKey: 'userTypes.guestDescription', supported: true },\r\n { id: 'shared', labelKey: 'userTypes.shared', descriptionKey: 'userTypes.sharedDescription', supported: false },\r\n { id: 'room', labelKey: 'userTypes.room', descriptionKey: 'userTypes.roomDescription', supported: false },\r\n { id: 'equipment', labelKey: 'userTypes.equipment', descriptionKey: 'userTypes.equipmentDescription', supported: false },\r\n];\r\n\r\n// Required permissions for Microsoft Graph API\r\nconst REQUIRED_PERMISSIONS = [\r\n { code: 'User.Read.All', descriptionKey: 'userReadAll' },\r\n { code: 'Group.Read.All', descriptionKey: 'groupReadAll' },\r\n { code: 'GroupMember.Read.All', descriptionKey: 'groupMemberReadAll' },\r\n];\r\n\r\n// ============================================\r\n// Reusable Components\r\n// ============================================\r\n\r\ninterface SectionCardProps {\r\n readonly icon: LucideIcon;\r\n readonly title: string;\r\n readonly description?: string;\r\n readonly action?: ReactNode;\r\n readonly children: ReactNode;\r\n readonly className?: string;\r\n}\r\n\r\nfunction SectionCard({ icon: Icon, title, description, action, children, className = '' }: SectionCardProps) {\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] shadow-sm overflow-hidden ${className}`}>\r\n {/* Header */}\r\n <div className=\"px-6 py-4 border-b border-[var(--border-subtle)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30\">\r\n <Icon className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <div>\r\n <h2 className=\"text-base font-semibold text-[var(--text-primary)]\">{title}</h2>\r\n {description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{description}</p>\r\n )}\r\n </div>\r\n </div>\r\n {action}\r\n </div>\r\n </div>\r\n {/* Content */}\r\n <div className=\"p-6\">\r\n {children}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\ninterface ToggleProps {\r\n readonly checked: boolean;\r\n readonly onChange: () => void;\r\n readonly label: string;\r\n readonly description?: string;\r\n}\r\n\r\nfunction Toggle({ checked, onChange, label, description }: ToggleProps) {\r\n return (\r\n <div className=\"flex items-center justify-between py-3\">\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <label className=\"text-sm font-medium text-[var(--text-primary)]\">{label}</label>\r\n {description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{description}</p>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n role=\"switch\"\r\n aria-checked={checked}\r\n onClick={onChange}\r\n className={`relative inline-flex h-6 w-11 flex-shrink-0 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] focus:ring-offset-2 focus:ring-offset-[var(--bg-primary)] ${\r\n checked ? 'bg-[var(--color-accent-600)]' : 'bg-[var(--bg-tertiary)]'\r\n }`}\r\n >\r\n <span\r\n className={`inline-block h-4 w-4 transform rounded-full bg-[var(--toggle-knob)] shadow-md transition-transform ${\r\n checked ? 'translate-x-6' : 'translate-x-1'\r\n }`}\r\n />\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\n// ============================================\r\n// Validation\r\n// ============================================\r\n\r\nconst isValidGuid = (value: string): boolean => {\r\n if (!value) return true;\r\n const guidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\r\n return guidRegex.test(value);\r\n};\r\n\r\nconst useEntraSettings = () => {\r\n const { t } = useTranslation(['entra', 'common']);\r\n const [loading, setLoading] = useState(true);\r\n const [saving, setSaving] = useState(false);\r\n const [testing, setTesting] = useState(false);\r\n const [testResult, setTestResult] = useState<TestConnectionResult | null>(null);\r\n const [showSecret, setShowSecret] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n const [hasExistingSecret, setHasExistingSecret] = useState(false);\r\n const [copiedPermission, setCopiedPermission] = useState<string | null>(null);\r\n const [validationErrors, setValidationErrors] = useState<{\r\n tenantId?: string;\r\n clientId?: string;\r\n }>({});\r\n\r\n const [credentials, setCredentials] = useState<EntraCredentials>({\r\n tenantId: '',\r\n clientId: '',\r\n clientSecret: '',\r\n });\r\n\r\n const [syncSettings, setSyncSettings] = useState<SyncSettings>({\r\n syncEnabled: false,\r\n syncIntervalMinutes: 60,\r\n useDeltaSync: true,\r\n defaultConflictResolution: 'ManualReview',\r\n autoCreateReferences: true,\r\n syncOnlyActiveUsers: true,\r\n syncUserTypes: 'member',\r\n });\r\n\r\n return {\r\n t, loading, setLoading, saving, setSaving, testing, setTesting,\r\n testResult, setTestResult, showSecret, setShowSecret, error, setError,\r\n success, setSuccess, hasExistingSecret, setHasExistingSecret,\r\n copiedPermission, setCopiedPermission, validationErrors, setValidationErrors,\r\n credentials, setCredentials, syncSettings, setSyncSettings\r\n };\r\n};\r\n\r\n// ============================================\r\n// Helpers\r\n// ============================================\r\n\r\nfunction getCheckboxCardClass(isDisabled: boolean, isChecked: boolean): string {\r\n if (isDisabled) return 'opacity-50 cursor-not-allowed border-[var(--border-color)] bg-[var(--bg-tertiary)]';\r\n if (isChecked) return 'cursor-pointer border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20';\r\n return 'cursor-pointer border-[var(--border-color)] bg-[var(--bg-secondary)] hover:bg-[var(--bg-tertiary)]';\r\n}\r\n\r\n// ============================================\r\n// Main Component\r\n// ============================================\r\n\r\nexport function EntraSettingsPage(): ReactElement {\r\n const state = useEntraSettings();\r\n\r\n const loadConfiguration = useCallback(async () => {\r\n try {\r\n state.setLoading(true);\r\n const config: EntraConfigurationDto = await entraApi.settings.getConfiguration();\r\n\r\n state.setCredentials({\r\n tenantId: config.tenantId || '',\r\n clientId: config.clientId || '',\r\n clientSecret: '',\r\n });\r\n state.setHasExistingSecret(config.hasClientSecret);\r\n\r\n state.setSyncSettings({\r\n syncEnabled: config.syncEnabled,\r\n syncIntervalMinutes: config.syncIntervalMinutes,\r\n useDeltaSync: config.useDeltaSync,\r\n defaultConflictResolution: config.defaultConflictResolution as SyncSettings['defaultConflictResolution'],\r\n autoCreateReferences: config.autoCreateReferences,\r\n syncOnlyActiveUsers: config.syncOnlyActiveUsers ?? true,\r\n syncUserTypes: config.syncUserTypes ?? 'member',\r\n });\r\n } catch (err) {\r\n console.error('Failed to load configuration:', err);\r\n state.setError(state.t('entra:settings.saveError'));\r\n } finally {\r\n state.setLoading(false);\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, []); // React setters are stable, no need to include them in dependencies\r\n\r\n useEffect(() => {\r\n loadConfiguration();\r\n }, [loadConfiguration]);\r\n\r\n const handleCopyPermission = async (code: string) => {\r\n try {\r\n await navigator.clipboard.writeText(code);\r\n state.setCopiedPermission(code);\r\n setTimeout(() => state.setCopiedPermission(null), 2000);\r\n } catch (err) {\r\n console.error('Failed to copy:', err);\r\n }\r\n };\r\n\r\n const validateCredentialField = (field: 'tenantId' | 'clientId', value: string) => {\r\n const errorKey = isValidGuid(value) ? undefined : state.t('entra:settings.invalidGuidFormat');\r\n state.setValidationErrors(prev => ({ ...prev, [field]: errorKey }));\r\n };\r\n\r\n const handleCredentialChange = (field: keyof EntraCredentials, value: string) => {\r\n state.setCredentials(prev => ({ ...prev, [field]: value }));\r\n if (field === 'tenantId' || field === 'clientId') {\r\n validateCredentialField(field, value);\r\n }\r\n };\r\n\r\n const hasValidationErrors = Boolean(\r\n state.validationErrors.tenantId || state.validationErrors.clientId\r\n );\r\n\r\n const handleTestConnection = async () => {\r\n state.setTesting(true);\r\n state.setTestResult(null);\r\n state.setError(null);\r\n state.setSuccess(null);\r\n try {\r\n let result: TestConnectionResult;\r\n\r\n if (state.credentials.clientSecret) {\r\n result = await entraApi.settings.testConnection({\r\n tenantId: state.credentials.tenantId,\r\n clientId: state.credentials.clientId,\r\n clientSecret: state.credentials.clientSecret,\r\n });\r\n } else if (state.hasExistingSecret) {\r\n result = await entraApi.settings.testStoredConnection();\r\n } else {\r\n state.setError(state.t('entra:settings.testFailed'));\r\n state.setTesting(false);\r\n return;\r\n }\r\n\r\n state.setTestResult(result);\r\n if (result.success) {\r\n state.setSuccess(state.t('entra:settings.testSuccess'));\r\n } else {\r\n state.setError(result.errorMessage || state.t('entra:settings.testFailed'));\r\n }\r\n } catch (err) {\r\n console.error('Connection test failed:', err);\r\n state.setTestResult({ success: false, errorMessage: state.t('entra:settings.testFailed'), tenantName: null, userCount: null, groupCount: null });\r\n state.setError(state.t('entra:settings.testFailed'));\r\n } finally {\r\n state.setTesting(false);\r\n }\r\n };\r\n\r\n const handleSaveCredentials = async () => {\r\n state.setSaving(true);\r\n state.setError(null);\r\n state.setSuccess(null);\r\n try {\r\n await entraApi.settings.saveCredentials({\r\n tenantId: state.credentials.tenantId,\r\n clientId: state.credentials.clientId,\r\n clientSecret: state.credentials.clientSecret,\r\n });\r\n state.setSuccess(state.t('entra:settings.credentialsSaved'));\r\n state.setHasExistingSecret(true);\r\n state.setCredentials((prev) => ({ ...prev, clientSecret: '' }));\r\n } catch (err) {\r\n console.error('Failed to save credentials:', err);\r\n state.setError(state.t('entra:settings.saveError'));\r\n } finally {\r\n state.setSaving(false);\r\n }\r\n };\r\n\r\n const handleSaveSettings = async () => {\r\n state.setSaving(true);\r\n state.setError(null);\r\n state.setSuccess(null);\r\n try {\r\n await entraApi.settings.saveSyncSettings({\r\n syncEnabled: state.syncSettings.syncEnabled,\r\n syncIntervalMinutes: state.syncSettings.syncIntervalMinutes,\r\n useDeltaSync: state.syncSettings.useDeltaSync,\r\n defaultConflictResolution: state.syncSettings.defaultConflictResolution,\r\n autoCreateReferences: state.syncSettings.autoCreateReferences,\r\n syncOnlyActiveUsers: state.syncSettings.syncOnlyActiveUsers,\r\n syncUserTypes: state.syncSettings.syncUserTypes,\r\n });\r\n state.setSuccess(state.t('entra:settings.settingsSaved'));\r\n } catch (err) {\r\n console.error('Failed to save settings:', err);\r\n state.setError(state.t('entra:settings.saveError'));\r\n } finally {\r\n state.setSaving(false);\r\n }\r\n };\r\n\r\n if (state.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 return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: state.t('header.title'), href: '/administration' },\r\n { label: state.t('entra.title', 'Microsoft Entra ID'), href: '/administration/entra' },\r\n { label: state.t('entra.settings', 'Settings') }\r\n ]}\r\n />\r\n\r\n {/* Page Header */}\r\n <div className=\"flex items-center gap-4\">\r\n <div className=\"p-3 rounded-[var(--radius-card)] bg-gradient-to-br from-[var(--color-accent-500)] to-[var(--color-accent-700)] shadow-lg\">\r\n <Settings className=\"w-7 h-7 text-white\" />\r\n </div>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {state.t('entra:settings.title')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {state.t('entra:settings.subtitle')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Required Permissions Warning */}\r\n <div className=\"rounded-[var(--radius-card)] border-2 border-[var(--warning-border)] bg-[var(--warning-bg)] overflow-hidden\">\r\n <div className=\"px-5 py-4\">\r\n <div className=\"flex items-start gap-4\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--warning-border)]\">\r\n <Shield className=\"w-5 h-5 text-[var(--warning-text)]\" />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center justify-between gap-4 mb-2\">\r\n <h2 className=\"font-semibold text-[var(--warning-text)]\">\r\n {state.t('entra:settings.permissionsWarningTitle')}\r\n </h2>\r\n <a\r\n href=\"https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade\"\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--warning-border)] text-[var(--warning-text)] hover:opacity-80 transition-opacity\"\r\n >\r\n {state.t('entra:settings.configureInAzure')}\r\n <ExternalLink className=\"w-3.5 h-3.5\" />\r\n </a>\r\n </div>\r\n <p className=\"text-sm text-[var(--warning-text)] opacity-90 mb-4\">\r\n {state.t('entra:settings.permissionsWarningDescription')}\r\n </p>\r\n\r\n {/* Copyable Permissions */}\r\n <div className=\"flex flex-wrap gap-2\">\r\n {REQUIRED_PERMISSIONS.map((perm) => (\r\n <button\r\n key={perm.code}\r\n onClick={() => handleCopyPermission(perm.code)}\r\n className=\"group inline-flex items-center gap-2 px-3 py-2 rounded-[var(--radius-button)] bg-[var(--bg-primary)] border border-[var(--warning-border)] hover:border-[var(--warning-dot)] transition-all hover:shadow-sm\"\r\n title={state.t(`entra:settings.permissions.${perm.descriptionKey}`)}\r\n >\r\n <code className=\"text-sm font-mono font-medium text-[var(--text-primary)]\">{perm.code}</code>\r\n {state.copiedPermission === perm.code ? (\r\n <Check className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n ) : (\r\n <Copy className=\"w-4 h-4 text-[var(--warning-text)] group-hover:opacity-80\" />\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Error/Success Messages */}\r\n {state.error && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)] flex-shrink-0\" />\r\n <span className=\"text-sm text-[var(--error-text)]\">{state.error}</span>\r\n </div>\r\n )}\r\n\r\n {state.success && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)] flex-shrink-0\" />\r\n <span className=\"text-sm text-[var(--success-text)]\">{state.success}</span>\r\n </div>\r\n )}\r\n\r\n {/* Main Content Grid */}\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {/* ============================================ */}\r\n {/* Left Column - Credentials */}\r\n {/* ============================================ */}\r\n <SectionCard\r\n icon={Key}\r\n title={state.t('entra:settings.credentials')}\r\n description=\"Azure AD Application\"\r\n action={\r\n <a\r\n href=\"https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade\"\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"inline-flex items-center gap-1.5 text-sm text-[var(--color-accent-500)] hover:text-[var(--color-accent-600)] transition-colors\"\r\n >\r\n {state.t('entra:settings.azurePortal')}\r\n <ExternalLink className=\"w-4 h-4\" />\r\n </a>\r\n }\r\n >\r\n <div className=\"space-y-5\">\r\n {/* Tenant ID */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {state.t('entra:settings.tenantId')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={state.credentials.tenantId}\r\n onChange={(e) => handleCredentialChange('tenantId', e.target.value)}\r\n placeholder=\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\r\n autoComplete=\"off\"\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border bg-[var(--bg-secondary)] text-[var(--text-primary)] font-mono text-sm focus:outline-none focus:ring-2 focus:border-transparent transition-shadow ${\r\n state.validationErrors.tenantId\r\n ? 'border-[var(--error-border)] focus:ring-[var(--error-border)]'\r\n : 'border-[var(--border-color)] focus:ring-[var(--color-accent-500)]'\r\n }`}\r\n />\r\n {state.validationErrors.tenantId ? (\r\n <p className=\"mt-1.5 text-xs text-[var(--error-text)]\">{state.validationErrors.tenantId}</p>\r\n ) : (\r\n <p className=\"mt-1.5 text-xs text-[var(--text-tertiary)]\">{state.t('entra:settings.tenantIdHelp')}</p>\r\n )}\r\n </div>\r\n\r\n {/* Client ID */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {state.t('entra:settings.clientId')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={state.credentials.clientId}\r\n onChange={(e) => handleCredentialChange('clientId', e.target.value)}\r\n placeholder=\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\r\n autoComplete=\"off\"\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border bg-[var(--bg-secondary)] text-[var(--text-primary)] font-mono text-sm focus:outline-none focus:ring-2 focus:border-transparent transition-shadow ${\r\n state.validationErrors.clientId\r\n ? 'border-[var(--error-border)] focus:ring-[var(--error-border)]'\r\n : 'border-[var(--border-color)] focus:ring-[var(--color-accent-500)]'\r\n }`}\r\n />\r\n {state.validationErrors.clientId ? (\r\n <p className=\"mt-1.5 text-xs text-[var(--error-text)]\">{state.validationErrors.clientId}</p>\r\n ) : (\r\n <p className=\"mt-1.5 text-xs text-[var(--text-tertiary)]\">{state.t('entra:settings.clientIdHelp')}</p>\r\n )}\r\n </div>\r\n\r\n {/* Client Secret */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {state.t('entra:settings.clientSecret')}\r\n {state.hasExistingSecret && (\r\n <span className=\"ml-2 inline-flex items-center gap-1 text-xs text-[var(--success-text)]\">\r\n <CheckCircle className=\"w-3 h-3\" />\r\n {state.t('common:configured')}\r\n </span>\r\n )}\r\n </label>\r\n <div className=\"relative\">\r\n <input\r\n type={state.showSecret ? 'text' : 'password'}\r\n value={state.credentials.clientSecret}\r\n onChange={(e) => handleCredentialChange('clientSecret', e.target.value)}\r\n placeholder={state.hasExistingSecret ? '••••••••••••••••••••••••••••••••••••••••' : 'OvA8Q~xxxxxxxxxxxxxxxxxxxxxxxxxxxx'}\r\n autoComplete=\"new-password\"\r\n className=\"w-full px-3 py-2.5 pr-10 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] font-mono text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-transparent transition-shadow\"\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => state.setShowSecret(!state.showSecret)}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 p-1 text-[var(--text-tertiary)] hover:text-[var(--text-primary)] transition-colors\"\r\n >\r\n {state.showSecret ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </button>\r\n </div>\r\n <p className=\"mt-1.5 text-xs text-[var(--text-tertiary)]\">{state.t('entra:settings.clientSecretHelp')}</p>\r\n </div>\r\n\r\n {/* Action Buttons */}\r\n <div className=\"flex items-center gap-3 pt-2\">\r\n <button\r\n onClick={handleTestConnection}\r\n disabled={state.testing || hasValidationErrors || !state.credentials.tenantId || !state.credentials.clientId || (!state.credentials.clientSecret && !state.hasExistingSecret)}\r\n className=\"inline-flex items-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {state.testing && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {!state.testing && state.testResult?.success && <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />}\r\n {!state.testing && state.testResult && !state.testResult.success && <AlertTriangle className=\"w-4 h-4 text-[var(--error-text)]\" />}\r\n {!state.testing && !state.testResult && <TestTube className=\"w-4 h-4\" />}\r\n {state.t('entra:settings.testConnection')}\r\n </button>\r\n <button\r\n onClick={handleSaveCredentials}\r\n disabled={state.saving || hasValidationErrors || !state.credentials.tenantId || !state.credentials.clientId || !state.credentials.clientSecret}\r\n className=\"inline-flex items-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm\"\r\n >\r\n {state.saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {state.t('common:save')}\r\n </button>\r\n </div>\r\n\r\n {/* Test Result Details */}\r\n {state.testResult?.success && (\r\n <div className=\"mt-4 p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <div className=\"flex items-center gap-2 mb-3\">\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n <span className=\"font-medium text-[var(--success-text)]\">\r\n {state.t('entra:settings.connectionSuccessful')}\r\n </span>\r\n </div>\r\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-3\">\r\n {state.testResult.tenantName && (\r\n <div className=\"flex items-center gap-2 p-2 rounded-[var(--radius-button)] bg-[var(--bg-primary)]\">\r\n <Building2 className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n <div className=\"min-w-0\">\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{state.t('entra:settings.tenantName')}</p>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] truncate\">{state.testResult.tenantName}</p>\r\n </div>\r\n </div>\r\n )}\r\n {state.testResult.userCount !== null && (\r\n <div className=\"flex items-center gap-2 p-2 rounded-[var(--radius-button)] bg-[var(--bg-primary)]\">\r\n <Users className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n <div>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{state.t('entra:settings.userCount')}</p>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">{state.testResult.userCount}</p>\r\n </div>\r\n </div>\r\n )}\r\n {state.testResult.groupCount !== null && (\r\n <div className=\"flex items-center gap-2 p-2 rounded-[var(--radius-button)] bg-[var(--bg-primary)]\">\r\n <Layers className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n <div>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{state.t('entra:settings.groupCount')}</p>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">{state.testResult.groupCount}</p>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </SectionCard>\r\n\r\n {/* ============================================ */}\r\n {/* Right Column - Sync Settings Stack */}\r\n {/* ============================================ */}\r\n <div className=\"space-y-6\">\r\n {/* Sync Configuration */}\r\n <SectionCard\r\n icon={Clock}\r\n title={state.t('entra:settings.syncSettings')}\r\n description=\"Scheduling & Performance\"\r\n >\r\n <div className=\"divide-y divide-[var(--border-subtle)]\">\r\n <Toggle\r\n checked={state.syncSettings.syncEnabled}\r\n onChange={() => state.setSyncSettings((prev) => ({ ...prev, syncEnabled: !prev.syncEnabled }))}\r\n label={state.t('entra:settings.syncEnabled')}\r\n description={state.t('entra:settings.syncEnabledHelp')}\r\n />\r\n\r\n <div className=\"py-4\">\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-2\">\r\n {state.t('entra:settings.syncInterval')}\r\n </label>\r\n <select\r\n value={state.syncSettings.syncIntervalMinutes}\r\n onChange={(e) => state.setSyncSettings((prev) => ({ ...prev, syncIntervalMinutes: Number(e.target.value) }))}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow\"\r\n >\r\n <option value={15}>15 {state.t('common:minutes')}</option>\r\n <option value={30}>30 {state.t('common:minutes')}</option>\r\n <option value={60}>1 {state.t('common:hour')}</option>\r\n <option value={120}>2 {state.t('common:hours')}</option>\r\n <option value={360}>6 {state.t('common:hours')}</option>\r\n <option value={720}>12 {state.t('common:hours')}</option>\r\n <option value={1440}>24 {state.t('common:hours')}</option>\r\n </select>\r\n </div>\r\n\r\n <Toggle\r\n checked={state.syncSettings.useDeltaSync}\r\n onChange={() => state.setSyncSettings((prev) => ({ ...prev, useDeltaSync: !prev.useDeltaSync }))}\r\n label={state.t('entra:settings.useDeltaSync')}\r\n description={state.t('entra:settings.useDeltaSyncHelp')}\r\n />\r\n\r\n <Toggle\r\n checked={state.syncSettings.autoCreateReferences}\r\n onChange={() => state.setSyncSettings((prev) => ({ ...prev, autoCreateReferences: !prev.autoCreateReferences }))}\r\n label={state.t('entra:settings.autoCreateReferences')}\r\n description={state.t('entra:settings.autoCreateReferencesHelp')}\r\n />\r\n </div>\r\n </SectionCard>\r\n\r\n {/* Conflict Resolution */}\r\n <SectionCard\r\n icon={GitMerge}\r\n title={state.t('entra:settings.conflictResolution')}\r\n description=\"Data Priority\"\r\n >\r\n <div>\r\n <select\r\n value={state.syncSettings.defaultConflictResolution}\r\n onChange={(e) => state.setSyncSettings((prev) => ({ ...prev, defaultConflictResolution: e.target.value as SyncSettings['defaultConflictResolution'] }))}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow\"\r\n >\r\n <option value=\"ManualReview\">{state.t('entra:settings.conflictResolutions.manualReview')}</option>\r\n <option value=\"EntraWins\">{state.t('entra:settings.conflictResolutions.entraWins')}</option>\r\n <option value=\"LocalWins\">{state.t('entra:settings.conflictResolutions.localWins')}</option>\r\n </select>\r\n <p className=\"mt-2 text-xs text-[var(--text-tertiary)]\">\r\n {state.t('entra:settings.conflictResolutionHelp')}\r\n </p>\r\n </div>\r\n </SectionCard>\r\n\r\n {/* User Filters */}\r\n <SectionCard\r\n icon={Filter}\r\n title={state.t('entra:settings.userSyncFilters')}\r\n description=\"User Types & Filters\"\r\n >\r\n <div className=\"space-y-4\">\r\n <Toggle\r\n checked={state.syncSettings.syncOnlyActiveUsers}\r\n onChange={() => state.setSyncSettings((prev) => ({ ...prev, syncOnlyActiveUsers: !prev.syncOnlyActiveUsers }))}\r\n label={state.t('entra:settings.syncOnlyActiveUsers')}\r\n description={state.t('entra:settings.syncOnlyActiveUsersHelp')}\r\n />\r\n\r\n <div className=\"pt-2 border-t border-[var(--border-subtle)]\">\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-2\">\r\n {state.t('entra:settings.syncUserTypesLabel')}\r\n </label>\r\n <p className=\"text-xs text-[var(--text-tertiary)] mb-3\">\r\n {state.t('entra:settings.syncUserTypesHelp')}\r\n </p>\r\n <div className=\"space-y-2\">\r\n {USER_TYPES.map((userType) => {\r\n const selectedTypes = state.syncSettings.syncUserTypes.split(',').map(t => t.trim()).filter(Boolean);\r\n const isChecked = selectedTypes.includes(userType.id);\r\n const isDisabled = !userType.supported;\r\n\r\n const handleToggle = () => {\r\n if (isDisabled) return;\r\n let newTypes: string[];\r\n if (isChecked) {\r\n newTypes = selectedTypes.filter(t => t !== userType.id);\r\n } else {\r\n newTypes = [...selectedTypes, userType.id];\r\n }\r\n if (newTypes.length === 0) newTypes = ['member'];\r\n state.setSyncSettings(prev => ({ ...prev, syncUserTypes: newTypes.join(',') }));\r\n };\r\n\r\n return (\r\n <label\r\n key={userType.id}\r\n className={`flex items-start gap-3 p-3 rounded-[var(--radius-button)] border transition-all ${\r\n getCheckboxCardClass(isDisabled, isChecked)\r\n }`}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={isChecked}\r\n onChange={handleToggle}\r\n disabled={isDisabled}\r\n className=\"mt-0.5 w-4 h-4 rounded border-[var(--border-color)] text-[var(--color-accent-600)] focus:ring-[var(--color-accent-500)] disabled:opacity-50\"\r\n />\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {state.t(`entra:settings.${userType.labelKey}`)}\r\n </span>\r\n {isDisabled && (\r\n <span className=\"text-xs px-1.5 py-0.5 rounded bg-[var(--bg-tertiary)] text-[var(--text-tertiary)]\">\r\n {state.t('common:comingSoon')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">\r\n {state.t(`entra:settings.${userType.descriptionKey}`)}\r\n </p>\r\n </div>\r\n </label>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n </div>\r\n </SectionCard>\r\n\r\n {/* Save Button */}\r\n <div className=\"flex justify-end\">\r\n <button\r\n onClick={handleSaveSettings}\r\n disabled={state.saving}\r\n className=\"inline-flex items-center gap-2 px-6 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm\"\r\n >\r\n {state.saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {state.t('common:save')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"names":["SyncStatusCard","resourceType","Icon","status","lastFullSyncAt","lastDeltaSyncAt","totalItemsSynced","pendingConflicts","lastError","syncing","canSync","onSync","formatDate","t","statusConfig","CheckCircle","XCircle","Loader2","Clock","StatusIcon","jsxs","jsx","Database","Calendar","RefreshCw","AlertCircle","Tooltip","EntraDashboardPage","useTranslation","hasPermission","useAuth","loading","setLoading","useState","refreshing","setRefreshing","syncStatus","setSyncStatus","error","setError","setSyncing","lastSyncResult","setLastSyncResult","loadData","useCallback","entraApi","err","axiosError","useEffect","handleRefresh","handleSync","type","result","handleForceFullSync","date","getResourceIcon","Users","Building2","Link2","Cloud","totalPendingConflicts","sum","s","Breadcrumb","Play","AlertTriangle","getGroupHierarchyDisplay","group","GitBranch","EntraGroupsPage","currentTenant","isGlobalView","useTenant","navigate","useNavigate","groups","setGroups","roles","setRoles","searchQuery","setSearchQuery","selectedGroup","setSelectedGroup","showAssignModal","setShowAssignModal","expandedGroupId","setExpandedGroupId","members","setMembers","loadingMembers","setLoadingMembers","viewMode","setViewMode","groupTypeFilter","setGroupTypeFilter","assigning","setAssigning","canAssign","groupsData","rolesData","adminApi","loadMembers","groupId","data","prev","reloadGroupsAndRoles","safeGroupsData","handleAssignRole","roleId","isInheritable","updatedGroup","g","handleRemoveRole","filteredGroups","matchesSearch","matchesType","X","Search","e","Filter","LayoutGrid","List","Shield","role","Plus","ChevronUp","ChevronDown","Fragment","member","Link","r","EntraUsersPage","users","setUsers","response","columns","user","Mail","ExternalLink","searchFilter","searchTerm","search","DataTable","EntraConflictsPage","conflicts","setConflicts","selectedConflict","setSelectedConflict","resolving","setResolving","abortControllerRef","useRef","isLoadingRef","handleResolve","resolution","notes","conflict","ConflictCard","ResolutionModal","USER_TYPES","REQUIRED_PERMISSIONS","SectionCard","title","description","action","children","className","Toggle","checked","onChange","label","isValidGuid","value","useEntraSettings","saving","setSaving","testing","setTesting","testResult","setTestResult","showSecret","setShowSecret","success","setSuccess","hasExistingSecret","setHasExistingSecret","copiedPermission","setCopiedPermission","validationErrors","setValidationErrors","credentials","setCredentials","syncSettings","setSyncSettings","getCheckboxCardClass","isDisabled","isChecked","EntraSettingsPage","state","loadConfiguration","config","handleCopyPermission","code","validateCredentialField","field","errorKey","handleCredentialChange","hasValidationErrors","handleTestConnection","handleSaveCredentials","handleSaveSettings","Settings","perm","Check","Copy","Key","EyeOff","Eye","TestTube","Save","Layers","GitMerge","userType","selectedTypes","handleToggle","newTypes"],"mappings":"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"}
1
+ {"version":3,"file":"index--NGcBYUu.js","sources":["../../src/pages/platform/administration/entra/EntraDashboardPage.tsx","../../src/pages/platform/administration/entra/EntraGroupsPage.tsx","../../src/pages/platform/administration/entra/EntraUsersPage.tsx","../../src/pages/platform/administration/entra/EntraConflictsPage.tsx","../../src/pages/platform/administration/entra/EntraSettingsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { Tooltip } from '@/components/ui/Tooltip';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport {\r\n Cloud,\r\n RefreshCw,\r\n Loader2,\r\n AlertTriangle,\r\n CheckCircle,\r\n XCircle,\r\n Clock,\r\n Users,\r\n Building2,\r\n Link2,\r\n Play,\r\n AlertCircle,\r\n Calendar,\r\n Database,\r\n} from 'lucide-react';\r\nimport {\r\n entraApi,\r\n type EntraSyncStatusDto,\r\n type EntraSyncResultDto,\r\n} from '@/services/api/entraApi';\r\n\r\n// ============================================\r\n// Sync Status Card Component\r\n// ============================================\r\n\r\ninterface SyncStatusCardProps {\r\n readonly resourceType: string;\r\n readonly icon: LucideIcon;\r\n readonly status: string;\r\n readonly lastFullSyncAt: string | null;\r\n readonly lastDeltaSyncAt: string | null;\r\n readonly totalItemsSynced: number;\r\n readonly pendingConflicts: number;\r\n readonly lastError: string | null;\r\n readonly syncing: boolean;\r\n readonly canSync: boolean;\r\n readonly onSync: () => void;\r\n readonly formatDate: (date: string | null) => string;\r\n readonly t: (key: string, options?: Record<string, unknown>) => string;\r\n}\r\n\r\nfunction SyncStatusCard({\r\n resourceType,\r\n icon: Icon,\r\n status,\r\n lastFullSyncAt,\r\n lastDeltaSyncAt,\r\n totalItemsSynced,\r\n pendingConflicts,\r\n lastError,\r\n syncing,\r\n canSync,\r\n onSync,\r\n formatDate,\r\n t,\r\n}: SyncStatusCardProps) {\r\n const getStatusConfig = () => {\r\n switch (status) {\r\n case 'Success':\r\n return {\r\n icon: CheckCircle,\r\n color: 'text-[var(--success-text)]',\r\n bg: 'bg-[var(--success-bg)]',\r\n label: t('common:success'),\r\n };\r\n case 'Failed':\r\n return {\r\n icon: XCircle,\r\n color: 'text-[var(--error-text)]',\r\n bg: 'bg-[var(--error-bg)]',\r\n label: t('common:failed'),\r\n };\r\n case 'Running':\r\n return {\r\n icon: Loader2,\r\n color: 'text-[var(--color-accent-500)]',\r\n bg: 'bg-[var(--color-accent-100)]',\r\n label: t('common:running'),\r\n animate: true,\r\n };\r\n default:\r\n return {\r\n icon: Clock,\r\n color: 'text-[var(--text-tertiary)]',\r\n bg: 'bg-[var(--bg-tertiary)]',\r\n label: t('common:pending'),\r\n };\r\n }\r\n };\r\n\r\n const statusConfig = getStatusConfig();\r\n const StatusIcon = statusConfig.icon;\r\n\r\n return (\r\n <div className=\"h-full flex flex-col rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] overflow-hidden shadow-sm hover:shadow-md transition-shadow\">\r\n {/* Header with gradient */}\r\n <div className=\"px-4 py-3 bg-gradient-to-r from-[var(--color-accent-500)]/10 to-[var(--color-accent-600)]/5 border-b border-[var(--border-color)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-[var(--color-accent-500)]/20\">\r\n <Icon className=\"w-5 h-5 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <h3 className=\"font-semibold text-[var(--text-primary)]\">\r\n {t(`entra:resourceTypes.${resourceType.toLowerCase()}`)}\r\n </h3>\r\n </div>\r\n <div className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium ${statusConfig.bg} ${statusConfig.color}`}>\r\n <StatusIcon className={`w-3.5 h-3.5 ${statusConfig.animate ? 'animate-spin' : ''}`} />\r\n {statusConfig.label}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Stats Grid */}\r\n <div className=\"flex-1 flex flex-col p-4\">\r\n <div className=\"grid grid-cols-3 gap-3 mb-4\">\r\n <div className=\"text-center p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-center gap-1 mb-1\">\r\n <Database className=\"w-3.5 h-3.5 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <p className=\"text-xl font-bold text-[var(--text-primary)]\">{totalItemsSynced.toLocaleString()}</p>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{t('entra:dashboard.itemsSynced')}</p>\r\n </div>\r\n <div className=\"text-center p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-center gap-1 mb-1\">\r\n <Calendar className=\"w-3.5 h-3.5 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] truncate\" title={formatDate(lastFullSyncAt)}>\r\n {lastFullSyncAt ? new Date(lastFullSyncAt).toLocaleDateString('fr-FR', { day: 'numeric', month: 'short' }) : '-'}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{t('entra:dashboard.lastFullSync')}</p>\r\n </div>\r\n <div className=\"text-center p-3 rounded-lg bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-center gap-1 mb-1\">\r\n <RefreshCw className=\"w-3.5 h-3.5 text-[var(--text-tertiary)]\" />\r\n </div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] truncate\" title={formatDate(lastDeltaSyncAt)}>\r\n {lastDeltaSyncAt ? new Date(lastDeltaSyncAt).toLocaleDateString('fr-FR', { day: 'numeric', month: 'short' }) : '-'}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{t('entra:dashboard.lastDeltaSync')}</p>\r\n </div>\r\n </div>\r\n\r\n {/* Pending Conflicts Warning */}\r\n {pendingConflicts > 0 && (\r\n <div className=\"flex items-center gap-2 p-3 mb-4 rounded-lg bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <AlertCircle className=\"w-4 h-4 text-[var(--warning-text)] flex-shrink-0\" />\r\n <span className=\"text-sm text-[var(--warning-text)] font-medium\">\r\n {pendingConflicts} {t('entra:dashboard.pendingConflicts')}\r\n </span>\r\n </div>\r\n )}\r\n\r\n {/* Last Error */}\r\n {lastError && (\r\n <div className=\"p-3 mb-4 rounded-lg bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <p className=\"text-xs text-[var(--error-text)] line-clamp-2\">{lastError}</p>\r\n </div>\r\n )}\r\n\r\n {/* Action Button - Always at bottom */}\r\n <Tooltip\r\n content={!canSync ? t('entra:dashboard.noSyncPermission') : undefined}\r\n position=\"top\"\r\n variant=\"error\"\r\n disabled={canSync}\r\n >\r\n <button\r\n onClick={onSync}\r\n disabled={syncing || !canSync}\r\n className=\"mt-auto w-full inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm\"\r\n >\r\n {syncing ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <RefreshCw className=\"w-4 h-4\" />\r\n )}\r\n {t('entra:dashboard.syncNow')}\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport function EntraDashboardPage(): ReactElement {\r\n const { t } = useTranslation(['entra', 'common']);\r\n const { hasPermission } = useAuth();\r\n const [loading, setLoading] = useState(true);\r\n const [refreshing, setRefreshing] = useState(false);\r\n const [syncStatus, setSyncStatus] = useState<EntraSyncStatusDto[]>([]);\r\n const [error, setError] = useState<string | null>(null);\r\n const [syncing, setSyncing] = useState<string | null>(null);\r\n const [lastSyncResult, setLastSyncResult] = useState<EntraSyncResultDto | null>(null);\r\n\r\n // Permission check for sync operations\r\n const canSync = hasPermission('administration.entra.execute');\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setError(null);\r\n const status = await entraApi.dashboard.getSyncStatus();\r\n setSyncStatus(Array.isArray(status) ? status : []);\r\n } catch (err: unknown) {\r\n console.error('Failed to load Entra dashboard data:', err);\r\n setSyncStatus([]);\r\n const axiosError = err as { response?: { status?: number } };\r\n if (axiosError.response?.status === 401) {\r\n setError(t('common:errors.sessionExpired'));\r\n } else if (axiosError.response?.status === 403) {\r\n setError(t('common:errors.noPermission'));\r\n } else {\r\n setError(t('entra:dashboard.loadError'));\r\n }\r\n } finally {\r\n setLoading(false);\r\n setRefreshing(false);\r\n }\r\n }, [t]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n const handleRefresh = () => {\r\n setRefreshing(true);\r\n loadData();\r\n };\r\n\r\n const handleSync = async (type: 'all' | 'users' | 'groups' | 'memberships') => {\r\n setSyncing(type);\r\n setLastSyncResult(null);\r\n try {\r\n let result: EntraSyncResultDto;\r\n switch (type) {\r\n case 'users':\r\n result = await entraApi.sync.syncUsers();\r\n break;\r\n case 'groups':\r\n result = await entraApi.sync.syncGroups();\r\n break;\r\n case 'memberships':\r\n result = await entraApi.sync.syncMemberships();\r\n break;\r\n default:\r\n result = await entraApi.sync.syncAll();\r\n }\r\n setLastSyncResult(result);\r\n await loadData();\r\n } catch (err: unknown) {\r\n console.error('Sync failed:', err);\r\n const axiosError = err as { response?: { status?: number } };\r\n if (axiosError.response?.status === 403) {\r\n setError(t('entra:dashboard.syncPermissionDenied'));\r\n } else if (axiosError.response?.status === 401) {\r\n setError(t('common:errors.sessionExpired'));\r\n } else {\r\n setError(t('entra:dashboard.syncError'));\r\n }\r\n } finally {\r\n setSyncing(null);\r\n }\r\n };\r\n\r\n const handleForceFullSync = async () => {\r\n if (!confirm(t('entra:dashboard.forceFullSyncConfirm'))) return;\r\n setSyncing('force');\r\n try {\r\n await entraApi.sync.forceFullSync();\r\n await loadData();\r\n } catch (err: unknown) {\r\n console.error('Force full sync failed:', err);\r\n const axiosError = err as { response?: { status?: number } };\r\n if (axiosError.response?.status === 403) {\r\n setError(t('entra:dashboard.syncPermissionDenied'));\r\n } else if (axiosError.response?.status === 401) {\r\n setError(t('common:errors.sessionExpired'));\r\n } else {\r\n setError(t('entra:dashboard.syncError'));\r\n }\r\n } finally {\r\n setSyncing(null);\r\n }\r\n };\r\n\r\n const formatDate = (date: string | null) => {\r\n if (!date) return t('common:never');\r\n return new Intl.DateTimeFormat('fr-FR', {\r\n dateStyle: 'medium',\r\n timeStyle: 'short',\r\n }).format(new Date(date));\r\n };\r\n\r\n const getResourceIcon = (resourceType: string): LucideIcon => {\r\n switch (resourceType) {\r\n case 'Users':\r\n return Users;\r\n case 'Groups':\r\n return Building2;\r\n case 'Memberships':\r\n return Link2;\r\n default:\r\n return Cloud;\r\n }\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\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 const totalPendingConflicts = syncStatus.reduce((sum, s) => sum + s.pendingConflicts, 0);\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('entra.title', 'Microsoft Entra ID'), href: '/administration/entra' },\r\n { label: t('entra.dashboard', 'Dashboard') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--color-accent-500)]/10\">\r\n <Cloud className=\"w-6 h-6 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('entra:dashboard.title')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:dashboard.subtitle')}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={handleRefresh}\r\n disabled={refreshing}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] disabled:opacity-50 transition-colors\"\r\n >\r\n <RefreshCw className={`w-4 h-4 ${refreshing ? 'animate-spin' : ''}`} />\r\n {t('common:refresh')}\r\n </button>\r\n <Tooltip\r\n content={!canSync ? t('entra:dashboard.noSyncPermission') : undefined}\r\n position=\"bottom\"\r\n variant=\"error\"\r\n disabled={canSync}\r\n >\r\n <button\r\n onClick={() => handleSync('all')}\r\n disabled={syncing !== null || !canSync}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {syncing === 'all' ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Play className=\"w-4 h-4\" />\r\n )}\r\n {t('entra:dashboard.syncAll')}\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </div>\r\n\r\n {/* Error */}\r\n {error && (\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 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Pending Conflicts Warning */}\r\n {totalPendingConflicts > 0 && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <div className=\"flex items-center gap-2 text-[var(--warning-text)]\">\r\n <AlertCircle className=\"w-5 h-5\" />\r\n <span>\r\n {t('entra:dashboard.conflictsWarning', { count: totalPendingConflicts })}\r\n </span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Last Sync Result */}\r\n {lastSyncResult && (\r\n <div className={`p-4 rounded-[var(--radius-card)] border ${\r\n lastSyncResult.success\r\n ? 'bg-[var(--success-bg)] border-[var(--success-border)]'\r\n : 'bg-[var(--error-bg)] border-[var(--error-border)]'\r\n }`}>\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n {lastSyncResult.success ? (\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n ) : (\r\n <XCircle className=\"w-5 h-5 text-[var(--error-text)]\" />\r\n )}\r\n <span className={lastSyncResult.success ? 'text-[var(--success-text)]' : 'text-[var(--error-text)]'}>\r\n {lastSyncResult.success\r\n ? t('entra:dashboard.syncSuccess')\r\n : t('entra:dashboard.syncFailed')}\r\n </span>\r\n </div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:dashboard.syncStats', {\r\n created: lastSyncResult.created,\r\n updated: lastSyncResult.updated,\r\n deleted: lastSyncResult.deleted,\r\n })}\r\n </div>\r\n </div>\r\n {lastSyncResult.errorMessage && (\r\n <p className=\"mt-2 text-sm text-[var(--error-text)]\">\r\n {lastSyncResult.errorMessage}\r\n </p>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Sync Status Cards */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\r\n {syncStatus.map((status) => (\r\n <SyncStatusCard\r\n key={status.resourceType}\r\n resourceType={status.resourceType}\r\n icon={getResourceIcon(status.resourceType)}\r\n status={status.status}\r\n lastFullSyncAt={status.lastFullSyncAt}\r\n lastDeltaSyncAt={status.lastDeltaSyncAt}\r\n totalItemsSynced={status.totalItemsSynced}\r\n pendingConflicts={status.pendingConflicts}\r\n lastError={status.lastError}\r\n syncing={syncing === status.resourceType.toLowerCase()}\r\n canSync={canSync}\r\n onSync={() => handleSync(status.resourceType.toLowerCase() as 'users' | 'groups' | 'memberships')}\r\n formatDate={formatDate}\r\n t={t}\r\n />\r\n ))}\r\n </div>\r\n\r\n {/* Force Full Sync */}\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h3 className=\"font-semibold text-[var(--text-primary)]\">\r\n {t('entra:dashboard.forceFullSync')}\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:dashboard.forceFullSyncDescription')}\r\n </p>\r\n </div>\r\n <Tooltip\r\n content={!canSync ? t('entra:dashboard.noSyncPermission') : undefined}\r\n position=\"left\"\r\n variant=\"error\"\r\n disabled={canSync}\r\n >\r\n <button\r\n onClick={handleForceFullSync}\r\n disabled={syncing !== null || !canSync}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--warning-border)] bg-[var(--warning-bg)] text-[var(--warning-text)] hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {syncing === 'force' ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <AlertTriangle className=\"w-4 h-4\" />\r\n )}\r\n {t('entra:dashboard.forceFullSync')}\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Link, useNavigate } from 'react-router-dom';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n Cloud,\r\n RefreshCw,\r\n Loader2,\r\n AlertTriangle,\r\n Search,\r\n Users,\r\n Shield,\r\n Plus,\r\n X,\r\n ChevronDown,\r\n ChevronUp,\r\n LayoutGrid,\r\n List,\r\n Filter,\r\n Building2,\r\n GitBranch,\r\n} from 'lucide-react';\r\nimport {\r\n entraApi,\r\n type EntraGroupDto,\r\n type EntraGroupMemberDto,\r\n} from '@/services/api/entraApi';\r\nimport { adminApi, type RoleListDto } from '@/services/api/adminApi';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\n\r\ntype ViewMode = 'cards' | 'table';\r\ntype GroupTypeFilter = 'all' | 'security' | 'distribution';\r\n\r\ninterface GroupWithMembers extends EntraGroupDto {\r\n membersLoaded?: EntraGroupMemberDto[];\r\n}\r\n\r\nconst getGroupHierarchyDisplay = (group: EntraGroupDto) => {\r\n if (group.parentGroupName) {\r\n return (\r\n <span className=\"flex items-center gap-1 text-xs\">\r\n <GitBranch className=\"w-3 h-3\" />\r\n {group.parentGroupName}\r\n </span>\r\n );\r\n }\r\n if (group.childGroupCount > 0) {\r\n return (\r\n <span className=\"flex items-center gap-1 text-xs text-[var(--text-tertiary)]\">\r\n {group.childGroupCount} child groups\r\n </span>\r\n );\r\n }\r\n return <span className=\"text-xs text-[var(--text-tertiary)]\">-</span>;\r\n};\r\n\r\nexport function EntraGroupsPage(): ReactElement {\r\n const { t } = useTranslation(['entra', 'admin', 'common']);\r\n const { hasPermission } = useAuth();\r\n const { currentTenant, isGlobalView } = useTenant();\r\n const navigate = useNavigate();\r\n const [loading, setLoading] = useState(true);\r\n const [groups, setGroups] = useState<GroupWithMembers[]>([]);\r\n const [roles, setRoles] = useState<RoleListDto[]>([]);\r\n const [error, setError] = useState<string | null>(null);\r\n const [searchQuery, setSearchQuery] = useState('');\r\n const [selectedGroup, setSelectedGroup] = useState<GroupWithMembers | null>(null);\r\n const [showAssignModal, setShowAssignModal] = useState(false);\r\n const [expandedGroupId, setExpandedGroupId] = useState<string | null>(null);\r\n const [members, setMembers] = useState<Record<string, EntraGroupMemberDto[]>>({});\r\n const [loadingMembers, setLoadingMembers] = useState<string | null>(null);\r\n const [viewMode, setViewMode] = useState<ViewMode>('cards');\r\n const [groupTypeFilter, setGroupTypeFilter] = useState<GroupTypeFilter>('all');\r\n const [assigning, setAssigning] = useState(false);\r\n\r\n const canAssign = hasPermission('administration.entra.assign');\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setError(null);\r\n const [groupsData, rolesData] = await Promise.all([\r\n entraApi.groups.getAll(),\r\n adminApi.roles.getAssignable(),\r\n ]);\r\n setGroups(Array.isArray(groupsData) ? groupsData : []);\r\n setRoles(Array.isArray(rolesData) ? rolesData : []);\r\n } catch (err: unknown) {\r\n console.error('Failed to load Entra groups:', err);\r\n setGroups([]);\r\n setRoles([]);\r\n const axiosError = err as { response?: { status?: number; data?: { code?: string } } };\r\n if (axiosError.response?.status === 401) {\r\n setError(t('common:errors.sessionExpired'));\r\n } else if (axiosError.response?.status === 403) {\r\n setError(t('common:errors.noPermission'));\r\n } else if (axiosError.response?.data?.code === 'TENANT_REQUIRED') {\r\n setError(t('entra:groups.tenantRequired'));\r\n } else {\r\n setError(t('entra:groups.loadError'));\r\n }\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [t, currentTenant?.id, isGlobalView]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n const loadMembers = async (groupId: string) => {\r\n if (members[groupId]) {\r\n setExpandedGroupId(expandedGroupId === groupId ? null : groupId);\r\n return;\r\n }\r\n\r\n setLoadingMembers(groupId);\r\n try {\r\n const data = await entraApi.groups.getMembers(groupId);\r\n setMembers(prev => ({ ...prev, [groupId]: data }));\r\n setExpandedGroupId(groupId);\r\n } catch (err) {\r\n console.error('Failed to load members:', err);\r\n setError(t('entra:groups.loadMembersError'));\r\n } finally {\r\n setLoadingMembers(null);\r\n }\r\n };\r\n\r\n const reloadGroupsAndRoles = useCallback(async () => {\r\n const [groupsData, rolesData] = await Promise.all([\r\n entraApi.groups.getAll(),\r\n adminApi.roles.getAssignable(),\r\n ]);\r\n const safeGroupsData = Array.isArray(groupsData) ? groupsData : [];\r\n setGroups(safeGroupsData);\r\n setRoles(Array.isArray(rolesData) ? rolesData : []);\r\n return safeGroupsData;\r\n }, [currentTenant?.id]);\r\n\r\n const handleAssignRole = async (roleId: string, isInheritable: boolean = true) => {\r\n if (!selectedGroup) return;\r\n setAssigning(true);\r\n try {\r\n await entraApi.groups.assignRole(selectedGroup.id, { roleId, isInheritable });\r\n const safeGroupsData = await reloadGroupsAndRoles();\r\n const updatedGroup = safeGroupsData.find(g => g.id === selectedGroup.id);\r\n if (updatedGroup) setSelectedGroup(updatedGroup);\r\n } catch (err) {\r\n console.error('Failed to assign role:', err);\r\n setError(t('entra:groups.assignError'));\r\n } finally {\r\n setAssigning(false);\r\n }\r\n };\r\n\r\n const handleRemoveRole = async (groupId: string, roleId: string) => {\r\n if (!confirm(t('entra:groups.removeRoleConfirm'))) return;\r\n try {\r\n await entraApi.groups.removeRole(groupId, roleId);\r\n await reloadGroupsAndRoles();\r\n if (selectedGroup?.id === groupId) {\r\n const updatedGroups = await entraApi.groups.getAll();\r\n const updatedGroup = updatedGroups.find(g => g.id === groupId);\r\n if (updatedGroup) setSelectedGroup(updatedGroup);\r\n }\r\n } catch (err) {\r\n console.error('Failed to remove role:', err);\r\n setError(t('entra:groups.removeError'));\r\n }\r\n };\r\n\r\n const filteredGroups = groups.filter((g) => {\r\n const matchesSearch =\r\n g.displayName.toLowerCase().includes(searchQuery.toLowerCase()) ||\r\n g.description?.toLowerCase().includes(searchQuery.toLowerCase());\r\n\r\n const matchesType =\r\n groupTypeFilter === 'all' ||\r\n (groupTypeFilter === 'security' && g.isSecurityGroup) ||\r\n (groupTypeFilter === 'distribution' && !g.isSecurityGroup);\r\n\r\n return matchesSearch && matchesType;\r\n });\r\n\r\n const formatDate = (date: string | null) => {\r\n if (!date) return '-';\r\n return new Intl.DateTimeFormat('fr-FR', {\r\n dateStyle: 'medium',\r\n timeStyle: 'short',\r\n }).format(new Date(date));\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\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 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('entra.title', 'Microsoft Entra ID'), href: '/administration/entra' },\r\n { label: t('entra.groups', 'Groups') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-blue-500/10\">\r\n <Cloud className=\"w-6 h-6 text-blue-500\" />\r\n </div>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('entra:groups.title')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:groups.subtitle', { count: groups.length })}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={loadData}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <RefreshCw className=\"w-4 h-4\" />\r\n {t('common:refresh')}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Info banner */}\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-blue-500/10 border border-blue-500/20\">\r\n <div className=\"flex items-start gap-3\">\r\n <Cloud className=\"w-5 h-5 text-blue-500 flex-shrink-0 mt-0.5\" />\r\n <div>\r\n <p className=\"text-sm text-[var(--text-primary)]\">\r\n {t('entra:groups.syncedInfo')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n {t('entra:groups.syncedInfoDescription')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Error */}\r\n {error && (\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 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n <button\r\n onClick={() => setError(null)}\r\n className=\"ml-auto p-1 hover:bg-[var(--error-text)]/10 rounded\"\r\n >\r\n <X className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Search & Filters */}\r\n <div className=\"flex flex-col sm:flex-row gap-4\">\r\n {/* Search */}\r\n <div className=\"relative flex-1\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n placeholder={t('entra:groups.searchPlaceholder')}\r\n value={searchQuery}\r\n onChange={(e) => setSearchQuery(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)] placeholder:text-[var(--text-tertiary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n\r\n {/* Type Filter */}\r\n <div className=\"flex items-center gap-2\">\r\n <Filter className=\"w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <select\r\n value={groupTypeFilter}\r\n onChange={(e) => setGroupTypeFilter(e.target.value as GroupTypeFilter)}\r\n className=\"px-3 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=\"all\">{t('admin:groups.allTypes')}</option>\r\n <option value=\"security\">{t('admin:groups.securityGroup')}</option>\r\n <option value=\"distribution\">{t('admin:groups.distributionGroup')}</option>\r\n </select>\r\n </div>\r\n\r\n {/* View Mode Toggle */}\r\n <div className=\"flex items-center gap-1 p-1 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n <button\r\n onClick={() => setViewMode('cards')}\r\n className={`p-2 rounded-[var(--radius-button)] transition-colors ${\r\n viewMode === 'cards'\r\n ? 'bg-[var(--color-accent-500)] text-white'\r\n : 'text-[var(--text-tertiary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n title={t('admin:groups.cardView')}\r\n >\r\n <LayoutGrid className=\"w-4 h-4\" />\r\n </button>\r\n <button\r\n onClick={() => setViewMode('table')}\r\n className={`p-2 rounded-[var(--radius-button)] transition-colors ${\r\n viewMode === 'table'\r\n ? 'bg-[var(--color-accent-500)] text-white'\r\n : 'text-[var(--text-tertiary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n title={t('admin:groups.tableView')}\r\n >\r\n <List className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Groups List */}\r\n {filteredGroups.length === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-secondary)]\">\r\n {searchQuery || groupTypeFilter !== 'all'\r\n ? t('admin:groups.noResults')\r\n : t('entra:groups.noGroups')}\r\n </div>\r\n )}\r\n {filteredGroups.length > 0 && viewMode === 'table' && (\r\n /* Table View */\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] overflow-hidden\">\r\n <table className=\"w-full\">\r\n <thead className=\"bg-[var(--bg-secondary)]\">\r\n <tr>\r\n <th className=\"px-4 py-3 text-left text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('admin:groups.groupName')}\r\n </th>\r\n <th className=\"px-4 py-3 text-left text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('common:type')}\r\n </th>\r\n <th className=\"px-4 py-3 text-left text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('admin:groups.members')}\r\n </th>\r\n <th className=\"px-4 py-3 text-left text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('entra:groups.hierarchy')}\r\n </th>\r\n <th className=\"px-4 py-3 text-left text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('admin:groups.assignedRoles')}\r\n </th>\r\n <th className=\"px-4 py-3 text-left text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('entra:groups.lastSynced')}\r\n </th>\r\n {canAssign && !isGlobalView && (\r\n <th className=\"px-4 py-3 text-right text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('common:actionsColumn')}\r\n </th>\r\n )}\r\n </tr>\r\n </thead>\r\n <tbody className=\"divide-y divide-[var(--border-color)]\">\r\n {filteredGroups.map((group) => (\r\n <tr\r\n key={group.id}\r\n className=\"hover:bg-[var(--bg-hover)] cursor-pointer\"\r\n onClick={() => navigate(`/administration/users/groups/${group.id}`)}\r\n >\r\n <td className=\"px-4 py-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`w-8 h-8 rounded-full flex items-center justify-center ${\r\n group.isSecurityGroup\r\n ? 'bg-blue-500/10 text-blue-500'\r\n : 'bg-purple-500/10 text-purple-500'\r\n }`}>\r\n {group.isSecurityGroup ? (\r\n <Shield className=\"w-4 h-4\" />\r\n ) : (\r\n <Building2 className=\"w-4 h-4\" />\r\n )}\r\n </div>\r\n <div>\r\n <span className=\"font-medium text-[var(--text-primary)]\">{group.displayName}</span>\r\n {group.description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] truncate max-w-xs\">\r\n {group.description}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3\">\r\n <span className={`px-2 py-1 text-xs rounded-[var(--radius-badge)] ${\r\n group.isSecurityGroup\r\n ? 'bg-blue-500/10 text-blue-500'\r\n : 'bg-purple-500/10 text-purple-500'\r\n }`}>\r\n {group.isSecurityGroup ? t('admin:groups.securityGroup') : t('admin:groups.distributionGroup')}\r\n </span>\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)]\">\r\n <span className=\"flex items-center gap-1\">\r\n <Users className=\"w-4 h-4\" />\r\n {group.memberCount}\r\n </span>\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)]\">\r\n {getGroupHierarchyDisplay(group)}\r\n </td>\r\n <td className=\"px-4 py-3\">\r\n <div className=\"flex flex-wrap gap-1\">\r\n {group.assignedRoles.slice(0, 2).map((role) => (\r\n <span\r\n key={role.roleId}\r\n className=\"px-2 py-0.5 text-xs rounded-[var(--radius-badge)] bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]\"\r\n >\r\n {role.roleName}\r\n </span>\r\n ))}\r\n {group.assignedRoles.length > 2 && (\r\n <span className=\"px-2 py-0.5 text-xs rounded-[var(--radius-badge)] bg-[var(--bg-tertiary)] text-[var(--text-tertiary)]\">\r\n +{group.assignedRoles.length - 2}\r\n </span>\r\n )}\r\n {group.inheritedRoles.length > 0 && (\r\n <span className=\"px-2 py-0.5 text-xs rounded-[var(--radius-badge)] bg-green-500/10 text-green-600\" title={t('entra:groups.inheritedRoles')}>\r\n +{group.inheritedRoles.length} {t('entra:groups.inherited')}\r\n </span>\r\n )}\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3 text-xs text-[var(--text-tertiary)]\">\r\n {formatDate(group.lastSyncedAt)}\r\n </td>\r\n {canAssign && !isGlobalView && (\r\n <td className=\"px-4 py-3 text-right\" onClick={(e) => e.stopPropagation()}>\r\n <button\r\n onClick={() => {\r\n setSelectedGroup(group);\r\n setShowAssignModal(true);\r\n }}\r\n className=\"p-2 rounded-[var(--radius-button)] text-[var(--text-tertiary)] hover:text-[var(--color-accent-500)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n title={t('admin:groups.assignRole')}\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n </button>\r\n </td>\r\n )}\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n )}\r\n {filteredGroups.length > 0 && viewMode !== 'table' && (\r\n /* Cards View */\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n {filteredGroups.map((group) => (\r\n <button\r\n type=\"button\"\r\n key={group.id}\r\n className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-secondary)] overflow-hidden cursor-pointer hover:border-[var(--color-accent-500)] transition-colors text-left\"\r\n onClick={() => navigate(`/administration/users/groups/${group.id}`)}\r\n >\r\n {/* Card Header */}\r\n <div className=\"p-4\">\r\n <div className=\"flex items-start justify-between gap-4\">\r\n <div className=\"flex items-start gap-3 min-w-0\">\r\n <div className={`p-2.5 rounded-[var(--radius-button)] flex-shrink-0 ${\r\n group.isSecurityGroup\r\n ? 'bg-blue-500/10 text-blue-500'\r\n : 'bg-purple-500/10 text-purple-500'\r\n }`}>\r\n {group.isSecurityGroup ? (\r\n <Shield className=\"w-5 h-5\" />\r\n ) : (\r\n <Building2 className=\"w-5 h-5\" />\r\n )}\r\n </div>\r\n <div className=\"min-w-0\">\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"font-semibold text-[var(--text-primary)] truncate\">\r\n {group.displayName}\r\n </span>\r\n <span className={`px-2 py-0.5 text-xs rounded-[var(--radius-badge)] ${\r\n group.isSecurityGroup\r\n ? 'bg-blue-500/10 text-blue-500 border border-blue-500/20'\r\n : 'bg-purple-500/10 text-purple-500 border border-purple-500/20'\r\n }`}>\r\n {group.isSecurityGroup ? t('admin:groups.securityGroup') : t('admin:groups.distributionGroup')}\r\n </span>\r\n {!group.isActive && (\r\n <span className=\"px-2 py-0.5 text-xs rounded-[var(--radius-badge)] bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)]\">\r\n {t('common:inactive')}\r\n </span>\r\n )}\r\n </div>\r\n {group.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mt-1 line-clamp-2\">\r\n {group.description}\r\n </p>\r\n )}\r\n <div className=\"flex items-center gap-4 mt-2 text-sm text-[var(--text-tertiary)] flex-wrap\">\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n loadMembers(group.id);\r\n }}\r\n className=\"flex items-center gap-1 hover:text-[var(--color-accent-500)] transition-colors\"\r\n >\r\n <Users className=\"w-4 h-4\" />\r\n {t('admin:groups.memberCount', { count: group.memberCount })}\r\n {loadingMembers === group.id && (\r\n <Loader2 className=\"w-3 h-3 animate-spin ml-1\" />\r\n )}\r\n {loadingMembers !== group.id && expandedGroupId === group.id && (\r\n <ChevronUp className=\"w-3 h-3 ml-1\" />\r\n )}\r\n {loadingMembers !== group.id && expandedGroupId !== group.id && (\r\n <ChevronDown className=\"w-3 h-3 ml-1\" />\r\n )}\r\n </button>\r\n {group.childGroupCount > 0 && (\r\n <span className=\"flex items-center gap-1 text-xs\">\r\n <GitBranch className=\"w-3 h-3\" />\r\n {group.childGroupCount} {t('entra:groups.childGroups')}\r\n </span>\r\n )}\r\n </div>\r\n {group.parentGroupName && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1 flex items-center gap-1\">\r\n <GitBranch className=\"w-3 h-3\" />\r\n {t('entra:groups.parentGroup')}: {group.parentGroupName}\r\n </p>\r\n )}\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-1\">\r\n {t('entra:groups.lastSynced')}: {formatDate(group.lastSyncedAt)}\r\n </p>\r\n </div>\r\n </div>\r\n {canAssign && !isGlobalView && (\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n setSelectedGroup(group);\r\n setShowAssignModal(true);\r\n }}\r\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors flex-shrink-0\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('admin:groups.assignRole')}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* Assigned Roles */}\r\n {(group.assignedRoles.length > 0 || group.inheritedRoles.length > 0) && (\r\n <div className=\"mt-4 pt-4 border-t border-[var(--border-color)]\">\r\n {group.assignedRoles.length > 0 && (\r\n <>\r\n <h4 className=\"text-sm font-medium text-[var(--text-primary)] mb-2\">\r\n {t('admin:groups.assignedRoles')}\r\n </h4>\r\n <div className=\"flex flex-wrap gap-2 mb-3\">\r\n {group.assignedRoles.map((role) => (\r\n <div\r\n key={role.roleId}\r\n className=\"inline-flex items-center gap-2 px-3 py-1.5 rounded-[var(--radius-badge)] bg-[var(--bg-primary)] border border-[var(--border-color)] group\"\r\n >\r\n <Shield className=\"w-4 h-4 text-[var(--color-accent-500)]\" />\r\n <span className=\"text-sm text-[var(--text-primary)]\">{role.roleName}</span>\r\n {role.isInheritable && (\r\n <span className=\"text-xs text-green-600\" title={t('entra:groups.inheritableRole')}>\r\n ↓\r\n </span>\r\n )}\r\n {canAssign && (\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n handleRemoveRole(group.id, role.roleId);\r\n }}\r\n className=\"ml-1 p-0.5 rounded opacity-0 group-hover:opacity-100 hover:bg-[var(--error-bg)] text-[var(--text-tertiary)] hover:text-[var(--error-text)] transition-all\"\r\n title={t('common:remove')}\r\n >\r\n <X className=\"w-3 h-3\" />\r\n </button>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n </>\r\n )}\r\n {group.inheritedRoles.length > 0 && (\r\n <>\r\n <h4 className=\"text-xs font-medium text-[var(--text-tertiary)] mb-2 flex items-center gap-1\">\r\n <GitBranch className=\"w-3 h-3\" />\r\n {t('entra:groups.inheritedRoles')}\r\n </h4>\r\n <div className=\"flex flex-wrap gap-2\">\r\n {group.inheritedRoles.map((role) => (\r\n <div\r\n key={`${role.roleId}-${role.sourceGroupId}`}\r\n className=\"inline-flex items-center gap-2 px-2 py-1 rounded-[var(--radius-badge)] bg-green-500/5 border border-green-500/20\"\r\n title={`${t('entra:groups.inheritedFrom')} ${role.sourceGroupName}`}\r\n >\r\n <Shield className=\"w-3 h-3 text-green-600\" />\r\n <span className=\"text-xs text-green-700\">{role.roleName}</span>\r\n <span className=\"text-xs text-green-600/60\">← {role.sourceGroupName}</span>\r\n </div>\r\n ))}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Members Panel */}\r\n {expandedGroupId === group.id && members[group.id] && (\r\n <div className=\"border-t border-[var(--border-color)] bg-[var(--bg-primary)]\" onClick={(e) => e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()} role=\"presentation\">\r\n <div className=\"p-4\">\r\n <h4 className=\"text-sm font-medium text-[var(--text-primary)] mb-3 flex items-center gap-2\">\r\n <Users className=\"w-4 h-4\" />\r\n {t('admin:groups.members')} ({members[group.id].length})\r\n </h4>\r\n {members[group.id].length === 0 ? (\r\n <p className=\"text-sm text-[var(--text-tertiary)]\">\r\n {t('admin:groups.noMembers')}\r\n </p>\r\n ) : (\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-2 max-h-64 overflow-y-auto\">\r\n {members[group.id].slice(0, 10).map((member) => (\r\n <Link\r\n key={member.userId}\r\n to={`/administration/users/${member.userId}`}\r\n className=\"flex items-center gap-3 p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <div className=\"w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium bg-[var(--color-accent-500)]/10 text-[var(--color-accent-500)]\">\r\n {member.fullName.charAt(0).toUpperCase()}\r\n </div>\r\n <div className=\"min-w-0 flex-1\">\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] truncate\">\r\n {member.fullName}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-tertiary)] truncate\">\r\n {member.email}\r\n </p>\r\n </div>\r\n {!member.isDirect && member.sourceGroupName && (\r\n <span className=\"text-xs text-[var(--text-tertiary)] flex items-center gap-1\" title={t('entra:groups.memberFromChildGroup')}>\r\n <GitBranch className=\"w-3 h-3\" />\r\n </span>\r\n )}\r\n </Link>\r\n ))}\r\n </div>\r\n )}\r\n {members[group.id].length > 10 && (\r\n <p className=\"mt-3 text-center text-sm text-[var(--text-tertiary)]\">\r\n {t('admin:groups.showingMembers', {\r\n shown: 10,\r\n total: members[group.id].length,\r\n })}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Assign Role Modal */}\r\n {showAssignModal && selectedGroup && (\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50\">\r\n <div className=\"w-full max-w-md rounded-[var(--radius-card)] bg-[var(--bg-secondary)] border border-[var(--border-color)] shadow-xl\">\r\n <div className=\"flex items-center justify-between p-4 border-b border-[var(--border-color)]\">\r\n <h2 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('admin:groups.assignRoleTitle')}\r\n </h2>\r\n <button\r\n onClick={() => {\r\n setShowAssignModal(false);\r\n setSelectedGroup(null);\r\n }}\r\n className=\"p-1 rounded hover:bg-[var(--bg-hover)] text-[var(--text-tertiary)]\"\r\n >\r\n <X className=\"w-5 h-5\" />\r\n </button>\r\n </div>\r\n <div className=\"p-4\">\r\n <p className=\"text-sm text-[var(--text-secondary)] mb-4\">\r\n {t('admin:groups.assignRoleDescription', { group: selectedGroup.displayName })}\r\n </p>\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto\">\r\n {roles\r\n .filter((role) => !selectedGroup.assignedRoles.some(r => r.roleId === role.id))\r\n .map((role) => (\r\n <button\r\n key={role.id}\r\n onClick={() => handleAssignRole(role.id)}\r\n disabled={assigning}\r\n className=\"w-full flex items-center gap-3 p-3 rounded-[var(--radius-button)] border border-[var(--border-color)] hover:border-[var(--color-accent-500)] hover:bg-[var(--bg-hover)] transition-colors text-left disabled:opacity-50\"\r\n >\r\n <Shield className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n <div className=\"flex-1\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">{role.name}</p>\r\n {role.description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{role.description}</p>\r\n )}\r\n </div>\r\n {assigning && (\r\n <Loader2 className=\"w-4 h-4 animate-spin text-[var(--color-accent-500)]\" />\r\n )}\r\n </button>\r\n ))}\r\n {roles.filter((role) => !selectedGroup.assignedRoles.some(r => r.roleId === role.id)).length === 0 && (\r\n <p className=\"text-sm text-[var(--text-tertiary)] text-center py-4\">\r\n {t('admin:groups.allRolesAssigned')}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n </div>\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 { useTranslation } from 'react-i18next';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n Users,\r\n RefreshCw,\r\n AlertTriangle,\r\n CheckCircle,\r\n XCircle,\r\n Mail,\r\n Calendar,\r\n ExternalLink,\r\n} from 'lucide-react';\r\nimport { adminApi, type UserListDto } from '@/services/api/adminApi';\r\nimport { DataTable, type DataTableColumn } from '@/components/ui/DataTable';\r\n\r\nexport function EntraUsersPage(): ReactElement {\r\n const { t } = useTranslation(['entra', 'common']);\r\n const navigate = useNavigate();\r\n const [loading, setLoading] = useState(true);\r\n const [users, setUsers] = useState<UserListDto[]>([]);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n setError(null);\r\n // Only fetch users synced from Entra ID (have entraObjectId)\r\n const response = await adminApi.users.getAll({ pageSize: 1000, entraOnly: true });\r\n setUsers(response?.items ?? []);\r\n } catch (err: unknown) {\r\n console.error('Failed to load users:', err);\r\n const axiosError = err as { response?: { status?: number } };\r\n if (axiosError.response?.status === 401) {\r\n setError(t('common:errors.sessionExpired'));\r\n } else if (axiosError.response?.status === 403) {\r\n setError(t('common:errors.noPermission'));\r\n } else {\r\n setError(t('entra:users.loadError'));\r\n }\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [t]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n const formatDate = (date: string | null) => {\r\n if (!date) return t('common:never');\r\n return new Intl.DateTimeFormat('fr-FR', {\r\n dateStyle: 'medium',\r\n timeStyle: 'short',\r\n }).format(new Date(date));\r\n };\r\n\r\n // Define columns for DataTable\r\n const columns: DataTableColumn<UserListDto>[] = [\r\n {\r\n key: 'fullName',\r\n label: t('entra:users.columns.user'),\r\n sortable: true,\r\n render: (user) => (\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"w-10 h-10 rounded-full bg-[var(--color-primary-100)] dark:bg-[var(--color-primary-900)] flex items-center justify-center flex-shrink-0\">\r\n <span className=\"text-sm font-medium text-[var(--color-primary-600)]\">\r\n {user.fullName?.charAt(0).toUpperCase() || '?'}\r\n </span>\r\n </div>\r\n <span className=\"font-medium text-[var(--text-primary)]\">{user.fullName}</span>\r\n </div>\r\n ),\r\n },\r\n {\r\n key: 'email',\r\n label: t('entra:users.columns.email'),\r\n sortable: true,\r\n render: (user) => (\r\n <div className=\"flex items-center gap-1 text-sm text-[var(--text-secondary)]\">\r\n <Mail className=\"w-4 h-4\" />\r\n {user.email}\r\n </div>\r\n ),\r\n },\r\n {\r\n key: 'isActive',\r\n label: t('entra:users.columns.status'),\r\n sortable: true,\r\n render: (user) =>\r\n user.isActive ? (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-1 text-xs rounded-full bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400\">\r\n <CheckCircle className=\"w-3 h-3\" />\r\n {t('common:active')}\r\n </span>\r\n ) : (\r\n <span className=\"inline-flex items-center gap-1 px-2 py-1 text-xs rounded-full bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400\">\r\n <XCircle className=\"w-3 h-3\" />\r\n {t('common:inactive')}\r\n </span>\r\n ),\r\n },\r\n {\r\n key: 'lastEntraSyncAt',\r\n label: t('entra:users.columns.lastSync'),\r\n sortable: true,\r\n render: (user) => (\r\n <div className=\"flex items-center gap-1 text-sm text-[var(--text-secondary)]\">\r\n <Calendar className=\"w-4 h-4\" />\r\n {formatDate(user.lastEntraSyncAt)}\r\n </div>\r\n ),\r\n },\r\n {\r\n key: 'actions',\r\n label: t('entra:users.columns.actions'),\r\n align: 'right',\r\n render: (user) => (\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n navigate(`/administration/users/${user.id}`);\r\n }}\r\n className=\"inline-flex items-center gap-1 text-sm text-[var(--color-primary-600)] hover:underline\"\r\n >\r\n {t('common:viewDetails')}\r\n <ExternalLink className=\"w-4 h-4\" />\r\n </button>\r\n ),\r\n },\r\n ];\r\n\r\n // Custom search filter for users\r\n const searchFilter = (user: UserListDto, searchTerm: string) => {\r\n const search = searchTerm.toLowerCase();\r\n return (\r\n user.fullName?.toLowerCase().includes(search) ||\r\n user.email?.toLowerCase().includes(search) ||\r\n false\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('entra.title', 'Microsoft Entra ID'), href: '/administration/entra' },\r\n { label: t('entra.users', 'Users') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-[var(--color-primary-100)] dark:bg-[var(--color-primary-900)]\">\r\n <Users className=\"w-6 h-6 text-[var(--color-primary-600)]\" />\r\n </div>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('entra:users.title')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:users.subtitle', { count: users.length })}\r\n </p>\r\n </div>\r\n </div>\r\n <button\r\n onClick={loadData}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg border border-[var(--border-primary)] bg-[var(--bg-primary)] text-[var(--text-primary)] hover:bg-[var(--bg-secondary)]\"\r\n >\r\n <RefreshCw className=\"w-4 h-4\" />\r\n {t('common:refresh')}\r\n </button>\r\n </div>\r\n\r\n {/* Error */}\r\n {error && (\r\n <div className=\"p-4 rounded-lg bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800\">\r\n <div className=\"flex items-center gap-2 text-red-700 dark:text-red-400\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* DataTable */}\r\n <DataTable\r\n data={users}\r\n columns={columns}\r\n loading={loading}\r\n searchable\r\n searchPlaceholder={t('entra:users.searchPlaceholder')}\r\n searchFilter={searchFilter}\r\n pagination={{ pageSize: 20, showSizeSelector: true }}\r\n onRowClick={(user) => navigate(`/administration/users/${user.id}`)}\r\n getRowKey={(user) => user.id}\r\n emptyMessage={t('entra:users.noUsers')}\r\n emptyIcon={<Users className=\"w-12 h-12 mx-auto text-[var(--text-secondary)] opacity-50\" />}\r\n defaultSortKey=\"fullName\"\r\n striped\r\n />\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback, useRef } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n AlertTriangle,\r\n RefreshCw,\r\n Loader2,\r\n CheckCircle,\r\n} from 'lucide-react';\r\nimport {\r\n entraApi,\r\n type EntraSyncConflictDto,\r\n type ResolveConflictRequest,\r\n} from '@/services/api/entraApi';\r\nimport { ConflictCard, ResolutionModal } from '@/components/platform/administration/entra';\r\n\r\n// ============================================\r\n// Main Component\r\n// ============================================\r\n\r\nexport function EntraConflictsPage(): ReactElement {\r\n const { t } = useTranslation(['entra', 'common']);\r\n const [loading, setLoading] = useState(true);\r\n const [conflicts, setConflicts] = useState<EntraSyncConflictDto[]>([]);\r\n const [error, setError] = useState<string | null>(null);\r\n const [selectedConflict, setSelectedConflict] = useState<EntraSyncConflictDto | null>(null);\r\n const [resolving, setResolving] = useState(false);\r\n\r\n // Abort controller ref for preventing race conditions\r\n const abortControllerRef = useRef<AbortController | null>(null);\r\n const isLoadingRef = useRef(false);\r\n\r\n const loadData = useCallback(async () => {\r\n // Prevent concurrent loads\r\n if (isLoadingRef.current) return;\r\n\r\n // Cancel any pending request\r\n if (abortControllerRef.current) {\r\n abortControllerRef.current.abort();\r\n }\r\n\r\n abortControllerRef.current = new AbortController();\r\n isLoadingRef.current = true;\r\n\r\n try {\r\n setError(null);\r\n const data = await entraApi.conflicts.getAll();\r\n setConflicts(Array.isArray(data) ? data : []);\r\n } catch (err: unknown) {\r\n // Ignore abort errors\r\n if (err instanceof Error && err.name === 'AbortError') {\r\n return;\r\n }\r\n // Log error type only, not the full error object (PII protection)\r\n console.error('Failed to load conflicts:', err instanceof Error ? err.message : 'Unknown error');\r\n setConflicts([]);\r\n const axiosError = err as { response?: { status?: number } };\r\n if (axiosError.response?.status === 401) {\r\n setError(t('common:errors.sessionExpired'));\r\n } else if (axiosError.response?.status === 403) {\r\n setError(t('common:errors.noPermission'));\r\n } else {\r\n setError(t('entra:conflicts.loadError'));\r\n }\r\n } finally {\r\n isLoadingRef.current = false;\r\n setLoading(false);\r\n }\r\n }, [t]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n\r\n // Cleanup on unmount\r\n return () => {\r\n if (abortControllerRef.current) {\r\n abortControllerRef.current.abort();\r\n }\r\n };\r\n }, [loadData]);\r\n\r\n const handleResolve = useCallback(async (resolution: ResolveConflictRequest['resolution'], notes?: string) => {\r\n if (!selectedConflict || resolving) return;\r\n\r\n setResolving(true);\r\n try {\r\n await entraApi.conflicts.resolve(selectedConflict.id, {\r\n resolution,\r\n notes: notes || undefined,\r\n });\r\n setSelectedConflict(null);\r\n await loadData();\r\n } catch (err) {\r\n // Log error type only, not the full error object (PII protection)\r\n console.error('Failed to resolve conflict:', err instanceof Error ? err.message : 'Unknown error');\r\n setError(t('entra:conflicts.resolveError'));\r\n } finally {\r\n setResolving(false);\r\n }\r\n }, [selectedConflict, resolving, loadData, t]);\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\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 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('entra.title', 'Microsoft Entra ID'), href: '/administration/entra' },\r\n { label: t('entra.conflicts', 'Conflicts') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--color-accent-500)]/10\">\r\n <AlertTriangle className=\"w-6 h-6 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {t('entra:conflicts.title')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('entra:conflicts.subtitle', { count: conflicts.length })}\r\n </p>\r\n </div>\r\n </div>\r\n <button\r\n onClick={loadData}\r\n disabled={loading}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-tertiary)] transition-colors disabled:opacity-50\"\r\n >\r\n <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />\r\n {t('common:refresh')}\r\n </button>\r\n </div>\r\n\r\n {/* Error */}\r\n {error && (\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 justify-between\">\r\n <div className=\"flex items-center gap-2 text-[var(--error-text)]\">\r\n <AlertTriangle className=\"w-5 h-5\" />\r\n <span>{error}</span>\r\n </div>\r\n <button\r\n onClick={() => setError(null)}\r\n className=\"text-[var(--error-text)] hover:opacity-70\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* No Conflicts - Empty State */}\r\n {conflicts.length === 0 ? (\r\n <div className=\"text-center py-16 px-6 rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)]\">\r\n <div className=\"mx-auto w-16 h-16 rounded-full bg-[var(--success-bg)] flex items-center justify-center mb-4\">\r\n <CheckCircle className=\"w-8 h-8 text-[var(--success-text)]\" />\r\n </div>\r\n <h2 className=\"text-xl font-semibold text-[var(--text-primary)] mb-2\">\r\n {t('entra:conflicts.noConflicts')}\r\n </h2>\r\n <p className=\"text-[var(--text-secondary)] max-w-md mx-auto\">\r\n {t('entra:conflicts.noConflictsDescription')}\r\n </p>\r\n </div>\r\n ) : (\r\n /* Conflicts Grid */\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {conflicts.map((conflict) => (\r\n <ConflictCard\r\n key={conflict.id}\r\n conflict={conflict}\r\n onResolve={setSelectedConflict}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Resolve Modal */}\r\n {selectedConflict && (\r\n <ResolutionModal\r\n conflict={selectedConflict}\r\n onClose={() => setSelectedConflict(null)}\r\n onResolve={handleResolve}\r\n resolving={resolving}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback, type ReactNode } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport {\r\n Settings,\r\n Key,\r\n Eye,\r\n EyeOff,\r\n Save,\r\n AlertTriangle,\r\n CheckCircle,\r\n ExternalLink,\r\n Shield,\r\n Clock,\r\n Loader2,\r\n TestTube,\r\n Users,\r\n Layers,\r\n Building2,\r\n Copy,\r\n Check,\r\n GitMerge,\r\n Filter,\r\n} from 'lucide-react';\r\nimport { entraApi } from '@/services/api/entraApi';\r\nimport type { TestConnectionResult, EntraConfigurationDto } from '@/services/api/entraApi';\r\n\r\ninterface EntraCredentials {\r\n tenantId: string;\r\n clientId: string;\r\n clientSecret: string;\r\n}\r\n\r\ninterface SyncSettings {\r\n syncEnabled: boolean;\r\n syncIntervalMinutes: number;\r\n useDeltaSync: boolean;\r\n defaultConflictResolution: 'ManualReview' | 'EntraWins' | 'LocalWins';\r\n autoCreateReferences: boolean;\r\n // User sync filters\r\n syncOnlyActiveUsers: boolean;\r\n syncUserTypes: string; // comma-separated: member, guest, shared, room, equipment\r\n}\r\n\r\n// Available user types for sync\r\n// Note: shared, room, equipment require mailboxSettings which is not available in bulk user listing API\r\nconst USER_TYPES = [\r\n { id: 'member', labelKey: 'userTypes.member', descriptionKey: 'userTypes.memberDescription', supported: true },\r\n { id: 'guest', labelKey: 'userTypes.guest', descriptionKey: 'userTypes.guestDescription', supported: true },\r\n { id: 'shared', labelKey: 'userTypes.shared', descriptionKey: 'userTypes.sharedDescription', supported: false },\r\n { id: 'room', labelKey: 'userTypes.room', descriptionKey: 'userTypes.roomDescription', supported: false },\r\n { id: 'equipment', labelKey: 'userTypes.equipment', descriptionKey: 'userTypes.equipmentDescription', supported: false },\r\n];\r\n\r\n// Required permissions for Microsoft Graph API\r\nconst REQUIRED_PERMISSIONS = [\r\n { code: 'User.Read.All', descriptionKey: 'userReadAll' },\r\n { code: 'Group.Read.All', descriptionKey: 'groupReadAll' },\r\n { code: 'GroupMember.Read.All', descriptionKey: 'groupMemberReadAll' },\r\n];\r\n\r\n// ============================================\r\n// Reusable Components\r\n// ============================================\r\n\r\ninterface SectionCardProps {\r\n readonly icon: LucideIcon;\r\n readonly title: string;\r\n readonly description?: string;\r\n readonly action?: ReactNode;\r\n readonly children: ReactNode;\r\n readonly className?: string;\r\n}\r\n\r\nfunction SectionCard({ icon: Icon, title, description, action, children, className = '' }: SectionCardProps) {\r\n return (\r\n <div className={`rounded-[var(--radius-card)] border border-[var(--border-color)] bg-[var(--bg-card)] shadow-sm overflow-hidden ${className}`}>\r\n {/* Header */}\r\n <div className=\"px-6 py-4 border-b border-[var(--border-subtle)] bg-[var(--bg-secondary)]\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30\">\r\n <Icon className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n </div>\r\n <div>\r\n <h2 className=\"text-base font-semibold text-[var(--text-primary)]\">{title}</h2>\r\n {description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{description}</p>\r\n )}\r\n </div>\r\n </div>\r\n {action}\r\n </div>\r\n </div>\r\n {/* Content */}\r\n <div className=\"p-6\">\r\n {children}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\ninterface ToggleProps {\r\n readonly checked: boolean;\r\n readonly onChange: () => void;\r\n readonly label: string;\r\n readonly description?: string;\r\n}\r\n\r\nfunction Toggle({ checked, onChange, label, description }: ToggleProps) {\r\n return (\r\n <div className=\"flex items-center justify-between py-3\">\r\n <div className=\"flex-1 min-w-0 pr-4\">\r\n <label className=\"text-sm font-medium text-[var(--text-primary)]\">{label}</label>\r\n {description && (\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">{description}</p>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n role=\"switch\"\r\n aria-checked={checked}\r\n onClick={onChange}\r\n className={`relative inline-flex h-6 w-11 flex-shrink-0 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] focus:ring-offset-2 focus:ring-offset-[var(--bg-primary)] ${\r\n checked ? 'bg-[var(--color-accent-600)]' : 'bg-[var(--bg-tertiary)]'\r\n }`}\r\n >\r\n <span\r\n className={`inline-block h-4 w-4 transform rounded-full bg-[var(--toggle-knob)] shadow-md transition-transform ${\r\n checked ? 'translate-x-6' : 'translate-x-1'\r\n }`}\r\n />\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\n// ============================================\r\n// Validation\r\n// ============================================\r\n\r\nconst isValidGuid = (value: string): boolean => {\r\n if (!value) return true;\r\n const guidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\r\n return guidRegex.test(value);\r\n};\r\n\r\nconst useEntraSettings = () => {\r\n const { t } = useTranslation(['entra', 'common']);\r\n const [loading, setLoading] = useState(true);\r\n const [saving, setSaving] = useState(false);\r\n const [testing, setTesting] = useState(false);\r\n const [testResult, setTestResult] = useState<TestConnectionResult | null>(null);\r\n const [showSecret, setShowSecret] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n const [hasExistingSecret, setHasExistingSecret] = useState(false);\r\n const [copiedPermission, setCopiedPermission] = useState<string | null>(null);\r\n const [validationErrors, setValidationErrors] = useState<{\r\n tenantId?: string;\r\n clientId?: string;\r\n }>({});\r\n\r\n const [credentials, setCredentials] = useState<EntraCredentials>({\r\n tenantId: '',\r\n clientId: '',\r\n clientSecret: '',\r\n });\r\n\r\n const [syncSettings, setSyncSettings] = useState<SyncSettings>({\r\n syncEnabled: false,\r\n syncIntervalMinutes: 60,\r\n useDeltaSync: true,\r\n defaultConflictResolution: 'ManualReview',\r\n autoCreateReferences: true,\r\n syncOnlyActiveUsers: true,\r\n syncUserTypes: 'member',\r\n });\r\n\r\n return {\r\n t, loading, setLoading, saving, setSaving, testing, setTesting,\r\n testResult, setTestResult, showSecret, setShowSecret, error, setError,\r\n success, setSuccess, hasExistingSecret, setHasExistingSecret,\r\n copiedPermission, setCopiedPermission, validationErrors, setValidationErrors,\r\n credentials, setCredentials, syncSettings, setSyncSettings\r\n };\r\n};\r\n\r\n// ============================================\r\n// Helpers\r\n// ============================================\r\n\r\nfunction getCheckboxCardClass(isDisabled: boolean, isChecked: boolean): string {\r\n if (isDisabled) return 'opacity-50 cursor-not-allowed border-[var(--border-color)] bg-[var(--bg-tertiary)]';\r\n if (isChecked) return 'cursor-pointer border-[var(--color-accent-500)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-900)]/20';\r\n return 'cursor-pointer border-[var(--border-color)] bg-[var(--bg-secondary)] hover:bg-[var(--bg-tertiary)]';\r\n}\r\n\r\n// ============================================\r\n// Main Component\r\n// ============================================\r\n\r\nexport function EntraSettingsPage(): ReactElement {\r\n const state = useEntraSettings();\r\n\r\n const loadConfiguration = useCallback(async () => {\r\n try {\r\n state.setLoading(true);\r\n const config: EntraConfigurationDto = await entraApi.settings.getConfiguration();\r\n\r\n state.setCredentials({\r\n tenantId: config.tenantId || '',\r\n clientId: config.clientId || '',\r\n clientSecret: '',\r\n });\r\n state.setHasExistingSecret(config.hasClientSecret);\r\n\r\n state.setSyncSettings({\r\n syncEnabled: config.syncEnabled,\r\n syncIntervalMinutes: config.syncIntervalMinutes,\r\n useDeltaSync: config.useDeltaSync,\r\n defaultConflictResolution: config.defaultConflictResolution as SyncSettings['defaultConflictResolution'],\r\n autoCreateReferences: config.autoCreateReferences,\r\n syncOnlyActiveUsers: config.syncOnlyActiveUsers ?? true,\r\n syncUserTypes: config.syncUserTypes ?? 'member',\r\n });\r\n } catch (err) {\r\n console.error('Failed to load configuration:', err);\r\n state.setError(state.t('entra:settings.saveError'));\r\n } finally {\r\n state.setLoading(false);\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, []); // React setters are stable, no need to include them in dependencies\r\n\r\n useEffect(() => {\r\n loadConfiguration();\r\n }, [loadConfiguration]);\r\n\r\n const handleCopyPermission = async (code: string) => {\r\n try {\r\n await navigator.clipboard.writeText(code);\r\n state.setCopiedPermission(code);\r\n setTimeout(() => state.setCopiedPermission(null), 2000);\r\n } catch (err) {\r\n console.error('Failed to copy:', err);\r\n }\r\n };\r\n\r\n const validateCredentialField = (field: 'tenantId' | 'clientId', value: string) => {\r\n const errorKey = isValidGuid(value) ? undefined : state.t('entra:settings.invalidGuidFormat');\r\n state.setValidationErrors(prev => ({ ...prev, [field]: errorKey }));\r\n };\r\n\r\n const handleCredentialChange = (field: keyof EntraCredentials, value: string) => {\r\n state.setCredentials(prev => ({ ...prev, [field]: value }));\r\n if (field === 'tenantId' || field === 'clientId') {\r\n validateCredentialField(field, value);\r\n }\r\n };\r\n\r\n const hasValidationErrors = Boolean(\r\n state.validationErrors.tenantId || state.validationErrors.clientId\r\n );\r\n\r\n const handleTestConnection = async () => {\r\n state.setTesting(true);\r\n state.setTestResult(null);\r\n state.setError(null);\r\n state.setSuccess(null);\r\n try {\r\n let result: TestConnectionResult;\r\n\r\n if (state.credentials.clientSecret) {\r\n result = await entraApi.settings.testConnection({\r\n tenantId: state.credentials.tenantId,\r\n clientId: state.credentials.clientId,\r\n clientSecret: state.credentials.clientSecret,\r\n });\r\n } else if (state.hasExistingSecret) {\r\n result = await entraApi.settings.testStoredConnection();\r\n } else {\r\n state.setError(state.t('entra:settings.testFailed'));\r\n state.setTesting(false);\r\n return;\r\n }\r\n\r\n state.setTestResult(result);\r\n if (result.success) {\r\n state.setSuccess(state.t('entra:settings.testSuccess'));\r\n } else {\r\n state.setError(result.errorMessage || state.t('entra:settings.testFailed'));\r\n }\r\n } catch (err) {\r\n console.error('Connection test failed:', err);\r\n state.setTestResult({ success: false, errorMessage: state.t('entra:settings.testFailed'), tenantName: null, userCount: null, groupCount: null });\r\n state.setError(state.t('entra:settings.testFailed'));\r\n } finally {\r\n state.setTesting(false);\r\n }\r\n };\r\n\r\n const handleSaveCredentials = async () => {\r\n state.setSaving(true);\r\n state.setError(null);\r\n state.setSuccess(null);\r\n try {\r\n await entraApi.settings.saveCredentials({\r\n tenantId: state.credentials.tenantId,\r\n clientId: state.credentials.clientId,\r\n clientSecret: state.credentials.clientSecret,\r\n });\r\n state.setSuccess(state.t('entra:settings.credentialsSaved'));\r\n state.setHasExistingSecret(true);\r\n state.setCredentials((prev) => ({ ...prev, clientSecret: '' }));\r\n } catch (err) {\r\n console.error('Failed to save credentials:', err);\r\n state.setError(state.t('entra:settings.saveError'));\r\n } finally {\r\n state.setSaving(false);\r\n }\r\n };\r\n\r\n const handleSaveSettings = async () => {\r\n state.setSaving(true);\r\n state.setError(null);\r\n state.setSuccess(null);\r\n try {\r\n await entraApi.settings.saveSyncSettings({\r\n syncEnabled: state.syncSettings.syncEnabled,\r\n syncIntervalMinutes: state.syncSettings.syncIntervalMinutes,\r\n useDeltaSync: state.syncSettings.useDeltaSync,\r\n defaultConflictResolution: state.syncSettings.defaultConflictResolution,\r\n autoCreateReferences: state.syncSettings.autoCreateReferences,\r\n syncOnlyActiveUsers: state.syncSettings.syncOnlyActiveUsers,\r\n syncUserTypes: state.syncSettings.syncUserTypes,\r\n });\r\n state.setSuccess(state.t('entra:settings.settingsSaved'));\r\n } catch (err) {\r\n console.error('Failed to save settings:', err);\r\n state.setError(state.t('entra:settings.saveError'));\r\n } finally {\r\n state.setSaving(false);\r\n }\r\n };\r\n\r\n if (state.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 return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: state.t('header.title'), href: '/administration' },\r\n { label: state.t('entra.title', 'Microsoft Entra ID'), href: '/administration/entra' },\r\n { label: state.t('entra.settings', 'Settings') }\r\n ]}\r\n />\r\n\r\n {/* Page Header */}\r\n <div className=\"flex items-center gap-4\">\r\n <div className=\"p-3 rounded-[var(--radius-card)] bg-gradient-to-br from-[var(--color-accent-500)] to-[var(--color-accent-700)] shadow-lg\">\r\n <Settings className=\"w-7 h-7 text-white\" />\r\n </div>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">\r\n {state.t('entra:settings.title')}\r\n </h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {state.t('entra:settings.subtitle')}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Required Permissions Warning */}\r\n <div className=\"rounded-[var(--radius-card)] border-2 border-[var(--warning-border)] bg-[var(--warning-bg)] overflow-hidden\">\r\n <div className=\"px-5 py-4\">\r\n <div className=\"flex items-start gap-4\">\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--warning-border)]\">\r\n <Shield className=\"w-5 h-5 text-[var(--warning-text)]\" />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center justify-between gap-4 mb-2\">\r\n <h2 className=\"font-semibold text-[var(--warning-text)]\">\r\n {state.t('entra:settings.permissionsWarningTitle')}\r\n </h2>\r\n <a\r\n href=\"https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade\"\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--warning-border)] text-[var(--warning-text)] hover:opacity-80 transition-opacity\"\r\n >\r\n {state.t('entra:settings.configureInAzure')}\r\n <ExternalLink className=\"w-3.5 h-3.5\" />\r\n </a>\r\n </div>\r\n <p className=\"text-sm text-[var(--warning-text)] opacity-90 mb-4\">\r\n {state.t('entra:settings.permissionsWarningDescription')}\r\n </p>\r\n\r\n {/* Copyable Permissions */}\r\n <div className=\"flex flex-wrap gap-2\">\r\n {REQUIRED_PERMISSIONS.map((perm) => (\r\n <button\r\n key={perm.code}\r\n onClick={() => handleCopyPermission(perm.code)}\r\n className=\"group inline-flex items-center gap-2 px-3 py-2 rounded-[var(--radius-button)] bg-[var(--bg-primary)] border border-[var(--warning-border)] hover:border-[var(--warning-dot)] transition-all hover:shadow-sm\"\r\n title={state.t(`entra:settings.permissions.${perm.descriptionKey}`)}\r\n >\r\n <code className=\"text-sm font-mono font-medium text-[var(--text-primary)]\">{perm.code}</code>\r\n {state.copiedPermission === perm.code ? (\r\n <Check className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n ) : (\r\n <Copy className=\"w-4 h-4 text-[var(--warning-text)] group-hover:opacity-80\" />\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Error/Success Messages */}\r\n {state.error && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)]\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--error-text)] flex-shrink-0\" />\r\n <span className=\"text-sm text-[var(--error-text)]\">{state.error}</span>\r\n </div>\r\n )}\r\n\r\n {state.success && (\r\n <div className=\"flex items-center gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)] flex-shrink-0\" />\r\n <span className=\"text-sm text-[var(--success-text)]\">{state.success}</span>\r\n </div>\r\n )}\r\n\r\n {/* Main Content Grid */}\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\r\n {/* ============================================ */}\r\n {/* Left Column - Credentials */}\r\n {/* ============================================ */}\r\n <SectionCard\r\n icon={Key}\r\n title={state.t('entra:settings.credentials')}\r\n description=\"Azure AD Application\"\r\n action={\r\n <a\r\n href=\"https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade\"\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"inline-flex items-center gap-1.5 text-sm text-[var(--color-accent-500)] hover:text-[var(--color-accent-600)] transition-colors\"\r\n >\r\n {state.t('entra:settings.azurePortal')}\r\n <ExternalLink className=\"w-4 h-4\" />\r\n </a>\r\n }\r\n >\r\n <div className=\"space-y-5\">\r\n {/* Tenant ID */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {state.t('entra:settings.tenantId')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={state.credentials.tenantId}\r\n onChange={(e) => handleCredentialChange('tenantId', e.target.value)}\r\n placeholder=\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\r\n autoComplete=\"off\"\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border bg-[var(--bg-secondary)] text-[var(--text-primary)] font-mono text-sm focus:outline-none focus:ring-2 focus:border-transparent transition-shadow ${\r\n state.validationErrors.tenantId\r\n ? 'border-[var(--error-border)] focus:ring-[var(--error-border)]'\r\n : 'border-[var(--border-color)] focus:ring-[var(--color-accent-500)]'\r\n }`}\r\n />\r\n {state.validationErrors.tenantId ? (\r\n <p className=\"mt-1.5 text-xs text-[var(--error-text)]\">{state.validationErrors.tenantId}</p>\r\n ) : (\r\n <p className=\"mt-1.5 text-xs text-[var(--text-tertiary)]\">{state.t('entra:settings.tenantIdHelp')}</p>\r\n )}\r\n </div>\r\n\r\n {/* Client ID */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {state.t('entra:settings.clientId')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={state.credentials.clientId}\r\n onChange={(e) => handleCredentialChange('clientId', e.target.value)}\r\n placeholder=\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\r\n autoComplete=\"off\"\r\n className={`w-full px-3 py-2.5 rounded-[var(--radius-input)] border bg-[var(--bg-secondary)] text-[var(--text-primary)] font-mono text-sm focus:outline-none focus:ring-2 focus:border-transparent transition-shadow ${\r\n state.validationErrors.clientId\r\n ? 'border-[var(--error-border)] focus:ring-[var(--error-border)]'\r\n : 'border-[var(--border-color)] focus:ring-[var(--color-accent-500)]'\r\n }`}\r\n />\r\n {state.validationErrors.clientId ? (\r\n <p className=\"mt-1.5 text-xs text-[var(--error-text)]\">{state.validationErrors.clientId}</p>\r\n ) : (\r\n <p className=\"mt-1.5 text-xs text-[var(--text-tertiary)]\">{state.t('entra:settings.clientIdHelp')}</p>\r\n )}\r\n </div>\r\n\r\n {/* Client Secret */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-1.5\">\r\n {state.t('entra:settings.clientSecret')}\r\n {state.hasExistingSecret && (\r\n <span className=\"ml-2 inline-flex items-center gap-1 text-xs text-[var(--success-text)]\">\r\n <CheckCircle className=\"w-3 h-3\" />\r\n {state.t('common:configured')}\r\n </span>\r\n )}\r\n </label>\r\n <div className=\"relative\">\r\n <input\r\n type={state.showSecret ? 'text' : 'password'}\r\n value={state.credentials.clientSecret}\r\n onChange={(e) => handleCredentialChange('clientSecret', e.target.value)}\r\n placeholder={state.hasExistingSecret ? '••••••••••••••••••••••••••••••••••••••••' : 'OvA8Q~xxxxxxxxxxxxxxxxxxxxxxxxxxxx'}\r\n autoComplete=\"new-password\"\r\n className=\"w-full px-3 py-2.5 pr-10 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] font-mono text-sm focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] focus:border-transparent transition-shadow\"\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => state.setShowSecret(!state.showSecret)}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 p-1 text-[var(--text-tertiary)] hover:text-[var(--text-primary)] transition-colors\"\r\n >\r\n {state.showSecret ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </button>\r\n </div>\r\n <p className=\"mt-1.5 text-xs text-[var(--text-tertiary)]\">{state.t('entra:settings.clientSecretHelp')}</p>\r\n </div>\r\n\r\n {/* Action Buttons */}\r\n <div className=\"flex items-center gap-3 pt-2\">\r\n <button\r\n onClick={handleTestConnection}\r\n disabled={state.testing || hasValidationErrors || !state.credentials.tenantId || !state.credentials.clientId || (!state.credentials.clientSecret && !state.hasExistingSecret)}\r\n className=\"inline-flex items-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] hover:bg-[var(--bg-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {state.testing && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {!state.testing && state.testResult?.success && <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />}\r\n {!state.testing && state.testResult && !state.testResult.success && <AlertTriangle className=\"w-4 h-4 text-[var(--error-text)]\" />}\r\n {!state.testing && !state.testResult && <TestTube className=\"w-4 h-4\" />}\r\n {state.t('entra:settings.testConnection')}\r\n </button>\r\n <button\r\n onClick={handleSaveCredentials}\r\n disabled={state.saving || hasValidationErrors || !state.credentials.tenantId || !state.credentials.clientId || !state.credentials.clientSecret}\r\n className=\"inline-flex items-center gap-2 px-4 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm\"\r\n >\r\n {state.saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {state.t('common:save')}\r\n </button>\r\n </div>\r\n\r\n {/* Test Result Details */}\r\n {state.testResult?.success && (\r\n <div className=\"mt-4 p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)]\">\r\n <div className=\"flex items-center gap-2 mb-3\">\r\n <CheckCircle className=\"w-5 h-5 text-[var(--success-text)]\" />\r\n <span className=\"font-medium text-[var(--success-text)]\">\r\n {state.t('entra:settings.connectionSuccessful')}\r\n </span>\r\n </div>\r\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-3\">\r\n {state.testResult.tenantName && (\r\n <div className=\"flex items-center gap-2 p-2 rounded-[var(--radius-button)] bg-[var(--bg-primary)]\">\r\n <Building2 className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n <div className=\"min-w-0\">\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{state.t('entra:settings.tenantName')}</p>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)] truncate\">{state.testResult.tenantName}</p>\r\n </div>\r\n </div>\r\n )}\r\n {state.testResult.userCount !== null && (\r\n <div className=\"flex items-center gap-2 p-2 rounded-[var(--radius-button)] bg-[var(--bg-primary)]\">\r\n <Users className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n <div>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{state.t('entra:settings.userCount')}</p>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">{state.testResult.userCount}</p>\r\n </div>\r\n </div>\r\n )}\r\n {state.testResult.groupCount !== null && (\r\n <div className=\"flex items-center gap-2 p-2 rounded-[var(--radius-button)] bg-[var(--bg-primary)]\">\r\n <Layers className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n <div>\r\n <p className=\"text-xs text-[var(--text-tertiary)]\">{state.t('entra:settings.groupCount')}</p>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">{state.testResult.groupCount}</p>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </SectionCard>\r\n\r\n {/* ============================================ */}\r\n {/* Right Column - Sync Settings Stack */}\r\n {/* ============================================ */}\r\n <div className=\"space-y-6\">\r\n {/* Sync Configuration */}\r\n <SectionCard\r\n icon={Clock}\r\n title={state.t('entra:settings.syncSettings')}\r\n description=\"Scheduling & Performance\"\r\n >\r\n <div className=\"divide-y divide-[var(--border-subtle)]\">\r\n <Toggle\r\n checked={state.syncSettings.syncEnabled}\r\n onChange={() => state.setSyncSettings((prev) => ({ ...prev, syncEnabled: !prev.syncEnabled }))}\r\n label={state.t('entra:settings.syncEnabled')}\r\n description={state.t('entra:settings.syncEnabledHelp')}\r\n />\r\n\r\n <div className=\"py-4\">\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-2\">\r\n {state.t('entra:settings.syncInterval')}\r\n </label>\r\n <select\r\n value={state.syncSettings.syncIntervalMinutes}\r\n onChange={(e) => state.setSyncSettings((prev) => ({ ...prev, syncIntervalMinutes: Number(e.target.value) }))}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow\"\r\n >\r\n <option value={15}>15 {state.t('common:minutes')}</option>\r\n <option value={30}>30 {state.t('common:minutes')}</option>\r\n <option value={60}>1 {state.t('common:hour')}</option>\r\n <option value={120}>2 {state.t('common:hours')}</option>\r\n <option value={360}>6 {state.t('common:hours')}</option>\r\n <option value={720}>12 {state.t('common:hours')}</option>\r\n <option value={1440}>24 {state.t('common:hours')}</option>\r\n </select>\r\n </div>\r\n\r\n <Toggle\r\n checked={state.syncSettings.useDeltaSync}\r\n onChange={() => state.setSyncSettings((prev) => ({ ...prev, useDeltaSync: !prev.useDeltaSync }))}\r\n label={state.t('entra:settings.useDeltaSync')}\r\n description={state.t('entra:settings.useDeltaSyncHelp')}\r\n />\r\n\r\n <Toggle\r\n checked={state.syncSettings.autoCreateReferences}\r\n onChange={() => state.setSyncSettings((prev) => ({ ...prev, autoCreateReferences: !prev.autoCreateReferences }))}\r\n label={state.t('entra:settings.autoCreateReferences')}\r\n description={state.t('entra:settings.autoCreateReferencesHelp')}\r\n />\r\n </div>\r\n </SectionCard>\r\n\r\n {/* Conflict Resolution */}\r\n <SectionCard\r\n icon={GitMerge}\r\n title={state.t('entra:settings.conflictResolution')}\r\n description=\"Data Priority\"\r\n >\r\n <div>\r\n <select\r\n value={state.syncSettings.defaultConflictResolution}\r\n onChange={(e) => state.setSyncSettings((prev) => ({ ...prev, defaultConflictResolution: e.target.value as SyncSettings['defaultConflictResolution'] }))}\r\n className=\"w-full px-3 py-2.5 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] transition-shadow\"\r\n >\r\n <option value=\"ManualReview\">{state.t('entra:settings.conflictResolutions.manualReview')}</option>\r\n <option value=\"EntraWins\">{state.t('entra:settings.conflictResolutions.entraWins')}</option>\r\n <option value=\"LocalWins\">{state.t('entra:settings.conflictResolutions.localWins')}</option>\r\n </select>\r\n <p className=\"mt-2 text-xs text-[var(--text-tertiary)]\">\r\n {state.t('entra:settings.conflictResolutionHelp')}\r\n </p>\r\n </div>\r\n </SectionCard>\r\n\r\n {/* User Filters */}\r\n <SectionCard\r\n icon={Filter}\r\n title={state.t('entra:settings.userSyncFilters')}\r\n description=\"User Types & Filters\"\r\n >\r\n <div className=\"space-y-4\">\r\n <Toggle\r\n checked={state.syncSettings.syncOnlyActiveUsers}\r\n onChange={() => state.setSyncSettings((prev) => ({ ...prev, syncOnlyActiveUsers: !prev.syncOnlyActiveUsers }))}\r\n label={state.t('entra:settings.syncOnlyActiveUsers')}\r\n description={state.t('entra:settings.syncOnlyActiveUsersHelp')}\r\n />\r\n\r\n <div className=\"pt-2 border-t border-[var(--border-subtle)]\">\r\n <label className=\"block text-sm font-medium text-[var(--text-primary)] mb-2\">\r\n {state.t('entra:settings.syncUserTypesLabel')}\r\n </label>\r\n <p className=\"text-xs text-[var(--text-tertiary)] mb-3\">\r\n {state.t('entra:settings.syncUserTypesHelp')}\r\n </p>\r\n <div className=\"space-y-2\">\r\n {USER_TYPES.map((userType) => {\r\n const selectedTypes = state.syncSettings.syncUserTypes.split(',').map(t => t.trim()).filter(Boolean);\r\n const isChecked = selectedTypes.includes(userType.id);\r\n const isDisabled = !userType.supported;\r\n\r\n const handleToggle = () => {\r\n if (isDisabled) return;\r\n let newTypes: string[];\r\n if (isChecked) {\r\n newTypes = selectedTypes.filter(t => t !== userType.id);\r\n } else {\r\n newTypes = [...selectedTypes, userType.id];\r\n }\r\n if (newTypes.length === 0) newTypes = ['member'];\r\n state.setSyncSettings(prev => ({ ...prev, syncUserTypes: newTypes.join(',') }));\r\n };\r\n\r\n return (\r\n <label\r\n key={userType.id}\r\n className={`flex items-start gap-3 p-3 rounded-[var(--radius-button)] border transition-all ${\r\n getCheckboxCardClass(isDisabled, isChecked)\r\n }`}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={isChecked}\r\n onChange={handleToggle}\r\n disabled={isDisabled}\r\n className=\"mt-0.5 w-4 h-4 rounded border-[var(--border-color)] text-[var(--color-accent-600)] focus:ring-[var(--color-accent-500)] disabled:opacity-50\"\r\n />\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {state.t(`entra:settings.${userType.labelKey}`)}\r\n </span>\r\n {isDisabled && (\r\n <span className=\"text-xs px-1.5 py-0.5 rounded bg-[var(--bg-tertiary)] text-[var(--text-tertiary)]\">\r\n {state.t('common:comingSoon')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">\r\n {state.t(`entra:settings.${userType.descriptionKey}`)}\r\n </p>\r\n </div>\r\n </label>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n </div>\r\n </SectionCard>\r\n\r\n {/* Save Button */}\r\n <div className=\"flex justify-end\">\r\n <button\r\n onClick={handleSaveSettings}\r\n disabled={state.saving}\r\n className=\"inline-flex items-center gap-2 px-6 py-2.5 text-sm font-medium rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm\"\r\n >\r\n {state.saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {state.t('common:save')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"names":["SyncStatusCard","resourceType","Icon","status","lastFullSyncAt","lastDeltaSyncAt","totalItemsSynced","pendingConflicts","lastError","syncing","canSync","onSync","formatDate","t","statusConfig","CheckCircle","XCircle","Loader2","Clock","StatusIcon","jsxs","jsx","Database","Calendar","RefreshCw","AlertCircle","Tooltip","EntraDashboardPage","useTranslation","hasPermission","useAuth","loading","setLoading","useState","refreshing","setRefreshing","syncStatus","setSyncStatus","error","setError","setSyncing","lastSyncResult","setLastSyncResult","loadData","useCallback","entraApi","err","axiosError","useEffect","handleRefresh","handleSync","type","result","handleForceFullSync","date","getResourceIcon","Users","Building2","Link2","Cloud","totalPendingConflicts","sum","s","Breadcrumb","Play","AlertTriangle","getGroupHierarchyDisplay","group","GitBranch","EntraGroupsPage","currentTenant","isGlobalView","useTenant","navigate","useNavigate","groups","setGroups","roles","setRoles","searchQuery","setSearchQuery","selectedGroup","setSelectedGroup","showAssignModal","setShowAssignModal","expandedGroupId","setExpandedGroupId","members","setMembers","loadingMembers","setLoadingMembers","viewMode","setViewMode","groupTypeFilter","setGroupTypeFilter","assigning","setAssigning","canAssign","groupsData","rolesData","adminApi","loadMembers","groupId","data","prev","reloadGroupsAndRoles","safeGroupsData","handleAssignRole","roleId","isInheritable","updatedGroup","g","handleRemoveRole","filteredGroups","matchesSearch","matchesType","X","Search","e","Filter","LayoutGrid","List","Shield","role","Plus","ChevronUp","ChevronDown","Fragment","member","Link","r","EntraUsersPage","users","setUsers","response","columns","user","Mail","ExternalLink","searchFilter","searchTerm","search","DataTable","EntraConflictsPage","conflicts","setConflicts","selectedConflict","setSelectedConflict","resolving","setResolving","abortControllerRef","useRef","isLoadingRef","handleResolve","resolution","notes","conflict","ConflictCard","ResolutionModal","USER_TYPES","REQUIRED_PERMISSIONS","SectionCard","title","description","action","children","className","Toggle","checked","onChange","label","isValidGuid","value","useEntraSettings","saving","setSaving","testing","setTesting","testResult","setTestResult","showSecret","setShowSecret","success","setSuccess","hasExistingSecret","setHasExistingSecret","copiedPermission","setCopiedPermission","validationErrors","setValidationErrors","credentials","setCredentials","syncSettings","setSyncSettings","getCheckboxCardClass","isDisabled","isChecked","EntraSettingsPage","state","loadConfiguration","config","handleCopyPermission","code","validateCredentialField","field","errorKey","handleCredentialChange","hasValidationErrors","handleTestConnection","handleSaveCredentials","handleSaveSettings","Settings","perm","Check","Copy","Key","EyeOff","Eye","TestTube","Save","Layers","GitMerge","userType","selectedTypes","handleToggle","newTypes"],"mappings":"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"}