@clickview/curator 1.101.0-rc.4 → 1.101.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/.vite/manifest.json +475 -475
  2. package/dist/Assets/js/dist/scripts/{Bs1Y6-vh.chunk.js → -OUl3n-W.chunk.js} +2 -2
  3. package/dist/Assets/js/dist/scripts/{Bs1Y6-vh.chunk.js.map → -OUl3n-W.chunk.js.map} +1 -1
  4. package/dist/Assets/js/dist/scripts/5FGdlWcH.chunk.js +9 -0
  5. package/dist/Assets/js/dist/scripts/5FGdlWcH.chunk.js.map +1 -0
  6. package/dist/Assets/js/dist/scripts/B0UOCPE6.chunk.js +2 -0
  7. package/dist/Assets/js/dist/scripts/{r-zw-56e.chunk.js.map → B0UOCPE6.chunk.js.map} +1 -1
  8. package/dist/Assets/js/dist/scripts/{Ds6WvphR2.chunk.js → BD2aIccu2.chunk.js} +2 -2
  9. package/dist/Assets/js/dist/scripts/{Ds6WvphR2.chunk.js.map → BD2aIccu2.chunk.js.map} +1 -1
  10. package/dist/Assets/js/dist/scripts/{BwpzKPd12.chunk.js → BJJeLngO2.chunk.js} +2 -2
  11. package/dist/Assets/js/dist/scripts/{BwpzKPd12.chunk.js.map → BJJeLngO2.chunk.js.map} +1 -1
  12. package/dist/Assets/js/dist/scripts/{CaG8Cjey2.chunk.js → BKQIzKcF2.chunk.js} +2 -2
  13. package/dist/Assets/js/dist/scripts/{CaG8Cjey2.chunk.js.map → BKQIzKcF2.chunk.js.map} +1 -1
  14. package/dist/Assets/js/dist/scripts/{BEw27Jf3.chunk.js → BOrAaHLK.chunk.js} +2 -2
  15. package/dist/Assets/js/dist/scripts/{BEw27Jf3.chunk.js.map → BOrAaHLK.chunk.js.map} +1 -1
  16. package/dist/Assets/js/dist/scripts/BSMzg7zU.chunk.js.map +1 -1
  17. package/dist/Assets/js/dist/scripts/{CO69n5GB2.chunk.js → BUWsFXQp2.chunk.js} +2 -2
  18. package/dist/Assets/js/dist/scripts/{CO69n5GB2.chunk.js.map → BUWsFXQp2.chunk.js.map} +1 -1
  19. package/dist/Assets/js/dist/scripts/{BZU4ADoQ2.chunk.js → C1xOGHlL2.chunk.js} +2 -2
  20. package/dist/Assets/js/dist/scripts/{BZU4ADoQ2.chunk.js.map → C1xOGHlL2.chunk.js.map} +1 -1
  21. package/dist/Assets/js/dist/scripts/{CbaobIxf2.chunk.js → CAo_C8em2.chunk.js} +2 -2
  22. package/dist/Assets/js/dist/scripts/{CbaobIxf2.chunk.js.map → CAo_C8em2.chunk.js.map} +1 -1
  23. package/dist/Assets/js/dist/scripts/{D_e7ctVq.chunk.js → COH92JF5.chunk.js} +2 -2
  24. package/dist/Assets/js/dist/scripts/{D_e7ctVq.chunk.js.map → COH92JF5.chunk.js.map} +1 -1
  25. package/dist/Assets/js/dist/scripts/{CJpr073K.chunk.js → CR-5nCWm.chunk.js} +2 -2
  26. package/dist/Assets/js/dist/scripts/{CJpr073K.chunk.js.map → CR-5nCWm.chunk.js.map} +1 -1
  27. package/dist/Assets/js/dist/scripts/{CqhZ98rZ2.chunk.js → CW1ea_Kx2.chunk.js} +2 -2
  28. package/dist/Assets/js/dist/scripts/{CqhZ98rZ2.chunk.js.map → CW1ea_Kx2.chunk.js.map} +1 -1
  29. package/dist/Assets/js/dist/scripts/{DPA1azNU2.chunk.js → Cbwl04yH2.chunk.js} +2 -2
  30. package/dist/Assets/js/dist/scripts/{DPA1azNU2.chunk.js.map → Cbwl04yH2.chunk.js.map} +1 -1
  31. package/dist/Assets/js/dist/scripts/{DsHVJvUP.chunk.js → CpqMUVVi.chunk.js} +2 -2
  32. package/dist/Assets/js/dist/scripts/{DsHVJvUP.chunk.js.map → CpqMUVVi.chunk.js.map} +1 -1
  33. package/dist/Assets/js/dist/scripts/{I_gdFDV7.chunk.js → CqZqlJSF.chunk.js} +2 -2
  34. package/dist/Assets/js/dist/scripts/{I_gdFDV7.chunk.js.map → CqZqlJSF.chunk.js.map} +1 -1
  35. package/dist/Assets/js/dist/scripts/{CofA9RRF.chunk.js → CzCUe0Ej.chunk.js} +2 -2
  36. package/dist/Assets/js/dist/scripts/{CofA9RRF.chunk.js.map → CzCUe0Ej.chunk.js.map} +1 -1
  37. package/dist/Assets/js/dist/scripts/{DhN_Jc2z.chunk.js → DTUkmChD.chunk.js} +3 -3
  38. package/dist/Assets/js/dist/scripts/{DhN_Jc2z.chunk.js.map → DTUkmChD.chunk.js.map} +1 -1
  39. package/dist/Assets/js/dist/scripts/{C8YkY0we.chunk.js → DW7-la-i.chunk.js} +2 -2
  40. package/dist/Assets/js/dist/scripts/{C8YkY0we.chunk.js.map → DW7-la-i.chunk.js.map} +1 -1
  41. package/dist/Assets/js/dist/scripts/{ecehd0o7.chunk.js → Dhnl-PB5.chunk.js} +2 -2
  42. package/dist/Assets/js/dist/scripts/{ecehd0o7.chunk.js.map → Dhnl-PB5.chunk.js.map} +1 -1
  43. package/dist/Assets/js/dist/scripts/{jdQzplq1.chunk.js → DuU4GBw5.chunk.js} +2 -2
  44. package/dist/Assets/js/dist/scripts/{jdQzplq1.chunk.js.map → DuU4GBw5.chunk.js.map} +1 -1
  45. package/dist/Assets/js/dist/scripts/{CvMpxc4j2.chunk.js → LmwQmHZz2.chunk.js} +2 -2
  46. package/dist/Assets/js/dist/scripts/{CvMpxc4j2.chunk.js.map → LmwQmHZz2.chunk.js.map} +1 -1
  47. package/dist/Assets/js/dist/scripts/{app-D2seXuq-.js → app-DHtN6XkT.js} +3 -3
  48. package/dist/Assets/js/dist/scripts/{app-D2seXuq-.js.map → app-DHtN6XkT.js.map} +1 -1
  49. package/dist/Assets/js/dist/scripts/{DUsXdKYh.chunk.js → eKSK4iyn.chunk.js} +2 -2
  50. package/dist/Assets/js/dist/scripts/{DUsXdKYh.chunk.js.map → eKSK4iyn.chunk.js.map} +1 -1
  51. package/dist/Assets/js/dist/scripts/{BdXsbiX1.chunk.js → esASf9N4.chunk.js} +2 -2
  52. package/dist/Assets/js/dist/scripts/{BdXsbiX1.chunk.js.map → esASf9N4.chunk.js.map} +1 -1
  53. package/dist/Assets/js/dist/scripts/{De-ohgjE.chunk.js → x1pOfdJd.chunk.js} +2 -2
  54. package/dist/Assets/js/dist/scripts/x1pOfdJd.chunk.js.map +1 -0
  55. package/dist/bundles.json +1 -1
  56. package/dist/en.json +1 -1
  57. package/package.json +1 -1
  58. package/dist/Assets/js/dist/scripts/C7Rwn3_U.chunk.js +0 -9
  59. package/dist/Assets/js/dist/scripts/C7Rwn3_U.chunk.js.map +0 -1
  60. package/dist/Assets/js/dist/scripts/De-ohgjE.chunk.js.map +0 -1
  61. package/dist/Assets/js/dist/scripts/r-zw-56e.chunk.js +0 -2
