@things-factory/worklist 10.1.27 → 10.1.29

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 (69) hide show
  1. package/approval-walk/harness.mjs +255 -0
  2. package/dist-client/pages/activity/activity-list-page.js +6 -11
  3. package/dist-client/pages/activity/activity-list-page.js.map +1 -1
  4. package/dist-client/pages/activity/activity-page.d.ts +6 -0
  5. package/dist-client/pages/activity/activity-page.js +173 -142
  6. package/dist-client/pages/activity/activity-page.js.map +1 -1
  7. package/dist-client/pages/activity/starter-list-page.js +6 -11
  8. package/dist-client/pages/activity/starter-list-page.js.map +1 -1
  9. package/dist-client/pages/activity-approval/activity-approval-list-page.js +6 -11
  10. package/dist-client/pages/activity-approval/activity-approval-list-page.js.map +1 -1
  11. package/dist-client/pages/activity-approval/activity-approval-page.d.ts +21 -4
  12. package/dist-client/pages/activity-approval/activity-approval-page.js +256 -173
  13. package/dist-client/pages/activity-approval/activity-approval-page.js.map +1 -1
  14. package/dist-client/pages/activity-catalog/activity-catalog-page.d.ts +6 -0
  15. package/dist-client/pages/activity-catalog/activity-catalog-page.js +43 -32
  16. package/dist-client/pages/activity-catalog/activity-catalog-page.js.map +1 -1
  17. package/dist-client/pages/activity-instance/activity-instance-list-page.js +79 -105
  18. package/dist-client/pages/activity-instance/activity-instance-list-page.js.map +1 -1
  19. package/dist-client/pages/activity-instance/activity-instance-search-page.js +3 -6
  20. package/dist-client/pages/activity-instance/activity-instance-search-page.js.map +1 -1
  21. package/dist-client/pages/activity-instance/activity-instance-start-page.d.ts +6 -0
  22. package/dist-client/pages/activity-instance/activity-instance-start-page.js +220 -161
  23. package/dist-client/pages/activity-instance/activity-instance-start-page.js.map +1 -1
  24. package/dist-client/pages/activity-stats/activity-stats-list-page.js +6 -11
  25. package/dist-client/pages/activity-stats/activity-stats-list-page.js.map +1 -1
  26. package/dist-client/pages/activity-store/activity-store-page.js +4 -11
  27. package/dist-client/pages/activity-store/activity-store-page.js.map +1 -1
  28. package/dist-client/pages/activity-supervisor/reporter-list-page.js +6 -11
  29. package/dist-client/pages/activity-supervisor/reporter-list-page.js.map +1 -1
  30. package/dist-client/pages/activity-template/activity-template-list-page.js +6 -11
  31. package/dist-client/pages/activity-template/activity-template-list-page.js.map +1 -1
  32. package/dist-client/pages/activity-thread/activity-thread-list-page.js +6 -11
  33. package/dist-client/pages/activity-thread/activity-thread-list-page.js.map +1 -1
  34. package/dist-client/pages/activity-thread/activity-thread-page.d.ts +7 -2
  35. package/dist-client/pages/activity-thread/activity-thread-page.js +101 -82
  36. package/dist-client/pages/activity-thread/activity-thread-page.js.map +1 -1
  37. package/dist-client/pages/activity-thread/activity-thread-view-page.d.ts +7 -2
  38. package/dist-client/pages/activity-thread/activity-thread-view-page.js +58 -23
  39. package/dist-client/pages/activity-thread/activity-thread-view-page.js.map +1 -1
  40. package/dist-client/pages/installable-activity/installable-activity-list-page.js +6 -11
  41. package/dist-client/pages/installable-activity/installable-activity-list-page.js.map +1 -1
  42. package/dist-client/pages/todo/approval-done-list-page.js +6 -11
  43. package/dist-client/pages/todo/approval-done-list-page.js.map +1 -1
  44. package/dist-client/pages/todo/approval-pending-list-page.js +4 -12
  45. package/dist-client/pages/todo/approval-pending-list-page.js.map +1 -1
  46. package/dist-client/pages/todo/done-list-calendar-page.js +4 -5
  47. package/dist-client/pages/todo/done-list-calendar-page.js.map +1 -1
  48. package/dist-client/pages/todo/done-list-page.js +6 -11
  49. package/dist-client/pages/todo/done-list-page.js.map +1 -1
  50. package/dist-client/pages/todo/draft-list-page.js +6 -11
  51. package/dist-client/pages/todo/draft-list-page.js.map +1 -1
  52. package/dist-client/pages/todo/pickable-list-page.js +6 -11
  53. package/dist-client/pages/todo/pickable-list-page.js.map +1 -1
  54. package/dist-client/pages/todo/todo-list-page.js +4 -11
  55. package/dist-client/pages/todo/todo-list-page.js.map +1 -1
  56. package/dist-client/tsconfig.tsbuildinfo +1 -1
  57. package/dist-server/service/activity/decision-key-declaration.d.ts +11 -2
  58. package/dist-server/service/activity/decision-key-declaration.js +22 -1
  59. package/dist-server/service/activity/decision-key-declaration.js.map +1 -1
  60. package/dist-server/service/installable-activity/installable-activity-query.d.ts +11 -0
  61. package/dist-server/service/installable-activity/installable-activity-query.js +31 -0
  62. package/dist-server/service/installable-activity/installable-activity-query.js.map +1 -1
  63. package/dist-server/tsconfig.tsbuildinfo +1 -1
  64. package/package.json +10 -11
  65. package/translations/en.json +27 -14
  66. package/translations/ja.json +27 -14
  67. package/translations/ko.json +27 -14
  68. package/translations/ms.json +27 -14
  69. package/translations/zh.json +27 -14
