@nyris/nyris-webapp 0.3.32 → 0.3.34

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 (84) hide show
  1. package/build/asset-manifest.json +28 -15
  2. package/build/index.html +1 -1
  3. package/build/js/settings.example.js +13 -25
  4. package/build/{precache-manifest.a2c0b5a7cde6667444733c63d9fcb7d5.js → precache-manifest.b85c7807a93875355f9f0f6490e6dc8c.js} +68 -16
  5. package/build/service-worker.js +1 -1
  6. package/build/static/css/main.f2aa67fc.chunk.css +2 -0
  7. package/build/static/css/main.f2aa67fc.chunk.css.map +1 -0
  8. package/build/static/js/2.d1f7e826.chunk.js +3 -0
  9. package/build/static/js/2.d1f7e826.chunk.js.map +1 -0
  10. package/build/static/js/main.e9aec8a9.chunk.js +3 -0
  11. package/build/static/js/main.e9aec8a9.chunk.js.map +1 -0
  12. package/build/static/media/filter.bc412f08.svg +3 -0
  13. package/build/static/media/icon_search_image2.fab34be4.svg +3 -0
  14. package/build/static/media/img-1-1.6144e5f9.png +0 -0
  15. package/build/static/media/img-1-2.ad943f0f.png +0 -0
  16. package/build/static/media/img2-1.a87c79c7.png +0 -0
  17. package/build/static/media/img2-2.39c5b73f.png +0 -0
  18. package/build/static/media/img3-1.443b0c3a.png +0 -0
  19. package/build/static/media/img3-2.37db7999.png +0 -0
  20. package/build/static/media/img4-1.9c34c158.png +0 -0
  21. package/build/static/media/img4-2.9d280a04.png +0 -0
  22. package/build/static/media/img5-1.b61dbd4d.png +0 -0
  23. package/build/static/media/img5-2.1c77c093.png +0 -0
  24. package/build/static/media/img6-1.8b03dd21.png +0 -0
  25. package/build/static/media/img6-2.1e3e7fed.png +0 -0
  26. package/build/static/media/{info-tooltip.5feeef22.svg → info-tooltip.b98e8a9c.svg} +2 -2
  27. package/build/static/media/take_photo.76423216.svg +5 -0
  28. package/package.json +3 -4
  29. package/public/js/settings.example.js +13 -25
  30. package/src/Store/constants.ts +0 -1
  31. package/src/Store/search/Search.ts +32 -17
  32. package/src/Store/search/search.initialState.ts +17 -16
  33. package/src/Store/search/types.ts +15 -14
  34. package/src/common/assets/icons/expand.svg +3 -27
  35. package/src/common/assets/icons/filter.svg +3 -0
  36. package/src/common/assets/icons/icon_search_image2.svg +2 -25
  37. package/src/common/assets/icons/info-tooltip.svg +2 -2
  38. package/src/common/assets/icons/take_photo.svg +5 -0
  39. package/src/common/assets/images/imageCaptureHelp/img-1-1.png +0 -0
  40. package/src/common/assets/images/imageCaptureHelp/img-1-2.png +0 -0
  41. package/src/common/assets/images/imageCaptureHelp/img2-1.png +0 -0
  42. package/src/common/assets/images/imageCaptureHelp/img2-2.png +0 -0
  43. package/src/common/assets/images/imageCaptureHelp/img3-1.png +0 -0
  44. package/src/common/assets/images/imageCaptureHelp/img3-2.png +0 -0
  45. package/src/common/assets/images/imageCaptureHelp/img4-1.png +0 -0
  46. package/src/common/assets/images/imageCaptureHelp/img4-2.png +0 -0
  47. package/src/common/assets/images/imageCaptureHelp/img5-1.png +0 -0
  48. package/src/common/assets/images/imageCaptureHelp/img5-2.png +0 -0
  49. package/src/common/assets/images/imageCaptureHelp/img6-1.png +0 -0
  50. package/src/common/assets/images/imageCaptureHelp/img6-2.png +0 -0
  51. package/src/components/DetailItem.tsx +91 -104
  52. package/src/components/DragDropFile.tsx +46 -66
  53. package/src/components/FooterMobile.tsx +80 -41
  54. package/src/components/HeaderMobile.tsx +225 -227
  55. package/src/components/ImageCaptureHelpModal.tsx +90 -0
  56. package/src/components/Layout.tsx +39 -9
  57. package/src/components/MobilePostFilter.tsx +20 -0
  58. package/src/components/PanelResult/expandable-panel.tsx +21 -21
  59. package/src/components/PanelResult/index.tsx +52 -19
  60. package/src/components/ProductList/index.tsx +14 -7
  61. package/src/components/appMobile.scss +64 -32
  62. package/src/components/carousel/ImagePreviewCarousel.tsx +1 -1
  63. package/src/components/drawer/cameraCustom.tsx +8 -33
  64. package/src/components/input/inputSearch.tsx +116 -147
  65. package/src/components/pre-filter/index.tsx +31 -22
  66. package/src/components/results/ItemResult.tsx +127 -144
  67. package/src/constants.ts +56 -0
  68. package/src/page/landingPage/AppMobile.tsx +34 -104
  69. package/src/page/landingPage/common.scss +164 -36
  70. package/src/page/result/index.tsx +70 -56
  71. package/src/services/Feedback.ts +20 -2
  72. package/src/services/types.ts +0 -1
  73. package/src/translations.ts +4 -0
  74. package/src/types.ts +3 -2
  75. package/build/static/css/main.d0b21fa5.chunk.css +0 -2
  76. package/build/static/css/main.d0b21fa5.chunk.css.map +0 -1
  77. package/build/static/js/2.985a6e2d.chunk.js +0 -3
  78. package/build/static/js/2.985a6e2d.chunk.js.map +0 -1
  79. package/build/static/js/main.1e8d5e32.chunk.js +0 -3
  80. package/build/static/js/main.1e8d5e32.chunk.js.map +0 -1
  81. package/build/static/media/expand.06cebf40.svg +0 -27
  82. package/build/static/media/icon_search_image2.e46fdfc5.svg +0 -26
  83. /package/build/static/js/{2.985a6e2d.chunk.js.LICENSE.txt → 2.d1f7e826.chunk.js.LICENSE.txt} +0 -0
  84. /package/build/static/js/{main.1e8d5e32.chunk.js.LICENSE.txt → main.e9aec8a9.chunk.js.LICENSE.txt} +0 -0
