@adminforth/bulk-ai-flow 1.2.1 → 1.4.0

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/build.log CHANGED
@@ -11,5 +11,5 @@ custom/tsconfig.json
11
11
  custom/visionAction.vue
12
12
  custom/visionTable.vue
13
13
 
14
- sent 56,324 bytes received 134 bytes 112,916.00 bytes/sec
15
- total size is 55,817 speedup is 0.99
14
+ sent 56,553 bytes received 134 bytes 113,374.00 bytes/sec
15
+ total size is 56,046 speedup is 0.99
@@ -339,7 +339,7 @@ async function getGenerationPrompt() {
339
339
  if(!resp) {
340
340
  emit('error', {
341
341
  isError: true,
342
- errorMessage: "Something went wrong. Check your internet connection and try again."
342
+ errorMessage: "Error getting generation prompts."
343
343
  });
344
344
  }
345
345
  return resp?.generationOptions || null;
@@ -400,7 +400,7 @@ async function generateImages() {
400
400
  });
401
401
  emit('error', {
402
402
  isError: true,
403
- errorMessage: error
403
+ errorMessage: "Error re-generating images"
404
404
  });
405
405
  }
406
406
  return;
@@ -8,7 +8,6 @@
8
8
  <Dialog ref="confirmDialog">
9
9
  <div
10
10
  class="fixed inset-0 z-20 flex items-center justify-center bg-black/40"
11
- @click="closeDialog"
12
11
  >
13
12
  <div
14
13
  class="bulk-vision-dialog flex items-center justify-center relative max-w-[95vw] min-w-[640px] max-h-[90vh] bg-white dark:bg-gray-900 rounded-md shadow-2xl overflow-hidden"
@@ -73,7 +72,7 @@ import VisionTable from './visionTable.vue'
73
72
  import adminforth from '@/adminforth';
74
73
  import { useI18n } from 'vue-i18n';
75
74
  import { useRoute } from 'vue-router';
76
- import { type AdminUser, type AdminForthResourceCommon } from '@/types';
75
+ import { AdminUser, type AdminForthResourceCommon } from '@/types';
77
76
 
78
77
  const route = useRoute();
79
78
  const { t } = useI18n();
@@ -429,10 +428,18 @@ async function saveData() {
429
428
  },
430
429
  });
431
430
 
432
- if(res.ok) {
431
+ if(res.ok === true) {
433
432
  confirmDialog.value.close();
434
433
  props.updateList();
435
434
  props.clearCheckboxes();
435
+ } else if (res.ok === false) {
436
+ adminforth.alert({
437
+ message: res.error,
438
+ variant: 'danger',
439
+ timeout: 'unlimited',
440
+ });
441
+ isError.value = true;
442
+ errorMessage.value = `Failed to save data. You are not allowed to save.`;
436
443
  } else {
437
444
  console.error('Error saving data:', res);
438
445
  isError.value = true;
@@ -339,7 +339,7 @@ async function getGenerationPrompt() {
339
339
  if(!resp) {
340
340
  emit('error', {
341
341
  isError: true,
342
- errorMessage: "Something went wrong. Check your internet connection and try again."
342
+ errorMessage: "Error getting generation prompts."
343
343
  });
344
344
  }
345
345
  return resp?.generationOptions || null;
@@ -400,7 +400,7 @@ async function generateImages() {
400
400
  });
401
401
  emit('error', {
402
402
  isError: true,
403
- errorMessage: error
403
+ errorMessage: "Error re-generating images"
404
404
  });
405
405
  }
406
406
  return;
@@ -8,7 +8,6 @@
8
8
  <Dialog ref="confirmDialog">
9
9
  <div
10
10
  class="fixed inset-0 z-20 flex items-center justify-center bg-black/40"
11
- @click="closeDialog"
12
11
  >
13
12
  <div
14
13
  class="bulk-vision-dialog flex items-center justify-center relative max-w-[95vw] min-w-[640px] max-h-[90vh] bg-white dark:bg-gray-900 rounded-md shadow-2xl overflow-hidden"
@@ -73,7 +72,7 @@ import VisionTable from './visionTable.vue'
73
72
  import adminforth from '@/adminforth';
74
73
  import { useI18n } from 'vue-i18n';
75
74
  import { useRoute } from 'vue-router';
76
- import { type AdminUser, type AdminForthResourceCommon } from '@/types';
75
+ import { AdminUser, type AdminForthResourceCommon } from '@/types';
77
76
 
78
77
  const route = useRoute();
79
78
  const { t } = useI18n();
@@ -429,10 +428,18 @@ async function saveData() {
429
428
  },
430
429
  });
