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 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
- import { v4 as uuidv4 } from 'uuid';
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
 
@@ -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 { v4 as uuidv4 } from 'uuid';
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 { v4 as uuid } from 'uuid';
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
- const newBulkActions = bulkActions.map((action) => {
278
- return Object.assign(action, { id: uuid() });
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 = newBulkActions;
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) {
@@ -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
- console.log('🪲Interpreting resource', resource.resourceId, source, 'adminUser', adminUser);
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="props.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
- import { v4 as uuid } from 'uuid';
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
- const newBulkActions = bulkActions.map((action) => {
317
- return Object.assign(action, { id: uuid() });
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 = newBulkActions;
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'];
@@ -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
- console.log('🪲Interpreting resource', resource.resourceId, source, 'adminUser', adminUser);
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.37",
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="props.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.