adminforth 1.1.34 → 1.1.36
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 +30 -22
- package/dist/spa/index.html +2 -2
- package/dist/spa/package-lock.json +17 -4
- package/dist/spa/package.json +2 -1
- package/dist/spa/spa/src/components/ResourceListTable.vue +1 -10
- package/dist/spa/src/App.vue +125 -45
- package/dist/spa/src/assets/logo.svg +19 -1
- package/dist/spa/src/components/AcceptModal.vue +2 -9
- package/dist/spa/src/components/BreadcrumbsWithButtons.vue +1 -1
- package/dist/spa/src/components/CustomDatePicker.vue +16 -3
- package/dist/spa/src/components/CustomDateRangePicker.vue +11 -2
- package/dist/spa/src/components/Dropdown.vue +6 -1
- package/dist/spa/src/components/Filters.vue +40 -19
- package/dist/spa/src/components/ResourceForm.vue +26 -24
- package/dist/spa/src/components/ResourceListTable.vue +419 -0
- package/dist/spa/src/components/Toast.vue +66 -0
- package/dist/spa/src/components/ValueRenderer.vue +14 -8
- package/dist/spa/src/composables/useFrontendApi.ts +26 -0
- package/dist/spa/src/composables/useStores.ts +113 -0
- package/dist/spa/src/main.ts +1 -1
- package/dist/spa/src/router/index.ts +30 -20
- package/dist/spa/src/spa_types/core.ts +51 -0
- package/dist/spa/src/stores/core.ts +48 -31
- package/dist/spa/src/stores/filters.ts +22 -0
- package/dist/spa/src/stores/modal.ts +13 -3
- package/dist/spa/src/stores/toast.ts +15 -0
- package/dist/spa/src/stores/user.ts +54 -0
- package/dist/spa/src/utils.ts +62 -7
- package/dist/spa/src/views/CreateView.vue +67 -15
- package/dist/spa/src/views/EditView.vue +45 -11
- package/dist/spa/src/views/ListView.vue +82 -366
- package/dist/spa/src/views/LoginView.vue +16 -4
- package/dist/spa/src/views/ShowView.vue +105 -21
- package/dist/spa/tailwind.config.js +1 -1
- package/dist/spa/vite.config.ts +6 -0
- package/index.ts +38 -28
- package/package.json +1 -1
- package/spa/src/components/ResourceListTable.vue +1 -10
- package/types/AdminForthConfig.ts +0 -3
- package/dist/plugins/AccessControl/index.js +0 -66
- package/dist/plugins/AccessControl/types.js +0 -1
- package/dist/spa/public/favicon.ico +0 -0
- package/dist/spa/spa/public/favicon.ico +0 -0
- package/dist/types.js +0 -30
- /package/dist/spa/{spa/public → public/assets}/favicon.png +0 -0
|
@@ -1,21 +1,38 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="relative">
|
|
3
|
+
<component
|
|
4
|
+
v-for="c in coreStore?.resourceOptions?.pageInjections?.show?.beforeBreadcrumbs || []"
|
|
5
|
+
:is="getCustomComponent(c)"
|
|
6
|
+
:meta="c.meta"
|
|
7
|
+
:record="coreStore.record"
|
|
8
|
+
:resource="coreStore.resource"
|
|
9
|
+
:adminUser="coreStore.adminUser"
|
|
10
|
+
/>
|
|
3
11
|
<BreadcrumbsWithButtons>
|
|
4
|
-
<RouterLink :to="{ name: 'resource-edit', params: { resourceId: $route.params.resourceId, primaryKey: $route.params.primaryKey } }"
|
|
5
|
-
class="flex items-center py-1 px-3
|
|
12
|
+
<RouterLink v-if="coreStore?.resourceOptions?.allowedActions?.edit" :to="{ name: 'resource-edit', params: { resourceId: $route.params.resourceId, primaryKey: $route.params.primaryKey } }"
|
|
13
|
+
class="flex items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-default border border-gray-300 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
|
|
6
14
|
>
|
|
7
15
|
<IconPenSolid class="w-4 h-4" />
|
|
8
16
|
Edit
|
|
9
17
|
</RouterLink>
|
|
10
18
|
|
|
11
|
-
<button @click="deleteRecord"
|
|
12
|
-
class="flex items-center py-1 px-3
|
|
19
|
+
<button v-if="coreStore?.resourceOptions?.allowedActions?.delete" @click="deleteRecord"
|
|
20
|
+
class="flex items-center py-1 px-3 text-sm font-medium rounded-default text-red-600 focus:outline-none bg-white 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"
|
|
13
21
|
>
|
|
14
22
|
<IconTrashBinSolid class="w-4 h-4" />
|
|
15
23
|
Delete
|
|
16
24
|
</button>
|
|
17
25
|
</BreadcrumbsWithButtons>
|
|
18
26
|
|
|
27
|
+
<component
|
|
28
|
+
v-for="c in coreStore?.resourceOptions?.pageInjections?.show?.afterBreadcrumbs || []"
|
|
29
|
+
:is="getCustomComponent(c)"
|
|
30
|
+
:meta="c.meta"
|
|
31
|
+
:record="coreStore.record"
|
|
32
|
+
:resource="coreStore.resource"
|
|
33
|
+
:adminUser="coreStore.adminUser"
|
|
34
|
+
/>
|
|
35
|
+
|
|
19
36
|
<div v-if="loading" role="status" class="max-w-sm animate-pulse">
|
|
20
37
|
<div class="h-2.5 bg-gray-200 rounded-full dark:bg-gray-700 w-48 mb-4"></div>
|
|
21
38
|
<div class="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[360px] mb-2.5"></div>
|
|
@@ -29,7 +46,7 @@
|
|
|
29
46
|
v-else
|
|
30
47
|
class="relative overflow-x-auto shadow-resourse-form-shadow "
|
|
31
48
|
>
|
|
32
|
-
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
|
|
49
|
+
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400 rounded-default">
|
|
33
50
|
<thead class="text-xs text-gray-700 uppercase bg-form-view-heading dark:bg-gray-700 dark:text-gray-400">
|
|
34
51
|
<tr>
|
|
35
52
|
<th scope="col" class="px-6 py-3">
|
|
@@ -41,23 +58,49 @@
|
|
|
41
58
|
</tr>
|
|
42
59
|
</thead>
|
|
43
60
|
<tbody>
|
|
44
|
-
<tr v-for="column in coreStore.
|
|
61
|
+
<tr v-for="column in coreStore.resource?.columns.filter(c => c.showIn.includes('show'))" :key="column.name"
|
|
45
62
|
class="bg-form-view-bg odd:dark:bg-gray-900 even:dark:bg-gray-800 border-b dark:border-gray-700"
|
|
46
63
|
>
|
|
47
|
-
|
|
48
|
-
|
|
64
|
+
<component
|
|
65
|
+
v-if="column.components?.showRow"
|
|
66
|
+
:is="getCustomComponent(column.components.showRow)"
|
|
67
|
+
:meta="column.components.showRow.meta"
|
|
68
|
+
:column="column"
|
|
69
|
+
:resource="coreStore.resource"
|
|
70
|
+
:record="coreStore.record"
|
|
71
|
+
/>
|
|
72
|
+
<template v-else>
|
|
73
|
+
<td class="px-6 py-4 whitespace-nowrap "> <!--align-top-->
|
|
74
|
+
{{ column.label }}
|
|
49
75
|
</td>
|
|
50
76
|
<td class="px-6 py-4 whitespace-nowrap whitespace-pre-wrap">
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
77
|
+
<component
|
|
78
|
+
v-if="showComponentsPerColumn[column.name]"
|
|
79
|
+
:is="showComponentsPerColumn[column.name]"
|
|
80
|
+
:resource="coreStore.resource"
|
|
81
|
+
:meta="column.components.show.meta"
|
|
82
|
+
:column="column"
|
|
83
|
+
:record="coreStore.record"
|
|
84
|
+
/>
|
|
85
|
+
<ValueRenderer v-else
|
|
86
|
+
:column="column"
|
|
87
|
+
:record="coreStore.record"
|
|
88
|
+
/>
|
|
56
89
|
</td>
|
|
90
|
+
</template>
|
|
57
91
|
</tr>
|
|
58
|
-
|
|
59
92
|
</tbody>
|
|
60
93
|
</table>
|
|
94
|
+
|
|
95
|
+
<component
|
|
96
|
+
v-for="c in coreStore?.resourceOptions?.pageInjections?.show?.bottom || []"
|
|
97
|
+
:is="getCustomComponent(c)"
|
|
98
|
+
:meta="c.meta"
|
|
99
|
+
:column="column"
|
|
100
|
+
:record="coreStore.record"
|
|
101
|
+
:resource="coreStore.resource"
|
|
102
|
+
:adminUser="coreStore.adminUser"
|
|
103
|
+
/>
|
|
61
104
|
</div>
|
|
62
105
|
|
|
63
106
|
|
|
@@ -68,37 +111,78 @@
|
|
|
68
111
|
<script setup>
|
|
69
112
|
|
|
70
113
|
import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
|
|
114
|
+
|
|
71
115
|
import ValueRenderer from '@/components/ValueRenderer.vue';
|
|
72
116
|
import { useCoreStore } from '@/stores/core';
|
|
73
|
-
import {
|
|
117
|
+
import { useModalStore } from '@/stores/modal';
|
|
118
|
+
import { getCustomComponent, checkAcessByAllowedActions } from '@/utils';
|
|
74
119
|
import { IconPenSolid, IconTrashBinSolid } from '@iconify-prerendered/vue-flowbite';
|
|
75
120
|
import { onMounted, ref } from 'vue';
|
|
76
|
-
import { useRoute } from 'vue-router';
|
|
121
|
+
import { useRoute,useRouter } from 'vue-router';
|
|
122
|
+
import {callAdminForthApi} from '@/utils';
|
|
123
|
+
import {showSuccesTost} from '@/composables/useFrontendApi';
|
|
77
124
|
|
|
78
125
|
|
|
79
126
|
const item = ref(null);
|
|
80
127
|
const route = useRoute();
|
|
128
|
+
const router = useRouter();
|
|
81
129
|
const loading = ref(false);
|
|
82
130
|
let showComponentsPerColumn = {};
|
|
83
131
|
|
|
132
|
+
console.log(route.params,'showWiev');
|
|
133
|
+
|
|
134
|
+
|
|
84
135
|
const coreStore = useCoreStore();
|
|
136
|
+
const modalStore = useModalStore();
|
|
85
137
|
|
|
86
138
|
onMounted(async () => {
|
|
87
139
|
loading.value = true;
|
|
88
|
-
await coreStore.
|
|
140
|
+
await coreStore.fetchResourceFull({
|
|
89
141
|
resourceId: route.params.resourceId
|
|
90
142
|
});
|
|
91
143
|
await coreStore.fetchRecord({
|
|
92
144
|
resourceId: route.params.resourceId,
|
|
93
145
|
primaryKey: route.params.primaryKey,
|
|
94
146
|
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
147
|
+
checkAcessByAllowedActions(coreStore.resourceOptions.allowedActions,'show');
|
|
148
|
+
|
|
149
|
+
showComponentsPerColumn = coreStore.resource.columns.reduce((acc, column) => {
|
|
150
|
+
if (column.components?.show) {
|
|
151
|
+
acc[column.name] = getCustomComponent(column.components.show);
|
|
98
152
|
}
|
|
99
153
|
return acc;
|
|
100
|
-
|
|
154
|
+
}, {});
|
|
101
155
|
loading.value = false;
|
|
102
156
|
});
|
|
103
157
|
|
|
158
|
+
async function deleteRecord(row) {
|
|
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({
|
|
167
|
+
path: '/delete_record',
|
|
168
|
+
method: 'POST',
|
|
169
|
+
body: {
|
|
170
|
+
resourceId: route.params.resourceId,
|
|
171
|
+
primaryKey: route.params.primaryKey,
|
|
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)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
} catch (e) {
|
|
181
|
+
console.error(e);
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
}
|
|
187
|
+
|
|
104
188
|
</script>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @type {import('tailwindcss').Config} */
|
|
2
2
|
export default {
|
|
3
|
-
content: ["./src/**/*.{vue, js}","./src/*.{vue, js}", "./index.html", "./node_modules/flowbite/**/*.js"],
|
|
3
|
+
content: ["./src/**/*.{vue, js, ts, tsx}","./src/*.{vue, js, ts, tsx}", "./index.html", "./node_modules/flowbite/**/*.js"],
|
|
4
4
|
theme: {
|
|
5
5
|
extend: {
|
|
6
6
|
/* IMPORTANT:ADMINFORTH TAILWIND STYLES */
|
package/dist/spa/vite.config.ts
CHANGED
package/index.ts
CHANGED
|
@@ -173,7 +173,7 @@ class AdminForth implements AdminForthClass {
|
|
|
173
173
|
errors.push(...this.checkCustomFileExists(this.config.customization.brandLogo));
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
if (
|
|
176
|
+
if (this.config.customization.favicon) {
|
|
177
177
|
errors.push(...this.checkCustomFileExists(this.config.customization.favicon));
|
|
178
178
|
}
|
|
179
179
|
|
|
@@ -732,16 +732,26 @@ class AdminForth implements AdminForthClass {
|
|
|
732
732
|
},
|
|
733
733
|
});
|
|
734
734
|
|
|
735
|
-
async function interpretResource(adminUser: AdminUser, resource: AdminForthResource, meta: any, source: ActionCheckSource) {
|
|
735
|
+
async function interpretResource(adminUser: AdminUser, resource: AdminForthResource, meta: any, source: ActionCheckSource): Promise<AdminForthResource> {
|
|
736
|
+
const newResource = JSON.parse(JSON.stringify(resource));
|
|
737
|
+
if (process.env.HEAVY_DEBUG) {
|
|
738
|
+
console.log('🪲Interpreting resource', resource.resourceId, source);
|
|
739
|
+
}
|
|
740
|
+
|
|
736
741
|
await Promise.all(
|
|
737
742
|
Object.entries(resource.options?.allowedActions || {}).map(
|
|
738
743
|
async ([key, value]: [string, AllowedActionValue]) => {
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
+
if (process.env.HEAVY_DEBUG) {
|
|
745
|
+
console.log('🪲checking for allowed call', key, 'value:', value, 'typeof', typeof value);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
// if callable then call
|
|
749
|
+
if (typeof value === 'function') {
|
|
750
|
+
resource.options.allowedActions[key] = await value({ adminUser, resource, meta, source });
|
|
751
|
+
}
|
|
752
|
+
})
|
|
744
753
|
);
|
|
754
|
+
return newResource;
|
|
745
755
|
}
|
|
746
756
|
|
|
747
757
|
function checkAccess(action: AllowedActionsEnum, resource: AdminForthResource): { allowed: boolean, error?: string } {
|
|
@@ -764,12 +774,12 @@ class AdminForth implements AdminForthClass {
|
|
|
764
774
|
if (this.statuses.dbDiscover !== 'done') {
|
|
765
775
|
return { error : 'Database discovery is still in progress, please try later' };
|
|
766
776
|
}
|
|
767
|
-
const
|
|
768
|
-
if (!
|
|
777
|
+
const configResource = this.config.resources.find((res) => res.resourceId == resourceId);
|
|
778
|
+
if (!configResource) {
|
|
769
779
|
return { error: `Resource ${resourceId} not found` };
|
|
770
780
|
}
|
|
771
781
|
|
|
772
|
-
await interpretResource(adminUser,
|
|
782
|
+
const resource = await interpretResource(adminUser, configResource, {}, ActionCheckSource.DisplayButtons);
|
|
773
783
|
|
|
774
784
|
// exclude "plugins" key
|
|
775
785
|
return { resource: { ...resource, plugins: undefined } };
|
|
@@ -789,12 +799,12 @@ class AdminForth implements AdminForthClass {
|
|
|
789
799
|
if (this.statuses.dbDiscover !== 'done') {
|
|
790
800
|
return { error : 'Database discovery is still in progress, please try later' };
|
|
791
801
|
}
|
|
792
|
-
const
|
|
793
|
-
if (!
|
|
802
|
+
const configResource = this.config.resources.find((res) => res.resourceId == resourceId);
|
|
803
|
+
if (!configResource) {
|
|
794
804
|
return { error: `Resource ${resourceId} not found` };
|
|
795
805
|
}
|
|
796
806
|
|
|
797
|
-
await interpretResource(adminUser,
|
|
807
|
+
const resource = await interpretResource(adminUser, configResource, { requestBody: body }, ActionCheckSource.DisplayButtons);
|
|
798
808
|
|
|
799
809
|
const { allowed, error } = checkAccess(source as AllowedActionsEnum, resource);
|
|
800
810
|
if (!allowed) {
|
|
@@ -1014,11 +1024,11 @@ class AdminForth implements AdminForthClass {
|
|
|
1014
1024
|
method: 'POST',
|
|
1015
1025
|
path: '/create_record',
|
|
1016
1026
|
handler: async ({ body, adminUser }) => {
|
|
1017
|
-
const
|
|
1018
|
-
if (!
|
|
1027
|
+
const configResource = this.config.resources.find((res) => res.resourceId == body['resourceId']);
|
|
1028
|
+
if (!configResource) {
|
|
1019
1029
|
return { error: `Resource '${body['resourceId']}' not found` };
|
|
1020
1030
|
}
|
|
1021
|
-
await interpretResource(adminUser,
|
|
1031
|
+
const resource = await interpretResource(adminUser, configResource, { requestBody: body}, ActionCheckSource.CreateRequest);
|
|
1022
1032
|
|
|
1023
1033
|
const { allowed, error } = checkAccess(AllowedActionsEnum.create, resource);
|
|
1024
1034
|
if (!allowed) {
|
|
@@ -1095,21 +1105,21 @@ class AdminForth implements AdminForthClass {
|
|
|
1095
1105
|
method: 'POST',
|
|
1096
1106
|
path: '/update_record',
|
|
1097
1107
|
handler: async ({ body, adminUser }) => {
|
|
1098
|
-
const
|
|
1099
|
-
if (!
|
|
1108
|
+
const configResource = this.config.resources.find((res) => res.resourceId == body['resourceId']);
|
|
1109
|
+
if (!configResource) {
|
|
1100
1110
|
return { error: `Resource '${body['resourceId']}' not found` };
|
|
1101
1111
|
}
|
|
1102
1112
|
|
|
1103
1113
|
const recordId = body['recordId'];
|
|
1104
|
-
const connector = this.connectors[
|
|
1105
|
-
const oldRecord = await connector.getRecordByPrimaryKey(
|
|
1114
|
+
const connector = this.connectors[configResource.dataSource];
|
|
1115
|
+
const oldRecord = await connector.getRecordByPrimaryKey(configResource, recordId)
|
|
1106
1116
|
if (!oldRecord) {
|
|
1107
|
-
const primaryKeyColumn =
|
|
1117
|
+
const primaryKeyColumn = configResource.columns.find((col) => col.primaryKey);
|
|
1108
1118
|
return { error: `Record with ${primaryKeyColumn.name} ${recordId} not found` };
|
|
1109
1119
|
}
|
|
1110
1120
|
const record = body['record'];
|
|
1111
1121
|
|
|
1112
|
-
await interpretResource(adminUser,
|
|
1122
|
+
const resource = await interpretResource(adminUser, configResource, { requestBody: body, record, oldRecord}, ActionCheckSource.EditRequest);
|
|
1113
1123
|
|
|
1114
1124
|
const { allowed, error } = checkAccess(AllowedActionsEnum.edit, resource);
|
|
1115
1125
|
if (!allowed) {
|
|
@@ -1168,19 +1178,19 @@ class AdminForth implements AdminForthClass {
|
|
|
1168
1178
|
method: 'POST',
|
|
1169
1179
|
path: '/delete_record',
|
|
1170
1180
|
handler: async ({ body, adminUser }) => {
|
|
1171
|
-
const
|
|
1172
|
-
const record = await this.connectors[
|
|
1173
|
-
if (!
|
|
1181
|
+
const configResource = this.config.resources.find((res) => res.resourceId == body['resourceId']);
|
|
1182
|
+
const record = await this.connectors[configResource.dataSource].getRecordByPrimaryKey(configResource, body['primaryKey']);
|
|
1183
|
+
if (!configResource) {
|
|
1174
1184
|
return { error: `Resource '${body['resourceId']}' not found` };
|
|
1175
1185
|
}
|
|
1176
1186
|
if (!record){
|
|
1177
1187
|
return { error: `Record with ${body['primaryKey']} not found` };
|
|
1178
1188
|
}
|
|
1179
|
-
if (
|
|
1180
|
-
return { error: `Resource '${
|
|
1189
|
+
if (configResource.options.allowedActions.delete === false) {
|
|
1190
|
+
return { error: `Resource '${configResource.resourceId}' does not allow delete action` };
|
|
1181
1191
|
}
|
|
1182
1192
|
|
|
1183
|
-
await interpretResource(adminUser,
|
|
1193
|
+
const resource = await interpretResource(adminUser, configResource, { requestBody: body }, ActionCheckSource.DeleteRequest);
|
|
1184
1194
|
|
|
1185
1195
|
const { allowed, error } = checkAccess(AllowedActionsEnum.delete, resource);
|
|
1186
1196
|
if (!allowed) {
|
package/package.json
CHANGED
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
</td>
|
|
119
119
|
</tr>
|
|
120
120
|
|
|
121
|
-
<tr
|
|
121
|
+
<tr v-else v-for="(row, rowI) in rows" :key="row.id"
|
|
122
122
|
class="bg-list-view-table-bg border-b dark:bg-gray-800 border-list-view-border-color dark:border-gray-700 hover:bg-list-view-table-row-hover dark:hover:bg-gray-600">
|
|
123
123
|
<td class="w-4 p-4">
|
|
124
124
|
<div class="flex items center">
|
|
@@ -385,15 +385,6 @@ function onSortButtonClick(field) {
|
|
|
385
385
|
}
|
|
386
386
|
}
|
|
387
387
|
|
|
388
|
-
const mouseDownTime = ref(0);
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
388
|
async function deleteRecord(row) {
|
|
398
389
|
const data = await window.adminforth.confirm({
|
|
399
390
|
message: 'Are you sure you want to delete this item?',
|
|
@@ -1,66 +0,0 @@
|
|
|
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
|
-
import AdminForthPlugin from "../base.js";
|
|
12
|
-
class AccessControlPlugin extends AdminForthPlugin {
|
|
13
|
-
constructor(options) {
|
|
14
|
-
super(options, import.meta.url);
|
|
15
|
-
this.options = options;
|
|
16
|
-
}
|
|
17
|
-
modifyResourceConfig(adminforth, resourceConfig) {
|
|
18
|
-
super.modifyResourceConfig(adminforth, resourceConfig);
|
|
19
|
-
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
|
-
}
|
|
64
|
-
}
|
|
65
|
-
AccessControlPlugin.defaultError = 'Sorry, you do not have access to this resource.';
|
|
66
|
-
export default AccessControlPlugin;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
Binary file
|
|
Binary file
|
package/dist/types.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// typical types which AdminForth supports
|
|
2
|
-
//
|
|
3
|
-
export const AdminForthTypes = {
|
|
4
|
-
STRING: 'string',
|
|
5
|
-
INTEGER: 'integer',
|
|
6
|
-
FLOAT: 'float',
|
|
7
|
-
DECIMAL: 'decimal',
|
|
8
|
-
BOOLEAN: 'boolean',
|
|
9
|
-
DATE: 'date',
|
|
10
|
-
DATETIME: 'datetime',
|
|
11
|
-
TIME: 'time',
|
|
12
|
-
TEXT: 'text',
|
|
13
|
-
JSON: 'json',
|
|
14
|
-
};
|
|
15
|
-
export const AdminForthFilterOperators = {
|
|
16
|
-
EQ: 'eq',
|
|
17
|
-
NE: 'ne',
|
|
18
|
-
GT: 'gt',
|
|
19
|
-
LT: 'lt',
|
|
20
|
-
GTE: 'gte',
|
|
21
|
-
LTE: 'lte',
|
|
22
|
-
LIKE: 'like',
|
|
23
|
-
ILIKE: 'ilike',
|
|
24
|
-
IN: 'in',
|
|
25
|
-
NIN: 'nin',
|
|
26
|
-
};
|
|
27
|
-
export const AdminForthSortDirections = {
|
|
28
|
-
ASC: 'asc',
|
|
29
|
-
DESC: 'desc',
|
|
30
|
-
};
|
|
File without changes
|