@nyris/nyris-webapp 0.3.93 → 0.3.95

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.
Files changed (36) hide show
  1. package/build/asset-manifest.json +6 -6
  2. package/build/index.html +1 -1
  3. package/build/js/settings.example.js +1 -0
  4. package/build/static/css/main.5fff4ca0.css +4 -0
  5. package/build/static/css/main.5fff4ca0.css.map +1 -0
  6. package/build/static/js/{main.c9bbbcb9.js → main.b80e9533.js} +3 -3
  7. package/build/static/js/{main.c9bbbcb9.js.map → main.b80e9533.js.map} +1 -1
  8. package/package.json +3 -3
  9. package/public/js/settings.example.js +1 -0
  10. package/src/components/ChatAssistant/useChatAssistantLogic.ts +1 -1
  11. package/src/components/CustomCameraDrawer.tsx +5 -5
  12. package/src/components/DragDropFile.tsx +4 -4
  13. package/src/components/ExperienceVisualSearch/ExperienceVisualSearchModal.tsx +1 -1
  14. package/src/components/ExperienceVisualSearch/ExperienceVisualSearchTrigger.tsx +1 -1
  15. package/src/components/ImagePreview.tsx +4 -4
  16. package/src/components/ImageUpload.tsx +6 -110
  17. package/src/components/MobileCameraCTA.tsx +1 -1
  18. package/src/components/Rfq/RfqBanner.tsx +3 -4
  19. package/src/components/SidePanel.tsx +8 -12
  20. package/src/components/SmartFilter.tsx +70 -42
  21. package/src/components/Toaster.tsx +3 -2
  22. package/src/hooks/useGoodResultsChat.ts +1 -1
  23. package/src/hooks/useImageSearch.ts +4 -8
  24. package/src/hooks/useResultEvaluator.ts +5 -4
  25. package/src/hooks/useUploadSearch.ts +170 -0
  26. package/src/layouts/AppLayout.tsx +70 -0
  27. package/src/pages/Home.tsx +2 -2
  28. package/src/pages/Result.tsx +9 -11
  29. package/src/services/vizo.ts +0 -6
  30. package/src/styles/common.scss +1 -0
  31. package/src/styles/experienceVisualSearch.scss +2 -0
  32. package/src/translations.ts +33 -18
  33. package/src/types.ts +1 -0
  34. package/build/static/css/main.fed38059.css +0 -4
  35. package/build/static/css/main.fed38059.css.map +0 -1
  36. /package/build/static/js/{main.c9bbbcb9.js.LICENSE.txt → main.b80e9533.js.LICENSE.txt} +0 -0
@@ -219,7 +219,8 @@ ${resultsSummary
219
219
  .map(
220
220
  r =>
221
221
  `${r.rank}. ${r.title}${r.description ? ` - ${r.description}` : ''} (Score: ${r.score})${r.metadata ? `\n Metadata: ${JSON.stringify(r.metadata)}` : ''}`,
222
- ).join('\n')}
222
+ )
223
+ .join('\n')}
223
224
 
224
225
  COMMON ATTRIBUTES FOUND IN RESULTS (for filter suggestions):
225
226
  ${JSON.stringify(attributeFrequency, null, 2)}
@@ -316,7 +317,7 @@ Evaluate if these results match the image. If they do (same type of product), ro
316
317
 
317
318
  const tableSuggestions = lookupRelatedParts(
318
319
  table,
319
- imageAnalysis.specification.product_category || '',
320
+ imageAnalysis?.specification?.product_category || '',
320
321
  );
321
322
  const hasTableSuggestions =
322
323
  !!tableSuggestions && tableSuggestions.length > 0;
@@ -329,7 +330,7 @@ Evaluate if these results match the image. If they do (same type of product), ro
329
330
  !relatedPartsUsed
