@things-factory/organization 6.2.103 → 6.2.111

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 (36) hide show
  1. package/client/pages/department/department-list-page.ts +308 -196
  2. package/client/pages/department/department-tree-page.ts +153 -403
  3. package/client/route.ts +4 -4
  4. package/client/types/department.ts +0 -8
  5. package/dist-client/pages/department/department-list-page.d.ts +12 -20
  6. package/dist-client/pages/department/department-list-page.js +308 -182
  7. package/dist-client/pages/department/department-list-page.js.map +1 -1
  8. package/dist-client/pages/department/department-tree-page.d.ts +10 -12
  9. package/dist-client/pages/department/department-tree-page.js +142 -382
  10. package/dist-client/pages/department/department-tree-page.js.map +1 -1
  11. package/dist-client/route.d.ts +1 -1
  12. package/dist-client/route.js +3 -3
  13. package/dist-client/route.js.map +1 -1
  14. package/dist-client/tsconfig.tsbuildinfo +1 -1
  15. package/dist-client/types/department.d.ts +0 -6
  16. package/dist-client/types/department.js +0 -5
  17. package/dist-client/types/department.js.map +1 -1
  18. package/dist-server/service/department/department-history.js +4 -15
  19. package/dist-server/service/department/department-history.js.map +1 -1
  20. package/dist-server/service/department/department-query.js +15 -10
  21. package/dist-server/service/department/department-query.js.map +1 -1
  22. package/dist-server/service/department/department-type.js +0 -8
  23. package/dist-server/service/department/department-type.js.map +1 -1
  24. package/dist-server/service/department/department.js +1 -15
  25. package/dist-server/service/department/department.js.map +1 -1
  26. package/dist-server/tsconfig.tsbuildinfo +1 -1
  27. package/package.json +2 -2
  28. package/server/service/department/department-history.ts +7 -31
  29. package/server/service/department/department-query.ts +13 -10
  30. package/server/service/department/department-type.ts +1 -7
  31. package/server/service/department/department.ts +0 -15
  32. package/translations/en.json +1 -0
  33. package/translations/ja.json +1 -0
  34. package/translations/ko.json +1 -0
  35. package/translations/ms.json +1 -0
  36. package/translations/zh.json +1 -0
@@ -4,18 +4,17 @@ import '@operato/context/ox-context-page-toolbar.js';
4
4
  import { CommonHeaderStyles, ScrollbarStyles } from '@operato/styles';
5
5
  import { PageView, store } from '@operato/shell';
6
6
  import { css, html } from 'lit';
7
- import { customElement, property, query, state } from 'lit/decorators.js';
7
+ import { customElement, query, state } from 'lit/decorators.js';
8
8
  import { ScopedElementsMixin } from '@open-wc/scoped-elements';
9
9
  import { client } from '@operato/graphql';
10
10
  import { i18next, localize } from '@operato/i18n';
11
- import { isMobileDevice } from '@operato/utils';
12
- import { DataGrist } from '@operato/data-grist';
13
11
  import { connect } from 'pwa-helpers/connect-mixin';
14
12
  import gql from 'graphql-tag';
15
13
  import { DepartmentImporter } from './department-importer';
16
14
  import { Department } from '../../types/department';
15
+ import { DepartmentView } from '../../component/department-view';
17
16
  const departmentFragment = gql `
18
- fragment Department_department on Department {
17
+ fragment departmentFragment on Department {
19
18
  id
20
19
  controlNo
21
20
  name
@@ -29,7 +28,6 @@ const departmentFragment = gql `
29
28
  email
30
29
  }
31
30
  active
32
- state
33
31
  picture
34
32
 
