@zealamic/payload-auth-rbac-plugin 1.0.0 → 1.0.1

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 (52) hide show
  1. package/dist/components/role-permission-matrix-client/default-data.js +2 -2
  2. package/dist/components/role-permission-matrix-client/default-data.js.map +1 -1
  3. package/dist/components/role-permission-matrix-client/index.js +2 -2
  4. package/dist/components/role-permission-matrix-client/index.js.map +1 -1
  5. package/dist/components/role-permission-matrix-client/matrix.module.scss +1 -4
  6. package/dist/components/role-permission-matrix-client/types.d.ts +4 -6
  7. package/dist/components/role-permission-matrix-client/types.js.map +1 -1
  8. package/docs/TRANSLATIONS.md +12 -5
  9. package/package.json +4 -27
  10. package/src/collections/permission-actions/default-data.ts +36 -0
  11. package/src/collections/permission-actions/index.ts +144 -0
  12. package/src/collections/permission-actions/types.ts +56 -0
  13. package/src/collections/permission-features/default-data.ts +30 -0
  14. package/src/collections/permission-features/index.ts +122 -0
  15. package/src/collections/permission-features/types.ts +47 -0
  16. package/src/collections/permissions/default-data.ts +38 -0
  17. package/src/collections/permissions/index.ts +160 -0
  18. package/src/collections/permissions/types.ts +57 -0
  19. package/src/collections/roles/default-data.ts +44 -0
  20. package/src/collections/roles/hooks/sync-permission-matrix-draft.ts +73 -0
  21. package/src/collections/roles/index.ts +178 -0
  22. package/src/collections/roles/types.ts +56 -0
  23. package/src/collections/roles-permissions/default-data.ts +28 -0
  24. package/src/collections/roles-permissions/index.ts +107 -0
  25. package/src/collections/roles-permissions/types.ts +42 -0
  26. package/src/collections/users/default-data.ts +19 -0
  27. package/src/collections/users/index.ts +148 -0
  28. package/src/collections/users/parent-path.ts +310 -0
  29. package/src/collections/users/types.ts +25 -0
  30. package/src/components/role-permission-matrix-client/default-data.ts +25 -0
  31. package/src/components/role-permission-matrix-client/index.tsx +369 -0
  32. package/src/components/role-permission-matrix-client/matrix.module.scss +66 -0
  33. package/src/components/role-permission-matrix-client/types.ts +16 -0
  34. package/src/endpoints/customEndpointHandler.ts +5 -0
  35. package/src/exports/client.ts +1 -0
  36. package/src/exports/rsc.ts +0 -0
  37. package/src/general-types.d.ts +5 -0
  38. package/src/index.ts +249 -0
  39. package/src/lib/constants/general.ts +1 -0
  40. package/src/lib/constants/index.ts +15 -0
  41. package/src/lib/constants/permission-action.ts +9 -0
  42. package/src/lib/constants/permission-feature.ts +4 -0
  43. package/src/lib/constants/permission.ts +4 -0
  44. package/src/lib/constants/role.ts +10 -0
  45. package/src/lib/constants/user.ts +1 -0
  46. package/src/lib/utils/access.ts +611 -0
  47. package/src/lib/utils/data.ts +7 -0
  48. package/src/lib/utils/fields.ts +62 -0
  49. package/src/lib/utils/index.ts +4 -0
  50. package/src/lib/utils/localization.ts +106 -0
  51. package/src/styles/variables.scss +1 -0
  52. package/src/types.ts +64 -0
@@ -7,12 +7,12 @@ export const rolePermissionMatrixClientDefaultTranslations = {
7
7
  placeholder: "Loading permission matrix..."
8
8
  },
9
9
  title: "Permission Matrix",
10
+ featuresLabel: "Features",
10
11
  features: {
11
- label: "Features",
12
12
  users: "Users"
13
13
  },
14
+ actionsLabel: "Actions",
14
15
  actions: {
15
- label: "Actions",
16
16
  create: "Create",
17
17
  read: "Read",
18
18
  update: "Update",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/role-permission-matrix-client/default-data.ts"],"sourcesContent":["import type { RolePermissionMatrixClientTranslations } from \"./types.js\";\n\nexport const rolePermissionMatrixClientDefaultTranslations: RolePermissionMatrixClientTranslations =\n {\n en: {\n viewInUpdateScreenOnly: {\n label: \"View permission matrix in update screen only\",\n },\n loading: {\n placeholder: \"Loading permission matrix...\",\n },\n title: \"Permission Matrix\",\n features: {\n label: \"Features\",\n users: \"Users\",\n },\n actions: {\n label: \"Actions\",\n create: \"Create\",\n read: \"Read\",\n update: \"Update\",\n delete: \"Delete\",\n },\n },\n };\n"],"names":["rolePermissionMatrixClientDefaultTranslations","en","viewInUpdateScreenOnly","label","loading","placeholder","title","features","users","actions","create","read","update","delete"],"mappings":"AAEA,OAAO,MAAMA,gDACX;IACEC,IAAI;QACFC,wBAAwB;YACtBC,OAAO;QACT;QACAC,SAAS;YACPC,aAAa;QACf;QACAC,OAAO;QACPC,UAAU;YACRJ,OAAO;YACPK,OAAO;QACT;QACAC,SAAS;YACPN,OAAO;YACPO,QAAQ;YACRC,MAAM;YACNC,QAAQ;YACRC,QAAQ;QACV;IACF;AACF,EAAE"}
