@adminforth/bulk-ai-flow 1.4.0 → 1.4.2

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,553 bytes received 134 bytes 113,374.00 bytes/sec
15
- total size is 56,046 speedup is 0.99
14
+ sent 57,708 bytes received 134 bytes 115,684.00 bytes/sec
15
+ total size is 57,208 speedup is 0.99
@@ -73,6 +73,7 @@ import adminforth from '@/adminforth';
73
73
  import { useI18n } from 'vue-i18n';
74
74
  import { useRoute } from 'vue-router';
75
75
  import { AdminUser, type AdminForthResourceCommon } from '@/types';
76
+ import { RateLimiter } from "adminforth";
76
77
 
77
78
  const route = useRoute();
78
79
  const { t } = useI18n();
@@ -143,7 +144,7 @@ const openDialog = async () => {
143
144
  }
144
145
 
145
146
  watch(selected, (val) => {
146
- console.log('Selected changed:', val);
147
+ //console.log('Selected changed:', val);
147
148
  checkedCount.value = val.filter(item => item.isChecked === true).length;
148
149
  }, { deep: true });
149
150
 
@@ -158,6 +159,7 @@ const closeDialog = () => {
158
159
  tableColumns.value = [];
159
160
  tableColumnsIndexes.value = [];
160
161
  isError.value = false;
162
+ isCriticalError.value = false;
161
163
  errorMessage.value = '';
162
164
  }
163
165
 
@@ -340,22 +342,42 @@ async function analyzeFields() {
340
342
 
341
343
  isAiResponseReceivedAnalize.value = props.checkboxes.map(() => true);
342
344
 
343
- res.result.forEach((item, idx) => {
344
- const pk = selected.value[idx]?.[primaryKey]
345
+ if (res?.error) {
346
+ adminforth.alert({
347
+ message: res.error,
348
+ variant: 'danger',
349
+ timeout: 'unlimited',
350
+ });
345
351
 
346
- if (pk) {
347
- selected.value[idx] = {
348
- ...selected.value[idx],
349
- ...item,
350
- isChecked: true,
351
- [primaryKey]: pk
352
+ console.error('Failed to analyze image(s):', res.error);
353
+ isError.value = true;
354
+ isCriticalError.value = true;
355
+ errorMessage.value = `Failed to fetch analyze image(s). Please, try to re-run the action.`;
356
+ } else {
357
+ res.result.forEach((item, idx) => {
358
+ const pk = selected.value[idx]?.[primaryKey]
359
+
360
+ if (pk) {
361
+ selected.value[idx] = {
362
+ ...selected.value[idx],
363
+ ...item,
364
+ isChecked: true,
365
+ [primaryKey]: pk
366
+ }
352
367
  }
353
- }
354
- })
368
+ })
369
+ }
355
370
  } catch (error) {
371
+ adminforth.alert({
372
+ message: error,
373
+ variant: 'danger',
374
+ timeout: 'unlimited',
375
+ });
376
+
356
377
  console.error('Failed to analyze image(s):', error);
357
378
  isError.value = true;
358
- errorMessage.value = `Failed to fetch analyze image(s). Please, try to re-run the action.`;
379
+ isCriticalError.value = true;
380
+ errorMessage.value = res.error;
359
381
  }
360
382
  }
361
383
 