@@ -1,11 +1,12 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  import '@material/web/icon/icon.js';
3
+ import '@operato/list-state/ox-page-state.js';
3
4
  import '@operato/property-editor/ox-properties-dynamic-view.js';
4
5
  import '@operato/board/ox-board-viewer.js';
5
6
  import '../../components/activity-approval-ribon.js';
6
7
  import '../../components/activity-thread-timeline.js';
7
8
  import gql from 'graphql-tag';
8
- import { css, html, nothing } from 'lit';
9
+ import { css, html, nothing, unsafeCSS } from 'lit';
9
10
  import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
10
11
  import { customElement, query, state } from 'lit/decorators.js';
11
12
  import { keyed } from 'lit/directives/keyed.js';
@@ -15,7 +16,7 @@ import { i18next, localize } from '@operato/i18n';
15
16
  import { ranMutation } from '../../components/say-outcome.js';
16
17
  import { approvalGate } from './approval-gate.js';
17
18
  import { PageView } from '@operato/shell';
18
- import { CommonButtonStyles, ScrollbarStyles } from '@operato/styles';
19
+ import { DocumentPageStyles, ScrollbarStyles } from '@operato/styles';
19
20
  import { provider } from '@operato/board/board-provider.js';
20
21
  import { isReferenceStep } from '@things-factory/organization/dist-client';
21
22
  import { ActivityFieldsStyles, declaredLabel, fieldValue, inputSpecOf, outputSpecOf, renderGiven } from '../../components/activity-fields.js';
@@ -102,16 +103,26 @@ const ActivityApprovalFetchResult = `\
102
103
  }
103
104
  }
104
105
  }`;
