@adminforth/bulk-ai-flow 1.14.4 → 1.14.6
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 +2 -2
- package/custom/ImageCompare.vue +5 -5
- package/custom/VisionAction.vue +10 -10
- package/custom/VisionTable.vue +9 -9
- package/dist/custom/ImageCompare.vue +5 -5
- package/dist/custom/VisionAction.vue +10 -10
- package/dist/custom/VisionTable.vue +9 -9
- package/dist/index.js +20 -15
- package/index.ts +10 -7
- package/package.json +1 -1
package/build.log
CHANGED
|
@@ -13,5 +13,5 @@ custom/package-lock.json
|
|
|
13
13
|
custom/package.json
|
|
14
14
|
custom/tsconfig.json
|
|
15
15
|
|
|
16
|
-
sent 74,
|
|
17
|
-
total size is 73,
|
|
16
|
+
sent 74,310 bytes received 172 bytes 148,964.00 bytes/sec
|
|
17
|
+
total size is 73,669 speedup is 0.99
|
package/custom/ImageCompare.vue
CHANGED
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
|
|
11
11
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
|
|
12
12
|
</svg>
|
|
13
|
-
<span class="sr-only">Close modal</span>
|
|
13
|
+
<span class="sr-only">{{ $t('Close modal') }}</span>
|
|
14
14
|
</button>
|
|
15
15
|
</div>
|
|
16
16
|
<div class="flex gap-4 items-start justify-between">
|
|
17
|
-
<h3 class="text-sm font-medium text-gray-700 mb-2">Old Image</h3>
|
|
18
|
-
<h3 class="text-sm font-medium text-gray-700 mb-2">New Image</h3>
|
|
17
|
+
<h3 class="text-sm font-medium text-gray-700 mb-2">{{ $t('Old Image') }}</h3>
|
|
18
|
+
<h3 class="text-sm font-medium text-gray-700 mb-2">{{ $t('New Image') }}</h3>
|
|
19
19
|
</div>
|
|
20
20
|
<div class="flex gap-4 items-center">
|
|
21
21
|
<!-- Old Image -->
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
class="w-full max-w-sm h-auto object-cover rounded-lg cursor-pointer border hover:border-blue-500 transition-colors duration-200"
|
|
30
30
|
/>
|
|
31
31
|
<div v-else class="w-full max-w-sm h-48 bg-gray-100 rounded-lg flex items-center justify-center">
|
|
32
|
-
<p class="text-gray-500">No old image</p>
|
|
32
|
+
<p class="text-gray-500">{{ $t('No old image') }}</p>
|
|
33
33
|
</div>
|
|
34
34
|
</div>
|
|
35
35
|
</div>
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
class="w-full max-w-sm h-auto object-cover rounded-lg cursor-pointer border hover:border-blue-500 transition-colors duration-200"
|
|
55
55
|
/>
|
|
56
56
|
<div v-else class="w-full max-w-sm h-48 bg-gray-100 rounded-lg flex items-center justify-center">
|
|
57
|
-
<p class="text-gray-500">No new image</p>
|
|
57
|
+
<p class="text-gray-500">{{ $t('No new image') }}</p>
|
|
58
58
|
</div>
|
|
59
59
|
</div>
|
|
60
60
|
</div>
|
package/custom/VisionAction.vue
CHANGED
|
@@ -302,7 +302,7 @@ async function getRecords() {
|
|
|
302
302
|
} catch (error) {
|
|
303
303
|
console.error('Failed to get records:', error);
|
|
304
304
|
isError.value = true;
|
|
305
|
-
errorMessage.value = `Failed to fetch records. Please, try to re-run the action
|
|
305
|
+
errorMessage.value = t(`Failed to fetch records. Please, try to re-run the action.`);
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
308
|
|
|
@@ -319,7 +319,7 @@ async function getImages() {
|
|
|
319
319
|
} catch (error) {
|
|
320
320
|
console.error('Failed to get images:', error);
|
|
321
321
|
isError.value = true;
|
|
322
|
-
errorMessage.value = `Failed to fetch images. Please, try to re-run the action
|
|
322
|
+
errorMessage.value = t(`Failed to fetch images. Please, try to re-run the action.`);
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
325
|
|
|
@@ -375,7 +375,7 @@ async function convertImages(fieldName, img) {
|
|
|
375
375
|
|
|
376
376
|
async function saveData() {
|
|
377
377
|
if (!selected.value?.length) {
|
|
378
|
-
adminforth.alert({ message: 'No items selected', variant: 'warning' });
|
|
378
|
+
adminforth.alert({ message: t('No items selected'), variant: 'warning' });
|
|
379
379
|
return;
|
|
380
380
|
}
|
|
381
381
|
try {
|
|
@@ -420,16 +420,16 @@ async function saveData() {
|
|
|
420
420
|
timeout: 'unlimited',
|
|
421
421
|
});
|
|
422
422
|
isError.value = true;
|
|
423
|
-
errorMessage.value = `Failed to save data. You are not allowed to save
|
|
423
|
+
errorMessage.value = t(`Failed to save data. You are not allowed to save.`);
|
|
424
424
|
} else {
|
|
425
425
|
console.error('Error saving data:', res);
|
|
426
426
|
isError.value = true;
|
|
427
|
-
errorMessage.value = `Failed to save data. Please, try to re-run the action
|
|
427
|
+
errorMessage.value = t(`Failed to save data. Please, try to re-run the action.`);
|
|
428
428
|
}
|
|
429
429
|
} catch (error) {
|
|
430
430
|
console.error('Error saving data:', error);
|
|
431
431
|
isError.value = true;
|
|
432
|
-
errorMessage.value = `Failed to save data. Please, try to re-run the action
|
|
432
|
+
errorMessage.value = t(`Failed to save data. Please, try to re-run the action.`);
|
|
433
433
|
} finally {
|
|
434
434
|
isLoading.value = false;
|
|
435
435
|
}
|
|
@@ -474,7 +474,7 @@ async function runAiAction({
|
|
|
474
474
|
if (rateLimitRes?.error) {
|
|
475
475
|
isRateLimitExceeded = true;
|
|
476
476
|
adminforth.alert({
|
|
477
|
-
message: `Rate limit exceeded for "${actionType.replace('_', ' ')}" action. Please try again later
|
|
477
|
+
message: t(`Rate limit exceeded for "${actionType.replace('_', ' ')}" action. Please try again later.`),
|
|
478
478
|
variant: 'danger',
|
|
479
479
|
timeout: 'unlimited',
|
|
480
480
|
});
|
|
@@ -482,7 +482,7 @@ async function runAiAction({
|
|
|
482
482
|
}
|
|
483
483
|
} catch (e) {
|
|
484
484
|
adminforth.alert({
|
|
485
|
-
message: `Error checking rate limit for "${actionType.replace('_', ' ')}" action
|
|
485
|
+
message: t(`Error checking rate limit for "${actionType.replace('_', ' ')}" action.`),
|
|
486
486
|
variant: 'danger',
|
|
487
487
|
timeout: 'unlimited',
|
|
488
488
|
});
|
|
@@ -516,7 +516,7 @@ async function runAiAction({
|
|
|
516
516
|
} catch (e) {
|
|
517
517
|
console.error(`Error during ${actionType} for item ${i}:`, e);
|
|
518
518
|
hasError = true;
|
|
519
|
-
errorMessage = `Failed to ${actionType.replace('_', ' ')}. Please, try to re-run the action
|
|
519
|
+
errorMessage = t(`Failed to ${actionType.replace('_', ' ')}. Please, try to re-run the action.`);
|
|
520
520
|
return { success: false, index: i, error: e };
|
|
521
521
|
}
|
|
522
522
|
});
|
|
@@ -591,7 +591,7 @@ async function runAiAction({
|
|
|
591
591
|
}
|
|
592
592
|
isAtLeastOneInProgress = true;
|
|
593
593
|
adminforth.alert({
|
|
594
|
-
message: `Generation action "${actionType.replace('_', ' ')}" failed for record: ${recordId}. Error: ${jobResponse.job?.error || 'Unknown error'}
|
|
594
|
+
message: t(`Generation action "${actionType.replace('_', ' ')}" failed for record: ${recordId}. Error: ${jobResponse.job?.error || 'Unknown error'}`),
|
|
595
595
|
variant: 'danger',
|
|
596
596
|
timeout: 'unlimited',
|
|
597
597
|
});
|
package/custom/VisionTable.vue
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
>
|
|
7
7
|
<!-- HEADER TEMPLATE -->
|
|
8
8
|
<template #header:checkboxes="{ item }">
|
|
9
|
-
MARK FOR SAVE
|
|
9
|
+
{{ $t('MARK FOR SAVE') }}
|
|
10
10
|
</template>
|
|
11
11
|
<!-- CHECKBOX CELL TEMPLATE -->
|
|
12
12
|
<template #cell:checkboxes="{ item }">
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
@click="zoomImage(image)"
|
|
29
29
|
/>
|
|
30
30
|
<div v-else class="w-20 h-20">
|
|
31
|
-
<p>Invalid source image</p>
|
|
31
|
+
<p>{{ $t('Invalid source image') }}</p>
|
|
32
32
|
</div>
|
|
33
33
|
</div>
|
|
34
34
|
</div>
|
|
35
35
|
<div class="flex items-center justify-center text-center w-20 h-20" v-else>
|
|
36
|
-
<p>No images found</p>
|
|
36
|
+
<p>{{ $t('No images found') }}</p>
|
|
37
37
|
</div>
|
|
38
38
|
<transition name="fade">
|
|
39
39
|
<div
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
</Select>
|
|
67
67
|
<Tooltip>
|
|
68
68
|
<div class="mt-2 flex items-center justify-start gap-1 hover:text-blue-500" :class="{ 'opacity-0': !hovers[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }">
|
|
69
|
-
<p class="text-sm ">old value</p>
|
|
69
|
+
<p class="text-sm ">{{ $t('old value') }}</p>
|
|
70
70
|
</div>
|
|
71
71
|
<template #tooltip>
|
|
72
72
|
{{ oldData[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }}
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
</Textarea>
|
|
83
83
|
<Tooltip>
|
|
84
84
|
<div class="mt-2 flex items-center justify-start gap-1 hover:text-blue-500" :class="{ 'opacity-0': !hovers[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }">
|
|
85
|
-
<p class="text-sm ">old value</p>
|
|
85
|
+
<p class="text-sm ">{{ $t('old value') }}</p>
|
|
86
86
|
</div>
|
|
87
87
|
<template #tooltip>
|
|
88
88
|
<p class="max-w-[200px]">{{ oldData[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }}</p>
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
</Toggle>
|
|
98
98
|
<Tooltip>
|
|
99
99
|
<div class="mt-2 flex items-center justify-start gap-1 hover:text-blue-500" :class="{ 'opacity-0': !hovers[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }">
|
|
100
|
-
<p class="text-sm ">old value</p>
|
|
100
|
+
<p class="text-sm ">{{ $t('old value') }}</p>
|
|
101
101
|
</div>
|
|
102
102
|
<template #tooltip>
|
|
103
103
|
{{ oldData[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }}
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
/>
|
|
114
114
|
<Tooltip>
|
|
115
115
|
<div class="mt-2 flex items-center justify-start gap-1 hover:text-blue-500" :class="{ 'opacity-0': !hovers[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }">
|
|
116
|
-
<p class="text-sm ">old value</p>
|
|
116
|
+
<p class="text-sm ">{{ $t('old value') }}</p>
|
|
117
117
|
</div>
|
|
118
118
|
<template #tooltip>
|
|
119
119
|
{{ oldData[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }}
|
|
@@ -137,14 +137,14 @@
|
|
|
137
137
|
:class="{ 'opacity-0': !hovers[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }"
|
|
138
138
|
@click="() => {openImageCompare[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] = true}"
|
|
139
139
|
>
|
|
140
|
-
old image
|
|
140
|
+
{{ $t('old image') }}
|
|
141
141
|
</p>
|
|
142
142
|
</div>
|
|
143
143
|
<div v-else class="flex items-center justify-center text-center w-20 h-20">
|
|
144
144
|
<Tooltip v-if="imageGenerationErrorMessage[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])] === 'No source images found'">
|
|
145
145
|
<p
|
|
146
146
|
>
|
|
147
|
-
Can't generate image.
|
|
147
|
+
{{ $t("Can't generate image.") }}
|
|
148
148
|
</p>
|
|
149
149
|
<template #tooltip>
|
|
150
150
|
{{ imageGenerationErrorMessage[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])] }}
|
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
|
|
11
11
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
|
|
12
12
|
</svg>
|
|
13
|
-
<span class="sr-only">Close modal</span>
|
|
13
|
+
<span class="sr-only">{{ $t('Close modal') }}</span>
|
|
14
14
|
</button>
|
|
15
15
|
</div>
|
|
16
16
|
<div class="flex gap-4 items-start justify-between">
|
|
17
|
-
<h3 class="text-sm font-medium text-gray-700 mb-2">Old Image</h3>
|
|
18
|
-
<h3 class="text-sm font-medium text-gray-700 mb-2">New Image</h3>
|
|
17
|
+
<h3 class="text-sm font-medium text-gray-700 mb-2">{{ $t('Old Image') }}</h3>
|
|
18
|
+
<h3 class="text-sm font-medium text-gray-700 mb-2">{{ $t('New Image') }}</h3>
|
|
19
19
|
</div>
|
|
20
20
|
<div class="flex gap-4 items-center">
|
|
21
21
|
<!-- Old Image -->
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
class="w-full max-w-sm h-auto object-cover rounded-lg cursor-pointer border hover:border-blue-500 transition-colors duration-200"
|
|
30
30
|
/>
|
|
31
31
|
<div v-else class="w-full max-w-sm h-48 bg-gray-100 rounded-lg flex items-center justify-center">
|
|
32
|
-
<p class="text-gray-500">No old image</p>
|
|
32
|
+
<p class="text-gray-500">{{ $t('No old image') }}</p>
|
|
33
33
|
</div>
|
|
34
34
|
</div>
|
|
35
35
|
</div>
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
class="w-full max-w-sm h-auto object-cover rounded-lg cursor-pointer border hover:border-blue-500 transition-colors duration-200"
|
|
55
55
|
/>
|
|
56
56
|
<div v-else class="w-full max-w-sm h-48 bg-gray-100 rounded-lg flex items-center justify-center">
|
|
57
|
-
<p class="text-gray-500">No new image</p>
|
|
57
|
+
<p class="text-gray-500">{{ $t('No new image') }}</p>
|
|
58
58
|
</div>
|
|
59
59
|
</div>
|
|
60
60
|
</div>
|
|
@@ -302,7 +302,7 @@ async function getRecords() {
|
|
|
302
302
|
} catch (error) {
|
|
303
303
|
console.error('Failed to get records:', error);
|
|
304
304
|
isError.value = true;
|
|
305
|
-
errorMessage.value = `Failed to fetch records. Please, try to re-run the action
|
|
305
|
+
errorMessage.value = t(`Failed to fetch records. Please, try to re-run the action.`);
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
308
|
|
|
@@ -319,7 +319,7 @@ async function getImages() {
|
|
|
319
319
|
} catch (error) {
|
|
320
320
|
console.error('Failed to get images:', error);
|
|
321
321
|
isError.value = true;
|
|
322
|
-
errorMessage.value = `Failed to fetch images. Please, try to re-run the action
|
|
322
|
+
errorMessage.value = t(`Failed to fetch images. Please, try to re-run the action.`);
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
325
|
|
|
@@ -375,7 +375,7 @@ async function convertImages(fieldName, img) {
|
|
|
375
375
|
|
|
376
376
|
async function saveData() {
|
|
377
377
|
if (!selected.value?.length) {
|
|
378
|
-
adminforth.alert({ message: 'No items selected', variant: 'warning' });
|
|
378
|
+
adminforth.alert({ message: t('No items selected'), variant: 'warning' });
|
|
379
379
|
return;
|
|
380
380
|
}
|
|
381
381
|
try {
|
|
@@ -420,16 +420,16 @@ async function saveData() {
|
|
|
420
420
|
timeout: 'unlimited',
|
|
421
421
|
});
|
|
422
422
|
isError.value = true;
|
|
423
|
-
errorMessage.value = `Failed to save data. You are not allowed to save
|
|
423
|
+
errorMessage.value = t(`Failed to save data. You are not allowed to save.`);
|
|
424
424
|
} else {
|
|
425
425
|
console.error('Error saving data:', res);
|
|
426
426
|
isError.value = true;
|
|
427
|
-
errorMessage.value = `Failed to save data. Please, try to re-run the action
|
|
427
|
+
errorMessage.value = t(`Failed to save data. Please, try to re-run the action.`);
|
|
428
428
|
}
|
|
429
429
|
} catch (error) {
|
|
430
430
|
console.error('Error saving data:', error);
|
|
431
431
|
isError.value = true;
|
|
432
|
-
errorMessage.value = `Failed to save data. Please, try to re-run the action
|
|
432
|
+
errorMessage.value = t(`Failed to save data. Please, try to re-run the action.`);
|
|
433
433
|
} finally {
|
|
434
434
|
isLoading.value = false;
|
|
435
435
|
}
|
|
@@ -474,7 +474,7 @@ async function runAiAction({
|
|
|
474
474
|
if (rateLimitRes?.error) {
|
|
475
475
|
isRateLimitExceeded = true;
|
|
476
476
|
adminforth.alert({
|
|
477
|
-
message: `Rate limit exceeded for "${actionType.replace('_', ' ')}" action. Please try again later
|
|
477
|
+
message: t(`Rate limit exceeded for "${actionType.replace('_', ' ')}" action. Please try again later.`),
|
|
478
478
|
variant: 'danger',
|
|
479
479
|
timeout: 'unlimited',
|
|
480
480
|
});
|
|
@@ -482,7 +482,7 @@ async function runAiAction({
|
|
|
482
482
|
}
|
|
483
483
|
} catch (e) {
|
|
484
484
|
adminforth.alert({
|
|
485
|
-
message: `Error checking rate limit for "${actionType.replace('_', ' ')}" action
|
|
485
|
+
message: t(`Error checking rate limit for "${actionType.replace('_', ' ')}" action.`),
|
|
486
486
|
variant: 'danger',
|
|
487
487
|
timeout: 'unlimited',
|
|
488
488
|
});
|
|
@@ -516,7 +516,7 @@ async function runAiAction({
|
|
|
516
516
|
} catch (e) {
|
|
517
517
|
console.error(`Error during ${actionType} for item ${i}:`, e);
|
|
518
518
|
hasError = true;
|
|
519
|
-
errorMessage = `Failed to ${actionType.replace('_', ' ')}. Please, try to re-run the action
|
|
519
|
+
errorMessage = t(`Failed to ${actionType.replace('_', ' ')}. Please, try to re-run the action.`);
|
|
520
520
|
return { success: false, index: i, error: e };
|
|
521
521
|
}
|
|
522
522
|
});
|
|
@@ -591,7 +591,7 @@ async function runAiAction({
|
|
|
591
591
|
}
|
|
592
592
|
isAtLeastOneInProgress = true;
|
|
593
593
|
adminforth.alert({
|
|
594
|
-
message: `Generation action "${actionType.replace('_', ' ')}" failed for record: ${recordId}. Error: ${jobResponse.job?.error || 'Unknown error'}
|
|
594
|
+
message: t(`Generation action "${actionType.replace('_', ' ')}" failed for record: ${recordId}. Error: ${jobResponse.job?.error || 'Unknown error'}`),
|
|
595
595
|
variant: 'danger',
|
|
596
596
|
timeout: 'unlimited',
|
|
597
597
|
});
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
>
|
|
7
7
|
<!-- HEADER TEMPLATE -->
|
|
8
8
|
<template #header:checkboxes="{ item }">
|
|
9
|
-
MARK FOR SAVE
|
|
9
|
+
{{ $t('MARK FOR SAVE') }}
|
|
10
10
|
</template>
|
|
11
11
|
<!-- CHECKBOX CELL TEMPLATE -->
|
|
12
12
|
<template #cell:checkboxes="{ item }">
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
@click="zoomImage(image)"
|
|
29
29
|
/>
|
|
30
30
|
<div v-else class="w-20 h-20">
|
|
31
|
-
<p>Invalid source image</p>
|
|
31
|
+
<p>{{ $t('Invalid source image') }}</p>
|
|
32
32
|
</div>
|
|
33
33
|
</div>
|
|
34
34
|
</div>
|
|
35
35
|
<div class="flex items-center justify-center text-center w-20 h-20" v-else>
|
|
36
|
-
<p>No images found</p>
|
|
36
|
+
<p>{{ $t('No images found') }}</p>
|
|
37
37
|
</div>
|
|
38
38
|
<transition name="fade">
|
|
39
39
|
<div
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
</Select>
|
|
67
67
|
<Tooltip>
|
|
68
68
|
<div class="mt-2 flex items-center justify-start gap-1 hover:text-blue-500" :class="{ 'opacity-0': !hovers[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }">
|
|
69
|
-
<p class="text-sm ">old value</p>
|
|
69
|
+
<p class="text-sm ">{{ $t('old value') }}</p>
|
|
70
70
|
</div>
|
|
71
71
|
<template #tooltip>
|
|
72
72
|
{{ oldData[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }}
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
</Textarea>
|
|
83
83
|
<Tooltip>
|
|
84
84
|
<div class="mt-2 flex items-center justify-start gap-1 hover:text-blue-500" :class="{ 'opacity-0': !hovers[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }">
|
|
85
|
-
<p class="text-sm ">old value</p>
|
|
85
|
+
<p class="text-sm ">{{ $t('old value') }}</p>
|
|
86
86
|
</div>
|
|
87
87
|
<template #tooltip>
|
|
88
88
|
<p class="max-w-[200px]">{{ oldData[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }}</p>
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
</Toggle>
|
|
98
98
|
<Tooltip>
|
|
99
99
|
<div class="mt-2 flex items-center justify-start gap-1 hover:text-blue-500" :class="{ 'opacity-0': !hovers[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }">
|
|
100
|
-
<p class="text-sm ">old value</p>
|
|
100
|
+
<p class="text-sm ">{{ $t('old value') }}</p>
|
|
101
101
|
</div>
|
|
102
102
|
<template #tooltip>
|
|
103
103
|
{{ oldData[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }}
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
/>
|
|
114
114
|
<Tooltip>
|
|
115
115
|
<div class="mt-2 flex items-center justify-start gap-1 hover:text-blue-500" :class="{ 'opacity-0': !hovers[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }">
|
|
116
|
-
<p class="text-sm ">old value</p>
|
|
116
|
+
<p class="text-sm ">{{ $t('old value') }}</p>
|
|
117
117
|
</div>
|
|
118
118
|
<template #tooltip>
|
|
119
119
|
{{ oldData[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }}
|
|
@@ -137,14 +137,14 @@
|
|
|
137
137
|
:class="{ 'opacity-0': !hovers[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] }"
|
|
138
138
|
@click="() => {openImageCompare[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])][n] = true}"
|
|
139
139
|
>
|
|
140
|
-
old image
|
|
140
|
+
{{ $t('old image') }}
|
|
141
141
|
</p>
|
|
142
142
|
</div>
|
|
143
143
|
<div v-else class="flex items-center justify-center text-center w-20 h-20">
|
|
144
144
|
<Tooltip v-if="imageGenerationErrorMessage[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])] === 'No source images found'">
|
|
145
145
|
<p
|
|
146
146
|
>
|
|
147
|
-
Can't generate image.
|
|
147
|
+
{{ $t("Can't generate image.") }}
|
|
148
148
|
</p>
|
|
149
149
|
<template #tooltip>
|
|
150
150
|
{{ imageGenerationErrorMessage[tableColumnsIndexes.findIndex(el => el[primaryKey] === item[primaryKey])] }}
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,7 @@ const jobs = new Map();
|
|
|
17
17
|
export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
18
18
|
constructor(options) {
|
|
19
19
|
super(options, import.meta.url);
|
|
20
|
+
this.rateLimiters = {};
|
|
20
21
|
this.options = options;
|
|
21
22
|
// for calculating average time
|
|
22
23
|
this.totalCalls = 0;
|
|
@@ -47,18 +48,22 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
47
48
|
return this.compileTemplates(this.options.generateImages, record, v => String(v.prompt));
|
|
48
49
|
}
|
|
49
50
|
checkRateLimit(field, fieldNameRateLimit, headers) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
if (fieldNameRateLimit) {
|
|
53
|
+
// rate limit
|
|
54
|
+
// const { error } = RateLimiter.checkRateLimit(
|
|
55
|
+
// field,
|
|
56
|
+
// fieldNameRateLimit,
|
|
57
|
+
// this.adminforth.auth.getClientIp(headers),
|
|
58
|
+
// );
|
|
59
|
+
if (!this.rateLimiters[field]) {
|
|
60
|
+
this.rateLimiters[field] = new RateLimiter(fieldNameRateLimit);
|
|
61
|
+
}
|
|
62
|
+
if (!(yield this.rateLimiters[field].consume(`${field}-${this.adminforth.auth.getClientIp(headers)}`))) {
|
|
63
|
+
return { error: "Rate limit exceeded" };
|
|
64
|
+
}
|
|
60
65
|
}
|
|
61
|
-
}
|
|
66
|
+
});
|
|
62
67
|
}
|
|
63
68
|
analyze_image(jobId, recordId, adminUser, headers) {
|
|
64
69
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -274,7 +279,7 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
274
279
|
var _a;
|
|
275
280
|
const Id = recordId;
|
|
276
281
|
let isError = false;
|
|
277
|
-
if (this.checkRateLimit(fieldName, this.options.generateImages[fieldName].rateLimit, headers)) {
|
|
282
|
+
if (yield this.checkRateLimit(fieldName, this.options.generateImages[fieldName].rateLimit, headers)) {
|
|
278
283
|
jobs.set(jobId, { status: 'failed', error: "Rate limit exceeded" });
|
|
279
284
|
return { error: "Rate limit exceeded" };
|
|
280
285
|
}
|
|
@@ -707,17 +712,17 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
707
712
|
var _b, _c, _d;
|
|
708
713
|
const actionType = body.actionType;
|
|
709
714
|
if (actionType === 'analyze' && ((_b = this.options.rateLimits) === null || _b === void 0 ? void 0 : _b.fillFieldsFromImages)) {
|
|
710
|
-
if (this.checkRateLimit("fillFieldsFromImages", this.options.rateLimits.fillFieldsFromImages, headers)) {
|
|
715
|
+
if (yield this.checkRateLimit("fillFieldsFromImages", this.options.rateLimits.fillFieldsFromImages, headers)) {
|
|
711
716
|
return { ok: false, error: "Rate limit exceeded for image analyze" };
|
|
712
717
|
}
|
|
713
718
|
}
|
|
714
719
|
if (actionType === 'analyze_no_images' && ((_c = this.options.rateLimits) === null || _c === void 0 ? void 0 : _c.fillPlainFields)) {
|
|
715
|
-
if (this.checkRateLimit("fillPlainFields", this.options.rateLimits.fillPlainFields, headers)) {
|
|
720
|
+
if (yield this.checkRateLimit("fillPlainFields", this.options.rateLimits.fillPlainFields, headers)) {
|
|
716
721
|
return { ok: false, error: "Rate limit exceeded for plain field analyze" };
|
|
717
722
|
}
|
|
718
723
|
}
|
|
719
724
|
if (actionType === 'generate_images' && ((_d = this.options.rateLimits) === null || _d === void 0 ? void 0 : _d.generateImages)) {
|
|
720
|
-
if (this.checkRateLimit("generateImages", this.options.rateLimits.generateImages, headers)) {
|
|
725
|
+
if (yield this.checkRateLimit("generateImages", this.options.rateLimits.generateImages, headers)) {
|
|
721
726
|
return { ok: false, error: "Rate limit exceeded for image generation" };
|
|
722
727
|
}
|
|
723
728
|
}
|
package/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
13
13
|
uploadPlugin: AdminForthPlugin;
|
|
14
14
|
totalCalls: number;
|
|
15
15
|
totalDuration: number;
|
|
16
|
+
rateLimiters: Record<string, RateLimiter> = {};
|
|
16
17
|
|
|
17
18
|
constructor(options: PluginOptions) {
|
|
18
19
|
super(options, import.meta.url);
|
|
@@ -54,7 +55,7 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
54
55
|
return this.compileTemplates(this.options.generateImages, record, v => String(v.prompt));
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
private checkRateLimit(field: string,fieldNameRateLimit: string | undefined, headers: Record<string, string | string[] | undefined>): { error?: string }
|
|
58
|
+
private async checkRateLimit(field: string, fieldNameRateLimit: string | undefined, headers: Record<string, string | string[] | undefined>): Promise<void | { error?: string; }> {
|
|
58
59
|
if (fieldNameRateLimit) {
|
|
59
60
|
// rate limit
|
|
60
61
|
// const { error } = RateLimiter.checkRateLimit(
|
|
@@ -62,8 +63,10 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
62
63
|
// fieldNameRateLimit,
|
|
63
64
|
// this.adminforth.auth.getClientIp(headers),
|
|
64
65
|
// );
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
if (!this.rateLimiters[field]) {
|
|
67
|
+
this.rateLimiters[field] = new RateLimiter(fieldNameRateLimit);
|
|
68
|
+
}
|
|
69
|
+
if (!await this.rateLimiters[field].consume(`${field}-${this.adminforth.auth.getClientIp(headers)}`)) {
|
|
67
70
|
return { error: "Rate limit exceeded" };
|
|
68
71
|
}
|
|
69
72
|
}
|
|
@@ -271,7 +274,7 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
271
274
|
private async regenerateImage(jobId: string, recordId: string, fieldName: string, prompt: string, adminUser: any, headers: Record<string, string | string[] | undefined>) {
|
|
272
275
|
const Id = recordId;
|
|
273
276
|
let isError = false;
|
|
274
|
-
if (this.checkRateLimit(fieldName, this.options.generateImages[fieldName].rateLimit, headers)) {
|
|
277
|
+
if (await this.checkRateLimit(fieldName, this.options.generateImages[fieldName].rateLimit, headers)) {
|
|
275
278
|
jobs.set(jobId, { status: 'failed', error: "Rate limit exceeded" });
|
|
276
279
|
return { error: "Rate limit exceeded" };
|
|
277
280
|
}
|
|
@@ -739,17 +742,17 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
739
742
|
handler: async ({ body, adminUser, headers }) => {
|
|
740
743
|
const actionType = body.actionType;
|
|
741
744
|
if (actionType === 'analyze' && this.options.rateLimits?.fillFieldsFromImages) {
|
|
742
|
-
if (this.checkRateLimit("fillFieldsFromImages" ,this.options.rateLimits.fillFieldsFromImages, headers)) {
|
|
745
|
+
if (await this.checkRateLimit("fillFieldsFromImages" ,this.options.rateLimits.fillFieldsFromImages, headers)) {
|
|
743
746
|
return {ok: false, error: "Rate limit exceeded for image analyze" };
|
|
744
747
|
}
|
|
745
748
|
}
|
|
746
749
|
if (actionType === 'analyze_no_images' && this.options.rateLimits?.fillPlainFields) {
|
|
747
|
-
if (this.checkRateLimit("fillPlainFields" ,this.options.rateLimits.fillPlainFields, headers)) {
|
|
750
|
+
if (await this.checkRateLimit("fillPlainFields" ,this.options.rateLimits.fillPlainFields, headers)) {
|
|
748
751
|
return {ok: false, error: "Rate limit exceeded for plain field analyze" };
|
|
749
752
|
}
|
|
750
753
|
}
|
|
751
754
|
if (actionType === 'generate_images' && this.options.rateLimits?.generateImages) {
|
|
752
|
-
if (this.checkRateLimit("generateImages" ,this.options.rateLimits.generateImages, headers)) {
|
|
755
|
+
if (await this.checkRateLimit("generateImages" ,this.options.rateLimits.generateImages, headers)) {
|
|
753
756
|
return {ok: false, error: "Rate limit exceeded for image generation" };
|
|
754
757
|
}
|
|
755
758
|
}
|