431
430
 
432
- if(res.ok) {
431
+ if(res.ok === true) {
433
432
  confirmDialog.value.close();
434
433
  props.updateList();
435
434
  props.clearCheckboxes();
435
+ } else if (res.ok === false) {
436
+ adminforth.alert({
437
+ message: res.error,
438
+ variant: 'danger',
439
+ timeout: 'unlimited',
440
+ });
441
+ isError.value = true;
442
+ errorMessage.value = `Failed to save data. You are not allowed to save.`;
436
443
  } else {
437
444
  console.error('Error saving data:', res);
438
445
  isError.value = true;
package/dist/index.js CHANGED
@@ -292,45 +292,54 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
292
292
  server.endpoint({
293
293
  method: 'POST',
294
294
  path: `/plugin/${this.pluginInstanceId}/update_fields`,
295
- handler: (body) => __awaiter(this, void 0, void 0, function* () {
296
- const selectedIds = body.body.selectedIds || [];
297
- const fieldsToUpdate = body.body.fields || {};
298
- const outputImageFields = [];
299
- if (this.options.generateImages) {
300
- for (const [key, value] of Object.entries(this.options.generateImages)) {
301
- outputImageFields.push(key);
302
- }
295
+ handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers }) {
296
+ let isAllowedToSave = { ok: true, error: '' };
297
+ if (this.options.isAllowedToSave) {
298
+ isAllowedToSave = yield this.options.isAllowedToSave({ record: {}, adminUser: adminUser, resource: this.resourceConfig });
303
299
  }
304
- const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
305
- const updates = selectedIds.map((ID, idx) => __awaiter(this, void 0, void 0, function* () {
306
- const oldRecord = yield this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ(primaryKeyColumn.name, ID)]);
307
- for (const [key, value] of Object.entries(outputImageFields)) {
308
- const columnPlugin = this.adminforth.activatedPlugins.find(p => p.resourceConfig.resourceId === this.resourceConfig.resourceId &&
309
- p.pluginOptions.pathColumnName === value);
310
- if (columnPlugin) {
311
- if (columnPlugin.pluginOptions.storageAdapter.objectCanBeAccesedPublicly()) {
312
- if (oldRecord[value]) {
313
- // put tag to delete old file
314
- try {
315
- yield columnPlugin.pluginOptions.storageAdapter.markKeyForDeletation(oldRecord[value]);
300
+ if (isAllowedToSave.ok !== false) {
301
+ const selectedIds = body.selectedIds || [];
302
+ const fieldsToUpdate = body.fields || {};
303
+ const outputImageFields = [];
304
+ if (this.options.generateImages) {
305
+ for (const [key, value] of Object.entries(this.options.generateImages)) {
306
+ outputImageFields.push(key);
307
+ }
308
+ }
309
+ const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
310
+ const updates = selectedIds.map((ID, idx) => __awaiter(this, void 0, void 0, function* () {
311
+ const oldRecord = yield this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ(primaryKeyColumn.name, ID)]);
312
+ for (const [key, value] of Object.entries(outputImageFields)) {
313
+ const columnPlugin = this.adminforth.activatedPlugins.find(p => p.resourceConfig.resourceId === this.resourceConfig.resourceId &&
314
+ p.pluginOptions.pathColumnName === value);
315
+ if (columnPlugin) {
316
+ if (columnPlugin.pluginOptions.storageAdapter.objectCanBeAccesedPublicly()) {
317
+ if (oldRecord[value]) {
318
+ // put tag to delete old file
319
+ try {
320
+ yield columnPlugin.pluginOptions.storageAdapter.markKeyForDeletation(oldRecord[value]);
321
+ }
322
+ catch (e) {
323
+ // file might be e.g. already deleted, so we catch error
324
+ console.error(`Error setting tag to true for object ${oldRecord[value]}. File will not be auto-cleaned up`, e);
325
+ }
316
326
  }
317
- catch (e) {
318
- // file might be e.g. already deleted, so we catch error
319
- console.error(`Error setting tag to true for object ${oldRecord[value]}. File will not be auto-cleaned up`, e);
327
+ if (fieldsToUpdate[idx][key] !== null) {
328
+ // remove tag from new file
329
+ // in this case we let it crash if it fails: this is a new file which just was uploaded.
330
+ yield columnPlugin.pluginOptions.storageAdapter.markKeyForNotDeletation(fieldsToUpdate[idx][value]);
320
331
  }
321
332
  }
322
- if (fieldsToUpdate[idx][key] !== null) {
323
- // remove tag from new file
324
- // in this case we let it crash if it fails: this is a new file which just was uploaded.
325
- yield columnPlugin.pluginOptions.storageAdapter.markKeyForNotDeletation(fieldsToUpdate[idx][value]);
326
- }
327
333
  }
328
334
  }
329
- }
330
- return this.adminforth.resource(this.resourceConfig.resourceId).update(ID, fieldsToUpdate[idx]);
331
- }));
332
- yield Promise.all(updates);
333
- return { ok: true };
335
+ return this.adminforth.resource(this.resourceConfig.resourceId).update(ID, fieldsToUpdate[idx]);
336
+ }));
337
+ yield Promise.all(updates);
338
+ return { ok: true };
339
+ }
340
+ else {
341
+ return { ok: false, error: isAllowedToSave.error };
342
+ }
334
343
  })
335
344
  });
336
345
  server.endpoint({
package/index.ts CHANGED
@@ -338,46 +338,54 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
338
338
  server.endpoint({
339
339
  method: 'POST',
340
340
  path: `/plugin/${this.pluginInstanceId}/update_fields`,
341
- handler: async ( body ) => {
342
- const selectedIds = body.body.selectedIds || [];
343
- const fieldsToUpdate = body.body.fields || {};
344
- const outputImageFields = [];
345
- if (this.options.generateImages) {
346
- for (const [key, value] of Object.entries(this.options.generateImages)) {
347
- outputImageFields.push(key);
348
- }
341
+ handler: async ({ body, adminUser, headers }) => {
342
+ let isAllowedToSave: any = { ok: true, error: '' };
343
+ if(this.options.isAllowedToSave) {
344
+ isAllowedToSave = await this.options.isAllowedToSave({ record: {}, adminUser: adminUser, resource: this.resourceConfig });
349
345
  }
350
- const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
351
- const updates = selectedIds.map(async (ID, idx) => {
352
- const oldRecord = await this.adminforth.resource(this.resourceConfig.resourceId).get( [Filters.EQ(primaryKeyColumn.name, ID)] );
353
- for (const [key, value] of Object.entries(outputImageFields)) {
354
- const columnPlugin = this.adminforth.activatedPlugins.find(p =>
355
- p.resourceConfig!.resourceId === this.resourceConfig.resourceId &&
356
- p.pluginOptions.pathColumnName === value
357
- );
358
- if (columnPlugin) {
359
- if(columnPlugin.pluginOptions.storageAdapter.objectCanBeAccesedPublicly()) {
360
- if (oldRecord[value]) {
361
- // put tag to delete old file
362
- try {
363
- await columnPlugin.pluginOptions.storageAdapter.markKeyForDeletation(oldRecord[value]);
364
- } catch (e) {
365
- // file might be e.g. already deleted, so we catch error
366
- console.error(`Error setting tag to true for object ${oldRecord[value]}. File will not be auto-cleaned up`, e);
346
+ if (isAllowedToSave.ok !== false) {
347
+ const selectedIds = body.selectedIds || [];
348
+ const fieldsToUpdate = body.fields || {};
349
+ const outputImageFields = [];
350
+ if (this.options.generateImages) {
351
+ for (const [key, value] of Object.entries(this.options.generateImages)) {
352
+ outputImageFields.push(key);
353
+ }
354
+ }
355
+ const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
356
+ const updates = selectedIds.map(async (ID, idx) => {
357
+ const oldRecord = await this.adminforth.resource(this.resourceConfig.resourceId).get( [Filters.EQ(primaryKeyColumn.name, ID)] );
358
+ for (const [key, value] of Object.entries(outputImageFields)) {
359
+ const columnPlugin = this.adminforth.activatedPlugins.find(p =>
360
+ p.resourceConfig!.resourceId === this.resourceConfig.resourceId &&
361
+ p.pluginOptions.pathColumnName === value
362
+ );
363
+ if (columnPlugin) {
364
+ if(columnPlugin.pluginOptions.storageAdapter.objectCanBeAccesedPublicly()) {
365
+ if (oldRecord[value]) {
366
+ // put tag to delete old file
367
+ try {
368
+ await columnPlugin.pluginOptions.storageAdapter.markKeyForDeletation(oldRecord[value]);
369
+ } catch (e) {
370
+ // file might be e.g. already deleted, so we catch error
371
+ console.error(`Error setting tag to true for object ${oldRecord[value]}. File will not be auto-cleaned up`, e);
372
+ }
373
+ }
374
+ if (fieldsToUpdate[idx][key] !== null) {
375
+ // remove tag from new file
376
+ // in this case we let it crash if it fails: this is a new file which just was uploaded.
377
+ await columnPlugin.pluginOptions.storageAdapter.markKeyForNotDeletation(fieldsToUpdate[idx][value]);
367
378
  }
368
- }
369
- if (fieldsToUpdate[idx][key] !== null) {
370
- // remove tag from new file
371
- // in this case we let it crash if it fails: this is a new file which just was uploaded.
372
- await columnPlugin.pluginOptions.storageAdapter.markKeyForNotDeletation(fieldsToUpdate[idx][value]);
373
379
  }
374
380
  }
375
381
  }
376
- }
377
- return this.adminforth.resource(this.resourceConfig.resourceId).update(ID, fieldsToUpdate[idx])
378
- });
379
- await Promise.all(updates);
380
- return { ok: true };
382
+ return this.adminforth.resource(this.resourceConfig.resourceId).update(ID, fieldsToUpdate[idx])
383
+ });
384
+ await Promise.all(updates);
385
+ return { ok: true };
386
+ } else {
387
+ return { ok: false, error: isAllowedToSave.error };
388
+ }
381
389
  }
382
390
  });
383
391
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminforth/bulk-ai-flow",
3
- "version": "1.2.1",
3
+ "version": "1.4.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/types.ts CHANGED
@@ -47,4 +47,19 @@ export interface PluginOptions {
47
47
  * As rateLimit on generateImages, but applied to bulk generations
48
48
  **/
49
49
  bulkGenerationRateLimit?: string,
50
+
51
+ /**
52
+ * Whether the user is allowed to save the generated images
53
+ */
54
+ isAllowedToSave?: ({ record, adminUser, resource }: {
55
+ record: any;
56
+ adminUser: any;
57
+ resource: any;
58
+ }) => Promise<{
59
+ ok: boolean;
60
+ error: string;
61
+ } | {
62
+ ok: boolean;
63
+ error?: undefined;
64
+ }>
50
65
  }