330
331
  ) {
331
332
  mappedOptions.push({
332
- label: `Find parts related to ${imageAnalysis.specification.product_category || 'request image'}`,
333
+ label: `Find parts related to ${imageAnalysis?.specification?.product_category || 'request image'}`,
333
334
  action_type: 'find_related_parts',
334
335
  key: 'find_related',
335
336
  value: 'find_related_parts',
@@ -353,7 +354,7 @@ Evaluate if these results match the image. If they do (same type of product), ro
353
354
  !relatedPartsUsed
354
355
  ) {
355
356
  mappedOptions.push({
356
- label: `Find parts related to ${imageAnalysis.specification.product_category || 'request image'}`,
357
+ label: `Find parts related to ${imageAnalysis?.specification?.product_category || 'request image'}`,
357
358
  action_type: 'find_related_parts',
358
359
  key: 'find_related',
359
360
  value: 'find_related_parts',
@@ -0,0 +1,170 @@
1
+ import { useCallback } from 'react';
2
+ import { clone } from 'lodash';
3
+ import { useNavigate } from 'react-router';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { isCadFile } from '@nyris/nyris-api';
6
+
7
+ import { useImageSearch } from 'hooks/useImageSearch';
8
+ import { useCadSearch } from 'hooks/useCadSearch';
9
+ import useRequestStore from 'stores/request/requestStore';
10
+
11
+ interface UploadFileOptions {
12
+ showPreFilter?: boolean;
13
+ resetTextSearch?: boolean;
14
+ }
15
+
16
+ export const useUploadSearch = () => {
17
+ const settings = window.settings;
18
+ const navigate = useNavigate();
19
+ const { t } = useTranslation();
20
+
21
+ const { singleImageSearch } = useImageSearch();
22
+ const { cadSearch } = useCadSearch();
23
+
24
+ const preFilterList = useRequestStore(state => state.preFilterList);
25
+ const specifications = useRequestStore(state => state.specifications);
26
+
27
+ const setQuery = useRequestStore(state => state.setQuery);
28
+ const setValueInput = useRequestStore(state => state.setValueInput);
29
+
30
+ const setRequestImages = useRequestStore(state => state.setRequestImages);
31
+ const setSpecifications = useRequestStore(state => state.setSpecifications);
32
+ const setShowLoading = useRequestStore(state => state.setShowLoading);
33
+ const setNameplateNotificationText = useRequestStore(
34
+ state => state.setNameplateNotificationText,
35
+ );
36
+ const setShowNotMatchedError = useRequestStore(
37
+ state => state.setShowNotMatchedError,
38
+ );
39
+ const setAlgoliaFilter = useRequestStore(state => state.setAlgoliaFilter);
40
+ const setPreFilter = useRequestStore(state => state.setPreFilter);
41
+ const setNameplateImage = useRequestStore(state => state.setNameplateImage);
42
+
43
+ const uploadFile = useCallback(
44
+ (
45
+ file: File,
46
+ {
47
+ showPreFilter = settings.preFilterOption,
48
+ resetTextSearch = true,
49
+ }: UploadFileOptions = {},
50
+ ) => {
51
+ if (resetTextSearch) {
52
+ setValueInput('');
53
+ setQuery('');
54
+ }
55
+
56
+ if (isCadFile(file)) {
57
+ return cadSearch({ file, settings, newSearch: true }).then(() => {});
58
+ }
59
+
60
+ setShowLoading(true);
61
+
62
+ return singleImageSearch({
63
+ image: file,
64
+ settings,
65
+ showFeedback: true,
66
+ newSearch: true,
67
+ clearPostFilter: true,
68
+ }).then(singleImageResp => {
69
+ const specificationPrefilter =
70
+ singleImageResp?.image_analysis?.specification?.prefilter_value ||
71
+ null;
72
+ const hasPrefilter = preFilterList.filter((filter: any) =>
73
+ filter.values.includes(specificationPrefilter),
74
+ );
75
+
76
+ if (specificationPrefilter) {
77
+ setRequestImages([]);
78
+ setShowNotMatchedError(false);
79
+
80
+ if (hasPrefilter.length) {
81
+ setSpecifications(
82
+ clone(singleImageResp?.image_analysis?.specification),
83
+ );
84
+ setNameplateImage(file);
85
+ setPreFilter({
86
+ [singleImageResp?.image_analysis?.specification?.prefilter_value]:
87
+ true,
88
+ });
89
+ setAlgoliaFilter(
90
+ `${settings.alogoliaFilterField}:'${singleImageResp?.image_analysis?.specification?.prefilter_value}'`,
91
+ );
92
+
93
+ setShowLoading(false);
94
+ navigate('/result');
95
+
96
+ setTimeout(() => {
97
+ setNameplateNotificationText(
98
+ t('We have successfully defined the search criteria', {
99
+ prefilter_value: specificationPrefilter,
100
+ preFilterTitle:
101
+ window.settings.preFilterTitle?.toLocaleLowerCase(),
102
+ }),
103
+ );
104
+ }, 1000);
105
+
106
+ setTimeout(() => {
107
+ setNameplateNotificationText('');
108
+ }, 10000);
109
+ }
110
+
111
+ if (!hasPrefilter.length && showPreFilter) {
112
+ setSpecifications(
113
+ clone({
114
+ ...singleImageResp?.image_analysis?.specification,
115
+ specificationPrefilter,
116
+ }),
117
+ );
118
+ navigate('/result');
119
+ setPreFilter({});
120
+ setAlgoliaFilter('');
121
+ setShowLoading(false);
122
+ setShowNotMatchedError(true);
123
+
124
+ setTimeout(() => {
125
+ setNameplateNotificationText(
126
+ t('Extracted details from the nameplate could not be matched', {
127
+ preFilterTitle:
128
+ window.settings.preFilterTitle?.toLocaleLowerCase(),
129
+ }),
130
+ );
131
+ }, 1000);
132
+
133
+ setTimeout(() => {
134
+ setNameplateNotificationText('');
135
+ }, 15000);
136
+ }
137
+ } else {
138
+ if (!specifications?.is_nameplate) {
139
+ setSpecifications({ ...specifications, is_nameplate: false });
140
+ }
141
+ setShowLoading(false);
142
+ navigate('/result');
143
+ }
144
+ });
145
+ },
146
+ [
147
+ cadSearch,
148
+ navigate,
149
+ preFilterList,
150
+ setAlgoliaFilter,
151
+ setNameplateImage,
152
+ setNameplateNotificationText,
153
+ setPreFilter,
154
+ setQuery,
155
+ setRequestImages,
156
+ setShowLoading,
157
+ setShowNotMatchedError,
158
+ setSpecifications,
159
+ setValueInput,
160
+ settings,
161
+ singleImageSearch,
162
+ specifications,
163
+ t,
164
+ ],
165
+ );
166
+
167
+ return {
168
+ uploadFile,
169
+ };
170
+ };
@@ -19,6 +19,9 @@ import useResultStore from 'stores/result/resultStore';
19
19
  import useUiStore from 'stores/ui/uiStore';
20
20
  import { Toaster } from 'components/Toaster';
21
21
  import { getFilters } from 'services/filter';
22
+ import { useUploadSearch } from 'hooks/useUploadSearch';
23
+ import { ToastHelper } from 'helpers/ToastHelper';
24
+ import { useTranslation } from 'react-i18next';
22
25
 
23
26
  i18n.use(initReactI18next).init({
24
27
  resources: translations,
@@ -31,7 +34,9 @@ i18n.use(initReactI18next).init({
31
34
 
32
35
  function AppLayout(): JSX.Element {
33
36
  const { isAuthenticated } = useAuth0();
37
+ const { t } = useTranslation();
34
38
  const { auth0, alogoliaFilterField, showPoweredByNyris } = window.settings;
39
+ const { uploadFile } = useUploadSearch();
35
40
 
36
41
  const showLayout = !auth0.enabled || (auth0.enabled && isAuthenticated);
37
42
  const location = useLocation();
@@ -47,10 +52,12 @@ function AppLayout(): JSX.Element {
47
52
 
48
53
  const setAlgoliaProducts = useResultStore(state => state.setAlgoliaProducts);
49
54
  const setIsAlgoliaLoading = useUiStore(state => state.setIsAlgoliaLoading);
55
+ const isFindApiLoading = useUiStore(state => state.isFindApiLoading);
50
56
 
51
57
  const setIsCadenasLoaded = useUiStore(state => state.setIsCadenasLoaded);
52
58
  const specifications = useRequestStore(state => state.specifications);
53
59
  const requestImages = useRequestStore(state => state.requestImages);
60
+ const showLoading = useRequestStore(state => state.showLoading);
54
61
 
55
62
  const { status } = useInstantSearch();
56
63
  const { items } = useHits();
@@ -143,6 +150,69 @@ function AppLayout(): JSX.Element {
143
150
  }
144
151
  }, [getPreFilters, showPreFilter]);
145
152
 
153
+ const getImageFromClipboard = useCallback(
154
+ (event: ClipboardEvent): File | null => {
155
+ const clipboardData = event.clipboardData;
156
+ if (!clipboardData) {
157
+ return null;
158
+ }
159
+
160
+ const imageItem = Array.from(clipboardData.items || []).find(
161
+ item => item.kind === 'file' && item.type.startsWith('image/'),
162
+ );
163
+
164
+ if (imageItem) {
165
+ return imageItem.getAsFile();
166
+ }
167
+
168
+ return (
169
+ Array.from(clipboardData.files || []).find(file =>
170
+ file.type.startsWith('image/'),
171
+ ) || null
172
+ );
173
+ },
174
+ [],
175
+ );
176
+
177
+ const handleClipboardPaste = useCallback(
178
+ (event: ClipboardEvent) => {
179
+ if (isFindApiLoading || showLoading) {
180
+ return;
181
+ }
182
+
183
+ const imageFile = getImageFromClipboard(event);
184
+ if (!imageFile) {
185
+ return;
186
+ }
187
+
188
+ event.preventDefault();
189
+ ToastHelper.success(
190
+ t('Image pasted from clipboard. Starting visual search.'),
191
+ );
192
+ uploadFile(imageFile, { showPreFilter });
193
+ },
194
+ [
195
+ getImageFromClipboard,
196
+ isFindApiLoading,
197
+ showLoading,
198
+ showPreFilter,
199
+ t,
200
+ uploadFile,
201
+ ],
202
+ );
203
+
204
+ useEffect(() => {
205
+ if (!showLayout) {
206
+ return;
207
+ }
208
+
209
+ document.addEventListener('paste', handleClipboardPaste);
210
+
211
+ return () => {
212
+ document.removeEventListener('paste', handleClipboardPaste);
213
+ };
214
+ }, [handleClipboardPaste, showLayout]);
215
+
146
216
  if (!showLayout) {
147
217
  return <Outlet />;
148
218
  }
@@ -84,7 +84,7 @@ function Home() {
84
84
  'items-center',
85
85
  'justify-center',
86
86
  'h-auto',
87
- 'mt-[calc(50vh-110px)]',
87
+ !window.settings.experienceVisualSearch ? 'mt-[calc(50vh-110px)]' : 'mt-[calc(50vh-156px)]',
88
88
  ])}
89
89
  >
90
90
  {geoLocation && <LocationInfoPopup />}
@@ -122,7 +122,7 @@ function Home() {
122
122
  </div>
123
123
  </div>
124
124
 
125
- <div className="flex flex-col desktop:hidden justify-center items-center w-full h-full ">
125
+ <div className="flex flex-col desktop:hidden justify-center items-center w-full h-full overflow-y-auto">
126
126
  <MobileCameraCTA setOpenModalCamera={setOpenModalCamera} />
127
127
  <div className="box-screenshot-camera">
128
128
  <CustomCamera
@@ -223,17 +223,14 @@ function Results() {
223
223
  >
224
224
  <div className="block desktop:hidden desktop:mb-0 mx-2">
225
225
  {requestImages[0] && <ImagePreview />}
226
- {isSmartFiltersEnabled &&
227
- (imageAnalysis?.imageDescription ||
228
- Object.keys(imageAnalysis?.specification || {}).length >
229
- 0) && (
230
- <div className="my-4">
231
- <SmartFilter
232
- imageAnalysis={imageAnalysis}
233
- specificationFilter={specificationFilter}
234
- />
235
- </div>
236
- )}
226
+ {isSmartFiltersEnabled && (
227
+ <div className="my-4">
228
+ <SmartFilter
229
+ imageAnalysis={imageAnalysis}
230
+ specificationFilter={specificationFilter}
231
+ />
232
+ </div>
233
+ )}
237
234
  {window.settings.showImageDetails &&
238
235
  (imageAnalysis?.imageDescription ||
239
236
  Object.keys(imageAnalysis?.specification || {}).length >
@@ -338,6 +335,7 @@ function Results() {
338
335
  'mx-0.5',
339
336
  'mobile-md:mx-2',
340
337
  'desktop:mx-4',
338
+ 'h-full',
341
339
  ])}
342
340
  >
343
341
  <div className="max-w-[840px] w-full relative flex flex-col justify-between mb-20 desktop:mb-0">
@@ -71,10 +71,6 @@ export interface SmartFilterRerankResponse {
71
71
 
72
72
  export interface SmartFilterGenerateParams {
73
73
  image: File | HTMLCanvasElement;
74
- prompt: string;
75
- model?: string;
76
- timeoutMs?: number;
77
- apiKey?: string;
78
74
  }
79
75
 
80
76
  export interface SmartFilterGenerateResponse {
@@ -135,7 +131,6 @@ export async function rerankSmartFilters({
135
131
 
136
132
  export async function generateSmartFilters({
137
133
  image,
138
- prompt,
139
134
  }: SmartFilterGenerateParams): Promise<SmartFilterGenerateResponse> {
140
135
  const settings = window.settings;
141
136
  const isSmartFiltersEnabled = !!settings.useSmartFilters;
@@ -154,7 +149,6 @@ export async function generateSmartFilters({
154
149
  } else {
155
150
  formData.append('image', image);
156
151
  }
157
- formData.append('prompt', prompt);
158
152
 
159
153
  try {
160
154
  const response = await axios.post<SmartFilterGenerateResponse>(
@@ -143,6 +143,7 @@
143
143
  justify-content: center;
144
144
  background-color: #16161680;
145
145
  &-body {
146
+ overflow-y: auto;
146
147
  padding: 32px;
147
148
  background: #F3F3F5;
148
149
  &.geolocation {
@@ -65,6 +65,7 @@ body.overflow-hidden {
65
65
  display: flex;
66
66
  flex-direction: row;
67
67
  flex-wrap: wrap;
68
+ justify-content: center;
68
69
  gap: 16px;
69
70
  width: 376px;
70
71
  .experience-visual-search-image-container {
@@ -166,6 +167,7 @@ body.overflow-hidden {
166
167
  padding: 32px 8px;
167
168
  &-content {
168
169
  &.experience-visual-search-images {
170
+ max-width: calc(100vw - 32px);
169
171
  width: 300px;
170
172
  gap: 8px;
171
173
  .experience-visual-search-image-container {
@@ -4,6 +4,8 @@ export const translations = {
4
4
  Search: 'Search',
5
5
  'Drag and drop': 'Drag and drop',
6
6
  'an image here': 'an image here',
7
+ 'Image pasted from clipboard. Starting visual search.':
8
+ 'Image pasted from clipboard. Starting visual search.',
7
9
  'Manufacturer Number': 'Manufacturer No.',
8
10
  'Mfr. No.': 'Mfr. No.',
9
11
  'Close group': 'Close group',
@@ -65,13 +67,16 @@ export const translations = {
65
67
  'Please enable location services when prompted.':
66
68
  'Please enable location services when prompted.',
67
69
  'I understand': 'I understand',
68
- 'We have successfully defined the search criteria': 'Nameplate detected and matched to {{prefilter_value}}. Items are shown for this {{preFilterTitle}}. You can now upload an image or enter a keyword to search.',
70
+ 'We have successfully defined the search criteria':
71
+ 'Nameplate detected and matched to {{prefilter_value}}. Items are shown for this {{preFilterTitle}}. You can now upload an image or enter a keyword to search.',
69
72
  'Type plates': 'Type plates',
70
- 'Parts': 'Parts',
71
- 'Labels': 'Labels',
72
- 'Barcodes': 'Barcodes',
73
- 'Nameplate not matching': 'Nameplate detected, but {{prefilter_value}} was not found in the list. You can select the correct {{preFilterTitle}} to continue.',
74
- 'Extracted details from the nameplate could not be matched': 'The extracted details could not be matched to a known {{preFilterTitle}}. Please select a different {{preFilterTitle}} and continue searching.',
73
+ Parts: 'Parts',
74
+ Labels: 'Labels',
75
+ Barcodes: 'Barcodes',
76
+ 'Nameplate not matching':
77
+ 'Nameplate detected, but {{prefilter_value}} was not found in the list. You can select the correct {{preFilterTitle}} to continue.',
78
+ 'Extracted details from the nameplate could not be matched':
79
+ 'The extracted details could not be matched to a known {{preFilterTitle}}. Please select a different {{preFilterTitle}} and continue searching.',
75
80
  'Showing results for machine': `Showing results for {{prefilter_title}} '{{prefilter_value}}'`,
76
81
  'No matches found for': `No matches found for {{prefilter_title}} '{{prefilter_value}}'. Showing all items instead.`,
77
82
  },
@@ -81,6 +86,8 @@ export const translations = {
81
86
  Search: 'Suche',
82
87
  'Drag and drop': 'Bild hierher ziehen',
83
88
  'an image here': '',
89
+ 'Image pasted from clipboard. Starting visual search.':
90
+ 'Bild aus der Zwischenablage eingefügt. Visuelle Suche gestartet.',
84
91
  'Mfr. No.': 'Herst. Teile-Nr.',
85
92
  'Manufacturer Number': 'Herstellerteilenummer',
86
93
  'Close group': 'Schließe Gruppe',
@@ -144,13 +151,16 @@ export const translations = {
144
151
  'Please enable location services when prompted.':
145
152
  'Bitte erlauben Sie den Zugriff auf Ihren Standort.',
146
153
  'I understand': 'Weiter',
147
- 'We have successfully defined the search criteria': 'Typenschild erkannt und mit {{prefilter_value}} abgeglichen. Es werden Artikel für dieses {{preFilterTitle}}. Sie können nun ein Bild hochladen oder ein Stichwort zur Suche eingeben.',
154
+ 'We have successfully defined the search criteria':
155
+ 'Typenschild erkannt und mit {{prefilter_value}} abgeglichen. Es werden Artikel für dieses {{preFilterTitle}}. Sie können nun ein Bild hochladen oder ein Stichwort zur Suche eingeben.',
148
156
  'Type plates': 'Typenschilder',
149
- 'Parts': 'Teile',
150
- 'Labels': 'Etiketten',
151
- 'Barcodes': 'Barcodes',
152
- 'Nameplate not matching': 'Typenschild erkannt, aber {{prefilter_value}} wurde nicht in der Liste gefunden. Sie können die richtigen {{preFilterTitle}}, um fortzufahren.',
153
- 'Extracted details from the nameplate could not be matched': 'Die extrahierten Details konnten keinem bekannten {{preFilterTitle}} zugeordnet werden. Bitte wählen Sie einen anderen {{preFilterTitle}} aus und setzen Sie die Suche fort.',
157
+ Parts: 'Teile',
158
+ Labels: 'Etiketten',
159
+ Barcodes: 'Barcodes',
160
+ 'Nameplate not matching':
161
+ 'Typenschild erkannt, aber {{prefilter_value}} wurde nicht in der Liste gefunden. Sie können die richtigen {{preFilterTitle}}, um fortzufahren.',
162
+ 'Extracted details from the nameplate could not be matched':
163
+ 'Die extrahierten Details konnten keinem bekannten {{preFilterTitle}} zugeordnet werden. Bitte wählen Sie einen anderen {{preFilterTitle}} aus und setzen Sie die Suche fort.',
154
164
  'Showing results for machine': `Ergebnisse für {{prefilter_title}} '{{prefilter_value}}' anzeigen`,
155
165
  'No matches found for': `Keine Übereinstimmungen gefunden für {{prefilter_title}} '{{prefilter_value}}'. Alle Artikel anzeigen stattdessen.`,
156
166
  },
@@ -160,6 +170,8 @@ export const translations = {
160
170
  Search: 'Busca',
161
171
  'Drag and drop': 'Escolha uma imagem',
162
172
  'an image here': '',
173
+ 'Image pasted from clipboard. Starting visual search.':
174
+ 'Imagem colada da área de transferência. A iniciar pesquisa visual.',
163
175
  'Manufacturer Number': 'Número do fabricante',
164
176
  'Mfr. No.': 'Nr. do Fab',
165
177
  'Close group': 'Fechar grupo',
@@ -224,13 +236,16 @@ export const translations = {
224
236
  'Please enable location services when prompted.':
225
237
  'Por favor, ative os serviços de localização quando solicitado',
226
238
  'I understand': 'Compreendo',
227
- 'We have successfully defined the search criteria': 'Placa de identificação detetada e correspondente a {{prefilter_value}}. São apresentados os itens para esta {{preFilterTitle}}. Agora pode carregar uma imagem ou introduzir uma palavra-chave para pesquisar.',
239
+ 'We have successfully defined the search criteria':
240
+ 'Placa de identificação detetada e correspondente a {{prefilter_value}}. São apresentados os itens para esta {{preFilterTitle}}. Agora pode carregar uma imagem ou introduzir uma palavra-chave para pesquisar.',
228
241
  'Type plates': 'Placa de identificação',
229
- 'Parts': 'Peças',
230
- 'Labels': 'Etiquetas',
231
- 'Barcodes': 'Códigos de barras',
232
- 'Nameplate not matching': 'Placa de identificação detetada, mas {{prefilter_value}} não foi encontrado na lista. Pode selecionar os {{preFilterTitle}} corretos para continuar.',
233
- 'Extracted details from the nameplate could not be matched': 'Os detalhes extraídos não puderam ser correspondidos a um {{preFilterTitle}} conhecido. Selecione um {{preFilterTitle}} diferente e continue a pesquisa.',
242
+ Parts: 'Peças',
243
+ Labels: 'Etiquetas',
244
+ Barcodes: 'Códigos de barras',
245
+ 'Nameplate not matching':
246
+ 'Placa de identificação detetada, mas {{prefilter_value}} não foi encontrado na lista. Pode selecionar os {{preFilterTitle}} corretos para continuar.',
247
+ 'Extracted details from the nameplate could not be matched':
248
+ 'Os detalhes extraídos não puderam ser correspondidos a um {{preFilterTitle}} conhecido. Selecione um {{preFilterTitle}} diferente e continue a pesquisa.',
234
249
  'Showing results for machine': `Mostrando resultados para {{prefilter_title}} '{{prefilter_value}}'`,
235
250
  'No matches found for': `Não foram encontrados resultados para {{prefilter_title}} '{{prefilter_value}}'. Mostrando todos os itens em vez disso.`,
236
251
  },
package/src/types.ts CHANGED
@@ -126,6 +126,7 @@ export interface AppSettings extends NyrisAPISettings {
126
126
  textSearchScoring?: Record<string, Record<string, number>>;
127
127
  theme: SearchSuiteSettings;
128
128
  visualSearchFilterKey?: string;
129
+ supportButtonLabel?: string;
129
130
  }
130
131
 
131
132
  export interface SearchSuiteSettings {