@nyris/nyris-webapp 0.3.6 → 0.3.13

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 +11 -11
  2. package/build/index.html +1 -1
  3. package/build/{precache-manifest.bffed513ca17d8ac16af1cc3aaa7d908.js → precache-manifest.793f0a4375602ec8cd0fba83bf0e3e67.js} +9 -9
  4. package/build/service-worker.js +1 -1
  5. package/build/static/css/main.0c9239ba.chunk.css +2 -0
  6. package/build/static/css/main.0c9239ba.chunk.css.map +1 -0
  7. package/build/static/js/2.520bb6d6.chunk.js +3 -0
  8. package/build/static/js/{2.4e9a4ce1.chunk.js.LICENSE.txt → 2.520bb6d6.chunk.js.LICENSE.txt} +0 -0
  9. package/build/static/js/2.520bb6d6.chunk.js.map +1 -0
  10. package/build/static/js/main.8405239a.chunk.js +2 -0
  11. package/build/static/js/main.8405239a.chunk.js.map +1 -0
  12. package/package.json +2 -2
  13. package/src/App.tsx +346 -213
  14. package/src/actions/nyrisAppActions.ts +69 -65
  15. package/src/actions/searchActions.ts +301 -196
  16. package/src/components/CategoryFilter.tsx +16 -13
  17. package/src/components/Codes.tsx +20 -16
  18. package/src/components/ExampleImages.tsx +27 -17
  19. package/src/components/Feedback.tsx +78 -48
  20. package/src/components/FiltersList.tsx +106 -59
  21. package/src/components/Header.tsx +29 -17
  22. package/src/components/PredictedCategories.tsx +15 -12
  23. package/src/components/Result.tsx +186 -113
  24. package/src/components/SelectedFiltersSummary.tsx +84 -0
  25. package/src/components/Sidebar.tsx +41 -32
  26. package/src/epics/index.ts +173 -104
  27. package/src/epics/search.ts +209 -177
  28. package/src/index.css +98 -9
  29. package/src/index.tsx +148 -144
  30. package/src/utils.ts +5 -0
  31. package/build/static/css/main.2a76dc8a.chunk.css +0 -2
  32. package/build/static/css/main.2a76dc8a.chunk.css.map +0 -1
  33. package/build/static/js/2.4e9a4ce1.chunk.js +0 -3
  34. package/build/static/js/2.4e9a4ce1.chunk.js.map +0 -1
  35. package/build/static/js/main.ec93aa4d.chunk.js +0 -2
  36. package/build/static/js/main.ec93aa4d.chunk.js.map +0 -1
  37. package/src/Demo2.tsx +0 -220
@@ -1,137 +1,210 @@
1
- import React from 'react';
2
- import {OfferNyrisResult as ResultData} from "@nyris/nyris-api";
1
+ import React from "react";
2
+ import { OfferNyrisResult as ResultData } from "@nyris/nyris-api";
3
3
 
4
4
  // TODO this needs refactoring: Make it one block with parameters for first line, second line, image url ..
5
5
 
6
6
  interface Options {
7
- result: any,
8
- noImageUrl: string,
9
- onImageClick: (e: React.MouseEvent) => void,
10
- onLinkClick: (e: React.MouseEvent) => void
7
+ result: any;
8
+ noImageUrl: string;
9
+ onImageClick: (e: React.MouseEvent) => void;
10
+ onLinkClick: (e: React.MouseEvent) => void;
11
11
  }
12
12
 
13
13
  const renderPrice = (result: ResultData) =>
14
- result.p ? '' + (result.p.vi / 100).toFixed(2) + ' ' + result.p.c : '';
14
+ result.p ? "" + (result.p.vi / 100).toFixed(2) + " " + result.p.c : "";
15
15
 
