@firecms/user_management 3.0.0-canary.8 → 3.0.0-canary.9

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 (38) hide show
  1. package/dist/UserManagementProvider.d.ts +4 -3
  2. package/dist/components/roles/RoleChip.d.ts +1 -1
  3. package/dist/components/roles/RolesDetailsForm.d.ts +1 -2
  4. package/dist/components/roles/RolesTable.d.ts +1 -1
  5. package/dist/components/roles/default_roles.d.ts +1 -1
  6. package/dist/components/users/UserDetailsForm.d.ts +2 -2
  7. package/dist/components/users/UsersTable.d.ts +2 -2
  8. package/dist/hooks/useUserManagement.d.ts +3 -2
  9. package/dist/index.es.js +9 -6
  10. package/dist/index.es.js.map +1 -1
  11. package/dist/index.umd.js +1 -1
  12. package/dist/index.umd.js.map +1 -1
  13. package/dist/types/index.d.ts +1 -2
  14. package/dist/types/persisted_user.d.ts +5 -0
  15. package/dist/types/user_management.d.ts +2 -4
  16. package/dist/utils/permissions.d.ts +3 -4
  17. package/package.json +6 -8
  18. package/src/UserManagementProvider.tsx +4 -3
  19. package/src/components/roles/RoleChip.tsx +1 -1
  20. package/src/components/roles/RolesDetailsForm.tsx +1 -2
  21. package/src/components/roles/RolesTable.tsx +1 -2
  22. package/src/components/roles/RolesView.tsx +1 -2
  23. package/src/components/roles/default_roles.tsx +1 -1
  24. package/src/components/users/UserDetailsForm.tsx +11 -12
  25. package/src/components/users/UsersTable.tsx +6 -6
  26. package/src/components/users/UsersView.tsx +3 -3
  27. package/src/hooks/useBuildFirestoreUserManagement.tsx +11 -8
  28. package/src/hooks/useUserManagement.tsx +3 -3
  29. package/src/types/index.ts +1 -2
  30. package/src/types/persisted_user.ts +6 -0
  31. package/src/types/user_management.tsx +2 -4
  32. package/src/useUserManagementPlugin.tsx +1 -1
  33. package/src/utils/permissions.ts +3 -4
  34. package/dist/types/firecms_user.d.ts +0 -7
  35. package/dist/types/roles.d.ts +0 -31
  36. package/src/types/firecms_user.ts +0 -8
  37. package/src/types/roles.ts +0 -41
  38. package/tailwind.config.js +0 -68
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(i,d){typeof exports=="object"&&typeof module<"u"?d(exports,require("react"),require("firebase/firestore"),require("react/jsx-runtime"),require("@firecms/ui"),require("yup"),require("@firecms/core"),require("@firecms/formex"),require("date-fns"),require("date-fns/locale")):typeof define=="function"&&define.amd?define(["exports","react","firebase/firestore","react/jsx-runtime","@firecms/ui","yup","@firecms/core","@firecms/formex","date-fns","date-fns/locale"],d):(i=typeof globalThis<"u"?globalThis:i||self,d(i.FireCMS={},i.React,i.firestore,i.jsxRuntime,i.ui,i.Yup,i.core,i.formex,i.dateFns,i.locales))})(this,function(i,d,k,e,l,ne,N,A,se,re){"use strict";function z(n){const s=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const o in n)if(o!=="default"){const c=Object.getOwnPropertyDescriptor(n,o);Object.defineProperty(s,o,c.get?c:{enumerable:!0,get:()=>n[o]})}}return s.default=n,Object.freeze(s)}const B=z(ne),ae=z(re),te=["Admin"],ie={read:!1,edit:!1,create:!1,delete:!1};function J({collection:n,user:s}){const o=s?.roles;if(o){if(n.ownerId===s?.uid)return{read:!0,create:!0,edit:!0,delete:!0};{const c={read:!1,create:!1,edit:!1,delete:!1};return o.map(r=>ce(r,n.id)).reduce(Y,c)}}else return ie}function ce(n,s){const o={read:n.isAdmin||n.defaultPermissions?.read,create:n.isAdmin||n.defaultPermissions?.create,edit:n.isAdmin||n.defaultPermissions?.edit,delete:n.isAdmin||n.defaultPermissions?.delete};return n.collectionPermissions&&n.collectionPermissions[s]?Y(n.collectionPermissions[s],o):n.defaultPermissions?Y(n.defaultPermissions,o):o}const Y=(n,s)=>({read:n.read||s.read,create:n.create||s.create,edit:n.edit||s.edit,delete:n.delete||s.delete});function de(n,s){return n?s.roles?s.roles.map(o=>n.find(c=>c.id===o.id)).filter(Boolean):[]:void 0}const H=(n,s)=>{const o=n.map(r=>r.id),c=s.map(r=>r.id);return o.length===s.length&&o.every(r=>c.includes(r))};function he(n,s){if(!s)return;const o=Ce(s),c=new Date(o.exp*1e3);localStorage.setItem(`auth_token::${n}`,JSON.stringify({token:s,expiry:c}))}function fe(n){const s=localStorage.getItem(`auth_token::${n}`);if(s){const o=JSON.parse(s);if(o.expiry=new Date(o.expiry),o.expiry>new Date)return o.token}}function ge(){for(let n=0;n<localStorage.length;n++){const s=localStorage.key(n);s?.startsWith("auth_token::")&&localStorage.removeItem(s)}}function Ce(n){if(!n)throw new Error("No JWT token");const o=n.split(".")[1].replace(/-/g,"+").replace(/_/g,"/"),c=decodeURIComponent(window.atob(o).split("").map(function(r){return"%"+("00"+r.charCodeAt(0).toString(16)).slice(-2)}).join(""));return JSON.parse(c)}function pe(n,s=10){if(!/^#([0-9A-Fa-f]{3}){1,2}$/.test(n))throw new Error("Invalid color format");let o=n.substring(1).split("");o.length===3&&(o=[o[0],o[0],o[1],o[1],o[2],o[2]]);let c=parseInt(o[0]+o[1],16),r=parseInt(o[2]+o[3],16),g=parseInt(o[4]+o[5],16);return c=Math.floor(c*(1-s/100)),r=Math.floor(r*(1-s/100)),g=Math.floor(g*(1-s/100)),"#"+(c<16?"0":"")+c.toString(16)+(r<16?"0":"")+r.toString(16)+(g<16?"0":"")+g.toString(16)}function me(n,s=10){if(!/^#([0-9A-Fa-f]{3}){1,2}$/.test(n))throw new Error("Invalid color format");let o=n.substring(1).split("");o.length===3&&(o=[o[0],o[0],o[1],o[1],o[2],o[2]]);const c=parseInt(o[0]+o[1],16),r=parseInt(o[2]+o[3],16),g=parseInt(o[4]+o[5],16),p=s/100;return`rgba(${c}, ${r}, ${g}, ${p})`}function be({firebaseApp:n,usersPath:s="__FIRECMS/config/users",rolesPath:o="__FIRECMS/config/roles",usersLimit:c,canEditRoles:r=!0,authController:g,allowDefaultRolesCreation:p,includeCollectionConfigPermissions:b}){const S=d.useRef(),[u,h]=d.useState(!0),[E,w]=d.useState(!0),[t,m]=d.useState([]),[U,y]=d.useState([]),_=U.map(v=>({...v,roles:t.filter(T=>v.roles?.includes(T.id))})),[q,f]=d.useState(),[C,D]=d.useState(),F=u||E,P=_.find(v=>v.email?.toLowerCase()===g.user?.email?.toLowerCase());d.useEffect(()=>{n&&(S.current=k.getFirestore(n))},[n]),d.useEffect(()=>{if(!n||!o)return;const v=k.getFirestore(n);return k.onSnapshot(k.collection(v,o),{next:T=>{f(void 0);try{const I=ve(T.docs);m(I)}catch(I){f(I)}h(!1)},error:T=>{f(T),h(!1)}})},[n,o]),d.useEffect(()=>{if(!n||!s)return;const v=k.getFirestore(n);return k.onSnapshot(k.collection(v,s),{next:T=>{D(void 0);try{const I=ue(T.docs);y(I)}catch(I){D(I)}w(!1)},error:T=>{D(T),w(!1)}})},[n,s]);const a=d.useCallback(async v=>{const T=S.current;if(!T||!s)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Persisting user",v);const I=v.roles.map(Ne=>Ne.id),{uid:$,...W}=v;return k.setDoc(k.doc(T,s,$),{...W,roles:I},{merge:!0}).then(()=>v)},[s]),x=d.useCallback(v=>{const T=S.current;if(!T||!o)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Persisting role",v);const{id:I,...$}=v,W=k.doc(T,o,I);return k.setDoc(W,$,{merge:!0})},[o]),L=d.useCallback(async v=>{const T=S.current;if(!T||!s)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Deleting",v);const{uid:I}=v;return k.deleteDoc(k.doc(T,s,I))},[s]),M=d.useCallback(v=>{const T=S.current;if(!T||!o)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Deleting",v);const{id:I}=v,$=k.doc(T,o,I);return k.deleteDoc($)},[o]),De=d.useCallback(({collection:v})=>J({collection:v,user:P??null}),[P?.uid]);return{loading:F,loggedInUser:P,roles:t,users:_,saveUser:a,saveRole:x,deleteUser:L,deleteRole:M,usersLimit:c,canEditRoles:r===void 0?!0:r,allowDefaultRolesCreation:p===void 0?!0:p,includeCollectionConfigPermissions:!!b,collectionPermissions:De}}const ue=n=>n.map(s=>{const o=s.data();return{uid:s.id,...o,created_on:o?.created_on?.toDate(),updated_on:o?.updated_on?.toDate()}}),ve=n=>n.map(s=>({id:s.id,...s.data()})),j=d.createContext({});function G({children:n,userManagement:s}){return e.jsx(j.Provider,{value:s,children:n})}const V=()=>d.useContext(j);function O({role:n}){let s;return n.isAdmin?s="blueDarker":n.id==="editor"?s="yellowLight":n.id==="viewer"?s="grayLight":s=l.getColorSchemeForSeed(n.id),e.jsx(l.Chip,{colorScheme:s,children:n.name},n.id)}const K=B.object().shape({id:B.string().required("Required"),name:B.string().required("Required")});function Q({open:n,role:s,editable:o,handleClose:c,collections:r}){const{saveRole:g}=V(),p=!s,[b,S]=d.useState(),u=d.useCallback(a=>(S(void 0),g(a)),[g]),h=A.useCreateFormex({initialValues:s??{name:""},onSubmit:(a,x)=>u(a).then(()=>{x.resetForm({values:a}),c()}).catch(L=>S(L)),validation:a=>K.validate(a,{abortEarly:!1}).then(()=>({})).catch(x=>{const L={};return x.inner.forEach(M=>{L[M.path]=M.message}),L})}),{isSubmitting:E,touched:w,values:t,errors:m,handleChange:U,setFieldValue:y,dirty:_,setFieldTouched:q}=h,f=t.isAdmin??!1,C=t.defaultPermissions?.create??!1,D=t.defaultPermissions?.read??!1,F=t.defaultPermissions?.edit??!1,P=t.defaultPermissions?.delete??!1;return d.useEffect(()=>{!A.getIn(w,"id")&&t.name&&y("id",N.toSnakeCase(t.name))},[w,t.name]),e.jsx(l.Dialog,{open:n,maxWidth:"4xl",children:e.jsx(A.Formex,{value:h,children:e.jsxs("form",{noValidate:!0,autoComplete:"off",onSubmit:h.handleSubmit,style:{display:"flex",flexDirection:"column",position:"relative",height:"100%"},children:[e.jsxs(l.DialogContent,{className:"flex-grow",children:[e.jsx("div",{className:"flex flex-row pt-12 pb-8",children:e.jsx(l.Typography,{variant:"h4",className:"flex-grow",children:"Role"})}),e.jsxs("div",{className:"grid grid-cols-12 gap-8",children:[e.jsxs("div",{className:"col-span-12 md:col-span-8",children:[e.jsx(l.TextField,{name:"name",required:!0,error:w.name&&!!m.name,value:t.name,disabled:f||!o,onChange:U,"aria-describedby":"name-helper-text",label:"Name"}),e.jsx(N.FieldCaption,{children:w.name&&m.name?m.name:"Name of this role"})]}),e.jsxs("div",{className:"col-span-12 md:col-span-4",children:[e.jsx(l.TextField,{name:"id",required:!0,error:w.id&&!!m.id,value:t.id,disabled:!p||!o,onChange:a=>{U(a),q("id",!0)},"aria-describedby":"id-helper-text",label:"ID"}),e.jsx(N.FieldCaption,{children:w.id&&m.id?m.id:"ID of this role"})]}),e.jsxs("div",{className:"col-span-12",children:[e.jsx(l.Paper,{className:"bg-inherit",children:e.jsxs(l.Table,{children:[e.jsxs(l.TableHeader,{children:[e.jsx(l.TableCell,{}),e.jsx(l.TableCell,{align:"center",children:"Create entities"}),e.jsx(l.TableCell,{align:"center",children:"Read entities"}),e.jsx(l.TableCell,{align:"center",children:"Update entities"}),e.jsx(l.TableCell,{align:"center",children:"Delete entities"})]}),e.jsxs(l.TableBody,{children:[e.jsxs(l.TableRow,{children:[e.jsx(l.TableCell,{scope:"row",children:e.jsx("strong",{children:"All collections"})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Tooltip,{title:"Create entities in collections",children:e.jsx(l.Checkbox,{disabled:f||!o,checked:(f||C)??!1,onCheckedChange:a=>y("defaultPermissions.create",a)})})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Tooltip,{title:"Access all data in every collection",children:e.jsx(l.Checkbox,{disabled:f||!o,checked:(f||D)??!1,onCheckedChange:a=>y("defaultPermissions.read",a)})})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Tooltip,{title:"Update data in any collection",children:e.jsx(l.Checkbox,{disabled:f||!o,checked:(f||F)??!1,onCheckedChange:a=>y("defaultPermissions.edit",a)})})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Tooltip,{title:"Delete data in any collection",children:e.jsx(l.Checkbox,{disabled:f||!o,checked:(f||P)??!1,onCheckedChange:a=>y("defaultPermissions.delete",a)})})})]}),r&&r.map(a=>e.jsxs(l.TableRow,{children:[e.jsx(l.TableCell,{scope:"row",children:a.name}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:f||C||!o,checked:(f||C||A.getIn(t,`collectionPermissions.${a.path}.create`))??!1,onCheckedChange:x=>y(`collectionPermissions.${a.path}.create`,x)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:f||D||!o,checked:(f||D||A.getIn(t,`collectionPermissions.${a.path}.read`))??!1,onCheckedChange:x=>y(`collectionPermissions.${a.path}.read`,x)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:f||F||!o,checked:(f||F||A.getIn(t,`collectionPermissions.${a.path}.edit`))??!1,onCheckedChange:x=>y(`collectionPermissions.${a.path}.edit`,x)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:f||P||!o,checked:(f||P||A.getIn(t,`collectionPermissions.${a.path}.delete`))??!1,onCheckedChange:x=>y(`collectionPermissions.${a.path}.delete`,x)})})]},a.name))]})]})}),e.jsx(N.FieldCaption,{children:"You can customise the permissions that the users related to this role can perform in the entities of each collection"})]}),e.jsxs("div",{className:"col-span-12 md:col-span-4",children:[e.jsxs(l.Select,{error:w.config&&!!m.config,id:"createCollections",name:"createCollections",label:"Create collections",position:"item-aligned",disabled:f||!o,onChange:a=>y("config.createCollections",a.target.value==="true"),value:f||t.config?.createCollections?"true":"false",renderValue:a=>a==="true"?"Yes":"No",children:[e.jsx(l.SelectItem,{value:"true",children:" Yes "}),e.jsx(l.SelectItem,{value:"false",children:" No "})]}),e.jsx(N.FieldCaption,{children:w.config&&m.config?m.config:"Can the user create collections"})]}),e.jsxs("div",{className:"col-span-12 md:col-span-4",children:[e.jsxs(l.Select,{error:w.config&&!!m.config,id:"editCollections",name:"editCollections",label:"Edit collections",disabled:f||!o,position:"item-aligned",onChange:a=>y("config.editCollections",a.target.value==="own"?"own":a.target.value==="true"),value:f?"true":t.config?.editCollections==="own"?"own":t.config?.editCollections?"true":"false",renderValue:a=>a==="own"?"Own":a==="true"?"Yes":"No",children:[e.jsx(l.SelectItem,{value:"true",children:" Yes "}),e.jsx(l.SelectItem,{value:"false",children:" No "}),e.jsx(l.SelectItem,{value:"own",children:" Only his/her own "})]}),e.jsx(N.FieldCaption,{children:w.config&&m.config?m.config:"Can the user edit collections"})]}),e.jsxs("div",{className:"col-span-12 md:col-span-4",children:[e.jsxs(l.Select,{error:w.config&&!!m.config,id:"deleteCollections",name:"deleteCollections",label:"Delete collections",disabled:f||!o,position:"item-aligned",onChange:a=>y("config.deleteCollections",a.target.value==="own"?"own":a.target.value==="true"),value:f?"true":t.config?.deleteCollections==="own"?"own":t.config?.deleteCollections?"true":"false",renderValue:a=>a==="own"?"Own":a==="true"?"Yes":"No",children:[e.jsx(l.SelectItem,{value:"true",children:" Yes "}),e.jsx(l.SelectItem,{value:"false",children:" No "}),e.jsx(l.SelectItem,{value:"own",children:" Only his/her own "})]}),e.jsx(N.FieldCaption,{children:w.config&&m.config?m.config:"Can the user delete collections"})]})]})]}),e.jsxs(l.DialogActions,{position:"sticky",children:[b&&e.jsx(l.Typography,{className:"text-red-500",children:"There was an error saving this role"}),e.jsx(l.Button,{variant:"text",onClick:()=>{c()},children:"Cancel"}),e.jsx(l.LoadingButton,{variant:"filled",color:"primary",type:"submit",disabled:!_,loading:E,startIcon:e.jsx(l.DoneIcon,{}),children:p?"Create role":"Update"})]})]})})})}const we=[{id:"admin",name:"Admin",isAdmin:!0},{id:"editor",name:"Editor",isAdmin:!1,defaultPermissions:{read:!0,create:!0,edit:!0,delete:!0},config:{createCollections:!0,editCollections:"own",deleteCollections:"own"}},{id:"viewer",name:"Viewer",isAdmin:!1,defaultPermissions:{read:!0,create:!1,edit:!1,delete:!1}}];function X({onRoleClicked:n,editable:s}){const{roles:o,saveRole:c,deleteRole:r,allowDefaultRolesCreation:g}=V(),[p,b]=d.useState(void 0),[S,u]=d.useState(!1);return e.jsxs("div",{className:"w-full overflow-auto",children:[e.jsxs(l.Table,{children:[e.jsxs(l.TableHeader,{children:[e.jsx(l.TableCell,{header:!0,className:"w-16"}),e.jsx(l.TableCell,{header:!0,children:"Role"}),e.jsx(l.TableCell,{header:!0,className:"items-center",children:"Is Admin"}),e.jsx(l.TableCell,{header:!0,children:"Default permissions"})]}),e.jsxs(l.TableBody,{children:[o&&o.map(h=>{const E=h.isAdmin||h.defaultPermissions?.create,w=h.isAdmin||h.defaultPermissions?.read,t=h.isAdmin||h.defaultPermissions?.edit,m=h.isAdmin||h.defaultPermissions?.delete;return e.jsxs(l.TableRow,{onClick:()=>{n(h)},children:[e.jsx(l.TableCell,{style:{width:"64px"},children:!h.isAdmin&&e.jsx(l.Tooltip,{title:"Delete this role",children:e.jsx(l.IconButton,{size:"small",disabled:!s,onClick:U=>(U.stopPropagation(),b(h)),children:e.jsx(l.DeleteIcon,{})})})}),e.jsx(l.TableCell,{children:e.jsx(O,{role:h})}),e.jsx(l.TableCell,{className:"items-center",children:e.jsx(l.Checkbox,{checked:h.isAdmin??!1})}),e.jsx(l.TableCell,{children:e.jsxs("ul",{children:[E&&e.jsx("li",{children:"Create"}),w&&e.jsx("li",{children:"Read"}),t&&e.jsx("li",{children:"Update"}),m&&e.jsx("li",{children:"Delete"})]})})]},h.name)}),(!o||o.length===0)&&e.jsx(l.TableRow,{children:e.jsx(l.TableCell,{colspan:4,children:e.jsxs(l.CenteredView,{className:"flex flex-col gap-4 my-8 items-center",children:[e.jsx(l.Typography,{variant:"label",children:"You don't have any roles yet."}),g&&e.jsx(l.Button,{variant:"outlined",onClick:()=>{we.forEach(h=>{c(h)})},children:"Create default roles"})]})})})]})]}),e.jsx(N.DeleteConfirmationDialog,{open:!!p,loading:S,onAccept:()=>{p&&(u(!0),r(p).then(()=>{b(void 0)}).finally(()=>{u(!1)}))},onCancel:()=>{b(void 0)},title:e.jsx(e.Fragment,{children:"Delete?"}),body:e.jsx(e.Fragment,{children:"Are you sure you want to delete this role?"})})]})}const Z=d.memo(function({children:s}){const{collections:o}=N.useNavigationController(),[c,r]=d.useState(!1),[g,p]=d.useState(),{canEditRoles:b}=V(),S=d.useCallback(h=>{r(!0),p(h)},[]),u=()=>{p(void 0),r(!1)};return e.jsxs(l.Container,{className:"w-full flex flex-col py-4 gap-4",maxWidth:"6xl",children:[s,e.jsxs("div",{className:"flex items-center mt-12",children:[e.jsx(l.Typography,{gutterBottom:!0,variant:"h4",className:"flex-grow",component:"h4",children:"Roles"}),e.jsx(l.Tooltip,{title:b?void 0:"Update plans to customise roles",children:e.jsx(l.Button,{size:"large",disabled:!b,startIcon:e.jsx(l.AddIcon,{}),onClick:()=>r(!0),children:"Add role"})})]}),e.jsx(X,{onRoleClicked:S,editable:!!b}),e.jsx(Q,{open:c,role:g,editable:b,collections:o,handleClose:u},g?.id??"new")]})}),R=B.object().shape({displayName:B.string().required("Required"),email:B.string().email().required("Required"),roles:B.array().min(1)});function ye(n,s,o,c,r){const g=o.filter(u=>u.roles.map(h=>h.id).includes("admin")),p=n.roles.map(u=>u.id).includes("admin");if((!r||!H(r.roles,s.roles))&&!p)throw new Error("Only admins can change roles");if(r&&r.roles.map(u=>u.id).includes("admin")&&!s.roles.map(u=>u.id).includes("admin")&&g.length===1)throw new Error("There must be at least one admin");return!0}function ee({open:n,user:s,handleClose:o}){const c=N.useSnackbarController(),{loggedInUser:r,saveUser:g,users:p,roles:b}=V(),S=!s,u=d.useCallback(C=>{if(!r)throw new Error("Logged user not found");try{return ye(r,C,p,b,s),g(C)}catch(D){return Promise.reject(D)}},[b,g,s,p,r]),h=A.useCreateFormex({initialValues:s??{displayName:"",email:"",roles:b.filter(C=>C.id==="editor")},validation:C=>R.validate(C,{abortEarly:!1}).then(()=>({})).catch(D=>D.inner.reduce((F,P)=>(F[P.path]=P.message,F),{})),onSubmit:(C,D)=>u(C).then(()=>{o(),D.resetForm({values:C})}).catch(F=>{c.open({type:"error",message:F.message})})}),{isSubmitting:E,touched:w,handleChange:t,values:m,errors:U,setFieldValue:y,dirty:_,handleSubmit:q,submitCount:f}=h;return e.jsx(l.Dialog,{open:n,onOpenChange:C=>C?void 0:o(),maxWidth:"4xl",children:e.jsx(A.Formex,{value:h,children:e.jsxs("form",{onSubmit:q,autoComplete:"off",noValidate:!0,style:{display:"flex",flexDirection:"column",position:"relative",height:"100%"},children:[e.jsxs(l.DialogContent,{className:"h-full flex-grow",children:[e.jsx("div",{className:"flex flex-row pt-4 pb-4",children:e.jsx(l.Typography,{variant:"h4",className:"flex-grow",children:"User"})}),e.jsxs("div",{className:"grid grid-cols-12 gap-8",children:[e.jsxs("div",{className:"col-span-12",children:[e.jsx(l.TextField,{name:"displayName",required:!0,error:f>0&&!!U.displayName,value:m.displayName??"",onChange:t,"aria-describedby":"name-helper-text",label:"Name"}),e.jsx(N.FieldCaption,{children:f>0&&U.displayName?U.displayName:"Name of this user"})]}),e.jsxs("div",{className:"col-span-12",children:[e.jsx(l.TextField,{required:!0,error:f>0&&!!U.email,name:"email",value:m.email??"",onChange:t,"aria-describedby":"email-helper-text",label:"Email"}),e.jsx(N.FieldCaption,{children:f>0&&U.email?U.email:"Email of this user"})]}),e.jsx("div",{className:"col-span-12",children:e.jsx(l.MultiSelect,{label:"Roles",value:m.roles.map(C=>C.id)??[],onMultiValueChange:C=>y("roles",C.map(D=>b.find(F=>F.id===D))),renderValue:C=>{const D=b.find(F=>F.id===C);return D?e.jsx("div",{className:"flex flex-wrap space-x-2 space-y-2",children:e.jsx(O,{role:D},D?.id)}):null},children:b.map(C=>e.jsx(l.MultiSelectItem,{value:C.id,children:e.jsx(O,{role:C},C?.id)},C.id))})})]})]}),e.jsxs(l.DialogActions,{children:[e.jsx(l.Button,{variant:"text",onClick:()=>{o()},children:"Cancel"}),e.jsx(l.LoadingButton,{variant:"filled",color:"primary",type:"submit",disabled:!_,loading:E,startIcon:e.jsx(l.DoneIcon,{}),children:S?"Create user":"Update"})]})]})})})}function le({onUserClicked:n}){const{users:s,saveUser:o,deleteUser:c}=V(),r=N.useAuthController(),g=N.useSnackbarController(),p=N.useCustomizationController(),b=p?.locale?ae[p?.locale]:void 0,S=p?.dateTimeFormat??N.defaultDateFormat,[u,h]=d.useState(void 0),[E,w]=d.useState(!1);return e.jsxs("div",{className:"overflow-auto",children:[e.jsxs(l.Table,{children:[e.jsxs(l.TableHeader,{children:[e.jsx(l.TableCell,{className:"truncate w-16"}),e.jsx(l.TableCell,{children:"ID"}),e.jsx(l.TableCell,{children:"Email"}),e.jsx(l.TableCell,{children:"Name"}),e.jsx(l.TableCell,{children:"Roles"}),e.jsx(l.TableCell,{children:"Created on"})]}),e.jsxs(l.TableBody,{children:[s&&s.map(t=>{const m=t.roles,U=t.created_on?se.format(t.created_on,S,{locale:b}):"";return e.jsxs(l.TableRow,{onClick:()=>{n(t)},children:[e.jsx(l.TableCell,{className:"w-10",children:e.jsx(l.Tooltip,{title:"Delete this user",children:e.jsx(l.IconButton,{size:"small",onClick:y=>(y.stopPropagation(),h(t)),children:e.jsx(l.DeleteIcon,{})})})}),e.jsx(l.TableCell,{children:t.uid}),e.jsx(l.TableCell,{children:t.email}),e.jsx(l.TableCell,{className:"font-medium align-left",children:t.displayName}),e.jsx(l.TableCell,{className:"align-left",children:m?e.jsx("div",{className:"flex flex-wrap gap-2",children:m.map(y=>e.jsx(O,{role:y},y?.id))}):null}),e.jsx(l.TableCell,{children:U})]},"row_"+t.uid)}),(!s||s.length===0)&&e.jsx(l.TableRow,{children:e.jsx(l.TableCell,{colspan:6,children:e.jsxs(l.CenteredView,{className:"flex flex-col gap-4 my-8 items-center",children:[e.jsx(l.Typography,{variant:"label",children:"There are no users yet"}),e.jsx(l.Button,{variant:"outlined",onClick:()=>{if(!r.user?.uid)throw Error("UsersTable, authController misconfiguration");o({uid:r.user?.uid,email:r.user?.email,displayName:r.user?.displayName,photoURL:r.user?.photoURL,providerId:r.user?.providerId,isAnonymous:r.user?.isAnonymous,roles:[{id:"admin",name:"Admin"}],created_on:new Date}).then(()=>{g.open({type:"success",message:"User added successfully"})}).catch(t=>{g.open({type:"error",message:"Error adding user: "+t.message})})},children:"Add the logged user as an admin"})]})})})]})]}),e.jsx(N.DeleteConfirmationDialog,{open:!!u,loading:E,onAccept:()=>{u&&(w(!0),c(u).then(()=>{h(void 0)}).catch(t=>{g.open({type:"error",message:"Error deleting user: "+t.message})}).finally(()=>{w(!1)}))},onCancel:()=>{h(void 0)},title:e.jsx(e.Fragment,{children:"Delete?"}),body:e.jsx(e.Fragment,{children:"Are you sure you want to delete this user?"})})]})}const oe=function({children:s}){const[o,c]=d.useState(),[r,g]=d.useState(),{users:p,usersLimit:b}=V(),S=b!==void 0&&p&&p.length>=b,u=d.useCallback(E=>{g(E),c(!0)},[]),h=d.useCallback(()=>{c(!1),g(void 0)},[]);return e.jsxs(l.Container,{className:"w-full flex flex-col py-4 gap-4",maxWidth:"6xl",children:[s,e.jsxs("div",{className:"flex items-center mt-12",children:[e.jsx(l.Typography,{gutterBottom:!0,variant:"h4",className:"flex-grow",component:"h4",children:"Users"}),e.jsx(l.Button,{size:"large",disabled:S,startIcon:e.jsx(l.AddIcon,{}),onClick:()=>c(!0),children:"Add user"})]}),e.jsx(le,{onUserClicked:u}),e.jsx(ee,{open:o??!1,user:r,handleClose:h},r?.uid??"new")]})};function Te({userManagement:n}){return{name:"User management plugin",loading:n.loading,provider:{Component:G,props:{userManagement:n}}}}const Se=[{path:"users",name:"CMS Users",group:"Admin",icon:"face",view:e.jsx(oe,{})},{path:"roles",name:"Roles",group:"Admin",icon:"gpp_good",view:e.jsx(Z,{})}];i.RESERVED_GROUPS=te,i.RoleChip=O,i.RoleYupSchema=K,i.RolesDetailsForm=Q,i.RolesTable=X,i.RolesView=Z,i.UserDetailsForm=ee,i.UserManagementContext=j,i.UserManagementProvider=G,i.UserYupSchema=R,i.UsersTable=le,i.UsersView=oe,i.areRolesEqual=H,i.cacheDelegatedLoginToken=he,i.clearDelegatedLoginTokensCache=ge,i.darkenColor=pe,i.getDelegatedLoginTokenFromCache=fe,i.getUserRoles=de,i.hexToRgbaWithOpacity=me,i.resolveUserRolePermissions=J,i.useBuildFirestoreUserManagement=be,i.useUserManagement=V,i.useUserManagementPlugin=Te,i.userManagementAdminViews=Se,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})});
1
+ (function(i,d){typeof exports=="object"&&typeof module<"u"?d(exports,require("react"),require("firebase/firestore"),require("react/jsx-runtime"),require("@firecms/ui"),require("yup"),require("@firecms/core"),require("@firecms/formex"),require("date-fns"),require("date-fns/locale")):typeof define=="function"&&define.amd?define(["exports","react","firebase/firestore","react/jsx-runtime","@firecms/ui","yup","@firecms/core","@firecms/formex","date-fns","date-fns/locale"],d):(i=typeof globalThis<"u"?globalThis:i||self,d(i.FireCMS={},i.React,i.firestore,i.jsxRuntime,i.ui,i.Yup,i.core,i.formex,i.dateFns,i.locales))})(this,function(i,d,k,e,l,ne,N,A,se,re){"use strict";function z(n){const s=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const o in n)if(o!=="default"){const c=Object.getOwnPropertyDescriptor(n,o);Object.defineProperty(s,o,c.get?c:{enumerable:!0,get:()=>n[o]})}}return s.default=n,Object.freeze(s)}const B=z(ne),ae=z(re),te=["Admin"],ie={read:!1,edit:!1,create:!1,delete:!1};function J({collection:n,user:s}){const o=s?.roles;if(o){if(n.ownerId===s?.uid)return{read:!0,create:!0,edit:!0,delete:!0};{const c={read:!1,create:!1,edit:!1,delete:!1};return o.map(r=>ce(r,n.id)).reduce(Y,c)}}else return ie}function ce(n,s){const o={read:n.isAdmin||n.defaultPermissions?.read,create:n.isAdmin||n.defaultPermissions?.create,edit:n.isAdmin||n.defaultPermissions?.edit,delete:n.isAdmin||n.defaultPermissions?.delete};return n.collectionPermissions&&n.collectionPermissions[s]?Y(n.collectionPermissions[s],o):n.defaultPermissions?Y(n.defaultPermissions,o):o}const Y=(n,s)=>({read:n.read||s.read,create:n.create||s.create,edit:n.edit||s.edit,delete:n.delete||s.delete});function de(n,s){return n?s.roles?s.roles.map(o=>n.find(c=>c.id===o.id)).filter(Boolean):[]:void 0}const H=(n,s)=>{const o=n.map(r=>r.id),c=s.map(r=>r.id);return o.length===s.length&&o.every(r=>c.includes(r))};function he(n,s){if(!s)return;const o=Ce(s),c=new Date(o.exp*1e3);localStorage.setItem(`auth_token::${n}`,JSON.stringify({token:s,expiry:c}))}function fe(n){const s=localStorage.getItem(`auth_token::${n}`);if(s){const o=JSON.parse(s);if(o.expiry=new Date(o.expiry),o.expiry>new Date)return o.token}}function ge(){for(let n=0;n<localStorage.length;n++){const s=localStorage.key(n);s?.startsWith("auth_token::")&&localStorage.removeItem(s)}}function Ce(n){if(!n)throw new Error("No JWT token");const o=n.split(".")[1].replace(/-/g,"+").replace(/_/g,"/"),c=decodeURIComponent(window.atob(o).split("").map(function(r){return"%"+("00"+r.charCodeAt(0).toString(16)).slice(-2)}).join(""));return JSON.parse(c)}function pe(n,s=10){if(!/^#([0-9A-Fa-f]{3}){1,2}$/.test(n))throw new Error("Invalid color format");let o=n.substring(1).split("");o.length===3&&(o=[o[0],o[0],o[1],o[1],o[2],o[2]]);let c=parseInt(o[0]+o[1],16),r=parseInt(o[2]+o[3],16),g=parseInt(o[4]+o[5],16);return c=Math.floor(c*(1-s/100)),r=Math.floor(r*(1-s/100)),g=Math.floor(g*(1-s/100)),"#"+(c<16?"0":"")+c.toString(16)+(r<16?"0":"")+r.toString(16)+(g<16?"0":"")+g.toString(16)}function me(n,s=10){if(!/^#([0-9A-Fa-f]{3}){1,2}$/.test(n))throw new Error("Invalid color format");let o=n.substring(1).split("");o.length===3&&(o=[o[0],o[0],o[1],o[1],o[2],o[2]]);const c=parseInt(o[0]+o[1],16),r=parseInt(o[2]+o[3],16),g=parseInt(o[4]+o[5],16),p=s/100;return`rgba(${c}, ${r}, ${g}, ${p})`}function be({firebaseApp:n,usersPath:s="__FIRECMS/config/users",rolesPath:o="__FIRECMS/config/roles",usersLimit:c,canEditRoles:r=!0,authController:g,allowDefaultRolesCreation:p,includeCollectionConfigPermissions:b}){const S=d.useRef(),[u,h]=d.useState(!0),[E,w]=d.useState(!0),[t,m]=d.useState([]),[U,y]=d.useState([]),_=U.map(v=>({...v,roles:t.filter(T=>v.roles?.includes(T.id))})),[q,f]=d.useState(),[C,D]=d.useState(),F=u||E,P=_.find(v=>v.email?.toLowerCase()===g.user?.email?.toLowerCase());d.useEffect(()=>{n&&(S.current=k.getFirestore(n))},[n]),d.useEffect(()=>{if(!n||!o)return;const v=k.getFirestore(n);return k.onSnapshot(k.collection(v,o),{next:T=>{f(void 0);try{const I=ve(T.docs);m(I)}catch(I){f(I)}h(!1)},error:T=>{f(T),h(!1)}})},[n,o]),d.useEffect(()=>{if(!n||!s)return;const v=k.getFirestore(n);return k.onSnapshot(k.collection(v,s),{next:T=>{D(void 0);try{const I=ue(T.docs);y(I)}catch(I){D(I)}w(!1)},error:T=>{D(T),w(!1)}})},[n,s]);const a=d.useCallback(async v=>{const T=S.current;if(!T||!s)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Persisting user",v);const I=v.roles?.map(Ne=>Ne.id),{uid:$,...W}=v;return k.setDoc(k.doc(T,s,$),{...W,roles:I},{merge:!0}).then(()=>v)},[s]),x=d.useCallback(v=>{const T=S.current;if(!T||!o)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Persisting role",v);const{id:I,...$}=v,W=k.doc(T,o,I);return k.setDoc(W,$,{merge:!0})},[o]),L=d.useCallback(async v=>{const T=S.current;if(!T||!s)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Deleting",v);const{uid:I}=v;return k.deleteDoc(k.doc(T,s,I))},[s]),M=d.useCallback(v=>{const T=S.current;if(!T||!o)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Deleting",v);const{id:I}=v,$=k.doc(T,o,I);return k.deleteDoc($)},[o]),De=d.useCallback(({collection:v})=>J({collection:v,user:P??null}),[P?.uid]);return{loading:F,loggedInUser:P,roles:t,users:_,saveUser:a,saveRole:x,deleteUser:L,deleteRole:M,usersLimit:c,canEditRoles:r===void 0?!0:r,allowDefaultRolesCreation:p===void 0?!0:p,includeCollectionConfigPermissions:!!b,collectionPermissions:De}}const ue=n=>n.map(s=>{const o=s.data();return{uid:s.id,...o,created_on:o?.created_on?.toDate(),updated_on:o?.updated_on?.toDate()}}),ve=n=>n.map(s=>({id:s.id,...s.data()})),j=d.createContext({});function G({children:n,userManagement:s}){return e.jsx(j.Provider,{value:s,children:n})}const V=()=>d.useContext(j);function O({role:n}){let s;return n.isAdmin?s="blueDarker":n.id==="editor"?s="yellowLight":n.id==="viewer"?s="grayLight":s=l.getColorSchemeForSeed(n.id),e.jsx(l.Chip,{colorScheme:s,children:n.name},n.id)}const K=B.object().shape({id:B.string().required("Required"),name:B.string().required("Required")});function Q({open:n,role:s,editable:o,handleClose:c,collections:r}){const{saveRole:g}=V(),p=!s,[b,S]=d.useState(),u=d.useCallback(a=>(S(void 0),g(a)),[g]),h=A.useCreateFormex({initialValues:s??{name:""},onSubmit:(a,x)=>u(a).then(()=>{x.resetForm({values:a}),c()}).catch(L=>S(L)),validation:a=>K.validate(a,{abortEarly:!1}).then(()=>({})).catch(x=>{const L={};return x.inner.forEach(M=>{L[M.path]=M.message}),L})}),{isSubmitting:E,touched:w,values:t,errors:m,handleChange:U,setFieldValue:y,dirty:_,setFieldTouched:q}=h,f=t.isAdmin??!1,C=t.defaultPermissions?.create??!1,D=t.defaultPermissions?.read??!1,F=t.defaultPermissions?.edit??!1,P=t.defaultPermissions?.delete??!1;return d.useEffect(()=>{!A.getIn(w,"id")&&t.name&&y("id",N.toSnakeCase(t.name))},[w,t.name]),e.jsx(l.Dialog,{open:n,maxWidth:"4xl",children:e.jsx(A.Formex,{value:h,children:e.jsxs("form",{noValidate:!0,autoComplete:"off",onSubmit:h.handleSubmit,style:{display:"flex",flexDirection:"column",position:"relative",height:"100%"},children:[e.jsxs(l.DialogContent,{className:"flex-grow",children:[e.jsx("div",{className:"flex flex-row pt-12 pb-8",children:e.jsx(l.Typography,{variant:"h4",className:"flex-grow",children:"Role"})}),e.jsxs("div",{className:"grid grid-cols-12 gap-8",children:[e.jsxs("div",{className:"col-span-12 md:col-span-8",children:[e.jsx(l.TextField,{name:"name",required:!0,error:w.name&&!!m.name,value:t.name,disabled:f||!o,onChange:U,"aria-describedby":"name-helper-text",label:"Name"}),e.jsx(N.FieldCaption,{children:w.name&&m.name?m.name:"Name of this role"})]}),e.jsxs("div",{className:"col-span-12 md:col-span-4",children:[e.jsx(l.TextField,{name:"id",required:!0,error:w.id&&!!m.id,value:t.id,disabled:!p||!o,onChange:a=>{U(a),q("id",!0)},"aria-describedby":"id-helper-text",label:"ID"}),e.jsx(N.FieldCaption,{children:w.id&&m.id?m.id:"ID of this role"})]}),e.jsxs("div",{className:"col-span-12",children:[e.jsx(l.Paper,{className:"bg-inherit",children:e.jsxs(l.Table,{children:[e.jsxs(l.TableHeader,{children:[e.jsx(l.TableCell,{}),e.jsx(l.TableCell,{align:"center",children:"Create entities"}),e.jsx(l.TableCell,{align:"center",children:"Read entities"}),e.jsx(l.TableCell,{align:"center",children:"Update entities"}),e.jsx(l.TableCell,{align:"center",children:"Delete entities"})]}),e.jsxs(l.TableBody,{children:[e.jsxs(l.TableRow,{children:[e.jsx(l.TableCell,{scope:"row",children:e.jsx("strong",{children:"All collections"})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Tooltip,{title:"Create entities in collections",children:e.jsx(l.Checkbox,{disabled:f||!o,checked:(f||C)??!1,onCheckedChange:a=>y("defaultPermissions.create",a)})})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Tooltip,{title:"Access all data in every collection",children:e.jsx(l.Checkbox,{disabled:f||!o,checked:(f||D)??!1,onCheckedChange:a=>y("defaultPermissions.read",a)})})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Tooltip,{title:"Update data in any collection",children:e.jsx(l.Checkbox,{disabled:f||!o,checked:(f||F)??!1,onCheckedChange:a=>y("defaultPermissions.edit",a)})})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Tooltip,{title:"Delete data in any collection",children:e.jsx(l.Checkbox,{disabled:f||!o,checked:(f||P)??!1,onCheckedChange:a=>y("defaultPermissions.delete",a)})})})]}),r&&r.map(a=>e.jsxs(l.TableRow,{children:[e.jsx(l.TableCell,{scope:"row",children:a.name}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:f||C||!o,checked:(f||C||A.getIn(t,`collectionPermissions.${a.path}.create`))??!1,onCheckedChange:x=>y(`collectionPermissions.${a.path}.create`,x)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:f||D||!o,checked:(f||D||A.getIn(t,`collectionPermissions.${a.path}.read`))??!1,onCheckedChange:x=>y(`collectionPermissions.${a.path}.read`,x)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:f||F||!o,checked:(f||F||A.getIn(t,`collectionPermissions.${a.path}.edit`))??!1,onCheckedChange:x=>y(`collectionPermissions.${a.path}.edit`,x)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:f||P||!o,checked:(f||P||A.getIn(t,`collectionPermissions.${a.path}.delete`))??!1,onCheckedChange:x=>y(`collectionPermissions.${a.path}.delete`,x)})})]},a.name))]})]})}),e.jsx(N.FieldCaption,{children:"You can customise the permissions that the users related to this role can perform in the entities of each collection"})]}),e.jsxs("div",{className:"col-span-12 md:col-span-4",children:[e.jsxs(l.Select,{error:w.config&&!!m.config,id:"createCollections",name:"createCollections",label:"Create collections",position:"item-aligned",disabled:f||!o,onChange:a=>y("config.createCollections",a.target.value==="true"),value:f||t.config?.createCollections?"true":"false",renderValue:a=>a==="true"?"Yes":"No",children:[e.jsx(l.SelectItem,{value:"true",children:" Yes "}),e.jsx(l.SelectItem,{value:"false",children:" No "})]}),e.jsx(N.FieldCaption,{children:w.config&&m.config?m.config:"Can the user create collections"})]}),e.jsxs("div",{className:"col-span-12 md:col-span-4",children:[e.jsxs(l.Select,{error:w.config&&!!m.config,id:"editCollections",name:"editCollections",label:"Edit collections",disabled:f||!o,position:"item-aligned",onChange:a=>y("config.editCollections",a.target.value==="own"?"own":a.target.value==="true"),value:f?"true":t.config?.editCollections==="own"?"own":t.config?.editCollections?"true":"false",renderValue:a=>a==="own"?"Own":a==="true"?"Yes":"No",children:[e.jsx(l.SelectItem,{value:"true",children:" Yes "}),e.jsx(l.SelectItem,{value:"false",children:" No "}),e.jsx(l.SelectItem,{value:"own",children:" Only his/her own "})]}),e.jsx(N.FieldCaption,{children:w.config&&m.config?m.config:"Can the user edit collections"})]}),e.jsxs("div",{className:"col-span-12 md:col-span-4",children:[e.jsxs(l.Select,{error:w.config&&!!m.config,id:"deleteCollections",name:"deleteCollections",label:"Delete collections",disabled:f||!o,position:"item-aligned",onChange:a=>y("config.deleteCollections",a.target.value==="own"?"own":a.target.value==="true"),value:f?"true":t.config?.deleteCollections==="own"?"own":t.config?.deleteCollections?"true":"false",renderValue:a=>a==="own"?"Own":a==="true"?"Yes":"No",children:[e.jsx(l.SelectItem,{value:"true",children:" Yes "}),e.jsx(l.SelectItem,{value:"false",children:" No "}),e.jsx(l.SelectItem,{value:"own",children:" Only his/her own "})]}),e.jsx(N.FieldCaption,{children:w.config&&m.config?m.config:"Can the user delete collections"})]})]})]}),e.jsxs(l.DialogActions,{position:"sticky",children:[b&&e.jsx(l.Typography,{className:"text-red-500",children:"There was an error saving this role"}),e.jsx(l.Button,{variant:"text",onClick:()=>{c()},children:"Cancel"}),e.jsx(l.LoadingButton,{variant:"filled",color:"primary",type:"submit",disabled:!_,loading:E,startIcon:e.jsx(l.DoneIcon,{}),children:p?"Create role":"Update"})]})]})})})}const we=[{id:"admin",name:"Admin",isAdmin:!0},{id:"editor",name:"Editor",isAdmin:!1,defaultPermissions:{read:!0,create:!0,edit:!0,delete:!0},config:{createCollections:!0,editCollections:"own",deleteCollections:"own"}},{id:"viewer",name:"Viewer",isAdmin:!1,defaultPermissions:{read:!0,create:!1,edit:!1,delete:!1}}];function X({onRoleClicked:n,editable:s}){const{roles:o,saveRole:c,deleteRole:r,allowDefaultRolesCreation:g}=V(),[p,b]=d.useState(void 0),[S,u]=d.useState(!1);return e.jsxs("div",{className:"w-full overflow-auto",children:[e.jsxs(l.Table,{children:[e.jsxs(l.TableHeader,{children:[e.jsx(l.TableCell,{header:!0,className:"w-16"}),e.jsx(l.TableCell,{header:!0,children:"Role"}),e.jsx(l.TableCell,{header:!0,className:"items-center",children:"Is Admin"}),e.jsx(l.TableCell,{header:!0,children:"Default permissions"})]}),e.jsxs(l.TableBody,{children:[o&&o.map(h=>{const E=h.isAdmin||h.defaultPermissions?.create,w=h.isAdmin||h.defaultPermissions?.read,t=h.isAdmin||h.defaultPermissions?.edit,m=h.isAdmin||h.defaultPermissions?.delete;return e.jsxs(l.TableRow,{onClick:()=>{n(h)},children:[e.jsx(l.TableCell,{style:{width:"64px"},children:!h.isAdmin&&e.jsx(l.Tooltip,{title:"Delete this role",children:e.jsx(l.IconButton,{size:"small",disabled:!s,onClick:U=>(U.stopPropagation(),b(h)),children:e.jsx(l.DeleteIcon,{})})})}),e.jsx(l.TableCell,{children:e.jsx(O,{role:h})}),e.jsx(l.TableCell,{className:"items-center",children:e.jsx(l.Checkbox,{checked:h.isAdmin??!1})}),e.jsx(l.TableCell,{children:e.jsxs("ul",{children:[E&&e.jsx("li",{children:"Create"}),w&&e.jsx("li",{children:"Read"}),t&&e.jsx("li",{children:"Update"}),m&&e.jsx("li",{children:"Delete"})]})})]},h.name)}),(!o||o.length===0)&&e.jsx(l.TableRow,{children:e.jsx(l.TableCell,{colspan:4,children:e.jsxs(l.CenteredView,{className:"flex flex-col gap-4 my-8 items-center",children:[e.jsx(l.Typography,{variant:"label",children:"You don't have any roles yet."}),g&&e.jsx(l.Button,{variant:"outlined",onClick:()=>{we.forEach(h=>{c(h)})},children:"Create default roles"})]})})})]})]}),e.jsx(N.DeleteConfirmationDialog,{open:!!p,loading:S,onAccept:()=>{p&&(u(!0),r(p).then(()=>{b(void 0)}).finally(()=>{u(!1)}))},onCancel:()=>{b(void 0)},title:e.jsx(e.Fragment,{children:"Delete?"}),body:e.jsx(e.Fragment,{children:"Are you sure you want to delete this role?"})})]})}const Z=d.memo(function({children:s}){const{collections:o}=N.useNavigationController(),[c,r]=d.useState(!1),[g,p]=d.useState(),{canEditRoles:b}=V(),S=d.useCallback(h=>{r(!0),p(h)},[]),u=()=>{p(void 0),r(!1)};return e.jsxs(l.Container,{className:"w-full flex flex-col py-4 gap-4",maxWidth:"6xl",children:[s,e.jsxs("div",{className:"flex items-center mt-12",children:[e.jsx(l.Typography,{gutterBottom:!0,variant:"h4",className:"flex-grow",component:"h4",children:"Roles"}),e.jsx(l.Tooltip,{title:b?void 0:"Update plans to customise roles",children:e.jsx(l.Button,{size:"large",disabled:!b,startIcon:e.jsx(l.AddIcon,{}),onClick:()=>r(!0),children:"Add role"})})]}),e.jsx(X,{onRoleClicked:S,editable:!!b}),e.jsx(Q,{open:c,role:g,editable:b,collections:o,handleClose:u},g?.id??"new")]})}),R=B.object().shape({displayName:B.string().required("Required"),email:B.string().email().required("Required"),roles:B.array().min(1)});function ye(n,s,o,c,r){const g=o.filter(u=>u.roles?.map(h=>h.id).includes("admin")),p=n.roles?.map(u=>u.id).includes("admin");if((!r||!H(r.roles??[],s.roles??[]))&&!p)throw new Error("Only admins can change roles");if(r&&r.roles?.map(u=>u.id).includes("admin")&&!s.roles?.map(u=>u.id).includes("admin")&&g.length===1)throw new Error("There must be at least one admin");return!0}function ee({open:n,user:s,handleClose:o}){const c=N.useSnackbarController(),{loggedInUser:r,saveUser:g,users:p,roles:b}=V(),S=!s,u=d.useCallback(C=>{if(!r)throw new Error("Logged user not found");try{return ye(r,C,p,b,s),g(C)}catch(D){return Promise.reject(D)}},[b,g,s,p,r]),h=A.useCreateFormex({initialValues:s??{displayName:"",email:"",roles:b.filter(C=>C.id==="editor")},validation:C=>R.validate(C,{abortEarly:!1}).then(()=>({})).catch(D=>D.inner.reduce((F,P)=>(F[P.path]=P.message,F),{})),onSubmit:(C,D)=>u(C).then(()=>{o(),D.resetForm({values:C})}).catch(F=>{c.open({type:"error",message:F.message})})}),{isSubmitting:E,touched:w,handleChange:t,values:m,errors:U,setFieldValue:y,dirty:_,handleSubmit:q,submitCount:f}=h;return e.jsx(l.Dialog,{open:n,onOpenChange:C=>C?void 0:o(),maxWidth:"4xl",children:e.jsx(A.Formex,{value:h,children:e.jsxs("form",{onSubmit:q,autoComplete:"off",noValidate:!0,style:{display:"flex",flexDirection:"column",position:"relative",height:"100%"},children:[e.jsxs(l.DialogContent,{className:"h-full flex-grow",children:[e.jsx("div",{className:"flex flex-row pt-4 pb-4",children:e.jsx(l.Typography,{variant:"h4",className:"flex-grow",children:"User"})}),e.jsxs("div",{className:"grid grid-cols-12 gap-8",children:[e.jsxs("div",{className:"col-span-12",children:[e.jsx(l.TextField,{name:"displayName",required:!0,error:f>0&&!!U.displayName,value:m.displayName??"",onChange:t,"aria-describedby":"name-helper-text",label:"Name"}),e.jsx(N.FieldCaption,{children:f>0&&U.displayName?U.displayName:"Name of this user"})]}),e.jsxs("div",{className:"col-span-12",children:[e.jsx(l.TextField,{required:!0,error:f>0&&!!U.email,name:"email",value:m.email??"",onChange:t,"aria-describedby":"email-helper-text",label:"Email"}),e.jsx(N.FieldCaption,{children:f>0&&U.email?U.email:"Email of this user"})]}),e.jsx("div",{className:"col-span-12",children:e.jsx(l.MultiSelect,{label:"Roles",value:m.roles?.map(C=>C.id)??[],onMultiValueChange:C=>y("roles",C.map(D=>b.find(F=>F.id===D))),renderValue:C=>{const D=b.find(F=>F.id===C);return D?e.jsx("div",{className:"flex flex-wrap space-x-2 space-y-2",children:e.jsx(O,{role:D},D?.id)}):null},children:b.map(C=>e.jsx(l.MultiSelectItem,{value:C.id,children:e.jsx(O,{role:C},C?.id)},C.id))})})]})]}),e.jsxs(l.DialogActions,{children:[e.jsx(l.Button,{variant:"text",onClick:()=>{o()},children:"Cancel"}),e.jsx(l.LoadingButton,{variant:"filled",color:"primary",type:"submit",disabled:!_,loading:E,startIcon:e.jsx(l.DoneIcon,{}),children:S?"Create user":"Update"})]})]})})})}function le({onUserClicked:n}){const{users:s,saveUser:o,deleteUser:c}=V(),r=N.useAuthController(),g=N.useSnackbarController(),p=N.useCustomizationController(),b=p?.locale?ae[p?.locale]:void 0,S=p?.dateTimeFormat??N.defaultDateFormat,[u,h]=d.useState(void 0),[E,w]=d.useState(!1);return e.jsxs("div",{className:"overflow-auto",children:[e.jsxs(l.Table,{children:[e.jsxs(l.TableHeader,{children:[e.jsx(l.TableCell,{className:"truncate w-16"}),e.jsx(l.TableCell,{children:"ID"}),e.jsx(l.TableCell,{children:"Email"}),e.jsx(l.TableCell,{children:"Name"}),e.jsx(l.TableCell,{children:"Roles"}),e.jsx(l.TableCell,{children:"Created on"})]}),e.jsxs(l.TableBody,{children:[s&&s.map(t=>{const m=t.roles,U=t.created_on?se.format(t.created_on,S,{locale:b}):"";return e.jsxs(l.TableRow,{onClick:()=>{n(t)},children:[e.jsx(l.TableCell,{className:"w-10",children:e.jsx(l.Tooltip,{title:"Delete this user",children:e.jsx(l.IconButton,{size:"small",onClick:y=>(y.stopPropagation(),h(t)),children:e.jsx(l.DeleteIcon,{})})})}),e.jsx(l.TableCell,{children:t.uid}),e.jsx(l.TableCell,{children:t.email}),e.jsx(l.TableCell,{className:"font-medium align-left",children:t.displayName}),e.jsx(l.TableCell,{className:"align-left",children:m?e.jsx("div",{className:"flex flex-wrap gap-2",children:m.map(y=>e.jsx(O,{role:y},y?.id))}):null}),e.jsx(l.TableCell,{children:U})]},"row_"+t.uid)}),(!s||s.length===0)&&e.jsx(l.TableRow,{children:e.jsx(l.TableCell,{colspan:6,children:e.jsxs(l.CenteredView,{className:"flex flex-col gap-4 my-8 items-center",children:[e.jsx(l.Typography,{variant:"label",children:"There are no users yet"}),e.jsx(l.Button,{variant:"outlined",onClick:()=>{if(!r.user?.uid)throw Error("UsersTable, authController misconfiguration");o({uid:r.user?.uid,email:r.user?.email,displayName:r.user?.displayName,photoURL:r.user?.photoURL,providerId:r.user?.providerId,isAnonymous:r.user?.isAnonymous,roles:[{id:"admin",name:"Admin"}],created_on:new Date}).then(()=>{g.open({type:"success",message:"User added successfully"})}).catch(t=>{g.open({type:"error",message:"Error adding user: "+t.message})})},children:"Add the logged user as an admin"})]})})})]})]}),e.jsx(N.DeleteConfirmationDialog,{open:!!u,loading:E,onAccept:()=>{u&&(w(!0),c(u).then(()=>{h(void 0)}).catch(t=>{g.open({type:"error",message:"Error deleting user: "+t.message})}).finally(()=>{w(!1)}))},onCancel:()=>{h(void 0)},title:e.jsx(e.Fragment,{children:"Delete?"}),body:e.jsx(e.Fragment,{children:"Are you sure you want to delete this user?"})})]})}const oe=function({children:s}){const[o,c]=d.useState(),[r,g]=d.useState(),{users:p,usersLimit:b}=V(),S=b!==void 0&&p&&p.length>=b,u=d.useCallback(E=>{g(E),c(!0)},[]),h=d.useCallback(()=>{c(!1),g(void 0)},[]);return e.jsxs(l.Container,{className:"w-full flex flex-col py-4 gap-4",maxWidth:"6xl",children:[s,e.jsxs("div",{className:"flex items-center mt-12",children:[e.jsx(l.Typography,{gutterBottom:!0,variant:"h4",className:"flex-grow",component:"h4",children:"Users"}),e.jsx(l.Button,{size:"large",disabled:S,startIcon:e.jsx(l.AddIcon,{}),onClick:()=>c(!0),children:"Add user"})]}),e.jsx(le,{onUserClicked:u}),e.jsx(ee,{open:o??!1,user:r,handleClose:h},r?.uid??"new")]})};function Te({userManagement:n}){return{name:"User management plugin",loading:n.loading,provider:{Component:G,props:{userManagement:n}}}}const Se=[{path:"users",name:"CMS Users",group:"Admin",icon:"face",view:e.jsx(oe,{})},{path:"roles",name:"Roles",group:"Admin",icon:"gpp_good",view:e.jsx(Z,{})}];i.RESERVED_GROUPS=te,i.RoleChip=O,i.RoleYupSchema=K,i.RolesDetailsForm=Q,i.RolesTable=X,i.RolesView=Z,i.UserDetailsForm=ee,i.UserManagementContext=j,i.UserManagementProvider=G,i.UserYupSchema=R,i.UsersTable=le,i.UsersView=oe,i.areRolesEqual=H,i.cacheDelegatedLoginToken=he,i.clearDelegatedLoginTokensCache=ge,i.darkenColor=pe,i.getDelegatedLoginTokenFromCache=fe,i.getUserRoles=de,i.hexToRgbaWithOpacity=me,i.resolveUserRolePermissions=J,i.useBuildFirestoreUserManagement=be,i.useUserManagement=V,i.useUserManagementPlugin=Te,i.userManagementAdminViews=Se,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})});
2
2
  //# sourceMappingURL=index.umd.js.map