@things-factory/organization 8.0.0-beta.8 → 8.0.0

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 (94) hide show
  1. package/client/bootstrap.ts +23 -0
  2. package/client/component/approval-line-brief.ts +119 -0
  3. package/client/component/approval-line-items-editor-popup.ts +91 -0
  4. package/client/component/approval-line-items-editor.ts +325 -0
  5. package/client/component/approval-line-selector.ts +235 -0
  6. package/client/component/approval-line-templates-manager.ts +229 -0
  7. package/client/component/approval-line-view.ts +122 -0
  8. package/client/component/assignees-editor-popup.ts +79 -0
  9. package/client/component/assignees-editor.ts +217 -0
  10. package/client/component/assignees-view.ts +55 -0
  11. package/client/component/department-selector.ts +151 -0
  12. package/client/component/department-view.ts +107 -0
  13. package/client/component/index.ts +16 -0
  14. package/client/component/recipients-editor-popup.ts +79 -0
  15. package/client/component/recipients-editor.ts +212 -0
  16. package/client/component/recipients-view.ts +55 -0
  17. package/client/grist-editor/grist-editor-approval-line.ts +70 -0
  18. package/client/grist-editor/grist-editor-assignees.ts +69 -0
  19. package/client/grist-editor/grist-editor-department-object.ts +78 -0
  20. package/client/grist-editor/grist-editor-recipients.ts +69 -0
  21. package/client/grist-editor/grist-renderer-approval-line.ts +13 -0
  22. package/client/grist-editor/grist-renderer-assignees.ts +13 -0
  23. package/client/grist-editor/grist-renderer-department-object.ts +13 -0
  24. package/client/grist-editor/grist-renderer-recipients.ts +13 -0
  25. package/client/index.ts +2 -0
  26. package/client/pages/approval-line/common-approval-line-templates-page.ts +382 -0
  27. package/client/pages/approval-line/my-approval-line-templates-page.ts +385 -0
  28. package/client/pages/department/department-importer.ts +87 -0
  29. package/client/pages/department/department-list-page.ts +450 -0
  30. package/client/pages/department/department-tree-page.ts +379 -0
  31. package/client/pages/employee/employee-importer.ts +87 -0
  32. package/client/pages/employee/employee-list-page.ts +772 -0
  33. package/client/pages/employee/employees-by-department.ts +519 -0
  34. package/client/route.ts +27 -0
  35. package/client/tsconfig.json +13 -0
  36. package/client/types/approval-line.ts +52 -0
  37. package/client/types/contact.ts +51 -0
  38. package/client/types/department.ts +29 -0
  39. package/client/types/employee.ts +50 -0
  40. package/client/types/index.ts +5 -0
  41. package/client/types/org-member.ts +27 -0
  42. package/dist-client/bootstrap.js +1 -8
  43. package/dist-client/bootstrap.js.map +1 -1
  44. package/dist-client/pages/employee/employee-list-page.js +3 -3
  45. package/dist-client/pages/employee/employee-list-page.js.map +1 -1
  46. package/dist-client/pages/employee/employees-by-department.js +2 -2
  47. package/dist-client/pages/employee/employees-by-department.js.map +1 -1
  48. package/dist-client/tsconfig.tsbuildinfo +1 -1
  49. package/dist-server/service/employee/employee-history.d.ts +2 -6
  50. package/dist-server/service/employee/employee-history.js +3 -23
  51. package/dist-server/service/employee/employee-history.js.map +1 -1
  52. package/dist-server/service/employee/employee-query.js +1 -1
  53. package/dist-server/service/employee/employee-query.js.map +1 -1
  54. package/dist-server/service/employee/employee-type.d.ts +5 -13
  55. package/dist-server/service/employee/employee-type.js +7 -39
  56. package/dist-server/service/employee/employee-type.js.map +1 -1
  57. package/dist-server/service/employee/employee.d.ts +2 -6
  58. package/dist-server/service/employee/employee.js +3 -23
  59. package/dist-server/service/employee/employee.js.map +1 -1
  60. package/dist-server/tsconfig.tsbuildinfo +1 -1
  61. package/package.json +12 -12
  62. package/server/controllers/register-employee-as-system-user.ts +136 -0
  63. package/server/index.ts +3 -0
  64. package/server/migrations/1723861013111-seed-organization-codes.ts +127 -0
  65. package/server/migrations/index.ts +9 -0
  66. package/server/routes.ts +26 -0
  67. package/server/service/approval-line/approval-line-item.ts +42 -0
  68. package/server/service/approval-line/approval-line-mutation.ts +394 -0
  69. package/server/service/approval-line/approval-line-query.ts +208 -0
  70. package/server/service/approval-line/approval-line-type.ts +63 -0
  71. package/server/service/approval-line/approval-line.ts +123 -0
  72. package/server/service/approval-line/index.ts +7 -0
  73. package/server/service/department/department-history.ts +141 -0
  74. package/server/service/department/department-mutation.ts +231 -0
  75. package/server/service/department/department-query.ts +131 -0
  76. package/server/service/department/department-type.ts +74 -0
  77. package/server/service/department/department.ts +116 -0
  78. package/server/service/department/event-subscriber.ts +17 -0
  79. package/server/service/department/index.ts +9 -0
  80. package/server/service/employee/employee-history.ts +173 -0
  81. package/server/service/employee/employee-mutation.ts +386 -0
  82. package/server/service/employee/employee-query.ts +172 -0
  83. package/server/service/employee/employee-type.ts +176 -0
  84. package/server/service/employee/employee.ts +177 -0
  85. package/server/service/employee/event-subscriber.ts +17 -0
  86. package/server/service/employee/index.ts +9 -0
  87. package/server/service/index.ts +39 -0
  88. package/server/tsconfig.json +10 -0
  89. package/dist-client/filters-form/filter-department-object.d.ts +0 -3
  90. package/dist-client/filters-form/filter-department-object.js +0 -8
  91. package/dist-client/filters-form/filter-department-object.js.map +0 -1
  92. package/dist-client/filters-form/ox-filter-department-object.d.ts +0 -15
  93. package/dist-client/filters-form/ox-filter-department-object.js +0 -130
  94. package/dist-client/filters-form/ox-filter-department-object.js.map +0 -1
