@firecms/user_management 3.0.0-canary.40 → 3.0.0-canary.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/{useBuildFirestoreUserManagement.d.ts → useFirestoreUserManagement.d.ts} +1 -1
- package/dist/index.es.js +385 -379
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +5 -6
- package/src/hooks/index.ts +1 -1
- package/src/hooks/{useBuildFirestoreUserManagement.tsx → useFirestoreUserManagement.tsx} +33 -25
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,y,e,l,ne,F,P,se,ae){"use strict";function z(r){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const o in r)if(o!=="default"){const c=Object.getOwnPropertyDescriptor(r,o);Object.defineProperty(n,o,c.get?c:{enumerable:!0,get:()=>r[o]})}}return n.default=r,Object.freeze(n)}const B=z(ne),te=z(ae),ie=["Admin"],ce={read:!1,edit:!1,create:!1,delete:!1};function J({collection:r,user:n}){const o=n?.roles;if(o){if(r.ownerId===n?.uid)return{read:!0,create:!0,edit:!0,delete:!0};{const c={read:!1,create:!1,edit:!1,delete:!1};return o.map(s=>de(s,r.id)).reduce(Y,c)}}else return ce}function de(r,n){const o={read:r.isAdmin||r.defaultPermissions?.read,create:r.isAdmin||r.defaultPermissions?.create,edit:r.isAdmin||r.defaultPermissions?.edit,delete:r.isAdmin||r.defaultPermissions?.delete};return r.collectionPermissions&&r.collectionPermissions[n]?Y(r.collectionPermissions[n],o):r.defaultPermissions?Y(r.defaultPermissions,o):o}const Y=(r,n)=>({read:r.read||n.read,create:r.create||n.create,edit:r.edit||n.edit,delete:r.delete||n.delete});function he(r,n){return r?n.roles?n.roles.map(o=>r.find(c=>c.id===o.id)).filter(Boolean):[]:void 0}const H=(r,n)=>{const o=r.map(s=>s.id),c=n.map(s=>s.id);return o.length===n.length&&o.every(s=>c.includes(s))};function ge(r,n){if(!n)return;const o=me(n),c=new Date(o.exp*1e3);localStorage.setItem(`auth_token::${r}`,JSON.stringify({token:n,expiry:c}))}function fe(r){const n=localStorage.getItem(`auth_token::${r}`);if(n){const o=JSON.parse(n);if(o.expiry=new Date(o.expiry),o.expiry>new Date)return o.token}}function Ce(){for(let r=0;r<localStorage.length;r++){const n=localStorage.key(r);n?.startsWith("auth_token::")&&localStorage.removeItem(n)}}function me(r){if(!r)throw new Error("No JWT token");const o=r.split(".")[1].replace(/-/g,"+").replace(/_/g,"/"),c=decodeURIComponent(window.atob(o).split("").map(function(s){return"%"+("00"+s.charCodeAt(0).toString(16)).slice(-2)}).join(""));return JSON.parse(c)}function pe(r,n=10){if(!/^#([0-9A-Fa-f]{3}){1,2}$/.test(r))throw new Error("Invalid color format");let o=r.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),s=parseInt(o[2]+o[3],16),m=parseInt(o[4]+o[5],16);return c=Math.floor(c*(1-n/100)),s=Math.floor(s*(1-n/100)),m=Math.floor(m*(1-n/100)),"#"+(c<16?"0":"")+c.toString(16)+(s<16?"0":"")+s.toString(16)+(m<16?"0":"")+m.toString(16)}function ue(r,n=10){if(!/^#([0-9A-Fa-f]{3}){1,2}$/.test(r))throw new Error("Invalid color format");let o=r.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),s=parseInt(o[2]+o[3],16),m=parseInt(o[4]+o[5],16),b=n/100;return`rgba(${c}, ${s}, ${m}, ${b})`}function be({firebaseApp:r,usersPath:n="__FIRECMS/config/users",rolesPath:o="__FIRECMS/config/roles",usersLimit:c,canEditRoles:s=!0,allowDefaultRolesCreation:m,includeCollectionConfigPermissions:b}){const[v,U]=d.useState(!0),[w,h]=d.useState(!0),[x,T]=d.useState([]),[t,p]=d.useState([]),S=t.map(C=>({...C,roles:x.filter(u=>C.roles?.includes(u.id))})),[D,_]=d.useState(),[q,g]=d.useState(),f=v||w;d.useEffect(()=>{if(!r||!o)return;const C=y.getFirestore(r);return y.onSnapshot(y.collection(C,o),{next:u=>{_(void 0);try{const k=we(u.docs);T(k)}catch(k){_(k)}U(!1)},error:u=>{_(u),U(!1)}})},[r,o]),d.useEffect(()=>{if(!r||!n)return;const C=y.getFirestore(r);return y.onSnapshot(y.collection(C,n),{next:u=>{g(void 0);try{const k=ve(u.docs);p(k)}catch(k){g(k)}h(!1)},error:u=>{g(u),h(!1)}})},[r,n]);const N=d.useCallback(async C=>{if(!r)throw Error("useFirestoreConfigurationPersistence Firebase not initialised");const u=y.getFirestore(r);if(!u||!n)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Persisting user",C);const k=C.roles?.map(Fe=>Fe.id),{uid:O,...W}=C,re={...W,roles:k};return O?y.setDoc(y.doc(u,n,O),re,{merge:!0}).then(()=>C):y.addDoc(y.collection(u,n),re).then(()=>C)},[n]),I=d.useCallback(C=>{if(!r)throw Error("useFirestoreConfigurationPersistence Firebase not initialised");const u=y.getFirestore(r);if(!u||!o)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Persisting role",C);const{id:k,...O}=C,W=y.doc(u,o,k);return y.setDoc(W,O,{merge:!0})},[o]),A=d.useCallback(async C=>{if(!r)throw Error("useFirestoreConfigurationPersistence Firebase not initialised");const u=y.getFirestore(r);if(!u||!n)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Deleting",C);const{uid:k}=C;return y.deleteDoc(y.doc(u,n,k))},[n]),a=d.useCallback(C=>{if(!r)throw Error("useFirestoreConfigurationPersistence Firebase not initialised");const u=y.getFirestore(r);if(!u||!o)throw Error("useFirestoreConfigurationPersistence Firestore not initialised");console.debug("Deleting",C);const{id:k}=C,O=y.doc(u,o,k);return y.deleteDoc(O)},[o]),E=d.useCallback(({collection:C,user:u})=>J({collection:C,user:u}),[]),V=S.map(C=>C.uid),M=d.useCallback(C=>{if(!S)throw Error("Users not loaded");return S.find(k=>k.email?.toLowerCase()===C?.email?.toLowerCase())?.roles},[V]),ke=d.useCallback(({user:C})=>{if(console.log("Authenticating user",C),f)return console.log("User management is still loading"),!1;if(S.length===0||S.find(k=>k.email?.toLowerCase()===C?.email?.toLowerCase()))return!0;throw Error("Could not find a user with the provided email")},[f,V]);return{loading:f,roles:x,users:S,saveUser:N,saveRole:I,deleteUser:A,deleteRole:a,usersLimit:c,canEditRoles:s===void 0?!0:s,allowDefaultRolesCreation:m===void 0?!0:m,includeCollectionConfigPermissions:!!b,collectionPermissions:E,defineRolesFor:M,authenticator:ke}}const ve=r=>r.map(n=>{const o=n.data();return{uid:n.id,...o,created_on:o?.created_on?.toDate(),updated_on:o?.updated_on?.toDate()}}),we=r=>r.map(n=>({id:n.id,...n.data()})),j=d.createContext({});function G({children:r,userManagement:n}){return e.jsx(j.Provider,{value:n,children:r})}const L=()=>d.useContext(j);function $({role:r}){let n;return r.isAdmin?n="blueDarker":r.id==="editor"?n="yellowLight":r.id==="viewer"?n="grayLight":n=l.getColorSchemeForSeed(r.id),e.jsx(l.Chip,{colorScheme:n,children:r.name},r.id)}const K=B.object().shape({id:B.string().required("Required"),name:B.string().required("Required")});function Q({open:r,role:n,editable:o,handleClose:c,collections:s}){const{saveRole:m}=L(),b=!n,[v,U]=d.useState(),w=d.useCallback(a=>(U(void 0),m(a)),[m]),h=P.useCreateFormex({initialValues:n??{name:""},onSubmit:(a,E)=>w(a).then(()=>{E.resetForm({values:a}),c()}).catch(V=>U(V)),validation:a=>K.validate(a,{abortEarly:!1}).then(()=>({})).catch(E=>{const V={};return E.inner.forEach(M=>{V[M.path]=M.message}),V})}),{isSubmitting:x,touched:T,values:t,errors:p,handleChange:S,setFieldValue:D,dirty:_,setFieldTouched:q}=h,g=t.isAdmin??!1,f=t.defaultPermissions?.create??!1,N=t.defaultPermissions?.read??!1,I=t.defaultPermissions?.edit??!1,A=t.defaultPermissions?.delete??!1;return d.useEffect(()=>{!P.getIn(T,"id")&&t.name&&D("id",F.toSnakeCase(t.name))},[T,t.name]),e.jsx(l.Dialog,{open:r,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&&!!p.name,value:t.name,disabled:g||!o,onChange:S,"aria-describedby":"name-helper-text",label:"Name"}),e.jsx(F.FieldCaption,{children:T.name&&p.name?p.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&&!!p.id,value:t.id,disabled:!b||!o,onChange:a=>{S(a),q("id",!0)},"aria-describedby":"id-helper-text",label:"ID"}),e.jsx(F.FieldCaption,{children:T.id&&p.id?p.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:g||!o,checked:(g||f)??!1,onCheckedChange:a=>D("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:g||!o,checked:(g||N)??!1,onCheckedChange:a=>D("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:g||!o,checked:(g||I)??!1,onCheckedChange:a=>D("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:g||!o,checked:(g||A)??!1,onCheckedChange:a=>D("defaultPermissions.delete",a)})})})]}),s&&s.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:g||f||!o,checked:(g||f||P.getIn(t,`collectionPermissions.${a.path}.create`))??!1,onCheckedChange:E=>D(`collectionPermissions.${a.path}.create`,E)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:g||N||!o,checked:(g||N||P.getIn(t,`collectionPermissions.${a.path}.read`))??!1,onCheckedChange:E=>D(`collectionPermissions.${a.path}.read`,E)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:g||I||!o,checked:(g||I||P.getIn(t,`collectionPermissions.${a.path}.edit`))??!1,onCheckedChange:E=>D(`collectionPermissions.${a.path}.edit`,E)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:g||A||!o,checked:(g||A||P.getIn(t,`collectionPermissions.${a.path}.delete`))??!1,onCheckedChange:E=>D(`collectionPermissions.${a.path}.delete`,E)})})]},a.name))]})]})}),e.jsx(F.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&&!!p.config,id:"createCollections",name:"createCollections",label:"Create collections",position:"item-aligned",disabled:g||!o,onChange:a=>D("config.createCollections",a.target.value==="true"),value:g||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(F.FieldCaption,{children:T.config&&p.config?p.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&&!!p.config,id:"editCollections",name:"editCollections",label:"Edit collections",disabled:g||!o,position:"item-aligned",onChange:a=>D("config.editCollections",a.target.value==="own"?"own":a.target.value==="true"),value:g?"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(F.FieldCaption,{children:T.config&&p.config?p.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&&!!p.config,id:"deleteCollections",name:"deleteCollections",label:"Delete collections",disabled:g||!o,position:"item-aligned",onChange:a=>D("config.deleteCollections",a.target.value==="own"?"own":a.target.value==="true"),value:g?"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(F.FieldCaption,{children:T.config&&p.config?p.config:"Can the user delete collections"})]})]})]}),e.jsxs(l.DialogActions,{position:"sticky",children:[v&&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:x,startIcon:e.jsx(l.DoneIcon,{}),children:b?"Create role":"Update"})]})]})})})}const ye=[{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:r,editable:n}){const{roles:o,saveRole:c,deleteRole:s,allowDefaultRolesCreation:m}=L(),[b,v]=d.useState(void 0),[U,w]=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 x=h.isAdmin||h.defaultPermissions?.create,T=h.isAdmin||h.defaultPermissions?.read,t=h.isAdmin||h.defaultPermissions?.edit,p=h.isAdmin||h.defaultPermissions?.delete;return e.jsxs(l.TableRow,{onClick:()=>{r(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:!n,onClick:S=>(S.stopPropagation(),v(h)),children:e.jsx(l.DeleteIcon,{})})})}),e.jsx(l.TableCell,{children:e.jsx($,{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"}),p&&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."}),m&&e.jsx(l.Button,{variant:"outlined",onClick:()=>{ye.forEach(h=>{c(h)})},children:"Create default roles"})]})})})]})]}),e.jsx(F.DeleteConfirmationDialog,{open:!!b,loading:U,onAccept:()=>{b&&(w(!0),s(b).then(()=>{v(void 0)}).finally(()=>{w(!1)}))},onCancel:()=>{v(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:n}){const{collections:o}=F.useNavigationController(),[c,s]=d.useState(!1),[m,b]=d.useState(),{canEditRoles:v}=L(),U=d.useCallback(h=>{s(!0),b(h)},[]),w=()=>{b(void 0),s(!1)};return e.jsxs(l.Container,{className:"w-full flex flex-col py-4 gap-4",maxWidth:"6xl",children:[n,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:v?void 0:"Update plans to customise roles",children:e.jsx(l.Button,{size:"large",disabled:!v,startIcon:e.jsx(l.AddIcon,{}),onClick:()=>s(!0),children:"Add role"})})]}),e.jsx(X,{onRoleClicked:U,editable:!!v}),e.jsx(Q,{open:c,role:m,editable:v,collections:o,handleClose:w},m?.id??"new")]})}),R=B.object().shape({displayName:B.string().required("Required"),email:B.string().email().required("Required"),roles:B.array().min(1)});function Te(r,n,o,c,s){const m=o.filter(w=>w.roles?.map(h=>h.id).includes("admin")),b=r.roles?.map(w=>w.id).includes("admin");if((!s||!H(s.roles??[],n.roles??[]))&&!b)throw new Error("Only admins can change roles");if(s&&s.roles?.map(w=>w.id).includes("admin")&&!n.roles?.map(w=>w.id).includes("admin")&&m.length===1)throw new Error("There must be at least one admin");return!0}function ee({open:r,user:n,handleClose:o}){const c=F.useSnackbarController(),{user:s}=F.useAuthController(),{saveUser:m,users:b,roles:v}=L(),U=!n,w=d.useCallback(f=>{if(!s)throw new Error("Logged user not found");try{return Te(s,f,b,v,n),m(f)}catch(N){return Promise.reject(N)}},[v,m,n,b,s]),h=P.useCreateFormex({initialValues:n??{displayName:"",email:"",roles:v.filter(f=>f.id==="editor")},validation:f=>R.validate(f,{abortEarly:!1}).then(()=>({})).catch(N=>N.inner.reduce((I,A)=>(I[A.path]=A.message,I),{})),onSubmit:(f,N)=>w(f).then(()=>{o(),N.resetForm({values:f})}).catch(I=>{c.open({type:"error",message:I.message})})}),{isSubmitting:x,touched:T,handleChange:t,values:p,errors:S,setFieldValue:D,dirty:_,handleSubmit:q,submitCount:g}=h;return e.jsx(l.Dialog,{open:r,onOpenChange:f=>f?void 0:o(),maxWidth:"4xl",children:e.jsx(P.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:g>0&&!!S.displayName,value:p.displayName??"",onChange:t,"aria-describedby":"name-helper-text",label:"Name"}),e.jsx(F.FieldCaption,{children:g>0&&S.displayName?S.displayName:"Name of this user"})]}),e.jsxs("div",{className:"col-span-12",children:[e.jsx(l.TextField,{required:!0,error:g>0&&!!S.email,name:"email",value:p.email??"",onChange:t,"aria-describedby":"email-helper-text",label:"Email"}),e.jsx(F.FieldCaption,{children:g>0&&S.email?S.email:"Email of this user"})]}),e.jsx("div",{className:"col-span-12",children:e.jsx(l.MultiSelect,{label:"Roles",value:p.roles?.map(f=>f.id)??[],onMultiValueChange:f=>D("roles",f.map(N=>v.find(I=>I.id===N))),renderValue:f=>{const N=v.find(I=>I.id===f);return N?e.jsx("div",{className:"flex flex-wrap space-x-2 space-y-2",children:e.jsx($,{role:N},N?.id)}):null},children:v.map(f=>e.jsx(l.MultiSelectItem,{value:f.id,children:e.jsx($,{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:!_,loading:x,startIcon:e.jsx(l.DoneIcon,{}),children:U?"Create user":"Update"})]})]})})})}function le({onUserClicked:r}){const{users:n,saveUser:o,deleteUser:c}=L(),s=F.useAuthController(),m=F.useSnackbarController(),b=F.useCustomizationController(),v=b?.locale?te[b?.locale]:void 0,U=b?.dateTimeFormat??F.defaultDateFormat,[w,h]=d.useState(void 0),[x,T]=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:[n&&n.map(t=>{const p=t.roles,S=t.created_on?se.format(t.created_on,U,{locale:v}):"";return e.jsxs(l.TableRow,{onClick:()=>{r(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:D=>(D.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:p?e.jsx("div",{className:"flex flex-wrap gap-2",children:p.map(D=>e.jsx($,{role:D},D?.id))}):null}),e.jsx(l.TableCell,{children:S})]},"row_"+t.uid)}),(!n||n.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(!s.user?.uid)throw Error("UsersTable, authController misconfiguration");o({uid:s.user?.uid,email:s.user?.email,displayName:s.user?.displayName,photoURL:s.user?.photoURL,providerId:s.user?.providerId,isAnonymous:s.user?.isAnonymous,roles:[{id:"admin",name:"Admin"}],created_on:new Date}).then(()=>{m.open({type:"success",message:"User added successfully"})}).catch(t=>{m.open({type:"error",message:"Error adding user: "+t.message})})},children:"Add the logged user as an admin"})]})})})]})]}),e.jsx(F.DeleteConfirmationDialog,{open:!!w,loading:x,onAccept:()=>{w&&(T(!0),c(w).then(()=>{h(void 0)}).catch(t=>{m.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:n}){const[o,c]=d.useState(),[s,m]=d.useState(),{users:b,usersLimit:v}=L(),U=v!==void 0&&b&&b.length>=v,w=d.useCallback(x=>{m(x),c(!0)},[]),h=d.useCallback(()=>{c(!1),m(void 0)},[]);return e.jsxs(l.Container,{className:"w-full flex flex-col py-4 gap-4",maxWidth:"6xl",children:[n,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:()=>c(!0),children:"Add user"})]}),e.jsx(le,{onUserClicked:w}),e.jsx(ee,{open:o??!1,user:s,handleClose:h},s?.uid??"new")]})};function Se({userManagement:r}){return{key:"user_management",loading:r.loading,provider:{Component:G,props:{userManagement:r}}}}const De=[{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=ie,i.RoleChip=$,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=ge,i.clearDelegatedLoginTokensCache=Ce,i.darkenColor=pe,i.getDelegatedLoginTokenFromCache=fe,i.getUserRoles=he,i.hexToRgbaWithOpacity=ue,i.resolveUserRolePermissions=J,i.useBuildFirestoreUserManagement=be,i.useUserManagement=L,i.useUserManagementPlugin=Se,i.userManagementAdminViews=De,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,T,e,l,re,k,P,se,ae){"use strict";function z(n){const r=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(r,o,c.get?c:{enumerable:!0,get:()=>n[o]})}}return r.default=n,Object.freeze(r)}const A=z(re),te=z(ae),ie=["Admin"],ce={read:!1,edit:!1,create:!1,delete:!1};function J({collection:n,user:r}){const o=r?.roles;if(o){if(n.ownerId===r?.uid)return{read:!0,create:!0,edit:!0,delete:!0};{const c={read:!1,create:!1,edit:!1,delete:!1};return o.map(s=>de(s,n.id)).reduce(Y,c)}}else return ce}function de(n,r){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[r]?Y(n.collectionPermissions[r],o):n.defaultPermissions?Y(n.defaultPermissions,o):o}const Y=(n,r)=>({read:n.read||r.read,create:n.create||r.create,edit:n.edit||r.edit,delete:n.delete||r.delete});function he(n,r){return n?r.roles?r.roles.map(o=>n.find(c=>c.id===o.id)).filter(Boolean):[]:void 0}const H=(n,r)=>{const o=n.map(s=>s.id),c=r.map(s=>s.id);return o.length===r.length&&o.every(s=>c.includes(s))};function ge(n,r){if(!r)return;const o=me(r),c=new Date(o.exp*1e3);localStorage.setItem(`auth_token::${n}`,JSON.stringify({token:r,expiry:c}))}function fe(n){const r=localStorage.getItem(`auth_token::${n}`);if(r){const o=JSON.parse(r);if(o.expiry=new Date(o.expiry),o.expiry>new Date)return o.token}}function Ce(){for(let n=0;n<localStorage.length;n++){const r=localStorage.key(n);r?.startsWith("auth_token::")&&localStorage.removeItem(r)}}function me(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(s){return"%"+("00"+s.charCodeAt(0).toString(16)).slice(-2)}).join(""));return JSON.parse(c)}function pe(n,r=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),s=parseInt(o[2]+o[3],16),C=parseInt(o[4]+o[5],16);return c=Math.floor(c*(1-r/100)),s=Math.floor(s*(1-r/100)),C=Math.floor(C*(1-r/100)),"#"+(c<16?"0":"")+c.toString(16)+(s<16?"0":"")+s.toString(16)+(C<16?"0":"")+C.toString(16)}function be(n,r=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),s=parseInt(o[2]+o[3],16),C=parseInt(o[4]+o[5],16),v=r/100;return`rgba(${c}, ${s}, ${C}, ${v})`}function ue({firebaseApp:n,usersPath:r="__FIRECMS/config/users",rolesPath:o="__FIRECMS/config/roles",usersLimit:c,canEditRoles:s=!0,allowDefaultRolesCreation:C,includeCollectionConfigPermissions:v}){const[p,N]=d.useState(!0),[w,h]=d.useState(!0),[E,S]=d.useState([]),[t,b]=d.useState([]),y=t.map(m=>({...m,roles:E.filter(u=>m.roles?.includes(u.id))})),[U,L]=d.useState(),[$,g]=d.useState(),f=p||w;console.log("loading",{rolesLoading:p,usersLoading:w,roles:E,usersWithRoleIds:t,users:y}),d.useEffect(()=>{if(!n||!o)return;const m=T.getFirestore(n);return T.onSnapshot(T.collection(m,o),{next:u=>{L(void 0);try{const D=we(u.docs);S(D)}catch(D){L(D)}N(!1)},error:u=>{L(u),N(!1)}})},[n,o]),d.useEffect(()=>{if(!n||!r)return;const m=T.getFirestore(n);return T.onSnapshot(T.collection(m,r),{next:u=>{g(void 0);try{const D=ve(u.docs);b(D)}catch(D){g(D)}h(!1)},error:u=>{g(u),h(!1)}})},[n,r]);const F=d.useCallback(async m=>{if(!n)throw Error("useFirestoreUserManagement Firebase not initialised");const u=T.getFirestore(n);if(!u||!r)throw Error("useFirestoreUserManagement Firestore not initialised");console.debug("Persisting user",m);const D=m.roles?.map(De=>De.id),{uid:V,...W}=m,ne={...W,roles:D};return V?T.setDoc(T.doc(u,r,V),ne,{merge:!0}).then(()=>m):T.addDoc(T.collection(u,r),ne).then(()=>m)},[r,n]),I=d.useCallback(m=>{if(!n)throw Error("useFirestoreUserManagement Firebase not initialised");const u=T.getFirestore(n);if(!u||!o)throw Error("useFirestoreUserManagement Firestore not initialised");console.debug("Persisting role",m);const{id:D,...V}=m,W=T.doc(u,o,D);return T.setDoc(W,V,{merge:!0})},[o,n]),B=d.useCallback(async m=>{if(!n)throw Error("useFirestoreUserManagement Firebase not initialised");const u=T.getFirestore(n);if(!u||!r)throw Error("useFirestoreUserManagement Firestore not initialised");console.debug("Deleting",m);const{uid:D}=m;return T.deleteDoc(T.doc(u,r,D))},[r,n]),a=d.useCallback(m=>{if(!n)throw Error("useFirestoreUserManagement Firebase not initialised");const u=T.getFirestore(n);if(!u||!o)throw Error("useFirestoreUserManagement Firestore not initialised");console.debug("Deleting",m);const{id:D}=m,V=T.doc(u,o,D);return T.deleteDoc(V)},[o,n]),x=d.useCallback(({collection:m,user:u})=>J({collection:m,user:u}),[]),_=d.useCallback(m=>{if(!y)throw Error("Users not loaded");return y.find(D=>D.email?.toLowerCase()===m?.email?.toLowerCase())?.roles},[y]),q=d.useCallback(({user:m})=>{if(console.log("Authenticating user",m),f)return console.log("User management is still loading"),!1;if(y.length===0||y.find(D=>D.email?.toLowerCase()===m?.email?.toLowerCase()))return!0;throw Error("Could not find a user with the provided email")},[f,y]);return{loading:f,roles:E,users:y,saveUser:F,saveRole:I,deleteUser:B,deleteRole:a,usersLimit:c,canEditRoles:s===void 0?!0:s,allowDefaultRolesCreation:C===void 0?!0:C,includeCollectionConfigPermissions:!!v,collectionPermissions:x,defineRolesFor:_,authenticator:q}}const ve=n=>n.map(r=>{const o=r.data();return{uid:r.id,...o,created_on:o?.created_on?.toDate(),updated_on:o?.updated_on?.toDate()}}),we=n=>n.map(r=>({id:r.id,...r.data()})),j=d.createContext({});function G({children:n,userManagement:r}){return e.jsx(j.Provider,{value:r,children:n})}const M=()=>d.useContext(j);function O({role:n}){let r;return n.isAdmin?r="blueDarker":n.id==="editor"?r="yellowLight":n.id==="viewer"?r="grayLight":r=l.getColorSchemeForSeed(n.id),e.jsx(l.Chip,{colorScheme:r,children:n.name},n.id)}const K=A.object().shape({id:A.string().required("Required"),name:A.string().required("Required")});function Q({open:n,role:r,editable:o,handleClose:c,collections:s}){const{saveRole:C}=M(),v=!r,[p,N]=d.useState(),w=d.useCallback(a=>(N(void 0),C(a)),[C]),h=P.useCreateFormex({initialValues:r??{name:""},onSubmit:(a,x)=>w(a).then(()=>{x.resetForm({values:a}),c()}).catch(_=>N(_)),validation:a=>K.validate(a,{abortEarly:!1}).then(()=>({})).catch(x=>{const _={};return x.inner.forEach(q=>{_[q.path]=q.message}),_})}),{isSubmitting:E,touched:S,values:t,errors:b,handleChange:y,setFieldValue:U,dirty:L,setFieldTouched:$}=h,g=t.isAdmin??!1,f=t.defaultPermissions?.create??!1,F=t.defaultPermissions?.read??!1,I=t.defaultPermissions?.edit??!1,B=t.defaultPermissions?.delete??!1;return d.useEffect(()=>{!P.getIn(S,"id")&&t.name&&U("id",k.toSnakeCase(t.name))},[S,t.name]),e.jsx(l.Dialog,{open:n,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:S.name&&!!b.name,value:t.name,disabled:g||!o,onChange:y,"aria-describedby":"name-helper-text",label:"Name"}),e.jsx(k.FieldCaption,{children:S.name&&b.name?b.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:S.id&&!!b.id,value:t.id,disabled:!v||!o,onChange:a=>{y(a),$("id",!0)},"aria-describedby":"id-helper-text",label:"ID"}),e.jsx(k.FieldCaption,{children:S.id&&b.id?b.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:g||!o,checked:(g||f)??!1,onCheckedChange:a=>U("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:g||!o,checked:(g||F)??!1,onCheckedChange:a=>U("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:g||!o,checked:(g||I)??!1,onCheckedChange:a=>U("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:g||!o,checked:(g||B)??!1,onCheckedChange:a=>U("defaultPermissions.delete",a)})})})]}),s&&s.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:g||f||!o,checked:(g||f||P.getIn(t,`collectionPermissions.${a.path}.create`))??!1,onCheckedChange:x=>U(`collectionPermissions.${a.path}.create`,x)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:g||F||!o,checked:(g||F||P.getIn(t,`collectionPermissions.${a.path}.read`))??!1,onCheckedChange:x=>U(`collectionPermissions.${a.path}.read`,x)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:g||I||!o,checked:(g||I||P.getIn(t,`collectionPermissions.${a.path}.edit`))??!1,onCheckedChange:x=>U(`collectionPermissions.${a.path}.edit`,x)})}),e.jsx(l.TableCell,{align:"center",children:e.jsx(l.Checkbox,{disabled:g||B||!o,checked:(g||B||P.getIn(t,`collectionPermissions.${a.path}.delete`))??!1,onCheckedChange:x=>U(`collectionPermissions.${a.path}.delete`,x)})})]},a.name))]})]})}),e.jsx(k.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:S.config&&!!b.config,id:"createCollections",name:"createCollections",label:"Create collections",position:"item-aligned",disabled:g||!o,onChange:a=>U("config.createCollections",a.target.value==="true"),value:g||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(k.FieldCaption,{children:S.config&&b.config?b.config:"Can the user create collections"})]}),e.jsxs("div",{className:"col-span-12 md:col-span-4",children:[e.jsxs(l.Select,{error:S.config&&!!b.config,id:"editCollections",name:"editCollections",label:"Edit collections",disabled:g||!o,position:"item-aligned",onChange:a=>U("config.editCollections",a.target.value==="own"?"own":a.target.value==="true"),value:g?"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(k.FieldCaption,{children:S.config&&b.config?b.config:"Can the user edit collections"})]}),e.jsxs("div",{className:"col-span-12 md:col-span-4",children:[e.jsxs(l.Select,{error:S.config&&!!b.config,id:"deleteCollections",name:"deleteCollections",label:"Delete collections",disabled:g||!o,position:"item-aligned",onChange:a=>U("config.deleteCollections",a.target.value==="own"?"own":a.target.value==="true"),value:g?"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(k.FieldCaption,{children:S.config&&b.config?b.config:"Can the user delete collections"})]})]})]}),e.jsxs(l.DialogActions,{position:"sticky",children:[p&&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:!L,loading:E,startIcon:e.jsx(l.DoneIcon,{}),children:v?"Create role":"Update"})]})]})})})}const ye=[{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:r}){const{roles:o,saveRole:c,deleteRole:s,allowDefaultRolesCreation:C}=M(),[v,p]=d.useState(void 0),[N,w]=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,S=h.isAdmin||h.defaultPermissions?.read,t=h.isAdmin||h.defaultPermissions?.edit,b=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:!r,onClick:y=>(y.stopPropagation(),p(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"}),S&&e.jsx("li",{children:"Read"}),t&&e.jsx("li",{children:"Update"}),b&&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."}),C&&e.jsx(l.Button,{variant:"outlined",onClick:()=>{ye.forEach(h=>{c(h)})},children:"Create default roles"})]})})})]})]}),e.jsx(k.DeleteConfirmationDialog,{open:!!v,loading:N,onAccept:()=>{v&&(w(!0),s(v).then(()=>{p(void 0)}).finally(()=>{w(!1)}))},onCancel:()=>{p(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:r}){const{collections:o}=k.useNavigationController(),[c,s]=d.useState(!1),[C,v]=d.useState(),{canEditRoles:p}=M(),N=d.useCallback(h=>{s(!0),v(h)},[]),w=()=>{v(void 0),s(!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:p?void 0:"Update plans to customise roles",children:e.jsx(l.Button,{size:"large",disabled:!p,startIcon:e.jsx(l.AddIcon,{}),onClick:()=>s(!0),children:"Add role"})})]}),e.jsx(X,{onRoleClicked:N,editable:!!p}),e.jsx(Q,{open:c,role:C,editable:p,collections:o,handleClose:w},C?.id??"new")]})}),R=A.object().shape({displayName:A.string().required("Required"),email:A.string().email().required("Required"),roles:A.array().min(1)});function Te(n,r,o,c,s){const C=o.filter(w=>w.roles?.map(h=>h.id).includes("admin")),v=n.roles?.map(w=>w.id).includes("admin");if((!s||!H(s.roles??[],r.roles??[]))&&!v)throw new Error("Only admins can change roles");if(s&&s.roles?.map(w=>w.id).includes("admin")&&!r.roles?.map(w=>w.id).includes("admin")&&C.length===1)throw new Error("There must be at least one admin");return!0}function ee({open:n,user:r,handleClose:o}){const c=k.useSnackbarController(),{user:s}=k.useAuthController(),{saveUser:C,users:v,roles:p}=M(),N=!r,w=d.useCallback(f=>{if(!s)throw new Error("Logged user not found");try{return Te(s,f,v,p,r),C(f)}catch(F){return Promise.reject(F)}},[p,C,r,v,s]),h=P.useCreateFormex({initialValues:r??{displayName:"",email:"",roles:p.filter(f=>f.id==="editor")},validation:f=>R.validate(f,{abortEarly:!1}).then(()=>({})).catch(F=>F.inner.reduce((I,B)=>(I[B.path]=B.message,I),{})),onSubmit:(f,F)=>w(f).then(()=>{o(),F.resetForm({values:f})}).catch(I=>{c.open({type:"error",message:I.message})})}),{isSubmitting:E,touched:S,handleChange:t,values:b,errors:y,setFieldValue:U,dirty:L,handleSubmit:$,submitCount:g}=h;return e.jsx(l.Dialog,{open:n,onOpenChange:f=>f?void 0:o(),maxWidth:"4xl",children:e.jsx(P.Formex,{value:h,children:e.jsxs("form",{onSubmit:$,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:g>0&&!!y.displayName,value:b.displayName??"",onChange:t,"aria-describedby":"name-helper-text",label:"Name"}),e.jsx(k.FieldCaption,{children:g>0&&y.displayName?y.displayName:"Name of this user"})]}),e.jsxs("div",{className:"col-span-12",children:[e.jsx(l.TextField,{required:!0,error:g>0&&!!y.email,name:"email",value:b.email??"",onChange:t,"aria-describedby":"email-helper-text",label:"Email"}),e.jsx(k.FieldCaption,{children:g>0&&y.email?y.email:"Email of this user"})]}),e.jsx("div",{className:"col-span-12",children:e.jsx(l.MultiSelect,{label:"Roles",value:b.roles?.map(f=>f.id)??[],onMultiValueChange:f=>U("roles",f.map(F=>p.find(I=>I.id===F))),renderValue:f=>{const F=p.find(I=>I.id===f);return F?e.jsx("div",{className:"flex flex-wrap space-x-2 space-y-2",children:e.jsx(O,{role:F},F?.id)}):null},children:p.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:!L,loading:E,startIcon:e.jsx(l.DoneIcon,{}),children:N?"Create user":"Update"})]})]})})})}function le({onUserClicked:n}){const{users:r,saveUser:o,deleteUser:c}=M(),s=k.useAuthController(),C=k.useSnackbarController(),v=k.useCustomizationController(),p=v?.locale?te[v?.locale]:void 0,N=v?.dateTimeFormat??k.defaultDateFormat,[w,h]=d.useState(void 0),[E,S]=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:[r&&r.map(t=>{const b=t.roles,y=t.created_on?se.format(t.created_on,N,{locale:p}):"";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:U=>(U.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:b?e.jsx("div",{className:"flex flex-wrap gap-2",children:b.map(U=>e.jsx(O,{role:U},U?.id))}):null}),e.jsx(l.TableCell,{children:y})]},"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(!s.user?.uid)throw Error("UsersTable, authController misconfiguration");o({uid:s.user?.uid,email:s.user?.email,displayName:s.user?.displayName,photoURL:s.user?.photoURL,providerId:s.user?.providerId,isAnonymous:s.user?.isAnonymous,roles:[{id:"admin",name:"Admin"}],created_on:new Date}).then(()=>{C.open({type:"success",message:"User added successfully"})}).catch(t=>{C.open({type:"error",message:"Error adding user: "+t.message})})},children:"Add the logged user as an admin"})]})})})]})]}),e.jsx(k.DeleteConfirmationDialog,{open:!!w,loading:E,onAccept:()=>{w&&(S(!0),c(w).then(()=>{h(void 0)}).catch(t=>{C.open({type:"error",message:"Error deleting user: "+t.message})}).finally(()=>{S(!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,c]=d.useState(),[s,C]=d.useState(),{users:v,usersLimit:p}=M(),N=p!==void 0&&v&&v.length>=p,w=d.useCallback(E=>{C(E),c(!0)},[]),h=d.useCallback(()=>{c(!1),C(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:N,startIcon:e.jsx(l.AddIcon,{}),onClick:()=>c(!0),children:"Add user"})]}),e.jsx(le,{onUserClicked:w}),e.jsx(ee,{open:o??!1,user:s,handleClose:h},s?.uid??"new")]})};function Se({userManagement:n}){return{key:"user_management",loading:n.loading,provider:{Component:G,props:{userManagement:n}}}}const Ue=[{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=ie,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=ge,i.clearDelegatedLoginTokensCache=Ce,i.darkenColor=pe,i.getDelegatedLoginTokenFromCache=fe,i.getUserRoles=he,i.hexToRgbaWithOpacity=be,i.resolveUserRolePermissions=J,i.useFirestoreUserManagement=ue,i.useUserManagement=M,i.useUserManagementPlugin=Se,i.userManagementAdminViews=Ue,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})});
|
2
2
|
//# sourceMappingURL=index.umd.js.map
|