105
- export const ActivityThreadStatus = { Unassigned: 'unassigned',
106
+ export const ActivityThreadStatus = {
107
+ Unassigned: 'unassigned',
106
108
  Assigned: 'assigned',
107
109
  Started: 'started',
108
110
  Delegated: 'delegated',
109
111
  Ended: 'ended',
110
112
  Aborted: 'aborted'
111
113
  };
114
+ /** 타임라인이 옆에 서는 폭 — 읽는 단 1080 + 사이 24 + 최소 판 360 + page 좌우 40. */
115
+ const BESIDE = '(min-width: 1504px)';
112
116
  let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(PageView) {
113
117
  constructor() {
114
118
  super(...arguments);
119
+ /**
120
+ * 타임라인이 옆에 설 만큼 넓은가.
121
+ *
122
+ * 폭은 CSS 가 정하지만 타임라인을 펴는 것은 속성이라 CSS 로 안 된다. 같은 값을 두 곳에 적지
123
+ * 않도록 물음은 하나이고(`BESIDE`), 그 물음을 CSS 와 여기가 함께 쓴다.
124
+ */
125
+ this.beside = false;
115
126
  /**
116
127
  * 조회를 마쳤나 — **「아직 안 읽었다」와 「없다」는 다르다.**
117
128
  *
@@ -122,21 +133,85 @@ let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(
122
133
  * 조회가 끝난 뒤에만 그 말을 한다. 그 전에는 아무 말도 하지 않는다.
123
134
  */
124
135
  this.loaded = false;
136
+ /** Why the approval could not be read - ox-page-state says it, with retry (ADR-0060 decision 8). */
137
+ this.loadError = null;
138
+ this.onBeside = () => (this.beside = !!this.media?.matches);
125
139
  }
126
140
  static { this.styles = [
141
+ /* The frame owns the page shell and the reading column (ADR-0060 decision 8). */
142
+ DocumentPageStyles,
127
143
  ScrollbarStyles,
128
144
  ActivityFieldsStyles,
129
145
  css `
130
146
  :host {
147
+ color: var(--ui-ink, #17242c);
148
+ font-size: var(--ui-t-body, 13px);
149
+ }
150
+
151
+ /*
152
+ * 넓을 때만 타임라인이 옆에 선다 — **읽는 단은 줄이지 않는다.**
153
+ *
154
+ * 결재자가 판단에 쓰는 것(결정 · 사유 · 의견)이 왼쪽이고, 참고하는 것(타임라인)이 오른쪽이다.
155
+ * 처음 낸 안은 읽는 단 1080 안에서 둘로 쪼개는 것이었는데, 그러면 결정 카드가 1014 에서
156
+ * 520 으로 줄어든다 — 주된 것을 좁혀 참고용 자리를 만드는 꼴이라 물렀다.
157
+ *
158
+ * 그래서 **읽는 단을 넘는 여분이 한 판만큼 있을 때만** 편다:
159
+ *
160
+ * 1080(읽는 단) + 24(사이) + 360(최소 판) + 40(page 좌우 여백) = 1504
161
+ *
162
+ * 그 아래에서는 한 단이고 차례가 그대로다 — 결재선 · 결정 · 타임라인 · 의견. 좁은 화면이
163
+ * 기본이고 넓은 화면이 덤이다.
164
+ */
165
+ @media ${unsafeCSS(BESIDE)} {
166
+ .page {
167
+ max-width: none;
168
+ display: grid;
169
+ grid-template-columns: var(--ui-measure, 1080px) minmax(360px, 1fr);
170
+ column-gap: 24px;
171
+ align-items: start;
172
+ }
173
+
174
+ /*
175
+ * 두 판의 자리는 문서 차례가 아니라 격자가 정한다. 문서 차례는 좁은 화면 그대로 두어야
176
+ * 하고(결재선 · 결정 · 타임라인 · 의견), 넓은 화면에서만 타임라인이 오른쪽으로 빠진다.
177
+ */
178
+ .main {
179
+ grid-column: 1;
180
+ min-width: 0;
181
+ }
182
+
183
+ /* 옆에 선 타임라인은 읽는 동안 따라온다 — 결정과 맞대어 보는 값이다. */
184
+ .aside {
185
+ grid-column: 2;
186
+ grid-row: 1 / span 3;
187
+ position: sticky;
188
+ top: 0;
189
+ }
190
+ }
191
+
192
+ .comment-actions {
131
193
  display: flex;
132
- flex-direction: column;
133
- position: relative;
194
+ justify-content: flex-end;
195
+ }
134
196
 
135
- width: 100%;
136
- overflow: auto;
137
- background: var(--ui-bg, #f0f2f4);
138
- color: var(--ui-ink, #17242c);
197
+ .comment-actions button {
198
+ display: inline-flex;
199
+ align-items: center;
200
+ gap: 4px;
201
+ height: var(--form-action-height, 32px);
202
+ padding: 0 12px;
203
+ border: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));
204
+ border-radius: var(--ui-r-small, 6px);
205
+ background: transparent;
206
+ color: var(--ui-ink, var(--md-sys-color-on-surface));
207
+ font: inherit;
139
208
  font-size: var(--ui-t-body, 13px);
209
+ cursor: pointer;
210
+ }
211
+
212
+ .comment-actions md-icon {
213
+ font-size: 16px;
214
+ --md-icon-size: 16px;
140
215
  }
141
216
 
142
217
  /* 카드가 담아 주므로 안에 들어오는 화면은 자기 면과 여백을 갖지 않는다. */
@@ -348,7 +423,6 @@ let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(
348
423
  font-size: var(--ui-t-small, 11.5px);
349
424
  color: var(--ui-muted, #57676f);
350
425
  }
351
-
352
426
  `
353
427
  ]; }
354
428
  /**
@@ -371,7 +445,13 @@ let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(
371
445
  }
372
446
  get context() {
373
447
  const judgment = this.activityApproval?.judgment;
374
- return { title: this.lifecycle?.params?.['title'] || i18next.t('title.activity approval'),
448
+ return {
449
+ /*
450
+ * 이 화면이 어떤 틀인가 — 동작 줄이 이것을 읽고 자기 오른쪽 끝을 내용에 맞춘다
451
+ * (ADR-0060 결정 9 보탬). 안 적으면 창 폭이고, 그것은 작업면의 모양이다.
452
+ */
453
+ frame: 'document',
454
+ title: this.lifecycle?.params?.['title'] || i18next.t('title.activity approval'),
375
455
  help: 'worklist/activity-approval',
376
456
  /*
377
457
  * 이 화면은 메뉴에 없다 — 「내 결재함」에서 줄을 눌러 들어온다. 그래서 왼쪽 메뉴가 가리킬
@@ -392,121 +472,103 @@ let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(
392
472
  * reader looking for them.
393
473
  */
394
474
  actions: judgment
395
- ? [
396
- { title: i18next.t('button.close'),
397
- action: () => {
398
- history.back();
399
- },
400
- ...CommonButtonStyles.back
401
- }
402
- ]
475
+ ? []
403
476
  : this.isReference
404
- ? [
405
- {
406
- title: i18next.t('button.save-note'),
407
- action: this.saveActivityApproval.bind(this),
408
- icon: 'edit_note',
409
- emphasis: { raised: true, outlined: false, dense: false, danger: false }
410
- },
411
- {
412
- title: i18next.t('button.close'),
413
- action: () => {
414
- history.back();
415
- },
416
- ...CommonButtonStyles.back,
417
- icon: 'close'
418
- }
419
- ]
477
+ ? []
420
478
  : /*
421
- * ── 세 단추의 순서와 무게 (2026-09-06) ──────────────────────────
422
- * 전에는 반려가 첫 자리였고, 승인 · 반려 · 저장이 모두 같은 모양이었다. 되돌리기 어려운
423
- * 것이 앞에 서고 무엇이 주된 흐름인지 화면이 말하지 않았다.
424
- *
425
- * 승인이 주 동작이다 — 채운 단추 하나. 반려는 대등한 선택이지만 예외 경로라 테두리
426
- * 단추로 그 옆에 둔다.
427
- *
428
- * 「저장」은 이름이 뜻을 말하지 않았다. 이 단추가 저장하는 것은 **의견 하나**이고
429
- * (saveActivityApproval 은 id 와 comment 만 보낸다), 판단은 미뤄 둔다. 그리고 그 결과는
430
- * 목록에서 「메모 있음」 표식으로 나타난다(activity-cells 의 approvalMarks). 목록이
431
- * 부르는 이름과 같은 낱말로 맞춘다.
432
- */
479
+ * ── 세 단추의 순서와 무게 (2026-09-06) ──────────────────────────
480
+ * 전에는 반려가 첫 자리였고, 승인 · 반려 · 저장이 모두 같은 모양이었다. 되돌리기 어려운
481
+ * 것이 앞에 서고 무엇이 주된 흐름인지 화면이 말하지 않았다.
482
+ *
483
+ * 승인이 주 동작이다 — 채운 단추 하나. 반려는 대등한 선택이지만 예외 경로라 테두리
484
+ * 단추로 그 옆에 둔다.
485
+ *
486
+ * 「저장」은 이름이 뜻을 말하지 않았다. 이 단추가 저장하는 것은 **의견 하나**이고
487
+ * (saveActivityApproval 은 id 와 comment 만 보낸다), 판단은 미뤄 둔다. 그리고 그 결과는
488
+ * 목록에서 「메모 있음」 표식으로 나타난다(activity-cells 의 approvalMarks). 목록이
489
+ * 부르는 이름과 같은 낱말로 맞춘다.
490
+ */
433
491
  [
434
- { title: i18next.t('button.approve'),
492
+ {
493
+ title: i18next.t('button.approve'),
435
494
  action: this.approveActivityApproval.bind(this),
436
495
  icon: 'approval',
437
- emphasis: { raised: true,
438
- outlined: false,
439
- dense: false,
440
- danger: false
441
- }
496
+ emphasis: { raised: true, outlined: false, dense: false, danger: false }
442
497
  },
443
- { title: i18next.t('button.reject'),
498
+ {
499
+ title: i18next.t('button.reject'),
444
500
  action: this.rejectActivityApproval.bind(this),
445
501
  icon: 'assignment_return',
446
- emphasis: { raised: false,
447
- outlined: true,
448
- dense: false,
449
- danger: false
450
- }
451
- },
452
- { title: i18next.t('button.save-note'),
453
- action: this.saveActivityApproval.bind(this),
454
- icon: 'edit_note',
455
- emphasis: { raised: false,
456
- outlined: true,
457
- dense: false,
458
- danger: false
459
- }
502
+ emphasis: { raised: false, outlined: true, dense: false, danger: false }
460
503
  },
461
- { title: i18next.t('button.close'),
462
- action: () => {
463
- history.back();
464
- },
465
- ...CommonButtonStyles.back,
466
- icon: 'close'
467
- }
468
504
  ]
469
505
  // activityApproval: this.activityApproval
470
506
  };
471
507
  }
508
+ connectedCallback() {
509
+ super.connectedCallback();
510
+ this.media = window.matchMedia(BESIDE);
511
+ this.onBeside();
512
+ this.media.addEventListener('change', this.onBeside);
513
+ }
514
+ disconnectedCallback() {
515
+ this.media?.removeEventListener('change', this.onBeside);
516
+ super.disconnectedCallback();
517
+ }
472
518
  render() {
473
- if (!this.activityThread) {
474
- return this.loaded
519
+ /* Reading and failing both drew nothing at all, so a failure looked like an empty screen. */
520
+ return html `<div class="page">
521
+ <ox-page-state
522
+ .loading=${!this.loaded && !this.loadError}
523
+ .error=${this.loadError}
524
+ @retry=${() => this.lastId && this.fetchActivityApproval(this.lastId)}
525
+ >${this.activityThread
526
+ ? this.renderApproval()
527
+ : this.loaded
475
528
  ? html `<div empty>
476
- <span class="title">${i18next.t('text.no activity thread info')}</span>
477
- <span class="why">${i18next.t('text.no-activity-thread-why')}</span>
478
- </div>`
479
- : nothing;
480
- }
529
+ <span class="title">${i18next.t('text.no activity thread info')}</span>
530
+ <span class="why">${i18next.t('text.no-activity-thread-why')}</span>
531
+ </div>`
532
+ : nothing}</ox-page-state
533
+ >
534
+ </div>`;
535
+ }
536
+ renderApproval() {
481
537
  const { terminatedAt } = this.activityApproval;
482
538
  const editable = !terminatedAt;
483
539
  return html `
484
- <activity-approval-ribon .activityApproval=${this.activityApproval}></activity-approval-ribon>
485
- ${this.activityContent()}
540
+ <div class="main">
541
+ <activity-approval-ribon .activityApproval=${this.activityApproval}></activity-approval-ribon>
542
+ ${this.activityContent()}
543
+ </div>
486
544
  <!--
487
545
  보일 항목이 하나도 없으면 타임라인을 편다 — 그때는 화면이 「아래 타임라인의 상신 사유와
488
546
  이력을 보고 판단하세요」로 여기를 가리키므로, 접혀 있으면 그 안내가 거짓말이 된다.
547
+
548
+ 옆에 설 자리가 있을 때도 편다. 접힌 줄을 눌러 펴는 동작이, 그 줄이 이미 보이는 자리에
549
+ 있으면 하는 일이 없다.
489
550
  -->
490
551
  <activity-thread-timeline
552
+ class="aside"
491
553
  .activityThread=${this.activityThread}
492
- ?open=${!this.hasFields()}
554
+ ?open=${!this.hasFields() || this.beside}
493
555
  short-form
494
556
  ></activity-thread-timeline>
495
557
  ${editable
496
558
  ? html `
497
- <div comment>
498
- <section>
499
- <h2>${i18next.t('field.wl-comment')}</h2>
500
- <textarea
501
- placeholder=${String(i18next.t(this.isReference
559
+ <div comment class="main">
560
+ <section>
561
+ <h2>${i18next.t('field.wl-comment')}</h2>
562
+ <textarea
563
+ placeholder=${String(i18next.t(this.isReference
502
564
  ? 'text.write-your-comment-as-reference'
503
565
  : 'text.explain the reason for approval/rejection'))}
504
- .value=${this.activityApproval?.comment}
505
- @change=${(e) => {
566
+ .value=${this.activityApproval?.comment}
567
+ @change=${(e) => {
506
568
  this.activityApproval.comment = e.target.value;
507
569
  }}
508
- ></textarea>
509
- <!--
570
+ ></textarea>
571
+ <!--
510
572
  반려는 의견이 필수다(rejectActivityApproval). 전에는 그 규칙을 **누른 뒤에** 토스트로
511
573
  알렸다. 되돌릴 수 없는 것과 뜻이 다른 동작은 하기 전에 말한다.
512
574
 
@@ -514,12 +576,23 @@ let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(
514
576
  and reject buttons are absent for them and a reader whose buttons are missing
515
577
  goes looking for them.
516
578
  -->
517
- <p class="hint">
518
- ${i18next.t(this.isReference ? 'text.reference-comment-hint' : 'text.approval-comment-hint')}
519
- </p>
520
- </section>
521
- </div>
522
- `
579
+ <p class="hint">
580
+ ${i18next.t(this.isReference ? 'text.reference-comment-hint' : 'text.approval-comment-hint')}
581
+ </p>
582
+
583
+ <!--
584
+ 의견을 저장하는 단추는 의견 상자 옆이다(ADR-0060 결정 9 보탬). 동작 줄에는
585
+ 결정만 둔다 — 전에는 승인 · 반려와 같은 줄에 같은 무게로 서서 셋 다 결정처럼
586
+ 읽혔고, 좁은 화면에서는 넘침 메뉴로 밀려 반려가 숨을 수 있었다.
587
+ -->
588
+ <div class="comment-actions">
589
+ <button @click=${this.saveActivityApproval.bind(this)}>
590
+ <md-icon>edit_note</md-icon>${i18next.t('button.save-note')}
591
+ </button>
592
+ </div>
593
+ </section>
594
+ </div>
595
+ `
523
596
  : nothing}
524
597
  `;
525
598
  }
@@ -652,48 +725,48 @@ let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(
652
725
  ${subject?.found ? html `<div class="subject">${this.slotText(subject)}</div>` : ''}
653
726
  ${reason
654
727
  ? html `
655
- <div class="block">
656
- <div class="label">${i18next.t('field.reason')}</div>
657
- <div class="said ${this.hasWords(reason) ? '' : 'none'}">
658
- ${this.hasWords(reason) ? this.slotText(reason) : i18next.t('text.no-reason-given')}
728
+ <div class="block">
729
+ <div class="label">${i18next.t('field.reason')}</div>
730
+ <div class="said ${this.hasWords(reason) ? '' : 'none'}">
731
+ ${this.hasWords(reason) ? this.slotText(reason) : i18next.t('text.no-reason-given')}
732
+ </div>
659
733
  </div>
660
- </div>
661
- `
734
+ `
662
735
  : ''}
663
736
  ${this.renderReversibility(reversibility)}
664
737
  ${evidence.length
665
738
  ? html `
666
- <div class="block">
667
- <div class="label">${i18next.t('label.what-it-was-judged-from')}</div>
668
- ${evidence.map(slot => html `
669
- <div class="evidence">
670
- ${declaredLabel(slot) ? html `<div class="label">${declaredLabel(slot)}</div>` : ''}
671
- <div>${this.slotText(slot)}</div>
672
- </div>
673
- `)}
674
- </div>
675
- `
739
+ <div class="block">
740
+ <div class="label">${i18next.t('label.what-it-was-judged-from')}</div>
741
+ ${evidence.map(slot => html `
742
+ <div class="evidence">
743
+ ${declaredLabel(slot) ? html `<div class="label">${declaredLabel(slot)}</div>` : ''}
744
+ <div>${this.slotText(slot)}</div>
745
+ </div>
746
+ `)}
747
+ </div>
748
+ `
676
749
  : ''}
677
750
  ${currentState?.found
678
751
  ? html `
679
- <div class="current-state">
680
- <div class="label">${declaredLabel(currentState) || i18next.t('label.current-state')}</div>
681
- <div>${this.slotText(currentState)}</div>
682
- </div>
683
- `
752
+ <div class="current-state">
753
+ <div class="label">${declaredLabel(currentState) || i18next.t('label.current-state')}</div>
754
+ <div>${this.slotText(currentState)}</div>
755
+ </div>
756
+ `
684
757
  : ''}
685
758
  ${consequences.length
686
759
  ? html `
687
- <div class="block">
688
- <div class="label">${i18next.t('label.what-changes')}</div>
689
- ${consequences.map(slot => html `
690
- <div class="consequence">
691
- ${declaredLabel(slot) ? html `<div class="label">${declaredLabel(slot)}</div>` : ''}
692
- <div>${this.slotText(slot)}</div>
693
- </div>
694
- `)}
695
- </div>
696
- `
760
+ <div class="block">
761
+ <div class="label">${i18next.t('label.what-changes')}</div>
762
+ ${consequences.map(slot => html `
763
+ <div class="consequence">
764
+ ${declaredLabel(slot) ? html `<div class="label">${declaredLabel(slot)}</div>` : ''}
765
+ <div>${this.slotText(slot)}</div>
766
+ </div>
767
+ `)}
768
+ </div>
769
+ `
697
770
  : ''}
698
771
  </section>
699
772
  `);
@@ -731,8 +804,7 @@ let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(
731
804
  <div class="reversibility" ?irreversible=${!said.reversible}>
732
805
  <md-icon>${said.reversible ? 'undo' : 'lock'}</md-icon>
733
806
  <span
734
- >${said.caveat ||
735
- i18next.t(said.reversible ? 'text.approval-is-reversible' : 'text.approval-is-irreversible')}</span
807
+ >${said.caveat || i18next.t(said.reversible ? 'text.approval-is-reversible' : 'text.approval-is-irreversible')}</span
736
808
  >
737
809
  </div>
738
810
  `;
@@ -810,19 +882,19 @@ let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(
810
882
  return keyed(this.activityApproval.id, html `
811
883
  ${inputSpec.length
812
884
  ? html `
813
- <section readonly>
814
- <h2>${i18next.t('label.activity-input')}</h2>
815
- ${renderGiven(inputSpec, input)}
816
- </section>
817
- `
885
+ <section readonly>
886
+ <h2>${i18next.t('label.activity-input')}</h2>
887
+ ${renderGiven(inputSpec, input)}
888
+ </section>
889
+ `
818
890
  : ''}
819
891
  ${outputSpec.length
820
892
  ? html `
821
- <section readonly>
822
- <h2>${i18next.t('field.artifact')}</h2>
823
- ${renderGiven(outputSpec, output)}
824
- </section>
825
- `
893
+ <section readonly>
894
+ <h2>${i18next.t('field.artifact')}</h2>
895
+ ${renderGiven(outputSpec, output)}
896
+ </section>
897
+ `
826
898
  : ''}
827
899
  `);
828
900
  }
@@ -833,8 +905,7 @@ let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(
833
905
  const { output, activityInstance } = this.activityThread;
834
906
  const { viewSource: boardId, input } = activityInstance || {};
835
907
  if (!this.board || this.board.id !== boardId) {
836
- this.board = { id: boardId
837
- };
908
+ this.board = { id: boardId };
838
909
  }
839
910
  return keyed(this.activityApproval.id, html `
840
911
  <ox-board-viewer
@@ -917,13 +988,28 @@ let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(
917
988
  }
918
989
  }
919
990
  async fetchActivityApproval(id) {
920
- const response = await client.query({ query: gql `
991
+ this.lastId = id;
992
+ this.loadError = null;
993
+ let response;
994
+ try {
995
+ response = await client.query({
996
+ query: gql `
921
997
  query activityApproval($id: String!) { activityApproval(id: $id) ${ActivityApprovalFetchResult}
922
998
  }
923
999
  `,
924
- variables: { id
925
- }
926
- });
1000
+ variables: { id }
1001
+ });
1002
+ }
1003
+ catch (error) {
1004
+ this.loadError = error;
1005
+ return;
1006
+ }
1007
+ if (response.errors?.length || !response.data?.activityApproval) {
1008
+ this.loadError = response.errors?.length
1009
+ ? response.errors
1010
+ : new Error(i18next.t('error.activity-approval not found', { activityApproval: id }));
1011
+ return;
1012
+ }
927
1013
  this.activityApproval = response.data.activityApproval;
928
1014
  this.loaded = true;
929
1015
  this.activityThread = this.activityApproval.activityThread;
@@ -952,27 +1038,22 @@ let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(
952
1038
  async rejectActivityApproval() {
953
1039
  var { id, comment } = this.activityApproval;
954
1040
  if (!comment) {
955
- document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.enter a comment')
956
- }
957
- }));
1041
+ document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.enter a comment') } }));
958
1042
  this.commentInput.focus();
959
1043
  return;
960
1044
  }
961
- const outcome = await ranMutation(() => client.mutate({ mutation: gql `
1045
+ const outcome = await ranMutation(() => client.mutate({
1046
+ mutation: gql `
962
1047
  mutation ($id: String!, $comment: String!) { rejectActivityApproval(id: $id, comment: $comment) ${ActivityApprovalFetchResult}
963
1048
  }
964
1049
  `,
965
- variables: { id,
966
- comment
967
- }
1050
+ variables: { id, comment }
968
1051
  }));
969
1052
  if (outcome.ok) {
970
1053
  this.activityApproval = outcome.data.rejectActivityApproval;
971
1054
  this.activityThread = this.activityApproval.activityThread;
972
1055
  this.updateContext();
973
- document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_rejected_successfully')
974
- }
975
- }));
1056
+ document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_rejected_successfully') } }));
976
1057
  }
977
1058
  }
978
1059
  async approveActivityApproval() {
@@ -980,40 +1061,34 @@ let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(
980
1061
  if (!(await this.confirmIfIrreversible())) {
981
1062
  return;
982
1063
  }
983
- const outcome = await ranMutation(() => client.mutate({ mutation: gql `
1064
+ const outcome = await ranMutation(() => client.mutate({
1065
+ mutation: gql `
984
1066
  mutation ($id: String!, $comment: String) { approveActivityApproval(id: $id, comment: $comment) ${ActivityApprovalFetchResult}
985
1067
  }
986
1068
  `,
987
- variables: { id,
988
- comment
989
- }
1069
+ variables: { id, comment }
990
1070
  }));
991
1071
  if (outcome.ok) {
992
1072
  this.activityApproval = outcome.data.approveActivityApproval;
993
1073
  this.activityThread = this.activityApproval.activityThread;
994
1074
  this.updateContext();
995
- document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_approved_successfully')
996
- }
997
- }));
1075
+ document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_approved_successfully') } }));
998
1076
  }
999
1077
  }