1
+ {"version":3,"sources":["../../../src/components/role-permission-matrix-client/default-data.ts"],"sourcesContent":["import type { RolePermissionMatrixClientTranslations } from \"./types.js\";\n\nexport const rolePermissionMatrixClientDefaultTranslations: RolePermissionMatrixClientTranslations =\n {\n en: {\n viewInUpdateScreenOnly: {\n label: \"View permission matrix in update screen only\",\n },\n loading: {\n placeholder: \"Loading permission matrix...\",\n },\n title: \"Permission Matrix\",\n featuresLabel: \"Features\",\n features: {\n users: \"Users\",\n },\n actionsLabel: \"Actions\",\n actions: {\n create: \"Create\",\n read: \"Read\",\n update: \"Update\",\n delete: \"Delete\",\n },\n },\n };\n"],"names":["rolePermissionMatrixClientDefaultTranslations","en","viewInUpdateScreenOnly","label","loading","placeholder","title","featuresLabel","features","users","actionsLabel","actions","create","read","update","delete"],"mappings":"AAEA,OAAO,MAAMA,gDACX;IACEC,IAAI;QACFC,wBAAwB;YACtBC,OAAO;QACT;QACAC,SAAS;YACPC,aAAa;QACf;QACAC,OAAO;QACPC,eAAe;QACfC,UAAU;YACRC,OAAO;QACT;QACAC,cAAc;QACdC,SAAS;YACPC,QAAQ;YACRC,MAAM;YACNC,QAAQ;YACRC,QAAQ;QACV;IACF;AACF,EAAE"}
@@ -131,12 +131,12 @@ export const RolePermissionMatrixClient = ()=>{
131
131
  children: [
132
132
  /*#__PURE__*/ _jsx("th", {
133
133
  className: styles[`${RBAC_PREFIX}-table-th-feature`],
134
- children: t(`components:rolePermissionMatrix:features:label`)
134
+ children: t(`components:rolePermissionMatrix:featuresLabel`)
135
135
  }),
136
136
  /*#__PURE__*/ _jsx("th", {
137
137
  className: styles[`${RBAC_PREFIX}-table-th-action`],
138
138
  colSpan: actions.filter((action)=>action.type === TYPE.MAIN).length,
139
- children: t(`components:rolePermissionMatrix:actions:label`)
139
+ children: t(`components:rolePermissionMatrix:actionsLabel`)
140
140
  })
141
141
  ]
142
142
  })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/role-permission-matrix-client/index.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useConfig,\n useDocumentInfo,\n useField,\n useTranslation,\n} from \"@payloadcms/ui\";\nimport { Fragment, useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport type { PermissionAction } from \"../../collections/permission-actions/types.js\";\nimport type { PermissionFeature } from \"../../collections/permission-features/types.js\";\nimport type { Permission } from \"../../collections/permissions/types.js\";\nimport type { RolePermission } from \"../../collections/roles-permissions/types.js\";\nimport { STATUS as PERMISSION_STATUS } from \"../../lib/constants/permission.js\";\nimport {\n STATUS as PERMISSION_ACTION_STATUS,\n TYPE,\n} from \"../../lib/constants/permission-action.js\";\nimport { STATUS as PERMISSION_FEATURE_STATUS } from \"../../lib/constants/permission-feature.js\";\nimport { toID } from \"../../lib/utils/data.js\";\n\nimport styles from \"./matrix.module.scss\";\n\nconst RBAC_PREFIX = \"rbac\";\n\ntype ApiListResponse<T> = {\n docs?: T[];\n};\n\nexport const RolePermissionMatrixClient = () => {\n const checkboxId = useId();\n const { config } = useConfig();\n const { hasSavePermission, id } = useDocumentInfo();\n const { setValue, value } = useField<Record<string, boolean> | null>({\n path: \"permissionMatrixDraft\",\n });\n const isReadOnly = !hasSavePermission;\n\n const [features, setFeatures] = useState<PermissionFeature[]>([]);\n const [actions, setActions] = useState<PermissionAction[]>([]);\n const [permissions, setPermissions] = useState<Permission[]>([]);\n const [rolePermissions, setRolePermissions] = useState<RolePermission[]>([]);\n const [loading, setLoading] = useState(true);\n const { t } = useTranslation();\n const seededForRoleIdRef = useRef<string | null>(null);\n\n useEffect(() => {\n const run = async () => {\n setLoading(true);\n try {\n const base = config?.routes?.api || \"/api\";\n\n const [featuresRes, actionsRes, permissionsRes, rolePermissionsRes] =\n await Promise.all([\n fetch(\n `${base}/permission-features?limit=0&depth=0&where[status][equals]=${PERMISSION_FEATURE_STATUS.ACTIVE}`,\n { credentials: \"include\" },\n ),\n fetch(\n `${base}/permission-actions?limit=0&depth=0&where[status][equals]=${PERMISSION_ACTION_STATUS.ACTIVE}`,\n { credentials: \"include\" },\n ),\n fetch(\n `${base}/permissions?limit=0&depth=1&where[status][equals]=${PERMISSION_STATUS.ACTIVE}`,\n { credentials: \"include\" },\n ),\n id\n ? fetch(\n `${base}/roles-permissions?limit=0&depth=0&where[role][equals]=${id}`,\n {\n credentials: \"include\",\n },\n )\n : Promise.resolve(new Response(JSON.stringify({ docs: [] }))),\n ]);\n\n const featuresJson =\n (await featuresRes.json()) as ApiListResponse<PermissionFeature>;\n const actionsJson =\n (await actionsRes.json()) as ApiListResponse<PermissionAction>;\n const permissionsJson =\n (await permissionsRes.json()) as ApiListResponse<Permission>;\n const rolePermissionsJson =\n (await rolePermissionsRes.json()) as ApiListResponse<RolePermission>;\n\n setFeatures(\n featuresJson.docs?.sort(\n (a, b) => (a?.sortOrder ?? 0) - (b?.sortOrder ?? 0),\n ) || [],\n );\n setActions(\n actionsJson.docs?.sort(\n (a, b) => (a?.sortOrder ?? 0) - (b?.sortOrder ?? 0),\n ) || [],\n );\n setPermissions(permissionsJson.docs || []);\n setRolePermissions(rolePermissionsJson.docs || []);\n } finally {\n setLoading(false);\n }\n };\n\n void run();\n }, [config?.routes?.api, id]);\n\n const enabledByPermissionID = useMemo(() => {\n const map = new Map<string, boolean>();\n for (const row of rolePermissions) {\n map.set(toID(row.permission), Boolean(row.enabled));\n }\n return map;\n }, [rolePermissions]);\n\n const draftValue = (\n value && typeof value === \"object\" && !Array.isArray(value) ? value : {}\n ) as Record<string, boolean>;\n\n useEffect(() => {\n if (!id || loading) {\n return;\n }\n\n const roleId = String(id);\n if (seededForRoleIdRef.current === roleId) {\n return;\n }\n\n const fromRolesPermissions: Record<string, boolean> = {};\n for (const [permissionID, enabled] of enabledByPermissionID.entries()) {\n if (permissionID) {\n fromRolesPermissions[permissionID] = enabled;\n }\n }\n\n const fromDocument =\n value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, boolean>)\n : {};\n\n const hasRolesPermissions = Object.keys(fromRolesPermissions).length > 0;\n const hasDocumentDraft = Object.keys(fromDocument).length > 0;\n\n if (!hasRolesPermissions && !hasDocumentDraft) {\n return;\n }\n\n seededForRoleIdRef.current = roleId;\n setValue({\n ...fromRolesPermissions,\n ...fromDocument,\n });\n }, [enabledByPermissionID, id, loading, setValue, value]);\n\n if (!id) {\n return (\n <div className={styles[`${RBAC_PREFIX}-component-placeholder`]}>\n {t(\n `components:rolePermissionMatrix:viewInUpdateScreenOnly:label` as Parameters<\n typeof t\n >[0],\n )}\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className={styles[`${RBAC_PREFIX}-component-placeholder`]}>\n {t(\n `components:rolePermissionMatrix:loading:placeholder` as Parameters<\n typeof t\n >[0],\n )}\n </div>\n );\n }\n\n return (\n <div>\n <div className={styles[`${RBAC_PREFIX}-component-title`]}>\n {t(`components:rolePermissionMatrix:title` as Parameters<typeof t>[0])}\n </div>\n\n <div className={styles[`${RBAC_PREFIX}-table-container`]}>\n <table className={styles[`${RBAC_PREFIX}-table`]}>\n <thead>\n <tr>\n <th className={styles[`${RBAC_PREFIX}-table-th-feature`]}>\n {t(\n `components:rolePermissionMatrix:features:label` as Parameters<\n typeof t\n >[0],\n )}\n </th>\n <th\n className={styles[`${RBAC_PREFIX}-table-th-action`]}\n colSpan={\n actions.filter((action) => action.type === TYPE.MAIN).length\n }\n >\n {t(\n `components:rolePermissionMatrix:actions:label` as Parameters<\n typeof t\n >[0],\n )}\n </th>\n </tr>\n </thead>\n <tbody>\n {features.map((feature) => {\n const mainActions = actions.filter(\n (action) => action.type === TYPE.MAIN,\n );\n const subActions = actions.filter(\n (action) =>\n action.type === TYPE.SUB &&\n permissions.some(\n (permission) =>\n toID(permission.permissionAction) === String(action.id) &&\n toID(permission.permissionFeature) === String(feature.id),\n ),\n );\n const isSubActionInPermission = subActions.length > 0;\n\n return (\n <Fragment key={String(feature.id)}>\n <tr>\n <td className={styles[`${RBAC_PREFIX}-table-td-feature`]}>\n {t(\n `components:rolePermissionMatrix:features:${feature.code}` as Parameters<\n typeof t\n >[0],\n ) || feature.id}\n </td>\n\n {mainActions.map((action) => {\n const matchedPermission = permissions.find(\n (permission) =>\n toID(permission.permissionFeature) ===\n String(feature.id) &&\n toID(permission.permissionAction) ===\n String(action.id),\n );\n\n if (!matchedPermission) {\n return (\n <td\n key={`${feature.id}-${action.id}`}\n className={styles[`${RBAC_PREFIX}-table-td-action`]}\n >\n -\n </td>\n );\n }\n\n const permissionID = String(matchedPermission.id);\n const checked =\n typeof draftValue[permissionID] === \"boolean\"\n ? draftValue[permissionID]\n : (enabledByPermissionID.get(permissionID) ?? false);\n\n return (\n <td\n key={`${feature.id}-${action.id}`}\n className={styles[`${RBAC_PREFIX}-table-td-action`]}\n >\n <div\n className={\n styles[`${RBAC_PREFIX}-table-td-action-container`]\n }\n >\n <input\n type=\"checkbox\"\n id={`permission-matrix-checkbox-${checkboxId}-${feature.id}-${action.id}`}\n name={`permission-matrix-checkbox-${checkboxId}-${feature.id}-${action.id}`}\n checked={checked}\n disabled={isReadOnly}\n onChange={(event) => {\n setValue({\n ...draftValue,\n [permissionID]: event.target.checked,\n });\n }}\n className={\n styles[`${RBAC_PREFIX}-table-td-action-input`]\n }\n />\n <label\n htmlFor={`permission-matrix-checkbox-${checkboxId}-${feature.id}-${action.id}`}\n className={\n styles[`${RBAC_PREFIX}-table-td-action-label`]\n }\n >\n {t(\n `components:rolePermissionMatrix:actions:${action.code}` as Parameters<\n typeof t\n >[0],\n ) || action.id}\n </label>\n </div>\n </td>\n );\n })}\n </tr>\n\n {isSubActionInPermission && (\n <tr>\n <td\n className={styles[`${RBAC_PREFIX}-table-td-feature`]}\n ></td>\n <td\n className={styles[`${RBAC_PREFIX}-table-td-action`]}\n colSpan={mainActions.length}\n >\n {subActions.map((action) => {\n const matchedPermission = permissions.find(\n (permission) =>\n toID(permission.permissionFeature) ===\n String(feature.id) &&\n toID(permission.permissionAction) ===\n String(action.id),\n );\n\n if (!matchedPermission) {\n return null;\n }\n\n const permissionID = String(matchedPermission.id);\n const checked =\n typeof draftValue[permissionID] === \"boolean\"\n ? draftValue[permissionID]\n : (enabledByPermissionID.get(permissionID) ??\n false);\n\n return (\n <div key={`${feature.id}-${action.id}-sub`}>\n <input\n type=\"checkbox\"\n checked={checked}\n disabled={isReadOnly}\n onChange={(event) => {\n setValue({\n ...draftValue,\n [permissionID]: event.target.checked,\n });\n }}\n />{\" \"}\n <span\n style={{\n display: \"inline-block\",\n }}\n >\n {action.code || action.id}\n </span>\n </div>\n );\n })}\n </td>\n </tr>\n )}\n </Fragment>\n );\n })}\n </tbody>\n </table>\n </div>\n </div>\n );\n};\n"],"names":["useConfig","useDocumentInfo","useField","useTranslation","Fragment","useEffect","useId","useMemo","useRef","useState","STATUS","PERMISSION_STATUS","PERMISSION_ACTION_STATUS","TYPE","PERMISSION_FEATURE_STATUS","toID","styles","RBAC_PREFIX","RolePermissionMatrixClient","checkboxId","config","hasSavePermission","id","setValue","value","path","isReadOnly","features","setFeatures","actions","setActions","permissions","setPermissions","rolePermissions","setRolePermissions","loading","setLoading","t","seededForRoleIdRef","run","base","routes","api","featuresRes","actionsRes","permissionsRes","rolePermissionsRes","Promise","all","fetch","ACTIVE","credentials","resolve","Response","JSON","stringify","docs","featuresJson","json","actionsJson","permissionsJson","rolePermissionsJson","sort","a","b","sortOrder","enabledByPermissionID","map","Map","row","set","permission","Boolean","enabled","draftValue","Array","isArray","roleId","String","current","fromRolesPermissions","permissionID","entries","fromDocument","hasRolesPermissions","Object","keys","length","hasDocumentDraft","div","className","table","thead","tr","th","colSpan","filter","action","type","MAIN","tbody","feature","mainActions","subActions","SUB","some","permissionAction","permissionFeature","isSubActionInPermission","td","code","matchedPermission","find","checked","get","input","name","disabled","onChange","event","target","label","htmlFor","span","style","display"],"mappings":"AAAA;;AAEA,SACEA,SAAS,EACTC,eAAe,EACfC,QAAQ,EACRC,cAAc,QACT,iBAAiB;AACxB,SAASC,QAAQ,EAAEC,SAAS,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAK9E,SAASC,UAAUC,iBAAiB,QAAQ,oCAAoC;AAChF,SACED,UAAUE,wBAAwB,EAClCC,IAAI,QACC,2CAA2C;AAClD,SAASH,UAAUI,yBAAyB,QAAQ,4CAA4C;AAChG,SAASC,IAAI,QAAQ,0BAA0B;AAE/C,OAAOC,YAAY,uBAAuB;AAE1C,MAAMC,cAAc;AAMpB,OAAO,MAAMC,6BAA6B;IACxC,MAAMC,aAAab;IACnB,MAAM,EAAEc,MAAM,EAAE,GAAGpB;IACnB,MAAM,EAAEqB,iBAAiB,EAAEC,EAAE,EAAE,GAAGrB;IAClC,MAAM,EAAEsB,QAAQ,EAAEC,KAAK,EAAE,GAAGtB,SAAyC;QACnEuB,MAAM;IACR;IACA,MAAMC,aAAa,CAACL;IAEpB,MAAM,CAACM,UAAUC,YAAY,GAAGnB,SAA8B,EAAE;IAChE,MAAM,CAACoB,SAASC,WAAW,GAAGrB,SAA6B,EAAE;IAC7D,MAAM,CAACsB,aAAaC,eAAe,GAAGvB,SAAuB,EAAE;IAC/D,MAAM,CAACwB,iBAAiBC,mBAAmB,GAAGzB,SAA2B,EAAE;IAC3E,MAAM,CAAC0B,SAASC,WAAW,GAAG3B,SAAS;IACvC,MAAM,EAAE4B,CAAC,EAAE,GAAGlC;IACd,MAAMmC,qBAAqB9B,OAAsB;IAEjDH,UAAU;QACR,MAAMkC,MAAM;YACVH,WAAW;YACX,IAAI;gBACF,MAAMI,OAAOpB,QAAQqB,QAAQC,OAAO;gBAEpC,MAAM,CAACC,aAAaC,YAAYC,gBAAgBC,mBAAmB,GACjE,MAAMC,QAAQC,GAAG,CAAC;oBAChBC,MACE,GAAGT,KAAK,2DAA2D,EAAE1B,0BAA0BoC,MAAM,EAAE,EACvG;wBAAEC,aAAa;oBAAU;oBAE3BF,MACE,GAAGT,KAAK,0DAA0D,EAAE5B,yBAAyBsC,MAAM,EAAE,EACrG;wBAAEC,aAAa;oBAAU;oBAE3BF,MACE,GAAGT,KAAK,mDAAmD,EAAE7B,kBAAkBuC,MAAM,EAAE,EACvF;wBAAEC,aAAa;oBAAU;oBAE3B7B,KACI2B,MACE,GAAGT,KAAK,uDAAuD,EAAElB,IAAI,EACrE;wBACE6B,aAAa;oBACf,KAEFJ,QAAQK,OAAO,CAAC,IAAIC,SAASC,KAAKC,SAAS,CAAC;wBAAEC,MAAM,EAAE;oBAAC;iBAC5D;gBAEH,MAAMC,eACH,MAAMd,YAAYe,IAAI;gBACzB,MAAMC,cACH,MAAMf,WAAWc,IAAI;gBACxB,MAAME,kBACH,MAAMf,eAAea,IAAI;gBAC5B,MAAMG,sBACH,MAAMf,mBAAmBY,IAAI;gBAEhC9B,YACE6B,aAAaD,IAAI,EAAEM,KACjB,CAACC,GAAGC,IAAM,AAACD,CAAAA,GAAGE,aAAa,CAAA,IAAMD,CAAAA,GAAGC,aAAa,CAAA,MAC9C,EAAE;gBAETnC,WACE6B,YAAYH,IAAI,EAAEM,KAChB,CAACC,GAAGC,IAAM,AAACD,CAAAA,GAAGE,aAAa,CAAA,IAAMD,CAAAA,GAAGC,aAAa,CAAA,MAC9C,EAAE;gBAETjC,eAAe4B,gBAAgBJ,IAAI,IAAI,EAAE;gBACzCtB,mBAAmB2B,oBAAoBL,IAAI,IAAI,EAAE;YACnD,SAAU;gBACRpB,WAAW;YACb;QACF;QAEA,KAAKG;IACP,GAAG;QAACnB,QAAQqB,QAAQC;QAAKpB;KAAG;IAE5B,MAAM4C,wBAAwB3D,QAAQ;QACpC,MAAM4D,MAAM,IAAIC;QAChB,KAAK,MAAMC,OAAOpC,gBAAiB;YACjCkC,IAAIG,GAAG,CAACvD,KAAKsD,IAAIE,UAAU,GAAGC,QAAQH,IAAII,OAAO;QACnD;QACA,OAAON;IACT,GAAG;QAAClC;KAAgB;IAEpB,MAAMyC,aACJlD,SAAS,OAAOA,UAAU,YAAY,CAACmD,MAAMC,OAAO,CAACpD,SAASA,QAAQ,CAAC;IAGzEnB,UAAU;QACR,IAAI,CAACiB,MAAMa,SAAS;YAClB;QACF;QAEA,MAAM0C,SAASC,OAAOxD;QACtB,IAAIgB,mBAAmByC,OAAO,KAAKF,QAAQ;YACzC;QACF;QAEA,MAAMG,uBAAgD,CAAC;QACvD,KAAK,MAAM,CAACC,cAAcR,QAAQ,IAAIP,sBAAsBgB,OAAO,GAAI;YACrE,IAAID,cAAc;gBAChBD,oBAAoB,CAACC,aAAa,GAAGR;YACvC;QACF;QAEA,MAAMU,eACJ3D,SAAS,OAAOA,UAAU,YAAY,CAACmD,MAAMC,OAAO,CAACpD,SAChDA,QACD,CAAC;QAEP,MAAM4D,sBAAsBC,OAAOC,IAAI,CAACN,sBAAsBO,MAAM,GAAG;QACvE,MAAMC,mBAAmBH,OAAOC,IAAI,CAACH,cAAcI,MAAM,GAAG;QAE5D,IAAI,CAACH,uBAAuB,CAACI,kBAAkB;YAC7C;QACF;QAEAlD,mBAAmByC,OAAO,GAAGF;QAC7BtD,SAAS;YACP,GAAGyD,oBAAoB;YACvB,GAAGG,YAAY;QACjB;IACF,GAAG;QAACjB;QAAuB5C;QAAIa;QAASZ;QAAUC;KAAM;IAExD,IAAI,CAACF,IAAI;QACP,qBACE,KAACmE;YAAIC,WAAW1E,MAAM,CAAC,GAAGC,YAAY,sBAAsB,CAAC,CAAC;sBAC3DoB,EACC,CAAC,4DAA4D,CAAC;;IAMtE;IAEA,IAAIF,SAAS;QACX,qBACE,KAACsD;YAAIC,WAAW1E,MAAM,CAAC,GAAGC,YAAY,sBAAsB,CAAC,CAAC;sBAC3DoB,EACC,CAAC,mDAAmD,CAAC;;IAM7D;IAEA,qBACE,MAACoD;;0BACC,KAACA;gBAAIC,WAAW1E,MAAM,CAAC,GAAGC,YAAY,gBAAgB,CAAC,CAAC;0BACrDoB,EAAE,CAAC,qCAAqC,CAAC;;0BAG5C,KAACoD;gBAAIC,WAAW1E,MAAM,CAAC,GAAGC,YAAY,gBAAgB,CAAC,CAAC;0BACtD,cAAA,MAAC0E;oBAAMD,WAAW1E,MAAM,CAAC,GAAGC,YAAY,MAAM,CAAC,CAAC;;sCAC9C,KAAC2E;sCACC,cAAA,MAACC;;kDACC,KAACC;wCAAGJ,WAAW1E,MAAM,CAAC,GAAGC,YAAY,iBAAiB,CAAC,CAAC;kDACrDoB,EACC,CAAC,8CAA8C,CAAC;;kDAKpD,KAACyD;wCACCJ,WAAW1E,MAAM,CAAC,GAAGC,YAAY,gBAAgB,CAAC,CAAC;wCACnD8E,SACElE,QAAQmE,MAAM,CAAC,CAACC,SAAWA,OAAOC,IAAI,KAAKrF,KAAKsF,IAAI,EAAEZ,MAAM;kDAG7DlD,EACC,CAAC,6CAA6C,CAAC;;;;;sCAOvD,KAAC+D;sCACEzE,SAASwC,GAAG,CAAC,CAACkC;gCACb,MAAMC,cAAczE,QAAQmE,MAAM,CAChC,CAACC,SAAWA,OAAOC,IAAI,KAAKrF,KAAKsF,IAAI;gCAEvC,MAAMI,aAAa1E,QAAQmE,MAAM,CAC/B,CAACC,SACCA,OAAOC,IAAI,KAAKrF,KAAK2F,GAAG,IACxBzE,YAAY0E,IAAI,CACd,CAAClC,aACCxD,KAAKwD,WAAWmC,gBAAgB,MAAM5B,OAAOmB,OAAO3E,EAAE,KACtDP,KAAKwD,WAAWoC,iBAAiB,MAAM7B,OAAOuB,QAAQ/E,EAAE;gCAGhE,MAAMsF,0BAA0BL,WAAWhB,MAAM,GAAG;gCAEpD,qBACE,MAACnF;;sDACC,MAACyF;;8DACC,KAACgB;oDAAGnB,WAAW1E,MAAM,CAAC,GAAGC,YAAY,iBAAiB,CAAC,CAAC;8DACrDoB,EACC,CAAC,yCAAyC,EAAEgE,QAAQS,IAAI,EAAE,KAGvDT,QAAQ/E,EAAE;;gDAGhBgF,YAAYnC,GAAG,CAAC,CAAC8B;oDAChB,MAAMc,oBAAoBhF,YAAYiF,IAAI,CACxC,CAACzC,aACCxD,KAAKwD,WAAWoC,iBAAiB,MAC/B7B,OAAOuB,QAAQ/E,EAAE,KACnBP,KAAKwD,WAAWmC,gBAAgB,MAC9B5B,OAAOmB,OAAO3E,EAAE;oDAGtB,IAAI,CAACyF,mBAAmB;wDACtB,qBACE,KAACF;4DAECnB,WAAW1E,MAAM,CAAC,GAAGC,YAAY,gBAAgB,CAAC,CAAC;sEACpD;2DAFM,GAAGoF,QAAQ/E,EAAE,CAAC,CAAC,EAAE2E,OAAO3E,EAAE,EAAE;oDAMvC;oDAEA,MAAM2D,eAAeH,OAAOiC,kBAAkBzF,EAAE;oDAChD,MAAM2F,UACJ,OAAOvC,UAAU,CAACO,aAAa,KAAK,YAChCP,UAAU,CAACO,aAAa,GACvBf,sBAAsBgD,GAAG,CAACjC,iBAAiB;oDAElD,qBACE,KAAC4B;wDAECnB,WAAW1E,MAAM,CAAC,GAAGC,YAAY,gBAAgB,CAAC,CAAC;kEAEnD,cAAA,MAACwE;4DACCC,WACE1E,MAAM,CAAC,GAAGC,YAAY,0BAA0B,CAAC,CAAC;;8EAGpD,KAACkG;oEACCjB,MAAK;oEACL5E,IAAI,CAAC,2BAA2B,EAAEH,WAAW,CAAC,EAAEkF,QAAQ/E,EAAE,CAAC,CAAC,EAAE2E,OAAO3E,EAAE,EAAE;oEACzE8F,MAAM,CAAC,2BAA2B,EAAEjG,WAAW,CAAC,EAAEkF,QAAQ/E,EAAE,CAAC,CAAC,EAAE2E,OAAO3E,EAAE,EAAE;oEAC3E2F,SAASA;oEACTI,UAAU3F;oEACV4F,UAAU,CAACC;wEACThG,SAAS;4EACP,GAAGmD,UAAU;4EACb,CAACO,aAAa,EAAEsC,MAAMC,MAAM,CAACP,OAAO;wEACtC;oEACF;oEACAvB,WACE1E,MAAM,CAAC,GAAGC,YAAY,sBAAsB,CAAC,CAAC;;8EAGlD,KAACwG;oEACCC,SAAS,CAAC,2BAA2B,EAAEvG,WAAW,CAAC,EAAEkF,QAAQ/E,EAAE,CAAC,CAAC,EAAE2E,OAAO3E,EAAE,EAAE;oEAC9EoE,WACE1E,MAAM,CAAC,GAAGC,YAAY,sBAAsB,CAAC,CAAC;8EAG/CoB,EACC,CAAC,wCAAwC,EAAE4D,OAAOa,IAAI,EAAE,KAGrDb,OAAO3E,EAAE;;;;uDAlCb,GAAG+E,QAAQ/E,EAAE,CAAC,CAAC,EAAE2E,OAAO3E,EAAE,EAAE;gDAuCvC;;;wCAGDsF,yCACC,MAACf;;8DACC,KAACgB;oDACCnB,WAAW1E,MAAM,CAAC,GAAGC,YAAY,iBAAiB,CAAC,CAAC;;8DAEtD,KAAC4F;oDACCnB,WAAW1E,MAAM,CAAC,GAAGC,YAAY,gBAAgB,CAAC,CAAC;oDACnD8E,SAASO,YAAYf,MAAM;8DAE1BgB,WAAWpC,GAAG,CAAC,CAAC8B;wDACf,MAAMc,oBAAoBhF,YAAYiF,IAAI,CACxC,CAACzC,aACCxD,KAAKwD,WAAWoC,iBAAiB,MAC/B7B,OAAOuB,QAAQ/E,EAAE,KACnBP,KAAKwD,WAAWmC,gBAAgB,MAC9B5B,OAAOmB,OAAO3E,EAAE;wDAGtB,IAAI,CAACyF,mBAAmB;4DACtB,OAAO;wDACT;wDAEA,MAAM9B,eAAeH,OAAOiC,kBAAkBzF,EAAE;wDAChD,MAAM2F,UACJ,OAAOvC,UAAU,CAACO,aAAa,KAAK,YAChCP,UAAU,CAACO,aAAa,GACvBf,sBAAsBgD,GAAG,CAACjC,iBAC3B;wDAEN,qBACE,MAACQ;;8EACC,KAAC0B;oEACCjB,MAAK;oEACLe,SAASA;oEACTI,UAAU3F;oEACV4F,UAAU,CAACC;wEACThG,SAAS;4EACP,GAAGmD,UAAU;4EACb,CAACO,aAAa,EAAEsC,MAAMC,MAAM,CAACP,OAAO;wEACtC;oEACF;;gEACC;8EACH,KAACU;oEACCC,OAAO;wEACLC,SAAS;oEACX;8EAEC5B,OAAOa,IAAI,IAAIb,OAAO3E,EAAE;;;2DAjBnB,GAAG+E,QAAQ/E,EAAE,CAAC,CAAC,EAAE2E,OAAO3E,EAAE,CAAC,IAAI,CAAC;oDAqB9C;;;;;mCAnIOwD,OAAOuB,QAAQ/E,EAAE;4BAyIpC;;;;;;;AAMZ,EAAE"}
