@things-factory/worklist 6.0.28 → 6.0.33

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 (127) hide show
  1. package/client/pages/activity/activity-list-page.ts +126 -3
  2. package/client/pages/activity/activity-partial-view.ts +3 -0
  3. package/client/pages/activity-approval/activity-approval-page.ts +6 -6
  4. package/client/pages/activity-template/activity-template-list-page.ts +30 -0
  5. package/client/pages/activity-thread/activity-thread-view-page.ts +293 -0
  6. package/client/pages/installable-activity/installable-activity-list-page.ts +30 -0
  7. package/client/pages/todo/approval-waiting-list-page.ts +7 -7
  8. package/client/pages/todo/done-list-page.ts +344 -0
  9. package/client/pages/todo/todo-list-page.ts +3 -4
  10. package/client/route.ts +8 -0
  11. package/client/types/activity.ts +6 -0
  12. package/dist-client/components/activity-search-keys-input.d.ts +17 -0
  13. package/dist-client/components/activity-search-keys-input.js +173 -0
  14. package/dist-client/components/activity-search-keys-input.js.map +1 -0
  15. package/dist-client/components/grist-editor-activity-search-key.d.ts +12 -0
  16. package/dist-client/components/grist-editor-activity-search-key.js +70 -0
  17. package/dist-client/components/grist-editor-activity-search-key.js.map +1 -0
  18. package/dist-client/components/popup-activity-search-keys-input.d.ts +17 -0
  19. package/dist-client/components/popup-activity-search-keys-input.js +177 -0
  20. package/dist-client/components/popup-activity-search-keys-input.js.map +1 -0
  21. package/dist-client/pages/activity/activity-list-page.d.ts +3 -1
  22. package/dist-client/pages/activity/activity-list-page.js +121 -3
  23. package/dist-client/pages/activity/activity-list-page.js.map +1 -1
  24. package/dist-client/pages/activity/activity-partial-view.js +1 -1
  25. package/dist-client/pages/activity/activity-partial-view.js.map +1 -1
  26. package/dist-client/pages/activity-approval/activity-approval-page.js +6 -6
  27. package/dist-client/pages/activity-approval/activity-approval-page.js.map +1 -1
  28. package/dist-client/pages/activity-template/activity-template-list-page.js +30 -0
  29. package/dist-client/pages/activity-template/activity-template-list-page.js.map +1 -1
  30. package/dist-client/pages/activity-thread/activity-thread-view-page.d.ts +43 -0
  31. package/dist-client/pages/activity-thread/activity-thread-view-page.js +268 -0
  32. package/dist-client/pages/activity-thread/activity-thread-view-page.js.map +1 -0
  33. package/dist-client/pages/installable-activity/installable-activity-list-page.js +30 -0
  34. package/dist-client/pages/installable-activity/installable-activity-list-page.js.map +1 -1
  35. package/dist-client/pages/todo/approval-waiting-list-page.js +7 -7
  36. package/dist-client/pages/todo/approval-waiting-list-page.js.map +1 -1
  37. package/dist-client/pages/todo/done-list-page.d.ts +44 -0
  38. package/dist-client/pages/todo/done-list-page.js +342 -0
  39. package/dist-client/pages/todo/done-list-page.js.map +1 -0
  40. package/dist-client/pages/todo/todo-list-page.js +3 -4
  41. package/dist-client/pages/todo/todo-list-page.js.map +1 -1
  42. package/dist-client/route.d.ts +1 -1
  43. package/dist-client/route.js +6 -0
  44. package/dist-client/route.js.map +1 -1
  45. package/dist-client/tsconfig.tsbuildinfo +1 -1
  46. package/dist-client/types/activity.d.ts +3 -0
  47. package/dist-client/types/activity.js.map +1 -1
  48. package/dist-client/types/domain.d.ts +16 -0
  49. package/dist-client/types/domain.js +3 -0
  50. package/dist-client/types/domain.js.map +1 -0
  51. package/dist-client/types/privilege.d.ts +16 -0
  52. package/dist-client/types/privilege.js +3 -0
  53. package/dist-client/types/privilege.js.map +1 -0
  54. package/dist-client/types/role.d.ts +19 -0
  55. package/dist-client/types/role.js +3 -0
  56. package/dist-client/types/role.js.map +1 -0
  57. package/dist-client/types/user.d.ts +18 -0
  58. package/dist-client/types/user.js +12 -0
  59. package/dist-client/types/user.js.map +1 -0
  60. package/dist-client/types.d.ts +10 -4
  61. package/dist-client/types.js.map +1 -1
  62. package/dist-server/controllers/activity-instance/draft.js +1 -1
  63. package/dist-server/controllers/activity-instance/draft.js.map +1 -1
  64. package/dist-server/controllers/activity-instance/post.js +9 -5
  65. package/dist-server/controllers/activity-instance/post.js.map +1 -1
  66. package/dist-server/controllers/common.js +14 -3
  67. package/dist-server/controllers/common.js.map +1 -1
  68. package/dist-server/routes.js +30 -0
  69. package/dist-server/routes.js.map +1 -1
  70. package/dist-server/service/activity/activity-history.js +28 -1
  71. package/dist-server/service/activity/activity-history.js.map +1 -1
  72. package/dist-server/service/activity/activity-mutation.js +92 -0
  73. package/dist-server/service/activity/activity-mutation.js.map +1 -1
  74. package/dist-server/service/activity/activity-type.js +32 -0
  75. package/dist-server/service/activity/activity-type.js.map +1 -1
  76. package/dist-server/service/activity/activity.js +23 -5
  77. package/dist-server/service/activity/activity.js.map +1 -1
  78. package/dist-server/service/activity-approval/event-subscriber.js.map +1 -1
  79. package/dist-server/service/activity-instance/activity-instance-type.js +16 -0
  80. package/dist-server/service/activity-instance/activity-instance-type.js.map +1 -1
  81. package/dist-server/service/activity-instance/activity-instance.js +10 -0
  82. package/dist-server/service/activity-instance/activity-instance.js.map +1 -1
  83. package/dist-server/service/activity-key-set/activity-key-item-type.js +50 -0
  84. package/dist-server/service/activity-key-set/activity-key-item-type.js.map +1 -0
  85. package/dist-server/service/activity-key-set/activity-key-set-mutation.js +127 -0
  86. package/dist-server/service/activity-key-set/activity-key-set-mutation.js.map +1 -0
  87. package/dist-server/service/activity-key-set/activity-key-set-query.js +97 -0
  88. package/dist-server/service/activity-key-set/activity-key-set-query.js.map +1 -0
  89. package/dist-server/service/activity-key-set/activity-key-set-type.js +74 -0
  90. package/dist-server/service/activity-key-set/activity-key-set-type.js.map +1 -0
  91. package/dist-server/service/activity-key-set/activity-key-set.js +86 -0
  92. package/dist-server/service/activity-key-set/activity-key-set.js.map +1 -0
  93. package/dist-server/service/activity-key-set/index.js +9 -0
  94. package/dist-server/service/activity-key-set/index.js.map +1 -0
  95. package/dist-server/service/activity-template/activity-template-type.js +16 -0
  96. package/dist-server/service/activity-template/activity-template-type.js.map +1 -1
  97. package/dist-server/service/activity-template/activity-template.js +10 -0
  98. package/dist-server/service/activity-template/activity-template.js.map +1 -1
  99. package/dist-server/service/activity-thread/activity-thread-query.js +27 -0
  100. package/dist-server/service/activity-thread/activity-thread-query.js.map +1 -1
  101. package/dist-server/service/installable-activity/installable-activity.js +8 -0
  102. package/dist-server/service/installable-activity/installable-activity.js.map +1 -1
  103. package/dist-server/tsconfig.tsbuildinfo +1 -1
  104. package/package.json +10 -8
  105. package/server/controllers/activity-instance/draft.ts +2 -0
  106. package/server/controllers/activity-instance/post.ts +11 -5
  107. package/server/controllers/common.ts +4 -0
  108. package/server/routes.ts +47 -0
  109. package/server/service/activity/activity-history.ts +23 -1
  110. package/server/service/activity/activity-mutation.ts +102 -0
  111. package/server/service/activity/activity-type.ts +24 -0
  112. package/server/service/activity/activity.ts +19 -5
  113. package/server/service/activity-approval/event-subscriber.ts +1 -1
  114. package/server/service/activity-instance/activity-instance-type.ts +12 -0
  115. package/server/service/activity-instance/activity-instance.ts +8 -0
  116. package/server/service/activity-template/activity-template-type.ts +12 -0
  117. package/server/service/activity-template/activity-template.ts +8 -0
  118. package/server/service/activity-thread/activity-thread-query.ts +24 -0
  119. package/server/service/installable-activity/installable-activity.ts +6 -0
  120. package/things-factory.config.js +2 -0
  121. package/translations/en.json +5 -0
  122. package/translations/ko.json +5 -0
  123. package/translations/ms.json +5 -0
  124. package/translations/zh.json +5 -0
  125. package/client/pages/activity-thread/activity-thread-view.ts +0 -102
  126. package/dist-server/controllers/activity-extension-controller.js +0 -11
  127. package/dist-server/controllers/activity-extension-controller.js.map +0 -1
