@things-factory/reference-app 5.0.0-zeta.8 → 5.0.1

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 (67) hide show
  1. package/client/bootstrap.js +21 -11
  2. package/client/components/ocr-viewpart.js +1 -1
  3. package/client/editors/id-editor.js +1 -1
  4. package/client/editors/id-selector.js +1 -1
  5. package/client/menu.js +10 -5
  6. package/client/pages/data-entry/data-entry-form.js +117 -0
  7. package/client/pages/data-entry/data-entry-generator-popup.js +110 -0
  8. package/client/pages/data-set/data-item-list.js +277 -0
  9. package/client/pages/data-set/data-set-importer.js +103 -0
  10. package/client/pages/data-set/data-set-list-page.js +738 -0
  11. package/client/pages/ocr-page.js +1 -1
  12. package/client/pages/operation/operation-api.js +85 -0
  13. package/client/pages/operation/operation-master.js +432 -0
  14. package/client/pages/pending-job-page.js +1 -1
  15. package/client/pages/product/product-api.js +150 -0
  16. package/client/pages/product/product-master.js +888 -0
  17. package/client/pages/product-combination-settings-popup.js +395 -0
  18. package/client/pages/product-combinations-popup.js +372 -0
  19. package/client/pages/product-details-popup.js +744 -0
  20. package/client/pages/upload-page.js +1 -1
  21. package/client/route.js +12 -0
  22. package/config/config.development.js +1 -1
  23. package/config.development.js +21 -0
  24. package/db.sqlite +0 -0
  25. package/dist-server/constants/index.js +18 -0
  26. package/dist-server/constants/index.js.map +1 -0
  27. package/dist-server/constants/type-constants.js +26 -0
  28. package/dist-server/constants/type-constants.js.map +1 -0
  29. package/dist-server/controllers/create-data-sample-mockup.js +236 -0
  30. package/dist-server/controllers/create-data-sample-mockup.js.map +1 -0
  31. package/dist-server/controllers/index.js +17 -0
  32. package/dist-server/controllers/index.js.map +1 -1
  33. package/dist-server/service/data-sample-mockup/data-sample-mockup-mutation.js +40 -0
  34. package/dist-server/service/data-sample-mockup/data-sample-mockup-mutation.js.map +1 -0
  35. package/dist-server/service/data-sample-mockup/data-sample-mockup-type.js +28 -0
  36. package/dist-server/service/data-sample-mockup/data-sample-mockup-type.js.map +1 -0
  37. package/dist-server/service/data-sample-mockup/index.js +7 -0
  38. package/dist-server/service/data-sample-mockup/index.js.map +1 -0
  39. package/dist-server/service/index.js +5 -2
  40. package/dist-server/service/index.js.map +1 -1
  41. package/dist-server/service/reference/reference-mutation.js +6 -3
  42. package/dist-server/service/reference/reference-mutation.js.map +1 -1
  43. package/dist-server/service/reference/reference-query.js +7 -4
  44. package/dist-server/service/reference/reference-query.js.map +1 -1
  45. package/logs/.08636eb59927f12972f6774f5947c8507b3564c2-audit.json +4 -14
  46. package/logs/.5e5d741d8b7784a2fbad65eedc0fd46946aaf6f2-audit.json +19 -69
  47. package/logs/application-2022-07-22-10.log +26 -0
  48. package/logs/connections-2022-07-12-00.log +0 -0
  49. package/logs/connections-2022-07-14-14.log +0 -0
  50. package/logs/connections-2022-07-14-15.log +0 -0
  51. package/logs/connections-2022-07-14-16.log +0 -0
  52. package/logs/connections-2022-07-14-17.log +0 -0
  53. package/logs/connections-2022-07-22-10.log +0 -0
  54. package/package.json +58 -56
  55. package/server/constants/index.ts +1 -0
  56. package/server/constants/type-constants.ts +24 -0
  57. package/server/controllers/create-data-sample-mockup.ts +268 -0
  58. package/server/controllers/index.ts +1 -0
  59. package/server/service/data-sample-mockup/data-sample-mockup-mutation.ts +18 -0
  60. package/server/service/data-sample-mockup/data-sample-mockup-type.ts +10 -0
  61. package/server/service/data-sample-mockup/index.ts +4 -0
  62. package/server/service/index.ts +5 -2
  63. package/server/service/reference/reference-mutation.ts +5 -3
  64. package/server/service/reference/reference-query.ts +8 -7
  65. package/things-factory.config.js +8 -0
  66. package/translations/en.json +6 -1
  67. package/translations/ko.json +7 -1