1
+ {"version":3,"sources":["../../../src/components/role-permission-matrix-client/index.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useConfig,\n useDocumentInfo,\n useField,\n useTranslation,\n} from \"@payloadcms/ui\";\nimport { Fragment, useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport type { PermissionAction } from \"../../collections/permission-actions/types.js\";\nimport type { PermissionFeature } from \"../../collections/permission-features/types.js\";\nimport type { Permission } from \"../../collections/permissions/types.js\";\nimport type { RolePermission } from \"../../collections/roles-permissions/types.js\";\nimport { STATUS as PERMISSION_STATUS } from \"../../lib/constants/permission.js\";\nimport {\n STATUS as PERMISSION_ACTION_STATUS,\n TYPE,\n} from \"../../lib/constants/permission-action.js\";\nimport { STATUS as PERMISSION_FEATURE_STATUS } from \"../../lib/constants/permission-feature.js\";\nimport { toID } from \"../../lib/utils/data.js\";\n\nimport styles from \"./matrix.module.scss\";\n\nconst RBAC_PREFIX = \"rbac\";\n\ntype ApiListResponse<T> = {\n docs?: T[];\n};\n\nexport const RolePermissionMatrixClient = () => {\n const checkboxId = useId();\n const { config } = useConfig();\n const { hasSavePermission, id } = useDocumentInfo();\n const { setValue, value } = useField<Record<string, boolean> | null>({\n path: \"permissionMatrixDraft\",\n });\n const isReadOnly = !hasSavePermission;\n\n const [features, setFeatures] = useState<PermissionFeature[]>([]);\n const [actions, setActions] = useState<PermissionAction[]>([]);\n const [permissions, setPermissions] = useState<Permission[]>([]);\n const [rolePermissions, setRolePermissions] = useState<RolePermission[]>([]);\n const [loading, setLoading] = useState(true);\n const { t } = useTranslation();\n const seededForRoleIdRef = useRef<string | null>(null);\n\n useEffect(() => {\n const run = async () => {\n setLoading(true);\n try {\n const base = config?.routes?.api || \"/api\";\n\n const [featuresRes, actionsRes, permissionsRes, rolePermissionsRes] =\n await Promise.all([\n fetch(\n `${base}/permission-features?limit=0&depth=0&where[status][equals]=${PERMISSION_FEATURE_STATUS.ACTIVE}`,\n { credentials: \"include\" },\n ),\n fetch(\n `${base}/permission-actions?limit=0&depth=0&where[status][equals]=${PERMISSION_ACTION_STATUS.ACTIVE}`,\n { credentials: \"include\" },\n ),\n fetch(\n `${base}/permissions?limit=0&depth=1&where[status][equals]=${PERMISSION_STATUS.ACTIVE}`,\n { credentials: \"include\" },\n ),\n id\n ? fetch(\n `${base}/roles-permissions?limit=0&depth=0&where[role][equals]=${id}`,\n {\n credentials: \"include\",\n },\n )\n : Promise.resolve(new Response(JSON.stringify({ docs: [] }))),\n ]);\n\n const featuresJson =\n (await featuresRes.json()) as ApiListResponse<PermissionFeature>;\n const actionsJson =\n (await actionsRes.json()) as ApiListResponse<PermissionAction>;\n const permissionsJson =\n (await permissionsRes.json()) as ApiListResponse<Permission>;\n const rolePermissionsJson =\n (await rolePermissionsRes.json()) as ApiListResponse<RolePermission>;\n\n setFeatures(\n featuresJson.docs?.sort(\n (a, b) => (a?.sortOrder ?? 0) - (b?.sortOrder ?? 0),\n ) || [],\n );\n setActions(\n actionsJson.docs?.sort(\n (a, b) => (a?.sortOrder ?? 0) - (b?.sortOrder ?? 0),\n ) || [],\n );\n setPermissions(permissionsJson.docs || []);\n setRolePermissions(rolePermissionsJson.docs || []);\n } finally {\n setLoading(false);\n }\n };\n\n void run();\n }, [config?.routes?.api, id]);\n\n const enabledByPermissionID = useMemo(() => {\n const map = new Map<string, boolean>();\n for (const row of rolePermissions) {\n map.set(toID(row.permission), Boolean(row.enabled));\n }\n return map;\n }, [rolePermissions]);\n\n const draftValue = (\n value && typeof value === \"object\" && !Array.isArray(value) ? value : {}\n ) as Record<string, boolean>;\n\n useEffect(() => {\n if (!id || loading) {\n return;\n }\n\n const roleId = String(id);\n if (seededForRoleIdRef.current === roleId) {\n return;\n }\n\n const fromRolesPermissions: Record<string, boolean> = {};\n for (const [permissionID, enabled] of enabledByPermissionID.entries()) {\n if (permissionID) {\n fromRolesPermissions[permissionID] = enabled;\n }\n }\n\n const fromDocument =\n value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, boolean>)\n : {};\n\n const hasRolesPermissions = Object.keys(fromRolesPermissions).length > 0;\n const hasDocumentDraft = Object.keys(fromDocument).length > 0;\n\n if (!hasRolesPermissions && !hasDocumentDraft) {\n return;\n }\n\n seededForRoleIdRef.current = roleId;\n setValue({\n ...fromRolesPermissions,\n ...fromDocument,\n });\n }, [enabledByPermissionID, id, loading, setValue, value]);\n\n if (!id) {\n return (\n <div className={styles[`${RBAC_PREFIX}-component-placeholder`]}>\n {t(\n `components:rolePermissionMatrix:viewInUpdateScreenOnly:label` as Parameters<\n typeof t\n >[0],\n )}\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className={styles[`${RBAC_PREFIX}-component-placeholder`]}>\n {t(\n `components:rolePermissionMatrix:loading:placeholder` as Parameters<\n typeof t\n >[0],\n )}\n </div>\n );\n }\n\n return (\n <div>\n <div className={styles[`${RBAC_PREFIX}-component-title`]}>\n {t(`components:rolePermissionMatrix:title` as Parameters<typeof t>[0])}\n </div>\n\n <div className={styles[`${RBAC_PREFIX}-table-container`]}>\n <table className={styles[`${RBAC_PREFIX}-table`]}>\n <thead>\n <tr>\n <th className={styles[`${RBAC_PREFIX}-table-th-feature`]}>\n {t(\n `components:rolePermissionMatrix:featuresLabel` as Parameters<\n typeof t\n >[0],\n )}\n </th>\n <th\n className={styles[`${RBAC_PREFIX}-table-th-action`]}\n colSpan={\n actions.filter((action) => action.type === TYPE.MAIN).length\n }\n >\n {t(\n `components:rolePermissionMatrix:actionsLabel` as Parameters<\n typeof t\n >[0],\n )}\n </th>\n </tr>\n </thead>\n <tbody>\n {features.map((feature) => {\n const mainActions = actions.filter(\n (action) => action.type === TYPE.MAIN,\n );\n const subActions = actions.filter(\n (action) =>\n action.type === TYPE.SUB &&\n permissions.some(\n (permission) =>\n toID(permission.permissionAction) === String(action.id) &&\n toID(permission.permissionFeature) === String(feature.id),\n ),\n );\n const isSubActionInPermission = subActions.length > 0;\n\n return (\n <Fragment key={String(feature.id)}>\n <tr>\n <td className={styles[`${RBAC_PREFIX}-table-td-feature`]}>\n {t(\n `components:rolePermissionMatrix:features:${feature.code}` as Parameters<\n typeof t\n >[0],\n ) || feature.id}\n </td>\n\n {mainActions.map((action) => {\n const matchedPermission = permissions.find(\n (permission) =>\n toID(permission.permissionFeature) ===\n String(feature.id) &&\n toID(permission.permissionAction) ===\n String(action.id),\n );\n\n if (!matchedPermission) {\n return (\n <td\n key={`${feature.id}-${action.id}`}\n className={styles[`${RBAC_PREFIX}-table-td-action`]}\n >\n -\n </td>\n );\n }\n\n const permissionID = String(matchedPermission.id);\n const checked =\n typeof draftValue[permissionID] === \"boolean\"\n ? draftValue[permissionID]\n : (enabledByPermissionID.get(permissionID) ?? false);\n\n return (\n <td\n key={`${feature.id}-${action.id}`}\n className={styles[`${RBAC_PREFIX}-table-td-action`]}\n >\n <div\n className={\n styles[`${RBAC_PREFIX}-table-td-action-container`]\n }\n >\n <input\n type=\"checkbox\"\n id={`permission-matrix-checkbox-${checkboxId}-${feature.id}-${action.id}`}\n name={`permission-matrix-checkbox-${checkboxId}-${feature.id}-${action.id}`}\n checked={checked}\n disabled={isReadOnly}\n onChange={(event) => {\n setValue({\n ...draftValue,\n [permissionID]: event.target.checked,\n });\n }}\n className={\n styles[`${RBAC_PREFIX}-table-td-action-input`]\n }\n />\n <label\n htmlFor={`permission-matrix-checkbox-${checkboxId}-${feature.id}-${action.id}`}\n className={\n styles[`${RBAC_PREFIX}-table-td-action-label`]\n }\n >\n {t(\n `components:rolePermissionMatrix:actions:${action.code}` as Parameters<\n typeof t\n >[0],\n ) || action.id}\n </label>\n </div>\n </td>\n );\n })}\n </tr>\n\n {isSubActionInPermission && (\n <tr>\n <td\n className={styles[`${RBAC_PREFIX}-table-td-feature`]}\n ></td>\n <td\n className={styles[`${RBAC_PREFIX}-table-td-action`]}\n colSpan={mainActions.length}\n >\n {subActions.map((action) => {\n const matchedPermission = permissions.find(\n (permission) =>\n toID(permission.permissionFeature) ===\n String(feature.id) &&\n toID(permission.permissionAction) ===\n String(action.id),\n );\n\n if (!matchedPermission) {\n return null;\n }\n\n const permissionID = String(matchedPermission.id);\n const checked =\n typeof draftValue[permissionID] === \"boolean\"\n ? draftValue[permissionID]\n : (enabledByPermissionID.get(permissionID) ??\n false);\n\n return (\n <div key={`${feature.id}-${action.id}-sub`}>\n <input\n type=\"checkbox\"\n checked={checked}\n disabled={isReadOnly}\n onChange={(event) => {\n setValue({\n ...draftValue,\n [permissionID]: event.target.checked,\n });\n }}\n />{\" \"}\n <span\n style={{\n display: \"inline-block\",\n }}\n >\n {action.code || action.id}\n </span>\n </div>\n );\n })}\n </td>\n </tr>\n )}\n </Fragment>\n );\n })}\n </tbody>\n </table>\n </div>\n </div>\n );\n};\n"],"names":["useConfig","useDocumentInfo","useField","useTranslation","Fragment","useEffect","useId","useMemo","useRef","useState","STATUS","PERMISSION_STATUS","PERMISSION_ACTION_STATUS","TYPE","PERMISSION_FEATURE_STATUS","toID","styles","RBAC_PREFIX","RolePermissionMatrixClient","checkboxId","config","hasSavePermission","id","setValue","value","path","isReadOnly","features","setFeatures","actions","setActions","permissions","setPermissions","rolePermissions","setRolePermissions","loading","setLoading","t","seededForRoleIdRef","run","base","routes","api","featuresRes","actionsRes","permissionsRes","rolePermissionsRes","Promise","all","fetch","ACTIVE","credentials","resolve","Response","JSON","stringify","docs","featuresJson","json","actionsJson","permissionsJson","rolePermissionsJson","sort","a","b","sortOrder","enabledByPermissionID","map","Map","row","set","permission","Boolean","enabled","draftValue","Array","isArray","roleId","String","current","fromRolesPermissions","permissionID","entries","fromDocument","hasRolesPermissions","Object","keys","length","hasDocumentDraft","div","className","table","thead","tr","th","colSpan","filter","action","type","MAIN","tbody","feature","mainActions","subActions","SUB","some","permissionAction","permissionFeature","isSubActionInPermission","td","code","matchedPermission","find","checked","get","input","name","disabled","onChange","event","target","label","htmlFor","span","style","display"],"mappings":"AAAA;;AAEA,SACEA,SAAS,EACTC,eAAe,EACfC,QAAQ,EACRC,cAAc,QACT,iBAAiB;AACxB,SAASC,QAAQ,EAAEC,SAAS,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAK9E,SAASC,UAAUC,iBAAiB,QAAQ,oCAAoC;AAChF,SACED,UAAUE,wBAAwB,EAClCC,IAAI,QACC,2CAA2C;AAClD,SAASH,UAAUI,yBAAyB,QAAQ,4CAA4C;AAChG,SAASC,IAAI,QAAQ,0BAA0B;AAE/C,OAAOC,YAAY,uBAAuB;AAE1C,MAAMC,cAAc;AAMpB,OAAO,MAAMC,6BAA6B;IACxC,MAAMC,aAAab;IACnB,MAAM,EAAEc,MAAM,EAAE,GAAGpB;IACnB,MAAM,EAAEqB,iBAAiB,EAAEC,EAAE,EAAE,GAAGrB;IAClC,MAAM,EAAEsB,QAAQ,EAAEC,KAAK,EAAE,GAAGtB,SAAyC;QACnEuB,MAAM;IACR;IACA,MAAMC,aAAa,CAACL;IAEpB,MAAM,CAACM,UAAUC,YAAY,GAAGnB,SAA8B,EAAE;IAChE,MAAM,CAACoB,SAASC,WAAW,GAAGrB,SAA6B,EAAE;IAC7D,MAAM,CAACsB,aAAaC,eAAe,GAAGvB,SAAuB,EAAE;IAC/D,MAAM,CAACwB,iBAAiBC,mBAAmB,GAAGzB,SAA2B,EAAE;IAC3E,MAAM,CAAC0B,SAASC,WAAW,GAAG3B,SAAS;IACvC,MAAM,EAAE4B,CAAC,EAAE,GAAGlC;IACd,MAAMmC,qBAAqB9B,OAAsB;IAEjDH,UAAU;QACR,MAAMkC,MAAM;YACVH,WAAW;YACX,IAAI;gBACF,MAAMI,OAAOpB,QAAQqB,QAAQC,OAAO;gBAEpC,MAAM,CAACC,aAAaC,YAAYC,gBAAgBC,mBAAmB,GACjE,MAAMC,QAAQC,GAAG,CAAC;oBAChBC,MACE,GAAGT,KAAK,2DAA2D,EAAE1B,0BAA0BoC,MAAM,EAAE,EACvG;wBAAEC,aAAa;oBAAU;oBAE3BF,MACE,GAAGT,KAAK,0DAA0D,EAAE5B,yBAAyBsC,MAAM,EAAE,EACrG;wBAAEC,aAAa;oBAAU;oBAE3BF,MACE,GAAGT,KAAK,mDAAmD,EAAE7B,kBAAkBuC,MAAM,EAAE,EACvF;wBAAEC,aAAa;oBAAU;oBAE3B7B,KACI2B,MACE,GAAGT,KAAK,uDAAuD,EAAElB,IAAI,EACrE;wBACE6B,aAAa;oBACf,KAEFJ,QAAQK,OAAO,CAAC,IAAIC,SAASC,KAAKC,SAAS,CAAC;wBAAEC,MAAM,EAAE;oBAAC;iBAC5D;gBAEH,MAAMC,eACH,MAAMd,YAAYe,IAAI;gBACzB,MAAMC,cACH,MAAMf,WAAWc,IAAI;gBACxB,MAAME,kBACH,MAAMf,eAAea,IAAI;gBAC5B,MAAMG,sBACH,MAAMf,mBAAmBY,IAAI;gBAEhC9B,YACE6B,aAAaD,IAAI,EAAEM,KACjB,CAACC,GAAGC,IAAM,AAACD,CAAAA,GAAGE,aAAa,CAAA,IAAMD,CAAAA,GAAGC,aAAa,CAAA,MAC9C,EAAE;gBAETnC,WACE6B,YAAYH,IAAI,EAAEM,KAChB,CAACC,GAAGC,IAAM,AAACD,CAAAA,GAAGE,aAAa,CAAA,IAAMD,CAAAA,GAAGC,aAAa,CAAA,MAC9C,EAAE;gBAETjC,eAAe4B,gBAAgBJ,IAAI,IAAI,EAAE;gBACzCtB,mBAAmB2B,oBAAoBL,IAAI,IAAI,EAAE;YACnD,SAAU;gBACRpB,WAAW;YACb;QACF;QAEA,KAAKG;IACP,GAAG;QAACnB,QAAQqB,QAAQC;QAAKpB;KAAG;IAE5B,MAAM4C,wBAAwB3D,QAAQ;QACpC,MAAM4D,MAAM,IAAIC;QAChB,KAAK,MAAMC,OAAOpC,gBAAiB;YACjCkC,IAAIG,GAAG,CAACvD,KAAKsD,IAAIE,UAAU,GAAGC,QAAQH,IAAII,OAAO;QACnD;QACA,OAAON;IACT,GAAG;QAAClC;KAAgB;IAEpB,MAAMyC,aACJlD,SAAS,OAAOA,UAAU,YAAY,CAACmD,MAAMC,OAAO,CAACpD,SAASA,QAAQ,CAAC;IAGzEnB,UAAU;QACR,IAAI,CAACiB,MAAMa,SAAS;YAClB;QACF;QAEA,MAAM0C,SAASC,OAAOxD;QACtB,IAAIgB,mBAAmByC,OAAO,KAAKF,QAAQ;YACzC;QACF;QAEA,MAAMG,uBAAgD,CAAC;QACvD,KAAK,MAAM,CAACC,cAAcR,QAAQ,IAAIP,sBAAsBgB,OAAO,GAAI;YACrE,IAAID,cAAc;gBAChBD,oBAAoB,CAACC,aAAa,GAAGR;YACvC;QACF;QAEA,MAAMU,eACJ3D,SAAS,OAAOA,UAAU,YAAY,CAACmD,MAAMC,OAAO,CAACpD,SAChDA,QACD,CAAC;QAEP,MAAM4D,sBAAsBC,OAAOC,IAAI,CAACN,sBAAsBO,MAAM,GAAG;QACvE,MAAMC,mBAAmBH,OAAOC,IAAI,CAACH,cAAcI,MAAM,GAAG;QAE5D,IAAI,CAACH,uBAAuB,CAACI,kBAAkB;YAC7C;QACF;QAEAlD,mBAAmByC,OAAO,GAAGF;QAC7BtD,SAAS;YACP,GAAGyD,oBAAoB;YACvB,GAAGG,YAAY;QACjB;IACF,GAAG;QAACjB;QAAuB5C;QAAIa;QAASZ;QAAUC;KAAM;IAExD,IAAI,CAACF,IAAI;QACP,qBACE,KAACmE;YAAIC,WAAW1E,MAAM,CAAC,GAAGC,YAAY,sBAAsB,CAAC,CAAC;sBAC3DoB,EACC,CAAC,4DAA4D,CAAC;;IAMtE;IAEA,IAAIF,SAAS;QACX,qBACE,KAACsD;YAAIC,WAAW1E,MAAM,CAAC,GAAGC,YAAY,sBAAsB,CAAC,CAAC;sBAC3DoB,EACC,CAAC,mDAAmD,CAAC;;IAM7D;IAEA,qBACE,MAACoD;;0BACC,KAACA;gBAAIC,WAAW1E,MAAM,CAAC,GAAGC,YAAY,gBAAgB,CAAC,CAAC;0BACrDoB,EAAE,CAAC,qCAAqC,CAAC;;0BAG5C,KAACoD;gBAAIC,WAAW1E,MAAM,CAAC,GAAGC,YAAY,gBAAgB,CAAC,CAAC;0BACtD,cAAA,MAAC0E;oBAAMD,WAAW1E,MAAM,CAAC,GAAGC,YAAY,MAAM,CAAC,CAAC;;sCAC9C,KAAC2E;sCACC,cAAA,MAACC;;kDACC,KAACC;wCAAGJ,WAAW1E,MAAM,CAAC,GAAGC,YAAY,iBAAiB,CAAC,CAAC;kDACrDoB,EACC,CAAC,6CAA6C,CAAC;;kDAKnD,KAACyD;wCACCJ,WAAW1E,MAAM,CAAC,GAAGC,YAAY,gBAAgB,CAAC,CAAC;wCACnD8E,SACElE,QAAQmE,MAAM,CAAC,CAACC,SAAWA,OAAOC,IAAI,KAAKrF,KAAKsF,IAAI,EAAEZ,MAAM;kDAG7DlD,EACC,CAAC,4CAA4C,CAAC;;;;;sCAOtD,KAAC+D;sCACEzE,SAASwC,GAAG,CAAC,CAACkC;gCACb,MAAMC,cAAczE,QAAQmE,MAAM,CAChC,CAACC,SAAWA,OAAOC,IAAI,KAAKrF,KAAKsF,IAAI;gCAEvC,MAAMI,aAAa1E,QAAQmE,MAAM,CAC/B,CAACC,SACCA,OAAOC,IAAI,KAAKrF,KAAK2F,GAAG,IACxBzE,YAAY0E,IAAI,CACd,CAAClC,aACCxD,KAAKwD,WAAWmC,gBAAgB,MAAM5B,OAAOmB,OAAO3E,EAAE,KACtDP,KAAKwD,WAAWoC,iBAAiB,MAAM7B,OAAOuB,QAAQ/E,EAAE;gCAGhE,MAAMsF,0BAA0BL,WAAWhB,MAAM,GAAG;gCAEpD,qBACE,MAACnF;;sDACC,MAACyF;;8DACC,KAACgB;oDAAGnB,WAAW1E,MAAM,CAAC,GAAGC,YAAY,iBAAiB,CAAC,CAAC;8DACrDoB,EACC,CAAC,yCAAyC,EAAEgE,QAAQS,IAAI,EAAE,KAGvDT,QAAQ/E,EAAE;;gDAGhBgF,YAAYnC,GAAG,CAAC,CAAC8B;oDAChB,MAAMc,oBAAoBhF,YAAYiF,IAAI,CACxC,CAACzC,aACCxD,KAAKwD,WAAWoC,iBAAiB,MAC/B7B,OAAOuB,QAAQ/E,EAAE,KACnBP,KAAKwD,WAAWmC,gBAAgB,MAC9B5B,OAAOmB,OAAO3E,EAAE;oDAGtB,IAAI,CAACyF,mBAAmB;wDACtB,qBACE,KAACF;4DAECnB,WAAW1E,MAAM,CAAC,GAAGC,YAAY,gBAAgB,CAAC,CAAC;sEACpD;2DAFM,GAAGoF,QAAQ/E,EAAE,CAAC,CAAC,EAAE2E,OAAO3E,EAAE,EAAE;oDAMvC;oDAEA,MAAM2D,eAAeH,OAAOiC,kBAAkBzF,EAAE;oDAChD,MAAM2F,UACJ,OAAOvC,UAAU,CAACO,aAAa,KAAK,YAChCP,UAAU,CAACO,aAAa,GACvBf,sBAAsBgD,GAAG,CAACjC,iBAAiB;oDAElD,qBACE,KAAC4B;wDAECnB,WAAW1E,MAAM,CAAC,GAAGC,YAAY,gBAAgB,CAAC,CAAC;kEAEnD,cAAA,MAACwE;4DACCC,WACE1E,MAAM,CAAC,GAAGC,YAAY,0BAA0B,CAAC,CAAC;;8EAGpD,KAACkG;oEACCjB,MAAK;oEACL5E,IAAI,CAAC,2BAA2B,EAAEH,WAAW,CAAC,EAAEkF,QAAQ/E,EAAE,CAAC,CAAC,EAAE2E,OAAO3E,EAAE,EAAE;oEACzE8F,MAAM,CAAC,2BAA2B,EAAEjG,WAAW,CAAC,EAAEkF,QAAQ/E,EAAE,CAAC,CAAC,EAAE2E,OAAO3E,EAAE,EAAE;oEAC3E2F,SAASA;oEACTI,UAAU3F;oEACV4F,UAAU,CAACC;wEACThG,SAAS;4EACP,GAAGmD,UAAU;4EACb,CAACO,aAAa,EAAEsC,MAAMC,MAAM,CAACP,OAAO;wEACtC;oEACF;oEACAvB,WACE1E,MAAM,CAAC,GAAGC,YAAY,sBAAsB,CAAC,CAAC;;8EAGlD,KAACwG;oEACCC,SAAS,CAAC,2BAA2B,EAAEvG,WAAW,CAAC,EAAEkF,QAAQ/E,EAAE,CAAC,CAAC,EAAE2E,OAAO3E,EAAE,EAAE;oEAC9EoE,WACE1E,MAAM,CAAC,GAAGC,YAAY,sBAAsB,CAAC,CAAC;8EAG/CoB,EACC,CAAC,wCAAwC,EAAE4D,OAAOa,IAAI,EAAE,KAGrDb,OAAO3E,EAAE;;;;uDAlCb,GAAG+E,QAAQ/E,EAAE,CAAC,CAAC,EAAE2E,OAAO3E,EAAE,EAAE;gDAuCvC;;;wCAGDsF,yCACC,MAACf;;8DACC,KAACgB;oDACCnB,WAAW1E,MAAM,CAAC,GAAGC,YAAY,iBAAiB,CAAC,CAAC;;8DAEtD,KAAC4F;oDACCnB,WAAW1E,MAAM,CAAC,GAAGC,YAAY,gBAAgB,CAAC,CAAC;oDACnD8E,SAASO,YAAYf,MAAM;8DAE1BgB,WAAWpC,GAAG,CAAC,CAAC8B;wDACf,MAAMc,oBAAoBhF,YAAYiF,IAAI,CACxC,CAACzC,aACCxD,KAAKwD,WAAWoC,iBAAiB,MAC/B7B,OAAOuB,QAAQ/E,EAAE,KACnBP,KAAKwD,WAAWmC,gBAAgB,MAC9B5B,OAAOmB,OAAO3E,EAAE;wDAGtB,IAAI,CAACyF,mBAAmB;4DACtB,OAAO;wDACT;wDAEA,MAAM9B,eAAeH,OAAOiC,kBAAkBzF,EAAE;wDAChD,MAAM2F,UACJ,OAAOvC,UAAU,CAACO,aAAa,KAAK,YAChCP,UAAU,CAACO,aAAa,GACvBf,sBAAsBgD,GAAG,CAACjC,iBAC3B;wDAEN,qBACE,MAACQ;;8EACC,KAAC0B;oEACCjB,MAAK;oEACLe,SAASA;oEACTI,UAAU3F;oEACV4F,UAAU,CAACC;wEACThG,SAAS;4EACP,GAAGmD,UAAU;4EACb,CAACO,aAAa,EAAEsC,MAAMC,MAAM,CAACP,OAAO;wEACtC;oEACF;;gEACC;8EACH,KAACU;oEACCC,OAAO;wEACLC,SAAS;oEACX;8EAEC5B,OAAOa,IAAI,IAAIb,OAAO3E,EAAE;;;2DAjBnB,GAAG+E,QAAQ/E,EAAE,CAAC,CAAC,EAAE2E,OAAO3E,EAAE,CAAC,IAAI,CAAC;oDAqB9C;;;;;mCAnIOwD,OAAOuB,QAAQ/E,EAAE;4BAyIpC;;;;;;;AAMZ,EAAE"}
@@ -1,6 +1,6 @@
1
1
  // Import Payload compile-time SCSS vars ($breakpoint-s-width, etc.).
