@things-factory/worklist 10.1.223 → 10.1.227

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/approval-walk/harness.mjs +2 -2
  2. package/dist-client/bootstrap.js +1 -1
  3. package/dist-client/bootstrap.js.map +1 -1
  4. package/dist-client/components/activity-approval-ribon.d.ts +3 -3
  5. package/dist-client/components/activity-approval-ribon.js +3 -3
  6. package/dist-client/components/activity-approval-ribon.js.map +1 -1
  7. package/dist-client/components/activity-instance-ribon.d.ts +3 -3
  8. package/dist-client/components/activity-instance-ribon.js +3 -3
  9. package/dist-client/components/activity-instance-ribon.js.map +1 -1
  10. package/dist-client/components/activity-thread-ribon.d.ts +3 -3
  11. package/dist-client/components/activity-thread-ribon.js +3 -3
  12. package/dist-client/components/activity-thread-ribon.js.map +1 -1
  13. package/dist-client/components/state-ribon.js +1 -1
  14. package/dist-client/components/state-ribon.js.map +1 -1
  15. package/dist-client/pages/activity-approval/activity-approval-page.js +3 -3
  16. package/dist-client/pages/activity-approval/activity-approval-page.js.map +1 -1
  17. package/dist-client/pages/activity-catalog/activity-stage.d.ts +1 -1
  18. package/dist-client/pages/activity-catalog/activity-stage.js +1 -1
  19. package/dist-client/pages/activity-catalog/activity-stage.js.map +1 -1
  20. package/dist-client/templates/activity-approval-context-template.js +1 -1
  21. package/dist-client/templates/activity-approval-context-template.js.map +1 -1
  22. package/dist-client/templates/activity-thread-context-template.js +1 -1
  23. package/dist-client/templates/activity-thread-context-template.js.map +1 -1
  24. package/dist-client/templates/context-panel.js +7 -7
  25. package/dist-client/templates/context-panel.js.map +1 -1
  26. package/dist-client/tsconfig.tsbuildinfo +1 -1
  27. package/dist-server/controllers/activity-installation/activity-installation-controller.d.ts +2 -2
  28. package/dist-server/controllers/activity-installation/activity-installation-controller.js +2 -2
  29. package/dist-server/controllers/activity-installation/activity-installation-controller.js.map +1 -1
  30. package/dist-server/tsconfig.tsbuildinfo +1 -1
  31. package/helps/dataset/activity-instance-search-page.ko.md +1 -1
  32. package/helps/worklist/activity-approval.ko.md +1 -1
  33. package/helps/worklist/activity-bank-page.ko.md +1 -1
  34. package/helps/worklist/activity-reporter-list.ko.md +1 -1
  35. package/helps/worklist/activity-store.ko.md +1 -1
  36. package/helps/worklist/activity-template.ko.md +1 -1
  37. package/helps/worklist/installable-activity.ko.md +1 -1
  38. package/package.json +12 -12
