@things-factory/worklist 10.1.261 → 10.1.262

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.
@@ -0,0 +1,14 @@
1
+ import { nothing } from 'lit';
2
+ /**
3
+ * The link to the record a task is about - the page its module named as `input.sourceHref`.
4
+ *
5
+ * Both readers of a task need it: the one who carries it out (the task screen) and the one who decides it (the approval
6
+ * screen). An approval card holds a few lines of the record; the approver judges the record itself, so the link to it
7
+ * stands on both screens, drawn here once.
8
+ *
9
+ * Only an application-relative address is drawn (`sourceAddress`); a plain click stays in the app, a modified click is
10
+ * left to the browser so the record can open in another tab.
11
+ */
12
+ export declare function renderSourceLink(input: {
13
+ sourceHref?: unknown;
14
+ } | null | undefined): import("lit-html").TemplateResult<1> | typeof nothing;
@@ -0,0 +1,32 @@
1
+ import { html, nothing } from 'lit';
2
+ import { i18next } from '@operato/i18n';
3
+ import { navigate } from '@operato/shell';
4
+ import { sourceAddress } from '../../shared/task-followup.js';
5
+ /**
6
+ * The link to the record a task is about - the page its module named as `input.sourceHref`.
7
+ *
8
+ * Both readers of a task need it: the one who carries it out (the task screen) and the one who decides it (the approval
9
+ * screen). An approval card holds a few lines of the record; the approver judges the record itself, so the link to it
10
+ * stands on both screens, drawn here once.
11
+ *
12
+ * Only an application-relative address is drawn (`sourceAddress`); a plain click stays in the app, a modified click is
13
+ * left to the browser so the record can open in another tab.
14
+ */
15
+ export function renderSourceLink(input) {
16
+ const address = sourceAddress(input?.sourceHref);
17
+ if (!address)
18
+ return nothing;
19
+ return html `<p source-link>
20
+ <a
21
+ href=${address}
22
+ @click=${(event) => {
23
+ if (event.button || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)
24
+ return;
25
+ event.preventDefault();
26
+ navigate(address);
27
+ }}
28
+ >${i18next.t('button.task-open-source')}</a
29
+ >
30
+ </p>`;
31
+ }
32
+ //# sourceMappingURL=source-link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-link.js","sourceRoot":"","sources":["../../client/components/source-link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAE7D;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAkD;IACjF,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;IAChD,IAAI,CAAC,OAAO;QAAE,OAAO,OAAO,CAAA;IAE5B,OAAO,IAAI,CAAA;;aAEA,OAAO;eACL,CAAC,KAAiB,EAAE,EAAE;QAC7B,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM;YAAE,OAAM;QAC5F,KAAK,CAAC,cAAc,EAAE,CAAA;QACtB,QAAQ,CAAC,OAAO,CAAC,CAAA;IACnB,CAAC;SACE,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAC;;OAEtC,CAAA;AACP,CAAC","sourcesContent":["import { html, nothing } from 'lit'\nimport { i18next } from '@operato/i18n'\nimport { navigate } from '@operato/shell'\n\nimport { sourceAddress } from '../../shared/task-followup.js'\n\n/**\n * The link to the record a task is about - the page its module named as `input.sourceHref`.\n *\n * Both readers of a task need it: the one who carries it out (the task screen) and the one who decides it (the approval\n * screen). An approval card holds a few lines of the record; the approver judges the record itself, so the link to it\n * stands on both screens, drawn here once.\n *\n * Only an application-relative address is drawn (`sourceAddress`); a plain click stays in the app, a modified click is\n * left to the browser so the record can open in another tab.\n */\nexport function renderSourceLink(input: { sourceHref?: unknown } | null | undefined) {\n const address = sourceAddress(input?.sourceHref)\n if (!address) return nothing\n\n return html`<p source-link>\n <a\n href=${address}\n @click=${(event: MouseEvent) => {\n if (event.button || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return\n event.preventDefault()\n navigate(address)\n }}\n >${i18next.t('button.task-open-source')}</a\n >\n </p>`\n}\n"]}
@@ -23,6 +23,7 @@ import { isReferenceStep } from '@things-factory/organization/dist-client';
23
23
  import { ActivityFieldsStyles, inputSpecOf, outputSpecOf, renderGiven } from '../../components/activity-fields.js';
24
24
  import { DecisionContentStyles, DecisionKeysFields, renderDecision } from '../../components/decision-content.js';
25
25
  import { decisionSlots, slotOfRole } from '../../components/decision-slots.js';
26
+ import { renderSourceLink } from '../../components/source-link.js';
26
27
  const ActivityApprovalFetchResult = `\
27
28
  { id
28
29
  judgment
@@ -471,6 +472,8 @@ let ActivityApprovalPage = class ActivityApprovalPage extends localize(i18next)(
471
472
  return html `
472
473
  <div class="main">
473
474
  <activity-approval-ribon .activityApproval=${this.activityApproval}></activity-approval-ribon>
475
+ <!-- The card holds a few lines of the record; the approver judges the record itself. -->
476
+ ${renderSourceLink(this.activityThread?.activityInstance?.input)}
474
477
  ${this.activityContent()}
475
478
  </div>
476
479
  <!--
