@things-factory/organization 9.1.13 → 10.0.0-beta.1

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 (28) hide show
  1. package/dist-client/pages/approval-line/common-approval-line-templates-page.d.ts +1 -7
  2. package/dist-client/pages/approval-line/common-approval-line-templates-page.js +69 -128
  3. package/dist-client/pages/approval-line/common-approval-line-templates-page.js.map +1 -1
  4. package/dist-client/pages/approval-line/my-approval-line-templates-page.d.ts +1 -7
  5. package/dist-client/pages/approval-line/my-approval-line-templates-page.js +71 -132
  6. package/dist-client/pages/approval-line/my-approval-line-templates-page.js.map +1 -1
  7. package/dist-client/pages/department/department-list-page.d.ts +1 -7
  8. package/dist-client/pages/department/department-list-page.js +88 -157
  9. package/dist-client/pages/department/department-list-page.js.map +1 -1
  10. package/dist-client/pages/department/department-tree-page.d.ts +1 -7
  11. package/dist-client/pages/department/department-tree-page.js +68 -114
  12. package/dist-client/pages/department/department-tree-page.js.map +1 -1
  13. package/dist-client/pages/employee/employee-list-page.d.ts +0 -6
  14. package/dist-client/pages/employee/employee-list-page.js +124 -234
  15. package/dist-client/pages/employee/employee-list-page.js.map +1 -1
  16. package/dist-client/pages/employee/employees-by-department.d.ts +1 -7
  17. package/dist-client/pages/employee/employees-by-department.js +105 -188
  18. package/dist-client/pages/employee/employees-by-department.js.map +1 -1
  19. package/dist-client/route.d.ts +1 -1
  20. package/dist-client/tsconfig.tsbuildinfo +1 -1
  21. package/dist-server/service/employee/employee-mutation.js +1 -1
  22. package/dist-server/service/employee/employee-mutation.js.map +1 -1
  23. package/dist-server/service/index.d.ts +2 -2
  24. package/dist-server/tsconfig.tsbuildinfo +1 -1
  25. package/package.json +12 -12
  26. package/spec/unit/approval-line.spec.ts +329 -0
  27. package/spec/unit/department.spec.ts +253 -0
  28. package/spec/unit/employee.spec.ts +271 -0
@@ -5,18 +5,17 @@ import '@things-factory/contact/dist-client';
5
5
  import gql from 'graphql-tag';
6
6
  import { css, html } from 'lit';
7
7
  import { customElement, property, query } from 'lit/decorators.js';
8
- import { connect } from 'pwa-helpers/connect-mixin';
9
8
  import { ScopedElementsMixin } from '@open-wc/scoped-elements';
10
9
  import { DataGrist } from '@operato/data-grist';
11
10
  import { client } from '@operato/graphql';
12
11
  import { i18next, localize } from '@operato/i18n';
13
12
  import { notify, openPopup } from '@operato/layout';
