@nyris/nyris-webapp 0.3.94 → 0.3.96
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/asset-manifest.json +3 -3
- package/build/index.html +1 -1
- package/build/static/js/main.fd12cce3.js +3 -0
- package/build/static/js/{main.09201b03.js.map → main.fd12cce3.js.map} +1 -1
- package/package.json +3 -3
- package/src/components/ImageUpload.tsx +6 -110
- package/src/components/PostFilter/PostFilterFindApi.tsx +123 -69
- package/src/components/PreFilter/PreFilter.tsx +10 -4
- package/src/components/Product/ProductList.tsx +4 -0
- package/src/components/Toaster.tsx +3 -2
- package/src/hooks/useEffectiveGroundingResults.ts +6 -1
- package/src/hooks/useImageSearch.ts +41 -6
- package/src/hooks/useUploadSearch.ts +170 -0
- package/src/layouts/AppLayout.tsx +70 -0
- package/src/pages/Result.tsx +8 -7
- package/src/stores/result/prodcuts/products.initialState.ts +2 -0
- package/src/stores/result/prodcuts/products.slice.ts +8 -0
- package/src/stores/types.ts +9 -0
- package/src/translations.ts +33 -18
- package/build/static/js/main.09201b03.js +0 -3
- /package/build/static/js/{main.09201b03.js.LICENSE.txt → main.fd12cce3.js.LICENSE.txt} +0 -0
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nyris/nyris-webapp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.96",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"@auth0/auth0-react": "^2.2.4",
|
|
6
6
|
"@emailjs/browser": "^4.3.3",
|
|
7
7
|
"@google/genai": "^1.46.0",
|
|
8
|
-
"@nyris/nyris-api": "^0.3.
|
|
9
|
-
"@nyris/nyris-react-components": "^0.3.
|
|
8
|
+
"@nyris/nyris-api": "^0.3.96",
|
|
9
|
+
"@nyris/nyris-react-components": "^0.3.96",
|
|
10
10
|
"@radix-ui/react-accordion": "^1.2.2",
|
|
11
11
|
"@radix-ui/react-dialog": "^1.1.4",
|
|
12
12
|
"@radix-ui/react-popover": "^1.1.4",
|
|
@@ -4,13 +4,10 @@ import { twMerge } from 'tailwind-merge';
|
|
|
4
4
|
import Tooltip from './Tooltip/TooltipComponent';
|
|
5
5
|
import { useAuth0 } from '@auth0/auth0-react';
|
|
6
6
|
import { useMemo, useState } from 'react';
|
|
7
|
-
import { useLocation
|
|
7
|
+
import { useLocation } from 'react-router';
|
|
8
8
|
import useRequestStore from 'stores/request/requestStore';
|
|
9
|
-
import { useImageSearch } from 'hooks/useImageSearch';
|
|
10
|
-
import { clone } from 'lodash';
|
|
11
|
-
import { useCadSearch } from 'hooks/useCadSearch';
|
|
12
|
-
import { isCadFile } from '@nyris/nyris-api';
|
|
13
9
|
import UploadDisclaimer from './UploadDisclaimer';
|
|
10
|
+
import { useUploadSearch } from 'hooks/useUploadSearch';
|
|
14
11
|
|
|
15
12
|
function ImageUpload({
|
|
16
13
|
onCameraClick,
|
|
@@ -25,27 +22,10 @@ function ImageUpload({
|
|
|
25
22
|
const { t } = useTranslation();
|
|
26
23
|
|
|
27
24
|
const location = useLocation();
|
|
28
|
-
const
|
|
25
|
+
const { uploadFile } = useUploadSearch();
|
|
29
26
|
|
|
30
|
-
const preFilterList = useRequestStore(state => state.preFilterList);
|
|
31
27
|
const requestImages = useRequestStore(state => state.requestImages);
|
|
32
|
-
const setQuery = useRequestStore(state => state.setQuery);
|
|
33
|
-
const setValueInput = useRequestStore(state => state.setValueInput);
|
|
34
28
|
const setMetaFilter = useRequestStore(state => state.setMetaFilter);
|
|
35
|
-
const specifications = useRequestStore(state => state.specifications);
|
|
36
|
-
|
|
37
|
-
const setRequestImages = useRequestStore(state => state.setRequestImages);
|
|
38
|
-
const setSpecifications = useRequestStore(state => state.setSpecifications);
|
|
39
|
-
const setShowLoading = useRequestStore(state => state.setShowLoading);
|
|
40
|
-
const setNameplateNotificationText = useRequestStore(
|
|
41
|
-
state => state.setNameplateNotificationText,
|
|
42
|
-
);
|
|
43
|
-
const setShowNotMatchedError = useRequestStore(
|
|
44
|
-
state => state.setShowNotMatchedError,
|
|
45
|
-
);
|
|
46
|
-
const setAlgoliaFilter = useRequestStore(state => state.setAlgoliaFilter);
|
|
47
|
-
const setPreFilter = useRequestStore(state => state.setPreFilter);
|
|
48
|
-
const setNameplateImage = useRequestStore(state => state.setNameplateImage);
|
|
49
29
|
|
|
50
30
|
const [showDisclaimer, setShowDisclaimer] = useState(false);
|
|
51
31
|
|
|
@@ -80,97 +60,13 @@ function ImageUpload({
|
|
|
80
60
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
81
61
|
}, [showDisclaimer, requestImages, disableDisclaimer]);
|
|
82
62
|
|
|
83
|
-
const { singleImageSearch } = useImageSearch();
|
|
84
|
-
const { cadSearch } = useCadSearch();
|
|
85
|
-
|
|
86
63
|
const handleUpload = (files: File[]) => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (isCadFile(files[0])) {
|
|
91
|
-
cadSearch({ file: files[0], settings, newSearch: true }).then(() => {});
|
|
92
|
-
|
|
64
|
+
const file = files[0];
|
|
65
|
+
if (!file) {
|
|
93
66
|
return;
|
|
94
67
|
}
|
|
95
68
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
singleImageSearch({
|
|
99
|
-
image: files[0],
|
|
100
|
-
settings: window.settings,
|
|
101
|
-
showFeedback: true,
|
|
102
|
-
newSearch: true,
|
|
103
|
-
clearPostFilter: true,
|
|
104
|
-
}).then(singleImageResp => {
|
|
105
|
-
const specificationPrefilter =
|
|
106
|
-
singleImageResp?.image_analysis?.specification?.prefilter_value || null;
|
|
107
|
-
const hasPrefilter = preFilterList.filter((filter: any) =>
|
|
108
|
-
filter.values.includes(specificationPrefilter),
|
|
109
|
-
);
|
|
110
|
-
if (specificationPrefilter) {
|
|
111
|
-
setRequestImages([]);
|
|
112
|
-
setShowNotMatchedError(false);
|
|
113
|
-
if (hasPrefilter.length) {
|
|
114
|
-
setSpecifications(
|
|
115
|
-
clone(singleImageResp?.image_analysis?.specification),
|
|
116
|
-
);
|
|
117
|
-
setNameplateImage(files[0]);
|
|
118
|
-
setPreFilter({
|
|
119
|
-
[singleImageResp?.image_analysis?.specification?.prefilter_value]:
|
|
120
|
-
true,
|
|
121
|
-
});
|
|
122
|
-
setAlgoliaFilter(
|
|
123
|
-
`${settings.alogoliaFilterField}:'${singleImageResp?.image_analysis?.specification?.prefilter_value}'`,
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
setShowLoading(false);
|
|
127
|
-
navigate('/result');
|
|
128
|
-
|
|
129
|
-
setTimeout(() => {
|
|
130
|
-
setNameplateNotificationText(
|
|
131
|
-
t('We have successfully defined the search criteria', {
|
|
132
|
-
prefilter_value: specificationPrefilter,
|
|
133
|
-
preFilterTitle:
|
|
134
|
-
window.settings.preFilterTitle?.toLocaleLowerCase(),
|
|
135
|
-
}),
|
|
136
|
-
);
|
|
137
|
-
}, 1000);
|
|
138
|
-
setTimeout(() => {
|
|
139
|
-
setNameplateNotificationText('');
|
|
140
|
-
}, 10000);
|
|
141
|
-
}
|
|
142
|
-
if (!hasPrefilter.length && showPreFilter) {
|
|
143
|
-
setSpecifications(
|
|
144
|
-
clone({
|
|
145
|
-
...singleImageResp?.image_analysis?.specification,
|
|
146
|
-
specificationPrefilter,
|
|
147
|
-
}),
|
|
148
|
-
);
|
|
149
|
-
navigate('/result');
|
|
150
|
-
setPreFilter({});
|
|
151
|
-
setAlgoliaFilter('');
|
|
152
|
-
setShowLoading(false);
|
|
153
|
-
setShowNotMatchedError(true);
|
|
154
|
-
setTimeout(() => {
|
|
155
|
-
setNameplateNotificationText(
|
|
156
|
-
t('Extracted details from the nameplate could not be matched', {
|
|
157
|
-
preFilterTitle:
|
|
158
|
-
window.settings.preFilterTitle?.toLocaleLowerCase(),
|
|
159
|
-
}),
|
|
160
|
-
);
|
|
161
|
-
}, 1000);
|
|
162
|
-
setTimeout(() => {
|
|
163
|
-
setNameplateNotificationText('');
|
|
164
|
-
}, 15000);
|
|
165
|
-
}
|
|
166
|
-
} else {
|
|
167
|
-
if (!specifications?.is_nameplate) {
|
|
168
|
-
setSpecifications({ ...specifications, is_nameplate: false });
|
|
169
|
-
}
|
|
170
|
-
setShowLoading(false);
|
|
171
|
-
navigate('/result');
|
|
172
|
-
}
|
|
173
|
-
});
|
|
69
|
+
uploadFile(file, { showPreFilter });
|
|
174
70
|
};
|
|
175
71
|
|
|
176
72
|
return (
|
|
@@ -6,9 +6,17 @@ import {
|
|
|
6
6
|
} from 'components/Accordion';
|
|
7
7
|
import { Icon } from '@nyris/nyris-react-components';
|
|
8
8
|
import { useTranslation } from 'react-i18next';
|
|
9
|
+
import { isEmpty } from 'lodash';
|
|
9
10
|
import useResultStore from 'stores/result/resultStore';
|
|
10
11
|
import useRequestStore from 'stores/request/requestStore';
|
|
11
|
-
import
|
|
12
|
+
import useUiStore from 'stores/ui/uiStore';
|
|
13
|
+
import { find } from 'services/visualSearch';
|
|
14
|
+
|
|
15
|
+
let postFilterRequestCounter = 0;
|
|
16
|
+
|
|
17
|
+
export function invalidatePostFilterRequests() {
|
|
18
|
+
postFilterRequestCounter += 1;
|
|
19
|
+
}
|
|
12
20
|
|
|
13
21
|
function PostFilterFindApi({
|
|
14
22
|
attribute,
|
|
@@ -26,84 +34,53 @@ function PostFilterFindApi({
|
|
|
26
34
|
const [itemsLimit, setItemsLimit] = useState(10);
|
|
27
35
|
const [searchInput, setSearchInput] = useState<string>('');
|
|
28
36
|
|
|
29
|
-
const
|
|
30
|
-
|
|
37
|
+
const postFilterFacets = useResultStore(state => state.postFilterFacets);
|
|
38
|
+
const setFindApiProducts = useResultStore(state => state.setFindApiProducts);
|
|
39
|
+
const setPostFilterSelections = useRequestStore(
|
|
40
|
+
state => state.setPostFilterSelections,
|
|
31
41
|
);
|
|
32
|
-
const groundingFilterResult = useResultStore(
|
|
33
|
-
state => state.groundingFilterResult,
|
|
34
|
-
);
|
|
35
|
-
const showingGroundingFilterResult = useResultStore(
|
|
36
|
-
state => state.showingGroundingFilterResult,
|
|
37
|
-
);
|
|
38
|
-
const query = useRequestStore(state => state.query);
|
|
39
|
-
const requestImages = useRequestStore(state => state.requestImages);
|
|
40
42
|
const postFilterSelections = useRequestStore(
|
|
41
43
|
state => state.postFilterSelections,
|
|
42
44
|
);
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
);
|
|
45
|
+
const query = useRequestStore(state => state.query);
|
|
46
|
+
const requestImages = useRequestStore(state => state.requestImages);
|
|
47
|
+
const regions = useRequestStore(state => state.regions);
|
|
48
|
+
const preFilter = useRequestStore(state => state.preFilter);
|
|
49
|
+
const preFilterList = useRequestStore(state => state.preFilterList);
|
|
50
|
+
const metaFilter = useRequestStore(state => state.metaFilter);
|
|
51
|
+
const setIsFindApiLoading = useUiStore(state => state.setIsFindApiLoading);
|
|
46
52
|
const { t } = useTranslation();
|
|
53
|
+
const settings = window.settings;
|
|
47
54
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (showingGroundingFilterResult && groundingFilterResult?.length > 0) {
|
|
56
|
-
const grounded = baseProducts.filter((product: any) =>
|
|
57
|
-
groundingFilterResult.some((result: any) => product.sku === result.sku),
|
|
58
|
-
);
|
|
59
|
-
if (grounded.length > 0) {
|
|
60
|
-
return grounded;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return baseProducts;
|
|
65
|
-
}, [
|
|
66
|
-
productsFromFindApi,
|
|
67
|
-
query,
|
|
68
|
-
requestImages,
|
|
69
|
-
showingGroundingFilterResult,
|
|
70
|
-
groundingFilterResult,
|
|
71
|
-
]);
|
|
72
|
-
|
|
73
|
-
const filteredProductsForCounts = useMemo(() => {
|
|
74
|
-
const selections = postFilterSelections || {};
|
|
75
|
-
const activeSelections = Object.entries(selections).filter(
|
|
76
|
-
([attr, values]) => attr !== attribute && Array.isArray(values),
|
|
55
|
+
const matchedFacet = useMemo(() => {
|
|
56
|
+
const facets = Array.isArray(postFilterFacets) ? postFilterFacets : [];
|
|
57
|
+
return facets.find(
|
|
58
|
+
(entry: { name?: string }) =>
|
|
59
|
+
entry.name?.toLocaleLowerCase() === attribute.toLocaleLowerCase(),
|
|
77
60
|
);
|
|
61
|
+
}, [attribute, postFilterFacets]);
|
|
78
62
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const filterValues = product.filters?.[attr];
|
|
86
|
-
if (!Array.isArray(filterValues) || filterValues.length === 0) {
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
return values.some(value => filterValues.includes(value));
|
|
90
|
-
}),
|
|
91
|
-
);
|
|
92
|
-
}, [attribute, postFilterSelections, productsForFilters]);
|
|
63
|
+
const preFilterApiKey =
|
|
64
|
+
preFilterList.find(
|
|
65
|
+
filter =>
|
|
66
|
+
filter.key?.toLocaleLowerCase() ===
|
|
67
|
+
settings.visualSearchFilterKey?.toLocaleLowerCase(),
|
|
68
|
+
)?.key ?? settings.visualSearchFilterKey;
|
|
93
69
|
|
|
94
70
|
const valueCounts = useMemo(() => {
|
|
95
71
|
const counts: Record<string, number> = {};
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
72
|
+
|
|
73
|
+
(matchedFacet?.values || []).forEach(
|
|
74
|
+
(entry: { value?: string; count?: number }) => {
|
|
75
|
+
const value = entry?.value;
|
|
76
|
+
if (value) {
|
|
77
|
+
counts[value] = entry.count ?? 0;
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
);
|
|
104
81
|
|
|
105
82
|
return counts;
|
|
106
|
-
}, [
|
|
83
|
+
}, [matchedFacet]);
|
|
107
84
|
|
|
108
85
|
const items = useMemo(() => {
|
|
109
86
|
const selectedValues = postFilterSelections?.[attribute] || [];
|
|
@@ -138,6 +115,85 @@ function PostFilterFindApi({
|
|
|
138
115
|
onVisibilityChange?.(attribute, isVisible);
|
|
139
116
|
}, [attribute, isVisible, onVisibilityChange]);
|
|
140
117
|
|
|
118
|
+
const handleFilterClick = (value: string, isRefined: boolean) => {
|
|
119
|
+
const currentSelections =
|
|
120
|
+
useRequestStore.getState().postFilterSelections || {};
|
|
121
|
+
const currentAttributeValues = currentSelections[attribute] || [];
|
|
122
|
+
const nextAttributeValues = isRefined
|
|
123
|
+
? currentAttributeValues.filter(item => item !== value)
|
|
124
|
+
: [...currentAttributeValues, value];
|
|
125
|
+
|
|
126
|
+
const nextSelections = { ...currentSelections };
|
|
127
|
+
if (nextAttributeValues.length > 0) {
|
|
128
|
+
nextSelections[attribute] = nextAttributeValues;
|
|
129
|
+
} else {
|
|
130
|
+
delete nextSelections[attribute];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
setPostFilterSelections(nextSelections);
|
|
134
|
+
|
|
135
|
+
const hasAnySelection = Object.values(nextSelections).some(
|
|
136
|
+
values => values.length > 0,
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
if (!hasAnySelection) {
|
|
140
|
+
const snapshot = useResultStore.getState().initialFindSearchSnapshot;
|
|
141
|
+
if (snapshot) {
|
|
142
|
+
setFindApiProducts(snapshot.results);
|
|
143
|
+
}
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const facets = useResultStore.getState().postFilterFacets || [];
|
|
148
|
+
const filters = [];
|
|
149
|
+
|
|
150
|
+
if (!isEmpty(preFilter)) {
|
|
151
|
+
filters.push({
|
|
152
|
+
key: preFilterApiKey,
|
|
153
|
+
values: Object.keys(preFilter).filter(key => preFilter[key]),
|
|
154
|
+
});
|
|
155
|
+
} else if (metaFilter) {
|
|
156
|
+
filters.push({
|
|
157
|
+
key: preFilterApiKey,
|
|
158
|
+
values: [metaFilter],
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
Object.entries(nextSelections).forEach(([attr, values]) => {
|
|
163
|
+
if (values.length > 0) {
|
|
164
|
+
const facet = facets.find(
|
|
165
|
+
(entry: { name?: string }) =>
|
|
166
|
+
entry.name?.toLocaleLowerCase() === attr.toLocaleLowerCase(),
|
|
167
|
+
);
|
|
168
|
+
filters.push({
|
|
169
|
+
key: facet?.name ?? attr,
|
|
170
|
+
values,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const requestId = ++postFilterRequestCounter;
|
|
176
|
+
setIsFindApiLoading(true);
|
|
177
|
+
void find({
|
|
178
|
+
image: requestImages[0],
|
|
179
|
+
settings,
|
|
180
|
+
region: regions[0],
|
|
181
|
+
filters,
|
|
182
|
+
text: !requestImages[0] ? query : undefined,
|
|
183
|
+
})
|
|
184
|
+
.then(response => {
|
|
185
|
+
if (requestId !== postFilterRequestCounter) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
setFindApiProducts(response?.results || []);
|
|
189
|
+
})
|
|
190
|
+
.finally(() => {
|
|
191
|
+
if (requestId === postFilterRequestCounter) {
|
|
192
|
+
setIsFindApiLoading(false);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
|
|
141
197
|
if (!isVisible) {
|
|
142
198
|
return null;
|
|
143
199
|
}
|
|
@@ -208,9 +264,7 @@ function PostFilterFindApi({
|
|
|
208
264
|
<input
|
|
209
265
|
type="checkbox"
|
|
210
266
|
checked={item.isRefined}
|
|
211
|
-
onChange={() =>
|
|
212
|
-
togglePostFilterSelection(attribute, item.value)
|
|
213
|
-
}
|
|
267
|
+
onChange={() => handleFilterClick(item.value, item.isRefined)}
|
|
214
268
|
className="cursor-pointer"
|
|
215
269
|
/>
|
|
216
270
|
<span className="text-xs font-normal pl-2 pr-1">
|
|
@@ -76,10 +76,16 @@ const PreFilterComponent = (props: Props) => {
|
|
|
76
76
|
};
|
|
77
77
|
}, []);
|
|
78
78
|
|
|
79
|
+
const matchedPreFilter = preFilterList.find(
|
|
80
|
+
value =>
|
|
81
|
+
value.key?.toLocaleLowerCase() ===
|
|
82
|
+
settings.visualSearchFilterKey?.toLocaleLowerCase(),
|
|
83
|
+
);
|
|
84
|
+
const preFilterApiKey =
|
|
85
|
+
matchedPreFilter?.key ?? settings.visualSearchFilterKey;
|
|
86
|
+
|
|
79
87
|
const getDataFilterDesktop = () => {
|
|
80
|
-
const arrResult =
|
|
81
|
-
preFilterList.find(value => value.key === settings.visualSearchFilterKey)
|
|
82
|
-
?.values || [];
|
|
88
|
+
const arrResult = matchedPreFilter?.values || [];
|
|
83
89
|
|
|
84
90
|
const newResult = arrResult.sort().reduce((a: any, c: any) => {
|
|
85
91
|
if (!c[0]) return a;
|
|
@@ -100,7 +106,7 @@ const PreFilterComponent = (props: Props) => {
|
|
|
100
106
|
}
|
|
101
107
|
setLoading(true);
|
|
102
108
|
const data = await searchFilters(
|
|
103
|
-
|
|
109
|
+
preFilterApiKey,
|
|
104
110
|
encodeURIComponent(value),
|
|
105
111
|
settings,
|
|
106
112
|
)
|
|
@@ -63,6 +63,10 @@ function ProductList({ sendFeedBackAction }: Props): JSX.Element {
|
|
|
63
63
|
}, [productsFromFindApi, query, requestImages]);
|
|
64
64
|
|
|
65
65
|
const postFilteredProducts = useMemo(() => {
|
|
66
|
+
if (!window.settings.algolia?.enabled && window.settings.postFilterOption) {
|
|
67
|
+
return textFilteredProducts;
|
|
68
|
+
}
|
|
69
|
+
|
|
66
70
|
const entries = Object.entries(postFilterSelections || {}).filter(
|
|
67
71
|
([, values]) => values?.length,
|
|
68
72
|
);
|
|
@@ -15,8 +15,9 @@ export const Toaster = () => {
|
|
|
15
15
|
<ReactHotToaster
|
|
16
16
|
position={isMobile ? 'bottom-center' : 'top-right'}
|
|
17
17
|
containerStyle={{
|
|
18
|
-
top:
|
|
19
|
-
bottom: isMobile ?
|
|
18
|
+
top: 100,
|
|
19
|
+
bottom: isMobile ? 90 : 'auto',
|
|
20
|
+
right: isMobile ? 15 : 25,
|
|
20
21
|
}}
|
|
21
22
|
>
|
|
22
23
|
{t => (
|
|
@@ -26,7 +26,12 @@ export function useEffectiveGroundingResults() {
|
|
|
26
26
|
const postEntries = Object.entries(postFilterSelections || {}).filter(
|
|
27
27
|
([, values]) => values?.length,
|
|
28
28
|
);
|
|
29
|
-
if (
|
|
29
|
+
if (
|
|
30
|
+
postEntries.length > 0 &&
|
|
31
|
+
!(
|
|
32
|
+
!window.settings.algolia?.enabled && window.settings.postFilterOption
|
|
33
|
+
)
|
|
34
|
+
) {
|
|
30
35
|
filteredProducts = filteredProducts.filter((product: any) => {
|
|
31
36
|
const productFilters = product?.filters || {};
|
|
32
37
|
return postEntries.every(([attribute, selectedValues]) => {
|
|
@@ -19,6 +19,7 @@ import useConversationStore from 'stores/chat/conversationStore';
|
|
|
19
19
|
import { useGroundedSearch } from './useGroundedSearch';
|
|
20
20
|
import { generateSmartFilters } from '../services/vizo';
|
|
21
21
|
import { cropImage } from 'utils/cropImageToBase64';
|
|
22
|
+
import { invalidatePostFilterRequests } from 'components/PostFilter/PostFilterFindApi';
|
|
22
23
|
|
|
23
24
|
export const useImageSearch = () => {
|
|
24
25
|
const setRegions = useRequestStore(state => state.setRegions);
|
|
@@ -68,6 +69,10 @@ export const useImageSearch = () => {
|
|
|
68
69
|
state => state.setGroundingFilterResult,
|
|
69
70
|
);
|
|
70
71
|
const setSmartFilters = useResultStore(state => state.setSmartFilters);
|
|
72
|
+
const setPostFilterFacets = useResultStore(state => state.setPostFilterFacets);
|
|
73
|
+
const setInitialFindSearchSnapshot = useResultStore(
|
|
74
|
+
state => state.setInitialFindSearchSnapshot,
|
|
75
|
+
);
|
|
71
76
|
|
|
72
77
|
const setGroundingError = useResultStore(state => state.setGroundingError);
|
|
73
78
|
|
|
@@ -110,6 +115,8 @@ export const useImageSearch = () => {
|
|
|
110
115
|
setGroundingFilterResult([]);
|
|
111
116
|
setGoogleGroundingResponse(null);
|
|
112
117
|
setGroundingError(null);
|
|
118
|
+
setPostFilterFacets([]);
|
|
119
|
+
setInitialFindSearchSnapshot(null);
|
|
113
120
|
if (isSmartFiltersEnabled) {
|
|
114
121
|
setSmartFilters({
|
|
115
122
|
status: 'idle',
|
|
@@ -185,9 +192,17 @@ export const useImageSearch = () => {
|
|
|
185
192
|
}
|
|
186
193
|
}
|
|
187
194
|
|
|
195
|
+
const preFilterList = useRequestStore.getState().preFilterList;
|
|
196
|
+
const preFilterApiKey =
|
|
197
|
+
preFilterList.find(
|
|
198
|
+
filter =>
|
|
199
|
+
filter.key?.toLocaleLowerCase() ===
|
|
200
|
+
settings.visualSearchFilterKey?.toLocaleLowerCase(),
|
|
201
|
+
)?.key ?? settings.visualSearchFilterKey;
|
|
202
|
+
|
|
188
203
|
const preFilterValues = [
|
|
189
204
|
{
|
|
190
|
-
key:
|
|
205
|
+
key: preFilterApiKey,
|
|
191
206
|
values: Object.keys(preFilterParams || preFilter),
|
|
192
207
|
},
|
|
193
208
|
];
|
|
@@ -272,6 +287,22 @@ export const useImageSearch = () => {
|
|
|
272
287
|
});
|
|
273
288
|
}
|
|
274
289
|
|
|
290
|
+
const shouldResetPostFilters =
|
|
291
|
+
clearPostFilter ||
|
|
292
|
+
(!settings.algolia?.enabled &&
|
|
293
|
+
!requestImage &&
|
|
294
|
+
settings.postFilterOption);
|
|
295
|
+
|
|
296
|
+
if (shouldResetPostFilters) {
|
|
297
|
+
invalidatePostFilterRequests();
|
|
298
|
+
refine();
|
|
299
|
+
clearPostFilterSelections();
|
|
300
|
+
if (clearPostFilter) {
|
|
301
|
+
setPostFilterFacets([]);
|
|
302
|
+
setInitialFindSearchSnapshot(null);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
275
306
|
try {
|
|
276
307
|
res = await find({
|
|
277
308
|
image: requestImage,
|
|
@@ -281,7 +312,7 @@ export const useImageSearch = () => {
|
|
|
281
312
|
: metaFilter
|
|
282
313
|
? [
|
|
283
314
|
{
|
|
284
|
-
key:
|
|
315
|
+
key: preFilterApiKey,
|
|
285
316
|
values: [metaFilter],
|
|
286
317
|
},
|
|
287
318
|
]
|
|
@@ -295,12 +326,14 @@ export const useImageSearch = () => {
|
|
|
295
326
|
: undefined,
|
|
296
327
|
});
|
|
297
328
|
useResultStore.getState().resetGrounding();
|
|
298
|
-
if (clearPostFilter) {
|
|
299
|
-
refine();
|
|
300
|
-
clearPostFilterSelections();
|
|
301
|
-
}
|
|
302
329
|
|
|
303
330
|
setFindApiProducts(res?.results);
|
|
331
|
+
const initialFacets = res?.facets || [];
|
|
332
|
+
setPostFilterFacets(initialFacets);
|
|
333
|
+
setInitialFindSearchSnapshot({
|
|
334
|
+
results: res?.results || [],
|
|
335
|
+
postFilterFacets: initialFacets,
|
|
336
|
+
});
|
|
304
337
|
setImageAnalysis(res?.image_analysis);
|
|
305
338
|
setSessionId(res?.session);
|
|
306
339
|
setRequestId(res?.id);
|
|
@@ -386,6 +419,8 @@ export const useImageSearch = () => {
|
|
|
386
419
|
setFirstSearchPreFilter,
|
|
387
420
|
setFirstRequestImageAnalysis,
|
|
388
421
|
setSmartFilters,
|
|
422
|
+
setPostFilterFacets,
|
|
423
|
+
setInitialFindSearchSnapshot,
|
|
389
424
|
],
|
|
390
425
|
);
|
|
391
426
|
|