@things-factory/worklist 6.2.96 → 6.2.98

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 (54) hide show
  1. package/client/components/activity-approval-timeline.ts +147 -0
  2. package/client/pages/activity-approval/activity-approval-page.ts +41 -145
  3. package/client/pages/activity-thread/activity-thread-page.ts +16 -3
  4. package/client/pages/activity-thread/activity-thread-view-page.ts +20 -8
  5. package/client/pages/activity-thread/activity-thread-view.ts +6 -114
  6. package/client/pages/todo/approval-done-list-page.ts +2 -1
  7. package/client/pages/todo/approval-pending-list-page.ts +17 -6
  8. package/client/pages/todo/done-list-page.ts +7 -2
  9. package/client/pages/todo/draft-list-page.ts +11 -1
  10. package/client/pages/todo/pickable-list-page.ts +25 -10
  11. package/client/pages/todo/todo-list-page.ts +10 -5
  12. package/client/templates/activity-approval-context-template.ts +8 -13
  13. package/client/templates/activity-instance-context-template.ts +16 -18
  14. package/client/templates/activity-thread-context-template.ts +47 -157
  15. package/dist-client/components/activity-approval-timeline.d.ts +18 -0
  16. package/dist-client/components/activity-approval-timeline.js +143 -0
  17. package/dist-client/components/activity-approval-timeline.js.map +1 -0
  18. package/dist-client/pages/activity-approval/activity-approval-page.d.ts +1 -2
  19. package/dist-client/pages/activity-approval/activity-approval-page.js +40 -137
  20. package/dist-client/pages/activity-approval/activity-approval-page.js.map +1 -1
  21. package/dist-client/pages/activity-thread/activity-thread-page.js +15 -3
  22. package/dist-client/pages/activity-thread/activity-thread-page.js.map +1 -1
  23. package/dist-client/pages/activity-thread/activity-thread-view-page.d.ts +1 -0
  24. package/dist-client/pages/activity-thread/activity-thread-view-page.js +18 -4
  25. package/dist-client/pages/activity-thread/activity-thread-view-page.js.map +1 -1
  26. package/dist-client/pages/activity-thread/activity-thread-view.d.ts +0 -2
  27. package/dist-client/pages/activity-thread/activity-thread-view.js +6 -101
  28. package/dist-client/pages/activity-thread/activity-thread-view.js.map +1 -1
  29. package/dist-client/pages/todo/approval-done-list-page.js +2 -1
  30. package/dist-client/pages/todo/approval-done-list-page.js.map +1 -1
  31. package/dist-client/pages/todo/approval-pending-list-page.js +14 -3
  32. package/dist-client/pages/todo/approval-pending-list-page.js.map +1 -1
  33. package/dist-client/pages/todo/done-list-page.js +7 -2
  34. package/dist-client/pages/todo/done-list-page.js.map +1 -1
  35. package/dist-client/pages/todo/draft-list-page.js +10 -1
  36. package/dist-client/pages/todo/draft-list-page.js.map +1 -1
  37. package/dist-client/pages/todo/pickable-list-page.js +19 -1
  38. package/dist-client/pages/todo/pickable-list-page.js.map +1 -1
  39. package/dist-client/pages/todo/todo-list-page.js +7 -2
  40. package/dist-client/pages/todo/todo-list-page.js.map +1 -1
  41. package/dist-client/templates/activity-approval-context-template.d.ts +1 -0
  42. package/dist-client/templates/activity-approval-context-template.js +8 -13
  43. package/dist-client/templates/activity-approval-context-template.js.map +1 -1
  44. package/dist-client/templates/activity-instance-context-template.js +15 -16
  45. package/dist-client/templates/activity-instance-context-template.js.map +1 -1
  46. package/dist-client/templates/activity-thread-context-template.d.ts +1 -0
  47. package/dist-client/templates/activity-thread-context-template.js +46 -151
  48. package/dist-client/templates/activity-thread-context-template.js.map +1 -1
  49. package/dist-client/tsconfig.tsbuildinfo +1 -1
  50. package/dist-server/service/activity-approval/activity-approval-mutation.js +0 -3
  51. package/dist-server/service/activity-approval/activity-approval-mutation.js.map +1 -1
  52. package/dist-server/tsconfig.tsbuildinfo +1 -1
  53. package/package.json +3 -3
  54. package/server/service/activity-approval/activity-approval-mutation.ts +3 -19