2
2
  // Note: @payloadcms/ui/scss/vars is not a published export — use dist/scss/vars.
3
- @use "../../../node_modules/@payloadcms/ui/dist/scss/vars" as payload-vars;
3
+ // @use "../../../node_modules/@payloadcms/ui/dist/scss/vars" as payload-vars;
4
4
  @use "../../styles/variables" as rbac-vars;
5
5
 
6
6
  $local-prefix: rbac-vars.$rbac-prefix;
@@ -26,9 +26,6 @@ $local-prefix: rbac-vars.$rbac-prefix;
26
26
  &-container {
27
27
  border-radius: var(--style-radius-m);
28
28
  border: 1px solid var(--theme-border-color);
29
- @media only screen and (min-width: payload-vars.$breakpoint-s-width) {
30
- border-radius: var(--style-radius-l);
31
- }
32
29
  }
33
30
  &-th {
34
31
  &-feature {
@@ -8,11 +8,9 @@ export type RolePermissionMatrixClientTranslations = {
8
8
  placeholder?: string;
9
9
  };
10
10
  title?: string;
11
- features?: {
12
- label?: string;
13
- } | Record<string, string>;
14
- actions?: {
15
- label?: string;
16
- } | Record<string, string>;
11
+ featuresLabel?: string;
12
+ features?: Record<string, string>;
13
+ actionsLabel?: string;
14
+ actions?: Record<string, string>;
17
15
  };
18
16
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/role-permission-matrix-client/types.ts"],"sourcesContent":["export type RolePermissionMatrixClientTranslations = {\n [locale: string]: {\n viewInUpdateScreenOnly?: {\n label?: string\n placeholder?: string\n }\n loading?: {\n placeholder?: string\n }\n title?: string\n features?:\n | {\n label?: string\n }\n | Record<string, string>\n actions?:\n | {\n label?: string\n }\n | Record<string, string>\n }\n}\n"],"names":[],"mappings":"AAAA,WAqBC"}
1
+ {"version":3,"sources":["../../../src/components/role-permission-matrix-client/types.ts"],"sourcesContent":["export type RolePermissionMatrixClientTranslations = {\n [locale: string]: {\n viewInUpdateScreenOnly?: {\n label?: string;\n placeholder?: string;\n };\n loading?: {\n placeholder?: string;\n };\n title?: string;\n featuresLabel?: string;\n features?: Record<string, string>;\n actionsLabel?: string;\n actions?: Record<string, string>;\n };\n};\n"],"names":[],"mappings":"AAAA,WAeE"}
@@ -225,9 +225,9 @@ Registered as Payload i18n keys: `components:rolePermissionMatrix:…`
225
225
  | `title` | Matrix heading |
226
226
  | `viewInUpdateScreenOnly.label` | Shown on create screen |
227
227
  | `loading.placeholder` | Loading state |
228
- | `features.label` | Features column header |
228
+ | `featuresLabel` | Features column header |
229
229
  | `features.{code}` | Label for main feature with matching `permission-features.code` |
230
- | `actions.label` | Actions column header |
230
+ | `actionsLabel` | Actions column header |
231
231
  | `actions.{code}` | Label for main action with matching `permission-actions.code` |
232
232
 
233
233
  ### Features (dynamic)
@@ -248,6 +248,8 @@ payloadAuthRbacPlugin({
248
248
  en: {
249
249
  components: {
250
250
  rolePermissionMatrix: {
251
+ // ... others
252
+ featuresLabel: "Features",
251
253
  features: {
252
254
  label: "Features",
253
255
  users: "Users", // permission-features.code = "users" (plugin default)
@@ -278,8 +280,9 @@ payloadAuthRbacPlugin({
278
280
  en: {
279
281
  components: {
280
282
  rolePermissionMatrix: {
283
+ // ... others
284
+ actionsLabel: "Actions",
281
285
  actions: {
282
- label: "Actions",
283
286
  create: "Create", // permission-actions.code = "create" (plugin default)
284
287
  read: "Read",
285
288
  update: "Update",
@@ -392,13 +395,17 @@ export default buildConfig({
392
395
  rolePermissionMatrix: {
393
396
  title: "Ma trận quyền",
394
397
  loading: { placeholder: "Đang tải..." },
395
- features: { label: "Tính năng" },
398
+ featuresLabel: "Tính năng",
399
+ features: {
400
+ // Mã tính năng của permission-features
401
+ },
402
+ actionsLabel: "Hành động",
396
403
  actions: {
397
- label: "Hành động",
398
404
  create: "Tạo",
399
405
  read: "Xem",
400
406
  update: "Sửa",
401
407
  delete: "Xóa",
408
+ // Mã hành đông của permission-features
402
409
  },
403
410
  },
404
411
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zealamic/payload-auth-rbac-plugin",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "A plugin for Payload CMS to manage authentication and authorization",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -47,7 +47,8 @@
47
47
  "files": [
48
48
  "dist",
49
49
  "docs",
50
- "assets"
50
+ "assets",
51
+ "src"
51
52
  ],
52
53
  "scripts": {
53
54
  "copy:styles": "node -e \"require('fs').cpSync('src/styles', 'dist/styles', {recursive:true})\"",
@@ -108,31 +109,7 @@
108
109
  "node": "^18.20.2 || >=20.9.0"
109
110
  },
110
111
  "publishConfig": {
111
- "access": "public",
112
- "main": "./dist/index.js",
113
- "types": "./dist/index.d.ts",
114
- "exports": {
115
- ".": {
116
- "types": "./dist/index.d.ts",
117
- "default": "./dist/index.js"
118
- },
119
- "./client": {
120
- "types": "./dist/exports/client.d.ts",
121
- "default": "./dist/exports/client.js"
122
- },
123
- "./rsc": {
124
- "types": "./dist/exports/rsc.d.ts",
125
- "default": "./dist/exports/rsc.js"
126
- },
127
- "./types": {
128
- "types": "./dist/types.d.ts",
129
- "default": "./dist/types.js"
130
- },
131
- "./utils": {
132
- "types": "./dist/lib/utils/index.d.ts",
133
- "default": "./dist/lib/utils/index.js"
134
- }
135
- }
112
+ "access": "public"
136
113
  },
137
114
  "registry": "https://registry.npmjs.org/",
138
115
  "dependencies": {}
@@ -0,0 +1,36 @@
1
+ import type { PermissionActionsCollectionTranslations } from "./types.js";
2
+
3
+ export const permissionActionsDefaultTranslations: PermissionActionsCollectionTranslations =
4
+ {
5
+ en: {
6
+ labels: {
7
+ singular: "Permission Action",
8
+ plural: "Permission Actions",
9
+ },
10
+ admin: {
11
+ group: "System",
12
+ },
13
+ fields: {
14
+ code: {
15
+ label: "Code",
16
+ placeholder: "Enter code",
17
+ },
18
+ type: {
19
+ label: "Type",
20
+ placeholder: "Select type",
21
+ mainLabel: "Main",
22
+ subLabel: "Sub",
23
+ },
24
+ sortOrder: {
25
+ label: "Sort Order",
26
+ placeholder: "Enter sort order",
27
+ },
28
+ status: {
29
+ label: "Status",
30
+ placeholder: "Select status",
31
+ activeLabel: "Active",
32
+ inactiveLabel: "Inactive",
33
+ },
34
+ },
35
+ },
36
+ };
@@ -0,0 +1,144 @@
1
+ import type { CollectionConfig } from "payload";
2
+ import { STATUS, TYPE } from "../../lib/constants/permission-action.js";
3
+ import {
4
+ getArrayOfMergedFieldAffectingData,
5
+ getSuperAdminAccess,
6
+ toLocaleRecord,
7
+ toSelectPlaceholder,
8
+ } from "../../lib/utils/index.js";
9
+ import type { PermissionActionsCollectionParams } from "./types.js";
10
+
11
+ export const getPermissionActionsCollection = (
12
+ params: PermissionActionsCollectionParams,
13
+ ) => {
14
+ const {
15
+ translations = {},
16
+ access = {},
17
+ fields = [],
18
+ labels = {},
19
+ admin = {},
20
+ } = params || {};
21
+ const arrTranslationsKeys = Object.keys(translations);
22
+ const permissionActions: CollectionConfig = {
23
+ slug: "permission-actions",
24
+ labels: {
25
+ singular: toLocaleRecord(
26
+ arrTranslationsKeys,
27
+ (locale) => translations[locale]?.labels?.singular,
28
+ ),
29
+ plural: toLocaleRecord(
30
+ arrTranslationsKeys,
31
+ (locale) => translations[locale]?.labels?.plural,
32
+ ),
33
+ ...labels,
34
+ },
35
+ admin: {
36
+ group: toLocaleRecord(
37
+ arrTranslationsKeys,
38
+ (locale) => translations[locale]?.admin?.group,
39
+ ),
40
+ useAsTitle: "code",
41
+ defaultColumns: ["code", "type", "status", "updatedAt"],
42
+ ...admin,
43
+ },
44
+ access: {
45
+ create: getSuperAdminAccess,
46
+ update: getSuperAdminAccess,
47
+ delete: getSuperAdminAccess,
48
+ read: getSuperAdminAccess,
49
+ readVersions: getSuperAdminAccess,
50
+ unlock: getSuperAdminAccess,
51
+ admin: ({ req }) => {
52
+ return getSuperAdminAccess({ req });
53
+ },
54
+ ...access,
55
+ },
56
+ fields: getArrayOfMergedFieldAffectingData({
57
+ fields,
58
+ defaultFields: [
59
+ {
60
+ name: "code",
61
+ type: "text",
62
+ required: true,
63
+ unique: true,
64
+ index: true,
65
+ label: toLocaleRecord(
66
+ arrTranslationsKeys,
67
+ (locale) => translations[locale]?.fields?.code?.label,
68
+ ),
69
+ admin: {
70
+ placeholder: toLocaleRecord(
71
+ arrTranslationsKeys,
72
+ (locale) => translations[locale]?.fields?.code?.placeholder,
73
+ ),
74
+ },
75
+ },
76
+ {
77
+ name: "type",
78
+ type: "select",
79
+ required: true,
80
+ label: toLocaleRecord(
81
+ arrTranslationsKeys,
82
+ (locale) => translations[locale]?.fields?.type?.label,
83
+ ),
84
+ options: Object.values(TYPE).map((type) => ({
85
+ label: toLocaleRecord(
86
+ arrTranslationsKeys,
87
+ (locale) => translations[locale]?.fields?.type?.[`${type}Label`],
88
+ ),
89
+ value: type,
90
+ })),
91
+ admin: {
92
+ placeholder: toSelectPlaceholder(
93
+ arrTranslationsKeys,
94
+ (locale) => translations[locale]?.fields?.type?.placeholder,
95
+ ),
96
+ },
97
+ },
98
+ {
99
+ name: "sortOrder",
100
+ type: "number",
101
+ required: false,
102
+ defaultValue: 0,
103
+ label: toLocaleRecord(
104
+ arrTranslationsKeys,
105
+ (locale) => translations[locale]?.fields?.sortOrder?.label,
106
+ ),
107
+ admin: {
108
+ placeholder: toLocaleRecord(
109
+ arrTranslationsKeys,
110
+ (locale) => translations[locale]?.fields?.sortOrder?.placeholder,
111
+ ),
112
+ },
113
+ },
114
+ {
115
+ name: "status",
116
+ type: "select",
117
+ required: true,
118
+ label: toLocaleRecord(
119
+ arrTranslationsKeys,
120
+ (locale) => translations[locale]?.fields?.status?.label,
121
+ ),
122
+ defaultValue: STATUS.ACTIVE,
123
+ options: Object.values(STATUS).map((status) => ({
124
+ label: toLocaleRecord(
125
+ arrTranslationsKeys,
126
+ (locale) =>
127
+ translations[locale]?.fields?.status?.[`${status}Label`],
128
+ ),
129
+ value: status,
130
+ })),
131
+ admin: {
132
+ placeholder: toSelectPlaceholder(
133
+ arrTranslationsKeys,
134
+ (locale) => translations[locale]?.fields?.status?.placeholder,
135
+ ),
136
+ },
137
+ },
138
+ ],
139
+ }),
140
+ timestamps: true,
141
+ };
142
+
143
+ return permissionActions;
144
+ };
@@ -0,0 +1,56 @@
1
+ import type { CollectionConfig, Field } from "payload";
2
+ import { STATUS, TYPE } from "../../lib/constants/permission-action.js";
3
+
4
+ export type PermissionActionsCollectionTranslations = {
5
+ [locale: string]: {
6
+ labels?: {
7
+ singular?: string;
8
+ plural?: string;
9
+ };
10
+ admin?: {
11
+ group?: string;
12
+ };
13
+ fields?: {
14
+ code?: {
15
+ label?: string;
16
+ placeholder?: string;
17
+ };
18
+ type?: {
19
+ label?: string;
20
+ placeholder?: string;
21
+ mainLabel?: string;
22
+ subLabel?: string;
23
+ };
24
+ sortOrder?: {
25
+ label?: string;
26
+ placeholder?: string;
27
+ };
28
+ status?: {
29
+ label?: string;
30
+ placeholder?: string;
31
+ activeLabel?: string;
32
+ inactiveLabel?: string;
33
+ };
34
+ };
35
+ };
36
+ };
37
+
38
+ export type PermissionActionsCollectionParams = {
39
+ translations?: PermissionActionsCollectionTranslations;
40
+ fields?: Field[];
41
+ access?: CollectionConfig["access"];
42
+ labels?: CollectionConfig["labels"];
43
+ admin?: CollectionConfig["admin"];
44
+ };
45
+
46
+ export type PermissionActionStatus = (typeof STATUS)[keyof typeof STATUS];
47
+
48
+ export type PermissionActionType = (typeof TYPE)[keyof typeof TYPE];
49
+
50
+ export type PermissionAction = {
51
+ id: string | number;
52
+ code?: string | null;
53
+ sortOrder?: number | null;
54
+ type?: PermissionActionType | null;
55
+ status?: PermissionActionStatus | null;
56
+ };
@@ -0,0 +1,30 @@
1
+ import type { PermissionFeaturesCollectionTranslations } from "./types.js";
2
+
3
+ export const permissionFeaturesDefaultTranslations: PermissionFeaturesCollectionTranslations =
4
+ {
5
+ en: {
6
+ labels: {
7
+ singular: "Permission Feature",
8
+ plural: "Permission Features",
9
+ },
10
+ admin: {
11
+ group: "System",
12
+ },
13
+ fields: {
14
+ code: {
15
+ label: "Code",
16
+ placeholder: "Enter code",
17
+ },
18
+ sortOrder: {
19
+ label: "Sort Order",
20
+ placeholder: "Enter sort order",
21
+ },
22
+ status: {
23
+ label: "Status",
24
+ placeholder: "Select status",
25
+ activeLabel: "Active",
26
+ inactiveLabel: "Inactive",
27
+ },
28
+ },
29
+ },
30
+ };