@things-factory/dataset 6.0.67 → 6.0.70

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 (56) hide show
  1. package/client/pages/data-set/data-set-list-page.ts +1 -1
  2. package/client/pages/data-summary/data-summary-list-page.ts +390 -0
  3. package/client/pages/data-summary/data-summary-search-page.ts +417 -0
  4. package/client/pages/data-summary/data-summary-view.ts +119 -0
  5. package/client/route.ts +12 -0
  6. package/dist-client/pages/data-set/data-set-list-page.js +1 -1
  7. package/dist-client/pages/data-set/data-set-list-page.js.map +1 -1
  8. package/dist-client/pages/data-summary/data-summary-importer.d.ts +22 -0
  9. package/dist-client/pages/data-summary/data-summary-importer.js +100 -0
  10. package/dist-client/pages/data-summary/data-summary-importer.js.map +1 -0
  11. package/dist-client/pages/data-summary/data-summary-list-page.d.ts +57 -0
  12. package/dist-client/pages/data-summary/data-summary-list-page.js +389 -0
  13. package/dist-client/pages/data-summary/data-summary-list-page.js.map +1 -0
  14. package/dist-client/pages/data-summary/data-summary-search-page.d.ts +63 -0
  15. package/dist-client/pages/data-summary/data-summary-search-page.js +407 -0
  16. package/dist-client/pages/data-summary/data-summary-search-page.js.map +1 -0
  17. package/dist-client/pages/data-summary/data-summary-view.d.ts +1 -0
  18. package/dist-client/pages/data-summary/data-summary-view.js +100 -0
  19. package/dist-client/pages/data-summary/data-summary-view.js.map +1 -0
  20. package/dist-client/route.js +9 -0
  21. package/dist-client/route.js.map +1 -1
  22. package/dist-client/tsconfig.tsbuildinfo +1 -1
  23. package/dist-server/controllers/create-data-sample.js +1 -1
  24. package/dist-server/controllers/create-data-sample.js.map +1 -1
  25. package/dist-server/controllers/generate-data-summary.js +94 -0
  26. package/dist-server/controllers/generate-data-summary.js.map +1 -0
  27. package/dist-server/controllers/generate-summary-data.js +88 -0
  28. package/dist-server/controllers/generate-summary-data.js.map +1 -0
  29. package/dist-server/service/data-summary/data-summary-mutation.js +28 -0
  30. package/dist-server/service/data-summary/data-summary-mutation.js.map +1 -0
  31. package/dist-server/service/data-summary/data-summary-query.js +136 -0
  32. package/dist-server/service/data-summary/data-summary-query.js.map +1 -0
  33. package/dist-server/service/data-summary/data-summary-type.js +57 -0
  34. package/dist-server/service/data-summary/data-summary-type.js.map +1 -0
  35. package/dist-server/service/data-summary/data-summary.js +188 -0
  36. package/dist-server/service/data-summary/data-summary.js.map +1 -0
  37. package/dist-server/service/data-summary/index.js +10 -0
  38. package/dist-server/service/data-summary/index.js.map +1 -0
  39. package/dist-server/service/index.js +4 -0
  40. package/dist-server/service/index.js.map +1 -1
  41. package/dist-server/tsconfig.tsbuildinfo +1 -1
  42. package/helps/dataset/data-summary.md +160 -0
  43. package/package.json +5 -5
  44. package/server/controllers/create-data-sample.ts +1 -1
  45. package/server/controllers/generate-data-summary.ts +124 -0
  46. package/server/service/data-summary/data-summary-mutation.ts +19 -0
  47. package/server/service/data-summary/data-summary-query.ts +96 -0
  48. package/server/service/data-summary/data-summary-type.ts +40 -0
  49. package/server/service/data-summary/data-summary.ts +165 -0
  50. package/server/service/data-summary/index.ts +7 -0
  51. package/server/service/index.ts +4 -0
  52. package/things-factory.config.js +10 -1
  53. package/translations/en.json +8 -0
  54. package/translations/ko.json +8 -0
  55. package/translations/ms.json +8 -0
  56. package/translations/zh.json +8 -0
