@things-factory/dataset 8.0.0-beta.9 → 8.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. package/client/activities/activity-data-collect-edit.ts +105 -0
  2. package/client/activities/activity-data-collect-view.ts +91 -0
  3. package/client/activities/activity-data-review-edit.ts +278 -0
  4. package/client/activities/activity-data-review-view.ts +226 -0
  5. package/client/activities/activity-ooc-resolve-edit.ts +195 -0
  6. package/client/activities/activity-ooc-resolve-view.ts +143 -0
  7. package/client/activities/activity-ooc-review-edit.ts +173 -0
  8. package/client/activities/activity-ooc-review-view.ts +129 -0
  9. package/client/bootstrap.ts +35 -0
  10. package/client/components/data-entry-form.ts +109 -0
  11. package/client/index.ts +1 -0
  12. package/client/pages/data-archive/data-archive-list-page.ts +277 -0
  13. package/client/pages/data-archive/data-archive-request-popup.ts +177 -0
  14. package/client/pages/data-entry/data-entry-list-page.ts +464 -0
  15. package/client/pages/data-key-set/data-key-item-list.ts +183 -0
  16. package/client/pages/data-key-set/data-key-set-importer.ts +89 -0
  17. package/client/pages/data-key-set/data-key-set-list-page.ts +413 -0
  18. package/client/pages/data-ooc/data-ooc-list-page.ts +549 -0
  19. package/client/pages/data-ooc/data-ooc-page.ts +164 -0
  20. package/client/pages/data-ooc/data-ooc-view.ts +236 -0
  21. package/client/pages/data-ooc/data-oocs-page.ts +200 -0
  22. package/client/pages/data-report/data-report-embed-page.ts +108 -0
  23. package/client/pages/data-report/data-report-list-page.ts +454 -0
  24. package/client/pages/data-report/data-report-samples-page.ts +174 -0
  25. package/client/pages/data-report/jasper-report-oocs-page.ts +110 -0
  26. package/client/pages/data-report/jasper-report-samples-crosstab-page.ts +110 -0
  27. package/client/pages/data-report/jasper-report-samples-page.ts +110 -0
  28. package/client/pages/data-sample/data-sample-list-page.ts +442 -0
  29. package/client/pages/data-sample/data-sample-page.ts +55 -0
  30. package/client/pages/data-sample/data-sample-search-page.ts +424 -0
  31. package/client/pages/data-sample/data-sample-view.ts +292 -0
  32. package/client/pages/data-sample/data-samples-page.ts +249 -0
  33. package/client/pages/data-sensor/data-sensor-list-page.ts +456 -0
  34. package/client/pages/data-set/data-item-list.ts +304 -0
  35. package/client/pages/data-set/data-set-importer.ts +89 -0
  36. package/client/pages/data-set/data-set-list-page.ts +1078 -0
  37. package/client/pages/data-summary/data-summary-list-page.ts +363 -0
  38. package/client/pages/data-summary/data-summary-period-page.ts +439 -0
  39. package/client/pages/data-summary/data-summary-search-page.ts +426 -0
  40. package/client/pages/data-summary/data-summary-view.ts +133 -0
  41. package/client/route.ts +91 -0
  42. package/client/tsconfig.json +13 -0
  43. package/dist-client/activities/activity-data-review-edit.js +19 -10
  44. package/dist-client/activities/activity-data-review-edit.js.map +1 -1
  45. package/dist-client/activities/activity-data-review-view.js +80 -0
  46. package/dist-client/activities/activity-data-review-view.js.map +1 -1
  47. package/dist-client/pages/data-entry/data-entry-list-page.js +2 -2
  48. package/dist-client/pages/data-entry/data-entry-list-page.js.map +1 -1
  49. package/dist-client/tsconfig.tsbuildinfo +1 -1
  50. package/dist-server/controllers/create-data-ooc.js +2 -0
  51. package/dist-server/controllers/create-data-ooc.js.map +1 -1
  52. package/dist-server/service/data-archive/index.d.ts +1 -1
  53. package/dist-server/service/data-ooc/index.d.ts +1 -1
  54. package/dist-server/service/data-sample/data-sample-query.d.ts +1 -1
  55. package/dist-server/service/data-sample/data-sample-query.js +3 -3
  56. package/dist-server/service/data-sample/data-sample-query.js.map +1 -1
  57. package/dist-server/service/data-sample/index.d.ts +1 -1
  58. package/dist-server/service/data-set/index.d.ts +1 -1
  59. package/dist-server/service/index.d.ts +2 -2
  60. package/dist-server/tsconfig.tsbuildinfo +1 -1
  61. package/package.json +26 -26
  62. package/server/activities/activity-data-collect.ts +100 -0
  63. package/server/activities/activity-data-review.ts +109 -0
  64. package/server/activities/activity-ooc-resolve.ts +123 -0
  65. package/server/activities/activity-ooc-review.ts +95 -0
  66. package/server/activities/index.ts +11 -0
  67. package/server/controllers/create-data-ooc.ts +80 -0
  68. package/server/controllers/create-data-sample.ts +323 -0
  69. package/server/controllers/data-use-case.ts +98 -0
  70. package/server/controllers/finalize-data-collection.ts +388 -0
  71. package/server/controllers/index.ts +6 -0
  72. package/server/controllers/issue-data-collection-task.ts +70 -0
  73. package/server/controllers/issue-ooc-resolve.ts +58 -0
  74. package/server/controllers/issue-ooc-review.ts +52 -0
  75. package/server/controllers/jasper-report.ts +186 -0
  76. package/server/controllers/query-data-summary-by-period.ts +178 -0
  77. package/server/controllers/shiny-report.ts +54 -0
  78. package/server/engine/index.ts +1 -0
  79. package/server/engine/task/create-data-sample.ts +100 -0
  80. package/server/engine/task/index.ts +2 -0
  81. package/server/engine/task/issue-collect-data.ts +45 -0
  82. package/server/index.ts +8 -0
  83. package/server/routes.ts +188 -0
  84. package/server/service/data-archive/data-archive-mutation.ts +273 -0
  85. package/server/service/data-archive/data-archive-query.ts +58 -0
  86. package/server/service/data-archive/data-archive-type.ts +48 -0
  87. package/server/service/data-archive/data-archive.ts +69 -0
  88. package/server/service/data-archive/index.ts +6 -0
  89. package/server/service/data-key-set/data-key-item-type.ts +31 -0
  90. package/server/service/data-key-set/data-key-set-mutation.ts +201 -0
  91. package/server/service/data-key-set/data-key-set-query.ts +68 -0
  92. package/server/service/data-key-set/data-key-set-type.ts +70 -0
  93. package/server/service/data-key-set/data-key-set.ts +86 -0
  94. package/server/service/data-key-set/index.ts +6 -0
  95. package/server/service/data-ooc/data-ooc-mutation.ts +154 -0
  96. package/server/service/data-ooc/data-ooc-query.ts +106 -0
  97. package/server/service/data-ooc/data-ooc-subscription.ts +48 -0
  98. package/server/service/data-ooc/data-ooc-type.ts +71 -0
  99. package/server/service/data-ooc/data-ooc.ts +259 -0
  100. package/server/service/data-ooc/index.ts +7 -0
  101. package/server/service/data-sample/data-sample-mutation.ts +18 -0
  102. package/server/service/data-sample/data-sample-query.ts +215 -0
  103. package/server/service/data-sample/data-sample-type.ts +47 -0
  104. package/server/service/data-sample/data-sample.ts +193 -0
  105. package/server/service/data-sample/index.ts +6 -0
  106. package/server/service/data-sensor/data-sensor-mutation.ts +116 -0
  107. package/server/service/data-sensor/data-sensor-query.ts +76 -0
  108. package/server/service/data-sensor/data-sensor-type.ts +104 -0
  109. package/server/service/data-sensor/data-sensor.ts +126 -0
  110. package/server/service/data-sensor/index.ts +6 -0
  111. package/server/service/data-set/data-item-type.ts +155 -0
  112. package/server/service/data-set/data-set-mutation.ts +552 -0
  113. package/server/service/data-set/data-set-query.ts +461 -0
  114. package/server/service/data-set/data-set-type.ts +204 -0
  115. package/server/service/data-set/data-set.ts +326 -0
  116. package/server/service/data-set/index.ts +6 -0
  117. package/server/service/data-set-history/data-set-history-query.ts +126 -0
  118. package/server/service/data-set-history/data-set-history-type.ts +12 -0
  119. package/server/service/data-set-history/data-set-history.ts +217 -0
  120. package/server/service/data-set-history/event-subscriber.ts +17 -0
  121. package/server/service/data-set-history/index.ts +7 -0
  122. package/server/service/data-spec/data-spec-manager.ts +21 -0
  123. package/server/service/data-spec/data-spec-query.ts +21 -0
  124. package/server/service/data-spec/data-spec.ts +45 -0
  125. package/server/service/data-spec/index.ts +5 -0
  126. package/server/service/data-summary/data-summary-mutation.ts +45 -0
  127. package/server/service/data-summary/data-summary-query.ts +179 -0
  128. package/server/service/data-summary/data-summary-type.ts +86 -0
  129. package/server/service/data-summary/data-summary.ts +170 -0
  130. package/server/service/data-summary/index.ts +7 -0
  131. package/server/service/index.ts +57 -0
  132. package/server/tsconfig.json +10 -0
  133. package/server/utils/config-resolver.ts +29 -0
  134. package/server/utils/index.ts +1 -0