@@ -0,0 +1,147 @@
1
+ import '@material/mwc-icon'
2
+ import '@things-factory/organization/dist-client/component/approval-line-view.js'
3
+
4
+ import { html, css, LitElement, nothing } from 'lit'
5
+ import { customElement, property } from 'lit/decorators.js'
6
+
7
+ import { connect } from 'pwa-helpers/connect-mixin'
8
+
9
+ import { store } from '@operato/shell'
10
+ import { i18next } from '@operato/i18n'
11
+
12
+ import { ActivityApproval } from '../types/activity-approval'
13
+
14
+ const formatter = new Intl.DateTimeFormat(navigator.language, { dateStyle: 'full', timeStyle: 'short' })
15
+
16
+ @customElement('activity-approval-timeline')
17
+ export class ActivityApprovalTimeline extends connect(store)(LitElement) {
18
+ static styles = [
19
+ css`
20
+ :host {
21
+ display: block;
22
+ }
23
+
24
+ [subtitle] {
25
+ padding: var(--padding-narrow) var(--padding-default);
26
+ background-color: var(--theme-white-color);
27
+ border: 2px solid var(--secondary-text-color);
28
+ border-radius: 15px;
29
+ box-shadow: var(--box-shadow);
30
+ color: var(--secondary-text-color);
31
+ font-weight: bold;
32
+ }
33
+
34
+ ol {
35
+ list-style: none;
36
+ margin: var(--margin-default) 0 0 var(--margin-narrow);
37
+ padding: 0;
38
+ }
39
+
40
+ li {
41
+ display: flex;
42
+ border: none;
43
+ }
44
+
45
+ [info] {
46
+ flex: 1;
47
+ color: var(--secondary-color);
48
+
49
+ strong {
50
+ float: right;
51
+ }
52
+
53
+ mwc-icon {
54
+ position: relative;
55
+ top: 3px;
56
+ font-size: var(--fontsize-large);
57
+ }
58
+
59
+ p {
60
+ background-color: #f4f4f4;
61
+ margin: var(--margin-narrow) 0 var(--margin-default) 0;
62
+ padding: var(--padding-narrow) var(--padding-default);
63
+ font-size: var(--fontsize-small);
64
+ text-align: justify;
65
+ min-height: 20px;
66
+ }
67
+
68
+ p::before {
69
+ content: '';
70
+ float: right;
71
+ margin-top: -10px;
72
+ margin-right: 20px;
73
+ border: 7px solid transparent;
74
+ border-bottom-color: #f4f4f4;
75
+ border-top: 0;
76
+ }
77
+ }
78
+
79
+ [date] {
80
+ opacity: 0.7;
81
+ flex: initial;
82
+ width: 200px;
83
+ max-width: 30%;
84
+ font-size: var(--fontsize-small);
85
+ color: var(--primary-text-color);
86
+ }
87
+
88
+ [status] {
89
+ margin: 0 var(--margin-narrow);
90
+ display: block;
91
+ border-radius: 50%;
92
+ flex: initial;
93
+ width: 12px;
94
+ height: 12px;
95
+ position: relative;
96
+ top: 3px;
97
+ border: 2px solid #fff;
98
+ background-color: var(--worklist-status-color, tomato);
99
+ color: var(--primary-text-color);
100
+ }
101
+
102
+ [status]::before {
103
+ content: '';
104
+ height: 60px;
105
+ width: 2px;
106
+ display: block;
107
+ position: relative;
108
+ margin-left: 5px;
109
+ background-color: var(--worklist-status-color, tomato);
110
+ opacity: 0.2;
111
+ }
112
+ `
113
+ ]
114
+
115
+ @property({ type: Object }) private activityThread
116
+
117
+ render() {
118
+ const { activityApprovals = [] } = this.activityThread || {}
119
+
120
+ return html` ${activityApprovals.length > 0
121
+ ? html`
122
+ <span subtitle>${i18next.t('label.review-and-approval')}</span>
123
+
124
+ <ol>
125
+ ${activityApprovals.map(approval => this.renderActivityApproval(approval))}
126
+ </ol>
127
+ `
128
+ : nothing}`
129
+ }
130
+
131
+ renderActivityApproval(activityApproval: ActivityApproval) {
132
+ const { judgment, approver, comment, createdAt, terminatedAt } = activityApproval
133
+ const { name } = approver || {}
134
+
135
+ return html`
136
+ <li>
137
+ <span date>${formatter.format(new Date(terminatedAt || createdAt!))}</span>
138
+ <span status></span>
139
+ <span info>
140
+ ${i18next.t('label.activity-state-' + (judgment || 'started'))}
141
+ <strong><mwc-icon>account_circle</mwc-icon>${name}</strong>
142
+ <p>${comment}</p>
143
+ </span>
144
+ </li>
145
+ `
146
+ }
147
+ }
@@ -1,11 +1,12 @@
1
1
  import '@operato/property-editor/ox-properties-dynamic-view.js'
