@atlashub/smartstack 3.21.0 → 3.24.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.
- package/dist/chunks/{AgentSkillsPage-7si3Ng8e.js → AgentSkillsPage-BWQSCYl-.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-7si3Ng8e.js.map → AgentSkillsPage-BWQSCYl-.js.map} +1 -1
- package/dist/chunks/{AgentSkillsPage-D0cD1QdM.js → AgentSkillsPage-IQcMnBaD.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-D0cD1QdM.js.map → AgentSkillsPage-IQcMnBaD.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-H_7ze33H.js → AgentWorkloadPage-DqrjkvWL.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-H_7ze33H.js.map → AgentWorkloadPage-DqrjkvWL.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-D4d86cdV.js → AgentWorkloadPage-w-HiyFYP.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-D4d86cdV.js.map → AgentWorkloadPage-w-HiyFYP.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-2ktkRrCb.js → ApiCatalogDetailPage-D3L8Yf4G.js} +3 -3
- package/dist/chunks/{ApiCatalogDetailPage-2ktkRrCb.js.map → ApiCatalogDetailPage-D3L8Yf4G.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-BQ53xuwD.js → ApiCatalogDetailPage-MPT3Kz6H.js} +2 -2
- package/dist/chunks/{ApiCatalogDetailPage-BQ53xuwD.js.map → ApiCatalogDetailPage-MPT3Kz6H.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-BEqTDJz8.js → ApiCatalogPage-D4Hg3uiS.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-BEqTDJz8.js.map → ApiCatalogPage-D4Hg3uiS.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-BBkWSLI8.js → ApiCatalogPage-DRg5Cz0r.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-BBkWSLI8.js.map → ApiCatalogPage-DRg5Cz0r.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage-BYJ2YMPq.js → ApplicationDetailPage-Caizuyn2.js} +2 -2
- package/dist/chunks/{ApplicationDetailPage-BYJ2YMPq.js.map → ApplicationDetailPage-Caizuyn2.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage-D8-bf1as.js → ApplicationDetailPage-CuCW6aMB.js} +4 -4
- package/dist/chunks/{ApplicationDetailPage-D8-bf1as.js.map → ApplicationDetailPage-CuCW6aMB.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-BBlLms2r.js → ApplicationsDashboardPage-B2MW8-Kc.js} +2 -2
- package/dist/chunks/{ApplicationsDashboardPage-BBlLms2r.js.map → ApplicationsDashboardPage-B2MW8-Kc.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-DTWZxJJM.js → ApplicationsDashboardPage-BDIjFIYZ.js} +3 -3
- package/dist/chunks/{ApplicationsDashboardPage-DTWZxJJM.js.map → ApplicationsDashboardPage-BDIjFIYZ.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-BQaMsK1K.js → ApplicationsGridPage-DV-FihKj.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-BQaMsK1K.js.map → ApplicationsGridPage-DV-FihKj.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-DbVcvezt.js → ApplicationsGridPage-DXsTfXPI.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-DbVcvezt.js.map → ApplicationsGridPage-DXsTfXPI.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-DYKM2Yeo.js → ApplicationsListPage--CGkyBuJ.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-DYKM2Yeo.js.map → ApplicationsListPage--CGkyBuJ.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-C91v2rZt.js → ApplicationsListPage-JUX823bh.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-C91v2rZt.js.map → ApplicationsListPage-JUX823bh.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-BCbgotIx.js → ApplicationsPage-6zgFye6w.js} +2 -2
- package/dist/chunks/{ApplicationsPage-BCbgotIx.js.map → ApplicationsPage-6zgFye6w.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-CW3-Hjlu.js → ApplicationsPage-CQPuuiO6.js} +4 -4
- package/dist/chunks/{ApplicationsPage-CW3-Hjlu.js.map → ApplicationsPage-CQPuuiO6.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-D8vfGDBN.js → AssignmentRulesPage-CFffeEbo.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-D8vfGDBN.js.map → AssignmentRulesPage-CFffeEbo.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-CxktlEMB.js → AssignmentRulesPage-D78UeUId.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-CxktlEMB.js.map → AssignmentRulesPage-D78UeUId.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-DmfBYQAD.js → AssignmentsPage-Cww2ifZF.js} +2 -2
- package/dist/chunks/{AssignmentsPage-DmfBYQAD.js.map → AssignmentsPage-Cww2ifZF.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-sRCCBmRc.js → AssignmentsPage-DE_QS2LO.js} +2 -2
- package/dist/chunks/{AssignmentsPage-sRCCBmRc.js.map → AssignmentsPage-DE_QS2LO.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-C7XiZxKb.js → AuthCallbackPage-CA2nO6DG.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-C7XiZxKb.js.map → AuthCallbackPage-CA2nO6DG.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-BCe_bwJM.js → AuthCallbackPage-CDUAoX-N.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-BCe_bwJM.js.map → AuthCallbackPage-CDUAoX-N.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-BUfGSqxF.js → ConfirmEmailPage-BqsILAYH.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-BUfGSqxF.js.map → ConfirmEmailPage-BqsILAYH.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-Buj4x-rx.js → ConfirmEmailPage-INeHCuMB.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-Buj4x-rx.js.map → ConfirmEmailPage-INeHCuMB.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-CKDX_HQm.js → CreateSupportTicketPage-BWeuV2aU.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-CKDX_HQm.js.map → CreateSupportTicketPage-BWeuV2aU.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-0LgY-_pu.js → CreateSupportTicketPage-OBwF4v7b.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-0LgY-_pu.js.map → CreateSupportTicketPage-OBwF4v7b.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CUZ80NGV.js → DashboardPage-CKHqWrdS.js} +3 -3
- package/dist/chunks/{DashboardPage-CUZ80NGV.js.map → DashboardPage-CKHqWrdS.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CaNOAstg.js → DashboardPage-COmc9b__.js} +3 -3
- package/dist/chunks/{DashboardPage-CaNOAstg.js.map → DashboardPage-COmc9b__.js.map} +1 -1
- package/dist/chunks/{DashboardPage-B48_rQFi.js → DashboardPage-CfKZHiSj.js} +2 -2
- package/dist/chunks/{DashboardPage-B48_rQFi.js.map → DashboardPage-CfKZHiSj.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CUZV1J9t.js → DashboardPage-CwEZZ3jx.js} +2 -2
- package/dist/chunks/{DashboardPage-CUZV1J9t.js.map → DashboardPage-CwEZZ3jx.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-CdzAbnGy.js → EscalationConfigPage--7lgZ0kJ.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-CdzAbnGy.js.map → EscalationConfigPage--7lgZ0kJ.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-CYGIl_e6.js → EscalationConfigPage-DPyiBcqV.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-CYGIl_e6.js.map → EscalationConfigPage-DPyiBcqV.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-lRpkwcX7.js → ForceChangePasswordPage-BE-6umub.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-lRpkwcX7.js.map → ForceChangePasswordPage-BE-6umub.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-CvmYAV3r.js → ForceChangePasswordPage-CnsYoWmV.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-CvmYAV3r.js.map → ForceChangePasswordPage-CnsYoWmV.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-0u49E4Pw.js → ForgotPasswordPage-CSq4DnFF.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-0u49E4Pw.js.map → ForgotPasswordPage-CSq4DnFF.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-CxQUqKOm.js → ForgotPasswordPage-DZLVolAC.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-CxQUqKOm.js.map → ForgotPasswordPage-DZLVolAC.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-DFBvVO1S.js → GroupDetailPage-Bf9Wb_2j.js} +5 -5
- package/dist/chunks/{GroupDetailPage-DFBvVO1S.js.map → GroupDetailPage-Bf9Wb_2j.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-B2FkKrGG.js → GroupDetailPage-R-hf3rJ7.js} +2 -2
- package/dist/chunks/{GroupDetailPage-B2FkKrGG.js.map → GroupDetailPage-R-hf3rJ7.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-C9IX4c0K.js → MyAccessRequestsPage-BIisvWM6.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-C9IX4c0K.js.map → MyAccessRequestsPage-BIisvWM6.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-D6pVULNM.js → MyAccessRequestsPage-BLSV7Tbx.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-D6pVULNM.js.map → MyAccessRequestsPage-BLSV7Tbx.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-BEcYYdGR.js → MyTenantsPage-D-7k9CP1.js} +3 -3
- package/dist/chunks/{MyTenantsPage-BEcYYdGR.js.map → MyTenantsPage-D-7k9CP1.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-D9f85zjF.js → MyTenantsPage-DqGW6aDt.js} +2 -2
- package/dist/chunks/{MyTenantsPage-D9f85zjF.js.map → MyTenantsPage-DqGW6aDt.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-DJR8h6y1.js → MyTicketsPage--DgDsnZA.js} +2 -2
- package/dist/chunks/{MyTicketsPage-DJR8h6y1.js.map → MyTicketsPage--DgDsnZA.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-DiOUExKJ.js → MyTicketsPage-CqJ3Aqob.js} +2 -2
- package/dist/chunks/{MyTicketsPage-DiOUExKJ.js.map → MyTicketsPage-CqJ3Aqob.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-CeHbxfZw.js → NavigationAppsPage-Bebis_RT.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-CeHbxfZw.js.map → NavigationAppsPage-Bebis_RT.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-If7tmCFY.js → NavigationAppsPage-THNPOAjv.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-If7tmCFY.js.map → NavigationAppsPage-THNPOAjv.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-C29Lln5o.js → NotificationsPage-CAbNW_Cn.js} +2 -2
- package/dist/chunks/{NotificationsPage-C29Lln5o.js.map → NotificationsPage-CAbNW_Cn.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-BiaLRb0s.js → NotificationsPage-DxwizUhL.js} +2 -2
- package/dist/chunks/{NotificationsPage-BiaLRb0s.js.map → NotificationsPage-DxwizUhL.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-DQrBKNBq.js → OnboardingWizardPage-C6HlbJ3K.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-DQrBKNBq.js.map → OnboardingWizardPage-C6HlbJ3K.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-BQah4cI8.js → OnboardingWizardPage-CyC2zONO.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-BQah4cI8.js.map → OnboardingWizardPage-CyC2zONO.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-Ckjdjvf9.js → PermissionDetailPage-BDHiNgky.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-Ckjdjvf9.js.map → PermissionDetailPage-BDHiNgky.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-Dh8v7mGj.js → PermissionDetailPage-C5K17ydY.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-Dh8v7mGj.js.map → PermissionDetailPage-C5K17ydY.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-l0PnY-EE.js → PermissionsPage-COI5LJPo.js} +2 -2
- package/dist/chunks/{PermissionsPage-l0PnY-EE.js.map → PermissionsPage-COI5LJPo.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-DLy9U3P3.js → PermissionsPage-CkOwH2_d.js} +2 -2
- package/dist/chunks/{PermissionsPage-DLy9U3P3.js.map → PermissionsPage-CkOwH2_d.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-DFBx38-x.js → PortalDashboardPage-CoEC4CmC.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-DFBx38-x.js.map → PortalDashboardPage-CoEC4CmC.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-rQYhrX0q.js → PortalDashboardPage-DrYymEf-.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-rQYhrX0q.js.map → PortalDashboardPage-DrYymEf-.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-BBu8yZQB.js → PreferencesPage-CJRaU3ba.js} +2 -2
- package/dist/chunks/{PreferencesPage-BBu8yZQB.js.map → PreferencesPage-CJRaU3ba.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-B81MsNV1.js → PreferencesPage-Cqr9mAab.js} +2 -2
- package/dist/chunks/{PreferencesPage-B81MsNV1.js.map → PreferencesPage-Cqr9mAab.js.map} +1 -1
- package/dist/chunks/{ProfilePage-DDrl10zj.js → ProfilePage-BZVpg6-l.js} +2 -2
- package/dist/chunks/{ProfilePage-DDrl10zj.js.map → ProfilePage-BZVpg6-l.js.map} +1 -1
- package/dist/chunks/{ProfilePage-DPoXwdnc.js → ProfilePage-Cu_FITeL.js} +2 -2
- package/dist/chunks/{ProfilePage-DPoXwdnc.js.map → ProfilePage-Cu_FITeL.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-eFsKjIEK.js → ReferencesManagementPage-DUlVk9Ps.js} +3 -3
- package/dist/chunks/{ReferencesManagementPage-eFsKjIEK.js.map → ReferencesManagementPage-DUlVk9Ps.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-DhVsuElE.js → ReferencesManagementPage-ZCuYtqd7.js} +2 -2
- package/dist/chunks/{ReferencesManagementPage-DhVsuElE.js.map → ReferencesManagementPage-ZCuYtqd7.js.map} +1 -1
- package/dist/chunks/{RegisterPage-CiQib3-6.js → RegisterPage-C4xmVwh9.js} +2 -2
- package/dist/chunks/{RegisterPage-CiQib3-6.js.map → RegisterPage-C4xmVwh9.js.map} +1 -1
- package/dist/chunks/{RegisterPage-bXCcJD88.js → RegisterPage-DGyzoIHT.js} +2 -2
- package/dist/chunks/{RegisterPage-bXCcJD88.js.map → RegisterPage-DGyzoIHT.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-Dqiahhnj.js → ResetPasswordPage-DqDD6VPR.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-Dqiahhnj.js.map → ResetPasswordPage-DqDD6VPR.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-CubPG3yv.js → ResetPasswordPage-Glu-aeqv.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-CubPG3yv.js.map → ResetPasswordPage-Glu-aeqv.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-Bg7XZmR1.js → ResolutionModal-CxjANAOP.js} +2 -2
- package/dist/chunks/{ResolutionModal-Bg7XZmR1.js.map → ResolutionModal-CxjANAOP.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-DqRk_T0n.js → ResolutionModal-Duat18qV.js} +2 -2
- package/dist/chunks/{ResolutionModal-DqRk_T0n.js.map → ResolutionModal-Duat18qV.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-Blau6_4c.js → RoleDetailPage-BQffUSnt.js} +3 -3
- package/dist/chunks/{RoleDetailPage-Blau6_4c.js.map → RoleDetailPage-BQffUSnt.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-CiRVxxIP.js → RoleDetailPage-JTm5lD1_.js} +2 -2
- package/dist/chunks/{RoleDetailPage-CiRVxxIP.js.map → RoleDetailPage-JTm5lD1_.js.map} +1 -1
- package/dist/chunks/{RolesPage-Pm-RN3lP.js → RolesPage-B9rRzciI.js} +2 -2
- package/dist/chunks/{RolesPage-Pm-RN3lP.js.map → RolesPage-B9rRzciI.js.map} +1 -1
- package/dist/chunks/{RolesPage-Cb8joqdJ.js → RolesPage-BN8_zMOC.js} +2 -2
- package/dist/chunks/{RolesPage-Cb8joqdJ.js.map → RolesPage-BN8_zMOC.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-B86McKM6.js → SlaConfigPage-B7kZNig4.js} +2 -2
- package/dist/chunks/{SlaConfigPage-B86McKM6.js.map → SlaConfigPage-B7kZNig4.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-BY7gvYU6.js → SlaConfigPage-okvZfA_K.js} +2 -2
- package/dist/chunks/{SlaConfigPage-BY7gvYU6.js.map → SlaConfigPage-okvZfA_K.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-BYxcLMSd.js → SupportPermissionsPage-DGAPqJbl.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-BYxcLMSd.js.map → SupportPermissionsPage-DGAPqJbl.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-MXqXNJIZ.js → SupportPermissionsPage-Dg_wLOme.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-MXqXNJIZ.js.map → SupportPermissionsPage-Dg_wLOme.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-BDguJ401.js → TemplatesPage-DT9fhlAU.js} +2 -2
- package/dist/chunks/{TemplatesPage-BDguJ401.js.map → TemplatesPage-DT9fhlAU.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-DdnGgioU.js → TemplatesPage-DiEk538p.js} +2 -2
- package/dist/chunks/{TemplatesPage-DdnGgioU.js.map → TemplatesPage-DiEk538p.js.map} +1 -1
- package/dist/chunks/{TenantCard-ffwWsgFQ.js → TenantCard-BbSYk9_Z.js} +2 -2
- package/dist/chunks/{TenantCard-ffwWsgFQ.js.map → TenantCard-BbSYk9_Z.js.map} +1 -1
- package/dist/chunks/{TenantCard-CUjb6og9.js → TenantCard-CEkiKxcZ.js} +2 -2
- package/dist/chunks/{TenantCard-CUjb6og9.js.map → TenantCard-CEkiKxcZ.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-Dz7i1I43.js → TenantScopeSelector-BWfYxvEa.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-Dz7i1I43.js.map → TenantScopeSelector-BWfYxvEa.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-Cym_Zyps.js → TenantScopeSelector-D-BKgQPV.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-Cym_Zyps.js.map → TenantScopeSelector-D-BKgQPV.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-GOh9GX7E.js → TicketDetailPage-C1mNS9Up.js} +2 -2
- package/dist/chunks/{TicketDetailPage-GOh9GX7E.js.map → TicketDetailPage-C1mNS9Up.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-Du8WMyqf.js → TicketDetailPage-ieVDRh42.js} +2 -2
- package/dist/chunks/{TicketDetailPage-Du8WMyqf.js.map → TicketDetailPage-ieVDRh42.js.map} +1 -1
- package/dist/chunks/{TicketsPage-Bqd6moQy.js → TicketsPage-CnuWsnIW.js} +2 -2
- package/dist/chunks/{TicketsPage-Bqd6moQy.js.map → TicketsPage-CnuWsnIW.js.map} +1 -1
- package/dist/chunks/{TicketsPage-WdU4Bb7M.js → TicketsPage-jjyY15_D.js} +2 -2
- package/dist/chunks/{TicketsPage-WdU4Bb7M.js.map → TicketsPage-jjyY15_D.js.map} +1 -1
- package/dist/chunks/{UserCreateTicketPage-Cm1emgwR.js → UserCreateTicketPage-B8Tvf-ag.js} +2 -2
- package/dist/chunks/{UserCreateTicketPage-Cm1emgwR.js.map → UserCreateTicketPage-B8Tvf-ag.js.map} +1 -1
- package/dist/chunks/{UserCreateTicketPage-BPw-5Y_D.js → UserCreateTicketPage-DnOsDlfO.js} +2 -2
- package/dist/chunks/{UserCreateTicketPage-BPw-5Y_D.js.map → UserCreateTicketPage-DnOsDlfO.js.map} +1 -1
- package/dist/chunks/{UserDashboardPage-BP5WeXPS.js → UserDashboardPage-BrtkJ-NB.js} +2 -2
- package/dist/chunks/{UserDashboardPage-BP5WeXPS.js.map → UserDashboardPage-BrtkJ-NB.js.map} +1 -1
- package/dist/chunks/{UserDashboardPage-B53C8fUq.js → UserDashboardPage-KLB5CQP5.js} +2 -2
- package/dist/chunks/{UserDashboardPage-B53C8fUq.js.map → UserDashboardPage-KLB5CQP5.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-B110bmGX.js → UserDetailPage-U7smBQoF.js} +5 -5
- package/dist/chunks/{UserDetailPage-B110bmGX.js.map → UserDetailPage-U7smBQoF.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-CV2VCE46.js → UserDetailPage-_J6lcKAU.js} +2 -2
- package/dist/chunks/{UserDetailPage-CV2VCE46.js.map → UserDetailPage-_J6lcKAU.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-CCNJON1V.js → UserTicketDetailPage-CWoYQgH-.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-CCNJON1V.js.map → UserTicketDetailPage-CWoYQgH-.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-V0mLXrox.js → UserTicketDetailPage-DkufSlvZ.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-V0mLXrox.js.map → UserTicketDetailPage-DkufSlvZ.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-CmdaU-z-.js → UsersGroupsPage-C38s2-Rq.js} +3 -3
- package/dist/chunks/{UsersGroupsPage-CmdaU-z-.js.map → UsersGroupsPage-C38s2-Rq.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-BgfAMgEP.js → UsersGroupsPage-Dq3rAteo.js} +2 -2
- package/dist/chunks/{UsersGroupsPage-BgfAMgEP.js.map → UsersGroupsPage-Dq3rAteo.js.map} +1 -1
- package/dist/chunks/{UsersPage-Bg7033pp.js → UsersPage-B5C5KEUR.js} +2 -2
- package/dist/chunks/{UsersPage-Bg7033pp.js.map → UsersPage-B5C5KEUR.js.map} +1 -1
- package/dist/chunks/{UsersPage-TYAfwPY1.js → UsersPage-CXC9Hvq6.js} +2 -2
- package/dist/chunks/{UsersPage-TYAfwPY1.js.map → UsersPage-CXC9Hvq6.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-DZeDvzwv.js → accessRequestsApi-B-4TJ5_U.js} +2 -2
- package/dist/chunks/{accessRequestsApi-DZeDvzwv.js.map → accessRequestsApi-B-4TJ5_U.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-ZXFPCid2.js → accessRequestsApi-DZSfThpd.js} +2 -2
- package/dist/chunks/{accessRequestsApi-ZXFPCid2.js.map → accessRequestsApi-DZSfThpd.js.map} +1 -1
- package/dist/chunks/{aiApi-CsH8DXgs.js → aiApi-B20Teu2v.js} +2 -2
- package/dist/chunks/{aiApi-CsH8DXgs.js.map → aiApi-B20Teu2v.js.map} +1 -1
- package/dist/chunks/{aiApi-CVPzFTXa.js → aiApi-DMGz-RPM.js} +2 -2
- package/dist/chunks/{aiApi-CVPzFTXa.js.map → aiApi-DMGz-RPM.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-B8AhFYLr.js → applicationAnalyticsApi-Bwa75Fzd.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-B8AhFYLr.js.map → applicationAnalyticsApi-Bwa75Fzd.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-Ce_1qOk-.js → applicationAnalyticsApi-CLBqRPfN.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-Ce_1qOk-.js.map → applicationAnalyticsApi-CLBqRPfN.js.map} +1 -1
- package/dist/chunks/{groupsApi-BgCk2fsp.js → groupsApi-QzXI-5xu.js} +2 -2
- package/dist/chunks/{groupsApi-BgCk2fsp.js.map → groupsApi-QzXI-5xu.js.map} +1 -1
- package/dist/chunks/{groupsApi-BIbG665N.js → groupsApi-hB9kSWEd.js} +2 -2
- package/dist/chunks/{groupsApi-BIbG665N.js.map → groupsApi-hB9kSWEd.js.map} +1 -1
- package/dist/chunks/{index-Cb3LotuT.js → index--NGcBYUu.js} +3 -3
- package/dist/chunks/{index-Cb3LotuT.js.map → index--NGcBYUu.js.map} +1 -1
- package/dist/chunks/{index-C33zcyF4.js → index--aPwOFjF.js} +2 -2
- package/dist/chunks/{index-C33zcyF4.js.map → index--aPwOFjF.js.map} +1 -1
- package/dist/chunks/{index-sMr9qND_.js → index-0VrOtwP0.js} +2 -2
- package/dist/chunks/{index-sMr9qND_.js.map → index-0VrOtwP0.js.map} +1 -1
- package/dist/chunks/{index-DDKetfKq.js → index-37U271aw.js} +2 -2
- package/dist/chunks/{index-DDKetfKq.js.map → index-37U271aw.js.map} +1 -1
- package/dist/chunks/{index-B9fS7ir6.js → index-B7qZTuQ-.js} +2 -2
- package/dist/chunks/{index-B9fS7ir6.js.map → index-B7qZTuQ-.js.map} +1 -1
- package/dist/chunks/{index-CdjBY7L8.js → index-Bedzmqr-.js} +2 -2
- package/dist/chunks/{index-CdjBY7L8.js.map → index-Bedzmqr-.js.map} +1 -1
- package/dist/chunks/{index-CHG_O1fS.js → index-Betxo5g5.js} +2 -2
- package/dist/chunks/{index-CHG_O1fS.js.map → index-Betxo5g5.js.map} +1 -1
- package/dist/chunks/{index-jiGu-H8x.js → index-BmaJz475.js} +2 -2
- package/dist/chunks/{index-jiGu-H8x.js.map → index-BmaJz475.js.map} +1 -1
- package/dist/chunks/{index-C53JoVNk.js → index-Buhqag3v.js} +2 -2
- package/dist/chunks/{index-C53JoVNk.js.map → index-Buhqag3v.js.map} +1 -1
- package/dist/chunks/{index-DO0Rw7hX.js → index-C3VxlfKq.js} +2 -2
- package/dist/chunks/{index-DO0Rw7hX.js.map → index-C3VxlfKq.js.map} +1 -1
- package/dist/chunks/{index-CSQ60fpG.js → index-CgpRo8Oe.js} +2 -2
- package/dist/chunks/{index-CSQ60fpG.js.map → index-CgpRo8Oe.js.map} +1 -1
- package/dist/chunks/{index-B-e-ELsf.js → index-DOY0w8Iu.js} +8 -8
- package/dist/chunks/{index-B-e-ELsf.js.map → index-DOY0w8Iu.js.map} +1 -1
- package/dist/chunks/{index-D2REDIRX.js → index-DwuvIOrQ.js} +2 -2
- package/dist/chunks/{index-D2REDIRX.js.map → index-DwuvIOrQ.js.map} +1 -1
- package/dist/chunks/{index-DCcl7Qof.js → index-DzedSLdI.js} +2 -2
- package/dist/chunks/{index-DCcl7Qof.js.map → index-DzedSLdI.js.map} +1 -1
- package/dist/chunks/{index-2wUhd9Lu.js → index-IgLVXPg8.js} +10 -10
- package/dist/chunks/index-IgLVXPg8.js.map +1 -0
- package/dist/chunks/{index-CwSaRXXg.js → index-lpIzhufD.js} +1916 -1900
- package/dist/chunks/index-lpIzhufD.js.map +1 -0
- package/dist/chunks/{index-Cuwn2q-f.js → index-mLUKwbGl.js} +4 -4
- package/dist/chunks/{index-Cuwn2q-f.js.map → index-mLUKwbGl.js.map} +1 -1
- package/dist/chunks/{index-B0mk2tNY.js → index-tO6MMIFB.js} +2 -2
- package/dist/chunks/{index-B0mk2tNY.js.map → index-tO6MMIFB.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-BpNANQ5s.js → tenantIconMap-BQD9byc8.js} +2 -2
- package/dist/chunks/{tenantIconMap-BpNANQ5s.js.map → tenantIconMap-BQD9byc8.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-DtdUgvJO.js → tenantIconMap-CTMuSt18.js} +2 -2
- package/dist/chunks/{tenantIconMap-DtdUgvJO.js.map → tenantIconMap-CTMuSt18.js.map} +1 -1
- package/dist/chunks/{ticketingApi-Bu4rKwLl.js → ticketingApi-BNIdox5t.js} +2 -2
- package/dist/chunks/{ticketingApi-Bu4rKwLl.js.map → ticketingApi-BNIdox5t.js.map} +1 -1
- package/dist/chunks/{ticketingApi-r4Avm9iS.js → ticketingApi-J0vC_t7r.js} +2 -2
- package/dist/chunks/{ticketingApi-r4Avm9iS.js.map → ticketingApi-J0vC_t7r.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-B9bF4swg.js → useAccessRequests-DCNNLnxk.js} +3 -3
- package/dist/chunks/{useAccessRequests-B9bF4swg.js.map → useAccessRequests-DCNNLnxk.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-JyPUX3Om.js → useAccessRequests-DT7X4FAK.js} +2 -2
- package/dist/chunks/{useAccessRequests-JyPUX3Om.js.map → useAccessRequests-DT7X4FAK.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-DjPQenC2.js → useUserAccessRequests-BYbmG4c7.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-DjPQenC2.js.map → useUserAccessRequests-BYbmG4c7.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-BB6FHW14.js → useUserAccessRequests-CylKxRN6.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-BB6FHW14.js.map → useUserAccessRequests-CylKxRN6.js.map} +1 -1
- package/dist/hooks/useCollapsibleState.d.ts +5 -2
- package/dist/hooks/useCollapsibleState.d.ts.map +1 -1
- package/dist/i18n/config.d.ts +1 -0
- package/dist/i18n/config.d.ts.map +1 -1
- package/dist/main.d.ts +0 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/smartstack.cjs +1 -1
- package/dist/smartstack.js +1 -1
- package/dist/utils/permissions.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/index-2wUhd9Lu.js.map +0 -1
- package/dist/chunks/index-CwSaRXXg.js.map +0 -1
package/dist/chunks/{ApplicationDetailPage-D8-bf1as.js.map → ApplicationDetailPage-CuCW6aMB.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationDetailPage-D8-bf1as.js","sources":["../../src/utils/renderLucideIcon.tsx","../../src/hooks/useApplicationDetail.ts","../../src/hooks/useApplicationModules.ts","../../src/hooks/useApplicationPermissions.ts","../../src/hooks/useApplicationPublication.ts","../../src/components/platform/administration/applications/ApplicationInfoTab.tsx","../../src/components/ui/SortableList.tsx","../../src/components/platform/administration/applications/ApplicationModulesTab.tsx","../../src/components/platform/administration/applications/ApplicationPermissionsTab.tsx","../../src/components/platform/administration/applications/ApplicationAccessTab.tsx","../../src/components/platform/administration/applications/ApplicationPublicationTab.tsx","../../src/pages/platform/administration/applications/ApplicationDetailPage.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport * as LucideIcons from 'lucide-react';\r\nimport type { LucideIcon } from 'lucide-react';\r\n\r\n/**\r\n * Renders a Lucide icon by name string or LucideIcon component.\r\n * Returns null if the icon name is invalid or null.\r\n */\r\nexport function renderLucideIcon(\r\n icon: LucideIcon | string | null | undefined,\r\n className = 'w-4 h-4',\r\n): ReactElement | null {\r\n if (!icon) return null;\r\n\r\n if (typeof icon === 'string') {\r\n const icons = LucideIcons as unknown as Record<string, LucideIcon>;\r\n const IconComponent = icons[icon];\r\n if (!IconComponent) return null;\r\n return <IconComponent className={className} />;\r\n }\r\n\r\n const Icon = icon;\r\n return <Icon className={className} />;\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n adminApi,\r\n type ApplicationDetailDto,\r\n type UpdateApplicationRequest,\r\n} from '@/services/api/adminApi';\r\n\r\nexport interface ApplicationFormData {\r\n label: string;\r\n description: string;\r\n icon: string;\r\n route: string;\r\n displayOrder: number;\r\n}\r\n\r\nexport interface UseApplicationDetailReturn {\r\n application: ApplicationDetailDto | null;\r\n loading: boolean;\r\n saving: boolean;\r\n error: string | null;\r\n success: string | null;\r\n formData: ApplicationFormData;\r\n setFormData: React.Dispatch<React.SetStateAction<ApplicationFormData>>;\r\n setError: (error: string | null) => void;\r\n setSuccess: (success: string | null) => void;\r\n loadApplication: (appId: string) => Promise<void>;\r\n handleSaveInfo: (appId: string, data: ApplicationFormData) => Promise<void>;\r\n handleToggleStatus: (appId: string) => Promise<void>;\r\n}\r\n\r\nexport function useApplicationDetail(): UseApplicationDetailReturn {\r\n const { t } = useTranslation('admin');\r\n\r\n const [application, setApplication] = useState<ApplicationDetailDto | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [saving, setSaving] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n\r\n const [formData, setFormData] = useState<ApplicationFormData>({\r\n label: '',\r\n description: '',\r\n icon: '',\r\n route: '',\r\n displayOrder: 0,\r\n });\r\n\r\n const loadApplication = useCallback(async (appId: string) => {\r\n if (!appId) return;\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n try {\r\n const data = await adminApi.applications.getById(appId);\r\n setApplication(data);\r\n setFormData({\r\n label: data.label,\r\n description: data.description || '',\r\n icon: data.icon || '',\r\n route: data.route || '',\r\n displayOrder: data.displayOrder,\r\n });\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('applicationDetail.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [t]);\r\n\r\n const handleSaveInfo = useCallback(async (appId: string, data: ApplicationFormData) => {\r\n if (!appId || !application) return;\r\n\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n\r\n try {\r\n const updateData: UpdateApplicationRequest = {\r\n label: data.label,\r\n description: data.description || undefined,\r\n icon: data.icon || undefined,\r\n route: data.route || undefined,\r\n displayOrder: data.displayOrder,\r\n };\r\n\r\n await adminApi.applications.update(appId, updateData);\r\n setSuccess(t('applicationDetail.success.saved'));\r\n await loadApplication(appId);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('applicationDetail.errors.saveFailed'));\r\n } finally {\r\n setSaving(false);\r\n }\r\n }, [application, t, loadApplication]);\r\n\r\n const handleToggleStatus = useCallback(async (appId: string) => {\r\n if (!appId || !application) return;\r\n\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n\r\n try {\r\n if (application.isActive) {\r\n await adminApi.applications.deactivate(appId);\r\n } else {\r\n await adminApi.applications.activate(appId);\r\n }\r\n\r\n setSuccess(\r\n application.isActive\r\n ? t('applicationDetail.success.deactivated')\r\n : t('applicationDetail.success.activated')\r\n );\r\n await loadApplication(appId);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('applicationDetail.errors.toggleFailed'));\r\n } finally {\r\n setSaving(false);\r\n }\r\n }, [application, t, loadApplication]);\r\n\r\n return {\r\n application,\r\n loading,\r\n saving,\r\n error,\r\n success,\r\n formData,\r\n setFormData,\r\n setError,\r\n setSuccess,\r\n loadApplication,\r\n handleSaveInfo,\r\n handleToggleStatus,\r\n };\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport {\r\n adminApi,\r\n type ApplicationModuleDto,\r\n type ModuleSectionDto,\r\n} from '@/services/api/adminApi';\r\n\r\nexport interface ModuleFormData {\r\n code: string;\r\n label: string;\r\n description: string;\r\n icon: string;\r\n route: string;\r\n displayOrder: number;\r\n}\r\n\r\nexport interface UseApplicationModulesReturn {\r\n expandedModules: Set<string>;\r\n moduleSections: Map<string, ModuleSectionDto[]>;\r\n loadingSections: Set<string>;\r\n reordering: boolean;\r\n editingModule: ApplicationModuleDto | null;\r\n moduleFormData: ModuleFormData;\r\n showModuleForm: boolean;\r\n toggleModuleExpand: (appId: string, moduleId: string) => Promise<void>;\r\n handleSaveModule: (appId: string, moduleId: string, data: ModuleFormData) => Promise<void>;\r\n handleModulesReorder: (appId: string, modules: (ApplicationModuleDto & { id: string })[]) => Promise<void>;\r\n handleSectionsReorder: (appId: string, moduleId: string, sections: ModuleSectionDto[]) => Promise<void>;\r\n startEditModule: (module: ApplicationModuleDto) => void;\r\n resetModuleForm: (moduleCount?: number) => void;\r\n setShowModuleForm: (show: boolean) => void;\r\n setEditingModule: (module: ApplicationModuleDto | null) => void;\r\n setModuleFormData: (data: ModuleFormData) => void;\r\n}\r\n\r\nexport function useApplicationModules(): UseApplicationModulesReturn {\r\n const [expandedModules, setExpandedModules] = useState<Set<string>>(new Set());\r\n const [moduleSections, setModuleSections] = useState<Map<string, ModuleSectionDto[]>>(new Map());\r\n const [loadingSections, setLoadingSections] = useState<Set<string>>(new Set());\r\n const [reordering, setReordering] = useState(false);\r\n\r\n const [editingModule, setEditingModule] = useState<ApplicationModuleDto | null>(null);\r\n const [moduleFormData, setModuleFormData] = useState<ModuleFormData>({\r\n code: '',\r\n label: '',\r\n description: '',\r\n icon: '',\r\n route: '',\r\n displayOrder: 0,\r\n });\r\n const [showModuleForm, setShowModuleForm] = useState(false);\r\n\r\n const toggleModuleExpand = useCallback(async (appId: string, moduleId: string) => {\r\n const isExpanding = !expandedModules.has(moduleId);\r\n\r\n setExpandedModules(prev => {\r\n const newSet = new Set(prev);\r\n if (newSet.has(moduleId)) {\r\n newSet.delete(moduleId);\r\n } else {\r\n newSet.add(moduleId);\r\n }\r\n return newSet;\r\n });\r\n\r\n // Load sections if expanding and not already loaded\r\n if (isExpanding && !moduleSections.has(moduleId)) {\r\n setLoadingSections(prev => new Set(prev).add(moduleId));\r\n try {\r\n const sections = await adminApi.applications.getModuleSections(appId, moduleId);\r\n setModuleSections(prev => new Map(prev).set(moduleId, sections));\r\n } catch (err) {\r\n console.error('Failed to load sections:', err);\r\n } finally {\r\n setLoadingSections(prev => {\r\n const newSet = new Set(prev);\r\n newSet.delete(moduleId);\r\n return newSet;\r\n });\r\n }\r\n }\r\n }, [expandedModules, moduleSections]);\r\n\r\n const handleSaveModule = useCallback(async (appId: string, moduleId: string, data: ModuleFormData) => {\r\n try {\r\n await adminApi.applications.updateModule(appId, moduleId, {\r\n label: data.label,\r\n description: data.description || undefined,\r\n icon: data.icon || undefined,\r\n route: data.route || undefined,\r\n displayOrder: data.displayOrder,\r\n });\r\n setShowModuleForm(false);\r\n setEditingModule(null);\r\n resetModuleForm();\r\n } catch (err) {\r\n console.error('Failed to save module:', err);\r\n throw err;\r\n }\r\n }, []);\r\n\r\n const handleModulesReorder = useCallback(async (appId: string, reorderedModules: (ApplicationModuleDto & { id: string })[]) => {\r\n // Optimistic update\r\n const newModules = reorderedModules.map((m, index) => ({ ...m, displayOrder: index }));\r\n\r\n setReordering(true);\r\n try {\r\n await adminApi.applications.reorderModules(appId, newModules.map((m, index) => ({ id: m.id, displayOrder: index })));\r\n } catch (err) {\r\n console.error('Failed to reorder modules:', err);\r\n throw err;\r\n } finally {\r\n setReordering(false);\r\n }\r\n }, []);\r\n\r\n const handleSectionsReorder = useCallback(async (appId: string, moduleId: string, reorderedSections: ModuleSectionDto[]) => {\r\n // Optimistic update\r\n const newSections = reorderedSections.map((s, index) => ({ ...s, displayOrder: index }));\r\n setModuleSections(prev => new Map(prev).set(moduleId, newSections));\r\n\r\n setReordering(true);\r\n try {\r\n await adminApi.applications.reorderSections(appId, moduleId, newSections.map((s, index) => ({ id: s.id, displayOrder: index })));\r\n } catch (err) {\r\n console.error('Failed to reorder sections:', err);\r\n // Reload sections on error\r\n try {\r\n const sections = await adminApi.applications.getModuleSections(appId, moduleId);\r\n setModuleSections(prev => new Map(prev).set(moduleId, sections));\r\n } catch (reloadErr) {\r\n console.error('Failed to reload sections:', reloadErr);\r\n }\r\n throw err;\r\n } finally {\r\n setReordering(false);\r\n }\r\n }, []);\r\n\r\n const startEditModule = useCallback((module: ApplicationModuleDto) => {\r\n setEditingModule(module);\r\n setModuleFormData({\r\n code: module.code,\r\n label: module.label,\r\n description: module.description || '',\r\n icon: module.icon || '',\r\n route: module.route || '',\r\n displayOrder: module.displayOrder,\r\n });\r\n setShowModuleForm(true);\r\n }, []);\r\n\r\n const resetModuleForm = useCallback((moduleCount?: number) => {\r\n setModuleFormData({\r\n code: '',\r\n label: '',\r\n description: '',\r\n icon: '',\r\n route: '',\r\n displayOrder: moduleCount || 0,\r\n });\r\n }, []);\r\n\r\n return {\r\n expandedModules,\r\n moduleSections,\r\n loadingSections,\r\n reordering,\r\n editingModule,\r\n moduleFormData,\r\n showModuleForm,\r\n toggleModuleExpand,\r\n handleSaveModule,\r\n handleModulesReorder,\r\n handleSectionsReorder,\r\n startEditModule,\r\n resetModuleForm,\r\n setShowModuleForm,\r\n setEditingModule,\r\n setModuleFormData,\r\n };\r\n}\r\n","import { useState, useCallback, useMemo } from 'react';\r\nimport { adminApi, type PermissionListDto, type RoleListDto, type MatrixRoleDto, type ApplicationDetailDto } from '@/services/api/adminApi';\r\n\r\nexport interface PermissionWithRoles {\r\n permission: PermissionListDto;\r\n roles: RoleListDto[];\r\n}\r\n\r\nexport interface RoleWithPermissions {\r\n role: RoleListDto;\r\n permissions: PermissionListDto[];\r\n}\r\n\r\nconst getPermissionWithRoles = (\r\n perm: PermissionListDto,\r\n matrixRoles: MatrixRoleDto[],\r\n allRoles: RoleListDto[]\r\n): PermissionWithRoles => {\r\n const rolesWithPerm = matrixRoles\r\n .filter(mr => mr.permissionIds.includes(perm.id))\r\n .map(mr => allRoles.find(r => r.id === mr.id)!)\r\n .filter(Boolean);\r\n return { permission: perm, roles: rolesWithPerm };\r\n};\r\n\r\nexport interface UseApplicationPermissionsReturn {\r\n roles: RoleListDto[];\r\n permissions: PermissionListDto[];\r\n permissionsWithRoles: PermissionWithRoles[];\r\n rolesWithAppAccess: RoleWithPermissions[];\r\n\r\n loadPermissionsData: (application: ApplicationDetailDto) => Promise<void>;\r\n loadRolesData: () => Promise<void>;\r\n}\r\n\r\nexport function useApplicationPermissions(): UseApplicationPermissionsReturn {\r\n const [roles, setRoles] = useState<RoleListDto[]>([]);\r\n const [permissions, setPermissions] = useState<PermissionListDto[]>([]);\r\n const [permissionsWithRoles, setPermissionsWithRoles] = useState<PermissionWithRoles[]>([]);\r\n\r\n const loadPermissionsData = useCallback(async (application: ApplicationDetailDto) => {\r\n try {\r\n const [matrix, allRoles] = await Promise.all([\r\n adminApi.permissions.getMatrix(),\r\n adminApi.roles.getAll(),\r\n ]);\r\n\r\n const appPermissionPrefix = `${application.code}.`.toLowerCase();\r\n const appPermissions = matrix.permissions.filter(p =>\r\n p.path.toLowerCase().startsWith(appPermissionPrefix)\r\n );\r\n\r\n setPermissions(appPermissions);\r\n setRoles(allRoles);\r\n\r\n const permWithRoles: PermissionWithRoles[] = appPermissions.map(perm =>\r\n getPermissionWithRoles(perm, matrix.roles, allRoles)\r\n );\r\n\r\n setPermissionsWithRoles(permWithRoles);\r\n } catch (err) {\r\n console.error('Failed to load permissions data:', err);\r\n throw err;\r\n }\r\n }, []);\r\n\r\n const loadRolesData = useCallback(async () => {\r\n try {\r\n const allRoles = await adminApi.roles.getAll();\r\n setRoles(allRoles);\r\n } catch (err) {\r\n console.error('Failed to load roles:', err);\r\n throw err;\r\n }\r\n }, []);\r\n\r\n const rolesWithAppAccess = useMemo<RoleWithPermissions[]>(() => {\r\n if (permissionsWithRoles.length === 0) return [];\r\n\r\n const roleAccessMap = new Map<string, { role: RoleListDto; permissions: PermissionListDto[] }>();\r\n\r\n permissionsWithRoles.forEach(({ permission, roles: permRoles }) => {\r\n permRoles.forEach(role => {\r\n if (!roleAccessMap.has(role.id)) {\r\n roleAccessMap.set(role.id, { role, permissions: [] });\r\n }\r\n roleAccessMap.get(role.id)!.permissions.push(permission);\r\n });\r\n });\r\n\r\n return Array.from(roleAccessMap.values()).sort((a, b) =>\r\n b.permissions.length - a.permissions.length\r\n );\r\n }, [permissionsWithRoles]);\r\n\r\n return {\r\n roles,\r\n permissions,\r\n permissionsWithRoles,\r\n rolesWithAppAccess,\r\n loadPermissionsData,\r\n loadRolesData,\r\n };\r\n}\r\n","import React, { useState, useCallback } from 'react';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport type {\r\n ApplicationTenantDto,\r\n AvailableTenantForAppDto,\r\n ApplicationAccessLevel,\r\n BulkAssignTenantsRequest,\r\n} from '@/services/api/adminApi';\r\n\r\nconst updateModuleAssignment = (module: BulkModuleNode, moduleId: string): BulkModuleNode => {\r\n if (module.id !== moduleId) return module;\r\n const newIsAssigned = !module.isAssigned;\r\n return {\r\n ...module,\r\n isAssigned: newIsAssigned,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: newIsAssigned })),\r\n };\r\n};\r\n\r\nconst updateSectionAssignment = (module: BulkModuleNode, moduleId: string, sectionId: string): BulkModuleNode => {\r\n if (module.id !== moduleId) return module;\r\n const newSections = module.sections.map(s =>\r\n s.id === sectionId ? { ...s, isAssigned: !s.isAssigned } : s\r\n );\r\n const allSectionsAssigned = newSections.every(s => s.isAssigned);\r\n return {\r\n ...module,\r\n isAssigned: allSectionsAssigned,\r\n sections: newSections,\r\n };\r\n};\r\n\r\nconst assignAllSections = (module: BulkModuleNode): BulkModuleNode => ({\r\n ...module,\r\n isAssigned: true,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: true })),\r\n});\r\n\r\nconst clearAllSections = (module: BulkModuleNode): BulkModuleNode => ({\r\n ...module,\r\n isAssigned: false,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: false })),\r\n});\r\n\r\n// Bulk operation interfaces\r\nexport interface BulkModuleNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n isAssigned: boolean;\r\n sections: BulkSectionNode[];\r\n}\r\n\r\nexport interface BulkSectionNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n isAssigned: boolean;\r\n}\r\n\r\nexport type BulkAccessMode = 'full' | 'custom';\r\n\r\nexport interface UseApplicationPublicationReturn {\r\n // State\r\n assignedTenants: ApplicationTenantDto[];\r\n availableTenants: AvailableTenantForAppDto[];\r\n showAssignModal: boolean;\r\n selectedTenantIds: string[];\r\n selectedAccessLevel: ApplicationAccessLevel;\r\n tenantSearch: string;\r\n showCustomizeDrawer: boolean;\r\n customizingTenant: ApplicationTenantDto | null;\r\n bulkAccessMode: BulkAccessMode;\r\n bulkModules: BulkModuleNode[];\r\n bulkExpandedModules: Set<string>;\r\n loadingBulkModules: boolean;\r\n isUpdateMode: boolean;\r\n updateMergeMode: 'merge' | 'replace';\r\n showConfirmRemovalDialog: boolean;\r\n pendingRemovals: { modules: number; sections: number };\r\n includePersonalTenants: boolean;\r\n isInDefaultPersonalTemplate: boolean;\r\n\r\n // Setters\r\n setAssignedTenants: React.Dispatch<React.SetStateAction<ApplicationTenantDto[]>>;\r\n setAvailableTenants: React.Dispatch<React.SetStateAction<AvailableTenantForAppDto[]>>;\r\n setShowAssignModal: React.Dispatch<React.SetStateAction<boolean>>;\r\n setSelectedTenantIds: React.Dispatch<React.SetStateAction<string[]>>;\r\n setSelectedAccessLevel: React.Dispatch<React.SetStateAction<ApplicationAccessLevel>>;\r\n setTenantSearch: React.Dispatch<React.SetStateAction<string>>;\r\n setShowCustomizeDrawer: React.Dispatch<React.SetStateAction<boolean>>;\r\n setCustomizingTenant: React.Dispatch<React.SetStateAction<ApplicationTenantDto | null>>;\r\n setBulkAccessMode: React.Dispatch<React.SetStateAction<BulkAccessMode>>;\r\n setBulkModules: React.Dispatch<React.SetStateAction<BulkModuleNode[]>>;\r\n setBulkExpandedModules: React.Dispatch<React.SetStateAction<Set<string>>>;\r\n setIsUpdateMode: React.Dispatch<React.SetStateAction<boolean>>;\r\n setUpdateMergeMode: React.Dispatch<React.SetStateAction<'merge' | 'replace'>>;\r\n setShowConfirmRemovalDialog: React.Dispatch<React.SetStateAction<boolean>>;\r\n setPendingRemovals: React.Dispatch<React.SetStateAction<{ modules: number; sections: number }>>;\r\n setIncludePersonalTenants: React.Dispatch<React.SetStateAction<boolean>>;\r\n\r\n // Publication operations\r\n loadPublicationData: (appId: string) => Promise<void>;\r\n loadBulkModules: (appId: string) => Promise<void>;\r\n\r\n // Bulk module operations\r\n toggleBulkModuleExpand: (moduleId: string) => void;\r\n toggleBulkModule: (moduleId: string) => void;\r\n toggleBulkSection: (moduleId: string, sectionId: string) => void;\r\n getBulkModuleCheckState: (module: BulkModuleNode) => 'checked' | 'unchecked' | 'indeterminate';\r\n getBulkStats: () => { totalModules: number; assignedModules: number; totalSections: number; assignedSections: number };\r\n selectAllBulkModules: () => void;\r\n clearBulkModules: () => void;\r\n\r\n // Tenant assignment operations\r\n toggleTenantSelection: (tenantId: string) => void;\r\n selectAllFilteredTenants: () => void;\r\n clearTenantSelection: () => void;\r\n\r\n // API operations\r\n handleAssignTenants: (appId: string, onSuccess?: () => void) => Promise<void>;\r\n handleUpdateTenants: (appId: string, onSuccess?: () => void) => Promise<void>;\r\n executeUpdateTenants: (appId: string, onSuccess?: () => void) => Promise<void>;\r\n handleRemoveTenant: (appId: string, tenantId: string, onSuccess?: () => void) => Promise<void>;\r\n handleUpdateAccessLevel: (appId: string, tenantId: string, accessLevel: ApplicationAccessLevel, onSuccess?: () => void) => Promise<void>;\r\n}\r\n\r\nexport function useApplicationPublication(): UseApplicationPublicationReturn {\r\n // Publication state\r\n const [assignedTenants, setAssignedTenants] = useState<ApplicationTenantDto[]>([]);\r\n const [availableTenants, setAvailableTenants] = useState<AvailableTenantForAppDto[]>([]);\r\n const [showAssignModal, setShowAssignModal] = useState(false);\r\n const [selectedTenantIds, setSelectedTenantIds] = useState<string[]>([]);\r\n const [selectedAccessLevel, setSelectedAccessLevel] = useState<ApplicationAccessLevel>('FullAccess');\r\n const [tenantSearch, setTenantSearch] = useState('');\r\n\r\n // Customize access drawer state\r\n const [showCustomizeDrawer, setShowCustomizeDrawer] = useState(false);\r\n const [customizingTenant, setCustomizingTenant] = useState<ApplicationTenantDto | null>(null);\r\n\r\n // Bulk customization state\r\n const [bulkAccessMode, setBulkAccessMode] = useState<BulkAccessMode>('full');\r\n const [bulkModules, setBulkModules] = useState<BulkModuleNode[]>([]);\r\n const [bulkExpandedModules, setBulkExpandedModules] = useState<Set<string>>(new Set());\r\n const [loadingBulkModules, setLoadingBulkModules] = useState(false);\r\n\r\n // Update mode state\r\n const [isUpdateMode, setIsUpdateMode] = useState(false);\r\n const [updateMergeMode, setUpdateMergeMode] = useState<'merge' | 'replace'>('merge');\r\n const [showConfirmRemovalDialog, setShowConfirmRemovalDialog] = useState(false);\r\n const [pendingRemovals, setPendingRemovals] = useState<{ modules: number; sections: number }>({ modules: 0, sections: 0 });\r\n\r\n // Personal tenant filter state\r\n const [includePersonalTenants, setIncludePersonalTenants] = useState(false);\r\n const [isInDefaultPersonalTemplate, setIsInDefaultPersonalTemplate] = useState(false);\r\n\r\n // Publication data loading\r\n const loadPublicationData = useCallback(async (appId: string) => {\r\n try {\r\n const [assigned, availableResponse] = await Promise.all([\r\n adminApi.applications.getTenants(appId),\r\n adminApi.applications.getAvailableTenants(appId),\r\n ]);\r\n setAssignedTenants(assigned);\r\n setAvailableTenants(availableResponse.tenants);\r\n setIsInDefaultPersonalTemplate(availableResponse.isInDefaultPersonalTemplate);\r\n } catch (err) {\r\n console.error('Failed to load publication data:', err);\r\n }\r\n }, []);\r\n\r\n // Load bulk modules for custom access mode\r\n const loadBulkModules = useCallback(async (appId: string) => {\r\n setLoadingBulkModules(true);\r\n try {\r\n const appModules = await adminApi.applications.getModules(appId);\r\n const moduleNodes: BulkModuleNode[] = [];\r\n\r\n for (const appModule of appModules) {\r\n const sections = await adminApi.applications.getModuleSections(appId, appModule.id);\r\n const sectionNodes: BulkSectionNode[] = sections.map(section => ({\r\n id: section.id,\r\n label: section.label,\r\n code: section.code,\r\n icon: section.icon,\r\n isAssigned: true,\r\n }));\r\n\r\n moduleNodes.push({\r\n id: appModule.id,\r\n label: appModule.label,\r\n code: appModule.code,\r\n icon: appModule.icon,\r\n isAssigned: true,\r\n sections: sectionNodes,\r\n });\r\n }\r\n\r\n setBulkModules(moduleNodes);\r\n } catch (err) {\r\n console.error('Failed to load bulk modules:', err);\r\n } finally {\r\n setLoadingBulkModules(false);\r\n }\r\n }, []);\r\n\r\n // Toggle bulk module expansion\r\n const toggleBulkModuleExpand = useCallback((moduleId: string) => {\r\n setBulkExpandedModules(prev => {\r\n const newSet = new Set(prev);\r\n if (newSet.has(moduleId)) {\r\n newSet.delete(moduleId);\r\n } else {\r\n newSet.add(moduleId);\r\n }\r\n return newSet;\r\n });\r\n }, []);\r\n\r\n // Toggle entire bulk module (all sections)\r\n const toggleBulkModule = useCallback((moduleId: string) => {\r\n setBulkModules(prev => prev.map(m => updateModuleAssignment(m, moduleId)));\r\n }, []);\r\n\r\n // Toggle bulk section within module\r\n const toggleBulkSection = useCallback((moduleId: string, sectionId: string) => {\r\n setBulkModules(prev => prev.map(m => updateSectionAssignment(m, moduleId, sectionId)));\r\n }, []);\r\n\r\n // Get checkbox state for bulk module (checked, unchecked, or indeterminate)\r\n const getBulkModuleCheckState = useCallback((module: BulkModuleNode): 'checked' | 'unchecked' | 'indeterminate' => {\r\n const assignedCount = module.sections.filter(s => s.isAssigned).length;\r\n if (assignedCount === 0) return 'unchecked';\r\n if (assignedCount === module.sections.length) return 'checked';\r\n return 'indeterminate';\r\n }, []);\r\n\r\n // Get statistics for bulk selection\r\n const getBulkStats = useCallback(() => {\r\n const totalModules = bulkModules.length;\r\n const assignedModules = bulkModules.filter(m => m.isAssigned || m.sections.some(s => s.isAssigned)).length;\r\n const totalSections = bulkModules.reduce((sum, m) => sum + m.sections.length, 0);\r\n const assignedSections = bulkModules.reduce((sum, m) => sum + m.sections.filter(s => s.isAssigned).length, 0);\r\n return { totalModules, assignedModules, totalSections, assignedSections };\r\n }, [bulkModules]);\r\n\r\n // Select all bulk modules\r\n const selectAllBulkModules = useCallback(() => {\r\n setBulkModules(prev => prev.map(m => assignAllSections(m)));\r\n }, []);\r\n\r\n // Clear all bulk module selections\r\n const clearBulkModules = useCallback(() => {\r\n setBulkModules(prev => prev.map(m => clearAllSections(m)));\r\n }, []);\r\n\r\n // Toggle tenant selection\r\n const toggleTenantSelection = useCallback((tenantId: string) => {\r\n setSelectedTenantIds(prev =>\r\n prev.includes(tenantId)\r\n ? prev.filter(id => id !== tenantId)\r\n : [...prev, tenantId]\r\n );\r\n }, []);\r\n\r\n // Select all filtered tenants (based on search and personal filter)\r\n const selectAllFilteredTenants = useCallback(() => {\r\n if (isUpdateMode) {\r\n const filteredIds = assignedTenants\r\n .filter(t => {\r\n const matchesSearch =\r\n t.tenantName.toLowerCase().includes(tenantSearch.toLowerCase()) ||\r\n t.tenantSlug.toLowerCase().includes(tenantSearch.toLowerCase());\r\n const matchesType = includePersonalTenants || t.tenantType !== 'Personal';\r\n return matchesSearch && matchesType;\r\n })\r\n .map(t => t.tenantId);\r\n setSelectedTenantIds(filteredIds);\r\n } else {\r\n const filteredIds = availableTenants\r\n .filter(t => {\r\n const matchesSearch =\r\n t.name.toLowerCase().includes(tenantSearch.toLowerCase()) ||\r\n t.slug.toLowerCase().includes(tenantSearch.toLowerCase());\r\n const matchesType = includePersonalTenants || t.type !== 'Personal';\r\n return matchesSearch && matchesType;\r\n })\r\n .map(t => t.id);\r\n setSelectedTenantIds(filteredIds);\r\n }\r\n }, [isUpdateMode, assignedTenants, availableTenants, tenantSearch, includePersonalTenants]);\r\n\r\n // Clear tenant selection\r\n const clearTenantSelection = useCallback(() => {\r\n setSelectedTenantIds([]);\r\n }, []);\r\n\r\n // Execute the actual update operation\r\n const executeUpdateTenants = useCallback(\r\n async (appId: string, onSuccess?: () => void) => {\r\n if (!appId || selectedTenantIds.length === 0) return;\r\n\r\n try {\r\n const request: BulkAssignTenantsRequest = {\r\n tenantIds: selectedTenantIds,\r\n accessLevel: selectedAccessLevel,\r\n accessMode: bulkAccessMode,\r\n mergeMode: updateMergeMode,\r\n };\r\n\r\n if (bulkAccessMode === 'custom') {\r\n request.moduleIds = bulkModules.filter(m => m.isAssigned).map(m => m.id);\r\n request.sectionIds = bulkModules.flatMap(m =>\r\n m.sections.filter(s => s.isAssigned).map(s => s.id)\r\n );\r\n }\r\n\r\n await adminApi.applications.bulkAssignTenants(appId, request);\r\n\r\n // Reset state\r\n setShowAssignModal(false);\r\n setSelectedTenantIds([]);\r\n setSelectedAccessLevel('FullAccess');\r\n setBulkAccessMode('full');\r\n setTenantSearch('');\r\n setIsUpdateMode(false);\r\n setUpdateMergeMode('merge');\r\n setShowConfirmRemovalDialog(false);\r\n await loadPublicationData(appId);\r\n\r\n if (onSuccess) onSuccess();\r\n } catch (err) {\r\n console.error('Failed to update tenant assignments:', err);\r\n throw err;\r\n }\r\n },\r\n [selectedTenantIds, selectedAccessLevel, bulkAccessMode, updateMergeMode, bulkModules, loadPublicationData]\r\n );\r\n\r\n // Assign application to tenants\r\n const handleAssignTenants = useCallback(\r\n async (appId: string, onSuccess?: () => void) => {\r\n if (!appId || selectedTenantIds.length === 0) return;\r\n\r\n try {\r\n const request: BulkAssignTenantsRequest = {\r\n tenantIds: selectedTenantIds,\r\n accessLevel: selectedAccessLevel,\r\n accessMode: bulkAccessMode,\r\n };\r\n\r\n if (bulkAccessMode === 'custom') {\r\n request.moduleIds = bulkModules.filter(m => m.isAssigned).map(m => m.id);\r\n request.sectionIds = bulkModules.flatMap(m =>\r\n m.sections.filter(s => s.isAssigned).map(s => s.id)\r\n );\r\n }\r\n\r\n await adminApi.applications.bulkAssignTenants(appId, request);\r\n\r\n // Reset state\r\n setShowAssignModal(false);\r\n setSelectedTenantIds([]);\r\n setSelectedAccessLevel('FullAccess');\r\n setBulkAccessMode('full');\r\n setTenantSearch('');\r\n await loadPublicationData(appId);\r\n\r\n if (onSuccess) onSuccess();\r\n } catch (err) {\r\n console.error('Failed to assign tenants:', err);\r\n throw err;\r\n }\r\n },\r\n [selectedTenantIds, selectedAccessLevel, bulkAccessMode, bulkModules, loadPublicationData]\r\n );\r\n\r\n // Update existing tenant assignments (with confirmation for replace mode)\r\n const handleUpdateTenants = useCallback(\r\n async (appId: string, onSuccess?: () => void) => {\r\n if (!appId || selectedTenantIds.length === 0) return;\r\n\r\n // Calculate potential removals in replace mode\r\n if (updateMergeMode === 'replace' && bulkAccessMode === 'custom') {\r\n let removedModulesCount = 0;\r\n let removedSectionsCount = 0;\r\n\r\n // Get current assignments for selected tenants and calculate diff\r\n for (const tenantId of selectedTenantIds) {\r\n try {\r\n const currentModules = await adminApi.tenants.getModules(tenantId);\r\n const currentSections = await adminApi.tenants.getSections(tenantId);\r\n\r\n const targetModuleIds = new Set(bulkModules.filter(m => m.isAssigned).map(m => m.id));\r\n const targetSectionIds = new Set(bulkModules.flatMap(m => m.sections.filter(s => s.isAssigned).map(s => s.id)));\r\n\r\n removedModulesCount += currentModules.filter(m => !targetModuleIds.has(m.moduleId)).length;\r\n removedSectionsCount += currentSections.filter(s => !targetSectionIds.has(s.sectionId)).length;\r\n } catch {\r\n // Ignore errors fetching current state\r\n }\r\n }\r\n\r\n // If there are removals, show confirmation dialog\r\n if (removedModulesCount > 0 || removedSectionsCount > 0) {\r\n setPendingRemovals({ modules: removedModulesCount, sections: removedSectionsCount });\r\n setShowConfirmRemovalDialog(true);\r\n return;\r\n }\r\n }\r\n\r\n await executeUpdateTenants(appId, onSuccess);\r\n },\r\n [\r\n selectedTenantIds,\r\n updateMergeMode,\r\n bulkAccessMode,\r\n bulkModules,\r\n executeUpdateTenants,\r\n ]\r\n );\r\n\r\n // Remove application from tenant\r\n const handleRemoveTenant = useCallback(\r\n async (appId: string, tenantId: string, onSuccess?: () => void) => {\r\n if (!appId) return;\r\n\r\n try {\r\n await adminApi.applications.removeFromTenant(appId, tenantId);\r\n await loadPublicationData(appId);\r\n\r\n if (onSuccess) onSuccess();\r\n } catch (err) {\r\n console.error('Failed to remove tenant:', err);\r\n throw err;\r\n }\r\n },\r\n [loadPublicationData]\r\n );\r\n\r\n // Update tenant access level\r\n const handleUpdateAccessLevel = useCallback(\r\n async (appId: string, tenantId: string, accessLevel: ApplicationAccessLevel, onSuccess?: () => void) => {\r\n if (!appId) return;\r\n\r\n try {\r\n await adminApi.applications.updateTenantAccessLevel(appId, tenantId, accessLevel);\r\n await loadPublicationData(appId);\r\n\r\n if (onSuccess) onSuccess();\r\n } catch (err) {\r\n console.error('Failed to update access level:', err);\r\n throw err;\r\n }\r\n },\r\n [loadPublicationData]\r\n );\r\n\r\n return {\r\n // State\r\n assignedTenants,\r\n availableTenants,\r\n showAssignModal,\r\n selectedTenantIds,\r\n selectedAccessLevel,\r\n tenantSearch,\r\n showCustomizeDrawer,\r\n customizingTenant,\r\n bulkAccessMode,\r\n bulkModules,\r\n bulkExpandedModules,\r\n loadingBulkModules,\r\n isUpdateMode,\r\n updateMergeMode,\r\n showConfirmRemovalDialog,\r\n pendingRemovals,\r\n includePersonalTenants,\r\n isInDefaultPersonalTemplate,\r\n\r\n // Setters\r\n setAssignedTenants,\r\n setAvailableTenants,\r\n setShowAssignModal,\r\n setSelectedTenantIds,\r\n setSelectedAccessLevel,\r\n setTenantSearch,\r\n setShowCustomizeDrawer,\r\n setCustomizingTenant,\r\n setBulkAccessMode,\r\n setBulkModules,\r\n setBulkExpandedModules,\r\n setIsUpdateMode,\r\n setUpdateMergeMode,\r\n setShowConfirmRemovalDialog,\r\n setPendingRemovals,\r\n setIncludePersonalTenants,\r\n\r\n // Operations\r\n loadPublicationData,\r\n loadBulkModules,\r\n toggleBulkModuleExpand,\r\n toggleBulkModule,\r\n toggleBulkSection,\r\n getBulkModuleCheckState,\r\n getBulkStats,\r\n selectAllBulkModules,\r\n clearBulkModules,\r\n toggleTenantSelection,\r\n selectAllFilteredTenants,\r\n clearTenantSelection,\r\n handleAssignTenants,\r\n handleUpdateTenants,\r\n executeUpdateTenants,\r\n handleRemoveTenant,\r\n handleUpdateAccessLevel,\r\n };\r\n}\r\n","import React from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Save, Loader2 } from 'lucide-react';\r\nimport type { ApplicationDetailDto } from '@/services/api/adminApi';\r\n\r\ninterface ApplicationInfoTabProps {\r\n readonly formData: {\r\n readonly label: string;\r\n readonly description: string;\r\n readonly icon: string;\r\n readonly route: string;\r\n readonly displayOrder: number;\r\n };\r\n readonly setFormData: React.Dispatch<\r\n React.SetStateAction<{\r\n readonly label: string;\r\n readonly description: string;\r\n readonly icon: string;\r\n readonly route: string;\r\n readonly displayOrder: number;\r\n }>\r\n >;\r\n readonly application: ApplicationDetailDto;\r\n readonly saving: boolean;\r\n readonly onSubmit: (e: React.FormEvent) => Promise<void>;\r\n}\r\n\r\nexport function ApplicationInfoTab({\r\n formData,\r\n setFormData,\r\n application,\r\n saving,\r\n onSubmit,\r\n}: ApplicationInfoTabProps): React.ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <form onSubmit={onSubmit} className=\"space-y-6\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.code')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={application.code}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.label')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.label}\r\n onChange={e =>\r\n setFormData(prev => ({ ...prev, label: e.target.value }))\r\n }\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n required\r\n />\r\n </div>\r\n <div className=\"md:col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.description')}\r\n </label>\r\n <textarea\r\n value={formData.description}\r\n onChange={e =>\r\n setFormData(prev => ({ ...prev, description: e.target.value }))\r\n }\r\n rows={3}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.icon')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.icon}\r\n onChange={e =>\r\n setFormData(prev => ({ ...prev, icon: e.target.value }))\r\n }\r\n placeholder={t('applicationDetail.fields.icon')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.route')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.route}\r\n onChange={e =>\r\n setFormData(prev => ({ ...prev, route: e.target.value }))\r\n }\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.displayOrder')}\r\n </label>\r\n <input\r\n type=\"number\"\r\n value={formData.displayOrder}\r\n onChange={e =>\r\n setFormData(prev => ({\r\n ...prev,\r\n displayOrder: parseInt(e.target.value) || 0,\r\n }))\r\n }\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.zone', 'Zone')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={application.zone || ''}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex justify-end\">\r\n <button\r\n type=\"submit\"\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-6 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Save className=\"w-4 h-4\" />\r\n )}\r\n {t('applicationDetail.actions.save')}\r\n </button>\r\n </div>\r\n </form>\r\n );\r\n}\r\n","import { useState, type ReactNode } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport {\r\n DndContext,\r\n closestCenter,\r\n KeyboardSensor,\r\n PointerSensor,\r\n useSensor,\r\n useSensors,\r\n type DragEndEvent,\r\n} from '@dnd-kit/core';\r\nimport {\r\n arrayMove,\r\n SortableContext,\r\n sortableKeyboardCoordinates,\r\n useSortable,\r\n verticalListSortingStrategy,\r\n} from '@dnd-kit/sortable';\r\nimport { CSS } from '@dnd-kit/utilities';\r\nimport { GripVertical } from 'lucide-react';\r\n\r\nexport interface SortableItem {\r\n id: string;\r\n [key: string]: unknown;\r\n}\r\n\r\ninterface SortableListProps<T extends SortableItem> {\r\n readonly items: T[];\r\n readonly onReorder: (items: T[]) => void;\r\n readonly renderItem: (item: T, dragHandle: ReactNode) => ReactNode;\r\n readonly disabled?: boolean;\r\n}\r\n\r\ninterface SortableItemWrapperProps {\r\n readonly id: string;\r\n readonly disabled?: boolean;\r\n readonly children: (dragHandle: ReactNode) => ReactNode;\r\n}\r\n\r\nfunction SortableItemWrapper({ id, disabled, children }: SortableItemWrapperProps) {\r\n const {\r\n attributes,\r\n listeners,\r\n setNodeRef,\r\n transform,\r\n transition,\r\n isDragging,\r\n } = useSortable({ id, disabled });\r\n\r\n const style = {\r\n transform: CSS.Transform.toString(transform),\r\n transition,\r\n opacity: isDragging ? 0.5 : 1,\r\n zIndex: isDragging ? 1 : 0,\r\n };\r\n\r\n const dragHandle = !disabled ? (\r\n <button\r\n type=\"button\"\r\n className=\"p-1.5 rounded hover:bg-[var(--bg-hover)] cursor-grab active:cursor-grabbing text-[var(--text-muted)] hover:text-[var(--text-secondary)] transition-colors\"\r\n {...attributes}\r\n {...listeners}\r\n >\r\n <GripVertical className=\"w-4 h-4\" />\r\n </button>\r\n ) : null;\r\n\r\n return (\r\n <div ref={setNodeRef} style={style}>\r\n {children(dragHandle)}\r\n </div>\r\n );\r\n}\r\n\r\nexport function SortableList<T extends SortableItem>({\r\n items,\r\n onReorder,\r\n renderItem,\r\n disabled = false,\r\n}: SortableListProps<T>): ReactElement {\r\n const [, setActiveId] = useState<string | null>(null);\r\n\r\n const sensors = useSensors(\r\n useSensor(PointerSensor, {\r\n activationConstraint: {\r\n distance: 8,\r\n },\r\n }),\r\n useSensor(KeyboardSensor, {\r\n coordinateGetter: sortableKeyboardCoordinates,\r\n })\r\n );\r\n\r\n const handleDragEnd = (event: DragEndEvent) => {\r\n const { active, over } = event;\r\n setActiveId(null);\r\n\r\n if (over && active.id !== over.id) {\r\n const oldIndex = items.findIndex((item) => item.id === active.id);\r\n const newIndex = items.findIndex((item) => item.id === over.id);\r\n const newItems = arrayMove(items, oldIndex, newIndex);\r\n onReorder(newItems);\r\n }\r\n };\r\n\r\n return (\r\n <DndContext\r\n sensors={sensors}\r\n collisionDetection={closestCenter}\r\n onDragStart={(event) => setActiveId(event.active.id as string)}\r\n onDragEnd={handleDragEnd}\r\n >\r\n <SortableContext\r\n items={items.map((item) => item.id)}\r\n strategy={verticalListSortingStrategy}\r\n disabled={disabled}\r\n >\r\n <div className=\"space-y-2\">\r\n {items.map((item) => (\r\n <SortableItemWrapper key={item.id} id={item.id} disabled={disabled}>\r\n {(dragHandle) => renderItem(item, dragHandle)}\r\n </SortableItemWrapper>\r\n ))}\r\n </div>\r\n </SortableContext>\r\n </DndContext>\r\n );\r\n}\r\n\r\nexport default SortableList;\r\n","import type { ReactElement } from 'react';\nimport { useTranslation } from 'react-i18next';\r\nimport { ChevronDown, ChevronRight, Edit, Layers, Loader2, Save } from 'lucide-react';\r\n\r\ntype TFunction = ReturnType<typeof useTranslation>['t'];\r\nimport { SortableList } from '@/components/ui/SortableList';\r\nimport { renderLucideIcon } from '@/utils/renderLucideIcon';\r\nimport type {\r\n ApplicationDetailDto,\r\n ApplicationModuleDto,\r\n ModuleSectionDto,\r\n} from '@/services/api/adminApi';\r\n\r\ninterface ApplicationModulesTabProps {\r\n readonly application: ApplicationDetailDto;\r\n readonly expandedModules: Set<string>;\r\n readonly moduleSections: Map<string, ModuleSectionDto[]>;\r\n readonly loadingSections: Set<string>;\r\n readonly reordering: boolean;\r\n readonly editingModule: ApplicationModuleDto | null;\r\n readonly moduleFormData: {\r\n readonly code: string;\r\n readonly label: string;\r\n readonly description: string;\r\n readonly icon: string;\r\n readonly route: string;\r\n readonly displayOrder: number;\r\n };\r\n readonly showModuleForm: boolean;\r\n readonly saving: boolean;\r\n readonly onToggleExpand: (moduleId: string) => void;\r\n readonly onStartEdit: (module: ApplicationModuleDto) => void;\r\n readonly onSaveModule: (e: React.FormEvent) => Promise<void>;\r\n readonly onCancelEdit: () => void;\r\n readonly onModulesReorder: (modules: (ApplicationModuleDto & { id: string })[]) => Promise<void>;\r\n readonly onSectionsReorder: (moduleId: string, sections: ModuleSectionDto[]) => Promise<void>;\r\n readonly setModuleFormData: React.Dispatch<\r\n React.SetStateAction<{\r\n readonly code: string;\r\n readonly label: string;\r\n readonly description: string;\r\n readonly icon: string;\r\n readonly route: string;\r\n readonly displayOrder: number;\r\n }>\r\n >;\r\n}\r\n\r\n\r\nconst renderModuleSections = (moduleId: string, loadingSections: Set<string>, moduleSections: Map<string, ModuleSectionDto[]>, onSectionsReorder: (moduleId: string, sections: ModuleSectionDto[]) => Promise<void>, reordering: boolean, t: TFunction) => {\r\n if (loadingSections.has(moduleId)) {\r\n return (\r\n <div className=\"flex items-center justify-center py-4\">\r\n <Loader2 className=\"w-5 h-5 animate-spin text-[var(--text-muted)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (moduleSections.get(moduleId)?.length === 0) {\r\n return (\r\n <p className=\"text-sm text-[var(--text-muted)] py-2\">\r\n {t('applicationDetail.modules.noSections', 'No sections')}\r\n </p>\r\n );\r\n }\r\n\r\n if (moduleSections.get(moduleId)) {\r\n return (\r\n <SortableList\r\n items={moduleSections.get(moduleId)!.map((s) => ({ ...s, id: s.id }))}\r\n onReorder={(sections) => onSectionsReorder(moduleId, sections)}\r\n disabled={reordering}\r\n renderItem={(section, sectionDragHandle) => (\r\n <div className=\"flex items-center gap-2 p-2 rounded bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n {sectionDragHandle}\r\n <div className=\"p-1 rounded bg-[var(--bg-tertiary)]\">\r\n {renderLucideIcon(section.icon, 'w-3 h-3') || (\r\n <Layers className=\"w-3 h-3 text-[var(--text-muted)]\" />\r\n )}\r\n </div>\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {section.label}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)]\">{section.code}</p>\r\n </div>\r\n <span\r\n className={`px-2 py-0.5 text-xs rounded-full ${\r\n section.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--error-bg)] text-[var(--error-text)]'\r\n }`}\r\n >\r\n {section.isActive ? t('common:active') : t('common:inactive')}\r\n </span>\r\n </div>\r\n )}\r\n />\r\n );\r\n }\r\n\r\n return null;\r\n};\r\n\r\nexport function ApplicationModulesTab({\r\n application,\r\n expandedModules,\r\n moduleSections,\r\n loadingSections,\r\n reordering,\r\n editingModule,\r\n moduleFormData,\r\n showModuleForm,\r\n saving,\r\n onToggleExpand,\r\n onStartEdit,\r\n onSaveModule,\r\n onCancelEdit,\r\n onModulesReorder,\r\n onSectionsReorder,\r\n setModuleFormData,\r\n}: ApplicationModulesTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('applicationDetail.modules.title')} ({application.modules.length})\r\n </h3>\r\n\r\n {showModuleForm && editingModule && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <h4 className=\"text-md font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('applicationDetail.modules.edit')}\r\n </h4>\r\n <form onSubmit={onSaveModule} className=\"space-y-4\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('applicationDetail.fields.code')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={moduleFormData.code}\r\n disabled\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('applicationDetail.fields.label')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={moduleFormData.label}\r\n onChange={(e) => setModuleFormData((prev) => ({ ...prev, label: e.target.value }))}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)]\"\r\n required\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('applicationDetail.fields.icon')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={moduleFormData.icon}\r\n onChange={(e) => setModuleFormData((prev) => ({ ...prev, icon: e.target.value }))}\r\n placeholder=\"Users\"\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('applicationDetail.fields.route')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={moduleFormData.route}\r\n onChange={(e) => setModuleFormData((prev) => ({ ...prev, route: e.target.value }))}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n <div className=\"md:col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('applicationDetail.fields.description')}\r\n </label>\r\n <textarea\r\n value={moduleFormData.description}\r\n onChange={(e) =>\r\n setModuleFormData((prev) => ({ ...prev, description: e.target.value }))\r\n }\r\n rows={2}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n </div>\r\n <div className=\"flex justify-end gap-2\">\r\n <button\r\n type=\"button\"\r\n onClick={onCancelEdit}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] font-medium text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n type=\"submit\"\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('common:save')}\r\n </button>\r\n </div>\r\n </form>\r\n </div>\r\n )}\r\n\r\n {application.modules.length === 0 ? (\r\n <p className=\"text-center py-8 text-[var(--text-muted)]\">\r\n {t('applicationDetail.modules.empty')}\r\n </p>\r\n ) : (\r\n <SortableList\r\n items={application.modules.map((m) => ({ ...m, id: m.id }))}\r\n onReorder={onModulesReorder}\r\n disabled={reordering}\r\n renderItem={(module, dragHandle) => (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--item-color-border)] hover:border-[var(--color-accent-600)] transition-colors\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n {dragHandle}\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)]\">\r\n {renderLucideIcon(module.icon, 'w-4 h-4') || (\r\n <Layers className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n )}\r\n </div>\r\n <button\r\n onClick={() => onToggleExpand(module.id)}\r\n className=\"p-1 rounded hover:bg-[var(--bg-hover)]\"\r\n aria-expanded={expandedModules.has(module.id)}\r\n aria-label={t('applicationDetail.modules.toggleExpand', 'Toggle sections')}\r\n >\r\n {expandedModules.has(module.id) ? (\r\n <ChevronDown className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n ) : (\r\n <ChevronRight className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n )}\r\n </button>\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">{module.label}</p>\r\n <p className=\"text-sm text-[var(--text-muted)]\">{module.code}</p>\r\n </div>\r\n <span\r\n className={`ml-2 px-2 py-0.5 text-xs font-medium rounded-full ${\r\n module.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--error-bg)] text-[var(--error-text)]'\r\n }`}\r\n >\r\n {module.isActive ? t('common:active') : t('common:inactive')}\r\n </span>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm text-[var(--text-muted)]\">\r\n {module.sectionsCount} {t('applicationDetail.modules.sections', 'sections')}\r\n </span>\r\n <button\r\n onClick={() => onStartEdit(module)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] text-[var(--text-secondary)]\"\r\n aria-label={t('applicationDetail.modules.edit')}\r\n >\r\n <Edit className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n {expandedModules.has(module.id) && (\r\n <div className=\"mt-3 pl-10 pt-3 border-t border-[var(--border-color)]\">\r\n <div className=\"grid grid-cols-2 gap-4 text-sm mb-4\">\r\n <div>\r\n <span className=\"text-[var(--text-muted)]\">\r\n {t('applicationDetail.fields.description')}:\r\n </span>\r\n <p className=\"text-[var(--text-primary)]\">{module.description || '-'}</p>\r\n </div>\r\n <div>\r\n <span className=\"text-[var(--text-muted)]\">\r\n {t('applicationDetail.fields.route')}:\r\n </span>\r\n <p className=\"text-[var(--text-primary)] font-mono\">{module.route || '-'}</p>\r\n </div>\r\n </div>\r\n {/* Sections */}\r\n <div className=\"mt-4\">\r\n <h5 className=\"text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.modules.sections', 'Sections')} ({module.sectionsCount})\r\n </h5>\r\n {renderModuleSections(module.id, loadingSections, moduleSections, onSectionsReorder, reordering, t)}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import type { ReactElement } from 'react';\nimport { useTranslation } from 'react-i18next';\r\nimport type { ApplicationDetailDto, PermissionListDto, RoleListDto } from '@/services/api/adminApi';\r\n\r\nexport interface PermissionWithRoles {\r\n permission: PermissionListDto;\r\n roles: RoleListDto[];\r\n}\r\n\r\nexport interface ApplicationPermissionsTabProps {\r\n readonly application: ApplicationDetailDto;\r\n readonly permissions: PermissionListDto[];\r\n readonly permissionsWithRoles: PermissionWithRoles[];\r\n}\r\n\r\nexport function ApplicationPermissionsTab({\r\n application,\r\n permissions,\r\n permissionsWithRoles,\r\n}: ApplicationPermissionsTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('applicationDetail.permissions.title')} ({permissions.length})\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {t('applicationDetail.permissions.description', {\r\n path: `${application.code}.*`,\r\n })}\r\n </p>\r\n\r\n {permissions.length === 0 ? (\r\n <p className=\"text-center py-8 text-[var(--text-muted)]\">\r\n {t('applicationDetail.permissions.empty')}\r\n </p>\r\n ) : (\r\n <div className=\"overflow-x-auto\">\r\n <table className=\"w-full\">\r\n <thead>\r\n <tr className=\"border-b border-[var(--border-color)]\">\r\n <th className=\"text-left py-3 px-4 text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('applicationDetail.permissions.path')}\r\n </th>\r\n <th className=\"text-left py-3 px-4 text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('applicationDetail.permissions.action')}\r\n </th>\r\n <th className=\"text-left py-3 px-4 text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('applicationDetail.permissions.type')}\r\n </th>\r\n <th className=\"text-left py-3 px-4 text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('applicationDetail.permissions.roles')}\r\n </th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {permissionsWithRoles.map(({ permission, roles: permRoles }) => (\r\n <tr\r\n key={permission.id}\r\n className=\"border-b border-[var(--border-color)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n <td className=\"py-3 px-4 font-mono text-sm text-[var(--text-primary)]\">\r\n {permission.path}\r\n </td>\r\n <td className=\"py-3 px-4\">\r\n {permission.action ? (\r\n <span className=\"px-2 py-1 text-xs font-medium rounded-full bg-[var(--accent-bg)] text-[var(--accent-text)]\">\r\n {permission.action}\r\n </span>\r\n ) : (\r\n '-'\r\n )}\r\n </td>\r\n <td className=\"py-3 px-4\">\r\n {permission.isWildcard ? (\r\n <span className=\"px-2 py-1 text-xs font-medium rounded-full bg-[var(--warning-bg)] text-[var(--warning-text)]\">\r\n {t('applicationDetail.permissions.wildcard', 'Wildcard')}\r\n </span>\r\n ) : (\r\n <span className=\"px-2 py-1 text-xs font-medium rounded-full bg-[var(--bg-tertiary)] text-[var(--text-muted)]\">\r\n {t('applicationDetail.permissions.specific', 'Specific')}\r\n </span>\r\n )}\r\n </td>\r\n <td className=\"py-3 px-4\">\r\n <div className=\"flex flex-wrap gap-1\">\r\n {permRoles.length === 0 ? (\r\n <span className=\"text-[var(--text-muted)] text-sm\">-</span>\r\n ) : (\r\n permRoles.slice(0, 3).map(role => (\r\n <span\r\n key={role.id}\r\n className=\"px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--color-accent-100)] text-[var(--color-accent-700)]\"\r\n >\r\n {role.name}\r\n </span>\r\n ))\r\n )}\r\n {permRoles.length > 3 && (\r\n <span className=\"px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--bg-tertiary)] text-[var(--text-muted)]\">\r\n +{permRoles.length - 3}\r\n </span>\r\n )}\r\n </div>\r\n </td>\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import type { ReactElement } from 'react';\nimport { Shield, Eye } from 'lucide-react';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\nexport interface RoleListDto {\r\n id: string;\r\n name: string;\r\n isSystem: boolean;\r\n usersCount: number;\r\n}\r\n\r\nexport interface PermissionListDto {\r\n id: string;\r\n path: string;\r\n isWildcard: boolean;\r\n}\r\n\r\nexport interface RoleWithPermissions {\r\n role: RoleListDto;\r\n permissions: PermissionListDto[];\r\n}\r\n\r\nexport interface ApplicationAccessTabProps {\r\n readonly rolesWithAppAccess: RoleWithPermissions[];\r\n readonly onNavigateToRole: (roleId: string) => void;\r\n}\r\n\r\nexport function ApplicationAccessTab({\r\n rolesWithAppAccess,\r\n onNavigateToRole,\r\n}: ApplicationAccessTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('applicationDetail.roles.title')} ({rolesWithAppAccess.length})\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {t('applicationDetail.roles.description')}\r\n </p>\r\n\r\n {rolesWithAppAccess.length === 0 ? (\r\n <p className=\"text-center py-8 text-[var(--text-muted)]\">\r\n {t('applicationDetail.roles.empty')}\r\n </p>\r\n ) : (\r\n <div className=\"space-y-3\">\r\n {rolesWithAppAccess.map(({ role, permissions: rolePermissions }) => (\r\n <div\r\n key={role.id}\r\n className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--item-color-border)] hover:border-[var(--color-accent-600)] transition-colors\"\r\n >\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)]\">\r\n <Shield className=\"w-5 h-5 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">{role.name}</p>\r\n {role.isSystem && (\r\n <span className=\"px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--warning-bg)] text-[var(--warning-text)]\">\r\n {t('applicationDetail.roles.system', 'System')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {role.usersCount} {t('applicationDetail.roles.users')} • {rolePermissions.length}{' '}\r\n {t('applicationDetail.roles.permissions')}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => onNavigateToRole(role.id)}\r\n className=\"flex items-center gap-1 px-3 py-1.5 rounded-[var(--radius-button)] text-sm font-medium text-[var(--color-accent-600)] hover:bg-[var(--color-accent-100)]\"\r\n >\r\n <Eye className=\"w-4 h-4\" />\r\n {t('applicationDetail.roles.viewRole')}\r\n </button>\r\n </div>\r\n </div>\r\n <div className=\"mt-3 flex flex-wrap gap-1\">\r\n {rolePermissions.slice(0, 5).map(perm => (\r\n <span\r\n key={perm.id}\r\n className=\"px-2 py-0.5 text-xs font-mono rounded bg-[var(--bg-tertiary)] text-[var(--text-muted)]\"\r\n >\r\n {perm.path.split('.').pop()}\r\n {perm.isWildcard && '.*'}\r\n </span>\r\n ))}\r\n {rolePermissions.length > 5 && (\r\n <span className=\"px-2 py-0.5 text-xs rounded bg-[var(--bg-tertiary)] text-[var(--text-muted)]\">\r\n +{rolePermissions.length - 5} {t('applicationDetail.roles.more', 'more')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","'use client';\r\n\r\nimport React from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Globe,\r\n} from 'lucide-react';\r\nimport type {\r\n ApplicationDetailDto,\r\n ApplicationTenantDto,\r\n ApplicationAccessLevel,\r\n AvailableTenantForAppDto,\r\n} from '@/services/api/adminApi';\r\nimport { useTenantTypeSettings } from '@/hooks/useTenantTypeSettings';\r\nimport { getLucideIcon, getColorClasses } from '@/utils/tenantIconMap';\r\n\r\nexport interface BulkModuleNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n isAssigned: boolean;\r\n sections: BulkSectionNode[];\r\n}\r\n\r\nexport interface BulkSectionNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n isAssigned: boolean;\r\n}\r\n\r\nexport interface ApplicationPublicationTabProps {\r\n readonly application: ApplicationDetailDto;\r\n readonly assignedTenants: ApplicationTenantDto[];\r\n readonly availableTenants: AvailableTenantForAppDto[];\r\n readonly showAssignModal: boolean;\r\n readonly selectedTenantIds: string[];\r\n readonly selectedAccessLevel: ApplicationAccessLevel;\r\n readonly tenantSearch: string;\r\n readonly showCustomizeDrawer: boolean;\r\n readonly customizingTenant: ApplicationTenantDto | null;\r\n readonly bulkAccessMode: 'full' | 'custom';\r\n readonly bulkModules: BulkModuleNode[];\r\n readonly bulkExpandedModules: Set<string>;\r\n readonly loadingBulkModules: boolean;\r\n readonly isUpdateMode: boolean;\r\n readonly updateMergeMode: 'merge' | 'replace';\r\n readonly showConfirmRemovalDialog: boolean;\r\n readonly pendingRemovals: { modules: number; sections: number };\r\n readonly saving: boolean;\r\n readonly includePersonalTenants: boolean;\r\n readonly isInDefaultPersonalTemplate: boolean;\r\n readonly onAddTenant: () => void;\r\n readonly onRemoveTenant: (tenantId: string) => Promise<void>;\r\n readonly onUpdateAccessLevel: (tenantId: string, accessLevel: ApplicationAccessLevel) => Promise<void>;\r\n readonly onCustomizeTenant: (tenant: ApplicationTenantDto) => void;\r\n readonly onCloseCustomizeDrawer: () => void;\r\n readonly onAssignTenants: () => Promise<void>;\r\n readonly onUpdateTenants: () => Promise<void>;\r\n readonly onExecuteUpdateTenants: () => Promise<void>;\r\n readonly onCancelRemovalDialog: () => void;\r\n readonly setShowAssignModal: (show: boolean) => void;\r\n readonly setSelectedTenantIds: React.Dispatch<React.SetStateAction<string[]>>;\r\n readonly setSelectedAccessLevel: React.Dispatch<React.SetStateAction<ApplicationAccessLevel>>;\r\n readonly setTenantSearch: (search: string) => void;\r\n readonly setBulkAccessMode: React.Dispatch<React.SetStateAction<'full' | 'custom'>>;\r\n readonly setIsUpdateMode: (mode: boolean) => void;\r\n readonly setUpdateMergeMode: React.Dispatch<React.SetStateAction<'merge' | 'replace'>>;\r\n readonly onToggleTenantSelection: (tenantId: string) => void;\r\n readonly onSelectAllFilteredTenants: () => void;\r\n readonly onClearTenantSelection: () => void;\r\n readonly setIncludePersonalTenants: (value: boolean) => void;\r\n readonly onLoadBulkModules: () => Promise<void>;\r\n readonly onToggleBulkModuleExpand: (moduleId: string) => void;\r\n readonly onToggleBulkModule: (moduleId: string) => void;\r\n readonly onToggleBulkSection: (moduleId: string, sectionId: string) => void;\r\n readonly onGetBulkModuleCheckState: (module: BulkModuleNode) => 'checked' | 'unchecked' | 'indeterminate';\r\n readonly onGetBulkStats: () => { totalModules: number; assignedModules: number; totalSections: number; assignedSections: number };\r\n readonly onSelectAllBulkModules: () => void;\r\n readonly onClearBulkModules: () => void;\r\n readonly appId: string;\r\n}\r\n\r\n// Helper: Get CSS classes for access level indicator color\r\nconst getAccessLevelColorClass = (accessLevel: ApplicationAccessLevel): string => {\r\n switch (accessLevel) {\r\n case 'FullAccess':\r\n return 'bg-green-500';\r\n case 'RequestAccess':\r\n return 'bg-amber-500';\r\n case 'Disabled':\r\n return 'bg-gray-400';\r\n default:\r\n return 'bg-gray-400';\r\n }\r\n};\r\n\r\n// Helper: Get access level label key\r\nconst getLabelKey = (level: ApplicationAccessLevel): string => {\r\n switch (level) {\r\n case 'FullAccess':\r\n return 'fullAccess';\r\n case 'RequestAccess':\r\n return 'requestAccess';\r\n case 'Disabled':\r\n return 'disabled';\r\n default:\r\n return 'disabled';\r\n }\r\n};\r\n\r\n// Helper: Get tenant icon and color from settings\r\nconst useTenantIconForType = () => {\r\n const { getIconForType } = useTenantTypeSettings();\r\n return (tenantType: string) => {\r\n const typeInfo = getIconForType(tenantType);\r\n const Icon = getLucideIcon(typeInfo.icon);\r\n const colors = getColorClasses(typeInfo.color);\r\n return { Icon, bgClass: colors.bg, colorClass: colors.text };\r\n };\r\n};\r\n\r\nexport const ApplicationPublicationTab: React.FC<ApplicationPublicationTabProps> = ({\r\n assignedTenants,\r\n}) => {\r\n const { t } = useTranslation('admin');\r\n const getTenantIconInfo = useTenantIconForType();\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Header Section */}\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('applicationDetail.publication.title', 'Tenant Publication')} ({assignedTenants.length})\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {t('applicationDetail.publication.description', 'Manage which tenants have access to this application')}\r\n </p>\r\n </div>\r\n\r\n {/* Access Levels Legend */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--bg-tertiary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-start gap-2\">\r\n <div className=\"w-3 h-3 mt-1 rounded-full bg-green-500 flex-shrink-0\" />\r\n <div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('applicationDetail.publication.accessLevels.fullAccess', 'Full Access')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)]\">\r\n {t('applicationDetail.publication.accessLevels.fullAccessDesc', 'Users can use all features')}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-start gap-2\">\r\n <div className=\"w-3 h-3 mt-1 rounded-full bg-amber-500 flex-shrink-0\" />\r\n <div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('applicationDetail.publication.accessLevels.requestAccess', 'Request Access')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)]\">\r\n {t('applicationDetail.publication.accessLevels.requestAccessDesc', 'Requires access request')}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-start gap-2\">\r\n <div className=\"w-3 h-3 mt-1 rounded-full bg-gray-400 flex-shrink-0\" />\r\n <div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('applicationDetail.publication.accessLevels.disabled', 'Disabled')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)]\">\r\n {t('applicationDetail.publication.accessLevels.disabledDesc', 'Not visible for tenant')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Assigned Tenants List or Empty State */}\r\n {assignedTenants.length === 0 ? (\r\n <div className=\"text-center py-12\">\r\n <Globe className=\"w-12 h-12 mx-auto text-[var(--text-muted)] mb-4\" />\r\n <p className=\"text-[var(--text-muted)]\">\r\n {t('applicationDetail.publication.empty', 'No tenants have access to this application yet')}\r\n </p>\r\n </div>\r\n ) : (\r\n <div className=\"space-y-3\">\r\n {assignedTenants.map(tenant => {\r\n const { Icon, bgClass, colorClass } = getTenantIconInfo(tenant.tenantType);\r\n const statusBgClass = tenant.tenantStatus === 'Active'\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--warning-bg)] text-[var(--warning-text)]';\r\n\r\n return (\r\n <div\r\n key={tenant.tenantId}\r\n className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--item-color-border)] hover:border-[var(--color-accent-600)] transition-colors\"\r\n >\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)] ${bgClass}`}>\r\n <Icon className={`w-5 h-5 ${colorClass}`} />\r\n </div>\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">{tenant.tenantName}</p>\r\n <span className={`px-2 py-0.5 text-xs font-medium rounded-full ${statusBgClass}`}>\r\n {tenant.tenantStatus}\r\n </span>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {tenant.tenantSlug} • {tenant.tenantType}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <div className={`w-2.5 h-2.5 rounded-full ${getAccessLevelColorClass(tenant.accessLevel as ApplicationAccessLevel)}`} />\r\n <span className=\"px-3 py-1.5 rounded-[var(--radius-input)] bg-[var(--bg-secondary)] border border-[var(--border-color)] text-sm text-[var(--text-primary)]\">\r\n {t(`applicationDetail.publication.accessLevels.${getLabelKey(tenant.accessLevel as ApplicationAccessLevel)}`, tenant.accessLevel)}\r\n </span>\r\n </div>\r\n </div>\r\n <div className=\"mt-2 text-xs text-[var(--text-muted)]\">\r\n {t('applicationDetail.publication.assignedAt', 'Assigned')}: {new Date(tenant.assignedAt).toLocaleDateString()}\r\n {tenant.assignedBy && ` ${t('applicationDetail.publication.by', 'by')} ${tenant.assignedBy}`}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import { useEffect, useMemo} from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useParams, useNavigate } from 'react-router-dom';\r\nimport { useTabNavigation } from '@/hooks/useTabNavigation';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n ArrowLeft,\r\n Settings,\r\n Layers,\r\n Shield,\r\n Users,\r\n Loader2,\r\n AlertTriangle,\r\n CheckCircle,\r\n Power,\r\n PowerOff,\r\n Globe,\r\n AlertCircle,\r\n Inbox,\r\n} from 'lucide-react';\r\nimport { renderLucideIcon } from '@/utils/renderLucideIcon';\r\nimport { useApplicationDetail } from '@/hooks/useApplicationDetail';\r\nimport { useApplicationModules } from '@/hooks/useApplicationModules';\r\nimport { useApplicationPermissions } from '@/hooks/useApplicationPermissions';\r\nimport { useApplicationPublication } from '@/hooks/useApplicationPublication';\r\nimport {\r\n ApplicationInfoTab,\r\n ApplicationModulesTab,\r\n ApplicationPermissionsTab,\r\n ApplicationAccessTab,\r\n ApplicationPublicationTab,\r\n} from '@/components/platform/administration/applications';\r\nimport { AccessRequestsListTab } from '@/components/platform/administration/access-requests';\r\nimport { useAccessRequests } from '@/hooks/useAccessRequests';\r\n\r\nconst VALID_TABS = ['info', 'modules', 'permissions', 'roles', 'publication', 'requests'] as const;\r\ntype TabId = typeof VALID_TABS[number];\r\n\r\nexport default function ApplicationDetailPage(): ReactElement {\r\n const { id: appId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('admin');\r\n const { hasPermission } = useAuth();\r\n\r\n const { currentTenant, isGlobalView } = useTenant();\r\n const canToggleStatus = hasPermission('administration.applications.execute');\r\n const { activeTab, setActiveTab } = useTabNavigation<TabId>('info', VALID_TABS);\r\n\r\n // Use all hooks\r\n const applicationDetail = useApplicationDetail();\r\n const applicationModules = useApplicationModules();\r\n const applicationPermissions = useApplicationPermissions();\r\n const applicationPublication = useApplicationPublication();\r\n const accessRequests = useAccessRequests('application', appId!);\r\n\r\n // Filter tenants based on current tenant context\r\n // When scoped to a specific tenant, only show that tenant in the publication modal\r\n const filteredAvailableTenants = useMemo(() => {\r\n if (isGlobalView || !currentTenant) return applicationPublication.availableTenants;\r\n return applicationPublication.availableTenants.filter(t => t.slug === currentTenant.slug);\r\n }, [applicationPublication.availableTenants, isGlobalView, currentTenant]);\r\n\r\n const filteredAssignedTenants = useMemo(() => {\r\n if (isGlobalView || !currentTenant) return applicationPublication.assignedTenants;\r\n return applicationPublication.assignedTenants.filter(t => t.tenantSlug === currentTenant.slug);\r\n }, [applicationPublication.assignedTenants, isGlobalView, currentTenant]);\r\n\r\n // Load data on mount\r\n useEffect(() => {\r\n if (appId) {\r\n applicationDetail.loadApplication(appId);\r\n }\r\n }, [appId]);\r\n\r\n // Load tab-specific data (lazy loading per tab)\r\n useEffect(() => {\r\n if (!applicationDetail.application) return;\r\n\r\n if (\r\n (activeTab === 'permissions' || activeTab === 'roles') &&\r\n applicationPermissions.permissions.length === 0\r\n ) {\r\n applicationPermissions.loadPermissionsData(applicationDetail.application);\r\n }\r\n if (\r\n activeTab === 'publication' &&\r\n applicationPublication.assignedTenants.length === 0\r\n ) {\r\n applicationPublication.loadPublicationData(appId!);\r\n }\r\n if (activeTab === 'requests') {\r\n accessRequests.loadRequests();\r\n }\r\n }, [\r\n activeTab,\r\n applicationDetail.application,\r\n applicationPublication.assignedTenants.length,\r\n ]);\r\n\r\n const tabs = [\r\n { id: 'info' as const, label: t('applicationDetail.tabs.info'), icon: Settings },\r\n { id: 'modules' as const, label: t('applicationDetail.tabs.modules'), icon: Layers },\r\n { id: 'permissions' as const, label: t('applicationDetail.tabs.permissions'), icon: Shield },\r\n { id: 'roles' as const, label: t('applicationDetail.tabs.roles'), icon: Users },\r\n { id: 'publication' as const, label: t('applicationDetail.tabs.publication'), icon: Globe },\r\n { id: 'requests' as const, label: t('applicationDetail.tabs.requests'), icon: Inbox },\r\n ];\r\n\r\n // Loading state\r\n if (applicationDetail.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 // Error or not found\r\n if (applicationDetail.error || !applicationDetail.application) {\r\n return (\r\n <div className=\"text-center py-12\">\r\n <AlertCircle className=\"w-12 h-12 text-[var(--error-text)] mx-auto mb-4\" />\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {applicationDetail.error || t('applicationDetail.notFound')}\r\n </p>\r\n <button\r\n onClick={() => navigate('/administration/applications')}\r\n className=\"mt-4 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)]\"\r\n >\r\n {t('applicationDetail.backToList')}\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n const permissionsLoaded = applicationPermissions.permissions.length > 0 || activeTab === 'permissions' || activeTab === 'roles';\r\n const publicationLoaded = applicationPublication.assignedTenants.length > 0 || activeTab === 'publication';\r\n\r\n const statsCards = [\r\n {\r\n label: t('applicationDetail.stats.modules'),\r\n value: applicationDetail.application.modules?.length || 0,\r\n color: 'blue' as const,\r\n },\r\n {\r\n label: t('applicationDetail.stats.permissions'),\r\n value: permissionsLoaded ? applicationPermissions.permissions.length : '—',\r\n color: 'green' as const,\r\n },\r\n {\r\n label: t('applicationDetail.stats.rolesWithAccess'),\r\n value: permissionsLoaded ? applicationPermissions.rolesWithAppAccess.length : '—',\r\n color: 'purple' as const,\r\n },\r\n {\r\n label: t('applicationDetail.stats.assignedTenants'),\r\n value: publicationLoaded ? filteredAssignedTenants.length : '—',\r\n color: 'yellow' as const,\r\n },\r\n {\r\n label: t('applicationDetail.stats.status'),\r\n value: applicationDetail.application.isActive ? t('common:active') : t('common:inactive'),\r\n color: applicationDetail.application.isActive ? 'green' : 'neutral',\r\n },\r\n ];\r\n\r\n const colorClasses: Record<string, string> = {\r\n blue: 'bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]',\r\n green: 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]',\r\n yellow: 'bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]',\r\n red: 'bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]',\r\n purple: 'bg-[var(--accent-bg)] text-[var(--accent-text)] border-[var(--color-accent-300)]',\r\n neutral: 'bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]',\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('breadcrumb.admin', { ns: 'navigation' }), href: '/administration' },\r\n { label: t('applications.title'), href: '/administration/applications' },\r\n { label: applicationDetail.application.label },\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/administration/applications')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n aria-label={t('common:back')}\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div className=\"flex items-center gap-3\">\r\n {renderLucideIcon(applicationDetail.application.icon, 'w-5 h-5')}\r\n <div className=\"flex-1\">\r\n <h1 className=\"text-xl sm:text-2xl font-bold text-[var(--text-primary)]\">\r\n {applicationDetail.application.label}\r\n </h1>\r\n {applicationDetail.application.description && (\r\n <p className=\"text-sm sm:text-base text-[var(--text-secondary)]\">\r\n {applicationDetail.application.description}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2 ml-auto\">\r\n <span\r\n className={`px-3 py-1 rounded-[var(--radius-badge)] text-sm font-medium ${\r\n applicationDetail.application.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)] border border-[var(--success-border)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)] border border-[var(--border-color)]'\r\n }`}\r\n >\r\n {applicationDetail.application.isActive ? t('common:active') : t('common:inactive')}\r\n </span>\r\n {canToggleStatus && (\r\n <button\r\n onClick={() => applicationDetail.handleToggleStatus(appId!)}\r\n disabled={applicationDetail.saving}\r\n className={`inline-flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium transition-colors ${\r\n applicationDetail.application.isActive\r\n ? 'bg-[var(--error-bg)] text-[var(--error-text)] border border-[var(--error-border)] hover:bg-[var(--error-border)]'\r\n : 'bg-[var(--success-bg)] text-[var(--success-text)] border border-[var(--success-border)] hover:bg-[var(--success-border)]'\r\n } disabled:opacity-50`}\r\n >\r\n {applicationDetail.saving && (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n )}\r\n {!applicationDetail.saving && applicationDetail.application.isActive && (\r\n <PowerOff className=\"w-4 h-4\" />\r\n )}\r\n {!applicationDetail.saving && !applicationDetail.application.isActive && (\r\n <Power className=\"w-4 h-4\" />\r\n )}\r\n {applicationDetail.application.isActive\r\n ? t('applicationDetail.deactivate')\r\n : t('applicationDetail.activate')}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Alerts */}\r\n {applicationDetail.error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)] text-[var(--error-text)] flex items-center gap-2\">\r\n <AlertTriangle className=\"w-5 h-5 flex-shrink-0\" />\r\n {applicationDetail.error}\r\n </div>\r\n )}\r\n {applicationDetail.success && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)] text-[var(--success-text)] flex items-center gap-2\">\r\n <CheckCircle className=\"w-5 h-5 flex-shrink-0\" />\r\n {applicationDetail.success}\r\n </div>\r\n )}\r\n\r\n {/* Stats cards */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-4\">\r\n {statsCards.map((stat) => (\r\n <div\r\n key={stat.label}\r\n className={`rounded-[var(--radius-card)] p-4 text-center border ${colorClasses[stat.color]}`}\r\n >\r\n <div className=\"text-2xl font-bold\">{stat.value}</div>\r\n <div className=\"text-sm opacity-80\">{stat.label}</div>\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Tabs */}\r\n <div\r\n className=\"flex gap-1 p-1 overflow-x-auto bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)]\"\r\n role=\"tablist\"\r\n aria-label={t('applicationDetail.tabs.label', 'Application tabs')}\r\n >\r\n {tabs.map((tab) => {\r\n const Icon = tab.icon;\r\n const isActive = activeTab === tab.id;\r\n return (\r\n <button\r\n key={tab.id}\r\n role=\"tab\"\r\n aria-selected={isActive}\r\n aria-controls={`tabpanel-${tab.id}`}\r\n onClick={() => setActiveTab(tab.id)}\r\n className={`flex items-center gap-2 px-4 py-2 whitespace-nowrap rounded-[var(--radius-button)] font-medium transition-colors ${\r\n isActive\r\n ? 'bg-[var(--color-accent-600)] text-white'\r\n : 'text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <Icon className=\"w-4 h-4\" />\r\n {tab.label}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n\r\n {/* Tab content */}\r\n <div\r\n className=\"bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-4 sm:p-6\"\r\n role=\"tabpanel\"\r\n id={`tabpanel-${activeTab}`}\r\n aria-labelledby={activeTab}\r\n >\r\n {/* Info Tab */}\r\n {activeTab === 'info' && (\r\n <ApplicationInfoTab\r\n formData={applicationDetail.formData}\r\n setFormData={applicationDetail.setFormData}\r\n application={applicationDetail.application!}\r\n saving={applicationDetail.saving}\r\n onSubmit={() =>\r\n applicationDetail.handleSaveInfo(appId!, applicationDetail.formData)\r\n }\r\n />\r\n )}\r\n\r\n {/* Modules Tab */}\r\n {activeTab === 'modules' && (\r\n <ApplicationModulesTab\r\n application={applicationDetail.application!}\r\n expandedModules={applicationModules.expandedModules}\r\n moduleSections={applicationModules.moduleSections}\r\n loadingSections={applicationModules.loadingSections}\r\n reordering={applicationModules.reordering}\r\n editingModule={applicationModules.editingModule}\r\n moduleFormData={applicationModules.moduleFormData}\r\n showModuleForm={applicationModules.showModuleForm}\r\n saving={applicationDetail.saving}\r\n onToggleExpand={(moduleId) =>\r\n applicationModules.toggleModuleExpand(appId!, moduleId)\r\n }\r\n onStartEdit={applicationModules.startEditModule}\r\n onSaveModule={async () => {\r\n await applicationModules.handleSaveModule(\r\n appId!,\r\n applicationModules.editingModule!.id,\r\n applicationModules.moduleFormData\r\n );\r\n applicationDetail.setSuccess(t('applicationDetail.success.moduleUpdated'));\r\n await applicationDetail.loadApplication(appId!);\r\n }}\r\n onCancelEdit={() => {\r\n applicationModules.setShowModuleForm(false);\r\n applicationModules.setEditingModule(null);\r\n }}\r\n onModulesReorder={async (modules) => {\r\n await applicationModules.handleModulesReorder(appId!, modules);\r\n await applicationDetail.loadApplication(appId!);\r\n }}\r\n onSectionsReorder={(moduleId, sections) =>\r\n applicationModules.handleSectionsReorder(appId!, moduleId, sections)\r\n }\r\n setModuleFormData={(value) => applicationModules.setModuleFormData(typeof value === 'function' ? value(applicationModules.moduleFormData) : value)}\r\n />\r\n )}\r\n\r\n {/* Permissions Tab */}\r\n {activeTab === 'permissions' && (\r\n <ApplicationPermissionsTab\r\n application={applicationDetail.application!}\r\n permissions={applicationPermissions.permissions}\r\n permissionsWithRoles={applicationPermissions.permissionsWithRoles}\r\n />\r\n )}\r\n\r\n {/* Roles Tab */}\r\n {activeTab === 'roles' && (\r\n <ApplicationAccessTab\r\n rolesWithAppAccess={applicationPermissions.rolesWithAppAccess}\r\n onNavigateToRole={(roleId) =>\r\n navigate(`/administration/permissions/roles/${roleId}`)\r\n }\r\n />\r\n )}\r\n\r\n {/* Publication Tab */}\r\n {activeTab === 'publication' && (\r\n <ApplicationPublicationTab\r\n application={applicationDetail.application!}\r\n assignedTenants={filteredAssignedTenants}\r\n availableTenants={filteredAvailableTenants}\r\n showAssignModal={applicationPublication.showAssignModal}\r\n selectedTenantIds={applicationPublication.selectedTenantIds}\r\n selectedAccessLevel={applicationPublication.selectedAccessLevel}\r\n tenantSearch={applicationPublication.tenantSearch}\r\n showCustomizeDrawer={applicationPublication.showCustomizeDrawer}\r\n customizingTenant={applicationPublication.customizingTenant}\r\n bulkAccessMode={applicationPublication.bulkAccessMode}\r\n bulkModules={applicationPublication.bulkModules}\r\n bulkExpandedModules={applicationPublication.bulkExpandedModules}\r\n loadingBulkModules={applicationPublication.loadingBulkModules}\r\n isUpdateMode={applicationPublication.isUpdateMode}\r\n updateMergeMode={applicationPublication.updateMergeMode}\r\n showConfirmRemovalDialog={applicationPublication.showConfirmRemovalDialog}\r\n pendingRemovals={applicationPublication.pendingRemovals}\r\n saving={applicationDetail.saving}\r\n includePersonalTenants={applicationPublication.includePersonalTenants}\r\n isInDefaultPersonalTemplate={applicationPublication.isInDefaultPersonalTemplate}\r\n onAddTenant={() => {\r\n applicationPublication.loadPublicationData(appId!);\r\n applicationPublication.setShowAssignModal(true);\r\n }}\r\n onRemoveTenant={(tenantId) =>\r\n applicationPublication.handleRemoveTenant(appId!, tenantId, () => {\r\n applicationDetail.setSuccess(t('applicationDetail.publication.success.removed'));\r\n })\r\n }\r\n onUpdateAccessLevel={(tenantId, accessLevel) =>\r\n applicationPublication.handleUpdateAccessLevel(appId!, tenantId, accessLevel, () => {\r\n applicationDetail.setSuccess(t('applicationDetail.publication.success.updated'));\r\n })\r\n }\r\n onCustomizeTenant={(tenant) => {\r\n applicationPublication.setCustomizingTenant(tenant);\r\n applicationPublication.setShowCustomizeDrawer(true);\r\n }}\r\n onCloseCustomizeDrawer={() => {\r\n applicationPublication.setShowCustomizeDrawer(false);\r\n applicationPublication.setCustomizingTenant(null);\r\n applicationPublication.loadPublicationData(appId!);\r\n }}\r\n onAssignTenants={() =>\r\n applicationPublication.handleAssignTenants(appId!, () => {\r\n applicationDetail.setSuccess(t('applicationDetail.publication.success.assigned'));\r\n applicationPublication.loadPublicationData(appId!);\r\n })\r\n }\r\n onUpdateTenants={() =>\r\n applicationPublication.handleUpdateTenants(appId!, () => {\r\n applicationDetail.setSuccess(t('applicationDetail.publication.success.updated'));\r\n applicationPublication.loadPublicationData(appId!);\r\n })\r\n }\r\n onExecuteUpdateTenants={() =>\r\n applicationPublication.executeUpdateTenants(appId!, () => {\r\n applicationDetail.setSuccess(t('applicationDetail.publication.success.updated'));\r\n applicationPublication.loadPublicationData(appId!);\r\n })\r\n }\r\n onCancelRemovalDialog={() => {\r\n applicationPublication.setShowConfirmRemovalDialog(false);\r\n applicationPublication.setUpdateMergeMode('merge');\r\n }}\r\n setShowAssignModal={applicationPublication.setShowAssignModal}\r\n setSelectedTenantIds={applicationPublication.setSelectedTenantIds}\r\n setSelectedAccessLevel={applicationPublication.setSelectedAccessLevel}\r\n setTenantSearch={applicationPublication.setTenantSearch}\r\n setBulkAccessMode={applicationPublication.setBulkAccessMode}\r\n setIsUpdateMode={applicationPublication.setIsUpdateMode}\r\n setUpdateMergeMode={applicationPublication.setUpdateMergeMode}\r\n onToggleTenantSelection={applicationPublication.toggleTenantSelection}\r\n onSelectAllFilteredTenants={applicationPublication.selectAllFilteredTenants}\r\n onClearTenantSelection={applicationPublication.clearTenantSelection}\r\n setIncludePersonalTenants={applicationPublication.setIncludePersonalTenants}\r\n onLoadBulkModules={() => applicationPublication.loadBulkModules(appId!)}\r\n onToggleBulkModuleExpand={applicationPublication.toggleBulkModuleExpand}\r\n onToggleBulkModule={applicationPublication.toggleBulkModule}\r\n onToggleBulkSection={applicationPublication.toggleBulkSection}\r\n onGetBulkModuleCheckState={applicationPublication.getBulkModuleCheckState}\r\n onGetBulkStats={applicationPublication.getBulkStats}\r\n onSelectAllBulkModules={applicationPublication.selectAllBulkModules}\r\n onClearBulkModules={applicationPublication.clearBulkModules}\r\n appId={appId!}\r\n />\r\n )}\r\n\r\n {/* Access Requests Tab */}\r\n {activeTab === 'requests' && (\r\n <AccessRequestsListTab\r\n requests={accessRequests.requests}\r\n loading={accessRequests.loading}\r\n onReload={() => accessRequests.loadRequests()}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"names":["renderLucideIcon","icon","className","IconComponent","LucideIcons","jsx","useApplicationDetail","useTranslation","application","setApplication","useState","loading","setLoading","saving","setSaving","error","setError","success","setSuccess","formData","setFormData","loadApplication","useCallback","appId","data","adminApi","err","handleSaveInfo","updateData","handleToggleStatus","useApplicationModules","expandedModules","setExpandedModules","moduleSections","setModuleSections","loadingSections","setLoadingSections","reordering","setReordering","editingModule","setEditingModule","moduleFormData","setModuleFormData","showModuleForm","setShowModuleForm","toggleModuleExpand","moduleId","isExpanding","prev","newSet","sections","handleSaveModule","resetModuleForm","handleModulesReorder","reorderedModules","newModules","m","index","handleSectionsReorder","reorderedSections","newSections","s","reloadErr","startEditModule","module","moduleCount","getPermissionWithRoles","perm","matrixRoles","allRoles","rolesWithPerm","mr","r","useApplicationPermissions","roles","setRoles","permissions","setPermissions","permissionsWithRoles","setPermissionsWithRoles","loadPermissionsData","matrix","appPermissionPrefix","appPermissions","p","permWithRoles","loadRolesData","rolesWithAppAccess","useMemo","roleAccessMap","permission","permRoles","role","a","b","updateModuleAssignment","newIsAssigned","updateSectionAssignment","sectionId","allSectionsAssigned","assignAllSections","clearAllSections","useApplicationPublication","assignedTenants","setAssignedTenants","availableTenants","setAvailableTenants","showAssignModal","setShowAssignModal","selectedTenantIds","setSelectedTenantIds","selectedAccessLevel","setSelectedAccessLevel","tenantSearch","setTenantSearch","showCustomizeDrawer","setShowCustomizeDrawer","customizingTenant","setCustomizingTenant","bulkAccessMode","setBulkAccessMode","bulkModules","setBulkModules","bulkExpandedModules","setBulkExpandedModules","loadingBulkModules","setLoadingBulkModules","isUpdateMode","setIsUpdateMode","updateMergeMode","setUpdateMergeMode","showConfirmRemovalDialog","setShowConfirmRemovalDialog","pendingRemovals","setPendingRemovals","includePersonalTenants","setIncludePersonalTenants","isInDefaultPersonalTemplate","setIsInDefaultPersonalTemplate","loadPublicationData","assigned","availableResponse","loadBulkModules","appModules","moduleNodes","appModule","sectionNodes","section","toggleBulkModuleExpand","toggleBulkModule","toggleBulkSection","getBulkModuleCheckState","assignedCount","getBulkStats","totalModules","assignedModules","totalSections","sum","assignedSections","selectAllBulkModules","clearBulkModules","toggleTenantSelection","tenantId","id","selectAllFilteredTenants","filteredIds","t","matchesSearch","matchesType","clearTenantSelection","executeUpdateTenants","onSuccess","request","handleAssignTenants","handleUpdateTenants","removedModulesCount","removedSectionsCount","currentModules","currentSections","targetModuleIds","targetSectionIds","handleRemoveTenant","handleUpdateAccessLevel","accessLevel","ApplicationInfoTab","onSubmit","jsxs","e","Loader2","Save","SortableItemWrapper","disabled","children","attributes","listeners","setNodeRef","transform","transition","isDragging","useSortable","style","CSS","dragHandle","GripVertical","SortableList","items","onReorder","renderItem","setActiveId","sensors","useSensors","useSensor","PointerSensor","KeyboardSensor","sortableKeyboardCoordinates","DndContext","closestCenter","event","active","over","oldIndex","item","newIndex","newItems","arrayMove","SortableContext","verticalListSortingStrategy","renderModuleSections","onSectionsReorder","sectionDragHandle","Layers","ApplicationModulesTab","onToggleExpand","onStartEdit","onSaveModule","onCancelEdit","onModulesReorder","ChevronDown","ChevronRight","Edit","ApplicationPermissionsTab","ApplicationAccessTab","onNavigateToRole","rolePermissions","Shield","Eye","getAccessLevelColorClass","getLabelKey","level","useTenantIconForType","getIconForType","useTenantTypeSettings","tenantType","typeInfo","Icon","getLucideIcon","colors","getColorClasses","ApplicationPublicationTab","getTenantIconInfo","Globe","tenant","bgClass","colorClass","statusBgClass","VALID_TABS","ApplicationDetailPage","useParams","navigate","useNavigate","hasPermission","useAuth","currentTenant","isGlobalView","useTenant","canToggleStatus","activeTab","setActiveTab","useTabNavigation","applicationDetail","applicationModules","applicationPermissions","applicationPublication","accessRequests","useAccessRequests","filteredAvailableTenants","filteredAssignedTenants","useEffect","tabs","Settings","Users","Inbox","AlertCircle","permissionsLoaded","publicationLoaded","statsCards","colorClasses","Breadcrumb","ArrowLeft","PowerOff","Power","AlertTriangle","CheckCircle","stat","tab","isActive","modules","value","roleId","AccessRequestsListTab"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ApplicationDetailPage-CuCW6aMB.js","sources":["../../src/utils/renderLucideIcon.tsx","../../src/hooks/useApplicationDetail.ts","../../src/hooks/useApplicationModules.ts","../../src/hooks/useApplicationPermissions.ts","../../src/hooks/useApplicationPublication.ts","../../src/components/platform/administration/applications/ApplicationInfoTab.tsx","../../src/components/ui/SortableList.tsx","../../src/components/platform/administration/applications/ApplicationModulesTab.tsx","../../src/components/platform/administration/applications/ApplicationPermissionsTab.tsx","../../src/components/platform/administration/applications/ApplicationAccessTab.tsx","../../src/components/platform/administration/applications/ApplicationPublicationTab.tsx","../../src/pages/platform/administration/applications/ApplicationDetailPage.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport * as LucideIcons from 'lucide-react';\r\nimport type { LucideIcon } from 'lucide-react';\r\n\r\n/**\r\n * Renders a Lucide icon by name string or LucideIcon component.\r\n * Returns null if the icon name is invalid or null.\r\n */\r\nexport function renderLucideIcon(\r\n icon: LucideIcon | string | null | undefined,\r\n className = 'w-4 h-4',\r\n): ReactElement | null {\r\n if (!icon) return null;\r\n\r\n if (typeof icon === 'string') {\r\n const icons = LucideIcons as unknown as Record<string, LucideIcon>;\r\n const IconComponent = icons[icon];\r\n if (!IconComponent) return null;\r\n return <IconComponent className={className} />;\r\n }\r\n\r\n const Icon = icon;\r\n return <Icon className={className} />;\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n adminApi,\r\n type ApplicationDetailDto,\r\n type UpdateApplicationRequest,\r\n} from '@/services/api/adminApi';\r\n\r\nexport interface ApplicationFormData {\r\n label: string;\r\n description: string;\r\n icon: string;\r\n route: string;\r\n displayOrder: number;\r\n}\r\n\r\nexport interface UseApplicationDetailReturn {\r\n application: ApplicationDetailDto | null;\r\n loading: boolean;\r\n saving: boolean;\r\n error: string | null;\r\n success: string | null;\r\n formData: ApplicationFormData;\r\n setFormData: React.Dispatch<React.SetStateAction<ApplicationFormData>>;\r\n setError: (error: string | null) => void;\r\n setSuccess: (success: string | null) => void;\r\n loadApplication: (appId: string) => Promise<void>;\r\n handleSaveInfo: (appId: string, data: ApplicationFormData) => Promise<void>;\r\n handleToggleStatus: (appId: string) => Promise<void>;\r\n}\r\n\r\nexport function useApplicationDetail(): UseApplicationDetailReturn {\r\n const { t } = useTranslation('admin');\r\n\r\n const [application, setApplication] = useState<ApplicationDetailDto | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [saving, setSaving] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n\r\n const [formData, setFormData] = useState<ApplicationFormData>({\r\n label: '',\r\n description: '',\r\n icon: '',\r\n route: '',\r\n displayOrder: 0,\r\n });\r\n\r\n const loadApplication = useCallback(async (appId: string) => {\r\n if (!appId) return;\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n try {\r\n const data = await adminApi.applications.getById(appId);\r\n setApplication(data);\r\n setFormData({\r\n label: data.label,\r\n description: data.description || '',\r\n icon: data.icon || '',\r\n route: data.route || '',\r\n displayOrder: data.displayOrder,\r\n });\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('applicationDetail.errors.loadFailed'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [t]);\r\n\r\n const handleSaveInfo = useCallback(async (appId: string, data: ApplicationFormData) => {\r\n if (!appId || !application) return;\r\n\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n\r\n try {\r\n const updateData: UpdateApplicationRequest = {\r\n label: data.label,\r\n description: data.description || undefined,\r\n icon: data.icon || undefined,\r\n route: data.route || undefined,\r\n displayOrder: data.displayOrder,\r\n };\r\n\r\n await adminApi.applications.update(appId, updateData);\r\n setSuccess(t('applicationDetail.success.saved'));\r\n await loadApplication(appId);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('applicationDetail.errors.saveFailed'));\r\n } finally {\r\n setSaving(false);\r\n }\r\n }, [application, t, loadApplication]);\r\n\r\n const handleToggleStatus = useCallback(async (appId: string) => {\r\n if (!appId || !application) return;\r\n\r\n setSaving(true);\r\n setError(null);\r\n setSuccess(null);\r\n\r\n try {\r\n if (application.isActive) {\r\n await adminApi.applications.deactivate(appId);\r\n } else {\r\n await adminApi.applications.activate(appId);\r\n }\r\n\r\n setSuccess(\r\n application.isActive\r\n ? t('applicationDetail.success.deactivated')\r\n : t('applicationDetail.success.activated')\r\n );\r\n await loadApplication(appId);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : t('applicationDetail.errors.toggleFailed'));\r\n } finally {\r\n setSaving(false);\r\n }\r\n }, [application, t, loadApplication]);\r\n\r\n return {\r\n application,\r\n loading,\r\n saving,\r\n error,\r\n success,\r\n formData,\r\n setFormData,\r\n setError,\r\n setSuccess,\r\n loadApplication,\r\n handleSaveInfo,\r\n handleToggleStatus,\r\n };\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport {\r\n adminApi,\r\n type ApplicationModuleDto,\r\n type ModuleSectionDto,\r\n} from '@/services/api/adminApi';\r\n\r\nexport interface ModuleFormData {\r\n code: string;\r\n label: string;\r\n description: string;\r\n icon: string;\r\n route: string;\r\n displayOrder: number;\r\n}\r\n\r\nexport interface UseApplicationModulesReturn {\r\n expandedModules: Set<string>;\r\n moduleSections: Map<string, ModuleSectionDto[]>;\r\n loadingSections: Set<string>;\r\n reordering: boolean;\r\n editingModule: ApplicationModuleDto | null;\r\n moduleFormData: ModuleFormData;\r\n showModuleForm: boolean;\r\n toggleModuleExpand: (appId: string, moduleId: string) => Promise<void>;\r\n handleSaveModule: (appId: string, moduleId: string, data: ModuleFormData) => Promise<void>;\r\n handleModulesReorder: (appId: string, modules: (ApplicationModuleDto & { id: string })[]) => Promise<void>;\r\n handleSectionsReorder: (appId: string, moduleId: string, sections: ModuleSectionDto[]) => Promise<void>;\r\n startEditModule: (module: ApplicationModuleDto) => void;\r\n resetModuleForm: (moduleCount?: number) => void;\r\n setShowModuleForm: (show: boolean) => void;\r\n setEditingModule: (module: ApplicationModuleDto | null) => void;\r\n setModuleFormData: (data: ModuleFormData) => void;\r\n}\r\n\r\nexport function useApplicationModules(): UseApplicationModulesReturn {\r\n const [expandedModules, setExpandedModules] = useState<Set<string>>(new Set());\r\n const [moduleSections, setModuleSections] = useState<Map<string, ModuleSectionDto[]>>(new Map());\r\n const [loadingSections, setLoadingSections] = useState<Set<string>>(new Set());\r\n const [reordering, setReordering] = useState(false);\r\n\r\n const [editingModule, setEditingModule] = useState<ApplicationModuleDto | null>(null);\r\n const [moduleFormData, setModuleFormData] = useState<ModuleFormData>({\r\n code: '',\r\n label: '',\r\n description: '',\r\n icon: '',\r\n route: '',\r\n displayOrder: 0,\r\n });\r\n const [showModuleForm, setShowModuleForm] = useState(false);\r\n\r\n const toggleModuleExpand = useCallback(async (appId: string, moduleId: string) => {\r\n const isExpanding = !expandedModules.has(moduleId);\r\n\r\n setExpandedModules(prev => {\r\n const newSet = new Set(prev);\r\n if (newSet.has(moduleId)) {\r\n newSet.delete(moduleId);\r\n } else {\r\n newSet.add(moduleId);\r\n }\r\n return newSet;\r\n });\r\n\r\n // Load sections if expanding and not already loaded\r\n if (isExpanding && !moduleSections.has(moduleId)) {\r\n setLoadingSections(prev => new Set(prev).add(moduleId));\r\n try {\r\n const sections = await adminApi.applications.getModuleSections(appId, moduleId);\r\n setModuleSections(prev => new Map(prev).set(moduleId, sections));\r\n } catch (err) {\r\n console.error('Failed to load sections:', err);\r\n } finally {\r\n setLoadingSections(prev => {\r\n const newSet = new Set(prev);\r\n newSet.delete(moduleId);\r\n return newSet;\r\n });\r\n }\r\n }\r\n }, [expandedModules, moduleSections]);\r\n\r\n const handleSaveModule = useCallback(async (appId: string, moduleId: string, data: ModuleFormData) => {\r\n try {\r\n await adminApi.applications.updateModule(appId, moduleId, {\r\n label: data.label,\r\n description: data.description || undefined,\r\n icon: data.icon || undefined,\r\n route: data.route || undefined,\r\n displayOrder: data.displayOrder,\r\n });\r\n setShowModuleForm(false);\r\n setEditingModule(null);\r\n resetModuleForm();\r\n } catch (err) {\r\n console.error('Failed to save module:', err);\r\n throw err;\r\n }\r\n }, []);\r\n\r\n const handleModulesReorder = useCallback(async (appId: string, reorderedModules: (ApplicationModuleDto & { id: string })[]) => {\r\n // Optimistic update\r\n const newModules = reorderedModules.map((m, index) => ({ ...m, displayOrder: index }));\r\n\r\n setReordering(true);\r\n try {\r\n await adminApi.applications.reorderModules(appId, newModules.map((m, index) => ({ id: m.id, displayOrder: index })));\r\n } catch (err) {\r\n console.error('Failed to reorder modules:', err);\r\n throw err;\r\n } finally {\r\n setReordering(false);\r\n }\r\n }, []);\r\n\r\n const handleSectionsReorder = useCallback(async (appId: string, moduleId: string, reorderedSections: ModuleSectionDto[]) => {\r\n // Optimistic update\r\n const newSections = reorderedSections.map((s, index) => ({ ...s, displayOrder: index }));\r\n setModuleSections(prev => new Map(prev).set(moduleId, newSections));\r\n\r\n setReordering(true);\r\n try {\r\n await adminApi.applications.reorderSections(appId, moduleId, newSections.map((s, index) => ({ id: s.id, displayOrder: index })));\r\n } catch (err) {\r\n console.error('Failed to reorder sections:', err);\r\n // Reload sections on error\r\n try {\r\n const sections = await adminApi.applications.getModuleSections(appId, moduleId);\r\n setModuleSections(prev => new Map(prev).set(moduleId, sections));\r\n } catch (reloadErr) {\r\n console.error('Failed to reload sections:', reloadErr);\r\n }\r\n throw err;\r\n } finally {\r\n setReordering(false);\r\n }\r\n }, []);\r\n\r\n const startEditModule = useCallback((module: ApplicationModuleDto) => {\r\n setEditingModule(module);\r\n setModuleFormData({\r\n code: module.code,\r\n label: module.label,\r\n description: module.description || '',\r\n icon: module.icon || '',\r\n route: module.route || '',\r\n displayOrder: module.displayOrder,\r\n });\r\n setShowModuleForm(true);\r\n }, []);\r\n\r\n const resetModuleForm = useCallback((moduleCount?: number) => {\r\n setModuleFormData({\r\n code: '',\r\n label: '',\r\n description: '',\r\n icon: '',\r\n route: '',\r\n displayOrder: moduleCount || 0,\r\n });\r\n }, []);\r\n\r\n return {\r\n expandedModules,\r\n moduleSections,\r\n loadingSections,\r\n reordering,\r\n editingModule,\r\n moduleFormData,\r\n showModuleForm,\r\n toggleModuleExpand,\r\n handleSaveModule,\r\n handleModulesReorder,\r\n handleSectionsReorder,\r\n startEditModule,\r\n resetModuleForm,\r\n setShowModuleForm,\r\n setEditingModule,\r\n setModuleFormData,\r\n };\r\n}\r\n","import { useState, useCallback, useMemo } from 'react';\r\nimport { adminApi, type PermissionListDto, type RoleListDto, type MatrixRoleDto, type ApplicationDetailDto } from '@/services/api/adminApi';\r\n\r\nexport interface PermissionWithRoles {\r\n permission: PermissionListDto;\r\n roles: RoleListDto[];\r\n}\r\n\r\nexport interface RoleWithPermissions {\r\n role: RoleListDto;\r\n permissions: PermissionListDto[];\r\n}\r\n\r\nconst getPermissionWithRoles = (\r\n perm: PermissionListDto,\r\n matrixRoles: MatrixRoleDto[],\r\n allRoles: RoleListDto[]\r\n): PermissionWithRoles => {\r\n const rolesWithPerm = matrixRoles\r\n .filter(mr => mr.permissionIds.includes(perm.id))\r\n .map(mr => allRoles.find(r => r.id === mr.id)!)\r\n .filter(Boolean);\r\n return { permission: perm, roles: rolesWithPerm };\r\n};\r\n\r\nexport interface UseApplicationPermissionsReturn {\r\n roles: RoleListDto[];\r\n permissions: PermissionListDto[];\r\n permissionsWithRoles: PermissionWithRoles[];\r\n rolesWithAppAccess: RoleWithPermissions[];\r\n\r\n loadPermissionsData: (application: ApplicationDetailDto) => Promise<void>;\r\n loadRolesData: () => Promise<void>;\r\n}\r\n\r\nexport function useApplicationPermissions(): UseApplicationPermissionsReturn {\r\n const [roles, setRoles] = useState<RoleListDto[]>([]);\r\n const [permissions, setPermissions] = useState<PermissionListDto[]>([]);\r\n const [permissionsWithRoles, setPermissionsWithRoles] = useState<PermissionWithRoles[]>([]);\r\n\r\n const loadPermissionsData = useCallback(async (application: ApplicationDetailDto) => {\r\n try {\r\n const [matrix, allRoles] = await Promise.all([\r\n adminApi.permissions.getMatrix(),\r\n adminApi.roles.getAll(),\r\n ]);\r\n\r\n const appPermissionPrefix = `${application.code}.`.toLowerCase();\r\n const appPermissions = matrix.permissions.filter(p =>\r\n p.path.toLowerCase().startsWith(appPermissionPrefix)\r\n );\r\n\r\n setPermissions(appPermissions);\r\n setRoles(allRoles);\r\n\r\n const permWithRoles: PermissionWithRoles[] = appPermissions.map(perm =>\r\n getPermissionWithRoles(perm, matrix.roles, allRoles)\r\n );\r\n\r\n setPermissionsWithRoles(permWithRoles);\r\n } catch (err) {\r\n console.error('Failed to load permissions data:', err);\r\n throw err;\r\n }\r\n }, []);\r\n\r\n const loadRolesData = useCallback(async () => {\r\n try {\r\n const allRoles = await adminApi.roles.getAll();\r\n setRoles(allRoles);\r\n } catch (err) {\r\n console.error('Failed to load roles:', err);\r\n throw err;\r\n }\r\n }, []);\r\n\r\n const rolesWithAppAccess = useMemo<RoleWithPermissions[]>(() => {\r\n if (permissionsWithRoles.length === 0) return [];\r\n\r\n const roleAccessMap = new Map<string, { role: RoleListDto; permissions: PermissionListDto[] }>();\r\n\r\n permissionsWithRoles.forEach(({ permission, roles: permRoles }) => {\r\n permRoles.forEach(role => {\r\n if (!roleAccessMap.has(role.id)) {\r\n roleAccessMap.set(role.id, { role, permissions: [] });\r\n }\r\n roleAccessMap.get(role.id)!.permissions.push(permission);\r\n });\r\n });\r\n\r\n return Array.from(roleAccessMap.values()).sort((a, b) =>\r\n b.permissions.length - a.permissions.length\r\n );\r\n }, [permissionsWithRoles]);\r\n\r\n return {\r\n roles,\r\n permissions,\r\n permissionsWithRoles,\r\n rolesWithAppAccess,\r\n loadPermissionsData,\r\n loadRolesData,\r\n };\r\n}\r\n","import React, { useState, useCallback } from 'react';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport type {\r\n ApplicationTenantDto,\r\n AvailableTenantForAppDto,\r\n ApplicationAccessLevel,\r\n BulkAssignTenantsRequest,\r\n} from '@/services/api/adminApi';\r\n\r\nconst updateModuleAssignment = (module: BulkModuleNode, moduleId: string): BulkModuleNode => {\r\n if (module.id !== moduleId) return module;\r\n const newIsAssigned = !module.isAssigned;\r\n return {\r\n ...module,\r\n isAssigned: newIsAssigned,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: newIsAssigned })),\r\n };\r\n};\r\n\r\nconst updateSectionAssignment = (module: BulkModuleNode, moduleId: string, sectionId: string): BulkModuleNode => {\r\n if (module.id !== moduleId) return module;\r\n const newSections = module.sections.map(s =>\r\n s.id === sectionId ? { ...s, isAssigned: !s.isAssigned } : s\r\n );\r\n const allSectionsAssigned = newSections.every(s => s.isAssigned);\r\n return {\r\n ...module,\r\n isAssigned: allSectionsAssigned,\r\n sections: newSections,\r\n };\r\n};\r\n\r\nconst assignAllSections = (module: BulkModuleNode): BulkModuleNode => ({\r\n ...module,\r\n isAssigned: true,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: true })),\r\n});\r\n\r\nconst clearAllSections = (module: BulkModuleNode): BulkModuleNode => ({\r\n ...module,\r\n isAssigned: false,\r\n sections: module.sections.map(s => ({ ...s, isAssigned: false })),\r\n});\r\n\r\n// Bulk operation interfaces\r\nexport interface BulkModuleNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n isAssigned: boolean;\r\n sections: BulkSectionNode[];\r\n}\r\n\r\nexport interface BulkSectionNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n isAssigned: boolean;\r\n}\r\n\r\nexport type BulkAccessMode = 'full' | 'custom';\r\n\r\nexport interface UseApplicationPublicationReturn {\r\n // State\r\n assignedTenants: ApplicationTenantDto[];\r\n availableTenants: AvailableTenantForAppDto[];\r\n showAssignModal: boolean;\r\n selectedTenantIds: string[];\r\n selectedAccessLevel: ApplicationAccessLevel;\r\n tenantSearch: string;\r\n showCustomizeDrawer: boolean;\r\n customizingTenant: ApplicationTenantDto | null;\r\n bulkAccessMode: BulkAccessMode;\r\n bulkModules: BulkModuleNode[];\r\n bulkExpandedModules: Set<string>;\r\n loadingBulkModules: boolean;\r\n isUpdateMode: boolean;\r\n updateMergeMode: 'merge' | 'replace';\r\n showConfirmRemovalDialog: boolean;\r\n pendingRemovals: { modules: number; sections: number };\r\n includePersonalTenants: boolean;\r\n isInDefaultPersonalTemplate: boolean;\r\n\r\n // Setters\r\n setAssignedTenants: React.Dispatch<React.SetStateAction<ApplicationTenantDto[]>>;\r\n setAvailableTenants: React.Dispatch<React.SetStateAction<AvailableTenantForAppDto[]>>;\r\n setShowAssignModal: React.Dispatch<React.SetStateAction<boolean>>;\r\n setSelectedTenantIds: React.Dispatch<React.SetStateAction<string[]>>;\r\n setSelectedAccessLevel: React.Dispatch<React.SetStateAction<ApplicationAccessLevel>>;\r\n setTenantSearch: React.Dispatch<React.SetStateAction<string>>;\r\n setShowCustomizeDrawer: React.Dispatch<React.SetStateAction<boolean>>;\r\n setCustomizingTenant: React.Dispatch<React.SetStateAction<ApplicationTenantDto | null>>;\r\n setBulkAccessMode: React.Dispatch<React.SetStateAction<BulkAccessMode>>;\r\n setBulkModules: React.Dispatch<React.SetStateAction<BulkModuleNode[]>>;\r\n setBulkExpandedModules: React.Dispatch<React.SetStateAction<Set<string>>>;\r\n setIsUpdateMode: React.Dispatch<React.SetStateAction<boolean>>;\r\n setUpdateMergeMode: React.Dispatch<React.SetStateAction<'merge' | 'replace'>>;\r\n setShowConfirmRemovalDialog: React.Dispatch<React.SetStateAction<boolean>>;\r\n setPendingRemovals: React.Dispatch<React.SetStateAction<{ modules: number; sections: number }>>;\r\n setIncludePersonalTenants: React.Dispatch<React.SetStateAction<boolean>>;\r\n\r\n // Publication operations\r\n loadPublicationData: (appId: string) => Promise<void>;\r\n loadBulkModules: (appId: string) => Promise<void>;\r\n\r\n // Bulk module operations\r\n toggleBulkModuleExpand: (moduleId: string) => void;\r\n toggleBulkModule: (moduleId: string) => void;\r\n toggleBulkSection: (moduleId: string, sectionId: string) => void;\r\n getBulkModuleCheckState: (module: BulkModuleNode) => 'checked' | 'unchecked' | 'indeterminate';\r\n getBulkStats: () => { totalModules: number; assignedModules: number; totalSections: number; assignedSections: number };\r\n selectAllBulkModules: () => void;\r\n clearBulkModules: () => void;\r\n\r\n // Tenant assignment operations\r\n toggleTenantSelection: (tenantId: string) => void;\r\n selectAllFilteredTenants: () => void;\r\n clearTenantSelection: () => void;\r\n\r\n // API operations\r\n handleAssignTenants: (appId: string, onSuccess?: () => void) => Promise<void>;\r\n handleUpdateTenants: (appId: string, onSuccess?: () => void) => Promise<void>;\r\n executeUpdateTenants: (appId: string, onSuccess?: () => void) => Promise<void>;\r\n handleRemoveTenant: (appId: string, tenantId: string, onSuccess?: () => void) => Promise<void>;\r\n handleUpdateAccessLevel: (appId: string, tenantId: string, accessLevel: ApplicationAccessLevel, onSuccess?: () => void) => Promise<void>;\r\n}\r\n\r\nexport function useApplicationPublication(): UseApplicationPublicationReturn {\r\n // Publication state\r\n const [assignedTenants, setAssignedTenants] = useState<ApplicationTenantDto[]>([]);\r\n const [availableTenants, setAvailableTenants] = useState<AvailableTenantForAppDto[]>([]);\r\n const [showAssignModal, setShowAssignModal] = useState(false);\r\n const [selectedTenantIds, setSelectedTenantIds] = useState<string[]>([]);\r\n const [selectedAccessLevel, setSelectedAccessLevel] = useState<ApplicationAccessLevel>('FullAccess');\r\n const [tenantSearch, setTenantSearch] = useState('');\r\n\r\n // Customize access drawer state\r\n const [showCustomizeDrawer, setShowCustomizeDrawer] = useState(false);\r\n const [customizingTenant, setCustomizingTenant] = useState<ApplicationTenantDto | null>(null);\r\n\r\n // Bulk customization state\r\n const [bulkAccessMode, setBulkAccessMode] = useState<BulkAccessMode>('full');\r\n const [bulkModules, setBulkModules] = useState<BulkModuleNode[]>([]);\r\n const [bulkExpandedModules, setBulkExpandedModules] = useState<Set<string>>(new Set());\r\n const [loadingBulkModules, setLoadingBulkModules] = useState(false);\r\n\r\n // Update mode state\r\n const [isUpdateMode, setIsUpdateMode] = useState(false);\r\n const [updateMergeMode, setUpdateMergeMode] = useState<'merge' | 'replace'>('merge');\r\n const [showConfirmRemovalDialog, setShowConfirmRemovalDialog] = useState(false);\r\n const [pendingRemovals, setPendingRemovals] = useState<{ modules: number; sections: number }>({ modules: 0, sections: 0 });\r\n\r\n // Personal tenant filter state\r\n const [includePersonalTenants, setIncludePersonalTenants] = useState(false);\r\n const [isInDefaultPersonalTemplate, setIsInDefaultPersonalTemplate] = useState(false);\r\n\r\n // Publication data loading\r\n const loadPublicationData = useCallback(async (appId: string) => {\r\n try {\r\n const [assigned, availableResponse] = await Promise.all([\r\n adminApi.applications.getTenants(appId),\r\n adminApi.applications.getAvailableTenants(appId),\r\n ]);\r\n setAssignedTenants(assigned);\r\n setAvailableTenants(availableResponse.tenants);\r\n setIsInDefaultPersonalTemplate(availableResponse.isInDefaultPersonalTemplate);\r\n } catch (err) {\r\n console.error('Failed to load publication data:', err);\r\n }\r\n }, []);\r\n\r\n // Load bulk modules for custom access mode\r\n const loadBulkModules = useCallback(async (appId: string) => {\r\n setLoadingBulkModules(true);\r\n try {\r\n const appModules = await adminApi.applications.getModules(appId);\r\n const moduleNodes: BulkModuleNode[] = [];\r\n\r\n for (const appModule of appModules) {\r\n const sections = await adminApi.applications.getModuleSections(appId, appModule.id);\r\n const sectionNodes: BulkSectionNode[] = sections.map(section => ({\r\n id: section.id,\r\n label: section.label,\r\n code: section.code,\r\n icon: section.icon,\r\n isAssigned: true,\r\n }));\r\n\r\n moduleNodes.push({\r\n id: appModule.id,\r\n label: appModule.label,\r\n code: appModule.code,\r\n icon: appModule.icon,\r\n isAssigned: true,\r\n sections: sectionNodes,\r\n });\r\n }\r\n\r\n setBulkModules(moduleNodes);\r\n } catch (err) {\r\n console.error('Failed to load bulk modules:', err);\r\n } finally {\r\n setLoadingBulkModules(false);\r\n }\r\n }, []);\r\n\r\n // Toggle bulk module expansion\r\n const toggleBulkModuleExpand = useCallback((moduleId: string) => {\r\n setBulkExpandedModules(prev => {\r\n const newSet = new Set(prev);\r\n if (newSet.has(moduleId)) {\r\n newSet.delete(moduleId);\r\n } else {\r\n newSet.add(moduleId);\r\n }\r\n return newSet;\r\n });\r\n }, []);\r\n\r\n // Toggle entire bulk module (all sections)\r\n const toggleBulkModule = useCallback((moduleId: string) => {\r\n setBulkModules(prev => prev.map(m => updateModuleAssignment(m, moduleId)));\r\n }, []);\r\n\r\n // Toggle bulk section within module\r\n const toggleBulkSection = useCallback((moduleId: string, sectionId: string) => {\r\n setBulkModules(prev => prev.map(m => updateSectionAssignment(m, moduleId, sectionId)));\r\n }, []);\r\n\r\n // Get checkbox state for bulk module (checked, unchecked, or indeterminate)\r\n const getBulkModuleCheckState = useCallback((module: BulkModuleNode): 'checked' | 'unchecked' | 'indeterminate' => {\r\n const assignedCount = module.sections.filter(s => s.isAssigned).length;\r\n if (assignedCount === 0) return 'unchecked';\r\n if (assignedCount === module.sections.length) return 'checked';\r\n return 'indeterminate';\r\n }, []);\r\n\r\n // Get statistics for bulk selection\r\n const getBulkStats = useCallback(() => {\r\n const totalModules = bulkModules.length;\r\n const assignedModules = bulkModules.filter(m => m.isAssigned || m.sections.some(s => s.isAssigned)).length;\r\n const totalSections = bulkModules.reduce((sum, m) => sum + m.sections.length, 0);\r\n const assignedSections = bulkModules.reduce((sum, m) => sum + m.sections.filter(s => s.isAssigned).length, 0);\r\n return { totalModules, assignedModules, totalSections, assignedSections };\r\n }, [bulkModules]);\r\n\r\n // Select all bulk modules\r\n const selectAllBulkModules = useCallback(() => {\r\n setBulkModules(prev => prev.map(m => assignAllSections(m)));\r\n }, []);\r\n\r\n // Clear all bulk module selections\r\n const clearBulkModules = useCallback(() => {\r\n setBulkModules(prev => prev.map(m => clearAllSections(m)));\r\n }, []);\r\n\r\n // Toggle tenant selection\r\n const toggleTenantSelection = useCallback((tenantId: string) => {\r\n setSelectedTenantIds(prev =>\r\n prev.includes(tenantId)\r\n ? prev.filter(id => id !== tenantId)\r\n : [...prev, tenantId]\r\n );\r\n }, []);\r\n\r\n // Select all filtered tenants (based on search and personal filter)\r\n const selectAllFilteredTenants = useCallback(() => {\r\n if (isUpdateMode) {\r\n const filteredIds = assignedTenants\r\n .filter(t => {\r\n const matchesSearch =\r\n t.tenantName.toLowerCase().includes(tenantSearch.toLowerCase()) ||\r\n t.tenantSlug.toLowerCase().includes(tenantSearch.toLowerCase());\r\n const matchesType = includePersonalTenants || t.tenantType !== 'Personal';\r\n return matchesSearch && matchesType;\r\n })\r\n .map(t => t.tenantId);\r\n setSelectedTenantIds(filteredIds);\r\n } else {\r\n const filteredIds = availableTenants\r\n .filter(t => {\r\n const matchesSearch =\r\n t.name.toLowerCase().includes(tenantSearch.toLowerCase()) ||\r\n t.slug.toLowerCase().includes(tenantSearch.toLowerCase());\r\n const matchesType = includePersonalTenants || t.type !== 'Personal';\r\n return matchesSearch && matchesType;\r\n })\r\n .map(t => t.id);\r\n setSelectedTenantIds(filteredIds);\r\n }\r\n }, [isUpdateMode, assignedTenants, availableTenants, tenantSearch, includePersonalTenants]);\r\n\r\n // Clear tenant selection\r\n const clearTenantSelection = useCallback(() => {\r\n setSelectedTenantIds([]);\r\n }, []);\r\n\r\n // Execute the actual update operation\r\n const executeUpdateTenants = useCallback(\r\n async (appId: string, onSuccess?: () => void) => {\r\n if (!appId || selectedTenantIds.length === 0) return;\r\n\r\n try {\r\n const request: BulkAssignTenantsRequest = {\r\n tenantIds: selectedTenantIds,\r\n accessLevel: selectedAccessLevel,\r\n accessMode: bulkAccessMode,\r\n mergeMode: updateMergeMode,\r\n };\r\n\r\n if (bulkAccessMode === 'custom') {\r\n request.moduleIds = bulkModules.filter(m => m.isAssigned).map(m => m.id);\r\n request.sectionIds = bulkModules.flatMap(m =>\r\n m.sections.filter(s => s.isAssigned).map(s => s.id)\r\n );\r\n }\r\n\r\n await adminApi.applications.bulkAssignTenants(appId, request);\r\n\r\n // Reset state\r\n setShowAssignModal(false);\r\n setSelectedTenantIds([]);\r\n setSelectedAccessLevel('FullAccess');\r\n setBulkAccessMode('full');\r\n setTenantSearch('');\r\n setIsUpdateMode(false);\r\n setUpdateMergeMode('merge');\r\n setShowConfirmRemovalDialog(false);\r\n await loadPublicationData(appId);\r\n\r\n if (onSuccess) onSuccess();\r\n } catch (err) {\r\n console.error('Failed to update tenant assignments:', err);\r\n throw err;\r\n }\r\n },\r\n [selectedTenantIds, selectedAccessLevel, bulkAccessMode, updateMergeMode, bulkModules, loadPublicationData]\r\n );\r\n\r\n // Assign application to tenants\r\n const handleAssignTenants = useCallback(\r\n async (appId: string, onSuccess?: () => void) => {\r\n if (!appId || selectedTenantIds.length === 0) return;\r\n\r\n try {\r\n const request: BulkAssignTenantsRequest = {\r\n tenantIds: selectedTenantIds,\r\n accessLevel: selectedAccessLevel,\r\n accessMode: bulkAccessMode,\r\n };\r\n\r\n if (bulkAccessMode === 'custom') {\r\n request.moduleIds = bulkModules.filter(m => m.isAssigned).map(m => m.id);\r\n request.sectionIds = bulkModules.flatMap(m =>\r\n m.sections.filter(s => s.isAssigned).map(s => s.id)\r\n );\r\n }\r\n\r\n await adminApi.applications.bulkAssignTenants(appId, request);\r\n\r\n // Reset state\r\n setShowAssignModal(false);\r\n setSelectedTenantIds([]);\r\n setSelectedAccessLevel('FullAccess');\r\n setBulkAccessMode('full');\r\n setTenantSearch('');\r\n await loadPublicationData(appId);\r\n\r\n if (onSuccess) onSuccess();\r\n } catch (err) {\r\n console.error('Failed to assign tenants:', err);\r\n throw err;\r\n }\r\n },\r\n [selectedTenantIds, selectedAccessLevel, bulkAccessMode, bulkModules, loadPublicationData]\r\n );\r\n\r\n // Update existing tenant assignments (with confirmation for replace mode)\r\n const handleUpdateTenants = useCallback(\r\n async (appId: string, onSuccess?: () => void) => {\r\n if (!appId || selectedTenantIds.length === 0) return;\r\n\r\n // Calculate potential removals in replace mode\r\n if (updateMergeMode === 'replace' && bulkAccessMode === 'custom') {\r\n let removedModulesCount = 0;\r\n let removedSectionsCount = 0;\r\n\r\n // Get current assignments for selected tenants and calculate diff\r\n for (const tenantId of selectedTenantIds) {\r\n try {\r\n const currentModules = await adminApi.tenants.getModules(tenantId);\r\n const currentSections = await adminApi.tenants.getSections(tenantId);\r\n\r\n const targetModuleIds = new Set(bulkModules.filter(m => m.isAssigned).map(m => m.id));\r\n const targetSectionIds = new Set(bulkModules.flatMap(m => m.sections.filter(s => s.isAssigned).map(s => s.id)));\r\n\r\n removedModulesCount += currentModules.filter(m => !targetModuleIds.has(m.moduleId)).length;\r\n removedSectionsCount += currentSections.filter(s => !targetSectionIds.has(s.sectionId)).length;\r\n } catch {\r\n // Ignore errors fetching current state\r\n }\r\n }\r\n\r\n // If there are removals, show confirmation dialog\r\n if (removedModulesCount > 0 || removedSectionsCount > 0) {\r\n setPendingRemovals({ modules: removedModulesCount, sections: removedSectionsCount });\r\n setShowConfirmRemovalDialog(true);\r\n return;\r\n }\r\n }\r\n\r\n await executeUpdateTenants(appId, onSuccess);\r\n },\r\n [\r\n selectedTenantIds,\r\n updateMergeMode,\r\n bulkAccessMode,\r\n bulkModules,\r\n executeUpdateTenants,\r\n ]\r\n );\r\n\r\n // Remove application from tenant\r\n const handleRemoveTenant = useCallback(\r\n async (appId: string, tenantId: string, onSuccess?: () => void) => {\r\n if (!appId) return;\r\n\r\n try {\r\n await adminApi.applications.removeFromTenant(appId, tenantId);\r\n await loadPublicationData(appId);\r\n\r\n if (onSuccess) onSuccess();\r\n } catch (err) {\r\n console.error('Failed to remove tenant:', err);\r\n throw err;\r\n }\r\n },\r\n [loadPublicationData]\r\n );\r\n\r\n // Update tenant access level\r\n const handleUpdateAccessLevel = useCallback(\r\n async (appId: string, tenantId: string, accessLevel: ApplicationAccessLevel, onSuccess?: () => void) => {\r\n if (!appId) return;\r\n\r\n try {\r\n await adminApi.applications.updateTenantAccessLevel(appId, tenantId, accessLevel);\r\n await loadPublicationData(appId);\r\n\r\n if (onSuccess) onSuccess();\r\n } catch (err) {\r\n console.error('Failed to update access level:', err);\r\n throw err;\r\n }\r\n },\r\n [loadPublicationData]\r\n );\r\n\r\n return {\r\n // State\r\n assignedTenants,\r\n availableTenants,\r\n showAssignModal,\r\n selectedTenantIds,\r\n selectedAccessLevel,\r\n tenantSearch,\r\n showCustomizeDrawer,\r\n customizingTenant,\r\n bulkAccessMode,\r\n bulkModules,\r\n bulkExpandedModules,\r\n loadingBulkModules,\r\n isUpdateMode,\r\n updateMergeMode,\r\n showConfirmRemovalDialog,\r\n pendingRemovals,\r\n includePersonalTenants,\r\n isInDefaultPersonalTemplate,\r\n\r\n // Setters\r\n setAssignedTenants,\r\n setAvailableTenants,\r\n setShowAssignModal,\r\n setSelectedTenantIds,\r\n setSelectedAccessLevel,\r\n setTenantSearch,\r\n setShowCustomizeDrawer,\r\n setCustomizingTenant,\r\n setBulkAccessMode,\r\n setBulkModules,\r\n setBulkExpandedModules,\r\n setIsUpdateMode,\r\n setUpdateMergeMode,\r\n setShowConfirmRemovalDialog,\r\n setPendingRemovals,\r\n setIncludePersonalTenants,\r\n\r\n // Operations\r\n loadPublicationData,\r\n loadBulkModules,\r\n toggleBulkModuleExpand,\r\n toggleBulkModule,\r\n toggleBulkSection,\r\n getBulkModuleCheckState,\r\n getBulkStats,\r\n selectAllBulkModules,\r\n clearBulkModules,\r\n toggleTenantSelection,\r\n selectAllFilteredTenants,\r\n clearTenantSelection,\r\n handleAssignTenants,\r\n handleUpdateTenants,\r\n executeUpdateTenants,\r\n handleRemoveTenant,\r\n handleUpdateAccessLevel,\r\n };\r\n}\r\n","import React from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Save, Loader2 } from 'lucide-react';\r\nimport type { ApplicationDetailDto } from '@/services/api/adminApi';\r\n\r\ninterface ApplicationInfoTabProps {\r\n readonly formData: {\r\n readonly label: string;\r\n readonly description: string;\r\n readonly icon: string;\r\n readonly route: string;\r\n readonly displayOrder: number;\r\n };\r\n readonly setFormData: React.Dispatch<\r\n React.SetStateAction<{\r\n readonly label: string;\r\n readonly description: string;\r\n readonly icon: string;\r\n readonly route: string;\r\n readonly displayOrder: number;\r\n }>\r\n >;\r\n readonly application: ApplicationDetailDto;\r\n readonly saving: boolean;\r\n readonly onSubmit: (e: React.FormEvent) => Promise<void>;\r\n}\r\n\r\nexport function ApplicationInfoTab({\r\n formData,\r\n setFormData,\r\n application,\r\n saving,\r\n onSubmit,\r\n}: ApplicationInfoTabProps): React.ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <form onSubmit={onSubmit} className=\"space-y-6\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.code')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={application.code}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.label')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.label}\r\n onChange={e =>\r\n setFormData(prev => ({ ...prev, label: e.target.value }))\r\n }\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n required\r\n />\r\n </div>\r\n <div className=\"md:col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.description')}\r\n </label>\r\n <textarea\r\n value={formData.description}\r\n onChange={e =>\r\n setFormData(prev => ({ ...prev, description: e.target.value }))\r\n }\r\n rows={3}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.icon')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.icon}\r\n onChange={e =>\r\n setFormData(prev => ({ ...prev, icon: e.target.value }))\r\n }\r\n placeholder={t('applicationDetail.fields.icon')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.route')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.route}\r\n onChange={e =>\r\n setFormData(prev => ({ ...prev, route: e.target.value }))\r\n }\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.displayOrder')}\r\n </label>\r\n <input\r\n type=\"number\"\r\n value={formData.displayOrder}\r\n onChange={e =>\r\n setFormData(prev => ({\r\n ...prev,\r\n displayOrder: parseInt(e.target.value) || 0,\r\n }))\r\n }\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.fields.zone', 'Zone')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={application.zone || ''}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex justify-end\">\r\n <button\r\n type=\"submit\"\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-6 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Save className=\"w-4 h-4\" />\r\n )}\r\n {t('applicationDetail.actions.save')}\r\n </button>\r\n </div>\r\n </form>\r\n );\r\n}\r\n","import { useState, type ReactNode } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport {\r\n DndContext,\r\n closestCenter,\r\n KeyboardSensor,\r\n PointerSensor,\r\n useSensor,\r\n useSensors,\r\n type DragEndEvent,\r\n} from '@dnd-kit/core';\r\nimport {\r\n arrayMove,\r\n SortableContext,\r\n sortableKeyboardCoordinates,\r\n useSortable,\r\n verticalListSortingStrategy,\r\n} from '@dnd-kit/sortable';\r\nimport { CSS } from '@dnd-kit/utilities';\r\nimport { GripVertical } from 'lucide-react';\r\n\r\nexport interface SortableItem {\r\n id: string;\r\n [key: string]: unknown;\r\n}\r\n\r\ninterface SortableListProps<T extends SortableItem> {\r\n readonly items: T[];\r\n readonly onReorder: (items: T[]) => void;\r\n readonly renderItem: (item: T, dragHandle: ReactNode) => ReactNode;\r\n readonly disabled?: boolean;\r\n}\r\n\r\ninterface SortableItemWrapperProps {\r\n readonly id: string;\r\n readonly disabled?: boolean;\r\n readonly children: (dragHandle: ReactNode) => ReactNode;\r\n}\r\n\r\nfunction SortableItemWrapper({ id, disabled, children }: SortableItemWrapperProps) {\r\n const {\r\n attributes,\r\n listeners,\r\n setNodeRef,\r\n transform,\r\n transition,\r\n isDragging,\r\n } = useSortable({ id, disabled });\r\n\r\n const style = {\r\n transform: CSS.Transform.toString(transform),\r\n transition,\r\n opacity: isDragging ? 0.5 : 1,\r\n zIndex: isDragging ? 1 : 0,\r\n };\r\n\r\n const dragHandle = !disabled ? (\r\n <button\r\n type=\"button\"\r\n className=\"p-1.5 rounded hover:bg-[var(--bg-hover)] cursor-grab active:cursor-grabbing text-[var(--text-muted)] hover:text-[var(--text-secondary)] transition-colors\"\r\n {...attributes}\r\n {...listeners}\r\n >\r\n <GripVertical className=\"w-4 h-4\" />\r\n </button>\r\n ) : null;\r\n\r\n return (\r\n <div ref={setNodeRef} style={style}>\r\n {children(dragHandle)}\r\n </div>\r\n );\r\n}\r\n\r\nexport function SortableList<T extends SortableItem>({\r\n items,\r\n onReorder,\r\n renderItem,\r\n disabled = false,\r\n}: SortableListProps<T>): ReactElement {\r\n const [, setActiveId] = useState<string | null>(null);\r\n\r\n const sensors = useSensors(\r\n useSensor(PointerSensor, {\r\n activationConstraint: {\r\n distance: 8,\r\n },\r\n }),\r\n useSensor(KeyboardSensor, {\r\n coordinateGetter: sortableKeyboardCoordinates,\r\n })\r\n );\r\n\r\n const handleDragEnd = (event: DragEndEvent) => {\r\n const { active, over } = event;\r\n setActiveId(null);\r\n\r\n if (over && active.id !== over.id) {\r\n const oldIndex = items.findIndex((item) => item.id === active.id);\r\n const newIndex = items.findIndex((item) => item.id === over.id);\r\n const newItems = arrayMove(items, oldIndex, newIndex);\r\n onReorder(newItems);\r\n }\r\n };\r\n\r\n return (\r\n <DndContext\r\n sensors={sensors}\r\n collisionDetection={closestCenter}\r\n onDragStart={(event) => setActiveId(event.active.id as string)}\r\n onDragEnd={handleDragEnd}\r\n >\r\n <SortableContext\r\n items={items.map((item) => item.id)}\r\n strategy={verticalListSortingStrategy}\r\n disabled={disabled}\r\n >\r\n <div className=\"space-y-2\">\r\n {items.map((item) => (\r\n <SortableItemWrapper key={item.id} id={item.id} disabled={disabled}>\r\n {(dragHandle) => renderItem(item, dragHandle)}\r\n </SortableItemWrapper>\r\n ))}\r\n </div>\r\n </SortableContext>\r\n </DndContext>\r\n );\r\n}\r\n\r\nexport default SortableList;\r\n","import type { ReactElement } from 'react';\nimport { useTranslation } from 'react-i18next';\r\nimport { ChevronDown, ChevronRight, Edit, Layers, Loader2, Save } from 'lucide-react';\r\n\r\ntype TFunction = ReturnType<typeof useTranslation>['t'];\r\nimport { SortableList } from '@/components/ui/SortableList';\r\nimport { renderLucideIcon } from '@/utils/renderLucideIcon';\r\nimport type {\r\n ApplicationDetailDto,\r\n ApplicationModuleDto,\r\n ModuleSectionDto,\r\n} from '@/services/api/adminApi';\r\n\r\ninterface ApplicationModulesTabProps {\r\n readonly application: ApplicationDetailDto;\r\n readonly expandedModules: Set<string>;\r\n readonly moduleSections: Map<string, ModuleSectionDto[]>;\r\n readonly loadingSections: Set<string>;\r\n readonly reordering: boolean;\r\n readonly editingModule: ApplicationModuleDto | null;\r\n readonly moduleFormData: {\r\n readonly code: string;\r\n readonly label: string;\r\n readonly description: string;\r\n readonly icon: string;\r\n readonly route: string;\r\n readonly displayOrder: number;\r\n };\r\n readonly showModuleForm: boolean;\r\n readonly saving: boolean;\r\n readonly onToggleExpand: (moduleId: string) => void;\r\n readonly onStartEdit: (module: ApplicationModuleDto) => void;\r\n readonly onSaveModule: (e: React.FormEvent) => Promise<void>;\r\n readonly onCancelEdit: () => void;\r\n readonly onModulesReorder: (modules: (ApplicationModuleDto & { id: string })[]) => Promise<void>;\r\n readonly onSectionsReorder: (moduleId: string, sections: ModuleSectionDto[]) => Promise<void>;\r\n readonly setModuleFormData: React.Dispatch<\r\n React.SetStateAction<{\r\n readonly code: string;\r\n readonly label: string;\r\n readonly description: string;\r\n readonly icon: string;\r\n readonly route: string;\r\n readonly displayOrder: number;\r\n }>\r\n >;\r\n}\r\n\r\n\r\nconst renderModuleSections = (moduleId: string, loadingSections: Set<string>, moduleSections: Map<string, ModuleSectionDto[]>, onSectionsReorder: (moduleId: string, sections: ModuleSectionDto[]) => Promise<void>, reordering: boolean, t: TFunction) => {\r\n if (loadingSections.has(moduleId)) {\r\n return (\r\n <div className=\"flex items-center justify-center py-4\">\r\n <Loader2 className=\"w-5 h-5 animate-spin text-[var(--text-muted)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (moduleSections.get(moduleId)?.length === 0) {\r\n return (\r\n <p className=\"text-sm text-[var(--text-muted)] py-2\">\r\n {t('applicationDetail.modules.noSections', 'No sections')}\r\n </p>\r\n );\r\n }\r\n\r\n if (moduleSections.get(moduleId)) {\r\n return (\r\n <SortableList\r\n items={moduleSections.get(moduleId)!.map((s) => ({ ...s, id: s.id }))}\r\n onReorder={(sections) => onSectionsReorder(moduleId, sections)}\r\n disabled={reordering}\r\n renderItem={(section, sectionDragHandle) => (\r\n <div className=\"flex items-center gap-2 p-2 rounded bg-[var(--bg-secondary)] border border-[var(--border-color)]\">\r\n {sectionDragHandle}\r\n <div className=\"p-1 rounded bg-[var(--bg-tertiary)]\">\r\n {renderLucideIcon(section.icon, 'w-3 h-3') || (\r\n <Layers className=\"w-3 h-3 text-[var(--text-muted)]\" />\r\n )}\r\n </div>\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {section.label}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)]\">{section.code}</p>\r\n </div>\r\n <span\r\n className={`px-2 py-0.5 text-xs rounded-full ${\r\n section.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--error-bg)] text-[var(--error-text)]'\r\n }`}\r\n >\r\n {section.isActive ? t('common:active') : t('common:inactive')}\r\n </span>\r\n </div>\r\n )}\r\n />\r\n );\r\n }\r\n\r\n return null;\r\n};\r\n\r\nexport function ApplicationModulesTab({\r\n application,\r\n expandedModules,\r\n moduleSections,\r\n loadingSections,\r\n reordering,\r\n editingModule,\r\n moduleFormData,\r\n showModuleForm,\r\n saving,\r\n onToggleExpand,\r\n onStartEdit,\r\n onSaveModule,\r\n onCancelEdit,\r\n onModulesReorder,\r\n onSectionsReorder,\r\n setModuleFormData,\r\n}: ApplicationModulesTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('applicationDetail.modules.title')} ({application.modules.length})\r\n </h3>\r\n\r\n {showModuleForm && editingModule && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)]\">\r\n <h4 className=\"text-md font-semibold text-[var(--text-primary)] mb-4\">\r\n {t('applicationDetail.modules.edit')}\r\n </h4>\r\n <form onSubmit={onSaveModule} className=\"space-y-4\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('applicationDetail.fields.code')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={moduleFormData.code}\r\n disabled\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('applicationDetail.fields.label')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={moduleFormData.label}\r\n onChange={(e) => setModuleFormData((prev) => ({ ...prev, label: e.target.value }))}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)]\"\r\n required\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('applicationDetail.fields.icon')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={moduleFormData.icon}\r\n onChange={(e) => setModuleFormData((prev) => ({ ...prev, icon: e.target.value }))}\r\n placeholder=\"Users\"\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('applicationDetail.fields.route')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={moduleFormData.route}\r\n onChange={(e) => setModuleFormData((prev) => ({ ...prev, route: e.target.value }))}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n <div className=\"md:col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('applicationDetail.fields.description')}\r\n </label>\r\n <textarea\r\n value={moduleFormData.description}\r\n onChange={(e) =>\r\n setModuleFormData((prev) => ({ ...prev, description: e.target.value }))\r\n }\r\n rows={2}\r\n className=\"w-full px-3 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)]\"\r\n />\r\n </div>\r\n </div>\r\n <div className=\"flex justify-end gap-2\">\r\n <button\r\n type=\"button\"\r\n onClick={onCancelEdit}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] font-medium text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common:cancel')}\r\n </button>\r\n <button\r\n type=\"submit\"\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('common:save')}\r\n </button>\r\n </div>\r\n </form>\r\n </div>\r\n )}\r\n\r\n {application.modules.length === 0 ? (\r\n <p className=\"text-center py-8 text-[var(--text-muted)]\">\r\n {t('applicationDetail.modules.empty')}\r\n </p>\r\n ) : (\r\n <SortableList\r\n items={application.modules.map((m) => ({ ...m, id: m.id }))}\r\n onReorder={onModulesReorder}\r\n disabled={reordering}\r\n renderItem={(module, dragHandle) => (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--item-color-border)] hover:border-[var(--color-accent-600)] transition-colors\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n {dragHandle}\r\n <div className=\"p-2 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)]\">\r\n {renderLucideIcon(module.icon, 'w-4 h-4') || (\r\n <Layers className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n )}\r\n </div>\r\n <button\r\n onClick={() => onToggleExpand(module.id)}\r\n className=\"p-1 rounded hover:bg-[var(--bg-hover)]\"\r\n aria-expanded={expandedModules.has(module.id)}\r\n aria-label={t('applicationDetail.modules.toggleExpand', 'Toggle sections')}\r\n >\r\n {expandedModules.has(module.id) ? (\r\n <ChevronDown className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n ) : (\r\n <ChevronRight className=\"w-4 h-4 text-[var(--text-muted)]\" />\r\n )}\r\n </button>\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)]\">{module.label}</p>\r\n <p className=\"text-sm text-[var(--text-muted)]\">{module.code}</p>\r\n </div>\r\n <span\r\n className={`ml-2 px-2 py-0.5 text-xs font-medium rounded-full ${\r\n module.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--error-bg)] text-[var(--error-text)]'\r\n }`}\r\n >\r\n {module.isActive ? t('common:active') : t('common:inactive')}\r\n </span>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm text-[var(--text-muted)]\">\r\n {module.sectionsCount} {t('applicationDetail.modules.sections', 'sections')}\r\n </span>\r\n <button\r\n onClick={() => onStartEdit(module)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] text-[var(--text-secondary)]\"\r\n aria-label={t('applicationDetail.modules.edit')}\r\n >\r\n <Edit className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n {expandedModules.has(module.id) && (\r\n <div className=\"mt-3 pl-10 pt-3 border-t border-[var(--border-color)]\">\r\n <div className=\"grid grid-cols-2 gap-4 text-sm mb-4\">\r\n <div>\r\n <span className=\"text-[var(--text-muted)]\">\r\n {t('applicationDetail.fields.description')}:\r\n </span>\r\n <p className=\"text-[var(--text-primary)]\">{module.description || '-'}</p>\r\n </div>\r\n <div>\r\n <span className=\"text-[var(--text-muted)]\">\r\n {t('applicationDetail.fields.route')}:\r\n </span>\r\n <p className=\"text-[var(--text-primary)] font-mono\">{module.route || '-'}</p>\r\n </div>\r\n </div>\r\n {/* Sections */}\r\n <div className=\"mt-4\">\r\n <h5 className=\"text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('applicationDetail.modules.sections', 'Sections')} ({module.sectionsCount})\r\n </h5>\r\n {renderModuleSections(module.id, loadingSections, moduleSections, onSectionsReorder, reordering, t)}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import type { ReactElement } from 'react';\nimport { useTranslation } from 'react-i18next';\r\nimport type { ApplicationDetailDto, PermissionListDto, RoleListDto } from '@/services/api/adminApi';\r\n\r\nexport interface PermissionWithRoles {\r\n permission: PermissionListDto;\r\n roles: RoleListDto[];\r\n}\r\n\r\nexport interface ApplicationPermissionsTabProps {\r\n readonly application: ApplicationDetailDto;\r\n readonly permissions: PermissionListDto[];\r\n readonly permissionsWithRoles: PermissionWithRoles[];\r\n}\r\n\r\nexport function ApplicationPermissionsTab({\r\n application,\r\n permissions,\r\n permissionsWithRoles,\r\n}: ApplicationPermissionsTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('applicationDetail.permissions.title')} ({permissions.length})\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {t('applicationDetail.permissions.description', {\r\n path: `${application.code}.*`,\r\n })}\r\n </p>\r\n\r\n {permissions.length === 0 ? (\r\n <p className=\"text-center py-8 text-[var(--text-muted)]\">\r\n {t('applicationDetail.permissions.empty')}\r\n </p>\r\n ) : (\r\n <div className=\"overflow-x-auto\">\r\n <table className=\"w-full\">\r\n <thead>\r\n <tr className=\"border-b border-[var(--border-color)]\">\r\n <th className=\"text-left py-3 px-4 text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('applicationDetail.permissions.path')}\r\n </th>\r\n <th className=\"text-left py-3 px-4 text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('applicationDetail.permissions.action')}\r\n </th>\r\n <th className=\"text-left py-3 px-4 text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('applicationDetail.permissions.type')}\r\n </th>\r\n <th className=\"text-left py-3 px-4 text-sm font-medium text-[var(--text-secondary)]\">\r\n {t('applicationDetail.permissions.roles')}\r\n </th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {permissionsWithRoles.map(({ permission, roles: permRoles }) => (\r\n <tr\r\n key={permission.id}\r\n className=\"border-b border-[var(--border-color)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n <td className=\"py-3 px-4 font-mono text-sm text-[var(--text-primary)]\">\r\n {permission.path}\r\n </td>\r\n <td className=\"py-3 px-4\">\r\n {permission.action ? (\r\n <span className=\"px-2 py-1 text-xs font-medium rounded-full bg-[var(--accent-bg)] text-[var(--accent-text)]\">\r\n {permission.action}\r\n </span>\r\n ) : (\r\n '-'\r\n )}\r\n </td>\r\n <td className=\"py-3 px-4\">\r\n {permission.isWildcard ? (\r\n <span className=\"px-2 py-1 text-xs font-medium rounded-full bg-[var(--warning-bg)] text-[var(--warning-text)]\">\r\n {t('applicationDetail.permissions.wildcard', 'Wildcard')}\r\n </span>\r\n ) : (\r\n <span className=\"px-2 py-1 text-xs font-medium rounded-full bg-[var(--bg-tertiary)] text-[var(--text-muted)]\">\r\n {t('applicationDetail.permissions.specific', 'Specific')}\r\n </span>\r\n )}\r\n </td>\r\n <td className=\"py-3 px-4\">\r\n <div className=\"flex flex-wrap gap-1\">\r\n {permRoles.length === 0 ? (\r\n <span className=\"text-[var(--text-muted)] text-sm\">-</span>\r\n ) : (\r\n permRoles.slice(0, 3).map(role => (\r\n <span\r\n key={role.id}\r\n className=\"px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--color-accent-100)] text-[var(--color-accent-700)]\"\r\n >\r\n {role.name}\r\n </span>\r\n ))\r\n )}\r\n {permRoles.length > 3 && (\r\n <span className=\"px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--bg-tertiary)] text-[var(--text-muted)]\">\r\n +{permRoles.length - 3}\r\n </span>\r\n )}\r\n </div>\r\n </td>\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import type { ReactElement } from 'react';\nimport { Shield, Eye } from 'lucide-react';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\nexport interface RoleListDto {\r\n id: string;\r\n name: string;\r\n isSystem: boolean;\r\n usersCount: number;\r\n}\r\n\r\nexport interface PermissionListDto {\r\n id: string;\r\n path: string;\r\n isWildcard: boolean;\r\n}\r\n\r\nexport interface RoleWithPermissions {\r\n role: RoleListDto;\r\n permissions: PermissionListDto[];\r\n}\r\n\r\nexport interface ApplicationAccessTabProps {\r\n readonly rolesWithAppAccess: RoleWithPermissions[];\r\n readonly onNavigateToRole: (roleId: string) => void;\r\n}\r\n\r\nexport function ApplicationAccessTab({\r\n rolesWithAppAccess,\r\n onNavigateToRole,\r\n}: ApplicationAccessTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('applicationDetail.roles.title')} ({rolesWithAppAccess.length})\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {t('applicationDetail.roles.description')}\r\n </p>\r\n\r\n {rolesWithAppAccess.length === 0 ? (\r\n <p className=\"text-center py-8 text-[var(--text-muted)]\">\r\n {t('applicationDetail.roles.empty')}\r\n </p>\r\n ) : (\r\n <div className=\"space-y-3\">\r\n {rolesWithAppAccess.map(({ role, permissions: rolePermissions }) => (\r\n <div\r\n key={role.id}\r\n className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--item-color-border)] hover:border-[var(--color-accent-600)] transition-colors\"\r\n >\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)]\">\r\n <Shield className=\"w-5 h-5 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">{role.name}</p>\r\n {role.isSystem && (\r\n <span className=\"px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--warning-bg)] text-[var(--warning-text)]\">\r\n {t('applicationDetail.roles.system', 'System')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {role.usersCount} {t('applicationDetail.roles.users')} • {rolePermissions.length}{' '}\r\n {t('applicationDetail.roles.permissions')}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => onNavigateToRole(role.id)}\r\n className=\"flex items-center gap-1 px-3 py-1.5 rounded-[var(--radius-button)] text-sm font-medium text-[var(--color-accent-600)] hover:bg-[var(--color-accent-100)]\"\r\n >\r\n <Eye className=\"w-4 h-4\" />\r\n {t('applicationDetail.roles.viewRole')}\r\n </button>\r\n </div>\r\n </div>\r\n <div className=\"mt-3 flex flex-wrap gap-1\">\r\n {rolePermissions.slice(0, 5).map(perm => (\r\n <span\r\n key={perm.id}\r\n className=\"px-2 py-0.5 text-xs font-mono rounded bg-[var(--bg-tertiary)] text-[var(--text-muted)]\"\r\n >\r\n {perm.path.split('.').pop()}\r\n {perm.isWildcard && '.*'}\r\n </span>\r\n ))}\r\n {rolePermissions.length > 5 && (\r\n <span className=\"px-2 py-0.5 text-xs rounded bg-[var(--bg-tertiary)] text-[var(--text-muted)]\">\r\n +{rolePermissions.length - 5} {t('applicationDetail.roles.more', 'more')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","'use client';\r\n\r\nimport React from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n Globe,\r\n} from 'lucide-react';\r\nimport type {\r\n ApplicationDetailDto,\r\n ApplicationTenantDto,\r\n ApplicationAccessLevel,\r\n AvailableTenantForAppDto,\r\n} from '@/services/api/adminApi';\r\nimport { useTenantTypeSettings } from '@/hooks/useTenantTypeSettings';\r\nimport { getLucideIcon, getColorClasses } from '@/utils/tenantIconMap';\r\n\r\nexport interface BulkModuleNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n isAssigned: boolean;\r\n sections: BulkSectionNode[];\r\n}\r\n\r\nexport interface BulkSectionNode {\r\n id: string;\r\n label: string;\r\n code: string;\r\n icon: string | null;\r\n isAssigned: boolean;\r\n}\r\n\r\nexport interface ApplicationPublicationTabProps {\r\n readonly application: ApplicationDetailDto;\r\n readonly assignedTenants: ApplicationTenantDto[];\r\n readonly availableTenants: AvailableTenantForAppDto[];\r\n readonly showAssignModal: boolean;\r\n readonly selectedTenantIds: string[];\r\n readonly selectedAccessLevel: ApplicationAccessLevel;\r\n readonly tenantSearch: string;\r\n readonly showCustomizeDrawer: boolean;\r\n readonly customizingTenant: ApplicationTenantDto | null;\r\n readonly bulkAccessMode: 'full' | 'custom';\r\n readonly bulkModules: BulkModuleNode[];\r\n readonly bulkExpandedModules: Set<string>;\r\n readonly loadingBulkModules: boolean;\r\n readonly isUpdateMode: boolean;\r\n readonly updateMergeMode: 'merge' | 'replace';\r\n readonly showConfirmRemovalDialog: boolean;\r\n readonly pendingRemovals: { modules: number; sections: number };\r\n readonly saving: boolean;\r\n readonly includePersonalTenants: boolean;\r\n readonly isInDefaultPersonalTemplate: boolean;\r\n readonly onAddTenant: () => void;\r\n readonly onRemoveTenant: (tenantId: string) => Promise<void>;\r\n readonly onUpdateAccessLevel: (tenantId: string, accessLevel: ApplicationAccessLevel) => Promise<void>;\r\n readonly onCustomizeTenant: (tenant: ApplicationTenantDto) => void;\r\n readonly onCloseCustomizeDrawer: () => void;\r\n readonly onAssignTenants: () => Promise<void>;\r\n readonly onUpdateTenants: () => Promise<void>;\r\n readonly onExecuteUpdateTenants: () => Promise<void>;\r\n readonly onCancelRemovalDialog: () => void;\r\n readonly setShowAssignModal: (show: boolean) => void;\r\n readonly setSelectedTenantIds: React.Dispatch<React.SetStateAction<string[]>>;\r\n readonly setSelectedAccessLevel: React.Dispatch<React.SetStateAction<ApplicationAccessLevel>>;\r\n readonly setTenantSearch: (search: string) => void;\r\n readonly setBulkAccessMode: React.Dispatch<React.SetStateAction<'full' | 'custom'>>;\r\n readonly setIsUpdateMode: (mode: boolean) => void;\r\n readonly setUpdateMergeMode: React.Dispatch<React.SetStateAction<'merge' | 'replace'>>;\r\n readonly onToggleTenantSelection: (tenantId: string) => void;\r\n readonly onSelectAllFilteredTenants: () => void;\r\n readonly onClearTenantSelection: () => void;\r\n readonly setIncludePersonalTenants: (value: boolean) => void;\r\n readonly onLoadBulkModules: () => Promise<void>;\r\n readonly onToggleBulkModuleExpand: (moduleId: string) => void;\r\n readonly onToggleBulkModule: (moduleId: string) => void;\r\n readonly onToggleBulkSection: (moduleId: string, sectionId: string) => void;\r\n readonly onGetBulkModuleCheckState: (module: BulkModuleNode) => 'checked' | 'unchecked' | 'indeterminate';\r\n readonly onGetBulkStats: () => { totalModules: number; assignedModules: number; totalSections: number; assignedSections: number };\r\n readonly onSelectAllBulkModules: () => void;\r\n readonly onClearBulkModules: () => void;\r\n readonly appId: string;\r\n}\r\n\r\n// Helper: Get CSS classes for access level indicator color\r\nconst getAccessLevelColorClass = (accessLevel: ApplicationAccessLevel): string => {\r\n switch (accessLevel) {\r\n case 'FullAccess':\r\n return 'bg-green-500';\r\n case 'RequestAccess':\r\n return 'bg-amber-500';\r\n case 'Disabled':\r\n return 'bg-gray-400';\r\n default:\r\n return 'bg-gray-400';\r\n }\r\n};\r\n\r\n// Helper: Get access level label key\r\nconst getLabelKey = (level: ApplicationAccessLevel): string => {\r\n switch (level) {\r\n case 'FullAccess':\r\n return 'fullAccess';\r\n case 'RequestAccess':\r\n return 'requestAccess';\r\n case 'Disabled':\r\n return 'disabled';\r\n default:\r\n return 'disabled';\r\n }\r\n};\r\n\r\n// Helper: Get tenant icon and color from settings\r\nconst useTenantIconForType = () => {\r\n const { getIconForType } = useTenantTypeSettings();\r\n return (tenantType: string) => {\r\n const typeInfo = getIconForType(tenantType);\r\n const Icon = getLucideIcon(typeInfo.icon);\r\n const colors = getColorClasses(typeInfo.color);\r\n return { Icon, bgClass: colors.bg, colorClass: colors.text };\r\n };\r\n};\r\n\r\nexport const ApplicationPublicationTab: React.FC<ApplicationPublicationTabProps> = ({\r\n assignedTenants,\r\n}) => {\r\n const { t } = useTranslation('admin');\r\n const getTenantIconInfo = useTenantIconForType();\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Header Section */}\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('applicationDetail.publication.title', 'Tenant Publication')} ({assignedTenants.length})\r\n </h3>\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {t('applicationDetail.publication.description', 'Manage which tenants have access to this application')}\r\n </p>\r\n </div>\r\n\r\n {/* Access Levels Legend */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-3 p-4 rounded-[var(--radius-card)] bg-[var(--bg-tertiary)] border border-[var(--border-color)]\">\r\n <div className=\"flex items-start gap-2\">\r\n <div className=\"w-3 h-3 mt-1 rounded-full bg-green-500 flex-shrink-0\" />\r\n <div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('applicationDetail.publication.accessLevels.fullAccess', 'Full Access')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)]\">\r\n {t('applicationDetail.publication.accessLevels.fullAccessDesc', 'Users can use all features')}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-start gap-2\">\r\n <div className=\"w-3 h-3 mt-1 rounded-full bg-amber-500 flex-shrink-0\" />\r\n <div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('applicationDetail.publication.accessLevels.requestAccess', 'Request Access')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)]\">\r\n {t('applicationDetail.publication.accessLevels.requestAccessDesc', 'Requires access request')}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-start gap-2\">\r\n <div className=\"w-3 h-3 mt-1 rounded-full bg-gray-400 flex-shrink-0\" />\r\n <div>\r\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {t('applicationDetail.publication.accessLevels.disabled', 'Disabled')}\r\n </p>\r\n <p className=\"text-xs text-[var(--text-muted)]\">\r\n {t('applicationDetail.publication.accessLevels.disabledDesc', 'Not visible for tenant')}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Assigned Tenants List or Empty State */}\r\n {assignedTenants.length === 0 ? (\r\n <div className=\"text-center py-12\">\r\n <Globe className=\"w-12 h-12 mx-auto text-[var(--text-muted)] mb-4\" />\r\n <p className=\"text-[var(--text-muted)]\">\r\n {t('applicationDetail.publication.empty', 'No tenants have access to this application yet')}\r\n </p>\r\n </div>\r\n ) : (\r\n <div className=\"space-y-3\">\r\n {assignedTenants.map(tenant => {\r\n const { Icon, bgClass, colorClass } = getTenantIconInfo(tenant.tenantType);\r\n const statusBgClass = tenant.tenantStatus === 'Active'\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--warning-bg)] text-[var(--warning-text)]';\r\n\r\n return (\r\n <div\r\n key={tenant.tenantId}\r\n className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--item-color-border)] hover:border-[var(--color-accent-600)] transition-colors\"\r\n >\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)] ${bgClass}`}>\r\n <Icon className={`w-5 h-5 ${colorClass}`} />\r\n </div>\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <p className=\"font-medium text-[var(--text-primary)]\">{tenant.tenantName}</p>\r\n <span className={`px-2 py-0.5 text-xs font-medium rounded-full ${statusBgClass}`}>\r\n {tenant.tenantStatus}\r\n </span>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-muted)]\">\r\n {tenant.tenantSlug} • {tenant.tenantType}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <div className={`w-2.5 h-2.5 rounded-full ${getAccessLevelColorClass(tenant.accessLevel as ApplicationAccessLevel)}`} />\r\n <span className=\"px-3 py-1.5 rounded-[var(--radius-input)] bg-[var(--bg-secondary)] border border-[var(--border-color)] text-sm text-[var(--text-primary)]\">\r\n {t(`applicationDetail.publication.accessLevels.${getLabelKey(tenant.accessLevel as ApplicationAccessLevel)}`, tenant.accessLevel)}\r\n </span>\r\n </div>\r\n </div>\r\n <div className=\"mt-2 text-xs text-[var(--text-muted)]\">\r\n {t('applicationDetail.publication.assignedAt', 'Assigned')}: {new Date(tenant.assignedAt).toLocaleDateString()}\r\n {tenant.assignedBy && ` ${t('applicationDetail.publication.by', 'by')} ${tenant.assignedBy}`}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import { useEffect, useMemo} from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useParams, useNavigate } from 'react-router-dom';\r\nimport { useTabNavigation } from '@/hooks/useTabNavigation';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n ArrowLeft,\r\n Settings,\r\n Layers,\r\n Shield,\r\n Users,\r\n Loader2,\r\n AlertTriangle,\r\n CheckCircle,\r\n Power,\r\n PowerOff,\r\n Globe,\r\n AlertCircle,\r\n Inbox,\r\n} from 'lucide-react';\r\nimport { renderLucideIcon } from '@/utils/renderLucideIcon';\r\nimport { useApplicationDetail } from '@/hooks/useApplicationDetail';\r\nimport { useApplicationModules } from '@/hooks/useApplicationModules';\r\nimport { useApplicationPermissions } from '@/hooks/useApplicationPermissions';\r\nimport { useApplicationPublication } from '@/hooks/useApplicationPublication';\r\nimport {\r\n ApplicationInfoTab,\r\n ApplicationModulesTab,\r\n ApplicationPermissionsTab,\r\n ApplicationAccessTab,\r\n ApplicationPublicationTab,\r\n} from '@/components/platform/administration/applications';\r\nimport { AccessRequestsListTab } from '@/components/platform/administration/access-requests';\r\nimport { useAccessRequests } from '@/hooks/useAccessRequests';\r\n\r\nconst VALID_TABS = ['info', 'modules', 'permissions', 'roles', 'publication', 'requests'] as const;\r\ntype TabId = typeof VALID_TABS[number];\r\n\r\nexport default function ApplicationDetailPage(): ReactElement {\r\n const { id: appId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('admin');\r\n const { hasPermission } = useAuth();\r\n\r\n const { currentTenant, isGlobalView } = useTenant();\r\n const canToggleStatus = hasPermission('administration.applications.execute');\r\n const { activeTab, setActiveTab } = useTabNavigation<TabId>('info', VALID_TABS);\r\n\r\n // Use all hooks\r\n const applicationDetail = useApplicationDetail();\r\n const applicationModules = useApplicationModules();\r\n const applicationPermissions = useApplicationPermissions();\r\n const applicationPublication = useApplicationPublication();\r\n const accessRequests = useAccessRequests('application', appId!);\r\n\r\n // Filter tenants based on current tenant context\r\n // When scoped to a specific tenant, only show that tenant in the publication modal\r\n const filteredAvailableTenants = useMemo(() => {\r\n if (isGlobalView || !currentTenant) return applicationPublication.availableTenants;\r\n return applicationPublication.availableTenants.filter(t => t.slug === currentTenant.slug);\r\n }, [applicationPublication.availableTenants, isGlobalView, currentTenant]);\r\n\r\n const filteredAssignedTenants = useMemo(() => {\r\n if (isGlobalView || !currentTenant) return applicationPublication.assignedTenants;\r\n return applicationPublication.assignedTenants.filter(t => t.tenantSlug === currentTenant.slug);\r\n }, [applicationPublication.assignedTenants, isGlobalView, currentTenant]);\r\n\r\n // Load data on mount\r\n useEffect(() => {\r\n if (appId) {\r\n applicationDetail.loadApplication(appId);\r\n }\r\n }, [appId]);\r\n\r\n // Load tab-specific data (lazy loading per tab)\r\n useEffect(() => {\r\n if (!applicationDetail.application) return;\r\n\r\n if (\r\n (activeTab === 'permissions' || activeTab === 'roles') &&\r\n applicationPermissions.permissions.length === 0\r\n ) {\r\n applicationPermissions.loadPermissionsData(applicationDetail.application);\r\n }\r\n if (\r\n activeTab === 'publication' &&\r\n applicationPublication.assignedTenants.length === 0\r\n ) {\r\n applicationPublication.loadPublicationData(appId!);\r\n }\r\n if (activeTab === 'requests') {\r\n accessRequests.loadRequests();\r\n }\r\n }, [\r\n activeTab,\r\n applicationDetail.application,\r\n applicationPublication.assignedTenants.length,\r\n ]);\r\n\r\n const tabs = [\r\n { id: 'info' as const, label: t('applicationDetail.tabs.info'), icon: Settings },\r\n { id: 'modules' as const, label: t('applicationDetail.tabs.modules'), icon: Layers },\r\n { id: 'permissions' as const, label: t('applicationDetail.tabs.permissions'), icon: Shield },\r\n { id: 'roles' as const, label: t('applicationDetail.tabs.roles'), icon: Users },\r\n { id: 'publication' as const, label: t('applicationDetail.tabs.publication'), icon: Globe },\r\n { id: 'requests' as const, label: t('applicationDetail.tabs.requests'), icon: Inbox },\r\n ];\r\n\r\n // Loading state\r\n if (applicationDetail.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 // Error or not found\r\n if (applicationDetail.error || !applicationDetail.application) {\r\n return (\r\n <div className=\"text-center py-12\">\r\n <AlertCircle className=\"w-12 h-12 text-[var(--error-text)] mx-auto mb-4\" />\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {applicationDetail.error || t('applicationDetail.notFound')}\r\n </p>\r\n <button\r\n onClick={() => navigate('/administration/applications')}\r\n className=\"mt-4 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)]\"\r\n >\r\n {t('applicationDetail.backToList')}\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n const permissionsLoaded = applicationPermissions.permissions.length > 0 || activeTab === 'permissions' || activeTab === 'roles';\r\n const publicationLoaded = applicationPublication.assignedTenants.length > 0 || activeTab === 'publication';\r\n\r\n const statsCards = [\r\n {\r\n label: t('applicationDetail.stats.modules'),\r\n value: applicationDetail.application.modules?.length || 0,\r\n color: 'blue' as const,\r\n },\r\n {\r\n label: t('applicationDetail.stats.permissions'),\r\n value: permissionsLoaded ? applicationPermissions.permissions.length : '—',\r\n color: 'green' as const,\r\n },\r\n {\r\n label: t('applicationDetail.stats.rolesWithAccess'),\r\n value: permissionsLoaded ? applicationPermissions.rolesWithAppAccess.length : '—',\r\n color: 'purple' as const,\r\n },\r\n {\r\n label: t('applicationDetail.stats.assignedTenants'),\r\n value: publicationLoaded ? filteredAssignedTenants.length : '—',\r\n color: 'yellow' as const,\r\n },\r\n {\r\n label: t('applicationDetail.stats.status'),\r\n value: applicationDetail.application.isActive ? t('common:active') : t('common:inactive'),\r\n color: applicationDetail.application.isActive ? 'green' : 'neutral',\r\n },\r\n ];\r\n\r\n const colorClasses: Record<string, string> = {\r\n blue: 'bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]',\r\n green: 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]',\r\n yellow: 'bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]',\r\n red: 'bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]',\r\n purple: 'bg-[var(--accent-bg)] text-[var(--accent-text)] border-[var(--color-accent-300)]',\r\n neutral: 'bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]',\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('breadcrumb.admin', { ns: 'navigation' }), href: '/administration' },\r\n { label: t('applications.title'), href: '/administration/applications' },\r\n { label: applicationDetail.application.label },\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/administration/applications')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n aria-label={t('common:back')}\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div className=\"flex items-center gap-3\">\r\n {renderLucideIcon(applicationDetail.application.icon, 'w-5 h-5')}\r\n <div className=\"flex-1\">\r\n <h1 className=\"text-xl sm:text-2xl font-bold text-[var(--text-primary)]\">\r\n {applicationDetail.application.label}\r\n </h1>\r\n {applicationDetail.application.description && (\r\n <p className=\"text-sm sm:text-base text-[var(--text-secondary)]\">\r\n {applicationDetail.application.description}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2 ml-auto\">\r\n <span\r\n className={`px-3 py-1 rounded-[var(--radius-badge)] text-sm font-medium ${\r\n applicationDetail.application.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)] border border-[var(--success-border)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)] border border-[var(--border-color)]'\r\n }`}\r\n >\r\n {applicationDetail.application.isActive ? t('common:active') : t('common:inactive')}\r\n </span>\r\n {canToggleStatus && (\r\n <button\r\n onClick={() => applicationDetail.handleToggleStatus(appId!)}\r\n disabled={applicationDetail.saving}\r\n className={`inline-flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium transition-colors ${\r\n applicationDetail.application.isActive\r\n ? 'bg-[var(--error-bg)] text-[var(--error-text)] border border-[var(--error-border)] hover:bg-[var(--error-border)]'\r\n : 'bg-[var(--success-bg)] text-[var(--success-text)] border border-[var(--success-border)] hover:bg-[var(--success-border)]'\r\n } disabled:opacity-50`}\r\n >\r\n {applicationDetail.saving && (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n )}\r\n {!applicationDetail.saving && applicationDetail.application.isActive && (\r\n <PowerOff className=\"w-4 h-4\" />\r\n )}\r\n {!applicationDetail.saving && !applicationDetail.application.isActive && (\r\n <Power className=\"w-4 h-4\" />\r\n )}\r\n {applicationDetail.application.isActive\r\n ? t('applicationDetail.deactivate')\r\n : t('applicationDetail.activate')}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Alerts */}\r\n {applicationDetail.error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)] text-[var(--error-text)] flex items-center gap-2\">\r\n <AlertTriangle className=\"w-5 h-5 flex-shrink-0\" />\r\n {applicationDetail.error}\r\n </div>\r\n )}\r\n {applicationDetail.success && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)] text-[var(--success-text)] flex items-center gap-2\">\r\n <CheckCircle className=\"w-5 h-5 flex-shrink-0\" />\r\n {applicationDetail.success}\r\n </div>\r\n )}\r\n\r\n {/* Stats cards */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-4\">\r\n {statsCards.map((stat) => (\r\n <div\r\n key={stat.label}\r\n className={`rounded-[var(--radius-card)] p-4 text-center border ${colorClasses[stat.color]}`}\r\n >\r\n <div className=\"text-2xl font-bold\">{stat.value}</div>\r\n <div className=\"text-sm opacity-80\">{stat.label}</div>\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Tabs */}\r\n <div\r\n className=\"flex gap-1 p-1 overflow-x-auto bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)]\"\r\n role=\"tablist\"\r\n aria-label={t('applicationDetail.tabs.label', 'Application tabs')}\r\n >\r\n {tabs.map((tab) => {\r\n const Icon = tab.icon;\r\n const isActive = activeTab === tab.id;\r\n return (\r\n <button\r\n key={tab.id}\r\n role=\"tab\"\r\n aria-selected={isActive}\r\n aria-controls={`tabpanel-${tab.id}`}\r\n onClick={() => setActiveTab(tab.id)}\r\n className={`flex items-center gap-2 px-4 py-2 whitespace-nowrap rounded-[var(--radius-button)] font-medium transition-colors ${\r\n isActive\r\n ? 'bg-[var(--color-accent-600)] text-white'\r\n : 'text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <Icon className=\"w-4 h-4\" />\r\n {tab.label}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n\r\n {/* Tab content */}\r\n <div\r\n className=\"bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-4 sm:p-6\"\r\n role=\"tabpanel\"\r\n id={`tabpanel-${activeTab}`}\r\n aria-labelledby={activeTab}\r\n >\r\n {/* Info Tab */}\r\n {activeTab === 'info' && (\r\n <ApplicationInfoTab\r\n formData={applicationDetail.formData}\r\n setFormData={applicationDetail.setFormData}\r\n application={applicationDetail.application!}\r\n saving={applicationDetail.saving}\r\n onSubmit={() =>\r\n applicationDetail.handleSaveInfo(appId!, applicationDetail.formData)\r\n }\r\n />\r\n )}\r\n\r\n {/* Modules Tab */}\r\n {activeTab === 'modules' && (\r\n <ApplicationModulesTab\r\n application={applicationDetail.application!}\r\n expandedModules={applicationModules.expandedModules}\r\n moduleSections={applicationModules.moduleSections}\r\n loadingSections={applicationModules.loadingSections}\r\n reordering={applicationModules.reordering}\r\n editingModule={applicationModules.editingModule}\r\n moduleFormData={applicationModules.moduleFormData}\r\n showModuleForm={applicationModules.showModuleForm}\r\n saving={applicationDetail.saving}\r\n onToggleExpand={(moduleId) =>\r\n applicationModules.toggleModuleExpand(appId!, moduleId)\r\n }\r\n onStartEdit={applicationModules.startEditModule}\r\n onSaveModule={async () => {\r\n await applicationModules.handleSaveModule(\r\n appId!,\r\n applicationModules.editingModule!.id,\r\n applicationModules.moduleFormData\r\n );\r\n applicationDetail.setSuccess(t('applicationDetail.success.moduleUpdated'));\r\n await applicationDetail.loadApplication(appId!);\r\n }}\r\n onCancelEdit={() => {\r\n applicationModules.setShowModuleForm(false);\r\n applicationModules.setEditingModule(null);\r\n }}\r\n onModulesReorder={async (modules) => {\r\n await applicationModules.handleModulesReorder(appId!, modules);\r\n await applicationDetail.loadApplication(appId!);\r\n }}\r\n onSectionsReorder={(moduleId, sections) =>\r\n applicationModules.handleSectionsReorder(appId!, moduleId, sections)\r\n }\r\n setModuleFormData={(value) => applicationModules.setModuleFormData(typeof value === 'function' ? value(applicationModules.moduleFormData) : value)}\r\n />\r\n )}\r\n\r\n {/* Permissions Tab */}\r\n {activeTab === 'permissions' && (\r\n <ApplicationPermissionsTab\r\n application={applicationDetail.application!}\r\n permissions={applicationPermissions.permissions}\r\n permissionsWithRoles={applicationPermissions.permissionsWithRoles}\r\n />\r\n )}\r\n\r\n {/* Roles Tab */}\r\n {activeTab === 'roles' && (\r\n <ApplicationAccessTab\r\n rolesWithAppAccess={applicationPermissions.rolesWithAppAccess}\r\n onNavigateToRole={(roleId) =>\r\n navigate(`/administration/permissions/roles/${roleId}`)\r\n }\r\n />\r\n )}\r\n\r\n {/* Publication Tab */}\r\n {activeTab === 'publication' && (\r\n <ApplicationPublicationTab\r\n application={applicationDetail.application!}\r\n assignedTenants={filteredAssignedTenants}\r\n availableTenants={filteredAvailableTenants}\r\n showAssignModal={applicationPublication.showAssignModal}\r\n selectedTenantIds={applicationPublication.selectedTenantIds}\r\n selectedAccessLevel={applicationPublication.selectedAccessLevel}\r\n tenantSearch={applicationPublication.tenantSearch}\r\n showCustomizeDrawer={applicationPublication.showCustomizeDrawer}\r\n customizingTenant={applicationPublication.customizingTenant}\r\n bulkAccessMode={applicationPublication.bulkAccessMode}\r\n bulkModules={applicationPublication.bulkModules}\r\n bulkExpandedModules={applicationPublication.bulkExpandedModules}\r\n loadingBulkModules={applicationPublication.loadingBulkModules}\r\n isUpdateMode={applicationPublication.isUpdateMode}\r\n updateMergeMode={applicationPublication.updateMergeMode}\r\n showConfirmRemovalDialog={applicationPublication.showConfirmRemovalDialog}\r\n pendingRemovals={applicationPublication.pendingRemovals}\r\n saving={applicationDetail.saving}\r\n includePersonalTenants={applicationPublication.includePersonalTenants}\r\n isInDefaultPersonalTemplate={applicationPublication.isInDefaultPersonalTemplate}\r\n onAddTenant={() => {\r\n applicationPublication.loadPublicationData(appId!);\r\n applicationPublication.setShowAssignModal(true);\r\n }}\r\n onRemoveTenant={(tenantId) =>\r\n applicationPublication.handleRemoveTenant(appId!, tenantId, () => {\r\n applicationDetail.setSuccess(t('applicationDetail.publication.success.removed'));\r\n })\r\n }\r\n onUpdateAccessLevel={(tenantId, accessLevel) =>\r\n applicationPublication.handleUpdateAccessLevel(appId!, tenantId, accessLevel, () => {\r\n applicationDetail.setSuccess(t('applicationDetail.publication.success.updated'));\r\n })\r\n }\r\n onCustomizeTenant={(tenant) => {\r\n applicationPublication.setCustomizingTenant(tenant);\r\n applicationPublication.setShowCustomizeDrawer(true);\r\n }}\r\n onCloseCustomizeDrawer={() => {\r\n applicationPublication.setShowCustomizeDrawer(false);\r\n applicationPublication.setCustomizingTenant(null);\r\n applicationPublication.loadPublicationData(appId!);\r\n }}\r\n onAssignTenants={() =>\r\n applicationPublication.handleAssignTenants(appId!, () => {\r\n applicationDetail.setSuccess(t('applicationDetail.publication.success.assigned'));\r\n applicationPublication.loadPublicationData(appId!);\r\n })\r\n }\r\n onUpdateTenants={() =>\r\n applicationPublication.handleUpdateTenants(appId!, () => {\r\n applicationDetail.setSuccess(t('applicationDetail.publication.success.updated'));\r\n applicationPublication.loadPublicationData(appId!);\r\n })\r\n }\r\n onExecuteUpdateTenants={() =>\r\n applicationPublication.executeUpdateTenants(appId!, () => {\r\n applicationDetail.setSuccess(t('applicationDetail.publication.success.updated'));\r\n applicationPublication.loadPublicationData(appId!);\r\n })\r\n }\r\n onCancelRemovalDialog={() => {\r\n applicationPublication.setShowConfirmRemovalDialog(false);\r\n applicationPublication.setUpdateMergeMode('merge');\r\n }}\r\n setShowAssignModal={applicationPublication.setShowAssignModal}\r\n setSelectedTenantIds={applicationPublication.setSelectedTenantIds}\r\n setSelectedAccessLevel={applicationPublication.setSelectedAccessLevel}\r\n setTenantSearch={applicationPublication.setTenantSearch}\r\n setBulkAccessMode={applicationPublication.setBulkAccessMode}\r\n setIsUpdateMode={applicationPublication.setIsUpdateMode}\r\n setUpdateMergeMode={applicationPublication.setUpdateMergeMode}\r\n onToggleTenantSelection={applicationPublication.toggleTenantSelection}\r\n onSelectAllFilteredTenants={applicationPublication.selectAllFilteredTenants}\r\n onClearTenantSelection={applicationPublication.clearTenantSelection}\r\n setIncludePersonalTenants={applicationPublication.setIncludePersonalTenants}\r\n onLoadBulkModules={() => applicationPublication.loadBulkModules(appId!)}\r\n onToggleBulkModuleExpand={applicationPublication.toggleBulkModuleExpand}\r\n onToggleBulkModule={applicationPublication.toggleBulkModule}\r\n onToggleBulkSection={applicationPublication.toggleBulkSection}\r\n onGetBulkModuleCheckState={applicationPublication.getBulkModuleCheckState}\r\n onGetBulkStats={applicationPublication.getBulkStats}\r\n onSelectAllBulkModules={applicationPublication.selectAllBulkModules}\r\n onClearBulkModules={applicationPublication.clearBulkModules}\r\n appId={appId!}\r\n />\r\n )}\r\n\r\n {/* Access Requests Tab */}\r\n {activeTab === 'requests' && (\r\n <AccessRequestsListTab\r\n requests={accessRequests.requests}\r\n loading={accessRequests.loading}\r\n onReload={() => accessRequests.loadRequests()}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n"],"names":["renderLucideIcon","icon","className","IconComponent","LucideIcons","jsx","useApplicationDetail","useTranslation","application","setApplication","useState","loading","setLoading","saving","setSaving","error","setError","success","setSuccess","formData","setFormData","loadApplication","useCallback","appId","data","adminApi","err","handleSaveInfo","updateData","handleToggleStatus","useApplicationModules","expandedModules","setExpandedModules","moduleSections","setModuleSections","loadingSections","setLoadingSections","reordering","setReordering","editingModule","setEditingModule","moduleFormData","setModuleFormData","showModuleForm","setShowModuleForm","toggleModuleExpand","moduleId","isExpanding","prev","newSet","sections","handleSaveModule","resetModuleForm","handleModulesReorder","reorderedModules","newModules","m","index","handleSectionsReorder","reorderedSections","newSections","s","reloadErr","startEditModule","module","moduleCount","getPermissionWithRoles","perm","matrixRoles","allRoles","rolesWithPerm","mr","r","useApplicationPermissions","roles","setRoles","permissions","setPermissions","permissionsWithRoles","setPermissionsWithRoles","loadPermissionsData","matrix","appPermissionPrefix","appPermissions","p","permWithRoles","loadRolesData","rolesWithAppAccess","useMemo","roleAccessMap","permission","permRoles","role","a","b","updateModuleAssignment","newIsAssigned","updateSectionAssignment","sectionId","allSectionsAssigned","assignAllSections","clearAllSections","useApplicationPublication","assignedTenants","setAssignedTenants","availableTenants","setAvailableTenants","showAssignModal","setShowAssignModal","selectedTenantIds","setSelectedTenantIds","selectedAccessLevel","setSelectedAccessLevel","tenantSearch","setTenantSearch","showCustomizeDrawer","setShowCustomizeDrawer","customizingTenant","setCustomizingTenant","bulkAccessMode","setBulkAccessMode","bulkModules","setBulkModules","bulkExpandedModules","setBulkExpandedModules","loadingBulkModules","setLoadingBulkModules","isUpdateMode","setIsUpdateMode","updateMergeMode","setUpdateMergeMode","showConfirmRemovalDialog","setShowConfirmRemovalDialog","pendingRemovals","setPendingRemovals","includePersonalTenants","setIncludePersonalTenants","isInDefaultPersonalTemplate","setIsInDefaultPersonalTemplate","loadPublicationData","assigned","availableResponse","loadBulkModules","appModules","moduleNodes","appModule","sectionNodes","section","toggleBulkModuleExpand","toggleBulkModule","toggleBulkSection","getBulkModuleCheckState","assignedCount","getBulkStats","totalModules","assignedModules","totalSections","sum","assignedSections","selectAllBulkModules","clearBulkModules","toggleTenantSelection","tenantId","id","selectAllFilteredTenants","filteredIds","t","matchesSearch","matchesType","clearTenantSelection","executeUpdateTenants","onSuccess","request","handleAssignTenants","handleUpdateTenants","removedModulesCount","removedSectionsCount","currentModules","currentSections","targetModuleIds","targetSectionIds","handleRemoveTenant","handleUpdateAccessLevel","accessLevel","ApplicationInfoTab","onSubmit","jsxs","e","Loader2","Save","SortableItemWrapper","disabled","children","attributes","listeners","setNodeRef","transform","transition","isDragging","useSortable","style","CSS","dragHandle","GripVertical","SortableList","items","onReorder","renderItem","setActiveId","sensors","useSensors","useSensor","PointerSensor","KeyboardSensor","sortableKeyboardCoordinates","DndContext","closestCenter","event","active","over","oldIndex","item","newIndex","newItems","arrayMove","SortableContext","verticalListSortingStrategy","renderModuleSections","onSectionsReorder","sectionDragHandle","Layers","ApplicationModulesTab","onToggleExpand","onStartEdit","onSaveModule","onCancelEdit","onModulesReorder","ChevronDown","ChevronRight","Edit","ApplicationPermissionsTab","ApplicationAccessTab","onNavigateToRole","rolePermissions","Shield","Eye","getAccessLevelColorClass","getLabelKey","level","useTenantIconForType","getIconForType","useTenantTypeSettings","tenantType","typeInfo","Icon","getLucideIcon","colors","getColorClasses","ApplicationPublicationTab","getTenantIconInfo","Globe","tenant","bgClass","colorClass","statusBgClass","VALID_TABS","ApplicationDetailPage","useParams","navigate","useNavigate","hasPermission","useAuth","currentTenant","isGlobalView","useTenant","canToggleStatus","activeTab","setActiveTab","useTabNavigation","applicationDetail","applicationModules","applicationPermissions","applicationPublication","accessRequests","useAccessRequests","filteredAvailableTenants","filteredAssignedTenants","useEffect","tabs","Settings","Users","Inbox","AlertCircle","permissionsLoaded","publicationLoaded","statsCards","colorClasses","Breadcrumb","ArrowLeft","PowerOff","Power","AlertTriangle","CheckCircle","stat","tab","isActive","modules","value","roleId","AccessRequestsListTab"],"mappings":"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"}
|