35
33
  updater {
@@ -55,10 +53,17 @@ let DepartmentTreePage = class DepartmentTreePage extends connect(store)(localiz
55
53
  title: i18next.t('button.add'),
56
54
  action: this.create.bind(this)
57
55
  },
56
+ this.selected
57
+ ? {
58
+ icon: 'save',
59
+ title: i18next.t('button.save'),
60
+ action: this.save.bind(this)
61
+ }
62
+ : null,
58
63
  {
59
- icon: 'save',
60
- title: i18next.t('button.save'),
61
- action: this.save.bind(this)
64
+ icon: 'refresh',
65
+ title: i18next.t('button.reset'),
66
+ action: this.reset.bind(this)
62
67
  },
63
68
  {
64
69
  icon: 'delete',
@@ -77,67 +82,100 @@ let DepartmentTreePage = class DepartmentTreePage extends connect(store)(localiz
77
82
  };
78
83
  }
79
84
  render() {
80
- const mode = isMobileDevice() ? 'CARD' : 'GRID';
81
85
  return html `
82
- <ox-grist .mode=${mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>
83
- <div slot="headroom" class="header">
84
- <div class="title">
85
- <mwc-icon>summarize</mwc-icon>
86
- ${i18next.t('title.department list')}
87
- </div>
86
+ <div class="header">
87
+ <div class="title">
88
+ <mwc-icon>summarize</mwc-icon>
89
+ ${i18next.t('title.department list')}
90
+ </div>
88
91
 
89
- <div class="filters">
90
- <ox-filters-form class="filter" autofocus without-search></ox-filters-form>
91
- </div>
92
+ <ox-context-page-toolbar class="actions" .context=${this.context}></ox-context-page-toolbar>
93
+ </div>
92
94
 
93
- <ox-context-page-toolbar class="actions" .context=${this.context}></ox-context-page-toolbar>
94
- </div>
95
- </ox-grist>
95
+ <ox-tree-vertical .data=${this.root} .selected=${this.selected} @select=${this.onSelect.bind(this)} label-property="name"></ox-tree-vertical>
96
+
97
+ <department-view .department=${this.selected}></department-view>
96
98
  `;
97
99
  }
98
- async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }) {
99
- const response = await client.query({
100
- query: gql `
101
- query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
102
- responses: departmentRoot {
103
- ...Department_department
104
- children(filters: $filters, pagination: $pagination, sortings: $sortings) {
105
- ...Department_department
106
- children(filters: $filters, pagination: $pagination, sortings: $sortings) {
107
- ...Department_department
108
- children(filters: $filters, pagination: $pagination, sortings: $sortings) {
109
- ...Department_department
110
- children(filters: $filters, pagination: $pagination, sortings: $sortings) {
111
- ...Department_department
112
- children(filters: $filters, pagination: $pagination, sortings: $sortings) {
113
- ...Department_department
114
- children(filters: $filters, pagination: $pagination, sortings: $sortings) {
115
- ...Department_department
116
- children(filters: $filters, pagination: $pagination, sortings: $sortings) {
117
- ...Department_department
118
- }
119
- }
120
- }
121
- }
122
- }
123
- }
124
- }
100
+ onSelect(e) {
101
+ this.selected = e.detail;
102
+ this.updateContext();
103
+ }
104
+ reset() {
105
+ this.departmentView.department = {};
106
+ }
107
+ async create() {
108
+ const { id: parentId } = this.selected || {};
109
+ const { controlNo, name, description, picture, active, manager } = this.departmentView.department;
110
+ var department = {
111
+ controlNo,
112
+ name,
113
+ description,
114
+ manager,
115
+ active
116
+ };
117
+ if (picture instanceof File) {
118
+ department.picture = picture;
119
+ }
120
+ if (parentId) {
121
+ department.parent = { id: parentId };
122
+ }
123
+ const response = await client.mutate({
124
+ mutation: gql `
125
+ mutation ($department: NewDepartment!) {
126
+ createDepartment(department: $department) {
127
+ ...departmentFragment
125
128
  }
126
129
  }
127
130
 
128
131
  ${departmentFragment}
129
132
  `,
130
133
  variables: {
131
- filters,
132
- pagination: { page, limit },
133
- sortings
134
+ department
135
+ },
136
+ context: {
137
+ hasUpload: true
134
138
  }
135
139
  });
136
- const root = response.data.responses;
137
- return {
138
- total: 1,
139
- records: [root]
140
+ this.selected = response.data.createDepartment;
141
+ this.updateContext();
142
+ await this.fetch();
143
+ }
144
+ async save() {
145
+ const { id, controlNo, name, description, picture, active, manager } = this.departmentView.department;
146
+ if (!id) {
147
+ alert('Please select department first.');
148
+ }
149
+ var patch = {
150
+ controlNo,
151
+ name,
152
+ description,
153
+ active,
154
+ manager
140
155
  };
156
+ if (picture instanceof File) {
157
+ patch.picture = picture;
158
+ }
159
+ const response = await client.mutate({
160
+ mutation: gql `
161
+ mutation ($id: String!, $patch: DepartmentPatch!) {
162
+ updateDepartment(id: $id, patch: $patch) {
163
+ ...departmentFragment
164
+ }
165
+ }
166
+
167
+ ${departmentFragment}
168
+ `,
169
+ variables: {
170
+ id,
171
+ patch
172
+ },
173
+ context: {
174
+ hasUpload: true
175
+ }
176
+ });
177
+ this.selected = response.data.updateDepartment;
178
+ this.fetch();
141
179
  }
142
180
  async delete() {
143
181
  var _a;
@@ -162,354 +200,80 @@ let DepartmentTreePage = class DepartmentTreePage extends connect(store)(localiz
162
200
  });
163
201
  this.selected = {};
164
202
  this.updateContext();
165
- await this.grist.fetch();
203
+ await this.fetch();
166
204
  }
167
205
  }
168
206
  async pageInitialized(lifecycle) {
169
- this.gristConfig = {
170
- pagination: { pages: [50, 100, 200] },
171
- list: {
172
- thumbnail: 'profile',
173
- fields: ['controlNo', 'name'],
174
- details: ['email', 'manager', 'updatedAt']
175
- },
176
- columns: [
177
- {
178
- type: 'gutter',
179
- gutterName: 'dirty',
180
- fixed: true
181
- },
182
- {
183
- type: 'tree',
184
- name: 'name',
185
- label: true,
186
- header: i18next.t('label.name'),
187
- record: {
188
- editable: true,
189
- options: {
190
- selectable: true
191
- }
192
- },
193
- filter: 'search',
194
- sortable: true,
195
- width: 200,
196
- fixed: true,
197
- handlers: {
198
- contextmenu: 'contextmenu-tree-mutation'
199
- }
200
- },
201
- { name: 'id', hidden: true },
202
- {
203
- type: 'string',
204
- name: 'controlNo',
205
- header: i18next.t('label.control-no'),
206
- record: {
207
- editable: true
208
- },
209
- filter: 'search',
210
- sortable: true,
211
- width: 110
212
- },
213
- {
214
- type: 'string',
215
- name: 'description',
216
- header: i18next.t('label.description'),
217
- record: {
218
- editable: true
219
- },
220
- filter: 'search',
221
- sortable: true,
222
- width: 110
223
- },
224
- {
225
- type: 'string',
226
- name: 'state',
227
- header: i18next.t('label.state'),
228
- record: {
229
- editable: true
230
- },
231
- sortable: true,
232
- width: 110
233
- },
234
- {
235
- type: 'resource-object',
236
- name: 'manager',
237
- header: i18next.t('label.manager'),
238
- record: {
239
- editable: true,
240
- options: {
241
- title: i18next.t('title.employee list'),
242
- queryName: 'employees',
243
- pagination: { pages: [50, 100, 200] },
244
- basicArgs: {
245
- filters: [
246
- {
247
- name: 'active',
248
- operator: 'eq',
249
- value: true
250
- }
251
- ]
252
- },
253
- list: { fields: ['controlNo', 'name', 'email'] },
254
- columns: [
255
- { name: 'id', hidden: true },
256
- {
257
- name: 'controlNo',
258
- width: 120,
259
- header: { renderer: () => i18next.t('field.control-no') },
260
- filter: 'search',
261
- sortable: true
262
- },
263
- {
264
- name: 'name',
265
- width: 120,
266
- header: { renderer: () => i18next.t('field.name') },
267
- filter: 'search',
268
- sortable: true
269
- },
270
- {
271
- name: 'email',
272
- width: 150,
273
- header: { renderer: () => i18next.t('label.email') },
274
- filter: 'search',
275
- sortable: true
276
- }
277
- ],
278
- valueField: 'id',
279
- nameField: 'name',
280
- descriptionField: 'controlNo'
281
- }
282
- },
283
- sortable: true,
284
- width: 120
285
- },
286
- {
287
- type: 'checkbox',
288
- name: 'active',
289
- label: true,
290
- header: i18next.t('field.active'),
291
- width: 70,
292
- record: {
293
- align: 'center',
294
- editable: true
295
- },
296
- filter: true,
297
- sortable: true
298
- },
299
- {
300
- type: 'resource-object',
301
- name: 'updater',
302
- header: i18next.t('field.updater'),
303
- width: 90,
304
- sortable: false
305
- },
306
- {
307
- type: 'datetime',
308
- name: 'updatedAt',
309
- header: i18next.t('field.updated_at'),
310
- width: 180,
311
- sortable: true
312
- },
313
- {
314
- type: 'image',
315
- name: 'picture',
316
- record: {
317
- renderer: function (value, column, record, rowIndex, field) {
318
- return html `<ox-pfp-view style="height:90%; width: unset; aspect-ratio: 1 / 1;" .profile=${record.picture} .name=${record.name}></ox-pfp-view>`;
319
- }
320
- },
321
- hidden: true
322
- }
323
- ],
324
- rows: {
325
- appendable: false,
326
- selectable: {
327
- multiple: true
328
- }
329
- },
330
- sorters: [
331
- {
332
- name: 'controlNo'
333
- }
334
- ],
335
- tree: {
336
- childrenProperty: 'children',
337
- expanded: () => true
338
- }
339
- };
207
+ this.fetch();
340
208
  }
341
209
  async pageUpdated(changes, lifecycle) {
342
210
  if (this.active) {
343
211
  // do something here when this page just became as active
344
212
  }
345
213
  }
346
- async create() {
347
- // const { id: parentId } = this.selected || {}
348
- // const { controlNo, name, description, state, picture, active, manager } = this.grist.department
349
- // var department = {
350
- // controlNo,
351
- // name,
352
- // description,
353
- // state,
354
- // manager,
355
- // active
356
- // } as any
357
- // if (picture instanceof File) {
358
- // department.picture = picture
359
- // }
360
- // if (parentId) {
361
- // department.parent = { id: parentId }
362
- // }
363
- // const response = await client.mutate({
364
- // mutation: gql`
365
- // mutation ($department: NewDepartment!) {
366
- // createDepartment(department: $department) {
367
- // ...Department_department
368
- // }
369
- // }
370
- // ${departmentFragment}
371
- // `,
372
- // variables: {
373
- // department
374
- // },
375
- // context: {
376
- // hasUpload: true
377
- // }
378
- // })
379
- // this.selected = response.data.createDepartment
380
- // this.updateContext()
381
- await this.grist.fetch();
382
- }
383
- // async _deleteDataSet() {
384
- // if (confirm(i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }))) {
385
- // const ids = this.grist.selected.map(record => record.id)
386
- // if (ids && ids.length > 0) {
387
- // const response = await client.mutate({
388
- // mutation: gql`
389
- // mutation ($ids: [String!]!) {
390
- // deleteDataSets(ids: $ids)
391
- // }
392
- // `,
393
- // variables: {
394
- // ids
395
- // }
396
- // })
397
- // if (!response.errors) {
398
- // this.grist.fetch()
399
- // notify({
400
- // message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
401
- // })
402
- // }
403
- // }
404
- // }
405
- // }
406
- // async _copyDataSet() {
407
- // var selected = this.grist.selected
408
- // if (selected.length == 0) return
409
- // if (!confirm(i18next.t('text.sure_to_x', { x: i18next.t('text.copy') }))) return
410
- // var response = await client.mutate({
411
- // mutation: gql`
412
- // mutation ($ids: [String!]!) {
413
- // copyDataSets(ids: $ids) {
414
- // id
415
- // }
416
- // }
417
- // `,
418
- // variables: {
419
- // ids: selected.map(r => r.id)
420
- // }
421
- // })
422
- // if (!response.errors) {
423
- // this.grist.fetch()
424
- // }
425
- // }
426
- // async save() {
427
- // const { id, controlNo, name, description, state, picture, active, manager } = this.departmentView.department
428
- // if (!id) {
429
- // alert('Please select department first.')
430
- // }
431
- // var patch = {
432
- // controlNo,
433
- // name,
434
- // description,
435
- // state,
436
- // active,
437
- // manager
438
- // } as any
439
- // if (picture instanceof File) {
440
- // patch.picture = picture
441
- // }
442
- // const response = await client.mutate({
443
- // mutation: gql`
444
- // mutation ($id: String!, $patch: DepartmentPatch!) {
445
- // updateDepartment(id: $id, patch: $patch) {
446
- // ...Department_department
447
- // }
448
- // }
449
- // ${departmentFragment}
450
- // `,
451
- // variables: {
452
- // id,
453
- // patch
454
- // },
455
- // context: {
456
- // hasUpload: true
457
- // }
458
- // })
459
- // this.selected = response.data.updateDepartment
460
- // this.fetch()
461
- // }
462
- async save() {
463
- let patches = this.grist.dirtyRecords;
464
- if (patches && patches.length) {
465
- patches = patches.map(patch => {
466
- let patchField = patch.id ? { id: patch.id } : {};
467
- const dirtyFields = patch.__dirtyfields__;
468
- for (let key in dirtyFields) {
469
- patchField[key] = dirtyFields[key].after;
214
+ async fetch() {
215
+ const response = await client.query({
216
+ query: gql `
217
+ query {
218
+ responses: departmentRoots {
219
+ total
220
+ items {
221
+ ...departmentFragment
222
+ children {
223
+ ...departmentFragment
224
+ children {
225
+ ...departmentFragment
226
+ children {
227
+ ...departmentFragment
228
+ children {
229
+ ...departmentFragment
230
+ children {
231
+ ...departmentFragment
232
+ children {
233
+ ...departmentFragment
234
+ children {
235
+ ...departmentFragment
236
+ }
237
+ }
238
+ }
239
+ }
240
+ }
470
241
  }
471
- patchField.cuFlag = patch.__dirty__;
472
- return patchField;
473
- });
474
- const response = await client.mutate({
475
- mutation: gql `
476
- mutation ($patches: [DepartmentPatch!]!) {
477
- updateMultipleDepartment(patches: $patches) {
478
- name
242
+ }
479
243
  }
480
244
  }
481
- `,
482
- variables: {
483
- patches
484
- },
485
- context: {
486
- hasUpload: true
487
- }
488
- });
489
- if (!response.errors) {
490
- this.grist.fetch();
491
- }
492
245
  }
246
+
247
+ ${departmentFragment}
248
+ `
249
+ });
250
+ const { items: records, total } = response.data.responses;
251
+ this.root = records[0];
493
252
  }
494
253
  async exportHandler() { }
495
254
  async importHandler(records) { }
496
255
  };
497
256
  DepartmentTreePage.styles = [
498
- ScrollbarStyles,
499
257
  CommonHeaderStyles,
258
+ ScrollbarStyles,
500
259
  css `
501
260
  :host {
502
261
  display: flex;
262
+ flex-direction: column;
503
263
 
504
264
  width: 100%;
265
+ overflow: auto;
266
+ }
505
267
 
506
- --grid-record-emphasized-background-color: #8b0000;
507
- --grid-record-emphasized-color: #ff6b6b;
268
+ ox-tree-vertical {
269
+ flex: 1;
508
270
  }
509
271
 
510
- ox-grist {
511
- overflow-y: auto;
272
+ department-view {
512
273
  flex: 1;
274
+
275
+ max-width: 500px;
276
+ align-self: center;
513
277
  }
514
278
  `
515
279
  ];
@@ -522,13 +286,9 @@ __decorate([
522
286
  __metadata("design:type", Department)
523
287
  ], DepartmentTreePage.prototype, "selected", void 0);
524
288
  __decorate([
525
- query('ox-grist'),
526
- __metadata("design:type", DataGrist)
527
- ], DepartmentTreePage.prototype, "grist", void 0);
528
- __decorate([
529
- property({ type: Object }),
530
- __metadata("design:type", Object)
531
- ], DepartmentTreePage.prototype, "gristConfig", void 0);
289
+ query('department-view'),
290
+ __metadata("design:type", DepartmentView)
291
+ ], DepartmentTreePage.prototype, "departmentView", void 0);
532
292
  DepartmentTreePage = __decorate([
533
293
  customElement('department-tree-page')
534
294
  ], DepartmentTreePage);