@@ -1 +1 @@
1
- {"version":3,"file":"activity-approval-page.js","sourceRoot":"","sources":["../../../client/pages/activity-approval/activity-approval-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/list-state/ox-page-state.js'\nimport '@operato/property-editor/ox-properties-dynamic-view.js'\nimport '@operato/board/ox-board-viewer.js'\nimport '../../components/activity-approval-ribon.js'\nimport '../../components/activity-thread-timeline.js'\n\nimport gql from 'graphql-tag'\nimport { TemplateResult, css, html, nothing, unsafeCSS } from 'lit'\nimport { DirectiveResult } from 'lit-html/directive.js'\nimport { unsafeHTML } from 'lit-html/directives/unsafe-html.js'\nimport { customElement, query, state } from 'lit/decorators.js'\nimport { keyed } from 'lit/directives/keyed.js'\nimport { MutationController, QueryController } from '@operato/graphql'\nimport { OxPrompt } from '@operato/popup'\nimport { i18next, localize } from '@operato/i18n'\nimport { mutationOutcome } from '../../components/mutation-outcome.js'\nimport { sayFailure } from '../../components/say-outcome.js'\nimport { approvalGate } from './approval-gate.js'\nimport { PageView, DraftController } from '@operato/shell'\nimport { DocumentPageStyles, ScrollbarStyles } from '@operato/styles'\nimport { provider } from '@operato/board/board-provider.js'\nimport { isReferenceStep } from '@things-factory/organization/dist-client'\n\nimport { ActivityFieldsStyles, inputSpecOf, outputSpecOf, renderGiven } from '../../components/activity-fields.js'\nimport { DecisionContentStyles, DecisionKeysFields, renderDecision } from '../../components/decision-content.js'\nimport { decisionSlots, slotOfRole } from '../../components/decision-slots.js'\n\nconst ActivityApprovalFetchResult = `\\\n{ id\n judgment\n comment\n approver { id\n name\n }\n round\n order\n createdAt\n terminatedAt\n activityThread { state\n dueAt\n assignedAt\n assignee { id\n name\n }\n updatedAt\n terminatedAt\n output\n activityApprovals { round\n order\n approver { id name\n }\n judgment\n participation\n comment\n createdAt\n updatedAt\n terminatedAt\n }\n activityThreadHistories { transaction\n reason\n updater { id name\n }\n updatedAt\n state\n output\n }\n activityInstance { id\n name\n description\n state\n activity { id\n label\n labelTKey\n ${DecisionKeysFields}\n model { name\n description\n active\n tag\n inout\n type\n unit\n options\n quantifier\n spec\n hidden\n }\n }\n approvalLine { type\n value\n participation\n notifyAfter\n approver { id\n name\n description\n controlNo\n }\n }\n thumbnail\n input\n output\n viewType\n viewSource\n dueAt\n createdAt\n } \n }\n}`\n\nexport const ActivityThreadStatus = {\n Unassigned: 'unassigned',\n Assigned: 'assigned',\n Started: 'started',\n Delegated: 'delegated',\n Ended: 'ended',\n Aborted: 'aborted'\n}\n\n/** 타임라인이 옆에 서는 폭 — 읽는 단 1080 + 사이 24 + 최소 패널 360 + page 좌우 40. */\nconst BESIDE = '(min-width: 1504px)'\n\n@customElement('activity-approval-page')\nexport class ActivityApprovalPage extends localize(i18next)(PageView) {\n static styles = [\n /* The frame owns the page shell and the reading column (ADR-0060 decision 8). */\n DocumentPageStyles,\n ScrollbarStyles,\n ActivityFieldsStyles,\n DecisionContentStyles,\n css`\n :host {\n color: var(--ui-ink, #17242c);\n font-size: var(--ui-t-body, 13px);\n }\n\n /*\n * 넓을 때만 타임라인이 옆에 선다 — **읽는 단은 줄이지 않는다.**\n *\n * 결재자가 판단에 쓰는 것(결정 · 사유 · 의견)이 왼쪽이고, 참고하는 것(타임라인)이 오른쪽이다.\n * 처음 낸 안은 읽는 단 1080 안에서 둘로 쪼개는 것이었는데, 그러면 결정 카드가 1014 에서\n * 520 으로 줄어든다 — 주된 것을 좁혀 참고용 자리를 만드는 꼴이라 물렀다.\n *\n * 그래서 **읽는 단을 넘는 여분이 한 판만큼 있을 때만** 편다:\n *\n * 1080(읽는 단) + 24(사이) + 360(최소 패널) + 40(page 좌우 여백) = 1504\n *\n * 그 아래에서는 한 단이고 차례가 그대로다 — 결재선 · 결정 · 타임라인 · 의견. 좁은 화면이\n * 기본이고 넓은 화면이 덤이다.\n */\n @media ${unsafeCSS(BESIDE)} {\n .page {\n max-width: none;\n display: grid;\n grid-template-columns: var(--ui-measure, 1080px) minmax(360px, 1fr);\n column-gap: 24px;\n align-items: start;\n }\n\n /*\n * 두 패널의 자리는 문서 차례가 아니라 격자가 정한다. 문서 차례는 좁은 화면 그대로 두어야\n * 하고(결재선 · 결정 · 타임라인 · 의견), 넓은 화면에서만 타임라인이 오른쪽으로 빠진다.\n */\n .main {\n grid-column: 1;\n min-width: 0;\n }\n\n /* 옆에 선 타임라인은 읽는 동안 따라온다 — 결정과 맞대어 보는 값이다. */\n .aside {\n grid-column: 2;\n grid-row: 1 / span 3;\n position: sticky;\n top: 0;\n }\n }\n\n .comment-actions {\n display: flex;\n justify-content: flex-end;\n }\n\n .comment-actions button {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: var(--form-action-height, 32px);\n padding: 0 12px;\n border: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));\n border-radius: var(--ui-r-small, 6px);\n background: transparent;\n color: var(--ui-ink, var(--md-sys-color-on-surface));\n font: inherit;\n font-size: var(--ui-t-body, 13px);\n cursor: pointer;\n }\n\n .comment-actions md-icon {\n font-size: 16px;\n --md-icon-size: 16px;\n }\n\n /* 카드가 담아 주므로 안에 들어오는 화면은 자기 면과 여백을 갖지 않는다. */\n /*\n * 줄어들지 않는다 — 줄어들면 본문이 잘린다.\n *\n * flex 항목인데 크기를 안 정해 두면 기본이 flex: 0 1 auto 다. **1 이 줄어든다는 뜻이다** —\n * 세로가 모자라면 브라우저가 이 칸부터 줄이는데, 여기엔 카드 모서리를 따라 자르려고\n * overflow: hidden 이 걸려 있어서 줄어든 만큼이 **스크롤도 없이 사라진다.**\n *\n * 완료 조회에서 실측했다(1400x620): 칸이 242px 로 줄고 내용은 362px 이라 「업무 내용」 절이\n * 대부분 잘렸고, 잘린 자리 바로 아래에서 타임라인이 시작하니 타임라인이 본문을 덮은 것처럼\n * 보였다. 세로가 넉넉하면 줄일 일이 없어 안 드러난다.\n *\n * 안에 오는 것은 문서다. 높이를 정해 주어야 하는 것은 board 뿐이고 board 는 이 칸을 거치지\n * 않는다(activityContent 참조). 문서는 제 높이로 서고, 모자라면 페이지 전체가 스크롤한다 —\n * :host 의 overflow: auto 가 그 자리다.\n */\n section[hosted] {\n flex: none;\n padding: 0;\n overflow: hidden;\n }\n\n ox-board-viewer {\n width: 100%;\n height: 100%;\n }\n\n activity-thread-timeline {\n margin: var(--spacing-large, 16px);\n }\n\n /*\n * 의견 칸 — 이 화면에서 **결재자가 유일하게 적는 자리**다.\n *\n * 화면 아래에 붙어 있어(sticky) 목록을 내려 읽는 동안에도 보인다. 그 자리를 지키되 모양은\n * 다른 절과 같은 카드로 둔다. 전에는 회색 면(surface-variant)에 다른 테두리라 이 화면에서\n * 혼자 다른 부품처럼 보였다.\n */\n /*\n * 의견 — 이 화면에서 **결재자가 유일하게 적는 자리**다.\n *\n * 화면 아래에 붙어 있어(sticky) 내용을 내려 읽는 동안에도 보인다. 그 자리를 지키되 모양은\n * 다른 절과 같은 카드로 둔다. 전에는 회색 면(surface-variant)에 다른 테두리라 이 화면에서\n * 혼자 다른 부품처럼 보였다.\n */\n div[comment] {\n position: sticky;\n bottom: 0;\n padding-bottom: var(--spacing-large, 16px);\n background: var(--ui-bg, #f0f2f4);\n }\n\n /*\n * 이 화면에서 **사용자가 유일하게 손대는 자리**라는 것을 모양으로 말한다.\n *\n * 나머지 절은 전부 읽는 것이고, 판단은 아래 툴바의 단추가 받는다. 그런데 의견 칸이 읽는\n * 절들과 똑같은 카드라 「내 차례가 어디인지」가 화면에 없었다. 왼쪽에 강조색 띠를 둔다 —\n * sticky 라 툴바 바로 위에 붙으므로 띠와 단추가 한 덩어리로 읽힌다.\n */\n div[comment] section {\n border-left: 3px solid var(--ui-accent, #00727e);\n }\n\n div[comment] textarea {\n display: block;\n box-sizing: border-box;\n width: 100%;\n height: 76px;\n padding: 10px 12px;\n background: var(--ui-panel, #ffffff);\n border: 1px solid var(--ui-line, #d5dce0);\n border-radius: var(--ui-r-small, 6px);\n color: var(--ui-ink, #17242c);\n font: inherit;\n font-size: var(--ui-t-body, 13px);\n resize: none;\n outline: none;\n }\n\n div[comment] textarea:focus {\n border-color: var(--ui-accent, #00727e);\n }\n\n div[comment] .hint {\n margin: 7px 0 0;\n font-size: var(--ui-t-small, 11.5px);\n color: var(--ui-faint, #8a959c);\n word-break: keep-all;\n }\n `\n ]\n\n /** The approval the address names. */\n @state() private approvalId = ''\n\n /* The approval shown, read for the id the address names (ADR-0190). */\n private approval = new QueryController(\n this,\n gql`\n query activityApproval($id: String!) {\n activityApproval(id: $id) ${ActivityApprovalFetchResult}\n }\n `,\n { variables: () => (this.approvalId ? { id: this.approvalId } : undefined) }\n )\n\n /* The opinion written here over the approval read; another approval drops it (ADR-0190 decision 2). */\n private draft = new DraftController<{ comment: string }>(this, {\n read: () => this.activityApproval,\n key: () => this.approvalId\n })\n\n /*\n * The changes made here: each reads what it changed again once done. This screen says its own failure\n * (sayFailure), so the GraphQL link stays quiet about it (ADR-0190).\n */\n private reject = new MutationController(\n this,\n gql`\n mutation ($id: String!, $comment: String!) {\n rejectActivityApproval(id: $id, comment: $comment) {\n id\n }\n }\n `,\n { refetch: () => [this.approval], showsError: true }\n )\n\n private approve = new MutationController(\n this,\n gql`\n mutation ($id: String!, $comment: String) {\n approveActivityApproval(id: $id, comment: $comment) {\n id\n }\n }\n `,\n { refetch: () => [this.approval], showsError: true }\n )\n\n private save = new MutationController(\n this,\n gql`\n mutation ($id: String!, $comment: String) {\n saveActivityApproval(id: $id, comment: $comment) {\n id\n }\n }\n `,\n { refetch: () => [this.approval], showsError: true }\n )\n\n get activityApproval(): any {\n return this.approval.data?.activityApproval\n }\n\n get activityThread(): any {\n return this.activityApproval?.activityThread\n }\n\n /**\n * 타임라인이 옆에 설 만큼 넓은가.\n *\n * 폭은 CSS 가 정하지만 타임라인을 펴는 것은 속성이라 CSS 로 안 된다. 같은 값을 두 곳에 적지\n * 않도록 물음은 하나이고(`BESIDE`), 그 물음을 CSS 와 여기가 함께 쓴다.\n */\n @state() private beside = false\n\n /**\n * 조회를 마쳤나 — **「아직 안 읽었다」와 「없다」는 다르다.**\n *\n * 전에는 값이 없으면 곧바로 「업무활동 정보가 없습니다」를 그렸다. 그런데 이 화면은 열리자마자\n * 조회를 시작하므로, 응답이 오기 전까지 **없다고 단언하는 화면**이 보인다. 목록에서 줄을 눌러\n * 들어온 사람은 방금 본 건이 없다는 말을 먼저 읽는다.\n *\n * 조회가 끝난 뒤에만 그 말을 한다. 그 전에는 아무 말도 하지 않는다.\n */\n get loaded(): boolean {\n return this.approval.data !== undefined\n }\n\n /** Why the approval could not be read - ox-page-state says it, with retry (ADR-0060 decision 8). */\n get loadError(): unknown {\n return (\n this.approval.error ??\n (this.loaded && !this.activityApproval\n ? new Error(i18next.t('error.activity-approval not found', { activityApproval: this.approvalId }))\n : null)\n )\n }\n\n @state() board: any\n /** The custom element and the approval read it was made for: another answer makes it again. */\n private custom?: { for: any; element: any }\n\n @query('textarea') commentInput!: HTMLTextAreaElement\n\n /**\n * Is the reader seated here as a reference — someone who comments and does not decide?\n *\n * The rule comes from organization's client types, the same function its own approval-line editor\n * and list use, so the two wire spellings of the enum are handled in one place. The approval line\n * answers rather than ActivityApproval.participation, matching what the server refuses on\n * (isReferenceOrder in approval-line.ts): the line decides who comes next, so letting the row\n * decide who may judge would leave two authorities with nothing to settle a disagreement.\n *\n * The value comes back false while the query is still out. That is the same answer as for an\n * approver, so the buttons show for a moment on a reference's screen — pressing one is refused by\n * the server, which is why the server closed first.\n */\n get isReference(): boolean {\n const approvalLine = this.activityThread?.activityInstance?.approvalLine\n const order = Number(this.activityApproval?.order ?? 0)\n\n return isReferenceStep(approvalLine?.[order - 1])\n }\n\n get context() {\n const judgment = this.activityApproval?.judgment\n\n return {\n /*\n * 이 화면이 어떤 틀인가 — 동작 줄이 이것을 읽고 자기 오른쪽 끝을 내용에 맞춘다\n * (ADR-0060 결정 9 보탬). 안 적으면 창 폭이고, 그것은 작업면의 모양이다.\n */\n frame: 'document',\n title: this.lifecycle?.params?.['title'] || i18next.t('title.activity approval'),\n help: 'worklist/activity-approval',\n /*\n * 이 화면은 메뉴에 없다 — 「내 결재함」에서 줄을 눌러 들어온다. 그래서 왼쪽 메뉴가 가리킬\n * 항목이 없고, 표시가 사라져 들어온 사람이 자기가 어디에 있는지 잃는다.\n *\n * 어느 목록에서 열리는지는 이 화면이 안다. 그것을 적어 둔다.\n */\n menu: 'approval-pending-list',\n /*\n * A reference is offered neither approve nor reject.\n *\n * ActivityApprovalJudgment has carried Closed for this seat from the start — \"the case ended\"\n * rather than a judgment — so a reference row was never meant to end in approved or rejected.\n * The buttons were offered anyway, and the server accepted them until 2026-09-09.\n *\n * What stays is the note, because a comment is the whole point of the seat, and close. The\n * hint under the textarea says which seat this is; buttons that simply vanish leave the\n * reader looking for them.\n */\n actions: judgment\n ? []\n : this.isReference\n ? []\n : /*\n * ── 결정 단추의 순서와 무게 (ADR-0060 결정 9 보탬) ─────────────\n * 전에는 반려가 첫 자리였고, 승인 · 반려 · 저장이 모두 같은 모양이었다. 되돌리기 어려운\n * 것이 앞에 서고 무엇이 주된 흐름인지 화면이 말하지 않았다.\n *\n * 승인이 주 동작이다 — 채운 단추 하나. 반려는 대등한 선택이지만 예외 경로라 테두리\n * 단추로 그 옆에 둔다.\n *\n * 「저장」은 이름이 뜻을 말하지 않았다. 이 단추가 저장하는 것은 **의견 하나**이고\n * (saveActivityApproval 은 id 와 comment 만 보낸다), 판단은 미뤄 둔다. 그리고 그 결과는\n * 목록에서 「메모 있음」 표식으로 나타난다(activity-cells 의 approvalMarks).\n * 메모 저장은 아래 의견 상자 옆에 두고, 이 줄에는 승인·반려만 둔다.\n */\n [\n {\n title: i18next.t('button.approve'),\n action: this.approveActivityApproval.bind(this),\n icon: 'approval',\n emphasis: { raised: true, outlined: false, dense: false, danger: false }\n },\n\n {\n title: i18next.t('button.reject'),\n action: this.rejectActivityApproval.bind(this),\n icon: 'assignment_return',\n emphasis: { raised: false, outlined: true, dense: false, danger: false }\n },\n\n ]\n // activityApproval: this.activityApproval\n }\n }\n\n private media?: MediaQueryList\n private onBeside = () => (this.beside = !!this.media?.matches)\n\n connectedCallback() {\n super.connectedCallback()\n this.media = window.matchMedia(BESIDE)\n this.onBeside()\n this.media.addEventListener('change', this.onBeside)\n }\n\n disconnectedCallback() {\n this.media?.removeEventListener('change', this.onBeside)\n super.disconnectedCallback()\n }\n\n render() {\n /* Reading and failing both drew nothing at all, so a failure looked like an empty screen. */\n return html`<div class=\"page\">\n <ox-page-state\n .loading=${!this.loaded && !this.loadError}\n .error=${this.loadError}\n @retry=${() => this.approval.refetch()}\n >${\n this.activityThread\n ? this.renderApproval()\n : this.loaded\n ? html`<div empty>\n <span class=\"title\">${i18next.t('text.no activity thread info')}</span>\n <span class=\"why\">${i18next.t('text.no-activity-thread-why')}</span>\n </div>`\n : nothing\n }</ox-page-state\n >\n </div>`\n }\n\n private renderApproval() {\n const { terminatedAt } = this.activityApproval\n const editable = !terminatedAt\n\n return html`\n <div class=\"main\">\n <activity-approval-ribon .activityApproval=${this.activityApproval}></activity-approval-ribon>\n ${this.activityContent()}\n </div>\n <!--\n 보일 항목이 하나도 없으면 타임라인을 편다 — 그때는 화면이 「아래 타임라인의 상신 사유와\n 이력을 보고 판단하세요」로 여기를 가리키므로, 접혀 있으면 그 안내가 거짓말이 된다.\n\n 옆에 설 자리가 있을 때도 편다. 접힌 줄을 눌러 펴는 동작이, 그 줄이 이미 보이는 자리에\n 있으면 하는 일이 없다.\n -->\n <activity-thread-timeline\n class=\"aside\"\n .activityThread=${this.activityThread}\n ?open=${!this.hasFields() || this.beside}\n short-form\n ></activity-thread-timeline>\n ${\n editable\n ? html`\n <div comment class=\"main\">\n <section>\n <h2>${i18next.t('field.wl-comment')}</h2>\n <textarea\n placeholder=${String(\n i18next.t(\n this.isReference\n ? 'text.write-your-comment-as-reference'\n : 'text.explain the reason for approval/rejection'\n )\n )}\n .value=${this.draft.value('comment') ?? ''}\n @input=${(e: Event) => this.draft.set('comment', (e.target as HTMLTextAreaElement).value)}\n ></textarea>\n <!--\n 반려는 의견이 필수다(rejectActivityApproval). 전에는 그 규칙을 **누른 뒤에** 토스트로\n 알렸다. 되돌릴 수 없는 것과 뜻이 다른 동작은 하기 전에 말한다.\n\n A reference reads a different line: this one names the seat, because the approve\n and reject buttons are absent for them and a reader whose buttons are missing\n goes looking for them.\n -->\n <p class=\"hint\">\n ${i18next.t(this.isReference ? 'text.reference-comment-hint' : 'text.approval-comment-hint')}\n </p>\n\n <!--\n 의견을 저장하는 단추는 의견 상자 옆이다(ADR-0060 결정 9 보탬). 동작 줄에는\n 결정만 둔다 — 전에는 승인 · 반려와 같은 줄에 같은 무게로 서서 셋 다 결정처럼\n 읽혔고, 좁은 화면에서는 넘침 메뉴로 밀려 반려가 숨을 수 있었다.\n -->\n <div class=\"comment-actions\">\n <button @click=${this.saveActivityApproval.bind(this)}>\n <md-icon>edit_note</md-icon>${i18next.t('button.save-note')}\n </button>\n </div>\n </section>\n </div>\n `\n : nothing\n }\n `\n }\n\n /** 화면에 낼 항목이 하나라도 있나. 타임라인을 펴 둘지 정하는 자리가 쓴다. */\n hasFields(): boolean {\n const model = this.activityThread?.activityInstance?.activity?.model\n\n return inputSpecOf(model).length > 0 || outputSpecOf(model).length > 0\n }\n\n activityContent() {\n switch (this.activityThread?.activityInstance?.viewType) {\n case 'template':\n return this.hostedContent(this.templateContent())\n case 'generated':\n return this.generatedContent()\n /* board 는 전체 화면을 쓰는 캔버스라 카드에 담지 않는다(hostedContent 머리말). */\n case 'board':\n return this.boardContent()\n case 'custom-element': {\n /*\n * The wrapper is for the element, not for the notice.\n *\n * hostedContent puts the content in a card so every ui type sits at the same place with the\n * same frame. The not-loaded notice is already a card — wrapping it drew a card inside a\n * card, two borders deep, and its margins landed unevenly: 16 above and none below, inside\n * a box that had its own padding. The generated branch returns the same notice unwrapped\n * and looks right.\n */\n const { viewSource: tagName } = this.activityThread?.activityInstance || {}\n\n /*\n * Naming no element is not the same as naming one that is missing.\n *\n * A template that stops providing a screen clears the field — installActivity does not\n * blank what a template leaves undefined, so clearing is written as null. That left\n * viewType saying custom-element with nothing named, and this branch answered \"the\n * screen could not be loaded\": a failure, for an activity that simply has no screen of its\n * own. Those read as different things to whoever is approving, and the second one is not\n * true.\n *\n * With nothing named, the generated screen is what this activity has — and it draws a\n * decision when the activity declares one, which the two plant forms that hit this do.\n */\n if (!tagName) {\n return this.generatedContent()\n }\n\n const element = this.customElementContent()\n\n return element ? this.hostedContent(element) : this.screenNotLoaded()\n }\n case 'page':\n case 'external':\n return html``\n default:\n return this.generatedContent()\n }\n }\n\n /**\n * 화면 종류가 달라도 **같은 자리에 같은 모양으로 놓인다.**\n *\n * worklist 는 네 가지로 내용을 그린다(generated · custom-element · template · board). 그중\n * generated 만 절 카드 안에 있었고 나머지 셋은 면 위에 맨몸으로 놓였다. 그래서 같은 결재 화면이\n * 액티비티에 따라 카드였다가 아니었다가 했다 — 아래의 타임라인 · 의견은 늘 카드라 위계도 어긋났다.\n *\n * board 는 뺀다. 전체 폭 · 전체 높이를 쓰는 캔버스라 카드 안에 넣으면 여백이 두 겹이 되고 크기가\n * 어긋난다.\n *\n * 카드는 여백을 두지 않는다(padding: 0). 안에 들어오는 것이 자기 조판을 갖고 있고, 두 겹으로\n * 주면 안쪽 내용이 카드 가운데로 밀린다.\n */\n hostedContent(content: unknown) {\n return html`<section hosted>${content}</section>`\n }\n\n templateContent() {\n if (!this.activityApproval) {\n return html``\n }\n\n const { viewSource: template } = this.activityThread?.activityInstance\n return unsafeHTML(template)\n }\n\n /**\n * 결재자가 보는 내용 — **전부 읽기 전용이다.**\n *\n * 전에는 「Output」 절을 편집기로 그리고 변경을 activityApproval.output 에 적었다. 그런데\n * approveActivityApproval / rejectActivityApproval 은 id 와 comment 만 보낸다 — 그 값은 어디에도\n * 가지 않는다. 결재자가 적을 수 있는 것은 의견 하나이고, 그것은 화면 아래 칸이 받는다.\n */\n /** The decision the activity declared, or nothing - drawn by `renderDecision`, the one drawing both screens use. */\n decisionContent() {\n const { activityInstance } = this.activityThread || {}\n const decision = renderDecision(activityInstance?.activity?.decisionKeys, activityInstance?.input)\n\n return decision === nothing ? nothing : keyed(this.activityApproval.id, decision)\n }\n\n generatedContent(): DirectiveResult {\n if (!this.activityApproval) {\n return html``\n }\n\n const { output, activityInstance } = this.activityThread || {}\n const { input } = activityInstance || {}\n\n /*\n * The declaration goes first. It answers \"what happens if I approve\", which is the question this\n * screen exists for; the model answers \"what are the values\", which is the fallback.\n */\n const decision = this.decisionContent()\n\n if (decision !== nothing) {\n return decision as DirectiveResult\n }\n\n const model = activityInstance?.activity?.model\n const inputSpec = inputSpecOf(model)\n const outputSpec = outputSpecOf(model)\n\n /*\n * **결재 화면에서 내용이 비어 있는 것은 경고다.**\n *\n * 업무 상세라면 「적을 것이 없다」로 끝난다. 여기서는 다르다 — 무엇을 승인하는지 모르는 채로\n * 승인 · 반려 버튼이 그대로 눌린다. 그 사실을 화면이 말하고, 대신 무엇을 보고 판단할지 알려\n * 준다(타임라인의 상신 사유).\n */\n if (!inputSpec.length && !outputSpec.length) {\n return keyed(\n this.activityApproval.id,\n html`<section empty>\n <span class=\"title\">${i18next.t('text.no-approval-content')}</span>\n <span class=\"why\">${i18next.t('text.no-approval-content-why')}</span>\n </section>`\n )\n }\n\n return keyed(\n this.activityApproval.id,\n html`\n ${\n inputSpec.length\n ? html`\n <section readonly>\n <h2>${i18next.t('label.activity-input')}</h2>\n ${renderGiven(inputSpec, input)}\n </section>\n `\n : ''\n }\n ${\n outputSpec.length\n ? html`\n <section readonly>\n <h2>${i18next.t('field.artifact')}</h2>\n ${renderGiven(outputSpec, output)}\n </section>\n `\n : ''\n }\n `\n )\n }\n\n boardContent(): DirectiveResult {\n if (!this.activityApproval) {\n return html``\n }\n\n const { output, activityInstance } = this.activityThread\n const { viewSource: boardId, input } = activityInstance || {}\n\n if (!this.board || this.board.id !== boardId) {\n this.board = { id: boardId }\n }\n\n return keyed(\n this.activityApproval.id,\n html`\n <ox-board-viewer\n style=\"background-color: white;\"\n .board=${this.board}\n .provider=${provider}\n .values=${{ ...input, ...output }}\n hide-fullscreen\n hide-navigation\n ></ox-board-viewer>\n `\n )\n }\n\n /**\n * The element the activity names, or a plain statement that it could not be loaded.\n *\n * document.createElement answers something for any name, so an activity pointing at an element\n * nobody registered used to produce an empty card. The approver got a screen with nothing on it\n * and the approve button still worked — plant shipped two such forms in one day and found them by\n * reading the file list, not by opening the screen.\n *\n * The reader is told what to judge by instead. Same shape as the empty generated screen: what is\n * missing, and where to look — the submission reason and the history in the timeline below.\n *\n * ── Waiting for a late definition ─────────────────────────────────────────\n * An element can be registered after this page renders, and answering \"not loaded\" forever in\n * that case would be a screen inventing a defect. whenDefined resolves whenever it arrives and\n * the page redraws; a name nobody ever registers simply never resolves, and the statement stands.\n */\n customElementContent() {\n if (!this.activityApproval) {\n return html``\n }\n\n const { output, activityInstance } = this.activityThread\n const { viewSource: tagName, input } = activityInstance || {}\n\n if (!customElements.get(tagName)) {\n customElements.whenDefined(tagName).then(() => this.requestUpdate())\n\n /* The caller draws the notice — unwrapped, because the notice is its own card. */\n return undefined\n }\n\n /* Made once per answer: the opinion typed below redraws the page, and the element shows the same approval. */\n if (this.custom && this.custom.for === this.activityApproval) {\n return this.custom.element\n }\n\n const element = document.createElement(tagName)\n element.id = 'custom-content'\n element.activityId = activityInstance.activity.id\n element.input = input\n element.output = output\n element.activityApproval = this.activityApproval\n\n this.custom = { for: this.activityApproval, element }\n return element\n }\n\n /** The activity names a screen and nothing registered it. Says what to judge by instead. */\n private screenNotLoaded() {\n return html`<section empty>\n <span class=\"title\">${i18next.t('text.approval-view-not-loaded')}</span>\n <span class=\"why\">${i18next.t('text.no-approval-content-why')}</span>\n </section>`\n }\n\n @query('ox-board-viewer') oxBoardViewer: any\n\n getOutputFromBoard() {\n const outputSpec = outputSpecOf(this.activityThread?.activityInstance?.activity?.model)\n const data = this.oxBoardViewer.getSceneValues()\n\n return outputSpec.reduce((output, spec) => {\n output[spec.name] = data[spec.name]\n return output\n }, {})\n }\n\n /**\n * 화면이 열리면 **의견 칸에 캐럿을 둔다.**\n *\n * 결재자가 이 화면에서 적는 것은 의견 하나다. 나머지는 전부 읽는 것이고, 판단은 아래 버튼이\n * 받는다. 그러면 열자마자 커서가 있어야 하는 자리는 하나뿐이다.\n *\n * 조건 둘을 지킨다.\n *\n * 활성 탭일 때만 MDI 라 뒤에 있는 탭이 응답을 받으면 앞 탭의 입력을 빼앗는다\n * 한 건에 한 번 갱신마다 focus 를 부르면 사용자가 옮긴 커서를 계속 되돌린다\n *\n * preventScroll 을 준다 — 화면을 아래로 끌어내리면 정작 무엇을 승인하는지가 위로 사라진다.\n */\n private focusedFor?: string\n\n private focusComment() {\n const id = this.activityApproval?.id\n\n if (!id || !this.active || this.activityApproval?.terminatedAt || this.focusedFor === id) {\n return\n }\n\n this.commentInput?.focus({ preventScroll: true })\n this.focusedFor = id\n }\n\n updated() {\n this.focusComment()\n }\n\n async pageUpdated(changes, lifecycle, changedBefore) {\n if (this.active && lifecycle.resourceId) {\n /* Entity 360 changes only the query address: the same approval is not read again, and its unsaved opinion stays. */\n /* Coming back to the tab, PageView reads the declared approval again; the opinion typed stays (the draft). */\n if (this.approvalId !== lifecycle.resourceId) this.approvalId = lifecycle.resourceId\n }\n }\n\n /*\n * The approval declared that it cannot be undone: ask once, as a destructive confirmation, before\n * sending it. Reversible and undeclared approvals go straight through, as before.\n */\n async confirmIfIrreversible(): Promise<boolean> {\n const { activityInstance } = this.activityThread || {}\n const slots = decisionSlots(activityInstance?.activity?.decisionKeys, activityInstance?.input)\n const gate = approvalGate(slotOfRole(slots, 'reversibility'))\n\n if (!gate.ask) {\n return true\n }\n\n return await OxPrompt.open({\n type: 'warning',\n title: i18next.t('text.approval-is-irreversible'),\n text: gate.caveat,\n /* From the declaration, not a literal: this screen does not decide what is irreversible. */\n confirmButton: { text: i18next.t('button.approve'), destructive: gate.ask },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n }\n\n /*\n * Each decision sends the opinion written now and reads the approval again once it went through; its answer is not\n * kept (ADR-0190 decision 2). The opinion sent is cleared then, and a failure keeps it.\n */\n async rejectActivityApproval() {\n const { id } = this.activityApproval\n const comment = this.draft.value('comment')\n\n if (!comment) {\n document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.enter a comment') } }))\n this.commentInput.focus()\n return\n }\n\n const rejected = await this.draft.submit(() => this.reject.run({ id, comment }))\n\n if (!rejected) {\n sayFailure(mutationOutcome(this.reject.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_rejected_successfully') } })\n )\n }\n\n async approveActivityApproval() {\n const { id } = this.activityApproval\n const comment = this.draft.value('comment')\n\n if (!(await this.confirmIfIrreversible())) {\n return\n }\n\n const approved = await this.draft.submit(() => this.approve.run({ id, comment }))\n\n if (!approved) {\n sayFailure(mutationOutcome(this.approve.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_approved_successfully') } })\n )\n }\n\n async saveActivityApproval() {\n const { id } = this.activityApproval\n const comment = this.draft.value('comment')\n\n const saved = await this.draft.submit(() => this.save.run({ id, comment }))\n\n if (!saved) {\n sayFailure(mutationOutcome(this.save.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_saved_successfully') } })\n )\n }\n}\n"]}
1
+ {"version":3,"file":"activity-approval-page.js","sourceRoot":"","sources":["../../../client/pages/activity-approval/activity-approval-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/list-state/ox-page-state.js'\nimport '@operato/property-editor/ox-properties-dynamic-view.js'\nimport '@operato/board/ox-board-viewer.js'\nimport '../../components/activity-approval-ribon.js'\nimport '../../components/activity-thread-timeline.js'\n\nimport gql from 'graphql-tag'\nimport { TemplateResult, css, html, nothing, unsafeCSS } from 'lit'\nimport { DirectiveResult } from 'lit-html/directive.js'\nimport { unsafeHTML } from 'lit-html/directives/unsafe-html.js'\nimport { customElement, query, state } from 'lit/decorators.js'\nimport { keyed } from 'lit/directives/keyed.js'\nimport { MutationController, QueryController } from '@operato/graphql'\nimport { OxPrompt } from '@operato/popup'\nimport { i18next, localize } from '@operato/i18n'\nimport { mutationOutcome } from '../../components/mutation-outcome.js'\nimport { sayFailure } from '../../components/say-outcome.js'\nimport { approvalGate } from './approval-gate.js'\nimport { PageView, DraftController } from '@operato/shell'\nimport { DocumentPageStyles, ScrollbarStyles } from '@operato/styles'\nimport { provider } from '@operato/board/board-provider.js'\nimport { isReferenceStep } from '@things-factory/organization/dist-client'\n\nimport { ActivityFieldsStyles, inputSpecOf, outputSpecOf, renderGiven } from '../../components/activity-fields.js'\nimport { DecisionContentStyles, DecisionKeysFields, renderDecision } from '../../components/decision-content.js'\nimport { decisionSlots, slotOfRole } from '../../components/decision-slots.js'\nimport { renderSourceLink } from '../../components/source-link.js'\n\nconst ActivityApprovalFetchResult = `\\\n{ id\n judgment\n comment\n approver { id\n name\n }\n round\n order\n createdAt\n terminatedAt\n activityThread { state\n dueAt\n assignedAt\n assignee { id\n name\n }\n updatedAt\n terminatedAt\n output\n activityApprovals { round\n order\n approver { id name\n }\n judgment\n participation\n comment\n createdAt\n updatedAt\n terminatedAt\n }\n activityThreadHistories { transaction\n reason\n updater { id name\n }\n updatedAt\n state\n output\n }\n activityInstance { id\n name\n description\n state\n activity { id\n label\n labelTKey\n ${DecisionKeysFields}\n model { name\n description\n active\n tag\n inout\n type\n unit\n options\n quantifier\n spec\n hidden\n }\n }\n approvalLine { type\n value\n participation\n notifyAfter\n approver { id\n name\n description\n controlNo\n }\n }\n thumbnail\n input\n output\n viewType\n viewSource\n dueAt\n createdAt\n } \n }\n}`\n\nexport const ActivityThreadStatus = {\n Unassigned: 'unassigned',\n Assigned: 'assigned',\n Started: 'started',\n Delegated: 'delegated',\n Ended: 'ended',\n Aborted: 'aborted'\n}\n\n/** 타임라인이 옆에 서는 폭 — 읽는 단 1080 + 사이 24 + 최소 패널 360 + page 좌우 40. */\nconst BESIDE = '(min-width: 1504px)'\n\n@customElement('activity-approval-page')\nexport class ActivityApprovalPage extends localize(i18next)(PageView) {\n static styles = [\n /* The frame owns the page shell and the reading column (ADR-0060 decision 8). */\n DocumentPageStyles,\n ScrollbarStyles,\n ActivityFieldsStyles,\n DecisionContentStyles,\n css`\n :host {\n color: var(--ui-ink, #17242c);\n font-size: var(--ui-t-body, 13px);\n }\n\n /*\n * 넓을 때만 타임라인이 옆에 선다 — **읽는 단은 줄이지 않는다.**\n *\n * 결재자가 판단에 쓰는 것(결정 · 사유 · 의견)이 왼쪽이고, 참고하는 것(타임라인)이 오른쪽이다.\n * 처음 낸 안은 읽는 단 1080 안에서 둘로 쪼개는 것이었는데, 그러면 결정 카드가 1014 에서\n * 520 으로 줄어든다 — 주된 것을 좁혀 참고용 자리를 만드는 꼴이라 물렀다.\n *\n * 그래서 **읽는 단을 넘는 여분이 한 판만큼 있을 때만** 편다:\n *\n * 1080(읽는 단) + 24(사이) + 360(최소 패널) + 40(page 좌우 여백) = 1504\n *\n * 그 아래에서는 한 단이고 차례가 그대로다 — 결재선 · 결정 · 타임라인 · 의견. 좁은 화면이\n * 기본이고 넓은 화면이 덤이다.\n */\n @media ${unsafeCSS(BESIDE)} {\n .page {\n max-width: none;\n display: grid;\n grid-template-columns: var(--ui-measure, 1080px) minmax(360px, 1fr);\n column-gap: 24px;\n align-items: start;\n }\n\n /*\n * 두 패널의 자리는 문서 차례가 아니라 격자가 정한다. 문서 차례는 좁은 화면 그대로 두어야\n * 하고(결재선 · 결정 · 타임라인 · 의견), 넓은 화면에서만 타임라인이 오른쪽으로 빠진다.\n */\n .main {\n grid-column: 1;\n min-width: 0;\n }\n\n /* 옆에 선 타임라인은 읽는 동안 따라온다 — 결정과 맞대어 보는 값이다. */\n .aside {\n grid-column: 2;\n grid-row: 1 / span 3;\n position: sticky;\n top: 0;\n }\n }\n\n .comment-actions {\n display: flex;\n justify-content: flex-end;\n }\n\n .comment-actions button {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: var(--form-action-height, 32px);\n padding: 0 12px;\n border: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));\n border-radius: var(--ui-r-small, 6px);\n background: transparent;\n color: var(--ui-ink, var(--md-sys-color-on-surface));\n font: inherit;\n font-size: var(--ui-t-body, 13px);\n cursor: pointer;\n }\n\n .comment-actions md-icon {\n font-size: 16px;\n --md-icon-size: 16px;\n }\n\n /* 카드가 담아 주므로 안에 들어오는 화면은 자기 면과 여백을 갖지 않는다. */\n /*\n * 줄어들지 않는다 — 줄어들면 본문이 잘린다.\n *\n * flex 항목인데 크기를 안 정해 두면 기본이 flex: 0 1 auto 다. **1 이 줄어든다는 뜻이다** —\n * 세로가 모자라면 브라우저가 이 칸부터 줄이는데, 여기엔 카드 모서리를 따라 자르려고\n * overflow: hidden 이 걸려 있어서 줄어든 만큼이 **스크롤도 없이 사라진다.**\n *\n * 완료 조회에서 실측했다(1400x620): 칸이 242px 로 줄고 내용은 362px 이라 「업무 내용」 절이\n * 대부분 잘렸고, 잘린 자리 바로 아래에서 타임라인이 시작하니 타임라인이 본문을 덮은 것처럼\n * 보였다. 세로가 넉넉하면 줄일 일이 없어 안 드러난다.\n *\n * 안에 오는 것은 문서다. 높이를 정해 주어야 하는 것은 board 뿐이고 board 는 이 칸을 거치지\n * 않는다(activityContent 참조). 문서는 제 높이로 서고, 모자라면 페이지 전체가 스크롤한다 —\n * :host 의 overflow: auto 가 그 자리다.\n */\n section[hosted] {\n flex: none;\n padding: 0;\n overflow: hidden;\n }\n\n ox-board-viewer {\n width: 100%;\n height: 100%;\n }\n\n activity-thread-timeline {\n margin: var(--spacing-large, 16px);\n }\n\n /*\n * 의견 칸 — 이 화면에서 **결재자가 유일하게 적는 자리**다.\n *\n * 화면 아래에 붙어 있어(sticky) 목록을 내려 읽는 동안에도 보인다. 그 자리를 지키되 모양은\n * 다른 절과 같은 카드로 둔다. 전에는 회색 면(surface-variant)에 다른 테두리라 이 화면에서\n * 혼자 다른 부품처럼 보였다.\n */\n /*\n * 의견 — 이 화면에서 **결재자가 유일하게 적는 자리**다.\n *\n * 화면 아래에 붙어 있어(sticky) 내용을 내려 읽는 동안에도 보인다. 그 자리를 지키되 모양은\n * 다른 절과 같은 카드로 둔다. 전에는 회색 면(surface-variant)에 다른 테두리라 이 화면에서\n * 혼자 다른 부품처럼 보였다.\n */\n div[comment] {\n position: sticky;\n bottom: 0;\n padding-bottom: var(--spacing-large, 16px);\n background: var(--ui-bg, #f0f2f4);\n }\n\n /*\n * 이 화면에서 **사용자가 유일하게 손대는 자리**라는 것을 모양으로 말한다.\n *\n * 나머지 절은 전부 읽는 것이고, 판단은 아래 툴바의 단추가 받는다. 그런데 의견 칸이 읽는\n * 절들과 똑같은 카드라 「내 차례가 어디인지」가 화면에 없었다. 왼쪽에 강조색 띠를 둔다 —\n * sticky 라 툴바 바로 위에 붙으므로 띠와 단추가 한 덩어리로 읽힌다.\n */\n div[comment] section {\n border-left: 3px solid var(--ui-accent, #00727e);\n }\n\n div[comment] textarea {\n display: block;\n box-sizing: border-box;\n width: 100%;\n height: 76px;\n padding: 10px 12px;\n background: var(--ui-panel, #ffffff);\n border: 1px solid var(--ui-line, #d5dce0);\n border-radius: var(--ui-r-small, 6px);\n color: var(--ui-ink, #17242c);\n font: inherit;\n font-size: var(--ui-t-body, 13px);\n resize: none;\n outline: none;\n }\n\n div[comment] textarea:focus {\n border-color: var(--ui-accent, #00727e);\n }\n\n div[comment] .hint {\n margin: 7px 0 0;\n font-size: var(--ui-t-small, 11.5px);\n color: var(--ui-faint, #8a959c);\n word-break: keep-all;\n }\n `\n ]\n\n /** The approval the address names. */\n @state() private approvalId = ''\n\n /* The approval shown, read for the id the address names (ADR-0190). */\n private approval = new QueryController(\n this,\n gql`\n query activityApproval($id: String!) {\n activityApproval(id: $id) ${ActivityApprovalFetchResult}\n }\n `,\n { variables: () => (this.approvalId ? { id: this.approvalId } : undefined) }\n )\n\n /* The opinion written here over the approval read; another approval drops it (ADR-0190 decision 2). */\n private draft = new DraftController<{ comment: string }>(this, {\n read: () => this.activityApproval,\n key: () => this.approvalId\n })\n\n /*\n * The changes made here: each reads what it changed again once done. This screen says its own failure\n * (sayFailure), so the GraphQL link stays quiet about it (ADR-0190).\n */\n private reject = new MutationController(\n this,\n gql`\n mutation ($id: String!, $comment: String!) {\n rejectActivityApproval(id: $id, comment: $comment) {\n id\n }\n }\n `,\n { refetch: () => [this.approval], showsError: true }\n )\n\n private approve = new MutationController(\n this,\n gql`\n mutation ($id: String!, $comment: String) {\n approveActivityApproval(id: $id, comment: $comment) {\n id\n }\n }\n `,\n { refetch: () => [this.approval], showsError: true }\n )\n\n private save = new MutationController(\n this,\n gql`\n mutation ($id: String!, $comment: String) {\n saveActivityApproval(id: $id, comment: $comment) {\n id\n }\n }\n `,\n { refetch: () => [this.approval], showsError: true }\n )\n\n get activityApproval(): any {\n return this.approval.data?.activityApproval\n }\n\n get activityThread(): any {\n return this.activityApproval?.activityThread\n }\n\n /**\n * 타임라인이 옆에 설 만큼 넓은가.\n *\n * 폭은 CSS 가 정하지만 타임라인을 펴는 것은 속성이라 CSS 로 안 된다. 같은 값을 두 곳에 적지\n * 않도록 물음은 하나이고(`BESIDE`), 그 물음을 CSS 와 여기가 함께 쓴다.\n */\n @state() private beside = false\n\n /**\n * 조회를 마쳤나 — **「아직 안 읽었다」와 「없다」는 다르다.**\n *\n * 전에는 값이 없으면 곧바로 「업무활동 정보가 없습니다」를 그렸다. 그런데 이 화면은 열리자마자\n * 조회를 시작하므로, 응답이 오기 전까지 **없다고 단언하는 화면**이 보인다. 목록에서 줄을 눌러\n * 들어온 사람은 방금 본 건이 없다는 말을 먼저 읽는다.\n *\n * 조회가 끝난 뒤에만 그 말을 한다. 그 전에는 아무 말도 하지 않는다.\n */\n get loaded(): boolean {\n return this.approval.data !== undefined\n }\n\n /** Why the approval could not be read - ox-page-state says it, with retry (ADR-0060 decision 8). */\n get loadError(): unknown {\n return (\n this.approval.error ??\n (this.loaded && !this.activityApproval\n ? new Error(i18next.t('error.activity-approval not found', { activityApproval: this.approvalId }))\n : null)\n )\n }\n\n @state() board: any\n /** The custom element and the approval read it was made for: another answer makes it again. */\n private custom?: { for: any; element: any }\n\n @query('textarea') commentInput!: HTMLTextAreaElement\n\n /**\n * Is the reader seated here as a reference — someone who comments and does not decide?\n *\n * The rule comes from organization's client types, the same function its own approval-line editor\n * and list use, so the two wire spellings of the enum are handled in one place. The approval line\n * answers rather than ActivityApproval.participation, matching what the server refuses on\n * (isReferenceOrder in approval-line.ts): the line decides who comes next, so letting the row\n * decide who may judge would leave two authorities with nothing to settle a disagreement.\n *\n * The value comes back false while the query is still out. That is the same answer as for an\n * approver, so the buttons show for a moment on a reference's screen — pressing one is refused by\n * the server, which is why the server closed first.\n */\n get isReference(): boolean {\n const approvalLine = this.activityThread?.activityInstance?.approvalLine\n const order = Number(this.activityApproval?.order ?? 0)\n\n return isReferenceStep(approvalLine?.[order - 1])\n }\n\n get context() {\n const judgment = this.activityApproval?.judgment\n\n return {\n /*\n * 이 화면이 어떤 틀인가 — 동작 줄이 이것을 읽고 자기 오른쪽 끝을 내용에 맞춘다\n * (ADR-0060 결정 9 보탬). 안 적으면 창 폭이고, 그것은 작업면의 모양이다.\n */\n frame: 'document',\n title: this.lifecycle?.params?.['title'] || i18next.t('title.activity approval'),\n help: 'worklist/activity-approval',\n /*\n * 이 화면은 메뉴에 없다 — 「내 결재함」에서 줄을 눌러 들어온다. 그래서 왼쪽 메뉴가 가리킬\n * 항목이 없고, 표시가 사라져 들어온 사람이 자기가 어디에 있는지 잃는다.\n *\n * 어느 목록에서 열리는지는 이 화면이 안다. 그것을 적어 둔다.\n */\n menu: 'approval-pending-list',\n /*\n * A reference is offered neither approve nor reject.\n *\n * ActivityApprovalJudgment has carried Closed for this seat from the start — \"the case ended\"\n * rather than a judgment — so a reference row was never meant to end in approved or rejected.\n * The buttons were offered anyway, and the server accepted them until 2026-09-09.\n *\n * What stays is the note, because a comment is the whole point of the seat, and close. The\n * hint under the textarea says which seat this is; buttons that simply vanish leave the\n * reader looking for them.\n */\n actions: judgment\n ? []\n : this.isReference\n ? []\n : /*\n * ── 결정 단추의 순서와 무게 (ADR-0060 결정 9 보탬) ─────────────\n * 전에는 반려가 첫 자리였고, 승인 · 반려 · 저장이 모두 같은 모양이었다. 되돌리기 어려운\n * 것이 앞에 서고 무엇이 주된 흐름인지 화면이 말하지 않았다.\n *\n * 승인이 주 동작이다 — 채운 단추 하나. 반려는 대등한 선택이지만 예외 경로라 테두리\n * 단추로 그 옆에 둔다.\n *\n * 「저장」은 이름이 뜻을 말하지 않았다. 이 단추가 저장하는 것은 **의견 하나**이고\n * (saveActivityApproval 은 id 와 comment 만 보낸다), 판단은 미뤄 둔다. 그리고 그 결과는\n * 목록에서 「메모 있음」 표식으로 나타난다(activity-cells 의 approvalMarks).\n * 메모 저장은 아래 의견 상자 옆에 두고, 이 줄에는 승인·반려만 둔다.\n */\n [\n {\n title: i18next.t('button.approve'),\n action: this.approveActivityApproval.bind(this),\n icon: 'approval',\n emphasis: { raised: true, outlined: false, dense: false, danger: false }\n },\n\n {\n title: i18next.t('button.reject'),\n action: this.rejectActivityApproval.bind(this),\n icon: 'assignment_return',\n emphasis: { raised: false, outlined: true, dense: false, danger: false }\n },\n\n ]\n // activityApproval: this.activityApproval\n }\n }\n\n private media?: MediaQueryList\n private onBeside = () => (this.beside = !!this.media?.matches)\n\n connectedCallback() {\n super.connectedCallback()\n this.media = window.matchMedia(BESIDE)\n this.onBeside()\n this.media.addEventListener('change', this.onBeside)\n }\n\n disconnectedCallback() {\n this.media?.removeEventListener('change', this.onBeside)\n super.disconnectedCallback()\n }\n\n render() {\n /* Reading and failing both drew nothing at all, so a failure looked like an empty screen. */\n return html`<div class=\"page\">\n <ox-page-state\n .loading=${!this.loaded && !this.loadError}\n .error=${this.loadError}\n @retry=${() => this.approval.refetch()}\n >${\n this.activityThread\n ? this.renderApproval()\n : this.loaded\n ? html`<div empty>\n <span class=\"title\">${i18next.t('text.no activity thread info')}</span>\n <span class=\"why\">${i18next.t('text.no-activity-thread-why')}</span>\n </div>`\n : nothing\n }</ox-page-state\n >\n </div>`\n }\n\n private renderApproval() {\n const { terminatedAt } = this.activityApproval\n const editable = !terminatedAt\n\n return html`\n <div class=\"main\">\n <activity-approval-ribon .activityApproval=${this.activityApproval}></activity-approval-ribon>\n <!-- The card holds a few lines of the record; the approver judges the record itself. -->\n ${renderSourceLink(this.activityThread?.activityInstance?.input)}\n ${this.activityContent()}\n </div>\n <!--\n 보일 항목이 하나도 없으면 타임라인을 편다 — 그때는 화면이 「아래 타임라인의 상신 사유와\n 이력을 보고 판단하세요」로 여기를 가리키므로, 접혀 있으면 그 안내가 거짓말이 된다.\n\n 옆에 설 자리가 있을 때도 편다. 접힌 줄을 눌러 펴는 동작이, 그 줄이 이미 보이는 자리에\n 있으면 하는 일이 없다.\n -->\n <activity-thread-timeline\n class=\"aside\"\n .activityThread=${this.activityThread}\n ?open=${!this.hasFields() || this.beside}\n short-form\n ></activity-thread-timeline>\n ${\n editable\n ? html`\n <div comment class=\"main\">\n <section>\n <h2>${i18next.t('field.wl-comment')}</h2>\n <textarea\n placeholder=${String(\n i18next.t(\n this.isReference\n ? 'text.write-your-comment-as-reference'\n : 'text.explain the reason for approval/rejection'\n )\n )}\n .value=${this.draft.value('comment') ?? ''}\n @input=${(e: Event) => this.draft.set('comment', (e.target as HTMLTextAreaElement).value)}\n ></textarea>\n <!--\n 반려는 의견이 필수다(rejectActivityApproval). 전에는 그 규칙을 **누른 뒤에** 토스트로\n 알렸다. 되돌릴 수 없는 것과 뜻이 다른 동작은 하기 전에 말한다.\n\n A reference reads a different line: this one names the seat, because the approve\n and reject buttons are absent for them and a reader whose buttons are missing\n goes looking for them.\n -->\n <p class=\"hint\">\n ${i18next.t(this.isReference ? 'text.reference-comment-hint' : 'text.approval-comment-hint')}\n </p>\n\n <!--\n 의견을 저장하는 단추는 의견 상자 옆이다(ADR-0060 결정 9 보탬). 동작 줄에는\n 결정만 둔다 — 전에는 승인 · 반려와 같은 줄에 같은 무게로 서서 셋 다 결정처럼\n 읽혔고, 좁은 화면에서는 넘침 메뉴로 밀려 반려가 숨을 수 있었다.\n -->\n <div class=\"comment-actions\">\n <button @click=${this.saveActivityApproval.bind(this)}>\n <md-icon>edit_note</md-icon>${i18next.t('button.save-note')}\n </button>\n </div>\n </section>\n </div>\n `\n : nothing\n }\n `\n }\n\n /** 화면에 낼 항목이 하나라도 있나. 타임라인을 펴 둘지 정하는 자리가 쓴다. */\n hasFields(): boolean {\n const model = this.activityThread?.activityInstance?.activity?.model\n\n return inputSpecOf(model).length > 0 || outputSpecOf(model).length > 0\n }\n\n activityContent() {\n switch (this.activityThread?.activityInstance?.viewType) {\n case 'template':\n return this.hostedContent(this.templateContent())\n case 'generated':\n return this.generatedContent()\n /* board 는 전체 화면을 쓰는 캔버스라 카드에 담지 않는다(hostedContent 머리말). */\n case 'board':\n return this.boardContent()\n case 'custom-element': {\n /*\n * The wrapper is for the element, not for the notice.\n *\n * hostedContent puts the content in a card so every ui type sits at the same place with the\n * same frame. The not-loaded notice is already a card — wrapping it drew a card inside a\n * card, two borders deep, and its margins landed unevenly: 16 above and none below, inside\n * a box that had its own padding. The generated branch returns the same notice unwrapped\n * and looks right.\n */\n const { viewSource: tagName } = this.activityThread?.activityInstance || {}\n\n /*\n * Naming no element is not the same as naming one that is missing.\n *\n * A template that stops providing a screen clears the field — installActivity does not\n * blank what a template leaves undefined, so clearing is written as null. That left\n * viewType saying custom-element with nothing named, and this branch answered \"the\n * screen could not be loaded\": a failure, for an activity that simply has no screen of its\n * own. Those read as different things to whoever is approving, and the second one is not\n * true.\n *\n * With nothing named, the generated screen is what this activity has — and it draws a\n * decision when the activity declares one, which the two plant forms that hit this do.\n */\n if (!tagName) {\n return this.generatedContent()\n }\n\n const element = this.customElementContent()\n\n return element ? this.hostedContent(element) : this.screenNotLoaded()\n }\n case 'page':\n case 'external':\n return html``\n default:\n return this.generatedContent()\n }\n }\n\n /**\n * 화면 종류가 달라도 **같은 자리에 같은 모양으로 놓인다.**\n *\n * worklist 는 네 가지로 내용을 그린다(generated · custom-element · template · board). 그중\n * generated 만 절 카드 안에 있었고 나머지 셋은 면 위에 맨몸으로 놓였다. 그래서 같은 결재 화면이\n * 액티비티에 따라 카드였다가 아니었다가 했다 — 아래의 타임라인 · 의견은 늘 카드라 위계도 어긋났다.\n *\n * board 는 뺀다. 전체 폭 · 전체 높이를 쓰는 캔버스라 카드 안에 넣으면 여백이 두 겹이 되고 크기가\n * 어긋난다.\n *\n * 카드는 여백을 두지 않는다(padding: 0). 안에 들어오는 것이 자기 조판을 갖고 있고, 두 겹으로\n * 주면 안쪽 내용이 카드 가운데로 밀린다.\n */\n hostedContent(content: unknown) {\n return html`<section hosted>${content}</section>`\n }\n\n templateContent() {\n if (!this.activityApproval) {\n return html``\n }\n\n const { viewSource: template } = this.activityThread?.activityInstance\n return unsafeHTML(template)\n }\n\n /**\n * 결재자가 보는 내용 — **전부 읽기 전용이다.**\n *\n * 전에는 「Output」 절을 편집기로 그리고 변경을 activityApproval.output 에 적었다. 그런데\n * approveActivityApproval / rejectActivityApproval 은 id 와 comment 만 보낸다 — 그 값은 어디에도\n * 가지 않는다. 결재자가 적을 수 있는 것은 의견 하나이고, 그것은 화면 아래 칸이 받는다.\n */\n /** The decision the activity declared, or nothing - drawn by `renderDecision`, the one drawing both screens use. */\n decisionContent() {\n const { activityInstance } = this.activityThread || {}\n const decision = renderDecision(activityInstance?.activity?.decisionKeys, activityInstance?.input)\n\n return decision === nothing ? nothing : keyed(this.activityApproval.id, decision)\n }\n\n generatedContent(): DirectiveResult {\n if (!this.activityApproval) {\n return html``\n }\n\n const { output, activityInstance } = this.activityThread || {}\n const { input } = activityInstance || {}\n\n /*\n * The declaration goes first. It answers \"what happens if I approve\", which is the question this\n * screen exists for; the model answers \"what are the values\", which is the fallback.\n */\n const decision = this.decisionContent()\n\n if (decision !== nothing) {\n return decision as DirectiveResult\n }\n\n const model = activityInstance?.activity?.model\n const inputSpec = inputSpecOf(model)\n const outputSpec = outputSpecOf(model)\n\n /*\n * **결재 화면에서 내용이 비어 있는 것은 경고다.**\n *\n * 업무 상세라면 「적을 것이 없다」로 끝난다. 여기서는 다르다 — 무엇을 승인하는지 모르는 채로\n * 승인 · 반려 버튼이 그대로 눌린다. 그 사실을 화면이 말하고, 대신 무엇을 보고 판단할지 알려\n * 준다(타임라인의 상신 사유).\n */\n if (!inputSpec.length && !outputSpec.length) {\n return keyed(\n this.activityApproval.id,\n html`<section empty>\n <span class=\"title\">${i18next.t('text.no-approval-content')}</span>\n <span class=\"why\">${i18next.t('text.no-approval-content-why')}</span>\n </section>`\n )\n }\n\n return keyed(\n this.activityApproval.id,\n html`\n ${\n inputSpec.length\n ? html`\n <section readonly>\n <h2>${i18next.t('label.activity-input')}</h2>\n ${renderGiven(inputSpec, input)}\n </section>\n `\n : ''\n }\n ${\n outputSpec.length\n ? html`\n <section readonly>\n <h2>${i18next.t('field.artifact')}</h2>\n ${renderGiven(outputSpec, output)}\n </section>\n `\n : ''\n }\n `\n )\n }\n\n boardContent(): DirectiveResult {\n if (!this.activityApproval) {\n return html``\n }\n\n const { output, activityInstance } = this.activityThread\n const { viewSource: boardId, input } = activityInstance || {}\n\n if (!this.board || this.board.id !== boardId) {\n this.board = { id: boardId }\n }\n\n return keyed(\n this.activityApproval.id,\n html`\n <ox-board-viewer\n style=\"background-color: white;\"\n .board=${this.board}\n .provider=${provider}\n .values=${{ ...input, ...output }}\n hide-fullscreen\n hide-navigation\n ></ox-board-viewer>\n `\n )\n }\n\n /**\n * The element the activity names, or a plain statement that it could not be loaded.\n *\n * document.createElement answers something for any name, so an activity pointing at an element\n * nobody registered used to produce an empty card. The approver got a screen with nothing on it\n * and the approve button still worked — plant shipped two such forms in one day and found them by\n * reading the file list, not by opening the screen.\n *\n * The reader is told what to judge by instead. Same shape as the empty generated screen: what is\n * missing, and where to look — the submission reason and the history in the timeline below.\n *\n * ── Waiting for a late definition ─────────────────────────────────────────\n * An element can be registered after this page renders, and answering \"not loaded\" forever in\n * that case would be a screen inventing a defect. whenDefined resolves whenever it arrives and\n * the page redraws; a name nobody ever registers simply never resolves, and the statement stands.\n */\n customElementContent() {\n if (!this.activityApproval) {\n return html``\n }\n\n const { output, activityInstance } = this.activityThread\n const { viewSource: tagName, input } = activityInstance || {}\n\n if (!customElements.get(tagName)) {\n customElements.whenDefined(tagName).then(() => this.requestUpdate())\n\n /* The caller draws the notice — unwrapped, because the notice is its own card. */\n return undefined\n }\n\n /* Made once per answer: the opinion typed below redraws the page, and the element shows the same approval. */\n if (this.custom && this.custom.for === this.activityApproval) {\n return this.custom.element\n }\n\n const element = document.createElement(tagName)\n element.id = 'custom-content'\n element.activityId = activityInstance.activity.id\n element.input = input\n element.output = output\n element.activityApproval = this.activityApproval\n\n this.custom = { for: this.activityApproval, element }\n return element\n }\n\n /** The activity names a screen and nothing registered it. Says what to judge by instead. */\n private screenNotLoaded() {\n return html`<section empty>\n <span class=\"title\">${i18next.t('text.approval-view-not-loaded')}</span>\n <span class=\"why\">${i18next.t('text.no-approval-content-why')}</span>\n </section>`\n }\n\n @query('ox-board-viewer') oxBoardViewer: any\n\n getOutputFromBoard() {\n const outputSpec = outputSpecOf(this.activityThread?.activityInstance?.activity?.model)\n const data = this.oxBoardViewer.getSceneValues()\n\n return outputSpec.reduce((output, spec) => {\n output[spec.name] = data[spec.name]\n return output\n }, {})\n }\n\n /**\n * 화면이 열리면 **의견 칸에 캐럿을 둔다.**\n *\n * 결재자가 이 화면에서 적는 것은 의견 하나다. 나머지는 전부 읽는 것이고, 판단은 아래 버튼이\n * 받는다. 그러면 열자마자 커서가 있어야 하는 자리는 하나뿐이다.\n *\n * 조건 둘을 지킨다.\n *\n * 활성 탭일 때만 MDI 라 뒤에 있는 탭이 응답을 받으면 앞 탭의 입력을 빼앗는다\n * 한 건에 한 번 갱신마다 focus 를 부르면 사용자가 옮긴 커서를 계속 되돌린다\n *\n * preventScroll 을 준다 — 화면을 아래로 끌어내리면 정작 무엇을 승인하는지가 위로 사라진다.\n */\n private focusedFor?: string\n\n private focusComment() {\n const id = this.activityApproval?.id\n\n if (!id || !this.active || this.activityApproval?.terminatedAt || this.focusedFor === id) {\n return\n }\n\n this.commentInput?.focus({ preventScroll: true })\n this.focusedFor = id\n }\n\n updated() {\n this.focusComment()\n }\n\n async pageUpdated(changes, lifecycle, changedBefore) {\n if (this.active && lifecycle.resourceId) {\n /* Entity 360 changes only the query address: the same approval is not read again, and its unsaved opinion stays. */\n /* Coming back to the tab, PageView reads the declared approval again; the opinion typed stays (the draft). */\n if (this.approvalId !== lifecycle.resourceId) this.approvalId = lifecycle.resourceId\n }\n }\n\n /*\n * The approval declared that it cannot be undone: ask once, as a destructive confirmation, before\n * sending it. Reversible and undeclared approvals go straight through, as before.\n */\n async confirmIfIrreversible(): Promise<boolean> {\n const { activityInstance } = this.activityThread || {}\n const slots = decisionSlots(activityInstance?.activity?.decisionKeys, activityInstance?.input)\n const gate = approvalGate(slotOfRole(slots, 'reversibility'))\n\n if (!gate.ask) {\n return true\n }\n\n return await OxPrompt.open({\n type: 'warning',\n title: i18next.t('text.approval-is-irreversible'),\n text: gate.caveat,\n /* From the declaration, not a literal: this screen does not decide what is irreversible. */\n confirmButton: { text: i18next.t('button.approve'), destructive: gate.ask },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n }\n\n /*\n * Each decision sends the opinion written now and reads the approval again once it went through; its answer is not\n * kept (ADR-0190 decision 2). The opinion sent is cleared then, and a failure keeps it.\n */\n async rejectActivityApproval() {\n const { id } = this.activityApproval\n const comment = this.draft.value('comment')\n\n if (!comment) {\n document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.enter a comment') } }))\n this.commentInput.focus()\n return\n }\n\n const rejected = await this.draft.submit(() => this.reject.run({ id, comment }))\n\n if (!rejected) {\n sayFailure(mutationOutcome(this.reject.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_rejected_successfully') } })\n )\n }\n\n async approveActivityApproval() {\n const { id } = this.activityApproval\n const comment = this.draft.value('comment')\n\n if (!(await this.confirmIfIrreversible())) {\n return\n }\n\n const approved = await this.draft.submit(() => this.approve.run({ id, comment }))\n\n if (!approved) {\n sayFailure(mutationOutcome(this.approve.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_approved_successfully') } })\n )\n }\n\n async saveActivityApproval() {\n const { id } = this.activityApproval\n const comment = this.draft.value('comment')\n\n const saved = await this.draft.submit(() => this.save.run({ id, comment }))\n\n if (!saved) {\n sayFailure(mutationOutcome(this.save.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_saved_successfully') } })\n )\n }\n}\n"]}
@@ -13,12 +13,13 @@ import { client, MutationController, QueryController } from '@operato/graphql';
13
13
  import { i18next, localize } from '@operato/i18n';
