@things-factory/worklist 6.1.54 → 6.1.56

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 (48) hide show
  1. package/client/components/activity-approval-ribon.ts +158 -0
  2. package/client/components/activity-instance-ribon.ts +15 -96
  3. package/client/components/activity-thread-ribon.ts +153 -0
  4. package/client/pages/activity-approval/activity-approval-page.ts +30 -3
  5. package/client/pages/activity-instance/activity-instance-start-page.ts +2 -2
  6. package/client/pages/activity-thread/activity-thread-page.ts +9 -4
  7. package/client/templates/activity-approval-context-template.ts +121 -23
  8. package/client/templates/activity-instance-context-template.ts +116 -115
  9. package/client/templates/activity-thread-context-template.ts +117 -18
  10. package/dist-client/components/activity-approval-ribon.d.ts +13 -0
  11. package/dist-client/components/activity-approval-ribon.js +159 -0
  12. package/dist-client/components/activity-approval-ribon.js.map +1 -0
  13. package/dist-client/components/activity-instance-ribon.d.ts +1 -0
  14. package/dist-client/components/activity-instance-ribon.js +15 -83
  15. package/dist-client/components/activity-instance-ribon.js.map +1 -1
  16. package/dist-client/components/activity-thread-ribon.d.ts +13 -0
  17. package/dist-client/components/activity-thread-ribon.js +153 -0
  18. package/dist-client/components/activity-thread-ribon.js.map +1 -0
  19. package/dist-client/pages/activity-approval/activity-approval-page.d.ts +5 -4
  20. package/dist-client/pages/activity-approval/activity-approval-page.js +26 -3
  21. package/dist-client/pages/activity-approval/activity-approval-page.js.map +1 -1
  22. package/dist-client/pages/activity-instance/activity-instance-start-page.d.ts +0 -1
  23. package/dist-client/pages/activity-instance/activity-instance-start-page.js +2 -2
  24. package/dist-client/pages/activity-instance/activity-instance-start-page.js.map +1 -1
  25. package/dist-client/pages/activity-thread/activity-thread-page.d.ts +4 -4
  26. package/dist-client/pages/activity-thread/activity-thread-page.js +8 -4
  27. package/dist-client/pages/activity-thread/activity-thread-page.js.map +1 -1
  28. package/dist-client/templates/activity-approval-context-template.js +124 -23
  29. package/dist-client/templates/activity-approval-context-template.js.map +1 -1
  30. package/dist-client/templates/activity-instance-context-template.js +116 -102
  31. package/dist-client/templates/activity-instance-context-template.js.map +1 -1
  32. package/dist-client/templates/activity-thread-context-template.js +120 -18
  33. package/dist-client/templates/activity-thread-context-template.js.map +1 -1
  34. package/dist-client/tsconfig.tsbuildinfo +1 -1
  35. package/dist-server/middlewares/index.js +8 -0
  36. package/dist-server/middlewares/index.js.map +1 -0
  37. package/dist-server/migrations/index.js +12 -0
  38. package/dist-server/migrations/index.js.map +1 -0
  39. package/dist-server/service/activity-approval/activity-approval-mutation.js +12 -0
  40. package/dist-server/service/activity-approval/activity-approval-mutation.js.map +1 -1
  41. package/dist-server/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +4 -4
  43. package/server/service/activity-approval/activity-approval-mutation.ts +19 -1
  44. package/translations/en.json +3 -0
  45. package/translations/ja.json +3 -0
  46. package/translations/ko.json +3 -0
  47. package/translations/ms.json +136 -133
  48. package/translations/zh.json +133 -130
