@things-factory/dataset 5.0.0-alpha.2 → 5.0.0-alpha.20

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 (96) hide show
  1. package/README.md +12 -0
  2. package/assets/data-samples.jpg +0 -0
  3. package/client/bootstrap.js +16 -1
  4. package/client/pages/data-entry-form.js +84 -0
  5. package/client/pages/data-item-list.js +58 -16
  6. package/client/pages/data-ooc-view.js +182 -0
  7. package/client/pages/data-ooc.js +469 -0
  8. package/client/pages/data-sample-view.js +97 -0
  9. package/client/pages/data-sample.js +130 -55
  10. package/client/pages/data-sensor.js +8 -18
  11. package/client/pages/data-set.js +126 -25
  12. package/client/route.js +4 -0
  13. package/dist-server/controllers/create-data-sample.js +122 -0
  14. package/dist-server/controllers/create-data-sample.js.map +1 -0
  15. package/dist-server/controllers/data-use-case.js +57 -0
  16. package/dist-server/controllers/data-use-case.js.map +1 -0
  17. package/dist-server/controllers/index.js +17 -0
  18. package/dist-server/controllers/index.js.map +1 -1
  19. package/dist-server/index.js +2 -0
  20. package/dist-server/index.js.map +1 -1
  21. package/dist-server/routes.js +9 -24
  22. package/dist-server/routes.js.map +1 -1
  23. package/dist-server/service/data-item/data-item-mutation.js +5 -1
  24. package/dist-server/service/data-item/data-item-mutation.js.map +1 -1
  25. package/dist-server/service/data-item/data-item-type.js +14 -5
  26. package/dist-server/service/data-item/data-item-type.js.map +1 -1
  27. package/dist-server/service/data-item/data-item.js +20 -7
  28. package/dist-server/service/data-item/data-item.js.map +1 -1
  29. package/dist-server/service/data-ooc/data-ooc-mutation.js +92 -0
  30. package/dist-server/service/data-ooc/data-ooc-mutation.js.map +1 -0
  31. package/dist-server/service/data-ooc/data-ooc-query.js +115 -0
  32. package/dist-server/service/data-ooc/data-ooc-query.js.map +1 -0
  33. package/dist-server/service/data-ooc/data-ooc-subscription.js +65 -0
  34. package/dist-server/service/data-ooc/data-ooc-subscription.js.map +1 -0
  35. package/dist-server/service/data-ooc/data-ooc-type.js +99 -0
  36. package/dist-server/service/data-ooc/data-ooc-type.js.map +1 -0
  37. package/dist-server/service/data-ooc/data-ooc.js +227 -0
  38. package/dist-server/service/data-ooc/data-ooc.js.map +1 -0
  39. package/dist-server/service/data-ooc/index.js +10 -0
  40. package/dist-server/service/data-ooc/index.js.map +1 -0
  41. package/dist-server/service/data-sample/data-sample-mutation.js +3 -105
  42. package/dist-server/service/data-sample/data-sample-mutation.js.map +1 -1
  43. package/dist-server/service/data-sample/data-sample-type.js +6 -43
  44. package/dist-server/service/data-sample/data-sample-type.js.map +1 -1
  45. package/dist-server/service/data-sample/data-sample.js +33 -12
  46. package/dist-server/service/data-sample/data-sample.js.map +1 -1
  47. package/dist-server/service/data-set/data-set-mutation.js +1 -2
  48. package/dist-server/service/data-set/data-set-mutation.js.map +1 -1
  49. package/dist-server/service/data-set/data-set-query.js +12 -0
  50. package/dist-server/service/data-set/data-set-query.js.map +1 -1
  51. package/dist-server/service/data-set/data-set-type.js +19 -2
  52. package/dist-server/service/data-set/data-set-type.js.map +1 -1
  53. package/dist-server/service/data-set/data-set.js +22 -10
  54. package/dist-server/service/data-set/data-set.js.map +1 -1
  55. package/dist-server/service/data-spec/data-spec-manager.js +20 -0
  56. package/dist-server/service/data-spec/data-spec-manager.js.map +1 -0
  57. package/dist-server/service/data-spec/data-spec-query.js +48 -0
  58. package/dist-server/service/data-spec/data-spec-query.js.map +1 -0
  59. package/dist-server/service/data-spec/data-spec.js +78 -0
  60. package/dist-server/service/data-spec/data-spec.js.map +1 -0
  61. package/dist-server/service/data-spec/index.js +8 -0
  62. package/dist-server/service/data-spec/index.js.map +1 -0
  63. package/dist-server/service/index.js +12 -4
  64. package/dist-server/service/index.js.map +1 -1
  65. package/package.json +15 -12
  66. package/server/controllers/create-data-sample.ts +161 -0
  67. package/server/controllers/data-use-case.ts +85 -0
  68. package/server/controllers/index.ts +1 -0
  69. package/server/index.ts +3 -0
  70. package/server/routes.ts +18 -32
  71. package/server/service/data-item/data-item-mutation.ts +6 -1
  72. package/server/service/data-item/data-item-type.ts +11 -7
  73. package/server/service/data-item/data-item.ts +16 -6
  74. package/server/service/data-ooc/data-ooc-mutation.ts +150 -0
  75. package/server/service/data-ooc/data-ooc-query.ts +63 -0
  76. package/server/service/data-ooc/data-ooc-subscription.ts +51 -0
  77. package/server/service/data-ooc/data-ooc-type.ts +62 -0
  78. package/server/service/data-ooc/data-ooc.ts +195 -0
  79. package/server/service/data-ooc/index.ts +7 -0
  80. package/server/service/data-sample/data-sample-mutation.ts +6 -128
  81. package/server/service/data-sample/data-sample-type.ts +4 -32
  82. package/server/service/data-sample/data-sample.ts +31 -10
  83. package/server/service/data-set/data-set-mutation.ts +1 -4
  84. package/server/service/data-set/data-set-query.ts +8 -1
  85. package/server/service/data-set/data-set-type.ts +17 -6
  86. package/server/service/data-set/data-set.ts +18 -8
  87. package/server/service/data-spec/data-spec-manager.ts +21 -0
  88. package/server/service/data-spec/data-spec-query.ts +21 -0
  89. package/server/service/data-spec/data-spec.ts +44 -0
  90. package/server/service/data-spec/index.ts +5 -0
  91. package/server/service/index.ts +16 -8
  92. package/things-factory.config.js +4 -0
  93. package/translations/en.json +20 -1
  94. package/translations/ko.json +21 -2
  95. package/translations/ms.json +20 -1
  96. package/translations/zh.json +20 -1