1000
1078
  async saveActivityApproval() {
1001
1079
  var { id, comment } = this.activityApproval;
1002
- const outcome = await ranMutation(() => client.mutate({ mutation: gql `
1080
+ const outcome = await ranMutation(() => client.mutate({
1081
+ mutation: gql `
1003
1082
  mutation ($id: String!, $comment: String) { saveActivityApproval(id: $id, comment: $comment) ${ActivityApprovalFetchResult}
1004
1083
  }
1005
1084
  `,
1006
- variables: { id,
1007
- comment
1008
- }
1085
+ variables: { id, comment }
1009
1086
  }));
1010
1087
  if (outcome.ok) {
1011
1088
  this.activityApproval = outcome.data.saveActivityApproval;
1012
1089
  this.activityThread = this.activityApproval.activityThread;
1013
1090
  this.updateContext();
1014
- document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_saved_successfully')
1015
- }
1016
- }));
1091
+ document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_saved_successfully') } }));
1017
1092
  }
1018
1093
  }
1019
1094
  };
@@ -1021,10 +1096,18 @@ __decorate([
1021
1096
  state(),
1022
1097
  __metadata("design:type", Object)
1023
1098
  ], ActivityApprovalPage.prototype, "activityApproval", void 0);
1099
+ __decorate([
1100
+ state(),
1101
+ __metadata("design:type", Object)
1102
+ ], ActivityApprovalPage.prototype, "beside", void 0);
1024
1103
  __decorate([
1025
1104
  state(),
1026
1105
  __metadata("design:type", Object)
1027
1106
  ], ActivityApprovalPage.prototype, "loaded", void 0);
1107
+ __decorate([
1108
+ state(),
1109
+ __metadata("design:type", Object)
1110
+ ], ActivityApprovalPage.prototype, "loadError", void 0);
1028
1111
  __decorate([
1029
1112
  state(),
1030
1113
  __metadata("design:type", Object)