16
- const renderDefault = ({result, noImageUrl, onImageClick, onLinkClick}: Options) => {
17
- return (
18
- <>
19
- <a href={result.l} className="imageLink" title="Click the image so see similar products"
20
- onClick={onImageClick}
21
- onAuxClick={onLinkClick}>
22
- <div className="prdctImg">
23
- <div className="imgWrap">
24
- <img src={(result.img && result.img.url + '?r=512x512') || noImageUrl} alt={result.title}/>
25
- </div>
26
- </div>
27
- </a>
28
- <div className="prdctDetailsWrap">
29
- <div>
30
- <div className="prdctTitle">{result.title}</div>
31
- <div className="prdctMeta">
32
- <span className="prdctPrice">{renderPrice(result)}</span>
33
- </div>
34
- <a onClick={onLinkClick} onAuxClick={onLinkClick} className="prdctShopLink" href={result.l}
35
- target="_blank" rel="noopener noreferrer">Buy Now</a>
36
- </div>
37
- </div>
38
- </>
39
- );
40
- };
41
-
42
- const renderSnr = ({result, noImageUrl, onImageClick, onLinkClick}: Options) => (
16
+ const renderDefault = ({
17
+ result,
18
+ noImageUrl,
19
+ onImageClick,
20
+ onLinkClick,
21
+ }: Options) => {
22
+ return (
43
23
  <>
44
- <a href={result.l} className="imageLink" onClick={onImageClick} onAuxClick={onLinkClick}>
45
- <div className="prdctImg">
46
- <div className="imgWrap">
47
- <img src={(result.img && result.img.url + '?r=512x512') || noImageUrl} alt={result.title}/>
48
- </div>
49
- </div>
50
- </a>
51
- <div className="prdctDetailsWrap">
52
- <div>
53
- <div className="prdctTitle">{result.sku}</div>
54
- <div className="prdctMeta" style={{height: '5em', whiteSpace: 'normal'}}>
55
- {result.title}
56
- </div>
57
- <a style={{backgroundImage: 'none', paddingLeft: '10px'}} className="prdctShopLink" href={result.l}
58
- target="_blank" rel="noopener noreferrer"
59
- onClick={onLinkClick} onAuxClick={onLinkClick}>Info</a>
60
- </div>
24
+ <a
25
+ href={result.l}
26
+ className="imageLink"
27
+ title="Click the image so see similar products"
28
+ onClick={onImageClick}
29
+ onAuxClick={onLinkClick}
30
+ >
31
+ <div className="prdctImg">
32
+ <div className="imgWrap">
33
+ <img
34
+ src={(result.img && result.img.url + "?r=512x512") || noImageUrl}
35
+ alt={result.title}
36
+ />
37
+ </div>
38
+ </div>
39
+ </a>
40
+ <div className="prdctDetailsWrap">
41
+ <div>
42
+ <div className="prdctTitle">{result.title}</div>
43
+ <div className="prdctMeta">
44
+ <span className="prdctPrice">{renderPrice(result)}</span>
45
+ </div>
46
+ <a
47
+ onClick={onLinkClick}
48
+ onAuxClick={onLinkClick}
49
+ className="prdctShopLink"
50
+ href={result.l}
51
+ target="_blank"
52
+ rel="noopener noreferrer"
53
+ >
54
+ Buy Now
55
+ </a>
61
56
  </div>
57
+ </div>
62
58
  </>
63
- );
59
+ );
60
+ };
64
61
 
