@firecms/user_management 3.0.0-beta.4.pre.1 → 3.0.0-canary.10

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 (39) 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/useBuildFirestoreUserManagement.d.ts +1 -3
  9. package/dist/hooks/useUserManagement.d.ts +3 -2
  10. package/dist/index.es.js +349 -338
  11. package/dist/index.es.js.map +1 -1
  12. package/dist/index.umd.js +1 -1
  13. package/dist/index.umd.js.map +1 -1
  14. package/dist/types/index.d.ts +1 -2
  15. package/dist/types/persisted_user.d.ts +5 -0
  16. package/dist/types/user_management.d.ts +7 -10
  17. package/dist/utils/permissions.d.ts +3 -4
  18. package/package.json +8 -9
  19. package/src/UserManagementProvider.tsx +4 -3
  20. package/src/components/roles/RoleChip.tsx +1 -1
  21. package/src/components/roles/RolesDetailsForm.tsx +1 -2
  22. package/src/components/roles/RolesTable.tsx +1 -2
  23. package/src/components/roles/RolesView.tsx +1 -2
  24. package/src/components/roles/default_roles.tsx +1 -1
  25. package/src/components/users/UserDetailsForm.tsx +14 -13
  26. package/src/components/users/UsersTable.tsx +9 -10
  27. package/src/components/users/UsersView.tsx +3 -3
  28. package/src/hooks/useBuildFirestoreUserManagement.tsx +22 -23
  29. package/src/hooks/useUserManagement.tsx +3 -3
  30. package/src/types/index.ts +1 -2
  31. package/src/types/persisted_user.ts +6 -0
  32. package/src/types/user_management.tsx +8 -11
  33. package/src/useUserManagementPlugin.tsx +2 -2
  34. package/src/utils/permissions.ts +7 -5
  35. package/dist/types/firecms_user.d.ts +0 -7
  36. package/dist/types/roles.d.ts +0 -31
  37. package/src/types/firecms_user.ts +0 -8
  38. package/src/types/roles.ts +0 -41
  39. 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,c){typeof exports=="object"&&typeof module<"u"?c(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"],c):(i=typeof globalThis<"u"?globalThis:i||self,c(i.FireCMS={},i.React,i.firestore,i.jsxRuntime,i.ui,i.Yup,i.core,i.formex,i.dateFns,i.locales))})(this,function(i,c,N,e,l,se,S,P,re,ne){"use strict";function z(s){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const o in s)if(o!=="default"){const d=Object.getOwnPropertyDescriptor(s,o);Object.defineProperty(r,o,d.get?d:{enumerable:!0,get:()=>s[o]})}}return r.default=s,Object.freeze(r)}const B=z(se),ae=z(ne),te=["Admin"],ie={read:!1,edit:!1,create:!1,delete:!1};function J({collection:s,user:r}){const o=r?.roles;if(o){if(s.ownerId===r?.uid)return{read:!0,create:!0,edit:!0,delete:!0};{const d={read:!1,create:!1,edit:!1,delete:!1};return o.map(n=>ce(n,s.id)).reduce(Y,d)}}else return ie}function ce(s,r){const o={read:s.isAdmin||s.defaultPermissions?.read,create:s.isAdmin||s.defaultPermissions?.create,edit:s.isAdmin||s.defaultPermissions?.edit,delete:s.isAdmin||s.defaultPermissions?.delete};return s.collectionPermissions&&s.collectionPermissions[r]?Y(s.collectionPermissions[r],o):s.defaultPermissions?Y(s.defaultPermissions,o):o}const Y=(s,r)=>({read:s.read||r.read,create:s.create||r.create,edit:s.edit||r.edit,delete:s.delete||r.delete});function de(s,r){return s?r.roles?r.roles.map(o=>s.find(d=>d.id===o.id)).filter(Boolean):[]:void 0}const H=(s,r)=>{const o=s.map(n=>n.id),d=r.map(n=>n.id);return o.length===r.length&&o.every(n=>d.includes(n))};function he(s,r){if(!r)return;const o=Ce(r),d=new Date(o.exp*1e3);localStorage.setItem(`auth_token::${s}`,JSON.stringify({token:r,expiry:d}))}function fe(s){const r=localStorage.getItem(`auth_token::${s}`);if(r){const o=JSON.parse(r);if(o.expiry=new Date(o.expiry),o.expiry>new Date)return o.token}}function ge(){for(let s=0;s<localStorage.length;s++){const r=localStorage.key(s);r?.startsWith("auth_token::")&&localStorage.removeItem(r)}}function Ce(s){if(!s)throw new Error("No JWT token");const o=s.split(".")[1].replace(/-/g,"+").replace(/_/g,"/"),d=decodeURIComponent(window.atob(o).split("").map(function(n){return"%"+("00"+n.charCodeAt(0).toString(16)).slice(-2)}).join(""));return JSON.parse(d)}function pe(s,r=10){if(!/^#([0-9A-Fa-f]{3}){1,2}$/.test(s))throw new Error("Invalid color format");let o=s.substring(1).split("");o.length===3&&(o=[o[0],o[0],o[1],o[1],o[2],o[2]]);let d=parseInt(o[0]+o[1],16),n=parseInt(o[2]+o[3],16),g=parseInt(o[4]+o[5],16);return d=Math.floor(d*(1-r/100)),n=Math.floor(n*(1-r/100)),g=Math.floor(g*(1-r/100)),"#"+(d<16?"0":"")+d.toString(16)+(n<16?"0":"")+n.toString(16)+(g<16?"0":"")+g.toString(16)}function me(s,r=10){if(!/^#([0-9A-Fa-f]{3}){1,2}$/.test(s))throw new Error("Invalid color format");let o=s.substring(1).split("");o.length===3&&(o=[o[0],o[0],o[1],o[1],o[2],o[2]]);const d=parseInt(o[0]+o[1],16),n=parseInt(o[2]+o[3],16),g=parseInt(o[4]+o[5],16),u=r/100;return`rgba(${d}, ${n}, ${g}, ${u})`}function be({firebaseApp:s,usersPath:r="__FIRECMS/config/users",rolesPath:o="__FIRECMS/config/roles",usersLimit:d,canEditRoles:n=!0,allowDefaultRolesCreation:g,includeCollectionConfigPermissions:u}){const C=c.useRef(),[U,v]=c.useState(!0),[h,x]=c.useState(!0),[T,t]=c.useState([]),[m,I]=c.useState([]),w=m.map(b=>({...b,roles:T.filter(y=>b.roles?.includes(y.id))})),[q,V]=c.useState(),[p,f]=c.useState(),D=U||h;c.useEffect(()=>{s&&(C.current=N.getFirestore(s))},[s]),c.useEffect(()=>{if(!s||!o)return;const b=N.getFirestore(s);return N.onSnapshot(N.collection(b,o),{next:y=>{V(void 0);try{const k=ve(y.docs);t(k)}catch(k){V(k)}v(!1)},error:y=>{V(y),v(!1)}})},[s,o]),c.useEffect(()=>{if(!s||!r)return;const b=N.getFirestore(s);return N.onSnapshot(N.collection(b,r),{next:y=>{f(void 0);try{const k=ue(y.docs);I(k)}catch(k){f(k)}x(!1)},error:y=>{f(y),x(!1)}})},[s,r]);const F=c.useCallback(async b=>{const y=C.current;if(!y||!r)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Persisting user",b);const k=b.roles?.map(ke=>ke.id),{uid:$,...W}=b;return N.setDoc(N.doc(y,r,$),{...W,roles:k},{merge:!0}).then(()=>b)},[r]),A=c.useCallback(b=>{const y=C.current;if(!y||!o)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Persisting role",b);const{id:k,...$}=b,W=N.doc(y,o,k);return N.setDoc(W,$,{merge:!0})},[o]),a=c.useCallback(async b=>{const y=C.current;if(!y||!r)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Deleting",b);const{uid:k}=b;return N.deleteDoc(N.doc(y,r,k))},[r]),E=c.useCallback(b=>{const y=C.current;if(!y||!o)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Deleting",b);const{id:k}=b,$=N.doc(y,o,k);return N.deleteDoc($)},[o]),L=c.useCallback(({collection:b,user:y})=>J({collection:b,user:y}),[]),M=w.map(b=>b.uid),De=c.useCallback(b=>{if(!w)throw Error("Users not loaded");return w.find(k=>k.email?.toLowerCase()===b?.email?.toLowerCase())?.roles},[M]);return{loading:D,roles:T,users:w,saveUser:F,saveRole:A,deleteUser:a,deleteRole:E,usersLimit:d,canEditRoles:n===void 0?!0:n,allowDefaultRolesCreation:g===void 0?!0:g,includeCollectionConfigPermissions:!!u,collectionPermissions:L,defineRolesFor:De}}const ue=s=>s.map(r=>{const o=r.data();return{uid:r.id,...o,created_on:o?.created_on?.toDate(),updated_on:o?.updated_on?.toDate()}}),ve=s=>s.map(r=>({id:r.id,...r.data()})),j=c.createContext({});function G({children:s,userManagement:r}){return e.jsx(j.Provider,{value:r,children:s})}const _=()=>c.useContext(j);function O({role:s}){let r;return s.isAdmin?r="blueDarker":s.id==="editor"?r="yellowLight":s.id==="viewer"?r="grayLight":r=l.getColorSchemeForSeed(s.id),e.jsx(l.Chip,{colorScheme:r,children:s.name},s.id)}const K=B.object().shape({id:B.string().required("Required"),name:B.string().required("Required")});function Q({open:s,role:r,editable:o,handleClose:d,collections:n}){const{saveRole:g}=_(),u=!r,[C,U]=c.useState(),v=c.useCallback(a=>(U(void 0),g(a)),[g]),h=P.useCreateFormex({initialValues:r??{name:""},onSubmit:(a,E)=>v(a).then(()=>{E.resetForm({values:a}),d()}).catch(L=>U(L)),validation:a=>K.validate(a,{abortEarly:!1}).then(()=>({})).catch(E=>{const L={};return E.inner.forEach(M=>{L[M.path]=M.message}),L})}),{isSubmitting:x,touched:T,values:t,errors:m,handleChange:I,setFieldValue:w,dirty:q,setFieldTouched:V}=h,p=t.isAdmin??!1,f=t.defaultPermissions?.create??!1,D=t.defaultPermissions?.read??!1,F=t.defaultPermissions?.edit??!1,A=t.defaultPermissions?.delete??!1;return c.useEffect(()=>{!P.getIn(T,"id")&&t.name&&w("id",S.toSnakeCase(t.name))},[T,t.name]),e.jsx(l.Dialog,{open:s,maxWidth:"4xl",children:e.jsx(P.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:T.name&&!!m.name,value:t.name,disabled:p||!o,onChange:I,"aria-describedby":"name-helper-text",label:"Name"}),e.jsx(S.FieldCaption,{children:T.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:T.id&&!!m.id,value:t.id,disabled:!u||!o,onChange:a=>{I(a),V("id",!0)},"aria-describedby":"id-helper-text",label:"ID"}),e.jsx(S.FieldCaption,{children:T.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:p||!o,checked:(p||f)??!1,onCheckedChange:a=>w("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:p||!o,checked:(p||D)??!1,onCheckedChange:a=>w("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:p||!o,checked:(p||F)??!1,onCheckedChange:a=>w("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:p||!o,checked:(p||A)??!1,onCheckedChange:a=>w("defaultPermissions.delete",a)})})})]}),n&&n.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:p||f||!o,checked:(p||f||P.getIn(t,`collectionPermissions.${a.path}.create`))??!1,onCheckedChange:E=>w(`collectionPermissions.${a.path}.create`,E)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:p||D||!o,checked:(p||D||P.getIn(t,`collectionPermissions.${a.path}.read`))??!1,onCheckedChange:E=>w(`collectionPermissions.${a.path}.read`,E)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:p||F||!o,checked:(p||F||P.getIn(t,`collectionPermissions.${a.path}.edit`))??!1,onCheckedChange:E=>w(`collectionPermissions.${a.path}.edit`,E)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:p||A||!o,checked:(p||A||P.getIn(t,`collectionPermissions.${a.path}.delete`))??!1,onCheckedChange:E=>w(`collectionPermissions.${a.path}.delete`,E)})})]},a.name))]})]})}),e.jsx(S.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:T.config&&!!m.config,id:"createCollections",name:"createCollections",label:"Create collections",position:"item-aligned",disabled:p||!o,onChange:a=>w("config.createCollections",a.target.value==="true"),value:p||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(S.FieldCaption,{children:T.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:T.config&&!!m.config,id:"editCollections",name:"editCollections",label:"Edit collections",disabled:p||!o,position:"item-aligned",onChange:a=>w("config.editCollections",a.target.value==="own"?"own":a.target.value==="true"),value:p?"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(S.FieldCaption,{children:T.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:T.config&&!!m.config,id:"deleteCollections",name:"deleteCollections",label:"Delete collections",disabled:p||!o,position:"item-aligned",onChange:a=>w("config.deleteCollections",a.target.value==="own"?"own":a.target.value==="true"),value:p?"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(S.FieldCaption,{children:T.config&&m.config?m.config:"Can the user delete collections"})]})]})]}),e.jsxs(l.DialogActions,{position:"sticky",children:[C&&e.jsx(l.Typography,{className:"text-red-500",children:"There was an error saving this role"}),e.jsx(l.Button,{variant:"text",onClick:()=>{d()},children:"Cancel"}),e.jsx(l.LoadingButton,{variant:"filled",color:"primary",type:"submit",disabled:!q,loading:x,startIcon:e.jsx(l.DoneIcon,{}),children:u?"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:s,editable:r}){const{roles:o,saveRole:d,deleteRole:n,allowDefaultRolesCreation:g}=_(),[u,C]=c.useState(void 0),[U,v]=c.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 x=h.isAdmin||h.defaultPermissions?.create,T=h.isAdmin||h.defaultPermissions?.read,t=h.isAdmin||h.defaultPermissions?.edit,m=h.isAdmin||h.defaultPermissions?.delete;return e.jsxs(l.TableRow,{onClick:()=>{s(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:!r,onClick:I=>(I.stopPropagation(),C(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:[x&&e.jsx("li",{children:"Create"}),T&&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=>{d(h)})},children:"Create default roles"})]})})})]})]}),e.jsx(S.DeleteConfirmationDialog,{open:!!u,loading:U,onAccept:()=>{u&&(v(!0),n(u).then(()=>{C(void 0)}).finally(()=>{v(!1)}))},onCancel:()=>{C(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=c.memo(function({children:r}){const{collections:o}=S.useNavigationController(),[d,n]=c.useState(!1),[g,u]=c.useState(),{canEditRoles:C}=_(),U=c.useCallback(h=>{n(!0),u(h)},[]),v=()=>{u(void 0),n(!1)};return e.jsxs(l.Container,{className:"w-full flex flex-col py-4 gap-4",maxWidth:"6xl",children:[r,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:C?void 0:"Update plans to customise roles",children:e.jsx(l.Button,{size:"large",disabled:!C,startIcon:e.jsx(l.AddIcon,{}),onClick:()=>n(!0),children:"Add role"})})]}),e.jsx(X,{onRoleClicked:U,editable:!!C}),e.jsx(Q,{open:d,role:g,editable:C,collections:o,handleClose:v},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(s,r,o,d,n){const g=o.filter(v=>v.roles?.map(h=>h.id).includes("admin")),u=s.roles?.map(v=>v.id).includes("admin");if((!n||!H(n.roles??[],r.roles??[]))&&!u)throw new Error("Only admins can change roles");if(n&&n.roles?.map(v=>v.id).includes("admin")&&!r.roles?.map(v=>v.id).includes("admin")&&g.length===1)throw new Error("There must be at least one admin");return!0}function ee({open:s,user:r,handleClose:o}){const d=S.useSnackbarController(),{user:n}=S.useAuthController(),{saveUser:g,users:u,roles:C}=_(),U=!r,v=c.useCallback(f=>{if(!n)throw new Error("Logged user not found");try{return ye(n,f,u,C,r),g(f)}catch(D){return Promise.reject(D)}},[C,g,r,u,n]),h=P.useCreateFormex({initialValues:r??{displayName:"",email:"",roles:C.filter(f=>f.id==="editor")},validation:f=>R.validate(f,{abortEarly:!1}).then(()=>({})).catch(D=>D.inner.reduce((F,A)=>(F[A.path]=A.message,F),{})),onSubmit:(f,D)=>v(f).then(()=>{o(),D.resetForm({values:f})}).catch(F=>{d.open({type:"error",message:F.message})})}),{isSubmitting:x,touched:T,handleChange:t,values:m,errors:I,setFieldValue:w,dirty:q,handleSubmit:V,submitCount:p}=h;return e.jsx(l.Dialog,{open:s,onOpenChange:f=>f?void 0:o(),maxWidth:"4xl",children:e.jsx(P.Formex,{value:h,children:e.jsxs("form",{onSubmit:V,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:p>0&&!!I.displayName,value:m.displayName??"",onChange:t,"aria-describedby":"name-helper-text",label:"Name"}),e.jsx(S.FieldCaption,{children:p>0&&I.displayName?I.displayName:"Name of this user"})]}),e.jsxs("div",{className:"col-span-12",children:[e.jsx(l.TextField,{required:!0,error:p>0&&!!I.email,name:"email",value:m.email??"",onChange:t,"aria-describedby":"email-helper-text",label:"Email"}),e.jsx(S.FieldCaption,{children:p>0&&I.email?I.email:"Email of this user"})]}),e.jsx("div",{className:"col-span-12",children:e.jsx(l.MultiSelect,{label:"Roles",value:m.roles?.map(f=>f.id)??[],onMultiValueChange:f=>w("roles",f.map(D=>C.find(F=>F.id===D))),renderValue:f=>{const D=C.find(F=>F.id===f);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:C.map(f=>e.jsx(l.MultiSelectItem,{value:f.id,children:e.jsx(O,{role:f},f?.id)},f.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:!q,loading:x,startIcon:e.jsx(l.DoneIcon,{}),children:U?"Create user":"Update"})]})]})})})}function le({onUserClicked:s}){const{users:r,saveUser:o,deleteUser:d}=_(),n=S.useAuthController(),g=S.useSnackbarController(),u=S.useCustomizationController(),C=u?.locale?ae[u?.locale]:void 0,U=u?.dateTimeFormat??S.defaultDateFormat,[v,h]=c.useState(void 0),[x,T]=c.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:[r&&r.map(t=>{const m=t.roles,I=t.created_on?re.format(t.created_on,U,{locale:C}):"";return e.jsxs(l.TableRow,{onClick:()=>{s(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:w=>(w.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(w=>e.jsx(O,{role:w},w?.id))}):null}),e.jsx(l.TableCell,{children:I})]},"row_"+t.uid)}),(!r||r.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(!n.user?.uid)throw Error("UsersTable, authController misconfiguration");o({uid:n.user?.uid,email:n.user?.email,displayName:n.user?.displayName,photoURL:n.user?.photoURL,providerId:n.user?.providerId,isAnonymous:n.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(S.DeleteConfirmationDialog,{open:!!v,loading:x,onAccept:()=>{v&&(T(!0),d(v).then(()=>{h(void 0)}).catch(t=>{g.open({type:"error",message:"Error deleting user: "+t.message})}).finally(()=>{T(!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:r}){const[o,d]=c.useState(),[n,g]=c.useState(),{users:u,usersLimit:C}=_(),U=C!==void 0&&u&&u.length>=C,v=c.useCallback(x=>{g(x),d(!0)},[]),h=c.useCallback(()=>{d(!1),g(void 0)},[]);return e.jsxs(l.Container,{className:"w-full flex flex-col py-4 gap-4",maxWidth:"6xl",children:[r,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:U,startIcon:e.jsx(l.AddIcon,{}),onClick:()=>d(!0),children:"Add user"})]}),e.jsx(le,{onUserClicked:v}),e.jsx(ee,{open:o??!1,user:n,handleClose:h},n?.uid??"new")]})};function Te({userManagement:s}){return{key:"user_management",loading:s.loading,provider:{Component:G,props:{userManagement:s}}}}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=_,i.useUserManagementPlugin=Te,i.userManagementAdminViews=Se,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})});
2
2
  //# sourceMappingURL=index.umd.js.map