14
- import { PageView, store } from '@operato/shell';
13
+ import { PageView } from '@operato/shell';
15
14
  import { CommonHeaderStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles';
16
15
  import { isMobileDevice } from '@operato/utils';
17
16
  import { p13n } from '@operato/p13n';
18
17
  import { EmployeeImporter } from './employee-importer';
19
- let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(localize(i18next)(ScopedElementsMixin(PageView)))) {
18
+ let EmployeeListPage = class EmployeeListPage extends p13n(localize(i18next)(ScopedElementsMixin(PageView))) {
20
19
  constructor() {
21
20
  super(...arguments);
22
21
  this.mode = isMobileDevice() ? 'CARD' : 'GRID';
@@ -26,8 +25,7 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
26
25
  CommonGristStyles,
27
26
  CommonHeaderStyles,
28
27
  css `
29
- :host {
30
- display: flex;
28
+ :host { display: flex;
31
29
 
32
30
  width: 100%;
33
31
 
@@ -35,62 +33,49 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
35
33
 
36
34
  --grid-record-emphasized-background-color: #8b0000;
37
35
  --grid-record-emphasized-color: #ff6b6b;
38
- }
36
+ }
39
37
 
40
- ox-grist {
41
- overflow-y: auto;
38
+ ox-grist { overflow-y: auto;
42
39
  flex: 1;
43
- }
40
+ }
44
41
 
45
- .header {
46
- grid-template-areas: 'filters actions';
47
- }
42
+ .header { grid-template-areas: 'filters actions';
43
+ }
48
44
  `
49
45
  ]; }
50
46
  static get scopedElements() {
51
- return {
52
- 'employee-importer': EmployeeImporter
47
+ return { 'employee-importer': EmployeeImporter
53
48
  };
54
49
  }
55
50
  get context() {
56
- return {
57
- title: i18next.t('title.employee list'),
58
- search: {
59
- handler: (search) => {
51
+ return { title: i18next.t('title.employee list'),
52
+ search: { handler: (search) => {
60
53
  this.grist.searchText = search;
61
54
  },
62
- value: this.grist?.searchText || ''
63
- },
64
- filter: {
65
- handler: () => {
55
+ value: this.grist?.searchText || '' },
56
+ filter: { handler: () => {
66
57
  this.grist.toggleHeadroom();
67
58
  }
68
59
  },
69
60
  help: 'organization/employee',
70
61
  actions: [
71
- {
72
- icon: 'save',
62
+ { icon: 'save',
73
63
  title: i18next.t('button.save'),
74
64
  action: this.onUpdateEmployee.bind(this)
75
65
  },
76
- {
77
- icon: 'delete',
66
+ { icon: 'delete',
78
67
  title: i18next.t('button.delete'),
79
68
  action: this.onDeleteEmployee.bind(this),
80
- emphasis: {
81
- danger: true
69
+ emphasis: { danger: true
82
70
  }
83
71
  }
84
72
  ],
85
- exportable: {
86
- name: i18next.t('title.employee list'),
73
+ exportable: { name: i18next.t('title.employee list'),
87
74
  data: this.exportHandler.bind(this)
88
75
  },
89
- importable: {
90
- handler: this.importHandler.bind(this)
76
+ importable: { handler: this.importHandler.bind(this)
91
77
  },
92
- toolbar: false
93
- };
78
+ toolbar: false };
94
79
  }
95
80
  render() {
96
81
  const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID');
@@ -114,47 +99,39 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
114
99
  `;
115
100
  }
116
101
  async pageInitialized(lifecycle) {
117
- this.gristConfig = {
118
- pagination: { pages: [50, 100, 200] },
119
- list: {
120
- thumbnail: 'profile',
102
+ this.gristConfig = { pagination: { pages: [50, 100, 200] },
103
+ list: { thumbnail: 'profile',
121
104
  fields: ['controlNo', 'name'],
122
105
  details: ['email', 'department', 'hiredOn', 'updatedAt']
123
106
  },
124
107
  columns: [
125
108
  { type: 'gutter', gutterName: 'sequence', fixed: true },
126
109
  { type: 'gutter', gutterName: 'row-selector', multiple: true, fixed: true },
127
- {
128
- type: 'gutter',
110
+ { type: 'gutter',
129
111
  gutterName: 'button',
130
112
  header: i18next.t('field.register-account'),
131
113
  icon: record => (record.id && !record.user ? 'badge' : ''),
132
114
  iconOnly: false,
133
115
  title: record => (record.id && !record.user ? i18next.t('button.register-account') : ''),
134
116
  width: 80,
135
- handlers: {
136
- click: (columns, data, column, record, rowIndex) => {
117
+ handlers: { click: (columns, data, column, record, rowIndex) => {
137
118
  if (!record || !record.id || record.user) {
138
- /* TODO record가 새로 추가된 것이면 리턴하도록 한다. */
139
119
  return;
140
120
  }
141
121
  this.attachSystemUser(record);
142
122
  }
143
123
  }
144
124
  },
145
- {
146
- type: 'image',
125
+ { type: 'image',
147
126
  name: 'profile',
148
127
  header: i18next.t('button.edit-contact'),
149
128
  width: 80,
150
- record: {
151
- align: 'center',
129
+ record: { align: 'center',
152
130
  renderer: function (value, column, record, rowIndex, field) {
153
131
  return html `<ox-pfp-view .profile=${record.profile} .name=${record.name || '+'}></ox-pfp-view>`;
154
132
  }
155
133
  },
156
- handlers: {
157
- click: async (columns, data, column, record, rowIndex) => {
134
+ handlers: { click: async (columns, data, column, record, rowIndex) => {
158
135
  if (record && record.contact) {
159
136
  this.openContactPopup(record);
160
137
  }
@@ -164,51 +141,42 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
164
141
  }
165
142
  }
166
143
  },
167
- {
168
- type: 'string',
144
+ { type: 'string',
169
145
  name: 'controlNo',
170
146
  fixed: true,
171
147
  header: i18next.t('field.control-no'),
172
- record: {
173
- editable: true,
148
+ record: { editable: true,
174
149
  mandatory: true
175
150
  },
176
151
  filter: 'search',
177
152
  sortable: true,
178
153
  width: 105
179
154
  },
180
- {
181
- type: 'string',
155
+ { type: 'string',
182
156
  name: 'name',
183
157
  fixed: true,
184
158
  header: i18next.t('field.name'),
185
- record: {
186
- editable: true,
159
+ record: { editable: true,
187
160
  mandatory: true
188
161
  },
189
162
  filter: 'search',
190
163
  sortable: true,
191
164
  width: 100
192
165
  },
193
- {
194
- type: 'string',
166
+ { type: 'string',
195
167
  name: 'alias',
196
168
  header: i18next.t('label.alias'),
197
- record: {
198
- editable: true
169
+ record: { editable: true
199
170
  },
200
171
  filter: 'search',
201
172
  sortable: false,
202
173
  width: 110
203
174
  },
204
- {
205
- type: 'resource-object',
175
+ { type: 'resource-object',
206
176
  name: 'user',
207
177
  header: i18next.t('field.system-user'),
208
- record: {
209
- editable: true,
210
- options: {
211
- title: i18next.t('title.lookup system-user'),
178
+ record: { editable: true,
179
+ options: { title: i18next.t('title.lookup system-user'),
212
180
  queryName: 'users',
213
181
  basicArgs: { filters: [{ name: 'userType', operator: 'eq', value: 'user' }] },
214
182
  descriptionField: 'email',
@@ -224,44 +192,35 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
224
192
  filter: 'search',
225
193
  width: 100
226
194
  },
227
- {
228
- type: 'code',
195
+ { type: 'code',
229
196
  name: 'type',
230
197
  header: i18next.t('field.type'),
231
198
  width: 115,
232
199
  sortable: true,
233
200
  filter: true,
234
- record: {
235
- editable: true,
201
+ record: { editable: true,
236
202
  codeName: 'EMPLOYEE_TYPE',
237
203
  selectDispOpt: 'name'
238
204
  }
239
205
  },
240
- {
241
- type: 'department-object',
206
+ { type: 'department-object',
242
207
  name: 'department',
243
208
  header: i18next.t('field.department'),
244
- record: {
245
- editable: true
209
+ record: { editable: true
246
210
  },
247
211
  sortable: false,
248
212
  filter: true,
249
213
  width: 130
250
214
  },
251
- {
252
- type: 'resource-object',
215
+ { type: 'resource-object',
253
216
  name: 'supervisor',
254
217
  header: i18next.t('field.supervisor'),
255
- record: {
256
- editable: true,
257
- options: {
258
- title: i18next.t('title.employee list'),
218
+ record: { editable: true,
219
+ options: { title: i18next.t('title.employee list'),
259
220
  queryName: 'employees',
260
221
  pagination: { pages: [50, 100, 200] },
261
- basicArgs: {
262
- filters: [
263
- {
264
- name: 'active',
222
+ basicArgs: { filters: [
223
+ { name: 'active',
265
224
  operator: 'eq',
266
225
  value: true
267
226
  }
@@ -270,62 +229,52 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
270
229
  list: { fields: ['controlNo', 'name', 'alias', 'hiredOn'] },
271
230
  columns: [
272
231
  { name: 'id', hidden: true },
273
- {
274
- name: 'controlNo',
232
+ { name: 'controlNo',
275
233
  width: 120,
276
234
  header: { renderer: () => i18next.t('field.control-no') },
277
235
  filter: 'search',
278
236
  sortable: true
279
237
  },
280
- {
281
- name: 'name',
238
+ { name: 'name',
282
239
  width: 120,
283
240
  header: { renderer: () => i18next.t('field.name') },
284
241
  filter: 'search',
285
242
  sortable: true
286
243
  },
287
- {
288
- name: 'alias',
244
+ { name: 'alias',
289
245
  width: 150,
290
246
  header: { renderer: () => i18next.t('label.alias') },
291
247
  filter: 'search',
292
248
  sortable: true
293
249
  },
294
- {
295
- type: 'code',
250
+ { type: 'code',
296
251
  name: 'type',
297
252
  width: 110,
298
253
  header: { renderer: () => i18next.t('label.type') },
299
- record: {
300
- editable: false,
254
+ record: { editable: false,
301
255
  codeName: 'EMPLOYEE_TYPE',
302
256
  selectDispOpt: 'name'
303
257
  }
304
258
  },
305
- {
306
- type: 'code',
259
+ { type: 'code',
307
260
  name: 'jobPosition',
308
261
  width: 110,
309
262
  header: { renderer: () => i18next.t('label.job-position') },
310
- record: {
311
- editable: false,
263
+ record: { editable: false,
312
264
  codeName: 'JOB_POSITION',
313
265
  selectDispOpt: 'name'
314
266
  }
315
267
  },
316
- {
317
- type: 'code',
268
+ { type: 'code',
318
269
  name: 'jobResponsibility',
319
270
  width: 200,
320
271
  header: { renderer: () => i18next.t('label.job-responsibility') },
321
- record: {
322
- editable: false,
272
+ record: { editable: false,
323
273
  codeName: 'JOB_RESPONSIBILITY',
324
274
  selectDispOpt: 'name'
325
275
  }
326
276
  },
327
- {
328
- type: 'date',
277
+ { type: 'date',
329
278
  name: 'hiredOn',
330
279
  header: { renderer: () => i18next.t('field.hired-on') },
331
280
  width: 120
@@ -339,142 +288,115 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
339
288
  sortable: false,
340
289
  width: 120
341
290
  },
342
- {
343
- type: 'string',
291
+ { type: 'string',
344
292
  name: 'email',
345
293
  header: i18next.t('field.email'),
346
294
  width: 200,
347
- record: {
348
- editable: false,
295
+ record: { editable: false,
349
296
  renderer: function (value, column, record, rowIndex, field) {
350
297
  return record.contact ? record.contact.email : '';
351
298
  }
352
299
  },
353
300
  sortable: false
354
301
  },
355
- {
356
- type: 'string',
302
+ { type: 'string',
357
303
  name: 'phone',
358
304
  header: i18next.t('field.phone'),
359
305
  width: 130,
360
- record: {
361
- editable: false,
306
+ record: { editable: false,
362
307
  renderer: function (value, column, record, rowIndex, field) {
363
308
  return record.contact ? record.contact.phone : '';
364
309
  }
365
310
  },
366
311
  sortable: false
367
312
  },
368
- {
369
- type: 'code',
313
+ { type: 'code',
370
314
  name: 'jobResponsibility',
371
315
  header: i18next.t('label.job-responsibility'),
372
316
  width: 175,
373
- record: {
374
- editable: true,
317
+ record: { editable: true,
375
318
  codeName: 'JOB_RESPONSIBILITY',
376
319
  selectDispOpt: 'name'
377
320
  },
378
321
  filter: true
379
322
  },
380
- {
381
- type: 'code',
323
+ { type: 'code',
382
324
  name: 'jobPosition',
383
325
  header: i18next.t('label.job-position'),
384
326
  width: 100,
385
- record: {
386
- editable: true,
327
+ record: { editable: true,
387
328
  codeName: 'JOB_POSITION',
388
329
  selectDispOpt: 'name'
389
330
  },
390
331
  filter: true
391
332
  },
392
- {
393
- type: 'date',
333
+ { type: 'date',
394
334
  name: 'hiredOn',
395
335
  header: i18next.t('field.hired-on'),
396
336
  width: 120,
397
- record: {
398
- editable: true
337
+ record: { editable: true
399
338
  },
400
339
  sortable: true
401
340
  },
402
- {
403
- type: 'date',
341
+ { type: 'date',
404
342
  name: 'retiredOn',
405
343
  header: i18next.t('label.retired-at'),
406
344
  width: 120,
407
- record: {
408
- editable: true
345
+ record: { editable: true
409
346
  }
410
347
  },
411
- {
412
- type: 'checkbox',
348
+ { type: 'checkbox',
413
349
  name: 'active',
414
350
  label: true,
415
351
  header: i18next.t('field.active'),
416
352
  width: 70,
417
- record: {
418
- align: 'center',
353
+ record: { align: 'center',
419
354
  editable: true
420
355
  },
421
356
  filter: true,
422
357
  sortable: false
423
358
  },
424
- {
425
- type: 'string',
359
+ { type: 'string',
426
360
  name: 'note',
427
361
  header: i18next.t('field.note'),
428
362
  width: 200,
429
- record: {
430
- editable: true
363
+ record: { editable: true
431
364
  },
432
365
  filter: 'search'
433
366
  },
434
- {
435
- type: 'resource-object',
367
+ { type: 'resource-object',
436
368
  name: 'updater',
437
369
  header: i18next.t('field.updater'),
438
370
  width: 90,
439
371
  sortable: false
440
372
  },
441
- {
442
- type: 'datetime',
373
+ { type: 'datetime',
443
374
  name: 'updatedAt',
444
375
  header: i18next.t('field.updated_at'),
445
376
  width: 180,
446
377
  sortable: true
447
378
  },
448
- {
449
- type: 'resource-object',
379
+ { type: 'resource-object',
450
380
  name: 'contact',
451
381
  hidden: true
452
382
  }
453
383
  ],
454
- rows: {
455
- selectable: {
456
- multiple: true
384
+ rows: { selectable: { multiple: true
457
385
  }
458
386
  },
459
387
  sorters: [
460
- {
461
- name: 'controlNo'
388
+ { name: 'controlNo'
462
389
  }
463
390
  ]
464
391
  };
465
392
  }
466
393
  async pageUpdated(changes, lifecycle) {
467
- if (this.active) {
468
- // do something here when this page just became as active
394
+ if (this.active) { // do something here when this page just became as active
469
395
  }
470
396
  }
471
397
  async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }) {
472
- const response = await client.query({
473
- query: gql `
474
- query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
475
- responses: employees(filters: $filters, pagination: $pagination, sortings: $sortings) {
476
- items {
477
- id
398
+ const response = await client.query({ query: gql `
399
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) { responses: employees(filters: $filters, pagination: $pagination, sortings: $sortings) { items { id
478
400
  controlNo
479
401
  name
480
402
  alias
@@ -484,55 +406,47 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
484
406
  active
485
407
  email
486
408
  phone
487
- user {
488
- id
409
+ user { id
489
410
  name
490
- }
491
- department {
492
- id
411
+ }
412
+ department { id
493
413
  controlNo
494
414
  name
495
415
  description
496
- }
497
- supervisor {
498
- id
416
+ }
417
+ supervisor { id
499
418
  name
500
419
  controlNo
501
- }
420
+ }
502
421
  note
503
422
  hiredOn
504
423
  retiredOn
505
- contact {
506
- id
424
+ contact { id
507
425
  email
508
426
  phone
509
427
  address
510
- }
511
- profile {
512
- left
428
+ }
429
+ profile { left
513
430
  top
514
431
  zoom
515
432
  picture
516
- }
517
- updater {
518
- id
433
+ }
434
+ updater { id
519
435
  name
520
- }
436
+ }
521
437
  updatedAt
522
- }
438
+ }
523
439
  total
524
- }
525
- }
440
+ }
441
+ }
526
442
  `,
527
- variables: {
528
- filters,
443
+ variables: { filters,
529
444
  pagination: { page, limit },
530
445
  sortings
531
446
  }
532
447
  });
533
448
  const records = response.data.responses.items;
534
- return {
535
- total: response.data.responses.total || 0,
449
+ return { total: response.data.responses.total || 0,
536
450
  records
537
451
  };
538
452
  }
@@ -540,20 +454,16 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
540
454
  if (confirm(i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }))) {
541
455
  const ids = this.grist.selected.map(record => record.id);
542
456
  if (ids && ids.length > 0) {
543
- const response = await client.mutate({
544
- mutation: gql `
545
- mutation ($ids: [String!]!) {
546
- deleteEmployees(ids: $ids)
547
- }
457
+ const response = await client.mutate({ mutation: gql `
458
+ mutation ($ids: [String!]!) { deleteEmployees(ids: $ids)
459
+ }
548
460
  `,
549
- variables: {
550
- ids
461
+ variables: { ids
551
462
  }
552
463
  });
553
464
  if (!response.errors) {
554
465
  this.grist.fetch();
555
- notify({
556
- message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
466
+ notify({ message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
557
467
  });
558
468
  }
559
469
  }
@@ -571,16 +481,12 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
571
481
  patchField.cuFlag = patch.__dirty__;
572
482
  return patchField;
573
483
  });
574
- const response = await client.mutate({
575
- mutation: gql `
576
- mutation ($patches: [EmployeePatch!]!) {
577
- updateMultipleEmployee(patches: $patches) {
578
- name
579
- }
580
- }
484
+ const response = await client.mutate({ mutation: gql `
485
+ mutation ($patches: [EmployeePatch!]!) { updateMultipleEmployee(patches: $patches) { name
486
+ }
487
+ }
581
488
  `,
582
- variables: {
583
- patches
489
+ variables: { patches
584
490
  }
585
491
  });
586
492
  if (!response.errors) {
@@ -618,8 +524,7 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
618
524
  this.grist.fetch();
619
525
  }}
620
526
  ></employee-importer>
621
- `, {
622
- backdrop: true,
527
+ `, { backdrop: true,
623
528
  size: 'large',
624
529
  title: i18next.t('title.import employee')
625
530
  });
@@ -642,8 +547,7 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
642
547
  }}
643
548
  detachable
644
549
  ></contact-popup>
645
- `, {
646
- backdrop: true,
550
+ `, { backdrop: true,
647
551
  size: 'large',
648
552
  title: i18next.t('title.contact')
649
553
  });
@@ -651,34 +555,27 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
651
555
  async openContactSelector(record) {
652
556
  const popup = openPopup(html `
653
557
  <contact-selector .confirmCallback=${selected => this.attachContact(record, selected)}></contact-selector>
654
- `, {
655
- backdrop: true,
558
+ `, { backdrop: true,
656
559
  size: 'large',
657
560
  title: i18next.t('title.contact')
658
561
  });
659
562
  }
660
563
  async attachContact(record, contact) {
661
564
  if (record.id) {
662
- const response = await client.mutate({
663
- mutation: gql `
664
- mutation ($id: String!, $contactId: String!) {
665
- attachContact(id: $id, contactId: $contactId) {
666
- id
667
- }
668
- }
565
+ const response = await client.mutate({ mutation: gql `
566
+ mutation ($id: String!, $contactId: String!) { attachContact(id: $id, contactId: $contactId) { id
567
+ }
568
+ }
669
569
  `,
670
- variables: {
671
- id: record.id,
570
+ variables: { id: record.id,
672
571
  contactId: contact.id
673
572
  }
674
573
  });
675
574
  this.grist.fetch();
676
575
  }
677
576
  else if (contact?.id) {
678
- this.grist.addRecord({
679
- name: contact.name,
680
- contact: {
681
- id: contact.id,
577
+ this.grist.addRecord({ name: contact.name,
578
+ contact: { id: contact.id,
682
579
  name: contact.name,
683
580
  email: contact.email,
684
581
  phone: contact.phone,
@@ -692,16 +589,12 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
692
589
  }
693
590
  async detachContact(record) {
694
591
  if (record.id) {
695
- const response = await client.mutate({
696
- mutation: gql `
697
- mutation ($id: String!) {
698
- detachContact(id: $id) {
699
- id
700
- }
701
- }
592
+ const response = await client.mutate({ mutation: gql `
593
+ mutation ($id: String!) { detachContact(id: $id) { id
594
+ }
595
+ }
702
596
  `,
703
- variables: {
704
- id: record.id
597
+ variables: { id: record.id
705
598
  }
706
599
  });
707
600
  this.grist.fetch();
@@ -713,14 +606,11 @@ let EmployeeListPage = class EmployeeListPage extends connect(store)(p13n(locali
713
606
  }
714
607
  async attachSystemUser(record) {
715
608
  if (!record.user) {
716
- await client.mutate({
717
- mutation: gql `
718
- mutation ($employeeId: String!) {
719
- registerEmployeeAsSystemUser(employeeId: $employeeId)
720
- }
609
+ await client.mutate({ mutation: gql `
610
+ mutation ($employeeId: String!) { registerEmployeeAsSystemUser(employeeId: $employeeId)
611
+ }
721
612
  `,
722
- variables: {
723
- employeeId: record.id
613
+ variables: { employeeId: record.id
724
614
  }
725
615
  });
726
616
  }