65
- const renderSnrMultilink = ({result, noImageUrl, onImageClick}: Options, onLinkClick: (url: string) => void) => (
66
- <>
67
- <a href={result.l} className="imageLink"
68
- onClick={onImageClick} onAuxClick={onImageClick}>
69
- <div className="prdctImg">
70
- <div className="imgWrap">
71
- <img src={(result.img && result.img.url + '?r=512x512') || noImageUrl} alt={result.title}/>
72
- </div>
73
- </div>
62
+ const renderSnr = ({
63
+ result,
64
+ noImageUrl,
65
+ onImageClick,
66
+ onLinkClick,
67
+ }: Options) => (
68
+ <>
69
+ <a
70
+ href={result.l}
71
+ className="imageLink"
72
+ onClick={onImageClick}
73
+ onAuxClick={onLinkClick}
74
+ >
75
+ <div className="prdctImg">
76
+ <div className="imgWrap">
77
+ <img
78
+ src={(result.img && result.img.url + "?r=512x512") || noImageUrl}
79
+ alt={result.title}
80
+ />
81
+ </div>
82
+ </div>
83
+ </a>
84
+ <div className="prdctDetailsWrap">
85
+ <div>
86
+ <div className="prdctTitle">{result.sku}</div>
87
+ <div
88
+ className="prdctMeta"
89
+ style={{ height: "5em", whiteSpace: "normal" }}
90
+ >
91
+ {result.title}
92
+ </div>
93
+ <a
94
+ style={{ backgroundImage: "none", paddingLeft: "10px" }}
95
+ className="prdctShopLink"
96
+ href={result.l}
97
+ target="_blank"
98
+ rel="noopener noreferrer"
99
+ onClick={onLinkClick}
100
+ onAuxClick={onLinkClick}
101
+ >
102
+ Info
74
103
  </a>
75
- <div className="prdctDetailsWrap">
76
- <div>
77
- <div className="prdctTitle">{result.sku}</div>
78
- <div className="prdctMeta" style={{height: '5em', whiteSpace: 'normal'}}>
79
- {result.title}
80
- </div>
81
- {result.l.map((l: { text: string, href: string }) =>
82
- <a style={{backgroundImage: 'none', paddingLeft: '10px'}} className="prdctShopLink" href={l.href}
83
- onClick={() => onLinkClick(l.href)} onAuxClick={() => onLinkClick(l.href)} target="_blank"
84
- key={l.href}
85
- rel="noopener noreferrer">{l.text}</a>
86
- )}
87
- </div>
104
+ </div>
105
+ </div>
106
+ </>
107
+ );
108
+
109
+ const renderSnrMultilink = (
110
+ { result, noImageUrl, onImageClick }: Options,
111
+ onLinkClick: (url: string) => void
112
+ ) => (
113
+ <>
114
+ <a
115
+ href={result.l}
116
+ className="imageLink"
117
+ onClick={onImageClick}
118
+ onAuxClick={onImageClick}
119
+ >
120
+ <div className="prdctImg">
121
+ <div className="imgWrap">
122
+ <img
123
+ src={(result.img && result.img.url + "?r=512x512") || noImageUrl}
124
+ alt={result.title}
125
+ />
88
126
  </div>
89
- </>
127
+ </div>
128
+ </a>
129
+ <div className="prdctDetailsWrap">
130
+ <div>
131
+ <div className="prdctTitle">{result.sku}</div>
132
+ <div
133
+ className="prdctMeta"
134
+ style={{ height: "5em", whiteSpace: "normal" }}
135
+ >
136
+ {result.title}
137
+ </div>
138
+ {result.l.map((l: { text: string; href: string }) => (
139
+ <a
140
+ style={{ backgroundImage: "none", paddingLeft: "10px" }}
141
+ className="prdctShopLink"
142
+ href={l.href}
143
+ onClick={() => onLinkClick(l.href)}
144
+ onAuxClick={() => onLinkClick(l.href)}
145
+ target="_blank"
146
+ key={l.href}
147
+ rel="noopener noreferrer"
148
+ >
149
+ {l.text}
150
+ </a>
151
+ ))}
152
+ </div>
153
+ </div>
154
+ </>
90
155
  );
91
156
 
92
157
  export interface ResultProps {
93
- result: any,
94
- style: any,
95
- template?: string,
96
- onImageClick: (pos: number, url: string) => void,
97
- onLinkClick: (pos: number, url: string) => void,
98
- noImageUrl?: string
158
+ result: any;
159
+ style: any;
160
+ template?: string;
161
+ onImageClick: (pos: number, url: string) => void;
162
+ onLinkClick: (pos: number, url: string) => void;
163
+ noImageUrl?: string;
99
164
  }
100
165
 
101
- const Result: React.FC<ResultProps> = ({result, style, template, onImageClick, onLinkClick, noImageUrl}) => {
102
- let options: Options = {
103
- onImageClick: (e: React.MouseEvent) => {
104
- e.preventDefault();
105
- onImageClick(result.position, result.img.url);
106
- },
107
- onLinkClick: (e: React.MouseEvent) => {
108
- e.preventDefault();
109
- onLinkClick(result.position, result.l);
110
- },
111
- noImageUrl: noImageUrl || 'images/ic_cam_large_noimage.png',
112
- result
113
- };
166
+ const Result: React.FC<ResultProps> = ({
167
+ result,
168
+ style,
169
+ template,
170
+ onImageClick,
171
+ onLinkClick,
172
+ noImageUrl,
173
+ }) => {
174
+ let options: Options = {
175
+ onImageClick: (e: React.MouseEvent) => {
176
+ e.preventDefault();
177
+ onImageClick(result.position, result.img.url);
178
+ },
179
+ onLinkClick: (e: React.MouseEvent) => {
180
+ e.preventDefault();
181
+ onLinkClick(result.position, result.l);
182
+ },
183
+ noImageUrl: noImageUrl || "images/ic_cam_large_noimage.png",
184
+ result,
185
+ };
114
186
 
115
- let resultInner = null;
116
- switch (template) {
117
- case "snr":
118
- resultInner = renderSnr(options);
119
- break;
120
- case "snr-multilink":
121
- resultInner = renderSnrMultilink(options, (url) => onLinkClick(result.position, url));
122
- break;
123
- case 'default':
124
- default:
125
- resultInner = renderDefault(options);
126
- break;
127
- }
187
+ let resultInner = null;
188
+ switch (template) {
189
+ case "snr":
190
+ resultInner = renderSnr(options);
191
+ break;
192
+ case "snr-multilink":
193
+ resultInner = renderSnrMultilink(options, (url) =>
194
+ onLinkClick(result.position, url)
195
+ );
196
+ break;
197
+ case "default":
198
+ default:
199
+ resultInner = renderDefault(options);
200
+ break;
201
+ }
128
202
 
129
- return (
130
- <div className="prdctItem" style={{...style}}>
131
- {resultInner}
132
- </div>
133
- );
203
+ return (
204
+ <div className="prdctItem" style={{ ...style }}>
205
+ {resultInner}
206
+ </div>
207
+ );
134
208
  };
135
209
 
136
-
137
210
  export default Result;
@@ -0,0 +1,84 @@
1
+ import React from "react";
2
+ import { BsX } from "react-icons/bs";
3
+ import { connect, ConnectedProps, useDispatch } from "react-redux";
4
+ import { AppState } from "../types";
5
+ import { capitalizeFirstLetter } from "../utils";
6
+ import {
7
+ removeFromSelectedFilters,
8
+ clearAllSelectedFilters,
9
+ filterChanged,
10
+ } from "../actions/searchActions";
11
+
12
+ const SelectedFiltersSummary: React.FC<selectedFiltersSummaryProps> = ({
13
+ search,
14
+ }) => {
15
+ const dispatch = useDispatch();
16
+ const handleRemoveFilterButtonClick = (key: string, value: string) => {
17
+ dispatch(removeFromSelectedFilters(key, value));
18
+ dispatch(filterChanged());
19
+ };
20
+
21
+ const clearAllSelectedFiltersFromList = () => {
22
+ dispatch(clearAllSelectedFilters());
23
+ dispatch(filterChanged());
24
+ };
25
+ const selectedValues = ([] as string[]).concat.apply(
26
+ [],
27
+ Array.from(search.selectedFilters.values())
28
+ );
29
+
30
+ return (
31
+ <div className="wrap-box-refinements">
32
+ <ul>
33
+ {Array.from(search.selectedFilters.keys()).map(
34
+ (filterKey) =>
35
+ search.selectedFilters.get(filterKey) &&
36
+ search.selectedFilters.get(filterKey)!.map((val) => {
37
+ return (
38
+ <li>
39
+ <button
40
+ onClick={() =>
41
+ handleRemoveFilterButtonClick(filterKey, val)
42
+ }
43
+ >
44
+ <span className="summary-label">
45
+ <div className="summary-label-key-text">
46
+ {capitalizeFirstLetter(val)}
47
+ <BsX />
48
+ </div>
49
+ </span>
50
+ </button>
51
+ </li>
52
+ );
53
+ })
54
+ )}
55
+ <li>
56
+ <button
57
+ className={
58
+ search.selectedFilters &&
59
+ search.selectedFilters.size > 0 &&
60
+ selectedValues &&
61
+ selectedValues.length > 0
62
+ ? "clear-all-filters "
63
+ : "clear-all-filters-hidden"
64
+ }
65
+ onClick={() => clearAllSelectedFiltersFromList()}
66
+ >
67
+ Clear All
68
+ </button>
69
+ </li>
70
+ </ul>
71
+ </div>
72
+ );
73
+ };
74
+
75
+ const mapStateToProps = (state: AppState) => ({
76
+ showPart: state.nyrisDesign.showPart,
77
+ search: {
78
+ filters: state.search.filters,
79
+ selectedFilters: state.search.selectedFilters,
80
+ },
81
+ });
82
+ const connector = connect(mapStateToProps);
83
+ type selectedFiltersSummaryProps = ConnectedProps<typeof connector>;
84
+ export default connect(mapStateToProps)(SelectedFiltersSummary);
@@ -1,40 +1,49 @@
1
- import React, { useState } from 'react';
2
- import {RiMenuLine} from 'react-icons/ri';
3
- import { Filter } from '../../../nyris-api/index';
4
- import FiltersList from './FiltersList';
1
+ import React, { useState } from "react";
2
+ import { RiMenuLine } from "react-icons/ri";
3
+ import { Filter } from "../../../nyris-api/index";
4
+ import FiltersList from "./FiltersList";
5
5
 
6
6
  interface SidebarProps {
7
- filters: Filter[]
7
+ filters: Filter[];
8
+ selectedFilters: Map<string, string[]>;
8
9
  }
9
10
 
10
- const Sidebar: React.FC<SidebarProps> = ({filters}) =>{
11
+ const Sidebar: React.FC<SidebarProps> = ({ filters, selectedFilters }) => {
12
+ console.log(filters);
11
13
  const [isExpanded, setIsExpanded] = useState(false);
12
- const handleToggler =()=>{
13
- if(isExpanded){
14
- setIsExpanded(false);
15
- return;
16
- }
17
- setIsExpanded(true);
18
- }
14
+ const handleToggler = () => {
15
+ if (isExpanded) {
16
+ setIsExpanded(false);
17
+ return;
18
+ }
19
+ setIsExpanded(true);
20
+ };
19
21
  return (
20
-
21
- <div className={isExpanded ? "sidebar" : "Sidebar collapsed"}>
22
- <div className="sidebarContent" >
23
- <div className="sidebarHeader">
24
- <RiMenuLine className="sidebar-icon" onClick={handleToggler}/>
25
- <h1 className={isExpanded ? "sidebar-logo" : "sidebar-logo collapsedHide"}> Select Filters </h1>
26
- </div>
27
- <div className={isExpanded ? "Sidebar-items" : "Sidebar-items collapsedHide"}>
28
- {filters && filters.map((x) => {
29
- return <FiltersList filter={x}/>
30
- })
31
- }
32
- </div>
33
- </div>
22
+ <div className={isExpanded ? "sidebar" : "Sidebar collapsed"}>
23
+ <div
24
+ className={
25
+ isExpanded ? "sidebarContent" : "sidebarContent overflowHidden"
26
+ }
27
+ >
28
+ <div className="sidebarHeader">
29
+ <RiMenuLine className="sidebar-icon" onClick={handleToggler} />
30
+ </div>
31
+ <div
32
+ className={
33
+ isExpanded ? "Sidebar-items" : "Sidebar-items collapsedHide"
34
+ }
35
+ >
36
+ {filters &&
37
+ filters.map((x) => {
38
+ let selectedValues = x.key
39
+ ? selectedFilters.get(x.key)
40
+ : undefined;
41
+ return <FiltersList filter={x} selectedValues={selectedValues} />;
42
+ })}
43
+ </div>
34
44
  </div>
35
-
36
-
37
- )
38
- }
45
+ </div>
46
+ );
47
+ };
39
48
 
40
- export default Sidebar
49
+ export default Sidebar;