package/README.md ADDED
@@ -0,0 +1,12 @@
1
+ # dataset
2
+ ## partition keys
3
+ At the early stage, partition keys are desinged for dynamic partitioning for Athena. But It will be required so many AWS Glue crawlers also by each 'data-sets'.
4
+ Now partition keys are fixed with some cases. Default is daily dataset, which has S3 Key like 'domain={domain}/datasetid={datasetid}/year=2022/month=3/day=25'. It will be set default with empty value in 'data-sets'.
5
+
6
+ In another case, it is necessary to divide by hours or minutes and store them. This datetime item must be included in the S3 key. It will be required a new Glue Crawler and a Glue Catalog Table. For example if you need to separate directory hourly, you should add "%H" for 'hour' to partition_keys for this. and also should add a new crawler. Look at the below picture for understanding.
7
+
8
+ ![Architecture for partitioning](./assets/data-samples.jpg)
9
+
10
+ These tasks are related for S3 request limitations.
11
+ > __3,500 PUT/COPY/POST/DELETE or 5,500 GET/HEAD requests per second per prefix in a bucket__
12
+ - https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html
Binary file
@@ -1 +1,16 @@
1
- export default function bootstrap() {}
1
+ import {
2
+ OxGristRendererJson5,
3
+ registerEditor as registerGristEditor,
4
+ registerRenderer as registerGristRenderer
5
+ } from '@operato/data-grist'
6
+
7
+ import { OxGristEditorDataItemSpec } from '@operato/dataset/grist-editor'
8
+ import { OxGristEditorPartitionKeys } from '@operato/app/grist-editor/ox-grist-editor-partition-keys.js'
9
+
10
+ export default function bootstrap() {
11
+ registerGristEditor('data-item-spec', OxGristEditorDataItemSpec)
12
+ registerGristRenderer('data-item-spec', OxGristRendererJson5)
13
+
14
+ registerGristEditor('partition-keys', OxGristEditorPartitionKeys)
15
+ registerGristRenderer('partition-keys', OxGristRendererJson5)
16
+ }
@@ -0,0 +1,84 @@
1
+ import '@operato/dataset/ox-data-entry-form.js'
2
+
3
+ import { LitElement, css, html } from 'lit'
4
+ import { i18next, localize } from '@operato/i18n'
5
+
6
+ import { client } from '@operato/graphql'
7
+ import gql from 'graphql-tag'
8
+
9
+ class DataEntryForm extends localize(i18next)(LitElement) {
10
+ static get properties() {
11
+ return {
12
+ dataSet: Object
13
+ }
14
+ }
15
+
16
+ static get styles() {
17
+ return [
18
+ css`
19
+ :host {
20
+ display: flex;
21
+ flex-direction: column;
22
+
23
+ background-color: #fff;
24
+ }
25
+
26
+ ox-data-entry-form {
27
+ flex: 1;
28
+ margin: 10px;
29
+ }
30
+
31
+ .button-container {
32
+ display: flex;
33
+ margin-left: auto;
34
+ padding: var(--padding-default);
35
+ }
36
+ `
37
+ ]
38
+ }
39
+
40
+ get entryForm() {
41
+ return this.renderRoot.querySelector('ox-data-entry-form')
42
+ }
43
+
44
+ render() {
45
+ return html`
46
+ <ox-data-entry-form .dataSet=${this.dataSet}></ox-data-entry-form>
47
+ <div class="button-container">
48
+ <mwc-button raised @click=${this._updateDataItems.bind(this)}>${i18next.t('button.save')}</mwc-button>
49
+ </div>
50
+ `
51
+ }
52
+
53
+ async _updateDataItems() {
54
+ const data = this.entryForm.buildValue()
55
+ const dataSample = {
56
+ dataSet: {
57
+ id: this.dataSet.id
58
+ },
59
+ data
60
+ }
61
+
62
+ const response = await client.mutate({
63
+ mutation: gql`
64
+ mutation ($dataSample: NewDataSample!) {
65
+ createDataSample(dataSample: $dataSample) {
66
+ id
67
+ collectedAt
68
+ }
69
+ }
70
+ `,
71
+ variables: {
72
+ dataSample
73
+ }
74
+ })
75
+
76
+ if (!response.errors) {
77
+ document.dispatchEvent(
78
+ new CustomEvent('notify', { detail: { message: i18next.t('text.data sample created successfully') } })
79
+ )
80
+ }
81
+ }
82
+ }
83
+
84
+ window.customElements.define('data-entry-form', DataEntryForm)
@@ -1,8 +1,8 @@
1
- import gql from 'graphql-tag'
2
- import { css, html, LitElement } from 'lit'
1
+ import { LitElement, css, html } from 'lit'
2
+ import { i18next, localize } from '@operato/i18n'
3
3
 
