@things-factory/dataset 5.0.0-alpha.4 → 5.0.0-alpha.42

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 +13 -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 -2
  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 +182 -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 +120 -0
  11. package/client/pages/data-report/jasper-report-samples-crosstab-page.js +120 -0
  12. package/client/pages/data-report/jasper-report-samples-page.js +120 -0
  13. package/client/pages/data-sample/data-sample-list-page.js +386 -0
  14. package/client/pages/data-sample/data-sample-view.js +97 -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} +37 -12
  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 +712 -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 +17 -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 +7 -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 +38 -9
  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 +185 -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 +1 -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 +9 -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 -172
  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 +52 -12
  97. package/server/service/data-set/data-set-query.ts +156 -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 -316
  107. package/client/pages/data-set.js +0 -457
@@ -0,0 +1,120 @@
1
+ import { css, html } from 'lit'
2
+ import '@operato/data-grist'
3
+ import '@operato/form'
4
+
5
+ import { i18next, localize } from '@operato/i18n'
6
+ import { CommonButtonStyles, ScrollbarStyles } from '@operato/styles'
7
+ import { PageView } from '@things-factory/shell'
8
+
9
+ class JasperReportSamplesCrosstabPage extends localize(i18next)(PageView) {
10
+ static get properties() {
11
+ return {
12
+ _grnNo: String,
13
+ _status: String,
14
+ resourceId: String,
15
+ params: Object
16
+ }
17
+ }
18
+
19
+ static get styles() {
20
+ return [
21
+ ScrollbarStyles,
22
+ css`
23
+ :host {
24
+ display: flex;
25
+ flex-direction: column;
26
+ padding: 0;
27
+ }
28
+
29
+ #container {
30
+ flex: 1;
31
+ padding: 0;
32
+ margin: 0;
33
+ border: 0;
34
+ }
35
+ `
36
+ ]
37
+ }
38
+
39
+ get context() {
40
+ const filters = [
41
+ {
42
+ name: 'workDateRange',
43
+ type: 'date',
44
+ label: 'date',
45
+ operator: 'between'
46
+ }
47
+ ]
48
+ var actions = [
49
+ {
50
+ title: i18next.t('button.print'),
51
+ action: () => {
52
+ this.renderRoot.querySelector('iframe').contentWindow.print()
53
+ },
54
+ ...CommonButtonStyles.print
55
+ }
56
+ ]
57
+ return {
58
+ title: 'jasper-report',
59
+ actions,
60
+ filters
61
+ }
62
+ }
63
+
64
+ render() {
65
+ return html`
66
+ <ox-filters-form-base
67
+ .filters=${this.context.filters}
68
+ @filters-change=${e => {
69
+ console.log('filters changed', e.detail)
70
+ this._reportTemplate(e.detail.filters)
71
+ }}
72
+ url-params-sensitive
73
+ ></ox-filters-form-base>
74
+ <iframe id="container"></iframe>
75
+ `
76
+ }
77
+
78
+ get searchForm() {
79
+ return this.renderRoot.querySelector('ox-filters-form-base')
80
+ }
81
+ async pageUpdated(changes, lifecycle) {
82
+ if (this.active) {
83
+ this.updateContext()
84
+ }
85
+ }
86
+
87
+ async _reportTemplate(filters) {
88
+ const params = filters.reduce((acc,curr) => (acc[curr.name] = curr.value, acc), {})
89
+ Object.assign(params, this.lifecycle.params)
90
+
91
+ const { workDateRange, workShift, template } = params
92
+
93
+ /** ignoring date conditions */
94
+ if (!workDateRange[0] || !workDateRange[1] || (workDateRange[0] > workDateRange[1])) {
95
+ return
96
+ }
97
+
98
+ /** urlencoded params including test values */
99
+ const urlParams = {
100
+ table: 'samples',
101
+ dataSetId: this.lifecycle.resourceId,
102
+ fromWorkDate: workDateRange[0],
103
+ toWorkDate: workDateRange[1],
104
+ workShift,
105
+ template,
106
+ templateType: 'crosstab'
107
+ }
108
+
109
+ const encodedUrlParams = Object.keys(urlParams).filter(key => {
110
+ // ignore empty
111
+ return !!urlParams[key]
112
+ }).map(key =>
113
+ `${key}=${encodeURIComponent(urlParams[key])}`
114
+ ).join('&')
115
+
116
+ this.shadowRoot.querySelector('#container').src = `/data-report/jasper?${encodedUrlParams}`
117
+ }
118
+ }
119
+
120
+ window.customElements.define('jasper-report-samples-crosstab-page', JasperReportSamplesCrosstabPage)
@@ -0,0 +1,120 @@
1
+ import { css, html } from 'lit'
2
+ import '@operato/data-grist'
3
+ import '@operato/form'
4
+
5
+ import { i18next, localize } from '@operato/i18n'
6
+ import { CommonButtonStyles, ScrollbarStyles } from '@operato/styles'
7
+ import { PageView } from '@things-factory/shell'
8
+
9
+ class JasperReportSamplesPage extends localize(i18next)(PageView) {
10
+ static get properties() {
11
+ return {
12
+ _grnNo: String,
13
+ _status: String,
14
+ resourceId: String,
15
+ params: Object
16
+ }
17
+ }
18
+
19
+ static get styles() {
20
+ return [
21
+ ScrollbarStyles,
22
+ css`
23
+ :host {
24
+ display: flex;
25
+ flex-direction: column;
26
+ padding: 0;
27
+ }
28
+
29
+ #container {
30
+ flex: 1;
31
+ padding: 0;
32
+ margin: 0;
33
+ border: 0;
34
+ }
35
+ `
36
+ ]
37
+ }
38
+
39
+ get context() {
40
+ const filters = [
41
+ {
42
+ name: 'workDateRange',
43
+ type: 'date',
44
+ label: 'date',
45
+ operator: 'between'
46
+ }
47
+ ]
48
+ var actions = [
49
+ {
50
+ title: i18next.t('button.print'),
51
+ action: () => {
52
+ this.renderRoot.querySelector('iframe').contentWindow.print()
53
+ },
54
+ ...CommonButtonStyles.print
55
+ }
56
+ ]
57
+ return {
58
+ title: 'jasper-report',
59
+ actions,
60
+ filters
61
+ }
62
+ }
63
+
64
+ render() {
65
+ return html`
66
+ <ox-filters-form-base
67
+ .filters=${this.context.filters}
68
+ @filters-change=${e => {
69
+ console.log('filters changed', e.detail)
70
+ this._reportTemplate(e.detail.filters)
71
+ }}
72
+ url-params-sensitive
73
+ ></ox-filters-form-base>
74
+ <iframe id="container"></iframe>
75
+ `
76
+ }
77
+
78
+ get searchForm() {
79
+ return this.renderRoot.querySelector('ox-filters-form-base')
80
+ }
81
+ async pageUpdated(changes, lifecycle) {
82
+ if (this.active) {
83
+ this.updateContext()
84
+ }
85
+ }
86
+
87
+ async _reportTemplate(filters) {
88
+ const params = filters.reduce((acc,curr) => (acc[curr.name] = curr.value, acc), {})
89
+ Object.assign(params, this.lifecycle.params)
90
+
91
+ const { workDateRange, workShift, template } = params
92
+
93
+ /** ignoring date conditions */
94
+ if (!workDateRange[0] || !workDateRange[1] || (workDateRange[0] > workDateRange[1])) {
95
+ return
96
+ }
97
+
98
+ /** urlencoded params including test values */
99
+ const urlParams = {
100
+ table: 'samples',
101
+ dataSetId: this.lifecycle.resourceId,
102
+ fromWorkDate: workDateRange[0],
103
+ toWorkDate: workDateRange[1],
104
+ workShift,
105
+ template,
106
+ templateType: 'normal'
107
+ }
108
+
109
+ const encodedUrlParams = Object.keys(urlParams).filter(key => {
110
+ // ignore empty
111
+ return !!urlParams[key]
112
+ }).map(key =>
113
+ `${key}=${encodeURIComponent(urlParams[key])}`
114
+ ).join('&')
115
+
116
+ this.shadowRoot.querySelector('#container').src = `/data-report/jasper?${encodedUrlParams}`
117
+ }
118
+ }
119
+
120
+ window.customElements.define('jasper-report-samples-page', JasperReportSamplesPage)
@@ -0,0 +1,386 @@
1
+ import '@operato/data-grist'
2
+ import './data-sample-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 { CommonGristStyles, ScrollbarStyles } from '@operato/styles'
13
+ import { isMobileDevice } from '@operato/utils'
14
+
15
+ export class DataSampleListPage extends connect(store)(localize(i18next)(PageView)) {
16
+ static get properties() {
17
+ return {
18
+ active: String,
19
+ gristConfig: Object,
20
+ mode: String
21
+ }
22
+ }
23
+
24
+ static get styles() {
25
+ return [
26
+ ScrollbarStyles,
27
+ CommonGristStyles,
28
+ css`
29
+ :host {
30
+ display: flex;
31
+ flex-direction: column;
32
+
33
+ overflow: hidden;
34
+ }
35
+
36
+ ox-grist {
37
+ overflow-y: auto;
38
+ flex: 1;
39
+ }
40
+ `
41
+ ]
42
+ }
43
+
44
+ get context() {
45
+ return {
46
+ title: i18next.t('title.data-sample list'),
47
+ help: 'dataset/data-sample',
48
+ actions: [],
49
+ exportable: {
50
+ name: i18next.t('title.data-sample list'),
51
+ data: this._exportableData.bind(this)
52
+ }
53
+ }
54
+ }
55
+
56
+ render() {
57
+ const mode = this.mode || (isMobileDevice() ? 'LIST' : 'GRID')
58
+
59
+ return html`
60
+ <ox-grist
61
+ .mode=${mode}
62
+ .config=${this.gristConfig}
63
+ .fetchHandler=${this.fetchHandler.bind(this)}
64
+ url-params-sensitive
65
+ >
66
+ <div slot="headroom">
67
+ <div id="filters">
68
+ <ox-filters-form></ox-filters-form>
69
+ </div>
70
+
71
+ <div id="sorters">
72
+ Sort
73
+ <mwc-icon
74
+ @click=${e => {
75
+ const target = e.currentTarget
76
+ this.renderRoot.querySelector('#sorter-control').open({
77
+ right: 0,
78
+ top: target.offsetTop + target.offsetHeight
79
+ })
80
+ }}
81
+ >expand_more</mwc-icon
82
+ >
83
+ <ox-popup id="sorter-control">
84
+ <ox-sorters-control> </ox-sorters-control>
85
+ </ox-popup>
86
+ </div>
87
+
88
+ <div id="modes">
89
+ <mwc-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</mwc-icon>
90
+ <mwc-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</mwc-icon>
91
+ <mwc-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</mwc-icon>
92
+ </div>
93
+ </div>
94
+ </ox-grist>
95
+ `
96
+ }
97
+
98
+ get grist() {
99
+ return this.renderRoot.querySelector('ox-grist')
100
+ }
101
+
102
+ async pageInitialized(lifecycle) {
103
+ this.gristConfig = {
104
+ list: { fields: ['dataSet', 'data', 'spec', 'updater', 'updatedAt'] },
105
+ columns: [
106
+ { type: 'gutter', gutterName: 'sequence' },
107
+ { type: 'gutter', gutterName: 'row-selector', multiple: true },
108
+ {
109
+ type: 'gutter',
110
+ gutterName: 'button',
111
+ icon: 'assignment',
112
+ handlers: {
113
+ click: (columns, data, column, record, rowIndex) => {
114
+ openPopup(
115
+ html` <data-sample-view .dataSample=${record} style="background-color: white;"></data-sample-view> `,
116
+ {
117
+ backdrop: true,
118
+ size: 'large',
119
+ title: i18next.t('title.data-sample view')
120
+ }
121
+ )
122
+ }
123
+ }
124
+ },
125
+ {
126
+ type: 'string',
127
+ name: 'name',
128
+ label: true,
129
+ header: i18next.t('field.name'),
130
+ record: {
131
+ editable: false
132
+ },
133
+ filter: 'search',
134
+ sortable: true,
135
+ width: 120,
136
+ imex: true
137
+ },
138
+ {
139
+ type: 'string',
140
+ name: 'description',
141
+ label: true,
142
+ header: i18next.t('field.description'),
143
+ record: {
144
+ editable: false
145
+ },
146
+ filter: 'search',
147
+ width: 150,
148
+ imex: true
149
+ },
150
+ {
151
+ type: 'resource-object',
152
+ name: 'dataSet',
153
+ header: i18next.t('field.data-set'),
154
+ record: {
155
+ editable: false
156
+ },
157
+ sortable: true,
158
+ width: 120,
159
+ imex: true
160
+ },
161
+ {
162
+ type: 'json5',
163
+ name: 'partitionKeys',
164
+ header: i18next.t('field.partition-keys'),
165
+ record: {
166
+ editable: false
167
+ },
168
+ width: 200,
169
+ imex: true
170
+ },
171
+ {
172
+ type: 'checkbox',
173
+ name: 'ooc',
174
+ header: i18next.t('field.ooc'),
175
+ record: {
176
+ editable: false
177
+ },
178
+ width: 30
179
+ },
180
+ {
181
+ type: 'checkbox',
182
+ name: 'oos',
183
+ header: i18next.t('field.oos'),
184
+ record: {
185
+ editable: false
186
+ },
187
+ width: 30
188
+ },
189
+ {
190
+ type: 'json5',
191
+ name: 'data',
192
+ header: i18next.t('field.data'),
193
+ record: {
194
+ editable: false
195
+ },
196
+ width: 200,
197
+ imex: true
198
+ },
199
+ {
200
+ type: 'json5',
201
+ name: 'spec',
202
+ header: i18next.t('field.spec'),
203
+ record: {
204
+ editable: false
205
+ },
206
+ width: 200
207
+ },
208
+ {
209
+ type: 'text',
210
+ name: 'rawData',
211
+ header: i18next.t('field.raw-data'),
212
+ record: {
213
+ editable: false
214
+ },
215
+ width: 200,
216
+ imex: true
217
+ },
218
+ {
219
+ type: 'string',
220
+ name: 'workDate',
221
+ header: i18next.t('field.work-date'),
222
+ sortable: true,
223
+ width: 80,
224
+ imex: true
225
+ },
226
+ {
227
+ type: 'string',
228
+ name: 'workShift',
229
+ header: i18next.t('field.work-shift'),
230
+ sortable: true,
231
+ width: 40,
232
+ imex: true
233
+ },
234
+ {
235
+ type: 'datetime',
236
+ name: 'collectedAt',
237
+ header: i18next.t('field.collected-at'),
238
+ sortable: true,
239
+ width: 180,
240
+ imex: true
241
+ },
242
+ {
243
+ type: 'resource-object',
244
+ name: 'updater',
245
+ header: i18next.t('field.updater'),
246
+ sortable: true,
247
+ width: 120,
248
+ imex: true
249
+ },
250
+ {
251
+ type: 'datetime',
252
+ name: 'updatedAt',
253
+ header: i18next.t('field.updated_at'),
254
+ sortable: true,
255
+ width: 180,
256
+ imex: true
257
+ }
258
+ ],
259
+ rows: {
260
+ appendable: false,
261
+ selectable: {
262
+ multiple: true
263
+ },
264
+ classifier: function (record, rowIndex) {
265
+ var emphasized
266
+ if (record['oos']) {
267
+ emphasized = ['red']
268
+ } else if (record['ooc']) {
269
+ emphasized = 'orange'
270
+ }
271
+
272
+ return {
273
+ emphasized
274
+ }
275
+ }
276
+ },
277
+ sorters: [
278
+ {
279
+ name: 'updatedAt',
280
+ desc: true
281
+ }
282
+ ]
283
+ }
284
+
285
+ await this.updateComplete
286
+
287
+ this.grist.fetch()
288
+ }
289
+
290
+ // async pageUpdated(changes, lifecycle) {
291
+ // if (this.active) {
292
+ // // update with url params value
293
+ // this._updateSearchConfig(lifecycle)
294
+ // await this.updateComplete
295
+
296
+ // this.grist.fetch()
297
+ // }
298
+ // }
299
+
300
+ async fetchHandler({ page, limit, sortings = [], filters = [] }) {
301
+ const response = await client.query({
302
+ query: gql`
303
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
304
+ responses: dataSamples(filters: $filters, pagination: $pagination, sortings: $sortings) {
305
+ items {
306
+ id
307
+ name
308
+ description
309
+ dataSet {
310
+ id
311
+ name
312
+ description
313
+ }
314
+ partitionKeys
315
+ data
316
+ rawData
317
+ spec
318
+ ooc
319
+ oos
320
+ workDate
321
+ workShift
322
+ updater {
323
+ id
324
+ name
325
+ }
326
+ updatedAt
327
+ collectedAt
328
+ }
329
+ total
330
+ }
331
+ }
332
+ `,
333
+ variables: {
334
+ filters,
335
+ pagination: { page, limit },
336
+ sortings
337
+ }
338
+ })
339
+
340
+ return {
341
+ total: response.data.responses.total || 0,
342
+ records: response.data.responses.items || []
343
+ }
344
+ }
345
+
346
+ _exportableData() {
347
+ let records = []
348
+ if (this.grist.selected && this.grist.selected.length > 0) {
349
+ records = this.grist.selected
350
+ } else {
351
+ records = this.grist.data.records
352
+ }
353
+
354
+ var headerSetting = this.grist.compiledConfig.columns
355
+ .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
356
+ .map(column => {
357
+ return column.imex === true
358
+ ? {
359
+ header: column.header.renderer(),
360
+ key: column.name,
361
+ width: column.width,
362
+ type: column.type
363
+ }
364
+ : column.imex
365
+ })
366
+
367
+ var data = records.map(item => {
368
+ return {
369
+ id: item.id,
370
+ ...this.gristConfig.columns
371
+ .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
372
+ .reduce((record, column) => {
373
+ const key = column.imex === true ? column.name : column.imex.key
374
+ record[key] = key
375
+ .split('.')
376
+ .reduce((obj, key) => (obj && obj[key] !== 'undefined' ? obj[key] : undefined), item)
377
+ return record
378
+ }, {})
379
+ }
380
+ })
381
+
382
+ return { header: headerSetting, data: data }
383
+ }
384
+ }
385
+
386
+ window.customElements.define('data-sample-list-page', DataSampleListPage)
@@ -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)