adminforth 1.2.36 → 1.2.38
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/basePlugin.ts +14 -2
- package/dist/basePlugin.js +8 -2
- package/dist/modules/configValidator.js +11 -4
- package/dist/modules/restApi.js +6 -10
- package/dist/spa/spa/src/components/ResourceForm.vue +3 -1
- package/dist/spa/spa/src/components/ResourceListTable.vue +12 -10
- package/dist/spa/spa/src/utils.ts +0 -1
- package/dist/spa/spa/src/views/ListView.vue +5 -13
- package/modules/configValidator.ts +14 -4
- package/modules/restApi.ts +5 -6
- package/package.json +2 -1
- package/spa/src/components/ResourceForm.vue +3 -1
- package/spa/src/components/ResourceListTable.vue +12 -10
- package/spa/src/utils.ts +0 -1
- package/spa/src/views/ListView.vue +5 -13
- package/types/AdminForthConfig.ts +12 -0
package/basePlugin.ts
CHANGED
|
@@ -3,7 +3,10 @@ import { getComponentNameFromPath } from './modules/utils.js';
|
|
|
3
3
|
import { currentFileDir } from './modules/utils.js';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import fs from 'fs';
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
import sha256 from 'crypto-js/sha256';
|
|
9
|
+
|
|
7
10
|
|
|
8
11
|
export default class AdminForthPlugin implements IAdminForthPlugin {
|
|
9
12
|
|
|
@@ -12,19 +15,28 @@ export default class AdminForthPlugin implements IAdminForthPlugin {
|
|
|
12
15
|
customFolderName: string = 'custom';
|
|
13
16
|
pluginInstanceId: string;
|
|
14
17
|
customFolderPath: string;
|
|
18
|
+
pluginOptions: any;
|
|
15
19
|
|
|
16
20
|
constructor(pluginOptions: any, metaUrl: string) {
|
|
17
21
|
// set up plugin here
|
|
18
22
|
this.pluginDir = currentFileDir(metaUrl);
|
|
19
|
-
this.pluginInstanceId = uuidv4();
|
|
20
23
|
this.customFolderPath = path.join(this.pluginDir, this.customFolderName);
|
|
24
|
+
this.pluginOptions = pluginOptions;
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
setupEndpoints(server: any) {
|
|
24
28
|
|
|
25
29
|
}
|
|
26
30
|
|
|
31
|
+
instanceUniqueRepresentation(pluginOptions: any) : string {
|
|
32
|
+
return 'non-uniquely-identified';
|
|
33
|
+
}
|
|
34
|
+
|
|
27
35
|
modifyResourceConfig(adminforth: IAdminForth, resourceConfig: AdminForthResource) {
|
|
36
|
+
this.pluginInstanceId = sha256(
|
|
37
|
+
`af_pl_${this.constructor.name}_${resourceConfig.resourceId}_${this.instanceUniqueRepresentation(this.pluginOptions)}`
|
|
38
|
+
).toString();
|
|
39
|
+
console.log(`5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣ Plugin instance id: ${this.pluginInstanceId}`);
|
|
28
40
|
this.adminforth = adminforth;
|
|
29
41
|
}
|
|
30
42
|
|
package/dist/basePlugin.js
CHANGED
|
@@ -2,18 +2,24 @@ import { getComponentNameFromPath } from './modules/utils.js';
|
|
|
2
2
|
import { currentFileDir } from './modules/utils.js';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import fs from 'fs';
|
|
5
|
-
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
import sha256 from 'crypto-js/sha256';
|
|
6
7
|
export default class AdminForthPlugin {
|
|
7
8
|
constructor(pluginOptions, metaUrl) {
|
|
8
9
|
this.customFolderName = 'custom';
|
|
9
10
|
// set up plugin here
|
|
10
11
|
this.pluginDir = currentFileDir(metaUrl);
|
|
11
|
-
this.pluginInstanceId = uuidv4();
|
|
12
12
|
this.customFolderPath = path.join(this.pluginDir, this.customFolderName);
|
|
13
|
+
this.pluginOptions = pluginOptions;
|
|
13
14
|
}
|
|
14
15
|
setupEndpoints(server) {
|
|
15
16
|
}
|
|
17
|
+
instanceUniqueRepresentation(pluginOptions) {
|
|
18
|
+
return 'non-uniquely-identified';
|
|
19
|
+
}
|
|
16
20
|
modifyResourceConfig(adminforth, resourceConfig) {
|
|
21
|
+
this.pluginInstanceId = sha256(`af_pl_${this.constructor.name}_${resourceConfig.resourceId}_${this.instanceUniqueRepresentation(this.pluginOptions)}`).toString();
|
|
22
|
+
console.log(`5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣5️⃣ Plugin instance id: ${this.pluginInstanceId}`);
|
|
17
23
|
this.adminforth = adminforth;
|
|
18
24
|
}
|
|
19
25
|
componentPath(componentFile) {
|
|
@@ -11,7 +11,8 @@ import { AdminForthResourcePages, AllowedActionsEnum, } from "../types/AdminFort
|
|
|
11
11
|
import fs from 'fs';
|
|
12
12
|
import path from 'path';
|
|
13
13
|
import { guessLabelFromName } from './utils.js';
|
|
14
|
-
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
import sha256 from 'crypto-js/sha256';
|
|
15
16
|
export default class ConfigValidator {
|
|
16
17
|
constructor(adminforth, config) {
|
|
17
18
|
this.adminforth = adminforth;
|
|
@@ -248,6 +249,7 @@ export default class ConfigValidator {
|
|
|
248
249
|
allowed: (_b) => __awaiter(this, [_b], void 0, function* ({ resource, adminUser, allowedActions }) { return allowedActions.delete; }),
|
|
249
250
|
action: (_c) => __awaiter(this, [_c], void 0, function* ({ selectedIds, adminUser }) {
|
|
250
251
|
const connector = this.adminforth.connectors[res.dataSource];
|
|
252
|
+
// for now if at least one error, stop and return error
|
|
251
253
|
let error = null;
|
|
252
254
|
yield Promise.all(selectedIds.map((recordId) => __awaiter(this, void 0, void 0, function* () {
|
|
253
255
|
const record = yield connector.getRecordByPrimaryKey(res, recordId);
|
|
@@ -257,6 +259,9 @@ export default class ConfigValidator {
|
|
|
257
259
|
error = resp.error;
|
|
258
260
|
}
|
|
259
261
|
})));
|
|
262
|
+
if (error) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
260
265
|
yield connector.deleteRecord({ resource: res, recordId });
|
|
261
266
|
// call afterDelete hook
|
|
262
267
|
yield Promise.all(res.hooks.delete.afterSave.map((hook) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -270,10 +275,12 @@ export default class ConfigValidator {
|
|
|
270
275
|
})
|
|
271
276
|
});
|
|
272
277
|
}
|
|
273
|
-
|
|
274
|
-
|
|
278
|
+
bulkActions.map((action) => {
|
|
279
|
+
if (!action.id) {
|
|
280
|
+
action.id = sha256(action.label).toString();
|
|
281
|
+
}
|
|
275
282
|
});
|
|
276
|
-
res.options.bulkActions =
|
|
283
|
+
res.options.bulkActions = bulkActions;
|
|
277
284
|
// if pageInjection is a string, make array with one element. Also check file exists
|
|
278
285
|
const possibleInjections = ['beforeBreadcrumbs', 'afterBreadcrumbs', 'bottom'];
|
|
279
286
|
if (res.options.pageInjections) {
|
package/dist/modules/restApi.js
CHANGED
|
@@ -200,9 +200,9 @@ export default class AdminForthRestAPI {
|
|
|
200
200
|
function interpretResource(adminUser, resource, meta, source) {
|
|
201
201
|
return __awaiter(this, void 0, void 0, function* () {
|
|
202
202
|
var _a;
|
|
203
|
-
if (process.env.HEAVY_DEBUG) {
|
|
204
|
-
|
|
205
|
-
}
|
|
203
|
+
// if (process.env.HEAVY_DEBUG) {
|
|
204
|
+
// console.log('🪲Interpreting resource', resource.resourceId, source, 'adminUser', adminUser);
|
|
205
|
+
// }
|
|
206
206
|
const allowedActions = {};
|
|
207
207
|
yield Promise.all(Object.entries(((_a = resource.options) === null || _a === void 0 ? void 0 : _a.allowedActions) || {}).map((_b) => __awaiter(this, [_b], void 0, function* ([key, value]) {
|
|
208
208
|
if (process.env.HEAVY_DEBUG) {
|
|
@@ -246,7 +246,6 @@ export default class AdminForthRestAPI {
|
|
|
246
246
|
yield Promise.all(resource.options.bulkActions.map((action) => __awaiter(this, void 0, void 0, function* () {
|
|
247
247
|
if (action.allowed) {
|
|
248
248
|
const res = yield action.allowed({ adminUser, resource, allowedActions });
|
|
249
|
-
console.log('🪲🪲🪲🪲checking for allowedActions', allowedActions, 'res', res);
|
|
250
249
|
if (res) {
|
|
251
250
|
allowedBulkActions.push(action);
|
|
252
251
|
}
|
|
@@ -622,13 +621,10 @@ export default class AdminForthRestAPI {
|
|
|
622
621
|
if (!execAllowed) {
|
|
623
622
|
return { error: `Action '${actionId}' is not allowed` };
|
|
624
623
|
}
|
|
625
|
-
yield action.action({ selectedIds: recordIds, adminUser, resource });
|
|
626
|
-
return {
|
|
627
|
-
actionId,
|
|
624
|
+
const response = yield action.action({ selectedIds: recordIds, adminUser, resource });
|
|
625
|
+
return Object.assign({ actionId,
|
|
628
626
|
recordIds,
|
|
629
|
-
resourceId,
|
|
630
|
-
status: 'success'
|
|
631
|
-
};
|
|
627
|
+
resourceId }, response);
|
|
632
628
|
})
|
|
633
629
|
});
|
|
634
630
|
// setup endpoints for all plugins
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
:value="currentValues[column.name]"
|
|
42
42
|
@update:value="setCurrentValue(column.name, $event)"
|
|
43
43
|
:meta="column.components[props.source].meta"
|
|
44
|
-
:record="
|
|
44
|
+
:record="currentValues"
|
|
45
45
|
@update:inValidity="customComponentsInValidity[column.name] = $event"
|
|
46
46
|
@update:emptiness="customComponentsEmptiness[column.name] = $event"
|
|
47
47
|
/>
|
|
@@ -238,6 +238,8 @@ const setCurrentValue = (key, value) => {
|
|
|
238
238
|
} else {
|
|
239
239
|
currentValues.value[key] = value;
|
|
240
240
|
}
|
|
241
|
+
currentValues.value = { ...currentValues.value };
|
|
242
|
+
console.log('3️⃣ setCurrentValue', key, value);
|
|
241
243
|
emit('update:record', currentValues.value);
|
|
242
244
|
};
|
|
243
245
|
|
|
@@ -228,7 +228,7 @@ import { callAdminForthApi, getIcon } from '@/utils';
|
|
|
228
228
|
import ValueRenderer from '@/components/ValueRenderer.vue';
|
|
229
229
|
import { getCustomComponent } from '@/utils';
|
|
230
230
|
import { useCoreStore } from '@/stores/core';
|
|
231
|
-
import { showSuccesTost } from '@/composables/useFrontendApi';
|
|
231
|
+
import { showSuccesTost, showErrorTost } from '@/composables/useFrontendApi';
|
|
232
232
|
import SkeleteLoader from '@/components/SkeleteLoader.vue';
|
|
233
233
|
|
|
234
234
|
import {
|
|
@@ -368,22 +368,24 @@ async function deleteRecord(row) {
|
|
|
368
368
|
if (data) {
|
|
369
369
|
try {
|
|
370
370
|
const res = await callAdminForthApi({
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
371
|
+
path: '/delete_record',
|
|
372
|
+
method: 'POST',
|
|
373
|
+
body: {
|
|
374
|
+
resourceId: props.resource.resourceId,
|
|
375
|
+
primaryKey: row._primaryKeyValue,
|
|
376
|
+
}
|
|
377
|
+
});
|
|
377
378
|
if (!res.error){
|
|
378
379
|
emits('update:records', true)
|
|
379
380
|
showSuccesTost('Record deleted successfully')
|
|
380
381
|
} else {
|
|
381
|
-
|
|
382
|
+
showErrorTost(res.error)
|
|
382
383
|
}
|
|
383
384
|
|
|
384
385
|
} catch (e) {
|
|
386
|
+
showErrorTost(`Something went wrong, please try again later`);
|
|
385
387
|
console.error(e);
|
|
386
|
-
|
|
387
|
-
|
|
388
|
+
};
|
|
389
|
+
}
|
|
388
390
|
}
|
|
389
391
|
</script>
|
|
@@ -42,7 +42,6 @@ export async function callAdminForthApi({ path, method, body=undefined }: {
|
|
|
42
42
|
|
|
43
43
|
export function getCustomComponent({ file, meta }: { file: string, meta: any }) {
|
|
44
44
|
const name = file.replace(/@/g, '').replace(/\./g, '').replace(/\//g, '');
|
|
45
|
-
console.log('resolving name', name);
|
|
46
45
|
return resolveComponent(name);
|
|
47
46
|
}
|
|
48
47
|
|
|
@@ -124,11 +124,7 @@ import { getCustomComponent } from '@/utils';
|
|
|
124
124
|
|
|
125
125
|
import {
|
|
126
126
|
IconBanOutline,
|
|
127
|
-
IconEyeSolid,
|
|
128
127
|
IconFilterOutline,
|
|
129
|
-
IconPenSolid,
|
|
130
|
-
IconTrashBinSolid,
|
|
131
|
-
IconInboxOutline,
|
|
132
128
|
IconPlusOutline
|
|
133
129
|
} from '@iconify-prerendered/vue-flowbite';
|
|
134
130
|
|
|
@@ -137,13 +133,11 @@ import Filters from '@/components/Filters.vue';
|
|
|
137
133
|
const filtersShow = ref(false);
|
|
138
134
|
|
|
139
135
|
const coreStore = useCoreStore();
|
|
140
|
-
const modalStore = useModalStore();
|
|
141
136
|
const filtersStore = useFiltersStore();
|
|
142
137
|
|
|
143
138
|
const route = useRoute();
|
|
144
139
|
|
|
145
140
|
const page = ref(1);
|
|
146
|
-
const filters = filtersStore.filters;
|
|
147
141
|
const columnsMinMax = ref({});
|
|
148
142
|
const sort = ref([]);
|
|
149
143
|
|
|
@@ -200,11 +194,6 @@ async function getList() {
|
|
|
200
194
|
totalRows.value = data.total;
|
|
201
195
|
}
|
|
202
196
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
197
|
async function startBulkAction(actionId) {
|
|
209
198
|
const data = await callAdminForthApi({
|
|
210
199
|
path: '/start_bulk_action',
|
|
@@ -216,10 +205,13 @@ async function startBulkAction(actionId) {
|
|
|
216
205
|
|
|
217
206
|
}
|
|
218
207
|
});
|
|
219
|
-
if (data?.
|
|
208
|
+
if (data?.ok) {
|
|
220
209
|
checkboxes.value = [];
|
|
210
|
+
await getList();
|
|
211
|
+
}
|
|
212
|
+
if (data?.error) {
|
|
213
|
+
showErrorTost(data.error);
|
|
221
214
|
}
|
|
222
|
-
await getList();
|
|
223
215
|
}
|
|
224
216
|
|
|
225
217
|
|
|
@@ -11,7 +11,9 @@ import {
|
|
|
11
11
|
import fs from 'fs';
|
|
12
12
|
import path from 'path';
|
|
13
13
|
import { guessLabelFromName } from './utils.js';
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
import sha256 from 'crypto-js/sha256';
|
|
15
17
|
|
|
16
18
|
export default class ConfigValidator implements IConfigValidator {
|
|
17
19
|
|
|
@@ -269,6 +271,8 @@ export default class ConfigValidator implements IConfigValidator {
|
|
|
269
271
|
allowed: async ({ resource, adminUser, allowedActions }) => { return allowedActions.delete },
|
|
270
272
|
action: async ({ selectedIds, adminUser }) => {
|
|
271
273
|
const connector = this.adminforth.connectors[res.dataSource];
|
|
274
|
+
|
|
275
|
+
// for now if at least one error, stop and return error
|
|
272
276
|
let error = null;
|
|
273
277
|
|
|
274
278
|
await Promise.all(
|
|
@@ -285,6 +289,10 @@ export default class ConfigValidator implements IConfigValidator {
|
|
|
285
289
|
}
|
|
286
290
|
)
|
|
287
291
|
)
|
|
292
|
+
|
|
293
|
+
if (error) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
288
296
|
|
|
289
297
|
await connector.deleteRecord({ resource: res, recordId });
|
|
290
298
|
// call afterDelete hook
|
|
@@ -307,10 +315,12 @@ export default class ConfigValidator implements IConfigValidator {
|
|
|
307
315
|
});
|
|
308
316
|
}
|
|
309
317
|
|
|
310
|
-
|
|
311
|
-
|
|
318
|
+
bulkActions.map((action) => {
|
|
319
|
+
if (!action.id) {
|
|
320
|
+
action.id = sha256(action.label).toString();
|
|
321
|
+
}
|
|
312
322
|
});
|
|
313
|
-
res.options.bulkActions =
|
|
323
|
+
res.options.bulkActions = bulkActions;
|
|
314
324
|
|
|
315
325
|
// if pageInjection is a string, make array with one element. Also check file exists
|
|
316
326
|
const possibleInjections = ['beforeBreadcrumbs', 'afterBreadcrumbs', 'bottom'];
|
package/modules/restApi.ts
CHANGED
|
@@ -225,9 +225,9 @@ export default class AdminForthRestAPI {
|
|
|
225
225
|
});
|
|
226
226
|
|
|
227
227
|
async function interpretResource(adminUser: AdminUser, resource: AdminForthResource, meta: any, source: ActionCheckSource): Promise<{allowedActions: AllowedActionsResolved}> {
|
|
228
|
-
if (process.env.HEAVY_DEBUG) {
|
|
229
|
-
|
|
230
|
-
}
|
|
228
|
+
// if (process.env.HEAVY_DEBUG) {
|
|
229
|
+
// console.log('🪲Interpreting resource', resource.resourceId, source, 'adminUser', adminUser);
|
|
230
|
+
// }
|
|
231
231
|
const allowedActions = {};
|
|
232
232
|
|
|
233
233
|
await Promise.all(
|
|
@@ -281,7 +281,6 @@ export default class AdminForthRestAPI {
|
|
|
281
281
|
resource.options.bulkActions.map(async (action) => {
|
|
282
282
|
if (action.allowed) {
|
|
283
283
|
const res = await action.allowed({ adminUser, resource, allowedActions });
|
|
284
|
-
console.log('🪲🪲🪲🪲checking for allowedActions', allowedActions, 'res', res);
|
|
285
284
|
if (res) {
|
|
286
285
|
allowedBulkActions.push(action);
|
|
287
286
|
}
|
|
@@ -712,13 +711,13 @@ export default class AdminForthRestAPI {
|
|
|
712
711
|
if (!execAllowed) {
|
|
713
712
|
return { error: `Action '${actionId}' is not allowed` };
|
|
714
713
|
}
|
|
715
|
-
await action.action({selectedIds: recordIds, adminUser, resource});
|
|
714
|
+
const response = await action.action({selectedIds: recordIds, adminUser, resource});
|
|
716
715
|
|
|
717
716
|
return {
|
|
718
717
|
actionId,
|
|
719
718
|
recordIds,
|
|
720
719
|
resourceId,
|
|
721
|
-
|
|
720
|
+
...response
|
|
722
721
|
}
|
|
723
722
|
}
|
|
724
723
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adminforth",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.38",
|
|
4
4
|
"description": "OpenSource Vue3 powered forth-generation admin panel",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"@clickhouse/client": "^1.4.0",
|
|
19
19
|
"better-sqlite3": "^10.0.0",
|
|
20
20
|
"crypto": "^1.0.1",
|
|
21
|
+
"crypto-js": "^4.2.0",
|
|
21
22
|
"dayjs": "^1.11.11",
|
|
22
23
|
"express": "^4.19.2",
|
|
23
24
|
"filewatcher": "^3.0.1",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
:value="currentValues[column.name]"
|
|
42
42
|
@update:value="setCurrentValue(column.name, $event)"
|
|
43
43
|
:meta="column.components[props.source].meta"
|
|
44
|
-
:record="
|
|
44
|
+
:record="currentValues"
|
|
45
45
|
@update:inValidity="customComponentsInValidity[column.name] = $event"
|
|
46
46
|
@update:emptiness="customComponentsEmptiness[column.name] = $event"
|
|
47
47
|
/>
|
|
@@ -238,6 +238,8 @@ const setCurrentValue = (key, value) => {
|
|
|
238
238
|
} else {
|
|
239
239
|
currentValues.value[key] = value;
|
|
240
240
|
}
|
|
241
|
+
currentValues.value = { ...currentValues.value };
|
|
242
|
+
console.log('3️⃣ setCurrentValue', key, value);
|
|
241
243
|
emit('update:record', currentValues.value);
|
|
242
244
|
};
|
|
243
245
|
|
|
@@ -228,7 +228,7 @@ import { callAdminForthApi, getIcon } from '@/utils';
|
|
|
228
228
|
import ValueRenderer from '@/components/ValueRenderer.vue';
|
|
229
229
|
import { getCustomComponent } from '@/utils';
|
|
230
230
|
import { useCoreStore } from '@/stores/core';
|
|
231
|
-
import { showSuccesTost } from '@/composables/useFrontendApi';
|
|
231
|
+
import { showSuccesTost, showErrorTost } from '@/composables/useFrontendApi';
|
|
232
232
|
import SkeleteLoader from '@/components/SkeleteLoader.vue';
|
|
233
233
|
|
|
234
234
|
import {
|
|
@@ -368,22 +368,24 @@ async function deleteRecord(row) {
|
|
|
368
368
|
if (data) {
|
|
369
369
|
try {
|
|
370
370
|
const res = await callAdminForthApi({
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
371
|
+
path: '/delete_record',
|
|
372
|
+
method: 'POST',
|
|
373
|
+
body: {
|
|
374
|
+
resourceId: props.resource.resourceId,
|
|
375
|
+
primaryKey: row._primaryKeyValue,
|
|
376
|
+
}
|
|
377
|
+
});
|
|
377
378
|
if (!res.error){
|
|
378
379
|
emits('update:records', true)
|
|
379
380
|
showSuccesTost('Record deleted successfully')
|
|
380
381
|
} else {
|
|
381
|
-
|
|
382
|
+
showErrorTost(res.error)
|
|
382
383
|
}
|
|
383
384
|
|
|
384
385
|
} catch (e) {
|
|
386
|
+
showErrorTost(`Something went wrong, please try again later`);
|
|
385
387
|
console.error(e);
|
|
386
|
-
|
|
387
|
-
|
|
388
|
+
};
|
|
389
|
+
}
|
|
388
390
|
}
|
|
389
391
|
</script>
|
package/spa/src/utils.ts
CHANGED
|
@@ -42,7 +42,6 @@ export async function callAdminForthApi({ path, method, body=undefined }: {
|
|
|
42
42
|
|
|
43
43
|
export function getCustomComponent({ file, meta }: { file: string, meta: any }) {
|
|
44
44
|
const name = file.replace(/@/g, '').replace(/\./g, '').replace(/\//g, '');
|
|
45
|
-
console.log('resolving name', name);
|
|
46
45
|
return resolveComponent(name);
|
|
47
46
|
}
|
|
48
47
|
|
|
@@ -124,11 +124,7 @@ import { getCustomComponent } from '@/utils';
|
|
|
124
124
|
|
|
125
125
|
import {
|
|
126
126
|
IconBanOutline,
|
|
127
|
-
IconEyeSolid,
|
|
128
127
|
IconFilterOutline,
|
|
129
|
-
IconPenSolid,
|
|
130
|
-
IconTrashBinSolid,
|
|
131
|
-
IconInboxOutline,
|
|
132
128
|
IconPlusOutline
|
|
133
129
|
} from '@iconify-prerendered/vue-flowbite';
|
|
134
130
|
|
|
@@ -137,13 +133,11 @@ import Filters from '@/components/Filters.vue';
|
|
|
137
133
|
const filtersShow = ref(false);
|
|
138
134
|
|
|
139
135
|
const coreStore = useCoreStore();
|
|
140
|
-
const modalStore = useModalStore();
|
|
141
136
|
const filtersStore = useFiltersStore();
|
|
142
137
|
|
|
143
138
|
const route = useRoute();
|
|
144
139
|
|
|
145
140
|
const page = ref(1);
|
|
146
|
-
const filters = filtersStore.filters;
|
|
147
141
|
const columnsMinMax = ref({});
|
|
148
142
|
const sort = ref([]);
|
|
149
143
|
|
|
@@ -200,11 +194,6 @@ async function getList() {
|
|
|
200
194
|
totalRows.value = data.total;
|
|
201
195
|
}
|
|
202
196
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
197
|
async function startBulkAction(actionId) {
|
|
209
198
|
const data = await callAdminForthApi({
|
|
210
199
|
path: '/start_bulk_action',
|
|
@@ -216,10 +205,13 @@ async function startBulkAction(actionId) {
|
|
|
216
205
|
|
|
217
206
|
}
|
|
218
207
|
});
|
|
219
|
-
if (data?.
|
|
208
|
+
if (data?.ok) {
|
|
220
209
|
checkboxes.value = [];
|
|
210
|
+
await getList();
|
|
211
|
+
}
|
|
212
|
+
if (data?.error) {
|
|
213
|
+
showErrorTost(data.error);
|
|
221
214
|
}
|
|
222
|
-
await getList();
|
|
223
215
|
}
|
|
224
216
|
|
|
225
217
|
|
|
@@ -276,6 +276,7 @@ export interface IAdminForthPlugin {
|
|
|
276
276
|
customFolderName: string;
|
|
277
277
|
pluginInstanceId: string;
|
|
278
278
|
customFolderPath: string;
|
|
279
|
+
pluginOptions: any;
|
|
279
280
|
|
|
280
281
|
/**
|
|
281
282
|
* AdminForth plugins concept is based on modification of full AdminForth configuration
|
|
@@ -289,6 +290,17 @@ export interface IAdminForthPlugin {
|
|
|
289
290
|
modifyResourceConfig(adminforth: IAdminForth, resourceConfig: AdminForthResource): void;
|
|
290
291
|
componentPath(componentFile: string): string;
|
|
291
292
|
|
|
293
|
+
/**
|
|
294
|
+
* If plugin should support multiple installations per one resource, this function that should return unique string for each instance of plugin.
|
|
295
|
+
* For example if plugin is installed for one column and this column defined as
|
|
296
|
+
* `targetColumn` in plugin options, then this method should return `${pluginOptions.targetColumn}`.
|
|
297
|
+
*
|
|
298
|
+
* If plugin should support only one installation per resource, option can return 'single'
|
|
299
|
+
* @param pluginOptions - options of plugin
|
|
300
|
+
*/
|
|
301
|
+
instanceUniqueRepresentation(pluginOptions: any) : string;
|
|
302
|
+
|
|
303
|
+
|
|
292
304
|
/**
|
|
293
305
|
* Optional method which will be called after AdminForth discovers all resources and their columns.
|
|
294
306
|
* Can be used to validate types of columns, check if some columns are missing, etc.
|