@things-factory/ops-master 10.1.31 → 10.1.34
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.
- package/dist-client/index.d.ts +1 -0
- package/dist-client/index.js +1 -0
- package/dist-client/index.js.map +1 -1
- package/dist-client/master-change-approval.d.ts +7 -0
- package/dist-client/master-change-approval.js +20 -0
- package/dist-client/master-change-approval.js.map +1 -0
- package/dist-client/pages/master/test-specification.d.ts +22 -85
- package/dist-client/pages/master/test-specification.js +190 -405
- package/dist-client/pages/master/test-specification.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/service/asset/asset-master-resolver.js +38 -34
- package/dist-server/service/asset/asset-master-resolver.js.map +1 -1
- package/dist-server/service/equipment/equipment-master-resolver.js +54 -49
- package/dist-server/service/equipment/equipment-master-resolver.js.map +1 -1
- package/dist-server/service/index.d.ts +8 -2
- package/dist-server/service/index.js +8 -0
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/location/location-master-resolver.js +34 -31
- package/dist-server/service/location/location-master-resolver.js.map +1 -1
- package/dist-server/service/master-change-policy.d.ts +23 -0
- package/dist-server/service/master-change-policy.js +129 -0
- package/dist-server/service/master-change-policy.js.map +1 -0
- package/dist-server/service/master-crud.js +6 -0
- package/dist-server/service/master-crud.js.map +1 -1
- package/dist-server/service/material/material-master-resolver.js +55 -51
- package/dist-server/service/material/material-master-resolver.js.map +1 -1
- package/dist-server/service/operation/operation-master-resolver.js +28 -25
- package/dist-server/service/operation/operation-master-resolver.js.map +1 -1
- package/dist-server/service/personnel/personnel-master-resolver.js +38 -34
- package/dist-server/service/personnel/personnel-master-resolver.js.map +1 -1
- package/dist-server/service/quality/nonconformance-cause-resolver.js +17 -14
- package/dist-server/service/quality/nonconformance-cause-resolver.js.map +1 -1
- package/dist-server/service/recipe/recipe-master-resolver.js +32 -28
- package/dist-server/service/recipe/recipe-master-resolver.js.map +1 -1
- package/dist-server/service/test-spec/index.d.ts +3 -2
- package/dist-server/service/test-spec/index.js +4 -2
- package/dist-server/service/test-spec/index.js.map +1 -1
- package/dist-server/service/test-spec/test-spec-effective-list.d.ts +32 -0
- package/dist-server/service/test-spec/test-spec-effective-list.js +40 -0
- package/dist-server/service/test-spec/test-spec-effective-list.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-master-resolver.d.ts +4 -14
- package/dist-server/service/test-spec/test-spec-master-resolver.js +12 -83
- package/dist-server/service/test-spec/test-spec-master-resolver.js.map +1 -1
- package/dist-server/service/test-spec/test-spec-query.js +7 -1
- package/dist-server/service/test-spec/test-spec-query.js.map +1 -1
- package/dist-server/service/test-spec/test-spec-revision-resolver.d.ts +52 -0
- package/dist-server/service/test-spec/test-spec-revision-resolver.js +76 -0
- package/dist-server/service/test-spec/test-spec-revision-resolver.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-revision-service.d.ts +117 -0
- package/dist-server/service/test-spec/test-spec-revision-service.js +519 -0
- package/dist-server/service/test-spec/test-spec-revision-service.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-revision.d.ts +82 -0
- package/dist-server/service/test-spec/test-spec-revision.js +329 -0
- package/dist-server/service/test-spec/test-spec-revision.js.map +1 -0
- package/dist-server/service/test-spec/test-specification.d.ts +4 -0
- package/dist-server/service/test-spec/test-specification.js +11 -2
- package/dist-server/service/test-spec/test-specification.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-specification.js","sourceRoot":"","sources":["../../../client/pages/master/test-specification.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist/ox-grist.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, query, state } from 'lit/decorators.js'\n\nimport { DataGrist } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { CustomAlert } from '@operato/shell'\nimport { notify } from '@operato/layout'\n\nimport { EFFECTIVE, IDENTITY, MasterPageBase, MasterSpec } from './master-page-base.js'\n\n/**\n * 무엇을 어떻게 검사하나 — 항목과 상하한과 방법.\n *\n * 인원 등급과 자산 등급이 이것을 요구 검사로 가리킨다.\n *\n * ── 왜 이 축만 자기 화면을 갖나 ────────────────────────────────────────────\n * 다른 축의 칸은 글자 · 숫자 · 날짜라서 공통 그리드 하나로 충분하다. 검사 명세는 다르다. **명세 하나가\n * 기준 여럿을 갖는다.** 기준 하나는 이름 · 설명 · 측정 속성 · 하한 · 상한 · 단위 · 표현식을 갖는다.\n *\n * 그것을 한 칸에 JSON 원문으로 보이면 품질팀장이 상한을 40.5 로 고치려고 중괄호를 세게 된다. 그것은\n * 기준 정보를 다루는 화면이 아니라 개발자가 JSON 을 손보는 화면이다. 실제로 한동안 그랬다.\n *\n * ── 화면은 JSON 을 모른다 ──────────────────────────────────────────────────\n * 서버가 기준을 **행으로** 낸다(`testSpecificationCriteria`) 그리고 행으로 받는다\n * (`updateTestSpecificationCriteria`). 옮김은 서버의 `criteria-rows.ts` 한 곳이 맡는다.\n *\n * 그래서 저장이 언젠가 표로 내려가도 **이 파일은 바뀌지 않는다.** 화면이 JSON 을 풀면 그날 이 코드가\n * 통째로 버려진다.\n *\n * ── 위아래로 나눈다 ────────────────────────────────────────────────────────\n * 위는 명세 목록, 아래는 **고른 명세의 기준**이다. 아무것도 안 고른 상태를 빈 표로 두지 않는다 —\n * 빈 표는 「기준이 없는 명세」와 같아 보이고, 그러면 사람이 기준을 다시 적는다.\n */\n@customElement('ops-master-test-specification')\nexport class OpsMasterTestSpecification extends MasterPageBase {\n static styles = [\n ...MasterPageBase.styles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n }\n\n /* 위가 목록, 아래가 그 명세의 기준. 기준 쪽을 조금 더 준다 — 줄이 여럿이다. */\n .split {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n }\n\n .split > ox-grist {\n flex: 4;\n min-height: 0;\n }\n\n .criteria {\n display: flex;\n flex-direction: column;\n flex: 5;\n min-height: 0;\n border-top: 1px solid var(--ui-line, #c9d4d9);\n }\n\n .criteria-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 6px 12px;\n background-color: var(--ui-panel-2, #f3f6f7);\n }\n\n .criteria-head .what {\n font-size: 13px;\n font-weight: 600;\n color: var(--ui-ink, #17272f);\n }\n\n /* 아직 저장하지 않은 것이 있다 — 저장을 누르기 전에 무엇이 나가는지 여기서 읽는다. */\n .criteria-head .pending {\n margin-right: 8px;\n font-family: inherit;\n font-style: normal;\n font-weight: 600;\n color: var(--status-warning-color, #b26a00);\n }\n\n .criteria-head .among {\n margin-left: 6px;\n font-style: normal;\n color: var(--status-warning-color, #b26a00);\n }\n\n .criteria-head .who {\n font-family: var(--theme-font-mono, monospace);\n font-size: 12px;\n color: var(--ui-muted, #57676f);\n }\n\n .criteria ox-grist {\n flex: 1;\n min-height: 0;\n }\n\n /* 아직 아무 명세도 안 골랐다. 빈 표를 보이지 않는다. */\n .nothing-picked {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n text-align: center;\n font-size: 13px;\n line-height: 1.6;\n color: var(--ui-muted, #57676f);\n }\n `\n ]\n\n protected get spec(): MasterSpec {\n return {\n key: 'testSpecification',\n title: 'test-specification',\n help: 'ops-master/test-specification',\n query: 'testSpecifications',\n mutation: 'updateMultipleTestSpecification',\n columns: [...IDENTITY, ...EFFECTIVE]\n }\n }\n\n /** 지금 고른 명세의 이름. 없으면 아래를 빈 표로 두지 않는다. */\n @state() private picked?: string\n\n /**\n * 지금 체크된 명세들.\n *\n * 아래는 **하나의 기준만** 보이는데 위에서 여럿을 체크할 수 있다(명세 여럿을 한 번에 종료하는 데\n * 쓴다). 그때 화면이 아무 말도 안 하면 보이는 기준이 **여럿을 합친 것**으로 읽힌다. 그래서 몇 개가\n * 체크돼 있는지 세어 말한다.\n */\n @state() private checked = new Set<string>()\n\n @query('#criteria-grist') private criteriaGrist!: DataGrist\n\n /**\n * 아래 표에서 아직 저장하지 않은 기준이 몇 건인가.\n *\n * ── 왜 세어 보이나 (2026-09-05) ────────────────────────────────────────\n * 이 화면은 표가 둘인데 「저장」은 하나다. 아래를 고쳐 놓고도 그것이 저장 대상인지 화면 어디에도\n * 안 적혀 있었다. 「복잡한 편집인데 저장 버튼의 기능이 위험해 보인다」(사용자).\n *\n * 세어서 표 머리에 적으면 두 가지가 한꺼번에 풀린다. 저장을 누르기 전에 **무엇이 나가는지** 보이고,\n * 다른 명세로 넘어가려 할 때 **버릴 것이 있다**는 사실도 보인다.\n */\n @state() private dirtyCriteria = 0\n\n private countDirtyCriteria() {\n this.dirtyCriteria = (this.criteriaGrist?.dirtyRecords ?? []).length\n }\n\n /**\n * 기준 표의 구성.\n *\n * **단위 칸을 좁히지 않는다.** `MMT`(mm) · `CEL`(℃) 같은 UN/CEFACT 코드가 들어가고, 잘리면\n * 「무엇으로 잰 값인지」가 화면에서 사라진다.\n */\n private get criteriaConfig(): any {\n return {\n /*\n * 명세는 골랐는데 그 안에 판단 기준이 하나도 없는 자리다. 왼쪽의 빈 목록과 뜻이 다르다 —\n * 「검사 명세가 없다」가 아니라 「이 명세가 아직 무엇으로 합격을 가르는지 말하지 않는다」이다.\n *\n * 고른 것이 없을 때는 아래 render 가 표 자체를 보이지 않는다(그 자리 주석 참조).\n */\n emptyNote: {\n title: i18next.t('text.criteria-empty'),\n description: i18next.t('text.criteria-empty-hint')\n },\n list: { fields: ['id', 'description'], details: [] },\n columns: [\n { type: 'gutter', gutterName: 'sequence', fixed: true },\n { type: 'gutter', gutterName: 'row-selector', multiple: true, fixed: true },\n {\n type: 'string',\n name: 'id',\n header: i18next.t('field.criterion-id'),\n record: { editable: true },\n width: 160,\n fixed: true\n },\n {\n type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n record: { editable: true },\n width: 180\n },\n {\n type: 'string',\n name: 'evaluatedPropertyId',\n header: i18next.t('field.evaluated-property'),\n record: { editable: true },\n width: 150\n },\n { type: 'float', name: 'minimum', header: i18next.t('field.minimum'), record: { editable: true }, width: 100 },\n { type: 'float', name: 'maximum', header: i18next.t('field.maximum'), record: { editable: true }, width: 100 },\n { type: 'string', name: 'uom', header: i18next.t('field.uom'), record: { editable: true }, width: 90 },\n {\n type: 'string',\n name: 'expression',\n header: i18next.t('field.expression'),\n record: { editable: true },\n width: 200\n }\n ],\n rows: { appendable: true, selectable: { multiple: true } }\n }\n }\n\n render() {\n return html`\n <div class=\"split\">\n <ox-grist\n .mode=${this.mode}\n .config=${this.gristConfig}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .personalConfigProvider=${this.getPagePreferenceProvider(`ox-grist-${this.spec.key}`)!}\n @select-record-change=${(e: CustomEvent) => this.pick(e)}\n >\n <div slot=\"headroom\" class=\"header\">${this.renderScope()}</div>\n <ox-grist-personalizer slot=\"setting\"></ox-grist-personalizer>\n </ox-grist>\n\n <div class=\"criteria\">\n <div class=\"criteria-head\">\n <span class=\"what\">${i18next.t('field.criteria')}</span>\n <span class=\"who\">\n ${this.dirtyCriteria\n ? html`<em class=\"pending\">${i18next.t('text.n-unsaved-criteria', { count: this.dirtyCriteria })}</em>`\n : ''}\n ${this.picked ?? ''}\n <!--\n 여럿 체크했는데 하나만 보이는 상태를 **말한다.** 아무 말도 안 하면 보이는 기준이\n 여럿을 합친 것으로 읽힌다.\n -->\n ${this.checked.size > 1\n ? html`<em class=\"among\">${i18next.t('text.of-n-selected', { count: this.checked.size })}</em>`\n : ''}\n </span>\n </div>\n ${this.picked\n ? html`\n <ox-grist\n id=\"criteria-grist\"\n mode=\"GRID\"\n .config=${this.criteriaConfig}\n .fetchHandler=${this.fetchCriteria.bind(this)}\n @field-change=${() => this.countDirtyCriteria()}\n @record-change=${() => this.countDirtyCriteria()}\n ></ox-grist>\n `\n : html`\n <!--\n 빈 표를 보이지 않는다. 빈 표는 「기준이 없는 명세」와 같아 보이고, 그러면 사람이\n 기준을 다시 적는다.\n -->\n <div class=\"nothing-picked\">${i18next.t('text.pick-a-specification-to-see-criteria')}</div>\n `}\n </div>\n </div>\n `\n }\n\n /**\n * 위에서 고른 줄이 아래를 정한다.\n *\n * ── detail 모양이 거터 설정에 따라 다르다 ─────────────────────────────────\n * `gutter-row-selector.js` 를 보면 두 모양을 낸다.\n *\n * ```\n * multiple: true { added: [record], removed: [] } ← 이 화면이 쓰는 것\n * 그 밖 { records: [record] }\n * ```\n *\n * 한쪽만 읽으면 **오류보고없이 아무것도 안 골라진다.** 오류가 나지 않고 아래 표만 영원히 안내 문구로\n * 남는다. 처음에 `records` 만 읽어서 실제로 그랬다. 그리드가 세우는 `__selected__` 를 읽는 방법도\n * 있는데, 그 표시는 이 화면에 오지 않았다. 그래서 **둘 다 읽는다.**\n *\n * 여럿 고르면 마지막에 고른 것을 본다. 아래는 명세 하나의 기준을 보이는 자리라 둘을 함께 보일 수\n * 없고, 아무 것이나 고르면 사람은 그것이 무엇의 기준인지 모른다.\n */\n private async pick(e: CustomEvent) {\n const detail = (e.detail ?? {}) as { added?: any[]; removed?: any[]; records?: any[] }\n const nameOf = (record: any) => String(record?.name ?? '')\n\n const added = detail.added ?? detail.records ?? []\n const removed = detail.removed ?? []\n\n /* `records` 는 「지금 고른 것 전부」다. `added`·`removed` 는 「이번에 바뀐 것」이다. */\n const next = detail.records ? new Set<string>() : new Set(this.checked)\n\n for (const record of removed) next.delete(nameOf(record))\n for (const record of added) next.add(nameOf(record))\n\n /* 아래에 무엇이 보일지 먼저 정하고, 바꾸기 전에 고치던 것이 있는지 본다. */\n let picked = this.picked\n\n if (added.length) {\n picked = nameOf(added[added.length - 1]) || undefined\n } else if (removed.some(record => nameOf(record) === this.picked)) {\n /* 지금 보고 있던 것을 풀었다. 남은 것이 하나면 그것을 보인다. */\n picked = next.size ? [...next][next.size - 1] : undefined\n } else if (detail.records && !detail.records.length) {\n picked = undefined\n }\n\n this.checked = next\n\n if (picked === this.picked) {\n return\n }\n\n /*\n * ── 고치던 기준을 **말없이 버리지 않는다** (2026-09-05) ────────────────\n *\n * 아래 표는 「지금 고른 명세」에 걸려 있다. 명세를 바꾸면 아래는 새 명세의 기준을 다시 읽어\n * 오고, 고치던 값은 그때 사라진다. [확인함] 2026-09-05 · CP-CAM-LEAK 의 하한을 고쳐 두고\n * CP-CAM-OQC 를 고른 뒤 돌아오니 원래 값이었다. 화면은 아무 말도 하지 않았다.\n *\n * 두 갈래로만 묻는다 — 어느 쪽을 골라도 넘어간다. 「머무르기」를 두면 위의 체크는 이미 옮겨\n * 갔는데 아래만 옛 명세를 보이는, 화면과 사실이 어긋난 상태가 남는다.\n */\n if (this.dirtyCriteria > 0) {\n const answer = await CustomAlert({\n type: 'question',\n title: i18next.t('text.n-unsaved-criteria', { count: this.dirtyCriteria }),\n text: i18next.t('text.leaving-discards-unsaved-criteria'),\n confirmButton: { text: i18next.t('button.save-and-leave') },\n cancelButton: { text: i18next.t('button.discard-and-leave') }\n })\n\n if (answer?.isConfirmed) {\n await this.save()\n }\n }\n\n this.picked = picked\n this.dirtyCriteria = 0\n }\n\n /**\n * 고른 명세의 기준을 읽는다.\n *\n * 못 읽으면 **빈 목록으로 바꾸지 않는다.** 빈 목록은 「기준이 없다」와 같아 보이고, 그러면 사람이\n * 기준을 다시 적어 넣는다. 무엇이 잘못됐는지 말하고 비운다.\n */\n private async fetchCriteria() {\n if (!this.picked) {\n return { total: 0, records: [] }\n }\n\n try {\n const response = await client.query({\n query: gql`\n query ($name: String!) {\n testSpecificationCriteria(name: $name) {\n id\n description\n evaluatedPropertyId\n minimum\n maximum\n uom\n expression\n keptFields\n }\n }\n `,\n variables: { name: this.picked },\n fetchPolicy: 'no-cache'\n })\n\n const rows = (response.data?.testSpecificationCriteria ?? []) as any[]\n\n /* 어느 줄인지 서버가 알아야 고칠 수 있다 — 이름은 고칠 수 있으므로 이름으로 찾을 수 없다. */\n return { total: rows.length, records: rows.map((row, index) => ({ ...row, rowIndex: index })) }\n } catch (error) {\n notify({ message: (error as Error).message, level: 'error' })\n return { total: 0, records: [] }\n }\n }\n\n /**\n * 저장 — **위와 아래를 따로 낸다.**\n *\n * 명세 자체(이름 · 버전 · 유효 기간)는 공통 규칙이 저장하고, 기준은 이 축의 뮤테이션이 저장한다.\n * 기준이 막히면 **명세 쪽도 되돌린다.** 절반만 저장되면 화면과 저장된 것이 달라진다.\n */\n protected async save() {\n const criteriaPatches = this.picked ? ((this.criteriaGrist?.dirtyRecords ?? []) as any[]) : []\n\n if (criteriaPatches.length) {\n let response: any\n\n try {\n response = await client.mutate({\n mutation: gql`\n mutation ($name: String!, $patches: [Object!]!) {\n updateTestSpecificationCriteria(name: $name, patches: $patches) {\n id\n }\n }\n `,\n variables: { name: this.picked, patches: criteriaPatches }\n })\n } catch (error) {\n /* 무엇이 왜 막혔는지 그대로 보인다 — 「저장할 수 없습니다」로는 고칠 곳을 모른다. */\n notify({ message: (error as Error).message, level: 'error' })\n return\n }\n\n /*\n * **`errors` 를 직접 본다.** 이 앱의 GraphQL 클라이언트는 서버가 거절해도 던지지 않고\n * `response.errors` 에 담아 돌려준다. `try/catch` 만 두면 거절이 오류 없이 지나가고, 화면은\n * 아무 일 없었다는 듯 다음으로 넘어간다 — **고친 것이 버려졌는데 사람은 저장된 줄 안다.**\n * 2026-09-02에 실제로 그랬다(단위를 지운 기준이 서버에서 막혔는데 화면은 「바뀐 것이 없습니다」).\n */\n if (response?.errors?.length) {\n notify({ message: response.errors.map((error: any) => error.message).join('\\n'), level: 'error' })\n return\n }\n }\n\n await super.save()\n\n if (criteriaPatches.length) {\n this.criteriaGrist?.fetch()\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"test-specification.js","sourceRoot":"","sources":["../../../client/pages/master/test-specification.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist/ox-grist.js'\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { notify } from '@operato/layout'\nimport { EFFECTIVE, IDENTITY, MasterPageBase, MasterSpec } from './master-page-base.js'\nimport { requestMasterChangeApproval } from '../../master-change-approval.js'\n\ntype Revision = {\n id?: string; specId?: string; editGeneration?: number; frozenAt?: string; activityInstanceId?: string;\n version: string; description?: string; effectiveFrom: string; reason: string; criteria: any[];\n}\ntype Overview = { specId: string; name: string; generation: number; revisions: Revision[];\n schedule: { revisionId: string; validFrom: string; validTo?: string; state: string }[] }\n\n/** Identity list, approved schedule, and draft workspace are separate surfaces. */\n@customElement('ops-master-test-specification')\nexport class OpsMasterTestSpecification extends MasterPageBase {\n static styles = [...MasterPageBase.styles, css`\n :host { display:flex; flex-direction:column; min-height:0 }\n ox-grist { flex:2; min-height:160px }\n section { flex:3; overflow:auto; padding:16px; border-top:1px solid var(--ui-line,#ccd5da) }\n .toolbar,.fields { display:flex; flex-wrap:wrap; gap:12px; align-items:end; margin-bottom:12px }\n label { display:flex; flex-direction:column; gap:4px; font-size:13px }\n input,button { font:inherit; padding:7px; border:1px solid var(--ui-line,#ccd5da); border-radius:3px }\n input { min-width:100px; max-width:220px }\n button { cursor:pointer; background:var(--ui-panel-2,#f3f6f7) }\n button:disabled { cursor:default; opacity:.5 }\n table { width:100%; border-collapse:collapse; margin:10px 0 18px; font-size:13px }\n th,td { padding:7px; text-align:left; border-bottom:1px solid var(--ui-line,#ccd5da); vertical-align:top }\n td input { width:100%; min-width:70px; box-sizing:border-box }\n .notice { padding:10px; background:var(--ui-panel-2,#f3f6f7) }\n .changed { background:var(--status-warning-background,#fff2d0) }\n h3 { margin:14px 0 8px; font-size:15px }\n `]\n @state() private overview?: Overview\n @state() private draft?: Revision\n @state() private newName = ''\n @state() private busy = false\n @state() private dirty = false\n private loadSerial = 0\n private t(key: string, fallback: string) { return i18next.t(`test-spec-revision.${key}`, { defaultValue: fallback }) }\n protected get spec(): MasterSpec {\n return { key:'testSpecification', title:'test-specification', help:'ops-master/test-specification',\n query:'testSpecifications', mutation:'updateMultipleTestSpecification',\n columns:[...IDENTITY, { name:'version', label:'version', type:'string' as const }, ...EFFECTIVE].map(column => ({ ...column, readonly:true })) }\n }\n get context(): any {\n return { ...super.context, importable:undefined, actions:[{\n title:this.t('new','새 검사 명세'), icon:'add', emphasis:{raised:true}, action:() => this.startNew()\n }] }\n }\n protected configOf() {\n const config = super.configOf()\n return { ...config, rows:{ ...config.rows, appendable:false, selectable:{multiple:false} } }\n }\n private canLeave() { return !this.dirty || window.confirm(this.t('discard','저장하지 않은 초안을 버리시겠습니까?')) }\n private startNew() {\n if (this.busy || !this.canLeave()) return\n ++this.loadSerial\n this.overview = undefined\n this.newName = ''\n this.draft = { version:'1', effectiveFrom:new Date().toISOString(), reason:'', criteria:[] }\n this.dirty = false\n }\n private async pick(event: CustomEvent) {\n const record = event.detail?.records?.[0] ?? event.detail?.added?.[0]\n if (!record?.id || this.busy || !this.canLeave()) return\n await this.run(async () => { await this.load(record.id); this.draft = undefined; this.dirty = false })\n }\n private async load(specId: string) {\n const serial = ++this.loadSerial\n const response = await client.query({ query:gql`query($specId:String!){testSpecificationRevisions(specId:$specId)}`,\n variables:{specId}, fetchPolicy:'no-cache' })\n this.assertResponse(response)\n if (serial === this.loadSerial) this.overview = response.data.testSpecificationRevisions\n }\n private assertResponse(response: any) {\n if (response?.errors?.length) throw new Error(response.errors.map((error:any) => error.message).join('\\n'))\n if (!response?.data) throw new Error(this.t('no-response','서버 응답을 확인할 수 없습니다. 다시 조회하십시오.'))\n }\n private async run(work: () => Promise<void>) {\n if (this.busy) return\n this.busy = true\n try { await work() } catch(error) { notify({message:(error as Error).message, level:'error'}) }\n finally { this.busy = false }\n }\n private openRevision(revision: Revision, fork = false) {\n if (this.busy || !this.canLeave()) return\n this.draft = JSON.parse(JSON.stringify(revision))\n if (fork) this.draft = { ...this.draft!, id:undefined, frozenAt:undefined, activityInstanceId:undefined,\n editGeneration:undefined, effectiveFrom:new Date().toISOString(), reason:'' }\n this.dirty = false\n }\n private change(field: string, value: any) { this.draft = { ...this.draft!, [field]:value }; this.dirty = true }\n private criterion(index:number, field:string, value:string) {\n const criteria = this.draft!.criteria.map(row => ({ ...row, ...(row.limit ? { limit:{...row.limit} } : {}) }))\n if (['minimum','maximum','uom'].includes(field)) {\n criteria[index].limit ??= {}\n if (!value) delete criteria[index].limit[field]\n else criteria[index].limit[field] = field === 'uom' ? value : Number(value)\n if (!Object.keys(criteria[index].limit).length) delete criteria[index].limit\n } else criteria[index][field] = value\n this.change('criteria',criteria)\n }\n protected async save() { await this.run(() => this.persist()) }\n private async persist() {\n if (!this.draft || this.draft.frozenAt) return\n const { version, description, effectiveFrom, reason, criteria } = this.draft\n const content = { version, description, effectiveFrom, reason, criteria }\n const response = this.draft.id\n ? await client.mutate({ mutation:gql`mutation($revisionId:String!,$editGeneration:Int!,$content:Object!){editTestSpecificationDraft(revisionId:$revisionId,editGeneration:$editGeneration,content:$content)}`,\n variables:{revisionId:this.draft.id,editGeneration:this.draft.editGeneration,content} })\n : await client.mutate({ mutation:gql`mutation($specId:String,$name:String,$content:Object!){createTestSpecificationDraft(specId:$specId,name:$name,content:$content)}`,\n variables:{specId:this.overview?.specId,name:this.overview ? undefined : this.newName,content} })\n this.assertResponse(response)\n this.draft = response.data.editTestSpecificationDraft ?? response.data.createTestSpecificationDraft\n this.dirty = false\n await this.load(this.draft!.specId!)\n this.grist?.fetch()\n }\n private async submit() {\n await this.run(async () => {\n await this.persist()\n if (!this.draft?.id || this.draft.frozenAt) return\n const policy = await client.query({ query:gql`query { masterChangePolicy(axis:\"testSpecification\") }`, fetchPolicy:'no-cache' })\n this.assertResponse(policy)\n if (policy.data.masterChangePolicy.approvalRequired) {\n await requestMasterChangeApproval(this, { axis:'testSpecification', revisionId:this.draft.id, editGeneration:this.draft.editGeneration! })\n } else {\n const response = await client.mutate({ mutation:gql`mutation($revisionId:String!,$editGeneration:Int!){publishTestSpecificationDraft(revisionId:$revisionId,editGeneration:$editGeneration)}`,\n variables:{revisionId:this.draft.id,editGeneration:this.draft.editGeneration} })\n this.assertResponse(response)\n }\n await this.load(this.draft.specId!)\n this.draft = this.overview!.revisions.find(row => row.id === this.draft!.id)\n notify({message:policy.data.masterChangePolicy.approvalRequired ? this.t('submitted','승인을 요청했습니다. 승인 전에는 검사에 적용되지 않습니다.') : this.t('published','정책에 따라 발행했습니다. 지정한 시각부터 적용됩니다.'),level:'info'})\n })\n }\n private criteriaTable(revision: Revision, editable = false, before?: Revision) {\n const fields = ['id','description','evaluatedPropertyId','minimum','maximum','uom','expression']\n const value = (row:any, field:string) => ['minimum','maximum','uom'].includes(field) ? row.limit?.[field] : row[field]\n return html`<table><thead><tr>${fields.map(field => html`<th>${field}</th>`)}${editable ? html`<th></th>` : ''}</tr></thead>\n <tbody>${revision.criteria.map((row,index) => html`<tr>${fields.map(field => {\n const prior = before?.criteria.find(item => item.id === row.id)\n const changed = before && value(prior ?? {},field) !== value(row,field)\n return html`<td class=${changed ? 'changed' : ''}>${editable\n ? html`<input aria-label=${`${row.id || index+1} ${field}`} .value=${String(value(row,field) ?? '')}\n type=${['minimum','maximum'].includes(field) ? 'number' : 'text'} step=\"any\"\n @input=${(e:Event) => this.criterion(index,field,(e.target as HTMLInputElement).value)}>`\n : value(row,field) ?? '—'}${changed ? html`<div><small>← ${value(prior ?? {},field) ?? '—'}</small></div>` : ''}</td>`\n })}${editable ? html`<td><button @click=${() => this.change('criteria',revision.criteria.filter((_,i)=>i!==index))}>${this.t('remove','삭제')}</button></td>` : ''}</tr>`)}\n </tbody></table>`\n }\n render() {\n const current = this.overview?.schedule.find(row => row.state === 'current')\n const currentRevision = this.overview?.revisions.find(row => row.id === current?.revisionId)\n const readonly = !!this.draft?.frozenAt || this.busy\n return html`\n <ox-grist .mode=${this.mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)} @select-record-change=${this.pick.bind(this)}></ox-grist>\n <section aria-busy=${this.busy}>\n ${this.overview ? html`<div class=\"toolbar\"><h3>${this.overview.name}</h3>\n <button ?disabled=${this.busy} @click=${() => this.run(()=>this.load(this.overview!.specId))}>${this.t('refresh','새로고침')}</button>\n <button ?disabled=${this.busy} @click=${() => this.openRevision(currentRevision ?? {version:'1',effectiveFrom:new Date().toISOString(),reason:'',criteria:[]},true)}>${this.t('fork','변경 초안 만들기')}</button></div>\n <h3>${this.t('schedule','승인된 적용 시간표')}</h3>\n <table><thead><tr><th>${this.t('state','상태')}</th><th>${this.t('version','버전')}</th><th>${this.t('from','이 시각부터')}</th><th>${this.t('to','이 시각 직전까지')}</th></tr></thead>\n <tbody>${this.overview.schedule.map(row => html`<tr><td>${this.t(row.state, {current:'현재 적용',scheduled:'적용 예정',expired:'적용 종료'}[row.state] ?? row.state)}</td>\n <td><button @click=${()=>this.openRevision(this.overview!.revisions.find(item=>item.id===row.revisionId)!)}>${this.overview!.revisions.find(item=>item.id===row.revisionId)?.version}</button></td>\n <td>${row.validFrom}</td><td>${row.validTo ?? '∞'}</td></tr>`)}</tbody></table>\n ${!current ? html`<p class=\"notice\">${this.t('no-current','현재 적용 가능한 승인본이 없습니다.')}</p>` : ''}\n <h3>${this.t('drafts','초안 · 상신본')}</h3><div class=\"toolbar\">${this.overview.revisions.filter(row=>!this.overview!.schedule.some(segment=>segment.revisionId===row.id)).map(row=>html`\n <button @click=${()=>this.openRevision(row)}>${row.version} · ${row.frozenAt ? this.t('frozen','상신본 — 결재 상태는 업무함에서 확인') : this.t('draft','편집 초안')}</button>`)}</div>\n ` : !this.draft ? html`<p>${this.t('pick','검사 명세를 선택하거나 새 명세를 만드십시오.')}</p>` : ''}\n ${this.draft ? html`<h3>${this.draft.frozenAt ? this.t('immutable','동결된 내용 — 수정하려면 새 초안을 만드십시오') : this.t('editing','편집 초안 — 아직 적용되지 않음')}</h3>\n <div class=\"fields\">\n ${!this.overview ? html`<label>${this.t('name','명세 이름')}<input ?disabled=${readonly} .value=${this.newName} @input=${(e:Event)=>{this.newName=(e.target as HTMLInputElement).value;this.dirty=true}}></label>` : ''}\n ${['version','description','effectiveFrom','reason'].map(field=>html`<label>${this.t(field,{version:'버전',description:'설명',effectiveFrom:'적용 시작 (시간대 포함 ISO 시각)',reason:'변경 사유'}[field]!)}\n <input ?disabled=${readonly} .value=${this.draft![field] ?? ''} @input=${(e:Event)=>this.change(field,(e.target as HTMLInputElement).value)}></label>`)}\n </div>\n ${this.criteriaTable(this.draft,!readonly,currentRevision)}\n ${currentRevision ? html`<details><summary>${this.t('before','현재 적용 중인 기준 전체 보기 (삭제된 항목 포함)')}</summary>${this.criteriaTable(currentRevision)}</details>` : ''}\n <div class=\"toolbar\">\n <button ?disabled=${readonly} @click=${()=>this.change('criteria',[...this.draft!.criteria,{id:''}])}>${this.t('add','기준 추가')}</button>\n <button ?disabled=${readonly} @click=${()=>this.save()}>${this.t('save','초안 저장')}</button>\n <button ?disabled=${readonly} @click=${()=>this.submit()}>${this.t('submit','저장 후 발행 / 승인 요청')}</button>\n ${this.draft.frozenAt ? html`<button ?disabled=${this.busy} @click=${()=>this.openRevision(this.draft!,true)}>${this.t('fork','변경 초안 만들기')}</button>` : ''}\n ${this.dirty ? html`<span>${this.t('unsaved','저장하지 않은 변경이 있습니다.')}</span>` : ''}\n </div>` : ''}\n </section>`\n }\n}\n"]}
|