14
14
  import { mutationOutcome } from '../../components/mutation-outcome.js';
15
15
  import { ranMutation, sayFailure } from '../../components/say-outcome.js';
16
- import { CustomAlert, navigate, PageView, DraftController } from '@operato/shell';
16
+ import { CustomAlert, PageView, DraftController } from '@operato/shell';
17
17
  import { CommonButtonStyles, DocumentPageStyles, ScrollbarStyles } from '@operato/styles';
18
18
  import { provider } from '@operato/board/board-provider.js';
19
19
  import { ActivityFieldsStyles, inputSpecOf, outputSpecOf, renderGiven } from '../../components/activity-fields.js';
20
20
  import { DecisionContentStyles, DecisionKeysFields, renderDecision } from '../../components/decision-content.js';
21
- import { followupActions, sourceAddress } from '../../../shared/task-followup.js';
21
+ import { followupActions } from '../../../shared/task-followup.js';
22
+ import { renderSourceLink } from '../../components/source-link.js';
22
23
  import { drawsAnything, submittableIn, threadSectionsOf } from './thread-sections.js';
23
24
  const ActivityThreadFetchResult = `\
24
25
  { id
@@ -291,16 +292,7 @@ let ActivityThreadPage = class ActivityThreadPage extends localize(i18next)(Page
291
292
  renderThread(activityThread) {
292
293
  return html `
