@atlashub/smartstack 3.21.0 → 3.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{AgentSkillsPage-7si3Ng8e.js → AgentSkillsPage-BWQSCYl-.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-7si3Ng8e.js.map → AgentSkillsPage-BWQSCYl-.js.map} +1 -1
- package/dist/chunks/{AgentSkillsPage-D0cD1QdM.js → AgentSkillsPage-IQcMnBaD.js} +2 -2
- package/dist/chunks/{AgentSkillsPage-D0cD1QdM.js.map → AgentSkillsPage-IQcMnBaD.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-H_7ze33H.js → AgentWorkloadPage-DqrjkvWL.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-H_7ze33H.js.map → AgentWorkloadPage-DqrjkvWL.js.map} +1 -1
- package/dist/chunks/{AgentWorkloadPage-D4d86cdV.js → AgentWorkloadPage-w-HiyFYP.js} +2 -2
- package/dist/chunks/{AgentWorkloadPage-D4d86cdV.js.map → AgentWorkloadPage-w-HiyFYP.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-2ktkRrCb.js → ApiCatalogDetailPage-D3L8Yf4G.js} +3 -3
- package/dist/chunks/{ApiCatalogDetailPage-2ktkRrCb.js.map → ApiCatalogDetailPage-D3L8Yf4G.js.map} +1 -1
- package/dist/chunks/{ApiCatalogDetailPage-BQ53xuwD.js → ApiCatalogDetailPage-MPT3Kz6H.js} +2 -2
- package/dist/chunks/{ApiCatalogDetailPage-BQ53xuwD.js.map → ApiCatalogDetailPage-MPT3Kz6H.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-BEqTDJz8.js → ApiCatalogPage-D4Hg3uiS.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-BEqTDJz8.js.map → ApiCatalogPage-D4Hg3uiS.js.map} +1 -1
- package/dist/chunks/{ApiCatalogPage-BBkWSLI8.js → ApiCatalogPage-DRg5Cz0r.js} +2 -2
- package/dist/chunks/{ApiCatalogPage-BBkWSLI8.js.map → ApiCatalogPage-DRg5Cz0r.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage-BYJ2YMPq.js → ApplicationDetailPage-Caizuyn2.js} +2 -2
- package/dist/chunks/{ApplicationDetailPage-BYJ2YMPq.js.map → ApplicationDetailPage-Caizuyn2.js.map} +1 -1
- package/dist/chunks/{ApplicationDetailPage-D8-bf1as.js → ApplicationDetailPage-CuCW6aMB.js} +4 -4
- package/dist/chunks/{ApplicationDetailPage-D8-bf1as.js.map → ApplicationDetailPage-CuCW6aMB.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-BBlLms2r.js → ApplicationsDashboardPage-B2MW8-Kc.js} +2 -2
- package/dist/chunks/{ApplicationsDashboardPage-BBlLms2r.js.map → ApplicationsDashboardPage-B2MW8-Kc.js.map} +1 -1
- package/dist/chunks/{ApplicationsDashboardPage-DTWZxJJM.js → ApplicationsDashboardPage-BDIjFIYZ.js} +3 -3
- package/dist/chunks/{ApplicationsDashboardPage-DTWZxJJM.js.map → ApplicationsDashboardPage-BDIjFIYZ.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-BQaMsK1K.js → ApplicationsGridPage-DV-FihKj.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-BQaMsK1K.js.map → ApplicationsGridPage-DV-FihKj.js.map} +1 -1
- package/dist/chunks/{ApplicationsGridPage-DbVcvezt.js → ApplicationsGridPage-DXsTfXPI.js} +2 -2
- package/dist/chunks/{ApplicationsGridPage-DbVcvezt.js.map → ApplicationsGridPage-DXsTfXPI.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-DYKM2Yeo.js → ApplicationsListPage--CGkyBuJ.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-DYKM2Yeo.js.map → ApplicationsListPage--CGkyBuJ.js.map} +1 -1
- package/dist/chunks/{ApplicationsListPage-C91v2rZt.js → ApplicationsListPage-JUX823bh.js} +2 -2
- package/dist/chunks/{ApplicationsListPage-C91v2rZt.js.map → ApplicationsListPage-JUX823bh.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-BCbgotIx.js → ApplicationsPage-6zgFye6w.js} +2 -2
- package/dist/chunks/{ApplicationsPage-BCbgotIx.js.map → ApplicationsPage-6zgFye6w.js.map} +1 -1
- package/dist/chunks/{ApplicationsPage-CW3-Hjlu.js → ApplicationsPage-CQPuuiO6.js} +4 -4
- package/dist/chunks/{ApplicationsPage-CW3-Hjlu.js.map → ApplicationsPage-CQPuuiO6.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-D8vfGDBN.js → AssignmentRulesPage-CFffeEbo.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-D8vfGDBN.js.map → AssignmentRulesPage-CFffeEbo.js.map} +1 -1
- package/dist/chunks/{AssignmentRulesPage-CxktlEMB.js → AssignmentRulesPage-D78UeUId.js} +2 -2
- package/dist/chunks/{AssignmentRulesPage-CxktlEMB.js.map → AssignmentRulesPage-D78UeUId.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-DmfBYQAD.js → AssignmentsPage-Cww2ifZF.js} +2 -2
- package/dist/chunks/{AssignmentsPage-DmfBYQAD.js.map → AssignmentsPage-Cww2ifZF.js.map} +1 -1
- package/dist/chunks/{AssignmentsPage-sRCCBmRc.js → AssignmentsPage-DE_QS2LO.js} +2 -2
- package/dist/chunks/{AssignmentsPage-sRCCBmRc.js.map → AssignmentsPage-DE_QS2LO.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-C7XiZxKb.js → AuthCallbackPage-CA2nO6DG.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-C7XiZxKb.js.map → AuthCallbackPage-CA2nO6DG.js.map} +1 -1
- package/dist/chunks/{AuthCallbackPage-BCe_bwJM.js → AuthCallbackPage-CDUAoX-N.js} +2 -2
- package/dist/chunks/{AuthCallbackPage-BCe_bwJM.js.map → AuthCallbackPage-CDUAoX-N.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-BUfGSqxF.js → ConfirmEmailPage-BqsILAYH.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-BUfGSqxF.js.map → ConfirmEmailPage-BqsILAYH.js.map} +1 -1
- package/dist/chunks/{ConfirmEmailPage-Buj4x-rx.js → ConfirmEmailPage-INeHCuMB.js} +2 -2
- package/dist/chunks/{ConfirmEmailPage-Buj4x-rx.js.map → ConfirmEmailPage-INeHCuMB.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-CKDX_HQm.js → CreateSupportTicketPage-BWeuV2aU.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-CKDX_HQm.js.map → CreateSupportTicketPage-BWeuV2aU.js.map} +1 -1
- package/dist/chunks/{CreateSupportTicketPage-0LgY-_pu.js → CreateSupportTicketPage-OBwF4v7b.js} +2 -2
- package/dist/chunks/{CreateSupportTicketPage-0LgY-_pu.js.map → CreateSupportTicketPage-OBwF4v7b.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CUZ80NGV.js → DashboardPage-CKHqWrdS.js} +3 -3
- package/dist/chunks/{DashboardPage-CUZ80NGV.js.map → DashboardPage-CKHqWrdS.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CaNOAstg.js → DashboardPage-COmc9b__.js} +3 -3
- package/dist/chunks/{DashboardPage-CaNOAstg.js.map → DashboardPage-COmc9b__.js.map} +1 -1
- package/dist/chunks/{DashboardPage-B48_rQFi.js → DashboardPage-CfKZHiSj.js} +2 -2
- package/dist/chunks/{DashboardPage-B48_rQFi.js.map → DashboardPage-CfKZHiSj.js.map} +1 -1
- package/dist/chunks/{DashboardPage-CUZV1J9t.js → DashboardPage-CwEZZ3jx.js} +2 -2
- package/dist/chunks/{DashboardPage-CUZV1J9t.js.map → DashboardPage-CwEZZ3jx.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-CdzAbnGy.js → EscalationConfigPage--7lgZ0kJ.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-CdzAbnGy.js.map → EscalationConfigPage--7lgZ0kJ.js.map} +1 -1
- package/dist/chunks/{EscalationConfigPage-CYGIl_e6.js → EscalationConfigPage-DPyiBcqV.js} +2 -2
- package/dist/chunks/{EscalationConfigPage-CYGIl_e6.js.map → EscalationConfigPage-DPyiBcqV.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-lRpkwcX7.js → ForceChangePasswordPage-BE-6umub.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-lRpkwcX7.js.map → ForceChangePasswordPage-BE-6umub.js.map} +1 -1
- package/dist/chunks/{ForceChangePasswordPage-CvmYAV3r.js → ForceChangePasswordPage-CnsYoWmV.js} +2 -2
- package/dist/chunks/{ForceChangePasswordPage-CvmYAV3r.js.map → ForceChangePasswordPage-CnsYoWmV.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-0u49E4Pw.js → ForgotPasswordPage-CSq4DnFF.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-0u49E4Pw.js.map → ForgotPasswordPage-CSq4DnFF.js.map} +1 -1
- package/dist/chunks/{ForgotPasswordPage-CxQUqKOm.js → ForgotPasswordPage-DZLVolAC.js} +2 -2
- package/dist/chunks/{ForgotPasswordPage-CxQUqKOm.js.map → ForgotPasswordPage-DZLVolAC.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-DFBvVO1S.js → GroupDetailPage-Bf9Wb_2j.js} +5 -5
- package/dist/chunks/{GroupDetailPage-DFBvVO1S.js.map → GroupDetailPage-Bf9Wb_2j.js.map} +1 -1
- package/dist/chunks/{GroupDetailPage-B2FkKrGG.js → GroupDetailPage-R-hf3rJ7.js} +2 -2
- package/dist/chunks/{GroupDetailPage-B2FkKrGG.js.map → GroupDetailPage-R-hf3rJ7.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-C9IX4c0K.js → MyAccessRequestsPage-BIisvWM6.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-C9IX4c0K.js.map → MyAccessRequestsPage-BIisvWM6.js.map} +1 -1
- package/dist/chunks/{MyAccessRequestsPage-D6pVULNM.js → MyAccessRequestsPage-BLSV7Tbx.js} +2 -2
- package/dist/chunks/{MyAccessRequestsPage-D6pVULNM.js.map → MyAccessRequestsPage-BLSV7Tbx.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-BEcYYdGR.js → MyTenantsPage-D-7k9CP1.js} +3 -3
- package/dist/chunks/{MyTenantsPage-BEcYYdGR.js.map → MyTenantsPage-D-7k9CP1.js.map} +1 -1
- package/dist/chunks/{MyTenantsPage-D9f85zjF.js → MyTenantsPage-DqGW6aDt.js} +2 -2
- package/dist/chunks/{MyTenantsPage-D9f85zjF.js.map → MyTenantsPage-DqGW6aDt.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-DJR8h6y1.js → MyTicketsPage--DgDsnZA.js} +2 -2
- package/dist/chunks/{MyTicketsPage-DJR8h6y1.js.map → MyTicketsPage--DgDsnZA.js.map} +1 -1
- package/dist/chunks/{MyTicketsPage-DiOUExKJ.js → MyTicketsPage-CqJ3Aqob.js} +2 -2
- package/dist/chunks/{MyTicketsPage-DiOUExKJ.js.map → MyTicketsPage-CqJ3Aqob.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-CeHbxfZw.js → NavigationAppsPage-Bebis_RT.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-CeHbxfZw.js.map → NavigationAppsPage-Bebis_RT.js.map} +1 -1
- package/dist/chunks/{NavigationAppsPage-If7tmCFY.js → NavigationAppsPage-THNPOAjv.js} +2 -2
- package/dist/chunks/{NavigationAppsPage-If7tmCFY.js.map → NavigationAppsPage-THNPOAjv.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-C29Lln5o.js → NotificationsPage-CAbNW_Cn.js} +2 -2
- package/dist/chunks/{NotificationsPage-C29Lln5o.js.map → NotificationsPage-CAbNW_Cn.js.map} +1 -1
- package/dist/chunks/{NotificationsPage-BiaLRb0s.js → NotificationsPage-DxwizUhL.js} +2 -2
- package/dist/chunks/{NotificationsPage-BiaLRb0s.js.map → NotificationsPage-DxwizUhL.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-DQrBKNBq.js → OnboardingWizardPage-C6HlbJ3K.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-DQrBKNBq.js.map → OnboardingWizardPage-C6HlbJ3K.js.map} +1 -1
- package/dist/chunks/{OnboardingWizardPage-BQah4cI8.js → OnboardingWizardPage-CyC2zONO.js} +2 -2
- package/dist/chunks/{OnboardingWizardPage-BQah4cI8.js.map → OnboardingWizardPage-CyC2zONO.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-Ckjdjvf9.js → PermissionDetailPage-BDHiNgky.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-Ckjdjvf9.js.map → PermissionDetailPage-BDHiNgky.js.map} +1 -1
- package/dist/chunks/{PermissionDetailPage-Dh8v7mGj.js → PermissionDetailPage-C5K17ydY.js} +2 -2
- package/dist/chunks/{PermissionDetailPage-Dh8v7mGj.js.map → PermissionDetailPage-C5K17ydY.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-l0PnY-EE.js → PermissionsPage-COI5LJPo.js} +2 -2
- package/dist/chunks/{PermissionsPage-l0PnY-EE.js.map → PermissionsPage-COI5LJPo.js.map} +1 -1
- package/dist/chunks/{PermissionsPage-DLy9U3P3.js → PermissionsPage-CkOwH2_d.js} +2 -2
- package/dist/chunks/{PermissionsPage-DLy9U3P3.js.map → PermissionsPage-CkOwH2_d.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-DFBx38-x.js → PortalDashboardPage-CoEC4CmC.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-DFBx38-x.js.map → PortalDashboardPage-CoEC4CmC.js.map} +1 -1
- package/dist/chunks/{PortalDashboardPage-rQYhrX0q.js → PortalDashboardPage-DrYymEf-.js} +2 -2
- package/dist/chunks/{PortalDashboardPage-rQYhrX0q.js.map → PortalDashboardPage-DrYymEf-.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-BBu8yZQB.js → PreferencesPage-CJRaU3ba.js} +2 -2
- package/dist/chunks/{PreferencesPage-BBu8yZQB.js.map → PreferencesPage-CJRaU3ba.js.map} +1 -1
- package/dist/chunks/{PreferencesPage-B81MsNV1.js → PreferencesPage-Cqr9mAab.js} +2 -2
- package/dist/chunks/{PreferencesPage-B81MsNV1.js.map → PreferencesPage-Cqr9mAab.js.map} +1 -1
- package/dist/chunks/{ProfilePage-DDrl10zj.js → ProfilePage-BZVpg6-l.js} +2 -2
- package/dist/chunks/{ProfilePage-DDrl10zj.js.map → ProfilePage-BZVpg6-l.js.map} +1 -1
- package/dist/chunks/{ProfilePage-DPoXwdnc.js → ProfilePage-Cu_FITeL.js} +2 -2
- package/dist/chunks/{ProfilePage-DPoXwdnc.js.map → ProfilePage-Cu_FITeL.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-eFsKjIEK.js → ReferencesManagementPage-DUlVk9Ps.js} +3 -3
- package/dist/chunks/{ReferencesManagementPage-eFsKjIEK.js.map → ReferencesManagementPage-DUlVk9Ps.js.map} +1 -1
- package/dist/chunks/{ReferencesManagementPage-DhVsuElE.js → ReferencesManagementPage-ZCuYtqd7.js} +2 -2
- package/dist/chunks/{ReferencesManagementPage-DhVsuElE.js.map → ReferencesManagementPage-ZCuYtqd7.js.map} +1 -1
- package/dist/chunks/{RegisterPage-CiQib3-6.js → RegisterPage-C4xmVwh9.js} +2 -2
- package/dist/chunks/{RegisterPage-CiQib3-6.js.map → RegisterPage-C4xmVwh9.js.map} +1 -1
- package/dist/chunks/{RegisterPage-bXCcJD88.js → RegisterPage-DGyzoIHT.js} +2 -2
- package/dist/chunks/{RegisterPage-bXCcJD88.js.map → RegisterPage-DGyzoIHT.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-Dqiahhnj.js → ResetPasswordPage-DqDD6VPR.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-Dqiahhnj.js.map → ResetPasswordPage-DqDD6VPR.js.map} +1 -1
- package/dist/chunks/{ResetPasswordPage-CubPG3yv.js → ResetPasswordPage-Glu-aeqv.js} +2 -2
- package/dist/chunks/{ResetPasswordPage-CubPG3yv.js.map → ResetPasswordPage-Glu-aeqv.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-Bg7XZmR1.js → ResolutionModal-CxjANAOP.js} +2 -2
- package/dist/chunks/{ResolutionModal-Bg7XZmR1.js.map → ResolutionModal-CxjANAOP.js.map} +1 -1
- package/dist/chunks/{ResolutionModal-DqRk_T0n.js → ResolutionModal-Duat18qV.js} +2 -2
- package/dist/chunks/{ResolutionModal-DqRk_T0n.js.map → ResolutionModal-Duat18qV.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-Blau6_4c.js → RoleDetailPage-BQffUSnt.js} +3 -3
- package/dist/chunks/{RoleDetailPage-Blau6_4c.js.map → RoleDetailPage-BQffUSnt.js.map} +1 -1
- package/dist/chunks/{RoleDetailPage-CiRVxxIP.js → RoleDetailPage-JTm5lD1_.js} +2 -2
- package/dist/chunks/{RoleDetailPage-CiRVxxIP.js.map → RoleDetailPage-JTm5lD1_.js.map} +1 -1
- package/dist/chunks/{RolesPage-Pm-RN3lP.js → RolesPage-B9rRzciI.js} +2 -2
- package/dist/chunks/{RolesPage-Pm-RN3lP.js.map → RolesPage-B9rRzciI.js.map} +1 -1
- package/dist/chunks/{RolesPage-Cb8joqdJ.js → RolesPage-BN8_zMOC.js} +2 -2
- package/dist/chunks/{RolesPage-Cb8joqdJ.js.map → RolesPage-BN8_zMOC.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-B86McKM6.js → SlaConfigPage-B7kZNig4.js} +2 -2
- package/dist/chunks/{SlaConfigPage-B86McKM6.js.map → SlaConfigPage-B7kZNig4.js.map} +1 -1
- package/dist/chunks/{SlaConfigPage-BY7gvYU6.js → SlaConfigPage-okvZfA_K.js} +2 -2
- package/dist/chunks/{SlaConfigPage-BY7gvYU6.js.map → SlaConfigPage-okvZfA_K.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-BYxcLMSd.js → SupportPermissionsPage-DGAPqJbl.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-BYxcLMSd.js.map → SupportPermissionsPage-DGAPqJbl.js.map} +1 -1
- package/dist/chunks/{SupportPermissionsPage-MXqXNJIZ.js → SupportPermissionsPage-Dg_wLOme.js} +2 -2
- package/dist/chunks/{SupportPermissionsPage-MXqXNJIZ.js.map → SupportPermissionsPage-Dg_wLOme.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-BDguJ401.js → TemplatesPage-DT9fhlAU.js} +2 -2
- package/dist/chunks/{TemplatesPage-BDguJ401.js.map → TemplatesPage-DT9fhlAU.js.map} +1 -1
- package/dist/chunks/{TemplatesPage-DdnGgioU.js → TemplatesPage-DiEk538p.js} +2 -2
- package/dist/chunks/{TemplatesPage-DdnGgioU.js.map → TemplatesPage-DiEk538p.js.map} +1 -1
- package/dist/chunks/{TenantCard-ffwWsgFQ.js → TenantCard-BbSYk9_Z.js} +2 -2
- package/dist/chunks/{TenantCard-ffwWsgFQ.js.map → TenantCard-BbSYk9_Z.js.map} +1 -1
- package/dist/chunks/{TenantCard-CUjb6og9.js → TenantCard-CEkiKxcZ.js} +2 -2
- package/dist/chunks/{TenantCard-CUjb6og9.js.map → TenantCard-CEkiKxcZ.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-Dz7i1I43.js → TenantScopeSelector-BWfYxvEa.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-Dz7i1I43.js.map → TenantScopeSelector-BWfYxvEa.js.map} +1 -1
- package/dist/chunks/{TenantScopeSelector-Cym_Zyps.js → TenantScopeSelector-D-BKgQPV.js} +2 -2
- package/dist/chunks/{TenantScopeSelector-Cym_Zyps.js.map → TenantScopeSelector-D-BKgQPV.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-GOh9GX7E.js → TicketDetailPage-C1mNS9Up.js} +2 -2
- package/dist/chunks/{TicketDetailPage-GOh9GX7E.js.map → TicketDetailPage-C1mNS9Up.js.map} +1 -1
- package/dist/chunks/{TicketDetailPage-Du8WMyqf.js → TicketDetailPage-ieVDRh42.js} +2 -2
- package/dist/chunks/{TicketDetailPage-Du8WMyqf.js.map → TicketDetailPage-ieVDRh42.js.map} +1 -1
- package/dist/chunks/{TicketsPage-Bqd6moQy.js → TicketsPage-CnuWsnIW.js} +2 -2
- package/dist/chunks/{TicketsPage-Bqd6moQy.js.map → TicketsPage-CnuWsnIW.js.map} +1 -1
- package/dist/chunks/{TicketsPage-WdU4Bb7M.js → TicketsPage-jjyY15_D.js} +2 -2
- package/dist/chunks/{TicketsPage-WdU4Bb7M.js.map → TicketsPage-jjyY15_D.js.map} +1 -1
- package/dist/chunks/{UserCreateTicketPage-Cm1emgwR.js → UserCreateTicketPage-B8Tvf-ag.js} +2 -2
- package/dist/chunks/{UserCreateTicketPage-Cm1emgwR.js.map → UserCreateTicketPage-B8Tvf-ag.js.map} +1 -1
- package/dist/chunks/{UserCreateTicketPage-BPw-5Y_D.js → UserCreateTicketPage-DnOsDlfO.js} +2 -2
- package/dist/chunks/{UserCreateTicketPage-BPw-5Y_D.js.map → UserCreateTicketPage-DnOsDlfO.js.map} +1 -1
- package/dist/chunks/{UserDashboardPage-BP5WeXPS.js → UserDashboardPage-BrtkJ-NB.js} +2 -2
- package/dist/chunks/{UserDashboardPage-BP5WeXPS.js.map → UserDashboardPage-BrtkJ-NB.js.map} +1 -1
- package/dist/chunks/{UserDashboardPage-B53C8fUq.js → UserDashboardPage-KLB5CQP5.js} +2 -2
- package/dist/chunks/{UserDashboardPage-B53C8fUq.js.map → UserDashboardPage-KLB5CQP5.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-B110bmGX.js → UserDetailPage-U7smBQoF.js} +5 -5
- package/dist/chunks/{UserDetailPage-B110bmGX.js.map → UserDetailPage-U7smBQoF.js.map} +1 -1
- package/dist/chunks/{UserDetailPage-CV2VCE46.js → UserDetailPage-_J6lcKAU.js} +2 -2
- package/dist/chunks/{UserDetailPage-CV2VCE46.js.map → UserDetailPage-_J6lcKAU.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-CCNJON1V.js → UserTicketDetailPage-CWoYQgH-.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-CCNJON1V.js.map → UserTicketDetailPage-CWoYQgH-.js.map} +1 -1
- package/dist/chunks/{UserTicketDetailPage-V0mLXrox.js → UserTicketDetailPage-DkufSlvZ.js} +2 -2
- package/dist/chunks/{UserTicketDetailPage-V0mLXrox.js.map → UserTicketDetailPage-DkufSlvZ.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-CmdaU-z-.js → UsersGroupsPage-C38s2-Rq.js} +3 -3
- package/dist/chunks/{UsersGroupsPage-CmdaU-z-.js.map → UsersGroupsPage-C38s2-Rq.js.map} +1 -1
- package/dist/chunks/{UsersGroupsPage-BgfAMgEP.js → UsersGroupsPage-Dq3rAteo.js} +2 -2
- package/dist/chunks/{UsersGroupsPage-BgfAMgEP.js.map → UsersGroupsPage-Dq3rAteo.js.map} +1 -1
- package/dist/chunks/{UsersPage-Bg7033pp.js → UsersPage-B5C5KEUR.js} +2 -2
- package/dist/chunks/{UsersPage-Bg7033pp.js.map → UsersPage-B5C5KEUR.js.map} +1 -1
- package/dist/chunks/{UsersPage-TYAfwPY1.js → UsersPage-CXC9Hvq6.js} +2 -2
- package/dist/chunks/{UsersPage-TYAfwPY1.js.map → UsersPage-CXC9Hvq6.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-DZeDvzwv.js → accessRequestsApi-B-4TJ5_U.js} +2 -2
- package/dist/chunks/{accessRequestsApi-DZeDvzwv.js.map → accessRequestsApi-B-4TJ5_U.js.map} +1 -1
- package/dist/chunks/{accessRequestsApi-ZXFPCid2.js → accessRequestsApi-DZSfThpd.js} +2 -2
- package/dist/chunks/{accessRequestsApi-ZXFPCid2.js.map → accessRequestsApi-DZSfThpd.js.map} +1 -1
- package/dist/chunks/{aiApi-CsH8DXgs.js → aiApi-B20Teu2v.js} +2 -2
- package/dist/chunks/{aiApi-CsH8DXgs.js.map → aiApi-B20Teu2v.js.map} +1 -1
- package/dist/chunks/{aiApi-CVPzFTXa.js → aiApi-DMGz-RPM.js} +2 -2
- package/dist/chunks/{aiApi-CVPzFTXa.js.map → aiApi-DMGz-RPM.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-B8AhFYLr.js → applicationAnalyticsApi-Bwa75Fzd.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-B8AhFYLr.js.map → applicationAnalyticsApi-Bwa75Fzd.js.map} +1 -1
- package/dist/chunks/{applicationAnalyticsApi-Ce_1qOk-.js → applicationAnalyticsApi-CLBqRPfN.js} +2 -2
- package/dist/chunks/{applicationAnalyticsApi-Ce_1qOk-.js.map → applicationAnalyticsApi-CLBqRPfN.js.map} +1 -1
- package/dist/chunks/{groupsApi-BgCk2fsp.js → groupsApi-QzXI-5xu.js} +2 -2
- package/dist/chunks/{groupsApi-BgCk2fsp.js.map → groupsApi-QzXI-5xu.js.map} +1 -1
- package/dist/chunks/{groupsApi-BIbG665N.js → groupsApi-hB9kSWEd.js} +2 -2
- package/dist/chunks/{groupsApi-BIbG665N.js.map → groupsApi-hB9kSWEd.js.map} +1 -1
- package/dist/chunks/{index-Cb3LotuT.js → index--NGcBYUu.js} +3 -3
- package/dist/chunks/{index-Cb3LotuT.js.map → index--NGcBYUu.js.map} +1 -1
- package/dist/chunks/{index-C33zcyF4.js → index--aPwOFjF.js} +2 -2
- package/dist/chunks/{index-C33zcyF4.js.map → index--aPwOFjF.js.map} +1 -1
- package/dist/chunks/{index-sMr9qND_.js → index-0VrOtwP0.js} +2 -2
- package/dist/chunks/{index-sMr9qND_.js.map → index-0VrOtwP0.js.map} +1 -1
- package/dist/chunks/{index-DDKetfKq.js → index-37U271aw.js} +2 -2
- package/dist/chunks/{index-DDKetfKq.js.map → index-37U271aw.js.map} +1 -1
- package/dist/chunks/{index-B9fS7ir6.js → index-B7qZTuQ-.js} +2 -2
- package/dist/chunks/{index-B9fS7ir6.js.map → index-B7qZTuQ-.js.map} +1 -1
- package/dist/chunks/{index-CdjBY7L8.js → index-Bedzmqr-.js} +2 -2
- package/dist/chunks/{index-CdjBY7L8.js.map → index-Bedzmqr-.js.map} +1 -1
- package/dist/chunks/{index-CHG_O1fS.js → index-Betxo5g5.js} +2 -2
- package/dist/chunks/{index-CHG_O1fS.js.map → index-Betxo5g5.js.map} +1 -1
- package/dist/chunks/{index-jiGu-H8x.js → index-BmaJz475.js} +2 -2
- package/dist/chunks/{index-jiGu-H8x.js.map → index-BmaJz475.js.map} +1 -1
- package/dist/chunks/{index-C53JoVNk.js → index-Buhqag3v.js} +2 -2
- package/dist/chunks/{index-C53JoVNk.js.map → index-Buhqag3v.js.map} +1 -1
- package/dist/chunks/{index-DO0Rw7hX.js → index-C3VxlfKq.js} +2 -2
- package/dist/chunks/{index-DO0Rw7hX.js.map → index-C3VxlfKq.js.map} +1 -1
- package/dist/chunks/{index-CSQ60fpG.js → index-CgpRo8Oe.js} +2 -2
- package/dist/chunks/{index-CSQ60fpG.js.map → index-CgpRo8Oe.js.map} +1 -1
- package/dist/chunks/{index-B-e-ELsf.js → index-DOY0w8Iu.js} +8 -8
- package/dist/chunks/{index-B-e-ELsf.js.map → index-DOY0w8Iu.js.map} +1 -1
- package/dist/chunks/{index-D2REDIRX.js → index-DwuvIOrQ.js} +2 -2
- package/dist/chunks/{index-D2REDIRX.js.map → index-DwuvIOrQ.js.map} +1 -1
- package/dist/chunks/{index-DCcl7Qof.js → index-DzedSLdI.js} +2 -2
- package/dist/chunks/{index-DCcl7Qof.js.map → index-DzedSLdI.js.map} +1 -1
- package/dist/chunks/{index-2wUhd9Lu.js → index-IgLVXPg8.js} +10 -10
- package/dist/chunks/index-IgLVXPg8.js.map +1 -0
- package/dist/chunks/{index-CwSaRXXg.js → index-lpIzhufD.js} +1916 -1900
- package/dist/chunks/index-lpIzhufD.js.map +1 -0
- package/dist/chunks/{index-Cuwn2q-f.js → index-mLUKwbGl.js} +4 -4
- package/dist/chunks/{index-Cuwn2q-f.js.map → index-mLUKwbGl.js.map} +1 -1
- package/dist/chunks/{index-B0mk2tNY.js → index-tO6MMIFB.js} +2 -2
- package/dist/chunks/{index-B0mk2tNY.js.map → index-tO6MMIFB.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-BpNANQ5s.js → tenantIconMap-BQD9byc8.js} +2 -2
- package/dist/chunks/{tenantIconMap-BpNANQ5s.js.map → tenantIconMap-BQD9byc8.js.map} +1 -1
- package/dist/chunks/{tenantIconMap-DtdUgvJO.js → tenantIconMap-CTMuSt18.js} +2 -2
- package/dist/chunks/{tenantIconMap-DtdUgvJO.js.map → tenantIconMap-CTMuSt18.js.map} +1 -1
- package/dist/chunks/{ticketingApi-Bu4rKwLl.js → ticketingApi-BNIdox5t.js} +2 -2
- package/dist/chunks/{ticketingApi-Bu4rKwLl.js.map → ticketingApi-BNIdox5t.js.map} +1 -1
- package/dist/chunks/{ticketingApi-r4Avm9iS.js → ticketingApi-J0vC_t7r.js} +2 -2
- package/dist/chunks/{ticketingApi-r4Avm9iS.js.map → ticketingApi-J0vC_t7r.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-B9bF4swg.js → useAccessRequests-DCNNLnxk.js} +3 -3
- package/dist/chunks/{useAccessRequests-B9bF4swg.js.map → useAccessRequests-DCNNLnxk.js.map} +1 -1
- package/dist/chunks/{useAccessRequests-JyPUX3Om.js → useAccessRequests-DT7X4FAK.js} +2 -2
- package/dist/chunks/{useAccessRequests-JyPUX3Om.js.map → useAccessRequests-DT7X4FAK.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-DjPQenC2.js → useUserAccessRequests-BYbmG4c7.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-DjPQenC2.js.map → useUserAccessRequests-BYbmG4c7.js.map} +1 -1
- package/dist/chunks/{useUserAccessRequests-BB6FHW14.js → useUserAccessRequests-CylKxRN6.js} +2 -2
- package/dist/chunks/{useUserAccessRequests-BB6FHW14.js.map → useUserAccessRequests-CylKxRN6.js.map} +1 -1
- package/dist/hooks/useCollapsibleState.d.ts +5 -2
- package/dist/hooks/useCollapsibleState.d.ts.map +1 -1
- package/dist/i18n/config.d.ts +1 -0
- package/dist/i18n/config.d.ts.map +1 -1
- package/dist/main.d.ts +0 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/smartstack.cjs +1 -1
- package/dist/smartstack.js +1 -1
- package/dist/utils/permissions.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/index-2wUhd9Lu.js.map +0 -1
- package/dist/chunks/index-CwSaRXXg.js.map +0 -1
|
@@ -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-IgLVXPg8.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-BWQSCYl-.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentSkillsPage-7si3Ng8e.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-BWQSCYl-.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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"}
|
|
@@ -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 { a6 as N, B as F } from "./index-
|
|
5
|
+
import { a6 as N, B as F } from "./index-lpIzhufD.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-IQcMnBaD.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentSkillsPage-D0cD1QdM.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-IQcMnBaD.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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"}
|
|
@@ -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 { a7 as F, B as R, a8 as M } from "./index-
|
|
5
|
+
import { a7 as F, B as R, a8 as M } from "./index-lpIzhufD.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-DqrjkvWL.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentWorkloadPage-H_7ze33H.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-DqrjkvWL.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":";;;;;AAOA,MAAMA,IAAuC;AAAA,EAC3C,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AACX,GAEMC,IAAkD;AAAA,EACtD,QAAQC;AAAA,EACR,MAAMC;AAAA,EACN,MAAMA;AAAA,EACN,SAASA;AACX,GAEMC,IAAe;AAAA,EACnB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AACP;AAEO,SAASC,IAAkC;AAChD,QAAM,EAAE,GAAAC,EAAA,IAAMC,EAAe,SAAS,GAChC,CAACC,GAASC,CAAU,IAAIC,EAAS,EAAI,GACrC,CAACC,GAAQC,CAAS,IAAIF,EAA6B,CAAA,CAAE,GACrD,CAACG,GAAaC,CAAc,IAAIJ,EAAS,EAAK,GAC9C,CAACK,GAAcC,CAAe,IAAIN,EAAiB,EAAE,GACrD,CAACO,GAAgBC,CAAiB,IAAIR,EAAwB,IAAI,GAElES,IAAeC,EAAY,YAAY;AAC3C,QAAI;AACF,MAAAX,EAAW,EAAI;AACf,YAAMY,IAAO,MAAMC,EAAY,OAAA;AAC/B,MAAAV,EAAUS,CAAI;AAAA,IAChB,SAASE,GAAO;AACd,cAAQ,MAAM,kCAAkCA,CAAK;AAAA,IACvD,UAAA;AACE,MAAAd,EAAW,EAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAA,CAAE;AAEL,EAAAe,EAAU,MAAM;AACd,IAAAL,EAAA;AAAA,EACF,GAAG,CAACA,CAAY,CAAC,GAEjBK,EAAU,MAAM;AACd,QAAI,CAACX,EAAa;AAClB,UAAMY,IAAW,YAAY,MAAMN,EAAA,GAAgB,GAAK;AACxD,WAAO,MAAM,cAAcM,CAAQ;AAAA,EACrC,GAAG,CAACZ,GAAaM,CAAY,CAAC;AAE9B,QAAMO,IAAwB,CAACC,MACtB,KAAK,MAAOA,EAAM,oBAAoBA,EAAM,uBAAwB,GAAG,GAG1EC,IAAyB,CAACC,MAC1BA,KAAW,KAAW,yBACtBA,KAAW,KAAW,2BACnB,0BAGHC,IAAe,OAAOC,GAAgBC,MAAsB;AAChE,QAAI;AACF,MAAAd,EAAkBa,CAAM,GACxB,MAAME,EAAgB,OAAOF,GAAQ,EAAE,QAAQC,GAAW,GAC1D,MAAMb,EAAA;AAAA,IACR,SAASI,GAAO;AACd,cAAQ,MAAM,4BAA4BA,CAAK;AAAA,IACjD,UAAA;AACE,MAAAL,EAAkB,IAAI;AAAA,IACxB;AAAA,EACF,GAEMgB,IAAiBnB,IACnBJ,EAAO,OAAO,CAACwB,MAAMA,EAAE,uBAAuBpB,CAAY,IAC1DJ,GAEEyB,IAAczB,EAAO,QACrB0B,IAAc1B,EAAO,OAAO,CAACwB,MAAMA,EAAE,uBAAuB,QAAQ,EAAE,QACtEG,IAAiB,KAAK;AAAA,IAC1B3B,EAAO,OAAO,CAAC4B,GAAKJ,MAAMI,IAAMb,EAAsBS,CAAC,GAAG,CAAC,KAAKxB,EAAO,UAAU;AAAA,EAAA,GAE7E6B,IAAkB7B,EAAO,OAAO,CAACwB,MAAMT,EAAsBS,CAAC,IAAI,EAAE,EAAE;AAE5E,SACE,gBAAAM,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAAC;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,EAAE,OAAOrC,EAAE,SAAS,SAAS,GAAG,MAAM,WAAA;AAAA,UACtC,EAAE,OAAOA,EAAE,qBAAqB,EAAA;AAAA,QAAE;AAAA,MACpC;AAAA,IAAA;AAAA,IAGF,gBAAAmC,EAAC,OAAA,EAAI,WAAU,oCACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EACC,UAAA;AAAA,QAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,sBAAsB,UAAApC,EAAE,qBAAqB,GAAE;AAAA,0BAC5D,KAAA,EAAE,WAAU,gCAAgC,UAAAA,EAAE,wBAAwB,EAAA,CAAE;AAAA,MAAA,GAC3E;AAAA,MACA,gBAAAmC,EAAC,OAAA,EAAI,WAAU,cACb,UAAA;AAAA,QAAA,gBAAAC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAMvB,EAAA;AAAA,YACf,WAAU;AAAA,YAEV,UAAA,gBAAAuB,EAACE,GAAA,EAAU,WAAU,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEjC,gBAAAH,EAAC,SAAA,EAAM,WAAU,mGACf,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS7B;AAAA,cACT,UAAU,CAAC,MAAMC,EAAe,EAAE,OAAO,OAAO;AAAA,cAChD,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,4BAEX,QAAA,EAAK,WAAU,WAAW,UAAAR,EAAE,6BAA6B,cAAc,EAAA,CAAE;AAAA,QAAA,EAAA,CAC5E;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAECE,IACC,gBAAAkC,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA,gBAAAA,EAACG,GAAA,EAAQ,WAAU,uDAAA,CAAuD,EAAA,CAC5E,IAEA,gBAAAJ,EAAAK,GAAA,EACE,UAAA;AAAA,MAAA,gBAAAL,EAAC,OAAA,EAAI,WAAU,yCACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAW,+BAA+BrC,EAAa,IAAI,IAC9D,UAAA;AAAA,UAAA,gBAAAsC,EAAC,OAAA,EAAI,WAAU,sBAAsB,UAAAN,GAAY;AAAA,4BAChD,OAAA,EAAI,WAAU,sBAAsB,UAAA9B,EAAE,iCAAiC,cAAc,EAAA,CAAE;AAAA,QAAA,GAC1F;AAAA,0BACC,OAAA,EAAI,WAAW,+BAA+BF,EAAa,KAAK,IAC/D,UAAA;AAAA,UAAA,gBAAAsC,EAAC,OAAA,EAAI,WAAU,sBAAsB,UAAAL,GAAY;AAAA,4BAChD,OAAA,EAAI,WAAU,sBAAsB,UAAA/B,EAAE,4BAA4B,QAAQ,EAAA,CAAE;AAAA,QAAA,GAC/E;AAAA,0BACC,OAAA,EAAI,WAAW,+BAA+BF,EAAa,MAAM,IAChE,UAAA;AAAA,UAAA,gBAAAqC,EAAC,OAAA,EAAI,WAAU,sBAAsB,UAAA;AAAA,YAAAH;AAAA,YAAe;AAAA,UAAA,GAAC;AAAA,4BACpD,OAAA,EAAI,WAAU,sBAAsB,UAAAhC,EAAE,oCAAoC,kBAAkB,EAAA,CAAE;AAAA,QAAA,GACjG;AAAA,0BACC,OAAA,EAAI,WAAW,+BAA+BF,EAAa,GAAG,IAC7D,UAAA;AAAA,UAAA,gBAAAsC,EAAC,OAAA,EAAI,WAAU,sBAAsB,UAAAF,GAAgB;AAAA,4BACpD,OAAA,EAAI,WAAU,sBAAsB,UAAAlC,EAAE,gCAAgC,YAAY,EAAA,CAAE;AAAA,QAAA,EAAA,CACvF;AAAA,MAAA,GACF;AAAA,MAEA,gBAAAoC,EAAC,OAAA,EAAI,WAAU,QACb,UAAA,gBAAAD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAO1B;AAAA,UACP,UAAU,CAAC,MAAMC,EAAgB,EAAE,OAAO,KAAK;AAAA,UAC/C,WAAU;AAAA,UAEV,UAAA;AAAA,YAAA,gBAAA0B,EAAC,YAAO,OAAM,IAAI,UAAApC,EAAE,cAAc,cAAc,GAAE;AAAA,8BACjD,UAAA,EAAO,OAAM,UAAU,UAAAA,EAAE,+BAA+B,QAAQ,GAAE;AAAA,8BAClE,UAAA,EAAO,OAAM,QAAQ,UAAAA,EAAE,6BAA6B,MAAM,GAAE;AAAA,8BAC5D,UAAA,EAAO,OAAM,QAAQ,UAAAA,EAAE,6BAA6B,MAAM,GAAE;AAAA,8BAC5D,UAAA,EAAO,OAAM,WAAW,UAAAA,EAAE,gCAAgC,SAAS,EAAA,CAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA,GAE1E;AAAA,MAEC4B,EAAe,WAAW,IACzB,gBAAAQ,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA,gBAAAA,EAAC,KAAA,EAAE,WAAU,gCAAgC,UAAApC,EAAE,uBAAuB,iBAAiB,EAAA,CAAE,EAAA,CAC3F,IAEA,gBAAAoC,EAAC,OAAA,EAAI,WAAU,0BACZ,UAAAR,EAAe,IAAI,CAACP,MAAU;AAC7B,cAAMoB,IAAa9C,EAAY0B,EAAM,kBAAkB,KAAKxB,GACtD6C,IAAqBtB,EAAsBC,CAAK;AAEtD,iCACG,OAAA,EAAuB,WAAU,YAChC,UAAA,gBAAAc,EAAC,OAAA,EAAI,WAAU,yCACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,yBAAyB,UAAAf,EAAM,YAAY,iBAAgB;AAAA,YACzE,gBAAAe,EAAC,KAAA,EAAE,WAAU,wCAAwC,YAAM,OAAA,CAAO;AAAA,UAAA,GACpE;AAAA,UAEA,gBAAAD,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,OAAE,WAAU,yDACV,UAAApC,EAAE,4BAA4B,gBAAgB,GACjD;AAAA,YACA,gBAAAoC,EAAC,KAAA,EAAE,WAAU,sBAAsB,YAAM,mBAAkB;AAAA,YAC3D,gBAAAD,EAAC,KAAA,EAAE,WAAU,wCACV,UAAA;AAAA,cAAAnC,EAAE,uBAAuB,UAAU;AAAA,cAAE;AAAA,cAAGqB,EAAM;AAAA,YAAA,EAAA,CACjD;AAAA,UAAA,GACF;AAAA,UAEA,gBAAAc,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,OAAE,WAAU,yDACV,UAAApC,EAAE,6BAA6B,aAAa,GAC/C;AAAA,YACA,gBAAAoC,EAAC,OAAA,EAAI,WAAU,oEACb,UAAA,gBAAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAW,UAAUd,EAAuBoB,CAAkB,CAAC;AAAA,gBAC/D,OAAO,EAAE,OAAO,GAAG,KAAK,IAAIA,GAAoB,GAAG,CAAC,IAAA;AAAA,cAAI;AAAA,YAAA,GAE5D;AAAA,YACA,gBAAAP,EAAC,KAAA,EAAE,WAAU,8BAA8B,UAAA;AAAA,cAAAO;AAAA,cAAmB;AAAA,YAAA,EAAA,CAAC;AAAA,UAAA,GACjE;AAAA,UAEA,gBAAAP,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,YAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,cAAA,gBAAAC,EAACK,GAAA,EAAW,WAAU,UAAA,CAAU;AAAA,gCAC/B,QAAA,EAAK,WAAW,8CAA8C/C,EAAa2B,EAAM,kBAAkB,CAAC,IAClG,UAAArB,EAAE,wBAAwBqB,EAAM,kBAAkB,IAAIA,EAAM,kBAAkB,EAAA,CACjF;AAAA,YAAA,GACF;AAAA,YACA,gBAAAc;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAOd,EAAM;AAAA,gBACb,UAAU,CAACsB,MAAMnB,EAAaH,EAAM,QAAQsB,EAAE,OAAO,KAAK;AAAA,gBAC1D,UAAUhC,MAAmBU,EAAM;AAAA,gBACnC,WAAU;AAAA,gBAEV,UAAA;AAAA,kBAAA,gBAAAe,EAAC,YAAO,OAAM,UAAU,UAAApC,EAAE,+BAA+B,QAAQ,GAAE;AAAA,oCAClE,UAAA,EAAO,OAAM,QAAQ,UAAAA,EAAE,6BAA6B,MAAM,GAAE;AAAA,oCAC5D,UAAA,EAAO,OAAM,QAAQ,UAAAA,EAAE,6BAA6B,MAAM,GAAE;AAAA,oCAC5D,UAAA,EAAO,OAAM,WAAW,UAAAA,EAAE,gCAAgC,SAAS,EAAA,CAAE;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UACxE,EAAA,CACF;AAAA,QAAA,GACF,EAAA,GAjDQqB,EAAM,MAkDhB;AAAA,MAEJ,CAAC,EAAA,CACH;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA,GAEJ;AAEJ;"}
|
|
@@ -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-IgLVXPg8.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-w-HiyFYP.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentWorkloadPage-D4d86cdV.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-w-HiyFYP.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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"}
|
|
@@ -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-lpIzhufD.js";
|
|
7
|
+
import { aiApi as _ } from "./aiApi-DMGz-RPM.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-D3L8Yf4G.js.map
|