4
4
  import { client } from '@operato/graphql'
5
- import { i18next, localize } from '@operato/i18n'
5
+ import gql from 'graphql-tag'
6
6
  import { isMobileDevice } from '@operato/utils'
7
7
 
8
8
  class DataItemList extends localize(i18next)(LitElement) {
@@ -33,9 +33,6 @@ class DataItemList extends localize(i18next)(LitElement) {
33
33
  padding: var(--padding-default);
34
34
  }
35
35
 
36
- form {
37
- position: relative;
38
- }
39
36
  [danger] {
40
37
  --mdc-theme-primary: var(--mdc-danger-button-primary-color);
41
38
  }
@@ -46,7 +43,7 @@ class DataItemList extends localize(i18next)(LitElement) {
46
43
  ]
47
44
  }
48
45
 
49
- get dataGrist() {
46
+ get grist() {
50
47
  return this.renderRoot.querySelector('ox-grist')
51
48
  }
52
49
 
@@ -64,8 +61,6 @@ class DataItemList extends localize(i18next)(LitElement) {
64
61
  `
65
62
  }
66
63
 
67
- async updated(changedProps) {}
68
-
69
64
  async firstUpdated() {
70
65
  this.gristConfig = {
71
66
  list: { fields: ['name', 'description', 'active'] },
@@ -149,7 +144,44 @@ class DataItemList extends localize(i18next)(LitElement) {
149
144
  name: 'type',
150
145
  header: i18next.t('field.type'),
151
146
  record: {
152
- options: ['number', 'text', 'select', 'boolean'],
147
+ options: ['', 'number', 'text', 'select', 'boolean', 'file'],
148
+ editable: true
149
+ },
150
+ width: 120
151
+ },
152
+ {
153
+ type: 'parameters',
154
+ name: 'options',
155
+ header: i18next.t('field.options'),
156
+ record: {
157
+ editable: true,
158
+ renderer: 'json5',
159
+ options: async (value, column, record, row, field) => {
160
+ return {
161
+ name: record.type,
162
+ help: '',
163
+ spec:
164
+ record.type === 'select'
165
+ ? [
166
+ {
167
+ type: 'options' /* property-editor type */,
168
+ name: 'options',
169
+ label: 'options'
170
+ }
171
+ ]
172
+ : [],
173
+ context: this.grist,
174
+ objectified: true
175
+ }
176
+ }
177
+ },
178
+ width: 120
179
+ },
180
+ {
181
+ type: 'string',
182
+ name: 'unit',
183
+ header: i18next.t('field.unit'),
184
+ record: {
153
185
  editable: true
154
186
  },
155
187
  width: 120
@@ -164,11 +196,16 @@ class DataItemList extends localize(i18next)(LitElement) {
164
196
  width: 60
165
197
  },
166
198
  {
167
- type: 'json',
199
+ type: 'data-item-spec',
168
200
  name: 'spec',
169
201
  header: i18next.t('field.spec'),
170
202
  record: {
171
- editable: true
203
+ editable: true,
204
+ options: {
205
+ name: '',
206
+ help: '',
207
+ objectified: true /* prevent from stringifying */
208
+ }
172
209
  },
173
210
  width: 200
174
211
  }
@@ -207,7 +244,10 @@ class DataItemList extends localize(i18next)(LitElement) {
207
244
  description
208
245
  sequence
209
246
  active
247
+ tag
210
248
  type
249
+ options
250
+ unit
211
251
  quota
212
252
  spec
213
253
  }
@@ -224,7 +264,7 @@ class DataItemList extends localize(i18next)(LitElement) {
224
264
  }
225
265
 
226
266
  async _updateDataItems() {
227
- let patches = this.dataGrist._data.records
267
+ let patches = this.grist._data.records
228
268
  if (patches && patches.length) {
229
269
  patches = patches.map(patch => {
230
270
  var patchField = {}
@@ -250,14 +290,16 @@ class DataItemList extends localize(i18next)(LitElement) {
250
290
  }
251
291
  })
252
292
 
253
- if (!response.errors) this.dataGrist.fetch()
293
+ if (!response.errors) {
294
+ this.grist.fetch()
295
+ }
254
296
  }
255
297
  }
256
298
 
257
299
  async _deleteDataItems() {
258
300
  if (!confirm(i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }))) return
259
301
 
260
- const ids = this.dataGrist.selected.map(record => record.id)
302
+ const ids = this.grist.selected.map(record => record.id)
261
303
  if (!(ids && ids.length > 0)) return
262
304
 
263
305
  const response = await client.mutate({
@@ -273,7 +315,7 @@ class DataItemList extends localize(i18next)(LitElement) {
273
315
 
274
316
  if (response.errors) return
275
317
 
276
- this.dataGrist.fetch()
318
+ this.grist.fetch()
277
319
  await document.dispatchEvent(
278
320
  new CustomEvent('notify', {
279
321
  detail: {
@@ -0,0 +1,182 @@
1
+ import '@operato/dataset/ox-data-ooc-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 DataOocView extends localize(i18next)(LitElement) {
11
+ static get styles() {
12
+ return [
13
+ ScrollbarStyles,
14
+ css`
15
+ :host {
16
+ display: flex;
17
+ flex-direction: column;
18
+
19
+ background-color: #fff;
20
+ }
21
+
22
+ div[content] {
23
+ flex: 1;
24
+
25
+ display: flex;
26
+ overflow: auto;
27
+ }
28
+
29
+ ox-data-ooc-view {
30
+ flex: 1;
31
+ padding: var(--padding-wide);
32
+ }
33
+
34
+ label[comment] {
35
+ display: flex;
36
+ flex-direction: column;
37
+
38
+ padding: var(--padding-wide);
39
+ }
40
+
41
+ label[comment] div {
42
+ display: flex;
43
+ }
44
+
45
+ mwc-icon {
46
+ color: var(--status-danger-color);
47
+ }
48
+
49
+ textarea {
50
+ border: var(--input-field-border);
51
+ border-radius: var(--input-border-radius);
52
+ padding: var(--input-field-padding);
53
+ font: var(--input-field-font);
54
+ }
55
+
56
+ .button-container {
57
+ display: flex;
58
+ margin-left: auto;
59
+ padding: var(--padding-default);
60
+ }
61
+ `
62
+ ]
63
+ }
64
+
65
+ static get properties() {
66
+ return {
67
+ dataSet: Object,
68
+ dataOoc: Object
69
+ }
70
+ }
71
+
72
+ get sampleView() {
73
+ return this.renderRoot.querySelector('ox-data-ooc-view')
74
+ }
75
+
76
+ render() {
77
+ const state = this.dataOoc.state
78
+
79
+ return html`
80
+ <div content>
81
+ <ox-data-ooc-view .dataSet=${this.dataSet} .dataOoc=${this.dataOoc}></ox-data-ooc-view>
82
+ </div>
83
+
84
+ ${state === 'CREATED' || state === 'REVIEWED'
85
+ ? html`
86
+ <label comment>
87
+ <div><mwc-icon>build_circle</mwc-icon> <span>correction activity</span></div>
88
+ <textarea placeholder="조치 내용을 입력해주세요."></textarea>
89
+ </label>
90
+ `
91
+ : html``}
92
+
93
+ <div class="button-container">
94
+ ${state === 'CREATED'
95
+ ? html`<mwc-button raised @click=${() => this._processOoc('REVIEWED')}
96
+ >${i18next.t('button.reviewed')}</mwc-button
97
+ >`
98
+ : state === 'REVIEWED'
99
+ ? html`<mwc-button raised @click=${() => this._processOoc('CORRECTED')}
100
+ >${i18next.t('button.corrected')}</mwc-button
101
+ >`
102
+ : html``}
103
+ </div>
104
+ `
105
+ }
106
+
107
+ updated(changes) {
108
+ if (changes.has('dataOoc')) {
109
+ this.fetchDataSet()
110
+ }
111
+ }
112
+
113
+ async fetchDataSet() {
114
+ const id = this.dataOoc?.dataSet?.id
115
+
116
+ if (id) {
117
+ const response = await client.query({
118
+ query: gql`
119
+ query ($id: String!) {
120
+ dataSet(id: $id) {
121
+ id
122
+ name
123
+ description
124
+ useCase
125
+ dataItems {
126
+ id
127
+ name
128
+ description
129
+ active
130
+ unit
131
+ tag
132
+ type
133
+ spec
134
+ }
135
+ }
136
+ }
137
+ `,
138
+ variables: {
139
+ id: this.dataOoc.dataSet.id
140
+ }
141
+ })
142
+
143
+ this.dataSet = response.data.dataSet
144
+ }
145
+ }
146
+
147
+ async _processOoc(state) {
148
+ const commentTextArea = this.renderRoot.querySelector('textarea')
149
+ const comment = commentTextArea && commentTextArea.value
150
+ if (!comment || !comment.trim()) {
151
+ commentTextArea.focus()
152
+ return
153
+ }
154
+
155
+ const patch = {
156
+ state,
157
+ correctiveAction: comment
158
+ }
159
+
160
+ const response = await client.mutate({
161
+ mutation: gql`
162
+ mutation ($id: String!, $patch: DataOocPatch!) {
163
+ updateDataOoc(id: $id, patch: $patch) {
164
+ id
165
+ }
166
+ }
167
+ `,
168
+ variables: {
169
+ id: this.dataOoc.id,
170
+ patch
171
+ }
172
+ })
173
+
174
+ if (!response.errors) {
175
+ document.dispatchEvent(
176
+ new CustomEvent('notify', { detail: { message: i18next.t('text.data ooc updated successfully') } })
177
+ )
178
+ }
179
+ }
180
+ }
181
+
182
+ window.customElements.define('data-ooc-view', DataOocView)