@atlashub/smartstack 3.29.0 → 3.31.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-ChykpPZx.js → AgentSkillsPage-CDMhqrhE.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-ChykpPZx.js.map → AgentSkillsPage-CDMhqrhE.js.map} +1 -1
- package/dist/chunks/{AgentSkillsPage-ABpqnnyK.js → AgentSkillsPage-DcvOMm5k.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-ABpqnnyK.js.map → AgentSkillsPage-DcvOMm5k.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-BltzNlXI.js → AgentWorkloadPage-DYBPNzjQ.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-BltzNlXI.js.map → AgentWorkloadPage-DYBPNzjQ.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-BI5QWJyQ.js → AgentWorkloadPage-YpJSDaWc.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-BI5QWJyQ.js.map → AgentWorkloadPage-YpJSDaWc.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-BaheZKBq.js → ApiCatalogDetailPage-9r1axtCg.js} +3 -3
- package/dist/chunks/{ApiCatalogDetailPage-BaheZKBq.js.map → ApiCatalogDetailPage-9r1axtCg.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-CsRxlHwO.js → ApiCatalogDetailPage-TjCQ8_A8.js} +2 -2
- package/dist/chunks/{ApiCatalogDetailPage-CsRxlHwO.js.map → ApiCatalogDetailPage-TjCQ8_A8.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-B0yIz8-U.js → ApiCatalogPage-COxazTnz.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-B0yIz8-U.js.map → ApiCatalogPage-COxazTnz.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-CqmmHpQ4.js → ApiCatalogPage-QRysH0pT.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-CqmmHpQ4.js.map → ApiCatalogPage-QRysH0pT.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage-CdT6KNd7.js → ApplicationDetailPage-Dbx01Ikm.js} +4 -4
- package/dist/chunks/{ApplicationDetailPage-CdT6KNd7.js.map → ApplicationDetailPage-Dbx01Ikm.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage-CngD5JSN.js → ApplicationDetailPage-jSHy3MPz.js} +2 -2
- package/dist/chunks/{ApplicationDetailPage-CngD5JSN.js.map → ApplicationDetailPage-jSHy3MPz.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-1V4iQ6eY.js → ApplicationsDashboardPage-CclKc0wI.js} +3 -3
- package/dist/chunks/{ApplicationsDashboardPage-1V4iQ6eY.js.map → ApplicationsDashboardPage-CclKc0wI.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-DHmnjk2O.js → ApplicationsDashboardPage-CxWmOc1x.js} +2 -2
- package/dist/chunks/{ApplicationsDashboardPage-DHmnjk2O.js.map → ApplicationsDashboardPage-CxWmOc1x.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-CiMJFlB_.js → ApplicationsGridPage-BJXWXwyI.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-CiMJFlB_.js.map → ApplicationsGridPage-BJXWXwyI.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-Bo3NDnBF.js → ApplicationsGridPage-D2l8cM3o.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-Bo3NDnBF.js.map → ApplicationsGridPage-D2l8cM3o.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-L2_S23aN.js → ApplicationsListPage-CMosl3my.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-L2_S23aN.js.map → ApplicationsListPage-CMosl3my.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-De8jQ1Cm.js → ApplicationsListPage-Dc6NGQ61.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-De8jQ1Cm.js.map → ApplicationsListPage-Dc6NGQ61.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-DBq7_Sm8.js → ApplicationsPage-DH7tpMlF.js} +2 -2
- package/dist/chunks/{ApplicationsPage-DBq7_Sm8.js.map → ApplicationsPage-DH7tpMlF.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-CiNI-b0R.js → ApplicationsPage-DI-iMqoJ.js} +4 -4
- package/dist/chunks/{ApplicationsPage-CiNI-b0R.js.map → ApplicationsPage-DI-iMqoJ.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-C8rfUsMB.js → AssignmentRulesPage-B5UbujbZ.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-C8rfUsMB.js.map → AssignmentRulesPage-B5UbujbZ.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-DFsO4ZES.js → AssignmentRulesPage-E79QBSLb.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-DFsO4ZES.js.map → AssignmentRulesPage-E79QBSLb.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-COCikISI.js → AssignmentsPage-CDFaL1gT.js} +2 -2
- package/dist/chunks/{AssignmentsPage-COCikISI.js.map → AssignmentsPage-CDFaL1gT.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-78C_EBsw.js → AssignmentsPage-CPeKJjyK.js} +2 -2
- package/dist/chunks/{AssignmentsPage-78C_EBsw.js.map → AssignmentsPage-CPeKJjyK.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-DqT6ueVi.js → AuthCallbackPage-BZ3Ocos5.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-DqT6ueVi.js.map → AuthCallbackPage-BZ3Ocos5.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-BF4bkTnR.js → AuthCallbackPage-Bml48QpH.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-BF4bkTnR.js.map → AuthCallbackPage-Bml48QpH.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-DJy4idrf.js → ConfirmEmailPage-DP1XPaKK.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-DJy4idrf.js.map → ConfirmEmailPage-DP1XPaKK.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-Bh_K5qJn.js → ConfirmEmailPage-DyzslZ06.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-Bh_K5qJn.js.map → ConfirmEmailPage-DyzslZ06.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-pL7jbG9o.js → CreateSupportTicketPage-Bz2KrMik.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-pL7jbG9o.js.map → CreateSupportTicketPage-Bz2KrMik.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-AVTwXbJd.js → CreateSupportTicketPage-hKjKM0Bh.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-AVTwXbJd.js.map → CreateSupportTicketPage-hKjKM0Bh.js.map} +1 -1
- package/dist/chunks/{DashboardPage-DdQlTLw0.js → DashboardPage-B4nAd8Tj.js} +2 -2
- package/dist/chunks/{DashboardPage-DdQlTLw0.js.map → DashboardPage-B4nAd8Tj.js.map} +1 -1
- package/dist/chunks/{DashboardPage-DOitDfGV.js → DashboardPage-C9qgPBS-.js} +3 -3
- package/dist/chunks/{DashboardPage-DOitDfGV.js.map → DashboardPage-C9qgPBS-.js.map} +1 -1
- package/dist/chunks/{DashboardPage-C55mIiB6.js → DashboardPage-CjbNGMo1.js} +3 -3
- package/dist/chunks/{DashboardPage-C55mIiB6.js.map → DashboardPage-CjbNGMo1.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CcCnUl7s.js → DashboardPage-rN7IFlTR.js} +2 -2
- package/dist/chunks/{DashboardPage-CcCnUl7s.js.map → DashboardPage-rN7IFlTR.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-DRr55328.js → EscalationConfigPage-CGv2L62M.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-DRr55328.js.map → EscalationConfigPage-CGv2L62M.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-DNnZftCH.js → EscalationConfigPage-DpYDmsgw.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-DNnZftCH.js.map → EscalationConfigPage-DpYDmsgw.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-1SCOPIqK.js → ForceChangePasswordPage-CLI_fpF4.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-1SCOPIqK.js.map → ForceChangePasswordPage-CLI_fpF4.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-DBeG_HRO.js → ForceChangePasswordPage-Db6sOrZN.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-DBeG_HRO.js.map → ForceChangePasswordPage-Db6sOrZN.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-Dlb6wKfC.js → ForgotPasswordPage-BhMz2B6A.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-Dlb6wKfC.js.map → ForgotPasswordPage-BhMz2B6A.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-DffYfXva.js → ForgotPasswordPage-D06arMXO.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-DffYfXva.js.map → ForgotPasswordPage-D06arMXO.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-C9nRbeHI.js → GroupDetailPage-BCM8KBCd.js} +5 -5
- package/dist/chunks/{GroupDetailPage-C9nRbeHI.js.map → GroupDetailPage-BCM8KBCd.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-CPPUWzXf.js → GroupDetailPage-CGMV3bWt.js} +2 -2
- package/dist/chunks/{GroupDetailPage-CPPUWzXf.js.map → GroupDetailPage-CGMV3bWt.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-BAX0xwJX.js → MyAccessRequestsPage-BBrwEomx.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-BAX0xwJX.js.map → MyAccessRequestsPage-BBrwEomx.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-BMY1V631.js → MyAccessRequestsPage-CrlWe3gd.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-BMY1V631.js.map → MyAccessRequestsPage-CrlWe3gd.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-BHtp67SD.js → MyTenantsPage-BOV34_rJ.js} +3 -3
- package/dist/chunks/{MyTenantsPage-BHtp67SD.js.map → MyTenantsPage-BOV34_rJ.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-Bbn4HxN2.js → MyTenantsPage-CK4-klmd.js} +2 -2
- package/dist/chunks/{MyTenantsPage-Bbn4HxN2.js.map → MyTenantsPage-CK4-klmd.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-D9IGVofj.js → MyTicketsPage-CFZ1G4dG.js} +2 -2
- package/dist/chunks/{MyTicketsPage-D9IGVofj.js.map → MyTicketsPage-CFZ1G4dG.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-BvZeiTXu.js → MyTicketsPage-DuhpwhZx.js} +2 -2
- package/dist/chunks/{MyTicketsPage-BvZeiTXu.js.map → MyTicketsPage-DuhpwhZx.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-ChtMK1yt.js → NavigationAppsPage-BnNQRfBP.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-ChtMK1yt.js.map → NavigationAppsPage-BnNQRfBP.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-DiPBCsAF.js → NavigationAppsPage-DdJxEoTZ.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-DiPBCsAF.js.map → NavigationAppsPage-DdJxEoTZ.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-BCnL9oPb.js → NotificationsPage-BllOlagk.js} +2 -2
- package/dist/chunks/{NotificationsPage-BCnL9oPb.js.map → NotificationsPage-BllOlagk.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-BxCiGzHk.js → NotificationsPage-D1T_ozHl.js} +2 -2
- package/dist/chunks/{NotificationsPage-BxCiGzHk.js.map → NotificationsPage-D1T_ozHl.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-CV_cxq7k.js → OnboardingWizardPage-CioLaCYz.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-CV_cxq7k.js.map → OnboardingWizardPage-CioLaCYz.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-Du-tQ2ag.js → OnboardingWizardPage-CrAQt7qL.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-Du-tQ2ag.js.map → OnboardingWizardPage-CrAQt7qL.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-C1iuWv0G.js → PermissionDetailPage-BIG78-1-.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-C1iuWv0G.js.map → PermissionDetailPage-BIG78-1-.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-Ds4Jt1os.js → PermissionDetailPage-CvPqugYu.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-Ds4Jt1os.js.map → PermissionDetailPage-CvPqugYu.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-BGI2nxCn.js → PermissionsPage-CDSuc8vw.js} +2 -2
- package/dist/chunks/{PermissionsPage-BGI2nxCn.js.map → PermissionsPage-CDSuc8vw.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-sauv7ct1.js → PermissionsPage-XaOrGrPZ.js} +2 -2
- package/dist/chunks/{PermissionsPage-sauv7ct1.js.map → PermissionsPage-XaOrGrPZ.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-CQWEcghD.js → PortalDashboardPage-BsWVXkMe.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-CQWEcghD.js.map → PortalDashboardPage-BsWVXkMe.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-2kCbJw9w.js → PortalDashboardPage-oSD7oQhJ.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-2kCbJw9w.js.map → PortalDashboardPage-oSD7oQhJ.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-Bu4gaDRb.js → PreferencesPage-DD0_XWdT.js} +2 -2
- package/dist/chunks/{PreferencesPage-Bu4gaDRb.js.map → PreferencesPage-DD0_XWdT.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-Dbg0bEYD.js → PreferencesPage-ca2BOdoH.js} +2 -2
- package/dist/chunks/{PreferencesPage-Dbg0bEYD.js.map → PreferencesPage-ca2BOdoH.js.map} +1 -1
- package/dist/chunks/{ProfilePage-DfiBhOUt.js → ProfilePage-Bex_JN5N.js} +2 -2
- package/dist/chunks/{ProfilePage-DfiBhOUt.js.map → ProfilePage-Bex_JN5N.js.map} +1 -1
- package/dist/chunks/{ProfilePage-C5QS7tsh.js → ProfilePage-C8tUIOnb.js} +2 -2
- package/dist/chunks/{ProfilePage-C5QS7tsh.js.map → ProfilePage-C8tUIOnb.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-C0RgHbJb.js → ReferencesManagementPage-B-FXS2ln.js} +2 -2
- package/dist/chunks/{ReferencesManagementPage-C0RgHbJb.js.map → ReferencesManagementPage-B-FXS2ln.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-Bs0mapj8.js → ReferencesManagementPage-C8KZprkI.js} +3 -3
- package/dist/chunks/{ReferencesManagementPage-Bs0mapj8.js.map → ReferencesManagementPage-C8KZprkI.js.map} +1 -1
- package/dist/chunks/{RegisterPage-DoeIiJt0.js → RegisterPage-BYt__zKJ.js} +2 -2
- package/dist/chunks/{RegisterPage-DoeIiJt0.js.map → RegisterPage-BYt__zKJ.js.map} +1 -1
- package/dist/chunks/{RegisterPage-DS1chV_A.js → RegisterPage-MWcVu-LY.js} +2 -2
- package/dist/chunks/{RegisterPage-DS1chV_A.js.map → RegisterPage-MWcVu-LY.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-3KEk3zj5.js → ResetPasswordPage-DaJiMj5Z.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-3KEk3zj5.js.map → ResetPasswordPage-DaJiMj5Z.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-C_VQSFB5.js → ResetPasswordPage-rCLUIj_T.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-C_VQSFB5.js.map → ResetPasswordPage-rCLUIj_T.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-S6URD--N.js → ResolutionModal-DeuPnLWg.js} +2 -2
- package/dist/chunks/{ResolutionModal-S6URD--N.js.map → ResolutionModal-DeuPnLWg.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-BzI1x79r.js → ResolutionModal-j7Rp6apG.js} +2 -2
- package/dist/chunks/{ResolutionModal-BzI1x79r.js.map → ResolutionModal-j7Rp6apG.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-SXK9cq_3.js → RoleDetailPage-CLtZWX17.js} +3 -3
- package/dist/chunks/{RoleDetailPage-SXK9cq_3.js.map → RoleDetailPage-CLtZWX17.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-DvEEWPKr.js → RoleDetailPage-TGyGmLMM.js} +2 -2
- package/dist/chunks/{RoleDetailPage-DvEEWPKr.js.map → RoleDetailPage-TGyGmLMM.js.map} +1 -1
- package/dist/chunks/{RolesPage-C5gYJxAl.js → RolesPage-C0c5G9e7.js} +2 -2
- package/dist/chunks/{RolesPage-C5gYJxAl.js.map → RolesPage-C0c5G9e7.js.map} +1 -1
- package/dist/chunks/{RolesPage-B75lCugt.js → RolesPage-Dm03fBBf.js} +2 -2
- package/dist/chunks/{RolesPage-B75lCugt.js.map → RolesPage-Dm03fBBf.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-BqXHATb6.js → SlaConfigPage-B4WDzEKi.js} +2 -2
- package/dist/chunks/{SlaConfigPage-BqXHATb6.js.map → SlaConfigPage-B4WDzEKi.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-DZ4P1FFW.js → SlaConfigPage-Cwo9NwxH.js} +2 -2
- package/dist/chunks/{SlaConfigPage-DZ4P1FFW.js.map → SlaConfigPage-Cwo9NwxH.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-DW7KJjYK.js → SupportPermissionsPage-CL12dFy-.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-DW7KJjYK.js.map → SupportPermissionsPage-CL12dFy-.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-B4xy_pCQ.js → SupportPermissionsPage-CneIhl30.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-B4xy_pCQ.js.map → SupportPermissionsPage-CneIhl30.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-m5-sLJ7F.js → TemplatesPage-DStKmwHT.js} +2 -2
- package/dist/chunks/{TemplatesPage-m5-sLJ7F.js.map → TemplatesPage-DStKmwHT.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-DZa0PQTE.js → TemplatesPage-X4Rrhs9p.js} +2 -2
- package/dist/chunks/{TemplatesPage-DZa0PQTE.js.map → TemplatesPage-X4Rrhs9p.js.map} +1 -1
- package/dist/chunks/{TenantCard-CqfifMrM.js → TenantCard-BUBYWtvR.js} +2 -2
- package/dist/chunks/{TenantCard-CqfifMrM.js.map → TenantCard-BUBYWtvR.js.map} +1 -1
- package/dist/chunks/{TenantCard-BJQi7Oew.js → TenantCard-CAgiB-NG.js} +2 -2
- package/dist/chunks/{TenantCard-BJQi7Oew.js.map → TenantCard-CAgiB-NG.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-CdiYJvuH.js → TenantScopeSelector-B9vtpIZx.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-CdiYJvuH.js.map → TenantScopeSelector-B9vtpIZx.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-Cl5DD318.js → TenantScopeSelector-BAoah-mL.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-Cl5DD318.js.map → TenantScopeSelector-BAoah-mL.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-C1UuMxD8.js → TicketDetailPage-BFcP4X8s.js} +2 -2
- package/dist/chunks/{TicketDetailPage-C1UuMxD8.js.map → TicketDetailPage-BFcP4X8s.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-BOC9rHu3.js → TicketDetailPage-D_Npnt4A.js} +2 -2
- package/dist/chunks/{TicketDetailPage-BOC9rHu3.js.map → TicketDetailPage-D_Npnt4A.js.map} +1 -1
- package/dist/chunks/{TicketsPage-BjaN4Baq.js → TicketsPage-DBP9kalU.js} +2 -2
- package/dist/chunks/{TicketsPage-BjaN4Baq.js.map → TicketsPage-DBP9kalU.js.map} +1 -1
- package/dist/chunks/{TicketsPage-BCgHZA-m.js → TicketsPage-p21DLhUb.js} +2 -2
- package/dist/chunks/{TicketsPage-BCgHZA-m.js.map → TicketsPage-p21DLhUb.js.map} +1 -1
- package/dist/chunks/{UserCreateTicketPage-ChQL1mVY.js → UserCreateTicketPage-DOwShnG8.js} +3 -3
- package/dist/chunks/UserCreateTicketPage-DOwShnG8.js.map +1 -0
- package/dist/chunks/{UserCreateTicketPage-DkjsHeV7.js → UserCreateTicketPage-lvlvp2u6.js} +48 -48
- package/dist/chunks/UserCreateTicketPage-lvlvp2u6.js.map +1 -0
- package/dist/chunks/{UserDashboardPage-81-3GJAQ.js → UserDashboardPage-C_tm7Pld.js} +2 -2
- package/dist/chunks/{UserDashboardPage-81-3GJAQ.js.map → UserDashboardPage-C_tm7Pld.js.map} +1 -1
- package/dist/chunks/{UserDashboardPage-BMYrtF3o.js → UserDashboardPage-Dp6q6FEW.js} +2 -2
- package/dist/chunks/{UserDashboardPage-BMYrtF3o.js.map → UserDashboardPage-Dp6q6FEW.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-D6oCH2eS.js → UserDetailPage-6grZ6gmV.js} +5 -5
- package/dist/chunks/{UserDetailPage-D6oCH2eS.js.map → UserDetailPage-6grZ6gmV.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-BMW8jAWG.js → UserDetailPage-DXLxO7LF.js} +2 -2
- package/dist/chunks/{UserDetailPage-BMW8jAWG.js.map → UserDetailPage-DXLxO7LF.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-ZH2BDWBt.js → UserTicketDetailPage-Ch9IfCPo.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-ZH2BDWBt.js.map → UserTicketDetailPage-Ch9IfCPo.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-Z_myXXJ0.js → UserTicketDetailPage-a4II5VEE.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-Z_myXXJ0.js.map → UserTicketDetailPage-a4II5VEE.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-B8Ka6uRa.js → UsersGroupsPage-B7Er0V4l.js} +3 -3
- package/dist/chunks/{UsersGroupsPage-B8Ka6uRa.js.map → UsersGroupsPage-B7Er0V4l.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-xJmGib8b.js → UsersGroupsPage-BeAv4QfV.js} +2 -2
- package/dist/chunks/{UsersGroupsPage-xJmGib8b.js.map → UsersGroupsPage-BeAv4QfV.js.map} +1 -1
- package/dist/chunks/{UsersPage-CQ38akZ_.js → UsersPage-0M1FLqOe.js} +2 -2
- package/dist/chunks/{UsersPage-CQ38akZ_.js.map → UsersPage-0M1FLqOe.js.map} +1 -1
- package/dist/chunks/{UsersPage-Bd2-vl39.js → UsersPage-ZR9r9vvf.js} +2 -2
- package/dist/chunks/{UsersPage-Bd2-vl39.js.map → UsersPage-ZR9r9vvf.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-DguOx0q0.js → accessRequestsApi-BJH8EE1K.js} +2 -2
- package/dist/chunks/{accessRequestsApi-DguOx0q0.js.map → accessRequestsApi-BJH8EE1K.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-COtWo9kC.js → accessRequestsApi-CBpF5d54.js} +2 -2
- package/dist/chunks/{accessRequestsApi-COtWo9kC.js.map → accessRequestsApi-CBpF5d54.js.map} +1 -1
- package/dist/chunks/{aiApi-CITiWGYX.js → aiApi-CkkWAvNB.js} +2 -2
- package/dist/chunks/{aiApi-CITiWGYX.js.map → aiApi-CkkWAvNB.js.map} +1 -1
- package/dist/chunks/{aiApi-BmZsud6O.js → aiApi-Dl7a2lWz.js} +2 -2
- package/dist/chunks/{aiApi-BmZsud6O.js.map → aiApi-Dl7a2lWz.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-D62lc6z4.js → applicationAnalyticsApi-BwcSE_H1.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-D62lc6z4.js.map → applicationAnalyticsApi-BwcSE_H1.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-BYoEJzSN.js → applicationAnalyticsApi-DKMmDvWk.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-BYoEJzSN.js.map → applicationAnalyticsApi-DKMmDvWk.js.map} +1 -1
- package/dist/chunks/auth-Ca2Rn6on.js +2 -0
- package/dist/chunks/auth-Ca2Rn6on.js.map +1 -0
- package/dist/chunks/auth-ClNTDOqm.js +18 -0
- package/dist/chunks/auth-ClNTDOqm.js.map +1 -0
- package/dist/chunks/auth-DECnMZjF.js +18 -0
- package/dist/chunks/auth-DECnMZjF.js.map +1 -0
- package/dist/chunks/auth-DPvxdqy4.js +18 -0
- package/dist/chunks/auth-DPvxdqy4.js.map +1 -0
- package/dist/chunks/auth-HzvnTaOm.js +2 -0
- package/dist/chunks/auth-HzvnTaOm.js.map +1 -0
- package/dist/chunks/auth-M6aNTKCH.js +2 -0
- package/dist/chunks/auth-M6aNTKCH.js.map +1 -0
- package/dist/chunks/auth-UHnAu6_e.js +2 -0
- package/dist/chunks/auth-UHnAu6_e.js.map +1 -0
- package/dist/chunks/auth-YrujJY7m.js +18 -0
- package/dist/chunks/auth-YrujJY7m.js.map +1 -0
- package/dist/chunks/{groupsApi-3CR-_g5b.js → groupsApi-BzDV3_Jc.js} +2 -2
- package/dist/chunks/{groupsApi-3CR-_g5b.js.map → groupsApi-BzDV3_Jc.js.map} +1 -1
- package/dist/chunks/{groupsApi-BUyBgf_N.js → groupsApi-CQ4vFMdP.js} +2 -2
- package/dist/chunks/{groupsApi-BUyBgf_N.js.map → groupsApi-CQ4vFMdP.js.map} +1 -1
- package/dist/chunks/{index-BIqcvvbh.js → index-BBmMbSZV.js} +9 -8
- package/dist/chunks/index-BBmMbSZV.js.map +1 -0
- package/dist/chunks/{index-_g82N2nb.js → index-BLlESTfA.js} +2 -2
- package/dist/chunks/{index-_g82N2nb.js.map → index-BLlESTfA.js.map} +1 -1
- package/dist/chunks/{index-DEOBhXS_.js → index-BPMjxWVx.js} +2 -2
- package/dist/chunks/{index-DEOBhXS_.js.map → index-BPMjxWVx.js.map} +1 -1
- package/dist/chunks/{index-Czk12A3G.js → index-CEbwdURd.js} +2 -2
- package/dist/chunks/{index-Czk12A3G.js.map → index-CEbwdURd.js.map} +1 -1
- package/dist/chunks/{index-BOKR3bw6.js → index-CUZygY5Q.js} +2 -2
- package/dist/chunks/{index-BOKR3bw6.js.map → index-CUZygY5Q.js.map} +1 -1
- package/dist/chunks/{index-IJR_91Yt.js → index-Ci1SqFiY.js} +2 -2
- package/dist/chunks/{index-IJR_91Yt.js.map → index-Ci1SqFiY.js.map} +1 -1
- package/dist/chunks/{index-Br2wsGE8.js → index-Cib93xtp.js} +2 -2
- package/dist/chunks/{index-Br2wsGE8.js.map → index-Cib93xtp.js.map} +1 -1
- package/dist/chunks/{index-BxHVPJ-j.js → index-CoHIgn5H.js} +2 -2
- package/dist/chunks/{index-BxHVPJ-j.js.map → index-CoHIgn5H.js.map} +1 -1
- package/dist/chunks/{index-DA5VyW0k.js → index-CpY95_ro.js} +2296 -2309
- package/dist/chunks/index-CpY95_ro.js.map +1 -0
- package/dist/chunks/{index-BMsjMCv9.js → index-D-2xSu5W.js} +3 -3
- package/dist/chunks/{index-BMsjMCv9.js.map → index-D-2xSu5W.js.map} +1 -1
- package/dist/chunks/{index-DIQ6Jmmq.js → index-D18t9DhC.js} +4 -4
- package/dist/chunks/{index-DIQ6Jmmq.js.map → index-D18t9DhC.js.map} +1 -1
- package/dist/chunks/index-DK5czlkn.js +48 -0
- package/dist/chunks/index-DK5czlkn.js.map +1 -0
- package/dist/chunks/{index-CxgEV-rT.js → index-DQd324n7.js} +2 -2
- package/dist/chunks/{index-CxgEV-rT.js.map → index-DQd324n7.js.map} +1 -1
- package/dist/chunks/{index-S-X8qFYW.js → index-Dbq-x5H9.js} +2 -2
- package/dist/chunks/{index-S-X8qFYW.js.map → index-Dbq-x5H9.js.map} +1 -1
- package/dist/chunks/{index-CNxx56kE.js → index-Det9dEaQ.js} +2 -2
- package/dist/chunks/{index-CNxx56kE.js.map → index-Det9dEaQ.js.map} +1 -1
- package/dist/chunks/{index-C1w97Ejz.js → index-bgT9XOKZ.js} +2 -2
- package/dist/chunks/{index-C1w97Ejz.js.map → index-bgT9XOKZ.js.map} +1 -1
- package/dist/chunks/index-h7ZrwrQg.js +2 -0
- package/dist/chunks/index-h7ZrwrQg.js.map +1 -0
- package/dist/chunks/{index-Djy4eIbB.js → index-k4USDz2P.js} +2 -2
- package/dist/chunks/{index-Djy4eIbB.js.map → index-k4USDz2P.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-COKA97Ug.js → tenantIconMap-7ihIWxAh.js} +2 -2
- package/dist/chunks/{tenantIconMap-COKA97Ug.js.map → tenantIconMap-7ihIWxAh.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-BuSQUUyZ.js → tenantIconMap-Dk6K-UTE.js} +2 -2
- package/dist/chunks/{tenantIconMap-BuSQUUyZ.js.map → tenantIconMap-Dk6K-UTE.js.map} +1 -1
- package/dist/chunks/{ticketingApi-C6EbupqP.js → ticketingApi-BCMKkzlv.js} +2 -2
- package/dist/chunks/{ticketingApi-C6EbupqP.js.map → ticketingApi-BCMKkzlv.js.map} +1 -1
- package/dist/chunks/{ticketingApi-DbREwHez.js → ticketingApi-Dwn7pl5z.js} +2 -2
- package/dist/chunks/{ticketingApi-DbREwHez.js.map → ticketingApi-Dwn7pl5z.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-vucIb3_w.js → useAccessRequests-Du7CvowE.js} +3 -3
- package/dist/chunks/{useAccessRequests-vucIb3_w.js.map → useAccessRequests-Du7CvowE.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-C0dY6y-4.js → useAccessRequests-gJ7yhWyi.js} +2 -2
- package/dist/chunks/{useAccessRequests-C0dY6y-4.js.map → useAccessRequests-gJ7yhWyi.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-Cj0nkesW.js → useUserAccessRequests-5wWea2Jg.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-Cj0nkesW.js.map → useUserAccessRequests-5wWea2Jg.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-BBcw1Rk9.js → useUserAccessRequests-Bk_v8egy.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-BBcw1Rk9.js.map → useUserAccessRequests-Bk_v8egy.js.map} +1 -1
- package/dist/components/routing/ProtectedRoute.d.ts.map +1 -1
- package/dist/contexts/AuthContext.d.ts.map +1 -1
- package/dist/pages/LoginPage.d.ts.map +1 -1
- package/dist/pages/platform/administration/tenants/TenantDetailPage.d.ts.map +1 -1
- package/dist/pages/platform/support/UserCreateTicketPage.d.ts.map +1 -1
- package/dist/services/api/apiClient.d.ts.map +1 -1
- package/dist/services/support/ticketDraftService.d.ts.map +1 -1
- package/dist/smartstack.cjs +1 -1
- package/dist/smartstack.js +6 -6
- package/dist/utils/permissions.generated.d.ts +288 -0
- package/dist/utils/permissions.generated.d.ts.map +1 -0
- package/dist/utils/uuid.d.ts +6 -0
- package/dist/utils/uuid.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/chunks/UserCreateTicketPage-ChQL1mVY.js.map +0 -1
- package/dist/chunks/UserCreateTicketPage-DkjsHeV7.js.map +0 -1
- package/dist/chunks/auth-B-hELPDB.js +0 -2
- package/dist/chunks/auth-B-hELPDB.js.map +0 -1
- package/dist/chunks/auth-BYaMuq7D.js +0 -16
- package/dist/chunks/auth-BYaMuq7D.js.map +0 -1
- package/dist/chunks/auth-C5zpZ9k7.js +0 -2
- package/dist/chunks/auth-C5zpZ9k7.js.map +0 -1
- package/dist/chunks/auth-CDpRMVv1.js +0 -16
- package/dist/chunks/auth-CDpRMVv1.js.map +0 -1
- package/dist/chunks/auth-CyPkCta2.js +0 -2
- package/dist/chunks/auth-CyPkCta2.js.map +0 -1
- package/dist/chunks/auth-DL47kvnl.js +0 -2
- package/dist/chunks/auth-DL47kvnl.js.map +0 -1
- package/dist/chunks/auth-Diiv90i1.js +0 -16
- package/dist/chunks/auth-Diiv90i1.js.map +0 -1
- package/dist/chunks/auth-rog9MvUr.js +0 -16
- package/dist/chunks/auth-rog9MvUr.js.map +0 -1
- package/dist/chunks/index-BIqcvvbh.js.map +0 -1
- package/dist/chunks/index-DA5VyW0k.js.map +0 -1
- package/dist/chunks/index-Dht6EQW1.js +0 -2
- package/dist/chunks/index-Dht6EQW1.js.map +0 -1
- package/dist/chunks/index-vXiLh35n.js +0 -48
- package/dist/chunks/index-vXiLh35n.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RolesPage-B75lCugt.js","sources":["../../src/pages/platform/administration/permissions/RolesPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback, useMemo } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Plus, Search, Edit2, Trash2, MoreHorizontal, X, Loader2, Users, Shield, Eye, Crown, UserCog, PenTool, Sparkles, Filter, AppWindow, ChevronDown } from 'lucide-react';\r\nimport { adminApi, type RoleListDto, type PermissionListDto, type CreateRoleRequest, type UpdateRoleRequest, type RoleCategory } from '@/services/api/adminApi';\r\nimport { Slot } from '@/extensions';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\n\r\nconst ALL_CATEGORIES: RoleCategory[] = ['Global', 'Admin', 'Manager', 'Contributor', 'Viewer', 'Custom'];\r\n\r\nconst CATEGORY_CONFIG: Record<RoleCategory, { icon: React.ElementType; color: string; bgColor: string; borderColor: string }> = {\r\n Global: {\r\n icon: Crown,\r\n color: 'text-purple-600 dark:text-purple-400',\r\n bgColor: 'bg-purple-50 dark:bg-purple-900/20',\r\n borderColor: 'border-purple-200 dark:border-purple-800'\r\n },\r\n Admin: {\r\n icon: Shield,\r\n color: 'text-red-600 dark:text-red-400',\r\n bgColor: 'bg-red-50 dark:bg-red-900/20',\r\n borderColor: 'border-red-200 dark:border-red-800'\r\n },\r\n Manager: {\r\n icon: UserCog,\r\n color: 'text-blue-600 dark:text-blue-400',\r\n bgColor: 'bg-blue-50 dark:bg-blue-900/20',\r\n borderColor: 'border-blue-200 dark:border-blue-800'\r\n },\r\n Contributor: {\r\n icon: PenTool,\r\n color: 'text-green-600 dark:text-green-400',\r\n bgColor: 'bg-green-50 dark:bg-green-900/20',\r\n borderColor: 'border-green-200 dark:border-green-800'\r\n },\r\n Viewer: {\r\n icon: Eye,\r\n color: 'text-gray-600 dark:text-gray-400',\r\n bgColor: 'bg-gray-50 dark:bg-gray-900/20',\r\n borderColor: 'border-gray-200 dark:border-gray-700'\r\n },\r\n Custom: {\r\n icon: Sparkles,\r\n color: 'text-orange-600 dark:text-orange-400',\r\n bgColor: 'bg-orange-50 dark:bg-orange-900/20',\r\n borderColor: 'border-orange-200 dark:border-orange-800'\r\n }\r\n};\r\n\r\nexport function RolesPage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n const [roles, setRoles] = useState<RoleListDto[]>([]);\r\n const [permissions, setPermissions] = useState<PermissionListDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [search, setSearch] = useState('');\r\n const [showModal, setShowModal] = useState(false);\r\n const [editingRole, setEditingRole] = useState<RoleListDto | null>(null);\r\n const [formData, setFormData] = useState<CreateRoleRequest>({\r\n name: '',\r\n description: '',\r\n permissionIds: []\r\n });\r\n const [saving, setSaving] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [menuOpen, setMenuOpen] = useState<string | null>(null);\r\n const [filter, setFilter] = useState<'system' | 'custom' | RoleCategory | null>(null);\r\n const [applicationFilter, setApplicationFilter] = useState<string | null>(null);\r\n const [categoryFilter, setCategoryFilter] = useState<RoleCategory | null>(null);\r\n\r\n const loadRoles = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const result = await adminApi.roles.getAll(search ? { search } : undefined);\r\n setRoles(result);\r\n } catch (err) {\r\n console.error('Failed to load roles:', err);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [search]);\r\n\r\n const loadPermissions = async () => {\r\n try {\r\n const result = await adminApi.permissions.getAll();\r\n setPermissions(result);\r\n } catch (err) {\r\n console.error('Failed to load permissions:', err);\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n loadRoles();\r\n loadPermissions();\r\n }, [loadRoles]);\r\n\r\n const handleSearch = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n loadRoles();\r\n };\r\n\r\n const openCreateModal = () => {\r\n setEditingRole(null);\r\n setFormData({ name: '', description: '', permissionIds: [] });\r\n setError(null);\r\n setShowModal(true);\r\n };\r\n\r\n const openEditModal = async (role: RoleListDto) => {\r\n try {\r\n const detail = await adminApi.roles.getById(role.id);\r\n setEditingRole(role);\r\n setFormData({\r\n name: detail.name,\r\n description: detail.description || '',\r\n parentRoleId: detail.parentRoleId || undefined,\r\n permissionIds: detail.permissions.map(p => p.id)\r\n });\r\n setError(null);\r\n setShowModal(true);\r\n } catch (err) {\r\n console.error('Failed to load role details:', err);\r\n }\r\n };\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setSaving(true);\r\n setError(null);\r\n\r\n try {\r\n if (editingRole) {\r\n const updateData: UpdateRoleRequest = {\r\n name: formData.name,\r\n description: formData.description,\r\n parentRoleId: formData.parentRoleId,\r\n permissionIds: formData.permissionIds\r\n };\r\n await adminApi.roles.update(editingRole.id, updateData);\r\n } else {\r\n await adminApi.roles.create(formData);\r\n }\r\n setShowModal(false);\r\n loadRoles();\r\n } catch (err: unknown) {\r\n const message = err instanceof Error ? err.message : 'An error occurred';\r\n setError(message);\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleDelete = async (role: RoleListDto) => {\r\n if (!confirm(t('roles.confirmDelete', { name: role.name }))) return;\r\n\r\n try {\r\n await adminApi.roles.delete(role.id);\r\n loadRoles();\r\n } catch (err: unknown) {\r\n const message = err instanceof Error ? err.message : 'An error occurred';\r\n alert(message);\r\n }\r\n setMenuOpen(null);\r\n };\r\n\r\n const handlePermissionToggle = (permissionId: string) => {\r\n setFormData(prev => ({\r\n ...prev,\r\n permissionIds: prev.permissionIds?.includes(permissionId)\r\n ? prev.permissionIds.filter(id => id !== permissionId)\r\n : [...(prev.permissionIds || []), permissionId]\r\n }));\r\n };\r\n\r\n const stats = useMemo(() => {\r\n const systemCount = roles.filter(r => r.isSystem).length;\r\n const customCount = roles.filter(r => !r.isSystem).length;\r\n const totalUsers = roles.reduce((sum, r) => sum + r.usersCount, 0);\r\n const categoryCount = roles.reduce((acc, r) => {\r\n acc[r.category] = (acc[r.category] || 0) + 1;\r\n return acc;\r\n }, {} as Record<string, number>);\r\n return { total: roles.length, systemCount, customCount, totalUsers, categoryCount };\r\n }, [roles]);\r\n\r\n const uniqueApplications = useMemo(() => {\r\n const appMap = new Map<string, string>();\r\n roles.forEach(r => {\r\n if (r.applicationId && r.applicationName) {\r\n appMap.set(r.applicationId, r.applicationName);\r\n }\r\n });\r\n return Array.from(appMap.entries())\r\n .map(([id, name]) => ({ id, name }))\r\n .sort((a, b) => a.name.localeCompare(b.name));\r\n }, [roles]);\r\n\r\n const filteredRoles = useMemo(() => {\r\n let result = roles;\r\n // System/custom filter (from stats bar)\r\n if (filter === 'system') result = result.filter(r => r.isSystem);\r\n else if (filter === 'custom') result = result.filter(r => !r.isSystem);\r\n else if (filter) result = result.filter(r => r.category === filter);\r\n // Application filter\r\n if (applicationFilter === '__global__') result = result.filter(r => !r.applicationId);\r\n else if (applicationFilter) result = result.filter(r => r.applicationId === applicationFilter);\r\n // Category filter\r\n if (categoryFilter) result = result.filter(r => r.category === categoryFilter);\r\n return result;\r\n }, [roles, filter, applicationFilter, categoryFilter]);\r\n\r\n const hasActiveFilters = filter !== null || applicationFilter !== null || categoryFilter !== null;\r\n\r\n const clearAllFilters = () => {\r\n setFilter(null);\r\n setApplicationFilter(null);\r\n setCategoryFilter(null);\r\n };\r\n\r\n const toggleFilter = (newFilter: 'system' | 'custom' | RoleCategory) => {\r\n setFilter(prev => prev === newFilter ? null : newFilter);\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('header.title'), href: '/administration' },\r\n { label: t('roles.title') }\r\n ]}\r\n />\r\n\r\n {/* Header with stats */}\r\n <div className=\"flex items-start justify-between\">\r\n <div>\r\n <div className=\"flex items-center gap-3\">\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">{t('roles.title')}</h1>\r\n {!loading && (\r\n <span className=\"px-3 py-1 rounded-full text-sm font-medium bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30 text-[var(--color-accent-700)] dark:text-[var(--color-accent-300)] border border-[var(--color-accent-200)] dark:border-[var(--color-accent-800)]\">\r\n {hasActiveFilters ? `${filteredRoles.length} / ${stats.total}` : stats.total} {t('roles.totalLabel')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-[var(--text-secondary)] mt-1\">{t('roles.list')}</p>\r\n {!loading && stats.total > 0 && (\r\n <div className=\"flex items-center gap-2 mt-3 text-sm\">\r\n <button\r\n onClick={() => toggleFilter('system')}\r\n className={`flex items-center gap-1.5 px-2.5 py-1 rounded-full transition-all ${\r\n filter === 'system'\r\n ? 'bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)] ring-2 ring-[var(--warning-border)]'\r\n : 'text-[var(--text-tertiary)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-secondary)]'\r\n }`}\r\n >\r\n <Shield className=\"w-4 h-4\" />\r\n {stats.systemCount} {t('roles.systemRoles')}\r\n </button>\r\n <button\r\n onClick={() => toggleFilter('custom')}\r\n className={`flex items-center gap-1.5 px-2.5 py-1 rounded-full transition-all ${\r\n filter === 'custom'\r\n ? 'bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30 text-[var(--color-accent-700)] dark:text-[var(--color-accent-300)] border border-[var(--color-accent-200)] dark:border-[var(--color-accent-800)] ring-2 ring-[var(--color-accent-300)] dark:ring-[var(--color-accent-700)]'\r\n : 'text-[var(--text-tertiary)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-secondary)]'\r\n }`}\r\n >\r\n <Sparkles className=\"w-4 h-4\" />\r\n {stats.customCount} {t('roles.customRoles')}\r\n </button>\r\n <span className=\"flex items-center gap-1.5 px-2.5 py-1 text-[var(--text-tertiary)]\">\r\n <Users className=\"w-4 h-4\" />\r\n {stats.totalUsers} {t('roles.totalUsers')}\r\n </span>\r\n {hasActiveFilters && (\r\n <button\r\n onClick={clearAllFilters}\r\n className=\"flex items-center gap-1 px-2 py-1 rounded-full text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-primary)] transition-colors\"\r\n title={t('roles.filters.clearAll')}\r\n >\r\n <X className=\"w-3.5 h-3.5\" />\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <Slot name=\"roles.header.actions\" context={{ roles, reload: loadRoles }} />\r\n <button\r\n onClick={openCreateModal}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white font-medium transition-colors\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('roles.create')}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Search + Filters */}\r\n <div className=\"flex flex-col gap-3\">\r\n <form onSubmit={handleSearch} className=\"flex gap-2\">\r\n <div className=\"relative flex-1 max-w-md\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--text-secondary)]\" />\r\n <input\r\n type=\"text\"\r\n value={search}\r\n onChange={e => setSearch(e.target.value)}\r\n placeholder={t('common.search')}\r\n className=\"w-full pl-10 pr-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n <button\r\n type=\"submit\"\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] text-[var(--text-primary)] font-medium transition-colors\"\r\n >\r\n {t('common.search')}\r\n </button>\r\n </form>\r\n\r\n {/* Filter bar */}\r\n <div className=\"flex flex-wrap items-center gap-3\">\r\n <div className=\"flex items-center gap-1.5 text-sm text-[var(--text-tertiary)]\">\r\n <Filter className=\"w-4 h-4\" />\r\n <span>{t('roles.filters.title')}</span>\r\n </div>\r\n\r\n {/* Application filter */}\r\n <div className=\"relative\">\r\n <select\r\n value={applicationFilter ?? ''}\r\n onChange={e => setApplicationFilter(e.target.value || null)}\r\n className=\"appearance-none pl-3 pr-8 py-1.5 text-sm rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] cursor-pointer\"\r\n >\r\n <option value=\"\">{t('roles.filters.allApplications')}</option>\r\n <option value=\"__global__\">{t('roles.filters.globalRoles')}</option>\r\n {uniqueApplications.map(app => (\r\n <option key={app.id} value={app.id}>{app.name}</option>\r\n ))}\r\n </select>\r\n <ChevronDown className=\"absolute right-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-[var(--text-tertiary)] pointer-events-none\" />\r\n </div>\r\n\r\n {/* Category filter */}\r\n <div className=\"relative\">\r\n <select\r\n value={categoryFilter ?? ''}\r\n onChange={e => setCategoryFilter((e.target.value || null) as RoleCategory | null)}\r\n className=\"appearance-none pl-3 pr-8 py-1.5 text-sm rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] cursor-pointer\"\r\n >\r\n <option value=\"\">{t('roles.filters.allCategories')}</option>\r\n {ALL_CATEGORIES.map(cat => (\r\n <option key={cat} value={cat}>{t(`roles.categories.${cat.toLowerCase()}`)}</option>\r\n ))}\r\n </select>\r\n <ChevronDown className=\"absolute right-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-[var(--text-tertiary)] pointer-events-none\" />\r\n </div>\r\n\r\n {/* Clear all filters */}\r\n {hasActiveFilters && (\r\n <button\r\n onClick={clearAllFilters}\r\n className=\"flex items-center gap-1.5 px-2.5 py-1.5 text-sm rounded-[var(--radius-button)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-primary)] transition-colors\"\r\n >\r\n <X className=\"w-3.5 h-3.5\" />\r\n {t('roles.filters.clearAll')}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Table */}\r\n <div className=\"card overflow-hidden\">\r\n <table className=\"w-full\">\r\n <thead>\r\n <tr className=\"bg-[var(--bg-secondary)]\">\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">{t('roles.columns.name')}</th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden md:table-cell\">{t('roles.columns.category')}</th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">{t('roles.columns.application')}</th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden xl:table-cell\">{t('roles.columns.description')}</th>\r\n <th className=\"text-center px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">{t('roles.columns.usersCount')}</th>\r\n <th className=\"text-center px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">{t('roles.permissions')}</th>\r\n <th className=\"w-24 px-4 py-3\"></th>\r\n </tr>\r\n </thead>\r\n <tbody className=\"divide-y divide-[var(--border-color)]\">\r\n {loading && (\r\n <tr>\r\n <td colSpan={7} className=\"px-6 py-12 text-center\">\r\n <Loader2 className=\"w-6 h-6 animate-spin mx-auto text-[var(--color-accent-500)]\" />\r\n </td>\r\n </tr>\r\n )}\r\n {!loading && filteredRoles.length === 0 && (\r\n <tr>\r\n <td colSpan={7} className=\"px-6 py-12 text-center text-[var(--text-secondary)]\">\r\n {hasActiveFilters ? (\r\n <div className=\"space-y-2\">\r\n <p>{t('roles.noRoles')}</p>\r\n <button\r\n onClick={clearAllFilters}\r\n className=\"text-[var(--color-accent-600)] hover:underline\"\r\n >\r\n {t('roles.filters.clearAll')}\r\n </button>\r\n </div>\r\n ) : t('roles.noRoles')}\r\n </td>\r\n </tr>\r\n )}\r\n {!loading && filteredRoles.length > 0 && (\r\n filteredRoles.map(role => {\r\n const categoryConfig = CATEGORY_CONFIG[role.category] || CATEGORY_CONFIG.Custom;\r\n const CategoryIcon = categoryConfig.icon;\r\n return (\r\n <tr\r\n key={role.id}\r\n onClick={() => navigate(`/administration/permissions/roles/${role.id}`)}\r\n className=\"hover:bg-[var(--bg-hover)] transition-colors cursor-pointer group\"\r\n >\r\n <td className=\"px-4 py-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`w-9 h-9 rounded-full flex items-center justify-center ${categoryConfig.bgColor} ${categoryConfig.borderColor} border`}>\r\n <CategoryIcon className={`w-4 h-4 ${categoryConfig.color}`} />\r\n </div>\r\n <div>\r\n <div className=\"font-medium text-[var(--text-primary)] group-hover:text-[var(--color-accent-600)] transition-colors\">{role.name}</div>\r\n {role.isSystem && (\r\n <span className=\"text-xs text-[var(--warning-text)]\">\r\n {t('roles.system')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3 hidden md:table-cell\">\r\n <button\r\n onClick={(e) => { e.stopPropagation(); setCategoryFilter(prev => prev === role.category ? null : role.category); }}\r\n className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-[var(--radius-badge)] text-xs font-medium border transition-all ${categoryConfig.bgColor} ${categoryConfig.color} ${categoryConfig.borderColor} hover:ring-2 hover:ring-offset-1 ${categoryFilter === role.category ? 'ring-2 ring-offset-1' : ''}`}\r\n >\r\n <CategoryIcon className=\"w-3.5 h-3.5\" />\r\n {t(`roles.categories.${role.category.toLowerCase()}`)}\r\n </button>\r\n </td>\r\n <td className=\"px-4 py-3 hidden lg:table-cell\">\r\n {role.applicationName ? (\r\n <button\r\n onClick={(e) => { e.stopPropagation(); setApplicationFilter(prev => prev === role.applicationId ? null : role.applicationId); }}\r\n className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-[var(--radius-badge)] text-xs font-medium border transition-all bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)] hover:ring-2 hover:ring-offset-1 ${applicationFilter === role.applicationId ? 'ring-2 ring-offset-1' : ''}`}\r\n >\r\n <AppWindow className=\"w-3.5 h-3.5\" />\r\n {role.applicationName}\r\n </button>\r\n ) : (\r\n <span className=\"inline-flex items-center gap-1.5 px-2.5 py-1 text-xs text-[var(--text-tertiary)]\">\r\n <Crown className=\"w-3.5 h-3.5\" />\r\n {t('roles.filters.globalRoles')}\r\n </span>\r\n )}\r\n </td>\r\n <td className=\"px-4 py-3 text-[var(--text-secondary)] max-w-xs truncate hidden xl:table-cell\">{role.description || '-'}</td>\r\n <td className=\"px-4 py-3 text-center\">\r\n <div className=\"inline-flex items-center gap-1.5 text-[var(--text-secondary)]\">\r\n <Users className=\"w-4 h-4\" />\r\n <span className=\"font-medium\">{role.usersCount}</span>\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3 text-center hidden lg:table-cell\">\r\n <div className=\"inline-flex items-center gap-1.5 text-[var(--text-secondary)]\">\r\n <Shield className=\"w-4 h-4\" />\r\n <span className=\"font-medium\">{role.permissionsCount}</span>\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3\">\r\n <div className=\"flex items-center justify-end gap-1\" onClick={e => e.stopPropagation()}>\r\n <button\r\n onClick={() => navigate(`/administration/permissions/roles/${role.id}`)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-tertiary)] transition-colors\"\r\n title={t('users.view')}\r\n >\r\n <Eye className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n </button>\r\n {!role.isSystem && (\r\n <div className=\"relative\">\r\n <button\r\n onClick={() => setMenuOpen(menuOpen === role.id ? null : role.id)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-tertiary)] transition-colors\"\r\n >\r\n <MoreHorizontal className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n </button>\r\n {menuOpen === role.id && (\r\n <div className=\"absolute right-0 top-full mt-1 w-48 py-1 bg-[var(--bg-secondary)] rounded-[var(--radius-menu-item)] border border-[var(--border-color)] shadow-lg z-10\">\r\n <button\r\n onClick={() => { openEditModal(role); setMenuOpen(null); }}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-left text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <Edit2 className=\"w-4 h-4\" />\r\n {t('common.edit')}\r\n </button>\r\n {role.usersCount === 0 && (\r\n <button\r\n onClick={() => handleDelete(role)}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-left text-[var(--error-text)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n {t('common.delete')}\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </td>\r\n </tr>\r\n );\r\n })\r\n )}\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n {/* Modal */}\r\n {showModal && (\r\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-modal)] w-full max-w-lg p-6 m-4 max-h-[90vh] overflow-y-auto\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {editingRole ? t('roles.edit') : t('roles.create')}\r\n </h2>\r\n <button onClick={() => setShowModal(false)} className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)]\">\r\n <X className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"mb-4 p-3 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)] text-[var(--error-text)] text-sm\">\r\n {error}\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roles.form.name')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n required\r\n value={formData.name}\r\n onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roles.form.description')}\r\n </label>\r\n <textarea\r\n value={formData.description}\r\n onChange={e => setFormData(prev => ({ ...prev, description: e.target.value }))}\r\n rows={3}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] resize-none\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('roles.permissions')}\r\n </label>\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto p-2 border border-[var(--border-color)] rounded-[var(--radius-card)]\">\r\n {permissions.map(permission => (\r\n <label key={permission.id} className=\"flex items-start gap-2 cursor-pointer p-2 hover:bg-[var(--bg-hover)] rounded-[var(--radius-button)]\">\r\n <input\r\n type=\"checkbox\"\r\n checked={formData.permissionIds?.includes(permission.id) || false}\r\n onChange={() => handlePermissionToggle(permission.id)}\r\n className=\"mt-0.5 rounded border-[var(--border-color)]\"\r\n />\r\n <div>\r\n <div className=\"text-[var(--text-primary)] font-mono text-sm\">{permission.path}</div>\r\n {permission.description && (\r\n <div className=\"text-xs text-[var(--text-secondary)]\">{permission.description}</div>\r\n )}\r\n </div>\r\n </label>\r\n ))}\r\n {permissions.length === 0 && (\r\n <div className=\"text-center py-4 text-[var(--text-secondary)]\">\r\n {t('roles.noPermissions')}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Extension form fields slot */}\r\n <Slot\r\n name=\"roles.form.fields.after\"\r\n context={{\r\n formData,\r\n onChange: (field: string, value: unknown) => {\r\n setFormData(prev => ({ ...prev, [field]: value }));\r\n },\r\n disabled: saving,\r\n isEditing: !!editingRole,\r\n role: editingRole,\r\n }}\r\n />\r\n\r\n <div className=\"flex justify-end gap-2 pt-4\">\r\n <button\r\n type=\"button\"\r\n onClick={() => setShowModal(false)}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] text-[var(--text-primary)] font-medium transition-colors\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n type=\"submit\"\r\n disabled={saving}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white font-medium transition-colors disabled:opacity-50 flex items-center gap-2\"\r\n >\r\n {saving && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {editingRole ? t('common.save') : t('common.create')}\r\n </button>\r\n </div>\r\n </form>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["ALL_CATEGORIES","CATEGORY_CONFIG","Crown","Shield","UserCog","PenTool","Eye","Sparkles","RolesPage","t","useTranslation","navigate","useNavigate","roles","setRoles","useState","permissions","setPermissions","loading","setLoading","search","setSearch","showModal","setShowModal","editingRole","setEditingRole","formData","setFormData","saving","setSaving","error","setError","menuOpen","setMenuOpen","filter","setFilter","applicationFilter","setApplicationFilter","categoryFilter","setCategoryFilter","loadRoles","useCallback","result","adminApi","err","loadPermissions","useEffect","handleSearch","e","openCreateModal","openEditModal","role","detail","p","handleSubmit","updateData","message","handleDelete","handlePermissionToggle","permissionId","prev","id","stats","useMemo","systemCount","r","customCount","totalUsers","sum","categoryCount","acc","uniqueApplications","appMap","name","a","b","filteredRoles","hasActiveFilters","clearAllFilters","toggleFilter","newFilter","jsxs","jsx","Breadcrumb","Users","X","Slot","Plus","Search","Filter","app","ChevronDown","cat","Loader2","categoryConfig","CategoryIcon","AppWindow","MoreHorizontal","Edit2","Trash2","permission","field","value"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RolesPage-Dm03fBBf.js","sources":["../../src/pages/platform/administration/permissions/RolesPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback, useMemo } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Plus, Search, Edit2, Trash2, MoreHorizontal, X, Loader2, Users, Shield, Eye, Crown, UserCog, PenTool, Sparkles, Filter, AppWindow, ChevronDown } from 'lucide-react';\r\nimport { adminApi, type RoleListDto, type PermissionListDto, type CreateRoleRequest, type UpdateRoleRequest, type RoleCategory } from '@/services/api/adminApi';\r\nimport { Slot } from '@/extensions';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\n\r\nconst ALL_CATEGORIES: RoleCategory[] = ['Global', 'Admin', 'Manager', 'Contributor', 'Viewer', 'Custom'];\r\n\r\nconst CATEGORY_CONFIG: Record<RoleCategory, { icon: React.ElementType; color: string; bgColor: string; borderColor: string }> = {\r\n Global: {\r\n icon: Crown,\r\n color: 'text-purple-600 dark:text-purple-400',\r\n bgColor: 'bg-purple-50 dark:bg-purple-900/20',\r\n borderColor: 'border-purple-200 dark:border-purple-800'\r\n },\r\n Admin: {\r\n icon: Shield,\r\n color: 'text-red-600 dark:text-red-400',\r\n bgColor: 'bg-red-50 dark:bg-red-900/20',\r\n borderColor: 'border-red-200 dark:border-red-800'\r\n },\r\n Manager: {\r\n icon: UserCog,\r\n color: 'text-blue-600 dark:text-blue-400',\r\n bgColor: 'bg-blue-50 dark:bg-blue-900/20',\r\n borderColor: 'border-blue-200 dark:border-blue-800'\r\n },\r\n Contributor: {\r\n icon: PenTool,\r\n color: 'text-green-600 dark:text-green-400',\r\n bgColor: 'bg-green-50 dark:bg-green-900/20',\r\n borderColor: 'border-green-200 dark:border-green-800'\r\n },\r\n Viewer: {\r\n icon: Eye,\r\n color: 'text-gray-600 dark:text-gray-400',\r\n bgColor: 'bg-gray-50 dark:bg-gray-900/20',\r\n borderColor: 'border-gray-200 dark:border-gray-700'\r\n },\r\n Custom: {\r\n icon: Sparkles,\r\n color: 'text-orange-600 dark:text-orange-400',\r\n bgColor: 'bg-orange-50 dark:bg-orange-900/20',\r\n borderColor: 'border-orange-200 dark:border-orange-800'\r\n }\r\n};\r\n\r\nexport function RolesPage(): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const navigate = useNavigate();\r\n const [roles, setRoles] = useState<RoleListDto[]>([]);\r\n const [permissions, setPermissions] = useState<PermissionListDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [search, setSearch] = useState('');\r\n const [showModal, setShowModal] = useState(false);\r\n const [editingRole, setEditingRole] = useState<RoleListDto | null>(null);\r\n const [formData, setFormData] = useState<CreateRoleRequest>({\r\n name: '',\r\n description: '',\r\n permissionIds: []\r\n });\r\n const [saving, setSaving] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [menuOpen, setMenuOpen] = useState<string | null>(null);\r\n const [filter, setFilter] = useState<'system' | 'custom' | RoleCategory | null>(null);\r\n const [applicationFilter, setApplicationFilter] = useState<string | null>(null);\r\n const [categoryFilter, setCategoryFilter] = useState<RoleCategory | null>(null);\r\n\r\n const loadRoles = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const result = await adminApi.roles.getAll(search ? { search } : undefined);\r\n setRoles(result);\r\n } catch (err) {\r\n console.error('Failed to load roles:', err);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [search]);\r\n\r\n const loadPermissions = async () => {\r\n try {\r\n const result = await adminApi.permissions.getAll();\r\n setPermissions(result);\r\n } catch (err) {\r\n console.error('Failed to load permissions:', err);\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n loadRoles();\r\n loadPermissions();\r\n }, [loadRoles]);\r\n\r\n const handleSearch = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n loadRoles();\r\n };\r\n\r\n const openCreateModal = () => {\r\n setEditingRole(null);\r\n setFormData({ name: '', description: '', permissionIds: [] });\r\n setError(null);\r\n setShowModal(true);\r\n };\r\n\r\n const openEditModal = async (role: RoleListDto) => {\r\n try {\r\n const detail = await adminApi.roles.getById(role.id);\r\n setEditingRole(role);\r\n setFormData({\r\n name: detail.name,\r\n description: detail.description || '',\r\n parentRoleId: detail.parentRoleId || undefined,\r\n permissionIds: detail.permissions.map(p => p.id)\r\n });\r\n setError(null);\r\n setShowModal(true);\r\n } catch (err) {\r\n console.error('Failed to load role details:', err);\r\n }\r\n };\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setSaving(true);\r\n setError(null);\r\n\r\n try {\r\n if (editingRole) {\r\n const updateData: UpdateRoleRequest = {\r\n name: formData.name,\r\n description: formData.description,\r\n parentRoleId: formData.parentRoleId,\r\n permissionIds: formData.permissionIds\r\n };\r\n await adminApi.roles.update(editingRole.id, updateData);\r\n } else {\r\n await adminApi.roles.create(formData);\r\n }\r\n setShowModal(false);\r\n loadRoles();\r\n } catch (err: unknown) {\r\n const message = err instanceof Error ? err.message : 'An error occurred';\r\n setError(message);\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleDelete = async (role: RoleListDto) => {\r\n if (!confirm(t('roles.confirmDelete', { name: role.name }))) return;\r\n\r\n try {\r\n await adminApi.roles.delete(role.id);\r\n loadRoles();\r\n } catch (err: unknown) {\r\n const message = err instanceof Error ? err.message : 'An error occurred';\r\n alert(message);\r\n }\r\n setMenuOpen(null);\r\n };\r\n\r\n const handlePermissionToggle = (permissionId: string) => {\r\n setFormData(prev => ({\r\n ...prev,\r\n permissionIds: prev.permissionIds?.includes(permissionId)\r\n ? prev.permissionIds.filter(id => id !== permissionId)\r\n : [...(prev.permissionIds || []), permissionId]\r\n }));\r\n };\r\n\r\n const stats = useMemo(() => {\r\n const systemCount = roles.filter(r => r.isSystem).length;\r\n const customCount = roles.filter(r => !r.isSystem).length;\r\n const totalUsers = roles.reduce((sum, r) => sum + r.usersCount, 0);\r\n const categoryCount = roles.reduce((acc, r) => {\r\n acc[r.category] = (acc[r.category] || 0) + 1;\r\n return acc;\r\n }, {} as Record<string, number>);\r\n return { total: roles.length, systemCount, customCount, totalUsers, categoryCount };\r\n }, [roles]);\r\n\r\n const uniqueApplications = useMemo(() => {\r\n const appMap = new Map<string, string>();\r\n roles.forEach(r => {\r\n if (r.applicationId && r.applicationName) {\r\n appMap.set(r.applicationId, r.applicationName);\r\n }\r\n });\r\n return Array.from(appMap.entries())\r\n .map(([id, name]) => ({ id, name }))\r\n .sort((a, b) => a.name.localeCompare(b.name));\r\n }, [roles]);\r\n\r\n const filteredRoles = useMemo(() => {\r\n let result = roles;\r\n // System/custom filter (from stats bar)\r\n if (filter === 'system') result = result.filter(r => r.isSystem);\r\n else if (filter === 'custom') result = result.filter(r => !r.isSystem);\r\n else if (filter) result = result.filter(r => r.category === filter);\r\n // Application filter\r\n if (applicationFilter === '__global__') result = result.filter(r => !r.applicationId);\r\n else if (applicationFilter) result = result.filter(r => r.applicationId === applicationFilter);\r\n // Category filter\r\n if (categoryFilter) result = result.filter(r => r.category === categoryFilter);\r\n return result;\r\n }, [roles, filter, applicationFilter, categoryFilter]);\r\n\r\n const hasActiveFilters = filter !== null || applicationFilter !== null || categoryFilter !== null;\r\n\r\n const clearAllFilters = () => {\r\n setFilter(null);\r\n setApplicationFilter(null);\r\n setCategoryFilter(null);\r\n };\r\n\r\n const toggleFilter = (newFilter: 'system' | 'custom' | RoleCategory) => {\r\n setFilter(prev => prev === newFilter ? null : newFilter);\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('header.title'), href: '/administration' },\r\n { label: t('roles.title') }\r\n ]}\r\n />\r\n\r\n {/* Header with stats */}\r\n <div className=\"flex items-start justify-between\">\r\n <div>\r\n <div className=\"flex items-center gap-3\">\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">{t('roles.title')}</h1>\r\n {!loading && (\r\n <span className=\"px-3 py-1 rounded-full text-sm font-medium bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30 text-[var(--color-accent-700)] dark:text-[var(--color-accent-300)] border border-[var(--color-accent-200)] dark:border-[var(--color-accent-800)]\">\r\n {hasActiveFilters ? `${filteredRoles.length} / ${stats.total}` : stats.total} {t('roles.totalLabel')}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-[var(--text-secondary)] mt-1\">{t('roles.list')}</p>\r\n {!loading && stats.total > 0 && (\r\n <div className=\"flex items-center gap-2 mt-3 text-sm\">\r\n <button\r\n onClick={() => toggleFilter('system')}\r\n className={`flex items-center gap-1.5 px-2.5 py-1 rounded-full transition-all ${\r\n filter === 'system'\r\n ? 'bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)] ring-2 ring-[var(--warning-border)]'\r\n : 'text-[var(--text-tertiary)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-secondary)]'\r\n }`}\r\n >\r\n <Shield className=\"w-4 h-4\" />\r\n {stats.systemCount} {t('roles.systemRoles')}\r\n </button>\r\n <button\r\n onClick={() => toggleFilter('custom')}\r\n className={`flex items-center gap-1.5 px-2.5 py-1 rounded-full transition-all ${\r\n filter === 'custom'\r\n ? 'bg-[var(--color-accent-100)] dark:bg-[var(--color-accent-900)]/30 text-[var(--color-accent-700)] dark:text-[var(--color-accent-300)] border border-[var(--color-accent-200)] dark:border-[var(--color-accent-800)] ring-2 ring-[var(--color-accent-300)] dark:ring-[var(--color-accent-700)]'\r\n : 'text-[var(--text-tertiary)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-secondary)]'\r\n }`}\r\n >\r\n <Sparkles className=\"w-4 h-4\" />\r\n {stats.customCount} {t('roles.customRoles')}\r\n </button>\r\n <span className=\"flex items-center gap-1.5 px-2.5 py-1 text-[var(--text-tertiary)]\">\r\n <Users className=\"w-4 h-4\" />\r\n {stats.totalUsers} {t('roles.totalUsers')}\r\n </span>\r\n {hasActiveFilters && (\r\n <button\r\n onClick={clearAllFilters}\r\n className=\"flex items-center gap-1 px-2 py-1 rounded-full text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-primary)] transition-colors\"\r\n title={t('roles.filters.clearAll')}\r\n >\r\n <X className=\"w-3.5 h-3.5\" />\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <Slot name=\"roles.header.actions\" context={{ roles, reload: loadRoles }} />\r\n <button\r\n onClick={openCreateModal}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white font-medium transition-colors\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('roles.create')}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Search + Filters */}\r\n <div className=\"flex flex-col gap-3\">\r\n <form onSubmit={handleSearch} className=\"flex gap-2\">\r\n <div className=\"relative flex-1 max-w-md\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--text-secondary)]\" />\r\n <input\r\n type=\"text\"\r\n value={search}\r\n onChange={e => setSearch(e.target.value)}\r\n placeholder={t('common.search')}\r\n className=\"w-full pl-10 pr-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n <button\r\n type=\"submit\"\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] text-[var(--text-primary)] font-medium transition-colors\"\r\n >\r\n {t('common.search')}\r\n </button>\r\n </form>\r\n\r\n {/* Filter bar */}\r\n <div className=\"flex flex-wrap items-center gap-3\">\r\n <div className=\"flex items-center gap-1.5 text-sm text-[var(--text-tertiary)]\">\r\n <Filter className=\"w-4 h-4\" />\r\n <span>{t('roles.filters.title')}</span>\r\n </div>\r\n\r\n {/* Application filter */}\r\n <div className=\"relative\">\r\n <select\r\n value={applicationFilter ?? ''}\r\n onChange={e => setApplicationFilter(e.target.value || null)}\r\n className=\"appearance-none pl-3 pr-8 py-1.5 text-sm rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] cursor-pointer\"\r\n >\r\n <option value=\"\">{t('roles.filters.allApplications')}</option>\r\n <option value=\"__global__\">{t('roles.filters.globalRoles')}</option>\r\n {uniqueApplications.map(app => (\r\n <option key={app.id} value={app.id}>{app.name}</option>\r\n ))}\r\n </select>\r\n <ChevronDown className=\"absolute right-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-[var(--text-tertiary)] pointer-events-none\" />\r\n </div>\r\n\r\n {/* Category filter */}\r\n <div className=\"relative\">\r\n <select\r\n value={categoryFilter ?? ''}\r\n onChange={e => setCategoryFilter((e.target.value || null) as RoleCategory | null)}\r\n className=\"appearance-none pl-3 pr-8 py-1.5 text-sm rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] cursor-pointer\"\r\n >\r\n <option value=\"\">{t('roles.filters.allCategories')}</option>\r\n {ALL_CATEGORIES.map(cat => (\r\n <option key={cat} value={cat}>{t(`roles.categories.${cat.toLowerCase()}`)}</option>\r\n ))}\r\n </select>\r\n <ChevronDown className=\"absolute right-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-[var(--text-tertiary)] pointer-events-none\" />\r\n </div>\r\n\r\n {/* Clear all filters */}\r\n {hasActiveFilters && (\r\n <button\r\n onClick={clearAllFilters}\r\n className=\"flex items-center gap-1.5 px-2.5 py-1.5 text-sm rounded-[var(--radius-button)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-primary)] transition-colors\"\r\n >\r\n <X className=\"w-3.5 h-3.5\" />\r\n {t('roles.filters.clearAll')}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Table */}\r\n <div className=\"card overflow-hidden\">\r\n <table className=\"w-full\">\r\n <thead>\r\n <tr className=\"bg-[var(--bg-secondary)]\">\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">{t('roles.columns.name')}</th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden md:table-cell\">{t('roles.columns.category')}</th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">{t('roles.columns.application')}</th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden xl:table-cell\">{t('roles.columns.description')}</th>\r\n <th className=\"text-center px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">{t('roles.columns.usersCount')}</th>\r\n <th className=\"text-center px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">{t('roles.permissions')}</th>\r\n <th className=\"w-24 px-4 py-3\"></th>\r\n </tr>\r\n </thead>\r\n <tbody className=\"divide-y divide-[var(--border-color)]\">\r\n {loading && (\r\n <tr>\r\n <td colSpan={7} className=\"px-6 py-12 text-center\">\r\n <Loader2 className=\"w-6 h-6 animate-spin mx-auto text-[var(--color-accent-500)]\" />\r\n </td>\r\n </tr>\r\n )}\r\n {!loading && filteredRoles.length === 0 && (\r\n <tr>\r\n <td colSpan={7} className=\"px-6 py-12 text-center text-[var(--text-secondary)]\">\r\n {hasActiveFilters ? (\r\n <div className=\"space-y-2\">\r\n <p>{t('roles.noRoles')}</p>\r\n <button\r\n onClick={clearAllFilters}\r\n className=\"text-[var(--color-accent-600)] hover:underline\"\r\n >\r\n {t('roles.filters.clearAll')}\r\n </button>\r\n </div>\r\n ) : t('roles.noRoles')}\r\n </td>\r\n </tr>\r\n )}\r\n {!loading && filteredRoles.length > 0 && (\r\n filteredRoles.map(role => {\r\n const categoryConfig = CATEGORY_CONFIG[role.category] || CATEGORY_CONFIG.Custom;\r\n const CategoryIcon = categoryConfig.icon;\r\n return (\r\n <tr\r\n key={role.id}\r\n onClick={() => navigate(`/administration/permissions/roles/${role.id}`)}\r\n className=\"hover:bg-[var(--bg-hover)] transition-colors cursor-pointer group\"\r\n >\r\n <td className=\"px-4 py-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className={`w-9 h-9 rounded-full flex items-center justify-center ${categoryConfig.bgColor} ${categoryConfig.borderColor} border`}>\r\n <CategoryIcon className={`w-4 h-4 ${categoryConfig.color}`} />\r\n </div>\r\n <div>\r\n <div className=\"font-medium text-[var(--text-primary)] group-hover:text-[var(--color-accent-600)] transition-colors\">{role.name}</div>\r\n {role.isSystem && (\r\n <span className=\"text-xs text-[var(--warning-text)]\">\r\n {t('roles.system')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3 hidden md:table-cell\">\r\n <button\r\n onClick={(e) => { e.stopPropagation(); setCategoryFilter(prev => prev === role.category ? null : role.category); }}\r\n className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-[var(--radius-badge)] text-xs font-medium border transition-all ${categoryConfig.bgColor} ${categoryConfig.color} ${categoryConfig.borderColor} hover:ring-2 hover:ring-offset-1 ${categoryFilter === role.category ? 'ring-2 ring-offset-1' : ''}`}\r\n >\r\n <CategoryIcon className=\"w-3.5 h-3.5\" />\r\n {t(`roles.categories.${role.category.toLowerCase()}`)}\r\n </button>\r\n </td>\r\n <td className=\"px-4 py-3 hidden lg:table-cell\">\r\n {role.applicationName ? (\r\n <button\r\n onClick={(e) => { e.stopPropagation(); setApplicationFilter(prev => prev === role.applicationId ? null : role.applicationId); }}\r\n className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-[var(--radius-badge)] text-xs font-medium border transition-all bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)] hover:ring-2 hover:ring-offset-1 ${applicationFilter === role.applicationId ? 'ring-2 ring-offset-1' : ''}`}\r\n >\r\n <AppWindow className=\"w-3.5 h-3.5\" />\r\n {role.applicationName}\r\n </button>\r\n ) : (\r\n <span className=\"inline-flex items-center gap-1.5 px-2.5 py-1 text-xs text-[var(--text-tertiary)]\">\r\n <Crown className=\"w-3.5 h-3.5\" />\r\n {t('roles.filters.globalRoles')}\r\n </span>\r\n )}\r\n </td>\r\n <td className=\"px-4 py-3 text-[var(--text-secondary)] max-w-xs truncate hidden xl:table-cell\">{role.description || '-'}</td>\r\n <td className=\"px-4 py-3 text-center\">\r\n <div className=\"inline-flex items-center gap-1.5 text-[var(--text-secondary)]\">\r\n <Users className=\"w-4 h-4\" />\r\n <span className=\"font-medium\">{role.usersCount}</span>\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3 text-center hidden lg:table-cell\">\r\n <div className=\"inline-flex items-center gap-1.5 text-[var(--text-secondary)]\">\r\n <Shield className=\"w-4 h-4\" />\r\n <span className=\"font-medium\">{role.permissionsCount}</span>\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3\">\r\n <div className=\"flex items-center justify-end gap-1\" onClick={e => e.stopPropagation()}>\r\n <button\r\n onClick={() => navigate(`/administration/permissions/roles/${role.id}`)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-tertiary)] transition-colors\"\r\n title={t('users.view')}\r\n >\r\n <Eye className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n </button>\r\n {!role.isSystem && (\r\n <div className=\"relative\">\r\n <button\r\n onClick={() => setMenuOpen(menuOpen === role.id ? null : role.id)}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-tertiary)] transition-colors\"\r\n >\r\n <MoreHorizontal className=\"w-4 h-4 text-[var(--text-secondary)]\" />\r\n </button>\r\n {menuOpen === role.id && (\r\n <div className=\"absolute right-0 top-full mt-1 w-48 py-1 bg-[var(--bg-secondary)] rounded-[var(--radius-menu-item)] border border-[var(--border-color)] shadow-lg z-10\">\r\n <button\r\n onClick={() => { openEditModal(role); setMenuOpen(null); }}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-left text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <Edit2 className=\"w-4 h-4\" />\r\n {t('common.edit')}\r\n </button>\r\n {role.usersCount === 0 && (\r\n <button\r\n onClick={() => handleDelete(role)}\r\n className=\"w-full flex items-center gap-2 px-4 py-2 text-left text-[var(--error-text)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n {t('common.delete')}\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </td>\r\n </tr>\r\n );\r\n })\r\n )}\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n {/* Modal */}\r\n {showModal && (\r\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-modal)] w-full max-w-lg p-6 m-4 max-h-[90vh] overflow-y-auto\">\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <h2 className=\"text-xl font-bold text-[var(--text-primary)]\">\r\n {editingRole ? t('roles.edit') : t('roles.create')}\r\n </h2>\r\n <button onClick={() => setShowModal(false)} className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)]\">\r\n <X className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"mb-4 p-3 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)] text-[var(--error-text)] text-sm\">\r\n {error}\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-4\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roles.form.name')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n required\r\n value={formData.name}\r\n onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)]\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('roles.form.description')}\r\n </label>\r\n <textarea\r\n value={formData.description}\r\n onChange={e => setFormData(prev => ({ ...prev, description: e.target.value }))}\r\n rows={3}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-secondary)] text-[var(--text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--color-accent-500)] resize-none\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('roles.permissions')}\r\n </label>\r\n <div className=\"space-y-2 max-h-64 overflow-y-auto p-2 border border-[var(--border-color)] rounded-[var(--radius-card)]\">\r\n {permissions.map(permission => (\r\n <label key={permission.id} className=\"flex items-start gap-2 cursor-pointer p-2 hover:bg-[var(--bg-hover)] rounded-[var(--radius-button)]\">\r\n <input\r\n type=\"checkbox\"\r\n checked={formData.permissionIds?.includes(permission.id) || false}\r\n onChange={() => handlePermissionToggle(permission.id)}\r\n className=\"mt-0.5 rounded border-[var(--border-color)]\"\r\n />\r\n <div>\r\n <div className=\"text-[var(--text-primary)] font-mono text-sm\">{permission.path}</div>\r\n {permission.description && (\r\n <div className=\"text-xs text-[var(--text-secondary)]\">{permission.description}</div>\r\n )}\r\n </div>\r\n </label>\r\n ))}\r\n {permissions.length === 0 && (\r\n <div className=\"text-center py-4 text-[var(--text-secondary)]\">\r\n {t('roles.noPermissions')}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Extension form fields slot */}\r\n <Slot\r\n name=\"roles.form.fields.after\"\r\n context={{\r\n formData,\r\n onChange: (field: string, value: unknown) => {\r\n setFormData(prev => ({ ...prev, [field]: value }));\r\n },\r\n disabled: saving,\r\n isEditing: !!editingRole,\r\n role: editingRole,\r\n }}\r\n />\r\n\r\n <div className=\"flex justify-end gap-2 pt-4\">\r\n <button\r\n type=\"button\"\r\n onClick={() => setShowModal(false)}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] text-[var(--text-primary)] font-medium transition-colors\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n type=\"submit\"\r\n disabled={saving}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] hover:bg-[var(--color-accent-700)] text-white font-medium transition-colors disabled:opacity-50 flex items-center gap-2\"\r\n >\r\n {saving && <Loader2 className=\"w-4 h-4 animate-spin\" />}\r\n {editingRole ? t('common.save') : t('common.create')}\r\n </button>\r\n </div>\r\n </form>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["ALL_CATEGORIES","CATEGORY_CONFIG","Crown","Shield","UserCog","PenTool","Eye","Sparkles","RolesPage","t","useTranslation","navigate","useNavigate","roles","setRoles","useState","permissions","setPermissions","loading","setLoading","search","setSearch","showModal","setShowModal","editingRole","setEditingRole","formData","setFormData","saving","setSaving","error","setError","menuOpen","setMenuOpen","filter","setFilter","applicationFilter","setApplicationFilter","categoryFilter","setCategoryFilter","loadRoles","useCallback","result","adminApi","err","loadPermissions","useEffect","handleSearch","e","openCreateModal","openEditModal","role","detail","p","handleSubmit","updateData","message","handleDelete","handlePermissionToggle","permissionId","prev","id","stats","useMemo","systemCount","r","customCount","totalUsers","sum","categoryCount","acc","uniqueApplications","appMap","name","a","b","filteredRoles","hasActiveFilters","clearAllFilters","toggleFilter","newFilter","jsxs","jsx","Breadcrumb","Users","X","Slot","Plus","Search","Filter","app","ChevronDown","cat","Loader2","categoryConfig","CategoryIcon","AppWindow","MoreHorizontal","Edit2","Trash2","permission","field","value"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { jsx as e, jsxs as s } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState as o, useCallback as $, useEffect as P } from "react";
|
|
3
3
|
import { useTranslation as E } from "react-i18next";
|
|
4
4
|
import { Loader2 as S, Clock as O, Check as j, Save as F, AlertTriangle as I } from "lucide-react";
|
|
5
|
-
import { Z as p, B as H } from "./index-
|
|
5
|
+
import { Z as p, B as H } from "./index-CpY95_ro.js";
|
|
6
6
|
const T = ["Critical", "High", "Medium", "Low"];
|
|
7
7
|
function K() {
|
|
8
8
|
const { t: i } = E("support"), [c, d] = o(!0), [m, h] = o(null), [b, C] = o([]), [f, M] = o([]), [l, L] = o(null), [x, g] = o({}), [N, y] = o(null), v = $(async () => {
|
|
@@ -248,4 +248,4 @@ function W(i) {
|
|
|
248
248
|
export {
|
|
249
249
|
K as SlaConfigPage
|
|
250
250
|
};
|
|
251
|
-
//# sourceMappingURL=SlaConfigPage-
|
|
251
|
+
//# sourceMappingURL=SlaConfigPage-B4WDzEKi.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SlaConfigPage-BqXHATb6.js","sources":["../../src/pages/platform/support/SlaConfigPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Clock, Save, AlertTriangle, Loader2, Check } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n slaApi,\r\n type SlaConfigurationDto,\r\n type EscalationRuleDto,\r\n type SlaMetricsDto,\r\n} from '@/services/api/supportApi';\r\n\r\nconst priorityOrder = ['Critical', 'High', 'Medium', 'Low'];\r\n\r\nexport function SlaConfigPage(): ReactElement {\r\n const { t } = useTranslation('support');\r\n const [loading, setLoading] = useState(true);\r\n const [saving, setSaving] = useState<string | null>(null);\r\n const [configs, setConfigs] = useState<SlaConfigurationDto[]>([]);\r\n const [escalationRules, setEscalationRules] = useState<EscalationRuleDto[]>([]);\r\n const [metrics, setMetrics] = useState<SlaMetricsDto | null>(null);\r\n const [editedConfigs, setEditedConfigs] = useState<Record<string, { response: number; resolution: number }>>({});\r\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const [configsRes, rulesRes, metricsRes] = await Promise.all([\r\n slaApi.getConfigurations(),\r\n slaApi.getEscalationRules(),\r\n slaApi.getMetrics(),\r\n ]);\r\n\r\n // Sort by priority order\r\n const sorted = [...configsRes].sort(\r\n (a, b) => priorityOrder.indexOf(a.priority) - priorityOrder.indexOf(b.priority)\r\n );\r\n\r\n setConfigs(sorted);\r\n setEscalationRules(rulesRes);\r\n setMetrics(metricsRes);\r\n\r\n // Initialize edited values\r\n const edited: Record<string, { response: number; resolution: number }> = {};\r\n sorted.forEach((c) => {\r\n edited[c.priority] = {\r\n response: c.responseTimeMinutes,\r\n resolution: c.resolutionTimeMinutes,\r\n };\r\n });\r\n setEditedConfigs(edited);\r\n } catch (error) {\r\n console.error('Failed to load SLA configurations:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n const handleSave = async (priority: string) => {\r\n const edited = editedConfigs[priority];\r\n if (!edited) return;\r\n\r\n try {\r\n setSaving(priority);\r\n await slaApi.updateConfiguration(priority, {\r\n responseTimeMinutes: edited.response,\r\n resolutionTimeMinutes: edited.resolution,\r\n });\r\n\r\n // Reload to get updated formatted strings\r\n await loadData();\r\n\r\n setSuccessMessage(`${priority} SLA configuration saved successfully`);\r\n setTimeout(() => setSuccessMessage(null), 3000);\r\n } catch (error) {\r\n console.error('Failed to save SLA configuration:', error);\r\n } finally {\r\n setSaving(null);\r\n }\r\n };\r\n\r\n const handleInputChange = (priority: string, field: 'response' | 'resolution', value: number) => {\r\n setEditedConfigs((prev) => ({\r\n ...prev,\r\n [priority]: {\r\n ...prev[priority],\r\n [field]: value,\r\n },\r\n }));\r\n };\r\n\r\n const hasChanges = (priority: string) => {\r\n const config = configs.find((c) => c.priority === priority);\r\n const edited = editedConfigs[priority];\r\n if (!config || !edited) return false;\r\n return (\r\n config.responseTimeMinutes !== edited.response ||\r\n config.resolutionTimeMinutes !== edited.resolution\r\n );\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('title', 'Support'), href: '/support' },\r\n { label: t('sla.title', 'SLA Configuration') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div>\r\n <h1 className=\"text-2xl font-bold flex items-center gap-2\">\r\n <Clock className=\"w-6 h-6\" />\r\n {t('sla.title', 'SLA Configuration')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n Configure Service Level Agreements for ticket response and resolution times\r\n </p>\r\n </div>\r\n\r\n {/* Success Message */}\r\n {successMessage && (\r\n <div className=\"bg-[var(--success-bg)] border border-[var(--success-border)] text-[var(--success-text)] px-4 py-3 rounded flex items-center gap-2\">\r\n <Check className=\"w-5 h-5\" />\r\n {successMessage}\r\n </div>\r\n )}\r\n\r\n {/* SLA Metrics Overview */}\r\n {metrics && (\r\n <div className=\"card p-4\">\r\n <h2 className=\"font-semibold mb-4\">Current SLA Performance</h2>\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\r\n <div className=\"text-center p-3 bg-[var(--bg-secondary)] rounded\">\r\n <div className=\"text-2xl font-bold\">{metrics.totalTickets}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">Total Tickets</div>\r\n </div>\r\n <div className=\"text-center p-3 bg-[var(--bg-secondary)] rounded\">\r\n <div className=\"text-2xl font-bold text-[var(--success-text)]\">{metrics.ticketsWithinSla}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">Within SLA</div>\r\n </div>\r\n <div className=\"text-center p-3 bg-[var(--bg-secondary)] rounded\">\r\n <div className=\"text-2xl font-bold text-[var(--error-text)]\">{metrics.ticketsBreached}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">Breached</div>\r\n </div>\r\n <div className=\"text-center p-3 bg-[var(--bg-secondary)] rounded\">\r\n <div className={`text-2xl font-bold ${metrics.slaCompliancePercentage >= 90 ? 'text-[var(--success-text)]' : 'text-[var(--warning-text)]'}`}>\r\n {metrics.slaCompliancePercentage.toFixed(1)}%\r\n </div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">Compliance</div>\r\n </div>\r\n </div>\r\n\r\n {/* Breaches by Priority */}\r\n {Object.keys(metrics.breachesByPriority).length > 0 && (\r\n <div className=\"mt-4 pt-4 border-t border-[var(--border-color)]\">\r\n <h3 className=\"text-sm font-medium mb-2\">Breaches by Priority</h3>\r\n <div className=\"flex gap-4\">\r\n {Object.entries(metrics.breachesByPriority).map(([priority, count]) => (\r\n <div key={priority} className=\"flex items-center gap-2\">\r\n <span className=\"text-sm\">{priority}:</span>\r\n <span className=\"font-medium text-[var(--error-text)]\">{count}</span>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* SLA Configurations */}\r\n <div className=\"card\">\r\n <div className=\"p-4 border-b border-[var(--border-color)]\">\r\n <h2 className=\"font-semibold\">Response & Resolution Times</h2>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n Define the maximum time allowed for initial response and complete resolution by priority\r\n </p>\r\n </div>\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)] bg-[var(--bg-secondary)]\">\r\n <th className=\"text-left p-4 font-medium\">Priority</th>\r\n <th className=\"text-left p-4 font-medium\">Response Time</th>\r\n <th className=\"text-left p-4 font-medium\">Resolution Time</th>\r\n <th className=\"text-left p-4 font-medium\">Status</th>\r\n <th className=\"text-right p-4 font-medium\">Actions</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {configs.map((config) => {\r\n const edited = editedConfigs[config.priority];\r\n const changed = hasChanges(config.priority);\r\n\r\n return (\r\n <tr key={config.id} className=\"border-b border-[var(--border-color)]\">\r\n <td className=\"p-4\">\r\n <span className={`inline-flex items-center px-3 py-1 rounded-[var(--radius-badge)] font-medium text-sm ${\r\n config.priority === 'Critical' ? 'bg-[var(--error-bg)] text-[var(--error-text)]' :\r\n config.priority === 'High' ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]' :\r\n config.priority === 'Medium' ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]' :\r\n 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n }`}>\r\n {config.priority}\r\n </span>\r\n </td>\r\n <td className=\"p-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n value={edited?.response ?? config.responseTimeMinutes}\r\n onChange={(e) =>\r\n handleInputChange(config.priority, 'response', parseInt(e.target.value) || 0)\r\n }\r\n className=\"input w-24\"\r\n />\r\n <span className=\"text-sm text-[var(--text-secondary)]\">minutes</span>\r\n <span className=\"text-sm text-[var(--text-secondary)] ml-2\">\r\n ({config.responseTimeFormatted})\r\n </span>\r\n </div>\r\n </td>\r\n <td className=\"p-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n value={edited?.resolution ?? config.resolutionTimeMinutes}\r\n onChange={(e) =>\r\n handleInputChange(config.priority, 'resolution', parseInt(e.target.value) || 0)\r\n }\r\n className=\"input w-24\"\r\n />\r\n <span className=\"text-sm text-[var(--text-secondary)]\">minutes</span>\r\n <span className=\"text-sm text-[var(--text-secondary)] ml-2\">\r\n ({config.resolutionTimeFormatted})\r\n </span>\r\n </div>\r\n </td>\r\n <td className=\"p-4\">\r\n {config.isActive ? (\r\n <span className=\"inline-flex items-center px-2 py-1 rounded bg-[var(--success-bg)] text-[var(--success-text)] text-sm\">\r\n Active\r\n </span>\r\n ) : (\r\n <span className=\"inline-flex items-center px-2 py-1 rounded bg-[var(--bg-secondary)] text-[var(--text-secondary)] text-sm\">\r\n Inactive\r\n </span>\r\n )}\r\n </td>\r\n <td className=\"p-4 text-right\">\r\n <button\r\n onClick={() => handleSave(config.priority)}\r\n disabled={!changed || saving === config.priority}\r\n className={`btn ${changed ? 'btn-primary' : 'btn-secondary'} flex items-center gap-2`}\r\n >\r\n {saving === config.priority ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Save className=\"w-4 h-4\" />\r\n )}\r\n Save\r\n </button>\r\n </td>\r\n </tr>\r\n );\r\n })}\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n\r\n {/* Escalation Rules */}\r\n <div className=\"card\">\r\n <div className=\"p-4 border-b border-[var(--border-color)]\">\r\n <h2 className=\"font-semibold\">Escalation Rules</h2>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n Automatic escalation paths when SLAs are breached\r\n </p>\r\n </div>\r\n\r\n {escalationRules.length > 0 ? (\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)] bg-[var(--bg-secondary)]\">\r\n <th className=\"text-left p-4 font-medium\">Level</th>\r\n <th className=\"text-left p-4 font-medium\">Trigger</th>\r\n <th className=\"text-left p-4 font-medium\">Delay After Breach</th>\r\n <th className=\"text-left p-4 font-medium\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {escalationRules.map((rule) => (\r\n <tr key={rule.id} className=\"border-b border-[var(--border-color)]\">\r\n <td className=\"p-4\">\r\n <span className=\"font-medium\">{rule.level}</span>\r\n </td>\r\n <td className=\"p-4\">\r\n <span className=\"text-sm\">{formatTriggerType(rule.triggerType)}</span>\r\n </td>\r\n <td className=\"p-4\">\r\n <span className=\"text-sm\">{formatMinutes(rule.delayAfterBreachMinutes)}</span>\r\n </td>\r\n <td className=\"p-4\">\r\n {rule.isActive ? (\r\n <span className=\"inline-flex items-center px-2 py-1 rounded bg-[var(--success-bg)] text-[var(--success-text)] text-sm\">\r\n Active\r\n </span>\r\n ) : (\r\n <span className=\"inline-flex items-center px-2 py-1 rounded bg-[var(--bg-secondary)] text-[var(--text-secondary)] text-sm\">\r\n Inactive\r\n </span>\r\n )}\r\n </td>\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n ) : (\r\n <div className=\"p-8 text-center text-[var(--text-secondary)]\">\r\n <AlertTriangle className=\"w-12 h-12 mx-auto mb-4 opacity-50\" />\r\n <p>No escalation rules configured</p>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Help Section */}\r\n <div className=\"card p-4 bg-[var(--info-bg)] border-[var(--info-border)]\">\r\n <h3 className=\"font-semibold text-[var(--info-text)] mb-2\">About SLA Configuration</h3>\r\n <ul className=\"text-sm text-[var(--info-text)] space-y-1\">\r\n <li>\r\n <strong>Response Time:</strong> Maximum time allowed for the first agent response after ticket creation\r\n </li>\r\n <li>\r\n <strong>Resolution Time:</strong> Maximum time allowed to fully resolve and close the ticket\r\n </li>\r\n <li>\r\n <strong>SLA Pause:</strong> SLA timers automatically pause when a ticket is placed On Hold\r\n </li>\r\n <li>\r\n <strong>Escalation:</strong> When SLA is breached, tickets are automatically escalated to higher levels\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction formatTriggerType(type: string): string {\r\n switch (type) {\r\n case 'ResponseBreach':\r\n return 'Response SLA Breached';\r\n case 'ResolutionBreach':\r\n return 'Resolution SLA Breached';\r\n default:\r\n return type;\r\n }\r\n}\r\n\r\nfunction formatMinutes(minutes: number): string {\r\n if (minutes < 60) return `${minutes} minutes`;\r\n const hours = Math.floor(minutes / 60);\r\n const mins = minutes % 60;\r\n if (hours < 24) return mins > 0 ? `${hours}h ${mins}m` : `${hours} hours`;\r\n const days = Math.floor(hours / 24);\r\n const remainingHours = hours % 24;\r\n return remainingHours > 0 ? `${days}d ${remainingHours}h` : `${days} days`;\r\n}\r\n"],"names":["priorityOrder","SlaConfigPage","t","useTranslation","loading","setLoading","useState","saving","setSaving","configs","setConfigs","escalationRules","setEscalationRules","metrics","setMetrics","editedConfigs","setEditedConfigs","successMessage","setSuccessMessage","loadData","useCallback","configsRes","rulesRes","metricsRes","slaApi","sorted","a","b","edited","c","error","useEffect","handleSave","priority","handleInputChange","field","value","prev","hasChanges","config","jsx","Loader2","jsxs","Breadcrumb","Clock","Check","count","changed","e","Save","rule","formatTriggerType","formatMinutes","AlertTriangle","type","minutes","hours","mins","days","remainingHours"],"mappings":";;;;;AAYA,MAAMA,IAAgB,CAAC,YAAY,QAAQ,UAAU,KAAK;AAEnD,SAASC,IAA8B;AAC5C,QAAM,EAAE,GAAAC,EAAA,IAAMC,EAAe,SAAS,GAChC,CAACC,GAASC,CAAU,IAAIC,EAAS,EAAI,GACrC,CAACC,GAAQC,CAAS,IAAIF,EAAwB,IAAI,GAClD,CAACG,GAASC,CAAU,IAAIJ,EAAgC,CAAA,CAAE,GAC1D,CAACK,GAAiBC,CAAkB,IAAIN,EAA8B,CAAA,CAAE,GACxE,CAACO,GAASC,CAAU,IAAIR,EAA+B,IAAI,GAC3D,CAACS,GAAeC,CAAgB,IAAIV,EAAmE,CAAA,CAAE,GACzG,CAACW,GAAgBC,CAAiB,IAAIZ,EAAwB,IAAI,GAElEa,IAAWC,EAAY,YAAY;AACvC,QAAI;AACF,MAAAf,EAAW,EAAI;AACf,YAAM,CAACgB,GAAYC,GAAUC,CAAU,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC3DC,EAAO,kBAAA;AAAA,QACPA,EAAO,mBAAA;AAAA,QACPA,EAAO,WAAA;AAAA,MAAW,CACnB,GAGKC,IAAS,CAAC,GAAGJ,CAAU,EAAE;AAAA,QAC7B,CAACK,GAAGC,MAAM3B,EAAc,QAAQ0B,EAAE,QAAQ,IAAI1B,EAAc,QAAQ2B,EAAE,QAAQ;AAAA,MAAA;AAGhF,MAAAjB,EAAWe,CAAM,GACjBb,EAAmBU,CAAQ,GAC3BR,EAAWS,CAAU;AAGrB,YAAMK,IAAmE,CAAA;AACzE,MAAAH,EAAO,QAAQ,CAACI,MAAM;AACpB,QAAAD,EAAOC,EAAE,QAAQ,IAAI;AAAA,UACnB,UAAUA,EAAE;AAAA,UACZ,YAAYA,EAAE;AAAA,QAAA;AAAA,MAElB,CAAC,GACDb,EAAiBY,CAAM;AAAA,IACzB,SAASE,GAAO;AACd,cAAQ,MAAM,sCAAsCA,CAAK;AAAA,IAC3D,UAAA;AACE,MAAAzB,EAAW,EAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAA,CAAE;AAEL,EAAA0B,EAAU,MAAM;AACd,IAAAZ,EAAA;AAAA,EACF,GAAG,CAACA,CAAQ,CAAC;AAEb,QAAMa,IAAa,OAAOC,MAAqB;AAC7C,UAAML,IAASb,EAAckB,CAAQ;AACrC,QAAKL;AAEL,UAAI;AACF,QAAApB,EAAUyB,CAAQ,GAClB,MAAMT,EAAO,oBAAoBS,GAAU;AAAA,UACzC,qBAAqBL,EAAO;AAAA,UAC5B,uBAAuBA,EAAO;AAAA,QAAA,CAC/B,GAGD,MAAMT,EAAA,GAEND,EAAkB,GAAGe,CAAQ,uCAAuC,GACpE,WAAW,MAAMf,EAAkB,IAAI,GAAG,GAAI;AAAA,MAChD,SAASY,GAAO;AACd,gBAAQ,MAAM,qCAAqCA,CAAK;AAAA,MAC1D,UAAA;AACE,QAAAtB,EAAU,IAAI;AAAA,MAChB;AAAA,EACF,GAEM0B,IAAoB,CAACD,GAAkBE,GAAkCC,MAAkB;AAC/F,IAAApB,EAAiB,CAACqB,OAAU;AAAA,MAC1B,GAAGA;AAAA,MACH,CAACJ,CAAQ,GAAG;AAAA,QACV,GAAGI,EAAKJ,CAAQ;AAAA,QAChB,CAACE,CAAK,GAAGC;AAAA,MAAA;AAAA,IACX,EACA;AAAA,EACJ,GAEME,IAAa,CAACL,MAAqB;AACvC,UAAMM,IAAS9B,EAAQ,KAAK,CAACoB,MAAMA,EAAE,aAAaI,CAAQ,GACpDL,IAASb,EAAckB,CAAQ;AACrC,WAAI,CAACM,KAAU,CAACX,IAAe,KAE7BW,EAAO,wBAAwBX,EAAO,YACtCW,EAAO,0BAA0BX,EAAO;AAAA,EAE5C;AAEA,SAAIxB,IAEA,gBAAAoC,EAAC,SAAI,WAAU,kDACb,4BAACC,GAAA,EAAQ,WAAU,wDAAuD,EAAA,CAC5E,IAKF,gBAAAC,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAAF;AAAA,MAACG;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,EAAE,OAAOzC,EAAE,SAAS,SAAS,GAAG,MAAM,WAAA;AAAA,UACtC,EAAE,OAAOA,EAAE,aAAa,mBAAmB,EAAA;AAAA,QAAE;AAAA,MAC/C;AAAA,IAAA;AAAA,sBAID,OAAA,EACC,UAAA;AAAA,MAAA,gBAAAwC,EAAC,MAAA,EAAG,WAAU,8CACZ,UAAA;AAAA,QAAA,gBAAAF,EAACI,GAAA,EAAM,WAAU,UAAA,CAAU;AAAA,QAC1B1C,EAAE,aAAa,mBAAmB;AAAA,MAAA,GACrC;AAAA,MACA,gBAAAsC,EAAC,KAAA,EAAE,WAAU,gCAA+B,UAAA,8EAAA,CAE5C;AAAA,IAAA,GACF;AAAA,IAGCvB,KACC,gBAAAyB,EAAC,OAAA,EAAI,WAAU,qIACb,UAAA;AAAA,MAAA,gBAAAF,EAACK,GAAA,EAAM,WAAU,UAAA,CAAU;AAAA,MAC1B5B;AAAA,IAAA,GACH;AAAA,IAIDJ,KACC,gBAAA6B,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,MAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,sBAAqB,UAAA,2BAAuB;AAAA,MAC1D,gBAAAE,EAAC,OAAA,EAAI,WAAU,yCACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oDACb,UAAA;AAAA,UAAA,gBAAAF,EAAC,OAAA,EAAI,WAAU,sBAAsB,UAAA3B,EAAQ,cAAa;AAAA,UAC1D,gBAAA2B,EAAC,OAAA,EAAI,WAAU,wCAAuC,UAAA,gBAAA,CAAa;AAAA,QAAA,GACrE;AAAA,QACA,gBAAAE,EAAC,OAAA,EAAI,WAAU,oDACb,UAAA;AAAA,UAAA,gBAAAF,EAAC,OAAA,EAAI,WAAU,iDAAiD,UAAA3B,EAAQ,kBAAiB;AAAA,UACzF,gBAAA2B,EAAC,OAAA,EAAI,WAAU,wCAAuC,UAAA,aAAA,CAAU;AAAA,QAAA,GAClE;AAAA,QACA,gBAAAE,EAAC,OAAA,EAAI,WAAU,oDACb,UAAA;AAAA,UAAA,gBAAAF,EAAC,OAAA,EAAI,WAAU,+CAA+C,UAAA3B,EAAQ,iBAAgB;AAAA,UACtF,gBAAA2B,EAAC,OAAA,EAAI,WAAU,wCAAuC,UAAA,WAAA,CAAQ;AAAA,QAAA,GAChE;AAAA,QACA,gBAAAE,EAAC,OAAA,EAAI,WAAU,oDACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAW,sBAAsB7B,EAAQ,2BAA2B,KAAK,+BAA+B,4BAA4B,IACtI,UAAA;AAAA,YAAAA,EAAQ,wBAAwB,QAAQ,CAAC;AAAA,YAAE;AAAA,UAAA,GAC9C;AAAA,UACA,gBAAA2B,EAAC,OAAA,EAAI,WAAU,wCAAuC,UAAA,aAAA,CAAU;AAAA,QAAA,EAAA,CAClE;AAAA,MAAA,GACF;AAAA,MAGC,OAAO,KAAK3B,EAAQ,kBAAkB,EAAE,SAAS,KAChD,gBAAA6B,EAAC,OAAA,EAAI,WAAU,mDACb,UAAA;AAAA,QAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,4BAA2B,UAAA,wBAAoB;AAAA,0BAC5D,OAAA,EAAI,WAAU,cACZ,UAAA,OAAO,QAAQ3B,EAAQ,kBAAkB,EAAE,IAAI,CAAC,CAACoB,GAAUa,CAAK,MAC/D,gBAAAJ,EAAC,OAAA,EAAmB,WAAU,2BAC5B,UAAA;AAAA,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,WAAW,UAAA;AAAA,YAAAT;AAAA,YAAS;AAAA,UAAA,GAAC;AAAA,UACrC,gBAAAO,EAAC,QAAA,EAAK,WAAU,wCAAwC,UAAAM,EAAA,CAAM;AAAA,QAAA,EAAA,GAFtDb,CAGV,CACD,EAAA,CACH;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,GAEJ;AAAA,IAIF,gBAAAS,EAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,6CACb,UAAA;AAAA,QAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,iBAAgB,UAAA,+BAA2B;AAAA,QACzD,gBAAAA,EAAC,KAAA,EAAE,WAAU,wCAAuC,UAAA,2FAAA,CAEpD;AAAA,MAAA,GACF;AAAA,wBAEC,OAAA,EAAI,WAAU,mBACb,UAAA,gBAAAE,EAAC,SAAA,EAAM,WAAU,UACf,UAAA;AAAA,QAAA,gBAAAF,EAAC,SAAA,EACC,UAAA,gBAAAE,EAAC,MAAA,EAAG,WAAU,kEACZ,UAAA;AAAA,UAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,YAAQ;AAAA,UAClD,gBAAAA,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,iBAAa;AAAA,UACvD,gBAAAA,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,mBAAe;AAAA,UACzD,gBAAAA,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,UAAM;AAAA,UAChD,gBAAAA,EAAC,MAAA,EAAG,WAAU,8BAA6B,UAAA,UAAA,CAAO;AAAA,QAAA,EAAA,CACpD,EAAA,CACF;AAAA,QACA,gBAAAA,EAAC,SAAA,EACE,UAAA/B,EAAQ,IAAI,CAAC8B,MAAW;AACvB,gBAAMX,IAASb,EAAcwB,EAAO,QAAQ,GACtCQ,IAAUT,EAAWC,EAAO,QAAQ;AAE1C,iBACE,gBAAAG,EAAC,MAAA,EAAmB,WAAU,yCAC5B,UAAA;AAAA,YAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,OACZ,UAAA,gBAAAA,EAAC,UAAK,WAAW,wFACfD,EAAO,aAAa,aAAa,kDACjCA,EAAO,aAAa,UACpBA,EAAO,aAAa,WADS,sDAE7B,6CACF,IACG,UAAAA,EAAO,SAAA,CACV,EAAA,CACF;AAAA,8BACC,MAAA,EAAG,WAAU,OACZ,UAAA,gBAAAG,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,cAAA,gBAAAF;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,KAAI;AAAA,kBACJ,OAAOZ,GAAQ,YAAYW,EAAO;AAAA,kBAClC,UAAU,CAACS,MACTd,EAAkBK,EAAO,UAAU,YAAY,SAASS,EAAE,OAAO,KAAK,KAAK,CAAC;AAAA,kBAE9E,WAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEZ,gBAAAR,EAAC,QAAA,EAAK,WAAU,wCAAuC,UAAA,WAAO;AAAA,cAC9D,gBAAAE,EAAC,QAAA,EAAK,WAAU,6CAA4C,UAAA;AAAA,gBAAA;AAAA,gBACxDH,EAAO;AAAA,gBAAsB;AAAA,cAAA,EAAA,CACjC;AAAA,YAAA,EAAA,CACF,EAAA,CACF;AAAA,8BACC,MAAA,EAAG,WAAU,OACZ,UAAA,gBAAAG,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,cAAA,gBAAAF;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,KAAI;AAAA,kBACJ,OAAOZ,GAAQ,cAAcW,EAAO;AAAA,kBACpC,UAAU,CAACS,MACTd,EAAkBK,EAAO,UAAU,cAAc,SAASS,EAAE,OAAO,KAAK,KAAK,CAAC;AAAA,kBAEhF,WAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEZ,gBAAAR,EAAC,QAAA,EAAK,WAAU,wCAAuC,UAAA,WAAO;AAAA,cAC9D,gBAAAE,EAAC,QAAA,EAAK,WAAU,6CAA4C,UAAA;AAAA,gBAAA;AAAA,gBACxDH,EAAO;AAAA,gBAAwB;AAAA,cAAA,EAAA,CACnC;AAAA,YAAA,EAAA,CACF,EAAA,CACF;AAAA,8BACC,MAAA,EAAG,WAAU,OACX,UAAAA,EAAO,WACN,gBAAAC,EAAC,QAAA,EAAK,WAAU,wGAAuG,oBAEvH,IAEA,gBAAAA,EAAC,UAAK,WAAU,4GAA2G,sBAE3H,EAAA,CAEJ;AAAA,YACA,gBAAAA,EAAC,MAAA,EAAG,WAAU,kBACZ,UAAA,gBAAAE;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,MAAMV,EAAWO,EAAO,QAAQ;AAAA,gBACzC,UAAU,CAACQ,KAAWxC,MAAWgC,EAAO;AAAA,gBACxC,WAAW,OAAOQ,IAAU,gBAAgB,eAAe;AAAA,gBAE1D,UAAA;AAAA,kBAAAxC,MAAWgC,EAAO,WACjB,gBAAAC,EAACC,GAAA,EAAQ,WAAU,wBAAuB,IAE1C,gBAAAD,EAACS,GAAA,EAAK,WAAU,UAAA,CAAU;AAAA,kBAC1B;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA,EAEJ,CACF;AAAA,UAAA,EAAA,GArEOV,EAAO,EAsEhB;AAAA,QAEJ,CAAC,EAAA,CACH;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAGA,gBAAAG,EAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,6CACb,UAAA;AAAA,QAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,iBAAgB,UAAA,oBAAgB;AAAA,QAC9C,gBAAAA,EAAC,KAAA,EAAE,WAAU,wCAAuC,UAAA,oDAAA,CAEpD;AAAA,MAAA,GACF;AAAA,MAEC7B,EAAgB,SAAS,IACxB,gBAAA6B,EAAC,OAAA,EAAI,WAAU,mBACb,UAAA,gBAAAE,EAAC,SAAA,EAAM,WAAU,UACf,UAAA;AAAA,QAAA,gBAAAF,EAAC,SAAA,EACC,UAAA,gBAAAE,EAAC,MAAA,EAAG,WAAU,kEACZ,UAAA;AAAA,UAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,SAAK;AAAA,UAC/C,gBAAAA,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,WAAO;AAAA,UACjD,gBAAAA,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,sBAAkB;AAAA,UAC5D,gBAAAA,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,SAAA,CAAM;AAAA,QAAA,EAAA,CAClD,EAAA,CACF;AAAA,QACA,gBAAAA,EAAC,WACE,UAAA7B,EAAgB,IAAI,CAACuC,MACpB,gBAAAR,EAAC,MAAA,EAAiB,WAAU,yCAC1B,UAAA;AAAA,UAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,OACZ,UAAA,gBAAAA,EAAC,UAAK,WAAU,eAAe,UAAAU,EAAK,MAAA,CAAM,EAAA,CAC5C;AAAA,UACA,gBAAAV,EAAC,MAAA,EAAG,WAAU,OACZ,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,WAAW,UAAAW,EAAkBD,EAAK,WAAW,EAAA,CAAE,GACjE;AAAA,UACA,gBAAAV,EAAC,MAAA,EAAG,WAAU,OACZ,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,WAAW,UAAAY,EAAcF,EAAK,uBAAuB,EAAA,CAAE,GACzE;AAAA,4BACC,MAAA,EAAG,WAAU,OACX,UAAAA,EAAK,WACJ,gBAAAV,EAAC,QAAA,EAAK,WAAU,wGAAuG,oBAEvH,IAEA,gBAAAA,EAAC,UAAK,WAAU,4GAA2G,sBAE3H,EAAA,CAEJ;AAAA,QAAA,KApBOU,EAAK,EAqBd,CACD,EAAA,CACH;AAAA,MAAA,EAAA,CACF,EAAA,CACF,IAEA,gBAAAR,EAAC,OAAA,EAAI,WAAU,gDACb,UAAA;AAAA,QAAA,gBAAAF,EAACa,GAAA,EAAc,WAAU,oCAAA,CAAoC;AAAA,QAC7D,gBAAAb,EAAC,OAAE,UAAA,iCAAA,CAA8B;AAAA,MAAA,EAAA,CACnC;AAAA,IAAA,GAEJ;AAAA,IAGA,gBAAAE,EAAC,OAAA,EAAI,WAAU,4DACb,UAAA;AAAA,MAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,8CAA6C,UAAA,2BAAuB;AAAA,MAClF,gBAAAE,EAAC,MAAA,EAAG,WAAU,6CACZ,UAAA;AAAA,QAAA,gBAAAA,EAAC,MAAA,EACC,UAAA;AAAA,UAAA,gBAAAF,EAAC,YAAO,UAAA,iBAAA,CAAc;AAAA,UAAS;AAAA,QAAA,GACjC;AAAA,0BACC,MAAA,EACC,UAAA;AAAA,UAAA,gBAAAA,EAAC,YAAO,UAAA,mBAAA,CAAgB;AAAA,UAAS;AAAA,QAAA,GACnC;AAAA,0BACC,MAAA,EACC,UAAA;AAAA,UAAA,gBAAAA,EAAC,YAAO,UAAA,aAAA,CAAU;AAAA,UAAS;AAAA,QAAA,GAC7B;AAAA,0BACC,MAAA,EACC,UAAA;AAAA,UAAA,gBAAAA,EAAC,YAAO,UAAA,cAAA,CAAW;AAAA,UAAS;AAAA,QAAA,EAAA,CAC9B;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAEA,SAASW,EAAkBG,GAAsB;AAC/C,UAAQA,GAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAOA;AAAA,EAAA;AAEb;AAEA,SAASF,EAAcG,GAAyB;AAC9C,MAAIA,IAAU,GAAI,QAAO,GAAGA,CAAO;AACnC,QAAMC,IAAQ,KAAK,MAAMD,IAAU,EAAE,GAC/BE,IAAOF,IAAU;AACvB,MAAIC,IAAQ,GAAI,QAAOC,IAAO,IAAI,GAAGD,CAAK,KAAKC,CAAI,MAAM,GAAGD,CAAK;AACjE,QAAME,IAAO,KAAK,MAAMF,IAAQ,EAAE,GAC5BG,IAAiBH,IAAQ;AAC/B,SAAOG,IAAiB,IAAI,GAAGD,CAAI,KAAKC,CAAc,MAAM,GAAGD,CAAI;AACrE;"}
|
|
1
|
+
{"version":3,"file":"SlaConfigPage-B4WDzEKi.js","sources":["../../src/pages/platform/support/SlaConfigPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Clock, Save, AlertTriangle, Loader2, Check } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport {\r\n slaApi,\r\n type SlaConfigurationDto,\r\n type EscalationRuleDto,\r\n type SlaMetricsDto,\r\n} from '@/services/api/supportApi';\r\n\r\nconst priorityOrder = ['Critical', 'High', 'Medium', 'Low'];\r\n\r\nexport function SlaConfigPage(): ReactElement {\r\n const { t } = useTranslation('support');\r\n const [loading, setLoading] = useState(true);\r\n const [saving, setSaving] = useState<string | null>(null);\r\n const [configs, setConfigs] = useState<SlaConfigurationDto[]>([]);\r\n const [escalationRules, setEscalationRules] = useState<EscalationRuleDto[]>([]);\r\n const [metrics, setMetrics] = useState<SlaMetricsDto | null>(null);\r\n const [editedConfigs, setEditedConfigs] = useState<Record<string, { response: number; resolution: number }>>({});\r\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const [configsRes, rulesRes, metricsRes] = await Promise.all([\r\n slaApi.getConfigurations(),\r\n slaApi.getEscalationRules(),\r\n slaApi.getMetrics(),\r\n ]);\r\n\r\n // Sort by priority order\r\n const sorted = [...configsRes].sort(\r\n (a, b) => priorityOrder.indexOf(a.priority) - priorityOrder.indexOf(b.priority)\r\n );\r\n\r\n setConfigs(sorted);\r\n setEscalationRules(rulesRes);\r\n setMetrics(metricsRes);\r\n\r\n // Initialize edited values\r\n const edited: Record<string, { response: number; resolution: number }> = {};\r\n sorted.forEach((c) => {\r\n edited[c.priority] = {\r\n response: c.responseTimeMinutes,\r\n resolution: c.resolutionTimeMinutes,\r\n };\r\n });\r\n setEditedConfigs(edited);\r\n } catch (error) {\r\n console.error('Failed to load SLA configurations:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n const handleSave = async (priority: string) => {\r\n const edited = editedConfigs[priority];\r\n if (!edited) return;\r\n\r\n try {\r\n setSaving(priority);\r\n await slaApi.updateConfiguration(priority, {\r\n responseTimeMinutes: edited.response,\r\n resolutionTimeMinutes: edited.resolution,\r\n });\r\n\r\n // Reload to get updated formatted strings\r\n await loadData();\r\n\r\n setSuccessMessage(`${priority} SLA configuration saved successfully`);\r\n setTimeout(() => setSuccessMessage(null), 3000);\r\n } catch (error) {\r\n console.error('Failed to save SLA configuration:', error);\r\n } finally {\r\n setSaving(null);\r\n }\r\n };\r\n\r\n const handleInputChange = (priority: string, field: 'response' | 'resolution', value: number) => {\r\n setEditedConfigs((prev) => ({\r\n ...prev,\r\n [priority]: {\r\n ...prev[priority],\r\n [field]: value,\r\n },\r\n }));\r\n };\r\n\r\n const hasChanges = (priority: string) => {\r\n const config = configs.find((c) => c.priority === priority);\r\n const edited = editedConfigs[priority];\r\n if (!config || !edited) return false;\r\n return (\r\n config.responseTimeMinutes !== edited.response ||\r\n config.resolutionTimeMinutes !== edited.resolution\r\n );\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('title', 'Support'), href: '/support' },\r\n { label: t('sla.title', 'SLA Configuration') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div>\r\n <h1 className=\"text-2xl font-bold flex items-center gap-2\">\r\n <Clock className=\"w-6 h-6\" />\r\n {t('sla.title', 'SLA Configuration')}\r\n </h1>\r\n <p className=\"text-[var(--text-secondary)]\">\r\n Configure Service Level Agreements for ticket response and resolution times\r\n </p>\r\n </div>\r\n\r\n {/* Success Message */}\r\n {successMessage && (\r\n <div className=\"bg-[var(--success-bg)] border border-[var(--success-border)] text-[var(--success-text)] px-4 py-3 rounded flex items-center gap-2\">\r\n <Check className=\"w-5 h-5\" />\r\n {successMessage}\r\n </div>\r\n )}\r\n\r\n {/* SLA Metrics Overview */}\r\n {metrics && (\r\n <div className=\"card p-4\">\r\n <h2 className=\"font-semibold mb-4\">Current SLA Performance</h2>\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\r\n <div className=\"text-center p-3 bg-[var(--bg-secondary)] rounded\">\r\n <div className=\"text-2xl font-bold\">{metrics.totalTickets}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">Total Tickets</div>\r\n </div>\r\n <div className=\"text-center p-3 bg-[var(--bg-secondary)] rounded\">\r\n <div className=\"text-2xl font-bold text-[var(--success-text)]\">{metrics.ticketsWithinSla}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">Within SLA</div>\r\n </div>\r\n <div className=\"text-center p-3 bg-[var(--bg-secondary)] rounded\">\r\n <div className=\"text-2xl font-bold text-[var(--error-text)]\">{metrics.ticketsBreached}</div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">Breached</div>\r\n </div>\r\n <div className=\"text-center p-3 bg-[var(--bg-secondary)] rounded\">\r\n <div className={`text-2xl font-bold ${metrics.slaCompliancePercentage >= 90 ? 'text-[var(--success-text)]' : 'text-[var(--warning-text)]'}`}>\r\n {metrics.slaCompliancePercentage.toFixed(1)}%\r\n </div>\r\n <div className=\"text-sm text-[var(--text-secondary)]\">Compliance</div>\r\n </div>\r\n </div>\r\n\r\n {/* Breaches by Priority */}\r\n {Object.keys(metrics.breachesByPriority).length > 0 && (\r\n <div className=\"mt-4 pt-4 border-t border-[var(--border-color)]\">\r\n <h3 className=\"text-sm font-medium mb-2\">Breaches by Priority</h3>\r\n <div className=\"flex gap-4\">\r\n {Object.entries(metrics.breachesByPriority).map(([priority, count]) => (\r\n <div key={priority} className=\"flex items-center gap-2\">\r\n <span className=\"text-sm\">{priority}:</span>\r\n <span className=\"font-medium text-[var(--error-text)]\">{count}</span>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* SLA Configurations */}\r\n <div className=\"card\">\r\n <div className=\"p-4 border-b border-[var(--border-color)]\">\r\n <h2 className=\"font-semibold\">Response & Resolution Times</h2>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n Define the maximum time allowed for initial response and complete resolution by priority\r\n </p>\r\n </div>\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)] bg-[var(--bg-secondary)]\">\r\n <th className=\"text-left p-4 font-medium\">Priority</th>\r\n <th className=\"text-left p-4 font-medium\">Response Time</th>\r\n <th className=\"text-left p-4 font-medium\">Resolution Time</th>\r\n <th className=\"text-left p-4 font-medium\">Status</th>\r\n <th className=\"text-right p-4 font-medium\">Actions</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {configs.map((config) => {\r\n const edited = editedConfigs[config.priority];\r\n const changed = hasChanges(config.priority);\r\n\r\n return (\r\n <tr key={config.id} className=\"border-b border-[var(--border-color)]\">\r\n <td className=\"p-4\">\r\n <span className={`inline-flex items-center px-3 py-1 rounded-[var(--radius-badge)] font-medium text-sm ${\r\n config.priority === 'Critical' ? 'bg-[var(--error-bg)] text-[var(--error-text)]' :\r\n config.priority === 'High' ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]' :\r\n config.priority === 'Medium' ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]' :\r\n 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n }`}>\r\n {config.priority}\r\n </span>\r\n </td>\r\n <td className=\"p-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n value={edited?.response ?? config.responseTimeMinutes}\r\n onChange={(e) =>\r\n handleInputChange(config.priority, 'response', parseInt(e.target.value) || 0)\r\n }\r\n className=\"input w-24\"\r\n />\r\n <span className=\"text-sm text-[var(--text-secondary)]\">minutes</span>\r\n <span className=\"text-sm text-[var(--text-secondary)] ml-2\">\r\n ({config.responseTimeFormatted})\r\n </span>\r\n </div>\r\n </td>\r\n <td className=\"p-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n value={edited?.resolution ?? config.resolutionTimeMinutes}\r\n onChange={(e) =>\r\n handleInputChange(config.priority, 'resolution', parseInt(e.target.value) || 0)\r\n }\r\n className=\"input w-24\"\r\n />\r\n <span className=\"text-sm text-[var(--text-secondary)]\">minutes</span>\r\n <span className=\"text-sm text-[var(--text-secondary)] ml-2\">\r\n ({config.resolutionTimeFormatted})\r\n </span>\r\n </div>\r\n </td>\r\n <td className=\"p-4\">\r\n {config.isActive ? (\r\n <span className=\"inline-flex items-center px-2 py-1 rounded bg-[var(--success-bg)] text-[var(--success-text)] text-sm\">\r\n Active\r\n </span>\r\n ) : (\r\n <span className=\"inline-flex items-center px-2 py-1 rounded bg-[var(--bg-secondary)] text-[var(--text-secondary)] text-sm\">\r\n Inactive\r\n </span>\r\n )}\r\n </td>\r\n <td className=\"p-4 text-right\">\r\n <button\r\n onClick={() => handleSave(config.priority)}\r\n disabled={!changed || saving === config.priority}\r\n className={`btn ${changed ? 'btn-primary' : 'btn-secondary'} flex items-center gap-2`}\r\n >\r\n {saving === config.priority ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Save className=\"w-4 h-4\" />\r\n )}\r\n Save\r\n </button>\r\n </td>\r\n </tr>\r\n );\r\n })}\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n\r\n {/* Escalation Rules */}\r\n <div className=\"card\">\r\n <div className=\"p-4 border-b border-[var(--border-color)]\">\r\n <h2 className=\"font-semibold\">Escalation Rules</h2>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n Automatic escalation paths when SLAs are breached\r\n </p>\r\n </div>\r\n\r\n {escalationRules.length > 0 ? (\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)] bg-[var(--bg-secondary)]\">\r\n <th className=\"text-left p-4 font-medium\">Level</th>\r\n <th className=\"text-left p-4 font-medium\">Trigger</th>\r\n <th className=\"text-left p-4 font-medium\">Delay After Breach</th>\r\n <th className=\"text-left p-4 font-medium\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {escalationRules.map((rule) => (\r\n <tr key={rule.id} className=\"border-b border-[var(--border-color)]\">\r\n <td className=\"p-4\">\r\n <span className=\"font-medium\">{rule.level}</span>\r\n </td>\r\n <td className=\"p-4\">\r\n <span className=\"text-sm\">{formatTriggerType(rule.triggerType)}</span>\r\n </td>\r\n <td className=\"p-4\">\r\n <span className=\"text-sm\">{formatMinutes(rule.delayAfterBreachMinutes)}</span>\r\n </td>\r\n <td className=\"p-4\">\r\n {rule.isActive ? (\r\n <span className=\"inline-flex items-center px-2 py-1 rounded bg-[var(--success-bg)] text-[var(--success-text)] text-sm\">\r\n Active\r\n </span>\r\n ) : (\r\n <span className=\"inline-flex items-center px-2 py-1 rounded bg-[var(--bg-secondary)] text-[var(--text-secondary)] text-sm\">\r\n Inactive\r\n </span>\r\n )}\r\n </td>\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n ) : (\r\n <div className=\"p-8 text-center text-[var(--text-secondary)]\">\r\n <AlertTriangle className=\"w-12 h-12 mx-auto mb-4 opacity-50\" />\r\n <p>No escalation rules configured</p>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Help Section */}\r\n <div className=\"card p-4 bg-[var(--info-bg)] border-[var(--info-border)]\">\r\n <h3 className=\"font-semibold text-[var(--info-text)] mb-2\">About SLA Configuration</h3>\r\n <ul className=\"text-sm text-[var(--info-text)] space-y-1\">\r\n <li>\r\n <strong>Response Time:</strong> Maximum time allowed for the first agent response after ticket creation\r\n </li>\r\n <li>\r\n <strong>Resolution Time:</strong> Maximum time allowed to fully resolve and close the ticket\r\n </li>\r\n <li>\r\n <strong>SLA Pause:</strong> SLA timers automatically pause when a ticket is placed On Hold\r\n </li>\r\n <li>\r\n <strong>Escalation:</strong> When SLA is breached, tickets are automatically escalated to higher levels\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction formatTriggerType(type: string): string {\r\n switch (type) {\r\n case 'ResponseBreach':\r\n return 'Response SLA Breached';\r\n case 'ResolutionBreach':\r\n return 'Resolution SLA Breached';\r\n default:\r\n return type;\r\n }\r\n}\r\n\r\nfunction formatMinutes(minutes: number): string {\r\n if (minutes < 60) return `${minutes} minutes`;\r\n const hours = Math.floor(minutes / 60);\r\n const mins = minutes % 60;\r\n if (hours < 24) return mins > 0 ? `${hours}h ${mins}m` : `${hours} hours`;\r\n const days = Math.floor(hours / 24);\r\n const remainingHours = hours % 24;\r\n return remainingHours > 0 ? `${days}d ${remainingHours}h` : `${days} days`;\r\n}\r\n"],"names":["priorityOrder","SlaConfigPage","t","useTranslation","loading","setLoading","useState","saving","setSaving","configs","setConfigs","escalationRules","setEscalationRules","metrics","setMetrics","editedConfigs","setEditedConfigs","successMessage","setSuccessMessage","loadData","useCallback","configsRes","rulesRes","metricsRes","slaApi","sorted","a","b","edited","c","error","useEffect","handleSave","priority","handleInputChange","field","value","prev","hasChanges","config","jsx","Loader2","jsxs","Breadcrumb","Clock","Check","count","changed","e","Save","rule","formatTriggerType","formatMinutes","AlertTriangle","type","minutes","hours","mins","days","remainingHours"],"mappings":";;;;;AAYA,MAAMA,IAAgB,CAAC,YAAY,QAAQ,UAAU,KAAK;AAEnD,SAASC,IAA8B;AAC5C,QAAM,EAAE,GAAAC,EAAA,IAAMC,EAAe,SAAS,GAChC,CAACC,GAASC,CAAU,IAAIC,EAAS,EAAI,GACrC,CAACC,GAAQC,CAAS,IAAIF,EAAwB,IAAI,GAClD,CAACG,GAASC,CAAU,IAAIJ,EAAgC,CAAA,CAAE,GAC1D,CAACK,GAAiBC,CAAkB,IAAIN,EAA8B,CAAA,CAAE,GACxE,CAACO,GAASC,CAAU,IAAIR,EAA+B,IAAI,GAC3D,CAACS,GAAeC,CAAgB,IAAIV,EAAmE,CAAA,CAAE,GACzG,CAACW,GAAgBC,CAAiB,IAAIZ,EAAwB,IAAI,GAElEa,IAAWC,EAAY,YAAY;AACvC,QAAI;AACF,MAAAf,EAAW,EAAI;AACf,YAAM,CAACgB,GAAYC,GAAUC,CAAU,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC3DC,EAAO,kBAAA;AAAA,QACPA,EAAO,mBAAA;AAAA,QACPA,EAAO,WAAA;AAAA,MAAW,CACnB,GAGKC,IAAS,CAAC,GAAGJ,CAAU,EAAE;AAAA,QAC7B,CAACK,GAAGC,MAAM3B,EAAc,QAAQ0B,EAAE,QAAQ,IAAI1B,EAAc,QAAQ2B,EAAE,QAAQ;AAAA,MAAA;AAGhF,MAAAjB,EAAWe,CAAM,GACjBb,EAAmBU,CAAQ,GAC3BR,EAAWS,CAAU;AAGrB,YAAMK,IAAmE,CAAA;AACzE,MAAAH,EAAO,QAAQ,CAACI,MAAM;AACpB,QAAAD,EAAOC,EAAE,QAAQ,IAAI;AAAA,UACnB,UAAUA,EAAE;AAAA,UACZ,YAAYA,EAAE;AAAA,QAAA;AAAA,MAElB,CAAC,GACDb,EAAiBY,CAAM;AAAA,IACzB,SAASE,GAAO;AACd,cAAQ,MAAM,sCAAsCA,CAAK;AAAA,IAC3D,UAAA;AACE,MAAAzB,EAAW,EAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAA,CAAE;AAEL,EAAA0B,EAAU,MAAM;AACd,IAAAZ,EAAA;AAAA,EACF,GAAG,CAACA,CAAQ,CAAC;AAEb,QAAMa,IAAa,OAAOC,MAAqB;AAC7C,UAAML,IAASb,EAAckB,CAAQ;AACrC,QAAKL;AAEL,UAAI;AACF,QAAApB,EAAUyB,CAAQ,GAClB,MAAMT,EAAO,oBAAoBS,GAAU;AAAA,UACzC,qBAAqBL,EAAO;AAAA,UAC5B,uBAAuBA,EAAO;AAAA,QAAA,CAC/B,GAGD,MAAMT,EAAA,GAEND,EAAkB,GAAGe,CAAQ,uCAAuC,GACpE,WAAW,MAAMf,EAAkB,IAAI,GAAG,GAAI;AAAA,MAChD,SAASY,GAAO;AACd,gBAAQ,MAAM,qCAAqCA,CAAK;AAAA,MAC1D,UAAA;AACE,QAAAtB,EAAU,IAAI;AAAA,MAChB;AAAA,EACF,GAEM0B,IAAoB,CAACD,GAAkBE,GAAkCC,MAAkB;AAC/F,IAAApB,EAAiB,CAACqB,OAAU;AAAA,MAC1B,GAAGA;AAAA,MACH,CAACJ,CAAQ,GAAG;AAAA,QACV,GAAGI,EAAKJ,CAAQ;AAAA,QAChB,CAACE,CAAK,GAAGC;AAAA,MAAA;AAAA,IACX,EACA;AAAA,EACJ,GAEME,IAAa,CAACL,MAAqB;AACvC,UAAMM,IAAS9B,EAAQ,KAAK,CAACoB,MAAMA,EAAE,aAAaI,CAAQ,GACpDL,IAASb,EAAckB,CAAQ;AACrC,WAAI,CAACM,KAAU,CAACX,IAAe,KAE7BW,EAAO,wBAAwBX,EAAO,YACtCW,EAAO,0BAA0BX,EAAO;AAAA,EAE5C;AAEA,SAAIxB,IAEA,gBAAAoC,EAAC,SAAI,WAAU,kDACb,4BAACC,GAAA,EAAQ,WAAU,wDAAuD,EAAA,CAC5E,IAKF,gBAAAC,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAAF;AAAA,MAACG;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,EAAE,OAAOzC,EAAE,SAAS,SAAS,GAAG,MAAM,WAAA;AAAA,UACtC,EAAE,OAAOA,EAAE,aAAa,mBAAmB,EAAA;AAAA,QAAE;AAAA,MAC/C;AAAA,IAAA;AAAA,sBAID,OAAA,EACC,UAAA;AAAA,MAAA,gBAAAwC,EAAC,MAAA,EAAG,WAAU,8CACZ,UAAA;AAAA,QAAA,gBAAAF,EAACI,GAAA,EAAM,WAAU,UAAA,CAAU;AAAA,QAC1B1C,EAAE,aAAa,mBAAmB;AAAA,MAAA,GACrC;AAAA,MACA,gBAAAsC,EAAC,KAAA,EAAE,WAAU,gCAA+B,UAAA,8EAAA,CAE5C;AAAA,IAAA,GACF;AAAA,IAGCvB,KACC,gBAAAyB,EAAC,OAAA,EAAI,WAAU,qIACb,UAAA;AAAA,MAAA,gBAAAF,EAACK,GAAA,EAAM,WAAU,UAAA,CAAU;AAAA,MAC1B5B;AAAA,IAAA,GACH;AAAA,IAIDJ,KACC,gBAAA6B,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,MAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,sBAAqB,UAAA,2BAAuB;AAAA,MAC1D,gBAAAE,EAAC,OAAA,EAAI,WAAU,yCACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oDACb,UAAA;AAAA,UAAA,gBAAAF,EAAC,OAAA,EAAI,WAAU,sBAAsB,UAAA3B,EAAQ,cAAa;AAAA,UAC1D,gBAAA2B,EAAC,OAAA,EAAI,WAAU,wCAAuC,UAAA,gBAAA,CAAa;AAAA,QAAA,GACrE;AAAA,QACA,gBAAAE,EAAC,OAAA,EAAI,WAAU,oDACb,UAAA;AAAA,UAAA,gBAAAF,EAAC,OAAA,EAAI,WAAU,iDAAiD,UAAA3B,EAAQ,kBAAiB;AAAA,UACzF,gBAAA2B,EAAC,OAAA,EAAI,WAAU,wCAAuC,UAAA,aAAA,CAAU;AAAA,QAAA,GAClE;AAAA,QACA,gBAAAE,EAAC,OAAA,EAAI,WAAU,oDACb,UAAA;AAAA,UAAA,gBAAAF,EAAC,OAAA,EAAI,WAAU,+CAA+C,UAAA3B,EAAQ,iBAAgB;AAAA,UACtF,gBAAA2B,EAAC,OAAA,EAAI,WAAU,wCAAuC,UAAA,WAAA,CAAQ;AAAA,QAAA,GAChE;AAAA,QACA,gBAAAE,EAAC,OAAA,EAAI,WAAU,oDACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAW,sBAAsB7B,EAAQ,2BAA2B,KAAK,+BAA+B,4BAA4B,IACtI,UAAA;AAAA,YAAAA,EAAQ,wBAAwB,QAAQ,CAAC;AAAA,YAAE;AAAA,UAAA,GAC9C;AAAA,UACA,gBAAA2B,EAAC,OAAA,EAAI,WAAU,wCAAuC,UAAA,aAAA,CAAU;AAAA,QAAA,EAAA,CAClE;AAAA,MAAA,GACF;AAAA,MAGC,OAAO,KAAK3B,EAAQ,kBAAkB,EAAE,SAAS,KAChD,gBAAA6B,EAAC,OAAA,EAAI,WAAU,mDACb,UAAA;AAAA,QAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,4BAA2B,UAAA,wBAAoB;AAAA,0BAC5D,OAAA,EAAI,WAAU,cACZ,UAAA,OAAO,QAAQ3B,EAAQ,kBAAkB,EAAE,IAAI,CAAC,CAACoB,GAAUa,CAAK,MAC/D,gBAAAJ,EAAC,OAAA,EAAmB,WAAU,2BAC5B,UAAA;AAAA,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,WAAW,UAAA;AAAA,YAAAT;AAAA,YAAS;AAAA,UAAA,GAAC;AAAA,UACrC,gBAAAO,EAAC,QAAA,EAAK,WAAU,wCAAwC,UAAAM,EAAA,CAAM;AAAA,QAAA,EAAA,GAFtDb,CAGV,CACD,EAAA,CACH;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,GAEJ;AAAA,IAIF,gBAAAS,EAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,6CACb,UAAA;AAAA,QAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,iBAAgB,UAAA,+BAA2B;AAAA,QACzD,gBAAAA,EAAC,KAAA,EAAE,WAAU,wCAAuC,UAAA,2FAAA,CAEpD;AAAA,MAAA,GACF;AAAA,wBAEC,OAAA,EAAI,WAAU,mBACb,UAAA,gBAAAE,EAAC,SAAA,EAAM,WAAU,UACf,UAAA;AAAA,QAAA,gBAAAF,EAAC,SAAA,EACC,UAAA,gBAAAE,EAAC,MAAA,EAAG,WAAU,kEACZ,UAAA;AAAA,UAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,YAAQ;AAAA,UAClD,gBAAAA,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,iBAAa;AAAA,UACvD,gBAAAA,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,mBAAe;AAAA,UACzD,gBAAAA,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,UAAM;AAAA,UAChD,gBAAAA,EAAC,MAAA,EAAG,WAAU,8BAA6B,UAAA,UAAA,CAAO;AAAA,QAAA,EAAA,CACpD,EAAA,CACF;AAAA,QACA,gBAAAA,EAAC,SAAA,EACE,UAAA/B,EAAQ,IAAI,CAAC8B,MAAW;AACvB,gBAAMX,IAASb,EAAcwB,EAAO,QAAQ,GACtCQ,IAAUT,EAAWC,EAAO,QAAQ;AAE1C,iBACE,gBAAAG,EAAC,MAAA,EAAmB,WAAU,yCAC5B,UAAA;AAAA,YAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,OACZ,UAAA,gBAAAA,EAAC,UAAK,WAAW,wFACfD,EAAO,aAAa,aAAa,kDACjCA,EAAO,aAAa,UACpBA,EAAO,aAAa,WADS,sDAE7B,6CACF,IACG,UAAAA,EAAO,SAAA,CACV,EAAA,CACF;AAAA,8BACC,MAAA,EAAG,WAAU,OACZ,UAAA,gBAAAG,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,cAAA,gBAAAF;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,KAAI;AAAA,kBACJ,OAAOZ,GAAQ,YAAYW,EAAO;AAAA,kBAClC,UAAU,CAACS,MACTd,EAAkBK,EAAO,UAAU,YAAY,SAASS,EAAE,OAAO,KAAK,KAAK,CAAC;AAAA,kBAE9E,WAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEZ,gBAAAR,EAAC,QAAA,EAAK,WAAU,wCAAuC,UAAA,WAAO;AAAA,cAC9D,gBAAAE,EAAC,QAAA,EAAK,WAAU,6CAA4C,UAAA;AAAA,gBAAA;AAAA,gBACxDH,EAAO;AAAA,gBAAsB;AAAA,cAAA,EAAA,CACjC;AAAA,YAAA,EAAA,CACF,EAAA,CACF;AAAA,8BACC,MAAA,EAAG,WAAU,OACZ,UAAA,gBAAAG,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,cAAA,gBAAAF;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,KAAI;AAAA,kBACJ,OAAOZ,GAAQ,cAAcW,EAAO;AAAA,kBACpC,UAAU,CAACS,MACTd,EAAkBK,EAAO,UAAU,cAAc,SAASS,EAAE,OAAO,KAAK,KAAK,CAAC;AAAA,kBAEhF,WAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEZ,gBAAAR,EAAC,QAAA,EAAK,WAAU,wCAAuC,UAAA,WAAO;AAAA,cAC9D,gBAAAE,EAAC,QAAA,EAAK,WAAU,6CAA4C,UAAA;AAAA,gBAAA;AAAA,gBACxDH,EAAO;AAAA,gBAAwB;AAAA,cAAA,EAAA,CACnC;AAAA,YAAA,EAAA,CACF,EAAA,CACF;AAAA,8BACC,MAAA,EAAG,WAAU,OACX,UAAAA,EAAO,WACN,gBAAAC,EAAC,QAAA,EAAK,WAAU,wGAAuG,oBAEvH,IAEA,gBAAAA,EAAC,UAAK,WAAU,4GAA2G,sBAE3H,EAAA,CAEJ;AAAA,YACA,gBAAAA,EAAC,MAAA,EAAG,WAAU,kBACZ,UAAA,gBAAAE;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,MAAMV,EAAWO,EAAO,QAAQ;AAAA,gBACzC,UAAU,CAACQ,KAAWxC,MAAWgC,EAAO;AAAA,gBACxC,WAAW,OAAOQ,IAAU,gBAAgB,eAAe;AAAA,gBAE1D,UAAA;AAAA,kBAAAxC,MAAWgC,EAAO,WACjB,gBAAAC,EAACC,GAAA,EAAQ,WAAU,wBAAuB,IAE1C,gBAAAD,EAACS,GAAA,EAAK,WAAU,UAAA,CAAU;AAAA,kBAC1B;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA,EAEJ,CACF;AAAA,UAAA,EAAA,GArEOV,EAAO,EAsEhB;AAAA,QAEJ,CAAC,EAAA,CACH;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAGA,gBAAAG,EAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,6CACb,UAAA;AAAA,QAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,iBAAgB,UAAA,oBAAgB;AAAA,QAC9C,gBAAAA,EAAC,KAAA,EAAE,WAAU,wCAAuC,UAAA,oDAAA,CAEpD;AAAA,MAAA,GACF;AAAA,MAEC7B,EAAgB,SAAS,IACxB,gBAAA6B,EAAC,OAAA,EAAI,WAAU,mBACb,UAAA,gBAAAE,EAAC,SAAA,EAAM,WAAU,UACf,UAAA;AAAA,QAAA,gBAAAF,EAAC,SAAA,EACC,UAAA,gBAAAE,EAAC,MAAA,EAAG,WAAU,kEACZ,UAAA;AAAA,UAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,SAAK;AAAA,UAC/C,gBAAAA,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,WAAO;AAAA,UACjD,gBAAAA,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,sBAAkB;AAAA,UAC5D,gBAAAA,EAAC,MAAA,EAAG,WAAU,6BAA4B,UAAA,SAAA,CAAM;AAAA,QAAA,EAAA,CAClD,EAAA,CACF;AAAA,QACA,gBAAAA,EAAC,WACE,UAAA7B,EAAgB,IAAI,CAACuC,MACpB,gBAAAR,EAAC,MAAA,EAAiB,WAAU,yCAC1B,UAAA;AAAA,UAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,OACZ,UAAA,gBAAAA,EAAC,UAAK,WAAU,eAAe,UAAAU,EAAK,MAAA,CAAM,EAAA,CAC5C;AAAA,UACA,gBAAAV,EAAC,MAAA,EAAG,WAAU,OACZ,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,WAAW,UAAAW,EAAkBD,EAAK,WAAW,EAAA,CAAE,GACjE;AAAA,UACA,gBAAAV,EAAC,MAAA,EAAG,WAAU,OACZ,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,WAAW,UAAAY,EAAcF,EAAK,uBAAuB,EAAA,CAAE,GACzE;AAAA,4BACC,MAAA,EAAG,WAAU,OACX,UAAAA,EAAK,WACJ,gBAAAV,EAAC,QAAA,EAAK,WAAU,wGAAuG,oBAEvH,IAEA,gBAAAA,EAAC,UAAK,WAAU,4GAA2G,sBAE3H,EAAA,CAEJ;AAAA,QAAA,KApBOU,EAAK,EAqBd,CACD,EAAA,CACH;AAAA,MAAA,EAAA,CACF,EAAA,CACF,IAEA,gBAAAR,EAAC,OAAA,EAAI,WAAU,gDACb,UAAA;AAAA,QAAA,gBAAAF,EAACa,GAAA,EAAc,WAAU,oCAAA,CAAoC;AAAA,QAC7D,gBAAAb,EAAC,OAAE,UAAA,iCAAA,CAA8B;AAAA,MAAA,EAAA,CACnC;AAAA,IAAA,GAEJ;AAAA,IAGA,gBAAAE,EAAC,OAAA,EAAI,WAAU,4DACb,UAAA;AAAA,MAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,8CAA6C,UAAA,2BAAuB;AAAA,MAClF,gBAAAE,EAAC,MAAA,EAAG,WAAU,6CACZ,UAAA;AAAA,QAAA,gBAAAA,EAAC,MAAA,EACC,UAAA;AAAA,UAAA,gBAAAF,EAAC,YAAO,UAAA,iBAAA,CAAc;AAAA,UAAS;AAAA,QAAA,GACjC;AAAA,0BACC,MAAA,EACC,UAAA;AAAA,UAAA,gBAAAA,EAAC,YAAO,UAAA,mBAAA,CAAgB;AAAA,UAAS;AAAA,QAAA,GACnC;AAAA,0BACC,MAAA,EACC,UAAA;AAAA,UAAA,gBAAAA,EAAC,YAAO,UAAA,aAAA,CAAU;AAAA,UAAS;AAAA,QAAA,GAC7B;AAAA,0BACC,MAAA,EACC,UAAA;AAAA,UAAA,gBAAAA,EAAC,YAAO,UAAA,cAAA,CAAW;AAAA,UAAS;AAAA,QAAA,EAAA,CAC9B;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAEA,SAASW,EAAkBG,GAAsB;AAC/C,UAAQA,GAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAOA;AAAA,EAAA;AAEb;AAEA,SAASF,EAAcG,GAAyB;AAC9C,MAAIA,IAAU,GAAI,QAAO,GAAGA,CAAO;AACnC,QAAMC,IAAQ,KAAK,MAAMD,IAAU,EAAE,GAC/BE,IAAOF,IAAU;AACvB,MAAIC,IAAQ,GAAI,QAAOC,IAAO,IAAI,GAAGD,CAAK,KAAKC,CAAI,MAAM,GAAGD,CAAK;AACjE,QAAME,IAAO,KAAK,MAAMF,IAAQ,EAAE,GAC5BG,IAAiBH,IAAQ;AAC/B,SAAOG,IAAiB,IAAI,GAAGD,CAAI,KAAKC,CAAc,MAAM,GAAGD,CAAI;AACrE;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),n=require("react"),k=require("react-i18next"),o=require("lucide-react"),u=require("./index-vXiLh35n.js"),A=["Critical","High","Medium","Low"];function B(){const{t:a}=k.useTranslation("support"),[c,d]=n.useState(!0),[x,m]=n.useState(null),[j,w]=n.useState([]),[b,T]=n.useState([]),[l,C]=n.useState(null),[p,g]=n.useState({}),[f,N]=n.useState(null),v=n.useCallback(async()=>{try{d(!0);const[s,t,r]=await Promise.all([u.slaApi.getConfigurations(),u.slaApi.getEscalationRules(),u.slaApi.getMetrics()]),i=[...s].sort((h,R)=>A.indexOf(h.priority)-A.indexOf(R.priority));w(i),T(t),C(r);const S={};i.forEach(h=>{S[h.priority]={response:h.responseTimeMinutes,resolution:h.resolutionTimeMinutes}}),g(S)}catch(s){console.error("Failed to load SLA configurations:",s)}finally{d(!1)}},[]);n.useEffect(()=>{v()},[v]);const L=async s=>{const t=p[s];if(t)try{m(s),await u.slaApi.updateConfiguration(s,{responseTimeMinutes:t.response,resolutionTimeMinutes:t.resolution}),await v(),N(`${s} SLA configuration saved successfully`),setTimeout(()=>N(null),3e3)}catch(r){console.error("Failed to save SLA configuration:",r)}finally{m(null)}},y=(s,t,r)=>{g(i=>({...i,[s]:{...i[s],[t]:r}}))},M=s=>{const t=j.find(i=>i.priority===s),r=p[s];return!t||!r?!1:t.responseTimeMinutes!==r.response||t.resolutionTimeMinutes!==r.resolution};return c?e.jsx("div",{className:"flex items-center justify-center min-h-[400px]",children:e.jsx(o.Loader2,{className:"w-8 h-8 animate-spin text-[var(--color-primary-600)]"})}):e.jsxs("div",{className:"space-y-6",children:[e.jsx(u.Breadcrumb,{items:[{label:a("title","Support"),href:"/support"},{label:a("sla.title","SLA Configuration")}]}),e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[e.jsx(o.Clock,{className:"w-6 h-6"}),a("sla.title","SLA Configuration")]}),e.jsx("p",{className:"text-[var(--text-secondary)]",children:"Configure Service Level Agreements for ticket response and resolution times"})]}),f&&e.jsxs("div",{className:"bg-[var(--success-bg)] border border-[var(--success-border)] text-[var(--success-text)] px-4 py-3 rounded flex items-center gap-2",children:[e.jsx(o.Check,{className:"w-5 h-5"}),f]}),l&&e.jsxs("div",{className:"card p-4",children:[e.jsx("h2",{className:"font-semibold mb-4",children:"Current SLA Performance"}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:[e.jsxs("div",{className:"text-center p-3 bg-[var(--bg-secondary)] rounded",children:[e.jsx("div",{className:"text-2xl font-bold",children:l.totalTickets}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Total Tickets"})]}),e.jsxs("div",{className:"text-center p-3 bg-[var(--bg-secondary)] rounded",children:[e.jsx("div",{className:"text-2xl font-bold text-[var(--success-text)]",children:l.ticketsWithinSla}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Within SLA"})]}),e.jsxs("div",{className:"text-center p-3 bg-[var(--bg-secondary)] rounded",children:[e.jsx("div",{className:"text-2xl font-bold text-[var(--error-text)]",children:l.ticketsBreached}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Breached"})]}),e.jsxs("div",{className:"text-center p-3 bg-[var(--bg-secondary)] rounded",children:[e.jsxs("div",{className:`text-2xl font-bold ${l.slaCompliancePercentage>=90?"text-[var(--success-text)]":"text-[var(--warning-text)]"}`,children:[l.slaCompliancePercentage.toFixed(1),"%"]}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Compliance"})]})]}),Object.keys(l.breachesByPriority).length>0&&e.jsxs("div",{className:"mt-4 pt-4 border-t border-[var(--border-color)]",children:[e.jsx("h3",{className:"text-sm font-medium mb-2",children:"Breaches by Priority"}),e.jsx("div",{className:"flex gap-4",children:Object.entries(l.breachesByPriority).map(([s,t])=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"text-sm",children:[s,":"]}),e.jsx("span",{className:"font-medium text-[var(--error-text)]",children:t})]},s))})]})]}),e.jsxs("div",{className:"card",children:[e.jsxs("div",{className:"p-4 border-b border-[var(--border-color)]",children:[e.jsx("h2",{className:"font-semibold",children:"Response & Resolution Times"}),e.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:"Define the maximum time allowed for initial response and complete resolution by priority"})]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[var(--border-color)] bg-[var(--bg-secondary)]",children:[e.jsx("th",{className:"text-left p-4 font-medium",children:"Priority"}),e.jsx("th",{className:"text-left p-4 font-medium",children:"Response Time"}),e.jsx("th",{className:"text-left p-4 font-medium",children:"Resolution Time"}),e.jsx("th",{className:"text-left p-4 font-medium",children:"Status"}),e.jsx("th",{className:"text-right p-4 font-medium",children:"Actions"})]})}),e.jsx("tbody",{children:j.map(s=>{const t=p[s.priority],r=M(s.priority);return e.jsxs("tr",{className:"border-b border-[var(--border-color)]",children:[e.jsx("td",{className:"p-4",children:e.jsx("span",{className:`inline-flex items-center px-3 py-1 rounded-[var(--radius-badge)] font-medium text-sm ${s.priority==="Critical"?"bg-[var(--error-bg)] text-[var(--error-text)]":s.priority==="High"||s.priority==="Medium"?"bg-[var(--warning-bg)] text-[var(--warning-text)]":"bg-[var(--info-bg)] text-[var(--info-text)]"}`,children:s.priority})}),e.jsx("td",{className:"p-4",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"number",min:"1",value:t?.response??s.responseTimeMinutes,onChange:i=>y(s.priority,"response",parseInt(i.target.value)||0),className:"input w-24"}),e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:"minutes"}),e.jsxs("span",{className:"text-sm text-[var(--text-secondary)] ml-2",children:["(",s.responseTimeFormatted,")"]})]})}),e.jsx("td",{className:"p-4",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"number",min:"1",value:t?.resolution??s.resolutionTimeMinutes,onChange:i=>y(s.priority,"resolution",parseInt(i.target.value)||0),className:"input w-24"}),e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:"minutes"}),e.jsxs("span",{className:"text-sm text-[var(--text-secondary)] ml-2",children:["(",s.resolutionTimeFormatted,")"]})]})}),e.jsx("td",{className:"p-4",children:s.isActive?e.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded bg-[var(--success-bg)] text-[var(--success-text)] text-sm",children:"Active"}):e.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded bg-[var(--bg-secondary)] text-[var(--text-secondary)] text-sm",children:"Inactive"})}),e.jsx("td",{className:"p-4 text-right",children:e.jsxs("button",{onClick:()=>L(s.priority),disabled:!r||x===s.priority,className:`btn ${r?"btn-primary":"btn-secondary"} flex items-center gap-2`,children:[x===s.priority?e.jsx(o.Loader2,{className:"w-4 h-4 animate-spin"}):e.jsx(o.Save,{className:"w-4 h-4"}),"Save"]})})]},s.id)})})]})})]}),e.jsxs("div",{className:"card",children:[e.jsxs("div",{className:"p-4 border-b border-[var(--border-color)]",children:[e.jsx("h2",{className:"font-semibold",children:"Escalation Rules"}),e.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:"Automatic escalation paths when SLAs are breached"})]}),b.length>0?e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[var(--border-color)] bg-[var(--bg-secondary)]",children:[e.jsx("th",{className:"text-left p-4 font-medium",children:"Level"}),e.jsx("th",{className:"text-left p-4 font-medium",children:"Trigger"}),e.jsx("th",{className:"text-left p-4 font-medium",children:"Delay After Breach"}),e.jsx("th",{className:"text-left p-4 font-medium",children:"Status"})]})}),e.jsx("tbody",{children:b.map(s=>e.jsxs("tr",{className:"border-b border-[var(--border-color)]",children:[e.jsx("td",{className:"p-4",children:e.jsx("span",{className:"font-medium",children:s.level})}),e.jsx("td",{className:"p-4",children:e.jsx("span",{className:"text-sm",children:P(s.triggerType)})}),e.jsx("td",{className:"p-4",children:e.jsx("span",{className:"text-sm",children:$(s.delayAfterBreachMinutes)})}),e.jsx("td",{className:"p-4",children:s.isActive?e.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded bg-[var(--success-bg)] text-[var(--success-text)] text-sm",children:"Active"}):e.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded bg-[var(--bg-secondary)] text-[var(--text-secondary)] text-sm",children:"Inactive"})})]},s.id))})]})}):e.jsxs("div",{className:"p-8 text-center text-[var(--text-secondary)]",children:[e.jsx(o.AlertTriangle,{className:"w-12 h-12 mx-auto mb-4 opacity-50"}),e.jsx("p",{children:"No escalation rules configured"})]})]}),e.jsxs("div",{className:"card p-4 bg-[var(--info-bg)] border-[var(--info-border)]",children:[e.jsx("h3",{className:"font-semibold text-[var(--info-text)] mb-2",children:"About SLA Configuration"}),e.jsxs("ul",{className:"text-sm text-[var(--info-text)] space-y-1",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Response Time:"})," Maximum time allowed for the first agent response after ticket creation"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Resolution Time:"})," Maximum time allowed to fully resolve and close the ticket"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"SLA Pause:"})," SLA timers automatically pause when a ticket is placed On Hold"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Escalation:"})," When SLA is breached, tickets are automatically escalated to higher levels"]})]})]})]})}function P(a){switch(a){case"ResponseBreach":return"Response SLA Breached";case"ResolutionBreach":return"Resolution SLA Breached";default:return a}}function $(a){if(a<60)return`${a} minutes`;const c=Math.floor(a/60),d=a%60;if(c<24)return d>0?`${c}h ${d}m`:`${c} hours`;const x=Math.floor(c/24),m=c%24;return m>0?`${x}d ${m}h`:`${x} days`}exports.SlaConfigPage=B;
|
|
2
|
-
//# sourceMappingURL=SlaConfigPage-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),n=require("react"),k=require("react-i18next"),o=require("lucide-react"),u=require("./index-DK5czlkn.js"),A=["Critical","High","Medium","Low"];function B(){const{t:a}=k.useTranslation("support"),[c,d]=n.useState(!0),[x,m]=n.useState(null),[j,w]=n.useState([]),[b,T]=n.useState([]),[l,C]=n.useState(null),[p,g]=n.useState({}),[f,N]=n.useState(null),v=n.useCallback(async()=>{try{d(!0);const[s,t,r]=await Promise.all([u.slaApi.getConfigurations(),u.slaApi.getEscalationRules(),u.slaApi.getMetrics()]),i=[...s].sort((h,R)=>A.indexOf(h.priority)-A.indexOf(R.priority));w(i),T(t),C(r);const S={};i.forEach(h=>{S[h.priority]={response:h.responseTimeMinutes,resolution:h.resolutionTimeMinutes}}),g(S)}catch(s){console.error("Failed to load SLA configurations:",s)}finally{d(!1)}},[]);n.useEffect(()=>{v()},[v]);const L=async s=>{const t=p[s];if(t)try{m(s),await u.slaApi.updateConfiguration(s,{responseTimeMinutes:t.response,resolutionTimeMinutes:t.resolution}),await v(),N(`${s} SLA configuration saved successfully`),setTimeout(()=>N(null),3e3)}catch(r){console.error("Failed to save SLA configuration:",r)}finally{m(null)}},y=(s,t,r)=>{g(i=>({...i,[s]:{...i[s],[t]:r}}))},M=s=>{const t=j.find(i=>i.priority===s),r=p[s];return!t||!r?!1:t.responseTimeMinutes!==r.response||t.resolutionTimeMinutes!==r.resolution};return c?e.jsx("div",{className:"flex items-center justify-center min-h-[400px]",children:e.jsx(o.Loader2,{className:"w-8 h-8 animate-spin text-[var(--color-primary-600)]"})}):e.jsxs("div",{className:"space-y-6",children:[e.jsx(u.Breadcrumb,{items:[{label:a("title","Support"),href:"/support"},{label:a("sla.title","SLA Configuration")}]}),e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[e.jsx(o.Clock,{className:"w-6 h-6"}),a("sla.title","SLA Configuration")]}),e.jsx("p",{className:"text-[var(--text-secondary)]",children:"Configure Service Level Agreements for ticket response and resolution times"})]}),f&&e.jsxs("div",{className:"bg-[var(--success-bg)] border border-[var(--success-border)] text-[var(--success-text)] px-4 py-3 rounded flex items-center gap-2",children:[e.jsx(o.Check,{className:"w-5 h-5"}),f]}),l&&e.jsxs("div",{className:"card p-4",children:[e.jsx("h2",{className:"font-semibold mb-4",children:"Current SLA Performance"}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:[e.jsxs("div",{className:"text-center p-3 bg-[var(--bg-secondary)] rounded",children:[e.jsx("div",{className:"text-2xl font-bold",children:l.totalTickets}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Total Tickets"})]}),e.jsxs("div",{className:"text-center p-3 bg-[var(--bg-secondary)] rounded",children:[e.jsx("div",{className:"text-2xl font-bold text-[var(--success-text)]",children:l.ticketsWithinSla}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Within SLA"})]}),e.jsxs("div",{className:"text-center p-3 bg-[var(--bg-secondary)] rounded",children:[e.jsx("div",{className:"text-2xl font-bold text-[var(--error-text)]",children:l.ticketsBreached}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Breached"})]}),e.jsxs("div",{className:"text-center p-3 bg-[var(--bg-secondary)] rounded",children:[e.jsxs("div",{className:`text-2xl font-bold ${l.slaCompliancePercentage>=90?"text-[var(--success-text)]":"text-[var(--warning-text)]"}`,children:[l.slaCompliancePercentage.toFixed(1),"%"]}),e.jsx("div",{className:"text-sm text-[var(--text-secondary)]",children:"Compliance"})]})]}),Object.keys(l.breachesByPriority).length>0&&e.jsxs("div",{className:"mt-4 pt-4 border-t border-[var(--border-color)]",children:[e.jsx("h3",{className:"text-sm font-medium mb-2",children:"Breaches by Priority"}),e.jsx("div",{className:"flex gap-4",children:Object.entries(l.breachesByPriority).map(([s,t])=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"text-sm",children:[s,":"]}),e.jsx("span",{className:"font-medium text-[var(--error-text)]",children:t})]},s))})]})]}),e.jsxs("div",{className:"card",children:[e.jsxs("div",{className:"p-4 border-b border-[var(--border-color)]",children:[e.jsx("h2",{className:"font-semibold",children:"Response & Resolution Times"}),e.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:"Define the maximum time allowed for initial response and complete resolution by priority"})]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[var(--border-color)] bg-[var(--bg-secondary)]",children:[e.jsx("th",{className:"text-left p-4 font-medium",children:"Priority"}),e.jsx("th",{className:"text-left p-4 font-medium",children:"Response Time"}),e.jsx("th",{className:"text-left p-4 font-medium",children:"Resolution Time"}),e.jsx("th",{className:"text-left p-4 font-medium",children:"Status"}),e.jsx("th",{className:"text-right p-4 font-medium",children:"Actions"})]})}),e.jsx("tbody",{children:j.map(s=>{const t=p[s.priority],r=M(s.priority);return e.jsxs("tr",{className:"border-b border-[var(--border-color)]",children:[e.jsx("td",{className:"p-4",children:e.jsx("span",{className:`inline-flex items-center px-3 py-1 rounded-[var(--radius-badge)] font-medium text-sm ${s.priority==="Critical"?"bg-[var(--error-bg)] text-[var(--error-text)]":s.priority==="High"||s.priority==="Medium"?"bg-[var(--warning-bg)] text-[var(--warning-text)]":"bg-[var(--info-bg)] text-[var(--info-text)]"}`,children:s.priority})}),e.jsx("td",{className:"p-4",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"number",min:"1",value:t?.response??s.responseTimeMinutes,onChange:i=>y(s.priority,"response",parseInt(i.target.value)||0),className:"input w-24"}),e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:"minutes"}),e.jsxs("span",{className:"text-sm text-[var(--text-secondary)] ml-2",children:["(",s.responseTimeFormatted,")"]})]})}),e.jsx("td",{className:"p-4",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"number",min:"1",value:t?.resolution??s.resolutionTimeMinutes,onChange:i=>y(s.priority,"resolution",parseInt(i.target.value)||0),className:"input w-24"}),e.jsx("span",{className:"text-sm text-[var(--text-secondary)]",children:"minutes"}),e.jsxs("span",{className:"text-sm text-[var(--text-secondary)] ml-2",children:["(",s.resolutionTimeFormatted,")"]})]})}),e.jsx("td",{className:"p-4",children:s.isActive?e.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded bg-[var(--success-bg)] text-[var(--success-text)] text-sm",children:"Active"}):e.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded bg-[var(--bg-secondary)] text-[var(--text-secondary)] text-sm",children:"Inactive"})}),e.jsx("td",{className:"p-4 text-right",children:e.jsxs("button",{onClick:()=>L(s.priority),disabled:!r||x===s.priority,className:`btn ${r?"btn-primary":"btn-secondary"} flex items-center gap-2`,children:[x===s.priority?e.jsx(o.Loader2,{className:"w-4 h-4 animate-spin"}):e.jsx(o.Save,{className:"w-4 h-4"}),"Save"]})})]},s.id)})})]})})]}),e.jsxs("div",{className:"card",children:[e.jsxs("div",{className:"p-4 border-b border-[var(--border-color)]",children:[e.jsx("h2",{className:"font-semibold",children:"Escalation Rules"}),e.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:"Automatic escalation paths when SLAs are breached"})]}),b.length>0?e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[var(--border-color)] bg-[var(--bg-secondary)]",children:[e.jsx("th",{className:"text-left p-4 font-medium",children:"Level"}),e.jsx("th",{className:"text-left p-4 font-medium",children:"Trigger"}),e.jsx("th",{className:"text-left p-4 font-medium",children:"Delay After Breach"}),e.jsx("th",{className:"text-left p-4 font-medium",children:"Status"})]})}),e.jsx("tbody",{children:b.map(s=>e.jsxs("tr",{className:"border-b border-[var(--border-color)]",children:[e.jsx("td",{className:"p-4",children:e.jsx("span",{className:"font-medium",children:s.level})}),e.jsx("td",{className:"p-4",children:e.jsx("span",{className:"text-sm",children:P(s.triggerType)})}),e.jsx("td",{className:"p-4",children:e.jsx("span",{className:"text-sm",children:$(s.delayAfterBreachMinutes)})}),e.jsx("td",{className:"p-4",children:s.isActive?e.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded bg-[var(--success-bg)] text-[var(--success-text)] text-sm",children:"Active"}):e.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded bg-[var(--bg-secondary)] text-[var(--text-secondary)] text-sm",children:"Inactive"})})]},s.id))})]})}):e.jsxs("div",{className:"p-8 text-center text-[var(--text-secondary)]",children:[e.jsx(o.AlertTriangle,{className:"w-12 h-12 mx-auto mb-4 opacity-50"}),e.jsx("p",{children:"No escalation rules configured"})]})]}),e.jsxs("div",{className:"card p-4 bg-[var(--info-bg)] border-[var(--info-border)]",children:[e.jsx("h3",{className:"font-semibold text-[var(--info-text)] mb-2",children:"About SLA Configuration"}),e.jsxs("ul",{className:"text-sm text-[var(--info-text)] space-y-1",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Response Time:"})," Maximum time allowed for the first agent response after ticket creation"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Resolution Time:"})," Maximum time allowed to fully resolve and close the ticket"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"SLA Pause:"})," SLA timers automatically pause when a ticket is placed On Hold"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Escalation:"})," When SLA is breached, tickets are automatically escalated to higher levels"]})]})]})]})}function P(a){switch(a){case"ResponseBreach":return"Response SLA Breached";case"ResolutionBreach":return"Resolution SLA Breached";default:return a}}function $(a){if(a<60)return`${a} minutes`;const c=Math.floor(a/60),d=a%60;if(c<24)return d>0?`${c}h ${d}m`:`${c} hours`;const x=Math.floor(c/24),m=c%24;return m>0?`${x}d ${m}h`:`${x} days`}exports.SlaConfigPage=B;
|
|
2
|
+
//# sourceMappingURL=SlaConfigPage-Cwo9NwxH.js.map
|