@things-factory/dataset 5.0.0-alpha.2 → 5.0.0-alpha.22

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 (96) hide show
  1. package/README.md +13 -0
  2. package/assets/data-samples.jpg +0 -0
  3. package/client/bootstrap.js +16 -1
  4. package/client/pages/data-entry-form.js +84 -0
  5. package/client/pages/data-item-list.js +58 -16
  6. package/client/pages/data-ooc-view.js +182 -0
  7. package/client/pages/data-ooc.js +487 -0
  8. package/client/pages/data-sample-view.js +97 -0
  9. package/client/pages/data-sample.js +149 -56
  10. package/client/pages/data-sensor.js +8 -18
  11. package/client/pages/data-set.js +200 -75
  12. package/client/route.js +4 -0
  13. package/dist-server/controllers/create-data-sample.js +124 -0
  14. package/dist-server/controllers/create-data-sample.js.map +1 -0
  15. package/dist-server/controllers/data-use-case.js +57 -0
  16. package/dist-server/controllers/data-use-case.js.map +1 -0
  17. package/dist-server/controllers/index.js +17 -0
  18. package/dist-server/controllers/index.js.map +1 -1
  19. package/dist-server/index.js +2 -0
  20. package/dist-server/index.js.map +1 -1
  21. package/dist-server/routes.js +9 -24
  22. package/dist-server/routes.js.map +1 -1
  23. package/dist-server/service/data-item/data-item-mutation.js +5 -1
  24. package/dist-server/service/data-item/data-item-mutation.js.map +1 -1
  25. package/dist-server/service/data-item/data-item-type.js +14 -5
  26. package/dist-server/service/data-item/data-item-type.js.map +1 -1
  27. package/dist-server/service/data-item/data-item.js +20 -7
  28. package/dist-server/service/data-item/data-item.js.map +1 -1
  29. package/dist-server/service/data-ooc/data-ooc-mutation.js +92 -0
  30. package/dist-server/service/data-ooc/data-ooc-mutation.js.map +1 -0
  31. package/dist-server/service/data-ooc/data-ooc-query.js +115 -0
  32. package/dist-server/service/data-ooc/data-ooc-query.js.map +1 -0
  33. package/dist-server/service/data-ooc/data-ooc-subscription.js +65 -0
  34. package/dist-server/service/data-ooc/data-ooc-subscription.js.map +1 -0
  35. package/dist-server/service/data-ooc/data-ooc-type.js +107 -0
  36. package/dist-server/service/data-ooc/data-ooc-type.js.map +1 -0
  37. package/dist-server/service/data-ooc/data-ooc.js +237 -0
  38. package/dist-server/service/data-ooc/data-ooc.js.map +1 -0
  39. package/dist-server/service/data-ooc/index.js +10 -0
  40. package/dist-server/service/data-ooc/index.js.map +1 -0
  41. package/dist-server/service/data-sample/data-sample-mutation.js +3 -105
  42. package/dist-server/service/data-sample/data-sample-mutation.js.map +1 -1
  43. package/dist-server/service/data-sample/data-sample-type.js +13 -42
  44. package/dist-server/service/data-sample/data-sample-type.js.map +1 -1
  45. package/dist-server/service/data-sample/data-sample.js +40 -9
  46. package/dist-server/service/data-sample/data-sample.js.map +1 -1
  47. package/dist-server/service/data-set/data-set-mutation.js +1 -2
  48. package/dist-server/service/data-set/data-set-mutation.js.map +1 -1
  49. package/dist-server/service/data-set/data-set-query.js +12 -0
  50. package/dist-server/service/data-set/data-set-query.js.map +1 -1
  51. package/dist-server/service/data-set/data-set-type.js +19 -2
  52. package/dist-server/service/data-set/data-set-type.js.map +1 -1
  53. package/dist-server/service/data-set/data-set.js +22 -10
  54. package/dist-server/service/data-set/data-set.js.map +1 -1
  55. package/dist-server/service/data-spec/data-spec-manager.js +20 -0
  56. package/dist-server/service/data-spec/data-spec-manager.js.map +1 -0
  57. package/dist-server/service/data-spec/data-spec-query.js +48 -0
  58. package/dist-server/service/data-spec/data-spec-query.js.map +1 -0
  59. package/dist-server/service/data-spec/data-spec.js +78 -0
  60. package/dist-server/service/data-spec/data-spec.js.map +1 -0
  61. package/dist-server/service/data-spec/index.js +8 -0
  62. package/dist-server/service/data-spec/index.js.map +1 -0
  63. package/dist-server/service/index.js +12 -4
  64. package/dist-server/service/index.js.map +1 -1
  65. package/package.json +15 -12
  66. package/server/controllers/create-data-sample.ts +166 -0
  67. package/server/controllers/data-use-case.ts +85 -0
  68. package/server/controllers/index.ts +1 -0
  69. package/server/index.ts +3 -0
  70. package/server/routes.ts +17 -31
  71. package/server/service/data-item/data-item-mutation.ts +6 -1
  72. package/server/service/data-item/data-item-type.ts +11 -7
  73. package/server/service/data-item/data-item.ts +16 -6
  74. package/server/service/data-ooc/data-ooc-mutation.ts +150 -0
  75. package/server/service/data-ooc/data-ooc-query.ts +63 -0
  76. package/server/service/data-ooc/data-ooc-subscription.ts +51 -0
  77. package/server/service/data-ooc/data-ooc-type.ts +68 -0
  78. package/server/service/data-ooc/data-ooc.ts +204 -0
  79. package/server/service/data-ooc/index.ts +7 -0
  80. package/server/service/data-sample/data-sample-mutation.ts +6 -128
  81. package/server/service/data-sample/data-sample-type.ts +8 -29
  82. package/server/service/data-sample/data-sample.ts +36 -6
  83. package/server/service/data-set/data-set-mutation.ts +1 -4
  84. package/server/service/data-set/data-set-query.ts +8 -1
  85. package/server/service/data-set/data-set-type.ts +17 -6
  86. package/server/service/data-set/data-set.ts +18 -8
  87. package/server/service/data-spec/data-spec-manager.ts +21 -0
  88. package/server/service/data-spec/data-spec-query.ts +21 -0
  89. package/server/service/data-spec/data-spec.ts +44 -0
  90. package/server/service/data-spec/index.ts +5 -0
  91. package/server/service/index.ts +16 -8
  92. package/things-factory.config.js +4 -0
  93. package/translations/en.json +21 -0
  94. package/translations/ko.json +22 -1
  95. package/translations/ms.json +21 -0
  96. package/translations/zh.json +21 -0