293
294
  <activity-thread-ribon .activityThread=${activityThread}></activity-thread-ribon>
294
- ${sourceAddress(activityThread.activityInstance?.input?.sourceHref)
295
- ? html `<p><a href=${sourceAddress(activityThread.activityInstance.input.sourceHref)}
296
- @click=${(event) => {
297
- if (event.button || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)
298
- return;
299
- event.preventDefault();
300
- navigate(sourceAddress(activityThread.activityInstance.input.sourceHref));
301
- }}>${i18next.t('button.task-open-source')}</a>
302
- </p>`
303
- : nothing}
295
+ ${renderSourceLink(activityThread.activityInstance?.input)}
304
296
  ${(activityThread.state === 'rejected' && !followupActions(activityThread).restartable) || followupActions(activityThread).sourceResubmission
305
297
  ? html `<p>${i18next.t('text.task-source-resubmit')}</p>` : nothing}
306
298
  ${this.activityContent()}
@@ -1 +1 @@
1
- {"version":3,"file":"activity-thread-page.js","sourceRoot":"","sources":["../../../client/pages/activity-thread/activity-thread-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/list-state/ox-page-state.js'\nimport '@operato/property-editor/ox-properties-dynamic-view.js'\nimport '@operato/board/ox-board-viewer.js'\nimport '../../components/activity-thread-ribon.js'\nimport '../../components/activity-thread-timeline.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, nothing } from 'lit'\nimport { DirectiveResult } from 'lit-html/directive.js'\nimport { unsafeHTML } from 'lit-html/directives/unsafe-html.js'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { keyed } from 'lit/directives/keyed.js'\nimport { client, MutationController, QueryController } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { mutationOutcome } from '../../components/mutation-outcome.js'\nimport { ranMutation, sayFailure } from '../../components/say-outcome.js'\nimport { CustomAlert, navigate, PageView, DraftController } from '@operato/shell'\nimport { CommonButtonStyles, DocumentPageStyles, ScrollbarStyles } from '@operato/styles'\nimport { provider } from '@operato/board/board-provider.js'\n\nimport { ActivityFieldsStyles, inputSpecOf, outputSpecOf, renderGiven } from '../../components/activity-fields.js'\nimport { DecisionContentStyles, DecisionKeysFields, renderDecision } from '../../components/decision-content.js'\nimport { followupActions, sourceAddress } from '../../../shared/task-followup.js'\nimport { drawsAnything, submittableIn, threadSectionsOf, ThreadSections } from './thread-sections.js'\n\nconst ActivityThreadFetchResult = `\\\n{ id\n state\n dueAt\n assignedAt\n assignee { id\n name\n }\n updatedAt\n output\n round\n activityApprovals { round\n order\n approver { id name\n }\n judgment\n participation\n comment\n createdAt\n updatedAt\n terminatedAt\n }\n activityThreadHistories { transaction\n reason\n updater { id name\n }\n updatedAt\n state\n output\n }\n activityInstance { id\n name\n description\n state\n rejectionIsFinal\n activity { id\n rejectionIsFinal\n ${DecisionKeysFields}\n model { name\n description\n active\n tag\n inout\n type\n unit\n options\n quantifier\n spec\n hidden\n }\n }\n approvalLine { type\n value\n participation\n notifyAfter\n approver { id\n name\n description\n controlNo\n }\n }\n thumbnail\n input\n output\n uiType\n uiSource\n dueAt\n terminatedAt\n terminator { name\n email\n }\n createdAt\n }\n}`\n\nexport const ActivityThreadStatus = {\n Unassigned: 'unassigned',\n Assigned: 'assigned',\n Started: 'started',\n Delegated: 'delegated',\n Rejected: 'rejected',\n Ended: 'ended',\n Aborted: 'aborted'\n}\n\n@customElement('activity-thread-page')\nexport class ActivityThreadPage extends localize(i18next)(PageView) {\n static styles = [\n /* The frame owns the page shell and the reading column (ADR-0060 decision 8). */\n DocumentPageStyles,\n ScrollbarStyles,\n ActivityFieldsStyles,\n DecisionContentStyles,\n css`\n :host {\n color: var(--ui-ink, #17242c);\n font-size: var(--ui-t-body, 13px);\n }\n\n /* 카드가 담아 주므로 안에 들어오는 화면은 자기 면과 여백을 갖지 않는다. */\n /*\n * 줄어들지 않는다 — 줄어들면 본문이 잘린다.\n *\n * flex 항목인데 크기를 안 정해 두면 기본이 flex: 0 1 auto 다. **1 이 줄어든다는 뜻이다** —\n * 세로가 모자라면 브라우저가 이 칸부터 줄이는데, 여기엔 카드 모서리를 따라 자르려고\n * overflow: hidden 이 걸려 있어서 줄어든 만큼이 **스크롤도 없이 사라진다.**\n *\n * 완료 조회에서 실측했다(1400x620): 칸이 242px 로 줄고 내용은 362px 이라 「업무 내용」 절이\n * 대부분 잘렸고, 잘린 자리 바로 아래에서 타임라인이 시작하니 타임라인이 본문을 덮은 것처럼\n * 보였다. 세로가 넉넉하면 줄일 일이 없어 안 드러난다.\n *\n * 안에 오는 것은 문서다. 높이를 정해 주어야 하는 것은 board 뿐이고 board 는 이 칸을 거치지\n * 않는다(activityContent 참조). 문서는 제 높이로 서고, 모자라면 페이지 전체가 스크롤한다 —\n * :host 의 overflow: auto 가 그 자리다.\n */\n section[hosted] {\n flex: none;\n padding: 0;\n overflow: hidden;\n }\n\n ox-board-viewer {\n width: 100%;\n height: 100%;\n }\n\n activity-thread-timeline {\n margin: var(--spacing-large, 16px);\n }\n `\n ]\n\n /** The thread the address names. */\n @state() private threadId = ''\n\n /* The thread shown, read for the id the address names (ADR-0190). */\n private thread = new QueryController(\n this,\n gql`\n query activityThread($id: String!) {\n activityThread(id: $id) ${ActivityThreadFetchResult}\n }\n `,\n { variables: () => (this.threadId ? { id: this.threadId } : undefined) }\n )\n\n /* What is written here over the thread read; another thread drops it (ADR-0190 decision 2). */\n private draft = new DraftController<{ output: any }>(this, {\n read: () => this.activityThread,\n key: () => this.threadId\n })\n\n /*\n * The changes made here: each reads what it changed again once done. This screen says its own failure\n * (sayFailure), so the GraphQL link stays quiet about it (ADR-0190).\n */\n private start = new MutationController(\n this,\n gql`\n mutation ($id: String!, $output: Object) {\n startActivityThread(id: $id, output: $output) {\n id\n }\n }\n `,\n { refetch: () => [this.thread], showsError: true }\n )\n\n private restart = new MutationController(\n this,\n gql`\n mutation ($id: String!, $output: Object) {\n restartActivityThread(id: $id, output: $output) {\n id\n }\n }\n `,\n { refetch: () => [this.thread], showsError: true }\n )\n\n private save = new MutationController(\n this,\n gql`\n mutation ($id: String!, $save: ActivityThreadSave!) {\n saveActivityThread(id: $id, save: $save) {\n id\n }\n }\n `,\n { refetch: () => [this.thread], context: { hasUpload: true }, showsError: true }\n )\n\n private finish = new MutationController(\n this,\n gql`\n mutation ($id: String!, $output: Object, $reason: String) {\n submitActivityThread(id: $id, output: $output, reason: $reason) {\n id\n }\n }\n `,\n { refetch: () => [this.thread], context: { hasUpload: true }, showsError: true }\n )\n\n get activityThread(): any {\n return this.thread.data?.activityThread\n }\n\n /**\n * 조회를 마쳤나 — **「아직 안 읽었다」와 「없다」는 다르다.**\n *\n * 전에는 값이 없으면 곧바로 「업무활동 정보가 없습니다」를 그렸다. 그런데 이 화면은 열리자마자\n * 조회를 시작하므로, 응답이 오기 전까지 **없다고 단언하는 화면**이 보인다. 목록에서 줄을 눌러\n * 들어온 사람은 방금 본 건이 없다는 말을 먼저 읽는다.\n *\n * 조회가 끝난 뒤에만 그 말을 한다. 그 전에는 아무 말도 하지 않는다.\n */\n get loaded(): boolean {\n return this.thread.data !== undefined\n }\n\n /** Why the task could not be read - ox-page-state says it, with retry (ADR-0060 decision 8). */\n get loadError(): unknown {\n return this.thread.error ?? null\n }\n\n /** The custom element and the thread read it was made for: another answer makes it again. */\n private custom?: { for: any; element: any }\n\n @state() board: any\n\n get context() {\n const state = this.activityThread?.state\n\n const { restartable, abortable, sourceResubmission } = followupActions(this.activityThread)\n const savable = submittableIn(state) && !sourceResubmission\n const submittable = savable\n // const delegatable = savable\n\n return {\n /*\n * 이 화면이 어떤 틀인가 — 동작 줄이 이것을 읽고 자기 오른쪽 끝을 내용에 맞춘다\n * (ADR-0060 결정 9 보탬). 안 적으면 창 폭이고, 그것은 작업면의 모양이다.\n */\n frame: 'document',\n title: this.lifecycle?.params?.['title'] || i18next.t('title.activity'),\n help: 'worklist/activity-thread-page',\n /*\n * 이 화면은 메뉴에 없다 — 「할 일」에서 줄을 눌러 들어온다. 그래서 왼쪽 메뉴가 가리킬\n * 항목이 없고, 표시가 사라져 들어온 사람이 자기가 어디에 있는지 잃는다.\n *\n * 어느 목록에서 열리는지는 이 화면이 안다. 그것을 적어 둔다.\n */\n menu: this.lifecycle?.params?.['box'] === 'draft-list' ? 'draft-list' : 'todo-list',\n actions: [\n savable && {\n title: i18next.t('button.save'),\n action: this._saveActivityThread.bind(this),\n ...CommonButtonStyles.save\n },\n\n submittable && {\n title: i18next.t('button.submit'),\n action: this._submitActivityThread.bind(this),\n ...CommonButtonStyles.submit\n },\n\n // delegatable && { // title: i18next.t('button.delegate'),\n // action: this._delegateActivityThread.bind(this),\n // ...CommonButtonStyles.save\n // },\n\n abortable && {\n title: i18next.t('button.abort'),\n action: this._abortActivityThread.bind(this),\n ...CommonButtonStyles.cancel\n },\n\n restartable && {\n title: i18next.t(this.lifecycle?.params?.['box'] === 'draft-list' ? 'button.revise-request' : 'button.restart'),\n action: this._restartActivityThread.bind(this),\n ...CommonButtonStyles.save\n }\n /*\n * 나가기는 동작 줄에 두지 않는다 (ADR-0060 결정 9 보탬 판정 2). 탭의 × 가 이미 하는 일이고,\n * 같은 곳으로 가는 문을 둘 두면 어느 쪽이 무엇을 하는지 사람이 눌러 봐야 안다.\n */\n ].filter(Boolean /* truthy only */)\n // activityThread: this.activityThread\n }\n }\n\n render() {\n const activityThread = this.activityThread\n\n /* Reading and failing both drew nothing at all, so a failure looked like an empty screen. */\n return html`<div class=\"page\">\n <ox-page-state\n .loading=${!this.loaded && !this.loadError}\n .error=${this.loadError}\n @retry=${() => this.thread.refetch()}\n >${\n !activityThread\n ? this.loaded\n ? html`<div empty>\n <span class=\"title\">${i18next.t('text.no activity thread info')}</span>\n <span class=\"why\">${i18next.t('text.no-activity-thread-why')}</span>\n </div>`\n : nothing\n : this.renderThread(activityThread)\n }</ox-page-state\n >\n </div>`\n }\n\n private renderThread(activityThread: any) {\n return html`\n <activity-thread-ribon .activityThread=${activityThread}></activity-thread-ribon>\n ${sourceAddress(activityThread.activityInstance?.input?.sourceHref)\n ? html`<p><a href=${sourceAddress(activityThread.activityInstance.input.sourceHref)!}\n @click=${(event: MouseEvent) => {\n if (event.button || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return\n event.preventDefault()\n navigate(sourceAddress(activityThread.activityInstance.input.sourceHref)!)\n }}>${i18next.t('button.task-open-source')}</a>\n </p>`\n : nothing}\n ${(activityThread.state === 'rejected' && !followupActions(activityThread).restartable) || followupActions(activityThread).sourceResubmission\n ? html`<p>${i18next.t('text.task-source-resubmit')}</p>` : nothing}\n ${this.activityContent()}\n <!--\n 위에 그린 것이 하나도 없으면 편다 — 그때 확인할 것은 타임라인뿐인데, 접혀 있으면 볼 것이\n 아무것도 없는 화면이 된다.\n -->\n <activity-thread-timeline\n .activityThread=${activityThread}\n ?open=${!drawsAnything(this.sections())}\n short-form\n ></activity-thread-timeline>\n `\n }\n\n /** 타임라인 위에 무엇을 그리나 — 규칙은 thread-sections 에 있다. */\n sections(): ThreadSections {\n const model = this.activityThread?.activityInstance?.activity?.model\n\n return threadSectionsOf({\n decision: this.decision() !== nothing,\n given: inputSpecOf(model).length,\n written: outputSpecOf(model).length,\n state: this.activityThread?.state\n })\n }\n\n /** 액티비티가 선언한 결재 내용 — 결재 화면과 같은 그리기다. */\n decision() {\n const activityInstance = this.activityThread?.activityInstance\n\n return renderDecision(activityInstance?.activity?.decisionKeys, activityInstance?.input)\n }\n\n activityContent() {\n switch (this.activityThread?.activityInstance?.uiType) {\n case 'template':\n return this.hostedContent(this.templateContent())\n case 'generated':\n return this.generatedContent()\n /* board 는 전체 화면을 쓰는 캔버스라 카드에 담지 않는다(hostedContent 머리말). */\n case 'board':\n return this.boardContent()\n case 'custom-element':\n return this.hostedContent(this.customElementContent())\n case 'page':\n case 'external':\n return html``\n default:\n return this.generatedContent()\n }\n }\n\n /**\n * 화면 종류가 달라도 **같은 자리에 같은 모양으로 놓인다.**\n *\n * worklist 는 네 가지로 내용을 그린다(generated · custom-element · template · board). 그중\n * generated 만 절 카드 안에 있었고 나머지 셋은 면 위에 맨몸으로 놓였다. 그래서 같은 결재 화면이\n * 액티비티에 따라 카드였다가 아니었다가 했다 — 아래의 타임라인 · 의견은 늘 카드라 위계도 어긋났다.\n *\n * board 는 뺀다. 전체 폭 · 전체 높이를 쓰는 캔버스라 카드 안에 넣으면 여백이 두 겹이 되고 크기가\n * 어긋난다.\n *\n * 카드는 여백을 두지 않는다(padding: 0). 안에 들어오는 것이 자기 조판을 갖고 있고, 두 겹으로\n * 주면 안쪽 내용이 카드 가운데로 밀린다.\n */\n hostedContent(content: unknown) {\n return html`<section hosted>${content}</section>`\n }\n\n templateContent() {\n if (!this.activityThread) {\n return html``\n }\n\n const { uiSource: template } = this.activityThread?.activityInstance\n return unsafeHTML(template)\n }\n\n generatedContent(): DirectiveResult {\n if (!this.activityThread) {\n return html``\n }\n\n var { activityInstance } = this.activityThread || {}\n var { input } = activityInstance || {}\n var output = this.draft.value('output')\n\n const model = activityInstance?.activity?.model\n const inputSpec = inputSpecOf(model)\n const outputSpec = outputSpecOf(model)\n\n if (!output) {\n output = inputSpec\n .filter(item => item.inout === 'inout')\n .reduce((output, item) => {\n output[item.tag] = input[item.tag]\n return output\n }, {})\n }\n\n /*\n * **빈 절은 그리지 않는다.**\n *\n * 처분 승인 액티비티에는 `out` 항목이 하나도 없다. 그런데도 화면이 「Output」 상자를 그려서,\n * 무엇을 적어야 하는지 없는데 적는 자리처럼 보였다. 항목이 없으면 그 절이 없는 것이다.\n *\n * 아무것도 없고 제출할 차례면 그 사실을 말한다 — 상태 ribbon 과 제출 버튼만 남은 화면은\n * 사용자에게 「덜 뜬 화면」으로 읽힌다. 제출한 뒤에는 말하지 않는다(thread-sections).\n */\n const sections = this.sections()\n\n if (sections.emptyNote) {\n return keyed(\n this.activityThread?.id,\n html`<section empty>\n <span class=\"title\">${i18next.t('text.no-activity-fields')}</span>\n <span class=\"why\">${i18next.t('text.no-activity-fields-why')}</span>\n </section>`\n )\n }\n\n if (!drawsAnything(sections)) {\n return nothing\n }\n\n return keyed(\n this.activityThread?.id,\n html`\n ${sections.decision ? this.decision() : ''}\n ${\n sections.given\n ? html`\n <section readonly>\n <h2>${i18next.t('label.activity-input')}</h2>\n ${renderGiven(inputSpec, input)}\n </section>\n `\n : ''\n }\n ${\n sections.written\n ? html`\n <section>\n <h2>${i18next.t('field.artifact')}</h2>\n <ox-properties-dynamic-view\n data-name=\"output\"\n .props=${outputSpec}\n .value=${output}\n @property-change=${e => this.draft.set('output', e.currentTarget.value)}\n ></ox-properties-dynamic-view>\n </section>\n `\n : ''\n }\n `\n )\n }\n\n boardContent(): DirectiveResult {\n if (!this.activityThread) {\n return html``\n }\n\n const { activityInstance } = this.activityThread\n const { uiSource: boardId, input } = activityInstance || {}\n const output = this.draft.value('output')\n\n if (!this.board || this.board.id !== boardId) {\n this.board = { id: boardId }\n }\n\n /* \n ox-board-viewer에서 provider에 의해 공급되는 board가 각 id별로 instance를 하나씩 밖에 가지지 않으므로,\n 동일한 id의 보드를 다른 page에 뺏기는 경우가 있다.\n 따라서, Page가 active될 때마다 타임스탬프를 refresh key로 설정하였다.\n */\n return keyed(\n this.activityThread.id,\n html`\n <ox-board-viewer\n style=\"background-color: white;\"\n .board=${this.board}\n .provider=${provider}\n .values=${{ ...input, ...output }}\n hide-fullscreen\n hide-navigation\n ></ox-board-viewer>\n `\n )\n }\n\n customElementContent() {\n if (!this.activityThread) {\n return html``\n }\n\n /* Made once per answer: what is written in it redraws the page, and a new element would drop the typing. */\n if (this.custom && this.custom.for === this.activityThread) {\n return this.custom.element\n }\n\n const { activityInstance } = this.activityThread\n const { uiSource: tagName, input } = activityInstance || {}\n\n const element = document.createElement(tagName)\n element.id = 'custom-content'\n element.activityId = activityInstance.activity.id\n element.input = input\n element.output = this.draft.value('output')\n element.activityThread = this.activityThread\n\n element.addEventListener('change', (e: CustomEvent) => this.draft.set('output', e.detail))\n\n this.custom = { for: this.activityThread, element }\n return element\n }\n\n @query('ox-board-viewer') oxBoardViewer: any\n\n getOutputFromBoard() {\n const outputSpec = outputSpecOf(this.activityThread?.activityInstance?.activity?.model)\n const data = this.oxBoardViewer.getSceneValues()\n\n return outputSpec.reduce((output, spec) => {\n output[spec.name] = data[spec.name]\n return output\n }, {})\n }\n\n async pageUpdated(changes, lifecycle, changedBefore) {\n if (this.active && lifecycle.resourceId) {\n this.threadId = lifecycle.resourceId\n }\n }\n\n /** What this task's output is to be: the board's values, or what was written over the thread read. */\n private outputToSend() {\n return this.activityThread.activityInstance?.uiType === 'board' ? this.getOutputFromBoard() : this.draft.value('output')\n }\n\n /*\n * Each change sends what is written now and reads the thread again once it went through; its answer is not kept\n * (ADR-0190 decision 2). The edits sent are cleared then, and a failure keeps them.\n */\n async _startActivityThread() {\n const { id } = this.activityThread\n const output = this.outputToSend()\n\n const done = await this.draft.submit(() => this.start.run({ id, output }))\n\n if (!done) {\n sayFailure(mutationOutcome(this.start.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_started_successfully') } })\n )\n }\n\n async _restartActivityThread() {\n const { id } = this.activityThread\n const output = this.outputToSend()\n\n const done = await this.draft.submit(() => this.restart.run({ id, output }))\n\n if (!done) {\n sayFailure(mutationOutcome(this.restart.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_restarted_successfully') } })\n )\n }\n\n async _delegateActivityThread() {\n throw 'not implemented yet'\n }\n\n async _saveActivityThread() {\n const { id } = this.activityThread\n const output = this.outputToSend()\n\n const done = await this.draft.submit(() => this.save.run({ id, save: { output } }))\n\n if (!done) {\n sayFailure(mutationOutcome(this.save.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_saved_successfully') } })\n )\n }\n\n async _submitActivityThread() {\n const { id, reason } = this.activityThread\n const output = this.outputToSend()\n\n const done = await this.draft.submit(() => this.finish.run({ id, output, reason }))\n\n if (!done) {\n sayFailure(mutationOutcome(this.finish.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_finished_successfully') } })\n )\n }\n\n async _abortActivityThread() {\n const answer = await CustomAlert({\n type: 'warning',\n title: i18next.t('button.abort'),\n text: i18next.t('text.task-abort-keeps-history'),\n confirmButton: { text: i18next.t('button.abort') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n if (!answer?.value) return\n const { id } = this.activityThread\n\n const outcome = await ranMutation(() =>\n client.mutate({\n mutation: gql`\n mutation ($id: String!, $reason: String) {\n abortActivityThread(id: $id, reason: $reason) {\n id\n }\n }\n `,\n variables: { id }\n })\n )\n\n if (outcome.ok) {\n /* Nothing more is written on an aborted task: what was typed on it goes with it. */\n this.draft.reset()\n await this.thread.refetch()\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_aborted_successfully') } })\n )\n }\n }\n}\n"]}
1
+ {"version":3,"file":"activity-thread-page.js","sourceRoot":"","sources":["../../../client/pages/activity-thread/activity-thread-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/list-state/ox-page-state.js'\nimport '@operato/property-editor/ox-properties-dynamic-view.js'\nimport '@operato/board/ox-board-viewer.js'\nimport '../../components/activity-thread-ribon.js'\nimport '../../components/activity-thread-timeline.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, nothing } from 'lit'\nimport { DirectiveResult } from 'lit-html/directive.js'\nimport { unsafeHTML } from 'lit-html/directives/unsafe-html.js'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { keyed } from 'lit/directives/keyed.js'\nimport { client, MutationController, QueryController } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { mutationOutcome } from '../../components/mutation-outcome.js'\nimport { ranMutation, sayFailure } from '../../components/say-outcome.js'\nimport { CustomAlert, PageView, DraftController } from '@operato/shell'\nimport { CommonButtonStyles, DocumentPageStyles, ScrollbarStyles } from '@operato/styles'\nimport { provider } from '@operato/board/board-provider.js'\n\nimport { ActivityFieldsStyles, inputSpecOf, outputSpecOf, renderGiven } from '../../components/activity-fields.js'\nimport { DecisionContentStyles, DecisionKeysFields, renderDecision } from '../../components/decision-content.js'\nimport { followupActions } from '../../../shared/task-followup.js'\nimport { renderSourceLink } from '../../components/source-link.js'\nimport { drawsAnything, submittableIn, threadSectionsOf, ThreadSections } from './thread-sections.js'\n\nconst ActivityThreadFetchResult = `\\\n{ id\n state\n dueAt\n assignedAt\n assignee { id\n name\n }\n updatedAt\n output\n round\n activityApprovals { round\n order\n approver { id name\n }\n judgment\n participation\n comment\n createdAt\n updatedAt\n terminatedAt\n }\n activityThreadHistories { transaction\n reason\n updater { id name\n }\n updatedAt\n state\n output\n }\n activityInstance { id\n name\n description\n state\n rejectionIsFinal\n activity { id\n rejectionIsFinal\n ${DecisionKeysFields}\n model { name\n description\n active\n tag\n inout\n type\n unit\n options\n quantifier\n spec\n hidden\n }\n }\n approvalLine { type\n value\n participation\n notifyAfter\n approver { id\n name\n description\n controlNo\n }\n }\n thumbnail\n input\n output\n uiType\n uiSource\n dueAt\n terminatedAt\n terminator { name\n email\n }\n createdAt\n }\n}`\n\nexport const ActivityThreadStatus = {\n Unassigned: 'unassigned',\n Assigned: 'assigned',\n Started: 'started',\n Delegated: 'delegated',\n Rejected: 'rejected',\n Ended: 'ended',\n Aborted: 'aborted'\n}\n\n@customElement('activity-thread-page')\nexport class ActivityThreadPage extends localize(i18next)(PageView) {\n static styles = [\n /* The frame owns the page shell and the reading column (ADR-0060 decision 8). */\n DocumentPageStyles,\n ScrollbarStyles,\n ActivityFieldsStyles,\n DecisionContentStyles,\n css`\n :host {\n color: var(--ui-ink, #17242c);\n font-size: var(--ui-t-body, 13px);\n }\n\n /* 카드가 담아 주므로 안에 들어오는 화면은 자기 면과 여백을 갖지 않는다. */\n /*\n * 줄어들지 않는다 — 줄어들면 본문이 잘린다.\n *\n * flex 항목인데 크기를 안 정해 두면 기본이 flex: 0 1 auto 다. **1 이 줄어든다는 뜻이다** —\n * 세로가 모자라면 브라우저가 이 칸부터 줄이는데, 여기엔 카드 모서리를 따라 자르려고\n * overflow: hidden 이 걸려 있어서 줄어든 만큼이 **스크롤도 없이 사라진다.**\n *\n * 완료 조회에서 실측했다(1400x620): 칸이 242px 로 줄고 내용은 362px 이라 「업무 내용」 절이\n * 대부분 잘렸고, 잘린 자리 바로 아래에서 타임라인이 시작하니 타임라인이 본문을 덮은 것처럼\n * 보였다. 세로가 넉넉하면 줄일 일이 없어 안 드러난다.\n *\n * 안에 오는 것은 문서다. 높이를 정해 주어야 하는 것은 board 뿐이고 board 는 이 칸을 거치지\n * 않는다(activityContent 참조). 문서는 제 높이로 서고, 모자라면 페이지 전체가 스크롤한다 —\n * :host 의 overflow: auto 가 그 자리다.\n */\n section[hosted] {\n flex: none;\n padding: 0;\n overflow: hidden;\n }\n\n ox-board-viewer {\n width: 100%;\n height: 100%;\n }\n\n activity-thread-timeline {\n margin: var(--spacing-large, 16px);\n }\n `\n ]\n\n /** The thread the address names. */\n @state() private threadId = ''\n\n /* The thread shown, read for the id the address names (ADR-0190). */\n private thread = new QueryController(\n this,\n gql`\n query activityThread($id: String!) {\n activityThread(id: $id) ${ActivityThreadFetchResult}\n }\n `,\n { variables: () => (this.threadId ? { id: this.threadId } : undefined) }\n )\n\n /* What is written here over the thread read; another thread drops it (ADR-0190 decision 2). */\n private draft = new DraftController<{ output: any }>(this, {\n read: () => this.activityThread,\n key: () => this.threadId\n })\n\n /*\n * The changes made here: each reads what it changed again once done. This screen says its own failure\n * (sayFailure), so the GraphQL link stays quiet about it (ADR-0190).\n */\n private start = new MutationController(\n this,\n gql`\n mutation ($id: String!, $output: Object) {\n startActivityThread(id: $id, output: $output) {\n id\n }\n }\n `,\n { refetch: () => [this.thread], showsError: true }\n )\n\n private restart = new MutationController(\n this,\n gql`\n mutation ($id: String!, $output: Object) {\n restartActivityThread(id: $id, output: $output) {\n id\n }\n }\n `,\n { refetch: () => [this.thread], showsError: true }\n )\n\n private save = new MutationController(\n this,\n gql`\n mutation ($id: String!, $save: ActivityThreadSave!) {\n saveActivityThread(id: $id, save: $save) {\n id\n }\n }\n `,\n { refetch: () => [this.thread], context: { hasUpload: true }, showsError: true }\n )\n\n private finish = new MutationController(\n this,\n gql`\n mutation ($id: String!, $output: Object, $reason: String) {\n submitActivityThread(id: $id, output: $output, reason: $reason) {\n id\n }\n }\n `,\n { refetch: () => [this.thread], context: { hasUpload: true }, showsError: true }\n )\n\n get activityThread(): any {\n return this.thread.data?.activityThread\n }\n\n /**\n * 조회를 마쳤나 — **「아직 안 읽었다」와 「없다」는 다르다.**\n *\n * 전에는 값이 없으면 곧바로 「업무활동 정보가 없습니다」를 그렸다. 그런데 이 화면은 열리자마자\n * 조회를 시작하므로, 응답이 오기 전까지 **없다고 단언하는 화면**이 보인다. 목록에서 줄을 눌러\n * 들어온 사람은 방금 본 건이 없다는 말을 먼저 읽는다.\n *\n * 조회가 끝난 뒤에만 그 말을 한다. 그 전에는 아무 말도 하지 않는다.\n */\n get loaded(): boolean {\n return this.thread.data !== undefined\n }\n\n /** Why the task could not be read - ox-page-state says it, with retry (ADR-0060 decision 8). */\n get loadError(): unknown {\n return this.thread.error ?? null\n }\n\n /** The custom element and the thread read it was made for: another answer makes it again. */\n private custom?: { for: any; element: any }\n\n @state() board: any\n\n get context() {\n const state = this.activityThread?.state\n\n const { restartable, abortable, sourceResubmission } = followupActions(this.activityThread)\n const savable = submittableIn(state) && !sourceResubmission\n const submittable = savable\n // const delegatable = savable\n\n return {\n /*\n * 이 화면이 어떤 틀인가 — 동작 줄이 이것을 읽고 자기 오른쪽 끝을 내용에 맞춘다\n * (ADR-0060 결정 9 보탬). 안 적으면 창 폭이고, 그것은 작업면의 모양이다.\n */\n frame: 'document',\n title: this.lifecycle?.params?.['title'] || i18next.t('title.activity'),\n help: 'worklist/activity-thread-page',\n /*\n * 이 화면은 메뉴에 없다 — 「할 일」에서 줄을 눌러 들어온다. 그래서 왼쪽 메뉴가 가리킬\n * 항목이 없고, 표시가 사라져 들어온 사람이 자기가 어디에 있는지 잃는다.\n *\n * 어느 목록에서 열리는지는 이 화면이 안다. 그것을 적어 둔다.\n */\n menu: this.lifecycle?.params?.['box'] === 'draft-list' ? 'draft-list' : 'todo-list',\n actions: [\n savable && {\n title: i18next.t('button.save'),\n action: this._saveActivityThread.bind(this),\n ...CommonButtonStyles.save\n },\n\n submittable && {\n title: i18next.t('button.submit'),\n action: this._submitActivityThread.bind(this),\n ...CommonButtonStyles.submit\n },\n\n // delegatable && { // title: i18next.t('button.delegate'),\n // action: this._delegateActivityThread.bind(this),\n // ...CommonButtonStyles.save\n // },\n\n abortable && {\n title: i18next.t('button.abort'),\n action: this._abortActivityThread.bind(this),\n ...CommonButtonStyles.cancel\n },\n\n restartable && {\n title: i18next.t(this.lifecycle?.params?.['box'] === 'draft-list' ? 'button.revise-request' : 'button.restart'),\n action: this._restartActivityThread.bind(this),\n ...CommonButtonStyles.save\n }\n /*\n * 나가기는 동작 줄에 두지 않는다 (ADR-0060 결정 9 보탬 판정 2). 탭의 × 가 이미 하는 일이고,\n * 같은 곳으로 가는 문을 둘 두면 어느 쪽이 무엇을 하는지 사람이 눌러 봐야 안다.\n */\n ].filter(Boolean /* truthy only */)\n // activityThread: this.activityThread\n }\n }\n\n render() {\n const activityThread = this.activityThread\n\n /* Reading and failing both drew nothing at all, so a failure looked like an empty screen. */\n return html`<div class=\"page\">\n <ox-page-state\n .loading=${!this.loaded && !this.loadError}\n .error=${this.loadError}\n @retry=${() => this.thread.refetch()}\n >${\n !activityThread\n ? this.loaded\n ? html`<div empty>\n <span class=\"title\">${i18next.t('text.no activity thread info')}</span>\n <span class=\"why\">${i18next.t('text.no-activity-thread-why')}</span>\n </div>`\n : nothing\n : this.renderThread(activityThread)\n }</ox-page-state\n >\n </div>`\n }\n\n private renderThread(activityThread: any) {\n return html`\n <activity-thread-ribon .activityThread=${activityThread}></activity-thread-ribon>\n ${renderSourceLink(activityThread.activityInstance?.input)}\n ${(activityThread.state === 'rejected' && !followupActions(activityThread).restartable) || followupActions(activityThread).sourceResubmission\n ? html`<p>${i18next.t('text.task-source-resubmit')}</p>` : nothing}\n ${this.activityContent()}\n <!--\n 위에 그린 것이 하나도 없으면 편다 — 그때 확인할 것은 타임라인뿐인데, 접혀 있으면 볼 것이\n 아무것도 없는 화면이 된다.\n -->\n <activity-thread-timeline\n .activityThread=${activityThread}\n ?open=${!drawsAnything(this.sections())}\n short-form\n ></activity-thread-timeline>\n `\n }\n\n /** 타임라인 위에 무엇을 그리나 — 규칙은 thread-sections 에 있다. */\n sections(): ThreadSections {\n const model = this.activityThread?.activityInstance?.activity?.model\n\n return threadSectionsOf({\n decision: this.decision() !== nothing,\n given: inputSpecOf(model).length,\n written: outputSpecOf(model).length,\n state: this.activityThread?.state\n })\n }\n\n /** 액티비티가 선언한 결재 내용 — 결재 화면과 같은 그리기다. */\n decision() {\n const activityInstance = this.activityThread?.activityInstance\n\n return renderDecision(activityInstance?.activity?.decisionKeys, activityInstance?.input)\n }\n\n activityContent() {\n switch (this.activityThread?.activityInstance?.uiType) {\n case 'template':\n return this.hostedContent(this.templateContent())\n case 'generated':\n return this.generatedContent()\n /* board 는 전체 화면을 쓰는 캔버스라 카드에 담지 않는다(hostedContent 머리말). */\n case 'board':\n return this.boardContent()\n case 'custom-element':\n return this.hostedContent(this.customElementContent())\n case 'page':\n case 'external':\n return html``\n default:\n return this.generatedContent()\n }\n }\n\n /**\n * 화면 종류가 달라도 **같은 자리에 같은 모양으로 놓인다.**\n *\n * worklist 는 네 가지로 내용을 그린다(generated · custom-element · template · board). 그중\n * generated 만 절 카드 안에 있었고 나머지 셋은 면 위에 맨몸으로 놓였다. 그래서 같은 결재 화면이\n * 액티비티에 따라 카드였다가 아니었다가 했다 — 아래의 타임라인 · 의견은 늘 카드라 위계도 어긋났다.\n *\n * board 는 뺀다. 전체 폭 · 전체 높이를 쓰는 캔버스라 카드 안에 넣으면 여백이 두 겹이 되고 크기가\n * 어긋난다.\n *\n * 카드는 여백을 두지 않는다(padding: 0). 안에 들어오는 것이 자기 조판을 갖고 있고, 두 겹으로\n * 주면 안쪽 내용이 카드 가운데로 밀린다.\n */\n hostedContent(content: unknown) {\n return html`<section hosted>${content}</section>`\n }\n\n templateContent() {\n if (!this.activityThread) {\n return html``\n }\n\n const { uiSource: template } = this.activityThread?.activityInstance\n return unsafeHTML(template)\n }\n\n generatedContent(): DirectiveResult {\n if (!this.activityThread) {\n return html``\n }\n\n var { activityInstance } = this.activityThread || {}\n var { input } = activityInstance || {}\n var output = this.draft.value('output')\n\n const model = activityInstance?.activity?.model\n const inputSpec = inputSpecOf(model)\n const outputSpec = outputSpecOf(model)\n\n if (!output) {\n output = inputSpec\n .filter(item => item.inout === 'inout')\n .reduce((output, item) => {\n output[item.tag] = input[item.tag]\n return output\n }, {})\n }\n\n /*\n * **빈 절은 그리지 않는다.**\n *\n * 처분 승인 액티비티에는 `out` 항목이 하나도 없다. 그런데도 화면이 「Output」 상자를 그려서,\n * 무엇을 적어야 하는지 없는데 적는 자리처럼 보였다. 항목이 없으면 그 절이 없는 것이다.\n *\n * 아무것도 없고 제출할 차례면 그 사실을 말한다 — 상태 ribbon 과 제출 버튼만 남은 화면은\n * 사용자에게 「덜 뜬 화면」으로 읽힌다. 제출한 뒤에는 말하지 않는다(thread-sections).\n */\n const sections = this.sections()\n\n if (sections.emptyNote) {\n return keyed(\n this.activityThread?.id,\n html`<section empty>\n <span class=\"title\">${i18next.t('text.no-activity-fields')}</span>\n <span class=\"why\">${i18next.t('text.no-activity-fields-why')}</span>\n </section>`\n )\n }\n\n if (!drawsAnything(sections)) {\n return nothing\n }\n\n return keyed(\n this.activityThread?.id,\n html`\n ${sections.decision ? this.decision() : ''}\n ${\n sections.given\n ? html`\n <section readonly>\n <h2>${i18next.t('label.activity-input')}</h2>\n ${renderGiven(inputSpec, input)}\n </section>\n `\n : ''\n }\n ${\n sections.written\n ? html`\n <section>\n <h2>${i18next.t('field.artifact')}</h2>\n <ox-properties-dynamic-view\n data-name=\"output\"\n .props=${outputSpec}\n .value=${output}\n @property-change=${e => this.draft.set('output', e.currentTarget.value)}\n ></ox-properties-dynamic-view>\n </section>\n `\n : ''\n }\n `\n )\n }\n\n boardContent(): DirectiveResult {\n if (!this.activityThread) {\n return html``\n }\n\n const { activityInstance } = this.activityThread\n const { uiSource: boardId, input } = activityInstance || {}\n const output = this.draft.value('output')\n\n if (!this.board || this.board.id !== boardId) {\n this.board = { id: boardId }\n }\n\n /* \n ox-board-viewer에서 provider에 의해 공급되는 board가 각 id별로 instance를 하나씩 밖에 가지지 않으므로,\n 동일한 id의 보드를 다른 page에 뺏기는 경우가 있다.\n 따라서, Page가 active될 때마다 타임스탬프를 refresh key로 설정하였다.\n */\n return keyed(\n this.activityThread.id,\n html`\n <ox-board-viewer\n style=\"background-color: white;\"\n .board=${this.board}\n .provider=${provider}\n .values=${{ ...input, ...output }}\n hide-fullscreen\n hide-navigation\n ></ox-board-viewer>\n `\n )\n }\n\n customElementContent() {\n if (!this.activityThread) {\n return html``\n }\n\n /* Made once per answer: what is written in it redraws the page, and a new element would drop the typing. */\n if (this.custom && this.custom.for === this.activityThread) {\n return this.custom.element\n }\n\n const { activityInstance } = this.activityThread\n const { uiSource: tagName, input } = activityInstance || {}\n\n const element = document.createElement(tagName)\n element.id = 'custom-content'\n element.activityId = activityInstance.activity.id\n element.input = input\n element.output = this.draft.value('output')\n element.activityThread = this.activityThread\n\n element.addEventListener('change', (e: CustomEvent) => this.draft.set('output', e.detail))\n\n this.custom = { for: this.activityThread, element }\n return element\n }\n\n @query('ox-board-viewer') oxBoardViewer: any\n\n getOutputFromBoard() {\n const outputSpec = outputSpecOf(this.activityThread?.activityInstance?.activity?.model)\n const data = this.oxBoardViewer.getSceneValues()\n\n return outputSpec.reduce((output, spec) => {\n output[spec.name] = data[spec.name]\n return output\n }, {})\n }\n\n async pageUpdated(changes, lifecycle, changedBefore) {\n if (this.active && lifecycle.resourceId) {\n this.threadId = lifecycle.resourceId\n }\n }\n\n /** What this task's output is to be: the board's values, or what was written over the thread read. */\n private outputToSend() {\n return this.activityThread.activityInstance?.uiType === 'board' ? this.getOutputFromBoard() : this.draft.value('output')\n }\n\n /*\n * Each change sends what is written now and reads the thread again once it went through; its answer is not kept\n * (ADR-0190 decision 2). The edits sent are cleared then, and a failure keeps them.\n */\n async _startActivityThread() {\n const { id } = this.activityThread\n const output = this.outputToSend()\n\n const done = await this.draft.submit(() => this.start.run({ id, output }))\n\n if (!done) {\n sayFailure(mutationOutcome(this.start.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_started_successfully') } })\n )\n }\n\n async _restartActivityThread() {\n const { id } = this.activityThread\n const output = this.outputToSend()\n\n const done = await this.draft.submit(() => this.restart.run({ id, output }))\n\n if (!done) {\n sayFailure(mutationOutcome(this.restart.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_restarted_successfully') } })\n )\n }\n\n async _delegateActivityThread() {\n throw 'not implemented yet'\n }\n\n async _saveActivityThread() {\n const { id } = this.activityThread\n const output = this.outputToSend()\n\n const done = await this.draft.submit(() => this.save.run({ id, save: { output } }))\n\n if (!done) {\n sayFailure(mutationOutcome(this.save.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_saved_successfully') } })\n )\n }\n\n async _submitActivityThread() {\n const { id, reason } = this.activityThread\n const output = this.outputToSend()\n\n const done = await this.draft.submit(() => this.finish.run({ id, output, reason }))\n\n if (!done) {\n sayFailure(mutationOutcome(this.finish.error))\n return\n }\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_finished_successfully') } })\n )\n }\n\n async _abortActivityThread() {\n const answer = await CustomAlert({\n type: 'warning',\n title: i18next.t('button.abort'),\n text: i18next.t('text.task-abort-keeps-history'),\n confirmButton: { text: i18next.t('button.abort') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n if (!answer?.value) return\n const { id } = this.activityThread\n\n const outcome = await ranMutation(() =>\n client.mutate({\n mutation: gql`\n mutation ($id: String!, $reason: String) {\n abortActivityThread(id: $id, reason: $reason) {\n id\n }\n }\n `,\n variables: { id }\n })\n )\n\n if (outcome.ok) {\n /* Nothing more is written on an aborted task: what was typed on it goes with it. */\n this.draft.reset()\n await this.thread.refetch()\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_aborted_successfully') } })\n )\n }\n }\n}\n"]}