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

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 (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
+ }