@things-factory/dataset 5.0.0-alpha.7 → 5.0.0-y.0

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 (107) hide show
  1. package/README.md +9 -0
  2. package/assets/data-samples.jpg +0 -0
  3. package/client/bootstrap.js +21 -1
  4. package/client/pages/{data-entry-form.js → data-entry/data-entry-form.js} +15 -3
  5. package/client/pages/data-entry/data-entry-list-page.js +423 -0
  6. package/client/pages/data-ooc/data-ooc-list-page.js +483 -0
  7. package/client/pages/data-ooc/data-ooc-view.js +183 -0
  8. package/client/pages/data-report/data-report-embed-page.js +113 -0
  9. package/client/pages/data-report/data-report-list-page.js +465 -0
  10. package/client/pages/data-report/jasper-report-oocs-page.js +122 -0
  11. package/client/pages/data-report/jasper-report-samples-crosstab-page.js +122 -0
  12. package/client/pages/data-report/jasper-report-samples-page.js +122 -0
  13. package/client/pages/data-sample/data-sample-list-page.js +386 -0
  14. package/client/pages/data-sample/data-sample-view.js +98 -0
  15. package/client/pages/{data-sensor.js → data-sensor/data-sensor-list-page.js} +43 -64
  16. package/client/pages/{data-item-list.js → data-set/data-item-list.js} +35 -10
  17. package/client/pages/{data-set-importer.js → data-set/data-set-importer.js} +0 -0
  18. package/client/pages/data-set/data-set-list-page.js +743 -0
  19. package/client/route.js +34 -6
  20. package/config/config.development.js +13 -0
  21. package/config/config.production.js +1 -0
  22. package/dist-server/controllers/create-data-sample.js +133 -0
  23. package/dist-server/controllers/create-data-sample.js.map +1 -0
  24. package/dist-server/controllers/data-use-case.js +57 -0
  25. package/dist-server/controllers/data-use-case.js.map +1 -0
  26. package/dist-server/controllers/index.js +18 -0
  27. package/dist-server/controllers/index.js.map +1 -1
  28. package/dist-server/controllers/jasper-report.js +156 -0
  29. package/dist-server/controllers/jasper-report.js.map +1 -0
  30. package/dist-server/index.js +1 -0
  31. package/dist-server/index.js.map +1 -1
  32. package/dist-server/routes.js +13 -24
  33. package/dist-server/routes.js.map +1 -1
  34. package/dist-server/service/data-item/data-item-mutation.js +5 -1
  35. package/dist-server/service/data-item/data-item-mutation.js.map +1 -1
  36. package/dist-server/service/data-item/data-item-query.js +6 -2
  37. package/dist-server/service/data-item/data-item-query.js.map +1 -1
  38. package/dist-server/service/data-item/data-item-type.js +15 -7
  39. package/dist-server/service/data-item/data-item-type.js.map +1 -1
  40. package/dist-server/service/data-item/data-item.js +17 -3
  41. package/dist-server/service/data-item/data-item.js.map +1 -1
  42. package/dist-server/service/data-ooc/data-ooc-mutation.js +92 -0
  43. package/dist-server/service/data-ooc/data-ooc-mutation.js.map +1 -0
  44. package/dist-server/service/data-ooc/data-ooc-query.js +120 -0
  45. package/dist-server/service/data-ooc/data-ooc-query.js.map +1 -0
  46. package/dist-server/service/data-ooc/data-ooc-subscription.js +65 -0
  47. package/dist-server/service/data-ooc/data-ooc-subscription.js.map +1 -0
  48. package/dist-server/service/data-ooc/data-ooc-type.js +107 -0
  49. package/dist-server/service/data-ooc/data-ooc-type.js.map +1 -0
  50. package/dist-server/service/data-ooc/data-ooc.js +237 -0
  51. package/dist-server/service/data-ooc/data-ooc.js.map +1 -0
  52. package/dist-server/service/data-ooc/index.js +10 -0
  53. package/dist-server/service/data-ooc/index.js.map +1 -0
  54. package/dist-server/service/data-sample/data-sample-mutation.js +2 -138
  55. package/dist-server/service/data-sample/data-sample-mutation.js.map +1 -1
  56. package/dist-server/service/data-sample/data-sample-query.js +7 -2
  57. package/dist-server/service/data-sample/data-sample-query.js.map +1 -1
  58. package/dist-server/service/data-sample/data-sample-type.js +12 -42
  59. package/dist-server/service/data-sample/data-sample-type.js.map +1 -1
  60. package/dist-server/service/data-sample/data-sample.js +34 -3
  61. package/dist-server/service/data-sample/data-sample.js.map +1 -1
  62. package/dist-server/service/data-sensor/data-sensor-query.js +7 -2
  63. package/dist-server/service/data-sensor/data-sensor-query.js.map +1 -1
  64. package/dist-server/service/data-set/data-set-mutation.js +40 -14
  65. package/dist-server/service/data-set/data-set-mutation.js.map +1 -1
  66. package/dist-server/service/data-set/data-set-query.js +189 -3
  67. package/dist-server/service/data-set/data-set-query.js.map +1 -1
  68. package/dist-server/service/data-set/data-set-type.js +84 -3
  69. package/dist-server/service/data-set/data-set-type.js.map +1 -1
  70. package/dist-server/service/data-set/data-set.js +110 -15
  71. package/dist-server/service/data-set/data-set.js.map +1 -1
  72. package/dist-server/service/index.js +6 -2
  73. package/dist-server/service/index.js.map +1 -1
  74. package/package.json +19 -13
  75. package/server/controllers/create-data-sample.ts +177 -0
  76. package/server/controllers/data-use-case.ts +85 -0
  77. package/server/controllers/index.ts +2 -0
  78. package/server/controllers/jasper-report.ts +170 -0
  79. package/server/index.ts +1 -0
  80. package/server/routes.ts +21 -31
  81. package/server/service/data-item/data-item-mutation.ts +6 -1
  82. package/server/service/data-item/data-item-query.ts +8 -3
  83. package/server/service/data-item/data-item-type.ts +10 -6
  84. package/server/service/data-item/data-item.ts +15 -4
  85. package/server/service/data-ooc/data-ooc-mutation.ts +150 -0
  86. package/server/service/data-ooc/data-ooc-query.ts +69 -0
  87. package/server/service/data-ooc/data-ooc-subscription.ts +51 -0
  88. package/server/service/data-ooc/data-ooc-type.ts +68 -0
  89. package/server/service/data-ooc/data-ooc.ts +204 -0
  90. package/server/service/data-ooc/index.ts +7 -0
  91. package/server/service/data-sample/data-sample-mutation.ts +3 -168
  92. package/server/service/data-sample/data-sample-query.ts +9 -3
  93. package/server/service/data-sample/data-sample-type.ts +7 -28
  94. package/server/service/data-sample/data-sample.ts +33 -3
  95. package/server/service/data-sensor/data-sensor-query.ts +9 -3
  96. package/server/service/data-set/data-set-mutation.ts +53 -14
  97. package/server/service/data-set/data-set-query.ts +164 -4
  98. package/server/service/data-set/data-set-type.ts +65 -4
  99. package/server/service/data-set/data-set.ts +100 -12
  100. package/server/service/index.ts +6 -2
  101. package/things-factory.config.js +35 -7
  102. package/translations/en.json +46 -3
  103. package/translations/ko.json +45 -3
  104. package/translations/ms.json +44 -3
  105. package/translations/zh.json +44 -3
  106. package/client/pages/data-sample.js +0 -307
  107. package/client/pages/data-set.js +0 -457