@@ -0,0 +1,372 @@
1
+ import '@things-factory/form-ui'
2
+ import '@operato/data-grist'
3
+ import './product-combination-settings-popup'
4
+
5
+ import gql from 'graphql-tag'
6
+ import { css, html, LitElement } from 'lit'
7
+
8
+ import { i18next, localize } from '@operato/i18n'
9
+ import { ScrollbarStyles } from '@operato/styles'
10
+ import { isMobileDevice } from '@operato/utils'
11
+ import { client, CustomAlert, gqlContext } from '@things-factory/shell'
12
+
13
+ class ProductCombinationsPopup extends localize(i18next)(LitElement) {
14
+ static get properties() {
15
+ return {
16
+ searchFields: Array,
17
+ productCombinationConfig: Object,
18
+ productCombinationData: Object,
19
+ productDetailId: String,
20
+ selectedProductCombination: Object,
21
+ productCombination: Object
22
+ }
23
+ }
24
+
25
+ static get styles() {
26
+ return [
27
+ ScrollbarStyles,
28
+ css`
29
+ :host {
30
+ display: flex;
31
+ flex-direction: column;
32
+ overflow: hidden;
33
+ background-color: white;
34
+ }
35
+ search-form {
36
+ overflow: visible;
37
+ }
38
+ ox-grist {
39
+ overflow-y: auto;
40
+ flex: 1;
41
+ }
42
+ .grist {
43
+ background-color: var(--main-section-background-color);
44
+ display: flex;
45
+ flex-direction: row;
46
+ flex: 1;
47
+ overflow-y: auto;
48
+ }
49
+ .grist-column {
50
+ flex: 1;
51
+ display: flex;
52
+ flex-direction: column;
53
+ overflow: auto;
54
+ }
55
+ .button-container {
56
+ padding: 10px 0 12px 0;
57
+ text-align: center;
58
+ }
59
+ [danger] {
60
+ --mdc-theme-primary: var(--mdc-danger-button-primary-color);
61
+ }
62
+ .header {
63
+ display: grid;
64
+ grid-template-columns: repeat(24, 1fr);
65
+ grid-gap: var(--form-grid-gap);
66
+ grid-auto-rows: minmax(24px, auto);
67
+ max-width: var(--form-multi-column-max-width);
68
+ margin-top: var(--form-margin);
69
+ margin-left: var(--form-margin);
70
+ margin-right: var(--form-margin);
71
+ }
72
+ .header legend {
73
+ grid-column: span 24;
74
+ text-transform: capitalize;
75
+
76
+ padding: var(--legend-padding);
77
+ font: var(--legend-font);
78
+ color: var(--legend-text-color);
79
+ border-bottom: var(--legend-border-bottom);
80
+ }
81
+ `
82
+ ]
83
+ }
84
+
85
+ constructor() {
86
+ super()
87
+ this.selectedProductCombination = {}
88
+ this.productCombinationData = { records: [] }
89
+ }
90
+
91
+ get searchForm() {
92
+ return this.shadowRoot.querySelector('#search-form')
93
+ }
94
+
95
+ get productCombinationGrist() {
96
+ return this.shadowRoot.querySelector('ox-grist#product_combination_grist')
97
+ }
98
+
99
+ render() {
100
+ return html`
101
+ <div class="grist">
102
+ <div class="grist-column">
103
+ <div class="header">
104
+ <legend>${i18next.t('title.combination')}</legend>
105
+ </div>
106
+
107
+ <search-form
108
+ id="search-form"
109
+ .fields=${this.searchFields}
110
+ @submit=${e => this.productCombinationGrist.fetch()}
111
+ ></search-form>
112
+
113
+ <ox-grist
114
+ id="product_combination_grist"
115
+ .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
116
+ .config=${this.productCombinationConfig}
117
+ .data=${this.productCombinationData}
118
+ .fetchHandler="${this.fetchHandler.bind(this)}"
119
+ ></ox-grist>
120
+
121
+ <div class="button-container">
122
+ <mwc-button @click=${this.saveProductCombinations} raised label="${i18next.t('button.save')}"></mwc-button>
123
+ <mwc-button
124
+ danger
125
+ @click=${() => {
126
+ history.back()
127
+ }}
128
+ raised
129
+ label="${i18next.t('button.cancel')}"
130
+ ></mwc-button>
131
+ </div>
132
+ </div>
133
+ ${Object.keys(this.selectedProductCombination).length > 0
134
+ ? html`<div class="grist-column">
135
+ <div class="header">
136
+ <legend>${i18next.t('title.combination_sets')}</legend>
137
+ </div>
138
+ <product-combination-settings-popup
139
+ .record="${this.selectedProductCombination}"
140
+ ></product-combination-settings-popup>
141
+ </div>`
142
+ : html``}
143
+ </div>
144
+ `
145
+ }
146
+
147
+ updated(changedProps) {
148
+ if (changedProps.has('productCombination')) {
149
+ if (Object.keys(this.productCombination).length > 0) {
150
+ this.selectedProductCombination = this.productCombination
151
+ } else {
152
+ this.selectedProductCombination = {}
153
+ }
154
+ }
155
+ }
156
+
157
+ async firstUpdated() {
158
+ this.searchFields = [
159
+ {
160
+ label: i18next.t('field.combination'),
161
+ name: 'name',
162
+ props: { searchOper: 'i_like' }
163
+ },
164
+ {
165
+ label: i18next.t('field.status'),
166
+ name: 'status',
167
+ props: {
168
+ searchOper: 'i_like'
169
+ }
170
+ }
171
+ ]
172
+
173
+ this.productCombinationConfig = {
174
+ pagination: { infinite: true },
175
+ rows: {
176
+ appendable: true,
177
+ handlers: {
178
+ click: (_columns, _data, _column, record, _rowIndex) => {
179
+ if (record && !record?.__dirty__) {
180
+ this.productCombination = record
181
+ } else {
182
+ this.productCombination = {}
183
+ }
184
+ }
185
+ }
186
+ },
187
+ columns: [
188
+ { type: 'gutter', gutterName: 'sequence' },
189
+ {
190
+ type: 'gutter',
191
+ gutterName: 'button',
192
+ icon: 'clear',
193
+ handlers: {
194
+ click: (_columns, _data, _column, record, _rowIndex) => {
195
+ if (record) this.deleteProductCombination(record)
196
+ }
197
+ }
198
+ },
199
+ {
200
+ type: 'string',
201
+ name: 'id',
202
+ hidden: true
203
+ },
204
+ {
205
+ type: 'string',
206
+ name: 'name',
207
+ header: i18next.t('field.combination'),
208
+ sortable: false,
209
+ record: { editable: true },
210
+ width: 150
211
+ },
212
+ {
213
+ type: 'string',
214
+ name: 'status',
215
+ header: i18next.t('field.status'),
216
+ sortable: true,
217
+ width: 100
218
+ }
219
+ ]
220
+ }
221
+ }
222
+
223
+ async fetchHandler({ page, limit, sorters = [] }) {
224
+ try {
225
+ if (!this.productDetailId) return
226
+
227
+ const pagination = { page, limit }
228
+ const sortings = sorters
229
+ let filters = await this.searchForm.getQueryFilters()
230
+ filters = [
231
+ ...filters,
232
+ { name: 'productDetail', operator: 'eq', value: this.productDetailId },
233
+ { name: 'deletedAt', operator: 'is_null', value: '' }
234
+ ]
235
+
236
+ const response = await client.query({
237
+ query: gql`
238
+ query productCombinations($filters: [Filter], $pagination: Pagination, $sortings: [Sorting]) {
239
+ productCombinations(filters: $filters, pagination: $pagination, sortings: $sortings) {
240
+ items {
241
+ id
242
+ name
243
+ status
244
+ product {
245
+ id
246
+ sku
247
+ name
248
+ description
249
+ }
250
+ productDetail {
251
+ id
252
+ name
253
+ gtin
254
+ }
255
+ }
256
+ total
257
+ }
258
+ }
259
+ `,
260
+ variables: { filters, pagination, sortings },
261
+ context: gqlContext()
262
+ })
263
+
264
+ if (!response.errors) {
265
+ this.productCombinationData = {
266
+ total: response.data.productCombinations.total || 0,
267
+ records: response.data.productCombinations.items || []
268
+ }
269
+ }
270
+ } catch (e) {
271
+ this._showToast(e)
272
+ }
273
+ }
274
+
275
+ async deleteProductCombination(record) {
276
+ try {
277
+ const answer = await CustomAlert({
278
+ type: 'warning',
279
+ title: i18next.t('button.delete'),
280
+ text: i18next.t('text.are_you_sure'),
281
+ confirmButton: { text: i18next.t('button.delete') },
282
+ cancelButton: { text: i18next.t('button.cancel') }
283
+ })
284
+
285
+ if (!answer.value) return
286
+
287
+ const response = await client.query({
288
+ query: gql`
289
+ mutation deleteProductCombination($id: String!) {
290
+ deleteProductCombination(id: $id)
291
+ }
292
+ `,
293
+ variables: {
294
+ id: record.id
295
+ },
296
+ context: gqlContext()
297
+ })
298
+ if (!response.errors) {
299
+ this.selectedProductCombination = []
300
+ this.productCombinationGrist.fetch()
301
+ await CustomAlert({
302
+ type: 'success',
303
+ title: i18next.t('text.success'),
304
+ text: ''
305
+ })
306
+ }
307
+ } catch (e) {
308
+ this._showToast(e)
309
+ }
310
+ }
311
+
312
+ async saveProductCombinations() {
313
+ try {
314
+ let patches = this.productCombinationGrist._data.records.map(record => {
315
+ return {
316
+ // only existing product combination will have id
317
+ id: record.id || '',
318
+ name: record.name,
319
+ status: record.status || 'ACTIVE'
320
+ }
321
+ })
322
+ if (patches) {
323
+ const response = await client.query({
324
+ query: gql`
325
+ mutation updateMultipleProductCombination($productDetailId: String!, $patches: [ProductCombinationPatch]!) {
326
+ updateMultipleProductCombination(productDetailId: $productDetailId, patches: $patches) {
327
+ id
328
+ name
329
+ description
330
+ }
331
+ }
332
+ `,
333
+ variables: {
334
+ productDetailId: this.productDetailId,
335
+ patches
336
+ },
337
+ context: gqlContext()
338
+ })
339
+ if (!response.errors) {
340
+ this.selectedProductCombination = []
341
+ this.productCombinationGrist.fetch()
342
+ await CustomAlert({
343
+ type: 'success',
344
+ title: i18next.t('text.success'),
345
+ text: ''
346
+ })
347
+ }
348
+ } else {
349
+ CustomAlert({
350
+ title: i18next.t('text.nothing_changed'),
351
+ text: i18next.t('text.there_is_nothing_to_save')
352
+ })
353
+ }
354
+ } catch (error) {
355
+ this._showToast(error)
356
+ }
357
+ }
358
+
359
+ _showToast({ type, level, message }) {
360
+ document.dispatchEvent(
361
+ new CustomEvent('notify', {
362
+ detail: {
363
+ type,
364
+ level,
365
+ message
366
+ }
367
+ })
368
+ )
369
+ }
370
+ }
371
+
372
+ window.customElements.define('product-combinations-popup', ProductCombinationsPopup)