@dssp/project 1.0.0-alpha.0 → 1.0.0-alpha.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 (98) hide show
  1. package/dist-client/tsconfig.tsbuildinfo +1 -1
  2. package/dist-server/tsconfig.tsbuildinfo +1 -1
  3. package/package.json +11 -11
  4. package/client/bootstrap.ts +0 -0
  5. package/client/index.ts +0 -0
  6. package/client/pages/lib/select2-component.ts +0 -175
  7. package/client/pages/lib/waether.ts +0 -159
  8. package/client/pages/project/component/project-update-header.ts +0 -88
  9. package/client/pages/project/popup/popup-plan-upload.ts +0 -138
  10. package/client/pages/project/popup/popup-project-create.ts +0 -147
  11. package/client/pages/project/popup/popup-schedule-upload.ts +0 -102
  12. package/client/pages/project/project-completed-list.ts +0 -281
  13. package/client/pages/project/project-detail.ts +0 -738
  14. package/client/pages/project/project-list.ts +0 -418
  15. package/client/pages/project/project-plan-management.ts +0 -476
  16. package/client/pages/project/project-schedule-list.ts +0 -294
  17. package/client/pages/project/project-schedule.ts +0 -393
  18. package/client/pages/project/project-setting-list.ts +0 -393
  19. package/client/pages/project/project-update.ts +0 -876
  20. package/client/pages/resource/construction-detail-type-popup.ts +0 -201
  21. package/client/pages/resource/construction-type-management.ts +0 -212
  22. package/client/pages/resource/inspection-drawing-type-management.ts +0 -245
  23. package/client/pages/resource/inspection-part-popup.ts +0 -201
  24. package/client/pages/resource/resource-importer.ts +0 -97
  25. package/client/pages/resource/resource-list-page.ts +0 -356
  26. package/client/pages/resource/worker-type-management.ts +0 -192
  27. package/client/pages/task/task-importer.ts +0 -94
  28. package/client/pages/task/task-list-page.ts +0 -340
  29. package/client/pages/task-resource/task-resource-importer.ts +0 -97
  30. package/client/pages/task-resource/task-resource-list-page.ts +0 -356
  31. package/client/route.ts +0 -55
  32. package/client/tsconfig.json +0 -11
  33. package/server/controllers/export-tasks.ts +0 -40
  34. package/server/controllers/import-task.ts +0 -134
  35. package/server/controllers/index.ts +0 -0
  36. package/server/controllers/parse-excel.ts +0 -86
  37. package/server/controllers/types.ts +0 -20
  38. package/server/index.ts +0 -4
  39. package/server/middlewares/index.ts +0 -3
  40. package/server/migrations/1723861466413-seed-roles.ts +0 -128
  41. package/server/migrations/1723861466414-seed-codes.ts +0 -157
  42. package/server/migrations/1723861476419-seed-resources.ts +0 -62
  43. package/server/migrations/1723861478420-seed-/bsample-project.ts +0 -87
  44. package/server/migrations/1723861478421-seed-/bsample-tasks.ts +0 -194
  45. package/server/migrations/index.ts +0 -9
  46. package/server/routes.ts +0 -108
  47. package/server/service/construction-detail-type/construction-detail-type-mutation.ts +0 -57
  48. package/server/service/construction-detail-type/construction-detail-type-query.ts +0 -31
  49. package/server/service/construction-detail-type/construction-detail-type-type.ts +0 -26
  50. package/server/service/construction-detail-type/construction-detail-type.ts +0 -52
  51. package/server/service/construction-detail-type/index.ts +0 -6
  52. package/server/service/construction-type/construction-type-mutation.ts +0 -66
  53. package/server/service/construction-type/construction-type-query.ts +0 -56
  54. package/server/service/construction-type/construction-type-type.ts +0 -26
  55. package/server/service/construction-type/construction-type.ts +0 -74
  56. package/server/service/construction-type/index.ts +0 -6
  57. package/server/service/index.ts +0 -56
  58. package/server/service/inspection-drawing-type/index.ts +0 -6
  59. package/server/service/inspection-drawing-type/inspection-drawing-type-mutation.ts +0 -69
  60. package/server/service/inspection-drawing-type/inspection-drawing-type-query.ts +0 -55
  61. package/server/service/inspection-drawing-type/inspection-drawing-type-type.ts +0 -23
  62. package/server/service/inspection-drawing-type/inspection-drawing-type.ts +0 -68
  63. package/server/service/inspection-part/index.ts +0 -6
  64. package/server/service/inspection-part/inspection-part-mutation.ts +0 -52
  65. package/server/service/inspection-part/inspection-part-query.ts +0 -41
  66. package/server/service/inspection-part/inspection-part-type.ts +0 -26
  67. package/server/service/inspection-part/inspection-part.ts +0 -51
  68. package/server/service/manager/index.ts +0 -6
  69. package/server/service/manager/manager-mutation.ts +0 -42
  70. package/server/service/manager/manager-query.ts +0 -28
  71. package/server/service/manager/manager-type.ts +0 -40
  72. package/server/service/manager/manager.ts +0 -29
  73. package/server/service/project/index.ts +0 -6
  74. package/server/service/project/project-mutation.ts +0 -255
  75. package/server/service/project/project-query.ts +0 -105
  76. package/server/service/project/project-type.ts +0 -72
  77. package/server/service/project/project.ts +0 -134
  78. package/server/service/resource/index.ts +0 -7
  79. package/server/service/resource/resource-mutation.ts +0 -137
  80. package/server/service/resource/resource-query.ts +0 -50
  81. package/server/service/resource/resource-type.ts +0 -41
  82. package/server/service/resource/resource.ts +0 -82
  83. package/server/service/task/index.ts +0 -6
  84. package/server/service/task/task-mutation.ts +0 -135
  85. package/server/service/task/task-query.ts +0 -169
  86. package/server/service/task/task-type.ts +0 -75
  87. package/server/service/task/task.ts +0 -130
  88. package/server/service/task-resource/index.ts +0 -7
  89. package/server/service/task-resource/task-resource-mutation.ts +0 -140
  90. package/server/service/task-resource/task-resource-query.ts +0 -36
  91. package/server/service/task-resource/task-resource-type.ts +0 -41
  92. package/server/service/task-resource/task-resource.ts +0 -51
  93. package/server/service/worker-type/index.ts +0 -6
  94. package/server/service/worker-type/worker-type-mutation.ts +0 -66
  95. package/server/service/worker-type/worker-type-query.ts +0 -47
  96. package/server/service/worker-type/worker-type-type.ts +0 -26
  97. package/server/service/worker-type/worker-type.ts +0 -68
  98. package/server/tsconfig.json +0 -10
