@things-factory/dataset 8.0.0-beta.8 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. package/client/activities/activity-data-collect-edit.ts +105 -0
  2. package/client/activities/activity-data-collect-view.ts +91 -0
  3. package/client/activities/activity-data-review-edit.ts +133 -0
  4. package/client/activities/activity-data-review-view.ts +145 -0
  5. package/client/activities/activity-ooc-resolve-edit.ts +195 -0
  6. package/client/activities/activity-ooc-resolve-view.ts +143 -0
  7. package/client/activities/activity-ooc-review-edit.ts +173 -0
  8. package/client/activities/activity-ooc-review-view.ts +129 -0
  9. package/client/bootstrap.ts +35 -0
  10. package/client/components/data-entry-form.ts +109 -0
  11. package/client/index.ts +1 -0
  12. package/client/pages/data-archive/data-archive-list-page.ts +277 -0
  13. package/client/pages/data-archive/data-archive-request-popup.ts +177 -0
  14. package/client/pages/data-entry/data-entry-list-page.ts +464 -0
  15. package/client/pages/data-key-set/data-key-item-list.ts +183 -0
  16. package/client/pages/data-key-set/data-key-set-importer.ts +89 -0
  17. package/client/pages/data-key-set/data-key-set-list-page.ts +413 -0
  18. package/client/pages/data-ooc/data-ooc-list-page.ts +549 -0
  19. package/client/pages/data-ooc/data-ooc-page.ts +164 -0
  20. package/client/pages/data-ooc/data-ooc-view.ts +236 -0
  21. package/client/pages/data-ooc/data-oocs-page.ts +200 -0
  22. package/client/pages/data-report/data-report-embed-page.ts +108 -0
  23. package/client/pages/data-report/data-report-list-page.ts +454 -0
  24. package/client/pages/data-report/data-report-samples-page.ts +174 -0
  25. package/client/pages/data-report/jasper-report-oocs-page.ts +110 -0
  26. package/client/pages/data-report/jasper-report-samples-crosstab-page.ts +110 -0
  27. package/client/pages/data-report/jasper-report-samples-page.ts +110 -0
  28. package/client/pages/data-sample/data-sample-list-page.ts +442 -0
  29. package/client/pages/data-sample/data-sample-page.ts +55 -0
  30. package/client/pages/data-sample/data-sample-search-page.ts +424 -0
  31. package/client/pages/data-sample/data-sample-view.ts +292 -0
  32. package/client/pages/data-sample/data-samples-page.ts +249 -0
  33. package/client/pages/data-sensor/data-sensor-list-page.ts +456 -0
  34. package/client/pages/data-set/data-item-list.ts +304 -0
  35. package/client/pages/data-set/data-set-importer.ts +89 -0
  36. package/client/pages/data-set/data-set-list-page.ts +1078 -0
  37. package/client/pages/data-summary/data-summary-list-page.ts +363 -0
  38. package/client/pages/data-summary/data-summary-period-page.ts +439 -0
  39. package/client/pages/data-summary/data-summary-search-page.ts +426 -0
  40. package/client/pages/data-summary/data-summary-view.ts +133 -0
  41. package/client/route.ts +91 -0
  42. package/client/tsconfig.json +13 -0
  43. package/dist-client/pages/data-entry/data-entry-list-page.js +2 -2
  44. package/dist-client/pages/data-entry/data-entry-list-page.js.map +1 -1
  45. package/dist-client/tsconfig.tsbuildinfo +1 -1
  46. package/dist-server/service/data-sample/data-sample-query.d.ts +1 -1
  47. package/dist-server/service/data-sample/data-sample-query.js +3 -3
  48. package/dist-server/service/data-sample/data-sample-query.js.map +1 -1
  49. package/dist-server/tsconfig.tsbuildinfo +1 -1
  50. package/package.json +26 -26
  51. package/server/activities/activity-data-collect.ts +100 -0
  52. package/server/activities/activity-data-review.ts +82 -0
  53. package/server/activities/activity-ooc-resolve.ts +123 -0
  54. package/server/activities/activity-ooc-review.ts +144 -0
  55. package/server/activities/index.ts +11 -0
  56. package/server/controllers/create-data-sample.ts +426 -0
  57. package/server/controllers/data-use-case.ts +98 -0
  58. package/server/controllers/finalize-data-collection.ts +388 -0
  59. package/server/controllers/index.ts +3 -0
  60. package/server/controllers/issue-data-collection-task.ts +70 -0
  61. package/server/controllers/jasper-report.ts +186 -0
  62. package/server/controllers/query-data-summary-by-period.ts +178 -0
  63. package/server/controllers/shiny-report.ts +54 -0
  64. package/server/engine/index.ts +1 -0
  65. package/server/engine/task/create-data-sample.ts +100 -0
  66. package/server/engine/task/index.ts +2 -0
  67. package/server/engine/task/issue-collect-data.ts +45 -0
  68. package/server/index.ts +8 -0
  69. package/server/routes.ts +188 -0
  70. package/server/service/data-archive/data-archive-mutation.ts +273 -0
  71. package/server/service/data-archive/data-archive-query.ts +58 -0
  72. package/server/service/data-archive/data-archive-type.ts +48 -0
  73. package/server/service/data-archive/data-archive.ts +69 -0
  74. package/server/service/data-archive/index.ts +6 -0
  75. package/server/service/data-key-set/data-key-item-type.ts +31 -0
  76. package/server/service/data-key-set/data-key-set-mutation.ts +201 -0
  77. package/server/service/data-key-set/data-key-set-query.ts +68 -0
  78. package/server/service/data-key-set/data-key-set-type.ts +70 -0
  79. package/server/service/data-key-set/data-key-set.ts +86 -0
  80. package/server/service/data-key-set/index.ts +6 -0
  81. package/server/service/data-ooc/data-ooc-mutation.ts +154 -0
  82. package/server/service/data-ooc/data-ooc-query.ts +106 -0
  83. package/server/service/data-ooc/data-ooc-subscription.ts +48 -0
  84. package/server/service/data-ooc/data-ooc-type.ts +71 -0
  85. package/server/service/data-ooc/data-ooc.ts +259 -0
  86. package/server/service/data-ooc/index.ts +7 -0
  87. package/server/service/data-sample/data-sample-mutation.ts +18 -0
  88. package/server/service/data-sample/data-sample-query.ts +215 -0
  89. package/server/service/data-sample/data-sample-type.ts +47 -0
  90. package/server/service/data-sample/data-sample.ts +193 -0
  91. package/server/service/data-sample/index.ts +6 -0
  92. package/server/service/data-sensor/data-sensor-mutation.ts +116 -0
  93. package/server/service/data-sensor/data-sensor-query.ts +76 -0
  94. package/server/service/data-sensor/data-sensor-type.ts +104 -0
  95. package/server/service/data-sensor/data-sensor.ts +126 -0
  96. package/server/service/data-sensor/index.ts +6 -0
  97. package/server/service/data-set/data-item-type.ts +155 -0
  98. package/server/service/data-set/data-set-mutation.ts +552 -0
  99. package/server/service/data-set/data-set-query.ts +461 -0
  100. package/server/service/data-set/data-set-type.ts +204 -0
  101. package/server/service/data-set/data-set.ts +326 -0
  102. package/server/service/data-set/index.ts +6 -0
  103. package/server/service/data-set-history/data-set-history-query.ts +126 -0
  104. package/server/service/data-set-history/data-set-history-type.ts +12 -0
  105. package/server/service/data-set-history/data-set-history.ts +217 -0
  106. package/server/service/data-set-history/event-subscriber.ts +17 -0
  107. package/server/service/data-set-history/index.ts +7 -0
  108. package/server/service/data-spec/data-spec-manager.ts +21 -0
  109. package/server/service/data-spec/data-spec-query.ts +21 -0
  110. package/server/service/data-spec/data-spec.ts +45 -0
  111. package/server/service/data-spec/index.ts +5 -0
  112. package/server/service/data-summary/data-summary-mutation.ts +45 -0
  113. package/server/service/data-summary/data-summary-query.ts +179 -0
  114. package/server/service/data-summary/data-summary-type.ts +86 -0
  115. package/server/service/data-summary/data-summary.ts +170 -0
  116. package/server/service/data-summary/index.ts +7 -0
  117. package/server/service/index.ts +57 -0
  118. package/server/tsconfig.json +10 -0
  119. package/server/utils/config-resolver.ts +29 -0
  120. package/server/utils/index.ts +1 -0