@@ -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 { client } from '@operato/graphql'\nimport { OxPrompt } from '@operato/popup'\nimport { i18next, localize } from '@operato/i18n'\nimport { ranMutation } from '../../components/say-outcome.js'\nimport { approvalGate } from './approval-gate.js'\nimport { PageView } 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 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 @state() activityApproval: any\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 @state() loaded = false\n /** Why the approval could not be read - ox-page-state says it, with retry (ADR-0060 decision 8). */\n @state() loadError: unknown = null\n private lastId?: string\n private approvalRead = 0\n\n @state() activityThread: any\n @state() board: 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.lastId && this.fetchActivityApproval(this.lastId)}\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.activityApproval?.comment}\n @input=${(e: Event) => {\n this.activityApproval.comment = (e.target as HTMLTextAreaElement).value\n }}\n @change=${(e: Event) => {\n this.activityApproval.comment = (e.target as HTMLTextAreaElement).value\n }}\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 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 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(changes) {\n if (changes.has('activityApproval')) {\n this.updateContext()\n this.focusComment()\n }\n }\n\n async pageUpdated(changes, lifecycle, changedBefore) {\n if (this.active && lifecycle.resourceId) {\n // Entity 360 changes only the query address. Do not reload the same approval and erase its unsaved opinion.\n if (this.lastId === lifecycle.resourceId && !('active' in changes)) return\n this.fetchActivityApproval(lifecycle.resourceId)\n }\n }\n\n async fetchActivityApproval(id) {\n const read = ++this.approvalRead\n if (this.lastId !== id) {\n this.activityApproval = undefined\n this.activityThread = undefined\n this.loaded = false\n }\n this.lastId = id\n this.loadError = null\n\n let response: any\n try {\n response = await client.query({\n query: gql`\n query activityApproval($id: String!) { activityApproval(id: $id) ${ActivityApprovalFetchResult}\n }\n `,\n variables: { id }\n })\n } catch (error) {\n if (read !== this.approvalRead) return\n this.loadError = error\n return\n }\n\n if (read !== this.approvalRead) return\n if (response.errors?.length || !response.data?.activityApproval) {\n this.loadError = response.errors?.length\n ? response.errors\n : new Error(i18next.t('error.activity-approval not found', { activityApproval: id }))\n return\n }\n\n this.activityApproval = response.data.activityApproval\n this.loaded = true\n this.activityThread = this.activityApproval.activityThread\n\n this.updateContext()\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 async rejectActivityApproval() {\n var { id, comment } = this.activityApproval\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 outcome = await ranMutation(() =>\n client.mutate({\n mutation: gql`\n mutation ($id: String!, $comment: String!) { rejectActivityApproval(id: $id, comment: $comment) ${ActivityApprovalFetchResult}\n }\n `,\n variables: { id, comment }\n })\n )\n\n if (outcome.ok) {\n this.activityApproval = outcome.data.rejectActivityApproval\n this.activityThread = this.activityApproval.activityThread\n\n this.updateContext()\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_rejected_successfully') } })\n )\n }\n }\n\n async approveActivityApproval() {\n var { id, comment } = this.activityApproval\n\n if (!(await this.confirmIfIrreversible())) {\n return\n }\n\n const outcome = await ranMutation(() =>\n client.mutate({\n mutation: gql`\n mutation ($id: String!, $comment: String) { approveActivityApproval(id: $id, comment: $comment) ${ActivityApprovalFetchResult}\n }\n `,\n variables: { id, comment }\n })\n )\n\n if (outcome.ok) {\n this.activityApproval = outcome.data.approveActivityApproval\n this.activityThread = this.activityApproval.activityThread\n\n this.updateContext()\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_approved_successfully') } })\n )\n }\n }\n\n async saveActivityApproval() {\n var { id, comment } = this.activityApproval\n\n const outcome = await ranMutation(() =>\n client.mutate({\n mutation: gql`\n mutation ($id: String!, $comment: String) { saveActivityApproval(id: $id, comment: $comment) ${ActivityApprovalFetchResult}\n }\n `,\n variables: { id, comment }\n })\n )\n\n if (outcome.ok) {\n this.activityApproval = outcome.data.saveActivityApproval\n this.activityThread = this.activityApproval.activityThread\n\n this.updateContext()\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_saved_successfully') } })\n )\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 { client } from '@operato/graphql'\nimport { OxPrompt } from '@operato/popup'\nimport { i18next, localize } from '@operato/i18n'\nimport { ranMutation } from '../../components/say-outcome.js'\nimport { approvalGate } from './approval-gate.js'\nimport { PageView } 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 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 @state() activityApproval: any\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 @state() loaded = false\n /** Why the approval could not be read - ox-page-state says it, with retry (ADR-0060 decision 8). */\n @state() loadError: unknown = null\n private lastId?: string\n private approvalRead = 0\n\n @state() activityThread: any\n @state() board: 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.lastId && this.fetchActivityApproval(this.lastId)}\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.activityApproval?.comment}\n @input=${(e: Event) => {\n this.activityApproval.comment = (e.target as HTMLTextAreaElement).value\n }}\n @change=${(e: Event) => {\n this.activityApproval.comment = (e.target as HTMLTextAreaElement).value\n }}\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 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 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(changes) {\n if (changes.has('activityApproval')) {\n this.updateContext()\n this.focusComment()\n }\n }\n\n async pageUpdated(changes, lifecycle, changedBefore) {\n if (this.active && lifecycle.resourceId) {\n // Entity 360 changes only the query address. Do not reload the same approval and erase its unsaved opinion.\n if (this.lastId === lifecycle.resourceId && !('active' in changes)) return\n this.fetchActivityApproval(lifecycle.resourceId)\n }\n }\n\n async fetchActivityApproval(id) {\n const read = ++this.approvalRead\n if (this.lastId !== id) {\n this.activityApproval = undefined\n this.activityThread = undefined\n this.loaded = false\n }\n this.lastId = id\n this.loadError = null\n\n let response: any\n try {\n response = await client.query({\n query: gql`\n query activityApproval($id: String!) { activityApproval(id: $id) ${ActivityApprovalFetchResult}\n }\n `,\n variables: { id }\n })\n } catch (error) {\n if (read !== this.approvalRead) return\n this.loadError = error\n return\n }\n\n if (read !== this.approvalRead) return\n if (response.errors?.length || !response.data?.activityApproval) {\n this.loadError = response.errors?.length\n ? response.errors\n : new Error(i18next.t('error.activity-approval not found', { activityApproval: id }))\n return\n }\n\n this.activityApproval = response.data.activityApproval\n this.loaded = true\n this.activityThread = this.activityApproval.activityThread\n\n this.updateContext()\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 async rejectActivityApproval() {\n var { id, comment } = this.activityApproval\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 outcome = await ranMutation(() =>\n client.mutate({\n mutation: gql`\n mutation ($id: String!, $comment: String!) { rejectActivityApproval(id: $id, comment: $comment) ${ActivityApprovalFetchResult}\n }\n `,\n variables: { id, comment }\n })\n )\n\n if (outcome.ok) {\n this.activityApproval = outcome.data.rejectActivityApproval\n this.activityThread = this.activityApproval.activityThread\n\n this.updateContext()\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_rejected_successfully') } })\n )\n }\n }\n\n async approveActivityApproval() {\n var { id, comment } = this.activityApproval\n\n if (!(await this.confirmIfIrreversible())) {\n return\n }\n\n const outcome = await ranMutation(() =>\n client.mutate({\n mutation: gql`\n mutation ($id: String!, $comment: String) { approveActivityApproval(id: $id, comment: $comment) ${ActivityApprovalFetchResult}\n }\n `,\n variables: { id, comment }\n })\n )\n\n if (outcome.ok) {\n this.activityApproval = outcome.data.approveActivityApproval\n this.activityThread = this.activityApproval.activityThread\n\n this.updateContext()\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_approved_successfully') } })\n )\n }\n }\n\n async saveActivityApproval() {\n var { id, comment } = this.activityApproval\n\n const outcome = await ranMutation(() =>\n client.mutate({\n mutation: gql`\n mutation ($id: String!, $comment: String) { saveActivityApproval(id: $id, comment: $comment) ${ActivityApprovalFetchResult}\n }\n `,\n variables: { id, comment }\n })\n )\n\n if (outcome.ok) {\n this.activityApproval = outcome.data.saveActivityApproval\n this.activityThread = this.activityApproval.activityThread\n\n this.updateContext()\n\n document.dispatchEvent(\n new CustomEvent('notify', { detail: { message: i18next.t('text.task_is_saved_successfully') } })\n )\n }\n }\n}\n"]}
@@ -17,7 +17,7 @@ export declare const STAGE_ORDER: string[];
17
17
  /**
18
18
  * 전선에서 온 단계를 **선언된 값으로 되돌린다.**
19
19
  *
20
- * 서버의 enum 철자와 화면의 철자가 판마다 달라진 적이 있어서, 글자만 남기고 맞춘다. 못 맞추면
20
+ * 서버의 enum 철자와 화면의 철자가 버전마다 달라진 적이 있어서, 글자만 남기고 맞춘다. 못 맞추면
21
21
  * 빈 문자열이다 — 모르는 것을 아무 단계로 채우지 않는다.
22
22
  */
23
23
  export declare function canonicalStage(raw?: string): string;
@@ -17,7 +17,7 @@ export const STAGE_ORDER = ['working', 'partial', 'declared', 'planned', 'not-wo
17
17
  /**
18
18
  * 전선에서 온 단계를 **선언된 값으로 되돌린다.**
19
19
  *
20
- * 서버의 enum 철자와 화면의 철자가 판마다 달라진 적이 있어서, 글자만 남기고 맞춘다. 못 맞추면
20
+ * 서버의 enum 철자와 화면의 철자가 버전마다 달라진 적이 있어서, 글자만 남기고 맞춘다. 못 맞추면
21
21
  * 빈 문자열이다 — 모르는 것을 아무 단계로 채우지 않는다.
22
22
  */
23
23
  export function canonicalStage(raw) {
@@ -1 +1 @@
1
- {"version":3,"file":"activity-stage.js","sourceRoot":"","sources":["../../../client/pages/activity-catalog/activity-stage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,CAAC,CAAA;AAExF;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;SAC3B,WAAW,EAAE;SACb,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;IAEzB,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAA;AAC/E,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,MAAM,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IAErD,sDAAsD;IACtD,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IAEjC,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,cAAc,CAAA;AAC7D,CAAC","sourcesContent":["/**\n * 업무의 단계 — 선언된 값을 읽고, 차례를 정한다.\n *\n * 카탈로그 목록과 업무 상세가 같은 답을 내야 해서 여기 한 벌만 둔다. 두 벌이 되면 한쪽만 고쳐도\n * 오류가 안 나고, 같은 업무가 목록과 상세에서 다른 단계로 보인다.\n */\n\n/**\n * 카드 차례 — **쓸 수 있는 것이 위.**\n *\n * 사용자는 지금 오는 업무를 보러 오고, 우리는 남은 것을 보러 온다. 두 독자를 한 화면에 두면서\n * 순서로 구분한다: 위쪽은 실제로 오는 업무, 아래쪽은 아직 없는 것과 여기 두지 않기로 한 것.\n *\n * **「업무함 아님」은 「예정」과 붙여 두지 않는다.** 섞이면 판단이 약속으로 읽힌다 — 안 만들기로\n * 정한 것이 곧 될 것처럼 보인다.\n */\nexport const STAGE_ORDER = ['working', 'partial', 'declared', 'planned', 'not-worklist']\n\n/**\n * 전선에서 온 단계를 **선언된 값으로 되돌린다.**\n *\n * 서버의 enum 철자와 화면의 철자가 판마다 달라진 적이 있어서, 글자만 남기고 맞춘다. 못 맞추면\n * 빈 문자열이다 — 모르는 것을 아무 단계로 채우지 않는다.\n */\nexport function canonicalStage(raw?: string): string {\n const flat = String(raw || '')\n .toLowerCase()\n .replace(/[^a-z]/g, '')\n\n return STAGE_ORDER.find(stage => stage.replace(/[^a-z]/g, '') === flat) || ''\n}\n\nexport function stageRank(stage?: string): number {\n const at = STAGE_ORDER.indexOf(canonicalStage(stage))\n\n /* 선언이 없는 것은 오는 것들 뒤, 예정 앞에 둔다 — 모른다는 것이 「없다」는 아니다. */\n return at < 0 ? STAGE_ORDER.indexOf('declared') : at\n}\n\n/**\n * 이 업무가 **설치될 수 있는 것인가.**\n *\n * 아직 만들지 않은 것(예정 · 업무함 아님)과 선언이 없는 것은 설치라는 말이 성립하지 않는다.\n * 그런 카드에 「아직 사용 안 함」을 붙이면 「예정」과 같은 말을 두 번 하는 것이다.\n */\nexport function isRegistered(stage?: string): boolean {\n const one = canonicalStage(stage)\n\n return !!one && one !== 'planned' && one !== 'not-worklist'\n}\n"]}
1
+ {"version":3,"file":"activity-stage.js","sourceRoot":"","sources":["../../../client/pages/activity-catalog/activity-stage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,CAAC,CAAA;AAExF;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;SAC3B,WAAW,EAAE;SACb,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;IAEzB,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAA;AAC/E,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,MAAM,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IAErD,sDAAsD;IACtD,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IAEjC,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,cAAc,CAAA;AAC7D,CAAC","sourcesContent":["/**\n * 업무의 단계 — 선언된 값을 읽고, 차례를 정한다.\n *\n * 카탈로그 목록과 업무 상세가 같은 답을 내야 해서 여기 한 벌만 둔다. 두 벌이 되면 한쪽만 고쳐도\n * 오류가 안 나고, 같은 업무가 목록과 상세에서 다른 단계로 보인다.\n */\n\n/**\n * 카드 차례 — **쓸 수 있는 것이 위.**\n *\n * 사용자는 지금 오는 업무를 보러 오고, 우리는 남은 것을 보러 온다. 두 독자를 한 화면에 두면서\n * 순서로 구분한다: 위쪽은 실제로 오는 업무, 아래쪽은 아직 없는 것과 여기 두지 않기로 한 것.\n *\n * **「업무함 아님」은 「예정」과 붙여 두지 않는다.** 섞이면 판단이 약속으로 읽힌다 — 안 만들기로\n * 정한 것이 곧 될 것처럼 보인다.\n */\nexport const STAGE_ORDER = ['working', 'partial', 'declared', 'planned', 'not-worklist']\n\n/**\n * 전선에서 온 단계를 **선언된 값으로 되돌린다.**\n *\n * 서버의 enum 철자와 화면의 철자가 버전마다 달라진 적이 있어서, 글자만 남기고 맞춘다. 못 맞추면\n * 빈 문자열이다 — 모르는 것을 아무 단계로 채우지 않는다.\n */\nexport function canonicalStage(raw?: string): string {\n const flat = String(raw || '')\n .toLowerCase()\n .replace(/[^a-z]/g, '')\n\n return STAGE_ORDER.find(stage => stage.replace(/[^a-z]/g, '') === flat) || ''\n}\n\nexport function stageRank(stage?: string): number {\n const at = STAGE_ORDER.indexOf(canonicalStage(stage))\n\n /* 선언이 없는 것은 오는 것들 뒤, 예정 앞에 둔다 — 모른다는 것이 「없다」는 아니다. */\n return at < 0 ? STAGE_ORDER.indexOf('declared') : at\n}\n\n/**\n * 이 업무가 **설치될 수 있는 것인가.**\n *\n * 아직 만들지 않은 것(예정 · 업무함 아님)과 선언이 없는 것은 설치라는 말이 성립하지 않는다.\n * 그런 카드에 「아직 사용 안 함」을 붙이면 「예정」과 같은 말을 두 번 하는 것이다.\n */\nexport function isRegistered(stage?: string): boolean {\n const one = canonicalStage(stage)\n\n return !!one && one !== 'planned' && one !== 'not-worklist'\n}\n"]}
@@ -83,7 +83,7 @@ let ActivityApprovalContextTemplate = class ActivityApprovalContextTemplate exte
83
83
  ? html ` <!--
84
84
  팝업 안에서는 편다. 팝업은 내용에 맞춰지지 않고 60%×60% 로 고정되므로
85
85
  (@operato/popup 의 [hovering=center]), 접어 두면 아래가 흰 여백으로 남는다.
86
- 그리고 여기서 이력은 보조가 아니다 — 이 판을 여는 이유의 절반이 「어떻게 여기까지 왔나」다.
86
+ 그리고 여기서 이력은 보조가 아니다 — 이 패널을 여는 이유의 절반이 「어떻게 여기까지 왔나」다.
87
87
  -->
88
88
  <activity-thread-timeline .activityThread=${activityThread} open short-form></activity-thread-timeline> `
89
89
  : nothing}
@@ -1 +1 @@
1
- {"version":3,"file":"activity-approval-context-template.js","sourceRoot":"","sources":["../../client/templates/activity-approval-context-template.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '../components/activity-thread-timeline'\n\nimport { html, css, LitElement, nothing } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { ContextToolbarOverlayStyle } from '@operato/context/ox-context-toolbar-overlay-style.js'\nimport { RouteController } from '@operato/shell'\nimport { i18next } from '@operato/i18n'\n\nimport { ContextPanelStyles, valueCell, whenCell } from './context-panel.js'\nimport { personValue } from '../components/activity-fields.js'\n\nimport '@things-factory/organization/dist-client/component/approval-line-view.js'\n\n/**\n * Who judged this step.\n *\n * An empty approver on a step nobody has reached is a state, not a missing value. The row used to\n * fall through to the generic 「값 없음」, which covers \"there is none, or the screen could not fetch\n * it\" — on a step that is simply waiting, that reads as a defect. Steps chosen by role have no\n * person until someone acts, so every pending approval showed it.\n *\n * The role is not named here. The diagram two inches above already lights up the waiting step and\n * labels it 역할; repeating it in this row says the same thing twice.\n *\n * Once a judgment exists the approver is a real person, and an empty one there would be a genuine\n * gap — so that case keeps the generic fallback.\n */\nfunction approverCell(approver: { name?: string } | undefined, judgment: string | undefined) {\n if (approver?.name || judgment) {\n return personValue(approver)\n }\n\n return html`<span class=\"none\">${i18next.t('text.approver-not-yet')}</span>`\n}\n\n@customElement('activity-approval-context-template')\nclass ActivityApprovalContextTemplate extends LitElement {\n static styles = [ContextToolbarOverlayStyle, ContextPanelStyles]\n\n @property({ type: Object }) private activityApproval\n\n private _routeCtrl = new RouteController(this)\n\n render() {\n const activityApproval = this._routeCtrl.context.activityApproval || this.activityApproval || {}\n\n const { round, order, approver, judgment, createdAt, activityThread } = activityApproval || {}\n const { state, dueAt, assignedAt, assignee, activityInstance, activityApprovals } = activityThread || {}\n const { name, description, thumbnail, approvalLine } = activityInstance || {}\n\n return html`\n <div flow>\n <div approval-line>\n <!-- 이 결재 줄의 순번이 곧 지금 단계다 — ribbon 과 같은 값을 쓴다. -->\n ${approvalLine\n ? html`<approval-line-view .model=${approvalLine} .current=${order}></approval-line-view>`\n : html``}\n </div>\n </div>\n\n <dl class=\"given\">\n <!-- 차수는 1일 때 적지 않는다. 2차 이상일 때만 「되돌아왔다」는 사실이 된다. -->\n ${Number(round) > 1\n ? html`\n <dt>${i18next.t('field.round')}</dt>\n <dd class=\"strong\">${round}</dd>\n `\n : nothing}\n\n <dt>${i18next.t('field.approval-order')}</dt>\n <dd class=\"strong\">${valueCell(order)}</dd>\n\n <dt>${i18next.t('field.wl-owner')}</dt>\n <dd class=\"strong\">${personValue(assignee)}</dd>\n\n <dt>${i18next.t('field.approver')}</dt>\n <dd class=\"strong\">${approverCell(approver, judgment)}</dd>\n\n <dt>${i18next.t('field.assigned-at')}</dt>\n <dd>${whenCell(assignedAt)}</dd>\n\n <dt>${i18next.t('field.due-at')}</dt>\n <dd>${whenCell(dueAt)}</dd>\n\n <!-- 전에는 라벨이 since 였다 — 다섯 언어를 갖춘 화면에 영문 한 낱말이 박혀 있었다. -->\n <dt>${i18next.t('field.approval-submitted-at')}</dt>\n <dd>${whenCell(createdAt)}</dd>\n </dl>\n\n ${activityApprovals && activityApprovals.length > 0\n ? html` <!--\n 팝업 안에서는 편다. 팝업은 내용에 맞춰지지 않고 60%×60% 로 고정되므로\n (@operato/popup 의 [hovering=center]), 접어 두면 아래가 흰 여백으로 남는다.\n 그리고 여기서 이력은 보조가 아니다 — 이 판을 여는 이유의 절반이 「어떻게 여기까지 왔나」다.\n -->\n <activity-thread-timeline .activityThread=${activityThread} open short-form></activity-thread-timeline> `\n : nothing}\n ${thumbnail\n ? html` <div thumbnail>\n <img src=${thumbnail} />\n </div>`\n : html``}\n `\n }\n\n}\n"]}
1
+ {"version":3,"file":"activity-approval-context-template.js","sourceRoot":"","sources":["../../client/templates/activity-approval-context-template.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '../components/activity-thread-timeline'\n\nimport { html, css, LitElement, nothing } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { ContextToolbarOverlayStyle } from '@operato/context/ox-context-toolbar-overlay-style.js'\nimport { RouteController } from '@operato/shell'\nimport { i18next } from '@operato/i18n'\n\nimport { ContextPanelStyles, valueCell, whenCell } from './context-panel.js'\nimport { personValue } from '../components/activity-fields.js'\n\nimport '@things-factory/organization/dist-client/component/approval-line-view.js'\n\n/**\n * Who judged this step.\n *\n * An empty approver on a step nobody has reached is a state, not a missing value. The row used to\n * fall through to the generic 「값 없음」, which covers \"there is none, or the screen could not fetch\n * it\" — on a step that is simply waiting, that reads as a defect. Steps chosen by role have no\n * person until someone acts, so every pending approval showed it.\n *\n * The role is not named here. The diagram two inches above already lights up the waiting step and\n * labels it 역할; repeating it in this row says the same thing twice.\n *\n * Once a judgment exists the approver is a real person, and an empty one there would be a genuine\n * gap — so that case keeps the generic fallback.\n */\nfunction approverCell(approver: { name?: string } | undefined, judgment: string | undefined) {\n if (approver?.name || judgment) {\n return personValue(approver)\n }\n\n return html`<span class=\"none\">${i18next.t('text.approver-not-yet')}</span>`\n}\n\n@customElement('activity-approval-context-template')\nclass ActivityApprovalContextTemplate extends LitElement {\n static styles = [ContextToolbarOverlayStyle, ContextPanelStyles]\n\n @property({ type: Object }) private activityApproval\n\n private _routeCtrl = new RouteController(this)\n\n render() {\n const activityApproval = this._routeCtrl.context.activityApproval || this.activityApproval || {}\n\n const { round, order, approver, judgment, createdAt, activityThread } = activityApproval || {}\n const { state, dueAt, assignedAt, assignee, activityInstance, activityApprovals } = activityThread || {}\n const { name, description, thumbnail, approvalLine } = activityInstance || {}\n\n return html`\n <div flow>\n <div approval-line>\n <!-- 이 결재 줄의 순번이 곧 지금 단계다 — ribbon 과 같은 값을 쓴다. -->\n ${approvalLine\n ? html`<approval-line-view .model=${approvalLine} .current=${order}></approval-line-view>`\n : html``}\n </div>\n </div>\n\n <dl class=\"given\">\n <!-- 차수는 1일 때 적지 않는다. 2차 이상일 때만 「되돌아왔다」는 사실이 된다. -->\n ${Number(round) > 1\n ? html`\n <dt>${i18next.t('field.round')}</dt>\n <dd class=\"strong\">${round}</dd>\n `\n : nothing}\n\n <dt>${i18next.t('field.approval-order')}</dt>\n <dd class=\"strong\">${valueCell(order)}</dd>\n\n <dt>${i18next.t('field.wl-owner')}</dt>\n <dd class=\"strong\">${personValue(assignee)}</dd>\n\n <dt>${i18next.t('field.approver')}</dt>\n <dd class=\"strong\">${approverCell(approver, judgment)}</dd>\n\n <dt>${i18next.t('field.assigned-at')}</dt>\n <dd>${whenCell(assignedAt)}</dd>\n\n <dt>${i18next.t('field.due-at')}</dt>\n <dd>${whenCell(dueAt)}</dd>\n\n <!-- 전에는 라벨이 since 였다 — 다섯 언어를 갖춘 화면에 영문 한 낱말이 박혀 있었다. -->\n <dt>${i18next.t('field.approval-submitted-at')}</dt>\n <dd>${whenCell(createdAt)}</dd>\n </dl>\n\n ${activityApprovals && activityApprovals.length > 0\n ? html` <!--\n 팝업 안에서는 편다. 팝업은 내용에 맞춰지지 않고 60%×60% 로 고정되므로\n (@operato/popup 의 [hovering=center]), 접어 두면 아래가 흰 여백으로 남는다.\n 그리고 여기서 이력은 보조가 아니다 — 이 패널을 여는 이유의 절반이 「어떻게 여기까지 왔나」다.\n -->\n <activity-thread-timeline .activityThread=${activityThread} open short-form></activity-thread-timeline> `\n : nothing}\n ${thumbnail\n ? html` <div thumbnail>\n <img src=${thumbnail} />\n </div>`\n : html``}\n `\n }\n\n}\n"]}
@@ -58,7 +58,7 @@ let ActivityThreadContextTemplate = class ActivityThreadContextTemplate extends
58
58
  <!--
59
59
  팝업 안에서는 편다. 팝업은 내용에 맞춰지지 않고 60%×60% 로 고정되므로
60
60
  (@operato/popup 의 [hovering=center]), 접어 두면 아래가 흰 여백으로 남는다.
61
- 그리고 여기서 이력은 보조가 아니다 — 이 판을 여는 이유의 절반이 「어떻게 여기까지 왔나」다.
61
+ 그리고 여기서 이력은 보조가 아니다 — 이 패널을 여는 이유의 절반이 「어떻게 여기까지 왔나」다.
62
62
  -->
63
63
  <activity-thread-timeline .activityThread=${activityThread} open short-form></activity-thread-timeline>
64
64
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"activity-thread-context-template.js","sourceRoot":"","sources":["../../client/templates/activity-thread-context-template.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,0EAA0E,CAAA;AACjF,OAAO,wCAAwC,CAAA;AAE/C,OAAO,EAAE,IAAI,EAAO,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,sDAAsD,CAAA;AACjG,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAE9D,OAAO,EAAE,kBAAkB,EAAa,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAG9D,IAAM,6BAA6B,GAAnC,MAAM,6BAA8B,SAAQ,UAAU;IAAtD;;QAKU,eAAU,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,CAAA;IAqDhD,CAAC;aAzDQ,WAAM,GAAG,CAAC,0BAA0B,EAAE,kBAAkB,CAAC,AAAnD,CAAmD;IAMhE,MAAM;QACJ,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,IAAI,EAAE,CAAA;QAE1F,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,GACpG,cAAc,IAAI,EAAE,CAAA;QACtB,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,gBAAgB,IAAI,EAAE,CAAA;QAElE,OAAO,IAAI,CAAA;;;YAGH,YAAY;YACZ,CAAC,CAAC,IAAI,CAAA;yBACO,YAAY;2BACV,oBAAoB,CAAC,iBAAiB,CAAC;qCAC7B;YACzB,CAAC,CAAC,IAAI,CAAA,EAAE;;;;;;UAMV,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;YACjB,CAAC,CAAC,IAAI,CAAA;oBACI,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;mCACT,KAAK;aAC3B;YACH,CAAC,CAAC,OAAO;;;cAGL,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;6BACZ,WAAW,CAAC,QAAQ,CAAC;;cAEpC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;cAC9B,QAAQ,CAAC,UAAU,CAAC;;cAEpB,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;cACzB,QAAQ,CAAC,KAAK,CAAC;;cAEf,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;cAChC,QAAQ,CAAC,YAAY,CAAC;;;;;;;;kDAQc,cAAc;KAC3D,CAAA;IACH,CAAC;;AArDmC;IAAnC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;qEAAuB;AAH9C,6BAA6B;IADlC,aAAa,CAAC,kCAAkC,CAAC;GAC5C,6BAA6B,CA0DlC","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@things-factory/organization/dist-client/component/approval-line-view.js'\nimport '../components/activity-thread-timeline'\n\nimport { html, css, LitElement, nothing } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { ContextToolbarOverlayStyle } from '@operato/context/ox-context-toolbar-overlay-style.js'\nimport { RouteController } from '@operato/shell'\nimport { i18next } from '@operato/i18n'\n\nimport { currentApprovalOrder } from '../approval-progress.js'\n\nimport { ContextPanelStyles, valueCell, whenCell } from './context-panel.js'\nimport { personValue } from '../components/activity-fields.js'\n\n@customElement('activity-thread-context-template')\nclass ActivityThreadContextTemplate extends LitElement {\n static styles = [ContextToolbarOverlayStyle, ContextPanelStyles]\n\n @property({ type: Object }) private activityThread\n\n private _routeCtrl = new RouteController(this)\n\n render() {\n const activityThread = this._routeCtrl.context.activityThread || this.activityThread || {}\n\n const { state, round, dueAt, assignedAt, terminatedAt, assignee, activityInstance, activityApprovals } =\n activityThread || {}\n const { name, description, approvalLine } = activityInstance || {}\n\n return html`\n <div flow>\n <div approval-line>\n ${approvalLine\n ? html`<approval-line-view\n .model=${approvalLine}\n .current=${currentApprovalOrder(activityApprovals)}\n ></approval-line-view>`\n : html``}\n </div>\n </div>\n\n <dl class=\"given\">\n <!-- 차수는 1일 때 적지 않는다 — 거의 모든 건이 1차라 그 줄이 아무것도 알려 주지 않는다. -->\n ${Number(round) > 1\n ? html`\n <dt>${i18next.t('field.round')}</dt>\n <dd class=\"strong\">${round}</dd>\n `\n : nothing}\n\n <!-- 화면 본문과 같은 낱말을 쓴다 — 목록의 칸도 「담당자」다. -->\n <dt>${i18next.t('field.wl-owner')}</dt>\n <dd class=\"strong\">${personValue(assignee)}</dd>\n\n <dt>${i18next.t('field.assigned-at')}</dt>\n <dd>${whenCell(assignedAt)}</dd>\n\n <dt>${i18next.t('field.due-at')}</dt>\n <dd>${whenCell(dueAt)}</dd>\n\n <dt>${i18next.t('field.terminated-at')}</dt>\n <dd>${whenCell(terminatedAt)}</dd>\n </dl>\n\n <!--\n 팝업 안에서는 편다. 팝업은 내용에 맞춰지지 않고 60%×60% 로 고정되므로\n (@operato/popup 의 [hovering=center]), 접어 두면 아래가 흰 여백으로 남는다.\n 그리고 여기서 이력은 보조가 아니다 — 이 판을 여는 이유의 절반이 「어떻게 여기까지 왔나」다.\n -->\n <activity-thread-timeline .activityThread=${activityThread} open short-form></activity-thread-timeline>\n `\n }\n\n}\n"]}
1
+ {"version":3,"file":"activity-thread-context-template.js","sourceRoot":"","sources":["../../client/templates/activity-thread-context-template.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,0EAA0E,CAAA;AACjF,OAAO,wCAAwC,CAAA;AAE/C,OAAO,EAAE,IAAI,EAAO,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,sDAAsD,CAAA;AACjG,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAE9D,OAAO,EAAE,kBAAkB,EAAa,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAG9D,IAAM,6BAA6B,GAAnC,MAAM,6BAA8B,SAAQ,UAAU;IAAtD;;QAKU,eAAU,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,CAAA;IAqDhD,CAAC;aAzDQ,WAAM,GAAG,CAAC,0BAA0B,EAAE,kBAAkB,CAAC,AAAnD,CAAmD;IAMhE,MAAM;QACJ,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,IAAI,EAAE,CAAA;QAE1F,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,GACpG,cAAc,IAAI,EAAE,CAAA;QACtB,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,gBAAgB,IAAI,EAAE,CAAA;QAElE,OAAO,IAAI,CAAA;;;YAGH,YAAY;YACZ,CAAC,CAAC,IAAI,CAAA;yBACO,YAAY;2BACV,oBAAoB,CAAC,iBAAiB,CAAC;qCAC7B;YACzB,CAAC,CAAC,IAAI,CAAA,EAAE;;;;;;UAMV,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;YACjB,CAAC,CAAC,IAAI,CAAA;oBACI,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;mCACT,KAAK;aAC3B;YACH,CAAC,CAAC,OAAO;;;cAGL,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;6BACZ,WAAW,CAAC,QAAQ,CAAC;;cAEpC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;cAC9B,QAAQ,CAAC,UAAU,CAAC;;cAEpB,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;cACzB,QAAQ,CAAC,KAAK,CAAC;;cAEf,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;cAChC,QAAQ,CAAC,YAAY,CAAC;;;;;;;;kDAQc,cAAc;KAC3D,CAAA;IACH,CAAC;;AArDmC;IAAnC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;qEAAuB;AAH9C,6BAA6B;IADlC,aAAa,CAAC,kCAAkC,CAAC;GAC5C,6BAA6B,CA0DlC","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@things-factory/organization/dist-client/component/approval-line-view.js'\nimport '../components/activity-thread-timeline'\n\nimport { html, css, LitElement, nothing } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { ContextToolbarOverlayStyle } from '@operato/context/ox-context-toolbar-overlay-style.js'\nimport { RouteController } from '@operato/shell'\nimport { i18next } from '@operato/i18n'\n\nimport { currentApprovalOrder } from '../approval-progress.js'\n\nimport { ContextPanelStyles, valueCell, whenCell } from './context-panel.js'\nimport { personValue } from '../components/activity-fields.js'\n\n@customElement('activity-thread-context-template')\nclass ActivityThreadContextTemplate extends LitElement {\n static styles = [ContextToolbarOverlayStyle, ContextPanelStyles]\n\n @property({ type: Object }) private activityThread\n\n private _routeCtrl = new RouteController(this)\n\n render() {\n const activityThread = this._routeCtrl.context.activityThread || this.activityThread || {}\n\n const { state, round, dueAt, assignedAt, terminatedAt, assignee, activityInstance, activityApprovals } =\n activityThread || {}\n const { name, description, approvalLine } = activityInstance || {}\n\n return html`\n <div flow>\n <div approval-line>\n ${approvalLine\n ? html`<approval-line-view\n .model=${approvalLine}\n .current=${currentApprovalOrder(activityApprovals)}\n ></approval-line-view>`\n : html``}\n </div>\n </div>\n\n <dl class=\"given\">\n <!-- 차수는 1일 때 적지 않는다 — 거의 모든 건이 1차라 그 줄이 아무것도 알려 주지 않는다. -->\n ${Number(round) > 1\n ? html`\n <dt>${i18next.t('field.round')}</dt>\n <dd class=\"strong\">${round}</dd>\n `\n : nothing}\n\n <!-- 화면 본문과 같은 낱말을 쓴다 — 목록의 칸도 「담당자」다. -->\n <dt>${i18next.t('field.wl-owner')}</dt>\n <dd class=\"strong\">${personValue(assignee)}</dd>\n\n <dt>${i18next.t('field.assigned-at')}</dt>\n <dd>${whenCell(assignedAt)}</dd>\n\n <dt>${i18next.t('field.due-at')}</dt>\n <dd>${whenCell(dueAt)}</dd>\n\n <dt>${i18next.t('field.terminated-at')}</dt>\n <dd>${whenCell(terminatedAt)}</dd>\n </dl>\n\n <!--\n 팝업 안에서는 편다. 팝업은 내용에 맞춰지지 않고 60%×60% 로 고정되므로\n (@operato/popup 의 [hovering=center]), 접어 두면 아래가 흰 여백으로 남는다.\n 그리고 여기서 이력은 보조가 아니다 — 이 패널을 여는 이유의 절반이 「어떻게 여기까지 왔나」다.\n -->\n <activity-thread-timeline .activityThread=${activityThread} open short-form></activity-thread-timeline>\n `\n }\n\n}\n"]}
@@ -24,7 +24,7 @@ import { fieldValue } from '../components/activity-fields.js';
24
24
  */
25
25
  /*
26
26
  * 스크롤바는 제품 표준을 따른다(@operato/styles 의 ScrollbarStyles — 5px · 투명 트랙).
27
- * 이 판은 반드시 스크롤한다(팝업이 고정 높이라 내용이 길면 안에서 넘긴다). 그런데 스타일을 안
27
+ * 이 패널은 반드시 스크롤한다(팝업이 고정 높이라 내용이 길면 안에서 넘긴다). 그런데 스타일을 안
28
28
  * 넣어 두어 좁은 화면에서 브라우저 기본 스크롤바가 그대로 나왔다 — 이 앱의 다른 스크롤 영역과
29
29
  * 굵기가 달랐다.
30
30
  */
@@ -36,8 +36,8 @@ export const ContextPanelStyles = [
36
36
  * openPopup 이 만드는 상자 안에 들어간다. 그 상자가 폭과 높이를 정하고
37
37
  * ([hovering=center] 의 60%×60%), 슬롯에 들어온 것을 width/height 100% 로 늘린다.
38
38
  *
39
- * 여기서 min-width / max-width / max-height 를 또 정했다가 **판이 상자보다 작아졌다** —
40
- * 실측: 상자 598px · 판 560px, 오른쪽 38px 이 빈 채로 남았다. 상자를 그대로 채운다.
39
+ * 여기서 min-width / max-width / max-height 를 또 정했다가 **패널이 상자보다 작아졌다** —
40
+ * 실측: 상자 598px · 패널 560px, 오른쪽 38px 이 빈 채로 남았다. 상자를 그대로 채운다.
41
41
  *
42
42
  * 면·테두리·모서리·그림자도 팝업의 것을 쓴다 — 여기서 또 그리면 상자가 두 겹이 된다.
43
43
  */
@@ -55,10 +55,10 @@ export const ContextPanelStyles = [
55
55
  }
56
56
 
57
57
  /*
58
- * 결재선 — 판의 머리. 아래로 한 줄 그어 정보와 나눈다.
58
+ * 결재선 — 패널의 머리. 아래로 한 줄 그어 정보와 나눈다.
59
59
  *
60
60
  * 회색으로 채우지 않는다(SurfaceStyles 가 정한 규칙). 전에는 결재선 컴포넌트가 자기 회색 면을
61
- * 칠해서 흰 판 위에 띠 하나가 얹혀 있었다.
61
+ * 칠해서 흰 패널 위에 띠 하나가 얹혀 있었다.
62
62
  */
63
63
  div[flow] {
64
64
  padding: var(--spacing-medium, 8px) var(--spacing-medium, 8px) 0;
@@ -66,7 +66,7 @@ export const ContextPanelStyles = [
66
66
  /*
67
67
  * 결재선이 판보다 넓을 수 있다 — 4단계짜리(나 · 품질팀장 · 공장장 · 생산팀장)가 좁은 화면의
68
68
  * 팝업에서 오른쪽으로 잘렸다. 줄바꿈은 안 된다(단계 사이 이음선이 절대 위치라 줄이 바뀌면
69
- * 허공에 그려진다). 그래서 이 띠 안에서만 가로로 넘긴다 — 판의 나머지는 그대로다.
69
+ * 허공에 그려진다). 그래서 이 띠 안에서만 가로로 넘긴다 — 패널의 나머지는 그대로다.
70
70
  */
71
71
  overflow-x: auto;
72
72
  }
@@ -79,7 +79,7 @@ export const ContextPanelStyles = [
79
79
  *
80
80
  * 왼쪽 기준선이 사라진다 라벨을 세로로 훑어 읽는 목록인데, 항목 수와 글자 길이에 따라
81
81
  * 블록이 좌우로 움직인다
82
- * 판 안에 축이 둘이 된다 아래 타임라인은 왼쪽 정박이라 두 기준선이 어긋난다
82
+ * 패널 안에 축이 둘이 된다 아래 타임라인은 왼쪽 정박이라 두 기준선이 어긋난다
83
83
  * 화면과 달라진다 상세 · 완료 조회의 같은 구조는 왼쪽 정박이다
84
84
  *
85
85
  * label/value 목록은 값이 짧으면 오른쪽이 남는다. 그것이 정상이다.
@@ -1 +1 @@
1
- {"version":3,"file":"context-panel.js","sourceRoot":"","sources":["../../client/templates/context-panel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE/B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAE7D;;;;;;;;;;;;;;;;;;GAkBG;AACH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,eAAe;IACf,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuIJ;CACA,CAAA;AAED,uCAAuC;AACvC,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,IAAI,CAAA,0CAA0C,OAAO,CAAC,CAAC,CAAC,uBAAuB,GAAG,KAAK,CAAC,SAAS,CAAA;AAC1G,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,QAAQ,CAAC,EAA2B;IAClD,OAAO,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAA;AACjC,CAAC;AAED,gCAAgC;AAChC,MAAM,UAAU,SAAS,CAAC,KAAW;IACnC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAA;AAC1B,CAAC","sourcesContent":["import { css, html } from 'lit'\n\nimport { ScrollbarStyles } from '@operato/styles'\n\nimport { i18next } from '@operato/i18n'\n\nimport { whenText } from '../when.js'\nimport { fieldValue } from '../components/activity-fields.js'\n\n/**\n * 문서 아이콘이 여는 곁 패널 — **세 템플릿이 한 모양을 쓴다.**\n *\n * activity-thread · activity-approval · activity-instance 의 context template 셋이 같은 것을 보인다\n * (결재선 · 이름 · 설명 · 상태 · 차수 · 담당자 · 시각 셋). 그런데 셋이 각자 스타일을 갖고 있었고,\n * 상태색 여덟 개와 자체 시각 formatter 가 세 벌로 복사되어 있었다.\n *\n * ── 무엇을 고쳤나 (2026-09-06) ─────────────────────────────────────────────\n * 1. 시각이 Monday, August 31, 2026 at 11:09 PM 이었다. 세 템플릿이 각자\n * Intl.DateTimeFormat(navigator.language, dateStyle full) 을 들고 있었다. 이 패널을 여는 화면은\n * 바로 뒤에서 2026. 8. 31. 오후 11:09 로 적고 있다 — 같은 값이 두 뼘 사이에서 두 말로 나왔다.\n * 2. 왼쪽에 상태색 삼각형이 붙어 있었다. 하드코딩된 hex 여덟 개 중 하나를 골라 칠하는 장식인데,\n * 상태는 이미 패널 안에 점과 글자로 적혀 있다. 같은 것을 두 번 말하면서 앱 팔레트를 따르지도\n * 않았다.\n * 3. 줄마다 배경색이 번갈아 깔렸다(nth-child odd). 여덟 줄짜리 표에 얼룩이 지고, 라벨 폭이 25% 로\n * 고정이라 좁은 화면에서는 값이 밀렸다.\n * 4. 값이 없으면 빈 칸이었다. 만기 시간과 완료 시간이 비어 있었는데, 값이 없는 것인지 화면이 못 낸\n * 것인지 구별되지 않는다.\n */\n/*\n * 스크롤바는 제품 표준을 따른다(@operato/styles 의 ScrollbarStyles — 5px · 투명 트랙).\n * 이 판은 반드시 스크롤한다(팝업이 고정 높이라 내용이 길면 안에서 넘긴다). 그런데 스타일을 안\n * 넣어 두어 좁은 화면에서 브라우저 기본 스크롤바가 그대로 나왔다 — 이 앱의 다른 스크롤 영역과\n * 굵기가 달랐다.\n */\nexport const ContextPanelStyles = [\n ScrollbarStyles,\n css`\n /*\n * ── 크기는 팝업이 정한다 ──────────────────────────────────────────────\n * openPopup 이 만드는 상자 안에 들어간다. 그 상자가 폭과 높이를 정하고\n * ([hovering=center] 의 60%×60%), 슬롯에 들어온 것을 width/height 100% 로 늘린다.\n *\n * 여기서 min-width / max-width / max-height 를 또 정했다가 **판이 상자보다 작아졌다** —\n * 실측: 상자 598px · 판 560px, 오른쪽 38px 이 빈 채로 남았다. 상자를 그대로 채운다.\n *\n * 면·테두리·모서리·그림자도 팝업의 것을 쓴다 — 여기서 또 그리면 상자가 두 겹이 된다.\n */\n :host {\n display: block;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n overflow: auto;\n\n background: var(--ui-panel, #ffffff);\n color: var(--ui-ink, #17242c);\n font-size: var(--ui-t-body, 13px);\n --context-ui-padding: 0;\n }\n\n /*\n * 결재선 — 판의 머리. 아래로 한 줄 그어 정보와 나눈다.\n *\n * 회색으로 채우지 않는다(SurfaceStyles 가 정한 규칙). 전에는 결재선 컴포넌트가 자기 회색 면을\n * 칠해서 흰 판 위에 띠 하나가 얹혀 있었다.\n */\n div[flow] {\n padding: var(--spacing-medium, 8px) var(--spacing-medium, 8px) 0;\n border-bottom: 1px solid var(--ui-line, #d5dce0);\n /*\n * 결재선이 판보다 넓을 수 있다 — 4단계짜리(나 · 품질팀장 · 공장장 · 생산팀장)가 좁은 화면의\n * 팝업에서 오른쪽으로 잘렸다. 줄바꿈은 안 된다(단계 사이 이음선이 절대 위치라 줄이 바뀌면\n * 허공에 그려진다). 그래서 이 띠 안에서만 가로로 넘긴다 — 판의 나머지는 그대로다.\n */\n overflow-x: auto;\n }\n\n /*\n * 이름과 값 — **본문 화면과 같은 구조다**(activity-fields 의 dl.given).\n *\n * ── 가운데로 밀었다가 되돌렸다 (2026-09-06) ──────────────────────────\n * 값이 짧아 오른쪽이 비는 것을 결함으로 보고 묶음을 가운데 정렬했다. 그것이 틀렸다.\n *\n * 왼쪽 기준선이 사라진다 라벨을 세로로 훑어 읽는 목록인데, 항목 수와 글자 길이에 따라\n * 블록이 좌우로 움직인다\n * 판 안에 축이 둘이 된다 아래 타임라인은 왼쪽 정박이라 두 기준선이 어긋난다\n * 화면과 달라진다 상세 · 완료 조회의 같은 구조는 왼쪽 정박이다\n *\n * label/value 목록은 값이 짧으면 오른쪽이 남는다. 그것이 정상이다.\n */\n dl.given {\n display: grid;\n grid-template-columns: minmax(80px, max-content) 1fr;\n gap: 8px var(--spacing-large, 16px);\n margin: 0;\n padding: var(--spacing-large, 16px);\n }\n\n dl.given dt {\n text-align: right;\n color: var(--ui-muted, #57676f);\n word-break: keep-all;\n }\n\n dl.given dd {\n margin: 0;\n color: var(--ui-ink, #17242c);\n word-break: break-word;\n }\n\n dl.given dd.strong {\n font-weight: 600;\n }\n\n dl.given .none {\n color: var(--ui-faint, #8a959c);\n }\n\n /* 상태 — 화면의 머리 띠와 같은 모양이다(state-ribon 의 .state). */\n .state {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n }\n\n .state .dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--worklist-state-color, var(--ui-muted, #57676f));\n }\n\n :host([state='unassigned']),\n :host([state='assigned']),\n :host([state='draft']) {\n --worklist-state-color: var(--ui-muted, #57676f);\n }\n\n :host([state='started']),\n :host([state='issued']),\n :host([state='posted']) {\n --worklist-state-color: var(--ui-accent, #00727e);\n }\n\n :host([state='submitted']),\n :host([state='escalated']),\n :host([state='delegated']),\n :host([state='pending']) {\n --worklist-state-color: var(--ui-info, #2b72ad);\n }\n\n :host([state='rejected']) {\n --worklist-state-color: var(--ui-warn, #9f5e02);\n }\n\n :host([state='ended']),\n :host([state='approved']) {\n --worklist-state-color: var(--ui-good, #297d39);\n }\n\n :host([state='aborted']),\n :host([state='deprecated']) {\n --worklist-state-color: var(--ui-crit, #d14946);\n }\n\n activity-thread-timeline {\n margin: 0 var(--spacing-large, 16px) var(--spacing-large, 16px);\n }\n\n\n`\n]\n\n/** 상태 한 칸 — 점과 이름. 색만으로 뜻을 전하지 않는다. */\nexport function stateCell(state?: string) {\n return html`<span class=\"state\"><i class=\"dot\"></i>${i18next.t('label.activity-state-' + state)}</span>`\n}\n\n/** 시각 한 칸 — 화면 본문과 같은 표기(when.ts). 없으면 없다고 말한다. */\nexport function whenCell(at?: string | number | Date) {\n return fieldValue(whenText(at))\n}\n\n/** 값 한 칸 — 없으면 빈 칸으로 두지 않는다. */\nexport function valueCell(value?: any) {\n return fieldValue(value)\n}\n"]}
1
+ {"version":3,"file":"context-panel.js","sourceRoot":"","sources":["../../client/templates/context-panel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE/B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAE7D;;;;;;;;;;;;;;;;;;GAkBG;AACH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,eAAe;IACf,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuIJ;CACA,CAAA;AAED,uCAAuC;AACvC,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,IAAI,CAAA,0CAA0C,OAAO,CAAC,CAAC,CAAC,uBAAuB,GAAG,KAAK,CAAC,SAAS,CAAA;AAC1G,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,QAAQ,CAAC,EAA2B;IAClD,OAAO,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAA;AACjC,CAAC;AAED,gCAAgC;AAChC,MAAM,UAAU,SAAS,CAAC,KAAW;IACnC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAA;AAC1B,CAAC","sourcesContent":["import { css, html } from 'lit'\n\nimport { ScrollbarStyles } from '@operato/styles'\n\nimport { i18next } from '@operato/i18n'\n\nimport { whenText } from '../when.js'\nimport { fieldValue } from '../components/activity-fields.js'\n\n/**\n * 문서 아이콘이 여는 곁 패널 — **세 템플릿이 한 모양을 쓴다.**\n *\n * activity-thread · activity-approval · activity-instance 의 context template 셋이 같은 것을 보인다\n * (결재선 · 이름 · 설명 · 상태 · 차수 · 담당자 · 시각 셋). 그런데 셋이 각자 스타일을 갖고 있었고,\n * 상태색 여덟 개와 자체 시각 formatter 가 세 벌로 복사되어 있었다.\n *\n * ── 무엇을 고쳤나 (2026-09-06) ─────────────────────────────────────────────\n * 1. 시각이 Monday, August 31, 2026 at 11:09 PM 이었다. 세 템플릿이 각자\n * Intl.DateTimeFormat(navigator.language, dateStyle full) 을 들고 있었다. 이 패널을 여는 화면은\n * 바로 뒤에서 2026. 8. 31. 오후 11:09 로 적고 있다 — 같은 값이 두 뼘 사이에서 두 말로 나왔다.\n * 2. 왼쪽에 상태색 삼각형이 붙어 있었다. 하드코딩된 hex 여덟 개 중 하나를 골라 칠하는 장식인데,\n * 상태는 이미 패널 안에 점과 글자로 적혀 있다. 같은 것을 두 번 말하면서 앱 팔레트를 따르지도\n * 않았다.\n * 3. 줄마다 배경색이 번갈아 깔렸다(nth-child odd). 여덟 줄짜리 표에 얼룩이 지고, 라벨 폭이 25% 로\n * 고정이라 좁은 화면에서는 값이 밀렸다.\n * 4. 값이 없으면 빈 칸이었다. 만기 시간과 완료 시간이 비어 있었는데, 값이 없는 것인지 화면이 못 낸\n * 것인지 구별되지 않는다.\n */\n/*\n * 스크롤바는 제품 표준을 따른다(@operato/styles 의 ScrollbarStyles — 5px · 투명 트랙).\n * 이 패널은 반드시 스크롤한다(팝업이 고정 높이라 내용이 길면 안에서 넘긴다). 그런데 스타일을 안\n * 넣어 두어 좁은 화면에서 브라우저 기본 스크롤바가 그대로 나왔다 — 이 앱의 다른 스크롤 영역과\n * 굵기가 달랐다.\n */\nexport const ContextPanelStyles = [\n ScrollbarStyles,\n css`\n /*\n * ── 크기는 팝업이 정한다 ──────────────────────────────────────────────\n * openPopup 이 만드는 상자 안에 들어간다. 그 상자가 폭과 높이를 정하고\n * ([hovering=center] 의 60%×60%), 슬롯에 들어온 것을 width/height 100% 로 늘린다.\n *\n * 여기서 min-width / max-width / max-height 를 또 정했다가 **패널이 상자보다 작아졌다** —\n * 실측: 상자 598px · 패널 560px, 오른쪽 38px 이 빈 채로 남았다. 상자를 그대로 채운다.\n *\n * 면·테두리·모서리·그림자도 팝업의 것을 쓴다 — 여기서 또 그리면 상자가 두 겹이 된다.\n */\n :host {\n display: block;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n overflow: auto;\n\n background: var(--ui-panel, #ffffff);\n color: var(--ui-ink, #17242c);\n font-size: var(--ui-t-body, 13px);\n --context-ui-padding: 0;\n }\n\n /*\n * 결재선 — 패널의 머리. 아래로 한 줄 그어 정보와 나눈다.\n *\n * 회색으로 채우지 않는다(SurfaceStyles 가 정한 규칙). 전에는 결재선 컴포넌트가 자기 회색 면을\n * 칠해서 흰 패널 위에 띠 하나가 얹혀 있었다.\n */\n div[flow] {\n padding: var(--spacing-medium, 8px) var(--spacing-medium, 8px) 0;\n border-bottom: 1px solid var(--ui-line, #d5dce0);\n /*\n * 결재선이 판보다 넓을 수 있다 — 4단계짜리(나 · 품질팀장 · 공장장 · 생산팀장)가 좁은 화면의\n * 팝업에서 오른쪽으로 잘렸다. 줄바꿈은 안 된다(단계 사이 이음선이 절대 위치라 줄이 바뀌면\n * 허공에 그려진다). 그래서 이 띠 안에서만 가로로 넘긴다 — 패널의 나머지는 그대로다.\n */\n overflow-x: auto;\n }\n\n /*\n * 이름과 값 — **본문 화면과 같은 구조다**(activity-fields 의 dl.given).\n *\n * ── 가운데로 밀었다가 되돌렸다 (2026-09-06) ──────────────────────────\n * 값이 짧아 오른쪽이 비는 것을 결함으로 보고 묶음을 가운데 정렬했다. 그것이 틀렸다.\n *\n * 왼쪽 기준선이 사라진다 라벨을 세로로 훑어 읽는 목록인데, 항목 수와 글자 길이에 따라\n * 블록이 좌우로 움직인다\n * 패널 안에 축이 둘이 된다 아래 타임라인은 왼쪽 정박이라 두 기준선이 어긋난다\n * 화면과 달라진다 상세 · 완료 조회의 같은 구조는 왼쪽 정박이다\n *\n * label/value 목록은 값이 짧으면 오른쪽이 남는다. 그것이 정상이다.\n */\n dl.given {\n display: grid;\n grid-template-columns: minmax(80px, max-content) 1fr;\n gap: 8px var(--spacing-large, 16px);\n margin: 0;\n padding: var(--spacing-large, 16px);\n }\n\n dl.given dt {\n text-align: right;\n color: var(--ui-muted, #57676f);\n word-break: keep-all;\n }\n\n dl.given dd {\n margin: 0;\n color: var(--ui-ink, #17242c);\n word-break: break-word;\n }\n\n dl.given dd.strong {\n font-weight: 600;\n }\n\n dl.given .none {\n color: var(--ui-faint, #8a959c);\n }\n\n /* 상태 — 화면의 머리 띠와 같은 모양이다(state-ribon 의 .state). */\n .state {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n }\n\n .state .dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--worklist-state-color, var(--ui-muted, #57676f));\n }\n\n :host([state='unassigned']),\n :host([state='assigned']),\n :host([state='draft']) {\n --worklist-state-color: var(--ui-muted, #57676f);\n }\n\n :host([state='started']),\n :host([state='issued']),\n :host([state='posted']) {\n --worklist-state-color: var(--ui-accent, #00727e);\n }\n\n :host([state='submitted']),\n :host([state='escalated']),\n :host([state='delegated']),\n :host([state='pending']) {\n --worklist-state-color: var(--ui-info, #2b72ad);\n }\n\n :host([state='rejected']) {\n --worklist-state-color: var(--ui-warn, #9f5e02);\n }\n\n :host([state='ended']),\n :host([state='approved']) {\n --worklist-state-color: var(--ui-good, #297d39);\n }\n\n :host([state='aborted']),\n :host([state='deprecated']) {\n --worklist-state-color: var(--ui-crit, #d14946);\n }\n\n activity-thread-timeline {\n margin: 0 var(--spacing-large, 16px) var(--spacing-large, 16px);\n }\n\n\n`\n]\n\n/** 상태 한 칸 — 점과 이름. 색만으로 뜻을 전하지 않는다. */\nexport function stateCell(state?: string) {\n return html`<span class=\"state\"><i class=\"dot\"></i>${i18next.t('label.activity-state-' + state)}</span>`\n}\n\n/** 시각 한 칸 — 화면 본문과 같은 표기(when.ts). 없으면 없다고 말한다. */\nexport function whenCell(at?: string | number | Date) {\n return fieldValue(whenText(at))\n}\n\n/** 값 한 칸 — 없으면 빈 칸으로 두지 않는다. */\nexport function valueCell(value?: any) {\n return fieldValue(value)\n}\n"]}