@@ -0,0 +1,382 @@
1
+ import '@operato/data-grist'
2
+ import '@operato/context/ox-context-page-toolbar.js'
3
+ import '../../component/approval-line-items-editor-popup'
4
+
5
+ import { CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'
6
+ import { PageView, store } from '@operato/shell'
7
+ import { css, html } from 'lit'
8
+
9
+ import { customElement, property, query } from 'lit/decorators.js'
10
+ import { ScopedElementsMixin } from '@open-wc/scoped-elements'
11
+ import { getRenderer, DataGrist, FetchOption } from '@operato/data-grist'
12
+ import { client } from '@operato/graphql'
13
+ import { i18next, localize } from '@operato/i18n'
14
+ import { notify, openPopup } from '@operato/layout'
15
+ import { adjustFilters, isMobileDevice } from '@operato/utils'
16
+
17
+ import { connect } from 'pwa-helpers/connect-mixin'
18
+ import gql from 'graphql-tag'
19
+
20
+ @customElement('common-approval-line-templates-page')
21
+ export class CommonApprovalLineTemplatesPage extends connect(store)(localize(i18next)(ScopedElementsMixin(PageView))) {
22
+ static styles = [
23
+ ScrollbarStyles,
24
+ CommonHeaderStyles,
25
+ css`
26
+ :host {
27
+ display: flex;
28
+
29
+ width: 100%;
30
+
31
+ --grid-record-emphasized-background-color: #8b0000;
32
+ --grid-record-emphasized-color: #ff6b6b;
33
+ }
34
+
35
+ ox-grist {
36
+ flex: 1;
37
+ }
38
+
39
+ .header {
40
+ grid-template-areas: 'filters actions';
41
+ }
42
+ `
43
+ ]
44
+
45
+ @property({ type: Object }) gristConfig: any
46
+ @property({ type: String }) mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'CARD' : 'GRID'
47
+
48
+ @query('ox-grist') private grist!: DataGrist
49
+
50
+ get context() {
51
+ return {
52
+ title: i18next.t('title.common-approval-line template list'),
53
+ search: {
54
+ handler: (search: string) => {
55
+ this.grist.searchText = search
56
+ },
57
+ value: this.grist?.searchText || ''
58
+ },
59
+ filter: {
60
+ handler: () => {
61
+ this.grist.toggleHeadroom()
62
+ }
63
+ },
64
+ help: 'organization/approval-line',
65
+ actions: [
66
+ {
67
+ icon: 'save',
68
+ title: i18next.t('button.save'),
69
+ action: this.updateApprovalLines.bind(this)
70
+ },
71
+ {
72
+ icon: 'delete',
73
+ title: i18next.t('button.delete'),
74
+ action: this.deleteApprovalLines.bind(this),
75
+ emphasis: {
76
+ danger: true
77
+ }
78
+ }
79
+ ],
80
+ toolbar: false
81
+ }
82
+ }
83
+
84
+ render() {
85
+ const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID')
86
+
87
+ return html`
88
+ <ox-grist .mode=${mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>
89
+ <div slot="headroom" class="header">
90
+ <ox-context-page-toolbar class="actions" .context=${this.context}></ox-context-page-toolbar>
91
+ </div>
92
+ </ox-grist>
93
+ `
94
+ }
95
+
96
+ async pageInitialized(lifecycle: any) {
97
+ this.gristConfig = {
98
+ list: {
99
+ fields: ['name', 'description'],
100
+ details: ['updatedAt']
101
+ },
102
+ columns: [
103
+ { type: 'gutter', gutterName: 'sequence', fixed: true },
104
+ { type: 'gutter', gutterName: 'row-selector', fixed: true, multiple: true },
105
+ {
106
+ type: 'gutter',
107
+ gutterName: 'button',
108
+ fixed: true,
109
+ icon: record => (!record ? 'reorder' : record.id ? 'reorder' : ''),
110
+ iconOnly: false,
111
+ title: record => (!record ? i18next.t('button.edit') : record.id ? i18next.t('button.edit') : ''),
112
+ width: 72,
113
+ handlers: {
114
+ click: (columns, data, column, record, rowIndex) => {
115
+ if (!record.id) {
116
+ return
117
+ }
118
+
119
+ const { id, model } = record
120
+ const popup = openPopup(
121
+ html`
122
+ <approval-line-items-editor-popup
123
+ .confirmCallback=${async model => {
124
+ await this.updateApprovalLine(id, model)
125
+ await this.grist.fetch()
126
+ }}
127
+ .value=${model}
128
+ ></approval-line-items-editor-popup>
129
+ `,
130
+ {
131
+ backdrop: true,
132
+ help: 'organization/approval-line-items-editor',
133
+ size: 'large',
134
+ title: i18next.t('title.approval-line item list')
135
+ }
136
+ )
137
+ popup.onclosed = () => {
138
+ this.grist?.fetch()
139
+ }
140
+ }
141
+ }
142
+ },
143
+ {
144
+ type: 'string',
145
+ name: 'name',
146
+ fixed: true,
147
+ header: i18next.t('field.name'),
148
+ record: {
149
+ editable: true
150
+ },
151
+ filter: 'search',
152
+ sortable: true,
153
+ width: 300
154
+ },
155
+ {
156
+ type: 'string',
157
+ name: 'description',
158
+ header: i18next.t('field.description'),
159
+ record: {
160
+ editable: true
161
+ },
162
+ filter: 'search',
163
+ width: 325
164
+ },
165
+ {
166
+ type: 'string',
167
+ name: 'ownerType',
168
+ header: i18next.t('field.owner-type'),
169
+ width: 120
170
+ },
171
+ {
172
+ type: 'resource-object',
173
+ name: 'owner',
174
+ header: i18next.t('field.owner'),
175
+ record: {
176
+ editable: false,
177
+ renderer: function (value, column, record, rowIndex, field) {
178
+ var options = {}
179
+ switch (record.ownerType) {
180
+ case 'Employee':
181
+ options = {
182
+ valueField: 'id',
183
+ nameField: 'name',
184
+ descriptionField: 'controlNo'
185
+ }
186
+ break
187
+ case 'Common':
188
+ default:
189
+ return
190
+ }
191
+
192
+ var dynamicRecord = { ...column.record, options }
193
+
194
+ return getRenderer(column.type)(value, { ...column, record: dynamicRecord }, record, rowIndex, field)
195
+ }
196
+ },
197
+ width: 180
198
+ },
199
+ {
200
+ type: 'resource-object',
201
+ name: 'updater',
202
+ header: i18next.t('field.updater'),
203
+ sortable: true,
204
+ width: 90
205
+ },
206
+ {
207
+ type: 'datetime',
208
+ name: 'updatedAt',
209
+ header: i18next.t('field.updated_at'),
210
+ sortable: true,
211
+ width: 180
212
+ }
213
+ ],
214
+ rows: {
215
+ selectable: {
216
+ multiple: true
217
+ }
218
+ },
219
+ sorters: [
220
+ {
221
+ name: 'name'
222
+ }
223
+ ]
224
+ }
225
+ }
226
+
227
+ async pageUpdated(changes: any, lifecycle: any) {
228
+ if (this.active) {
229
+ // do something here when this page just became as active
230
+ }
231
+ }
232
+
233
+ async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) {
234
+ const response = await client.query({
235
+ query: gql`
236
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
237
+ responses: approvalLines(filters: $filters, pagination: $pagination, sortings: $sortings) {
238
+ items {
239
+ id
240
+ name
241
+ description
242
+ ownerType
243
+ owner {
244
+ id
245
+ name
246
+ description
247
+ controlNo
248
+ }
249
+ model {
250
+ type
251
+ approver {
252
+ id
253
+ name
254
+ description
255
+ controlNo
256
+ }
257
+ }
258
+ updater {
259
+ id
260
+ name
261
+ }
262
+ updatedAt
263
+ }
264
+ total
265
+ }
266
+ }
267
+ `,
268
+ variables: {
269
+ filters: adjustFilters(filters, [{ name: 'ownerType', operator: 'eq', value: 'Common' }]),
270
+ pagination: { page, limit },
271
+ sortings
272
+ }
273
+ })
274
+
275
+ return {
276
+ total: response.data.responses.total || 0,
277
+ records: response.data.responses.items || []
278
+ }
279
+ }
280
+
281
+ async deleteApprovalLines() {
282
+ if (confirm(i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }))) {
283
+ const ids = this.grist.selected.map(record => record.id)
284
+ if (ids && ids.length > 0) {
285
+ const response = await client.mutate({
286
+ mutation: gql`
287
+ mutation ($ids: [String!]!) {
288
+ deleteApprovalLines(ids: $ids)
289
+ }
290
+ `,
291
+ variables: {
292
+ ids
293
+ }
294
+ })
295
+
296
+ if (!response.errors) {
297
+ this.grist.fetch()
298
+ notify({
299
+ message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
300
+ })
301
+ }
302
+ }
303
+ }
304
+ }
305
+
306
+ async updateApprovalLines() {
307
+ let patches = this.grist.dirtyRecords
308
+ if (patches && patches.length) {
309
+ patches = patches.map(patch => {
310
+ let patchField: any = patch.id ? { id: patch.id } : {}
311
+ const dirtyFields = patch.__dirtyfields__
312
+ for (let key in dirtyFields) {
313
+ patchField[key] = dirtyFields[key].after
314
+ }
315
+
316
+ patchField['ownerType'] = 'Common'
317
+ patchField['owner'] = null
318
+
319
+ patchField.cuFlag = patch.__dirty__
320
+
321
+ return patchField
322
+ })
323
+
324
+ const response = await client.mutate({
325
+ mutation: gql`
326
+ mutation ($patches: [ApprovalLinePatch!]!) {
327
+ updateMultipleApprovalLine(patches: $patches) {
328
+ name
329
+ }
330
+ }
331
+ `,
332
+ variables: {
333
+ patches
334
+ }
335
+ })
336
+
337
+ if (!response.errors) {
338
+ this.grist.fetch()
339
+ }
340
+ }
341
+ }
342
+
343
+ async updateApprovalLine(id, model) {
344
+ const response = await client.mutate({
345
+ mutation: gql`
346
+ mutation ($id: String!, $patch: ApprovalLinePatch!) {
347
+ updateApprovalLine(id: $id, patch: $patch) {
348
+ id
349
+ name
350
+ model {
351
+ type
352
+ approver {
353
+ id
354
+ name
355
+ description
356
+ controlNo
357
+ }
358
+ }
359
+ }
360
+ }
361
+ `,
362
+ variables: {
363
+ id,
364
+ patch: {
365
+ model,
366
+ cuFlag: 'M'
367
+ }
368
+ }
369
+ })
370
+ if (!response.errors) {
371
+ await document.dispatchEvent(
372
+ new CustomEvent('notify', {
373
+ detail: {
374
+ message: i18next.t('text.info_x_successfully', {
375
+ x: i18next.t('button.save')
376
+ })
377
+ }
378
+ })
379
+ )
380
+ }
381
+ }
382
+ }