@@ -0,0 +1,439 @@
1
+ import '@material/web/icon/icon.js'
2
+ import '@operato/input/ox-input-select-buttons.js'
3
+ import '@operato/data-grist'
4
+ import '@operato/context/ox-context-page-toolbar.js'
5
+
6
+ import gql from 'graphql-tag'
7
+ import { css, html } from 'lit'
8
+ import { customElement, property, query, state } from 'lit/decorators.js'
9
+ import { connect } from 'pwa-helpers/connect-mixin'
10
+
11
+ import { DataGrist, FetchOption, GristRecord } from '@operato/data-grist'
12
+ import { client } from '@operato/graphql'
13
+ import { i18next, localize } from '@operato/i18n'
14
+ import { PageView, store } from '@operato/shell'
15
+ import { CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'
16
+ import { isMobileDevice } from '@operato/utils'
17
+ import { DataItem } from '@operato/dataset'
18
+
19
+ enum DataSetSummaryGroupType {
20
+ Today = 'today',
21
+ ThisMonth = 'this month',
22
+ ThirtyDays = '30 days',
23
+ ThisYear = 'this year',
24
+ TwelveMonths = '12 months'
25
+ }
26
+
27
+ @customElement('data-summary-period-page')
28
+ export class DataSummaryGroupPage extends connect(store)(localize(i18next)(PageView)) {
29
+ static styles = [
30
+ ScrollbarStyles,
31
+ CommonHeaderStyles,
32
+ css`
33
+ :host {
34
+ display: flex;
35
+ flex-direction: column;
36
+
37
+ overflow: hidden;
38
+ }
39
+
40
+ ox-grist {
41
+ overflow-y: auto;
42
+ flex: 1;
43
+ }
44
+
45
+ .header {
46
+ grid-template-areas: 'filters actions';
47
+ }
48
+ `
49
+ ]
50
+
51
+ @state() dataSetId?: string
52
+ @state() period?: string = DataSetSummaryGroupType.ThisMonth
53
+ @state() withKeys: boolean = false
54
+
55
+ @state() dataSet: any
56
+ @state() dataKeySet: any
57
+ @state() dataItems?: DataItem[]
58
+
59
+ @state() gristConfig: any
60
+ @state() mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'CARD' : 'GRID'
61
+
62
+ @query('ox-grist') private grist!: DataGrist
63
+
64
+ get context() {
65
+ return {
66
+ title: i18next.t('title.data-summary period'),
67
+ help: 'dataset/data-summary-period',
68
+ actions: [
69
+ {
70
+ type: 'icon',
71
+ icon: 'search',
72
+ action: () => {
73
+ this.grist.fetch()
74
+ }
75
+ }
76
+ ],
77
+ exportable: {
78
+ name: i18next.t('title.data-summary period'),
79
+ data: this._exportableData.bind(this)
80
+ },
81
+ toolbar: false
82
+ }
83
+ }
84
+
85
+ render() {
86
+ const mode = this.mode || (isMobileDevice() ? 'LIST' : 'GRID')
87
+
88
+ return html`
89
+ <ox-grist .mode=${mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>
90
+ <div slot="headroom" class="header">
91
+ <div
92
+ class="filters"
93
+ @change=${(e: CustomEvent) => {
94
+ const element = e.target as Element
95
+ if (element?.hasAttribute('period')) {
96
+ this.period = (element as any)?.value
97
+ } else if (element?.hasAttribute('with-keys')) {
98
+ this.withKeys = (element as any)?.checked
99
+ }
100
+
101
+ this.refreshGristConfig()
102
+ this.grist.fetch()
103
+ }}
104
+ >
105
+ <ox-input-select-buttons
106
+ class="filter"
107
+ .value=${this.period}
108
+ .options=${[
109
+ {
110
+ display: i18next.t('label.period-this-month'),
111
+ value: 'this month'
112
+ },
113
+ {
114
+ display: i18next.t('label.period-30-days'),
115
+ value: '30 days'
116
+ },
117
+ {
118
+ display: i18next.t('label.period-this-year'),
119
+ value: 'this year'
120
+ },
121
+ {
122
+ display: i18next.t('label.period-12-months'),
123
+ value: '12 months'
124
+ },
125
+ {
126
+ display: i18next.t('label.period-today'),
127
+ value: 'today'
128
+ }
129
+ ]}
130
+ period
131
+ ></ox-input-select-buttons>
132
+
133
+ <ox-checkbox class="filter" with-keys>${i18next.t('label.group-by data-keys')}</ox-checkbox>
134
+ </div>
135
+
136
+ <ox-context-page-toolbar class="actions" .context=${this.context}></ox-context-page-toolbar>
137
+ </div>
138
+ </ox-grist>
139
+ `
140
+ }
141
+
142
+ pageUpdated(changes, lifecycle) {
143
+ if (this.active) {
144
+ this.dataSetId = lifecycle.resourceId
145
+ return
146
+ }
147
+ }
148
+
149
+ async updated(changes) {
150
+ if (changes.has('dataSetId')) {
151
+ const response = await client.query({
152
+ query: gql`
153
+ query ($id: String!) {
154
+ dataSet(id: $id) {
155
+ id
156
+ name
157
+ summaryPeriod
158
+ dataItems {
159
+ name
160
+ description
161
+ active
162
+ hidden
163
+ tag
164
+ group
165
+ type
166
+ unit
167
+ options
168
+ quota
169
+ spec
170
+ stat
171
+ }
172
+ dataKeySet {
173
+ id
174
+ name
175
+ description
176
+ dataKeyItems {
177
+ name
178
+ description
179
+ dataKey
180
+ tKey
181
+ }
182
+ }
183
+ }
184
+ }
185
+ `,
186
+ variables: {
187
+ id: this.dataSetId
188
+ }
189
+ })
190
+
191
+ this.dataSet = response.data?.dataSet
192
+ this.dataKeySet = this.dataSet?.dataKeySet || {}
193
+ this.dataItems = this.dataSet?.dataItems || []
194
+
195
+ this.refreshGristConfig()
196
+ this.grist.fetch()
197
+ }
198
+ }
199
+
200
+ getKeyColumns() {
201
+ if (!this.withKeys) {
202
+ return []
203
+ }
204
+
205
+ return (
206
+ this.dataKeySet?.dataKeyItems.map((item, index) => {
207
+ return {
208
+ type: 'string',
209
+ name: `key0${index + 1}`,
210
+ header: i18next.t(item.tKey),
211
+ label: true,
212
+ record: {
213
+ editable: false
214
+ },
215
+ sortable: true,
216
+ filter: 'i_like',
217
+ width: 120,
218
+ imex: true
219
+ }
220
+ }) || []
221
+ )
222
+ }
223
+
224
+ getDataColumns() {
225
+ return (
226
+ this.dataItems
227
+ ?.filter(dataItem => dataItem.active && dataItem.stat)
228
+ .map((item, index) => {
229
+ return {
230
+ type: 'number',
231
+ name: `data0${index + 1}`,
232
+ header: i18next.t(item.name),
233
+ label: true,
234
+ record: {
235
+ editable: false
236
+ },
237
+ width: 120,
238
+ imex: true
239
+ }
240
+ }) || []
241
+ )
242
+ }
243
+
244
+ refreshGristConfig() {
245
+ const keyColumns = this.getKeyColumns()
246
+ const dataColumns = this.getDataColumns()
247
+
248
+ const listFields = [] as string[]
249
+ if (this.period == DataSetSummaryGroupType.ThisYear || this.period == DataSetSummaryGroupType.TwelveMonths) {
250
+ listFields.push('month')
251
+ }
252
+ if (this.period != DataSetSummaryGroupType.ThisYear && this.period != DataSetSummaryGroupType.TwelveMonths) {
253
+ listFields.push('date')
254
+ }
255
+ if (this.period == DataSetSummaryGroupType.Today) {
256
+ listFields.push('period')
257
+ }
258
+
259
+ keyColumns.map(col => listFields.push(col.name))
260
+ dataColumns.map(col => listFields.push(col.name))
261
+
262
+ listFields.push('count', 'countOoc', 'countOos')
263
+
264
+ this.gristConfig = {
265
+ list: { fields: listFields },
266
+ columns: [
267
+ { type: 'gutter', gutterName: 'sequence', fixed: true },
268
+ (this.period == DataSetSummaryGroupType.ThisYear || this.period == DataSetSummaryGroupType.TwelveMonths) && {
269
+ type: 'string',
270
+ name: 'month',
271
+ fixed: true,
272
+ header: i18next.t('field.month'),
273
+ label: true,
274
+ width: 80,
275
+ sortable: true,
276
+ imex: true
277
+ },
278
+ this.period != DataSetSummaryGroupType.ThisYear &&
279
+ this.period != DataSetSummaryGroupType.TwelveMonths && {
280
+ type: 'string',
281
+ name: 'date',
282
+ fixed: true,
283
+ header: i18next.t('field.date'),
284
+ label: true,
285
+ sortable: true,
286
+ width: 80,
287
+ imex: true
288
+ },
289
+ this.period == DataSetSummaryGroupType.Today && {
290
+ type: 'string',
291
+ name: 'period',
292
+ fixed: true,
293
+ header: i18next.t('field.time-period'),
294
+ label: true,
295
+ sortable: true,
296
+ width: 80,
297
+ imex: true
298
+ },
299
+ ...keyColumns,
300
+ ...dataColumns,
301
+ {
302
+ type: 'number',
303
+ name: 'count',
304
+ header: i18next.t('field.count'),
305
+ label: true,
306
+ record: {
307
+ editable: false
308
+ },
309
+ width: 30
310
+ },
311
+ {
312
+ type: 'number',
313
+ name: 'countOoc',
314
+ label: true,
315
+ header: i18next.t('field.count-ooc'),
316
+ record: {
317
+ editable: false
318
+ },
319
+ width: 30
320
+ },
321
+ {
322
+ type: 'number',
323
+ name: 'countOos',
324
+ header: i18next.t('field.count-oos'),
325
+ label: true,
326
+ record: {
327
+ editable: false
328
+ },
329
+ width: 30
330
+ }
331
+ ].filter(Boolean),
332
+ pagination: {
333
+ infinite: true
334
+ },
335
+ rows: {
336
+ appendable: false,
337
+ selectable: {
338
+ multiple: true
339
+ }
340
+ }
341
+ }
342
+ }
343
+
344
+ async fetchHandler({ page, limit, sortings = [], filters = [] }: FetchOption) {
345
+ if (!this.dataSetId) {
346
+ return { records: [], total: 0 }
347
+ }
348
+
349
+ const response = await client.query({
350
+ query: gql`
351
+ query (
352
+ $dataSetName: String!
353
+ $period: String!
354
+ $dataKeys: [String!]
355
+ $filters: [Filter!]
356
+ $pagination: Pagination
357
+ $sortings: [Sorting!]
358
+ ) {
359
+ dataSummaryByPeriod(
360
+ dataSetName: $dataSetName
361
+ period: $period
362
+ dataKeys: $dataKeys
363
+ filters: $filters
364
+ pagination: $pagination
365
+ sortings: $sortings
366
+ ) {
367
+ month
368
+ date
369
+ period
370
+ key01
371
+ key02
372
+ key03
373
+ key04
374
+ key05
375
+ data01
376
+ data02
377
+ data03
378
+ data04
379
+ data05
380
+ count
381
+ countOoc
382
+ countOos
383
+ }
384
+ }
385
+ `,
386
+ variables: {
387
+ dataSetName: this.dataSet.name,
388
+ period: this.period,
389
+ dataKeys: this.withKeys ? null : [],
390
+ filters,
391
+ pagination: { page, limit },
392
+ sortings
393
+ }
394
+ })
395
+
396
+ return {
397
+ records: response.data?.dataSummaryByPeriod || []
398
+ }
399
+ }
400
+
401
+ _exportableData() {
402
+ let records = [] as GristRecord[]
403
+ if (this.grist.selected && this.grist.selected.length > 0) {
404
+ records = this.grist.selected
405
+ } else {
406
+ records = this.grist.data.records
407
+ }
408
+
409
+ var headerSetting = this.grist.compiledConfig.columns
410
+ .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
411
+ .map(column => {
412
+ return column.imex === true
413
+ ? {
414
+ header: column.header.renderer(column),
415
+ key: column.name,
416
+ width: column.width,
417
+ type: column.type
418
+ }
419
+ : column.imex
420
+ })
421
+
422
+ var data = records.map(item => {
423
+ return {
424
+ id: item.id,
425
+ ...this.gristConfig.columns
426
+ .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
427
+ .reduce((record, column) => {
428
+ const key = column.imex === true ? column.name : column.imex.key
429
+ record[key] = key
430
+ .split('.')
431
+ .reduce((obj, key) => (obj && obj[key] !== 'undefined' ? obj[key] : undefined), item)
432
+ return record
433
+ }, {})
434
+ }
435
+ })
436
+
437
+ return { header: headerSetting, data: data }
438
+ }
439
+ }