@@ -5,11 +5,12 @@ import gql from 'graphql-tag'
5
5
  import { css, html } from 'lit'
6
6
  import { customElement, property, query } from 'lit/decorators.js'
7
7
  import { connect } from 'pwa-helpers/connect-mixin.js'
8
+ import moment from 'moment-timezone'
8
9
 
9
10
  import { DataGrist, getEditor, getRenderer } from '@operato/data-grist'
10
11
  import { client } from '@operato/graphql'
11
12
  import { i18next, localize } from '@operato/i18n'
12
- import { openPopup } from '@operato/layout'
13
+ import { notify, openPopup } from '@operato/layout'
13
14
  import { PageView, store } from '@operato/shell'
14
15
  import { CommonButtonStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles'
15
16
  import { isMobileDevice } from '@operato/utils'
@@ -22,6 +23,8 @@ export const ActivityStatus = [
22
23
  { display: 'Released', value: 'released' },
23
24
  { display: 'Deprecated', value: 'deprecated' }
24
25
  ]
26
+ const DEFAULT_TZ = Intl.DateTimeFormat().resolvedOptions().timeZone
27
+ const TIMEZONE_OPTIONS = ['', DEFAULT_TZ, ...moment.tz.names().filter(tz => tz !== DEFAULT_TZ)]
25
28
 
26
29
  @customElement('activity-list-page')
27
30
  export class ActivityListPage extends connect(store)(localize(i18next)(PageView)) {
@@ -64,7 +67,7 @@ export class ActivityListPage extends connect(store)(localize(i18next)(PageView)
64
67
  actions: [
65
68
  {
66
69
  title: i18next.t('button.save'),
67
- action: this._updateActivity.bind(this),
70
+ action: this.updateActivity.bind(this),
68
71
  ...CommonButtonStyles.save
69
72
  }
70
73
  ]
@@ -117,6 +120,24 @@ export class ActivityListPage extends connect(store)(localize(i18next)(PageView)
117
120
  columns: [
118
121
  { type: 'gutter', gutterName: 'sequence' },
119
122
  { type: 'gutter', gutterName: 'row-selector', multiple: true },
123
+ {
124
+ type: 'gutter',
125
+ gutterName: 'button',
126
+ icon: record => (!record || !record.name ? '' : record.scheduleId ? 'pause' : 'play_arrow'),
127
+ handlers: {
128
+ click: (columns, data, column, record, rowIndex) => {
129
+ if (!record || !record.name) {
130
+ /* TODO record가 새로 추가된 것이면 리턴하도록 한다. */
131
+ return
132
+ }
133
+ if (record.scheduleId) {
134
+ this.stopActivitySchedule(record)
135
+ } else {
136
+ this.startActivitySchedule(record)
137
+ }
138
+ }
139
+ }
140
+ },
120
141
  {
121
142
  type: 'gutter',
122
143
  gutterName: 'button',
@@ -226,6 +247,22 @@ export class ActivityListPage extends connect(store)(localize(i18next)(PageView)
226
247
  },
227
248
  width: 80
228
249
  },
250
+ {
251
+ type: 'select',
252
+ name: 'timezone',
253
+ header: i18next.t('field.timezone'),
254
+ record: {
255
+ editable: true,
256
+ options: TIMEZONE_OPTIONS
257
+ },
258
+ width: 120,
259
+ imex: {
260
+ width: 13,
261
+ header: i18next.t('field.timezone'),
262
+ type: 'select',
263
+ key: 'timezone'
264
+ }
265
+ },
229
266
  {
230
267
  type: 'image',
231
268
  name: 'thumbnail',
@@ -321,6 +358,34 @@ export class ActivityListPage extends connect(store)(localize(i18next)(PageView)
321
358
  },
322
359
  width: 140
323
360
  },
361
+ {
362
+ type: 'select',
363
+ name: 'viewType',
364
+ label: true,
365
+ header: i18next.t('field.view-type'),
366
+ record: {
367
+ editable: true,
368
+ options: ActivityUITypes
369
+ },
370
+ width: 80
371
+ },
372
+ {
373
+ type: 'string',
374
+ name: 'viewSource',
375
+ header: i18next.t('field.view-source'),
376
+ record: {
377
+ editable: true,
378
+ editor: function (value, column, record, rowIndex, field) {
379
+ var type = record.viewType !== 'board' ? 'script' : 'board'
380
+ return getEditor(type)(value, column, record, rowIndex, field)
381
+ },
382
+ renderer: function (value, column, record, rowIndex, field) {
383
+ var type = record.viewType !== 'board' ? 'script' : 'board'
384
+ return getRenderer(type)(value, column, record, rowIndex, field)
385
+ }
386
+ },
387
+ width: 140
388
+ },
324
389
  {
325
390
  type: 'select',
326
391
  name: 'reportType',
@@ -491,10 +556,14 @@ export class ActivityListPage extends connect(store)(localize(i18next)(PageView)
491
556
  }
492
557
  uiType
493
558
  uiSource
559
+ viewType
560
+ viewSource
494
561
  reportType
495
562
  reportSource
496
563
  startable
497
564
  schedule
565
+ timezone
566
+ scheduleId
498
567
  standardTime
499
568
  leadTime
500
569
  cycleTime
@@ -522,7 +591,7 @@ export class ActivityListPage extends connect(store)(localize(i18next)(PageView)
522
591
  }
523
592
  }
524
593
 
525
- async _updateActivity() {
594
+ async updateActivity() {
526
595
  let patches = this.grist?.dirtyRecords
527
596
  if (patches && patches.length) {
528
597
  patches = patches.map(patch => {
@@ -557,4 +626,58 @@ export class ActivityListPage extends connect(store)(localize(i18next)(PageView)
557
626
  }
558
627
  }
559
628
  }
629
+
630
+ async startActivitySchedule(record) {
631
+ var response = await client.mutate({
632
+ mutation: gql`
633
+ mutation ($activityId: String!) {
634
+ startActivitySchedule(activityId: $activityId) {
635
+ scheduleId
636
+ }
637
+ }
638
+ `,
639
+ variables: {
640
+ activityId: record.id
641
+ }
642
+ })
643
+
644
+ const scheduleId = response.data.startActivitySchedule.scheduleId
645
+ record.scheduleId = scheduleId
646
+
647
+ notify({
648
+ level: 'info',
649
+ message: `${record.scheduleId ? 'success' : 'fail'} to start activity schedule : ${record.name}`
650
+ })
651
+
652
+ this.grist.fetch()
653
+ }
654
+
655
+ async stopActivitySchedule(record) {
656
+ var response = await client.mutate({
657
+ mutation: gql`
658
+ mutation ($activityId: String!) {
659
+ stopActivitySchedule(activityId: $activityId) {
660
+ scheduleId
661
+ }
662
+ }
663
+ `,
664
+ variables: {
665
+ activityId: record.id
666
+ }
667
+ })
668
+
669
+ if (!response.errors) {
670
+ notify({
671
+ level: 'info',
672
+ message: `success to stop activity schedule : ${record.name}`
673
+ })
674
+ } else {
675
+ notify({
676
+ level: 'error',
677
+ message: `${response.errors.map(error => error.message).join('\n')}`
678
+ })
679
+ }
680
+
681
+ this.grist.fetch()
682
+ }
560
683
  }
@@ -46,6 +46,7 @@ export class ActivityView extends localize(i18next)(LitElement) {
46
46
  priority,
47
47
  startable,
48
48
  schedule,
49
+ timzeone,
49
50
  standardTime,
50
51
  cycleTime,
51
52
  tactTime,
@@ -57,6 +58,8 @@ export class ActivityView extends localize(i18next)(LitElement) {
57
58
  approvalLine,
58
59
  uiType,
59
60
  uiSource,
61
+ viewType,
62
+ viewSource,
60
63
  reportType,
61
64
  reportSource
62
65
  } = this.activity
@@ -67,8 +67,8 @@ const ActivityApprovalFetchResult = `\
67
67
  thumbnail
68
68
  input
69
69
  output
70
- uiType
71
- uiSource
70
+ viewType
71
+ viewSource
72
72
  dueAt
73
73
  createdAt
74
74
  }
@@ -181,7 +181,7 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
181
181
  }
182
182
 
183
183
  activityContent() {
184
- switch (this.activityThread?.activityInstance?.uiType) {
184
+ switch (this.activityThread?.activityInstance?.viewType) {
185
185
  case 'template':
186
186
  return this.templateContent()
187
187
  case 'generated':
@@ -198,7 +198,7 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
198
198
  }
199
199
 
200
200
  templateContent() {
201
- const { uiSource: template } = this.activityThread?.activityInstance
201
+ const { viewSource: template } = this.activityThread?.activityInstance
202
202
  return unsafeHTML(template)
203
203
  }
204
204
 
@@ -271,7 +271,7 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
271
271
 
272
272
  boardContent() {
273
273
  const { output, activityInstance } = this.activityThread
274
- const { uiSource: boardId, input } = activityInstance || {}
274
+ const { viewSource: boardId, input } = activityInstance || {}
275
275
 
276
276
  if (!this.board || this.board.id !== boardId) {
277
277
  this.board = {
@@ -296,7 +296,7 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
296
296
 
297
297
  customElementContent() {
298
298
  const { output, activityInstance } = this.activityThread
299
- const { uiSource: tagName, input } = activityInstance || {}
299
+ const { viewSource: tagName, input } = activityInstance || {}
300
300
 
301
301
  const element = document.createElement(tagName)
302
302
  element.id = 'custom-content'
@@ -215,6 +215,34 @@ export class ActivityTemplateListPage extends connect(store)(localize(i18next)(P
215
215
  },
216
216
  width: 140
217
217
  },
218
+ {
219
+ type: 'select',
220
+ name: 'viewType',
221
+ label: true,
222
+ header: i18next.t('field.view-type'),
223
+ record: {
224
+ editable: true,
225
+ options: ActivityUITypes
226
+ },
227
+ width: 80
228
+ },
229
+ {
230
+ type: 'string',
231
+ name: 'viewSource',
232
+ header: i18next.t('field.view-source'),
233
+ record: {
234
+ editable: true,
235
+ editor: function (value, column, record, rowIndex, field) {
236
+ var type = record.viewType !== 'board' ? 'script' : 'board'
237
+ return getEditor(type)(value, column, record, rowIndex, field)
238
+ },
239
+ renderer: function (value, column, record, rowIndex, field) {
240
+ var type = record.viewType !== 'board' ? 'script' : 'board'
241
+ return getRenderer(type)(value, column, record, rowIndex, field)
242
+ }
243
+ },
244
+ width: 140
245
+ },
218
246
  {
219
247
  type: 'select',
220
248
  name: 'reportType',
@@ -320,6 +348,8 @@ export class ActivityTemplateListPage extends connect(store)(localize(i18next)(P
320
348
  active
321
349
  uiType
322
350
  uiSource
351
+ viewType
352
+ viewSource
323
353
  reportType
324
354
  reportSource
325
355
  updater {
@@ -0,0 +1,293 @@
1
+ import '@operato/property-editor/ox-properties-dynamic-view.js'
2
+ import '@operato/board/ox-board-viewer.js'
3
+
4
+ import gql from 'graphql-tag'
5
+ import { css, html } from 'lit'
6
+ import { unsafeHTML } from 'lit-html/directives/unsafe-html.js'
7
+ import { customElement, property, query, state } from 'lit/decorators.js'
8
+ import { keyed } from 'lit/directives/keyed.js'
9
+ import { connect } from 'pwa-helpers/connect-mixin.js'
10
+
11
+ import { client } from '@operato/graphql'
12
+ import { i18next, localize } from '@operato/i18n'
13
+ import { PageView, store } from '@operato/shell'
14
+ import { CommonGristStyles, ScrollbarStyles } from '@operato/styles'
15
+ import { provider } from '@things-factory/board-ui'
16
+
17
+ const ActivityThreadFetchResult = `\
18
+ {
19
+ id
20
+ state
21
+ dueAt
22
+ assignedAt
23
+ assignee {
24
+ id
25
+ name
26
+ }
27
+ output
28
+ round
29
+ activityInstance {
30
+ id
31
+ name
32
+ description
33
+ state
34
+ activity {
35
+ model {
36
+ name
37
+ description
38
+ active
39
+ tag
40
+ inout
41
+ type
42
+ unit
43
+ options
44
+ quantifier
45
+ spec
46
+ }
47
+ }
48
+ approvalLine {
49
+ type
50
+ value
51
+ approver {
52
+ id
53
+ name
54
+ description
55
+ controlNo
56
+ }
57
+ }
58
+ thumbnail
59
+ input
60
+ output
61
+ viewType
62
+ viewSource
63
+ dueAt
64
+ createdAt
65
+ }
66
+ }`
67
+
68
+ export const ActivityThreadStatus = {
69
+ Assigned: 'assigned',
70
+ Started: 'started',
71
+ Delegated: 'delegated',
72
+ Rejected: 'rejected',
73
+ Ended: 'ended',
74
+ Aborted: 'aborted'
75
+ }
76
+
77
+ @customElement('activity-thread-view-page')
78
+ export class ActivityThreadViewPage extends connect(store)(localize(i18next)(PageView)) {
79
+ static styles = [
80
+ ScrollbarStyles,
81
+ CommonGristStyles,
82
+ css`
83
+ :host {
84
+ display: flex;
85
+ flex-direction: column;
86
+
87
+ width: 100%;
88
+ padding: 5px;
89
+ overflow: auto;
90
+ }
91
+
92
+ ox-board-viewer {
93
+ width: 100%;
94
+ height: 100%;
95
+ }
96
+
97
+ #custom-content {
98
+ flex: 1;
99
+ }
100
+ `
101
+ ]
102
+
103
+ @state() activityThread: any
104
+ @state() board: any
105
+
106
+ get context() {
107
+ return {
108
+ title: this.lifecycle?.params?.['title'] || i18next.t('title.activity'),
109
+ help: 'worklist/activity',
110
+ actions: [],
111
+ activityThread: this.activityThread
112
+ }
113
+ }
114
+
115
+ render() {
116
+ return html` ${this.activityContent()}`
117
+ }
118
+
119
+ activityContent() {
120
+ switch (this.activityThread?.activityInstance?.viewType) {
121
+ case 'template':
122
+ return this.templateContent()
123
+ case 'generated':
124
+ return this.generatedContent()
125
+ case 'board':
126
+ return this.boardContent()
127
+ case 'custom-element':
128
+ return this.customElementContent()
129
+ case 'page':
130
+ case 'external':
131
+ default:
132
+ return html``
133
+ }
134
+ }
135
+
136
+ templateContent() {
137
+ const { viewSource: template } = this.activityThread?.activityInstance
138
+ return unsafeHTML(template)
139
+ }
140
+
141
+ getInputSpec() {
142
+ const model = this.activityThread?.activityInstance?.activity?.model
143
+
144
+ return (model || [])
145
+ .filter(item => item.inout === 'in' || item.inout === 'inout')
146
+ .map(item => {
147
+ return {
148
+ ...item,
149
+ label: item.name
150
+ }
151
+ })
152
+ }
153
+
154
+ getOutputSpec() {
155
+ const model = this.activityThread?.activityInstance?.activity?.model
156
+
157
+ return (model || [])
158
+ .filter(item => item.inout === 'inout' || item.inout === 'out')
159
+ .map(item => {
160
+ return {
161
+ ...item,
162
+ label: item.name
163
+ }
164
+ })
165
+ }
166
+
167
+ generatedContent() {
168
+ var { output, activityInstance } = this.activityThread || {}
169
+ var { input } = activityInstance || {}
170
+
171
+ const inputSpec = this.getInputSpec()
172
+ const outputSpec = this.getOutputSpec()
173
+
174
+ if (!output) {
175
+ output = inputSpec
176
+ .filter(item => item.inout === 'inout')
177
+ .reduce((inout, item) => {
178
+ inout[item.name] = input[item.name]
179
+ return inout
180
+ }, {})
181
+ }
182
+
183
+ return keyed(
184
+ this.activityThread.id,
185
+ html`
186
+ <fieldset>
187
+ <legend>Input</legend>
188
+ <ox-properties-dynamic-view
189
+ data-name="input"
190
+ .props=${inputSpec}
191
+ .value=${input}
192
+ ></ox-properties-dynamic-view>
193
+ </fieldset>
194
+
195
+ <fieldset>
196
+ <legend>Output</legend>
197
+ <ox-properties-dynamic-view
198
+ data-name="output"
199
+ .props=${outputSpec}
200
+ .value=${output}
201
+ @property-change=${e => (this.activityThread.output = e.currentTarget.value)}
202
+ ></ox-properties-dynamic-view>
203
+ </fieldset>
204
+ `
205
+ )
206
+ }
207
+
208
+ boardContent() {
209
+ const { output, activityInstance } = this.activityThread
210
+ const { viewSource: boardId, input } = activityInstance || {}
211
+
212
+ if (!this.board || this.board.id !== boardId) {
213
+ this.board = {
214
+ id: boardId
215
+ }
216
+ }
217
+
218
+ /*
219
+ ox-board-viewer에서 provider에 의해 공급되는 board가 각 id별로 instance를 하나씩 밖에 가지지 않으므로,
220
+ 동일한 id의 보드를 다른 page에 뺏기는 경우가 있다.
221
+ 따라서, Page가 active될 때마다 타임스탬프를 refresh key로 설정하였다.
222
+ */
223
+ return keyed(
224
+ this.activityThread.id,
225
+ html`
226
+ <ox-board-viewer
227
+ style="background-color: white;"
228
+ .board=${this.board}
229
+ .provider=${provider}
230
+ .values=${{ ...input, ...output }}
231
+ hide-fullscreen
232
+ hide-navigation
233
+ ></ox-board-viewer>
234
+ `
235
+ )
236
+ }
237
+
238
+ customElementContent() {
239
+ const { output, activityInstance } = this.activityThread
240
+ const { viewSource: tagName, input } = activityInstance || {}
241
+
242
+ const element = document.createElement(tagName)
243
+ element.id = 'custom-content'
244
+ element.input = input
245
+ element.output = output
246
+ element.addEventListener('change', (e: CustomEvent) => {
247
+ this.activityThread.output = e.detail
248
+ })
249
+
250
+ return element
251
+ }
252
+
253
+ @query('ox-board-viewer') oxBoardViewer: any
254
+
255
+ getOutputFromBoard() {
256
+ const outputSpec = this.getOutputSpec()
257
+ const data = this.oxBoardViewer.getSceneValues()
258
+
259
+ return outputSpec.reduce((output, spec) => {
260
+ output[spec.name] = data[spec.name]
261
+ return output
262
+ }, {})
263
+ }
264
+
265
+ updated(changes) {
266
+ if (changes.has('activityThread')) {
267
+ this.updateContext()
268
+ }
269
+ }
270
+
271
+ async pageUpdated(changes, lifecycle, changedBefore) {
272
+ if (this.active) {
273
+ this.fetchActivityThread(lifecycle.resourceId)
274
+ }
275
+ }
276
+
277
+ async fetchActivityThread(id) {
278
+ const response = await client.query({
279
+ query: gql`
280
+ query activityThread($id: String!) {
281
+ activityThread(id: $id) ${ActivityThreadFetchResult}
282
+ }
283
+ `,
284
+ variables: {
285
+ id
286
+ }
287
+ })
288
+
289
+ this.activityThread = response.data.activityThread
290
+
291
+ this.updateContext()
292
+ }
293
+ }
@@ -229,6 +229,34 @@ export class ActivityTemplateListPage extends connect(store)(localize(i18next)(P
229
229
  },
230
230
  width: 140
231
231
  },
232
+ {
233
+ type: 'select',
234
+ name: 'viewType',
235
+ label: true,
236
+ header: i18next.t('field.view-type'),
237
+ record: {
238
+ editable: true,
239
+ options: ActivityUITypes
240
+ },
241
+ width: 80
242
+ },
243
+ {
244
+ type: 'string',
245
+ name: 'viewSource',
246
+ header: i18next.t('field.view-source'),
247
+ record: {
248
+ editable: true,
249
+ editor: function (value, column, record, rowIndex, field) {
250
+ var type = record.viewType !== 'board' ? 'script' : 'board'
251
+ return getEditor(type)(value, column, record, rowIndex, field)
252
+ },
253
+ renderer: function (value, column, record, rowIndex, field) {
254
+ var type = record.viewType !== 'board' ? 'script' : 'board'
255
+ return getRenderer(type)(value, column, record, rowIndex, field)
256
+ }
257
+ },
258
+ width: 140
259
+ },
232
260
  {
233
261
  type: 'select',
234
262
  name: 'reportType',
@@ -334,6 +362,8 @@ export class ActivityTemplateListPage extends connect(store)(localize(i18next)(P
334
362
  thumbnail
335
363
  uiType
336
364
  uiSource
365
+ viewType
366
+ viewSource
337
367
  reportType
338
368
  reportSource
339
369
  }
@@ -153,14 +153,14 @@ export class ApprovalWaitingListPage extends connect(store)(localize(i18next)(Pa
153
153
  },
154
154
  {
155
155
  type: 'string',
156
- name: 'uiSource',
157
- header: i18next.t('field.ui-source'),
156
+ name: 'viewSource',
157
+ header: i18next.t('field.view-source'),
158
158
  record: {
159
159
  editable: false,
160
160
  renderer: function (value, column, record, rowIndex, field) {
161
- const { uiType, uiSource } = record.activity || {}
162
- var type = uiType !== 'board' ? 'string' : 'board'
163
- return getRenderer(type)(uiSource, column, record, rowIndex, field)
161
+ const { viewType, viewSource } = record.activity || {}
162
+ var type = viewType !== 'board' ? 'string' : 'board'
163
+ return getRenderer(type)(viewSource, column, record, rowIndex, field)
164
164
  }
165
165
  },
166
166
  width: 140,
@@ -314,8 +314,8 @@ export class ApprovalWaitingListPage extends connect(store)(localize(i18next)(Pa
314
314
  input
315
315
  refBy
316
316
  activityType
317
- uiType
318
- uiSource
317
+ viewType
318
+ viewSource
319
319
  thumbnail
320
320
  updatedAt
321
321
  createdAt