@@ -0,0 +1,487 @@
1
+ import '@operato/data-grist'
2
+ import './data-ooc-view.js'
3
+
4
+ import gql from 'graphql-tag'
5
+ import { css, html } from 'lit'
6
+ import { connect } from 'pwa-helpers/connect-mixin'
7
+
8
+ import { client } from '@operato/graphql'
9
+ import { i18next, localize } from '@operato/i18n'
10
+ import { openPopup } from '@operato/layout'
11
+ import { PageView, store } from '@operato/shell'
12
+ import { ScrollbarStyles } from '@operato/styles'
13
+ import { isMobileDevice } from '@operato/utils'
14
+
15
+ export class DataOoc extends connect(store)(localize(i18next)(PageView)) {
16
+ static get properties() {
17
+ return {
18
+ active: String,
19
+ gristConfig: Object
20
+ }
21
+ }
22
+
23
+ static get styles() {
24
+ return [
25
+ ScrollbarStyles,
26
+ css`
27
+ :host {
28
+ display: flex;
29
+ flex-direction: column;
30
+
31
+ overflow: hidden;
32
+ }
33
+
34
+ ox-grist {
35
+ overflow-y: auto;
36
+ flex: 1;
37
+ }
38
+
39
+ #filters {
40
+ display: flex;
41
+ flex-direction: row;
42
+ justify-content: space-between;
43
+
44
+ background-color: white;
45
+ }
46
+
47
+ #filters > * {
48
+ padding: var(--padding-default) var(--padding-wide);
49
+ }
50
+ `
51
+ ]
52
+ }
53
+
54
+ get context() {
55
+ return {
56
+ title: i18next.t('title.data-ooc list'),
57
+ help: 'integration/ui/data-ooc',
58
+ actions: [
59
+ // {
60
+ // title: i18next.t('button.save'),
61
+ // action: this._updateDataOoc.bind(this),
62
+ // ...CommonButtonStyles.save
63
+ // }
64
+ ],
65
+ exportable: {
66
+ name: i18next.t('title.data-ooc list'),
67
+ data: this._exportableData.bind(this)
68
+ }
69
+ }
70
+ }
71
+
72
+ render() {
73
+ return html`
74
+ <ox-grist
75
+ .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
76
+ .config=${this.gristConfig}
77
+ .fetchHandler=${this.fetchHandler.bind(this)}
78
+ >
79
+ <div slot="headroom" id="filters">
80
+ <ox-filters-form></ox-filters-form>
81
+ </div>
82
+ </ox-grist>
83
+ `
84
+ }
85
+
86
+ get grist() {
87
+ return this.renderRoot.querySelector('ox-grist')
88
+ }
89
+
90
+ // update with url params value
91
+ _updateSearchConfig(lifecycle) {
92
+ // this.searchConfig = this.searchConfig.map(conf => {
93
+ // if (conf.name in lifecycle.params) {
94
+ // conf.value = lifecycle.params[conf.name]
95
+ // } else {
96
+ // delete conf.value
97
+ // }
98
+ // return conf
99
+ // })
100
+ }
101
+
102
+ // set default field value to record with searchConfig
103
+ _setDefaultFieldsValue(fields) {
104
+ // this.searchConfig.forEach(conf => {
105
+ // if (!fields[conf.name] && conf.value) {
106
+ // fields[conf.name] = conf.value
107
+ // }
108
+ // })
109
+ }
110
+
111
+ async pageInitialized(lifecycle) {
112
+ this._updateSearchConfig(lifecycle)
113
+
114
+ this.gristConfig = {
115
+ list: {
116
+ fields: ['dataSet', 'data', 'spec', 'correctiveAction', 'corrector', 'correctedAt', 'collectedAt', 'creator']
117
+ },
118
+ columns: [
119
+ { type: 'gutter', gutterName: 'sequence' },
120
+ { type: 'gutter', gutterName: 'row-selector', multiple: true },
121
+ {
122
+ type: 'gutter',
123
+ gutterName: 'button',
124
+ icon: 'assignment_turned_in',
125
+ handlers: {
126
+ click: (columns, data, column, record, rowIndex) => {
127
+ const popup = openPopup(
128
+ html` <data-ooc-view .dataOoc=${record} style="background-color: white;"></data-ooc-view> `,
129
+ {
130
+ backdrop: true,
131
+ size: 'large',
132
+ title: i18next.t('title.data-ooc view')
133
+ }
134
+ )
135
+ popup.onclosed = () => {
136
+ this.grist.fetch()
137
+ }
138
+ }
139
+ }
140
+ },
141
+ {
142
+ type: 'string',
143
+ name: 'name',
144
+ label: true,
145
+ header: i18next.t('field.name'),
146
+ record: {
147
+ editable: true
148
+ },
149
+ filter: 'search',
150
+ sortable: true,
151
+ width: 120,
152
+ imex: true
153
+ },
154
+ {
155
+ type: 'string',
156
+ name: 'description',
157
+ label: true,
158
+ header: i18next.t('field.description'),
159
+ record: {
160
+ editable: true
161
+ },
162
+ filter: 'search',
163
+ width: 150,
164
+ imex: true
165
+ },
166
+ {
167
+ type: 'string',
168
+ name: 'history',
169
+ hidden: true,
170
+ imex: true
171
+ },
172
+ {
173
+ type: 'checkbox',
174
+ name: 'ooc',
175
+ header: i18next.t('field.ooc'),
176
+ record: {
177
+ editable: false
178
+ },
179
+ width: 30
180
+ },
181
+ {
182
+ type: 'checkbox',
183
+ name: 'oos',
184
+ header: i18next.t('field.oos'),
185
+ record: {
186
+ editable: false
187
+ },
188
+ width: 30
189
+ },
190
+ {
191
+ type: 'select',
192
+ name: 'state',
193
+ label: true,
194
+ header: i18next.t('field.state'),
195
+ record: {
196
+ editable: false,
197
+ options: ['', 'CREATED', 'REVIEWED', 'CORRECTED']
198
+ },
199
+ width: 100,
200
+ filter: true,
201
+ imex: true
202
+ },
203
+ {
204
+ type: 'textarea',
205
+ name: 'correctiveAction',
206
+ label: true,
207
+ header: i18next.t('field.corrective-action'),
208
+ record: {
209
+ editable: true
210
+ },
211
+ width: 150,
212
+ imex: true
213
+ },
214
+ {
215
+ type: 'resource-object',
216
+ name: 'dataSet',
217
+ header: i18next.t('field.data-set'),
218
+ record: {
219
+ editable: false
220
+ },
221
+ sortable: true,
222
+ width: 120,
223
+ imex: true
224
+ },
225
+ {
226
+ type: 'json5',
227
+ name: 'partitionKeys',
228
+ header: i18next.t('field.partition-keys'),
229
+ record: {
230
+ editable: false
231
+ },
232
+ width: 200,
233
+ imex: true
234
+ },
235
+ {
236
+ type: 'json5',
237
+ name: 'data',
238
+ header: i18next.t('field.data'),
239
+ record: {
240
+ editable: false
241
+ },
242
+ width: 200,
243
+ imex: true
244
+ },
245
+ {
246
+ type: 'json5',
247
+ name: 'spec',
248
+ header: i18next.t('field.spec'),
249
+ record: {
250
+ editable: false
251
+ },
252
+ width: 200
253
+ },
254
+ {
255
+ type: 'text',
256
+ name: 'rawData',
257
+ header: i18next.t('field.raw-data'),
258
+ record: {
259
+ editable: false
260
+ },
261
+ width: 200,
262
+ imex: true
263
+ },
264
+ {
265
+ type: 'string',
266
+ name: 'workDate',
267
+ header: i18next.t('field.work-date'),
268
+ sortable: true,
269
+ width: 80,
270
+ imex: true
271
+ },
272
+ {
273
+ type: 'string',
274
+ name: 'workShift',
275
+ header: i18next.t('field.work-shift'),
276
+ sortable: true,
277
+ width: 40,
278
+ imex: true
279
+ },
280
+ {
281
+ type: 'datetime',
282
+ name: 'collectedAt',
283
+ header: i18next.t('field.collected_at'),
284
+ sortable: true,
285
+ width: 180,
286
+ imex: true
287
+ },
288
+ {
289
+ type: 'resource-object',
290
+ name: 'updater',
291
+ header: i18next.t('field.updater'),
292
+ sortable: true,
293
+ width: 120,
294
+ imex: true
295
+ },
296
+ {
297
+ type: 'datetime',
298
+ name: 'updatedAt',
299
+ header: i18next.t('field.updated_at'),
300
+ sortable: true,
301
+ width: 180,
302
+ imex: true
303
+ }
304
+ ],
305
+ rows: {
306
+ appendable: false,
307
+ selectable: {
308
+ multiple: true
309
+ }
310
+ },
311
+ sorters: [
312
+ {
313
+ name: 'updatedAt',
314
+ desc: true
315
+ }
316
+ ]
317
+ }
318
+
319
+ await this.updateComplete
320
+
321
+ this.grist.fetch()
322
+ }
323
+
324
+ async pageUpdated(changes, lifecycle) {
325
+ if (this.active) {
326
+ // update with url params value
327
+ this._updateSearchConfig(lifecycle)
328
+ await this.updateComplete
329
+
330
+ this.grist.fetch()
331
+ }
332
+ }
333
+
334
+ async fetchHandler({ page, limit, sortings = [], filters = [] }) {
335
+ const response = await client.query({
336
+ query: gql`
337
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
338
+ responses: dataOocs(filters: $filters, pagination: $pagination, sortings: $sortings) {
339
+ items {
340
+ id
341
+ name
342
+ description
343
+ dataSet {
344
+ id
345
+ name
346
+ }
347
+ dataSample {
348
+ id
349
+ name
350
+ }
351
+ partitionKeys
352
+ data
353
+ state
354
+ spec
355
+ ooc
356
+ oos
357
+ history
358
+ workDate
359
+ workShift
360
+ correctiveAction
361
+ correctedAt
362
+ corrector {
363
+ id
364
+ name
365
+ }
366
+ updater {
367
+ id
368
+ name
369
+ }
370
+ updatedAt
371
+ collectedAt
372
+ }
373
+ total
374
+ }
375
+ }
376
+ `,
377
+ variables: {
378
+ filters,
379
+ pagination: { page, limit },
380
+ sortings
381
+ }
382
+ })
383
+
384
+ return {
385
+ total: response.data.responses.total || 0,
386
+ records: response.data.responses.items || []
387
+ }
388
+ }
389
+
390
+ // async _updateDataOoc() {
391
+ // let patches = this.grist.dirtyRecords
392
+ // if (patches && patches.length) {
393
+ // patches = patches.map(patch => {
394
+ // let patchField = patch.id ? { id: patch.id } : {}
395
+ // const dirtyFields = patch.__dirtyfields__
396
+ // for (let key in dirtyFields) {
397
+ // patchField[key] = dirtyFields[key].after
398
+ // }
399
+ // this._setDefaultFieldsValue(patchField)
400
+ // patchField.cuFlag = patch.__dirty__
401
+
402
+ // return patchField
403
+ // })
404
+
405
+ // const response = await client.mutate({
406
+ // mutation: gql`
407
+ // mutation ($patches: [DataOocPatch!]!) {
408
+ // updateMultipleDataOoc(patches: $patches) {
409
+ // name
410
+ // }
411
+ // }
412
+ // `,
413
+ // variables: {
414
+ // patches
415
+ // }
416
+ // })
417
+
418
+ // if (!response.errors) this.grist.fetch()
419
+ // }
420
+ // }
421
+
422
+ // async _deleteDataOoc() {
423
+ // if (confirm(i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }))) {
424
+ // const ids = this.grist.selected.map(record => record.id)
425
+ // if (ids && ids.length > 0) {
426
+ // const response = await client.mutate({
427
+ // mutation: gql`
428
+ // mutation ($ids: [String!]!) {
429
+ // deleteDataOocs(ids: $ids)
430
+ // }
431
+ // `,
432
+ // variables: {
433
+ // ids
434
+ // }
435
+ // })
436
+
437
+ // if (!response.errors) {
438
+ // this.grist.fetch()
439
+ // notify({
440
+ // message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
441
+ // })
442
+ // }
443
+ // }
444
+ // }
445
+ // }
446
+
447
+ _exportableData() {
448
+ let records = []
449
+ if (this.grist.selected && this.grist.selected.length > 0) {
450
+ records = this.grist.selected
451
+ } else {
452
+ records = this.grist.data.records
453
+ }
454
+
455
+ var headerSetting = this.grist.compiledConfig.columns
456
+ .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
457
+ .map(column => {
458
+ return column.imex === true
459
+ ? {
460
+ header: column.header.renderer(),
461
+ key: column.name,
462
+ width: column.width,
463
+ type: column.type
464
+ }
465
+ : column.imex
466
+ })
467
+
468
+ var data = records.map(item => {
469
+ return {
470
+ id: item.id,
471
+ ...this.gristConfig.columns
472
+ .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
473
+ .reduce((record, column) => {
474
+ const key = column.imex === true ? column.name : column.imex.key
475
+ record[key] = key
476
+ .split('.')
477
+ .reduce((obj, key) => (obj && obj[key] !== 'undefined' ? obj[key] : undefined), item)
478
+ return record
479
+ }, {})
480
+ }
481
+ })
482
+
483
+ return { header: headerSetting, data: data }
484
+ }
485
+ }
486
+
487
+ window.customElements.define('data-ooc-page', DataOoc)
@@ -0,0 +1,97 @@
1
+ import '@operato/dataset/ox-data-sample-view.js'
2
+
3
+ import { LitElement, css, html } from 'lit'
4
+ import { i18next, localize } from '@operato/i18n'
5
+
6
+ import { ScrollbarStyles } from '@operato/styles'
7
+ import { client } from '@operato/graphql'
8
+ import gql from 'graphql-tag'
9
+
10
+ class DataSampleView extends localize(i18next)(LitElement) {
11
+ static get properties() {
12
+ return {
13
+ dataSet: Object,
14
+ dataSample: Object
15
+ }
16
+ }
17
+
18
+ static get styles() {
19
+ return [
20
+ ScrollbarStyles,
21
+ css`
22
+ :host {
23
+ display: flex;
24
+ flex-direction: column;
25
+
26
+ background-color: #fff;
27
+ }
28
+
29
+ div[content] {
30
+ flex: 1;
31
+
32
+ display: flex;
33
+ overflow: auto;
34
+ }
35
+
36
+ ox-data-sample-view {
37
+ flex: 1;
38
+ padding: var(--padding-wide);
39
+ }
40
+ `
41
+ ]
42
+ }
43
+
44
+ get sampleView() {
45
+ return this.renderRoot.querySelector('ox-data-sample-view')
46
+ }
47
+
48
+ render() {
49
+ return html`
50
+ <div content>
51
+ <ox-data-sample-view .dataSet=${this.dataSet} .dataSample=${this.dataSample}></ox-data-sample-view>
52
+ </div>
53
+ `
54
+ }
55
+
56
+ updated(changes) {
57
+ if (changes.has('dataSample')) {
58
+ this.fetchDataSet()
59
+ }
60
+ }
61
+
62
+ async fetchDataSet() {
63
+ const id = this.dataSample?.dataSet?.id
64
+
65
+ if (id) {
66
+ const response = await client.query({
67
+ query: gql`
68
+ query ($id: String!) {
69
+ dataSet(id: $id) {
70
+ id
71
+ name
72
+ description
73
+ useCase
74
+ dataItems {
75
+ id
76
+ name
77
+ description
78
+ active
79
+ unit
80
+ tag
81
+ type
82
+ spec
83
+ }
84
+ }
85
+ }
86
+ `,
87
+ variables: {
88
+ id: this.dataSample.dataSet.id
89
+ }
90
+ })
91
+
92
+ this.dataSet = response.data.dataSet
93
+ }
94
+ }
95
+ }
96
+
97
+ window.customElements.define('data-sample-view', DataSampleView)