@nyris/nyris-webapp 0.3.9 → 0.3.12

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 (36) hide show
  1. package/build/asset-manifest.json +11 -11
  2. package/build/index.html +1 -1
  3. package/build/{precache-manifest.a97813497ab8d37548141e5e2618d0dc.js → precache-manifest.1b00dd5c15aa0815244681503d6fa9da.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.6e13adbe.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.ef6a9744.chunk.js +2 -0
  11. package/build/static/js/main.ef6a9744.chunk.js.map +1 -0
  12. package/package.json +2 -2
  13. package/src/App.tsx +333 -188
  14. package/src/actions/nyrisAppActions.ts +69 -65
  15. package/src/actions/searchActions.ts +301 -195
  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 +113 -58
  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 +85 -0
  25. package/src/components/Sidebar.tsx +44 -34
  26. package/src/epics/index.ts +173 -104
  27. package/src/epics/search.ts +214 -139
  28. package/src/index.css +95 -6
  29. package/src/index.tsx +147 -145
  30. package/src/utils.ts +5 -0
  31. package/build/static/css/main.0481043c.chunk.css +0 -2
  32. package/build/static/css/main.0481043c.chunk.css.map +0 -1
  33. package/build/static/js/2.6e13adbe.chunk.js +0 -3
  34. package/build/static/js/2.6e13adbe.chunk.js.map +0 -1
  35. package/build/static/js/main.f5da7aa4.chunk.js +0 -2
  36. package/build/static/js/main.f5da7aa4.chunk.js.map +0 -1
@@ -1,164 +1,239 @@
1
- import {EpicConf} from "./types";
2
- import {combineEpics, ofType} from "redux-observable";
3
- import {switchMap, withLatestFrom} from "rxjs/operators";
4
- import {AppAction} from "../types";
5
- import {ImageSearchOptions, urlOrBlobToCanvas, isCadFile, isImageFile, Filter } from "@nyris/nyris-api";
6
- import {imageLoaded, cadFileLoaded} from "../actions/searchActions";
7
-
8
- const imageSearch: EpicConf = (action$, state$, {api}) => action$.pipe(
9
- ofType('SEARCH_REQUEST_START'),
1
+ import { EpicConf } from "./types";
2
+ import { combineEpics, ofType } from "redux-observable";
3
+ import { switchMap, withLatestFrom } from "rxjs/operators";
4
+ import { AppAction } from "../types";
5
+ import {
6
+ ImageSearchOptions,
7
+ urlOrBlobToCanvas,
8
+ isCadFile,
9
+ isImageFile,
10
+ Filter,
11
+ } from "@nyris/nyris-api";
12
+ import { imageLoaded, cadFileLoaded } from "../actions/searchActions";
13
+
14
+ const imageSearch: EpicConf = (action$, state$, { api }) =>
15
+ action$.pipe(
16
+ ofType("SEARCH_REQUEST_START"),
10
17
  withLatestFrom(state$),
11
- switchMap(async ([action, state]) : Promise<AppAction> => {
12
- if (action.type !== 'SEARCH_REQUEST_START') {
13
- throw new Error(`Wrong action type ${action.type}`);
14
- }
15
- console.log("state search ");
16
- console.log(state.search.selectedFilters);
17
-
18
- if ('image' in action) {
19
- let { image, normalizedRect} = action;
20
- console.log("Selected Filters");
21
- let selectedFilters = new Array<Filter>();
22
- if(state.search.selectedFilters.size > 0 ){
23
- state.search.selectedFilters.forEach((values, key) => {
24
- let filterObj: Filter ={
25
- key : key,
26
- values : values
27
- }
28
- selectedFilters.push(filterObj);
29
- });
30
- }
31
-
32
- let options : ImageSearchOptions = {
33
- cropRect: normalizedRect
34
- };
35
-
36
- try {
37
- if(selectedFilters && selectedFilters.length> 0)
38
- {
39
- console.log("With Filters");
40
- const {results, duration, requestId, categoryPredictions, codes} = await api.findByImageWithFilters(image, options, selectedFilters);
41
- return ({ type: 'SEARCH_REQUEST_SUCCEED', results, requestId, duration, categoryPredictions, codes });
42
-
43
- }
44
- else{
45
- console.log("Without Filters");
46
- const {results, duration, requestId, categoryPredictions, codes} = await api.findByImage(image, options);
47
- return ({ type: 'SEARCH_REQUEST_SUCCEED', results, requestId, duration, categoryPredictions, codes });
48
- }
49
- } catch (e) {
50
- console.warn('search failed', e);
51
- return ({ type: 'SEARCH_REQUEST_FAIL', reason: e.message, exception: e });
18
+ switchMap(async ([action, state]): Promise<AppAction> => {
19
+ if (action.type !== "SEARCH_REQUEST_START") {
20
+ throw new Error(`Wrong action type ${action.type}`);
21
+ }
22
+ if ("image" in action) {
23
+ let { image, normalizedRect } = action;
24
+
25
+ // refactor this
26
+ let selectedFilters = new Array<Filter>();
27
+ if (state.search.selectedFilters.size > 0) {
28
+ state.search.selectedFilters.forEach((values, key) => {
29
+ if (values && values.length > 0) {
30
+ let filterObj: Filter = {
31
+ key: key,
32
+ values: values,
33
+ };
34
+ selectedFilters.push(filterObj);
52
35
  }
36
+ });
53
37
  }
54
38
 
55
- if ('file' in action) {
56
- console.log('file');
57
- let { file } = action;
39
+ let options: ImageSearchOptions = {
40
+ cropRect: normalizedRect,
41
+ };
58
42
 
59
- let options : ImageSearchOptions = { };
60
-
61
- try {
62
- const {results, duration, requestId, categoryPredictions, codes} = await api.findByCad(file, options);
63
- return ({ type: 'SEARCH_REQUEST_SUCCEED', results, requestId, duration, categoryPredictions, codes });
64
- } catch (e) {
65
- console.warn('search failed', e);
66
- return ({ type: 'SEARCH_REQUEST_FAIL', reason: e.message, exception: e });
67
- }
43
+ try {
44
+ if (selectedFilters && selectedFilters.length > 0) {
45
+ console.log("With Filters");
46
+ const { results, duration, requestId, categoryPredictions, codes } =
47
+ await api.findByImageWithFilters(image, options, selectedFilters);
48
+ return {
49
+ type: "SEARCH_REQUEST_SUCCEED",
50
+ results,
51
+ requestId,
52
+ duration,
53
+ categoryPredictions,
54
+ codes,
55
+ };
56
+ } else {
57
+ console.log("Without Filters");
58
+ const { results, duration, requestId, categoryPredictions, codes } =
59
+ await api.findByImage(image, options);
60
+ return {
61
+ type: "SEARCH_REQUEST_SUCCEED",
62
+ results,
63
+ requestId,
64
+ duration,
65
+ categoryPredictions,
66
+ codes,
67
+ };
68
+ }
69
+ } catch (e) {
70
+ console.warn("search failed", e);
71
+ return {
72
+ type: "SEARCH_REQUEST_FAIL",
73
+ reason: e.message,
74
+ exception: e,
75
+ };
68
76
  }
69
- throw new Error(`Wrong action content ${action}`);
70
- })
71
- );
77
+ }
72
78
 
73
- const regionSearch: EpicConf = (action$, state$, {api}) => action$.pipe(
74
- ofType('REGION_REQUEST_START'),
75
- withLatestFrom(state$),
76
- switchMap(async ([action, {settings}]) : Promise<AppAction> => {
77
- if (action.type !== 'REGION_REQUEST_START') {
78
- throw new Error(`Wrong action type ${action.type}`);
79
- }
79
+ if ("file" in action) {
80
+ console.log("file");
81
+ let { file } = action;
80
82
 
81
- let { image } = action;
83
+ let options: ImageSearchOptions = {};
82
84
 
83
85
  try {
84
- let regions = await api.findRegions(image);
85
- return {type: 'REGION_REQUEST_SUCCEED', regions };
86
-
86
+ const { results, duration, requestId, categoryPredictions, codes } =
87
+ await api.findByCad(file, options);
88
+ return {
89
+ type: "SEARCH_REQUEST_SUCCEED",
90
+ results,
91
+ requestId,
92
+ duration,
93
+ categoryPredictions,
94
+ codes,
95
+ };
87
96
  } catch (e) {
88
- console.error(e);
89
- return {type: 'REGION_REQUEST_FAIL', reason: e.message, exception: e};
97
+ console.warn("search failed", e);
98
+ return {
99
+ type: "SEARCH_REQUEST_FAIL",
100
+ reason: e.message,
101
+ exception: e,
102
+ };
90
103
  }
104
+ }
105
+ throw new Error(`Wrong action content ${action}`);
91
106
  })
92
- );
107
+ );
93
108
 
94
- const loadFile: EpicConf = (action$) => action$.pipe(
95
- ofType('LOAD_FILE'),
96
- switchMap(async (action) : Promise<AppAction> => {
97
- if (action.type !== 'LOAD_FILE') {
98
- throw new Error(`Wrong action type ${action.type}`);
99
- }
100
- const randomId = Math.random().toString();
101
- if ('file' in action) {
102
- const file = action.file;
103
- if (isImageFile(file)) {
104
- return imageLoaded(await urlOrBlobToCanvas(file), randomId);
105
- }
106
- if (isCadFile(file)) {
107
- return cadFileLoaded(file, randomId);
108
- }
109
- }
110
- throw new Error(`LOAD_FILE action wrong properties ${Object.keys(action).join(',')}`);
109
+ const regionSearch: EpicConf = (action$, state$, { api }) =>
110
+ action$.pipe(
111
+ ofType("REGION_REQUEST_START"),
112
+ withLatestFrom(state$),
113
+ switchMap(async ([action, { settings }]): Promise<AppAction> => {
114
+ if (action.type !== "REGION_REQUEST_START") {
115
+ throw new Error(`Wrong action type ${action.type}`);
116
+ }
117
+
118
+ let { image } = action;
119
+
120
+ try {
121
+ let regions = await api.findRegions(image);
122
+ return { type: "REGION_REQUEST_SUCCEED", regions };
123
+ } catch (e) {
124
+ console.error(e);
125
+ return { type: "REGION_REQUEST_FAIL", reason: e.message, exception: e };
126
+ }
111
127
  })
112
- );
113
-
114
- const loadImage: EpicConf = (action$) => action$.pipe(
115
- ofType('LOAD_IMAGE'),
116
- switchMap(async (action) : Promise<AppAction> => {
117
- if (action.type !== 'LOAD_IMAGE') {
118
- throw new Error(`Wrong action type ${action.type}`);
119
- }
120
- const randomId = Math.random().toString();
121
- if ('url' in action) {
122
- return imageLoaded(await urlOrBlobToCanvas(action.url), randomId);
128
+ );
129
+
130
+ const loadFile: EpicConf = (action$) =>
131
+ action$.pipe(
132
+ ofType("LOAD_FILE"),
133
+ switchMap(async (action): Promise<AppAction> => {
134
+ if (action.type !== "LOAD_FILE") {
135
+ throw new Error(`Wrong action type ${action.type}`);
136
+ }
137
+ const randomId = Math.random().toString();
138
+ if ("file" in action) {
139
+ const file = action.file;
140
+ if (isImageFile(file)) {
141
+ return imageLoaded(await urlOrBlobToCanvas(file), randomId);
123
142
  }
124
- if ('file' in action) {
125
- return imageLoaded(await urlOrBlobToCanvas(action.file), randomId);
143
+ if (isCadFile(file)) {
144
+ return cadFileLoaded(file, randomId);
126
145
  }
127
- if ('image' in action) {
128
- return imageLoaded(action.image, randomId);
129
- }
130
- throw new Error(`LOAD_IMAGE action wrong properties ${Object.keys(action).join(',')}`);
146
+ }
147
+ throw new Error(
148
+ `LOAD_FILE action wrong properties ${Object.keys(action).join(",")}`
149
+ );
131
150
  })
132
- );
133
-
151
+ );
152
+
153
+ const loadImage: EpicConf = (action$) =>
154
+ action$.pipe(
155
+ ofType("LOAD_IMAGE"),
156
+ switchMap(async (action): Promise<AppAction> => {
157
+ if (action.type !== "LOAD_IMAGE") {
158
+ throw new Error(`Wrong action type ${action.type}`);
159
+ }
160
+ const randomId = Math.random().toString();
161
+ if ("url" in action) {
162
+ return imageLoaded(await urlOrBlobToCanvas(action.url), randomId);
163
+ }
164
+ if ("file" in action) {
165
+ return imageLoaded(await urlOrBlobToCanvas(action.file), randomId);
166
+ }
167
+ if ("image" in action) {
168
+ return imageLoaded(action.image, randomId);
169
+ }
170
+ throw new Error(
171
+ `LOAD_IMAGE action wrong properties ${Object.keys(action).join(",")}`
172
+ );
173
+ })
174
+ );
134
175
 
135
- const loadFilters: EpicConf = (action$, state$, {api}) => action$.pipe(
136
- ofType('LOAD_FILTERS'),
176
+ const loadFilters: EpicConf = (action$, state$, { api }) =>
177
+ action$.pipe(
178
+ ofType("LOAD_FILTERS"),
137
179
  withLatestFrom(state$),
138
- switchMap(async ([action, state]) : Promise<AppAction> => {
139
- if(action.type !== 'LOAD_FILTERS'){
140
- throw new Error(`Wrong action type ${action.type}`);
141
- }
142
- try {
143
- // use find filters
144
-
145
- let filters = await api.getFilters();
146
-
147
- filters= filters.slice(0, 3);
148
- console.log(filters);
149
- return {type: 'LOAD_FILTERS_SUCCESS', filters };
180
+ switchMap(async ([action, state]): Promise<AppAction> => {
181
+ if (action.type !== "LOAD_FILTERS") {
182
+ throw new Error(`Wrong action type ${action.type}`);
183
+ }
184
+ try {
185
+ // use find filters
186
+
187
+ let filters = await api.getFilters();
188
+
189
+ filters = filters.slice(0, 3);
190
+ console.log(filters);
191
+ return { type: "LOAD_FILTERS_SUCCESS", filters };
192
+ } catch (e) {
193
+ console.error(e);
194
+ return { type: "LOAD_FILTERS_FAIL", reason: e.message, exception: e };
195
+ }
196
+ })
197
+ );
150
198
 
151
- } catch (e) {
152
- console.error(e);
153
- return {type: 'LOAD_FILTERS_FAIL', reason: e.message, exception: e};
199
+ const searchFilters: EpicConf = (action$, state$, { api }) =>
200
+ action$.pipe(
201
+ ofType("SEARCH_FILTERS"),
202
+ withLatestFrom(state$),
203
+ switchMap(async ([action, state]): Promise<AppAction> => {
204
+ if (action.type !== "SEARCH_FILTERS") {
205
+ throw new Error(`Wrong action type ${action.type}`);
206
+ }
207
+ try {
208
+ // use find filters
209
+ let { key, value } = action;
210
+ let values: string[] = [];
211
+ if (value) {
212
+ let response = await api.searchFilters(key, value);
213
+ if (response && response.length > 0) {
214
+ values = values.concat(await api.searchFilters(key, value));
215
+ }
216
+ } else {
217
+ // if no value load default values in search
218
+ let defaultfilters = await api.getFilters();
219
+ let filter = defaultfilters.find((x) => x.key === key);
220
+ if (filter && filter.values && filter.values.length > 0) {
221
+ values = filter.values;
222
+ }
154
223
  }
224
+ return { type: "UPDATE_FILTERS", key, values };
225
+ } catch (e) {
226
+ console.error(e);
227
+ return { type: "LOAD_FILTERS_FAIL", reason: e.message, exception: e };
228
+ }
155
229
  })
156
- );
157
-
230
+ );
158
231
 
159
232
  export default combineEpics(
160
- imageSearch,
161
- regionSearch,
162
- loadFile,
163
- loadImage,
164
- loadFilters);
233
+ imageSearch,
234
+ regionSearch,
235
+ loadFile,
236
+ loadImage,
237
+ loadFilters,
238
+ searchFilters
239
+ );
package/src/index.css CHANGED
@@ -315,7 +315,7 @@ h1, h2 {
315
315
 
316
316
  h1 {
317
317
  font-size: 25px;
318
- margin: 0 auto 25px
318
+ margin: 0 auto
319
319
  }
320
320
 
321
321
  h1.entry-title a {
@@ -1455,7 +1455,7 @@ a img.aligncenter {
1455
1455
  background: #031F2B;
1456
1456
 
1457
1457
  -ms-flex-pack: justify;
1458
- height: calc( 100vh - 60px);
1458
+ height: 100%;
1459
1459
  }
1460
1460
  .sidebar {
1461
1461
  order: 0;
@@ -1468,14 +1468,15 @@ a img.aligncenter {
1468
1468
  -webkit-flex: 0 0 329px;
1469
1469
  -ms-flex: 0 0 329px;
1470
1470
  flex: 0 0 240px;
1471
- border-right: 1px solid #eee;
1472
1471
  width: 25%;
1472
+ height:100%
1473
1473
  }
1474
1474
  .mainContent{
1475
1475
  width: calc(100vh-230);
1476
1476
  flex: 0 0 80%;
1477
1477
  flex-grow: 1;
1478
1478
  position: inherit;
1479
+ border-left: 1px solid #eee;
1479
1480
  }
1480
1481
  .sidebarContent {
1481
1482
  height: 100%;
@@ -1487,7 +1488,7 @@ a img.aligncenter {
1487
1488
  .sidebarHeader{
1488
1489
  display: flex;
1489
1490
  align-items: center;
1490
- padding: 16px;
1491
+ padding: 3px;
1491
1492
  }
1492
1493
  .sidebar-icon{
1493
1494
  width: 1.25em;
@@ -1502,8 +1503,11 @@ a img.aligncenter {
1502
1503
  font-size: 16px;
1503
1504
  float: left;
1504
1505
  color: white;
1505
- margin-top: 27px;
1506
+ margin-top: 7px;
1506
1507
  }
1508
+ .sidebarContent{
1509
+ overflow-y: auto;
1510
+ }
1507
1511
  .Sidebar-items{
1508
1512
  display: flex;
1509
1513
  flex-direction: column;
@@ -1535,11 +1539,96 @@ a img.aligncenter {
1535
1539
  }
1536
1540
  .sidebar-text{
1537
1541
  color: white;
1542
+ font-size: 16px;
1543
+ }
1544
+ .overflowHidden{
1545
+ overflow-y: hidden;
1538
1546
  }
1539
-
1540
1547
  .itemLabel{
1541
1548
  padding-left: 10px;
1549
+ font-size: 14px;
1550
+ max-width: 3ch;
1551
+ overflow: hidden;
1552
+ text-overflow: ellipsis;
1553
+ }
1554
+ .itemLabel:hover::before {
1555
+ content: attr(data-title);
1556
+ position: absolute;
1557
+ bottom: -46px;
1558
+ padding: 10px;
1559
+ background: #000;
1560
+ color: #fff;
1561
+ font-size: 14px;
1562
+ white-space: nowrap;
1563
+ }
1564
+ .itemLabel:hover::after {
1565
+ content: '';
1566
+ position: absolute;
1567
+ bottom: -12px;
1568
+ left: 8px;
1569
+ border: 8px solid transparent;
1570
+ border-bottom: 8px solid #000;
1571
+ }
1572
+
1573
+ #searchQueryInput {
1574
+ width: 100%;
1575
+ height: 1.8rem;
1576
+ background: #f5f5f5;
1577
+ outline: none;
1578
+ border: none;
1579
+ border-radius: 1.625rem;
1580
+ padding: 0 3.5rem 0 1.5rem;
1581
+ font-size: 1rem;
1582
+ }
1583
+
1584
+ #searchQuerySubmit {
1585
+ width: 3.5rem;
1586
+ height: 2.8rem;
1587
+ margin-left: -3.5rem;
1588
+ background: none;
1589
+ border: none;
1590
+ outline: none;
1591
+ }
1592
+
1593
+ .searchBar {
1594
+ width: 100%;
1595
+ display: flex;
1596
+ flex-direction: row;
1597
+ align-items: center;
1542
1598
  }
1599
+
1600
+ .wrap-box-refinements{
1601
+ width: 100%;
1602
+ margin-top: 16px;
1603
+ }
1604
+ .wrap-box-refinements ul{
1605
+ display: flex;
1606
+ flex-wrap: wrap;
1607
+ width: 100%;
1608
+ grid-gap: 8px;
1609
+ gap: 8px;
1610
+ align-items: center;
1611
+ }
1612
+ .summary-label{
1613
+ width: 100%;
1614
+ display: inherit;
1615
+ align-items: inherit;
1616
+ justify-content: inherit;
1617
+ }
1618
+
1619
+ .summary-label-key-text{
1620
+ font-size: 13px;
1621
+ }
1622
+
1623
+ .clear-all-filters-hidden{
1624
+ display: none;
1625
+ }
1626
+ .clear-all-filters{
1627
+ border: 0;
1628
+ background: initial;
1629
+ color: red;
1630
+ font-size: 13px;
1631
+ }
1543
1632
  #catlist a { display: inline-block; padding: 10px; border-radius: 10px; }
1544
1633
  #catlist a:hover { background-color: white; }
1545
1634
  #catlist a.selected { background-color: #444; color: #ddd; }