@atlashub/smartstack 3.29.0 → 3.30.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-CVq3qZoe.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-ChykpPZx.js.map → AgentSkillsPage-CVq3qZoe.js.map} +1 -1
- package/dist/chunks/{AgentSkillsPage-ABpqnnyK.js → AgentSkillsPage-DJb49NMA.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-ABpqnnyK.js.map → AgentSkillsPage-DJb49NMA.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-BltzNlXI.js → AgentWorkloadPage-D_nk3gKj.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-BltzNlXI.js.map → AgentWorkloadPage-D_nk3gKj.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-BI5QWJyQ.js → AgentWorkloadPage-oHEi-sFh.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-BI5QWJyQ.js.map → AgentWorkloadPage-oHEi-sFh.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-BaheZKBq.js → ApiCatalogDetailPage-Cr0q2HnB.js} +3 -3
- package/dist/chunks/{ApiCatalogDetailPage-BaheZKBq.js.map → ApiCatalogDetailPage-Cr0q2HnB.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-CsRxlHwO.js → ApiCatalogDetailPage-DX8buBkV.js} +2 -2
- package/dist/chunks/{ApiCatalogDetailPage-CsRxlHwO.js.map → ApiCatalogDetailPage-DX8buBkV.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-CqmmHpQ4.js → ApiCatalogPage-DN7sazvI.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-CqmmHpQ4.js.map → ApiCatalogPage-DN7sazvI.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-B0yIz8-U.js → ApiCatalogPage-DqboIzZE.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-B0yIz8-U.js.map → ApiCatalogPage-DqboIzZE.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage-CngD5JSN.js → ApplicationDetailPage--9YwwS5A.js} +2 -2
- package/dist/chunks/{ApplicationDetailPage-CngD5JSN.js.map → ApplicationDetailPage--9YwwS5A.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage-CdT6KNd7.js → ApplicationDetailPage-CCNjr64K.js} +4 -4
- package/dist/chunks/{ApplicationDetailPage-CdT6KNd7.js.map → ApplicationDetailPage-CCNjr64K.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-DHmnjk2O.js → ApplicationsDashboardPage-BSsHN3Yj.js} +2 -2
- package/dist/chunks/{ApplicationsDashboardPage-DHmnjk2O.js.map → ApplicationsDashboardPage-BSsHN3Yj.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-1V4iQ6eY.js → ApplicationsDashboardPage-Bs-Xgca4.js} +3 -3
- package/dist/chunks/{ApplicationsDashboardPage-1V4iQ6eY.js.map → ApplicationsDashboardPage-Bs-Xgca4.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-Bo3NDnBF.js → ApplicationsGridPage-DDysNWJ5.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-Bo3NDnBF.js.map → ApplicationsGridPage-DDysNWJ5.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-CiMJFlB_.js → ApplicationsGridPage-s1WEzOXS.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-CiMJFlB_.js.map → ApplicationsGridPage-s1WEzOXS.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-L2_S23aN.js → ApplicationsListPage-B3CSMiV0.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-L2_S23aN.js.map → ApplicationsListPage-B3CSMiV0.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-De8jQ1Cm.js → ApplicationsListPage-B6ZCecIl.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-De8jQ1Cm.js.map → ApplicationsListPage-B6ZCecIl.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-DBq7_Sm8.js → ApplicationsPage-BBaiBM--.js} +2 -2
- package/dist/chunks/{ApplicationsPage-DBq7_Sm8.js.map → ApplicationsPage-BBaiBM--.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-CiNI-b0R.js → ApplicationsPage-ztPwoAGt.js} +4 -4
- package/dist/chunks/{ApplicationsPage-CiNI-b0R.js.map → ApplicationsPage-ztPwoAGt.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-DFsO4ZES.js → AssignmentRulesPage-CK4L4rBO.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-DFsO4ZES.js.map → AssignmentRulesPage-CK4L4rBO.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-C8rfUsMB.js → AssignmentRulesPage-DFSVFFXr.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-C8rfUsMB.js.map → AssignmentRulesPage-DFSVFFXr.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-78C_EBsw.js → AssignmentsPage-Bp7oQD7Q.js} +2 -2
- package/dist/chunks/{AssignmentsPage-78C_EBsw.js.map → AssignmentsPage-Bp7oQD7Q.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-COCikISI.js → AssignmentsPage-JCLpyg94.js} +2 -2
- package/dist/chunks/{AssignmentsPage-COCikISI.js.map → AssignmentsPage-JCLpyg94.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-DqT6ueVi.js → AuthCallbackPage-Bl9xlJ3h.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-DqT6ueVi.js.map → AuthCallbackPage-Bl9xlJ3h.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-BF4bkTnR.js → AuthCallbackPage-CzMHz4jy.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-BF4bkTnR.js.map → AuthCallbackPage-CzMHz4jy.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-Bh_K5qJn.js → ConfirmEmailPage-D_8T1vqV.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-Bh_K5qJn.js.map → ConfirmEmailPage-D_8T1vqV.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-DJy4idrf.js → ConfirmEmailPage-M7mJgXvn.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-DJy4idrf.js.map → ConfirmEmailPage-M7mJgXvn.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-pL7jbG9o.js → CreateSupportTicketPage-BNEGavlu.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-pL7jbG9o.js.map → CreateSupportTicketPage-BNEGavlu.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-AVTwXbJd.js → CreateSupportTicketPage-C2X2mfds.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-AVTwXbJd.js.map → CreateSupportTicketPage-C2X2mfds.js.map} +1 -1
- package/dist/chunks/{DashboardPage-DdQlTLw0.js → DashboardPage-4oy2YqvT.js} +2 -2
- package/dist/chunks/{DashboardPage-DdQlTLw0.js.map → DashboardPage-4oy2YqvT.js.map} +1 -1
- package/dist/chunks/{DashboardPage-C55mIiB6.js → DashboardPage-CO-8B8EI.js} +3 -3
- package/dist/chunks/{DashboardPage-C55mIiB6.js.map → DashboardPage-CO-8B8EI.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CcCnUl7s.js → DashboardPage-CPArUG-S.js} +2 -2
- package/dist/chunks/{DashboardPage-CcCnUl7s.js.map → DashboardPage-CPArUG-S.js.map} +1 -1
- package/dist/chunks/{DashboardPage-DOitDfGV.js → DashboardPage-D5MRMxEV.js} +3 -3
- package/dist/chunks/{DashboardPage-DOitDfGV.js.map → DashboardPage-D5MRMxEV.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-DNnZftCH.js → EscalationConfigPage-CwdnfJbJ.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-DNnZftCH.js.map → EscalationConfigPage-CwdnfJbJ.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-DRr55328.js → EscalationConfigPage-DnjLFXnL.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-DRr55328.js.map → EscalationConfigPage-DnjLFXnL.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-1SCOPIqK.js → ForceChangePasswordPage-ZEIfyqwE.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-1SCOPIqK.js.map → ForceChangePasswordPage-ZEIfyqwE.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-DBeG_HRO.js → ForceChangePasswordPage-sh-3h_H9.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-DBeG_HRO.js.map → ForceChangePasswordPage-sh-3h_H9.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-Dlb6wKfC.js → ForgotPasswordPage-B4M6-xeM.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-Dlb6wKfC.js.map → ForgotPasswordPage-B4M6-xeM.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-DffYfXva.js → ForgotPasswordPage-MIu-U7p0.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-DffYfXva.js.map → ForgotPasswordPage-MIu-U7p0.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-C9nRbeHI.js → GroupDetailPage-4XK3Bs_r.js} +5 -5
- package/dist/chunks/{GroupDetailPage-C9nRbeHI.js.map → GroupDetailPage-4XK3Bs_r.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-CPPUWzXf.js → GroupDetailPage-C-kvtd2T.js} +2 -2
- package/dist/chunks/{GroupDetailPage-CPPUWzXf.js.map → GroupDetailPage-C-kvtd2T.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-BAX0xwJX.js → MyAccessRequestsPage-CP41FzHi.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-BAX0xwJX.js.map → MyAccessRequestsPage-CP41FzHi.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-BMY1V631.js → MyAccessRequestsPage-DzrXTrVi.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-BMY1V631.js.map → MyAccessRequestsPage-DzrXTrVi.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-Bbn4HxN2.js → MyTenantsPage-CZRkMbh8.js} +2 -2
- package/dist/chunks/{MyTenantsPage-Bbn4HxN2.js.map → MyTenantsPage-CZRkMbh8.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-BHtp67SD.js → MyTenantsPage-V_SwYio2.js} +3 -3
- package/dist/chunks/{MyTenantsPage-BHtp67SD.js.map → MyTenantsPage-V_SwYio2.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-BvZeiTXu.js → MyTicketsPage-DOUhaLal.js} +2 -2
- package/dist/chunks/{MyTicketsPage-BvZeiTXu.js.map → MyTicketsPage-DOUhaLal.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-D9IGVofj.js → MyTicketsPage-DnvAIeyr.js} +2 -2
- package/dist/chunks/{MyTicketsPage-D9IGVofj.js.map → MyTicketsPage-DnvAIeyr.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-DiPBCsAF.js → NavigationAppsPage-DXvpLsbt.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-DiPBCsAF.js.map → NavigationAppsPage-DXvpLsbt.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-ChtMK1yt.js → NavigationAppsPage-DfTa4jCG.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-ChtMK1yt.js.map → NavigationAppsPage-DfTa4jCG.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-BxCiGzHk.js → NotificationsPage-D76MdAs-.js} +2 -2
- package/dist/chunks/{NotificationsPage-BxCiGzHk.js.map → NotificationsPage-D76MdAs-.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-BCnL9oPb.js → NotificationsPage-I1yCk7tk.js} +2 -2
- package/dist/chunks/{NotificationsPage-BCnL9oPb.js.map → NotificationsPage-I1yCk7tk.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-CV_cxq7k.js → OnboardingWizardPage-BRUzcl1A.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-CV_cxq7k.js.map → OnboardingWizardPage-BRUzcl1A.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-Du-tQ2ag.js → OnboardingWizardPage-DtWUPCh3.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-Du-tQ2ag.js.map → OnboardingWizardPage-DtWUPCh3.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-C1iuWv0G.js → PermissionDetailPage-CUNKbl7t.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-C1iuWv0G.js.map → PermissionDetailPage-CUNKbl7t.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-Ds4Jt1os.js → PermissionDetailPage-DJJGbXoX.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-Ds4Jt1os.js.map → PermissionDetailPage-DJJGbXoX.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-BGI2nxCn.js → PermissionsPage-B8wmawPV.js} +2 -2
- package/dist/chunks/{PermissionsPage-BGI2nxCn.js.map → PermissionsPage-B8wmawPV.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-sauv7ct1.js → PermissionsPage-Dbjcctuh.js} +2 -2
- package/dist/chunks/{PermissionsPage-sauv7ct1.js.map → PermissionsPage-Dbjcctuh.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-CQWEcghD.js → PortalDashboardPage-BeNfBZmb.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-CQWEcghD.js.map → PortalDashboardPage-BeNfBZmb.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-2kCbJw9w.js → PortalDashboardPage-zii0ll57.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-2kCbJw9w.js.map → PortalDashboardPage-zii0ll57.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-Bu4gaDRb.js → PreferencesPage-BCpuIGzv.js} +2 -2
- package/dist/chunks/{PreferencesPage-Bu4gaDRb.js.map → PreferencesPage-BCpuIGzv.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-Dbg0bEYD.js → PreferencesPage-BmvrBaAD.js} +2 -2
- package/dist/chunks/{PreferencesPage-Dbg0bEYD.js.map → PreferencesPage-BmvrBaAD.js.map} +1 -1
- package/dist/chunks/{ProfilePage-C5QS7tsh.js → ProfilePage-eowQd59_.js} +2 -2
- package/dist/chunks/{ProfilePage-C5QS7tsh.js.map → ProfilePage-eowQd59_.js.map} +1 -1
- package/dist/chunks/{ProfilePage-DfiBhOUt.js → ProfilePage-mf5wI0-n.js} +2 -2
- package/dist/chunks/{ProfilePage-DfiBhOUt.js.map → ProfilePage-mf5wI0-n.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-Bs0mapj8.js → ReferencesManagementPage-8UPgkVE8.js} +3 -3
- package/dist/chunks/{ReferencesManagementPage-Bs0mapj8.js.map → ReferencesManagementPage-8UPgkVE8.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-C0RgHbJb.js → ReferencesManagementPage-CLsaUNqA.js} +2 -2
- package/dist/chunks/{ReferencesManagementPage-C0RgHbJb.js.map → ReferencesManagementPage-CLsaUNqA.js.map} +1 -1
- package/dist/chunks/{RegisterPage-DS1chV_A.js → RegisterPage-57X-ILDb.js} +2 -2
- package/dist/chunks/{RegisterPage-DS1chV_A.js.map → RegisterPage-57X-ILDb.js.map} +1 -1
- package/dist/chunks/{RegisterPage-DoeIiJt0.js → RegisterPage-CNyHSbqs.js} +2 -2
- package/dist/chunks/{RegisterPage-DoeIiJt0.js.map → RegisterPage-CNyHSbqs.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-3KEk3zj5.js → ResetPasswordPage-CyV8l-Zo.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-3KEk3zj5.js.map → ResetPasswordPage-CyV8l-Zo.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-C_VQSFB5.js → ResetPasswordPage-JW8-mh_k.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-C_VQSFB5.js.map → ResetPasswordPage-JW8-mh_k.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-S6URD--N.js → ResolutionModal-CjwE73NX.js} +2 -2
- package/dist/chunks/{ResolutionModal-S6URD--N.js.map → ResolutionModal-CjwE73NX.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-BzI1x79r.js → ResolutionModal-wddG59kg.js} +2 -2
- package/dist/chunks/{ResolutionModal-BzI1x79r.js.map → ResolutionModal-wddG59kg.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-SXK9cq_3.js → RoleDetailPage-CrioVHFI.js} +3 -3
- package/dist/chunks/{RoleDetailPage-SXK9cq_3.js.map → RoleDetailPage-CrioVHFI.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-DvEEWPKr.js → RoleDetailPage-TUOGR1ow.js} +2 -2
- package/dist/chunks/{RoleDetailPage-DvEEWPKr.js.map → RoleDetailPage-TUOGR1ow.js.map} +1 -1
- package/dist/chunks/{RolesPage-B75lCugt.js → RolesPage-CAcols3D.js} +2 -2
- package/dist/chunks/{RolesPage-B75lCugt.js.map → RolesPage-CAcols3D.js.map} +1 -1
- package/dist/chunks/{RolesPage-C5gYJxAl.js → RolesPage-sJBWaNff.js} +2 -2
- package/dist/chunks/{RolesPage-C5gYJxAl.js.map → RolesPage-sJBWaNff.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-BqXHATb6.js → SlaConfigPage-BPGRloOS.js} +2 -2
- package/dist/chunks/{SlaConfigPage-BqXHATb6.js.map → SlaConfigPage-BPGRloOS.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-DZ4P1FFW.js → SlaConfigPage-D5TRn7Ir.js} +2 -2
- package/dist/chunks/{SlaConfigPage-DZ4P1FFW.js.map → SlaConfigPage-D5TRn7Ir.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-B4xy_pCQ.js → SupportPermissionsPage-Dc2bWTzG.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-B4xy_pCQ.js.map → SupportPermissionsPage-Dc2bWTzG.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-DW7KJjYK.js → SupportPermissionsPage-UXmYLrIq.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-DW7KJjYK.js.map → SupportPermissionsPage-UXmYLrIq.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-DZa0PQTE.js → TemplatesPage-dmPlqqiD.js} +2 -2
- package/dist/chunks/{TemplatesPage-DZa0PQTE.js.map → TemplatesPage-dmPlqqiD.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-m5-sLJ7F.js → TemplatesPage-nTY85sNA.js} +2 -2
- package/dist/chunks/{TemplatesPage-m5-sLJ7F.js.map → TemplatesPage-nTY85sNA.js.map} +1 -1
- package/dist/chunks/{TenantCard-BJQi7Oew.js → TenantCard-BUXfstRZ.js} +2 -2
- package/dist/chunks/{TenantCard-BJQi7Oew.js.map → TenantCard-BUXfstRZ.js.map} +1 -1
- package/dist/chunks/{TenantCard-CqfifMrM.js → TenantCard-BhT-31ls.js} +2 -2
- package/dist/chunks/{TenantCard-CqfifMrM.js.map → TenantCard-BhT-31ls.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-CdiYJvuH.js → TenantScopeSelector-3_mzBLNI.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-CdiYJvuH.js.map → TenantScopeSelector-3_mzBLNI.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-Cl5DD318.js → TenantScopeSelector-B-SRDR2R.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-Cl5DD318.js.map → TenantScopeSelector-B-SRDR2R.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-BOC9rHu3.js → TicketDetailPage-B4cR3rOC.js} +2 -2
- package/dist/chunks/{TicketDetailPage-BOC9rHu3.js.map → TicketDetailPage-B4cR3rOC.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-C1UuMxD8.js → TicketDetailPage-xN3wPnFL.js} +2 -2
- package/dist/chunks/{TicketDetailPage-C1UuMxD8.js.map → TicketDetailPage-xN3wPnFL.js.map} +1 -1
- package/dist/chunks/{TicketsPage-BCgHZA-m.js → TicketsPage-CkHgXSxU.js} +2 -2
- package/dist/chunks/{TicketsPage-BCgHZA-m.js.map → TicketsPage-CkHgXSxU.js.map} +1 -1
- package/dist/chunks/{TicketsPage-BjaN4Baq.js → TicketsPage-Dwi2xpMI.js} +2 -2
- package/dist/chunks/{TicketsPage-BjaN4Baq.js.map → TicketsPage-Dwi2xpMI.js.map} +1 -1
- package/dist/chunks/{UserCreateTicketPage-ChQL1mVY.js → UserCreateTicketPage-D2a3EOey.js} +3 -3
- package/dist/chunks/UserCreateTicketPage-D2a3EOey.js.map +1 -0
- package/dist/chunks/{UserCreateTicketPage-DkjsHeV7.js → UserCreateTicketPage-bcbSLglE.js} +48 -48
- package/dist/chunks/UserCreateTicketPage-bcbSLglE.js.map +1 -0
- package/dist/chunks/{UserDashboardPage-BMYrtF3o.js → UserDashboardPage-DwnDRNoW.js} +2 -2
- package/dist/chunks/{UserDashboardPage-BMYrtF3o.js.map → UserDashboardPage-DwnDRNoW.js.map} +1 -1
- package/dist/chunks/{UserDashboardPage-81-3GJAQ.js → UserDashboardPage-ZMsx8LWw.js} +2 -2
- package/dist/chunks/{UserDashboardPage-81-3GJAQ.js.map → UserDashboardPage-ZMsx8LWw.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-BMW8jAWG.js → UserDetailPage-BRFowOFL.js} +2 -2
- package/dist/chunks/{UserDetailPage-BMW8jAWG.js.map → UserDetailPage-BRFowOFL.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-D6oCH2eS.js → UserDetailPage-CZyV-zsg.js} +5 -5
- package/dist/chunks/{UserDetailPage-D6oCH2eS.js.map → UserDetailPage-CZyV-zsg.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-ZH2BDWBt.js → UserTicketDetailPage-BstGk_BP.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-ZH2BDWBt.js.map → UserTicketDetailPage-BstGk_BP.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-Z_myXXJ0.js → UserTicketDetailPage-DzB_pELt.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-Z_myXXJ0.js.map → UserTicketDetailPage-DzB_pELt.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-B8Ka6uRa.js → UsersGroupsPage-BygTv_kK.js} +3 -3
- package/dist/chunks/{UsersGroupsPage-B8Ka6uRa.js.map → UsersGroupsPage-BygTv_kK.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-xJmGib8b.js → UsersGroupsPage-DTmhzttW.js} +2 -2
- package/dist/chunks/{UsersGroupsPage-xJmGib8b.js.map → UsersGroupsPage-DTmhzttW.js.map} +1 -1
- package/dist/chunks/{UsersPage-CQ38akZ_.js → UsersPage-DcwLyMAX.js} +2 -2
- package/dist/chunks/{UsersPage-CQ38akZ_.js.map → UsersPage-DcwLyMAX.js.map} +1 -1
- package/dist/chunks/{UsersPage-Bd2-vl39.js → UsersPage-TIqSHgHj.js} +2 -2
- package/dist/chunks/{UsersPage-Bd2-vl39.js.map → UsersPage-TIqSHgHj.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-DguOx0q0.js → accessRequestsApi-3FjMFbpa.js} +2 -2
- package/dist/chunks/{accessRequestsApi-DguOx0q0.js.map → accessRequestsApi-3FjMFbpa.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-COtWo9kC.js → accessRequestsApi-B6dsJzvH.js} +2 -2
- package/dist/chunks/{accessRequestsApi-COtWo9kC.js.map → accessRequestsApi-B6dsJzvH.js.map} +1 -1
- package/dist/chunks/{aiApi-CITiWGYX.js → aiApi-9G4wG_mT.js} +2 -2
- package/dist/chunks/{aiApi-CITiWGYX.js.map → aiApi-9G4wG_mT.js.map} +1 -1
- package/dist/chunks/{aiApi-BmZsud6O.js → aiApi-DXOdsoxr.js} +2 -2
- package/dist/chunks/{aiApi-BmZsud6O.js.map → aiApi-DXOdsoxr.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-BYoEJzSN.js → applicationAnalyticsApi-D0DEp9Y-.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-BYoEJzSN.js.map → applicationAnalyticsApi-D0DEp9Y-.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-D62lc6z4.js → applicationAnalyticsApi-DhOd6idI.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-D62lc6z4.js.map → applicationAnalyticsApi-DhOd6idI.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-Db8G2lLs.js} +2 -2
- package/dist/chunks/{groupsApi-3CR-_g5b.js.map → groupsApi-Db8G2lLs.js.map} +1 -1
- package/dist/chunks/{groupsApi-BUyBgf_N.js → groupsApi-lbxNsHFv.js} +2 -2
- package/dist/chunks/{groupsApi-BUyBgf_N.js.map → groupsApi-lbxNsHFv.js.map} +1 -1
- package/dist/chunks/{index-IJR_91Yt.js → index-BI2dc1FS.js} +2 -2
- package/dist/chunks/{index-IJR_91Yt.js.map → index-BI2dc1FS.js.map} +1 -1
- package/dist/chunks/{index-DIQ6Jmmq.js → index-Bn8HzILk.js} +4 -4
- package/dist/chunks/{index-DIQ6Jmmq.js.map → index-Bn8HzILk.js.map} +1 -1
- package/dist/chunks/{index-DA5VyW0k.js → index-CN2WRyg1.js} +2249 -2264
- package/dist/chunks/index-CN2WRyg1.js.map +1 -0
- package/dist/chunks/{index-Br2wsGE8.js → index-CTGSmYvs.js} +2 -2
- package/dist/chunks/{index-Br2wsGE8.js.map → index-CTGSmYvs.js.map} +1 -1
- package/dist/chunks/index-CUICSveU.js +2 -0
- package/dist/chunks/index-CUICSveU.js.map +1 -0
- package/dist/chunks/{index-S-X8qFYW.js → index-CgtbaFf5.js} +2 -2
- package/dist/chunks/{index-S-X8qFYW.js.map → index-CgtbaFf5.js.map} +1 -1
- package/dist/chunks/{index-_g82N2nb.js → index-D0HS542b.js} +2 -2
- package/dist/chunks/{index-_g82N2nb.js.map → index-D0HS542b.js.map} +1 -1
- package/dist/chunks/{index-BIqcvvbh.js → index-DEtq-xUL.js} +9 -8
- package/dist/chunks/index-DEtq-xUL.js.map +1 -0
- package/dist/chunks/{index-BOKR3bw6.js → index-DF93KQFR.js} +2 -2
- package/dist/chunks/{index-BOKR3bw6.js.map → index-DF93KQFR.js.map} +1 -1
- package/dist/chunks/{index-CxgEV-rT.js → index-DLekpNSE.js} +2 -2
- package/dist/chunks/{index-CxgEV-rT.js.map → index-DLekpNSE.js.map} +1 -1
- package/dist/chunks/{index-DEOBhXS_.js → index-DUS-tunb.js} +2 -2
- package/dist/chunks/{index-DEOBhXS_.js.map → index-DUS-tunb.js.map} +1 -1
- package/dist/chunks/{index-BMsjMCv9.js → index-DjC1u2hI.js} +3 -3
- package/dist/chunks/{index-BMsjMCv9.js.map → index-DjC1u2hI.js.map} +1 -1
- package/dist/chunks/{index-BxHVPJ-j.js → index-DqbVFB1H.js} +2 -2
- package/dist/chunks/{index-BxHVPJ-j.js.map → index-DqbVFB1H.js.map} +1 -1
- package/dist/chunks/{index-Djy4eIbB.js → index-DwqLhQ8S.js} +2 -2
- package/dist/chunks/{index-Djy4eIbB.js.map → index-DwqLhQ8S.js.map} +1 -1
- package/dist/chunks/{index-C1w97Ejz.js → index-HsAOBno4.js} +2 -2
- package/dist/chunks/{index-C1w97Ejz.js.map → index-HsAOBno4.js.map} +1 -1
- package/dist/chunks/{index-Czk12A3G.js → index-TiWOcC0g.js} +2 -2
- package/dist/chunks/{index-Czk12A3G.js.map → index-TiWOcC0g.js.map} +1 -1
- package/dist/chunks/{index-vXiLh35n.js → index-cAikSVW0.js} +13 -13
- package/dist/chunks/index-cAikSVW0.js.map +1 -0
- package/dist/chunks/{index-CNxx56kE.js → index-xhRXN1Jq.js} +2 -2
- package/dist/chunks/{index-CNxx56kE.js.map → index-xhRXN1Jq.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-COKA97Ug.js → tenantIconMap-CHeS7oLt.js} +2 -2
- package/dist/chunks/{tenantIconMap-COKA97Ug.js.map → tenantIconMap-CHeS7oLt.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-BuSQUUyZ.js → tenantIconMap-__FKj6CN.js} +2 -2
- package/dist/chunks/{tenantIconMap-BuSQUUyZ.js.map → tenantIconMap-__FKj6CN.js.map} +1 -1
- package/dist/chunks/{ticketingApi-DbREwHez.js → ticketingApi-Cj239hYB.js} +2 -2
- package/dist/chunks/{ticketingApi-DbREwHez.js.map → ticketingApi-Cj239hYB.js.map} +1 -1
- package/dist/chunks/{ticketingApi-C6EbupqP.js → ticketingApi-DF4RwD_6.js} +2 -2
- package/dist/chunks/{ticketingApi-C6EbupqP.js.map → ticketingApi-DF4RwD_6.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-vucIb3_w.js → useAccessRequests-CFam8zFR.js} +3 -3
- package/dist/chunks/{useAccessRequests-vucIb3_w.js.map → useAccessRequests-CFam8zFR.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-C0dY6y-4.js → useAccessRequests-CViOUwyF.js} +2 -2
- package/dist/chunks/{useAccessRequests-C0dY6y-4.js.map → useAccessRequests-CViOUwyF.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-BBcw1Rk9.js → useUserAccessRequests-B-Cs6NX1.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-BBcw1Rk9.js.map → useUserAccessRequests-B-Cs6NX1.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-Cj0nkesW.js → useUserAccessRequests-CslSQeBJ.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-Cj0nkesW.js.map → useUserAccessRequests-CslSQeBJ.js.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.map +0 -1
|
@@ -2,7 +2,7 @@ import { jsxs as l, jsx as r } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState as i, useCallback as M, useEffect as B } from "react";
|
|
3
3
|
import { useTranslation as P } from "react-i18next";
|
|
4
4
|
import { Loader2 as $, Edit2 as R, Trash2 as T, Plus as U } from "lucide-react";
|
|
5
|
-
import {
|
|
5
|
+
import { a7 as N, B as F } from "./index-CN2WRyg1.js";
|
|
6
6
|
const q = {
|
|
7
7
|
1: "bg-[var(--error-bg)] text-[var(--error-text)]",
|
|
8
8
|
2: "bg-[var(--warning-bg)] text-[var(--warning-text)]",
|
|
@@ -217,4 +217,4 @@ function K() {
|
|
|
217
217
|
export {
|
|
218
218
|
K as AgentSkillsPage
|
|
219
219
|
};
|
|
220
|
-
//# sourceMappingURL=AgentSkillsPage-
|
|
220
|
+
//# sourceMappingURL=AgentSkillsPage-CVq3qZoe.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentSkillsPage-ChykpPZx.js","sources":["../../src/pages/platform/support/AgentSkillsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, Edit2, Trash2, Plus } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { skillsApi, type AgentSkillDto, type UpdateAgentSkillsRequest } from '@/services/api/assignmentApi';\r\n\r\nconst proficiencyColors: Record<number, string> = {\r\n 1: 'bg-[var(--error-bg)] text-[var(--error-text)]',\r\n 2: 'bg-[var(--warning-bg)] text-[var(--warning-text)]',\r\n 3: 'bg-[var(--info-bg)] text-[var(--info-text)]',\r\n 4: 'bg-[var(--success-bg)] text-[var(--success-text)]',\r\n 5: 'bg-[var(--success-bg)] text-[var(--success-text)]',\r\n};\r\n\r\nconst skillCategories = ['Billing', 'Technical', 'Security', 'General', 'Networking', 'Software', 'Hardware'];\r\n\r\ninterface Agent {\r\n userId: string;\r\n userName: string | null;\r\n skills: AgentSkillDto[];\r\n}\r\n\r\ninterface EditableSkill {\r\n skillCategory: string;\r\n proficiencyLevel: number;\r\n}\r\n\r\nexport function AgentSkillsPage(): ReactElement {\r\n const { t } = useTranslation('support');\r\n const [loading, setLoading] = useState(true);\r\n const [agents, setAgents] = useState<Agent[]>([]);\r\n const [search, setSearch] = useState('');\r\n const [editingUserId, setEditingUserId] = useState<string | null>(null);\r\n const [editingSkills, setEditingSkills] = useState<EditableSkill[]>([]);\r\n const [saving, setSaving] = useState(false);\r\n\r\n const loadAgents = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const data = await skillsApi.getAll();\r\n const grouped = groupSkillsByAgent(data);\r\n setAgents(grouped);\r\n } catch (error) {\r\n console.error('Failed to load agent skills:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n loadAgents();\r\n }, [loadAgents]);\r\n\r\n const groupSkillsByAgent = (skills: AgentSkillDto[]): Agent[] => {\r\n const agentMap = new Map<string, Agent>();\r\n skills.forEach((skill) => {\r\n if (!agentMap.has(skill.userId)) {\r\n agentMap.set(skill.userId, {\r\n userId: skill.userId,\r\n userName: null,\r\n skills: [],\r\n });\r\n }\r\n agentMap.get(skill.userId)!.skills.push(skill);\r\n });\r\n return Array.from(agentMap.values()).sort((a, b) =>\r\n (a.userName || '').localeCompare(b.userName || '')\r\n );\r\n };\r\n\r\n const filteredAgents = agents.filter((agent) =>\r\n (agent.userName || '').toLowerCase().includes(search.toLowerCase())\r\n );\r\n\r\n const getProficiencyLabel = (level: number): string => {\r\n const labels: Record<number, string> = {\r\n 1: t('agentSkills.proficiency.beginner'),\r\n 2: t('agentSkills.proficiency.intermediate'),\r\n 3: t('agentSkills.proficiency.advanced'),\r\n 4: t('agentSkills.proficiency.expert'),\r\n 5: t('agentSkills.proficiency.master'),\r\n };\r\n return labels[level] || '';\r\n };\r\n\r\n const openEditModal = (agent: Agent) => {\r\n setEditingUserId(agent.userId);\r\n setEditingSkills(\r\n agent.skills.map((s) => ({\r\n skillCategory: s.skillCategory,\r\n proficiencyLevel: s.proficiencyLevel,\r\n }))\r\n );\r\n };\r\n\r\n const closeEditModal = () => {\r\n setEditingUserId(null);\r\n setEditingSkills([]);\r\n };\r\n\r\n const addSkillRow = () => {\r\n setEditingSkills([...editingSkills, { skillCategory: '', proficiencyLevel: 3 }]);\r\n };\r\n\r\n const removeSkillRow = (index: number) => {\r\n setEditingSkills(editingSkills.filter((_, i) => i !== index));\r\n };\r\n\r\n const updateSkillRow = (index: number, field: keyof EditableSkill, value: string | number) => {\r\n const updated = [...editingSkills];\r\n updated[index] = { ...updated[index], [field]: value };\r\n setEditingSkills(updated);\r\n };\r\n\r\n const saveSkills = async () => {\r\n if (!editingUserId) return;\r\n try {\r\n setSaving(true);\r\n const request: UpdateAgentSkillsRequest = {\r\n skills: editingSkills.filter((s) => s.skillCategory.trim()),\r\n };\r\n await skillsApi.update(editingUserId, request);\r\n await loadAgents();\r\n closeEditModal();\r\n } catch (error) {\r\n console.error('Failed to save skills:', error);\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('title', 'Support'), href: '/support' },\r\n { label: t('assignment.skills') },\r\n ]}\r\n />\r\n\r\n <div>\r\n <h1 className=\"text-2xl font-bold\">{t('assignment.skills')}</h1>\r\n <p className=\"text-[var(--text-secondary)]\">{t('assignment.availabilityDescription', 'Manage agent skills and proficiency levels')}</p>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <input\r\n type=\"text\"\r\n placeholder={t('common:search', 'Search agents...')}\r\n value={search}\r\n onChange={(e) => setSearch(e.target.value)}\r\n className=\"w-full px-4 py-2 border rounded-lg bg-[var(--bg-primary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n />\r\n </div>\r\n\r\n {loading && (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n )}\r\n {!loading && filteredAgents.length === 0 && (\r\n <div className=\"text-center py-12\">\r\n <p className=\"text-[var(--text-secondary)]\">{t('assignment.noAgents', 'No agents found')}</p>\r\n </div>\r\n )}\r\n {!loading && filteredAgents.length > 0 && (\r\n <div className=\"space-y-4\">\r\n {filteredAgents.map((agent) => (\r\n <div key={agent.userId} className=\"card p-6\">\r\n <div className=\"flex items-start justify-between mb-4\">\r\n <div>\r\n <h3 className=\"text-lg font-semibold\">{agent.userName || 'Unknown Agent'}</h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{agent.userId}</p>\r\n </div>\r\n <button\r\n onClick={() => openEditModal(agent)}\r\n className=\"flex items-center gap-2 px-3 py-2 bg-[var(--color-primary-600)] text-white rounded-lg hover:bg-[var(--color-primary-700)]\"\r\n >\r\n <Edit2 className=\"w-4 h-4\" />\r\n {t('common:edit', 'Edit')}\r\n </button>\r\n </div>\r\n\r\n {agent.skills.length > 0 ? (\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n {agent.skills.map((skill) => (\r\n <div\r\n key={`${skill.skillCategory}-${skill.proficiencyLevel}`}\r\n className=\"flex items-center justify-between p-3 bg-[var(--bg-secondary)] rounded-lg\"\r\n >\r\n <div>\r\n <p className=\"font-medium text-sm\">{skill.skillCategory}</p>\r\n </div>\r\n <span className={`px-3 py-1 rounded-full text-xs font-medium ${proficiencyColors[skill.proficiencyLevel]}`}>\r\n {getProficiencyLabel(skill.proficiencyLevel)}\r\n </span>\r\n </div>\r\n ))}\r\n </div>\r\n ) : (\r\n <p className=\"text-sm text-[var(--text-secondary)] italic\">{t('assignment.noSkills', 'No skills assigned')}</p>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {editingUserId && (\r\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4\">\r\n <div className=\"bg-[var(--bg-primary)] rounded-lg shadow-lg max-w-2xl w-full max-h-96 overflow-y-auto\">\r\n <div className=\"sticky top-0 bg-[var(--bg-primary)] border-b border-[var(--border-color)] p-6 flex items-center justify-between\">\r\n <h2 className=\"text-lg font-semibold\">{t('assignment.editSkills', 'Edit Skills')}</h2>\r\n <button\r\n onClick={closeEditModal}\r\n className=\"text-[var(--text-secondary)] hover:text-[var(--text-primary)]\"\r\n >\r\n ✕\r\n </button>\r\n </div>\r\n\r\n <div className=\"p-6 space-y-4\">\r\n {editingSkills.map((skill, index) => (\r\n <div key={`skill-${index}`} className=\"flex gap-3 items-end\">\r\n <div className=\"flex-1\">\r\n <label className=\"block text-xs font-medium mb-1 text-[var(--text-secondary)]\">\r\n {t('assignment.skillCategory', 'Skill Category')}\r\n </label>\r\n <select\r\n value={skill.skillCategory}\r\n onChange={(e) => updateSkillRow(index, 'skillCategory', e.target.value)}\r\n className=\"w-full px-3 py-2 border rounded-lg bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n <option value=\"\">Select skill...</option>\r\n {skillCategories.map((cat) => (\r\n <option key={cat} value={cat}>\r\n {cat}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n <div className=\"w-32\">\r\n <label className=\"block text-xs font-medium mb-1 text-[var(--text-secondary)]\">\r\n {t('assignment.proficiency', 'Proficiency')}\r\n </label>\r\n <select\r\n value={skill.proficiencyLevel}\r\n onChange={(e) => updateSkillRow(index, 'proficiencyLevel', parseInt(e.target.value))}\r\n className=\"w-full px-3 py-2 border rounded-lg bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n {[1, 2, 3, 4, 5].map((level) => (\r\n <option key={level} value={level}>\r\n {getProficiencyLabel(level)}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n <button\r\n onClick={() => removeSkillRow(index)}\r\n className=\"p-2 text-[var(--error-text)] hover:bg-[var(--error-bg)] rounded-lg\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n ))}\r\n\r\n <button\r\n onClick={addSkillRow}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm border border-[var(--border-color)] rounded-lg hover:bg-[var(--bg-secondary)]\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('assignment.addSkill', 'Add Skill')}\r\n </button>\r\n </div>\r\n\r\n <div className=\"sticky bottom-0 bg-[var(--bg-primary)] border-t border-[var(--border-color)] p-6 flex justify-end gap-3\">\r\n <button\r\n onClick={closeEditModal}\r\n className=\"px-4 py-2 border border-[var(--border-color)] rounded-lg hover:bg-[var(--bg-secondary)]\"\r\n >\r\n {t('common:cancel', 'Cancel')}\r\n </button>\r\n <button\r\n onClick={saveSkills}\r\n disabled={saving}\r\n className=\"px-4 py-2 bg-[var(--color-primary-600)] text-white rounded-lg hover:bg-[var(--color-primary-700)] disabled:opacity-50\"\r\n >\r\n {saving ? t('common:saving', 'Saving...') : t('common:save', 'Save')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["proficiencyColors","skillCategories","AgentSkillsPage","t","useTranslation","loading","setLoading","useState","agents","setAgents","search","setSearch","editingUserId","setEditingUserId","editingSkills","setEditingSkills","saving","setSaving","loadAgents","useCallback","data","skillsApi","grouped","groupSkillsByAgent","error","useEffect","skills","agentMap","skill","a","b","filteredAgents","agent","getProficiencyLabel","level","openEditModal","s","closeEditModal","addSkillRow","removeSkillRow","index","_","i","updateSkillRow","field","value","updated","saveSkills","request","jsxs","jsx","Breadcrumb","Loader2","Edit2","e","cat","Trash2","Plus"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AgentSkillsPage-CVq3qZoe.js","sources":["../../src/pages/platform/support/AgentSkillsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, Edit2, Trash2, Plus } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { skillsApi, type AgentSkillDto, type UpdateAgentSkillsRequest } from '@/services/api/assignmentApi';\r\n\r\nconst proficiencyColors: Record<number, string> = {\r\n 1: 'bg-[var(--error-bg)] text-[var(--error-text)]',\r\n 2: 'bg-[var(--warning-bg)] text-[var(--warning-text)]',\r\n 3: 'bg-[var(--info-bg)] text-[var(--info-text)]',\r\n 4: 'bg-[var(--success-bg)] text-[var(--success-text)]',\r\n 5: 'bg-[var(--success-bg)] text-[var(--success-text)]',\r\n};\r\n\r\nconst skillCategories = ['Billing', 'Technical', 'Security', 'General', 'Networking', 'Software', 'Hardware'];\r\n\r\ninterface Agent {\r\n userId: string;\r\n userName: string | null;\r\n skills: AgentSkillDto[];\r\n}\r\n\r\ninterface EditableSkill {\r\n skillCategory: string;\r\n proficiencyLevel: number;\r\n}\r\n\r\nexport function AgentSkillsPage(): ReactElement {\r\n const { t } = useTranslation('support');\r\n const [loading, setLoading] = useState(true);\r\n const [agents, setAgents] = useState<Agent[]>([]);\r\n const [search, setSearch] = useState('');\r\n const [editingUserId, setEditingUserId] = useState<string | null>(null);\r\n const [editingSkills, setEditingSkills] = useState<EditableSkill[]>([]);\r\n const [saving, setSaving] = useState(false);\r\n\r\n const loadAgents = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const data = await skillsApi.getAll();\r\n const grouped = groupSkillsByAgent(data);\r\n setAgents(grouped);\r\n } catch (error) {\r\n console.error('Failed to load agent skills:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n loadAgents();\r\n }, [loadAgents]);\r\n\r\n const groupSkillsByAgent = (skills: AgentSkillDto[]): Agent[] => {\r\n const agentMap = new Map<string, Agent>();\r\n skills.forEach((skill) => {\r\n if (!agentMap.has(skill.userId)) {\r\n agentMap.set(skill.userId, {\r\n userId: skill.userId,\r\n userName: null,\r\n skills: [],\r\n });\r\n }\r\n agentMap.get(skill.userId)!.skills.push(skill);\r\n });\r\n return Array.from(agentMap.values()).sort((a, b) =>\r\n (a.userName || '').localeCompare(b.userName || '')\r\n );\r\n };\r\n\r\n const filteredAgents = agents.filter((agent) =>\r\n (agent.userName || '').toLowerCase().includes(search.toLowerCase())\r\n );\r\n\r\n const getProficiencyLabel = (level: number): string => {\r\n const labels: Record<number, string> = {\r\n 1: t('agentSkills.proficiency.beginner'),\r\n 2: t('agentSkills.proficiency.intermediate'),\r\n 3: t('agentSkills.proficiency.advanced'),\r\n 4: t('agentSkills.proficiency.expert'),\r\n 5: t('agentSkills.proficiency.master'),\r\n };\r\n return labels[level] || '';\r\n };\r\n\r\n const openEditModal = (agent: Agent) => {\r\n setEditingUserId(agent.userId);\r\n setEditingSkills(\r\n agent.skills.map((s) => ({\r\n skillCategory: s.skillCategory,\r\n proficiencyLevel: s.proficiencyLevel,\r\n }))\r\n );\r\n };\r\n\r\n const closeEditModal = () => {\r\n setEditingUserId(null);\r\n setEditingSkills([]);\r\n };\r\n\r\n const addSkillRow = () => {\r\n setEditingSkills([...editingSkills, { skillCategory: '', proficiencyLevel: 3 }]);\r\n };\r\n\r\n const removeSkillRow = (index: number) => {\r\n setEditingSkills(editingSkills.filter((_, i) => i !== index));\r\n };\r\n\r\n const updateSkillRow = (index: number, field: keyof EditableSkill, value: string | number) => {\r\n const updated = [...editingSkills];\r\n updated[index] = { ...updated[index], [field]: value };\r\n setEditingSkills(updated);\r\n };\r\n\r\n const saveSkills = async () => {\r\n if (!editingUserId) return;\r\n try {\r\n setSaving(true);\r\n const request: UpdateAgentSkillsRequest = {\r\n skills: editingSkills.filter((s) => s.skillCategory.trim()),\r\n };\r\n await skillsApi.update(editingUserId, request);\r\n await loadAgents();\r\n closeEditModal();\r\n } catch (error) {\r\n console.error('Failed to save skills:', error);\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('title', 'Support'), href: '/support' },\r\n { label: t('assignment.skills') },\r\n ]}\r\n />\r\n\r\n <div>\r\n <h1 className=\"text-2xl font-bold\">{t('assignment.skills')}</h1>\r\n <p className=\"text-[var(--text-secondary)]\">{t('assignment.availabilityDescription', 'Manage agent skills and proficiency levels')}</p>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <input\r\n type=\"text\"\r\n placeholder={t('common:search', 'Search agents...')}\r\n value={search}\r\n onChange={(e) => setSearch(e.target.value)}\r\n className=\"w-full px-4 py-2 border rounded-lg bg-[var(--bg-primary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n />\r\n </div>\r\n\r\n {loading && (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n )}\r\n {!loading && filteredAgents.length === 0 && (\r\n <div className=\"text-center py-12\">\r\n <p className=\"text-[var(--text-secondary)]\">{t('assignment.noAgents', 'No agents found')}</p>\r\n </div>\r\n )}\r\n {!loading && filteredAgents.length > 0 && (\r\n <div className=\"space-y-4\">\r\n {filteredAgents.map((agent) => (\r\n <div key={agent.userId} className=\"card p-6\">\r\n <div className=\"flex items-start justify-between mb-4\">\r\n <div>\r\n <h3 className=\"text-lg font-semibold\">{agent.userName || 'Unknown Agent'}</h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{agent.userId}</p>\r\n </div>\r\n <button\r\n onClick={() => openEditModal(agent)}\r\n className=\"flex items-center gap-2 px-3 py-2 bg-[var(--color-primary-600)] text-white rounded-lg hover:bg-[var(--color-primary-700)]\"\r\n >\r\n <Edit2 className=\"w-4 h-4\" />\r\n {t('common:edit', 'Edit')}\r\n </button>\r\n </div>\r\n\r\n {agent.skills.length > 0 ? (\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n {agent.skills.map((skill) => (\r\n <div\r\n key={`${skill.skillCategory}-${skill.proficiencyLevel}`}\r\n className=\"flex items-center justify-between p-3 bg-[var(--bg-secondary)] rounded-lg\"\r\n >\r\n <div>\r\n <p className=\"font-medium text-sm\">{skill.skillCategory}</p>\r\n </div>\r\n <span className={`px-3 py-1 rounded-full text-xs font-medium ${proficiencyColors[skill.proficiencyLevel]}`}>\r\n {getProficiencyLabel(skill.proficiencyLevel)}\r\n </span>\r\n </div>\r\n ))}\r\n </div>\r\n ) : (\r\n <p className=\"text-sm text-[var(--text-secondary)] italic\">{t('assignment.noSkills', 'No skills assigned')}</p>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {editingUserId && (\r\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4\">\r\n <div className=\"bg-[var(--bg-primary)] rounded-lg shadow-lg max-w-2xl w-full max-h-96 overflow-y-auto\">\r\n <div className=\"sticky top-0 bg-[var(--bg-primary)] border-b border-[var(--border-color)] p-6 flex items-center justify-between\">\r\n <h2 className=\"text-lg font-semibold\">{t('assignment.editSkills', 'Edit Skills')}</h2>\r\n <button\r\n onClick={closeEditModal}\r\n className=\"text-[var(--text-secondary)] hover:text-[var(--text-primary)]\"\r\n >\r\n ✕\r\n </button>\r\n </div>\r\n\r\n <div className=\"p-6 space-y-4\">\r\n {editingSkills.map((skill, index) => (\r\n <div key={`skill-${index}`} className=\"flex gap-3 items-end\">\r\n <div className=\"flex-1\">\r\n <label className=\"block text-xs font-medium mb-1 text-[var(--text-secondary)]\">\r\n {t('assignment.skillCategory', 'Skill Category')}\r\n </label>\r\n <select\r\n value={skill.skillCategory}\r\n onChange={(e) => updateSkillRow(index, 'skillCategory', e.target.value)}\r\n className=\"w-full px-3 py-2 border rounded-lg bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n <option value=\"\">Select skill...</option>\r\n {skillCategories.map((cat) => (\r\n <option key={cat} value={cat}>\r\n {cat}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n <div className=\"w-32\">\r\n <label className=\"block text-xs font-medium mb-1 text-[var(--text-secondary)]\">\r\n {t('assignment.proficiency', 'Proficiency')}\r\n </label>\r\n <select\r\n value={skill.proficiencyLevel}\r\n onChange={(e) => updateSkillRow(index, 'proficiencyLevel', parseInt(e.target.value))}\r\n className=\"w-full px-3 py-2 border rounded-lg bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n {[1, 2, 3, 4, 5].map((level) => (\r\n <option key={level} value={level}>\r\n {getProficiencyLabel(level)}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n <button\r\n onClick={() => removeSkillRow(index)}\r\n className=\"p-2 text-[var(--error-text)] hover:bg-[var(--error-bg)] rounded-lg\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n ))}\r\n\r\n <button\r\n onClick={addSkillRow}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm border border-[var(--border-color)] rounded-lg hover:bg-[var(--bg-secondary)]\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('assignment.addSkill', 'Add Skill')}\r\n </button>\r\n </div>\r\n\r\n <div className=\"sticky bottom-0 bg-[var(--bg-primary)] border-t border-[var(--border-color)] p-6 flex justify-end gap-3\">\r\n <button\r\n onClick={closeEditModal}\r\n className=\"px-4 py-2 border border-[var(--border-color)] rounded-lg hover:bg-[var(--bg-secondary)]\"\r\n >\r\n {t('common:cancel', 'Cancel')}\r\n </button>\r\n <button\r\n onClick={saveSkills}\r\n disabled={saving}\r\n className=\"px-4 py-2 bg-[var(--color-primary-600)] text-white rounded-lg hover:bg-[var(--color-primary-700)] disabled:opacity-50\"\r\n >\r\n {saving ? t('common:saving', 'Saving...') : t('common:save', 'Save')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["proficiencyColors","skillCategories","AgentSkillsPage","t","useTranslation","loading","setLoading","useState","agents","setAgents","search","setSearch","editingUserId","setEditingUserId","editingSkills","setEditingSkills","saving","setSaving","loadAgents","useCallback","data","skillsApi","grouped","groupSkillsByAgent","error","useEffect","skills","agentMap","skill","a","b","filteredAgents","agent","getProficiencyLabel","level","openEditModal","s","closeEditModal","addSkillRow","removeSkillRow","index","_","i","updateSkillRow","field","value","updated","saveSkills","request","jsxs","jsx","Breadcrumb","Loader2","Edit2","e","cat","Trash2","Plus"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),l=require("react"),q=require("react-i18next"),o=require("lucide-react"),p=require("./index-
|
|
2
|
-
//# sourceMappingURL=AgentSkillsPage-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),l=require("react"),q=require("react-i18next"),o=require("lucide-react"),p=require("./index-cAikSVW0.js"),M={1:"bg-[var(--error-bg)] text-[var(--error-text)]",2:"bg-[var(--warning-bg)] text-[var(--warning-text)]",3:"bg-[var(--info-bg)] text-[var(--info-text)]",4:"bg-[var(--success-bg)] text-[var(--success-text)]",5:"bg-[var(--success-bg)] text-[var(--success-text)]"},P=["Billing","Technical","Security","General","Networking","Software","Hardware"];function R(){const{t:a}=q.useTranslation("support"),[d,v]=l.useState(!0),[N,S]=l.useState([]),[b,w]=l.useState(""),[m,y]=l.useState(null),[i,n]=l.useState([]),[h,f]=l.useState(!1),g=l.useCallback(async()=>{try{v(!0);const s=await p.skillsApi.getAll(),r=C(s);S(r)}catch(s){console.error("Failed to load agent skills:",s)}finally{v(!1)}},[]);l.useEffect(()=>{g()},[g]);const C=s=>{const r=new Map;return s.forEach(t=>{r.has(t.userId)||r.set(t.userId,{userId:t.userId,userName:null,skills:[]}),r.get(t.userId).skills.push(t)}),Array.from(r.values()).sort((t,c)=>(t.userName||"").localeCompare(c.userName||""))},x=N.filter(s=>(s.userName||"").toLowerCase().includes(b.toLowerCase())),j=s=>({1:a("agentSkills.proficiency.beginner"),2:a("agentSkills.proficiency.intermediate"),3:a("agentSkills.proficiency.advanced"),4:a("agentSkills.proficiency.expert"),5:a("agentSkills.proficiency.master")})[s]||"",L=s=>{y(s.userId),n(s.skills.map(r=>({skillCategory:r.skillCategory,proficiencyLevel:r.proficiencyLevel})))},u=()=>{y(null),n([])},A=()=>{n([...i,{skillCategory:"",proficiencyLevel:3}])},I=s=>{n(i.filter((r,t)=>t!==s))},k=(s,r,t)=>{const c=[...i];c[s]={...c[s],[r]:t},n(c)},E=async()=>{if(m)try{f(!0);const s={skills:i.filter(r=>r.skillCategory.trim())};await p.skillsApi.update(m,s),await g(),u()}catch(s){console.error("Failed to save skills:",s)}finally{f(!1)}};return e.jsxs("div",{className:"space-y-6",children:[e.jsx(p.Breadcrumb,{items:[{label:a("title","Support"),href:"/support"},{label:a("assignment.skills")}]}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold",children:a("assignment.skills")}),e.jsx("p",{className:"text-[var(--text-secondary)]",children:a("assignment.availabilityDescription","Manage agent skills and proficiency levels")})]}),e.jsx("div",{className:"mb-4",children:e.jsx("input",{type:"text",placeholder:a("common:search","Search agents..."),value:b,onChange:s=>w(s.target.value),className:"w-full px-4 py-2 border rounded-lg bg-[var(--bg-primary)] text-[var(--text-primary)] border-[var(--border-color)]"})}),d&&e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(o.Loader2,{className:"w-8 h-8 animate-spin text-[var(--color-primary-600)]"})}),!d&&x.length===0&&e.jsx("div",{className:"text-center py-12",children:e.jsx("p",{className:"text-[var(--text-secondary)]",children:a("assignment.noAgents","No agents found")})}),!d&&x.length>0&&e.jsx("div",{className:"space-y-4",children:x.map(s=>e.jsxs("div",{className:"card p-6",children:[e.jsxs("div",{className:"flex items-start justify-between mb-4",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold",children:s.userName||"Unknown Agent"}),e.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:s.userId})]}),e.jsxs("button",{onClick:()=>L(s),className:"flex items-center gap-2 px-3 py-2 bg-[var(--color-primary-600)] text-white rounded-lg hover:bg-[var(--color-primary-700)]",children:[e.jsx(o.Edit2,{className:"w-4 h-4"}),a("common:edit","Edit")]})]}),s.skills.length>0?e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:s.skills.map(r=>e.jsxs("div",{className:"flex items-center justify-between p-3 bg-[var(--bg-secondary)] rounded-lg",children:[e.jsx("div",{children:e.jsx("p",{className:"font-medium text-sm",children:r.skillCategory})}),e.jsx("span",{className:`px-3 py-1 rounded-full text-xs font-medium ${M[r.proficiencyLevel]}`,children:j(r.proficiencyLevel)})]},`${r.skillCategory}-${r.proficiencyLevel}`))}):e.jsx("p",{className:"text-sm text-[var(--text-secondary)] italic",children:a("assignment.noSkills","No skills assigned")})]},s.userId))}),m&&e.jsx("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4",children:e.jsxs("div",{className:"bg-[var(--bg-primary)] rounded-lg shadow-lg max-w-2xl w-full max-h-96 overflow-y-auto",children:[e.jsxs("div",{className:"sticky top-0 bg-[var(--bg-primary)] border-b border-[var(--border-color)] p-6 flex items-center justify-between",children:[e.jsx("h2",{className:"text-lg font-semibold",children:a("assignment.editSkills","Edit Skills")}),e.jsx("button",{onClick:u,className:"text-[var(--text-secondary)] hover:text-[var(--text-primary)]",children:"✕"})]}),e.jsxs("div",{className:"p-6 space-y-4",children:[i.map((s,r)=>e.jsxs("div",{className:"flex gap-3 items-end",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("label",{className:"block text-xs font-medium mb-1 text-[var(--text-secondary)]",children:a("assignment.skillCategory","Skill Category")}),e.jsxs("select",{value:s.skillCategory,onChange:t=>k(r,"skillCategory",t.target.value),className:"w-full px-3 py-2 border rounded-lg bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]",children:[e.jsx("option",{value:"",children:"Select skill..."}),P.map(t=>e.jsx("option",{value:t,children:t},t))]})]}),e.jsxs("div",{className:"w-32",children:[e.jsx("label",{className:"block text-xs font-medium mb-1 text-[var(--text-secondary)]",children:a("assignment.proficiency","Proficiency")}),e.jsx("select",{value:s.proficiencyLevel,onChange:t=>k(r,"proficiencyLevel",parseInt(t.target.value)),className:"w-full px-3 py-2 border rounded-lg bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]",children:[1,2,3,4,5].map(t=>e.jsx("option",{value:t,children:j(t)},t))})]}),e.jsx("button",{onClick:()=>I(r),className:"p-2 text-[var(--error-text)] hover:bg-[var(--error-bg)] rounded-lg",children:e.jsx(o.Trash2,{className:"w-4 h-4"})})]},`skill-${r}`)),e.jsxs("button",{onClick:A,className:"flex items-center gap-2 px-4 py-2 text-sm border border-[var(--border-color)] rounded-lg hover:bg-[var(--bg-secondary)]",children:[e.jsx(o.Plus,{className:"w-4 h-4"}),a("assignment.addSkill","Add Skill")]})]}),e.jsxs("div",{className:"sticky bottom-0 bg-[var(--bg-primary)] border-t border-[var(--border-color)] p-6 flex justify-end gap-3",children:[e.jsx("button",{onClick:u,className:"px-4 py-2 border border-[var(--border-color)] rounded-lg hover:bg-[var(--bg-secondary)]",children:a("common:cancel","Cancel")}),e.jsx("button",{onClick:E,disabled:h,className:"px-4 py-2 bg-[var(--color-primary-600)] text-white rounded-lg hover:bg-[var(--color-primary-700)] disabled:opacity-50",children:h?a("common:saving","Saving..."):a("common:save","Save")})]})]})})]})}exports.AgentSkillsPage=R;
|
|
2
|
+
//# sourceMappingURL=AgentSkillsPage-DJb49NMA.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentSkillsPage-ABpqnnyK.js","sources":["../../src/pages/platform/support/AgentSkillsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, Edit2, Trash2, Plus } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { skillsApi, type AgentSkillDto, type UpdateAgentSkillsRequest } from '@/services/api/assignmentApi';\r\n\r\nconst proficiencyColors: Record<number, string> = {\r\n 1: 'bg-[var(--error-bg)] text-[var(--error-text)]',\r\n 2: 'bg-[var(--warning-bg)] text-[var(--warning-text)]',\r\n 3: 'bg-[var(--info-bg)] text-[var(--info-text)]',\r\n 4: 'bg-[var(--success-bg)] text-[var(--success-text)]',\r\n 5: 'bg-[var(--success-bg)] text-[var(--success-text)]',\r\n};\r\n\r\nconst skillCategories = ['Billing', 'Technical', 'Security', 'General', 'Networking', 'Software', 'Hardware'];\r\n\r\ninterface Agent {\r\n userId: string;\r\n userName: string | null;\r\n skills: AgentSkillDto[];\r\n}\r\n\r\ninterface EditableSkill {\r\n skillCategory: string;\r\n proficiencyLevel: number;\r\n}\r\n\r\nexport function AgentSkillsPage(): ReactElement {\r\n const { t } = useTranslation('support');\r\n const [loading, setLoading] = useState(true);\r\n const [agents, setAgents] = useState<Agent[]>([]);\r\n const [search, setSearch] = useState('');\r\n const [editingUserId, setEditingUserId] = useState<string | null>(null);\r\n const [editingSkills, setEditingSkills] = useState<EditableSkill[]>([]);\r\n const [saving, setSaving] = useState(false);\r\n\r\n const loadAgents = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const data = await skillsApi.getAll();\r\n const grouped = groupSkillsByAgent(data);\r\n setAgents(grouped);\r\n } catch (error) {\r\n console.error('Failed to load agent skills:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n loadAgents();\r\n }, [loadAgents]);\r\n\r\n const groupSkillsByAgent = (skills: AgentSkillDto[]): Agent[] => {\r\n const agentMap = new Map<string, Agent>();\r\n skills.forEach((skill) => {\r\n if (!agentMap.has(skill.userId)) {\r\n agentMap.set(skill.userId, {\r\n userId: skill.userId,\r\n userName: null,\r\n skills: [],\r\n });\r\n }\r\n agentMap.get(skill.userId)!.skills.push(skill);\r\n });\r\n return Array.from(agentMap.values()).sort((a, b) =>\r\n (a.userName || '').localeCompare(b.userName || '')\r\n );\r\n };\r\n\r\n const filteredAgents = agents.filter((agent) =>\r\n (agent.userName || '').toLowerCase().includes(search.toLowerCase())\r\n );\r\n\r\n const getProficiencyLabel = (level: number): string => {\r\n const labels: Record<number, string> = {\r\n 1: t('agentSkills.proficiency.beginner'),\r\n 2: t('agentSkills.proficiency.intermediate'),\r\n 3: t('agentSkills.proficiency.advanced'),\r\n 4: t('agentSkills.proficiency.expert'),\r\n 5: t('agentSkills.proficiency.master'),\r\n };\r\n return labels[level] || '';\r\n };\r\n\r\n const openEditModal = (agent: Agent) => {\r\n setEditingUserId(agent.userId);\r\n setEditingSkills(\r\n agent.skills.map((s) => ({\r\n skillCategory: s.skillCategory,\r\n proficiencyLevel: s.proficiencyLevel,\r\n }))\r\n );\r\n };\r\n\r\n const closeEditModal = () => {\r\n setEditingUserId(null);\r\n setEditingSkills([]);\r\n };\r\n\r\n const addSkillRow = () => {\r\n setEditingSkills([...editingSkills, { skillCategory: '', proficiencyLevel: 3 }]);\r\n };\r\n\r\n const removeSkillRow = (index: number) => {\r\n setEditingSkills(editingSkills.filter((_, i) => i !== index));\r\n };\r\n\r\n const updateSkillRow = (index: number, field: keyof EditableSkill, value: string | number) => {\r\n const updated = [...editingSkills];\r\n updated[index] = { ...updated[index], [field]: value };\r\n setEditingSkills(updated);\r\n };\r\n\r\n const saveSkills = async () => {\r\n if (!editingUserId) return;\r\n try {\r\n setSaving(true);\r\n const request: UpdateAgentSkillsRequest = {\r\n skills: editingSkills.filter((s) => s.skillCategory.trim()),\r\n };\r\n await skillsApi.update(editingUserId, request);\r\n await loadAgents();\r\n closeEditModal();\r\n } catch (error) {\r\n console.error('Failed to save skills:', error);\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('title', 'Support'), href: '/support' },\r\n { label: t('assignment.skills') },\r\n ]}\r\n />\r\n\r\n <div>\r\n <h1 className=\"text-2xl font-bold\">{t('assignment.skills')}</h1>\r\n <p className=\"text-[var(--text-secondary)]\">{t('assignment.availabilityDescription', 'Manage agent skills and proficiency levels')}</p>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <input\r\n type=\"text\"\r\n placeholder={t('common:search', 'Search agents...')}\r\n value={search}\r\n onChange={(e) => setSearch(e.target.value)}\r\n className=\"w-full px-4 py-2 border rounded-lg bg-[var(--bg-primary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n />\r\n </div>\r\n\r\n {loading && (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n )}\r\n {!loading && filteredAgents.length === 0 && (\r\n <div className=\"text-center py-12\">\r\n <p className=\"text-[var(--text-secondary)]\">{t('assignment.noAgents', 'No agents found')}</p>\r\n </div>\r\n )}\r\n {!loading && filteredAgents.length > 0 && (\r\n <div className=\"space-y-4\">\r\n {filteredAgents.map((agent) => (\r\n <div key={agent.userId} className=\"card p-6\">\r\n <div className=\"flex items-start justify-between mb-4\">\r\n <div>\r\n <h3 className=\"text-lg font-semibold\">{agent.userName || 'Unknown Agent'}</h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{agent.userId}</p>\r\n </div>\r\n <button\r\n onClick={() => openEditModal(agent)}\r\n className=\"flex items-center gap-2 px-3 py-2 bg-[var(--color-primary-600)] text-white rounded-lg hover:bg-[var(--color-primary-700)]\"\r\n >\r\n <Edit2 className=\"w-4 h-4\" />\r\n {t('common:edit', 'Edit')}\r\n </button>\r\n </div>\r\n\r\n {agent.skills.length > 0 ? (\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n {agent.skills.map((skill) => (\r\n <div\r\n key={`${skill.skillCategory}-${skill.proficiencyLevel}`}\r\n className=\"flex items-center justify-between p-3 bg-[var(--bg-secondary)] rounded-lg\"\r\n >\r\n <div>\r\n <p className=\"font-medium text-sm\">{skill.skillCategory}</p>\r\n </div>\r\n <span className={`px-3 py-1 rounded-full text-xs font-medium ${proficiencyColors[skill.proficiencyLevel]}`}>\r\n {getProficiencyLabel(skill.proficiencyLevel)}\r\n </span>\r\n </div>\r\n ))}\r\n </div>\r\n ) : (\r\n <p className=\"text-sm text-[var(--text-secondary)] italic\">{t('assignment.noSkills', 'No skills assigned')}</p>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {editingUserId && (\r\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4\">\r\n <div className=\"bg-[var(--bg-primary)] rounded-lg shadow-lg max-w-2xl w-full max-h-96 overflow-y-auto\">\r\n <div className=\"sticky top-0 bg-[var(--bg-primary)] border-b border-[var(--border-color)] p-6 flex items-center justify-between\">\r\n <h2 className=\"text-lg font-semibold\">{t('assignment.editSkills', 'Edit Skills')}</h2>\r\n <button\r\n onClick={closeEditModal}\r\n className=\"text-[var(--text-secondary)] hover:text-[var(--text-primary)]\"\r\n >\r\n ✕\r\n </button>\r\n </div>\r\n\r\n <div className=\"p-6 space-y-4\">\r\n {editingSkills.map((skill, index) => (\r\n <div key={`skill-${index}`} className=\"flex gap-3 items-end\">\r\n <div className=\"flex-1\">\r\n <label className=\"block text-xs font-medium mb-1 text-[var(--text-secondary)]\">\r\n {t('assignment.skillCategory', 'Skill Category')}\r\n </label>\r\n <select\r\n value={skill.skillCategory}\r\n onChange={(e) => updateSkillRow(index, 'skillCategory', e.target.value)}\r\n className=\"w-full px-3 py-2 border rounded-lg bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n <option value=\"\">Select skill...</option>\r\n {skillCategories.map((cat) => (\r\n <option key={cat} value={cat}>\r\n {cat}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n <div className=\"w-32\">\r\n <label className=\"block text-xs font-medium mb-1 text-[var(--text-secondary)]\">\r\n {t('assignment.proficiency', 'Proficiency')}\r\n </label>\r\n <select\r\n value={skill.proficiencyLevel}\r\n onChange={(e) => updateSkillRow(index, 'proficiencyLevel', parseInt(e.target.value))}\r\n className=\"w-full px-3 py-2 border rounded-lg bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n {[1, 2, 3, 4, 5].map((level) => (\r\n <option key={level} value={level}>\r\n {getProficiencyLabel(level)}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n <button\r\n onClick={() => removeSkillRow(index)}\r\n className=\"p-2 text-[var(--error-text)] hover:bg-[var(--error-bg)] rounded-lg\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n ))}\r\n\r\n <button\r\n onClick={addSkillRow}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm border border-[var(--border-color)] rounded-lg hover:bg-[var(--bg-secondary)]\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('assignment.addSkill', 'Add Skill')}\r\n </button>\r\n </div>\r\n\r\n <div className=\"sticky bottom-0 bg-[var(--bg-primary)] border-t border-[var(--border-color)] p-6 flex justify-end gap-3\">\r\n <button\r\n onClick={closeEditModal}\r\n className=\"px-4 py-2 border border-[var(--border-color)] rounded-lg hover:bg-[var(--bg-secondary)]\"\r\n >\r\n {t('common:cancel', 'Cancel')}\r\n </button>\r\n <button\r\n onClick={saveSkills}\r\n disabled={saving}\r\n className=\"px-4 py-2 bg-[var(--color-primary-600)] text-white rounded-lg hover:bg-[var(--color-primary-700)] disabled:opacity-50\"\r\n >\r\n {saving ? t('common:saving', 'Saving...') : t('common:save', 'Save')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["proficiencyColors","skillCategories","AgentSkillsPage","t","useTranslation","loading","setLoading","useState","agents","setAgents","search","setSearch","editingUserId","setEditingUserId","editingSkills","setEditingSkills","saving","setSaving","loadAgents","useCallback","data","skillsApi","grouped","groupSkillsByAgent","error","useEffect","skills","agentMap","skill","a","b","filteredAgents","agent","getProficiencyLabel","level","openEditModal","s","closeEditModal","addSkillRow","removeSkillRow","index","_","i","updateSkillRow","field","value","updated","saveSkills","request","jsxs","jsx","Breadcrumb","e","Loader2","Edit2","cat","Trash2","Plus"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AgentSkillsPage-DJb49NMA.js","sources":["../../src/pages/platform/support/AgentSkillsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, Edit2, Trash2, Plus } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { skillsApi, type AgentSkillDto, type UpdateAgentSkillsRequest } from '@/services/api/assignmentApi';\r\n\r\nconst proficiencyColors: Record<number, string> = {\r\n 1: 'bg-[var(--error-bg)] text-[var(--error-text)]',\r\n 2: 'bg-[var(--warning-bg)] text-[var(--warning-text)]',\r\n 3: 'bg-[var(--info-bg)] text-[var(--info-text)]',\r\n 4: 'bg-[var(--success-bg)] text-[var(--success-text)]',\r\n 5: 'bg-[var(--success-bg)] text-[var(--success-text)]',\r\n};\r\n\r\nconst skillCategories = ['Billing', 'Technical', 'Security', 'General', 'Networking', 'Software', 'Hardware'];\r\n\r\ninterface Agent {\r\n userId: string;\r\n userName: string | null;\r\n skills: AgentSkillDto[];\r\n}\r\n\r\ninterface EditableSkill {\r\n skillCategory: string;\r\n proficiencyLevel: number;\r\n}\r\n\r\nexport function AgentSkillsPage(): ReactElement {\r\n const { t } = useTranslation('support');\r\n const [loading, setLoading] = useState(true);\r\n const [agents, setAgents] = useState<Agent[]>([]);\r\n const [search, setSearch] = useState('');\r\n const [editingUserId, setEditingUserId] = useState<string | null>(null);\r\n const [editingSkills, setEditingSkills] = useState<EditableSkill[]>([]);\r\n const [saving, setSaving] = useState(false);\r\n\r\n const loadAgents = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const data = await skillsApi.getAll();\r\n const grouped = groupSkillsByAgent(data);\r\n setAgents(grouped);\r\n } catch (error) {\r\n console.error('Failed to load agent skills:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n loadAgents();\r\n }, [loadAgents]);\r\n\r\n const groupSkillsByAgent = (skills: AgentSkillDto[]): Agent[] => {\r\n const agentMap = new Map<string, Agent>();\r\n skills.forEach((skill) => {\r\n if (!agentMap.has(skill.userId)) {\r\n agentMap.set(skill.userId, {\r\n userId: skill.userId,\r\n userName: null,\r\n skills: [],\r\n });\r\n }\r\n agentMap.get(skill.userId)!.skills.push(skill);\r\n });\r\n return Array.from(agentMap.values()).sort((a, b) =>\r\n (a.userName || '').localeCompare(b.userName || '')\r\n );\r\n };\r\n\r\n const filteredAgents = agents.filter((agent) =>\r\n (agent.userName || '').toLowerCase().includes(search.toLowerCase())\r\n );\r\n\r\n const getProficiencyLabel = (level: number): string => {\r\n const labels: Record<number, string> = {\r\n 1: t('agentSkills.proficiency.beginner'),\r\n 2: t('agentSkills.proficiency.intermediate'),\r\n 3: t('agentSkills.proficiency.advanced'),\r\n 4: t('agentSkills.proficiency.expert'),\r\n 5: t('agentSkills.proficiency.master'),\r\n };\r\n return labels[level] || '';\r\n };\r\n\r\n const openEditModal = (agent: Agent) => {\r\n setEditingUserId(agent.userId);\r\n setEditingSkills(\r\n agent.skills.map((s) => ({\r\n skillCategory: s.skillCategory,\r\n proficiencyLevel: s.proficiencyLevel,\r\n }))\r\n );\r\n };\r\n\r\n const closeEditModal = () => {\r\n setEditingUserId(null);\r\n setEditingSkills([]);\r\n };\r\n\r\n const addSkillRow = () => {\r\n setEditingSkills([...editingSkills, { skillCategory: '', proficiencyLevel: 3 }]);\r\n };\r\n\r\n const removeSkillRow = (index: number) => {\r\n setEditingSkills(editingSkills.filter((_, i) => i !== index));\r\n };\r\n\r\n const updateSkillRow = (index: number, field: keyof EditableSkill, value: string | number) => {\r\n const updated = [...editingSkills];\r\n updated[index] = { ...updated[index], [field]: value };\r\n setEditingSkills(updated);\r\n };\r\n\r\n const saveSkills = async () => {\r\n if (!editingUserId) return;\r\n try {\r\n setSaving(true);\r\n const request: UpdateAgentSkillsRequest = {\r\n skills: editingSkills.filter((s) => s.skillCategory.trim()),\r\n };\r\n await skillsApi.update(editingUserId, request);\r\n await loadAgents();\r\n closeEditModal();\r\n } catch (error) {\r\n console.error('Failed to save skills:', error);\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('title', 'Support'), href: '/support' },\r\n { label: t('assignment.skills') },\r\n ]}\r\n />\r\n\r\n <div>\r\n <h1 className=\"text-2xl font-bold\">{t('assignment.skills')}</h1>\r\n <p className=\"text-[var(--text-secondary)]\">{t('assignment.availabilityDescription', 'Manage agent skills and proficiency levels')}</p>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <input\r\n type=\"text\"\r\n placeholder={t('common:search', 'Search agents...')}\r\n value={search}\r\n onChange={(e) => setSearch(e.target.value)}\r\n className=\"w-full px-4 py-2 border rounded-lg bg-[var(--bg-primary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n />\r\n </div>\r\n\r\n {loading && (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n )}\r\n {!loading && filteredAgents.length === 0 && (\r\n <div className=\"text-center py-12\">\r\n <p className=\"text-[var(--text-secondary)]\">{t('assignment.noAgents', 'No agents found')}</p>\r\n </div>\r\n )}\r\n {!loading && filteredAgents.length > 0 && (\r\n <div className=\"space-y-4\">\r\n {filteredAgents.map((agent) => (\r\n <div key={agent.userId} className=\"card p-6\">\r\n <div className=\"flex items-start justify-between mb-4\">\r\n <div>\r\n <h3 className=\"text-lg font-semibold\">{agent.userName || 'Unknown Agent'}</h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{agent.userId}</p>\r\n </div>\r\n <button\r\n onClick={() => openEditModal(agent)}\r\n className=\"flex items-center gap-2 px-3 py-2 bg-[var(--color-primary-600)] text-white rounded-lg hover:bg-[var(--color-primary-700)]\"\r\n >\r\n <Edit2 className=\"w-4 h-4\" />\r\n {t('common:edit', 'Edit')}\r\n </button>\r\n </div>\r\n\r\n {agent.skills.length > 0 ? (\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n {agent.skills.map((skill) => (\r\n <div\r\n key={`${skill.skillCategory}-${skill.proficiencyLevel}`}\r\n className=\"flex items-center justify-between p-3 bg-[var(--bg-secondary)] rounded-lg\"\r\n >\r\n <div>\r\n <p className=\"font-medium text-sm\">{skill.skillCategory}</p>\r\n </div>\r\n <span className={`px-3 py-1 rounded-full text-xs font-medium ${proficiencyColors[skill.proficiencyLevel]}`}>\r\n {getProficiencyLabel(skill.proficiencyLevel)}\r\n </span>\r\n </div>\r\n ))}\r\n </div>\r\n ) : (\r\n <p className=\"text-sm text-[var(--text-secondary)] italic\">{t('assignment.noSkills', 'No skills assigned')}</p>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {editingUserId && (\r\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4\">\r\n <div className=\"bg-[var(--bg-primary)] rounded-lg shadow-lg max-w-2xl w-full max-h-96 overflow-y-auto\">\r\n <div className=\"sticky top-0 bg-[var(--bg-primary)] border-b border-[var(--border-color)] p-6 flex items-center justify-between\">\r\n <h2 className=\"text-lg font-semibold\">{t('assignment.editSkills', 'Edit Skills')}</h2>\r\n <button\r\n onClick={closeEditModal}\r\n className=\"text-[var(--text-secondary)] hover:text-[var(--text-primary)]\"\r\n >\r\n ✕\r\n </button>\r\n </div>\r\n\r\n <div className=\"p-6 space-y-4\">\r\n {editingSkills.map((skill, index) => (\r\n <div key={`skill-${index}`} className=\"flex gap-3 items-end\">\r\n <div className=\"flex-1\">\r\n <label className=\"block text-xs font-medium mb-1 text-[var(--text-secondary)]\">\r\n {t('assignment.skillCategory', 'Skill Category')}\r\n </label>\r\n <select\r\n value={skill.skillCategory}\r\n onChange={(e) => updateSkillRow(index, 'skillCategory', e.target.value)}\r\n className=\"w-full px-3 py-2 border rounded-lg bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n <option value=\"\">Select skill...</option>\r\n {skillCategories.map((cat) => (\r\n <option key={cat} value={cat}>\r\n {cat}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n <div className=\"w-32\">\r\n <label className=\"block text-xs font-medium mb-1 text-[var(--text-secondary)]\">\r\n {t('assignment.proficiency', 'Proficiency')}\r\n </label>\r\n <select\r\n value={skill.proficiencyLevel}\r\n onChange={(e) => updateSkillRow(index, 'proficiencyLevel', parseInt(e.target.value))}\r\n className=\"w-full px-3 py-2 border rounded-lg bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n {[1, 2, 3, 4, 5].map((level) => (\r\n <option key={level} value={level}>\r\n {getProficiencyLabel(level)}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n <button\r\n onClick={() => removeSkillRow(index)}\r\n className=\"p-2 text-[var(--error-text)] hover:bg-[var(--error-bg)] rounded-lg\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n ))}\r\n\r\n <button\r\n onClick={addSkillRow}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm border border-[var(--border-color)] rounded-lg hover:bg-[var(--bg-secondary)]\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('assignment.addSkill', 'Add Skill')}\r\n </button>\r\n </div>\r\n\r\n <div className=\"sticky bottom-0 bg-[var(--bg-primary)] border-t border-[var(--border-color)] p-6 flex justify-end gap-3\">\r\n <button\r\n onClick={closeEditModal}\r\n className=\"px-4 py-2 border border-[var(--border-color)] rounded-lg hover:bg-[var(--bg-secondary)]\"\r\n >\r\n {t('common:cancel', 'Cancel')}\r\n </button>\r\n <button\r\n onClick={saveSkills}\r\n disabled={saving}\r\n className=\"px-4 py-2 bg-[var(--color-primary-600)] text-white rounded-lg hover:bg-[var(--color-primary-700)] disabled:opacity-50\"\r\n >\r\n {saving ? t('common:saving', 'Saving...') : t('common:save', 'Save')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["proficiencyColors","skillCategories","AgentSkillsPage","t","useTranslation","loading","setLoading","useState","agents","setAgents","search","setSearch","editingUserId","setEditingUserId","editingSkills","setEditingSkills","saving","setSaving","loadAgents","useCallback","data","skillsApi","grouped","groupSkillsByAgent","error","useEffect","skills","agentMap","skill","a","b","filteredAgents","agent","getProficiencyLabel","level","openEditModal","s","closeEditModal","addSkillRow","removeSkillRow","index","_","i","updateSkillRow","field","value","updated","saveSkills","request","jsxs","jsx","Breadcrumb","e","Loader2","Edit2","cat","Trash2","Plus"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),a=require("react"),O=require("react-i18next"),l=require("lucide-react"),g=require("./index-
|
|
2
|
-
//# sourceMappingURL=AgentWorkloadPage-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),a=require("react"),O=require("react-i18next"),l=require("lucide-react"),g=require("./index-cAikSVW0.js"),B={Online:"bg-[var(--success-bg)] text-[var(--success-text)]",Busy:"bg-[var(--warning-bg)] text-[var(--warning-text)]",Away:"bg-[var(--info-bg)] text-[var(--info-text)]",Offline:"bg-[var(--bg-secondary)] text-[var(--text-secondary)]"},I={Online:l.CheckCircle,Busy:l.AlertCircle,Away:l.AlertCircle,Offline:l.AlertCircle},c={blue:"bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]",green:"bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]",yellow:"bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]",red:"bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]"};function T(){const{t:s}=O.useTranslation("support"),[b,v]=a.useState(!0),[r,p]=a.useState([]),[d,f]=a.useState(!1),[x,y]=a.useState(""),[j,m]=a.useState(null),n=a.useCallback(async()=>{try{v(!0);const t=await g.workloadApi.getAll();p(t)}catch(t){console.error("Failed to load agent workload:",t)}finally{v(!1)}},[]);a.useEffect(()=>{n()},[n]),a.useEffect(()=>{if(!d)return;const t=setInterval(()=>n(),3e4);return()=>clearInterval(t)},[d,n]);const u=t=>Math.round(t.activeTicketCount/t.maxConcurrentTickets*100),N=t=>t>=90?"bg-[var(--error-bg)]":t>=70?"bg-[var(--warning-bg)]":"bg-[var(--success-bg)]",k=async(t,i)=>{try{m(t),await g.availabilityApi.update(t,{status:i}),await n()}catch(o){console.error("Failed to change status:",o)}finally{m(null)}},h=x?r.filter(t=>t.availabilityStatus===x):r,w=r.length,A=r.filter(t=>t.availabilityStatus==="Online").length,C=Math.round(r.reduce((t,i)=>t+u(i),0)/(r.length||1)),S=r.filter(t=>u(t)>80).length;return e.jsxs("div",{className:"space-y-6",children:[e.jsx(g.Breadcrumb,{items:[{label:s("title","Support"),href:"/support"},{label:s("agentWorkload.title")}]}),e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold",children:s("agentWorkload.title")}),e.jsx("p",{className:"text-[var(--text-secondary)]",children:s("agentWorkload.subtitle")})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:()=>n(),className:"p-2 rounded-lg hover:bg-[var(--bg-secondary)]",children:e.jsx(l.RefreshCw,{className:"w-5 h-5"})}),e.jsxs("label",{className:"flex items-center gap-2 px-4 py-2 border border-[var(--border-color)] rounded-lg cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:d,onChange:t=>f(t.target.checked),className:"w-4 h-4"}),e.jsx("span",{className:"text-sm",children:s("agentWorkload.autoRefresh","Auto-refresh")})]})]})]}),b?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(l.Loader2,{className:"w-8 h-8 animate-spin text-[var(--color-primary-600)]"})}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:[e.jsxs("div",{className:`card p-4 text-center border ${c.blue}`,children:[e.jsx("div",{className:"text-2xl font-bold",children:w}),e.jsx("div",{className:"text-sm opacity-80",children:s("agentWorkload.kpi.totalAgents","Total Agents")})]}),e.jsxs("div",{className:`card p-4 text-center border ${c.green}`,children:[e.jsx("div",{className:"text-2xl font-bold",children:A}),e.jsx("div",{className:"text-sm opacity-80",children:s("agentWorkload.kpi.online","Online")})]}),e.jsxs("div",{className:`card p-4 text-center border ${c.yellow}`,children:[e.jsxs("div",{className:"text-2xl font-bold",children:[C,"%"]}),e.jsx("div",{className:"text-sm opacity-80",children:s("agentWorkload.kpi.avgUtilization","Avg. Utilization")})]}),e.jsxs("div",{className:`card p-4 text-center border ${c.red}`,children:[e.jsx("div",{className:"text-2xl font-bold",children:S}),e.jsx("div",{className:"text-sm opacity-80",children:s("agentWorkload.kpi.overloaded","Overloaded")})]})]}),e.jsx("div",{className:"mb-4",children:e.jsxs("select",{value:x,onChange:t=>y(t.target.value),className:"px-4 py-2 border rounded-lg bg-[var(--bg-primary)] text-[var(--text-primary)] border-[var(--border-color)]",children:[e.jsx("option",{value:"",children:s("common:all","All Statuses")}),e.jsx("option",{value:"Online",children:s("agentWorkload.status.Online","Online")}),e.jsx("option",{value:"Busy",children:s("agentWorkload.status.Busy","Busy")}),e.jsx("option",{value:"Away",children:s("agentWorkload.status.Away","Away")}),e.jsx("option",{value:"Offline",children:s("agentWorkload.status.Offline","Offline")})]})}),h.length===0?e.jsx("div",{className:"text-center py-12",children:e.jsx("p",{className:"text-[var(--text-secondary)]",children:s("assignment.noAgents","No agents found")})}):e.jsx("div",{className:"grid grid-cols-1 gap-4",children:h.map(t=>{const i=I[t.availabilityStatus]||l.AlertCircle,o=u(t);return e.jsx("div",{className:"card p-6",children:e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-6",children:[e.jsxs("div",{className:"md:col-span-1",children:[e.jsx("h3",{className:"font-semibold text-lg",children:t.userName||"Unknown Agent"}),e.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:t.userId})]}),e.jsxs("div",{className:"md:col-span-1",children:[e.jsx("p",{className:"text-xs text-[var(--text-secondary)] font-medium mb-1",children:s("assignment.activeTickets","Active Tickets")}),e.jsx("p",{className:"text-2xl font-bold",children:t.activeTicketCount}),e.jsxs("p",{className:"text-xs text-[var(--text-secondary)]",children:[s("assignment.capacity","Capacity"),": ",t.maxConcurrentTickets]})]}),e.jsxs("div",{className:"md:col-span-1",children:[e.jsx("p",{className:"text-xs text-[var(--text-secondary)] font-medium mb-2",children:s("agentWorkload.utilization","Utilization")}),e.jsx("div",{className:"w-full bg-[var(--bg-secondary)] rounded-full h-2 overflow-hidden",children:e.jsx("div",{className:`h-full ${N(o)} transition-all`,style:{width:`${Math.min(o,100)}%`}})}),e.jsxs("p",{className:"text-sm font-semibold mt-1",children:[o,"%"]})]}),e.jsxs("div",{className:"md:col-span-1 flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 justify-center",children:[e.jsx(i,{className:"w-5 h-5"}),e.jsx("span",{className:`px-3 py-1 rounded-full text-xs font-medium ${B[t.availabilityStatus]}`,children:s(`agentWorkload.status.${t.availabilityStatus}`,t.availabilityStatus)})]}),e.jsxs("select",{value:t.availabilityStatus,onChange:W=>k(t.userId,W.target.value),disabled:j===t.userId,className:"w-full px-2 py-1 text-xs border rounded bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]",children:[e.jsx("option",{value:"Online",children:s("agentWorkload.status.Online","Online")}),e.jsx("option",{value:"Busy",children:s("agentWorkload.status.Busy","Busy")}),e.jsx("option",{value:"Away",children:s("agentWorkload.status.Away","Away")}),e.jsx("option",{value:"Offline",children:s("agentWorkload.status.Offline","Offline")})]})]})]})},t.userId)})})]})]})}exports.AgentWorkloadPage=T;
|
|
2
|
+
//# sourceMappingURL=AgentWorkloadPage-D_nk3gKj.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentWorkloadPage-BltzNlXI.js","sources":["../../src/pages/platform/support/AgentWorkloadPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, AlertCircle, CheckCircle, RefreshCw } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { workloadApi, availabilityApi, type AgentWorkloadDto } from '@/services/api/assignmentApi';\r\n\r\nconst statusColors: Record<string, string> = {\r\n Online: 'bg-[var(--success-bg)] text-[var(--success-text)]',\r\n Busy: 'bg-[var(--warning-bg)] text-[var(--warning-text)]',\r\n Away: 'bg-[var(--info-bg)] text-[var(--info-text)]',\r\n Offline: 'bg-[var(--bg-secondary)] text-[var(--text-secondary)]',\r\n};\r\n\r\nconst statusIcons: Record<string, typeof AlertCircle> = {\r\n Online: CheckCircle,\r\n Busy: AlertCircle,\r\n Away: AlertCircle,\r\n Offline: AlertCircle,\r\n};\r\n\r\nconst colorClasses = {\r\n blue: 'bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]',\r\n green: 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]',\r\n yellow: 'bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]',\r\n red: 'bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]',\r\n};\r\n\r\nexport function AgentWorkloadPage(): ReactElement {\r\n const { t } = useTranslation('support');\r\n const [loading, setLoading] = useState(true);\r\n const [agents, setAgents] = useState<AgentWorkloadDto[]>([]);\r\n const [autoRefresh, setAutoRefresh] = useState(false);\r\n const [statusFilter, setStatusFilter] = useState<string>('');\r\n const [changingStatus, setChangingStatus] = useState<string | null>(null);\r\n\r\n const loadWorkload = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const data = await workloadApi.getAll();\r\n setAgents(data);\r\n } catch (error) {\r\n console.error('Failed to load agent workload:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n loadWorkload();\r\n }, [loadWorkload]);\r\n\r\n useEffect(() => {\r\n if (!autoRefresh) return;\r\n const interval = setInterval(() => loadWorkload(), 30000);\r\n return () => clearInterval(interval);\r\n }, [autoRefresh, loadWorkload]);\r\n\r\n const getUtilizationPercent = (agent: AgentWorkloadDto): number => {\r\n return Math.round((agent.activeTicketCount / agent.maxConcurrentTickets) * 100);\r\n };\r\n\r\n const getUtilizationBarColor = (percent: number): string => {\r\n if (percent >= 90) return 'bg-[var(--error-bg)]';\r\n if (percent >= 70) return 'bg-[var(--warning-bg)]';\r\n return 'bg-[var(--success-bg)]';\r\n };\r\n\r\n const changeStatus = async (userId: string, newStatus: string) => {\r\n try {\r\n setChangingStatus(userId);\r\n await availabilityApi.update(userId, { status: newStatus });\r\n await loadWorkload();\r\n } catch (error) {\r\n console.error('Failed to change status:', error);\r\n } finally {\r\n setChangingStatus(null);\r\n }\r\n };\r\n\r\n const filteredAgents = statusFilter\r\n ? agents.filter((a) => a.availabilityStatus === statusFilter)\r\n : agents;\r\n\r\n const totalAgents = agents.length;\r\n const onlineCount = agents.filter((a) => a.availabilityStatus === 'Online').length;\r\n const avgUtilization = Math.round(\r\n agents.reduce((sum, a) => sum + getUtilizationPercent(a), 0) / (agents.length || 1)\r\n );\r\n const overloadedCount = agents.filter((a) => getUtilizationPercent(a) > 80).length;\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('agentWorkload.title') },\r\n ]}\r\n />\r\n\r\n <div className=\"flex items-start justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold\">{t('agentWorkload.title')}</h1>\r\n <p className=\"text-[var(--text-secondary)]\">{t('agentWorkload.subtitle')}</p>\r\n </div>\r\n <div className=\"flex gap-2\">\r\n <button\r\n onClick={() => loadWorkload()}\r\n className=\"p-2 rounded-lg hover:bg-[var(--bg-secondary)]\"\r\n >\r\n <RefreshCw className=\"w-5 h-5\" />\r\n </button>\r\n <label className=\"flex items-center gap-2 px-4 py-2 border border-[var(--border-color)] rounded-lg cursor-pointer\">\r\n <input\r\n type=\"checkbox\"\r\n checked={autoRefresh}\r\n onChange={(e) => setAutoRefresh(e.target.checked)}\r\n className=\"w-4 h-4\"\r\n />\r\n <span className=\"text-sm\">{t('agentWorkload.autoRefresh', 'Auto-refresh')}</span>\r\n </label>\r\n </div>\r\n </div>\r\n\r\n {loading ? (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n ) : (\r\n <>\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\r\n <div className={`card p-4 text-center border ${colorClasses.blue}`}>\r\n <div className=\"text-2xl font-bold\">{totalAgents}</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.totalAgents', 'Total Agents')}</div>\r\n </div>\r\n <div className={`card p-4 text-center border ${colorClasses.green}`}>\r\n <div className=\"text-2xl font-bold\">{onlineCount}</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.online', 'Online')}</div>\r\n </div>\r\n <div className={`card p-4 text-center border ${colorClasses.yellow}`}>\r\n <div className=\"text-2xl font-bold\">{avgUtilization}%</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.avgUtilization', 'Avg. Utilization')}</div>\r\n </div>\r\n <div className={`card p-4 text-center border ${colorClasses.red}`}>\r\n <div className=\"text-2xl font-bold\">{overloadedCount}</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.overloaded', 'Overloaded')}</div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <select\r\n value={statusFilter}\r\n onChange={(e) => setStatusFilter(e.target.value)}\r\n className=\"px-4 py-2 border rounded-lg bg-[var(--bg-primary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n <option value=\"\">{t('common:all', 'All Statuses')}</option>\r\n <option value=\"Online\">{t('agentWorkload.status.Online', 'Online')}</option>\r\n <option value=\"Busy\">{t('agentWorkload.status.Busy', 'Busy')}</option>\r\n <option value=\"Away\">{t('agentWorkload.status.Away', 'Away')}</option>\r\n <option value=\"Offline\">{t('agentWorkload.status.Offline', 'Offline')}</option>\r\n </select>\r\n </div>\r\n\r\n {filteredAgents.length === 0 ? (\r\n <div className=\"text-center py-12\">\r\n <p className=\"text-[var(--text-secondary)]\">{t('assignment.noAgents', 'No agents found')}</p>\r\n </div>\r\n ) : (\r\n <div className=\"grid grid-cols-1 gap-4\">\r\n {filteredAgents.map((agent) => {\r\n const StatusIcon = statusIcons[agent.availabilityStatus] || AlertCircle;\r\n const utilizationPercent = getUtilizationPercent(agent);\r\n\r\n return (\r\n <div key={agent.userId} className=\"card p-6\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-4 gap-6\">\r\n <div className=\"md:col-span-1\">\r\n <h3 className=\"font-semibold text-lg\">{agent.userName || 'Unknown Agent'}</h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{agent.userId}</p>\r\n </div>\r\n\r\n <div className=\"md:col-span-1\">\r\n <p className=\"text-xs text-[var(--text-secondary)] font-medium mb-1\">\r\n {t('assignment.activeTickets', 'Active Tickets')}\r\n </p>\r\n <p className=\"text-2xl font-bold\">{agent.activeTicketCount}</p>\r\n <p className=\"text-xs text-[var(--text-secondary)]\">\r\n {t('assignment.capacity', 'Capacity')}: {agent.maxConcurrentTickets}\r\n </p>\r\n </div>\r\n\r\n <div className=\"md:col-span-1\">\r\n <p className=\"text-xs text-[var(--text-secondary)] font-medium mb-2\">\r\n {t('agentWorkload.utilization', 'Utilization')}\r\n </p>\r\n <div className=\"w-full bg-[var(--bg-secondary)] rounded-full h-2 overflow-hidden\">\r\n <div\r\n className={`h-full ${getUtilizationBarColor(utilizationPercent)} transition-all`}\r\n style={{ width: `${Math.min(utilizationPercent, 100)}%` }}\r\n />\r\n </div>\r\n <p className=\"text-sm font-semibold mt-1\">{utilizationPercent}%</p>\r\n </div>\r\n\r\n <div className=\"md:col-span-1 flex flex-col gap-2\">\r\n <div className=\"flex items-center gap-2 justify-center\">\r\n <StatusIcon className=\"w-5 h-5\" />\r\n <span className={`px-3 py-1 rounded-full text-xs font-medium ${statusColors[agent.availabilityStatus]}`}>\r\n {t(`agentWorkload.status.${agent.availabilityStatus}`, agent.availabilityStatus)}\r\n </span>\r\n </div>\r\n <select\r\n value={agent.availabilityStatus}\r\n onChange={(e) => changeStatus(agent.userId, e.target.value)}\r\n disabled={changingStatus === agent.userId}\r\n className=\"w-full px-2 py-1 text-xs border rounded bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n <option value=\"Online\">{t('agentWorkload.status.Online', 'Online')}</option>\r\n <option value=\"Busy\">{t('agentWorkload.status.Busy', 'Busy')}</option>\r\n <option value=\"Away\">{t('agentWorkload.status.Away', 'Away')}</option>\r\n <option value=\"Offline\">{t('agentWorkload.status.Offline', 'Offline')}</option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["statusColors","statusIcons","CheckCircle","AlertCircle","colorClasses","AgentWorkloadPage","t","useTranslation","loading","setLoading","useState","agents","setAgents","autoRefresh","setAutoRefresh","statusFilter","setStatusFilter","changingStatus","setChangingStatus","loadWorkload","useCallback","data","workloadApi","error","useEffect","interval","getUtilizationPercent","agent","getUtilizationBarColor","percent","changeStatus","userId","newStatus","availabilityApi","filteredAgents","a","totalAgents","onlineCount","avgUtilization","sum","overloadedCount","jsxs","jsx","Breadcrumb","RefreshCw","e","Loader2","Fragment","StatusIcon","utilizationPercent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AgentWorkloadPage-D_nk3gKj.js","sources":["../../src/pages/platform/support/AgentWorkloadPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, AlertCircle, CheckCircle, RefreshCw } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { workloadApi, availabilityApi, type AgentWorkloadDto } from '@/services/api/assignmentApi';\r\n\r\nconst statusColors: Record<string, string> = {\r\n Online: 'bg-[var(--success-bg)] text-[var(--success-text)]',\r\n Busy: 'bg-[var(--warning-bg)] text-[var(--warning-text)]',\r\n Away: 'bg-[var(--info-bg)] text-[var(--info-text)]',\r\n Offline: 'bg-[var(--bg-secondary)] text-[var(--text-secondary)]',\r\n};\r\n\r\nconst statusIcons: Record<string, typeof AlertCircle> = {\r\n Online: CheckCircle,\r\n Busy: AlertCircle,\r\n Away: AlertCircle,\r\n Offline: AlertCircle,\r\n};\r\n\r\nconst colorClasses = {\r\n blue: 'bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]',\r\n green: 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]',\r\n yellow: 'bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]',\r\n red: 'bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]',\r\n};\r\n\r\nexport function AgentWorkloadPage(): ReactElement {\r\n const { t } = useTranslation('support');\r\n const [loading, setLoading] = useState(true);\r\n const [agents, setAgents] = useState<AgentWorkloadDto[]>([]);\r\n const [autoRefresh, setAutoRefresh] = useState(false);\r\n const [statusFilter, setStatusFilter] = useState<string>('');\r\n const [changingStatus, setChangingStatus] = useState<string | null>(null);\r\n\r\n const loadWorkload = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const data = await workloadApi.getAll();\r\n setAgents(data);\r\n } catch (error) {\r\n console.error('Failed to load agent workload:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n loadWorkload();\r\n }, [loadWorkload]);\r\n\r\n useEffect(() => {\r\n if (!autoRefresh) return;\r\n const interval = setInterval(() => loadWorkload(), 30000);\r\n return () => clearInterval(interval);\r\n }, [autoRefresh, loadWorkload]);\r\n\r\n const getUtilizationPercent = (agent: AgentWorkloadDto): number => {\r\n return Math.round((agent.activeTicketCount / agent.maxConcurrentTickets) * 100);\r\n };\r\n\r\n const getUtilizationBarColor = (percent: number): string => {\r\n if (percent >= 90) return 'bg-[var(--error-bg)]';\r\n if (percent >= 70) return 'bg-[var(--warning-bg)]';\r\n return 'bg-[var(--success-bg)]';\r\n };\r\n\r\n const changeStatus = async (userId: string, newStatus: string) => {\r\n try {\r\n setChangingStatus(userId);\r\n await availabilityApi.update(userId, { status: newStatus });\r\n await loadWorkload();\r\n } catch (error) {\r\n console.error('Failed to change status:', error);\r\n } finally {\r\n setChangingStatus(null);\r\n }\r\n };\r\n\r\n const filteredAgents = statusFilter\r\n ? agents.filter((a) => a.availabilityStatus === statusFilter)\r\n : agents;\r\n\r\n const totalAgents = agents.length;\r\n const onlineCount = agents.filter((a) => a.availabilityStatus === 'Online').length;\r\n const avgUtilization = Math.round(\r\n agents.reduce((sum, a) => sum + getUtilizationPercent(a), 0) / (agents.length || 1)\r\n );\r\n const overloadedCount = agents.filter((a) => getUtilizationPercent(a) > 80).length;\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('agentWorkload.title') },\r\n ]}\r\n />\r\n\r\n <div className=\"flex items-start justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold\">{t('agentWorkload.title')}</h1>\r\n <p className=\"text-[var(--text-secondary)]\">{t('agentWorkload.subtitle')}</p>\r\n </div>\r\n <div className=\"flex gap-2\">\r\n <button\r\n onClick={() => loadWorkload()}\r\n className=\"p-2 rounded-lg hover:bg-[var(--bg-secondary)]\"\r\n >\r\n <RefreshCw className=\"w-5 h-5\" />\r\n </button>\r\n <label className=\"flex items-center gap-2 px-4 py-2 border border-[var(--border-color)] rounded-lg cursor-pointer\">\r\n <input\r\n type=\"checkbox\"\r\n checked={autoRefresh}\r\n onChange={(e) => setAutoRefresh(e.target.checked)}\r\n className=\"w-4 h-4\"\r\n />\r\n <span className=\"text-sm\">{t('agentWorkload.autoRefresh', 'Auto-refresh')}</span>\r\n </label>\r\n </div>\r\n </div>\r\n\r\n {loading ? (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n ) : (\r\n <>\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\r\n <div className={`card p-4 text-center border ${colorClasses.blue}`}>\r\n <div className=\"text-2xl font-bold\">{totalAgents}</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.totalAgents', 'Total Agents')}</div>\r\n </div>\r\n <div className={`card p-4 text-center border ${colorClasses.green}`}>\r\n <div className=\"text-2xl font-bold\">{onlineCount}</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.online', 'Online')}</div>\r\n </div>\r\n <div className={`card p-4 text-center border ${colorClasses.yellow}`}>\r\n <div className=\"text-2xl font-bold\">{avgUtilization}%</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.avgUtilization', 'Avg. Utilization')}</div>\r\n </div>\r\n <div className={`card p-4 text-center border ${colorClasses.red}`}>\r\n <div className=\"text-2xl font-bold\">{overloadedCount}</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.overloaded', 'Overloaded')}</div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <select\r\n value={statusFilter}\r\n onChange={(e) => setStatusFilter(e.target.value)}\r\n className=\"px-4 py-2 border rounded-lg bg-[var(--bg-primary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n <option value=\"\">{t('common:all', 'All Statuses')}</option>\r\n <option value=\"Online\">{t('agentWorkload.status.Online', 'Online')}</option>\r\n <option value=\"Busy\">{t('agentWorkload.status.Busy', 'Busy')}</option>\r\n <option value=\"Away\">{t('agentWorkload.status.Away', 'Away')}</option>\r\n <option value=\"Offline\">{t('agentWorkload.status.Offline', 'Offline')}</option>\r\n </select>\r\n </div>\r\n\r\n {filteredAgents.length === 0 ? (\r\n <div className=\"text-center py-12\">\r\n <p className=\"text-[var(--text-secondary)]\">{t('assignment.noAgents', 'No agents found')}</p>\r\n </div>\r\n ) : (\r\n <div className=\"grid grid-cols-1 gap-4\">\r\n {filteredAgents.map((agent) => {\r\n const StatusIcon = statusIcons[agent.availabilityStatus] || AlertCircle;\r\n const utilizationPercent = getUtilizationPercent(agent);\r\n\r\n return (\r\n <div key={agent.userId} className=\"card p-6\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-4 gap-6\">\r\n <div className=\"md:col-span-1\">\r\n <h3 className=\"font-semibold text-lg\">{agent.userName || 'Unknown Agent'}</h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{agent.userId}</p>\r\n </div>\r\n\r\n <div className=\"md:col-span-1\">\r\n <p className=\"text-xs text-[var(--text-secondary)] font-medium mb-1\">\r\n {t('assignment.activeTickets', 'Active Tickets')}\r\n </p>\r\n <p className=\"text-2xl font-bold\">{agent.activeTicketCount}</p>\r\n <p className=\"text-xs text-[var(--text-secondary)]\">\r\n {t('assignment.capacity', 'Capacity')}: {agent.maxConcurrentTickets}\r\n </p>\r\n </div>\r\n\r\n <div className=\"md:col-span-1\">\r\n <p className=\"text-xs text-[var(--text-secondary)] font-medium mb-2\">\r\n {t('agentWorkload.utilization', 'Utilization')}\r\n </p>\r\n <div className=\"w-full bg-[var(--bg-secondary)] rounded-full h-2 overflow-hidden\">\r\n <div\r\n className={`h-full ${getUtilizationBarColor(utilizationPercent)} transition-all`}\r\n style={{ width: `${Math.min(utilizationPercent, 100)}%` }}\r\n />\r\n </div>\r\n <p className=\"text-sm font-semibold mt-1\">{utilizationPercent}%</p>\r\n </div>\r\n\r\n <div className=\"md:col-span-1 flex flex-col gap-2\">\r\n <div className=\"flex items-center gap-2 justify-center\">\r\n <StatusIcon className=\"w-5 h-5\" />\r\n <span className={`px-3 py-1 rounded-full text-xs font-medium ${statusColors[agent.availabilityStatus]}`}>\r\n {t(`agentWorkload.status.${agent.availabilityStatus}`, agent.availabilityStatus)}\r\n </span>\r\n </div>\r\n <select\r\n value={agent.availabilityStatus}\r\n onChange={(e) => changeStatus(agent.userId, e.target.value)}\r\n disabled={changingStatus === agent.userId}\r\n className=\"w-full px-2 py-1 text-xs border rounded bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n <option value=\"Online\">{t('agentWorkload.status.Online', 'Online')}</option>\r\n <option value=\"Busy\">{t('agentWorkload.status.Busy', 'Busy')}</option>\r\n <option value=\"Away\">{t('agentWorkload.status.Away', 'Away')}</option>\r\n <option value=\"Offline\">{t('agentWorkload.status.Offline', 'Offline')}</option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["statusColors","statusIcons","CheckCircle","AlertCircle","colorClasses","AgentWorkloadPage","t","useTranslation","loading","setLoading","useState","agents","setAgents","autoRefresh","setAutoRefresh","statusFilter","setStatusFilter","changingStatus","setChangingStatus","loadWorkload","useCallback","data","workloadApi","error","useEffect","interval","getUtilizationPercent","agent","getUtilizationBarColor","percent","changeStatus","userId","newStatus","availabilityApi","filteredAgents","a","totalAgents","onlineCount","avgUtilization","sum","overloadedCount","jsxs","jsx","Breadcrumb","RefreshCw","e","Loader2","Fragment","StatusIcon","utilizationPercent"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { jsxs as r, jsx as t, Fragment as z } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState as o, useCallback as T, useEffect as b } from "react";
|
|
3
3
|
import { useTranslation as $ } from "react-i18next";
|
|
4
4
|
import { RefreshCw as I, Loader2 as U, AlertCircle as d, CheckCircle as j } from "lucide-react";
|
|
5
|
-
import {
|
|
5
|
+
import { a8 as F, B as R, a9 as M } from "./index-CN2WRyg1.js";
|
|
6
6
|
const P = {
|
|
7
7
|
Online: "bg-[var(--success-bg)] text-[var(--success-text)]",
|
|
8
8
|
Busy: "bg-[var(--warning-bg)] text-[var(--warning-text)]",
|
|
@@ -183,4 +183,4 @@ function J() {
|
|
|
183
183
|
export {
|
|
184
184
|
J as AgentWorkloadPage
|
|
185
185
|
};
|
|
186
|
-
//# sourceMappingURL=AgentWorkloadPage-
|
|
186
|
+
//# sourceMappingURL=AgentWorkloadPage-oHEi-sFh.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentWorkloadPage-BI5QWJyQ.js","sources":["../../src/pages/platform/support/AgentWorkloadPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, AlertCircle, CheckCircle, RefreshCw } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { workloadApi, availabilityApi, type AgentWorkloadDto } from '@/services/api/assignmentApi';\r\n\r\nconst statusColors: Record<string, string> = {\r\n Online: 'bg-[var(--success-bg)] text-[var(--success-text)]',\r\n Busy: 'bg-[var(--warning-bg)] text-[var(--warning-text)]',\r\n Away: 'bg-[var(--info-bg)] text-[var(--info-text)]',\r\n Offline: 'bg-[var(--bg-secondary)] text-[var(--text-secondary)]',\r\n};\r\n\r\nconst statusIcons: Record<string, typeof AlertCircle> = {\r\n Online: CheckCircle,\r\n Busy: AlertCircle,\r\n Away: AlertCircle,\r\n Offline: AlertCircle,\r\n};\r\n\r\nconst colorClasses = {\r\n blue: 'bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]',\r\n green: 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]',\r\n yellow: 'bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]',\r\n red: 'bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]',\r\n};\r\n\r\nexport function AgentWorkloadPage(): ReactElement {\r\n const { t } = useTranslation('support');\r\n const [loading, setLoading] = useState(true);\r\n const [agents, setAgents] = useState<AgentWorkloadDto[]>([]);\r\n const [autoRefresh, setAutoRefresh] = useState(false);\r\n const [statusFilter, setStatusFilter] = useState<string>('');\r\n const [changingStatus, setChangingStatus] = useState<string | null>(null);\r\n\r\n const loadWorkload = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const data = await workloadApi.getAll();\r\n setAgents(data);\r\n } catch (error) {\r\n console.error('Failed to load agent workload:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n loadWorkload();\r\n }, [loadWorkload]);\r\n\r\n useEffect(() => {\r\n if (!autoRefresh) return;\r\n const interval = setInterval(() => loadWorkload(), 30000);\r\n return () => clearInterval(interval);\r\n }, [autoRefresh, loadWorkload]);\r\n\r\n const getUtilizationPercent = (agent: AgentWorkloadDto): number => {\r\n return Math.round((agent.activeTicketCount / agent.maxConcurrentTickets) * 100);\r\n };\r\n\r\n const getUtilizationBarColor = (percent: number): string => {\r\n if (percent >= 90) return 'bg-[var(--error-bg)]';\r\n if (percent >= 70) return 'bg-[var(--warning-bg)]';\r\n return 'bg-[var(--success-bg)]';\r\n };\r\n\r\n const changeStatus = async (userId: string, newStatus: string) => {\r\n try {\r\n setChangingStatus(userId);\r\n await availabilityApi.update(userId, { status: newStatus });\r\n await loadWorkload();\r\n } catch (error) {\r\n console.error('Failed to change status:', error);\r\n } finally {\r\n setChangingStatus(null);\r\n }\r\n };\r\n\r\n const filteredAgents = statusFilter\r\n ? agents.filter((a) => a.availabilityStatus === statusFilter)\r\n : agents;\r\n\r\n const totalAgents = agents.length;\r\n const onlineCount = agents.filter((a) => a.availabilityStatus === 'Online').length;\r\n const avgUtilization = Math.round(\r\n agents.reduce((sum, a) => sum + getUtilizationPercent(a), 0) / (agents.length || 1)\r\n );\r\n const overloadedCount = agents.filter((a) => getUtilizationPercent(a) > 80).length;\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('agentWorkload.title') },\r\n ]}\r\n />\r\n\r\n <div className=\"flex items-start justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold\">{t('agentWorkload.title')}</h1>\r\n <p className=\"text-[var(--text-secondary)]\">{t('agentWorkload.subtitle')}</p>\r\n </div>\r\n <div className=\"flex gap-2\">\r\n <button\r\n onClick={() => loadWorkload()}\r\n className=\"p-2 rounded-lg hover:bg-[var(--bg-secondary)]\"\r\n >\r\n <RefreshCw className=\"w-5 h-5\" />\r\n </button>\r\n <label className=\"flex items-center gap-2 px-4 py-2 border border-[var(--border-color)] rounded-lg cursor-pointer\">\r\n <input\r\n type=\"checkbox\"\r\n checked={autoRefresh}\r\n onChange={(e) => setAutoRefresh(e.target.checked)}\r\n className=\"w-4 h-4\"\r\n />\r\n <span className=\"text-sm\">{t('agentWorkload.autoRefresh', 'Auto-refresh')}</span>\r\n </label>\r\n </div>\r\n </div>\r\n\r\n {loading ? (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n ) : (\r\n <>\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\r\n <div className={`card p-4 text-center border ${colorClasses.blue}`}>\r\n <div className=\"text-2xl font-bold\">{totalAgents}</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.totalAgents', 'Total Agents')}</div>\r\n </div>\r\n <div className={`card p-4 text-center border ${colorClasses.green}`}>\r\n <div className=\"text-2xl font-bold\">{onlineCount}</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.online', 'Online')}</div>\r\n </div>\r\n <div className={`card p-4 text-center border ${colorClasses.yellow}`}>\r\n <div className=\"text-2xl font-bold\">{avgUtilization}%</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.avgUtilization', 'Avg. Utilization')}</div>\r\n </div>\r\n <div className={`card p-4 text-center border ${colorClasses.red}`}>\r\n <div className=\"text-2xl font-bold\">{overloadedCount}</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.overloaded', 'Overloaded')}</div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <select\r\n value={statusFilter}\r\n onChange={(e) => setStatusFilter(e.target.value)}\r\n className=\"px-4 py-2 border rounded-lg bg-[var(--bg-primary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n <option value=\"\">{t('common:all', 'All Statuses')}</option>\r\n <option value=\"Online\">{t('agentWorkload.status.Online', 'Online')}</option>\r\n <option value=\"Busy\">{t('agentWorkload.status.Busy', 'Busy')}</option>\r\n <option value=\"Away\">{t('agentWorkload.status.Away', 'Away')}</option>\r\n <option value=\"Offline\">{t('agentWorkload.status.Offline', 'Offline')}</option>\r\n </select>\r\n </div>\r\n\r\n {filteredAgents.length === 0 ? (\r\n <div className=\"text-center py-12\">\r\n <p className=\"text-[var(--text-secondary)]\">{t('assignment.noAgents', 'No agents found')}</p>\r\n </div>\r\n ) : (\r\n <div className=\"grid grid-cols-1 gap-4\">\r\n {filteredAgents.map((agent) => {\r\n const StatusIcon = statusIcons[agent.availabilityStatus] || AlertCircle;\r\n const utilizationPercent = getUtilizationPercent(agent);\r\n\r\n return (\r\n <div key={agent.userId} className=\"card p-6\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-4 gap-6\">\r\n <div className=\"md:col-span-1\">\r\n <h3 className=\"font-semibold text-lg\">{agent.userName || 'Unknown Agent'}</h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{agent.userId}</p>\r\n </div>\r\n\r\n <div className=\"md:col-span-1\">\r\n <p className=\"text-xs text-[var(--text-secondary)] font-medium mb-1\">\r\n {t('assignment.activeTickets', 'Active Tickets')}\r\n </p>\r\n <p className=\"text-2xl font-bold\">{agent.activeTicketCount}</p>\r\n <p className=\"text-xs text-[var(--text-secondary)]\">\r\n {t('assignment.capacity', 'Capacity')}: {agent.maxConcurrentTickets}\r\n </p>\r\n </div>\r\n\r\n <div className=\"md:col-span-1\">\r\n <p className=\"text-xs text-[var(--text-secondary)] font-medium mb-2\">\r\n {t('agentWorkload.utilization', 'Utilization')}\r\n </p>\r\n <div className=\"w-full bg-[var(--bg-secondary)] rounded-full h-2 overflow-hidden\">\r\n <div\r\n className={`h-full ${getUtilizationBarColor(utilizationPercent)} transition-all`}\r\n style={{ width: `${Math.min(utilizationPercent, 100)}%` }}\r\n />\r\n </div>\r\n <p className=\"text-sm font-semibold mt-1\">{utilizationPercent}%</p>\r\n </div>\r\n\r\n <div className=\"md:col-span-1 flex flex-col gap-2\">\r\n <div className=\"flex items-center gap-2 justify-center\">\r\n <StatusIcon className=\"w-5 h-5\" />\r\n <span className={`px-3 py-1 rounded-full text-xs font-medium ${statusColors[agent.availabilityStatus]}`}>\r\n {t(`agentWorkload.status.${agent.availabilityStatus}`, agent.availabilityStatus)}\r\n </span>\r\n </div>\r\n <select\r\n value={agent.availabilityStatus}\r\n onChange={(e) => changeStatus(agent.userId, e.target.value)}\r\n disabled={changingStatus === agent.userId}\r\n className=\"w-full px-2 py-1 text-xs border rounded bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n <option value=\"Online\">{t('agentWorkload.status.Online', 'Online')}</option>\r\n <option value=\"Busy\">{t('agentWorkload.status.Busy', 'Busy')}</option>\r\n <option value=\"Away\">{t('agentWorkload.status.Away', 'Away')}</option>\r\n <option value=\"Offline\">{t('agentWorkload.status.Offline', 'Offline')}</option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["statusColors","statusIcons","CheckCircle","AlertCircle","colorClasses","AgentWorkloadPage","t","useTranslation","loading","setLoading","useState","agents","setAgents","autoRefresh","setAutoRefresh","statusFilter","setStatusFilter","changingStatus","setChangingStatus","loadWorkload","useCallback","data","workloadApi","error","useEffect","interval","getUtilizationPercent","agent","getUtilizationBarColor","percent","changeStatus","userId","newStatus","availabilityApi","filteredAgents","a","totalAgents","onlineCount","avgUtilization","sum","overloadedCount","jsxs","jsx","Breadcrumb","RefreshCw","Loader2","Fragment","StatusIcon","utilizationPercent","e"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AgentWorkloadPage-oHEi-sFh.js","sources":["../../src/pages/platform/support/AgentWorkloadPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, AlertCircle, CheckCircle, RefreshCw } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { workloadApi, availabilityApi, type AgentWorkloadDto } from '@/services/api/assignmentApi';\r\n\r\nconst statusColors: Record<string, string> = {\r\n Online: 'bg-[var(--success-bg)] text-[var(--success-text)]',\r\n Busy: 'bg-[var(--warning-bg)] text-[var(--warning-text)]',\r\n Away: 'bg-[var(--info-bg)] text-[var(--info-text)]',\r\n Offline: 'bg-[var(--bg-secondary)] text-[var(--text-secondary)]',\r\n};\r\n\r\nconst statusIcons: Record<string, typeof AlertCircle> = {\r\n Online: CheckCircle,\r\n Busy: AlertCircle,\r\n Away: AlertCircle,\r\n Offline: AlertCircle,\r\n};\r\n\r\nconst colorClasses = {\r\n blue: 'bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]',\r\n green: 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]',\r\n yellow: 'bg-[var(--warning-bg)] text-[var(--warning-text)] border-[var(--warning-border)]',\r\n red: 'bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]',\r\n};\r\n\r\nexport function AgentWorkloadPage(): ReactElement {\r\n const { t } = useTranslation('support');\r\n const [loading, setLoading] = useState(true);\r\n const [agents, setAgents] = useState<AgentWorkloadDto[]>([]);\r\n const [autoRefresh, setAutoRefresh] = useState(false);\r\n const [statusFilter, setStatusFilter] = useState<string>('');\r\n const [changingStatus, setChangingStatus] = useState<string | null>(null);\r\n\r\n const loadWorkload = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const data = await workloadApi.getAll();\r\n setAgents(data);\r\n } catch (error) {\r\n console.error('Failed to load agent workload:', error);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n loadWorkload();\r\n }, [loadWorkload]);\r\n\r\n useEffect(() => {\r\n if (!autoRefresh) return;\r\n const interval = setInterval(() => loadWorkload(), 30000);\r\n return () => clearInterval(interval);\r\n }, [autoRefresh, loadWorkload]);\r\n\r\n const getUtilizationPercent = (agent: AgentWorkloadDto): number => {\r\n return Math.round((agent.activeTicketCount / agent.maxConcurrentTickets) * 100);\r\n };\r\n\r\n const getUtilizationBarColor = (percent: number): string => {\r\n if (percent >= 90) return 'bg-[var(--error-bg)]';\r\n if (percent >= 70) return 'bg-[var(--warning-bg)]';\r\n return 'bg-[var(--success-bg)]';\r\n };\r\n\r\n const changeStatus = async (userId: string, newStatus: string) => {\r\n try {\r\n setChangingStatus(userId);\r\n await availabilityApi.update(userId, { status: newStatus });\r\n await loadWorkload();\r\n } catch (error) {\r\n console.error('Failed to change status:', error);\r\n } finally {\r\n setChangingStatus(null);\r\n }\r\n };\r\n\r\n const filteredAgents = statusFilter\r\n ? agents.filter((a) => a.availabilityStatus === statusFilter)\r\n : agents;\r\n\r\n const totalAgents = agents.length;\r\n const onlineCount = agents.filter((a) => a.availabilityStatus === 'Online').length;\r\n const avgUtilization = Math.round(\r\n agents.reduce((sum, a) => sum + getUtilizationPercent(a), 0) / (agents.length || 1)\r\n );\r\n const overloadedCount = agents.filter((a) => getUtilizationPercent(a) > 80).length;\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('agentWorkload.title') },\r\n ]}\r\n />\r\n\r\n <div className=\"flex items-start justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold\">{t('agentWorkload.title')}</h1>\r\n <p className=\"text-[var(--text-secondary)]\">{t('agentWorkload.subtitle')}</p>\r\n </div>\r\n <div className=\"flex gap-2\">\r\n <button\r\n onClick={() => loadWorkload()}\r\n className=\"p-2 rounded-lg hover:bg-[var(--bg-secondary)]\"\r\n >\r\n <RefreshCw className=\"w-5 h-5\" />\r\n </button>\r\n <label className=\"flex items-center gap-2 px-4 py-2 border border-[var(--border-color)] rounded-lg cursor-pointer\">\r\n <input\r\n type=\"checkbox\"\r\n checked={autoRefresh}\r\n onChange={(e) => setAutoRefresh(e.target.checked)}\r\n className=\"w-4 h-4\"\r\n />\r\n <span className=\"text-sm\">{t('agentWorkload.autoRefresh', 'Auto-refresh')}</span>\r\n </label>\r\n </div>\r\n </div>\r\n\r\n {loading ? (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n ) : (\r\n <>\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\r\n <div className={`card p-4 text-center border ${colorClasses.blue}`}>\r\n <div className=\"text-2xl font-bold\">{totalAgents}</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.totalAgents', 'Total Agents')}</div>\r\n </div>\r\n <div className={`card p-4 text-center border ${colorClasses.green}`}>\r\n <div className=\"text-2xl font-bold\">{onlineCount}</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.online', 'Online')}</div>\r\n </div>\r\n <div className={`card p-4 text-center border ${colorClasses.yellow}`}>\r\n <div className=\"text-2xl font-bold\">{avgUtilization}%</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.avgUtilization', 'Avg. Utilization')}</div>\r\n </div>\r\n <div className={`card p-4 text-center border ${colorClasses.red}`}>\r\n <div className=\"text-2xl font-bold\">{overloadedCount}</div>\r\n <div className=\"text-sm opacity-80\">{t('agentWorkload.kpi.overloaded', 'Overloaded')}</div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"mb-4\">\r\n <select\r\n value={statusFilter}\r\n onChange={(e) => setStatusFilter(e.target.value)}\r\n className=\"px-4 py-2 border rounded-lg bg-[var(--bg-primary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n <option value=\"\">{t('common:all', 'All Statuses')}</option>\r\n <option value=\"Online\">{t('agentWorkload.status.Online', 'Online')}</option>\r\n <option value=\"Busy\">{t('agentWorkload.status.Busy', 'Busy')}</option>\r\n <option value=\"Away\">{t('agentWorkload.status.Away', 'Away')}</option>\r\n <option value=\"Offline\">{t('agentWorkload.status.Offline', 'Offline')}</option>\r\n </select>\r\n </div>\r\n\r\n {filteredAgents.length === 0 ? (\r\n <div className=\"text-center py-12\">\r\n <p className=\"text-[var(--text-secondary)]\">{t('assignment.noAgents', 'No agents found')}</p>\r\n </div>\r\n ) : (\r\n <div className=\"grid grid-cols-1 gap-4\">\r\n {filteredAgents.map((agent) => {\r\n const StatusIcon = statusIcons[agent.availabilityStatus] || AlertCircle;\r\n const utilizationPercent = getUtilizationPercent(agent);\r\n\r\n return (\r\n <div key={agent.userId} className=\"card p-6\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-4 gap-6\">\r\n <div className=\"md:col-span-1\">\r\n <h3 className=\"font-semibold text-lg\">{agent.userName || 'Unknown Agent'}</h3>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{agent.userId}</p>\r\n </div>\r\n\r\n <div className=\"md:col-span-1\">\r\n <p className=\"text-xs text-[var(--text-secondary)] font-medium mb-1\">\r\n {t('assignment.activeTickets', 'Active Tickets')}\r\n </p>\r\n <p className=\"text-2xl font-bold\">{agent.activeTicketCount}</p>\r\n <p className=\"text-xs text-[var(--text-secondary)]\">\r\n {t('assignment.capacity', 'Capacity')}: {agent.maxConcurrentTickets}\r\n </p>\r\n </div>\r\n\r\n <div className=\"md:col-span-1\">\r\n <p className=\"text-xs text-[var(--text-secondary)] font-medium mb-2\">\r\n {t('agentWorkload.utilization', 'Utilization')}\r\n </p>\r\n <div className=\"w-full bg-[var(--bg-secondary)] rounded-full h-2 overflow-hidden\">\r\n <div\r\n className={`h-full ${getUtilizationBarColor(utilizationPercent)} transition-all`}\r\n style={{ width: `${Math.min(utilizationPercent, 100)}%` }}\r\n />\r\n </div>\r\n <p className=\"text-sm font-semibold mt-1\">{utilizationPercent}%</p>\r\n </div>\r\n\r\n <div className=\"md:col-span-1 flex flex-col gap-2\">\r\n <div className=\"flex items-center gap-2 justify-center\">\r\n <StatusIcon className=\"w-5 h-5\" />\r\n <span className={`px-3 py-1 rounded-full text-xs font-medium ${statusColors[agent.availabilityStatus]}`}>\r\n {t(`agentWorkload.status.${agent.availabilityStatus}`, agent.availabilityStatus)}\r\n </span>\r\n </div>\r\n <select\r\n value={agent.availabilityStatus}\r\n onChange={(e) => changeStatus(agent.userId, e.target.value)}\r\n disabled={changingStatus === agent.userId}\r\n className=\"w-full px-2 py-1 text-xs border rounded bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]\"\r\n >\r\n <option value=\"Online\">{t('agentWorkload.status.Online', 'Online')}</option>\r\n <option value=\"Busy\">{t('agentWorkload.status.Busy', 'Busy')}</option>\r\n <option value=\"Away\">{t('agentWorkload.status.Away', 'Away')}</option>\r\n <option value=\"Offline\">{t('agentWorkload.status.Offline', 'Offline')}</option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["statusColors","statusIcons","CheckCircle","AlertCircle","colorClasses","AgentWorkloadPage","t","useTranslation","loading","setLoading","useState","agents","setAgents","autoRefresh","setAutoRefresh","statusFilter","setStatusFilter","changingStatus","setChangingStatus","loadWorkload","useCallback","data","workloadApi","error","useEffect","interval","getUtilizationPercent","agent","getUtilizationBarColor","percent","changeStatus","userId","newStatus","availabilityApi","filteredAgents","a","totalAgents","onlineCount","avgUtilization","sum","overloadedCount","jsxs","jsx","Breadcrumb","RefreshCw","Loader2","Fragment","StatusIcon","utilizationPercent","e"],"mappings":"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"}
|
|
@@ -3,8 +3,8 @@ import { useState as d, useEffect as k, useMemo as m } from "react";
|
|
|
3
3
|
import { useParams as L, useNavigate as R } from "react-router-dom";
|
|
4
4
|
import { useTranslation as $ } from "react-i18next";
|
|
5
5
|
import { Loader2 as S, ArrowLeft as P, AlertTriangle as q, BookOpen as G, Layers as M, Database as U, Zap as B, Clock as j, Shield as H, Code2 as z, FileCode2 as F, Brain as O, Check as J, Copy as W } from "lucide-react";
|
|
6
|
-
import { B as Z, k as V } from "./index-
|
|
7
|
-
import { aiApi as _ } from "./aiApi-
|
|
6
|
+
import { B as Z, k as V } from "./index-CN2WRyg1.js";
|
|
7
|
+
import { aiApi as _ } from "./aiApi-9G4wG_mT.js";
|
|
8
8
|
const h = {
|
|
9
9
|
User: {
|
|
10
10
|
paginated: !0,
|
|
@@ -507,4 +507,4 @@ function Ue() {
|
|
|
507
507
|
export {
|
|
508
508
|
Ue as ApiCatalogDetailPage
|
|
509
509
|
};
|
|
510
|
-
//# sourceMappingURL=ApiCatalogDetailPage-
|
|
510
|
+
//# sourceMappingURL=ApiCatalogDetailPage-Cr0q2HnB.js.map
|