@@ -0,0 +1,109 @@
1
+ import '@material/web/icon/icon.js'
2
+ import '@operato/dataset/ox-data-entry-form.js'
3
+
4
+ import gql from 'graphql-tag'
5
+ import { css, html, LitElement } from 'lit'
6
+ import { customElement, property, query, state } from 'lit/decorators.js'
7
+
8
+ import { client } from '@operato/graphql'
9
+ import { i18next, localize } from '@operato/i18n'
10
+ import { CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'
11
+ import { OxDataEntryForm } from '@operato/dataset/ox-data-entry-form.js'
12
+ import { DataSet } from '@operato/dataset'
13
+
14
+ @customElement('data-entry-form')
15
+ export class DataEntryForm extends localize(i18next)(LitElement) {
16
+ static styles = [
17
+ CommonHeaderStyles,
18
+ ScrollbarStyles,
19
+ css`
20
+ :host {
21
+ display: flex;
22
+ flex-direction: column;
23
+
24
+ background-color: var(--md-sys-color-surface);
25
+ }
26
+
27
+ ox-data-entry-form {
28
+ flex: 1;
29
+ padding: 10px;
30
+ overflow: auto;
31
+ }
32
+
33
+ .footer span {
34
+ font-size: 0.8em;
35
+ color: var(--md-sys-color-on-surface);
36
+ line-height: 1.5;
37
+ padding: 10px;
38
+ }
39
+ `
40
+ ]
41
+
42
+ @property({ type: Object }) dataSet?: DataSet & { id: string }
43
+
44
+ @state() dataSample?: { id: string; collectedAt: Date }
45
+
46
+ @query('ox-data-entry-form') entryForm!: OxDataEntryForm
47
+
48
+ render() {
49
+ return html`
50
+ <ox-data-entry-form .dataSet=${this.dataSet}></ox-data-entry-form>
51
+
52
+ <div class="footer">
53
+ <div filler></div>
54
+ ${!this.dataSample
55
+ ? html`
56
+ <button @click=${this.updateDataItems.bind(this)} done>
57
+ <md-icon>save</md-icon>${i18next.t('button.save')}
58
+ </button>
59
+ `
60
+ : html` <span>${i18next.t('field.collected-at')}: ${this.dataSample.collectedAt.toLocaleString()}</span> `}
61
+ </div>
62
+ `
63
+ }
64
+
65
+ private async updateDataItems() {
66
+ //@ts-ignore TODO replace with following line and confirm
67
+ const data = this.entryForm.buildValue()
68
+
69
+ const dataSample = {
70
+ dataSet: {
71
+ id: this.dataSet?.id
72
+ },
73
+ data
74
+ } as any
75
+
76
+ if (this.dataSample?.collectedAt) {
77
+ dataSample.collectedAt = this.dataSample.collectedAt
78
+ }
79
+
80
+ const response = await client.mutate({
81
+ mutation: gql`
82
+ mutation ($dataSample: NewDataSample!) {
83
+ createDataSample(dataSample: $dataSample) {
84
+ id
85
+ collectedAt
86
+ }
87
+ }
88
+ `,
89
+ variables: {
90
+ dataSample
91
+ },
92
+ context: {
93
+ hasUpload: true
94
+ }
95
+ })
96
+
97
+ if (!response.errors) {
98
+ const { id, collectedAt } = response.data.createDataSample
99
+ this.dataSample = {
100
+ id,
101
+ collectedAt: new Date(collectedAt)
102
+ }
103
+
104
+ document.dispatchEvent(
105
+ new CustomEvent('notify', { detail: { message: i18next.t('text.data sample created successfully') } })
106
+ )
107
+ }
108
+ }
109
+ }
@@ -0,0 +1 @@
1
+ export * from './components/data-entry-form.js'
@@ -0,0 +1,277 @@
1
+ import '@material/web/icon/icon.js'
2
+ import '@operato/data-grist'
3
+ import '@operato/context/ox-context-page-toolbar.js'
4
+
5
+ import gql from 'graphql-tag'
6
+ import { css, html } from 'lit'
7
+ import { customElement, property, query, state } from 'lit/decorators.js'
8
+ import { connect } from 'pwa-helpers/connect-mixin'
9
+
10
+ import { DataGrist, FetchOption, GristRecord } from '@operato/data-grist'
11
+ import { client } from '@operato/graphql'
12
+ import { i18next, localize } from '@operato/i18n'
13
+ import { PopupHandle, openPopup } from '@operato/layout'
14
+ import { PageView, store } from '@operato/shell'
15
+ import { CommonButtonStyles, CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'
16
+ import { isMobileDevice } from '@operato/utils'
17
+
18
+ import './data-archive-request-popup'
19
+
20
+ @customElement('data-archive-list-page')
21
+ export class DataArchiveListPage extends connect(store)(localize(i18next)(PageView)) {
22
+ static styles = [
23
+ ScrollbarStyles,
24
+ CommonHeaderStyles,
25
+ css`
26
+ :host {
27
+ display: flex;
28
+ flex-direction: column;
29
+
30
+ overflow: hidden;
31
+ }
32
+
33
+ ox-grist {
34
+ overflow-y: auto;
35
+ flex: 1;
36
+ }
37
+
38
+ .header {
39
+ grid-template-areas: 'filters actions';
40
+ }
41
+ `
42
+ ]
43
+
44
+ @state() gristConfig: any
45
+ @state() mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'CARD' : 'GRID'
46
+
47
+ @query('ox-grist') private grist!: DataGrist
48
+
49
+ private popup?: PopupHandle
50
+
51
+ get context() {
52
+ return {
53
+ title: i18next.t('title.data-archive list'),
54
+ search: {
55
+ handler: (search: string) => {
56
+ this.grist.searchText = search
57
+ },
58
+ value: this.grist?.searchText || ''
59
+ },
60
+ filter: {
61
+ handler: () => {
62
+ this.grist.toggleHeadroom()
63
+ }
64
+ },
65
+ help: 'dataset/data-archive',
66
+ actions: [
67
+ {
68
+ title: i18next.t('button.request-archive'),
69
+ action: this.openArchivePopup.bind(this),
70
+ icon: 'archive'
71
+ }
72
+ ],
73
+ exportable: {
74
+ name: i18next.t('title.data-archive list'),
75
+ data: this._exportableData.bind(this)
76
+ },
77
+ toolbar: false
78
+ }
79
+ }
80
+
81
+ render() {
82
+ const mode = this.mode || (isMobileDevice() ? 'LIST' : 'GRID')
83
+
84
+ return html`
85
+ <ox-grist
86
+ .mode=${mode}
87
+ .config=${this.gristConfig}
88
+ .fetchHandler=${this.fetchHandler.bind(this)}
89
+ ?url-params-sensitive=${false /* this.active */}
90
+ >
91
+ <div slot="headroom" class="header">
92
+ <!-- <div class="filters">
93
+ <ox-filters-form class="filter" autofocus without-search></ox-filters-form>
94
+ </div> -->
95
+
96
+ <ox-context-page-toolbar class="actions" .context=${this.context}></ox-context-page-toolbar>
97
+ </div>
98
+ </ox-grist>
99
+ `
100
+ }
101
+
102
+ async pageInitialized(lifecycle) {
103
+ this.gristConfig = {
104
+ list: { fields: ['updater', 'updatedAt'] },
105
+ columns: [
106
+ { type: 'gutter', gutterName: 'sequence' },
107
+ // { type: 'gutter', gutterName: 'row-selector', multiple: true },
108
+ {
109
+ type: 'resource-object',
110
+ name: 'creator',
111
+ header: i18next.t('field.creator'),
112
+ sortable: true,
113
+ width: 120,
114
+ imex: true
115
+ },
116
+ {
117
+ type: 'datetime',
118
+ name: 'createdAt',
119
+ header: i18next.t('field.created_at'),
120
+ sortable: true,
121
+ width: 180,
122
+ imex: true
123
+ },
124
+ {
125
+ type: 'datetime',
126
+ name: 'updatedAt',
127
+ header: i18next.t('field.updated_at'),
128
+ sortable: true,
129
+ width: 180,
130
+ imex: true
131
+ },
132
+ {
133
+ type: 'json5',
134
+ name: 'requestParams',
135
+ header: i18next.t('field.request-params'),
136
+ record: {
137
+ editable: false
138
+ },
139
+ width: 200,
140
+ imex: true
141
+ },
142
+ {
143
+ type: 'string',
144
+ name: 'downloadUrl',
145
+ label: true,
146
+ header: i18next.t('field.download-url'),
147
+ record: {
148
+ editable: false
149
+ },
150
+ width: 240,
151
+ imex: true
152
+ },
153
+ {
154
+ type: 'string',
155
+ name: 'status',
156
+ label: true,
157
+ header: i18next.t('field.status'),
158
+ record: {
159
+ editable: false
160
+ },
161
+ sortable: true,
162
+ width: 120,
163
+ imex: true
164
+ }
165
+ ],
166
+ rows: {
167
+ appendable: false,
168
+ selectable: {
169
+ multiple: true
170
+ }
171
+ },
172
+ sorters: [
173
+ {
174
+ name: 'createdAt',
175
+ desc: true
176
+ }
177
+ ]
178
+ }
179
+ }
180
+
181
+ closePopupAndRefesh() {
182
+ this.popup?.close()
183
+ this.grist.fetch()
184
+ }
185
+
186
+ async openArchivePopup() {
187
+ this.popup = openPopup(
188
+ html` <data-archive-request-popup
189
+ @requested=${this.closePopupAndRefesh.bind(this)}
190
+ @created=${this.closePopupAndRefesh.bind(this)}
191
+ ></data-archive-request-popup>`,
192
+ {
193
+ backdrop: true,
194
+ size: 'small',
195
+ title: i18next.t('title.data-archive request popup')
196
+ }
197
+ )
198
+ }
199
+
200
+ async fetchHandler({ page, limit, sortings = [], filters = [] }: FetchOption) {
201
+ const response = await client.query({
202
+ query: gql`
203
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
204
+ responses: dataArchives(filters: $filters, pagination: $pagination, sortings: $sortings) {
205
+ items {
206
+ id
207
+ type
208
+ requestParams
209
+ downloadUrl
210
+ status
211
+ creator {
212
+ id
213
+ name
214
+ }
215
+ updater {
216
+ id
217
+ name
218
+ }
219
+ updatedAt
220
+ createdAt
221
+ }
222
+ total
223
+ }
224
+ }
225
+ `,
226
+ variables: {
227
+ filters,
228
+ pagination: { page, limit },
229
+ sortings
230
+ }
231
+ })
232
+
233
+ return {
234
+ total: response.data.responses.total || 0,
235
+ records: response.data.responses.items || []
236
+ }
237
+ }
238
+
239
+ _exportableData() {
240
+ let records = [] as GristRecord[]
241
+ if (this.grist.selected && this.grist.selected.length > 0) {
242
+ records = this.grist.selected
243
+ } else {
244
+ records = this.grist.data.records
245
+ }
246
+
247
+ var headerSetting = this.grist.compiledConfig.columns
248
+ .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
249
+ .map(column => {
250
+ return column.imex === true
251
+ ? {
252
+ header: column.header.renderer(column),
253
+ key: column.name,
254
+ width: column.width,
255
+ type: column.type
256
+ }
257
+ : column.imex
258
+ })
259
+
260
+ var data = records.map(item => {
261
+ return {
262
+ id: item.id,
263
+ ...this.gristConfig.columns
264
+ .filter(column => column.type !== 'gutter' && column.record !== undefined && column.imex !== undefined)
265
+ .reduce((record, column) => {
266
+ const key = column.imex === true ? column.name : column.imex.key
267
+ record[key] = key
268
+ .split('.')
269
+ .reduce((obj, key) => (obj && obj[key] !== 'undefined' ? obj[key] : undefined), item)
270
+ return record
271
+ }, {})
272
+ }
273
+ })
274
+
275
+ return { header: headerSetting, data: data }
276
+ }
277
+ }
@@ -0,0 +1,177 @@
1
+ import '@material/web/icon/icon.js'
2
+
3
+ import gql from 'graphql-tag'
4
+ import { css, html, LitElement } from 'lit'
5
+ import { customElement, property, query, state } from 'lit/decorators.js'
6
+
7
+ import { i18next, localize } from '@operato/i18n'
8
+ import { client } from '@operato/graphql'
9
+ import { SingleColumnFormStyles } from '@operato/form'
10
+ import { CommonHeaderStyles } from '@operato/styles'
11
+
12
+ import moment from '@operato/moment-timezone-es'
13
+ import { CustomAlert } from '@operato/shell'
14
+
15
+ @customElement('data-archive-request-popup')
16
+ class DataArchiveRequestPopup extends localize(i18next)(LitElement) {
17
+ static styles = [
18
+ CommonHeaderStyles,
19
+ SingleColumnFormStyles,
20
+ css`
21
+ :host {
22
+ padding: 10px;
23
+ display: flex;
24
+ flex-direction: column;
25
+ overflow-x: overlay;
26
+ background-color: var(--md-sys-color-background);
27
+ }
28
+
29
+ form {
30
+ overflow: auto;
31
+ }
32
+ `
33
+ ]
34
+
35
+ @state() dataSetTypes: any
36
+
37
+ render() {
38
+ return html`
39
+ <form id="input-form" name="generation" class="single-column-form" @submit=${e => this.onSubmit(e)}>
40
+ <fieldset>
41
+ <label>${i18next.t('label.start-date')}</label>
42
+ <input type="month" name="startDate" required />
43
+ <label>${i18next.t('label.end-date')}</label>
44
+ <input type="month" name="endDate" .value=${moment().format('YYYY-MM')} />
45
+ <label>${i18next.t('label.data-set-type')}</label>
46
+ <select name="type" required>
47
+ ${(this.dataSetTypes || []).map(t => html`<option value=${t && t.value}>${t && t.display}</option>`)}
48
+ </select>
49
+ </fieldset>
50
+ </form>
51
+
52
+ <div class="footer">
53
+ <div filler></div>
54
+ <button @click=${this.requestArchive} done>
55
+ <md-icon>archive</md-icon>${String(i18next.t('button.submit'))}
56
+ </button>
57
+ </div>
58
+ `
59
+ }
60
+
61
+ async firstUpdated() {}
62
+
63
+ async onSubmit(e) {
64
+ e.preventDefault()
65
+ this.requestArchive()
66
+ }
67
+
68
+ serializeFormData() {
69
+ const obj = {}
70
+
71
+ Array.from(this.shadowRoot!.querySelectorAll('form#input-form input, select')).forEach((field: Element) => {
72
+ const input = field as HTMLInputElement
73
+ if (!input.hasAttribute('hidden') && input.value) {
74
+ obj[input.name] = input.type === 'checkbox' ? input.checked : input.value
75
+ }
76
+ })
77
+
78
+ if (obj['startDate']) {
79
+ obj['startDate'] += '-01'
80
+ }
81
+
82
+ if (obj['endDate']) {
83
+ const endDate = moment(obj['endDate']).endOf('month')
84
+ const today = moment()
85
+ const format = 'YYYY-MM-DD'
86
+
87
+ obj['endDate'] = endDate > today ? today.format(format) : endDate.format(format)
88
+ }
89
+
90
+ return obj
91
+ }
92
+
93
+ /** request download url. */
94
+ async requestArchive() {
95
+ // #1 request download url
96
+ const dataArchive = {
97
+ requestParams: this.serializeFormData(),
98
+ status: 'requested'
99
+ }
100
+
101
+ const response = await client.mutate({
102
+ mutation: gql`
103
+ mutation createDataArchive($dataArchive: NewDataArchive!) {
104
+ createDataArchive(dataArchive: $dataArchive) {
105
+ id
106
+ status
107
+ }
108
+ }
109
+ `,
110
+ variables: { dataArchive }
111
+ })
112
+
113
+ if (!response.errors) {
114
+ this.dispatchEvent(new CustomEvent('requested', {}))
115
+
116
+ const {
117
+ createDataArchive: { id }
118
+ } = response.data
119
+ dataArchive['id'] = id
120
+
121
+ this._generateArchiveAndDownloadUrl(dataArchive)
122
+
123
+ await CustomAlert({
124
+ type: 'info',
125
+ title: i18next.t('title.ready'),
126
+ text: i18next.t('text.data-archive waits'),
127
+ confirmButton: { text: i18next.t('button.confirm') }
128
+ })
129
+ } else {
130
+ console.error(response.errors)
131
+ this.showToast(i18next.t('text.failed'))
132
+ }
133
+ }
134
+
135
+ async _generateArchiveAndDownloadUrl(dataArchive) {
136
+ const response = await client.mutate({
137
+ mutation: gql`
138
+ mutation generatePresignedUrl($patch: DataArchivePatch!) {
139
+ generatePresignedUrl(patch: $patch) {
140
+ id
141
+ downloadUrl
142
+ status
143
+ }
144
+ }
145
+ `,
146
+ variables: { patch: dataArchive }
147
+ })
148
+
149
+ if (!response.errors) {
150
+ this.showToast(i18next.t('title.data-archive downloads ready'))
151
+ this.dispatchEvent(new CustomEvent('created', {}))
152
+ } else {
153
+ console.error(response.errors)
154
+ this.showToast(i18next.t('text.failed'))
155
+ }
156
+ }
157
+
158
+ showToast(message) {
159
+ document.dispatchEvent(new CustomEvent('notify', { detail: { message } }))
160
+ }
161
+
162
+ constructor() {
163
+ super()
164
+
165
+ this.dataSetTypes = [
166
+ {},
167
+ {
168
+ display: i18next.t('text.manually collected'),
169
+ value: 'manual'
170
+ },
171
+ {
172
+ display: i18next.t('text.automatically collected'),
173
+ value: 'automatic'
174
+ }
175
+ ]
176
+ }
177
+ }