@nyris/nyris-webapp 0.3.13 → 0.3.14
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 +11 -11
- package/build/index.html +1 -1
- package/build/js/settings.example.js +30 -0
- package/build/{precache-manifest.793f0a4375602ec8cd0fba83bf0e3e67.js → precache-manifest.fa9930c6ba4e9fb0ebad3869127ef308.js} +9 -9
- package/build/service-worker.js +1 -1
- package/build/static/css/{main.0c9239ba.chunk.css → main.6633770c.chunk.css} +2 -2
- package/build/static/css/main.6633770c.chunk.css.map +1 -0
- package/build/static/js/{2.520bb6d6.chunk.js → 2.0798bb8b.chunk.js} +3 -3
- package/build/static/js/{2.520bb6d6.chunk.js.LICENSE.txt → 2.0798bb8b.chunk.js.LICENSE.txt} +0 -0
- package/build/static/js/2.0798bb8b.chunk.js.map +1 -0
- package/build/static/js/main.31212715.chunk.js +2 -0
- package/build/static/js/main.31212715.chunk.js.map +1 -0
- package/package.json +2 -2
- package/public/js/settings.example.js +30 -0
- package/src/App.tsx +141 -268
- package/src/actions/searchActions.ts +5 -19
- package/src/components/CategoryFilter.tsx +13 -16
- package/src/components/Codes.tsx +16 -20
- package/src/components/ExampleImages.tsx +17 -27
- package/src/components/Feedback.tsx +48 -78
- package/src/components/PredictedCategories.tsx +12 -15
- package/src/components/Result.tsx +113 -186
- package/src/epics/index.ts +94 -143
- package/src/epics/search.ts +75 -114
- package/src/index.tsx +55 -63
- package/build/static/css/main.0c9239ba.chunk.css.map +0 -1
- package/build/static/js/2.520bb6d6.chunk.js.map +0 -1
- package/build/static/js/main.8405239a.chunk.js +0 -2
- package/build/static/js/main.8405239a.chunk.js.map +0 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var settings = {
|
|
2
|
+
"apiKey": "xxx",
|
|
3
|
+
"maxWidth": 500,
|
|
4
|
+
"maxHeight": 500,
|
|
5
|
+
"jpegQuality": 0.9,
|
|
6
|
+
"regions": true,
|
|
7
|
+
"preview": true,
|
|
8
|
+
"baseUrl": "https://api.nyris.io",
|
|
9
|
+
"xOptions": "",
|
|
10
|
+
"exampleImages": [
|
|
11
|
+
"https://img.nyris.io/demo/everybag/kissen.jpg",
|
|
12
|
+
"https://img.nyris.io/demo/everybag/aspirin.jpg",
|
|
13
|
+
"https://img.nyris.io/demo/everybag/lego.jpg",
|
|
14
|
+
"https://img.nyris.io/demo/everybag/wdr_add_2.jpg",
|
|
15
|
+
"https://img.nyris.io/demo/everybag/mb-dle-4.jpg",
|
|
16
|
+
"https://img.nyris.io/demo/everybag/1.jpg",
|
|
17
|
+
"https://img.nyris.io/demo/everybag/5.jpg",
|
|
18
|
+
"https://img.nyris.io/demo/everybag/6.jpg"
|
|
19
|
+
],
|
|
20
|
+
"instantRedirectPatterns": [
|
|
21
|
+
'^https?://(www.)?youtube.com/',
|
|
22
|
+
'^https?://(www.)?youtu.be/',
|
|
23
|
+
'^https?://(www.)?vimeo.com/',
|
|
24
|
+
'^https?://(www.)?dailymotion.com/',
|
|
25
|
+
'^https?://(www.)?dai.ly/'
|
|
26
|
+
]
|
|
27
|
+
};
|
|
28
|
+
settings["customSearchRequest"] = null;
|
|
29
|
+
settings["responseHook"] = null;
|
|
30
|
+
|
package/src/App.tsx
CHANGED
|
@@ -1,51 +1,44 @@
|
|
|
1
|
-
import
|
|
1
|
+
import './App.css';
|
|
2
|
+
import React, {useEffect, useState} from 'react';
|
|
3
|
+
import Result from './components/Result';
|
|
4
|
+
import ExampleImages from './components/ExampleImages';
|
|
5
|
+
import Feedback from './components/Feedback';
|
|
6
|
+
import CategoryFilter from "./components/CategoryFilter";
|
|
7
|
+
import PredictedCategories from "./components/PredictedCategories";
|
|
8
|
+
import Codes from "./components/Codes";
|
|
9
|
+
import {Code, CategoryPrediction, RectCoords, Region, cadExtensions, Filter} from "@nyris/nyris-api";
|
|
10
|
+
import { useDropzone} from "react-dropzone";
|
|
11
|
+
import classNames from 'classnames';
|
|
12
|
+
import {Animate, NodeGroup} from "react-move";
|
|
13
|
+
import {AppSettings, MDSettings, CanvasWithId} from "./types";
|
|
14
|
+
import {NyrisAppPart, NyrisFeedbackState} from "./actions/nyrisAppActions";
|
|
15
|
+
import {makeFileHandler, Capture, Preview} from "@nyris/nyris-react-components";
|
|
16
|
+
import {Box,Snackbar} from "@material-ui/core";
|
|
17
|
+
import MuiAlert, { AlertProps } from '@material-ui/lab/Alert';
|
|
2
18
|
import { useDispatch } from "react-redux";
|
|
3
|
-
import { Animate, NodeGroup } from "react-move";
|
|
4
|
-
import { useDropzone } from "react-dropzone";
|
|
5
|
-
import { Box, Snackbar } from "@material-ui/core";
|
|
6
|
-
import { Alert } from "@material-ui/lab";
|
|
7
|
-
import classNames from "classnames";
|
|
8
19
|
import { loadFilters } from "./actions/searchActions";
|
|
9
|
-
import Result from "./components/Result";
|
|
10
20
|
import Sidebar from "./components/Sidebar";
|
|
11
21
|
import Header from "./components/Header";
|
|
12
|
-
import Feedback from "./components/Feedback";
|
|
13
|
-
import CategoryFilter from "./components/CategoryFilter";
|
|
14
|
-
import Codes from "./components/Codes";
|
|
15
|
-
import PredictedCategories from "./components/PredictedCategories";
|
|
16
|
-
import ExampleImages from "./components/ExampleImages";
|
|
17
|
-
import {
|
|
18
|
-
makeFileHandler,
|
|
19
|
-
Capture,
|
|
20
|
-
Preview,
|
|
21
|
-
} from "@nyris/nyris-react-components";
|
|
22
|
-
import {
|
|
23
|
-
RectCoords,
|
|
24
|
-
cadExtensions,
|
|
25
|
-
CategoryPrediction,
|
|
26
|
-
Code,
|
|
27
|
-
Region,
|
|
28
|
-
Filter,
|
|
29
|
-
} from "@nyris/nyris-api";
|
|
30
|
-
import { AppSettings, CanvasWithId, MDSettings } from "./types";
|
|
31
|
-
import { NyrisAppPart, NyrisFeedbackState } from "./actions/nyrisAppActions";
|
|
32
22
|
import SelectedFiltersSummary from "./components/SelectedFiltersSummary";
|
|
33
23
|
|
|
24
|
+
|
|
34
25
|
export interface AppHandlers {
|
|
35
|
-
onExampleImageClick: (url: string) => void
|
|
36
|
-
onImageClick: (position: number, url: string) => void
|
|
37
|
-
onLinkClick: (position: number, url: string) => void
|
|
38
|
-
onFileDropped: (file: File) => void
|
|
39
|
-
onCaptureComplete: (image: HTMLCanvasElement) => void
|
|
40
|
-
onCaptureCanceled: () => void
|
|
41
|
-
onSelectFile: (f: File) => void
|
|
42
|
-
onCameraClick: () => void
|
|
43
|
-
onShowStart: () => void
|
|
44
|
-
onSelectionChange: (r: RectCoords) => void
|
|
45
|
-
onPositiveFeedback: () => void
|
|
46
|
-
onNegativeFeedback: () => void
|
|
47
|
-
onCloseFeedback: () => void
|
|
26
|
+
onExampleImageClick: (url: string) => void,
|
|
27
|
+
onImageClick: (position: number, url: string) => void,
|
|
28
|
+
onLinkClick: (position: number, url: string) => void,
|
|
29
|
+
onFileDropped: (file: File) => void,
|
|
30
|
+
onCaptureComplete: (image: HTMLCanvasElement) => void,
|
|
31
|
+
onCaptureCanceled: () => void,
|
|
32
|
+
onSelectFile: (f: File) => void,
|
|
33
|
+
onCameraClick: () => void,
|
|
34
|
+
onShowStart: () => void,
|
|
35
|
+
onSelectionChange: (r: RectCoords) => void,
|
|
36
|
+
onPositiveFeedback: () => void,
|
|
37
|
+
onNegativeFeedback: () => void,
|
|
38
|
+
onCloseFeedback: () => void,
|
|
48
39
|
}
|
|
40
|
+
|
|
41
|
+
|
|
49
42
|
export interface AppProps {
|
|
50
43
|
search: {
|
|
51
44
|
results: any[];
|
|
@@ -70,41 +63,29 @@ export interface AppProps {
|
|
|
70
63
|
mdSettings: MDSettings;
|
|
71
64
|
}
|
|
72
65
|
|
|
66
|
+
|
|
67
|
+
function Alert(props: AlertProps) {
|
|
68
|
+
return <MuiAlert elevation={6} variant="filled" {...props} />;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
73
72
|
const App: React.FC<AppProps> = ({
|
|
74
|
-
search: {
|
|
75
|
-
|
|
76
|
-
regions,
|
|
77
|
-
previewSelection,
|
|
78
|
-
requestId,
|
|
79
|
-
duration,
|
|
80
|
-
errorMessage,
|
|
81
|
-
filterOptions,
|
|
82
|
-
categoryPredictions,
|
|
83
|
-
codes,
|
|
84
|
-
toastErrorMessage,
|
|
85
|
-
filters,
|
|
86
|
-
selectedFilters,
|
|
87
|
-
},
|
|
88
|
-
showPart,
|
|
89
|
-
settings,
|
|
90
|
-
handlers,
|
|
91
|
-
loading,
|
|
92
|
-
previewImage,
|
|
93
|
-
feedbackState,
|
|
73
|
+
search: {results, regions, previewSelection, requestId, duration, errorMessage, filterOptions, categoryPredictions, codes, toastErrorMessage, filters, selectedFilters},
|
|
74
|
+
showPart, settings, handlers, loading, previewImage, feedbackState
|
|
94
75
|
}) => {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
});
|
|
76
|
+
|
|
77
|
+
const {getRootProps, getInputProps, isDragActive} = useDropzone({onDrop: (fs: File[]) => handlers.onFileDropped(fs[0])});
|
|
98
78
|
|
|
99
79
|
const minPreviewHeight = 400;
|
|
100
80
|
const halfOfTheScreenHeight = Math.floor(window.innerHeight * 0.45);
|
|
101
81
|
const maxPreviewHeight = Math.max(minPreviewHeight, halfOfTheScreenHeight);
|
|
82
|
+
const acceptTypes =
|
|
83
|
+
[ 'image/*' ].concat(
|
|
84
|
+
settings.cadSearch ? cadExtensions : []
|
|
85
|
+
).join(',');
|
|
102
86
|
const [toastOpen, setToastOpen] = useState(false);
|
|
103
|
-
const dispatch = useDispatch();
|
|
104
87
|
|
|
105
|
-
const
|
|
106
|
-
.concat(settings.cadSearch ? cadExtensions : [])
|
|
107
|
-
.join(",");
|
|
88
|
+
const dispatch = useDispatch();
|
|
108
89
|
|
|
109
90
|
useEffect(() => {
|
|
110
91
|
if (toastErrorMessage !== "") {
|
|
@@ -123,31 +104,17 @@ const App: React.FC<AppProps> = ({
|
|
|
123
104
|
<Sidebar filters={filters} selectedFilters={selectedFilters} />
|
|
124
105
|
|
|
125
106
|
<div className="mainContent">
|
|
126
|
-
|
|
127
|
-
<Capture
|
|
128
|
-
|
|
129
|
-
onCaptureCanceled={handlers.onCaptureCanceled}
|
|
130
|
-
useAppText="Use default camera app"
|
|
131
|
-
/>
|
|
132
|
-
)}
|
|
133
|
-
|
|
107
|
+
{showPart === 'camera' &&
|
|
108
|
+
<Capture onCaptureComplete={handlers.onCaptureComplete} onCaptureCanceled={handlers.onCaptureCanceled}
|
|
109
|
+
useAppText='Use default camera app'/>}
|
|
134
110
|
<SelectedFiltersSummary />
|
|
135
|
-
<div
|
|
136
|
-
className={classNames("headSection", {
|
|
137
|
-
hidden: showPart === "results",
|
|
138
|
-
})}
|
|
139
|
-
id="headSection"
|
|
140
|
-
>
|
|
111
|
+
<div className={classNames('headSection', {hidden: showPart === 'results'})} id="headSection">
|
|
141
112
|
<div
|
|
142
113
|
{...getRootProps({
|
|
143
114
|
onClick: (e) => {
|
|
144
115
|
e.stopPropagation();
|
|
145
116
|
},
|
|
146
|
-
})}
|
|
147
|
-
className={classNames("wrapper", "dragAndDropActionArea", {
|
|
148
|
-
fileIsHover: isDragActive,
|
|
149
|
-
})}
|
|
150
|
-
>
|
|
117
|
+
})} className={classNames('wrapper', 'dragAndDropActionArea', {'fileIsHover': isDragActive})}>
|
|
151
118
|
<div className={classNames("contentWrap")}>
|
|
152
119
|
<Box
|
|
153
120
|
display="flex"
|
|
@@ -157,32 +124,15 @@ const App: React.FC<AppProps> = ({
|
|
|
157
124
|
minHeight="100vh"
|
|
158
125
|
>
|
|
159
126
|
<section className="uploadImage">
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
onClick={handlers.onCameraClick}
|
|
168
|
-
/>
|
|
169
|
-
<input
|
|
170
|
-
type="file"
|
|
171
|
-
name="file"
|
|
172
|
-
id="capture_file"
|
|
173
|
-
className="inputfile"
|
|
174
|
-
accept={acceptTypes}
|
|
175
|
-
capture="environment"
|
|
176
|
-
/>
|
|
177
|
-
<input
|
|
178
|
-
{...getInputProps()}
|
|
179
|
-
type="file"
|
|
180
|
-
name="file"
|
|
181
|
-
id="select_file"
|
|
182
|
-
className="inputfile"
|
|
183
|
-
accept={acceptTypes}
|
|
184
|
-
onChange={makeFileHandler(handlers.onSelectFile)}
|
|
127
|
+
<input type="button" name="file" id="capture" className="inputfile" accept="image/*"
|
|
128
|
+
capture="environment" onClick={handlers.onCameraClick}/>
|
|
129
|
+
<input type="file" name="file" id="capture_file" className="inputfile" accept={acceptTypes}
|
|
130
|
+
capture="environment"/>
|
|
131
|
+
<input {...getInputProps()} type="file" name="file" id="select_file" className="inputfile"
|
|
132
|
+
accept={acceptTypes}
|
|
133
|
+
onChange={makeFileHandler(handlers.onSelectFile)}
|
|
185
134
|
/>
|
|
135
|
+
|
|
186
136
|
<div className="onDesktop">
|
|
187
137
|
Drop an image
|
|
188
138
|
<div className="smallText">or</div>
|
|
@@ -198,34 +148,20 @@ const App: React.FC<AppProps> = ({
|
|
|
198
148
|
<span className="onMobile">Take a picture</span>
|
|
199
149
|
</label>
|
|
200
150
|
<br />
|
|
201
|
-
<label
|
|
202
|
-
|
|
203
|
-
className="btn primary"
|
|
204
|
-
style={{ width: "12em" }}
|
|
205
|
-
>
|
|
206
|
-
<span>Select a file</span>
|
|
151
|
+
<label htmlFor="select_file" className="btn primary" style={{width: '22em'}}>
|
|
152
|
+
<span>Select a file</span>
|
|
207
153
|
</label>
|
|
208
|
-
<label
|
|
209
|
-
htmlFor="capture"
|
|
210
|
-
className="mobileUploadHandler onMobile"
|
|
211
|
-
/>
|
|
154
|
+
<label htmlFor="capture" className="mobileUploadHandler onMobile"/>
|
|
212
155
|
</section>
|
|
213
|
-
<ExampleImages
|
|
214
|
-
images={settings.exampleImages}
|
|
215
|
-
onExampleImageClicked={handlers.onExampleImageClick}
|
|
216
|
-
/>
|
|
156
|
+
<ExampleImages images={settings.exampleImages} onExampleImageClicked={handlers.onExampleImageClick}/>
|
|
217
157
|
</Box>
|
|
218
158
|
</div>
|
|
219
159
|
</div>
|
|
220
160
|
|
|
221
161
|
<div className="headerSeparatorTop" />
|
|
222
162
|
<div className="headerSeparatorBack" />
|
|
223
|
-
<div
|
|
224
|
-
|
|
225
|
-
hidden: showPart !== "results",
|
|
226
|
-
})}
|
|
227
|
-
onClick={handlers.onShowStart}
|
|
228
|
-
>
|
|
163
|
+
<div className={classNames('tryDifferent', {hidden: showPart !== 'results'})}
|
|
164
|
+
onClick={handlers.onShowStart}>
|
|
229
165
|
<div className="icIcon"></div>
|
|
230
166
|
<div className="textDesc"> Try a different image</div>
|
|
231
167
|
<br style={{ clear: "both" }} />
|
|
@@ -233,155 +169,92 @@ const App: React.FC<AppProps> = ({
|
|
|
233
169
|
</div>
|
|
234
170
|
|
|
235
171
|
<section
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
>
|
|
243
|
-
{errorMessage && (
|
|
244
|
-
<div className="errorMsg">
|
|
245
|
-
{errorMessage}
|
|
246
|
-
<div
|
|
247
|
-
style={{
|
|
248
|
-
textAlign: "center",
|
|
249
|
-
fontSize: "0ß.7em",
|
|
250
|
-
paddingTop: "0.8em",
|
|
251
|
-
}}
|
|
252
|
-
>
|
|
253
|
-
<span>
|
|
254
|
-
Make sure to include the request ID when reporting a
|
|
255
|
-
problem: {requestId}
|
|
256
|
-
</span>
|
|
172
|
+
className={classNames('results', {resultsActive: showPart === 'results'}, (results.length === 1 ? 'singleProduct' : 'multipleProducts'))}>
|
|
173
|
+
{errorMessage &&
|
|
174
|
+
<div className="errorMsg">
|
|
175
|
+
{errorMessage}
|
|
176
|
+
<div style={{textAlign: 'center', fontSize: '0.7em', paddingTop: '0.8em'}}><span>Make sure to include the request ID when reporting a problem: {requestId}</span>
|
|
177
|
+
</div>
|
|
257
178
|
</div>
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
179
|
+
}
|
|
180
|
+
<Animate show={loading} start={{opacity: 0.0}} enter={{opacity: [1.0], timing: {duration: 300}}}
|
|
181
|
+
leave={{opacity: [0.0], timing: {duration: 300}}}>
|
|
182
|
+
{s =>
|
|
183
|
+
<div className="loadingOverlay" style={{...s}}>
|
|
184
|
+
<div className="loading"/>
|
|
185
|
+
</div>
|
|
186
|
+
}
|
|
187
|
+
</Animate>
|
|
188
|
+
{settings.preview && previewImage &&
|
|
189
|
+
<div className="preview">
|
|
190
|
+
<Preview key={previewImage.id}
|
|
191
|
+
maxWidth={document.body.clientWidth} maxHeight={maxPreviewHeight}
|
|
192
|
+
dotColor="#4C8F9F"
|
|
193
|
+
onSelectionChange={handlers.onSelectionChange} regions={regions}
|
|
194
|
+
selection={previewSelection} image={previewImage.canvas}/>
|
|
269
195
|
</div>
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
<
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
dotColor="#4C8F9F"
|
|
279
|
-
onSelectionChange={handlers.onSelectionChange}
|
|
280
|
-
regions={regions}
|
|
281
|
-
selection={previewSelection}
|
|
282
|
-
image={previewImage.canvas}
|
|
283
|
-
/>
|
|
284
|
-
</div>
|
|
285
|
-
)}
|
|
286
|
-
<div className="predicted-categories">
|
|
287
|
-
<PredictedCategories cs={categoryPredictions} />
|
|
288
|
-
</div>
|
|
289
|
-
<div className="predicted-categories">
|
|
290
|
-
<Codes codes={codes} />
|
|
291
|
-
</div>
|
|
292
|
-
<CategoryFilter cats={filterOptions} />
|
|
196
|
+
}
|
|
197
|
+
<div className="predicted-categories">
|
|
198
|
+
<PredictedCategories cs={categoryPredictions}/>
|
|
199
|
+
</div>
|
|
200
|
+
<div className="predicted-categories">
|
|
201
|
+
<Codes codes={codes}/>
|
|
202
|
+
</div>
|
|
203
|
+
<CategoryFilter cats={filterOptions}/>
|
|
293
204
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
onLinkClick={handlers.onLinkClick}
|
|
314
|
-
result={data}
|
|
315
|
-
style={{
|
|
316
|
-
opacity: state.opacity,
|
|
317
|
-
transform: `translateX(${state.translateX}%)`,
|
|
318
|
-
}}
|
|
319
|
-
/>
|
|
320
|
-
))}
|
|
321
|
-
</>
|
|
322
|
-
)}
|
|
323
|
-
</NodeGroup>
|
|
205
|
+
<div className="wrapper">
|
|
206
|
+
<NodeGroup data={results}
|
|
207
|
+
keyAccessor={r => r.sku}
|
|
208
|
+
start={(r, i) => ({opacity: 0, translateX: -100})}
|
|
209
|
+
enter={(r, i) => ({
|
|
210
|
+
opacity: [1],
|
|
211
|
+
translateX: [0],
|
|
212
|
+
timing: {delay: i * 100, duration: 300}
|
|
213
|
+
})}
|
|
214
|
+
>
|
|
215
|
+
{rs => <>{rs.map(({key, data, state}) => <Result
|
|
216
|
+
key={key}
|
|
217
|
+
noImageUrl={settings.noImageUrl}
|
|
218
|
+
template={settings.resultTemplate}
|
|
219
|
+
onImageClick={handlers.onImageClick}
|
|
220
|
+
onLinkClick={handlers.onLinkClick}
|
|
221
|
+
result={data}
|
|
222
|
+
style={{opacity: state.opacity, transform: `translateX(${state.translateX}%)`}}/>)}</>}
|
|
223
|
+
</NodeGroup>
|
|
324
224
|
|
|
325
|
-
|
|
326
|
-
<div className="noResults">
|
|
327
|
-
We did not find anything{" "}
|
|
328
|
-
<span role="img" aria-label="sad face">
|
|
329
|
-
😕
|
|
330
|
-
</span>
|
|
331
|
-
</div>
|
|
332
|
-
)}
|
|
225
|
+
{results.length === 0 && showPart === 'results' && !loading && (
|
|
333
226
|
|
|
334
|
-
|
|
227
|
+
<div className="noResults">We did not find anything <span role="img"
|
|
228
|
+
aria-label="sad face">😕</span></div>
|
|
229
|
+
)}
|
|
335
230
|
|
|
336
|
-
|
|
337
|
-
<div
|
|
338
|
-
style={{
|
|
339
|
-
textAlign: "center",
|
|
340
|
-
fontSize: "0.7em",
|
|
341
|
-
paddingTop: "0.8em",
|
|
342
|
-
}}
|
|
343
|
-
>
|
|
344
|
-
Search took {duration.toFixed(2)} seconds
|
|
345
|
-
</div>
|
|
346
|
-
)}
|
|
231
|
+
<br style={{clear: 'both'}}/>
|
|
347
232
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
textAlign:
|
|
352
|
-
|
|
353
|
-
paddingTop: "0.8em",
|
|
354
|
-
}}
|
|
355
|
-
>
|
|
356
|
-
Request identifier {requestId}
|
|
233
|
+
{duration && showPart === 'results' && (<div style={{textAlign: 'center', fontSize: '0.7em', paddingTop: '0.8em'}}>Search
|
|
234
|
+
took {duration.toFixed(2)} seconds</div>)}
|
|
235
|
+
|
|
236
|
+
{requestId && showPart === 'results' && <div style={{textAlign: 'center', fontSize: '0.7em', paddingTop: '0.8em'}}>Request
|
|
237
|
+
identifier {requestId}</div>}
|
|
357
238
|
</div>
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
239
|
+
</section>
|
|
240
|
+
|
|
241
|
+
<Snackbar open={toastOpen} autoHideDuration={3000} onClose={() => setToastOpen(false)}>
|
|
242
|
+
<Alert onClose={() => setToastOpen(false)} severity="error">
|
|
243
|
+
{toastErrorMessage}
|
|
244
|
+
</Alert>
|
|
245
|
+
</Snackbar>
|
|
361
246
|
|
|
362
|
-
<Snackbar
|
|
363
|
-
open={toastOpen}
|
|
364
|
-
autoHideDuration={3000}
|
|
365
|
-
onClose={() => setToastOpen(false)}
|
|
366
|
-
>
|
|
367
|
-
<Alert onClose={() => setToastOpen(false)} severity="error">
|
|
368
|
-
{toastErrorMessage}
|
|
369
|
-
</Alert>
|
|
370
|
-
</Snackbar>
|
|
371
247
|
</div>
|
|
372
248
|
</div>
|
|
373
249
|
<section className="footnote">
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
onNegativeFeedback={handlers.onNegativeFeedback}
|
|
383
|
-
onClose={handlers.onCloseFeedback}
|
|
384
|
-
/>
|
|
250
|
+
<div className="wrapper">
|
|
251
|
+
© 2017 - 2019 <a href="https://nyris.io">nyris GmbH</a> - All rights reserved - <a
|
|
252
|
+
href="https://nyris.io/imprint/">Imprint</a>
|
|
253
|
+
</div>
|
|
254
|
+
</section>
|
|
255
|
+
<Feedback feedbackState={feedbackState} onPositiveFeedback={handlers.onPositiveFeedback}
|
|
256
|
+
onNegativeFeedback={handlers.onNegativeFeedback} onClose={handlers.onCloseFeedback}/>
|
|
257
|
+
|
|
385
258
|
</React.Fragment>
|
|
386
259
|
);
|
|
387
260
|
};
|
|
@@ -279,16 +279,9 @@ function ADDtoSelectedfilters(
|
|
|
279
279
|
key: string,
|
|
280
280
|
value: string
|
|
281
281
|
): Map<string, string[]> {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
values.push(value);
|
|
286
|
-
} else {
|
|
287
|
-
values = new Array<string>(value);
|
|
288
|
-
}
|
|
289
|
-
selectedFilters.set(key, values);
|
|
290
|
-
}
|
|
291
|
-
console.log(selectedFilters);
|
|
282
|
+
let values = selectedFilters.get(key) || new Array<string>();
|
|
283
|
+
values.push(value);
|
|
284
|
+
selectedFilters.set(key, values);
|
|
292
285
|
return selectedFilters;
|
|
293
286
|
}
|
|
294
287
|
|
|
@@ -297,26 +290,19 @@ function RemoveFromSelectedFilters(
|
|
|
297
290
|
key: string,
|
|
298
291
|
value: string
|
|
299
292
|
): Map<string, string[]> {
|
|
300
|
-
|
|
301
|
-
let values = selectedFilters.get(key);
|
|
293
|
+
let values = selectedFilters.get(key);
|
|
302
294
|
if (values) {
|
|
303
295
|
values = values.filter((x) => x !== value);
|
|
304
296
|
selectedFilters.set(key, values);
|
|
305
297
|
}
|
|
306
|
-
|
|
307
|
-
console.log(selectedFilters);
|
|
298
|
+
|
|
308
299
|
return selectedFilters;
|
|
309
300
|
}
|
|
310
301
|
|
|
311
302
|
function UpdateFilters(filters: Filter[], key: string, values: string[]) {
|
|
312
|
-
console.log(filters);
|
|
313
|
-
console.log(key);
|
|
314
|
-
console.log(values);
|
|
315
|
-
console.log(filters.find((x) => x.key === key));
|
|
316
303
|
if (filters && filters.length > 0 && filters.find((x) => x.key === key)) {
|
|
317
304
|
let idx = filters.findIndex((x) => x.key === key);
|
|
318
305
|
filters[idx].values = values;
|
|
319
|
-
console.log(filters);
|
|
320
306
|
}
|
|
321
307
|
|
|
322
308
|
return filters;
|
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
import React from
|
|
1
|
+
import React from 'react';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
</div>
|
|
17
|
-
);
|
|
3
|
+
|
|
4
|
+
const CategoryFilter = ({cats}: {cats: string[]}) => {
|
|
5
|
+
if (cats.length === 0) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
return (
|
|
9
|
+
<div id="catlist" style={{'textAlign': 'center'}}>
|
|
10
|
+
{
|
|
11
|
+
cats.map((s) => <a key={s} href="#top">{s}</a>) // TODO fix link
|
|
12
|
+
}
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
18
15
|
};
|
|
19
16
|
|
|
20
17
|
export default CategoryFilter;
|
package/src/components/Codes.tsx
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import {
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {Code} from '@nyris/nyris-api';
|
|
3
3
|
|
|
4
4
|
interface Props {
|
|
5
|
-
|
|
5
|
+
codes: Code[]
|
|
6
6
|
}
|
|
7
|
-
const Codes = ({
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
))}
|
|
21
|
-
</div>
|
|
22
|
-
</>
|
|
23
|
-
);
|
|
7
|
+
const Codes = ({codes}: Props) =>
|
|
8
|
+
<>
|
|
9
|
+
<div className="codes" style={{textAlign: 'center'}}>
|
|
10
|
+
{codes.length > 0 && <span style={{fontSize: '0.8em'}}>Codes<br/> </span> }
|
|
11
|
+
{codes.map((c, i) =>
|
|
12
|
+
<small key={i} title={c.type}>
|
|
13
|
+
{c.value}
|
|
14
|
+
</small>)}
|
|
15
|
+
</div>
|
|
16
|
+
</>
|
|
17
|
+
;
|
|
18
|
+
|
|
19
|
+
|
|
24
20
|
export default Codes;
|