@things-factory/organization 7.0.0-alpha.0 → 7.0.0-alpha.3

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