@@ -374,23 +396,40 @@ async function analyzeFieldsNoImages() {
374
396
  if(!props.meta.isFieldsForAnalizeFromImages) {
375
397
  isAiResponseReceivedAnalize.value = props.checkboxes.map(() => true);
376
398
  }
377
-
378
- res.result.forEach((item, idx) => {
379
- const pk = selected.value[idx]?.[primaryKey]
380
-
381
- if (pk) {
382
- selected.value[idx] = {
383
- ...selected.value[idx],
384
- ...item,
385
- isChecked: true,
386
- [primaryKey]: pk
399
+ if(res?.error) {
400
+ adminforth.alert({
401
+ message: res.error,
402
+ variant: 'danger',
403
+ timeout: 'unlimited',
404
+ });
405
+ console.error('Failed to analyze fields:', res.error);
406
+ isError.value = true;
407
+ isCriticalError.value = true;
408
+ errorMessage.value = res.error;
409
+ } else {
410
+ res.result.forEach((item, idx) => {
411
+ const pk = selected.value[idx]?.[primaryKey]
412
+
413
+ if (pk) {
414
+ selected.value[idx] = {
415
+ ...selected.value[idx],
416
+ ...item,
417
+ isChecked: true,
418
+ [primaryKey]: pk
419
+ }
387
420
  }
388
- }
389
- })
421
+ })
422
+ }
390
423
  } catch (error) {
391
- console.error('Failed to analyze fields:', error);
392
- isError.value = true;
393
- errorMessage.value = `Failed to analyze fields. Please, try to re-run the action.`;
424
+ adminforth.alert({
425
+ message: error,
426
+ variant: 'danger',
427
+ timeout: 'unlimited',
428
+ });
429
+ console.error('Failed to analyze fields:', error);
430
+ isError.value = true;
431
+ isCriticalError.value = true;
432
+ errorMessage.value = `Failed to analyze fields. Please, try to re-run the action.`;
394
433
  }
395
434
  }
396
435
 
@@ -490,7 +529,10 @@ async function generateImages() {
490
529
  message: error,
491
530
  variant: 'danger',
492
531
  timeout: 'unlimited',
493
- });
532
+ });;
533
+ isError.value = true;
534
+ isCriticalError.value = true;
535
+ errorMessage.value = error;
494
536
  } else {
495
537
  res.result.forEach((item, idx) => {
496
538
  const pk = selected.value[idx]?.[primaryKey]
@@ -73,6 +73,7 @@ import adminforth from '@/adminforth';
73
73
  import { useI18n } from 'vue-i18n';
74
74
  import { useRoute } from 'vue-router';
75
75
  import { AdminUser, type AdminForthResourceCommon } from '@/types';
76
+ import { RateLimiter } from "adminforth";
76
77
 
77
78
  const route = useRoute();
78
79
  const { t } = useI18n();
@@ -143,7 +144,7 @@ const openDialog = async () => {
143
144
  }
144
145
 
145
146
  watch(selected, (val) => {
146
- console.log('Selected changed:', val);
147
+ //console.log('Selected changed:', val);
147
148
  checkedCount.value = val.filter(item => item.isChecked === true).length;
148
149
  }, { deep: true });
149
150
 
@@ -158,6 +159,7 @@ const closeDialog = () => {
158
159
  tableColumns.value = [];
159
160
  tableColumnsIndexes.value = [];
160
161
  isError.value = false;
162
+ isCriticalError.value = false;
161
163
  errorMessage.value = '';
162
164
  }
163
165
 
@@ -340,22 +342,42 @@ async function analyzeFields() {
340
342
 
341
343
  isAiResponseReceivedAnalize.value = props.checkboxes.map(() => true);
342
344
 
343
- res.result.forEach((item, idx) => {
344
- const pk = selected.value[idx]?.[primaryKey]
345
+ if (res?.error) {
346
+ adminforth.alert({
347
+ message: res.error,
348
+ variant: 'danger',
349
+ timeout: 'unlimited',
350
+ });
345
351
 
346
- if (pk) {
347
- selected.value[idx] = {
348
- ...selected.value[idx],
349
- ...item,
350
- isChecked: true,
351
- [primaryKey]: pk
352
+ console.error('Failed to analyze image(s):', res.error);
353
+ isError.value = true;
354
+ isCriticalError.value = true;
355
+ errorMessage.value = `Failed to fetch analyze image(s). Please, try to re-run the action.`;
356
+ } else {
357
+ res.result.forEach((item, idx) => {
358
+ const pk = selected.value[idx]?.[primaryKey]
359
+
360
+ if (pk) {
361
+ selected.value[idx] = {
362
+ ...selected.value[idx],
363
+ ...item,
364
+ isChecked: true,
365
+ [primaryKey]: pk
366
+ }
352
367
  }
353
- }
354
- })
368
+ })
369
+ }
355
370
  } catch (error) {
371
+ adminforth.alert({
372
+ message: error,
373
+ variant: 'danger',
374
+ timeout: 'unlimited',
375
+ });
376
+
356
377
  console.error('Failed to analyze image(s):', error);
357
378
  isError.value = true;
358
- errorMessage.value = `Failed to fetch analyze image(s). Please, try to re-run the action.`;
379
+ isCriticalError.value = true;
380
+ errorMessage.value = res.error;
359
381
  }
360
382
  }
361
383
 
@@ -374,23 +396,40 @@ async function analyzeFieldsNoImages() {
374
396
  if(!props.meta.isFieldsForAnalizeFromImages) {
375
397
  isAiResponseReceivedAnalize.value = props.checkboxes.map(() => true);
376
398
  }
377
-
378
- res.result.forEach((item, idx) => {
379
- const pk = selected.value[idx]?.[primaryKey]
380
-
381
- if (pk) {
382
- selected.value[idx] = {
383
- ...selected.value[idx],
384
- ...item,
385
- isChecked: true,
386
- [primaryKey]: pk
399
+ if(res?.error) {
400
+ adminforth.alert({
401
+ message: res.error,
402
+ variant: 'danger',
403
+ timeout: 'unlimited',
404
+ });
405
+ console.error('Failed to analyze fields:', res.error);
406
+ isError.value = true;
407
+ isCriticalError.value = true;
408
+ errorMessage.value = res.error;
409
+ } else {
410
+ res.result.forEach((item, idx) => {
411
+ const pk = selected.value[idx]?.[primaryKey]
412
+
413
+ if (pk) {
414
+ selected.value[idx] = {
415
+ ...selected.value[idx],
416
+ ...item,
417
+ isChecked: true,
418
+ [primaryKey]: pk
419
+ }
387
420
  }
388
- }
389
- })
421
+ })
422
+ }
390
423
  } catch (error) {
391
- console.error('Failed to analyze fields:', error);
392
- isError.value = true;
393
- errorMessage.value = `Failed to analyze fields. Please, try to re-run the action.`;
424
+ adminforth.alert({
425
+ message: error,
426
+ variant: 'danger',
427
+ timeout: 'unlimited',
428
+ });
429
+ console.error('Failed to analyze fields:', error);
430
+ isError.value = true;
431
+ isCriticalError.value = true;
432
+ errorMessage.value = `Failed to analyze fields. Please, try to re-run the action.`;
394
433
  }
395
434
  }
396
435
 
@@ -490,7 +529,10 @@ async function generateImages() {
490
529
  message: error,
491
530
  variant: 'danger',
492
531
  timeout: 'unlimited',
493
- });
532
+ });;
533
+ isError.value = true;
534
+ isCriticalError.value = true;
535
+ errorMessage.value = error;
494
536
  } else {
495
537
  res.result.forEach((item, idx) => {
496
538
  const pk = selected.value[idx]?.[primaryKey]
package/dist/index.js CHANGED
@@ -67,6 +67,30 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
67
67
  }
68
68
  }
69
69
  }