@@ -0,0 +1,158 @@
1
+ import '@material/mwc-button'
2
+ import '@operato/property-editor/ox-properties-dynamic-view.js'
3
+ import '@things-factory/organization/dist-client/component/approval-line-brief.js'
4
+ import '../templates/activity-approval-context-template.js'
5
+
6
+ import { css, html, LitElement } from 'lit'
7
+ import { customElement, property, state } from 'lit/decorators.js'
8
+
9
+ import { i18next, localize } from '@operato/i18n'
10
+ import { toggleOverlay } from '@operato/layout'
11
+
12
+ @customElement('activity-approval-ribon')
13
+ export class ActivityApprovalRibon extends localize(i18next)(LitElement) {
14
+ static styles = [
15
+ css`
16
+ :host {
17
+ display: flex;
18
+ background-color: var(--worklist-status-color);
19
+ color: var(--theme-white-color);
20
+ align-items: center;
21
+ min-height: 44px;
22
+ --fontsize-small: 12px;
23
+ }
24
+
25
+ div {
26
+ border-left: var(--border-dark-color);
27
+ padding: var(--padding-narrow) var(--padding-default);
28
+ align-self: center;
29
+ }
30
+
31
+ :host([state='assigned']) {
32
+ --worklist-status-color: #5f7184;
33
+ }
34
+
35
+ :host([state='started']) {
36
+ --worklist-status-color: #56af45;
37
+ }
38
+
39
+ :host([state='delegated']) {
40
+ --worklist-status-color: #8654b0;
41
+ }
42
+
43
+ :host([state='submitted']) {
44
+ --worklist-status-color: #428df3;
45
+ }
46
+
47
+ :host([state='escalated']) {
48
+ --worklist-status-color: #595de5;
49
+ }
50
+
51
+ :host([state='rejected']) {
52
+ --worklist-status-color: #f27429;
53
+ }
54
+
55
+ :host([state='ended']) {
56
+ --worklist-status-color: #02acae;
57
+ }
58
+
59
+ :host([state='aborted']) {
60
+ --worklist-status-color: #cb3a33;
61
+ }
62
+
63
+ mwc-icon {
64
+ font-size: 24px;
65
+ }
66
+
67
+ [desc] {
68
+ flex: 2;
69
+ font-size: var(--fontsize-small);
70
+ }
71
+
72
+ [desc] * {
73
+ vertical-align: middle;
74
+ }
75
+
76
+ [assignee] {
77
+ text-align: center;
78
+ font-size: var(--fontsize-small);
79
+ line-height: 1.3;
80
+ }
81
+
82
+ [assignee] span {
83
+ display: block;
84
+ font-size: var(--fontsize-large);
85
+ font-weight: bold;
86
+ }
87
+
88
+ approval-line-brief {
89
+ background-color: var(--worklist-status-color);
90
+ flex: 2;
91
+ font-size: var(--fontsize-small);
92
+ }
93
+
94
+ @media only screen and (max-width: 460px) {
95
+ :host {
96
+ flex-direction: column;
97
+ }
98
+ div {
99
+ border-left: none;
100
+ border-bottom: var(--border-dark-color);
101
+ }
102
+ [assignee] {
103
+ display: none;
104
+ }
105
+ mwc-icon {
106
+ padding: 0;
107
+ }
108
+ }
109
+ `
110
+ ]
111
+
112
+ @property({ type: Object }) activityApproval: any
113
+
114
+ render() {
115
+ const { activityInstance, state } = this.activityApproval?.activityThread || {}
116
+ const { description, assignee, approvalLine, activity } = activityInstance || {}
117
+ const { startingType } = activity || {}
118
+
119
+ return html`
120
+ <div desc>
121
+ <mwc-icon
122
+ @click=${() => {
123
+ toggleOverlay('activity-info-overlay', {
124
+ template: html`<activity-approval-context-template
125
+ .activityApproval=${this.activityApproval}
126
+ state=${state}
127
+ ></activity-approval-context-template>`
128
+ })
129
+ }}
130
+ >description</mwc-icon
131
+ >
132
+ ${description}
133
+ </div>
134
+ ${startingType == 'issue' && assignee
135
+ ? html`
136
+ <div assignee>
137
+ ${i18next.t('field.assignee')}
138
+ <span>${assignee?.name}&nbsp;</span>
139
+ </div>
140
+ `
141
+ : html``}
142
+ ${approvalLine
143
+ ? html`<approval-line-brief
144
+ .model=${approvalLine}
145
+ .current=${this.activityApproval.order}
146
+ ></approval-line-brief>`
147
+ : html``}
148
+ `
149
+ }
150
+
151
+ updated(changes) {
152
+ if (changes.has('activityApproval')) {
153
+ const { state } = this.activityApproval.activityThread
154
+
155
+ this.setAttribute('state', state)
156
+ }
157
+ }
158
+ }
@@ -1,5 +1,6 @@
1
1
  import '@material/mwc-button'
2
2
  import '@operato/property-editor/ox-properties-dynamic-view.js'
3
+ import '@things-factory/organization/dist-client/component/approval-line-brief.js'
3
4
  import '../templates/activity-instance-context-template.js'
4
5
 
5
6
  import { css, html, LitElement } from 'lit'
@@ -16,6 +17,8 @@ export class ActivityInstanceRibon extends localize(i18next)(LitElement) {
16
17
  display: flex;
17
18
  background-color: var(--worklist-status-color);
18
19
  color: var(--theme-white-color);
20
+ align-items: center;
21
+ min-height: 44px;
19
22
  --fontsize-small: 12px;
20
23
  }
21
24
 
@@ -61,11 +64,11 @@ export class ActivityInstanceRibon extends localize(i18next)(LitElement) {
61
64
  font-size: 24px;
62
65
  }
63
66
 
64
- [desc],
65
- [flow] {
67
+ [desc] {
66
68
  flex: 2;
67
69
  font-size: var(--fontsize-small);
68
70
  }
71
+
69
72
  [desc] * {
70
73
  vertical-align: middle;
71
74
  }
@@ -82,63 +85,10 @@ export class ActivityInstanceRibon extends localize(i18next)(LitElement) {
82
85
  font-weight: bold;
83
86
  }
84
87
 
85
- [flow] ul {
86
- list-style: none;
87
- margin: 0;
88
- padding: 0;
89
- display: flex;
90
- }
91
-
92
- [flow] li {
93
- width: 85px;
94
- text-align: center;
95
- color: rgba(255, 255, 255, 0.7);
96
- }
97
-
98
- [flow] span:before {
99
- content: '';
100
- height: 2px;
101
- width: 70px;
102
- display: block;
103
- position: absolute;
104
- margin-left: -70px;
105
- margin-top: 6px;
106
- background-color: rgba(0, 0, 0, 0.4);
107
- }
108
-
109
- [flow] span {
110
- display: block;
111
- width: 15px;
112
- height: 15px;
113
- margin: auto;
114
- background-color: rgba(0, 0, 0, 0.4);
115
- border-radius: 50%;
116
- color: var(--theme-white-color);
117
- line-height: 1.2;
118
- }
119
-
120
- [flow] [past] span {
121
- background-color: rgba(255, 255, 255, 0.9);
122
- color: var(--primary-text-color);
123
- }
124
-
125
- [flow] [now] span {
126
- background-color: #84d600;
127
- color: var(--theme-white-color);
128
- }
129
-
130
- [flow] [now] {
131
- font-weight: bold;
132
- color: var(--theme-white-color);
133
- }
134
-
135
- [flow] [past] span:before,
136
- [flow] [now] span:before {
137
- background-color: rgba(255, 255, 255, 0.9);
138
- }
139
-
140
- [flow] li:first-child span:before {
141
- display: none;
88
+ approval-line-brief {
89
+ background-color: var(--worklist-status-color);
90
+ flex: 2;
91
+ font-size: var(--fontsize-small);
142
92
  }
143
93
 
144
94
  @media only screen and (max-width: 460px) {
@@ -160,34 +110,10 @@ export class ActivityInstanceRibon extends localize(i18next)(LitElement) {
160
110
  ]
161
111
 
162
112
  @property({ type: Object }) activityInstance: any = {}
163
- // @property({ type: Array }) activityThreads: any
164
-
165
- // @state() picked: boolean = false
166
113
 
167
114
  render() {
168
- const {
169
- id,
170
- name,
171
- description,
172
- input,
173
- state,
174
- assignee,
175
- threadsMin = 0,
176
- threadsMax = 0,
177
- activity
178
- } = this.activityInstance || {}
179
- const { startingType, model, thumbnail } = activity || {}
180
-
181
- // const inputSpec = (model || [])
182
- // .filter(item => item.inout === 'in' || item.inout === 'inout')
183
- // .map(item => {
184
- // return {
185
- // ...item,
186
- // label: item.name
187
- // }
188
- // })
189
-
190
- // const pickable = !this.picked && this.activityThreads?.length < threadsMax
115
+ const { description, state, assignee, approvalLine, activity } = this.activityInstance || {}
116
+ const { startingType } = activity || {}
191
117
 
192
118
  return html`
193
119
  <div desc>
@@ -204,22 +130,15 @@ export class ActivityInstanceRibon extends localize(i18next)(LitElement) {
204
130
  >
205
131
  ${description}
206
132
  </div>
207
- ${startingType == 'issue'
133
+ ${startingType == 'issue' && assignee
208
134
  ? html`
209
135
  <div assignee>
210
- ${i18next.t('label.assignee')}
211
- <span>${assignee?.name}</span>
136
+ ${i18next.t('field.assignee')}
137
+ <span>${assignee?.name}&nbsp;</span>
212
138
  </div>
213
139
  `
214
140
  : html``}
215
-
216
- <div flow>
217
- <ul>
218
- <li past><span>1</span>myself</li>
219
- <li now><span>2</span>경리실장</li>
220
- <li><span>3</span>사장님</li>
221
- </ul>
222
- </div>
141
+ ${approvalLine ? html`<approval-line-brief .model=${approvalLine}></approval-line-brief>` : html``}
223
142
  `
224
143
  }
225
144
 
@@ -0,0 +1,153 @@
1
+ import '@material/mwc-button'
2
+ import '@operato/property-editor/ox-properties-dynamic-view.js'
3
+ import '@things-factory/organization/dist-client/component/approval-line-brief.js'
4
+ import '../templates/activity-thread-context-template.js'
5
+
6
+ import { css, html, LitElement } from 'lit'
7
+ import { customElement, property, state } from 'lit/decorators.js'
8
+
9
+ import { i18next, localize } from '@operato/i18n'
10
+ import { toggleOverlay } from '@operato/layout'
11
+
12
+ @customElement('activity-thread-ribon')
13
+ export class ActivityThreadRibon extends localize(i18next)(LitElement) {
14
+ static styles = [
15
+ css`
16
+ :host {
17
+ display: flex;
18
+ background-color: var(--worklist-status-color);
19
+ color: var(--theme-white-color);
20
+ align-items: center;
21
+ min-height: 44px;
22
+ --fontsize-small: 12px;
23
+ }
24
+
25
+ div {
26
+ border-left: var(--border-dark-color);
27
+ padding: var(--padding-narrow) var(--padding-default);
28
+ align-self: center;
29
+ }
30
+
31
+ :host([state='assigned']) {
32
+ --worklist-status-color: #5f7184;
33
+ }
34
+
35
+ :host([state='started']) {
36
+ --worklist-status-color: #56af45;
37
+ }
38
+
39
+ :host([state='delegated']) {
40
+ --worklist-status-color: #8654b0;
41
+ }
42
+
43
+ :host([state='submitted']) {
44
+ --worklist-status-color: #428df3;
45
+ }
46
+
47
+ :host([state='escalated']) {
48
+ --worklist-status-color: #595de5;
49
+ }
50
+
51
+ :host([state='rejected']) {
52
+ --worklist-status-color: #f27429;
53
+ }
54
+
55
+ :host([state='ended']) {
56
+ --worklist-status-color: #02acae;
57
+ }
58
+
59
+ :host([state='aborted']) {
60
+ --worklist-status-color: #cb3a33;
61
+ }
62
+
63
+ mwc-icon {
64
+ font-size: 24px;
65
+ }
66
+
67
+ [desc] {
68
+ flex: 2;
69
+ font-size: var(--fontsize-small);
70
+ }
71
+
72
+ [desc] * {
73
+ vertical-align: middle;
74
+ }
75
+
76
+ [assignee] {
77
+ text-align: center;
78
+ font-size: var(--fontsize-small);
79
+ line-height: 1.3;
80
+ }
81
+
82
+ [assignee] span {
83
+ display: block;
84
+ font-size: var(--fontsize-large);
85
+ font-weight: bold;
86
+ }
87
+
88
+ approval-line-brief {
89
+ background-color: var(--worklist-status-color);
90
+ flex: 2;
91
+ font-size: var(--fontsize-small);
92
+ }
93
+
94
+ @media only screen and (max-width: 460px) {
95
+ :host {
96
+ flex-direction: column;
97
+ }
98
+ div {
99
+ border-left: none;
100
+ border-bottom: var(--border-dark-color);
101
+ }
102
+ [assignee] {
103
+ display: none;
104
+ }
105
+ mwc-icon {
106
+ padding: 0;
107
+ }
108
+ }
109
+ `
110
+ ]
111
+
112
+ @property({ type: Object }) activityThread: any
113
+
114
+ render() {
115
+ const { state, activityInstance } = this.activityThread
116
+ const { description, assignee, approvalLine, activity } = activityInstance || {}
117
+ const { startingType } = activity || {}
118
+
119
+ return html`
120
+ <div desc>
121
+ <mwc-icon
122
+ @click=${() => {
123
+ toggleOverlay('activity-info-overlay', {
124
+ template: html`<activity-thread-context-template
125
+ .activityThread=${this.activityThread}
126
+ state=${state}
127
+ ></activity-thread-context-template>`
128
+ })
129
+ }}
130
+ >description</mwc-icon
131
+ >
132
+ ${description}
133
+ </div>
134
+ ${startingType == 'issue' && assignee
135
+ ? html`
136
+ <div assignee>
137
+ ${i18next.t('field.assignee')}
138
+ <span>${assignee?.name}&nbsp;</span>
139
+ </div>
140
+ `
141
+ : html``}
142
+ ${approvalLine ? html`<approval-line-brief .model=${approvalLine}></approval-line-brief>` : html``}
143
+ `
144
+ }
145
+
146
+ updated(changes) {
147
+ if (changes.has('activityThread')) {
148
+ const { state } = this.activityThread
149
+
150
+ this.setAttribute('state', state)
151
+ }
152
+ }
153
+ }
@@ -1,5 +1,6 @@
1
1
  import '@operato/property-editor/ox-properties-dynamic-view.js'
2
2
  import '@operato/board/ox-board-viewer.js'
3
+ import '../../components/activity-approval-ribon.js'
3
4
 
4
5
  import gql from 'graphql-tag'
5
6
  import { css, html } from 'lit'
@@ -96,7 +97,6 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
96
97
  position: relative;
97
98
 
98
99
  width: 100%;
99
- padding: 5px;
100
100
  overflow: auto;
101
101
  }
102
102
 
@@ -136,6 +136,8 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
136
136
  @state() activityThread: any
137
137
  @state() board: any
138
138
 
139
+ @query('textarea') commentInput!: HTMLTextAreaElement
140
+
139
141
  get context() {
140
142
  const judgment = this.activityApproval?.judgment
141
143
 
@@ -162,13 +164,14 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
162
164
  action: this.saveActivityApproval.bind(this),
163
165
  ...CommonButtonStyles.save
164
166
  }
165
- ],
166
- activityApproval: this.activityApproval
167
+ ]
168
+ // activityApproval: this.activityApproval
167
169
  }
168
170
  }
169
171
 
170
172
  render() {
171
173
  return html`
174
+ <activity-approval-ribon .activityApproval=${this.activityApproval}></activity-approval-ribon>
172
175
  ${this.activityContent()}
173
176
  <div comment>
174
177
  <textarea
@@ -356,6 +359,18 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
356
359
  async rejectActivityApproval() {
357
360
  var { id, comment } = this.activityApproval
358
361
 
362
+ if (!comment) {
363
+ document.dispatchEvent(
364
+ new CustomEvent('notify', {
365
+ detail: {
366
+ message: i18next.t('text.enter a comment')
367
+ }
368
+ })
369
+ )
370
+ this.commentInput.focus()
371
+ return
372
+ }
373
+
359
374
  const response = await client.mutate({
360
375
  mutation: gql`
361
376
  mutation ($id: String!, $comment: String!) {
@@ -387,6 +402,18 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
387
402
  async approveActivityApproval() {
388
403
  var { id, comment } = this.activityApproval
389
404
 
405
+ if (!comment) {
406
+ document.dispatchEvent(
407
+ new CustomEvent('notify', {
408
+ detail: {
409
+ message: i18next.t('text.enter a comment')
410
+ }
411
+ })
412
+ )
413
+ this.commentInput.focus()
414
+ return
415
+ }
416
+
390
417
  const response = await client.mutate({
391
418
  mutation: gql`
392
419
  mutation ($id: String!, $comment: String!) {
@@ -66,8 +66,8 @@ export class ActivityInstanceStartPage extends connect(store)(localize(i18next)(
66
66
  action: this.issueActivityInstance.bind(this),
67
67
  ...CommonButtonStyles.submit
68
68
  }
69
- ].filter(Boolean /* truthy only */),
70
- activityInstance: this.activityInstance
69
+ ].filter(Boolean /* truthy only */)
70
+ // activityInstance: this.activityInstance
71
71
  }
72
72
  }
73
73
 
@@ -1,5 +1,6 @@
1
1
  import '@operato/property-editor/ox-properties-dynamic-view.js'
2
2
  import '@operato/board/ox-board-viewer.js'
3
+ import '../../components/activity-thread-ribon.js'
3
4
 
4
5
  import gql from 'graphql-tag'
5
6
  import { css, html } from 'lit'
@@ -86,7 +87,6 @@ export class ActivityThreadPage extends connect(store)(localize(i18next)(PageVie
86
87
  flex-direction: column;
87
88
 
88
89
  width: 100%;
89
- padding: 5px;
90
90
  overflow: auto;
91
91
  }
92
92
 
@@ -146,13 +146,18 @@ export class ActivityThreadPage extends connect(store)(localize(i18next)(PageVie
146
146
  action: this._abortActivityThread.bind(this),
147
147
  ...CommonButtonStyles.cancel
148
148
  }
149
- ].filter(Boolean /* truthy only */),
150
- activityThread: this.activityThread
149
+ ].filter(Boolean /* truthy only */)
150
+ // activityThread: this.activityThread
151
151
  }
152
152
  }
153
153
 
154
154
  render() {
155
- return html` ${this.activityContent()}`
155
+ const activityThread = this.activityThread
156
+
157
+ return html` ${activityThread
158
+ ? html`<activity-thread-ribon .activityThread=${activityThread}></activity-thread-ribon>`
159
+ : html``}
160
+ ${this.activityContent()}`
156
161
  }
157
162
 
158
163
  activityContent() {