@@ -248,7 +248,7 @@ export class DataSetListPage extends connect(store)(localize(i18next)(PageView))
248
248
  type: 'gutter',
249
249
  gutterName: 'button',
250
250
  title: i18next.t('title.data collecting schedule (un)register'),
251
- icon: record => (!record || !record.name ? '' : record.scheduleId ? 'pause' : 'play_arrow'),
251
+ icon: record => (!record || record.scheduleId ? 'event_available' : ''),
252
252
  handlers: {
253
253
  click: (columns, data, column, record, rowIndex) => {
254
254
  if (!record || !record.name) {
@@ -0,0 +1,390 @@
1
+ import '@operato/data-grist'
2
+ import './data-summary-view.js'
3
+
4
+ import { CommonButtonStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles'
5
+ import { PageView, store } from '@operato/shell'
6
+ import { css, html } from 'lit'
7
+ import { customElement, property, query } from 'lit/decorators.js'
8
+ import { ScopedElementsMixin } from '@open-wc/scoped-elements'
9
+ import { ColumnConfig, DataGrist, GristRecord, FetchOption, SortersControl } from '@operato/data-grist'
10
+ import { client } from '@operato/graphql'
11
+ import { i18next, localize } from '@operato/i18n'
12
+ import { notify, openPopup } from '@operato/layout'
13
+ import { OxPopup } from '@operato/popup'
14
+ import { isMobileDevice } from '@operato/utils'
15
+
16
+ import { connect } from 'pwa-helpers/connect-mixin'
17
+ import gql from 'graphql-tag'
18
+
19
+ @customElement('data-summary-list-page')
20
+ export class DataSummaryListPage extends connect(store)(localize(i18next)(PageView)) {
21
+ static styles = [
22
+ ScrollbarStyles,
23
+ CommonGristStyles,
24
+ css`
25
+ :host {
26
+ display: flex;
27
+
28
+ width: 100%;
29
+
30
+ --grid-record-emphasized-background-color: red;
31
+ --grid-record-emphasized-color: yellow;
32
+ }
33
+ `
34
+ ]
35
+
36
+ @property({ type: Object }) gristConfig: any
37
+ @property({ type: String }) mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'CARD' : 'GRID'
38
+
39
+ @query('ox-grist') private grist!: DataGrist
40
+ @query('#sorter-control') private sortersControl!: OxPopup
41
+
42
+ get context() {
43
+ return {
44
+ search: {
45
+ handler: (search: string) => {
46
+ this.grist.searchText = search
47
+ },
48
+ placeholder: i18next.t('title.data-summary list'),
49
+ value: this.grist.searchText
50
+ },
51
+ filter: {
52
+ handler: () => {
53
+ this.grist.toggleHeadroom()
54
+ }
55
+ },
56
+ help: 'dataset/data-summary',
57
+ exportable: {
58
+ name: i18next.t('title.data-summary list'),
59
+ data: this._exportableData.bind(this)
60
+ }
61
+ }
62
+ }
63
+
64
+ render() {
65
+ const mode = this.mode || (isMobileDevice() ? 'LIST' : 'GRID')
66
+
67
+ return html`
68
+ <ox-grist
69
+ .mode=${mode}
70
+ .config=${this.gristConfig}
71
+ .fetchHandler=${this.fetchHandler.bind(this)}
72
+ ?url-params-sensitive=${false /* this.active */}
73
+ >
74
+ <div slot="headroom">
75
+ <div id="filters">
76
+ <ox-filters-form autofocus without-search></ox-filters-form>
77
+ </div>
78
+
79
+ <div id="sorters">
80
+ Sort
81
+ <mwc-icon
82
+ @click=${e => {
83
+ const target = e.currentTarget
84
+ this.sortersControl.open({
85
+ right: 0,
86
+ top: target.offsetTop + target.offsetHeight
87
+ })
88
+ }}
89
+ >expand_more</mwc-icon
90
+ >
91
+ <ox-popup id="sorter-control">
92
+ <ox-sorters-control> </ox-sorters-control>
93
+ </ox-popup>
94
+ </div>
95
+
96
+ <div id="modes">
97
+ <mwc-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</mwc-icon>
98
+ <mwc-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</mwc-icon>
99
+ <mwc-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</mwc-icon>
100
+ </div>
101
+ </div>
102
+ </ox-grist>
103
+ `
104
+ }
105
+
106
+ async pageInitialized(lifecycle) {
107
+ const today = new Date().toISOString().split('T')[0]
108
+
109
+ this.gristConfig = {
110
+ list: { fields: ['dataSet', 'data', 'updater', 'updatedAt'] },
111
+ columns: [
112
+ { type: 'gutter', gutterName: 'sequence' },
113
+ { type: 'gutter', gutterName: 'row-selector', multiple: true },
114
+ {
115
+ type: 'gutter',
116
+ gutterName: 'button',
117
+ icon: 'assignment',
118
+ title: i18next.t('title.open data summary view'),
119
+ handlers: {
120
+ click: (columns, data, column, record, rowIndex) => {
121
+ openPopup(
122
+ html`
123
+ <data-summary-view data-summary-id=${record.id} style="background-color: white;"></data-summary-view>
124
+ `,
125
+ {
126
+ backdrop: true,
127
+ size: 'large',
128
+ title: i18next.t('title.data-summary view')
129
+ }
130
+ )
131
+ }
132
+ }
133
+ },
134
+ {
135
+ type: 'string',
136
+ name: 'name',
137
+ label: true,
138
+ header: i18next.t('field.name'),
139
+ record: {
140
+ editable: false
141
+ },
142
+ filter: 'search',
143
+ sortable: true,
144
+ width: 120,
145
+ imex: true
146
+ },
147
+ {
148
+ type: 'string',
149
+ name: 'description',
150
+ label: true,
151
+ header: i18next.t('field.description'),
152
+ record: {
153
+ editable: false
154
+ },
155
+ filter: 'search',
156
+ width: 150,
157
+ imex: true
158
+ },
159
+ {
160
+ type: 'string',
161
+ name: 'workDate',
162
+ header: i18next.t('field.work-date'),
163
+ sortable: true,
164
+ filter: {
165
+ type: 'date',
166
+ operator: 'between',
167
+ value: [today, today]
168
+ },
169
+ width: 80,
170
+ imex: true
171
+ },
172
+ {
173
+ type: 'string',
174
+ name: 'workShift',
175
+ header: i18next.t('field.work-shift'),
176
+ sortable: true,
177
+ width: 60,
178
+ imex: true
179
+ },
180
+ {
181
+ type: 'string',
182
+ name: 'key01',
183
+ header: i18next.t('field.key-01'),
184
+ record: {
185
+ editable: false
186
+ },
187
+ sortable: true,
188
+ width: 120,
189
+ imex: true
190
+ },
191
+ {
192
+ type: 'string',
193
+ name: 'key02',
194
+ header: i18next.t('field.key-02'),
195
+ record: {
196
+ editable: false
197
+ },
198
+ sortable: true,
199
+ width: 120,
200
+ imex: true
201
+ },
202
+ {
203
+ type: 'string',
204
+ name: 'key03',
205
+ header: i18next.t('field.key-03'),
206
+ record: {
207
+ editable: false
208
+ },
209
+ sortable: true,
210
+ width: 120,
211
+ imex: true
212
+ },
213
+ {
214
+ type: 'string',
215
+ name: 'key04',
216
+ header: i18next.t('field.key-04'),
217
+ record: {
218
+ editable: false
219
+ },
220
+ sortable: true,
221
+ width: 120,
222
+ imex: true
223
+ },
224
+ {
225
+ type: 'string',
226
+ name: 'key05',
227
+ header: i18next.t('field.key-05'),
228
+ record: {
229
+ editable: false
230
+ },
231
+ sortable: true,
232
+ width: 120,
233
+ imex: true
234
+ },
235
+ {
236
+ type: 'checkbox',
237
+ name: 'count',
238
+ header: i18next.t('field.count'),
239
+ record: {
240
+ editable: false
241
+ },
242
+ width: 30
243
+ },
244
+ {
245
+ type: 'checkbox',
246
+ name: 'countOoc',
247
+ header: i18next.t('field.count-ooc'),
248
+ record: {
249
+ editable: false
250
+ },
251
+ width: 30
252
+ },
253
+ {
254
+ type: 'checkbox',
255
+ name: 'countOos',
256
+ header: i18next.t('field.count-oos'),
257
+ record: {
258
+ editable: false
259
+ },
260
+ width: 30
261
+ },
262
+ {
263
+ type: 'resource-object',
264
+ name: 'updater',
265
+ header: i18next.t('field.updater'),
266
+ sortable: true,
267
+ width: 120,
268
+ imex: true
269
+ },
270
+ {
271
+ type: 'datetime',
272
+ name: 'updatedAt',
273
+ header: i18next.t('field.updated_at'),
274
+ sortable: true,
275
+ width: 180,
276
+ imex: true
277
+ }
278
+ ],
279
+ rows: {
280
+ appendable: false,
281
+ selectable: {
282
+ multiple: true
283
+ },
284
+ classifier: function (record, rowIndex) {
285
+ var emphasized
286
+ if (record['oos']) {
287
+ emphasized = ['red']
288
+ } else if (record['ooc']) {
289
+ emphasized = 'orange'
290
+ }
291
+
292
+ return {
293
+ emphasized
294
+ }
295
+ }
296
+ },
297
+ sorters: [
298
+ {
299
+ name: 'workDate',
300
+ desc: true
301
+ }
302
+ ]
303
+ }
304
+ }
305
+
306
+ async fetchHandler({ page, limit, sortings = [], filters = [] }: FetchOption) {
307
+ const response = await client.query({
308
+ query: gql`
309
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
310
+ responses: dataSummaries(filters: $filters, pagination: $pagination, sortings: $sortings) {
311
+ items {
312
+ id
313
+ name
314
+ description
315
+ dataSet {
316
+ id
317
+ }
318
+ workDate
319
+ workShift
320
+ key01
321
+ key02
322
+ key03
323
+ key04
324
+ key05
325
+ summary
326
+ count
327
+ countOoc
328
+ countOos
329
+ updater {
330
+ id
331
+ name
332
+ }
333
+ updatedAt
334
+ }
335
+ total
336
+ }
337
+ }
338
+ `,
339
+ variables: {
340
+ filters,
341
+ pagination: { page, limit },
342
+ sortings
343
+ }
344
+ })
345
+
346
+ return {
347
+ total: response.data.responses.total || 0,
348
+ records: response.data.responses.items || []
349
+ }
350
+ }
351
+
352
+ _exportableData() {
353
+ let records = [] as GristRecord[]
354
+ if (this.grist.selected && this.grist.selected.length > 0) {
355
+ records = this.grist.selected
356
+ } else {
357
+ records = this.grist.data.records
358
+ }
359
+
360
+ var headerSetting = this.grist.compiledConfig.columns
361
+ .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
362
+ .map(column => {
363
+ return column.imex === true
364
+ ? {
365
+ header: column.header.renderer(column),
366
+ key: column.name,
367
+ width: column.width,
368
+ type: column.type
369
+ }
370
+ : column.imex
371
+ })
372
+
373
+ var data = records.map(item => {
374
+ return {
375
+ id: item.id,
376
+ ...this.gristConfig.columns
377
+ .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
378
+ .reduce((record, column) => {
379
+ const key = column.imex === true ? column.name : column.imex.key
380
+ record[key] = key
381
+ .split('.')
382
+ .reduce((obj, key) => (obj && obj[key] !== 'undefined' ? obj[key] : undefined), item)
383
+ return record
384
+ }, {})
385
+ }
386
+ })
387
+
388
+ return { header: headerSetting, data: data }
389
+ }
390
+ }