adminforth 1.2.13 → 1.2.15

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.
@@ -608,18 +608,21 @@ export default class AdminForthRestAPI {
608
608
  method: 'POST',
609
609
  path: '/start_bulk_action',
610
610
  handler: (_11) => __awaiter(this, [_11], void 0, function* ({ body }) {
611
- const { resourceId, actionId, recordIds } = body;
611
+ const { resourceId, actionId, recordIds, adminUser } = body;
612
612
  const resource = this.adminforth.config.resources.find((res) => res.resourceId == resourceId);
613
613
  if (!resource) {
614
614
  return { error: `Resource '${resourceId}' not found` };
615
615
  }
616
+ const { allowedActions } = yield interpretResource(adminUser, resource, { requestBody: body }, ActionCheckSource.BulkActionRequest);
616
617
  const action = resource.options.bulkActions.find((act) => act.id == actionId);
617
618
  if (!action) {
618
619
  return { error: `Action '${actionId}' not found` };
619
620
  }
620
- else {
621
- yield action.action({ selectedIds: recordIds });
621
+ const execAllowed = yield action.allowed({ adminUser, resource, recordIds, allowedActions });
622
+ if (!execAllowed) {
623
+ return { error: `Action '${actionId}' is not allowed` };
622
624
  }
625
+ yield action.action({ selectedIds: recordIds });
623
626
  return {
624
627
  actionId,
625
628
  recordIds,
@@ -70,6 +70,7 @@ export var ActionCheckSource;
70
70
  ActionCheckSource["EditRequest"] = "editRequest";
71
71
  ActionCheckSource["CreateRequest"] = "createRequest";
72
72
  ActionCheckSource["DeleteRequest"] = "deleteRequest";
73
+ ActionCheckSource["BulkActionRequest"] = "bulkActionRequest";
73
74
  })(ActionCheckSource || (ActionCheckSource = {}));
74
75
  export var AdminForthDataTypes;
75
76
  (function (AdminForthDataTypes) {
@@ -696,24 +696,29 @@ export default class AdminForthRestAPI {
696
696
  method: 'POST',
697
697
  path: '/start_bulk_action',
698
698
  handler: async ({ body }) => {
699
- const { resourceId, actionId, recordIds } = body;
699
+ const { resourceId, actionId, recordIds, adminUser } = body;
700
700
  const resource = this.adminforth.config.resources.find((res) => res.resourceId == resourceId);
701
701
  if (!resource) {
702
702
  return { error: `Resource '${resourceId}' not found` };
703
703
  }
704
+ const { allowedActions } = await interpretResource(adminUser, resource, { requestBody: body }, ActionCheckSource.BulkActionRequest);
705
+
704
706
  const action = resource.options.bulkActions.find((act) => act.id == actionId);
705
707
  if (!action) {
706
- return { error: `Action '${actionId}' not found` };
707
- } else{
708
- await action.action({selectedIds:recordIds})
709
-
708
+ return { error: `Action '${actionId}' not found` };
709
+ }
710
+
711
+ const execAllowed = await action.allowed({ adminUser, resource, recordIds, allowedActions });
712
+ if (!execAllowed) {
713
+ return { error: `Action '${actionId}' is not allowed` };
710
714
  }
715
+ await action.action({selectedIds:recordIds})
716
+
711
717
  return {
712
718
  actionId,
713
719
  recordIds,
714
720
  resourceId,
715
- status:'success'
716
-
721
+ status: 'success'
717
722
  }
718
723
  }
719
724
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adminforth",
3
- "version": "1.2.13",
3
+ "version": "1.2.15",
4
4
  "description": "OpenSource Vue3 powered forth-generation admin panel",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -740,11 +740,13 @@ export type AdminForthResource = {
740
740
  * Example:
741
741
  *
742
742
  * ```ts
743
+ * import { AdminForthSortDirections } from 'adminforth';
744
+ *
745
+ * ...
746
+ *
743
747
  * defaultSort: {
744
748
  * columnName: 'created_at',
745
749
  * direction: AdminForthSortDirections.ASC,
746
- * // or
747
- * // direction: 'asc' // if you are using non-typescript
748
750
  * }
749
751
  * ```
750
752
  *
@@ -761,6 +763,10 @@ export type AdminForthResource = {
761
763
  */
762
764
  direction: AdminForthSortDirections | string,
763
765
  }
766
+
767
+ /**
768
+ * Custom bulk actions list
769
+ */
764
770
  bulkActions?: Array<{
765
771
  id?: string,
766
772
  label: string,
@@ -768,12 +774,87 @@ export type AdminForthResource = {
768
774
  icon?: string,
769
775
  action: Function,
770
776
  confirm?: string,
771
- allowed?: ({ resource, adminUser }: {
772
- resource: AdminForthResource,
777
+
778
+ /**
779
+ * Allowed callback called to check whether action is allowed for user.
780
+ * 1. It called first time when user goes to list view. If callback returns false, action button will be hidden on list view.
781
+ * 2. This same callback called second time when user clicks an action button. If callback returns false, action will not be executed.
782
+ * In second time recordIds will be passed to callback (because checkbox for items are selected), so you can use this to make additional
783
+ * checks ( for example to check if user has permission for certain records ).
784
+ *
785
+ * Example:
786
+ *
787
+ * ```ts
788
+ * allowed: async ({ resource, adminUser, recordIds }) => {
789
+ * if (adminUser.isRoot || adminUser.dbUser.role !== 'superadmin') {
790
+ * return false;
791
+ * }
792
+ * return true;
793
+ * }
794
+ * ```
795
+ *
796
+ */
797
+ allowed?: ({ resource, adminUser, recordIds }: {
798
+
799
+ /**
800
+ * recordIds will be passed only once user tries to perform bulk action by clicking on button
801
+ */
802
+ recordIds?: Array<any>,
803
+ resource: AdminForthResource,
804
+
805
+ /**
806
+ * Admin user object
807
+ */
773
808
  adminUser: AdminUser,
809
+
810
+ /**
811
+ * Allowed standard actions for current user resolved by calling allowedActions callbacks if they are passed.
812
+ * You can use this variable to rely on standard actions permissions. E.g. if you have custom actions "Mark as read", you
813
+ * might want to allow it only for users who have "edit" action allowed:
814
+ *
815
+ * Example:
816
+ *
817
+ * ```ts
818
+ *
819
+ * options: {
820
+ * bulkActions: [
821
+ * {
822
+ * label: 'Mark as read',
823
+ * action: async ({ resource, recordIds }) => {
824
+ * await markAsRead(recordIds);
825
+ * },
826
+ * allowed: ({ allowedActions }) => allowedActions.edit,
827
+ * }
828
+ * ],
829
+ * allowedActions: {
830
+ * edit: ({ resource, adminUser, recordIds }) => {
831
+ * return adminUser.isRoot || adminUser.dbUser.role === 'superadmin';
832
+ * }
833
+ * }
834
+ * }
835
+ * ```
836
+ *
837
+ */
774
838
  allowedActions: AllowedActionsResolved,
775
839
  }) => Promise<boolean>,
776
840
  }>,
841
+
842
+ /**
843
+ * Allowed actions for resource.
844
+ *
845
+ * Example:
846
+ *
847
+ * ```ts
848
+ * allowedActions: {
849
+ * create: ({ resource, adminUser }) => {
850
+ * // Allow only superadmin or root user to create records
851
+ * return adminUser.isRoot || adminUser.dbUser.role === 'superadmin';
852
+ * },
853
+ * delete: false, // disable delete action for all users
854
+ * }
855
+ * ```
856
+ *
857
+ */
777
858
  allowedActions?: AllowedActions,
778
859
 
779
860
  /**
@@ -1133,6 +1214,7 @@ export enum ActionCheckSource {
1133
1214
  EditRequest = 'editRequest',
1134
1215
  CreateRequest = 'createRequest',
1135
1216
  DeleteRequest = 'deleteRequest',
1217
+ BulkActionRequest = 'bulkActionRequest',
1136
1218
  }
1137
1219
 
1138
1220
  /**