@things-factory/worklist 6.1.83 → 6.1.87

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 (30) hide show
  1. package/client/pages/activity-approval/activity-approval-page.ts +130 -6
  2. package/client/pages/activity-instance/activity-instance-search-page.ts +17 -28
  3. package/client/pages/activity-supervisor/reporter-list-page.ts +15 -9
  4. package/client/pages/activity-thread/activity-thread-page.ts +12 -0
  5. package/client/pages/activity-thread/activity-thread-view-page.ts +12 -0
  6. package/client/templates/activity-thread-context-template.ts +111 -14
  7. package/client/types/types.ts +7 -0
  8. package/dist-client/pages/activity-approval/activity-approval-page.d.ts +2 -0
  9. package/dist-client/pages/activity-approval/activity-approval-page.js +124 -6
  10. package/dist-client/pages/activity-approval/activity-approval-page.js.map +1 -1
  11. package/dist-client/pages/activity-instance/activity-instance-search-page.js +17 -28
  12. package/dist-client/pages/activity-instance/activity-instance-search-page.js.map +1 -1
  13. package/dist-client/pages/activity-supervisor/reporter-list-page.js +15 -9
  14. package/dist-client/pages/activity-supervisor/reporter-list-page.js.map +1 -1
  15. package/dist-client/pages/activity-thread/activity-thread-page.js +12 -0
  16. package/dist-client/pages/activity-thread/activity-thread-page.js.map +1 -1
  17. package/dist-client/pages/activity-thread/activity-thread-view-page.js +12 -0
  18. package/dist-client/pages/activity-thread/activity-thread-view-page.js.map +1 -1
  19. package/dist-client/templates/activity-thread-context-template.js +108 -14
  20. package/dist-client/templates/activity-thread-context-template.js.map +1 -1
  21. package/dist-client/tsconfig.tsbuildinfo +1 -1
  22. package/dist-client/types/types.d.ts +4 -0
  23. package/dist-client/types/types.js +6 -0
  24. package/dist-client/types/types.js.map +1 -1
  25. package/dist-server/tsconfig.tsbuildinfo +1 -1
  26. package/package.json +9 -9
  27. package/dist-server/middlewares/index.js +0 -8
  28. package/dist-server/middlewares/index.js.map +0 -1
  29. package/dist-server/migrations/index.js +0 -12
  30. package/dist-server/migrations/index.js.map +0 -1
@@ -14,6 +14,9 @@ import { i18next, localize } from '@operato/i18n'
14
14
  import { PageView, store } from '@operato/shell'
15
15
  import { CommonButtonStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles'
16
16
  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' })
17
20
 
18
21
  const ActivityApprovalFetchResult = `\
19
22
  {
@@ -36,6 +39,18 @@ const ActivityApprovalFetchResult = `\
36
39
  name
37
40
  }
38
41
  output
42
+ activityApprovals {
43
+ round
44
+ order
45
+ approver {
46
+ name
47
+ email
48
+ }
49
+ judgment
50
+ comment
51
+ createdAt
52
+ terminatedAt
53
+ }
39
54
  activityInstance {
40
55
  id
41
56
  name
@@ -98,6 +113,7 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
98
113
 
99
114
  width: 100%;
100
115
  overflow: auto;
116
+ background-color: var(--main-section-background-color);
101
117
  }
102
118
 
103
119
  ox-board-viewer {
@@ -106,13 +122,13 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
106
122
  }
107
123
 
108
124
  #custom-content {
109
- flex: 1;
125
+ overflow: auto;
110
126
  }
111
127
 
112
128
  div[comment] {
113
129
  display: flex;
130
+ flex-direction: column;
114
131
  width: 100%;
115
- height: 100px;
116
132
  right: 0;
117
133
  bottom: 0;
118
134
  margin: 0;
@@ -121,12 +137,86 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
121
137
  margin-top: auto;
122
138
  }
123
139
 