70
+ checkRateLimitForBulkGenerationRateLimit(source_api, headers) {
71
+ if (!this.options.bulkGenerationRateLimit) {
72
+ return;
73
+ }
74
+ const hasGenerateImages = !!this.options.generateImages && Object.keys(this.options.generateImages).length > 0;
75
+ const hasFillFieldsFromImages = !!this.options.fillFieldsFromImages && Object.keys(this.options.fillFieldsFromImages).length > 0;
76
+ const hasFillPlainFields = !!this.options.fillPlainFields && Object.keys(this.options.fillPlainFields).length > 0;
77
+ let shouldCheckRateLimit = false;
78
+ if (hasGenerateImages && source_api === 'generateImages') {
79
+ shouldCheckRateLimit = true;
80
+ }
81
+ else if (hasFillFieldsFromImages && source_api === 'fillFieldsFromImages' && !hasGenerateImages) {
82
+ shouldCheckRateLimit = true;
83
+ }
84
+ else if (hasFillPlainFields && source_api === 'fillPlainFields' && !hasFillFieldsFromImages && !hasGenerateImages) {
85
+ shouldCheckRateLimit = true;
86
+ }
87
+ if (shouldCheckRateLimit) {
88
+ const result = this.checkRateLimit(this.options.bulkGenerationRateLimit, headers);
89
+ if (result) {
90
+ return { error: "Rate limit exceeded" };
91
+ }
92
+ }
93
+ }
70
94
  modifyResourceConfig(adminforth, resourceConfig) {
71
95
  const _super = Object.create(null, {
72
96
  modifyResourceConfig: { get: () => super.modifyResourceConfig }
@@ -172,13 +196,16 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
172
196
  isImageGeneration: this.options.generateImages ? Object.keys(this.options.generateImages).length > 0 : false
173
197
  }
174
198
  };
175
- if (!this.resourceConfig.options.pageInjections) {
176
- this.resourceConfig.options.pageInjections = {};
199
+ if (!resourceConfig.options.pageInjections) {
200
+ resourceConfig.options.pageInjections = {};
201
+ }
202
+ if (!resourceConfig.options.pageInjections.list) {
203
+ resourceConfig.options.pageInjections.list = {};
177
204
  }
178
- if (!this.resourceConfig.options.pageInjections.list) {
179
- this.resourceConfig.options.pageInjections.list = {};
205
+ if (!resourceConfig.options.pageInjections.list.threeDotsDropdownItems) {
206
+ resourceConfig.options.pageInjections.list.threeDotsDropdownItems = [];
180
207
  }
181
- this.resourceConfig.options.pageInjections.list.threeDotsDropdownItems = [pageInjection];
208
+ resourceConfig.options.pageInjections.list.threeDotsDropdownItems.push(pageInjection);
182
209
  });
183
210
  }
