@nyris/nyris-webapp 0.3.86 → 0.3.88

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 (37) 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.ba1c7479.css +4 -0
  5. package/build/static/css/main.ba1c7479.css.map +1 -0
  6. package/build/static/js/main.e861b336.js +3 -0
  7. package/build/static/js/{main.1e617139.js.map → main.e861b336.js.map} +1 -1
  8. package/package.json +3 -3
  9. package/public/js/settings.example.js +1 -0
  10. package/src/components/Carousel/ImagePreviewCarousel.tsx +1 -1
  11. package/src/components/CustomCameraDrawer.tsx +73 -3
  12. package/src/components/DragDropFile.tsx +121 -46
  13. package/src/components/Header.tsx +17 -12
  14. package/src/components/Hint.tsx +98 -0
  15. package/src/components/ImagePreview.tsx +79 -10
  16. package/src/components/Inquiry/InquiryModal.tsx +40 -9
  17. package/src/components/PreFilter/PreFilter.tsx +14 -0
  18. package/src/components/Product/Product.tsx +3 -3
  19. package/src/components/Product/ProductDetailView.tsx +2 -4
  20. package/src/components/Product/ProductList.tsx +0 -5
  21. package/src/components/SidePanel.tsx +77 -84
  22. package/src/components/TextSearch.tsx +161 -9
  23. package/src/layouts/AppLayout.tsx +14 -10
  24. package/src/pages/Home.tsx +20 -2
  25. package/src/pages/Result.tsx +84 -65
  26. package/src/stores/request/requestStore.ts +5 -1
  27. package/src/stores/request/specifications/specifications.initialState.ts +9 -0
  28. package/src/stores/request/specifications/specifications.slice.ts +15 -0
  29. package/src/stores/types.ts +16 -0
  30. package/src/styles/common.scss +15 -0
  31. package/src/styles/product.scss +13 -1
  32. package/src/translations.ts +27 -0
  33. package/src/types.ts +1 -0
  34. package/build/static/css/main.a0a44a64.css +0 -4
  35. package/build/static/css/main.a0a44a64.css.map +0 -1
  36. package/build/static/js/main.1e617139.js +0 -3
  37. /package/build/static/js/{main.1e617139.js.LICENSE.txt → main.e861b336.js.LICENSE.txt} +0 -0
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@nyris/nyris-webapp",
3
- "version": "0.3.86",
3
+ "version": "0.3.88",
4
4
  "dependencies": {
5
5
  "@auth0/auth0-react": "^2.2.4",
6
6
  "@emailjs/browser": "^4.3.3",
7
- "@nyris/nyris-api": "^0.3.86",
8
- "@nyris/nyris-react-components": "^0.3.86",
7
+ "@nyris/nyris-api": "^0.3.88",
8
+ "@nyris/nyris-react-components": "^0.3.88",
9
9
  "@radix-ui/react-accordion": "^1.2.2",
10
10
  "@radix-ui/react-dialog": "^1.1.4",
11
11
  "@radix-ui/react-popover": "^1.1.4",
@@ -89,6 +89,7 @@ var settings = {
89
89
  showFeedback: false,
90
90
  geoLocation: false,
91
91
  geoLocationMessage: '',
92
+ showImageDetails: false,
92
93
  rfq: {
93
94
  enabled: '',
94
95
  emailTemplateId: '',
@@ -84,7 +84,7 @@ export const ImagePreviewCarousel = (props: Props) => {
84
84
  }}
85
85
  options={mainOptions}
86
86
  ref={mainRef}
87
- style={{ maxWidth: '100%', height: isMobile ? '80%' : '' }}
87
+ style={{ maxWidth: '100%', height: isMobile ? '80%' : 'calc(100% - 48px);' }}
88
88
  >
89
89
  {renderSlides()}
90
90
  </Splide>
@@ -18,6 +18,9 @@ import {
18
18
  } from './Drawer/Drawer';
19
19
  import { useCadSearch } from 'hooks/useCadSearch';
20
20
  import { isCadFile } from '@nyris/nyris-api';
21
+ import { clone } from 'lodash';
22
+ import { getFilters } from '../services/filter';
23
+ import { useTranslation } from 'react-i18next';
21
24
 
22
25
  interface Props {
23
26
  show: boolean;
@@ -35,18 +38,42 @@ function CustomCamera(props: Props) {
35
38
  const location = useLocation();
36
39
  const { singleImageSearch } = useImageSearch();
37
40
  const { cadSearch } = useCadSearch();
41
+ const { t } = useTranslation();
38
42
 
39
43
  const requestImages = useRequestStore(state => state.requestImages);
40
-
44
+ const specifications = useRequestStore(state => state.specifications);
45
+ const setSpecifications = useRequestStore(state => state.setSpecifications);
46
+ const setRequestImages = useRequestStore(state => state.setRequestImages);
47
+ const setNameplateNotificationText = useRequestStore(state => state.setNameplateNotificationText);
48
+ const setAlgoliaFilter = useRequestStore(state => state.setAlgoliaFilter);
49
+ const setPreFilter = useRequestStore(state => state.setPreFilter);
50
+ const setShowLoading = useRequestStore(state => state.setShowLoading);
51
+ const setNameplateImage = useRequestStore(state => state.setNameplateImage);
52
+ const setShowNotMatchedError = useRequestStore(state => state.setShowNotMatchedError);
41
53
  const [capturedImages, setCapturedImages] = useState<HTMLCanvasElement[]>([]);
42
54
  const [currentIndex, setCurrentIndex] = useState(0);
43
55
  const [imageCaptureHelpModal, setImageCaptureHelpModal] = useState(false);
56
+ const [resultFilter, setResultFilter] = useState<any>([]);
44
57
 
45
58
  const videoConstraints = {
46
59
  width: 1080,
47
60
  aspectRatio: 1.11111,
48
61
  };
49
62
 
63
+ const getPreFilters = async () => {
64
+ getFilters(1000, settings)
65
+ .then(res => {
66
+ setResultFilter(res);
67
+ })
68
+ .catch((e: any) => {
69
+ console.log('err getDataFilterDesktop', e);
70
+ });
71
+ }
72
+
73
+ useEffect(() => {
74
+ getPreFilters()
75
+ }, []);
76
+
50
77
  const handlerFindImage = async (image: any) => {
51
78
  if (location.pathname !== '/result') {
52
79
  navigate('/result');
@@ -65,8 +92,51 @@ function CustomCamera(props: Props) {
65
92
  settings,
66
93
  newSearch,
67
94
  showFeedback: true,
68
- }).then(() => {});
69
- handleClose();
95
+ }).then((singleImageResp) => {
96
+ const specificationPrefilter = singleImageResp.image_analysis?.specification?.prefilter_value || null;
97
+ const hasPrefilter = resultFilter.filter((filter: any) => filter.values.includes(specificationPrefilter));
98
+ if (specificationPrefilter) {
99
+ setRequestImages([]);
100
+ setShowNotMatchedError(false);
101
+ if (hasPrefilter.length) {
102
+ setSpecifications(clone(singleImageResp.image_analysis.specification));
103
+ setNameplateImage(image);
104
+ setPreFilter({[singleImageResp.image_analysis?.specification?.prefilter_value]: true});
105
+ setAlgoliaFilter(`${settings.alogoliaFilterField}:'${singleImageResp.image_analysis?.specification?.prefilter_value}'`);
106
+
107
+ setShowLoading(false);
108
+ handleClose();
109
+
110
+ setNameplateNotificationText(t('We have successfully defined the search criteria', { prefilter_value: specificationPrefilter, preFilterTitle: window.settings.preFilterTitle?.toLocaleLowerCase() }));
111
+ setTimeout(() => {
112
+ setNameplateNotificationText('');
113
+ }, 5000);
114
+ }
115
+ if (!hasPrefilter.length && window.settings.preFilterOption) {
116
+ setSpecifications(clone({...singleImageResp.image_analysis.specification, prefilter_value: '', specificationPrefilter}));
117
+ setPreFilter({});
118
+ setAlgoliaFilter('');
119
+ setShowLoading(false);
120
+ handleClose();
121
+ setShowNotMatchedError(true);
122
+ setTimeout(() => {
123
+ setNameplateNotificationText(t('Extracted details from the nameplate could not be matched', { preFilterTitle: window.settings.preFilterTitle?.toLocaleLowerCase() }));
124
+ }, 1000);
125
+ setTimeout(() => {
126
+ setNameplateNotificationText('');
127
+ }, 6000);
128
+ }
129
+ } else {
130
+ if (specifications?.is_nameplate) {
131
+ setSpecifications({...specifications, prefilter_value: '', specificationPrefilter: ''});
132
+ } else {
133
+ setSpecifications({...specifications, is_nameplate: false});
134
+ }
135
+ setShowLoading(false);
136
+ handleClose();
137
+ }
138
+ });
139
+
70
140
  };
71
141
 
72
142
  const handleClose = () => {
@@ -1,15 +1,17 @@
1
- import { memo } from 'react';
1
+ import { memo, useEffect, useState } from 'react';
2
2
  import { twMerge } from 'tailwind-merge';
3
3
  import { useTranslation } from 'react-i18next';
4
4
 
5
- import { Icon } from '@nyris/nyris-react-components';
6
-
7
5
  import Loading from './Loading';
8
6
  import { useImageSearch } from 'hooks/useImageSearch';
9
7
  import useDragAndDrop from 'hooks/useDragAndDrop';
10
8
  import { useNavigate } from 'react-router';
11
9
  import { useCadSearch } from 'hooks/useCadSearch';
12
10
  import { isCadFile } from '@nyris/nyris-api';
11
+ import Hint from './Hint';
12
+ import { clone } from 'lodash';
13
+ import useRequestStore from '../stores/request/requestStore';
14
+ import { getFilters } from '../services/filter';
13
15
 
14
16
  interface Props {
15
17
  onChangeLoading?: any;
@@ -24,8 +26,33 @@ function DragDropFile(props: Props) {
24
26
  const { singleImageSearch } = useImageSearch();
25
27
  const { cadSearch } = useCadSearch();
26
28
 
29
+ const [resultFilter, setResultFilter] = useState<any>([]);
30
+
31
+ const specifications = useRequestStore(state => state.specifications);
32
+ const setRequestImages = useRequestStore(state => state.setRequestImages);
33
+ const setSpecifications = useRequestStore(state => state.setSpecifications);
34
+ const setNameplateNotificationText = useRequestStore(state => state.setNameplateNotificationText);
35
+ const setShowNotMatchedError = useRequestStore(state => state.setShowNotMatchedError);
36
+ const setAlgoliaFilter = useRequestStore(state => state.setAlgoliaFilter);
37
+ const setPreFilter = useRequestStore(state => state.setPreFilter);
38
+ const setShowLoading = useRequestStore(state => state.setShowLoading);
39
+ const setNameplateImage = useRequestStore(state => state.setNameplateImage);
40
+
41
+ const getPreFilters = async () => {
42
+ getFilters(1000, window.settings)
43
+ .then(res => {
44
+ setResultFilter(res);
45
+ })
46
+ .catch((e: any) => {
47
+ console.log('err getDataFilterDesktop', e);
48
+ });
49
+ }
50
+
51
+ useEffect(() => {
52
+ getPreFilters()
53
+ }, []);
54
+
27
55
  const handleUpload = (file: File) => {
28
- navigate('/result');
29
56
 
30
57
  if (isCadFile(file)) {
31
58
  cadSearch({
@@ -37,11 +64,58 @@ function DragDropFile(props: Props) {
37
64
  return;
38
65
  }
39
66
 
67
+ setShowLoading(true);
68
+
40
69
  singleImageSearch({
41
70
  image: file,
42
71
  settings: window.settings,
43
72
  showFeedback: true,
44
- }).then(() => {});
73
+ }).then((singleImageResp) => {
74
+ const specificationPrefilter = singleImageResp.image_analysis?.specification?.prefilter_value || null;
75
+ const hasPrefilter = resultFilter.filter((filter: any) => filter.values.includes(specificationPrefilter));
76
+ if (specificationPrefilter) {
77
+ setRequestImages([]);
78
+ setShowNotMatchedError(false);
79
+ if (hasPrefilter.length) {
80
+ setSpecifications(clone(singleImageResp.image_analysis.specification));
81
+ setNameplateImage(file);
82
+ setPreFilter({[singleImageResp.image_analysis?.specification?.prefilter_value]: true});
83
+ setAlgoliaFilter(`${window.settings.alogoliaFilterField}:'${singleImageResp.image_analysis?.specification?.prefilter_value}'`);
84
+
85
+ setShowLoading(false);
86
+ navigate('/result');
87
+
88
+ setTimeout(() => {
89
+ setNameplateNotificationText(t('We have successfully defined the search criteria', { prefilter_value: specificationPrefilter, preFilterTitle: window.settings.preFilterTitle?.toLocaleLowerCase() }));
90
+ }, 1000);
91
+ setTimeout(() => {
92
+ setNameplateNotificationText('');
93
+ }, 6000);
94
+ }
95
+ if (!hasPrefilter.length && window.settings.preFilterOption) {
96
+ setSpecifications(clone({...singleImageResp.image_analysis.specification, prefilter_value: '', specificationPrefilter}));
97
+ navigate('/result');
98
+ setPreFilter({});
99
+ setAlgoliaFilter('');
100
+ setShowLoading(false);
101
+ setShowNotMatchedError(true);
102
+ setTimeout(() => {
103
+ setNameplateNotificationText(t('Extracted details from the nameplate could not be matched', { preFilterTitle: window.settings.preFilterTitle?.toLocaleLowerCase() }));
104
+ }, 1000);
105
+ setTimeout(() => {
106
+ setNameplateNotificationText('');
107
+ }, 6000);
108
+ }
109
+ } else {
110
+ if (specifications?.is_nameplate) {
111
+ setSpecifications({...specifications, prefilter_value: '', specificationPrefilter: ''});
112
+ } else {
113
+ setSpecifications({...specifications, is_nameplate: false});
114
+ }
115
+ setShowLoading(false);
116
+ navigate('/result');
117
+ }
118
+ });
45
119
  };
46
120
 
47
121
  const { isDragging, dragProps } = useDragAndDrop({
@@ -49,52 +123,53 @@ function DragDropFile(props: Props) {
49
123
  });
50
124
 
51
125
  return (
52
- <label
53
- htmlFor="select_file"
54
- className={
55
- 'flex flex-col items-center justify-center mt-8 px-4 bg-[#fafafa]'
56
- }
57
- >
58
- {isLoading && <Loading />}
59
-
60
- <div
61
- className={'relative flex flex-col items-center justify-center w-full'}
62
- {...dragProps}
126
+ <>
127
+ <label
128
+ htmlFor="select_file"
129
+ className={
130
+ 'flex flex-col items-center justify-center mt-8 bg-[#fafafa] drag-n-drop-label'
131
+ }
63
132
  >
133
+ {isLoading && <Loading />}
134
+
64
135
  <div
65
- className={twMerge([
66
- 'flex flex-col items-center w-full cursor-pointer pb-4 pt-4 rounded-[60px]',
67
- 'text-[#cacad1] hover:text-primary',
68
- 'border-2 border-dashed border-transparent hover:border-[#e0e0e0]',
69
- isDragging && 'text-primary border-[#e0e0e0]',
70
- ])}
136
+ className={'relative flex flex-col items-center justify-center w-full'}
137
+ {...dragProps}
71
138
  >
72
- <div style={{ marginBottom: 16 }}>
73
- <Icon name="drop" width={48} height={48} />
74
- </div>
75
- <div className="" style={{ fontSize: 14 }}>
76
- <span className="font-bold text-sm pr-1">{t('Drag and drop')}</span>
77
- {t('an image here')}
139
+ <div
140
+ className={twMerge([
141
+ 'drag-n-drop-inner',
142
+ 'flex flex-col items-center w-full cursor-pointer pb-4 pt-4 rounded-[12px]',
143
+ 'text-[#cacad1] hover:text-primary',
144
+ 'border-2 border-dashed border-transparent hover:border-[#e0e0e0]',
145
+ isDragging && 'text-primary border-[#e0e0e0]',
146
+ ])}
147
+ >
148
+ <div className="" style={{ fontSize: 14 }}>
149
+ <span className="font-bold text-sm pr-1">{t('Drag and drop')}</span>
150
+ {t('an image here')}
151
+ </div>
152
+ <Hint />
153
+ <input
154
+ onChange={e => {
155
+ e.stopPropagation();
156
+ if (e.target.files && e.target.files[0]) {
157
+ handleUpload(e.target.files[0]);
158
+ e.target.value = '';
159
+ }
160
+ }}
161
+ style={{}}
162
+ type="file"
163
+ name="file"
164
+ id="select_file"
165
+ className="absolute z-[-1] opacity-0"
166
+ placeholder="Choose photo"
167
+ accept={'.stp,.step,.stl,.obj,.glb,.gltf,.heic,.heif,.pdf,image/*'}
168
+ />
78
169
  </div>
79
- <input
80
- onChange={e => {
81
- e.stopPropagation();
82
- if (e.target.files && e.target.files[0]) {
83
- handleUpload(e.target.files[0]);
84
- e.target.value = '';
85
- }
86
- }}
87
- style={{}}
88
- type="file"
89
- name="file"
90
- id="select_file"
91
- className="absolute z-[-1] opacity-0"
92
- placeholder="Choose photo"
93
- accept={'.stp,.step,.stl,.obj,.glb,.gltf,.heic,.heif,.pdf,image/*'}
94
- />
95
170
  </div>
96
- </div>
97
- </label>
171
+ </label>
172
+ </>
98
173
  );
99
174
  }
100
175
 
@@ -19,6 +19,7 @@ function Header() {
19
19
 
20
20
  const reset = useRequestStore(state => state.reset);
21
21
  const resetResultStore = useResultStore(state => state.reset);
22
+ const setSpecifications = useRequestStore(state => state.setSpecifications);
22
23
 
23
24
  const showSearchBar = location?.pathname === '/result';
24
25
 
@@ -42,8 +43,9 @@ function Header() {
42
43
  >
43
44
  <div
44
45
  className={twMerge([
46
+ 'w-full',
45
47
  'flex',
46
- 'justify-between',
48
+ 'justify-center',
47
49
  'items-center',
48
50
  'relative',
49
51
  'h-full',
@@ -51,10 +53,11 @@ function Header() {
51
53
  >
52
54
  <NavLink
53
55
  to="/"
54
- style={{ lineHeight: 0 }}
56
+ style={{ lineHeight: 0, position: 'absolute', left: 0 }}
55
57
  onClick={() => {
56
58
  reset();
57
59
  resetResultStore();
60
+ setSpecifications(null);
58
61
  }}
59
62
  >
60
63
  <img
@@ -68,16 +71,18 @@ function Header() {
68
71
  />
69
72
  </NavLink>
70
73
 
71
- <div
72
- className={twMerge(['hidden', showSearchBar && 'desktop:block'])}
73
- style={{
74
- position: 'absolute',
75
- left: '50%',
76
- top: '50%',
77
- transform: 'translate(-50%, -50%)',
78
- }}
79
- >
80
- <TextSearch />
74
+ <div>
75
+ <div
76
+ className={twMerge(['hidden', showSearchBar && 'desktop:block'])}
77
+ style={{
78
+ // position: 'relative',
79
+ // left: '50%',
80
+ // top: '50%',
81
+ // transform: 'translate(-50%, -50%)',
82
+ }}
83
+ >
84
+ <TextSearch />
85
+ </div>
81
86
  </div>
82
87
 
83
88
  {auth0.enabled && isAuthenticated && (
@@ -0,0 +1,98 @@
1
+ import React from 'react';
2
+ import { Icon } from '@nyris/nyris-react-components';
3
+ import { useTranslation } from 'react-i18next';
4
+
5
+ const Hint = () => {
6
+ const { t } = useTranslation();
7
+ return (
8
+ <div
9
+ style={{
10
+ width: 'max-content',
11
+ minWidth: 240,
12
+ display: 'flex',
13
+ flexDirection: 'row',
14
+ justifyContent: 'space-between',
15
+ marginTop: 16,
16
+ fontSize: 9,
17
+ fontWeight: 700,
18
+ whiteSpace: 'nowrap',
19
+ gap: 16,
20
+ }}
21
+ >
22
+ <div
23
+ style={{
24
+ display: 'flex',
25
+ flexDirection: 'column',
26
+ alignItems: 'center',
27
+ flex: 1,
28
+ }}
29
+ >
30
+ <Icon
31
+ name="typeplate"
32
+ width={24}
33
+ height={24}
34
+ style={{
35
+ marginBottom: 8,
36
+ }}
37
+ />
38
+ {t('Type plates')}
39
+ </div>
40
+ <div
41
+ style={{
42
+ display: 'flex',
43
+ flexDirection: 'column',
44
+ alignItems: 'center',
45
+ flex: 1,
46
+ }}
47
+ >
48
+ <Icon
49
+ name="part"
50
+ width={24}
51
+ height={24}
52
+ style={{
53
+ marginBottom: 8,
54
+ }}
55
+ />
56
+ {t('Parts')}
57
+ </div>
58
+ <div
59
+ style={{
60
+ display: 'flex',
61
+ flexDirection: 'column',
62
+ alignItems: 'center',
63
+ flex: 1,
64
+ }}
65
+ >
66
+ <Icon
67
+ name="label"
68
+ width={24}
69
+ height={24}
70
+ style={{
71
+ marginBottom: 8,
72
+ }}
73
+ />
74
+ {t('Labels')}
75
+ </div>
76
+ <div
77
+ style={{
78
+ display: 'flex',
79
+ flexDirection: 'column',
80
+ alignItems: 'center',
81
+ flex: 1,
82
+ }}
83
+ >
84
+ <Icon
85
+ name="barcode"
86
+ width={24}
87
+ height={24}
88
+ style={{
89
+ marginBottom: 8,
90
+ }}
91
+ />
92
+ {t('Barcodes')}
93
+ </div>
94
+ </div>
95
+ );
96
+ };
97
+
98
+ export default Hint;
@@ -1,6 +1,6 @@
1
- import React, { useCallback, useRef, useState } from 'react';
1
+ import React, {useCallback, useEffect, useRef, useState} from 'react';
2
2
 
3
- import { debounce } from 'lodash';
3
+ import {clone, debounce} from 'lodash';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  import { useNavigate } from 'react-router';
6
6
  import { useTranslation } from 'react-i18next';
@@ -12,6 +12,7 @@ import { DEFAULT_REGION } from '../constants';
12
12
  import { useImageSearch } from 'hooks/useImageSearch';
13
13
  import useRequestStore from 'stores/request/requestStore';
14
14
  import useResultStore from 'stores/result/resultStore';
15
+ import { getFilters } from '../services/filter';
15
16
 
16
17
  function ImagePreviewComponent({
17
18
  showAdjustInfo = false,
@@ -23,6 +24,7 @@ function ImagePreviewComponent({
23
24
  }) {
24
25
  const [showAdjustInfoBasedOnConfidence, setShowAdjustInfoBasedOnConfidence] =
25
26
  useState(false);
27
+ const [resultFilter, setResultFilter] = useState<any>([]);
26
28
 
27
29
  const { t } = useTranslation();
28
30
  const navigate = useNavigate();
@@ -30,11 +32,19 @@ function ImagePreviewComponent({
30
32
  const isMultiImageSearchEnabled = settings.multiImageSearch;
31
33
 
32
34
  const requestImages = useRequestStore(state => state.requestImages);
35
+ const specifications = useRequestStore(state => state.specifications);
33
36
  const resetRegions = useRequestStore(state => state.resetRegions);
34
37
  const setRequestImages = useRequestStore(state => state.setRequestImages);
35
38
  const regions = useRequestStore(state => state.regions);
36
39
  const updateRegion = useRequestStore(state => state.updateRegion);
37
40
  const resetRequestStore = useRequestStore(state => state.reset);
41
+ const setSpecifications = useRequestStore(state => state.setSpecifications);
42
+ const setShowLoading = useRequestStore(state => state.setShowLoading);
43
+ const setNameplateNotificationText = useRequestStore(state => state.setNameplateNotificationText);
44
+ const setAlgoliaFilter = useRequestStore(state => state.setAlgoliaFilter);
45
+ const setPreFilter = useRequestStore(state => state.setPreFilter);
46
+ const setNameplateImage = useRequestStore(state => state.setNameplateImage);
47
+ const setShowNotMatchedError = useRequestStore(state => state.setShowNotMatchedError);
38
48
 
39
49
  const detectedRegions = useResultStore(state => state.detectedRegions);
40
50
  const resetResultStore = useResultStore(state => state.reset);
@@ -48,6 +58,20 @@ function ImagePreviewComponent({
48
58
 
49
59
  const previewWrapperRef = useRef<any>(null);
50
60
 
61
+ const getPreFilters = async () => {
62
+ getFilters(1000, settings)
63
+ .then(res => {
64
+ setResultFilter(res);
65
+ })
66
+ .catch((e: any) => {
67
+ console.log('err getDataFilterDesktop', e);
68
+ });
69
+ };
70
+
71
+ useEffect(() => {
72
+ getPreFilters()
73
+ }, []);
74
+
51
75
  const onImageRemove = () => {
52
76
  resetRegions();
53
77
  setRequestImages([]);
@@ -55,6 +79,7 @@ function ImagePreviewComponent({
55
79
  navigate('/');
56
80
  resetResultStore();
57
81
  resetRequestStore();
82
+ setSpecifications(null);
58
83
  };
59
84
 
60
85
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -69,15 +94,59 @@ function ImagePreviewComponent({
69
94
  showFeedback: true,
70
95
  compress: false,
71
96
  }).then((res: any) => {
72
- const highConfidence = res.results.find(
73
- (data: { score: number }) => data.score >= 0.65,
74
- );
75
- if (!highConfidence) {
76
- setShowAdjustInfoBasedOnConfidence(true);
97
+ const specificationPrefilter = res.image_analysis?.specification?.prefilter_value || null;
98
+ const hasPrefilter = resultFilter.filter((filter: any) => filter.values.includes(specificationPrefilter));
99
+ if (specificationPrefilter) {
100
+ setRequestImages([]);
101
+ setShowNotMatchedError(false);
102
+ if (hasPrefilter.length) {
103
+ setSpecifications(clone(res.image_analysis.specification));
104
+ setNameplateImage(image);
105
+ setPreFilter({[res.image_analysis?.specification?.prefilter_value]: true});
106
+ setAlgoliaFilter(`${settings.alogoliaFilterField}:'${res.image_analysis?.specification?.prefilter_value}'`);
107
+
108
+ setShowLoading(false);
109
+ navigate('/result');
110
+
111
+ setTimeout(() => {
112
+ setNameplateNotificationText(t('We have successfully defined the search criteria', {
113
+ prefilter_value: specificationPrefilter,
114
+ preFilterTitle: window.settings.preFilterTitle?.toLocaleLowerCase()
115
+ }));
116
+ }, 1000);
117
+ setTimeout(() => {
118
+ setNameplateNotificationText('');
119
+ }, 6000);
120
+ }
121
+ if (!hasPrefilter.length && window.settings.preFilterOption) {
122
+ setSpecifications(clone({...res.image_analysis.specification, prefilter_value: '', specificationPrefilter}));
123
+ setPreFilter({});
124
+ setAlgoliaFilter('');
125
+ setShowLoading(false);
126
+ setShowNotMatchedError(true);
127
+ setTimeout(() => {
128
+ setNameplateNotificationText(t('Extracted details from the nameplate could not be matched', { preFilterTitle: window.settings.preFilterTitle?.toLocaleLowerCase() }));
129
+ }, 1000);
130
+ setTimeout(() => {
131
+ setNameplateNotificationText('');
132
+ }, 6000);
133
+ }
134
+ } else {
135
+ if (specifications?.is_nameplate) {
136
+ setSpecifications({...specifications, prefilter_value: '', specificationPrefilter: ''});
137
+ } else {
138
+ setSpecifications({...specifications, is_nameplate: false});
139
+ }
140
+ const highConfidence = res.results.find(
141
+ (data: { score: number }) => data.score >= 0.65,
142
+ );
143
+ if (!highConfidence) {
144
+ setShowAdjustInfoBasedOnConfidence(true);
145
+ }
146
+ setTimeout(() => {
147
+ setShowAdjustInfoBasedOnConfidence(false);
148
+ }, 2000);
77
149
  }
78
- setTimeout(() => {
79
- setShowAdjustInfoBasedOnConfidence(false);
80
- }, 2000);
81
150
  });
82
151
  return;
83
152
  }, 1500),