@@ -1,2 +1,2 @@
1
- import{C as e,a as t,ln as n,r}from"./BlDu0qdC.chunk.js";import{n as i}from"./DqUkhPat.chunk.js";import{t as a}from"./DEBg-sxL.chunk.js";import{t as o}from"./BvMTtGLi.chunk.js";import{r as s}from"./DkstLT1W.chunk.js";import{c,d as l}from"./BIZf7Q462.chunk.js";import"./COkf8IPk2.chunk.js";import{t as u}from"./C1PTqhPY2.chunk.js";import{t as d}from"./Bt5qHBoM2.chunk.js";import{r as f,t as p}from"./lFyCTjyz2.chunk.js";import{t as m}from"./Dky2FRAZ.chunk.js";import{t as h}from"./C-KuBn_h.chunk.js";import{n as g}from"./BwAM2wHw.chunk.js";import{t as _}from"./CWbBaJAA.chunk.js";import{t as v}from"./DLDFNrWX2.chunk.js";import{t as y}from"./CVBPygL42.chunk.js";import{t as b}from"./BpUUlg_v2.chunk.js";import{t as x}from"./C1sAaO9k.chunk.js";import{t as S}from"./Bidcjyrx.chunk.js";import{t as C}from"./DxyWWBj-.chunk.js";import{t as ee}from"./a2U2Z4t12.chunk.js";import{t as te}from"./CGACfSBR.chunk.js";import{t as w}from"./D2Da5UcT.chunk.js";import{r as T,t as E}from"./v-3x6QfN.chunk.js";import{t as ne}from"./CEetwDE1.chunk.js";import{t as re}from"./BkB6-4E82.chunk.js";import{n as ie,t as ae}from"./7_JVCgAt2.chunk.js";import{t as D}from"./gzUId2LV2.chunk.js";import{t as O}from"./DFTL10vi2.chunk.js";import{r as k}from"./Dw2_OYS32.chunk.js";import{t as oe}from"./DpqKiNuw.chunk.js";import{n as se}from"./r-zw-56e.chunk.js";var A=n(t()),j=r();function M(e){switch(p.getUserType(e)){case u.Learner:return`Student`;case u.Staff:return`Staff`;case u.Unknown:return`Unknown`;default:return`Unknown`}}var N=g(),P={title:()=>N.accessor(`title`,{id:`title`,header:``,cell:e=>(0,j.jsx)(`div`,{className:`font-label`,children:e.getValue()})}),value:()=>N.accessor(`value`,{id:`value`,header:``,cell:e=>(0,j.jsx)(`div`,{children:e.getValue()})}),action:()=>N.accessor(`action`,{id:`action`,header:``,cell:e=>e.getValue()?(0,j.jsx)(`div`,{children:e.getValue()}):null})};function ce({user:e,onUnverifyEmail:t,onSendPasswordResetEmail:n,onVerifyEmail:r,customerless:a}){let o=e.metadata?.isEmailVerified,s=e.status===f.Active,c=[{title:`Email`,value:(0,j.jsxs)(`div`,{className:`d-flex gap-2 align-items-center`,children:[o&&(0,j.jsx)(i,{svg:x}),e.email||`-`]}),action:e.email&&s&&!a?(0,j.jsx)(`div`,{className:`d-flex justify-content-end`,children:(0,j.jsx)(m,{className:`p-0 ms-2 text-info`,title:o?`Unverify email`:`Verify email`,variant:`link`,onClick:o?t:r,children:o?`Unverify email`:`Verify email`})}):null},{title:`Last Name`,value:e.surname},{title:`First Name`,value:e.name},{title:`User Type`,value:(0,j.jsx)(`div`,{className:k(M(e)),children:M(e)})},{title:`Display Name`,value:e.metadata.displayName||`-`},{title:`Username`,value:e.username,action:s&&o&&n?(0,j.jsx)(`div`,{className:`d-flex justify-content-end`,children:(0,j.jsx)(m,{className:`p-0 ms-2 text-info`,title:`Send password reset email`,variant:`link`,onClick:n,children:`Send password reset email`})}):null}],l={...D,header:`d-none`,row:``};return(0,j.jsx)(_,{data:c,columns:Object.values(P).map(e=>e()),theme:l})}function F(t){A.useEffect(()=>{t.id||e.trigger({application:o.CRM_STUDIO,action:a.CrmStudio.USERS})},[t.id]);let[n,r]=A.useState(!1),[,i]=A.useState(!1),[,g]=C(te.BULK_REMOVE_USERS),[_,x]=A.useState(!1),[D,k]=A.useState(!1),M=y(),{hasPermissions:N,isLoading:P}=v();(0,A.useEffect)(()=>{P||x(N(s.UsersSsoUpdate)||!1)},[P]);let F=S.user(t.id),I=c(E.getUserWithCustomers(t.id)),L=c(F),R=I.hasCompleted&&(I.data?.userProfiles?.data.length>0||I.data?.userProfile)?I.data?.userProfile?.customer?.id&&p.getUserStatusFromValue(I.data?.userProfile?.status)===f.Active?I.data?.userProfile?.customer?.id:I.data?.userProfiles?.data?.find(e=>p.getUserStatusFromValue(e.status)===f.Active)?.customer?.id:null,z=E.getUser(R,t.id),B=c(R?z:null),V={...I.data,...L.data,...B.data},H={...V,status:p.getUserStatusFromValue(V.status)},U=c(d.currentUser()),W=c(R?E.yearGroups(R):null),G=c(R?E.passwordPolicy(R):null),le=c(R&&E.getAuthenticationMethodsByUserIds(R,[t.id],z.normalizeOptions?.namespace)),K=H.userType,q=l(),J=R?I.hasCompleted&&L.hasCompleted&&B.hasCompleted&&W.hasCompleted&&G.hasCompleted&&le.hasCompleted:L.hasCompleted;function ue(e){let t=T.formatCreateOrValidateUserRequest([e],H.userType,R);return q(E.bulkValidate(t,!1,R))}async function Y(e,t){try{i(!0);let n=await ue(e);if(!T.handleAsyncErrors(n,e,H,t)){i(!1);return}let a=T.formatEditUserRequest(e);await q(E.updateUser(R,a,U.data.id)),M.success(`User updated successfully`),r(!1),t&&t()}catch{M.error(`Failed to update user. Please try again.`),t&&t()}finally{i(!1)}}async function X(e){try{await q(E.resendActivationEmail(R,e.id)),M.success(`Activation email sent successfully.`)}catch{M.error(`Failed to send activation email.`)}}async function Z(){try{i(!0),await q(E.sendPasswordResetEmail(R,H.id)),M.success(`Password reset email sent successfully.`)}catch{M.error(`Failed to send password reset email.`)}}async function Q(e){try{i(!0),await q(E.resendVerificationEmail(R,e.id)),M.success(`Email verification email sent successfully.`)}catch{M.error(`Failed to send email verification email.`)}}async function de(){e.trigger({application:o.CRM_STUDIO,action:a.CrmStudio.DELETE_USER_EMAIL,args:[R,H.id],params:{userType:K}})}function fe(){return H.userProfiles?.data?(H.userProfiles?.data||[]).some(e=>p.getUserStatusFromValue(e.status)===f.Active):!1}let $=H.userProfiles?.data?.length===0;return A.useEffect(()=>{J&&k(fe())},[J]),(0,j.jsx)(ae,{view:ie.Users,children:(0,j.jsxs)(oe,{title:`Overview`,currentTabId:`overview`,id:t.id,loading:!J,children:[!R&&(0,j.jsx)(`div`,{className:`mb-3`,children:(0,j.jsx)(O,{variant:`warning`,className:`w-100`,children:`This user is not associated with any customers, and therefore cannot be edited. In order to edit this user, please add to a customer in the customer schools tab.`})}),H.id&&p.hasSso(H)&&(0,j.jsx)(`div`,{className:`mb-3`,children:(0,j.jsx)(O,{variant:`warning`,className:`w-100`,children:`Some of this user’s account details are managed by their SSO provider.`})}),R&&!D&&(0,j.jsx)(`div`,{className:`mb-3`,children:(0,j.jsx)(O,{variant:`warning`,className:`w-100`,children:`This user has no active customers, and therefore cannot be edited. In order to edit this user, please activate a customer in the customer schools tab.`})}),J&&H&&(0,j.jsxs)(`div`,{children:[(0,j.jsx)(re,{heading:`User details`,svg:b,buttonClassname:`null`,onClick:R?()=>r(!0):void 0,disableCollapse:!0,children:(0,j.jsx)(ce,{user:H,onUnverifyEmail:()=>de(),onSendPasswordResetEmail:()=>Z(),onVerifyEmail:()=>Q(H),customerless:!R})}),(0,j.jsxs)(`div`,{className:`d-flex justify-content-end mt-3 gap-2`,children:[!!N(s.UsersSsoUpdate)&&D&&(0,j.jsx)(ee.Toggle,{on:_,onClick:()=>x(e=>!e),label:`Allow ClickView Staff to edit SSO fields`,disabled:!p.hasSso(H),tooltip:!p.hasSso(H)&&`This user doesn't sign in with SSO`}),H.email&&H.status===f.Inactive&&!H.metadata.isEmailVerified&&(0,j.jsx)(m,{variant:`outline-dark`,onClick:()=>X(H),children:`Resend activation email`}),J&&(()=>{let e=H.status===f.Active&&($||!D),t=!$&&D,n=t?`This user has active customers, therefore this action is not allowed.`:void 0;return e?(0,j.jsx)(w,{className:`btn btn-danger`,appLink:{application:o.CRM_STUDIO,action:a.CrmStudio.TOGGLE_USER_STATUS,args:[null,H.id]},children:`Deactivate account`}):(0,j.jsx)(w,{className:`btn btn-danger${t?` pointer-events-none opacity-50`:``}`,appLink:{application:o.CRM_STUDIO,action:a.CrmStudio.BULK_REMOVE_USERS,args:[R],params:{userType:K}},onClick:()=>g({allUsers:!1,users:[H],totalUsers:1,redirectToSearch:!1}),disabled:t,tooltip:n,children:`Delete account`})})()]})]}),n&&J&&(0,j.jsx)(h,{title:`Edit User details`,closePopup:()=>r(!1),children:(0,j.jsx)(ne,{user:H,userType:H.userType,yearGroups:H.userType===u.Learner?Array.isArray(W)?W:[]:null,initialValues:se(H,R),initialErrors:T.getInitialErrorsForInvalidYearGroups(H.masterYearGroup),onSubmit:Y,onClickResendActivationEmail:X,onClickSendResetEmail:Z,onClickSendVerificationEmail:Q,onClickCancel:()=>r(!1),currentUser:U.data,emailRequired:H.userType===u.Staff,showActions:!1,passwordPolicy:G.data,showDisplayNameField:H.userType===u.Staff,hideAdminToggle:!0,hideSsoToggle:!0,hideYearLevel:!0,canEditSsoFields:_})})]})})}export{F as UserOverviewView};
2
- //# sourceMappingURL=Bs1Y6-vh.chunk.js.map
1
+ import{C as e,a as t,ln as n,r}from"./BlDu0qdC.chunk.js";import{n as i}from"./DqUkhPat.chunk.js";import{t as a}from"./DEBg-sxL.chunk.js";import{t as o}from"./BvMTtGLi.chunk.js";import{r as s}from"./DkstLT1W.chunk.js";import{c,d as l}from"./BIZf7Q462.chunk.js";import"./COkf8IPk2.chunk.js";import{t as u}from"./C1PTqhPY2.chunk.js";import{t as d}from"./Bt5qHBoM2.chunk.js";import{r as f,t as p}from"./lFyCTjyz2.chunk.js";import{t as m}from"./Dky2FRAZ.chunk.js";import{t as h}from"./C-KuBn_h.chunk.js";import{n as g}from"./BwAM2wHw.chunk.js";import{t as _}from"./CWbBaJAA.chunk.js";import{t as v}from"./DLDFNrWX2.chunk.js";import{t as y}from"./CVBPygL42.chunk.js";import{t as b}from"./BpUUlg_v2.chunk.js";import{t as x}from"./C1sAaO9k.chunk.js";import{t as S}from"./Bidcjyrx.chunk.js";import{t as C}from"./DxyWWBj-.chunk.js";import{t as ee}from"./a2U2Z4t12.chunk.js";import{t as te}from"./CGACfSBR.chunk.js";import{t as w}from"./D2Da5UcT.chunk.js";import{r as T,t as E}from"./v-3x6QfN.chunk.js";import{t as ne}from"./CEetwDE1.chunk.js";import{t as re}from"./BkB6-4E82.chunk.js";import{n as ie,t as ae}from"./7_JVCgAt2.chunk.js";import{t as D}from"./gzUId2LV2.chunk.js";import{t as O}from"./DFTL10vi2.chunk.js";import{r as k}from"./Dw2_OYS32.chunk.js";import{t as oe}from"./DpqKiNuw.chunk.js";import{n as se}from"./B0UOCPE6.chunk.js";var A=n(t()),j=r();function M(e){switch(p.getUserType(e)){case u.Learner:return`Student`;case u.Staff:return`Staff`;case u.Unknown:return`Unknown`;default:return`Unknown`}}var N=g(),P={title:()=>N.accessor(`title`,{id:`title`,header:``,cell:e=>(0,j.jsx)(`div`,{className:`font-label`,children:e.getValue()})}),value:()=>N.accessor(`value`,{id:`value`,header:``,cell:e=>(0,j.jsx)(`div`,{children:e.getValue()})}),action:()=>N.accessor(`action`,{id:`action`,header:``,cell:e=>e.getValue()?(0,j.jsx)(`div`,{children:e.getValue()}):null})};function ce({user:e,onUnverifyEmail:t,onSendPasswordResetEmail:n,onVerifyEmail:r,customerless:a}){let o=e.metadata?.isEmailVerified,s=e.status===f.Active,c=[{title:`Email`,value:(0,j.jsxs)(`div`,{className:`d-flex gap-2 align-items-center`,children:[o&&(0,j.jsx)(i,{svg:x}),e.email||`-`]}),action:e.email&&s&&!a?(0,j.jsx)(`div`,{className:`d-flex justify-content-end`,children:(0,j.jsx)(m,{className:`p-0 ms-2 text-info`,title:o?`Unverify email`:`Verify email`,variant:`link`,onClick:o?t:r,children:o?`Unverify email`:`Verify email`})}):null},{title:`Last Name`,value:e.surname},{title:`First Name`,value:e.name},{title:`User Type`,value:(0,j.jsx)(`div`,{className:k(M(e)),children:M(e)})},{title:`Display Name`,value:e.metadata.displayName||`-`},{title:`Username`,value:e.username,action:s&&o&&n?(0,j.jsx)(`div`,{className:`d-flex justify-content-end`,children:(0,j.jsx)(m,{className:`p-0 ms-2 text-info`,title:`Send password reset email`,variant:`link`,onClick:n,children:`Send password reset email`})}):null}],l={...D,header:`d-none`,row:``};return(0,j.jsx)(_,{data:c,columns:Object.values(P).map(e=>e()),theme:l})}function F(t){A.useEffect(()=>{t.id||e.trigger({application:o.CRM_STUDIO,action:a.CrmStudio.USERS})},[t.id]);let[n,r]=A.useState(!1),[,i]=A.useState(!1),[,g]=C(te.BULK_REMOVE_USERS),[_,x]=A.useState(!1),[D,k]=A.useState(!1),M=y(),{hasPermissions:N,isLoading:P}=v();(0,A.useEffect)(()=>{P||x(N(s.UsersSsoUpdate)||!1)},[P]);let F=S.user(t.id),I=c(E.getUserWithCustomers(t.id)),L=c(F),R=I.hasCompleted&&(I.data?.userProfiles?.data.length>0||I.data?.userProfile)?I.data?.userProfile?.customer?.id&&p.getUserStatusFromValue(I.data?.userProfile?.status)===f.Active?I.data?.userProfile?.customer?.id:I.data?.userProfiles?.data?.find(e=>p.getUserStatusFromValue(e.status)===f.Active)?.customer?.id:null,z=E.getUser(R,t.id),B=c(R?z:null),V={...I.data,...L.data,...B.data},H={...V,status:p.getUserStatusFromValue(V.status)},U=c(d.currentUser()),W=c(R?E.yearGroups(R):null),G=c(R?E.passwordPolicy(R):null),le=c(R&&E.getAuthenticationMethodsByUserIds(R,[t.id],z.normalizeOptions?.namespace)),K=H.userType,q=l(),J=R?I.hasCompleted&&L.hasCompleted&&B.hasCompleted&&W.hasCompleted&&G.hasCompleted&&le.hasCompleted:L.hasCompleted;function ue(e){let t=T.formatCreateOrValidateUserRequest([e],H.userType,R);return q(E.bulkValidate(t,!1,R))}async function Y(e,t){try{i(!0);let n=await ue(e);if(!T.handleAsyncErrors(n,e,H,t)){i(!1);return}let a=T.formatEditUserRequest(e);await q(E.updateUser(R,a,U.data.id)),M.success(`User updated successfully`),r(!1),t&&t()}catch{M.error(`Failed to update user. Please try again.`),t&&t()}finally{i(!1)}}async function X(e){try{await q(E.resendActivationEmail(R,e.id)),M.success(`Activation email sent successfully.`)}catch{M.error(`Failed to send activation email.`)}}async function Z(){try{i(!0),await q(E.sendPasswordResetEmail(R,H.id)),M.success(`Password reset email sent successfully.`)}catch{M.error(`Failed to send password reset email.`)}}async function Q(e){try{i(!0),await q(E.resendVerificationEmail(R,e.id)),M.success(`Email verification email sent successfully.`)}catch{M.error(`Failed to send email verification email.`)}}async function de(){e.trigger({application:o.CRM_STUDIO,action:a.CrmStudio.DELETE_USER_EMAIL,args:[R,H.id],params:{userType:K}})}function fe(){return H.userProfiles?.data?(H.userProfiles?.data||[]).some(e=>p.getUserStatusFromValue(e.status)===f.Active):!1}let $=H.userProfiles?.data?.length===0;return A.useEffect(()=>{J&&k(fe())},[J]),(0,j.jsx)(ae,{view:ie.Users,children:(0,j.jsxs)(oe,{title:`Overview`,currentTabId:`overview`,id:t.id,loading:!J,children:[!R&&(0,j.jsx)(`div`,{className:`mb-3`,children:(0,j.jsx)(O,{variant:`warning`,className:`w-100`,children:`This user is not associated with any customers, and therefore cannot be edited. In order to edit this user, please add to a customer in the customer schools tab.`})}),H.id&&p.hasSso(H)&&(0,j.jsx)(`div`,{className:`mb-3`,children:(0,j.jsx)(O,{variant:`warning`,className:`w-100`,children:`Some of this user’s account details are managed by their SSO provider.`})}),R&&!D&&(0,j.jsx)(`div`,{className:`mb-3`,children:(0,j.jsx)(O,{variant:`warning`,className:`w-100`,children:`This user has no active customers, and therefore cannot be edited. In order to edit this user, please activate a customer in the customer schools tab.`})}),J&&H&&(0,j.jsxs)(`div`,{children:[(0,j.jsx)(re,{heading:`User details`,svg:b,buttonClassname:`null`,onClick:R?()=>r(!0):void 0,disableCollapse:!0,children:(0,j.jsx)(ce,{user:H,onUnverifyEmail:()=>de(),onSendPasswordResetEmail:()=>Z(),onVerifyEmail:()=>Q(H),customerless:!R})}),(0,j.jsxs)(`div`,{className:`d-flex justify-content-end mt-3 gap-2`,children:[!!N(s.UsersSsoUpdate)&&D&&(0,j.jsx)(ee.Toggle,{on:_,onClick:()=>x(e=>!e),label:`Allow ClickView Staff to edit SSO fields`,disabled:!p.hasSso(H),tooltip:!p.hasSso(H)&&`This user doesn't sign in with SSO`}),H.email&&H.status===f.Inactive&&!H.metadata.isEmailVerified&&(0,j.jsx)(m,{variant:`outline-dark`,onClick:()=>X(H),children:`Resend activation email`}),J&&(()=>{let e=H.status===f.Active&&($||!D),t=!$&&D,n=t?`This user has active customers, therefore this action is not allowed.`:void 0;return e?(0,j.jsx)(w,{className:`btn btn-danger`,appLink:{application:o.CRM_STUDIO,action:a.CrmStudio.TOGGLE_USER_STATUS,args:[null,H.id]},children:`Deactivate account`}):(0,j.jsx)(w,{className:`btn btn-danger${t?` pointer-events-none opacity-50`:``}`,appLink:{application:o.CRM_STUDIO,action:a.CrmStudio.BULK_REMOVE_USERS,args:[R],params:{userType:K}},onClick:()=>g({allUsers:!1,users:[H],totalUsers:1,redirectToSearch:!1}),disabled:t,tooltip:n,children:`Delete account`})})()]})]}),n&&J&&(0,j.jsx)(h,{title:`Edit User details`,closePopup:()=>r(!1),children:(0,j.jsx)(ne,{user:H,userType:H.userType,yearGroups:H.userType===u.Learner?Array.isArray(W)?W:[]:null,initialValues:se(H,R),initialErrors:T.getInitialErrorsForInvalidYearGroups(H.masterYearGroup),onSubmit:Y,onClickResendActivationEmail:X,onClickSendResetEmail:Z,onClickSendVerificationEmail:Q,onClickCancel:()=>r(!1),currentUser:U.data,emailRequired:H.userType===u.Staff,showActions:!1,passwordPolicy:G.data,showDisplayNameField:H.userType===u.Staff,hideAdminToggle:!0,hideSsoToggle:!0,hideYearLevel:!0,canEditSsoFields:_})})]})})}export{F as UserOverviewView};
2
+ //# sourceMappingURL=-OUl3n-W.chunk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Bs1Y6-vh.chunk.js","names":[],"sources":["../../../../../src/apps/crm-studio/components/tables/UserOverviewTable.tsx","../../../../../src/apps/crm-studio/views/users/UserOverviewView.tsx"],"sourcesContent":["import React from 'react';\nimport { Button } from 'react-bootstrap';\nimport { createColumnHelper } from '@tanstack/react-table';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { TableV2 } from 'libs/shared/components/table-v2/TableV2';\nimport { ObjectStatus } from 'libs/shared/enums/ObjectStatus';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { CheckCircleSvg } from 'libs/shared/images/svg/status/CheckCircleSvg';\nimport { User } from 'libs/shared/interfaces/models/User';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport { getUserTypeClassname } from 'apps/crm-studio/components/tables/UsersTable';\n\nimport { CrmStudioTableTheme } from './CrmStudioTableTheme';\n\nexport function getTypeText(user: User): string {\n switch (UserHelper.getUserType(user)) {\n case UserGroup.Learner:\n return 'Student';\n case UserGroup.Staff:\n return 'Staff';\n case UserGroup.Unknown:\n return 'Unknown';\n default:\n return 'Unknown';\n }\n}\n\nexport interface UserOverviewDataRow {\n title: string;\n value: React.ReactNode;\n action?: React.ReactNode;\n}\n\nconst columnHelper = createColumnHelper<UserOverviewDataRow>();\nconst UserOverviewColumns = {\n title: () =>\n columnHelper.accessor('title', {\n id: 'title',\n header: '',\n cell: props => <div className='font-label'>{props.getValue()}</div>\n }),\n value: () =>\n columnHelper.accessor('value', {\n id: 'value',\n header: '',\n cell: props => <div>{props.getValue()}</div>\n }),\n action: () =>\n columnHelper.accessor('action', {\n id: 'action',\n header: '',\n cell: props => props.getValue() ? <div>{props.getValue()}</div> : null\n })\n};\n\nexport function UserOverviewTable({ user, onUnverifyEmail, onSendPasswordResetEmail, onVerifyEmail, customerless }: {\n user: User,\n onUnverifyEmail?: () => void,\n onSendPasswordResetEmail?: () => void,\n onVerifyEmail?: () => void,\n customerless?: boolean\n}) {\n const emailVerified = user.metadata?.isEmailVerified;\n const isActive = user.status === ObjectStatus.Active;\n const data: UserOverviewDataRow[] = [\n {\n title: 'Email',\n value: (\n <div className='d-flex gap-2 align-items-center'>\n {emailVerified && (\n <SvgContainer\n svg={CheckCircleSvg}\n />\n )}\n {user.email || '-'}\n </div>\n ),\n action: (\n user.email && isActive && !customerless ? (\n <div className='d-flex justify-content-end'>\n <Button\n className='p-0 ms-2 text-info'\n title={emailVerified ? 'Unverify email' : 'Verify email'}\n variant='link'\n onClick={emailVerified ? onUnverifyEmail : onVerifyEmail}\n >\n {emailVerified ? 'Unverify email' : 'Verify email'}\n </Button>\n </div>\n ) : null\n )\n },\n { title: 'Last Name', value: user.surname },\n { title: 'First Name', value: user.name },\n { title: 'User Type', value: (\n <div className={getUserTypeClassname(getTypeText(user))}>\n {getTypeText(user) }\n </div>\n ) },\n { title: 'Display Name', value: user.metadata.displayName || '-' },\n {\n title: 'Username',\n value: user.username,\n action: (isActive && emailVerified && onSendPasswordResetEmail) ? (\n <div className='d-flex justify-content-end'>\n <Button\n className='p-0 ms-2 text-info'\n title='Send password reset email'\n variant='link'\n onClick={onSendPasswordResetEmail}\n >\n Send password reset email\n </Button>\n </div>\n ) : null\n }\n ];\n\n const theme = {\n ...CrmStudioTableTheme,\n header: 'd-none',\n row: ''\n };\n \n return (\n <TableV2\n data={data}\n columns={Object.values(UserOverviewColumns).map(column => column())}\n theme={theme}\n />\n );\n}\n","import React, { useEffect } from 'react';\nimport { Button } from 'react-bootstrap';\n\nimport { AppLinkHelper } from 'libs/common/backbone/core';\nimport { Core } from 'libs/common/backbone/index';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { Flight } from 'libs/common/react/index';\n\nimport { EditUserDetails } from 'libs/shared/apps/user-manager/components/edit-user-details/EditUserDetails';\nimport { EditUserRequest } from 'libs/shared/apps/user-manager/interfaces';\nimport { SecuritySettingsResponse } from 'libs/shared/apps/user-manager/interfaces/SecuritySettingsResponse';\nimport { BulkRemoveUsersViewModel } from 'libs/shared/apps/user-manager/interfaces/viewmodels/BulkRemoveUsersViewModel';\nimport { UserManagerHelper } from 'libs/shared/apps/user-manager/utils/UserManagerHelper';\nimport { ActionButton } from 'libs/shared/components/actions/ActionButton';\nimport { AlertV2 } from 'libs/shared/components/alert-v2/AlertV2';\nimport { DropdownContainer } from 'libs/shared/components/dropdown-container/DropdownContainer';\nimport { FormSubmissionOptions } from 'libs/shared/components/forms/form-wrapper/FormWrapper';\nimport { Popup } from 'libs/shared/components/popup/Popup';\nimport { PopupButtons } from 'libs/shared/components/popup/PopupButtons';\nimport { ObjectStatus } from 'libs/shared/enums/ObjectStatus';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { EditSvg } from 'libs/shared/images/svg/actions/EditSvg';\nimport { CurrentUser, User } from 'libs/shared/interfaces/models/User';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport { Actions } from 'shared/constants/CuratorActions';\nimport { ViewModelKeys } from 'shared/constants/CuratorViewModels';\nimport { AppChannels } from 'shared/constants/RadioChannels';\nimport { CuratorPermissionName } from 'shared/enums/CuratorPermissionName';\nimport { useCuratorPermissions } from 'shared/hooks/UseCuratorPermissions';\n\nimport { UserOverviewTable } from 'apps/crm-studio/components/tables/UserOverviewTable';\nimport { CustomerRequests } from 'apps/crm-studio/flight-requests/CustomerRequests';\nimport { CrmStudioLayoutView, CrmStudioLayoutViewPage } from 'apps/crm-studio/views/layout/CrmStudioLayout';\nimport { CrmStudioUserLayout } from 'apps/crm-studio/views/layout/CrmStudioUserLayout';\nimport { getUserInitialValues } from 'apps/crm-studio/views/users/edit-user/EditUserUtils';\nimport { CuratorUserRequests } from 'apps/users/flight-requests/CuratorUserRequests';\n\ninterface UserOverviewViewProps {\n id: string;\n}\n\nexport function UserOverviewView(props: UserOverviewViewProps) {\n// handle after delete the current user\n React.useEffect(() => {\n if (!props.id) {\n Core.AppLinkHelper.trigger({\n application: AppChannels.CRM_STUDIO,\n action: Actions.CrmStudio.USERS\n });\n }\n }, [props.id]);\n\n const [ showEditModal, setShowEditModal ] = React.useState(false);\n const [ , setShowSpinner ] = React.useState(false);\n const [ , setViewModel ] = useViewModel<BulkRemoveUsersViewModel>(ViewModelKeys.BULK_REMOVE_USERS);\n const [ editSsoFields, setEditSsoFields ] = React.useState(false);\n const [ isAnyCustomerActive, setIsAnyCustomerActive ] = React.useState(false);\n\n const alerts = useAlerts();\n const { hasPermissions, isLoading } = useCuratorPermissions();\n\n useEffect(() => {\n if (!isLoading) {\n setEditSsoFields(hasPermissions(CuratorPermissionName.UsersSsoUpdate) || false);\n }\n }, [isLoading]);\n\n const userCustomerlessRequest = CuratorUserRequests.user(props.id);\n const userWithCustomersRequest = CustomerRequests.getUserWithCustomers(props.id);\n\n const userWithCustomers = Flight.useBasicFetch<User>(userWithCustomersRequest);\n const userCustomerless = Flight.useBasicFetch<User>(userCustomerlessRequest);\n\n const userHasCustomer = userWithCustomers.hasCompleted && (\n userWithCustomers.data?.userProfiles?.data.length > 0 || userWithCustomers.data?.userProfile\n );\n\n const customerId = userHasCustomer ?\n (\n userWithCustomers.data?.userProfile?.customer?.id &&\n UserHelper.getUserStatusFromValue(userWithCustomers.data?.userProfile?.status) === ObjectStatus.Active ?\n userWithCustomers.data?.userProfile?.customer?.id :\n userWithCustomers.data?.userProfiles?.data?.find(\n profile => UserHelper.getUserStatusFromValue(profile.status) === ObjectStatus.Active\n )?.customer?.id\n ) :\n null;\n\n const userExtraRequest = CustomerRequests.getUser(customerId, props.id);\n const userExtra = Flight.useBasicFetch<User>(customerId ? userExtraRequest : null);\n\n const _mergedUser = { ...userWithCustomers.data, ...userCustomerless.data, ...userExtra.data };\n const user = { ..._mergedUser, status: UserHelper.getUserStatusFromValue(_mergedUser.status) };\n\n const currentUser = Flight.useBasicFetch(UserRequests.currentUser());\n const yearGroups = Flight.useBasicFetch(\n customerId ? CustomerRequests.yearGroups(customerId) : null\n );\n const passwordPolicy = Flight.useBasicFetch<SecuritySettingsResponse>(\n customerId ? CustomerRequests.passwordPolicy(customerId) : null\n );\n const authMethods = Flight.useBasicFetch(\n customerId && CustomerRequests.getAuthenticationMethodsByUserIds(\n customerId,\n [props.id],\n userExtraRequest.normalizeOptions?.namespace\n )\n );\n\n const userType = user.userType;\n const fetchAsync = Flight.useGetFetchAsync();\n\n const isLoaded = customerId ? (\n userWithCustomers.hasCompleted &&\n userCustomerless.hasCompleted &&\n userExtra.hasCompleted &&\n yearGroups.hasCompleted &&\n passwordPolicy.hasCompleted &&\n authMethods.hasCompleted\n ) : (\n userCustomerless.hasCompleted\n );\n\n function validateUser(_user: EditUserRequest): Promise<any> {\n const data = UserManagerHelper.formatCreateOrValidateUserRequest([_user], user.userType, customerId);\n return fetchAsync(CustomerRequests.bulkValidate(data, false, customerId));\n }\n\n async function saveUser(_user: EditUserRequest, onDone: (options?: FormSubmissionOptions) => void): Promise<void> {\n try {\n setShowSpinner(true);\n const errors = await validateUser(_user);\n const isValid = UserManagerHelper.handleAsyncErrors(errors, _user, user, onDone);\n if (!isValid) {\n setShowSpinner(false);\n return;\n }\n const data = UserManagerHelper.formatEditUserRequest(_user);\n await fetchAsync(CustomerRequests.updateUser(\n customerId,\n data,\n (currentUser.data as CurrentUser).id\n ));\n alerts.success('User updated successfully');\n setShowEditModal(false);\n if (onDone) onDone();\n } catch {\n alerts.error('Failed to update user. Please try again.');\n if (onDone) onDone();\n } finally {\n setShowSpinner(false);\n }\n }\n\n async function resendActivationEmail(_user: User) {\n try {\n await fetchAsync(CustomerRequests.resendActivationEmail(customerId, _user.id));\n alerts.success('Activation email sent successfully.');\n } catch {\n alerts.error('Failed to send activation email.');\n }\n }\n\n async function confirmSendPasswordResetEmail() {\n try {\n setShowSpinner(true);\n await fetchAsync(CustomerRequests.sendPasswordResetEmail(customerId, user.id));\n alerts.success('Password reset email sent successfully.');\n } catch {\n alerts.error('Failed to send password reset email.');\n }\n }\n\n async function resendVerificationEmail(_user: User) {\n try {\n setShowSpinner(true);\n await fetchAsync(CustomerRequests.resendVerificationEmail(customerId, _user.id));\n alerts.success('Email verification email sent successfully.');\n } catch {\n alerts.error('Failed to send email verification email.');\n }\n }\n\n async function deleteEmail(): Promise<void> {\n AppLinkHelper.trigger({\n application: AppChannels.CRM_STUDIO,\n action: Actions.CrmStudio.DELETE_USER_EMAIL,\n args: [ customerId, user.id ],\n params: { userType }\n });\n }\n\n function checkIfAnyCustomerActive(): boolean {\n if (!user.userProfiles?.data) return false;\n const profiles = user.userProfiles?.data || [];\n return profiles.some(profile => UserHelper.getUserStatusFromValue(profile.status) === ObjectStatus.Active);\n }\n const isCustomerlessUser = user.userProfiles?.data?.length === 0;\n\n React.useEffect(() => {\n if (isLoaded) {\n setIsAnyCustomerActive(checkIfAnyCustomerActive());\n }\n }, [isLoaded]);\n\n return (\n <CrmStudioLayoutView view={CrmStudioLayoutViewPage.Users}>\n <CrmStudioUserLayout\n title='Overview'\n currentTabId='overview'\n id={props.id}\n loading={!isLoaded}\n >\n {!customerId && (\n <div className='mb-3'>\n <AlertV2 variant='warning' className='w-100'>\n This user is not associated with any customers, and therefore cannot be\n edited. In order to edit this user, please add to a customer in the customer schools tab.\n </AlertV2>\n </div>\n )}\n {(user.id && UserHelper.hasSso(user)) && (\n <div className='mb-3'>\n <AlertV2 variant='warning' className='w-100'>\n Some of this user’s account details are managed by their SSO provider.\n </AlertV2>\n </div>\n )}\n {customerId && !isAnyCustomerActive && (\n <div className='mb-3'>\n <AlertV2 variant='warning' className='w-100'>\n This user has no active customers, and therefore cannot be\n edited. In order to edit this user, please activate a customer in the customer schools tab.\n </AlertV2>\n </div>\n )}\n {isLoaded && user && (\n <div>\n <DropdownContainer\n heading='User details'\n svg={EditSvg}\n buttonClassname='null'\n onClick={(customerId) ?\n () => setShowEditModal(true) :\n undefined\n }\n disableCollapse\n >\n <UserOverviewTable\n user={user}\n onUnverifyEmail={() => deleteEmail()}\n onSendPasswordResetEmail={() => confirmSendPasswordResetEmail()}\n onVerifyEmail={() => resendVerificationEmail(user)}\n customerless={!customerId}\n />\n </DropdownContainer>\n <div className='d-flex justify-content-end mt-3 gap-2'>\n {!!hasPermissions(CuratorPermissionName.UsersSsoUpdate) && isAnyCustomerActive && (\n <PopupButtons.Toggle\n on={editSsoFields}\n onClick={() => setEditSsoFields(v => !v)}\n label='Allow ClickView Staff to edit SSO fields'\n disabled={!UserHelper.hasSso(user)}\n tooltip={!UserHelper.hasSso(user) && 'This user doesn\\'t sign in with SSO'}\n />\n )}\n {user.email &&\n user.status === ObjectStatus.Inactive &&\n !user.metadata.isEmailVerified && (\n <Button\n variant='outline-dark'\n onClick={() => resendActivationEmail(user)}\n >\n Resend activation email\n </Button>\n )}\n {isLoaded && (() => {\n const showDeactivate = user.status === ObjectStatus.Active &&\n (isCustomerlessUser || !isAnyCustomerActive);\n const deleteDisabled = !isCustomerlessUser && isAnyCustomerActive;\n const deleteDisabledTooltip = deleteDisabled ?\n 'This user has active customers, therefore this action is not allowed.' :\n undefined;\n\n if (showDeactivate) {\n return (\n <ActionButton\n className='btn btn-danger'\n appLink={{\n application: AppChannels.CRM_STUDIO,\n action: Actions.CrmStudio.TOGGLE_USER_STATUS,\n args: [ null, user.id ]\n }}\n >\n Deactivate account\n </ActionButton>\n );\n }\n\n return (\n <ActionButton\n className={`btn btn-danger${deleteDisabled ? ' pointer-events-none opacity-50' : ''}`}\n appLink={{\n application: AppChannels.CRM_STUDIO,\n action: Actions.CrmStudio.BULK_REMOVE_USERS,\n args: [customerId],\n params: { userType }\n }}\n onClick={() => setViewModel({\n allUsers: false, users: [user], totalUsers: 1, redirectToSearch: false\n })}\n disabled={deleteDisabled}\n tooltip={deleteDisabledTooltip}\n >\n Delete account\n </ActionButton>\n );\n })()}\n </div>\n </div>\n )}\n {showEditModal && isLoaded && (\n <Popup title='Edit User details' closePopup={() => setShowEditModal(false)}>\n <EditUserDetails\n user={user}\n userType={user.userType}\n yearGroups={\n user.userType === UserGroup.Learner ?\n (Array.isArray(yearGroups) ? yearGroups : []) :\n null\n }\n initialValues={getUserInitialValues(user, customerId)}\n initialErrors={UserManagerHelper.getInitialErrorsForInvalidYearGroups(user.masterYearGroup)}\n onSubmit={saveUser}\n onClickResendActivationEmail={resendActivationEmail}\n onClickSendResetEmail={confirmSendPasswordResetEmail}\n onClickSendVerificationEmail={resendVerificationEmail}\n onClickCancel={() => setShowEditModal(false)}\n currentUser={currentUser.data as CurrentUser}\n emailRequired={user.userType === UserGroup.Staff}\n showActions={false}\n passwordPolicy={passwordPolicy.data}\n showDisplayNameField={user.userType === UserGroup.Staff}\n hideAdminToggle={true}\n hideSsoToggle={true}\n hideYearLevel={true}\n canEditSsoFields={editSsoFields}\n />\n </Popup>\n )}\n </CrmStudioUserLayout>\n </CrmStudioLayoutView>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"-OUl3n-W.chunk.js","names":[],"sources":["../../../../../src/apps/crm-studio/components/tables/UserOverviewTable.tsx","../../../../../src/apps/crm-studio/views/users/UserOverviewView.tsx"],"sourcesContent":["import React from 'react';\nimport { Button } from 'react-bootstrap';\nimport { createColumnHelper } from '@tanstack/react-table';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { TableV2 } from 'libs/shared/components/table-v2/TableV2';\nimport { ObjectStatus } from 'libs/shared/enums/ObjectStatus';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { CheckCircleSvg } from 'libs/shared/images/svg/status/CheckCircleSvg';\nimport { User } from 'libs/shared/interfaces/models/User';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport { getUserTypeClassname } from 'apps/crm-studio/components/tables/UsersTable';\n\nimport { CrmStudioTableTheme } from './CrmStudioTableTheme';\n\nexport function getTypeText(user: User): string {\n switch (UserHelper.getUserType(user)) {\n case UserGroup.Learner:\n return 'Student';\n case UserGroup.Staff:\n return 'Staff';\n case UserGroup.Unknown:\n return 'Unknown';\n default:\n return 'Unknown';\n }\n}\n\nexport interface UserOverviewDataRow {\n title: string;\n value: React.ReactNode;\n action?: React.ReactNode;\n}\n\nconst columnHelper = createColumnHelper<UserOverviewDataRow>();\nconst UserOverviewColumns = {\n title: () =>\n columnHelper.accessor('title', {\n id: 'title',\n header: '',\n cell: props => <div className='font-label'>{props.getValue()}</div>\n }),\n value: () =>\n columnHelper.accessor('value', {\n id: 'value',\n header: '',\n cell: props => <div>{props.getValue()}</div>\n }),\n action: () =>\n columnHelper.accessor('action', {\n id: 'action',\n header: '',\n cell: props => props.getValue() ? <div>{props.getValue()}</div> : null\n })\n};\n\nexport function UserOverviewTable({ user, onUnverifyEmail, onSendPasswordResetEmail, onVerifyEmail, customerless }: {\n user: User,\n onUnverifyEmail?: () => void,\n onSendPasswordResetEmail?: () => void,\n onVerifyEmail?: () => void,\n customerless?: boolean\n}) {\n const emailVerified = user.metadata?.isEmailVerified;\n const isActive = user.status === ObjectStatus.Active;\n const data: UserOverviewDataRow[] = [\n {\n title: 'Email',\n value: (\n <div className='d-flex gap-2 align-items-center'>\n {emailVerified && (\n <SvgContainer\n svg={CheckCircleSvg}\n />\n )}\n {user.email || '-'}\n </div>\n ),\n action: (\n user.email && isActive && !customerless ? (\n <div className='d-flex justify-content-end'>\n <Button\n className='p-0 ms-2 text-info'\n title={emailVerified ? 'Unverify email' : 'Verify email'}\n variant='link'\n onClick={emailVerified ? onUnverifyEmail : onVerifyEmail}\n >\n {emailVerified ? 'Unverify email' : 'Verify email'}\n </Button>\n </div>\n ) : null\n )\n },\n { title: 'Last Name', value: user.surname },\n { title: 'First Name', value: user.name },\n { title: 'User Type', value: (\n <div className={getUserTypeClassname(getTypeText(user))}>\n {getTypeText(user) }\n </div>\n ) },\n { title: 'Display Name', value: user.metadata.displayName || '-' },\n {\n title: 'Username',\n value: user.username,\n action: (isActive && emailVerified && onSendPasswordResetEmail) ? (\n <div className='d-flex justify-content-end'>\n <Button\n className='p-0 ms-2 text-info'\n title='Send password reset email'\n variant='link'\n onClick={onSendPasswordResetEmail}\n >\n Send password reset email\n </Button>\n </div>\n ) : null\n }\n ];\n\n const theme = {\n ...CrmStudioTableTheme,\n header: 'd-none',\n row: ''\n };\n \n return (\n <TableV2\n data={data}\n columns={Object.values(UserOverviewColumns).map(column => column())}\n theme={theme}\n />\n );\n}\n","import React, { useEffect } from 'react';\nimport { Button } from 'react-bootstrap';\n\nimport { AppLinkHelper } from 'libs/common/backbone/core';\nimport { Core } from 'libs/common/backbone/index';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { Flight } from 'libs/common/react/index';\n\nimport { EditUserDetails } from 'libs/shared/apps/user-manager/components/edit-user-details/EditUserDetails';\nimport { EditUserRequest } from 'libs/shared/apps/user-manager/interfaces';\nimport { SecuritySettingsResponse } from 'libs/shared/apps/user-manager/interfaces/SecuritySettingsResponse';\nimport { BulkRemoveUsersViewModel } from 'libs/shared/apps/user-manager/interfaces/viewmodels/BulkRemoveUsersViewModel';\nimport { UserManagerHelper } from 'libs/shared/apps/user-manager/utils/UserManagerHelper';\nimport { ActionButton } from 'libs/shared/components/actions/ActionButton';\nimport { AlertV2 } from 'libs/shared/components/alert-v2/AlertV2';\nimport { DropdownContainer } from 'libs/shared/components/dropdown-container/DropdownContainer';\nimport { FormSubmissionOptions } from 'libs/shared/components/forms/form-wrapper/FormWrapper';\nimport { Popup } from 'libs/shared/components/popup/Popup';\nimport { PopupButtons } from 'libs/shared/components/popup/PopupButtons';\nimport { ObjectStatus } from 'libs/shared/enums/ObjectStatus';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { EditSvg } from 'libs/shared/images/svg/actions/EditSvg';\nimport { CurrentUser, User } from 'libs/shared/interfaces/models/User';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport { Actions } from 'shared/constants/CuratorActions';\nimport { ViewModelKeys } from 'shared/constants/CuratorViewModels';\nimport { AppChannels } from 'shared/constants/RadioChannels';\nimport { CuratorPermissionName } from 'shared/enums/CuratorPermissionName';\nimport { useCuratorPermissions } from 'shared/hooks/UseCuratorPermissions';\n\nimport { UserOverviewTable } from 'apps/crm-studio/components/tables/UserOverviewTable';\nimport { CustomerRequests } from 'apps/crm-studio/flight-requests/CustomerRequests';\nimport { CrmStudioLayoutView, CrmStudioLayoutViewPage } from 'apps/crm-studio/views/layout/CrmStudioLayout';\nimport { CrmStudioUserLayout } from 'apps/crm-studio/views/layout/CrmStudioUserLayout';\nimport { getUserInitialValues } from 'apps/crm-studio/views/users/edit-user/EditUserUtils';\nimport { CuratorUserRequests } from 'apps/users/flight-requests/CuratorUserRequests';\n\ninterface UserOverviewViewProps {\n id: string;\n}\n\nexport function UserOverviewView(props: UserOverviewViewProps) {\n// handle after delete the current user\n React.useEffect(() => {\n if (!props.id) {\n Core.AppLinkHelper.trigger({\n application: AppChannels.CRM_STUDIO,\n action: Actions.CrmStudio.USERS\n });\n }\n }, [props.id]);\n\n const [ showEditModal, setShowEditModal ] = React.useState(false);\n const [ , setShowSpinner ] = React.useState(false);\n const [ , setViewModel ] = useViewModel<BulkRemoveUsersViewModel>(ViewModelKeys.BULK_REMOVE_USERS);\n const [ editSsoFields, setEditSsoFields ] = React.useState(false);\n const [ isAnyCustomerActive, setIsAnyCustomerActive ] = React.useState(false);\n\n const alerts = useAlerts();\n const { hasPermissions, isLoading } = useCuratorPermissions();\n\n useEffect(() => {\n if (!isLoading) {\n setEditSsoFields(hasPermissions(CuratorPermissionName.UsersSsoUpdate) || false);\n }\n }, [isLoading]);\n\n const userCustomerlessRequest = CuratorUserRequests.user(props.id);\n const userWithCustomersRequest = CustomerRequests.getUserWithCustomers(props.id);\n\n const userWithCustomers = Flight.useBasicFetch<User>(userWithCustomersRequest);\n const userCustomerless = Flight.useBasicFetch<User>(userCustomerlessRequest);\n\n const userHasCustomer = userWithCustomers.hasCompleted && (\n userWithCustomers.data?.userProfiles?.data.length > 0 || userWithCustomers.data?.userProfile\n );\n\n const customerId = userHasCustomer ?\n (\n userWithCustomers.data?.userProfile?.customer?.id &&\n UserHelper.getUserStatusFromValue(userWithCustomers.data?.userProfile?.status) === ObjectStatus.Active ?\n userWithCustomers.data?.userProfile?.customer?.id :\n userWithCustomers.data?.userProfiles?.data?.find(\n profile => UserHelper.getUserStatusFromValue(profile.status) === ObjectStatus.Active\n )?.customer?.id\n ) :\n null;\n\n const userExtraRequest = CustomerRequests.getUser(customerId, props.id);\n const userExtra = Flight.useBasicFetch<User>(customerId ? userExtraRequest : null);\n\n const _mergedUser = { ...userWithCustomers.data, ...userCustomerless.data, ...userExtra.data };\n const user = { ..._mergedUser, status: UserHelper.getUserStatusFromValue(_mergedUser.status) };\n\n const currentUser = Flight.useBasicFetch(UserRequests.currentUser());\n const yearGroups = Flight.useBasicFetch(\n customerId ? CustomerRequests.yearGroups(customerId) : null\n );\n const passwordPolicy = Flight.useBasicFetch<SecuritySettingsResponse>(\n customerId ? CustomerRequests.passwordPolicy(customerId) : null\n );\n const authMethods = Flight.useBasicFetch(\n customerId && CustomerRequests.getAuthenticationMethodsByUserIds(\n customerId,\n [props.id],\n userExtraRequest.normalizeOptions?.namespace\n )\n );\n\n const userType = user.userType;\n const fetchAsync = Flight.useGetFetchAsync();\n\n const isLoaded = customerId ? (\n userWithCustomers.hasCompleted &&\n userCustomerless.hasCompleted &&\n userExtra.hasCompleted &&\n yearGroups.hasCompleted &&\n passwordPolicy.hasCompleted &&\n authMethods.hasCompleted\n ) : (\n userCustomerless.hasCompleted\n );\n\n function validateUser(_user: EditUserRequest): Promise<any> {\n const data = UserManagerHelper.formatCreateOrValidateUserRequest([_user], user.userType, customerId);\n return fetchAsync(CustomerRequests.bulkValidate(data, false, customerId));\n }\n\n async function saveUser(_user: EditUserRequest, onDone: (options?: FormSubmissionOptions) => void): Promise<void> {\n try {\n setShowSpinner(true);\n const errors = await validateUser(_user);\n const isValid = UserManagerHelper.handleAsyncErrors(errors, _user, user, onDone);\n if (!isValid) {\n setShowSpinner(false);\n return;\n }\n const data = UserManagerHelper.formatEditUserRequest(_user);\n await fetchAsync(CustomerRequests.updateUser(\n customerId,\n data,\n (currentUser.data as CurrentUser).id\n ));\n alerts.success('User updated successfully');\n setShowEditModal(false);\n if (onDone) onDone();\n } catch {\n alerts.error('Failed to update user. Please try again.');\n if (onDone) onDone();\n } finally {\n setShowSpinner(false);\n }\n }\n\n async function resendActivationEmail(_user: User) {\n try {\n await fetchAsync(CustomerRequests.resendActivationEmail(customerId, _user.id));\n alerts.success('Activation email sent successfully.');\n } catch {\n alerts.error('Failed to send activation email.');\n }\n }\n\n async function confirmSendPasswordResetEmail() {\n try {\n setShowSpinner(true);\n await fetchAsync(CustomerRequests.sendPasswordResetEmail(customerId, user.id));\n alerts.success('Password reset email sent successfully.');\n } catch {\n alerts.error('Failed to send password reset email.');\n }\n }\n\n async function resendVerificationEmail(_user: User) {\n try {\n setShowSpinner(true);\n await fetchAsync(CustomerRequests.resendVerificationEmail(customerId, _user.id));\n alerts.success('Email verification email sent successfully.');\n } catch {\n alerts.error('Failed to send email verification email.');\n }\n }\n\n async function deleteEmail(): Promise<void> {\n AppLinkHelper.trigger({\n application: AppChannels.CRM_STUDIO,\n action: Actions.CrmStudio.DELETE_USER_EMAIL,\n args: [ customerId, user.id ],\n params: { userType }\n });\n }\n\n function checkIfAnyCustomerActive(): boolean {\n if (!user.userProfiles?.data) return false;\n const profiles = user.userProfiles?.data || [];\n return profiles.some(profile => UserHelper.getUserStatusFromValue(profile.status) === ObjectStatus.Active);\n }\n const isCustomerlessUser = user.userProfiles?.data?.length === 0;\n\n React.useEffect(() => {\n if (isLoaded) {\n setIsAnyCustomerActive(checkIfAnyCustomerActive());\n }\n }, [isLoaded]);\n\n return (\n <CrmStudioLayoutView view={CrmStudioLayoutViewPage.Users}>\n <CrmStudioUserLayout\n title='Overview'\n currentTabId='overview'\n id={props.id}\n loading={!isLoaded}\n >\n {!customerId && (\n <div className='mb-3'>\n <AlertV2 variant='warning' className='w-100'>\n This user is not associated with any customers, and therefore cannot be\n edited. In order to edit this user, please add to a customer in the customer schools tab.\n </AlertV2>\n </div>\n )}\n {(user.id && UserHelper.hasSso(user)) && (\n <div className='mb-3'>\n <AlertV2 variant='warning' className='w-100'>\n Some of this user’s account details are managed by their SSO provider.\n </AlertV2>\n </div>\n )}\n {customerId && !isAnyCustomerActive && (\n <div className='mb-3'>\n <AlertV2 variant='warning' className='w-100'>\n This user has no active customers, and therefore cannot be\n edited. In order to edit this user, please activate a customer in the customer schools tab.\n </AlertV2>\n </div>\n )}\n {isLoaded && user && (\n <div>\n <DropdownContainer\n heading='User details'\n svg={EditSvg}\n buttonClassname='null'\n onClick={(customerId) ?\n () => setShowEditModal(true) :\n undefined\n }\n disableCollapse\n >\n <UserOverviewTable\n user={user}\n onUnverifyEmail={() => deleteEmail()}\n onSendPasswordResetEmail={() => confirmSendPasswordResetEmail()}\n onVerifyEmail={() => resendVerificationEmail(user)}\n customerless={!customerId}\n />\n </DropdownContainer>\n <div className='d-flex justify-content-end mt-3 gap-2'>\n {!!hasPermissions(CuratorPermissionName.UsersSsoUpdate) && isAnyCustomerActive && (\n <PopupButtons.Toggle\n on={editSsoFields}\n onClick={() => setEditSsoFields(v => !v)}\n label='Allow ClickView Staff to edit SSO fields'\n disabled={!UserHelper.hasSso(user)}\n tooltip={!UserHelper.hasSso(user) && 'This user doesn\\'t sign in with SSO'}\n />\n )}\n {user.email &&\n user.status === ObjectStatus.Inactive &&\n !user.metadata.isEmailVerified && (\n <Button\n variant='outline-dark'\n onClick={() => resendActivationEmail(user)}\n >\n Resend activation email\n </Button>\n )}\n {isLoaded && (() => {\n const showDeactivate = user.status === ObjectStatus.Active &&\n (isCustomerlessUser || !isAnyCustomerActive);\n const deleteDisabled = !isCustomerlessUser && isAnyCustomerActive;\n const deleteDisabledTooltip = deleteDisabled ?\n 'This user has active customers, therefore this action is not allowed.' :\n undefined;\n\n if (showDeactivate) {\n return (\n <ActionButton\n className='btn btn-danger'\n appLink={{\n application: AppChannels.CRM_STUDIO,\n action: Actions.CrmStudio.TOGGLE_USER_STATUS,\n args: [ null, user.id ]\n }}\n >\n Deactivate account\n </ActionButton>\n );\n }\n\n return (\n <ActionButton\n className={`btn btn-danger${deleteDisabled ? ' pointer-events-none opacity-50' : ''}`}\n appLink={{\n application: AppChannels.CRM_STUDIO,\n action: Actions.CrmStudio.BULK_REMOVE_USERS,\n args: [customerId],\n params: { userType }\n }}\n onClick={() => setViewModel({\n allUsers: false, users: [user], totalUsers: 1, redirectToSearch: false\n })}\n disabled={deleteDisabled}\n tooltip={deleteDisabledTooltip}\n >\n Delete account\n </ActionButton>\n );\n })()}\n </div>\n </div>\n )}\n {showEditModal && isLoaded && (\n <Popup title='Edit User details' closePopup={() => setShowEditModal(false)}>\n <EditUserDetails\n user={user}\n userType={user.userType}\n yearGroups={\n user.userType === UserGroup.Learner ?\n (Array.isArray(yearGroups) ? yearGroups : []) :\n null\n }\n initialValues={getUserInitialValues(user, customerId)}\n initialErrors={UserManagerHelper.getInitialErrorsForInvalidYearGroups(user.masterYearGroup)}\n onSubmit={saveUser}\n onClickResendActivationEmail={resendActivationEmail}\n onClickSendResetEmail={confirmSendPasswordResetEmail}\n onClickSendVerificationEmail={resendVerificationEmail}\n onClickCancel={() => setShowEditModal(false)}\n currentUser={currentUser.data as CurrentUser}\n emailRequired={user.userType === UserGroup.Staff}\n showActions={false}\n passwordPolicy={passwordPolicy.data}\n showDisplayNameField={user.userType === UserGroup.Staff}\n hideAdminToggle={true}\n hideSsoToggle={true}\n hideYearLevel={true}\n canEditSsoFields={editSsoFields}\n />\n </Popup>\n )}\n </CrmStudioUserLayout>\n </CrmStudioLayoutView>\n );\n}\n"],"mappings":"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"}