@@ -0,0 +1,743 @@
1
+ import '@operato/data-grist'
2
+ import './data-item-list.js'
3
+ import './data-set-importer.js'
4
+ import '../data-entry/data-entry-form.js'
5
+
6
+ import gql from 'graphql-tag'
7
+ import { css, html } from 'lit'
8
+ import moment from 'moment-timezone'
9
+ import { connect } from 'pwa-helpers/connect-mixin'
10
+
11
+ import { getEditor, getRenderer } from '@operato/data-grist'
12
+ import { OxDataUseCase } from '@operato/dataset'
13
+ import { client } from '@operato/graphql'
14
+ import { i18next, localize } from '@operato/i18n'
15
+ import { notify, openPopup } from '@operato/layout'
16
+ import { PageView, store } from '@operato/shell'
17
+ import { CommonButtonStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles'
18
+ import { isMobileDevice } from '@operato/utils'
19
+
20
+ const DEFAULT_TZ = Intl.DateTimeFormat().resolvedOptions().timeZone
21
+ const TIMEZONE_OPTIONS = ['', DEFAULT_TZ, ...moment.tz.names().filter(tz => tz !== DEFAULT_TZ)]
22
+
23
+ const ENTRY_TYPES = [
24
+ {
25
+ display: '',
26
+ value: ''
27
+ },
28
+ {
29
+ display: 'Generated',
30
+ value: 'generated'
31
+ },
32
+ {
33
+ display: 'Board',
34
+ value: 'board'
35
+ },
36
+ {
37
+ display: 'Page',
38
+ value: 'page'
39
+ },
40
+ {
41
+ display: 'External URL',
42
+ value: 'external'
43
+ }
44
+ ]
45
+
46
+ const MONITOR_TYPES = [
47
+ {
48
+ display: '',
49
+ value: ''
50
+ },
51
+ {
52
+ display: 'Generated',
53
+ value: 'generated'
54
+ },
55
+ {
56
+ display: 'Board',
57
+ value: 'board'
58
+ },
59
+ {
60
+ display: 'Page',
61
+ value: 'page'
62
+ },
63
+ {
64
+ display: 'External URL',
65
+ value: 'external'
66
+ }
67
+ ]
68
+
69
+ const REPORT_TYPES = [
70
+ {
71
+ display: '',
72
+ value: ''
73
+ },
74
+ {
75
+ display: 'Generated',
76
+ value: 'generated'
77
+ },
78
+ {
79
+ display: 'Embed',
80
+ value: 'embed'
81
+ },
82
+ {
83
+ display: 'Page',
84
+ value: 'page'
85
+ },
86
+ {
87
+ display: 'External URL',
88
+ value: 'external'
89
+ }
90
+ ]
91
+
92
+ const USECASE_OPTIONS = () => {
93
+ return ['', ...OxDataUseCase.getUseCaseNames()].map(name => {
94
+ return {
95
+ display: name,
96
+ value: name
97
+ }
98
+ })
99
+ }
100
+ export class DataSetListPage extends connect(store)(localize(i18next)(PageView)) {
101
+ static get properties() {
102
+ return {
103
+ gristConfig: Object,
104
+ mode: String
105
+ }
106
+ }
107
+
108
+ static get styles() {
109
+ return [
110
+ ScrollbarStyles,
111
+ CommonGristStyles,
112
+ css`
113
+ :host {
114
+ display: flex;
115
+
116
+ width: 100%;
117
+
118
+ --grid-record-emphasized-background-color: red;
119
+ --grid-record-emphasized-color: yellow;
120
+ }
121
+ `
122
+ ]
123
+ }
124
+
125
+ get context() {
126
+ return {
127
+ title: i18next.t('title.data-set list'),
128
+ help: 'dataset/data-set',
129
+ actions: [
130
+ {
131
+ title: i18next.t('button.copy'),
132
+ action: this._copyDataSet.bind(this),
133
+ ...CommonButtonStyles.copy
134
+ },
135
+ {
136
+ title: i18next.t('button.save'),
137
+ action: this._updateDataSet.bind(this),
138
+ ...CommonButtonStyles.save
139
+ },
140
+ {
141
+ title: i18next.t('button.delete'),
142
+ action: this._deleteDataSet.bind(this),
143
+ ...CommonButtonStyles.delete
144
+ }
145
+ ],
146
+ exportable: {
147
+ name: i18next.t('title.data-set list'),
148
+ data: this.exportHandler.bind(this)
149
+ },
150
+ importable: {
151
+ handler: this.importHandler.bind(this)
152
+ }
153
+ }
154
+ }
155
+
156
+ render() {
157
+ const mode = this.mode || (isMobileDevice() ? 'LIST' : 'GRID')
158
+
159
+ return html`
160
+ <ox-grist
161
+ .mode=${mode}
162
+ .config=${this.gristConfig}
163
+ .fetchHandler=${this.fetchHandler.bind(this)}
164
+ ?url-params-sensitive=${this.active}
165
+ >
166
+ <div slot="headroom">
167
+ <div id="filters">
168
+ <ox-filters-form></ox-filters-form>
169
+ </div>
170
+
171
+ <div id="sorters">
172
+ Sort
173
+ <mwc-icon
174
+ @click=${e => {
175
+ const target = e.currentTarget
176
+ this.renderRoot.querySelector('#sorter-control').open({
177
+ right: 0,
178
+ top: target.offsetTop + target.offsetHeight
179
+ })
180
+ }}
181
+ >expand_more</mwc-icon
182
+ >
183
+ <ox-popup id="sorter-control">
184
+ <ox-sorters-control> </ox-sorters-control>
185
+ </ox-popup>
186
+ </div>
187
+
188
+ <div id="modes">
189
+ <mwc-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</mwc-icon>
190
+ <mwc-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</mwc-icon>
191
+ <mwc-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</mwc-icon>
192
+ </div>
193
+ </div>
194
+ </ox-grist>
195
+ `
196
+ }
197
+
198
+ get grist() {
199
+ return this.renderRoot.querySelector('ox-grist')
200
+ }
201
+
202
+ async pageInitialized(lifecycle) {
203
+ this.gristConfig = {
204
+ list: {
205
+ fields: ['name', 'description'],
206
+ details: ['schedule', 'active']
207
+ },
208
+ columns: [
209
+ { type: 'gutter', gutterName: 'sequence' },
210
+ { type: 'gutter', gutterName: 'row-selector', multiple: true },
211
+ {
212
+ type: 'gutter',
213
+ gutterName: 'button',
214
+ icon: 'reorder',
215
+ handlers: {
216
+ click: (columns, data, column, record, rowIndex) => {
217
+ if (!record.id) return
218
+ const popup = openPopup(html` <data-item-list .dataSet=${record}></data-item-list> `, {
219
+ backdrop: true,
220
+ help: 'data-set/ui/data-item-list',
221
+ size: 'large',
222
+ title: i18next.t('title.data-item list')
223
+ })
224
+ popup.onclosed = () => {
225
+ this.grist.fetch()
226
+ }
227
+ }
228
+ }
229
+ },
230
+ {
231
+ type: 'gutter',
232
+ gutterName: 'button',
233
+ icon: 'fact_check',
234
+ handlers: {
235
+ click: (columns, data, column, record, rowIndex) => {
236
+ openPopup(
237
+ html` <data-entry-form .dataSet=${record} style="background-color: white;"></data-entry-form> `,
238
+ {
239
+ backdrop: true,
240
+ size: 'large',
241
+ title: i18next.t('title.data-entry-form')
242
+ }
243
+ )
244
+ }
245
+ }
246
+ },
247
+ {
248
+ type: 'string',
249
+ name: 'name',
250
+ header: i18next.t('field.name'),
251
+ record: {
252
+ editable: true
253
+ },
254
+ filter: 'search',
255
+ sortable: true,
256
+ width: 150,
257
+ imex: {
258
+ width: 25,
259
+ header: i18next.t('field.name'),
260
+ type: 'string',
261
+ key: 'name'
262
+ }
263
+ },
264
+ {
265
+ type: 'string',
266
+ name: 'description',
267
+ header: i18next.t('field.description'),
268
+ record: {
269
+ editable: true
270
+ },
271
+ filter: 'search',
272
+ width: 200,
273
+ imex: {
274
+ width: 33,
275
+ header: i18next.t('field.description'),
276
+ type: 'string',
277
+ key: 'description'
278
+ }
279
+ },
280
+ {
281
+ type: 'checkbox',
282
+ name: 'active',
283
+ label: true,
284
+ header: i18next.t('field.active'),
285
+ record: {
286
+ editable: true
287
+ },
288
+ filter: true,
289
+ sortable: true,
290
+ width: 60,
291
+ imex: {
292
+ width: 10,
293
+ header: i18next.t('field.active'),
294
+ type: 'checkbox',
295
+ key: 'active'
296
+ }
297
+ },
298
+ {
299
+ type: 'select',
300
+ name: 'type',
301
+ label: true,
302
+ header: i18next.t('field.type'),
303
+ record: {
304
+ editable: true,
305
+ options: [
306
+ {},
307
+ {
308
+ display: i18next.t('text.manually collected'),
309
+ value: 'manual'
310
+ },
311
+ {
312
+ display: i18next.t('text.automatically collected'),
313
+ value: 'automatic'
314
+ }
315
+ ]
316
+ },
317
+ sortable: true,
318
+ filter: true,
319
+ width: 60,
320
+ imex: {
321
+ width: 10,
322
+ header: i18next.t('field.type'),
323
+ type: 'select',
324
+ key: 'type'
325
+ }
326
+ },
327
+ {
328
+ type: 'select',
329
+ name: 'useCase',
330
+ label: true,
331
+ header: i18next.t('field.use-case'),
332
+ record: {
333
+ editable: true,
334
+ options: USECASE_OPTIONS
335
+ },
336
+ sortable: true,
337
+ filter: true,
338
+ width: 80
339
+ },
340
+ {
341
+ type: 'partition-keys',
342
+ name: 'partitionKeys',
343
+ header: i18next.t('field.partition-keys'),
344
+ record: {
345
+ editable: true,
346
+ options: {
347
+ objectified: true /* transfered as a object type */
348
+ }
349
+ },
350
+ width: 200
351
+ },
352
+ {
353
+ type: 'crontab',
354
+ name: 'schedule',
355
+ label: true,
356
+ header: i18next.t('field.schedule'),
357
+ record: {
358
+ editable: true,
359
+ options: {
360
+ objectified: true
361
+ }
362
+ },
363
+ width: 80,
364
+ label: true,
365
+ imex: {
366
+ width: 13,
367
+ header: i18next.t('field.schedule'),
368
+ type: 'string',
369
+ key: 'schedule'
370
+ }
371
+ },
372
+ {
373
+ type: 'select',
374
+ name: 'timezone',
375
+ header: i18next.t('field.timezone'),
376
+ record: {
377
+ editable: true,
378
+ options: TIMEZONE_OPTIONS
379
+ },
380
+ width: 120,
381
+ imex: {
382
+ width: 13,
383
+ header: i18next.t('field.timezone'),
384
+ type: 'select',
385
+ key: 'timezone'
386
+ }
387
+ },
388
+ {
389
+ type: 'resource-object',
390
+ name: 'supervisoryRole',
391
+ header: i18next.t('field.supervisory-role'),
392
+ record: {
393
+ editable: true,
394
+ options: {
395
+ queryName: 'roles'
396
+ }
397
+ },
398
+ sortable: true,
399
+ filter: 'like',
400
+ width: 120
401
+ },
402
+ {
403
+ type: 'resource-object',
404
+ name: 'entryRole',
405
+ header: i18next.t('field.entry-role'),
406
+ record: {
407
+ editable: true,
408
+ options: {
409
+ queryName: 'roles'
410
+ }
411
+ },
412
+ sortable: true,
413
+ width: 120
414
+ },
415
+ {
416
+ type: 'select',
417
+ name: 'entryType',
418
+ label: true,
419
+ header: i18next.t('field.entry-type'),
420
+ record: {
421
+ editable: true,
422
+ options: ENTRY_TYPES
423
+ },
424
+ width: 80
425
+ },
426
+ {
427
+ type: 'string',
428
+ name: 'entryView',
429
+ header: i18next.t('field.entry-view'),
430
+ record: {
431
+ editable: true,
432
+ editor: function (value, column, record, rowIndex, field) {
433
+ var type = record.entryType !== 'board' ? 'string' : 'board'
434
+ return getEditor(type)(value, column, record, rowIndex, field)
435
+ },
436
+ renderer: function (value, column, record, rowIndex, field) {
437
+ var type = record.entryType !== 'board' ? 'string' : 'board'
438
+ return getRenderer(type)(value, column, record, rowIndex, field)
439
+ }
440
+ },
441
+ width: 140
442
+ },
443
+ {
444
+ type: 'select',
445
+ name: 'monitorType',
446
+ label: true,
447
+ header: i18next.t('field.monitor-type'),
448
+ record: {
449
+ editable: true,
450
+ options: MONITOR_TYPES
451
+ },
452
+ width: 80
453
+ },
454
+ {
455
+ type: 'string',
456
+ name: 'monitorView',
457
+ header: i18next.t('field.monitor-view'),
458
+ record: {
459
+ editable: true,
460
+ editor: function (value, column, record, rowIndex, field) {
461
+ var type = record.monitorType !== 'board' ? 'string' : 'board'
462
+ return getEditor(type)(value, column, record, rowIndex, field)
463
+ },
464
+ renderer: function (value, column, record, rowIndex, field) {
465
+ var type = record.monitorType !== 'board' ? 'string' : 'board'
466
+ return getRenderer(type)(value, column, record, rowIndex, field)
467
+ }
468
+ },
469
+ width: 140
470
+ },
471
+ {
472
+ type: 'select',
473
+ name: 'reportType',
474
+ label: true,
475
+ header: i18next.t('field.report-type'),
476
+ record: {
477
+ editable: true,
478
+ options: REPORT_TYPES
479
+ },
480
+ width: 80
481
+ },
482
+ {
483
+ type: 'string',
484
+ name: 'reportView',
485
+ header: i18next.t('field.report-view'),
486
+ record: {
487
+ editable: true,
488
+ editor: function (value, column, record, rowIndex, field) {
489
+ var type = record.reportType !== 'custom' ? 'string' : 'script'
490
+ return getEditor(type)(value, column, record, rowIndex, field)
491
+ },
492
+ renderer: function (value, column, record, rowIndex, field) {
493
+ var type = record.reportType !== 'custom' ? 'string' : 'string'
494
+ return getRenderer(type)(value, column, record, rowIndex, field)
495
+ }
496
+ },
497
+ width: 140
498
+ },
499
+ {
500
+ type: 'file',
501
+ name: 'reportTemplate',
502
+ header: i18next.t('field.report-template'),
503
+ record: {
504
+ editable: true
505
+ },
506
+ width: 80
507
+ },
508
+ {
509
+ type: 'resource-object',
510
+ name: 'updater',
511
+ header: i18next.t('field.updater'),
512
+ record: {
513
+ editable: false
514
+ },
515
+ sortable: true,
516
+ width: 120
517
+ },
518
+ {
519
+ type: 'datetime',
520
+ name: 'updatedAt',
521
+ header: i18next.t('field.updated_at'),
522
+ record: {
523
+ editable: false
524
+ },
525
+ sortable: true,
526
+ width: 180
527
+ }
528
+ ],
529
+ rows: {
530
+ selectable: {
531
+ multiple: true
532
+ }
533
+ },
534
+ sorters: [
535
+ {
536
+ name: 'name'
537
+ }
538
+ ]
539
+ }
540
+
541
+ await this.updateComplete
542
+
543
+ this.grist.fetch()
544
+ }
545
+
546
+ async fetchHandler({ page, limit, sortings = [], filters = [] }) {
547
+ const response = await client.query({
548
+ query: gql`
549
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
550
+ responses: dataSets(filters: $filters, pagination: $pagination, sortings: $sortings) {
551
+ items {
552
+ id
553
+ name
554
+ description
555
+ partitionKeys
556
+ active
557
+ type
558
+ useCase
559
+ schedule
560
+ timezone
561
+ entryRole {
562
+ id
563
+ name
564
+ }
565
+ supervisoryRole {
566
+ id
567
+ name
568
+ }
569
+ entryType
570
+ entryView
571
+ monitorType
572
+ monitorView
573
+ reportType
574
+ reportView
575
+ reportTemplate
576
+ updater {
577
+ id
578
+ name
579
+ }
580
+ updatedAt
581
+ dataItems {
582
+ name
583
+ description
584
+ sequence
585
+ active
586
+ tag
587
+ type
588
+ unit
589
+ options
590
+ quota
591
+ spec
592
+ }
593
+ }
594
+ total
595
+ }
596
+ }
597
+ `,
598
+ variables: {
599
+ filters,
600
+ pagination: { page, limit },
601
+ sortings
602
+ }
603
+ })
604
+
605
+ return {
606
+ total: response.data.responses.total || 0,
607
+ records: response.data.responses.items || []
608
+ }
609
+ }
610
+
611
+ async _deleteDataSet() {
612
+ if (confirm(i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }))) {
613
+ const ids = this.grist.selected.map(record => record.id)
614
+ if (ids && ids.length > 0) {
615
+ const response = await client.mutate({
616
+ mutation: gql`
617
+ mutation ($ids: [String!]!) {
618
+ deleteDataSets(ids: $ids)
619
+ }
620
+ `,
621
+ variables: {
622
+ ids
623
+ }
624
+ })
625
+
626
+ if (!response.errors) {
627
+ this.grist.fetch()
628
+ notify({
629
+ message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
630
+ })
631
+ }
632
+ }
633
+ }
634
+ }
635
+
636
+ async _copyDataSet() {
637
+ var selected = this.grist.selected
638
+ if (selected.length == 0) return
639
+
640
+ if (!confirm(i18next.t('text.sure_to_x', { x: i18next.t('text.copy') }))) return
641
+ var response = await client.mutate({
642
+ mutation: gql`
643
+ mutation ($ids: [String!]!) {
644
+ copyDataSets(ids: $ids) {
645
+ id
646
+ }
647
+ }
648
+ `,
649
+ variables: {
650
+ ids: selected.map(r => r.id)
651
+ }
652
+ })
653
+
654
+ if (!response.errors) {
655
+ this.grist.fetch()
656
+ }
657
+ }
658
+
659
+ async _updateDataSet() {
660
+ let patches = this.grist.dirtyRecords
661
+ if (patches && patches.length) {
662
+ patches = patches.map(patch => {
663
+ let patchField = patch.id ? { id: patch.id } : {}
664
+ const dirtyFields = patch.__dirtyfields__
665
+ for (let key in dirtyFields) {
666
+ patchField[key] = dirtyFields[key].after
667
+ }
668
+ if (patchField['reportTemplate'] instanceof FileList) {
669
+ patchField['reportTemplate'] = patchField['reportTemplate'][0]
670
+ }
671
+ patchField.cuFlag = patch.__dirty__
672
+
673
+ return patchField
674
+ })
675
+
676
+ const response = await client.mutate({
677
+ mutation: gql`
678
+ mutation ($patches: [DataSetPatch!]!) {
679
+ updateMultipleDataSet(patches: $patches) {
680
+ name
681
+ }
682
+ }
683
+ `,
684
+ variables: {
685
+ patches
686
+ },
687
+ context: {
688
+ hasUpload: true
689
+ }
690
+ })
691
+
692
+ if (!response.errors) {
693
+ this.grist.fetch()
694
+ }
695
+ }
696
+ }
697
+
698
+ async exportHandler() {
699
+ var headerSetting = this.grist._config.columns
700
+ .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
701
+ .map(column => {
702
+ return column.imex
703
+ })
704
+
705
+ let records = this.grist.data.records
706
+
707
+ var data = records.map(item => {
708
+ return {
709
+ id: item.id,
710
+ ...this.grist._config.columns
711
+ .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
712
+ .reduce((record, column) => {
713
+ record[column.imex.key] = column.imex.key
714
+ .split('.')
715
+ .reduce((obj, key) => (obj && obj[key] !== 'undefined' ? obj[key] : undefined), item)
716
+ return record
717
+ }, {})
718
+ }
719
+ })
720
+ return { header: headerSetting, data: data }
721
+ }
722
+
723
+ async importHandler(records) {
724
+ openPopup(
725
+ html`
726
+ <data-set-importer
727
+ .dataSets=${records}
728
+ @imported=${() => {
729
+ history.back()
730
+ this.grist.fetch()
731
+ }}
732
+ ></data-set-importer>
733
+ `,
734
+ {
735
+ backdrop: true,
736
+ size: 'large',
737
+ title: i18next.t('title.import data-set')
738
+ }
739
+ )
740
+ }
741
+ }
742
+
743
+ window.customElements.define('data-set-list-page', DataSetListPage)