@@ -1,201 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '@operato/data-grist/ox-grist.js'
3
-
4
- import gql from 'graphql-tag'
5
- import { css, html, LitElement } from 'lit'
6
- import { customElement, property, query } from 'lit/decorators.js'
7
-
8
- import { DataGrist } from '@operato/data-grist/ox-grist.js'
9
- import { client } from '@operato/graphql'
10
- import { ButtonContainerStyles } from '@operato/styles'
11
- import { FetchOption } from '@operato/data-grist'
12
- import { notify } from '@operato/layout'
13
-
14
- @customElement('inspection-part-popup')
15
- class InspectionPartPopup extends LitElement {
16
- static styles = [
17
- ButtonContainerStyles,
18
- css`
19
- :host {
20
- display: flex;
21
- flex-direction: column;
22
-
23
- background-color: var(--md-sys-color-surface);
24
- }
25
-
26
- ox-grist {
27
- flex: 1;
28
- }
29
- `
30
- ]
31
-
32
- @property({ type: Object }) inspectionDrawingType: any
33
- @property({ type: Object }) gristConfig: any
34
-
35
- @query('ox-grist') grist!: DataGrist
36
-
37
- render() {
38
- return html`
39
- <ox-grist .mode=${'GRID'} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}></ox-grist>
40
- <div class="button-container">
41
- <button danger @click=${this._deleteInspectionPart.bind(this)}><md-icon>delete</md-icon>삭제</button>
42
- <button @click=${this._updateInspectionPart.bind(this)}><md-icon>save</md-icon>저장</button>
43
- </div>
44
- `
45
- }
46
-
47
- async firstUpdated() {
48
- this.gristConfig = {
49
- columns: [
50
- { type: 'gutter', gutterName: 'row-selector', multiple: true },
51
- {
52
- type: 'gutter',
53
- gutterName: 'button',
54
- fixed: true,
55
- icon: 'add',
56
- handlers: {
57
- click: 'record-copy'
58
- }
59
- },
60
- { type: 'gutter', gutterName: 'sequence' },
61
- {
62
- type: 'gutter',
63
- gutterName: 'button',
64
- icon: 'arrow_upward',
65
- handlers: {
66
- click: 'move-up'
67
- }
68
- },
69
- {
70
- type: 'gutter',
71
- gutterName: 'button',
72
- icon: 'arrow_downward',
73
- handlers: {
74
- click: 'move-down'
75
- }
76
- },
77
- {
78
- type: 'number',
79
- name: 'sequence',
80
- hidden: true
81
- },
82
- {
83
- type: 'string',
84
- name: 'id',
85
- hidden: true
86
- },
87
- {
88
- type: 'string',
89
- name: 'name',
90
- header: '검측 부위',
91
- record: {
92
- editable: true
93
- },
94
- width: 300
95
- }
96
- ],
97
- rows: {
98
- selectable: {
99
- multiple: true
100
- }
101
- },
102
- pagination: {
103
- infinite: true
104
- },
105
- sorters: [{ name: 'sequence' }]
106
- }
107
- }
108
-
109
- async fetchHandler({ page, limit, sorters = [] }: FetchOption) {
110
- const response = await client.query({
111
- query: gql`
112
- query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
113
- inspectionParts(filters: $filters, pagination: $pagination, sortings: $sortings) {
114
- items {
115
- id
116
- sequence
117
- name
118
- }
119
- }
120
- }
121
- `,
122
- variables: {
123
- filters: {
124
- name: 'inspectionDrawingTypeId',
125
- value: this.inspectionDrawingType.id,
126
- operator: 'eq'
127
- },
128
- sortings: [{ name: 'sequence' }]
129
- }
130
- })
131
-
132
- return {
133
- total: response.data.inspectionParts.total || 0,
134
- records: response.data.inspectionParts.items || []
135
- }
136
- }
137
-
138
- private async _deleteInspectionPart() {
139
- if (confirm('삭제하시겠습니까?')) {
140
- const ids = this.grist.selected.map(record => record.id)
141
- if (ids && ids.length > 0) {
142
- const response = await client.mutate({
143
- mutation: gql`
144
- mutation ($ids: [String!]!) {
145
- deleteInspectionParts(ids: $ids)
146
- }
147
- `,
148
- variables: {
149
- ids
150
- }
151
- })
152
-
153
- if (!response.errors) {
154
- this.grist.fetch()
155
- notify({ message: '삭제되었습니다.' })
156
- }
157
- }
158
- }
159
- }
160
-
161
- async _updateInspectionPart() {
162
- let patches = this.grist.dirtyData.records
163
- if (patches) {
164
- patches = patches.map(patch => {
165
- const { __origin__: { __typename, ...patchField } = {}, __dirtyfields__ } = patch
166
-
167
- for (let key in __dirtyfields__) {
168
- patchField[key] = __dirtyfields__[key].after
169
- }
170
-
171
- return patchField
172
- })
173
-
174
- const response = await client.mutate({
175
- mutation: gql`
176
- mutation UpdateMultipleInspectionPart($inspectionDrawingTypeId: String!, $patches: [InspectionPartPatch!]!) {
177
- updateMultipleInspectionPart(inspectionDrawingTypeId: $inspectionDrawingTypeId, patches: $patches) {
178
- id
179
- }
180
- }
181
- `,
182
- variables: {
183
- inspectionDrawingTypeId: this.inspectionDrawingType.id,
184
- patches
185
- }
186
- })
187
-
188
- if (!response.errors) {
189
- this.grist.fetch()
190
- notify({ message: '저장되었습니다.' })
191
- this.requestRefresh()
192
- } else {
193
- notify({ message: '저장에 실패하였습니다.', level: 'error' })
194
- }
195
- }
196
- }
197
-
198
- requestRefresh() {
199
- this.dispatchEvent(new CustomEvent('requestRefresh'))
200
- }
201
- }
@@ -1,97 +0,0 @@
1
- import '@material/web/button/elevated-button.js'
2
- import '@operato/data-grist'
3
-
4
- import gql from 'graphql-tag'
5
- import { css, html, LitElement } from 'lit'
6
- import { property, state } from 'lit/decorators.js'
7
-
8
- import { client } from '@operato/graphql'
9
- import { i18next } from '@operato/i18n'
10
- import { isMobileDevice } from '@operato/utils'
11
-
12
- export class ResourceImporter extends LitElement {
13
- static styles = [
14
- css`
15
- :host {
16
- display: flex;
17
- flex-direction: column;
18
-
19
- background-color: #fff;
20
- }
21
-
22
- ox-grist {
23
- flex: 1;
24
- }
25
-
26
- .button-container {
27
- display: flex;
28
- margin-left: auto;
29
- padding: var(--padding-default);
30
- }
31
-
32
- md-elevated-button {
33
- margin-left: var(--margin-default);
34
- }
35
- `
36
- ]
37
-
38
- @state() private resources: any[] = []
39
- @state() private columns = {
40
- list: { fields: ['name', 'description'] },
41
- pagination: { infinite: true },
42
- columns: [
43
- {
44
- type: 'string',
45
- name: 'name',
46
- header: i18next.t('field.name'),
47
- width: 150
48
- },
49
- {
50
- type: 'string',
51
- name: 'description',
52
- header: i18next.t('field.description'),
53
- width: 200
54
- },
55
- {
56
- type: 'checkbox',
57
- name: 'active',
58
- header: i18next.t('field.active'),
59
- width: 60
60
- }
61
- ]
62
- }
63
-
64
- render() {
65
- return html`
66
- <ox-grist
67
- .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
68
- .config=${this.columns}
69
- .data=${
70
- {
71
- records: this.resources
72
- }
73
- }
74
- ></ox-grist>
75
-
76
- <div class="button-container">
77
- <md-elevated-button raised @click="${this.save.bind(this)}">${i18next.t('button.save')}</md-elevated-button>
78
- </div>
79
- `
80
- }
81
-
82
- private async save() {
83
- const response = await client.mutate({
84
- mutation: gql`
85
- mutation importResources($resources: [ResourcePatch!]!) {
86
- importResources(resources: $resources)
87
- }
88
- `,
89
- variables: { resources: this.resources }
90
- })
91
-
92
- if (response.errors?.length) return
93
-
94
- this.dispatchEvent(new CustomEvent('imported'))
95
- }
96
- }
97
-
@@ -1,356 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '@operato/data-grist'
3
-
4
- import { CommonButtonStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles'
5
- import { PageView, store } from '@operato/shell'
6
- import { css, html } from 'lit'
7
- import { customElement, property, query, state } from 'lit/decorators.js'
8
- import { ScopedElementsMixin } from '@open-wc/scoped-elements'
9
- import {
10
- ColumnConfig,
11
- DataGrist,
12
- FetchOption,
13
- SortersControl
14
- } from '@operato/data-grist'
15
- import { client } from '@operato/graphql'
16
- import { i18next, localize } from '@operato/i18n'
17
- import { notify, openPopup } from '@operato/layout'
18
- import { OxPopup, OxPrompt } from '@operato/popup'
19
- import { isMobileDevice } from '@operato/utils'
20
-
21
- import { connect } from 'pwa-helpers/connect-mixin'
22
- import gql from 'graphql-tag'
23
-
24
- import { ResourceImporter } from './resource-importer'
25
-
26
- @customElement('resource-list-page')
27
- export class ResourceListPage extends connect(store)(localize(i18next)(ScopedElementsMixin(PageView))) {
28
-
29
- static styles = [
30
- ScrollbarStyles,
31
- CommonGristStyles,
32
- css`
33
- :host {
34
- display: flex;
35
-
36
- width: 100%;
37
-
38
- --grid-record-emphasized-background-color: red;
39
- --grid-record-emphasized-color: yellow;
40
- }
41
- `
42
- ]
43
-
44
- static get scopedElements() {
45
- return {
46
- 'resource-importer': ResourceImporter
47
- }
48
- }
49
-
50
- @state() private gristConfig: any
51
- @state() private mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'CARD' : 'GRID'
52
-
53
- @query('ox-grist') private grist!: DataGrist
54
- @query('#sorter-control') private sortersControl!: OxPopup
55
-
56
- get context() {
57
- return {
58
- title: i18next.t('title.resource list'),
59
- search: {
60
- handler: (search: string) => {
61
- this.grist.searchText = search
62
- },
63
- value: this.grist.searchText
64
- },
65
- filter: {
66
- handler: () => {
67
- this.grist.toggleHeadroom()
68
- }
69
- },
70
- help: 'project/resource',
71
- actions: [
72
- {
73
- title: i18next.t('button.save'),
74
- action: this.updateResource.bind(this),
75
- ...CommonButtonStyles.save
76
- },
77
- {
78
- title: i18next.t('button.delete'),
79
- action: this.deleteResource.bind(this),
80
- ...CommonButtonStyles.delete
81
- }
82
- ],
83
- exportable: {
84
- name: i18next.t('title.resource list'),
85
- data: this.exportHandler.bind(this)
86
- },
87
- importable: {
88
- handler: this.importHandler.bind(this)
89
- }
90
- }
91
- }
92
-
93
- render() {
94
- const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID')
95
-
96
- return html`
97
- <ox-grist
98
- .mode=${mode}
99
- .config=${this.gristConfig}
100
- .fetchHandler=${this.fetchHandler.bind(this)}
101
- >
102
- <div slot="headroom">
103
- <div id="filters">
104
- <ox-filters-form autofocus></ox-filters-form>
105
- </div>
106
-
107
- <div id="sorters">
108
- Sort
109
- <md-icon
110
- @click=${e => {
111
- const target = e.currentTarget
112
- this.sortersControl.open({
113
- right: 0,
114
- top: target.offsetTop + target.offsetHeight
115
- })
116
- }}
117
- >expand_more</md-icon
118
- >
119
- <ox-popup id="sorter-control">
120
- <ox-sorters-control> </ox-sorters-control>
121
- </ox-popup>
122
- </div>
123
-
124
- <div id="modes">
125
- <md-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</md-icon>
126
- <md-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</md-icon>
127
- <md-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</md-icon>
128
- </div>
129
- </div>
130
- </ox-grist>
131
- `
132
- }
133
-
134
- async pageInitialized(lifecycle: any) {
135
- this.gristConfig = {
136
- list: {
137
- fields: ['name', 'description'],
138
- details: ['active', 'updatedAt']
139
- },
140
- columns: [
141
- { type: 'gutter', gutterName: 'sequence' },
142
- { type: 'gutter', gutterName: 'row-selector', multiple: true },
143
- {
144
- type: 'string',
145
- name: 'name',
146
- header: i18next.t('field.name'),
147
- record: {
148
- editable: true
149
- },
150
- filter: 'search',
151
- sortable: true,
152
- width: 150
153
- },
154
- {
155
- type: 'string',
156
- name: 'description',
157
- header: i18next.t('field.description'),
158
- record: {
159
- editable: true
160
- },
161
- filter: 'search',
162
- width: 200
163
- },
164
- {
165
- type: 'checkbox',
166
- name: 'active',
167
- label: true,
168
- header: i18next.t('field.active'),
169
- record: {
170
- editable: true
171
- },
172
- filter: true,
173
- sortable: true,
174
- width: 60
175
- },
176
- {
177
- type: 'resource-object',
178
- name: 'updater',
179
- header: i18next.t('field.updater'),
180
- record: {
181
- editable: false
182
- },
183
- sortable: true,
184
- width: 120
185
- },
186
- {
187
- type: 'datetime',
188
- name: 'updatedAt',
189
- header: i18next.t('field.updated_at'),
190
- record: {
191
- editable: false
192
- },
193
- sortable: true,
194
- width: 180
195
- }
196
- ],
197
- rows: {
198
- selectable: {
199
- multiple: true
200
- }
201
- },
202
- sorters: [
203
- {
204
- name: 'name'
205
- }
206
- ]
207
- }
208
- }
209
-
210
- async pageUpdated(changes: any, lifecycle: any) {
211
- if (this.active) {
212
- // do something here when this page just became as active
213
- }
214
- }
215
-
216
- async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) {
217
- const response = await client.query({
218
- query: gql`
219
- query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
220
- responses: resources(filters: $filters, pagination: $pagination, sortings: $sortings) {
221
- items {
222
- id
223
- name
224
- description
225
- active
226
- updater {
227
- id
228
- name
229
- }
230
- updatedAt
231
- }
232
- total
233
- }
234
- }
235
- `,
236
- variables: {
237
- filters,
238
- pagination: { page, limit },
239
- sortings
240
- }
241
- })
242
-
243
- return {
244
- total: response.data.responses.total || 0,
245
- records: response.data.responses.items || []
246
- }
247
- }
248
-
249
- private async deleteResource() {
250
- if (
251
- await OxPrompt.open({
252
- title: i18next.t('text.are_you_sure'),
253
- text: i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }),
254
- confirmButton: { text: i18next.t('button.confirm') },
255
- cancelButton: { text: i18next.t('button.cancel') }
256
- })
257
- ) {
258
- const ids = this.grist.selected.map(record => record.id)
259
- if (ids && ids.length > 0) {
260
- const response = await client.mutate({
261
- mutation: gql`
262
- mutation ($ids: [String!]!) {
263
- deleteResources(ids: $ids)
264
- }
265
- `,
266
- variables: {
267
- ids
268
- }
269
- })
270
-
271
- if (!response.errors) {
272
- this.grist.fetch()
273
- notify({
274
- message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
275
- })
276
- }
277
- }
278
- }
279
- }
280
-
281
- private async updateResource() {
282
- let patches = this.grist.dirtyRecords
283
- if (patches && patches.length) {
284
- patches = patches.map(patch => {
285
- let patchField: any = patch.id ? { id: patch.id } : {}
286
- const dirtyFields = patch.__dirtyfields__
287
- for (let key in dirtyFields) {
288
- patchField[key] = dirtyFields[key].after
289
- }
290
- patchField.cuFlag = patch.__dirty__
291
-
292
- return patchField
293
- })
294
-
295
- const response = await client.mutate({
296
- mutation: gql`
297
- mutation ($patches: [ResourcePatch!]!) {
298
- updateMultipleResource(patches: $patches) {
299
- name
300
- }
301
- }
302
- `,
303
- variables: {
304
- patches
305
- }
306
- })
307
-
308
- if (!response.errors) {
309
- this.grist.fetch()
310
- }
311
- }
312
- }
313
-
314
- private async exportHandler() {
315
- const exportTargets = this.grist.selected.length ? this.grist.selected : this.grist.dirtyData.records
316
- const targetFieldSet = new Set([
317
- 'id',
318
- 'name',
319
- 'description',
320
- 'active'
321
- ])
322
-
323
- return exportTargets.map(resource => {
324
- let tempObj = {}
325
- for (const field of targetFieldSet) {
326
- tempObj[field] = resource[field]
327
- }
328
-
329
- return tempObj
330
- })
331
- }
332
-
333
- private async importHandler(records) {
334
- const popup = openPopup(
335
- html`
336
- <resource-importer
337
- .resources=${records}
338
- @imported=${() => {
339
- history.back()
340
- this.grist.fetch()
341
- }}
342
- ></resource-importer>
343
- `,
344
- {
345
- backdrop: true,
346
- size: 'large',
347
- title: i18next.t('title.import resource')
348
- }
349
- )
350
-
351
- popup.onclosed = () => {
352
- this.grist.fetch()
353
- }
354
- }
355
- }
356
-