124
- div[comment] textarea {
140
+ div[timeline] {
141
+ margin-bottom: var(--margin-default);
142
+ padding: var(--padding-default);
143
+ border-bottom: var(--border-dark-color);
144
+ }
145
+ div[timeline] [subtitle] {
146
+ padding: var(--padding-narrow) var(--padding-default);
147
+ background-color: var(--theme-white-color);
148
+ border: 2px solid var(--secondary-text-color);
149
+ border-radius: 15px;
150
+ box-shadow: var(--box-shadow);
151
+ color: var(--secondary-text-color);
152
+ font-weight: bold;
153
+ }
154
+ div[timeline] ol {
155
+ list-style: none;
156
+ margin: var(--margin-default) 0 0 var(--margin-narrow);
157
+ padding: 0;
158
+ }
159
+ [timeline] li {
160
+ display: flex;
161
+ }
162
+ [timeline] [info] {
125
163
  flex: 1;
126
- padding: 10px;
164
+ }
165
+ [timeline] [date] {
166
+ opacity: 0.7;
167
+ width: 110px;
168
+ font-size: var(--fontsize-small);
169
+ }
170
+ [timeline] [info] strong {
171
+ float: right;
172
+ }
173
+ [timeline] [status] {
174
+ margin: 0 var(--margin-narrow);
175
+ display: block;
176
+ border-radius: 50%;
177
+ width: 12px;
178
+ height: 12px;
179
+ position: relative;
180
+ top: 3px;
181
+ border: 2px solid #fff;
182
+ background-color: var(--worklist-status-color, tomato);
183
+ }
184
+ [timeline] [status]::before {
185
+ content: '';
186
+ height: 60px;
187
+ width: 2px;
188
+ display: block;
189
+ position: relative;
190
+ margin-left: 5px;
191
+ background-color: var(--worklist-status-color, tomato);
192
+ opacity: 0.2;
193
+ }
194
+ [timeline] [info] mwc-icon {
195
+ position: relative;
196
+ top: 3px;
197
+ font-size: var(--fontsize-large);
198
+ }
199
+ [timeline] [info] p {
200
+ background-color: var(--theme-white-color);
201
+ margin: var(--margin-narrow) 0 var(--margin-default) 0;
202
+ padding: var(--padding-narrow) var(--padding-default);
203
+ font-size: var(--fontsize-small);
204
+ text-align: justify;
205
+ }
206
+ [timeline] [info] p::before {
207
+ content: '';
208
+ float: right;
209
+ margin-top: -10px;
210
+ margin-right: 20px;
211
+ border: 7px solid transparent;
212
+ border-bottom-color: #f4f4f4;
213
+ border-top: 0;
214
+ }
215
+ div[comment] textarea {
216
+ margin: 0 var(--margin-default) var(--margin-default) var(--margin-default);
217
+ padding: var(--input-padding);
127
218
  resize: none;
128
- background-color: black;
129
- color: yellow;
219
+ font: var(--input-font);
130
220
  outline: none;
131
221
  }
132
222
  `
@@ -170,10 +260,27 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
170
260
  }
171
261
 
172
262
  render() {
263
+ if (!this.activityThread) {
264
+ return html`<div>no activity thread info.</div>`
265
+ }
266
+
267
+ const { activityApprovals = [] } = this.activityThread
268
+ const approvals = activityApprovals
269
+ .sort((a, b) => (a.round > b.round ? 1 : a.round < b.round ? -1 : a.order! > b.order! ? 1 : -1))
270
+ .slice(0, -1)
271
+
173
272
  return html`
174
273
  <activity-approval-ribon .activityApproval=${this.activityApproval}></activity-approval-ribon>
175
274
  ${this.activityContent()}
176
275
  <div comment>
276
+ <div timeline>
277
+ <span subtitle>${i18next.t('label.review-and-approval')}</span>
278
+
279
+ <ol>
280
+ ${approvals.map(approval => this.renderActivityApproval(approval))}
281
+ </ol>
282
+ </div>
283
+
177
284
  <textarea
178
285
  placeholder="Jot down your comment here."
179
286
  .value=${this.activityApproval?.comment}
@@ -185,6 +292,23 @@ export class ActivityApprovalPage extends connect(store)(localize(i18next)(PageV
185
292
  `
186
293
  }
187
294
 
295
+ renderActivityApproval(activityApproval: ActivityApproval) {
296
+ const { judgment, approver, comment, round, order, createdAt, terminatedAt } = activityApproval
297
+ const { name, email } = approver || {}
298
+
299
+ return html`
300
+ <li>
301
+ <span date>${formatter.format(new Date(terminatedAt || createdAt!))}</span>
302
+ <span status></span>
303
+ <span info>
304
+ ${i18next.t('label.activity-state-' + (judgment || 'started'))}
305
+ <strong><mwc-icon>account_circle</mwc-icon>${name}</strong>
306
+ <p>${comment}</p>
307
+ </span>
308
+ </li>
309
+ `
310
+ }
311
+
188
312
  activityContent() {
189
313
  switch (this.activityThread?.activityInstance?.viewType) {
190
314
  case 'template':
@@ -163,9 +163,10 @@ export class ActivityInstanceSearchPage extends connect(store)(localize(i18next)
163
163
 
164
164
  refreshGristConfig() {
165
165
  this.gristConfig = {
166
+ pagination: { pages : [50, 100, 200] },
166
167
  list: {
167
168
  fields: ['name', 'description'],
168
- details: ['updatedAt', 'updater', 'createdAt', 'creator']
169
+ details: ['updatedAt', 'updater']
169
170
  },
170
171
  columns: [
171
172
  { type: 'gutter', gutterName: 'sequence' },
@@ -202,7 +203,7 @@ export class ActivityInstanceSearchPage extends connect(store)(localize(i18next)
202
203
  },
203
204
  filter: 'search',
204
205
  sortable: true,
205
- width: 235,
206
+ width: 250,
206
207
  imex: true
207
208
  },
208
209
  {
@@ -213,7 +214,17 @@ export class ActivityInstanceSearchPage extends connect(store)(localize(i18next)
213
214
  editable: false
214
215
  },
215
216
  filter: 'search',
216
- width: 250,
217
+ width: 300,
218
+ imex: true
219
+ },
220
+ {
221
+ type: 'string',
222
+ name: 'state',
223
+ header: i18next.t('label.status'),
224
+ record: {
225
+ editable: false
226
+ },
227
+ width: 80,
217
228
  imex: true
218
229
  },
219
230
  ...this.getSearchKeyColumns(),
@@ -237,31 +248,13 @@ export class ActivityInstanceSearchPage extends connect(store)(localize(i18next)
237
248
  hidden: true,
238
249
  imex: true
239
250
  },
240
- {
241
- type: 'resource-object',
242
- name: 'creator',
243
- header: i18next.t('field.creator'),
244
- sortable: true,
245
- label: true,
246
- width: 100,
247
- imex: true
248
- },
249
- {
250
- type: 'datetime',
251
- name: 'createdAt',
252
- header: i18next.t('field.created_at'),
253
- sortable: true,
254
- label: true,
255
- width: 180,
256
- imex: true
257
- },
258
251
  {
259
252
  type: 'resource-object',
260
253
  name: 'updater',
261
254
  header: i18next.t('field.updater'),
262
255
  sortable: true,
263
256
  label: true,
264
- width: 100,
257
+ width: 90,
265
258
  imex: true
266
259
  },
267
260
  {
@@ -282,7 +275,7 @@ export class ActivityInstanceSearchPage extends connect(store)(localize(i18next)
282
275
  },
283
276
  sorters: [
284
277
  {
285
- name: 'updatedAt',
278
+ name: 'createdAt',
286
279
  desc: true
287
280
  }
288
281
  ]
@@ -307,6 +300,7 @@ export class ActivityInstanceSearchPage extends connect(store)(localize(i18next)
307
300
  id
308
301
  name
309
302
  description
303
+ state
310
304
  key01
311
305
  key02
312
306
  key03
@@ -319,11 +313,6 @@ export class ActivityInstanceSearchPage extends connect(store)(localize(i18next)
319
313
  name
320
314
  }
321
315
  updatedAt
322
- creator {
323
- id
324
- name
325
- }
326
- createdAt
327
316
  }
328
317
  total
329
318
  }
@@ -94,6 +94,7 @@ export class ReporterListPage extends connect(store)(localize(i18next)(PageView)
94
94
 
95
95
  async pageInitialized(lifecycle) {
96
96
  this.gristConfig = {
97
+ pagination: { pages : [50, 100, 200] },
97
98
  list: {
98
99
  thumbnail: 'thumbnail',
99
100
  fields: ['name', 'description'],
@@ -133,33 +134,37 @@ export class ReporterListPage extends connect(store)(localize(i18next)(PageView)
133
134
  header: i18next.t('field.name'),
134
135
  filter: 'search',
135
136
  sortable: true,
136
- width: 250
137
+ width: 385
137
138
  },
138
139
  {
139
140
  type: 'string',
140
141
  name: 'description',
141
142
  header: i18next.t('field.description'),
142
143
  filter: 'search',
143
- width: 300
144
+ width: 400
144
145
  },
145
146
  {
146
147
  type: 'string',
147
148
  name: 'activityType',
148
149
  label: true,
149
150
  header: i18next.t('field.activity-type'),
150
- sortable: true,
151
- // filter: {
152
- // type: 'select',
153
- // options: ActivityTypes
154
- // },
155
- width: 100
151
+ sortable: false,
152
+ width: 85
153
+ },
154
+ {
155
+ type: 'string',
156
+ name: 'state',
157
+ label: true,
158
+ header: i18next.t('label.status'),
159
+ sortable: false,
160
+ width: 85
156
161
  },
157
162
  {
158
163
  type: 'resource-object',
159
164
  name: 'updater',
160
165
  header: i18next.t('field.updater'),
161
166
  sortable: true,
162
- width: 100
167
+ width: 90
163
168
  },
164
169
  {
165
170
  type: 'datetime',
@@ -202,6 +207,7 @@ export class ReporterListPage extends connect(store)(localize(i18next)(PageView)
202
207
  id
203
208
  name
204
209
  description
210
+ state
205
211
  activityType
206
212
  priority
207
213
  thumbnail
@@ -27,6 +27,18 @@ const ActivityThreadFetchResult = `\
27
27
  }
28
28
  output
29
29
  round
30
+ activityApprovals {
31
+ round
32
+ order
33
+ approver {
34
+ name
35
+ email
36
+ }
37
+ judgment
38
+ comment
39
+ createdAt
40
+ terminatedAt
41
+ }
30
42
  activityInstance {
31
43
  id
32
44
  name
@@ -27,6 +27,18 @@ const ActivityThreadFetchResult = `\
27
27
  }
28
28
  output
29
29
  round
30
+ activityApprovals {
31
+ round
32
+ order
33
+ approver {
34
+ name
35
+ email
36
+ }
37
+ judgment
38
+ comment
39
+ createdAt
40
+ terminatedAt
41
+ }
30
42
  activityInstance {
31
43
  id
32
44
  name
@@ -1,4 +1,5 @@
1
1
  import '@material/mwc-icon'
2
+ import '@things-factory/organization/dist-client/component/approval-line-view.js'
2
3
 
3
4
  import { html, css, LitElement } from 'lit'
4
5
  import { customElement, property, state } from 'lit/decorators.js'
@@ -9,7 +10,7 @@ import { ContextToolbarOverlayStyle } from '@operato/context/ox-context-toolbar-
9
10
  import { store } from '@operato/shell'
10
11
  import { i18next } from '@operato/i18n'
11
12
 
12
- import '@things-factory/organization/dist-client/component/approval-line-view.js'
13
+ import { ActivityApproval } from '../types/activity-approval'
13
14
 
14
15
  const formatter = new Intl.DateTimeFormat(navigator.language, { dateStyle: 'full', timeStyle: 'short' })
15
16
 
@@ -58,14 +59,14 @@ class ActivityThreadContextTemplate extends connect(store)(LitElement) {
58
59
  --worklist-status-color: #cb3a33;
59
60
  }
60
61
 
61
- [info],
62
+ div[info],
62
63
  [assignees] {
63
64
  padding: var(--padding-default);
64
65
  border-bottom: var(--border-dark-color);
65
66
  color: var(--secondary-color);
66
67
  }
67
68
 
68
- [info] div {
69
+ div[info] div {
69
70
  display: flex;
70
71
  align-items: center;
71
72
  padding: var(--padding-narrow);
@@ -75,18 +76,18 @@ class ActivityThreadContextTemplate extends connect(store)(LitElement) {
75
76
  overflow: hidden;
76
77
  }
77
78
 
78
- [info] div:nth-child(odd) {
79
+ div[info] div:nth-child(odd) {
79
80
  background-color: var(--main-section-background-color);
80
81
  }
81
82
 
82
- [info] label {
83
+ div[info] label {
83
84
  display: inline-block;
84
85
  width: 25%;
85
86
  text-align: right;
86
87
  margin-right: 20px;
87
88
  }
88
89
 
89
- [info] span {
90
+ div[info] span {
90
91
  width: 15px;
91
92
  height: 15px;
92
93
  background-color: var(--worklist-status-color, tomato);
@@ -94,14 +95,85 @@ class ActivityThreadContextTemplate extends connect(store)(LitElement) {
94
95
  border-radius: 50%;
95
96
  }
96
97
 
97
- :host:before {
98
+ div[timeline] {
99
+ margin-bottom: var(--margin-default);
100
+ padding: var(--padding-default);
101
+ }
102
+ div[timeline] [subtitle] {
103
+ padding: var(--padding-narrow) var(--padding-default);
104
+ background-color: var(--theme-white-color);
105
+ border: 2px solid var(--secondary-text-color);
106
+ border-radius: 15px;
107
+ box-shadow: var(--box-shadow);
108
+ color: var(--secondary-text-color);
109
+ font-weight: bold;
110
+ }
111
+ div[timeline] ol {
112
+ list-style: none;
113
+ margin: var(--margin-default) 0 0 var(--margin-narrow);
114
+ padding: 0;
115
+ }
116
+ [timeline] li {
117
+ display: flex;
118
+ border:none;
119
+ }
120
+ [timeline] [info] {
121
+ flex: 1;
122
+ color:initial;
123
+ }
124
+ [timeline] [date] {
125
+ opacity: 0.7;
126
+ flex:initial;
127
+ width: 110px;
128
+ font-size: var(--fontsize-small);
129
+ color:var(--primary-text-color);
130
+ }
131
+ [timeline] [info] strong {
132
+ float: right;
133
+ }
134
+ [timeline] [status] {
135
+ margin: 0 var(--margin-narrow);
136
+ display: block;
137
+ border-radius: 50%;
138
+ flex:initial;
139
+ width: 12px;
140
+ height: 12px;
141
+ position: relative;
142
+ top: 3px;
143
+ border: 2px solid #fff;
144
+ background-color: var(--worklist-status-color, tomato);
145
+ color:var(--primary-text-color);
146
+ }
147
+ [timeline] [status]::before {
98
148
  content: '';
99
- position: absolute;
100
- width: 0;
101
- height: 0;
102
- border: 22px solid transparent;
103
- border-left-color: var(--worklist-status-color);
104
- border-right: 0;
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
+ font-size: var(--fontsize-small);
167
+ text-align: justify;
168
+ }
169
+ [timeline] [info] p::before {
170
+ content: '';
171
+ float: right;
172
+ margin-top: -10px;
173
+ margin-right: 20px;
174
+ border: 7px solid transparent;
175
+ border-bottom-color: #f4f4f4;
176
+ border-top: 0;
105
177
  }
106
178
 
107
179
  [thumbnail] {
@@ -125,7 +197,7 @@ class ActivityThreadContextTemplate extends connect(store)(LitElement) {
125
197
  render() {
126
198
  const activityThread = this.context.activityThread || this.activityThread || {}
127
199
 
128
- const { state, round, dueAt, assignedAt, assignee, activityInstance } = activityThread || {}
200
+ const { state, round, dueAt, assignedAt, assignee, activityInstance, activityApprovals } = activityThread || {}
129
201
  const { name, description, thumbnail, approvalLine } = activityInstance || {}
130
202
 
131
203
  return html`
@@ -151,6 +223,14 @@ class ActivityThreadContextTemplate extends connect(store)(LitElement) {
151
223
  <div><label>${i18next.t('field.due-at')}</label> ${dueAt && formatter.format(new Date(dueAt))}</div>
152
224
  </div>
153
225
 
226
+ <div timeline>
227
+ <span subtitle>${i18next.t('label.review-and-approval')}</span>
228
+
229
+ <ol>
230
+ ${activityApprovals.map(approval => this.renderActivityApproval(approval))}
231
+ </ol>
232
+ </div>
233
+
154
234
  ${thumbnail
155
235
  ? html` <div thumbnail>
156
236
  <img src=${thumbnail} />
@@ -159,6 +239,23 @@ class ActivityThreadContextTemplate extends connect(store)(LitElement) {
159
239
  `
160
240
  }
161
241
 
242
+ renderActivityApproval(activityApproval: ActivityApproval) {
243
+ const { judgment, approver, comment, round, order, createdAt, terminatedAt } = activityApproval
244
+ const { name, email } = approver || {}
245
+
246
+ return html`
247
+ <li>
248
+ <span date>${formatter.format(new Date(terminatedAt || createdAt!))}</span>
249
+ <span status></span>
250
+ <span info>
251
+ ${i18next.t('label.activity-state-' + (judgment || 'started'))}
252
+ <strong><mwc-icon>account_circle</mwc-icon>${name}</strong>
253
+ <p>${comment}</p>
254
+ </span>
255
+ </li>
256
+ `
257
+ }
258
+
162
259
  stateChanged(state) {
163
260
  this.context = state.route.context
164
261
  }
@@ -37,3 +37,10 @@ export const ActivityStartingTypes = [
37
37
  { display: i18next.t('label.activity-starting-type-post'), value: 'post' },
38
38
  { display: i18next.t('label.activity-starting-type-issue'), value: 'issue' }
39
39
  ]
40
+
41
+ export const ActivityStatus = [
42
+ { display: '', value: '' },
43
+ { display: i18next.t('label.activity-state-draft'), value: 'draft' },
44
+ { display: i18next.t('label.activity-state-released'), value: 'released' },
45
+ { display: i18next.t('label.activity-state-deprecated'), value: 'deprecated' }
46
+ ]
@@ -2,6 +2,7 @@ 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
4
  import { PageView } from '@operato/shell';
5
+ import { ActivityApproval } from '../../types/activity-approval.js';
5
6
  export declare const ActivityThreadStatus: {
6
7
  Assigned: string;
7
8
  Started: string;
@@ -38,6 +39,7 @@ export declare class ActivityApprovalPage extends ActivityApprovalPage_base {
38
39
  }[];
39
40
  };
40
41
  render(): import("lit-html").TemplateResult<1>;
42
+ renderActivityApproval(activityApproval: ActivityApproval): import("lit-html").TemplateResult<1>;
41
43
  activityContent(): any;
42
44
  templateContent(): import("lit-html/directive.js").DirectiveResult<typeof import("lit-html/directives/unsafe-html.js").UnsafeHTMLDirective>;
43
45
  getInputSpec(): any;