@things-factory/dataset 5.0.0-alpha.3 → 5.0.0-alpha.32
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.
- package/README.md +13 -0
- package/assets/data-samples.jpg +0 -0
- package/client/bootstrap.js +16 -1
- package/client/pages/data-entry/data-entry-form.js +85 -0
- package/client/pages/data-entry/data-entry-list-page.js +464 -0
- package/client/pages/data-ooc/data-ooc-list-page.js +488 -0
- package/client/pages/data-ooc/data-ooc-view.js +182 -0
- package/client/pages/{data-sample.js → data-sample/data-sample-list-page.js} +153 -59
- package/client/pages/data-sample/data-sample-view.js +97 -0
- package/client/pages/{data-sensor.js → data-sensor/data-sensor-list-page.js} +11 -16
- package/client/pages/{data-item-list.js → data-set/data-item-list.js} +70 -16
- package/client/pages/{data-set-importer.js → data-set/data-set-importer.js} +0 -0
- package/client/pages/{data-set.js → data-set/data-set-list-page.js} +282 -76
- package/client/route.js +14 -6
- package/dist-server/controllers/create-data-sample.js +133 -0
- package/dist-server/controllers/create-data-sample.js.map +1 -0
- package/dist-server/controllers/data-use-case.js +57 -0
- package/dist-server/controllers/data-use-case.js.map +1 -0
- package/dist-server/controllers/index.js +17 -0
- package/dist-server/controllers/index.js.map +1 -1
- package/dist-server/index.js +2 -0
- package/dist-server/index.js.map +1 -1
- package/dist-server/routes.js +9 -24
- package/dist-server/routes.js.map +1 -1
- package/dist-server/service/data-item/data-item-mutation.js +5 -1
- package/dist-server/service/data-item/data-item-mutation.js.map +1 -1
- package/dist-server/service/data-item/data-item-type.js +18 -6
- package/dist-server/service/data-item/data-item-type.js.map +1 -1
- package/dist-server/service/data-item/data-item.js +27 -7
- package/dist-server/service/data-item/data-item.js.map +1 -1
- package/dist-server/service/data-ooc/data-ooc-mutation.js +92 -0
- package/dist-server/service/data-ooc/data-ooc-mutation.js.map +1 -0
- package/dist-server/service/data-ooc/data-ooc-query.js +115 -0
- package/dist-server/service/data-ooc/data-ooc-query.js.map +1 -0
- package/dist-server/service/data-ooc/data-ooc-subscription.js +65 -0
- package/dist-server/service/data-ooc/data-ooc-subscription.js.map +1 -0
- package/dist-server/service/data-ooc/data-ooc-type.js +107 -0
- package/dist-server/service/data-ooc/data-ooc-type.js.map +1 -0
- package/dist-server/service/data-ooc/data-ooc.js +237 -0
- package/dist-server/service/data-ooc/data-ooc.js.map +1 -0
- package/dist-server/service/data-ooc/index.js +10 -0
- package/dist-server/service/data-ooc/index.js.map +1 -0
- package/dist-server/service/data-sample/data-sample-mutation.js +3 -105
- package/dist-server/service/data-sample/data-sample-mutation.js.map +1 -1
- package/dist-server/service/data-sample/data-sample-type.js +12 -42
- package/dist-server/service/data-sample/data-sample-type.js.map +1 -1
- package/dist-server/service/data-sample/data-sample.js +34 -3
- package/dist-server/service/data-sample/data-sample.js.map +1 -1
- package/dist-server/service/data-set/data-set-mutation.js +1 -2
- package/dist-server/service/data-set/data-set-mutation.js.map +1 -1
- package/dist-server/service/data-set/data-set-query.js +110 -1
- package/dist-server/service/data-set/data-set-query.js.map +1 -1
- package/dist-server/service/data-set/data-set-type.js +48 -4
- package/dist-server/service/data-set/data-set-type.js.map +1 -1
- package/dist-server/service/data-set/data-set.js +59 -15
- package/dist-server/service/data-set/data-set.js.map +1 -1
- package/dist-server/service/data-spec/data-spec-manager.js +20 -0
- package/dist-server/service/data-spec/data-spec-manager.js.map +1 -0
- package/dist-server/service/data-spec/data-spec-query.js +48 -0
- package/dist-server/service/data-spec/data-spec-query.js.map +1 -0
- package/dist-server/service/data-spec/data-spec.js +78 -0
- package/dist-server/service/data-spec/data-spec.js.map +1 -0
- package/dist-server/service/data-spec/index.js +8 -0
- package/dist-server/service/data-spec/index.js.map +1 -0
- package/dist-server/service/index.js +12 -4
- package/dist-server/service/index.js.map +1 -1
- package/package.json +18 -12
- package/server/controllers/create-data-sample.ts +175 -0
- package/server/controllers/data-use-case.ts +85 -0
- package/server/controllers/index.ts +1 -0
- package/server/index.ts +3 -0
- package/server/routes.ts +17 -31
- package/server/service/data-item/data-item-mutation.ts +6 -1
- package/server/service/data-item/data-item-type.ts +13 -6
- package/server/service/data-item/data-item.ts +21 -5
- package/server/service/data-ooc/data-ooc-mutation.ts +150 -0
- package/server/service/data-ooc/data-ooc-query.ts +63 -0
- package/server/service/data-ooc/data-ooc-subscription.ts +51 -0
- package/server/service/data-ooc/data-ooc-type.ts +68 -0
- package/server/service/data-ooc/data-ooc.ts +204 -0
- package/server/service/data-ooc/index.ts +7 -0
- package/server/service/data-sample/data-sample-mutation.ts +6 -128
- package/server/service/data-sample/data-sample-type.ts +7 -28
- package/server/service/data-sample/data-sample.ts +33 -3
- package/server/service/data-set/data-set-mutation.ts +1 -4
- package/server/service/data-set/data-set-query.ts +87 -2
- package/server/service/data-set/data-set-type.ts +37 -4
- package/server/service/data-set/data-set.ts +52 -12
- package/server/service/data-spec/data-spec-manager.ts +21 -0
- package/server/service/data-spec/data-spec-query.ts +21 -0
- package/server/service/data-spec/data-spec.ts +44 -0
- package/server/service/data-spec/index.ts +5 -0
- package/server/service/index.ts +16 -8
- package/things-factory.config.js +14 -6
- package/translations/en.json +30 -0
- package/translations/ko.json +30 -1
- package/translations/ms.json +29 -0
- package/translations/zh.json +29 -0
- package/yarn-error.log +23244 -0
@@ -1,53 +1,81 @@
|
|
1
1
|
import '@operato/data-grist'
|
2
|
-
import './data-item-list'
|
3
|
-
import './data-set-importer'
|
2
|
+
import './data-item-list.js'
|
3
|
+
import './data-set-importer.js'
|
4
|
+
import '../data-entry/data-entry-form.js'
|
4
5
|
|
5
6
|
import gql from 'graphql-tag'
|
7
|
+
import JSON5 from 'json5'
|
6
8
|
import { css, html } from 'lit'
|
7
9
|
import moment from 'moment-timezone'
|
8
10
|
import { connect } from 'pwa-helpers/connect-mixin'
|
9
11
|
|
12
|
+
import { getEditor, getRenderer } from '@operato/data-grist'
|
13
|
+
import { OxDataUseCase } from '@operato/dataset'
|
10
14
|
import { client } from '@operato/graphql'
|
11
15
|
import { i18next, localize } from '@operato/i18n'
|
12
16
|
import { notify, openPopup } from '@operato/layout'
|
13
17
|
import { PageView, store } from '@operato/shell'
|
14
|
-
import { CommonButtonStyles, ScrollbarStyles } from '@operato/styles'
|
18
|
+
import { CommonButtonStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles'
|
15
19
|
import { isMobileDevice } from '@operato/utils'
|
16
20
|
|
17
|
-
|
21
|
+
const DEFAULT_TZ = Intl.DateTimeFormat().resolvedOptions().timeZone
|
22
|
+
const TIMEZONE_OPTIONS = ['', DEFAULT_TZ, ...moment.tz.names().filter(tz => tz !== DEFAULT_TZ)]
|
23
|
+
|
24
|
+
const VIEW_TYPES = [
|
25
|
+
{
|
26
|
+
display: '',
|
27
|
+
value: ''
|
28
|
+
},
|
29
|
+
{
|
30
|
+
display: 'Generated',
|
31
|
+
value: 'generated'
|
32
|
+
},
|
33
|
+
{
|
34
|
+
display: 'Board',
|
35
|
+
value: 'board'
|
36
|
+
},
|
37
|
+
{
|
38
|
+
display: 'Page',
|
39
|
+
value: 'page'
|
40
|
+
},
|
41
|
+
{
|
42
|
+
display: 'External URL',
|
43
|
+
value: 'external'
|
44
|
+
}
|
45
|
+
]
|
46
|
+
|
47
|
+
const USECASE_OPTIONS = () => {
|
48
|
+
return ['', ...OxDataUseCase.getUseCaseNames()].map(name => {
|
49
|
+
return {
|
50
|
+
display: name,
|
51
|
+
value: name
|
52
|
+
}
|
53
|
+
})
|
54
|
+
}
|
55
|
+
|
56
|
+
export class DataSetListPage extends connect(store)(localize(i18next)(PageView)) {
|
18
57
|
static get properties() {
|
19
58
|
return {
|
20
59
|
active: String,
|
21
|
-
gristConfig: Object
|
60
|
+
gristConfig: Object,
|
61
|
+
filters: Object,
|
62
|
+
sorters: Object,
|
63
|
+
mode: String
|
22
64
|
}
|
23
65
|
}
|
24
66
|
|
25
67
|
static get styles() {
|
26
68
|
return [
|
27
69
|
ScrollbarStyles,
|
70
|
+
CommonGristStyles,
|
28
71
|
css`
|
29
72
|
:host {
|
30
73
|
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
|
-
#filters {
|
42
|
-
display: flex;
|
43
|
-
flex-direction: row;
|
44
|
-
justify-content: space-between;
|
45
74
|
|
46
|
-
|
47
|
-
}
|
75
|
+
width: 100%;
|
48
76
|
|
49
|
-
|
50
|
-
|
77
|
+
--grid-record-emphasized-background-color: red;
|
78
|
+
--grid-record-emphasized-color: yellow;
|
51
79
|
}
|
52
80
|
`
|
53
81
|
]
|
@@ -56,7 +84,7 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
56
84
|
get context() {
|
57
85
|
return {
|
58
86
|
title: i18next.t('title.data-set list'),
|
59
|
-
help: '
|
87
|
+
help: 'dataset/data-set',
|
60
88
|
actions: [
|
61
89
|
{
|
62
90
|
title: i18next.t('button.copy'),
|
@@ -85,14 +113,43 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
85
113
|
}
|
86
114
|
|
87
115
|
render() {
|
116
|
+
const mode = this.mode || (isMobileDevice() ? 'LIST' : 'GRID')
|
117
|
+
|
88
118
|
return html`
|
89
119
|
<ox-grist
|
90
|
-
.mode=${
|
120
|
+
.mode=${mode}
|
91
121
|
.config=${this.gristConfig}
|
122
|
+
.filters=${this.filters}
|
123
|
+
.orders=${this.orders}
|
92
124
|
.fetchHandler=${this.fetchHandler.bind(this)}
|
93
125
|
>
|
94
126
|
<div slot="headroom" id="filters">
|
95
|
-
<
|
127
|
+
<div id="filters">
|
128
|
+
<ox-filters-form></ox-filters-form>
|
129
|
+
</div>
|
130
|
+
|
131
|
+
<div id="sorters">
|
132
|
+
Sort
|
133
|
+
<mwc-icon
|
134
|
+
@click=${e => {
|
135
|
+
const target = e.currentTarget
|
136
|
+
this.renderRoot.querySelector('#sorter-control').open({
|
137
|
+
right: 0,
|
138
|
+
top: target.offsetTop + target.offsetHeight
|
139
|
+
})
|
140
|
+
}}
|
141
|
+
>expand_more</mwc-icon
|
142
|
+
>
|
143
|
+
<ox-popup id="sorter-control">
|
144
|
+
<ox-sorters-control> </ox-sorters-control>
|
145
|
+
</ox-popup>
|
146
|
+
</div>
|
147
|
+
|
148
|
+
<div id="modes">
|
149
|
+
<mwc-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</mwc-icon>
|
150
|
+
<mwc-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</mwc-icon>
|
151
|
+
<mwc-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</mwc-icon>
|
152
|
+
</div>
|
96
153
|
</div>
|
97
154
|
</ox-grist>
|
98
155
|
`
|
@@ -102,32 +159,12 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
102
159
|
return this.renderRoot.querySelector('ox-grist')
|
103
160
|
}
|
104
161
|
|
105
|
-
// update with url params value
|
106
|
-
_updateSearchConfig(lifecycle) {
|
107
|
-
// this.searchConfig = this.searchConfig.map(conf => {
|
108
|
-
// if (conf.name in lifecycle.params) {
|
109
|
-
// conf.value = lifecycle.params[conf.name]
|
110
|
-
// } else {
|
111
|
-
// delete conf.value
|
112
|
-
// }
|
113
|
-
// return conf
|
114
|
-
// })
|
115
|
-
}
|
116
|
-
|
117
|
-
// set default field value to record with searchConfig
|
118
|
-
_setDefaultFieldsValue(fields) {
|
119
|
-
// this.searchConfig.forEach(conf => {
|
120
|
-
// if (!fields[conf.name] && conf.value) {
|
121
|
-
// fields[conf.name] = conf.value
|
122
|
-
// }
|
123
|
-
// })
|
124
|
-
}
|
125
|
-
|
126
162
|
async pageInitialized(lifecycle) {
|
127
|
-
this._updateSearchConfig(lifecycle)
|
128
|
-
|
129
163
|
this.gristConfig = {
|
130
|
-
list: {
|
164
|
+
list: {
|
165
|
+
fields: ['name', 'description'],
|
166
|
+
details: ['schedule', 'active']
|
167
|
+
},
|
131
168
|
columns: [
|
132
169
|
{ type: 'gutter', gutterName: 'sequence' },
|
133
170
|
{ type: 'gutter', gutterName: 'row-selector', multiple: true },
|
@@ -138,19 +175,38 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
138
175
|
handlers: {
|
139
176
|
click: (columns, data, column, record, rowIndex) => {
|
140
177
|
if (!record.id) return
|
141
|
-
openPopup(html` <data-item-list .dataSet=${record}></data-item-list> `, {
|
178
|
+
const popup = openPopup(html` <data-item-list .dataSet=${record}></data-item-list> `, {
|
142
179
|
backdrop: true,
|
143
180
|
help: 'data-set/ui/data-item-list',
|
144
181
|
size: 'large',
|
145
182
|
title: i18next.t('title.data-item list')
|
146
183
|
})
|
184
|
+
popup.onclosed = () => {
|
185
|
+
this.grist.fetch()
|
186
|
+
}
|
187
|
+
}
|
188
|
+
}
|
189
|
+
},
|
190
|
+
{
|
191
|
+
type: 'gutter',
|
192
|
+
gutterName: 'button',
|
193
|
+
icon: 'fact_check',
|
194
|
+
handlers: {
|
195
|
+
click: (columns, data, column, record, rowIndex) => {
|
196
|
+
openPopup(
|
197
|
+
html` <data-entry-form .dataSet=${record} style="background-color: white;"></data-entry-form> `,
|
198
|
+
{
|
199
|
+
backdrop: true,
|
200
|
+
size: 'large',
|
201
|
+
title: i18next.t('title.data-entry-form')
|
202
|
+
}
|
203
|
+
)
|
147
204
|
}
|
148
205
|
}
|
149
206
|
},
|
150
207
|
{
|
151
208
|
type: 'string',
|
152
209
|
name: 'name',
|
153
|
-
label: true,
|
154
210
|
header: i18next.t('field.name'),
|
155
211
|
record: {
|
156
212
|
editable: true
|
@@ -162,7 +218,6 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
162
218
|
{
|
163
219
|
type: 'string',
|
164
220
|
name: 'description',
|
165
|
-
label: true,
|
166
221
|
header: i18next.t('field.description'),
|
167
222
|
record: {
|
168
223
|
editable: true
|
@@ -178,15 +233,58 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
178
233
|
record: {
|
179
234
|
editable: true
|
180
235
|
},
|
236
|
+
filter: true,
|
237
|
+
sortable: true,
|
238
|
+
width: 60
|
239
|
+
},
|
240
|
+
{
|
241
|
+
type: 'select',
|
242
|
+
name: 'type',
|
243
|
+
label: true,
|
244
|
+
header: i18next.t('field.type'),
|
245
|
+
record: {
|
246
|
+
editable: true,
|
247
|
+
options: [
|
248
|
+
{},
|
249
|
+
{
|
250
|
+
display: 'Manually Collected',
|
251
|
+
value: 'manual'
|
252
|
+
},
|
253
|
+
{
|
254
|
+
display: 'Automatically Collected',
|
255
|
+
value: 'automatic'
|
256
|
+
}
|
257
|
+
]
|
258
|
+
},
|
181
259
|
sortable: true,
|
260
|
+
filter: true,
|
182
261
|
width: 60
|
183
262
|
},
|
184
263
|
{
|
185
|
-
type: '
|
264
|
+
type: 'select',
|
265
|
+
name: 'useCase',
|
266
|
+
label: true,
|
267
|
+
header: i18next.t('field.use-case'),
|
268
|
+
record: {
|
269
|
+
editable: true,
|
270
|
+
options: USECASE_OPTIONS
|
271
|
+
},
|
272
|
+
sortable: true,
|
273
|
+
filter: {
|
274
|
+
operator: 'eq',
|
275
|
+
options: USECASE_OPTIONS /* in case select options type is a function, filter should have its own options */
|
276
|
+
},
|
277
|
+
width: 80
|
278
|
+
},
|
279
|
+
{
|
280
|
+
type: 'partition-keys',
|
186
281
|
name: 'partitionKeys',
|
187
282
|
header: i18next.t('field.partition-keys'),
|
188
283
|
record: {
|
189
|
-
editable: true
|
284
|
+
editable: true,
|
285
|
+
options: {
|
286
|
+
objectified: true /* transfered as a object type */
|
287
|
+
}
|
190
288
|
},
|
191
289
|
width: 200
|
192
290
|
},
|
@@ -196,7 +294,10 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
196
294
|
label: true,
|
197
295
|
header: i18next.t('field.schedule'),
|
198
296
|
record: {
|
199
|
-
editable: true
|
297
|
+
editable: true,
|
298
|
+
options: {
|
299
|
+
objectified: true
|
300
|
+
}
|
200
301
|
},
|
201
302
|
width: 80,
|
202
303
|
label: true
|
@@ -207,12 +308,81 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
207
308
|
header: i18next.t('field.timezone'),
|
208
309
|
record: {
|
209
310
|
editable: true,
|
210
|
-
options:
|
311
|
+
options: TIMEZONE_OPTIONS
|
312
|
+
},
|
313
|
+
width: 120
|
314
|
+
},
|
315
|
+
{
|
316
|
+
type: 'resource-object',
|
317
|
+
name: 'supervisoryRole',
|
318
|
+
header: i18next.t('field.supervisory-role'),
|
319
|
+
record: {
|
320
|
+
editable: true,
|
321
|
+
options: {
|
322
|
+
queryName: 'roles'
|
323
|
+
}
|
211
324
|
},
|
325
|
+
sortable: true,
|
212
326
|
width: 120
|
213
327
|
},
|
214
328
|
{
|
215
|
-
type: '
|
329
|
+
type: 'select',
|
330
|
+
name: 'entryType',
|
331
|
+
label: true,
|
332
|
+
header: i18next.t('field.entry-type'),
|
333
|
+
record: {
|
334
|
+
editable: true,
|
335
|
+
options: VIEW_TYPES
|
336
|
+
},
|
337
|
+
width: 80
|
338
|
+
},
|
339
|
+
{
|
340
|
+
type: 'string',
|
341
|
+
name: 'entryView',
|
342
|
+
header: i18next.t('field.entry-view'),
|
343
|
+
record: {
|
344
|
+
editable: true,
|
345
|
+
editor: function (value, column, record, rowIndex, field) {
|
346
|
+
var type = record.entryType !== 'board' ? 'string' : 'board'
|
347
|
+
return getEditor(type)(value, column, record, rowIndex, field)
|
348
|
+
},
|
349
|
+
renderer: function (value, column, record, rowIndex, field) {
|
350
|
+
var type = record.entryType !== 'board' ? 'string' : 'board'
|
351
|
+
return getRenderer(type)(value, column, record, rowIndex, field)
|
352
|
+
}
|
353
|
+
},
|
354
|
+
width: 140
|
355
|
+
},
|
356
|
+
{
|
357
|
+
type: 'select',
|
358
|
+
name: 'monitorType',
|
359
|
+
label: true,
|
360
|
+
header: i18next.t('field.monitor-type'),
|
361
|
+
record: {
|
362
|
+
editable: true,
|
363
|
+
options: VIEW_TYPES
|
364
|
+
},
|
365
|
+
width: 80
|
366
|
+
},
|
367
|
+
{
|
368
|
+
type: 'string',
|
369
|
+
name: 'monitorView',
|
370
|
+
header: i18next.t('field.monitor-view'),
|
371
|
+
record: {
|
372
|
+
editable: true,
|
373
|
+
editor: function (value, column, record, rowIndex, field) {
|
374
|
+
var type = record.monitorType !== 'board' ? 'string' : 'board'
|
375
|
+
return getEditor(type)(value, column, record, rowIndex, field)
|
376
|
+
},
|
377
|
+
renderer: function (value, column, record, rowIndex, field) {
|
378
|
+
var type = record.monitorType !== 'board' ? 'string' : 'board'
|
379
|
+
return getRenderer(type)(value, column, record, rowIndex, field)
|
380
|
+
}
|
381
|
+
},
|
382
|
+
width: 140
|
383
|
+
},
|
384
|
+
{
|
385
|
+
type: 'resource-object',
|
216
386
|
name: 'updater',
|
217
387
|
header: i18next.t('field.updater'),
|
218
388
|
record: {
|
@@ -251,10 +421,28 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
251
421
|
|
252
422
|
async pageUpdated(changes, lifecycle) {
|
253
423
|
if (this.active) {
|
254
|
-
// update with url params value
|
255
|
-
this._updateSearchConfig(lifecycle)
|
256
424
|
await this.updateComplete
|
257
425
|
|
426
|
+
var filters = lifecycle.params?.['filters']
|
427
|
+
if (filters) {
|
428
|
+
try {
|
429
|
+
filters = JSON5.parse(filters)
|
430
|
+
this.filters = filters
|
431
|
+
} catch (e) {
|
432
|
+
console.error(`filters parameter parsing error: ${e}`)
|
433
|
+
}
|
434
|
+
}
|
435
|
+
|
436
|
+
var sorters = lifecycle.params?.['sorters']
|
437
|
+
if (sorters) {
|
438
|
+
try {
|
439
|
+
sorters = JSON5.parse(sorters)
|
440
|
+
this.sorters = sorters
|
441
|
+
} catch (e) {
|
442
|
+
console.error(`sorters parameter parsing error: ${e}`)
|
443
|
+
}
|
444
|
+
}
|
445
|
+
|
258
446
|
this.grist.fetch()
|
259
447
|
}
|
260
448
|
}
|
@@ -269,10 +457,19 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
269
457
|
name
|
270
458
|
description
|
271
459
|
partitionKeys
|
272
|
-
slugger
|
273
460
|
active
|
461
|
+
type
|
462
|
+
useCase
|
274
463
|
schedule
|
275
464
|
timezone
|
465
|
+
supervisoryRole {
|
466
|
+
id
|
467
|
+
name
|
468
|
+
}
|
469
|
+
entryType
|
470
|
+
entryView
|
471
|
+
monitorType
|
472
|
+
monitorView
|
276
473
|
updater {
|
277
474
|
id
|
278
475
|
name
|
@@ -283,7 +480,10 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
283
480
|
description
|
284
481
|
sequence
|
285
482
|
active
|
483
|
+
tag
|
286
484
|
type
|
485
|
+
unit
|
486
|
+
options
|
287
487
|
quota
|
288
488
|
spec
|
289
489
|
}
|
@@ -330,13 +530,6 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
330
530
|
}
|
331
531
|
}
|
332
532
|
|
333
|
-
async stateChanged(state) {
|
334
|
-
if (this.active && this._currentPopupName && !state.layout.viewparts[this._currentPopupName]) {
|
335
|
-
this.grist.fetch()
|
336
|
-
this._currentPopupName = null
|
337
|
-
}
|
338
|
-
}
|
339
|
-
|
340
533
|
async _copyDataSet() {
|
341
534
|
var selected = this.grist.selected
|
342
535
|
if (selected.length == 0) return
|
@@ -355,7 +548,9 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
355
548
|
}
|
356
549
|
})
|
357
550
|
|
358
|
-
if (!response.errors)
|
551
|
+
if (!response.errors) {
|
552
|
+
this.grist.fetch()
|
553
|
+
}
|
359
554
|
}
|
360
555
|
|
361
556
|
async _updateDataSet() {
|
@@ -367,7 +562,6 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
367
562
|
for (let key in dirtyFields) {
|
368
563
|
patchField[key] = dirtyFields[key].after
|
369
564
|
}
|
370
|
-
this._setDefaultFieldsValue(patchField)
|
371
565
|
patchField.cuFlag = patch.__dirty__
|
372
566
|
|
373
567
|
return patchField
|
@@ -386,13 +580,25 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
386
580
|
}
|
387
581
|
})
|
388
582
|
|
389
|
-
if (!response.errors)
|
583
|
+
if (!response.errors) {
|
584
|
+
this.grist.fetch()
|
585
|
+
}
|
390
586
|
}
|
391
587
|
}
|
392
588
|
|
393
589
|
async exportHandler() {
|
394
590
|
const exportTargets = this.grist.selected.length ? this.grist.selected : this.grist.dirtyData.records
|
395
|
-
const targetFieldSet = new Set([
|
591
|
+
const targetFieldSet = new Set([
|
592
|
+
'id',
|
593
|
+
'name',
|
594
|
+
'type',
|
595
|
+
'description',
|
596
|
+
'tag',
|
597
|
+
'schedule',
|
598
|
+
'timezone',
|
599
|
+
'active',
|
600
|
+
'dataItems'
|
601
|
+
])
|
396
602
|
|
397
603
|
return exportTargets.map(dataSet => {
|
398
604
|
let tempObj = {}
|
@@ -408,11 +614,11 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
408
614
|
openPopup(
|
409
615
|
html`
|
410
616
|
<data-set-importer
|
411
|
-
.dataSets
|
412
|
-
@imported
|
617
|
+
.dataSets=${records}
|
618
|
+
@imported=${() => {
|
413
619
|
history.back()
|
414
620
|
this.grist.fetch()
|
415
|
-
}}
|
621
|
+
}}
|
416
622
|
></data-set-importer>
|
417
623
|
`,
|
418
624
|
{
|
@@ -424,4 +630,4 @@ export class DataSet extends connect(store)(localize(i18next)(PageView)) {
|
|
424
630
|
}
|
425
631
|
}
|
426
632
|
|
427
|
-
window.customElements.define('data-set-page',
|
633
|
+
window.customElements.define('data-set-list-page', DataSetListPage)
|
package/client/route.js
CHANGED
@@ -1,15 +1,23 @@
|
|
1
1
|
export default function route(page) {
|
2
2
|
switch (page) {
|
3
|
-
case 'data-set':
|
4
|
-
import('./pages/data-set')
|
3
|
+
case 'data-set-list':
|
4
|
+
import('./pages/data-set/data-set-list-page.js')
|
5
5
|
return page
|
6
6
|
|
7
|
-
case 'data-sensor':
|
8
|
-
import('./pages/data-sensor')
|
7
|
+
case 'data-sensor-list':
|
8
|
+
import('./pages/data-sensor/data-sensor-list-page.js')
|
9
9
|
return page
|
10
10
|
|
11
|
-
case 'data-sample':
|
12
|
-
import('./pages/data-sample')
|
11
|
+
case 'data-sample-list':
|
12
|
+
import('./pages/data-sample/data-sample-list-page.js')
|
13
|
+
return page
|
14
|
+
|
15
|
+
case 'data-ooc-list':
|
16
|
+
import('./pages/data-ooc/data-ooc-list-page.js')
|
17
|
+
return page
|
18
|
+
|
19
|
+
case 'data-entry-list':
|
20
|
+
import('./pages/data-entry/data-entry-list-page.js')
|
13
21
|
return page
|
14
22
|
}
|
15
23
|
}
|
@@ -0,0 +1,133 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.createDataSample = void 0;
|
7
|
+
const moment_timezone_1 = __importDefault(require("moment-timezone"));
|
8
|
+
const shell_1 = require("@things-factory/shell");
|
9
|
+
const data_item_1 = require("../service/data-item/data-item");
|
10
|
+
const data_ooc_1 = require("../service/data-ooc/data-ooc");
|
11
|
+
const data_sample_1 = require("../service/data-sample/data-sample");
|
12
|
+
const data_set_1 = require("../service/data-set/data-set");
|
13
|
+
const data_use_case_1 = require("./data-use-case");
|
14
|
+
const work_shift_1 = require("@things-factory/work-shift");
|
15
|
+
const debug = require('debug')('things-factory:dataset:controller/save-data-sample');
|
16
|
+
// parse variable javascript string pattern
|
17
|
+
const replaceVariables = (keys, dic) => {
|
18
|
+
for (const k in keys) {
|
19
|
+
const matches = keys[k].match(/\$\{\w*\}/g);
|
20
|
+
matches &&
|
21
|
+
matches.forEach(m => {
|
22
|
+
keys[k] = keys[k].replace(m, dic[m.slice(2, -1)]);
|
23
|
+
});
|
24
|
+
}
|
25
|
+
return keys;
|
26
|
+
};
|
27
|
+
// It is required UTC date for Partitioning File System like AWS S3 from Athena.
|
28
|
+
// ex) %YYYY, %MM, %DD
|
29
|
+
const formatDate = (keys, _moment) => {
|
30
|
+
for (const k in keys) {
|
31
|
+
const matches = keys[k].match(/%\w*/g);
|
32
|
+
matches &&
|
33
|
+
matches.forEach(m => {
|
34
|
+
keys[k] = keys[k].replace(m, _moment.format(m.substr(1)));
|
35
|
+
});
|
36
|
+
}
|
37
|
+
return keys;
|
38
|
+
};
|
39
|
+
async function createDataSample(dataSample, context) {
|
40
|
+
const { domain, user, tx } = context.state;
|
41
|
+
const dataSet = await tx.getRepository(data_set_1.DataSet).findOne({
|
42
|
+
where: { id: dataSample.dataSet.id }
|
43
|
+
});
|
44
|
+
const dataItems = await tx.getRepository(data_item_1.DataItem).find({
|
45
|
+
where: {
|
46
|
+
domain,
|
47
|
+
dataSet
|
48
|
+
},
|
49
|
+
order: {
|
50
|
+
sequence: 'DESC'
|
51
|
+
}
|
52
|
+
});
|
53
|
+
const spec = dataItems.reduce((spec, dataItem) => {
|
54
|
+
spec[dataItem.tag] = Object.assign(Object.assign({}, dataItem.spec), { name: dataItem.name, hidden: dataItem.hidden });
|
55
|
+
return spec;
|
56
|
+
}, {});
|
57
|
+
const collectedAt = dataSample.collectedAt || new Date();
|
58
|
+
// workDate ex) 2022-04-04
|
59
|
+
const { workDate, workShift } = await (0, work_shift_1.getWorkDateAndShift)(domain, collectedAt);
|
60
|
+
const dateFormat = 'YYYY-MM-DD';
|
61
|
+
// local time dataSet timezone or domain timezone or default 'UTC'
|
62
|
+
const timezone = dataSet['timezone'] || domain['timezone'] || 'UTC';
|
63
|
+
// const collectedAt = dataSample.collectedAt || new Date()
|
64
|
+
const localDateTz = (0, moment_timezone_1.default)(collectedAt).tz(timezone);
|
65
|
+
const defaultPartitionKeys = {
|
66
|
+
domain: domain.subdomain,
|
67
|
+
datasetid: dataSample.dataSet.id,
|
68
|
+
date: localDateTz.format(dateFormat),
|
69
|
+
workdate: workDate,
|
70
|
+
workshift: workShift
|
71
|
+
};
|
72
|
+
var partitionKeys = Object.assign(Object.assign({}, defaultPartitionKeys), dataSet.partitionKeys);
|
73
|
+
partitionKeys = formatDate(partitionKeys, localDateTz);
|
74
|
+
partitionKeys = replaceVariables(partitionKeys, Object.assign({}, dataSample.data));
|
75
|
+
const { ooc, oos } = data_use_case_1.DataUseCase.evaluate(dataSet, dataItems, dataSample.data) || {};
|
76
|
+
const result = await tx.getRepository(data_sample_1.DataSample).save(Object.assign(Object.assign({ name: dataSet.name, description: dataSet.description, useCase: dataSet.useCase }, dataSample), { domain,
|
77
|
+
partitionKeys,
|
78
|
+
spec,
|
79
|
+
ooc,
|
80
|
+
oos,
|
81
|
+
collectedAt,
|
82
|
+
workDate,
|
83
|
+
workShift, creator: user, updater: user }));
|
84
|
+
if (ooc || oos) {
|
85
|
+
const dataOoc = await tx.getRepository(data_ooc_1.DataOoc).save({
|
86
|
+
name: dataSet.name,
|
87
|
+
description: dataSet.description,
|
88
|
+
useCase: dataSet.useCase,
|
89
|
+
dataSet,
|
90
|
+
dataSample: result,
|
91
|
+
data: dataSample.data,
|
92
|
+
rawData: dataSample.rawData,
|
93
|
+
domain,
|
94
|
+
partitionKeys,
|
95
|
+
spec,
|
96
|
+
ooc,
|
97
|
+
oos,
|
98
|
+
history: [
|
99
|
+
{
|
100
|
+
user: {
|
101
|
+
id: user.id,
|
102
|
+
name: user.name
|
103
|
+
},
|
104
|
+
state: data_ooc_1.DataOocStatus.CREATED,
|
105
|
+
timestamp: Date.now()
|
106
|
+
}
|
107
|
+
],
|
108
|
+
state: data_ooc_1.DataOocStatus.CREATED,
|
109
|
+
workDate,
|
110
|
+
workShift,
|
111
|
+
collectedAt,
|
112
|
+
creator: user,
|
113
|
+
updater: user
|
114
|
+
});
|
115
|
+
shell_1.pubsub.publish('data-ooc', {
|
116
|
+
dataOoc,
|
117
|
+
supervisoryRoleId: dataSet.supervisoryRoleId
|
118
|
+
});
|
119
|
+
shell_1.pubsub.publish('notification', {
|
120
|
+
notification: {
|
121
|
+
domain,
|
122
|
+
type: 'error',
|
123
|
+
title: `Data OOC occurred on '${dataSet.name}'`,
|
124
|
+
body: `Data OOC occurred on '${dataSet.name}'`,
|
125
|
+
url: (0, shell_1.getRedirectSubdomainPath)(context, domain.subdomain, `/data-ooc/${dataOoc.id}`),
|
126
|
+
timestamp: collectedAt
|
127
|
+
}
|
128
|
+
});
|
129
|
+
}
|
130
|
+
return result;
|
131
|
+
}
|
132
|
+
exports.createDataSample = createDataSample;
|
133
|
+
//# sourceMappingURL=create-data-sample.js.map
|