adminforth 1.2.37 → 1.2.39
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 +13 -2
- package/dist/basePlugin.js +6 -2
- package/dist/modules/configValidator.js +6 -4
- package/dist/modules/restApi.js +3 -4
- package/dist/spa/spa/src/components/ResourceForm.vue +3 -1
- package/dist/spa/spa/src/utils.ts +0 -1
- package/dist/spa/spa/src/views/ListView.vue +0 -6
- package/modules/configValidator.ts +9 -4
- package/modules/restApi.ts +3 -4
- package/package.json +1 -2
- package/spa/src/components/ResourceForm.vue +3 -1
- package/spa/src/utils.ts +0 -1
- package/spa/src/views/ListView.vue +0 -6
- package/types/AdminForthConfig.ts +12 -0
package/basePlugin.ts
CHANGED
|
@@ -3,7 +3,9 @@ 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
|
+
import crypto from 'crypto';
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
export default class AdminForthPlugin implements IAdminForthPlugin {
|
|
9
11
|
|
|
@@ -12,19 +14,28 @@ export default class AdminForthPlugin implements IAdminForthPlugin {
|
|
|
12
14
|
customFolderName: string = 'custom';
|
|
13
15
|
pluginInstanceId: string;
|
|
14
16
|
customFolderPath: string;
|
|
17
|
+
pluginOptions: any;
|
|
15
18
|
|
|
16
19
|
constructor(pluginOptions: any, metaUrl: string) {
|
|
17
20
|
// set up plugin here
|
|
18
21
|
this.pluginDir = currentFileDir(metaUrl);
|
|
19
|
-
this.pluginInstanceId = uuidv4();
|
|
20
22
|
this.customFolderPath = path.join(this.pluginDir, this.customFolderName);
|
|
23
|
+
this.pluginOptions = pluginOptions;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
setupEndpoints(server: any) {
|
|
24
27
|
|
|
25
28
|
}
|
|
26
29
|
|
|
30
|
+
instanceUniqueRepresentation(pluginOptions: any) : string {
|
|
31
|
+
return 'non-uniquely-identified';
|
|
32
|
+
}
|
|
33
|
+
|
|
27
34
|
modifyResourceConfig(adminforth: IAdminForth, resourceConfig: AdminForthResource) {
|
|
35
|
+
this.pluginInstanceId = crypto.createHash('sha256').update(
|
|
36
|
+
`af_pl_${this.constructor.name}_${resourceConfig.resourceId}_${this.instanceUniqueRepresentation(this.pluginOptions)}`
|
|
37
|
+
).digest('hex')
|
|
38
|
+
|
|
28
39
|
this.adminforth = adminforth;
|
|
29
40
|
}
|
|
30
41
|
|
package/dist/basePlugin.js
CHANGED
|
@@ -2,18 +2,22 @@ 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
|
-
import
|
|
5
|
+
import crypto from 'crypto';
|
|
6
6
|
export default class AdminForthPlugin {
|
|
7
7
|
constructor(pluginOptions, metaUrl) {
|
|
8
8
|
this.customFolderName = 'custom';
|
|
9
9
|
// set up plugin here
|
|
10
10
|
this.pluginDir = currentFileDir(metaUrl);
|
|
11
|
-
this.pluginInstanceId = uuidv4();
|
|
12
11
|
this.customFolderPath = path.join(this.pluginDir, this.customFolderName);
|
|
12
|
+
this.pluginOptions = pluginOptions;
|
|
13
13
|
}
|
|
14
14
|
setupEndpoints(server) {
|
|
15
15
|
}
|
|
16
|
+
instanceUniqueRepresentation(pluginOptions) {
|
|
17
|
+
return 'non-uniquely-identified';
|
|
18
|
+
}
|
|
16
19
|
modifyResourceConfig(adminforth, resourceConfig) {
|
|
20
|
+
this.pluginInstanceId = crypto.createHash('sha256').update(`af_pl_${this.constructor.name}_${resourceConfig.resourceId}_${this.instanceUniqueRepresentation(this.pluginOptions)}`).digest('hex');
|
|
17
21
|
this.adminforth = adminforth;
|
|
18
22
|
}
|
|
19
23
|
componentPath(componentFile) {
|
|
@@ -11,7 +11,7 @@ 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
|
-
import
|
|
14
|
+
import crypto from 'crypto';
|
|
15
15
|
export default class ConfigValidator {
|
|
16
16
|
constructor(adminforth, config) {
|
|
17
17
|
this.adminforth = adminforth;
|
|
@@ -274,10 +274,12 @@ export default class ConfigValidator {
|
|
|
274
274
|
})
|
|
275
275
|
});
|
|
276
276
|
}
|
|
277
|
-
|
|
278
|
-
|
|
277
|
+
bulkActions.map((action) => {
|
|
278
|
+
if (!action.id) {
|
|
279
|
+
action.id = crypto.createHash('sha256').update(action.label).digest('hex');
|
|
280
|
+
}
|
|
279
281
|
});
|
|
280
|
-
res.options.bulkActions =
|
|
282
|
+
res.options.bulkActions = bulkActions;
|
|
281
283
|
// if pageInjection is a string, make array with one element. Also check file exists
|
|
282
284
|
const possibleInjections = ['beforeBreadcrumbs', 'afterBreadcrumbs', 'bottom'];
|
|
283
285
|
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
|
}
|
|
@@ -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
|
|
|
@@ -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
|
|
|
@@ -11,7 +11,8 @@ import {
|
|
|
11
11
|
import fs from 'fs';
|
|
12
12
|
import path from 'path';
|
|
13
13
|
import { guessLabelFromName } from './utils.js';
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
import crypto from 'crypto';
|
|
15
16
|
|
|
16
17
|
export default class ConfigValidator implements IConfigValidator {
|
|
17
18
|
|
|
@@ -313,10 +314,14 @@ export default class ConfigValidator implements IConfigValidator {
|
|
|
313
314
|
});
|
|
314
315
|
}
|
|
315
316
|
|
|
316
|
-
|
|
317
|
-
|
|
317
|
+
bulkActions.map((action) => {
|
|
318
|
+
if (!action.id) {
|
|
319
|
+
action.id = crypto.createHash('sha256').update(
|
|
320
|
+
action.label,
|
|
321
|
+
).digest('hex');
|
|
322
|
+
}
|
|
318
323
|
});
|
|
319
|
-
res.options.bulkActions =
|
|
324
|
+
res.options.bulkActions = bulkActions;
|
|
320
325
|
|
|
321
326
|
// if pageInjection is a string, make array with one element. Also check file exists
|
|
322
327
|
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
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adminforth",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.39",
|
|
4
4
|
"description": "OpenSource Vue3 powered forth-generation admin panel",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@clickhouse/client": "^1.4.0",
|
|
19
19
|
"better-sqlite3": "^10.0.0",
|
|
20
|
-
"crypto": "^1.0.1",
|
|
21
20
|
"dayjs": "^1.11.11",
|
|
22
21
|
"express": "^4.19.2",
|
|
23
22
|
"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
|
|
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
|
|
|
@@ -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.
|