adminforth 1.1.22 → 1.1.24
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/index.js +12 -12
- package/dist/plugins/AuditLog/index.js +3 -56
- package/dist/spa/spa/src/composables/useFrontendApi.ts +12 -0
- package/dist/spa/spa/src/views/ShowView.vue +22 -27
- package/dist/types/AdminForthConfig.js +9 -0
- package/index.ts +16 -19
- package/package.json +1 -1
- package/plugins/AuditLog/types.ts +4 -0
- package/spa/src/composables/useFrontendApi.ts +12 -0
- package/spa/src/views/ShowView.vue +22 -27
- package/types/AdminForthConfig.ts +23 -1
- package/plugins/AccessControl/types.ts +0 -7
- /package/plugins/{AccessControl → AuditLog}/index.ts +0 -0
package/dist/index.js
CHANGED
|
@@ -23,7 +23,7 @@ import ExpressServer from './servers/express.js';
|
|
|
23
23
|
import { v1 as uuid } from 'uuid';
|
|
24
24
|
import fs from 'fs';
|
|
25
25
|
import { ADMINFORTH_VERSION, listify } from './modules/utils.js';
|
|
26
|
-
import { AdminForthFilterOperators, AdminForthDataTypes, AdminForthResourcePages, AllowedActionsEnum } from './types/AdminForthConfig.js';
|
|
26
|
+
import { AdminForthFilterOperators, AdminForthDataTypes, AdminForthResourcePages, AllowedActionsEnum, ActionCheckSource } from './types/AdminForthConfig.js';
|
|
27
27
|
import path from 'path';
|
|
28
28
|
//get array from enum AdminForthResourcePages
|
|
29
29
|
class AdminForth {
|
|
@@ -633,13 +633,13 @@ class AdminForth {
|
|
|
633
633
|
};
|
|
634
634
|
}),
|
|
635
635
|
});
|
|
636
|
-
function interpretResource(adminUser, resource, meta) {
|
|
636
|
+
function interpretResource(adminUser, resource, meta, source) {
|
|
637
637
|
return __awaiter(this, void 0, void 0, function* () {
|
|
638
638
|
var _b;
|
|
639
639
|
yield Promise.all(Object.entries(((_b = resource.options) === null || _b === void 0 ? void 0 : _b.allowedActions) || {}).map((_c) => __awaiter(this, [_c], void 0, function* ([key, value]) {
|
|
640
640
|
// if callable then call
|
|
641
641
|
if (typeof value === 'function') {
|
|
642
|
-
resource.options.allowedActions[key] = yield value(adminUser, resource, meta);
|
|
642
|
+
resource.options.allowedActions[key] = yield value({ adminUser, resource, meta, source });
|
|
643
643
|
}
|
|
644
644
|
})));
|
|
645
645
|
});
|
|
@@ -667,7 +667,7 @@ class AdminForth {
|
|
|
667
667
|
if (!resource) {
|
|
668
668
|
return { error: `Resource ${resourceId} not found` };
|
|
669
669
|
}
|
|
670
|
-
yield interpretResource(adminUser, resource, {});
|
|
670
|
+
yield interpretResource(adminUser, resource, {}, ActionCheckSource.DisplayButtons);
|
|
671
671
|
// exclude "plugins" key
|
|
672
672
|
return { resource: Object.assign(Object.assign({}, resource), { plugins: undefined }) };
|
|
673
673
|
}),
|
|
@@ -691,7 +691,7 @@ class AdminForth {
|
|
|
691
691
|
if (!resource) {
|
|
692
692
|
return { error: `Resource ${resourceId} not found` };
|
|
693
693
|
}
|
|
694
|
-
yield interpretResource(adminUser, resource, { requestBody: body });
|
|
694
|
+
yield interpretResource(adminUser, resource, { requestBody: body }, ActionCheckSource.DisplayButtons);
|
|
695
695
|
const { allowed, error } = checkAccess(source, resource);
|
|
696
696
|
console.log('allowed', allowed, error);
|
|
697
697
|
if (!allowed) {
|
|
@@ -891,7 +891,7 @@ class AdminForth {
|
|
|
891
891
|
if (!resource) {
|
|
892
892
|
return { error: `Resource '${body['resourceId']}' not found` };
|
|
893
893
|
}
|
|
894
|
-
yield interpretResource(adminUser, resource, { requestBody: body });
|
|
894
|
+
yield interpretResource(adminUser, resource, { requestBody: body }, ActionCheckSource.CreateRequest);
|
|
895
895
|
const { allowed, error } = checkAccess(AllowedActionsEnum.create, resource);
|
|
896
896
|
if (!allowed) {
|
|
897
897
|
return { error };
|
|
@@ -963,11 +963,6 @@ class AdminForth {
|
|
|
963
963
|
if (!resource) {
|
|
964
964
|
return { error: `Resource '${body['resourceId']}' not found` };
|
|
965
965
|
}
|
|
966
|
-
yield interpretResource(adminUser, resource, { requestBody: body });
|
|
967
|
-
const { allowed, error } = checkAccess(AllowedActionsEnum.edit, resource);
|
|
968
|
-
if (!allowed) {
|
|
969
|
-
return { error };
|
|
970
|
-
}
|
|
971
966
|
const recordId = body['recordId'];
|
|
972
967
|
const connector = this.connectors[resource.dataSource];
|
|
973
968
|
const oldRecord = yield connector.getRecordByPrimaryKey(resource, recordId);
|
|
@@ -976,6 +971,11 @@ class AdminForth {
|
|
|
976
971
|
return { error: `Record with ${primaryKeyColumn.name} ${recordId} not found` };
|
|
977
972
|
}
|
|
978
973
|
const record = body['record'];
|
|
974
|
+
yield interpretResource(adminUser, resource, { requestBody: body, record, oldRecord }, ActionCheckSource.EditRequest);
|
|
975
|
+
const { allowed, error } = checkAccess(AllowedActionsEnum.edit, resource);
|
|
976
|
+
if (!allowed) {
|
|
977
|
+
return { error };
|
|
978
|
+
}
|
|
979
979
|
// execute hook if needed
|
|
980
980
|
for (const hook of listify((_6 = (_5 = resource.hooks) === null || _5 === void 0 ? void 0 : _5.edit) === null || _6 === void 0 ? void 0 : _6.beforeSave)) {
|
|
981
981
|
const resp = yield hook({ resource, record, adminUser });
|
|
@@ -1035,7 +1035,7 @@ class AdminForth {
|
|
|
1035
1035
|
if (resource.options.allowedActions.delete === false) {
|
|
1036
1036
|
return { error: `Resource '${resource.resourceId}' does not allow delete action` };
|
|
1037
1037
|
}
|
|
1038
|
-
yield interpretResource(adminUser, resource, { requestBody: body });
|
|
1038
|
+
yield interpretResource(adminUser, resource, { requestBody: body }, ActionCheckSource.DeleteRequest);
|
|
1039
1039
|
const { allowed, error } = checkAccess(AllowedActionsEnum.delete, resource);
|
|
1040
1040
|
if (!allowed) {
|
|
1041
1041
|
return { error };
|
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
import { AllowedActionsEnum } from "../../types/AdminForthConfig.js";
|
|
11
1
|
import AdminForthPlugin from "../base.js";
|
|
12
|
-
class
|
|
2
|
+
class AuditLogPlugin extends AdminForthPlugin {
|
|
13
3
|
constructor(options) {
|
|
14
4
|
super(options, import.meta.url);
|
|
15
5
|
this.options = options;
|
|
@@ -17,50 +7,7 @@ class AccessControlPlugin extends AdminForthPlugin {
|
|
|
17
7
|
modifyResourceConfig(adminforth, resourceConfig) {
|
|
18
8
|
super.modifyResourceConfig(adminforth, resourceConfig);
|
|
19
9
|
this.adminforth = adminforth;
|
|
20
|
-
if (!resourceConfig.hooks) {
|
|
21
|
-
resourceConfig.hooks = {};
|
|
22
|
-
}
|
|
23
|
-
const checkAccess = (adminUser, action, meta) => __awaiter(this, void 0, void 0, function* () {
|
|
24
|
-
const hasAccessOrError = yield this.options.hasAccess(adminUser, action, meta);
|
|
25
|
-
if (hasAccessOrError === true) {
|
|
26
|
-
return { ok: true };
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
return { ok: false, error: hasAccessOrError || AccessControlPlugin.defaultError };
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
const bindHookCheck = (action, hookName) => {
|
|
33
|
-
if (!resourceConfig.hooks[action]) {
|
|
34
|
-
resourceConfig.hooks[action] = {};
|
|
35
|
-
}
|
|
36
|
-
if (!resourceConfig.hooks[action][hookName]) {
|
|
37
|
-
resourceConfig.hooks[action][hookName] = [];
|
|
38
|
-
}
|
|
39
|
-
if (hookName === 'beforeDatasourceRequest') {
|
|
40
|
-
resourceConfig.hooks[action][hookName].unshift((_a) => __awaiter(this, [_a], void 0, function* ({ adminUser, query }) {
|
|
41
|
-
return checkAccess(adminUser, action, { query });
|
|
42
|
-
}));
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
resourceConfig.hooks[action][hookName].unshift((_b) => __awaiter(this, [_b], void 0, function* ({ adminUser, record }) {
|
|
46
|
-
return checkAccess(adminUser, action, { record });
|
|
47
|
-
}));
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
// List check
|
|
51
|
-
bindHookCheck(AllowedActionsEnum.list, 'beforeDatasourceRequest');
|
|
52
|
-
// Show check
|
|
53
|
-
bindHookCheck(AllowedActionsEnum.show, 'beforeDatasourceRequest');
|
|
54
|
-
// Edit check
|
|
55
|
-
bindHookCheck(AllowedActionsEnum.edit, 'beforeDatasourceRequest');
|
|
56
|
-
// create check
|
|
57
|
-
bindHookCheck(AllowedActionsEnum.create, 'beforeSave');
|
|
58
|
-
// edit check
|
|
59
|
-
bindHookCheck(AllowedActionsEnum.edit, 'beforeSave');
|
|
60
|
-
// delete check
|
|
61
|
-
bindHookCheck(AllowedActionsEnum.delete, 'beforeSave');
|
|
62
|
-
console.log('resourceConfig', resourceConfig);
|
|
63
10
|
}
|
|
64
11
|
}
|
|
65
|
-
|
|
66
|
-
export default
|
|
12
|
+
AuditLogPlugin.defaultError = 'Sorry, you do not have access to this resource.';
|
|
13
|
+
export default AuditLogPlugin;
|
|
@@ -12,3 +12,15 @@ export function showErrorTost(message: string, timeout?: number) {
|
|
|
12
12
|
window.adminforth.alert({ message, variant: 'danger', timeout: timeout || 'unlimited'});
|
|
13
13
|
return message;
|
|
14
14
|
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
const useFrontendApi = () => {
|
|
18
|
+
return {
|
|
19
|
+
showSuccesTost,
|
|
20
|
+
showWarningTost,
|
|
21
|
+
showErrorTost
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
export default useFrontendApi;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
Edit
|
|
17
17
|
</RouterLink>
|
|
18
18
|
|
|
19
|
-
<button v-if="coreStore?.resourceOptions?.allowedActions?.delete" @click="
|
|
19
|
+
<button v-if="coreStore?.resourceOptions?.allowedActions?.delete" @click="deleteRecord"
|
|
20
20
|
class="flex items-center py-1 px-3 text-sm font-medium rounded-default text-red-600 focus:outline-none bg-white rounded border border-gray-300 hover:bg-gray-100 hover:text-red-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-red-500 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
|
|
21
21
|
>
|
|
22
22
|
<IconTrashBinSolid class="w-4 h-4" />
|
|
@@ -120,6 +120,7 @@ import { IconPenSolid, IconTrashBinSolid } from '@iconify-prerendered/vue-flowbi
|
|
|
120
120
|
import { onMounted, ref } from 'vue';
|
|
121
121
|
import { useRoute,useRouter } from 'vue-router';
|
|
122
122
|
import {callAdminForthApi} from '@/utils';
|
|
123
|
+
import {showSuccesTost} from '@/composables/useFrontendApi';
|
|
123
124
|
|
|
124
125
|
|
|
125
126
|
const item = ref(null);
|
|
@@ -154,40 +155,34 @@ onMounted(async () => {
|
|
|
154
155
|
loading.value = false;
|
|
155
156
|
});
|
|
156
157
|
|
|
157
|
-
function showDeleteModal(row) {
|
|
158
|
-
if (!coreStore.config?.deleteConfirmation) {
|
|
159
|
-
return deleteRecord(row);
|
|
160
|
-
}
|
|
161
|
-
modalStore.setModalContent({
|
|
162
|
-
content: 'Are you sure you want to delete this item?',
|
|
163
|
-
acceptText: 'Delete',
|
|
164
|
-
cancelText: 'Cancel',
|
|
165
|
-
});
|
|
166
|
-
modalStore.setOnAcceptFunction(() => {
|
|
167
|
-
return deleteRecord(row)
|
|
168
|
-
})
|
|
169
|
-
modalStore.togleModal();
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
|
|
174
158
|
async function deleteRecord(row) {
|
|
175
|
-
|
|
176
|
-
|
|
159
|
+
const data = await window.adminforth.confirm({
|
|
160
|
+
message: 'Are you sure you want to delete this item?',
|
|
161
|
+
yes: 'Delete',
|
|
162
|
+
no: 'Cancel',
|
|
163
|
+
});
|
|
164
|
+
if (data) {
|
|
165
|
+
try {
|
|
166
|
+
const res = await callAdminForthApi({
|
|
177
167
|
path: '/delete_record',
|
|
178
168
|
method: 'POST',
|
|
179
169
|
body: {
|
|
180
170
|
resourceId: route.params.resourceId,
|
|
181
171
|
primaryKey: route.params.primaryKey,
|
|
182
|
-
|
|
172
|
+
}});
|
|
173
|
+
if (!res.error){
|
|
174
|
+
router.push({ name: 'resource-list', params: { resourceId: route.params.resourceId } });
|
|
175
|
+
showSuccesTost('Record deleted successfully')
|
|
176
|
+
} else {
|
|
177
|
+
console.error(res.error)
|
|
183
178
|
}
|
|
184
|
-
});
|
|
185
|
-
router.push({ name: 'resource-list', params: { resourceId: route.params.resourceId } });
|
|
186
|
-
} catch (error) {
|
|
187
|
-
console.log(error);
|
|
188
|
-
}
|
|
189
179
|
|
|
190
|
-
|
|
180
|
+
} catch (e) {
|
|
181
|
+
console.error(e);
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
191
186
|
}
|
|
192
187
|
|
|
193
188
|
</script>
|
|
@@ -61,6 +61,15 @@ export var AllowedActionsEnum;
|
|
|
61
61
|
AllowedActionsEnum["delete"] = "delete";
|
|
62
62
|
AllowedActionsEnum["filter"] = "filter";
|
|
63
63
|
})(AllowedActionsEnum || (AllowedActionsEnum = {}));
|
|
64
|
+
export var ActionCheckSource;
|
|
65
|
+
(function (ActionCheckSource) {
|
|
66
|
+
ActionCheckSource["DisplayButtons"] = "displayButtons";
|
|
67
|
+
ActionCheckSource["ListRequest"] = "listRequest";
|
|
68
|
+
ActionCheckSource["ShowRequest"] = "showRequest";
|
|
69
|
+
ActionCheckSource["EditRequest"] = "editRequest";
|
|
70
|
+
ActionCheckSource["CreateRequest"] = "createRequest";
|
|
71
|
+
ActionCheckSource["DeleteRequest"] = "deleteRequest";
|
|
72
|
+
})(ActionCheckSource || (ActionCheckSource = {}));
|
|
64
73
|
export var AdminForthDataTypes;
|
|
65
74
|
(function (AdminForthDataTypes) {
|
|
66
75
|
AdminForthDataTypes["STRING"] = "string";
|
package/index.ts
CHANGED
|
@@ -16,11 +16,11 @@ import { AdminForthConfig, AdminForthClass, AdminForthComponentDeclaration, Admi
|
|
|
16
16
|
BeforeDataSourceRequestFunction,
|
|
17
17
|
AfterDataSourceResponseFunction, AllowedActionValue, AdminUser,
|
|
18
18
|
AdminForthResource,
|
|
19
|
-
AllowedActionsEnum
|
|
19
|
+
AllowedActionsEnum,
|
|
20
|
+
ActionCheckSource
|
|
20
21
|
} from './types/AdminForthConfig.js';
|
|
21
22
|
import path from 'path';
|
|
22
23
|
import AdminForthPlugin from './plugins/base.js';
|
|
23
|
-
import { tr } from '@faker-js/faker';
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
//get array from enum AdminForthResourcePages
|
|
@@ -697,10 +697,6 @@ class AdminForth implements AdminForthClass {
|
|
|
697
697
|
}
|
|
698
698
|
newMenu.push(newMenuItem)
|
|
699
699
|
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
700
|
|
|
705
701
|
return {
|
|
706
702
|
user: userData,
|
|
@@ -725,13 +721,13 @@ class AdminForth implements AdminForthClass {
|
|
|
725
721
|
},
|
|
726
722
|
});
|
|
727
723
|
|
|
728
|
-
async function interpretResource(adminUser: AdminUser, resource: AdminForthResource, meta: any) {
|
|
724
|
+
async function interpretResource(adminUser: AdminUser, resource: AdminForthResource, meta: any, source: ActionCheckSource) {
|
|
729
725
|
await Promise.all(
|
|
730
726
|
Object.entries(resource.options?.allowedActions || {}).map(
|
|
731
727
|
async ([key, value]: [string, AllowedActionValue]) => {
|
|
732
728
|
// if callable then call
|
|
733
729
|
if (typeof value === 'function') {
|
|
734
|
-
resource.options.allowedActions[key] = await value( adminUser, resource, meta );
|
|
730
|
+
resource.options.allowedActions[key] = await value({ adminUser, resource, meta, source });
|
|
735
731
|
}
|
|
736
732
|
})
|
|
737
733
|
);
|
|
@@ -762,7 +758,7 @@ class AdminForth implements AdminForthClass {
|
|
|
762
758
|
return { error: `Resource ${resourceId} not found` };
|
|
763
759
|
}
|
|
764
760
|
|
|
765
|
-
await interpretResource(adminUser, resource, {});
|
|
761
|
+
await interpretResource(adminUser, resource, {}, ActionCheckSource.DisplayButtons);
|
|
766
762
|
|
|
767
763
|
// exclude "plugins" key
|
|
768
764
|
return { resource: { ...resource, plugins: undefined } };
|
|
@@ -787,7 +783,7 @@ class AdminForth implements AdminForthClass {
|
|
|
787
783
|
return { error: `Resource ${resourceId} not found` };
|
|
788
784
|
}
|
|
789
785
|
|
|
790
|
-
await interpretResource(adminUser, resource, { requestBody: body });
|
|
786
|
+
await interpretResource(adminUser, resource, { requestBody: body }, ActionCheckSource.DisplayButtons);
|
|
791
787
|
|
|
792
788
|
const { allowed, error } = checkAccess(source as AllowedActionsEnum, resource);
|
|
793
789
|
console.log('allowed', allowed, error);
|
|
@@ -1012,7 +1008,7 @@ class AdminForth implements AdminForthClass {
|
|
|
1012
1008
|
if (!resource) {
|
|
1013
1009
|
return { error: `Resource '${body['resourceId']}' not found` };
|
|
1014
1010
|
}
|
|
1015
|
-
await interpretResource(adminUser, resource, { requestBody: body
|
|
1011
|
+
await interpretResource(adminUser, resource, { requestBody: body}, ActionCheckSource.CreateRequest);
|
|
1016
1012
|
|
|
1017
1013
|
const { allowed, error } = checkAccess(AllowedActionsEnum.create, resource);
|
|
1018
1014
|
if (!allowed) {
|
|
@@ -1093,13 +1089,7 @@ class AdminForth implements AdminForthClass {
|
|
|
1093
1089
|
if (!resource) {
|
|
1094
1090
|
return { error: `Resource '${body['resourceId']}' not found` };
|
|
1095
1091
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
const { allowed, error } = checkAccess(AllowedActionsEnum.edit, resource);
|
|
1099
|
-
if (!allowed) {
|
|
1100
|
-
return { error };
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1092
|
+
|
|
1103
1093
|
const recordId = body['recordId'];
|
|
1104
1094
|
const connector = this.connectors[resource.dataSource];
|
|
1105
1095
|
const oldRecord = await connector.getRecordByPrimaryKey(resource, recordId)
|
|
@@ -1109,6 +1099,13 @@ class AdminForth implements AdminForthClass {
|
|
|
1109
1099
|
}
|
|
1110
1100
|
const record = body['record'];
|
|
1111
1101
|
|
|
1102
|
+
await interpretResource(adminUser, resource, { requestBody: body, record, oldRecord}, ActionCheckSource.EditRequest);
|
|
1103
|
+
|
|
1104
|
+
const { allowed, error } = checkAccess(AllowedActionsEnum.edit, resource);
|
|
1105
|
+
if (!allowed) {
|
|
1106
|
+
return { error };
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1112
1109
|
// execute hook if needed
|
|
1113
1110
|
for (const hook of listify(resource.hooks?.edit?.beforeSave as BeforeSaveFunction[])) {
|
|
1114
1111
|
const resp = await hook({ resource, record, adminUser });
|
|
@@ -1173,7 +1170,7 @@ class AdminForth implements AdminForthClass {
|
|
|
1173
1170
|
return { error: `Resource '${resource.resourceId}' does not allow delete action` };
|
|
1174
1171
|
}
|
|
1175
1172
|
|
|
1176
|
-
await interpretResource(adminUser, resource, { requestBody: body });
|
|
1173
|
+
await interpretResource(adminUser, resource, { requestBody: body }, ActionCheckSource.DeleteRequest);
|
|
1177
1174
|
|
|
1178
1175
|
const { allowed, error } = checkAccess(AllowedActionsEnum.delete, resource);
|
|
1179
1176
|
if (!allowed) {
|
package/package.json
CHANGED
|
@@ -12,3 +12,15 @@ export function showErrorTost(message: string, timeout?: number) {
|
|
|
12
12
|
window.adminforth.alert({ message, variant: 'danger', timeout: timeout || 'unlimited'});
|
|
13
13
|
return message;
|
|
14
14
|
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
const useFrontendApi = () => {
|
|
18
|
+
return {
|
|
19
|
+
showSuccesTost,
|
|
20
|
+
showWarningTost,
|
|
21
|
+
showErrorTost
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
export default useFrontendApi;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
Edit
|
|
17
17
|
</RouterLink>
|
|
18
18
|
|
|
19
|
-
<button v-if="coreStore?.resourceOptions?.allowedActions?.delete" @click="
|
|
19
|
+
<button v-if="coreStore?.resourceOptions?.allowedActions?.delete" @click="deleteRecord"
|
|
20
20
|
class="flex items-center py-1 px-3 text-sm font-medium rounded-default text-red-600 focus:outline-none bg-white rounded border border-gray-300 hover:bg-gray-100 hover:text-red-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-red-500 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
|
|
21
21
|
>
|
|
22
22
|
<IconTrashBinSolid class="w-4 h-4" />
|
|
@@ -120,6 +120,7 @@ import { IconPenSolid, IconTrashBinSolid } from '@iconify-prerendered/vue-flowbi
|
|
|
120
120
|
import { onMounted, ref } from 'vue';
|
|
121
121
|
import { useRoute,useRouter } from 'vue-router';
|
|
122
122
|
import {callAdminForthApi} from '@/utils';
|
|
123
|
+
import {showSuccesTost} from '@/composables/useFrontendApi';
|
|
123
124
|
|
|
124
125
|
|
|
125
126
|
const item = ref(null);
|
|
@@ -154,40 +155,34 @@ onMounted(async () => {
|
|
|
154
155
|
loading.value = false;
|
|
155
156
|
});
|
|
156
157
|
|
|
157
|
-
function showDeleteModal(row) {
|
|
158
|
-
if (!coreStore.config?.deleteConfirmation) {
|
|
159
|
-
return deleteRecord(row);
|
|
160
|
-
}
|
|
161
|
-
modalStore.setModalContent({
|
|
162
|
-
content: 'Are you sure you want to delete this item?',
|
|
163
|
-
acceptText: 'Delete',
|
|
164
|
-
cancelText: 'Cancel',
|
|
165
|
-
});
|
|
166
|
-
modalStore.setOnAcceptFunction(() => {
|
|
167
|
-
return deleteRecord(row)
|
|
168
|
-
})
|
|
169
|
-
modalStore.togleModal();
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
|
|
174
158
|
async function deleteRecord(row) {
|
|
175
|
-
|
|
176
|
-
|
|
159
|
+
const data = await window.adminforth.confirm({
|
|
160
|
+
message: 'Are you sure you want to delete this item?',
|
|
161
|
+
yes: 'Delete',
|
|
162
|
+
no: 'Cancel',
|
|
163
|
+
});
|
|
164
|
+
if (data) {
|
|
165
|
+
try {
|
|
166
|
+
const res = await callAdminForthApi({
|
|
177
167
|
path: '/delete_record',
|
|
178
168
|
method: 'POST',
|
|
179
169
|
body: {
|
|
180
170
|
resourceId: route.params.resourceId,
|
|
181
171
|
primaryKey: route.params.primaryKey,
|
|
182
|
-
|
|
172
|
+
}});
|
|
173
|
+
if (!res.error){
|
|
174
|
+
router.push({ name: 'resource-list', params: { resourceId: route.params.resourceId } });
|
|
175
|
+
showSuccesTost('Record deleted successfully')
|
|
176
|
+
} else {
|
|
177
|
+
console.error(res.error)
|
|
183
178
|
}
|
|
184
|
-
});
|
|
185
|
-
router.push({ name: 'resource-list', params: { resourceId: route.params.resourceId } });
|
|
186
|
-
} catch (error) {
|
|
187
|
-
console.log(error);
|
|
188
|
-
}
|
|
189
179
|
|
|
190
|
-
|
|
180
|
+
} catch (e) {
|
|
181
|
+
console.error(e);
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
191
186
|
}
|
|
192
187
|
|
|
193
188
|
</script>
|
|
@@ -838,7 +838,29 @@ export enum AllowedActionsEnum {
|
|
|
838
838
|
* or function which returns Boolean or string with error message
|
|
839
839
|
*
|
|
840
840
|
*/
|
|
841
|
-
export type AllowedActionValue = boolean | ((adminUser
|
|
841
|
+
export type AllowedActionValue = boolean | (({adminUser, resource, meta, source}: {
|
|
842
|
+
adminUser: AdminUser,
|
|
843
|
+
resource: AdminForthResource,
|
|
844
|
+
|
|
845
|
+
/**
|
|
846
|
+
* Meta object which will pass request information just in case
|
|
847
|
+
*/
|
|
848
|
+
meta: any,
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* Source of the check
|
|
852
|
+
*/
|
|
853
|
+
source: ActionCheckSource,
|
|
854
|
+
}) => Promise<boolean | string>);
|
|
855
|
+
|
|
856
|
+
export enum ActionCheckSource {
|
|
857
|
+
DisplayButtons = 'displayButtons',
|
|
858
|
+
ListRequest = 'listRequest',
|
|
859
|
+
ShowRequest = 'showRequest',
|
|
860
|
+
EditRequest = 'editRequest',
|
|
861
|
+
CreateRequest = 'createRequest',
|
|
862
|
+
DeleteRequest = 'deleteRequest',
|
|
863
|
+
}
|
|
842
864
|
|
|
843
865
|
/**
|
|
844
866
|
* Object which describes allowed actions for user.
|
|
File without changes
|