@@ -1,9 +1,8 @@
1
- import { Box, Button, Tooltip, Typography } from '@material-ui/core';
1
+ import { Box, Button, Tooltip } from '@material-ui/core';
2
2
  import IconButton from '@material-ui/core/IconButton';
3
3
  import ClearOutlinedIcon from '@material-ui/icons/ClearOutlined';
4
4
  import CloseIcon from '@material-ui/icons/Close';
5
5
  import IconCamera from 'common/assets/icons/camera.svg';
6
- import IconSearch from 'common/assets/icons/icon_search.svg';
7
6
  import { useQuery } from 'hooks/useQuery';
8
7
  import { debounce, isEmpty } from 'lodash';
9
8
  import React, { memo, useCallback, useEffect, useRef, useState } from 'react';
@@ -13,6 +12,7 @@ import { useMediaQuery } from 'react-responsive';
13
12
  import { useHistory } from 'react-router-dom';
14
13
  import { createImage, findByImage, findRegions } from 'services/image';
15
14
  import { ReactComponent as IconFilter } from 'common/assets/icons/filter_settings.svg';
15
+ import { ReactComponent as IconSearch } from 'common/assets/icons/icon_search.svg';
16
16
 
17
17
  import {
18
18
  reset,
@@ -20,7 +20,6 @@ import {
20
20
  setRequestImage,
21
21
  setSearchResults,
22
22
  updateStatusLoading,
23
- setUpdateKeyFilterDesktop,
24
23
  loadingActionResults,
25
24
  setRegions,
26
25
  setSelectedRegion,
@@ -29,9 +28,7 @@ import { useAppDispatch, useAppSelector } from 'Store/Store';
29
28
  import DefaultModal from 'components/modal/DefaultModal';
30
29
  import PreFilterComponent from 'components/pre-filter';
31
30
  import { RectCoords } from '@nyris/nyris-api';
32
- import { truncateString } from 'helpers/truncateString';
33
31
  import { useTranslation } from 'react-i18next';
34
- import heic2any from 'heic2any';
35
32
 
36
33
  const SearchBox = (props: any) => {
37
34
  const { refine, onToggleFilterMobile }: any = props;
@@ -88,76 +85,58 @@ const SearchBox = (props: any) => {
88
85
  }, 500),
89
86
  [],
90
87
  );
91
- const handleVisualSearch = async (blob: Blob) => {
92
- dispatch(updateStatusLoading(true));
93
- dispatch(loadingActionResults());
94
- if (history.location.pathname !== '/result') {
95
- history.push('/result');
96
- }
97
- let payload: any;
98
- let filters: any[] = [];
99
- let region: RectCoords | undefined;
100
- dispatch(setImageSearchInput(URL.createObjectURL(blob)));
101
- // @ts-ignore
102
- let image = await createImage(blob);
103
- dispatch(setRequestImage(image));
104
- const preFilter = [
105
- {
106
- key: settings.visualSearchFilterKey,
107
- values: [`${keyFilter}`],
108
- },
109
- ];
110
-
111
- if (settings.regions) {
112
- let res = await findRegions(image, settings);
113
- dispatch(setRegions(res.regions));
114
- region = res.selectedRegion;
115
- dispatch(setSelectedRegion(region));
116
- }
117
88
 
118
- return findByImage({
119
- image,
120
- settings,
121
- filters: keyFilter ? preFilter : undefined,
122
- region,
123
- })
124
- .then((res: any) => {
125
- res?.results.map((item: any) => {
126
- filters.push({
127
- sku: item.sku,
128
- score: item.score,
129
- });
130
- });
131
- payload = {
132
- ...res,
133
- filters,
134
- };
135
- dispatch(setSearchResults(payload));
136
- dispatch(updateStatusLoading(false));
137
- })
138
- .catch((e: any) => {
139
- console.log('error input search', e);
140
- dispatch(updateStatusLoading(false));
141
- });
142
- };
143
89
  const { getInputProps } = useDropzone({
144
90
  onDrop: async (fs: File[]) => {
145
- var file = fs[0];
146
- if (file.type === 'image/heic') {
147
- heic2any({
148
- blob: file as Blob,
149
- toType: 'image/png',
150
- quality: 1.0,
151
- })
152
- .then(function (resultBlob) {
153
- handleVisualSearch(resultBlob as Blob);
154
- })
155
- .catch(function (error) {
156
- console.error('Error converting HEIC to PNG:', error);
157
- });
158
- } else {
159
- handleVisualSearch(fs[0]);
91
+ dispatch(updateStatusLoading(true));
92
+ dispatch(loadingActionResults());
93
+ if (history.location.pathname !== '/result') {
94
+ history.push('/result');
160
95
  }
96
+ let payload: any;
97
+ let filters: any[] = [];
98
+ let region: RectCoords | undefined;
99
+ dispatch(setImageSearchInput(URL.createObjectURL(fs[0])));
100
+ let image = await createImage(fs[0]);
101
+ dispatch(setRequestImage(image));
102
+ const preFilter = [
103
+ {
104
+ key: settings.visualSearchFilterKey,
105
+ values: [`${keyFilter}`],
106
+ },
107
+ ];
108
+
109
+ if (settings.regions) {
110
+ let res = await findRegions(image, settings);
111
+ dispatch(setRegions(res.regions));
112
+ region = res.selectedRegion;
113
+ dispatch(setSelectedRegion(region));
114
+ }
115
+
116
+ return findByImage({
117
+ image,
118
+ settings,
119
+ filters: keyFilter ? preFilter : undefined,
120
+ region,
121
+ })
122
+ .then((res: any) => {
123
+ res?.results.map((item: any) => {
124
+ filters.push({
125
+ sku: item.sku,
126
+ score: item.score,
127
+ });
128
+ });
129
+ payload = {
130
+ ...res,
131
+ filters,
132
+ };
133
+ dispatch(setSearchResults(payload));
134
+ dispatch(updateStatusLoading(false));
135
+ })
136
+ .catch((e: any) => {
137
+ console.log('error input search', e);
138
+ dispatch(updateStatusLoading(false));
139
+ });
161
140
  },
162
141
  });
163
142
 
@@ -172,16 +151,75 @@ const SearchBox = (props: any) => {
172
151
  };
173
152
 
174
153
  return (
175
- <Box className="wrap-input-search">
176
- <div style={{ padding: 10 }} className="box-input-search d-flex">
154
+ <div className="wrap-input-search-field">
155
+ <div className="box-input-search d-flex">
177
156
  <form noValidate action="" role="search">
178
157
  <Box className="box-inp">
158
+ <Tooltip
159
+ title={keyFilter ? keyFilter : 'Add pre-filter'}
160
+ placement="top"
161
+ arrow={true}
162
+ disableHoverListener={!settings.preFilterOption}
163
+ >
164
+ <Box
165
+ className="pre-filter-icon"
166
+ style={{
167
+ cursor: settings.preFilterOption ? 'pointer' : 'default',
168
+ }}
169
+ onClick={() =>
170
+ settings.preFilterOption
171
+ ? setToggleModalFilterDesktop(true)
172
+ : false
173
+ }
174
+ >
175
+ {settings.preFilterOption && (
176
+ <div
177
+ className="icon-hover"
178
+ style={{
179
+ ...(keyFilter
180
+ ? {
181
+ backgroundColor: `${settings.theme?.secondaryColor}26`,
182
+ }
183
+ : {}),
184
+ }}
185
+ >
186
+ <IconFilter color="black" />
187
+ </div>
188
+ )}
189
+ {!settings.preFilterOption && (
190
+ <IconSearch width={16} height={16} />
191
+ )}
192
+ {keyFilter && (
193
+ <div
194
+ style={{
195
+ position: 'absolute',
196
+ top: '6px',
197
+ left: '31px',
198
+ display: 'flex',
199
+ justifyContent: 'center',
200
+ alignItems: 'center',
201
+ background: 'white',
202
+ width: '10px',
203
+ height: '10px',
204
+ borderRadius: '100%',
205
+ }}
206
+ >
207
+ <div
208
+ style={{
209
+ width: '8px',
210
+ height: '8px',
211
+ background: settings.theme?.secondaryColor,
212
+ borderRadius: '100%',
213
+ }}
214
+ ></div>
215
+ </div>
216
+ )}
217
+ </Box>
218
+ </Tooltip>
179
219
  <Box
180
220
  style={{
181
221
  height: '75%',
182
222
  order: 1,
183
- paddingLeft: imageThumbSearchInput || keyFilter ? 0 : 10,
184
- marginLeft: keyFilter ? 0 : 5,
185
223
  }}
186
224
  >
187
225
  {imageThumbSearchInput && (
@@ -227,60 +265,12 @@ const SearchBox = (props: any) => {
227
265
  )}
228
266
  </Box>
229
267
 
230
- {!valueInput && (
231
- <Box
232
- className="icon-search"
233
- style={
234
- imageThumbSearchInput
235
- ? { order: 2, marginLeft: 5 }
236
- : { order: 2 }
237
- }
238
- >
239
- <img src={IconSearch} alt="" width={24} height={24} />
240
- </Box>
241
- )}
242
-
243
- {keyFilter && !isMobile && (
244
- <Box
245
- className="box-key-filter"
246
- style={{
247
- order: 0,
248
- marginRight: 5,
249
- border: `2px solid ${settings.theme?.secondaryColor}c7`,
250
- }}
251
- >
252
- <Tooltip
253
- title={keyFilter}
254
- placement="top"
255
- arrow={true}
256
- disableHoverListener={keyFilter.length < 16}
257
- >
258
- <Typography>{truncateString(keyFilter, 15)}</Typography>
259
- </Tooltip>
260
-
261
- <Tooltip title="Remove pre-filter" placement="top" arrow={true}>
262
- <Button
263
- onClick={() => dispatch(setUpdateKeyFilterDesktop(''))}
264
- style={{ padding: '6px 2px' }}
265
- >
266
- <CloseIcon
267
- style={{
268
- fontSize: 20,
269
- color: settings.theme?.secondaryColor,
270
- }}
271
- />
272
- </Button>
273
- </Tooltip>
274
- </Box>
275
- )}
276
-
277
268
  <input
278
269
  style={{
279
270
  border: '0px',
280
271
  width: '100%',
281
272
  fontSize: 14,
282
273
  color: '#2B2C46',
283
- fontStyle: 'italic',
284
274
  }}
285
275
  className="input-search"
286
276
  placeholder={t('Search')}
@@ -316,26 +306,6 @@ const SearchBox = (props: any) => {
316
306
  )}
317
307
  {!isMobile ? (
318
308
  <div className="wrap-box-input-mobile d-flex">
319
- {settings.preFilterOption && (
320
- <Tooltip
321
- title="Add or change pre-filter"
322
- placement="top"
323
- arrow={true}
324
- style={{ backgroundColor: '#000000' }}
325
- >
326
- <Button
327
- onClick={() => setToggleModalFilterDesktop(true)}
328
- style={{
329
- width: 32,
330
- height: 32,
331
- borderRadius: '100%',
332
- marginRight: 10,
333
- }}
334
- >
335
- <IconFilter />
336
- </Button>
337
- </Tooltip>
338
- )}
339
309
  <input
340
310
  accept="image/*"
341
311
  id="icon-button-file"
@@ -381,20 +351,19 @@ const SearchBox = (props: any) => {
381
351
  )}
382
352
  </form>
383
353
  </div>
384
-
385
354
  {settings.preFilterOption && (
386
355
  <DefaultModal
387
356
  openModal={isOpenModalFilterDesktop}
388
357
  handleClose={() => setToggleModalFilterDesktop(false)}
389
- classNameModal="wrap-filter-destop"
390
- classNameComponentChild="bg-white box-filter-destop"
358
+ classNameModal="wrap-filter-desktop"
359
+ classNameComponentChild="bg-white box-filter-desktop"
391
360
  >
392
361
  <PreFilterComponent
393
362
  handleClose={() => setToggleModalFilterDesktop(false)}
394
363
  />
395
364
  </DefaultModal>
396
365
  )}
397
- </Box>
366
+ </div>
398
367
  );
399
368
  };
400
369
 
@@ -109,22 +109,37 @@ function PreFilterComponent(props: Props) {
109
109
  flexDirection={'column'}
110
110
  style={{ position: 'relative' }}
111
111
  >
112
- <Typography
112
+ <div
113
113
  style={{
114
- color: '#000',
115
- fontSize: '24px',
116
- fontWeight: 700,
117
- paddingLeft: isMobile ? '0px' : '14px',
118
- marginBottom: isMobile ? '0px' : '-8px',
119
- marginTop: isMobile ? '0px' : '24px',
114
+ background: 'white',
115
+ width: '100%',
116
+ display: 'flex',
117
+ justifyContent: 'space-between',
118
+ position: 'sticky',
119
+ top: 0,
120
+ zIndex: 100,
120
121
  }}
121
122
  >
122
- {settings.preFilterTitle}
123
- </Typography>
123
+ <Typography
124
+ style={{
125
+ color: '#000',
126
+ fontSize: '24px',
127
+ fontWeight: 700,
128
+ paddingLeft: isMobile ? '0px' : '14px',
129
+ marginBottom: isMobile ? '0px' : '-8px',
130
+ marginTop: isMobile ? '0px' : '24px',
131
+ }}
132
+ >
133
+ {settings.preFilterTitle}
134
+ </Typography>
124
135
 
136
+ <Button onClick={handleClose}>
137
+ <CloseIcon />
138
+ </Button>
139
+ </div>
125
140
  <Box
126
141
  className="box-top"
127
- style={isMobile ? { padding: 0 } : undefined}
142
+ style={isMobile ? { padding: 0, marginTop: '16px' } : undefined}
128
143
  display={'flex'}
129
144
  justifyContent={'space-between'}
130
145
  alignItems={'center'}
@@ -172,16 +187,10 @@ function PreFilterComponent(props: Props) {
172
187
  }}
173
188
  />
174
189
  </Box>
175
-
176
- {!isMobile && (
177
- <Button onClick={handleClose}>
178
- <CloseIcon />
179
- </Button>
180
- )}
181
190
  </Box>
182
191
 
183
- <Box style={{ margin: '10px 16px' }}>
184
- {keyFilter && isMobile && (
192
+ {keyFilter && isMobile && (
193
+ <Box style={{ margin: '10px 16px' }}>
185
194
  <Box
186
195
  display={'flex'}
187
196
  className="box-keyFilter"
@@ -192,8 +201,8 @@ function PreFilterComponent(props: Props) {
192
201
  <CloseIcon style={{ fontSize: 12, color: '#2B2C46' }} />
193
202
  </Button>
194
203
  </Box>
195
- )}
196
- </Box>
204
+ </Box>
205
+ )}
197
206
  <Box
198
207
  className="box-bottom"
199
208
  height={'100%'}
@@ -274,7 +283,7 @@ function PreFilterComponent(props: Props) {
274
283
  <Typography>No result found</Typography>
275
284
  )}
276
285
  </Box>
277
- {keyFilter && !isMobile && (
286
+ {!isMobile && (
278
287
  <Box
279
288
  className="footer"
280
289
  style={{ height: 64, marginTop: 'auto' }}
@@ -308,7 +317,7 @@ function PreFilterComponent(props: Props) {
308
317
  </Button>
309
318
  </Box>
310
319
  )}
311
- {keyFilter && isMobile && (
320
+ {isMobile && (
312
321
  <Box
313
322
  className="footer"
314
323
  style={{