2
2
  import '@operato/board/ox-board-viewer.js'
3
3
  import '../../components/activity-approval-ribon.js'
4
+ import '../../components/activity-approval-timeline.js'
4
5
 
5
6
  import gql from 'graphql-tag'
6
- import { css, html } from 'lit'
7
+ import { css, html, nothing } from 'lit'
7
8
  import { unsafeHTML } from 'lit-html/directives/unsafe-html.js'
8
- import { customElement, property, query, state } from 'lit/decorators.js'
9
+ import { customElement, query, state } from 'lit/decorators.js'
9
10
  import { keyed } from 'lit/directives/keyed.js'
10
11
  import { connect } from 'pwa-helpers/connect-mixin.js'
11
12
 
@@ -14,9 +15,6 @@ import { i18next, localize } from '@operato/i18n'
14
15
  import { PageView, store } from '@operato/shell'
15
16
  import { CommonButtonStyles, ScrollbarStyles } from '@operato/styles'
16
17
  import { provider } from '@things-factory/board-ui'
17
- import { ActivityApproval } from '../../types/activity-approval.js'
18
-
19
- const formatter = new Intl.DateTimeFormat(navigator.language, { dateStyle: 'short', timeStyle: 'short' })
20
18
 
21
19
  const ActivityApprovalFetchResult = `\
22
20
  {
@@ -30,6 +28,7 @@ const ActivityApprovalFetchResult = `\
30
28
  round
31
29
  order
32
30
  createdAt
31
+ terminatedAt
33
32
  activityThread {
34
33
  state
35
34
  dueAt
@@ -122,106 +121,35 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
122
121
  height: 100%;
123
122
  }
124
123
 
125
- #custom-content {
126
- overflow: auto;
124
+ activity-approval-timeline {
125
+ margin: var(--margin-default);
126
+ padding: var(--padding-default);
127
127
  }
128
128
 
129
129
  div[comment] {
130
130
  display: flex;
131
- flex-direction: column;
132
- width: 100%;
133
- right: 0;
131
+ position: sticky;
134
132
  bottom: 0;
135
133
  margin: 0;
136
134
  padding: 0;
137
- opacity: 0.8;
138
- margin-top: auto;
135
+ width: 100%;
136
+ background-color: var(--main-section-background-color);
139
137
 
140
- max-height: 40%;
138
+ textarea {
139
+ flex: 1;
140
+ margin: var(--margin-default);
141
+ padding: var(--input-padding);
142
+ font: var(--input-font);
143
+ outline: none;
144
+ height: 80px;
145
+ border-radius: 10px;
146
+ border: var(--input-field-border);
147
+ resize: none;
148
+ }
141
149
  }
142
150
 