184
211
  validateConfigAfterDiscover(adminforth, resourceConfig) {
@@ -195,6 +222,9 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
195
222
  path: `/plugin/${this.pluginInstanceId}/analyze`,
196
223
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers }) {
197
224
  const selectedIds = body.selectedIds || [];
225
+ if (this.checkRateLimitForBulkGenerationRateLimit("fillFieldsFromImages", headers)) {
226
+ return { error: "Rate limit exceeded" };
227
+ }
198
228
  const tasks = selectedIds.map((ID) => __awaiter(this, void 0, void 0, function* () {
199
229
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
200
230
  // Fetch the record using the provided ID
@@ -232,6 +262,9 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
232
262
  path: `/plugin/${this.pluginInstanceId}/analyze_no_images`,
233
263
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers }) {
234
264
  const selectedIds = body.selectedIds || [];
265
+ if (this.checkRateLimitForBulkGenerationRateLimit("fillPlainFields", headers)) {
266
+ return { error: "Rate limit exceeded" };
267
+ }
235
268
  const tasks = selectedIds.map((ID) => __awaiter(this, void 0, void 0, function* () {
236
269
  // Fetch the record using the provided ID
237
270
  const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
@@ -394,7 +427,7 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
394
427
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, headers }) {
395
428
  const selectedIds = body.selectedIds || [];
396
429
  const STUB_MODE = false;
397
- if (this.checkRateLimit(this.options.bulkGenerationRateLimit, headers)) {
430
+ if (this.checkRateLimitForBulkGenerationRateLimit("generateImages", headers)) {
398
431
  return { error: "Rate limit exceeded" };
399
432
  }
400
433
  const start = +new Date();
package/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { AdminForthPlugin, Filters } from "adminforth";
2
- import type { IAdminForth, IHttpServer, AdminForthResourcePages, AdminForthResourceColumn, AdminForthDataTypes, AdminForthResource } from "adminforth";
2
+ import type { IAdminForth, IHttpServer, AdminForthComponentDeclaration, AdminForthResourceColumn, AdminForthDataTypes, AdminForthResource } from "adminforth";
3
3
  import type { PluginOptions } from './types.js';
4
4
  import { json } from "stream/consumers";
5
5
  import Handlebars, { compile } from 'handlebars';
@@ -75,6 +75,33 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
75
75
  }
76
76
  }
77
77
 
78
+ private checkRateLimitForBulkGenerationRateLimit(source_api: string, headers: Record<string, string | string[] | undefined>): { error?: string } | void {
79
+ if (!this.options.bulkGenerationRateLimit) {
80
+ return;
81
+ }
82
+
83
+ const hasGenerateImages = !!this.options.generateImages && Object.keys(this.options.generateImages).length > 0;
84
+ const hasFillFieldsFromImages = !!this.options.fillFieldsFromImages && Object.keys(this.options.fillFieldsFromImages).length > 0;
85
+ const hasFillPlainFields = !!this.options.fillPlainFields && Object.keys(this.options.fillPlainFields).length > 0;
86
+
87
+ let shouldCheckRateLimit = false;
88
+
89
+ if (hasGenerateImages && source_api === 'generateImages') {
90
+ shouldCheckRateLimit = true;
91
+ } else if (hasFillFieldsFromImages && source_api === 'fillFieldsFromImages' && !hasGenerateImages) {
92
+ shouldCheckRateLimit = true;
93
+ } else if (hasFillPlainFields && source_api === 'fillPlainFields' && !hasFillFieldsFromImages && !hasGenerateImages) {
94
+ shouldCheckRateLimit = true;
95
+ }
96
+
97
+ if (shouldCheckRateLimit) {
98
+ const result = this.checkRateLimit(this.options.bulkGenerationRateLimit, headers);
99
+ if (result) {
100
+ return { error: "Rate limit exceeded" };
101
+ }
102
+ }
103
+ }
104
+
78
105
  async modifyResourceConfig(adminforth: IAdminForth, resourceConfig: AdminForthResource) {
79
106
  super.modifyResourceConfig(adminforth, resourceConfig);
80
107
 
@@ -192,15 +219,18 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
192
219
  isImageGeneration: this.options.generateImages ? Object.keys(this.options.generateImages).length > 0 : false
193
220
  }
194
221
  }
195
-
196
- if (!this.resourceConfig.options.pageInjections) {
197
- this.resourceConfig.options.pageInjections = {};
222
+
223
+ if (!resourceConfig.options.pageInjections) {
224
+ resourceConfig.options.pageInjections = {};
198
225
  }
199
- if (!this.resourceConfig.options.pageInjections.list) {
200
- this.resourceConfig.options.pageInjections.list = {};
226
+ if (!resourceConfig.options.pageInjections.list) {
227
+ resourceConfig.options.pageInjections.list = {};
228
+ }
229
+ if (!resourceConfig.options.pageInjections.list.threeDotsDropdownItems) {
230
+ resourceConfig.options.pageInjections.list.threeDotsDropdownItems = [];
201
231
  }
202
232
 
203
- this.resourceConfig.options.pageInjections.list.threeDotsDropdownItems = [pageInjection];
233
+ (resourceConfig.options.pageInjections.list.threeDotsDropdownItems as AdminForthComponentDeclaration[]).push(pageInjection);
204
234
  }
205
235
 
206
236
  validateConfigAfterDiscover(adminforth: IAdminForth, resourceConfig: AdminForthResource) {
@@ -221,6 +251,9 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
221
251
  path: `/plugin/${this.pluginInstanceId}/analyze`,
222
252
  handler: async ({ body, adminUser, headers }) => {
223
253
  const selectedIds = body.selectedIds || [];
254
+ if (this.checkRateLimitForBulkGenerationRateLimit("fillFieldsFromImages",headers)) {
255
+ return { error: "Rate limit exceeded" };
256
+ }
224
257
  const tasks = selectedIds.map(async (ID) => {
225
258
  // Fetch the record using the provided ID
226
259
  const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
@@ -266,6 +299,9 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
266
299
  path: `/plugin/${this.pluginInstanceId}/analyze_no_images`,
267
300
  handler: async ({ body, adminUser, headers }) => {
268
301
  const selectedIds = body.selectedIds || [];
302
+ if (this.checkRateLimitForBulkGenerationRateLimit("fillPlainFields",headers)) {
303
+ return { error: "Rate limit exceeded" };
304
+ }
269
305
  const tasks = selectedIds.map(async (ID) => {
270
306
  // Fetch the record using the provided ID
271
307
  const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
@@ -447,8 +483,7 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
447
483
  handler: async ({ body, headers }) => {
448
484
  const selectedIds = body.selectedIds || [];
449
485
  const STUB_MODE = false;
450
-
451
- if (this.checkRateLimit(this.options.bulkGenerationRateLimit, headers)) {
486
+ if (this.checkRateLimitForBulkGenerationRateLimit("generateImages",headers)) {
452
487
  return { error: "Rate limit exceeded" };
453
488
  }
454
489
  const start = +new Date();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminforth/bulk-ai-flow",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },