@nyris/nyris-webapp 0.3.89 → 0.3.90
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/_headers +2 -0
- package/build/asset-manifest.json +6 -6
- package/build/index.html +1 -1
- package/build/js/settings.example.js +17 -0
- package/build/static/css/main.734b52e1.css +4 -0
- package/build/static/css/main.734b52e1.css.map +1 -0
- package/build/static/js/main.cede3ae1.js +3 -0
- package/build/static/js/{main.ca8b95bc.js.map → main.cede3ae1.js.map} +1 -1
- package/package.json +3 -3
- package/public/_headers +2 -0
- package/public/index.html +1 -1
- package/public/js/settings.example.js +17 -0
- package/src/App.tsx +5 -3
- package/src/components/Cart.tsx +321 -0
- package/src/components/CustomCameraDrawer.tsx +4 -22
- package/src/components/DragDropFile.tsx +57 -38
- package/src/components/ExperienceVisualSearch/ExperienceVisualSearch.tsx +6 -1
- package/src/components/ExperienceVisualSearch/ExperienceVisualSearchTrigger.tsx +2 -2
- package/src/components/GroundingSpecs.tsx +47 -0
- package/src/components/Header.tsx +94 -93
- package/src/components/HitsPerPage.tsx +4 -2
- package/src/components/ImagePreview.tsx +64 -31
- package/src/components/ImageUpload.tsx +247 -0
- package/src/components/ItemSpecification.tsx +164 -0
- package/src/components/MatchNotificationBanner.tsx +165 -0
- package/src/components/PostFilter/PostFilter.tsx +22 -1
- package/src/components/PostFilter/PostFilterComponent.tsx +59 -26
- package/src/components/PostFilter/PostFilterFindApi.tsx +242 -0
- package/src/components/PoweredBy.tsx +16 -0
- package/src/components/PreFilter/PreFilter.tsx +77 -54
- package/src/components/Product/Product.tsx +186 -28
- package/src/components/Product/ProductAttribute.tsx +2 -2
- package/src/components/Product/ProductDetailView.tsx +123 -18
- package/src/components/Product/ProductDetailViewModal.tsx +3 -0
- package/src/components/Product/ProductList.tsx +78 -8
- package/src/components/SidePanel.tsx +212 -120
- package/src/components/TextSearch.tsx +82 -203
- package/src/components/Toaster.tsx +34 -15
- package/src/helpers/ToastHelper.ts +6 -2
- package/src/hooks/useCadSearch.ts +5 -0
- package/src/hooks/useImageSearch.ts +102 -13
- package/src/index.css +59 -0
- package/src/layouts/AppLayout.tsx +16 -14
- package/src/pages/Home.tsx +61 -13
- package/src/pages/Result.tsx +287 -295
- package/src/services/vizo.ts +161 -0
- package/src/stores/request/Misc/misc.initialstate.ts +1 -0
- package/src/stores/request/Misc/misc.slice.ts +1 -0
- package/src/stores/request/filter/filter.initialState.ts +3 -0
- package/src/stores/request/filter/filter.slice.ts +23 -0
- package/src/stores/result/prodcuts/products.initialState.ts +4 -0
- package/src/stores/result/prodcuts/products.slice.ts +15 -0
- package/src/stores/types.ts +27 -1
- package/src/stores/ui/loading/loading.initialState.ts +1 -0
- package/src/stores/ui/loading/loading.slice.ts +4 -0
- package/src/stores/ui/sidePanel/sidePanel.initialState.ts +5 -0
- package/src/stores/ui/sidePanel/sidePanel.slice.ts +11 -0
- package/src/stores/ui/uiStore.ts +4 -1
- package/src/styles/Cart.scss +210 -0
- package/src/styles/common.scss +10 -0
- package/src/translations.ts +4 -4
- package/src/types.ts +11 -3
- package/src/utils/prepareImageList.ts +6 -5
- package/src/utils/textSearchFilter.ts +203 -0
- package/tailwind.config.js +1 -0
- package/build/static/css/main.ba1c7479.css +0 -4
- package/build/static/css/main.ba1c7479.css.map +0 -1
- package/build/static/js/main.ca8b95bc.js +0 -3
- package/src/components/Footer.tsx +0 -21
- /package/build/static/js/{main.ca8b95bc.js.LICENSE.txt → main.cede3ae1.js.LICENSE.txt} +0 -0
|
@@ -21,7 +21,12 @@ function ExperienceVisualSearch({
|
|
|
21
21
|
const { singleImageSearch } = useImageSearch();
|
|
22
22
|
|
|
23
23
|
const initiateVisualSearch = async (blob: string) => {
|
|
24
|
-
singleImageSearch({
|
|
24
|
+
singleImageSearch({
|
|
25
|
+
image: blob,
|
|
26
|
+
settings,
|
|
27
|
+
clearPostFilter: true,
|
|
28
|
+
newSearch: true,
|
|
29
|
+
}).then(() => {});
|
|
25
30
|
navigate('/result');
|
|
26
31
|
};
|
|
27
32
|
|
|
@@ -48,8 +48,8 @@ function ExperienceVisualSearchTrigger({
|
|
|
48
48
|
<>
|
|
49
49
|
<div className="flex flex-col items-center">
|
|
50
50
|
<div
|
|
51
|
-
className={`group bg-[#3E36DC] w-
|
|
52
|
-
expand ? '
|
|
51
|
+
className={`group bg-[#3E36DC] w-10 hover:w-[215px] hover:gap-2 ${
|
|
52
|
+
expand ? 'w-[215px] gap-2' : ''
|
|
53
53
|
} h-10 flex flex-row justify-center items-center rounded-full cursor-pointer my-8 transition-all duration-300`}
|
|
54
54
|
onClick={() => modalToggle(true)}
|
|
55
55
|
>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
interface GroundingSpec {
|
|
4
|
+
label: string;
|
|
5
|
+
value: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const GroundingSpecs = ({ data }: { data: any }) => {
|
|
9
|
+
// Mapping the complex JSON object to the flat GroundingSpec interface
|
|
10
|
+
const [specs, setSpecs] = React.useState<GroundingSpec[]>([]);
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const newSpecs: GroundingSpec[] = [];
|
|
14
|
+
if (data.product_name) {
|
|
15
|
+
newSpecs.push({ label: 'Product Name', value: data.product_name });
|
|
16
|
+
}
|
|
17
|
+
if (data.brand) {
|
|
18
|
+
newSpecs.push({ label: 'Brand', value: data.brand });
|
|
19
|
+
}
|
|
20
|
+
if (data.category) {
|
|
21
|
+
newSpecs.push({ label: 'Category', value: data.category });
|
|
22
|
+
}
|
|
23
|
+
// Dynamically mapping the nested key_specs
|
|
24
|
+
Object.entries(data.key_specs || {}).forEach(([key, val]) => {
|
|
25
|
+
newSpecs.push({ label: key, value: String(val) });
|
|
26
|
+
});
|
|
27
|
+
setSpecs(newSpecs);
|
|
28
|
+
}, [data]);
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<div className="flex flex-col text-[10px] leading-4">
|
|
32
|
+
{specs.map((spec, index) => (
|
|
33
|
+
<div
|
|
34
|
+
key={index}
|
|
35
|
+
className={`flex items-center gap-2 py-[3px] pl-2 rounded-sm ${
|
|
36
|
+
index % 2 === 0 ? 'bg-[#F3F4F8]' : 'bg-white'
|
|
37
|
+
}`}
|
|
38
|
+
>
|
|
39
|
+
<div className="w-1/3 text-[#3B3E5F] font-semibold">{spec.label}</div>
|
|
40
|
+
<div className="w-2/3 text-[#3B3E5F]">{spec.value}</div>
|
|
41
|
+
</div>
|
|
42
|
+
))}
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default GroundingSpecs;
|
|
@@ -11,6 +11,7 @@ import { useState } from 'react';
|
|
|
11
11
|
import LogoutModal from './LogoutModal';
|
|
12
12
|
import { Popover, PopoverContent, PopoverTrigger } from './popover';
|
|
13
13
|
import useResultStore from 'stores/result/resultStore';
|
|
14
|
+
import Cart from './Cart';
|
|
14
15
|
|
|
15
16
|
function Header() {
|
|
16
17
|
const { theme, auth0 } = window.settings;
|
|
@@ -42,109 +43,109 @@ function Header() {
|
|
|
42
43
|
style={{ background: theme?.headerColor }}
|
|
43
44
|
>
|
|
44
45
|
<div
|
|
45
|
-
className={twMerge([
|
|
46
|
-
|
|
47
|
-
'flex',
|
|
48
|
-
'justify-center',
|
|
49
|
-
'items-center',
|
|
50
|
-
'relative',
|
|
51
|
-
'h-full',
|
|
52
|
-
])}
|
|
46
|
+
className={twMerge(['w-full', 'flex', 'items-center', 'h-full'])}
|
|
47
|
+
style={{ display: 'flex', alignItems: 'center', height: '100%' }}
|
|
53
48
|
>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
reset();
|
|
59
|
-
resetResultStore();
|
|
60
|
-
setSpecifications(null);
|
|
61
|
-
}}
|
|
49
|
+
{/* Left: Logo */}
|
|
50
|
+
<div
|
|
51
|
+
className="flex items-center justify-start min-w-0"
|
|
52
|
+
style={{ flex: '0 0 auto' }}
|
|
62
53
|
>
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
54
|
+
<NavLink
|
|
55
|
+
to="/"
|
|
56
|
+
style={{ lineHeight: 0 }}
|
|
57
|
+
onClick={() => {
|
|
58
|
+
reset();
|
|
59
|
+
resetResultStore();
|
|
60
|
+
setSpecifications(null);
|
|
70
61
|
}}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
62
|
+
>
|
|
63
|
+
<img
|
|
64
|
+
src={theme?.appBarLogoUrl}
|
|
65
|
+
alt="logo"
|
|
66
|
+
style={{
|
|
67
|
+
aspectRatio: 1,
|
|
68
|
+
width: theme?.logoWidth,
|
|
69
|
+
height: theme?.logoHeight,
|
|
70
|
+
}}
|
|
71
|
+
/>
|
|
72
|
+
</NavLink>
|
|
73
|
+
</div>
|
|
74
|
+
{/* Center: Search bar */}
|
|
75
|
+
<div className="flex-1 flex justify-center items-center min-w-0">
|
|
75
76
|
<div
|
|
76
77
|
className={twMerge(['hidden', showSearchBar && 'desktop:block'])}
|
|
77
|
-
style={{
|
|
78
|
-
// position: 'relative',
|
|
79
|
-
// left: '50%',
|
|
80
|
-
// top: '50%',
|
|
81
|
-
// transform: 'translate(-50%, -50%)',
|
|
82
|
-
}}
|
|
83
78
|
>
|
|
84
79
|
<TextSearch />
|
|
85
80
|
</div>
|
|
86
81
|
</div>
|
|
82
|
+
{/* Right: Cart and user actions */}
|
|
83
|
+
<div
|
|
84
|
+
className="flex items-center justify-end min-w-0 gap-4"
|
|
85
|
+
style={{ flex: '0 0 auto' }}
|
|
86
|
+
>
|
|
87
|
+
{window.settings.cart && <Cart />}
|
|
87
88
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
89
|
+
{auth0.enabled && isAuthenticated && (
|
|
90
|
+
<>
|
|
91
|
+
<div
|
|
92
|
+
className="hidden desktop:block"
|
|
93
|
+
style={{ position: 'relative' }}
|
|
94
|
+
>
|
|
95
|
+
<Popover>
|
|
96
|
+
<PopoverTrigger>
|
|
97
|
+
<div
|
|
98
|
+
style={{
|
|
99
|
+
display: 'flex',
|
|
100
|
+
columnGap: '16px',
|
|
101
|
+
alignItems: 'center',
|
|
102
|
+
cursor: 'pointer',
|
|
103
|
+
}}
|
|
104
|
+
>
|
|
105
|
+
<p style={{ color: '#2B2C46' }}>{user?.email}</p>
|
|
106
|
+
<Icon name="avatar" />
|
|
107
|
+
</div>
|
|
108
|
+
</PopoverTrigger>
|
|
109
|
+
<PopoverContent className="w-[152px] bg-white p-2 shadow-outer">
|
|
110
|
+
<div
|
|
111
|
+
className={twMerge([
|
|
112
|
+
'flex',
|
|
113
|
+
'w-[75px]',
|
|
114
|
+
'h-[24px]',
|
|
115
|
+
'px-2',
|
|
116
|
+
'items-center',
|
|
117
|
+
'bg-[#2B2C46]',
|
|
118
|
+
'text-white',
|
|
119
|
+
'text-[10px]',
|
|
120
|
+
'cursor-pointer',
|
|
121
|
+
])}
|
|
122
|
+
onClick={() => {
|
|
123
|
+
logout({
|
|
124
|
+
logoutParams: { returnTo: window.location.origin },
|
|
125
|
+
});
|
|
126
|
+
}}
|
|
127
|
+
>
|
|
128
|
+
Sign out
|
|
129
|
+
</div>
|
|
130
|
+
</PopoverContent>
|
|
131
|
+
</Popover>
|
|
132
|
+
</div>
|
|
133
|
+
<div
|
|
134
|
+
className="block desktop:hidden cursor-pointer"
|
|
135
|
+
onClick={() => {
|
|
136
|
+
setShowLogoutModal(true);
|
|
137
|
+
}}
|
|
138
|
+
>
|
|
139
|
+
<Icon
|
|
140
|
+
name="logout"
|
|
141
|
+
className="text-[#AAABB5]"
|
|
142
|
+
width={24}
|
|
143
|
+
height={24}
|
|
144
|
+
/>
|
|
145
|
+
</div>
|
|
146
|
+
</>
|
|
147
|
+
)}
|
|
148
|
+
</div>
|
|
148
149
|
</div>
|
|
149
150
|
<LogoutModal
|
|
150
151
|
setShowLogoutModal={setShowLogoutModal}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useTranslation } from 'react-i18next';
|
|
2
2
|
import { useHitsPerPage, UseHitsPerPageProps } from 'react-instantsearch';
|
|
3
|
+
import PoweredBy from './PoweredBy';
|
|
3
4
|
|
|
4
5
|
export const HitsPerPage = (props: UseHitsPerPageProps) => {
|
|
5
6
|
const { items, refine } = useHitsPerPage(props);
|
|
@@ -10,8 +11,8 @@ export const HitsPerPage = (props: UseHitsPerPageProps) => {
|
|
|
10
11
|
|
|
11
12
|
return (
|
|
12
13
|
<>
|
|
13
|
-
<div className="w-full
|
|
14
|
-
<div className="self-stretch
|
|
14
|
+
<div className="w-full px-4 h-10 bg-white border border-solid border-[#DDDEE7] items-center hidden desktop:inline-flex justify-between">
|
|
15
|
+
<div className="self-stretch pr-6 border-r border-solid border-[#DDDEE7] justify-center items-center gap-1 flex">
|
|
15
16
|
<div className="text-[#2b2c46] text-[13px] font-normal font-['Source Sans 3'] leading-none tracking-tight">
|
|
16
17
|
{t('Items per page')}:
|
|
17
18
|
</div>
|
|
@@ -29,6 +30,7 @@ export const HitsPerPage = (props: UseHitsPerPageProps) => {
|
|
|
29
30
|
))}
|
|
30
31
|
</select>
|
|
31
32
|
</div>
|
|
33
|
+
{window.settings.showPoweredByNyris && <PoweredBy />}
|
|
32
34
|
</div>
|
|
33
35
|
</>
|
|
34
36
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import React, {useCallback, useEffect, useRef, useState} from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
|
-
import {clone, 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,7 +12,6 @@ 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';
|
|
16
15
|
|
|
17
16
|
function ImagePreviewComponent({
|
|
18
17
|
showAdjustInfo = false,
|
|
@@ -24,13 +23,13 @@ function ImagePreviewComponent({
|
|
|
24
23
|
}) {
|
|
25
24
|
const [showAdjustInfoBasedOnConfidence, setShowAdjustInfoBasedOnConfidence] =
|
|
26
25
|
useState(false);
|
|
27
|
-
const [resultFilter, setResultFilter] = useState<any>([]);
|
|
28
26
|
|
|
29
27
|
const { t } = useTranslation();
|
|
30
28
|
const navigate = useNavigate();
|
|
31
29
|
const settings = window.settings;
|
|
32
30
|
const isMultiImageSearchEnabled = settings.multiImageSearch;
|
|
33
31
|
|
|
32
|
+
const preFilterList = useRequestStore(state => state.preFilterList);
|
|
34
33
|
const requestImages = useRequestStore(state => state.requestImages);
|
|
35
34
|
const specifications = useRequestStore(state => state.specifications);
|
|
36
35
|
const resetRegions = useRequestStore(state => state.resetRegions);
|
|
@@ -40,11 +39,15 @@ function ImagePreviewComponent({
|
|
|
40
39
|
const resetRequestStore = useRequestStore(state => state.reset);
|
|
41
40
|
const setSpecifications = useRequestStore(state => state.setSpecifications);
|
|
42
41
|
const setShowLoading = useRequestStore(state => state.setShowLoading);
|
|
43
|
-
const setNameplateNotificationText = useRequestStore(
|
|
42
|
+
const setNameplateNotificationText = useRequestStore(
|
|
43
|
+
state => state.setNameplateNotificationText,
|
|
44
|
+
);
|
|
44
45
|
const setAlgoliaFilter = useRequestStore(state => state.setAlgoliaFilter);
|
|
45
46
|
const setPreFilter = useRequestStore(state => state.setPreFilter);
|
|
46
47
|
const setNameplateImage = useRequestStore(state => state.setNameplateImage);
|
|
47
|
-
const setShowNotMatchedError = useRequestStore(
|
|
48
|
+
const setShowNotMatchedError = useRequestStore(
|
|
49
|
+
state => state.setShowNotMatchedError,
|
|
50
|
+
);
|
|
48
51
|
|
|
49
52
|
const detectedRegions = useResultStore(state => state.detectedRegions);
|
|
50
53
|
const resetResultStore = useResultStore(state => state.reset);
|
|
@@ -55,21 +58,31 @@ function ImagePreviewComponent({
|
|
|
55
58
|
|
|
56
59
|
const [isVisible] = useState(true);
|
|
57
60
|
const [zIndex] = useState<number>(0);
|
|
61
|
+
const [previewWidth, setPreviewWidth] = useState(0);
|
|
58
62
|
|
|
59
63
|
const previewWrapperRef = useRef<any>(null);
|
|
60
64
|
|
|
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
65
|
useEffect(() => {
|
|
72
|
-
|
|
66
|
+
const container = previewWrapperRef.current as HTMLDivElement | null;
|
|
67
|
+
if (!container) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const updateWidth = () => {
|
|
72
|
+
const nextWidth = Math.round(container.getBoundingClientRect().width);
|
|
73
|
+
setPreviewWidth(prevWidth =>
|
|
74
|
+
prevWidth === nextWidth ? prevWidth : nextWidth,
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
updateWidth();
|
|
79
|
+
|
|
80
|
+
const resizeObserver = new ResizeObserver(updateWidth);
|
|
81
|
+
resizeObserver.observe(container);
|
|
82
|
+
|
|
83
|
+
return () => {
|
|
84
|
+
resizeObserver.disconnect();
|
|
85
|
+
};
|
|
73
86
|
}, []);
|
|
74
87
|
|
|
75
88
|
const onImageRemove = () => {
|
|
@@ -94,48 +107,66 @@ function ImagePreviewComponent({
|
|
|
94
107
|
showFeedback: true,
|
|
95
108
|
compress: false,
|
|
96
109
|
}).then((res: any) => {
|
|
97
|
-
const specificationPrefilter =
|
|
98
|
-
|
|
110
|
+
const specificationPrefilter =
|
|
111
|
+
res.image_analysis?.specification?.prefilter_value || null;
|
|
112
|
+
const hasPrefilter = preFilterList.filter((filter: any) =>
|
|
113
|
+
filter.values.includes(specificationPrefilter),
|
|
114
|
+
);
|
|
99
115
|
if (specificationPrefilter) {
|
|
100
116
|
setRequestImages([]);
|
|
101
117
|
setShowNotMatchedError(false);
|
|
102
118
|
if (hasPrefilter.length) {
|
|
103
119
|
setSpecifications(clone(res.image_analysis.specification));
|
|
104
120
|
setNameplateImage(image);
|
|
105
|
-
setPreFilter({
|
|
106
|
-
|
|
121
|
+
setPreFilter({
|
|
122
|
+
[res.image_analysis?.specification?.prefilter_value]: true,
|
|
123
|
+
});
|
|
124
|
+
setAlgoliaFilter(
|
|
125
|
+
`${settings.alogoliaFilterField}:'${res.image_analysis?.specification?.prefilter_value}'`,
|
|
126
|
+
);
|
|
107
127
|
|
|
108
128
|
setShowLoading(false);
|
|
109
129
|
navigate('/result');
|
|
110
130
|
|
|
111
131
|
setTimeout(() => {
|
|
112
|
-
setNameplateNotificationText(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
132
|
+
setNameplateNotificationText(
|
|
133
|
+
t('We have successfully defined the search criteria', {
|
|
134
|
+
prefilter_value: specificationPrefilter,
|
|
135
|
+
preFilterTitle:
|
|
136
|
+
window.settings.preFilterTitle?.toLocaleLowerCase(),
|
|
137
|
+
}),
|
|
138
|
+
);
|
|
116
139
|
}, 1000);
|
|
117
140
|
setTimeout(() => {
|
|
118
141
|
setNameplateNotificationText('');
|
|
119
142
|
}, 6000);
|
|
120
143
|
}
|
|
121
144
|
if (!hasPrefilter.length && window.settings.preFilterOption) {
|
|
122
|
-
setSpecifications(
|
|
145
|
+
setSpecifications(
|
|
146
|
+
clone({
|
|
147
|
+
...res.image_analysis.specification,
|
|
148
|
+
specificationPrefilter,
|
|
149
|
+
}),
|
|
150
|
+
);
|
|
123
151
|
setPreFilter({});
|
|
124
152
|
setAlgoliaFilter('');
|
|
125
153
|
setShowLoading(false);
|
|
126
154
|
setShowNotMatchedError(true);
|
|
127
155
|
setTimeout(() => {
|
|
128
|
-
setNameplateNotificationText(
|
|
156
|
+
setNameplateNotificationText(
|
|
157
|
+
t('Extracted details from the nameplate could not be matched', {
|
|
158
|
+
preFilterTitle:
|
|
159
|
+
window.settings.preFilterTitle?.toLocaleLowerCase(),
|
|
160
|
+
}),
|
|
161
|
+
);
|
|
129
162
|
}, 1000);
|
|
130
163
|
setTimeout(() => {
|
|
131
164
|
setNameplateNotificationText('');
|
|
132
165
|
}, 6000);
|
|
133
166
|
}
|
|
134
167
|
} else {
|
|
135
|
-
if (specifications?.is_nameplate) {
|
|
136
|
-
setSpecifications({...specifications,
|
|
137
|
-
} else {
|
|
138
|
-
setSpecifications({...specifications, is_nameplate: false});
|
|
168
|
+
if (!specifications?.is_nameplate) {
|
|
169
|
+
setSpecifications({ ...specifications, is_nameplate: false });
|
|
139
170
|
}
|
|
140
171
|
const highConfidence = res.results.find(
|
|
141
172
|
(data: { score: number }) => data.score >= 0.65,
|
|
@@ -173,6 +204,7 @@ function ImagePreviewComponent({
|
|
|
173
204
|
'justify-center',
|
|
174
205
|
isVisible ? (!isMultiImageSearchEnabled ? 'py-5' : 'pt-6') : '',
|
|
175
206
|
'px-7',
|
|
207
|
+
'box-border',
|
|
176
208
|
'w-full',
|
|
177
209
|
'desktop:px-5',
|
|
178
210
|
'relative',
|
|
@@ -202,6 +234,7 @@ function ImagePreviewComponent({
|
|
|
202
234
|
])}
|
|
203
235
|
>
|
|
204
236
|
<Preview
|
|
237
|
+
key={previewWidth}
|
|
205
238
|
onSelectionChange={(r: RectCoords) => {
|
|
206
239
|
debouncedOnImageSelectionChange(r, currentIndex);
|
|
207
240
|
}}
|