143
- div[timeline] {
144
- margin-bottom: var(--margin-default);
145
- padding: var(--padding-default);
146
- border-bottom: var(--border-dark-color);
147
- overflow: auto;
148
- }
149
- div[timeline] [subtitle] {
150
- padding: var(--padding-narrow) var(--padding-default);
151
- background-color: var(--theme-white-color);
152
- border: 2px solid var(--secondary-text-color);
153
- border-radius: 15px;
154
- box-shadow: var(--box-shadow);
155
- color: var(--secondary-text-color);
156
- font-weight: bold;
157
- }
158
- div[timeline] ol {
159
- list-style: none;
160
- margin: var(--margin-default) 0 0 var(--margin-narrow);
161
- padding: 0;
162
- }
163
- [timeline] li {
164
- display: flex;
165
- }
166
- [timeline] [info] {
167
- flex: 1;
168
- }
169
- [timeline] [date] {
170
- opacity: 0.7;
171
- width: 130px;
172
- font-size: var(--fontsize-small);
173
- }
174
- [timeline] [info] strong {
175
- float: right;
176
- }
177
- [timeline] [status] {
178
- margin: 0 var(--margin-narrow);
179
- display: block;
180
- border-radius: 50%;
181
- width: 12px;
182
- height: 12px;
183
- position: relative;
184
- top: 3px;
185
- border: 2px solid #fff;
186
- background-color: var(--worklist-status-color, tomato);
187
- }
188
- [timeline] [status]::before {
189
- content: '';
190
- height: 60px;
191
- width: 2px;
192
- display: block;
193
- position: relative;
194
- margin-left: 5px;
195
- background-color: var(--worklist-status-color, tomato);
196
- opacity: 0.2;
197
- }
198
- [timeline] [info] mwc-icon {
199
- position: relative;
200
- top: 3px;
201
- font-size: var(--fontsize-large);
202
- }
203
- [timeline] [info] p {
204
- background-color: var(--theme-white-color);
205
- margin: var(--margin-narrow) 0 var(--margin-default) 0;
206
- padding: var(--padding-narrow) var(--padding-default);
207
- font-size: var(--fontsize-small);
208
- text-align: justify;
209
- }
210
- [timeline] [info] p::before {
211
- content: '';
212
- float: right;
213
- margin-top: -10px;
214
- margin-right: 20px;
215
- border: 7px solid transparent;
216
- border-bottom-color: #f4f4f4;
217
- border-top: 0;
218
- }
219
- div[comment] textarea {
220
- margin: 0 var(--margin-default) var(--margin-default) var(--margin-default);
221
- padding: var(--input-padding);
222
- resize: none;
223
- font: var(--input-font);
224
- outline: none;
151
+ div[empty] {
152
+ align-self: center;
225
153
  }
226
154
  `
227
155
  ]
@@ -265,49 +193,29 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
265
193
 
266
194
  render() {
267
195
  if (!this.activityThread) {
268
- return html`<div>no activity thread info.</div>`
196
+ return html`<div empty>no activity thread info.</div>`
269
197
  }
270
198
 
271
- const { activityApprovals = [] } = this.activityThread
272
- const approvals = activityApprovals.sort((a, b) => (a.round > b.round ? 1 : a.round < b.round ? -1 : a.order! > b.order! ? 1 : -1)).slice(0, -1)
199
+ const { terminatedAt } = this.activityApproval
200
+ const editable = !terminatedAt
273
201
 
274
202
  return html`
275
203
  <activity-approval-ribon .activityApproval=${this.activityApproval}></activity-approval-ribon>
276
204
  ${this.activityContent()}
277
- <div comment>
278
- <div timeline>
279
- <span subtitle>${i18next.t('label.review-and-approval')}</span>
280
-
281
- <ol>
282
- ${approvals.map(approval => this.renderActivityApproval(approval))}
283
- </ol>
284
- </div>
285
-
286
- <textarea
287
- placeholder=${String(i18next.t('text.explain the reason for approval/rejection'))}
288
- .value=${this.activityApproval?.comment}
289
- @change=${(e: Event) => {
290
- this.activityApproval.comment = (e.target as HTMLTextAreaElement).value
291
- }}
292
- ></textarea>
293
- </div>
294
- `
295
- }
296
-
297
- renderActivityApproval(activityApproval: ActivityApproval) {
298
- const { judgment, approver, comment, round, order, createdAt, terminatedAt } = activityApproval
299
- const { name, email } = approver || {}
300
-
301
- return html`
302
- <li>
303
- <span date>${formatter.format(new Date(terminatedAt || createdAt!))}</span>
304
- <span status></span>
305
- <span info>
306
- ${i18next.t('label.activity-state-' + (judgment || 'started'))}
307
- <strong><mwc-icon>account_circle</mwc-icon>${name}</strong>
308
- <p>${comment}</p>
309
- </span>
310
- </li>
205
+ <activity-approval-timeline .activityThread=${this.activityThread}></activity-approval-timeline>
206
+ ${editable
207
+ ? html`
208
+ <div comment>
209
+ <textarea
210
+ placeholder=${String(i18next.t('text.explain the reason for approval/rejection'))}
211
+ .value=${this.activityApproval?.comment}
212
+ @change=${(e: Event) => {
213
+ this.activityApproval.comment = (e.target as HTMLTextAreaElement).value
214
+ }}
215
+ ></textarea>
216
+ </div>
217
+ `
218
+ : nothing}
311
219
  `
312
220
  }
313
221
 
@@ -544,21 +452,9 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
544
452
  async approveActivityApproval() {
545
453
  var { id, comment } = this.activityApproval
546
454
 
547
- if (!comment) {
548
- document.dispatchEvent(
549
- new CustomEvent('notify', {
550
- detail: {
551
- message: i18next.t('text.enter a comment')
552
- }
553
- })
554
- )
555
- this.commentInput.focus()
556
- return
557
- }
558
-
559
455
  const response = await client.mutate({
560
456
  mutation: gql`
561
- mutation ($id: String!, $comment: String!) {
457
+ mutation ($id: String!, $comment: String) {
562
458
  approveActivityApproval(id: $id, comment: $comment) ${ActivityApprovalFetchResult}
563
459
  }
564
460
  `,
@@ -112,8 +112,13 @@ export class ActivityThreadPage extends connect(store)(localize(i18next)(PageVie
112
112
  height: 100%;
113
113
  }
114
114
 
115
- #custom-content {
116
- flex: 1;
115
+ activity-approval-timeline {
116
+ margin: var(--margin-default);
117
+ padding: var(--padding-default);
118
+ }
119
+
120
+ div[empty] {
121
+ align-self: center;
117
122
  }
118
123
  `
119
124
  ]
@@ -171,7 +176,15 @@ export class ActivityThreadPage extends connect(store)(localize(i18next)(PageVie
171
176
  render() {
172
177
  const activityThread = this.activityThread
173
178
 
174
- return html` ${activityThread ? html`<activity-thread-ribon .activityThread=${activityThread}></activity-thread-ribon>` : html``} ${this.activityContent()}`
179
+ if (!activityThread) {
180
+ return html`<div empty>no activity thread info.</div> `
181
+ }
182
+
183
+ return html`
184
+ <activity-thread-ribon .activityThread=${activityThread}></activity-thread-ribon>
185
+ ${this.activityContent()}
186
+ <activity-approval-timeline .activityThread=${activityThread}></activity-approval-timeline>
187
+ `
175
188
  }
176
189
 
177
190
  activityContent() {
@@ -1,5 +1,6 @@
1
1
  import '@operato/board/ox-board-viewer.js'
2
2
  import '../../components/activity-thread-ribon.js'
3
+ import '../../components/activity-approval-timeline.js'
3
4
  import './activity-thread-view.js'
4
5
 
5
6
  import gql from 'graphql-tag'
@@ -115,9 +116,18 @@ export class ActivityThreadViewPage extends connect(store)(localize(i18next)(Pag
115
116
  padding: var(--padding-default);
116
117
  }
117
118
 
119
+ activity-approval-timeline {
120
+ margin: var(--margin-default);
121
+ padding: var(--padding-default);
122
+ }
123
+
118
124
  #custom-content {
119
125
  flex: 1;
120
126
  }
127
+
128
+ div[empty] {
129
+ align-self: center;
130
+ }
121
131
  `
122
132
  ]
123
133
 
@@ -136,10 +146,15 @@ export class ActivityThreadViewPage extends connect(store)(localize(i18next)(Pag
136
146
  render() {
137
147
  const activityThread = this.activityThread
138
148
 
139
- return html` ${activityThread
140
- ? html`<activity-thread-ribon .activityThread=${activityThread}></activity-thread-ribon>`
141
- : html``}
142
- ${this.activityContent()}`
149
+ if (!activityThread) {
150
+ return html`<div empty>no activity thread info.</div> `
151
+ }
152
+
153
+ return html`
154
+ <activity-thread-ribon .activityThread=${activityThread}></activity-thread-ribon>
155
+ ${this.activityContent()}
156
+ <activity-approval-timeline .activityThread=${activityThread}></activity-approval-timeline>
157
+ `
143
158
  }
144
159
 
145
160
  activityContent() {
@@ -204,10 +219,7 @@ export class ActivityThreadViewPage extends connect(store)(localize(i18next)(Pag
204
219
  return html``
205
220
  }
206
221
 
207
- return keyed(
208
- this.activityThread.id,
209
- html` <activity-thread-view .activityThreadId=${this.activityThread.id}></activity-thread-view> `
210
- )
222
+ return keyed(this.activityThread.id, html` <activity-thread-view .activityThreadId=${this.activityThread.id}></activity-thread-view> `)
211
223
  }
212
224
 
213
225
  boardContent() {
@@ -114,74 +114,14 @@ export class ActivityThreadView extends localize(i18next)(LitElement) {
114
114
  font: bold 16px var(--theme-font);
115
115
  color: var(--secondary-text-color);
116
116
  }
117
- [timeline] ol {
118
- list-style: none;
119
- margin: 0;
120
- padding: 0;
121
- }
122
- [timeline] li {
123
- display: flex;
124
- }
125
- [timeline] [info] {
126
- flex: 1;
127
- }
128
- [timeline] [date] {
129
- opacity: 0.7;
130
- width: 130px;
131
- font-size: var(--fontsize-small);
132
- }
133
- [timeline] [info] strong {
134
- float: right;
135
- }
136
- [timeline] [status] {
137
- margin: 0 var(--margin-narrow);
138
- display: block;
139
- border-radius: 50%;
140
- width: 12px;
141
- height: 12px;
142
- position: relative;
143
- top: 3px;
144
- border: 2px solid #fff;
145
- background-color: var(--worklist-status-color, tomato);
146
- }
147
- [timeline] [status]::before {
148
- content: '';
149
- height: 60px;
150
- width: 2px;
151
- display: block;
152
- position: relative;
153
- margin-left: 5px;
154
- background-color: var(--worklist-status-color, tomato);
155
- opacity: 0.2;
156
- }
157
- [timeline] [info] mwc-icon {
158
- position: relative;
159
- top: 3px;
160
- font-size: var(--fontsize-large);
161
- }
162
- [timeline] [info] p {
163
- background-color: #f4f4f4;
164
- margin: var(--margin-narrow) 0 var(--margin-default) 0;
165
- padding: var(--padding-narrow) var(--padding-default);
166
- border-radius: var(--border-radius);
167
- font-size: var(--fontsize-small);
168
- text-align: justify;
169
- }
170
- [timeline] [info] p::before {
171
- content: '';
172
- float: right;
173
- margin-top: -10px;
174
- margin-right: 20px;
175
- border: 7px solid transparent;
176
- border-bottom-color: #f4f4f4;
177
- border-top: 0;
178
- }
117
+
179
118
  [thread] div {
180
119
  border-bottom: var(--border-dark-color);
181
120
  padding: var(--padding-narrow);
182
121
  text-align: right;
183
122
  overflow: hidden;
184
123
  }
124
+
185
125
  [thread] div label {
186
126
  float: left;
187
127
  width: 25%;
@@ -203,23 +143,9 @@ export class ActivityThreadView extends localize(i18next)(LitElement) {
203
143
  return html`<div>no activity thread info.</div>`
204
144
  }
205
145
 
206
- const {
207
- state,
208
- assignee,
209
- output,
210
- round,
211
- activityApprovals = [],
212
- assignedAt,
213
- startedAt,
214
- terminatedAt,
215
- activityInstance
216
- } = this.activityThread
217
- const { input, approvalLine } = activityInstance!
146
+ const { state, assignee, output, round, assignedAt, startedAt, terminatedAt, activityInstance } = this.activityThread
147
+ const { input } = activityInstance!
218
148
  const { name, email } = assignee || {}
219
- const approvals = activityApprovals.sort((a, b) =>
220
- a.round < b.round ? 1 : a.round > b.round ? -1 : a.order! < b.order! ? 1 : -1
221
- )
222
- const current = approvals[0]?.round == round ? approvals[0].order : -1
223
149
 
224
150
  return html`
225
151
  <div assignee>
@@ -234,13 +160,9 @@ export class ActivityThreadView extends localize(i18next)(LitElement) {
234
160
  <span status></span>
235
161
  <strong>${i18next.t('label.activity-state-' + state)}</strong>
236
162
  </div>
237
- <div>
238
- <label>${i18next.t('field.assigned-at')}</label> ${assignedAt && formatter.format(new Date(assignedAt))}
239
- </div>
163
+ <div><label>${i18next.t('field.assigned-at')}</label> ${assignedAt && formatter.format(new Date(assignedAt))}</div>
240
164
  <div><label>${i18next.t('field.started-at')}</label> ${startedAt && formatter.format(new Date(startedAt))}</div>
241
- <div>
242
- <label>${i18next.t('field.terminated-at')}</label> ${terminatedAt && formatter.format(new Date(terminatedAt))}
243
- </div>
165
+ <div><label>${i18next.t('field.terminated-at')}</label> ${terminatedAt && formatter.format(new Date(terminatedAt))}</div>
244
166
  <div><label>${i18next.t('field.round')}</label> ${round}</div>
245
167
  </div>
246
168
 
@@ -248,36 +170,6 @@ export class ActivityThreadView extends localize(i18next)(LitElement) {
248
170
  <span subtitle>${i18next.t('field.artifact')}</span>
249
171
  ${this.renderInOut({ ...input, ...output })}
250
172
  </div>
251
- <div timeline>
252
- <span subtitle>${i18next.t('label.review-and-approval')}</span>
253
-
254
- <div>
255
- ${approvalLine
256
- ? html`<approval-line-view .model=${approvalLine} .current=${current}></approval-line-view>`
257
- : html``}
258
- </div>
259
-
260
- <ol>
261
- ${approvals.map(approval => this.renderActivityApproval(approval))}
262
- </ol>
263
- </div>
264
- `
265
- }
266
-
267
- renderActivityApproval(activityApproval: ActivityApproval) {
268
- const { judgment, approver, comment, round, order, createdAt, terminatedAt } = activityApproval
269
- const { name, email } = approver || {}
270
-
271
- return html`
272
- <li>
273
- <span date>${formatter.format(new Date(terminatedAt || createdAt!))}</span>
274
- <span status></span>
275
- <span info>
276
- ${i18next.t('label.activity-state-' + (judgment || 'started'))}
277
- <strong><mwc-icon>account_circle</mwc-icon>${name}</strong>
278
- <p>${comment}</p>
279
- </span>
280
- </li>
281
173
  `
282
174
  }
283
175
 
@@ -243,7 +243,8 @@ export class ApprovalDoneListPage extends connect(store)(localize(i18next)(PageV
243
243
  }
244
244
  ],
245
245
  rows: {
246
- appendable: false
246
+ appendable: false,
247
+ editable: false
247
248
  },
248
249
  sorters: [
249
250
  {
@@ -127,7 +127,6 @@ export class ApprovalPendingListPage extends connect(store)(localize(i18next)(Pa
127
127
  icon: record => (record && !record.comment ? 'new_label' : 'label'),
128
128
  handlers: {
129
129
  click: (columns, data, column, record, rowIndex) => {
130
- const { id } = record
131
130
  this.openActivityApproval(record)
132
131
  }
133
132
  }
@@ -281,11 +280,23 @@ export class ApprovalPendingListPage extends connect(store)(localize(i18next)(Pa
281
280
  name: 'thumbnail',
282
281
  header: i18next.t('field.thumbnail'),
283
282
  record: { editable: false },
284
- hidden: true
283
+ hidden: true,
284
+ handlers: {
285
+ click: (columns, data, column, record, rowIndex) => {
286
+ const { id } = record
287
+ this.openActivityApproval(record)
288
+ }
289
+ }
285
290
  }
286
291
  ],
287
292
  rows: {
288
- appendable: false
293
+ appendable: false,
294
+ editable: false,
295
+ handlers: {
296
+ click: (columns, data, column, record, rowIndex) => {
297
+ this.openActivityApproval(record)
298
+ }
299
+ }
289
300
  },
290
301
  sorters: [
291
302
  {
@@ -402,9 +413,9 @@ export class ApprovalPendingListPage extends connect(store)(localize(i18next)(Pa
402
413
  const minutes = Math.floor(secs / MIN)
403
414
  const seconds = secs - minutes * MIN
404
415
 
405
- yield `${positive ? '' : '- '}${days ? `${days}${i18next.t('label.days')} ` : ''}${
406
- hours ? `${hours}${i18next.t('label.hours')} ` : ''
407
- }${minutes ? `${minutes}${i18next.t('label.minutes')} ` : ''}`
416
+ yield `${positive ? '' : '- '}${days ? `${days}${i18next.t('label.days')} ` : ''}${hours ? `${hours}${i18next.t('label.hours')} ` : ''}${
417
+ minutes ? `${minutes}${i18next.t('label.minutes')} ` : ''
418
+ }`
408
419
 
409
420
  await sleep(60 * 1000)
410
421
  }