@things-factory/ops-master 10.1.33 → 10.1.35

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 (150) hide show
  1. package/dist-client/index.d.ts +1 -0
  2. package/dist-client/index.js +1 -0
  3. package/dist-client/index.js.map +1 -1
  4. package/dist-client/master-change-approval.d.ts +14 -0
  5. package/dist-client/master-change-approval.js +36 -0
  6. package/dist-client/master-change-approval.js.map +1 -0
  7. package/dist-client/pages/master/material-definition.d.ts +4 -11
  8. package/dist-client/pages/master/material-definition.js +5 -53
  9. package/dist-client/pages/master/material-definition.js.map +1 -1
  10. package/dist-client/pages/master/material-revision-fields.d.ts +2 -0
  11. package/dist-client/pages/master/material-revision-fields.js +43 -0
  12. package/dist-client/pages/master/material-revision-fields.js.map +1 -0
  13. package/dist-client/pages/master/recipe-definition.d.ts +4 -135
  14. package/dist-client/pages/master/recipe-definition.js +7 -397
  15. package/dist-client/pages/master/recipe-definition.js.map +1 -1
  16. package/dist-client/pages/master/revision-comparison.d.ts +48 -0
  17. package/dist-client/pages/master/revision-comparison.js +553 -0
  18. package/dist-client/pages/master/revision-comparison.js.map +1 -0
  19. package/dist-client/pages/master/revision-view.d.ts +19 -0
  20. package/dist-client/pages/master/revision-view.js +133 -0
  21. package/dist-client/pages/master/revision-view.js.map +1 -0
  22. package/dist-client/pages/master/revision-workspace.d.ts +50 -0
  23. package/dist-client/pages/master/revision-workspace.js +752 -0
  24. package/dist-client/pages/master/revision-workspace.js.map +1 -0
  25. package/dist-client/pages/master/test-specification.d.ts +4 -92
  26. package/dist-client/pages/master/test-specification.js +5 -440
  27. package/dist-client/pages/master/test-specification.js.map +1 -1
  28. package/dist-client/tsconfig.tsbuildinfo +1 -1
  29. package/dist-server/service/asset/asset-master-resolver.js +38 -34
  30. package/dist-server/service/asset/asset-master-resolver.js.map +1 -1
  31. package/dist-server/service/asset/index.d.ts +2 -2
  32. package/dist-server/service/equipment/equipment-master-resolver.js +54 -49
  33. package/dist-server/service/equipment/equipment-master-resolver.js.map +1 -1
  34. package/dist-server/service/equipment/index.d.ts +2 -2
  35. package/dist-server/service/index.d.ts +18 -2
  36. package/dist-server/service/index.js +18 -0
  37. package/dist-server/service/index.js.map +1 -1
  38. package/dist-server/service/location/index.d.ts +1 -1
  39. package/dist-server/service/location/location-master-resolver.js +34 -31
  40. package/dist-server/service/location/location-master-resolver.js.map +1 -1
  41. package/dist-server/service/master-axis.js +1 -1
  42. package/dist-server/service/master-axis.js.map +1 -1
  43. package/dist-server/service/master-change-policy.d.ts +23 -0
  44. package/dist-server/service/master-change-policy.js +134 -0
  45. package/dist-server/service/master-change-policy.js.map +1 -0
  46. package/dist-server/service/master-conformance-resolver.js +11 -1
  47. package/dist-server/service/master-conformance-resolver.js.map +1 -1
  48. package/dist-server/service/master-crud.js +9 -0
  49. package/dist-server/service/master-crud.js.map +1 -1
  50. package/dist-server/service/master-list.js +6 -0
  51. package/dist-server/service/master-list.js.map +1 -1
  52. package/dist-server/service/material/index.d.ts +3 -2
  53. package/dist-server/service/material/index.js +4 -2
  54. package/dist-server/service/material/index.js.map +1 -1
  55. package/dist-server/service/material/material-axis-status.d.ts +8 -0
  56. package/dist-server/service/material/material-axis-status.js +19 -0
  57. package/dist-server/service/material/material-axis-status.js.map +1 -0
  58. package/dist-server/service/material/material-definition.d.ts +3 -0
  59. package/dist-server/service/material/material-definition.js +13 -0
  60. package/dist-server/service/material/material-definition.js.map +1 -1
  61. package/dist-server/service/material/material-effective-list.d.ts +39 -0
  62. package/dist-server/service/material/material-effective-list.js +54 -0
  63. package/dist-server/service/material/material-effective-list.js.map +1 -0
  64. package/dist-server/service/material/material-master-resolver.js +59 -61
  65. package/dist-server/service/material/material-master-resolver.js.map +1 -1
  66. package/dist-server/service/material/material-query.js +9 -2
  67. package/dist-server/service/material/material-query.js.map +1 -1
  68. package/dist-server/service/material/material-revision-content.d.ts +10 -0
  69. package/dist-server/service/material/material-revision-content.js +92 -0
  70. package/dist-server/service/material/material-revision-content.js.map +1 -0
  71. package/dist-server/service/material/material-revision-resolver.d.ts +54 -0
  72. package/dist-server/service/material/material-revision-resolver.js +76 -0
  73. package/dist-server/service/material/material-revision-resolver.js.map +1 -0
  74. package/dist-server/service/material/material-revision-service.d.ts +144 -0
  75. package/dist-server/service/material/material-revision-service.js +534 -0
  76. package/dist-server/service/material/material-revision-service.js.map +1 -0
  77. package/dist-server/service/material/material-revision.d.ts +84 -0
  78. package/dist-server/service/material/material-revision.js +339 -0
  79. package/dist-server/service/material/material-revision.js.map +1 -0
  80. package/dist-server/service/operation/index.d.ts +1 -1
  81. package/dist-server/service/operation/operation-definition.js +1 -0
  82. package/dist-server/service/operation/operation-definition.js.map +1 -1
  83. package/dist-server/service/operation/operation-master-resolver.js +30 -30
  84. package/dist-server/service/operation/operation-master-resolver.js.map +1 -1
  85. package/dist-server/service/personnel/index.d.ts +2 -2
  86. package/dist-server/service/personnel/personnel-master-resolver.js +38 -34
  87. package/dist-server/service/personnel/personnel-master-resolver.js.map +1 -1
  88. package/dist-server/service/quality/nonconformance-cause-resolver.js +17 -14
  89. package/dist-server/service/quality/nonconformance-cause-resolver.js.map +1 -1
  90. package/dist-server/service/recipe/index.d.ts +3 -2
  91. package/dist-server/service/recipe/index.js +4 -2
  92. package/dist-server/service/recipe/index.js.map +1 -1
  93. package/dist-server/service/recipe/recipe-definition.d.ts +4 -0
  94. package/dist-server/service/recipe/recipe-definition.js +14 -1
  95. package/dist-server/service/recipe/recipe-definition.js.map +1 -1
  96. package/dist-server/service/recipe/recipe-effective-list.d.ts +49 -0
  97. package/dist-server/service/recipe/recipe-effective-list.js +96 -0
  98. package/dist-server/service/recipe/recipe-effective-list.js.map +1 -0
  99. package/dist-server/service/recipe/recipe-master-resolver.js +32 -28
  100. package/dist-server/service/recipe/recipe-master-resolver.js.map +1 -1
  101. package/dist-server/service/recipe/recipe-query.js +9 -2
  102. package/dist-server/service/recipe/recipe-query.js.map +1 -1
  103. package/dist-server/service/recipe/recipe-revision-content.d.ts +32 -0
  104. package/dist-server/service/recipe/recipe-revision-content.js +65 -0
  105. package/dist-server/service/recipe/recipe-revision-content.js.map +1 -0
  106. package/dist-server/service/recipe/recipe-revision-line.d.ts +30 -0
  107. package/dist-server/service/recipe/recipe-revision-line.js +95 -0
  108. package/dist-server/service/recipe/recipe-revision-line.js.map +1 -0
  109. package/dist-server/service/recipe/recipe-revision-resolver.d.ts +59 -0
  110. package/dist-server/service/recipe/recipe-revision-resolver.js +76 -0
  111. package/dist-server/service/recipe/recipe-revision-resolver.js.map +1 -0
  112. package/dist-server/service/recipe/recipe-revision-service.d.ts +147 -0
  113. package/dist-server/service/recipe/recipe-revision-service.js +591 -0
  114. package/dist-server/service/recipe/recipe-revision-service.js.map +1 -0
  115. package/dist-server/service/recipe/recipe-revision.d.ts +100 -0
  116. package/dist-server/service/recipe/recipe-revision.js +373 -0
  117. package/dist-server/service/recipe/recipe-revision.js.map +1 -0
  118. package/dist-server/service/recipe/route-definition.js +1 -0
  119. package/dist-server/service/recipe/route-definition.js.map +1 -1
  120. package/dist-server/service/resource/class-members.js +9 -0
  121. package/dist-server/service/resource/class-members.js.map +1 -1
  122. package/dist-server/service/status/master-status.js +2 -1
  123. package/dist-server/service/status/master-status.js.map +1 -1
  124. package/dist-server/service/test-spec/index.d.ts +3 -2
  125. package/dist-server/service/test-spec/index.js +4 -2
  126. package/dist-server/service/test-spec/index.js.map +1 -1
  127. package/dist-server/service/test-spec/test-spec-effective-list.d.ts +34 -0
  128. package/dist-server/service/test-spec/test-spec-effective-list.js +42 -0
  129. package/dist-server/service/test-spec/test-spec-effective-list.js.map +1 -0
  130. package/dist-server/service/test-spec/test-spec-master-resolver.d.ts +4 -14
  131. package/dist-server/service/test-spec/test-spec-master-resolver.js +12 -83
  132. package/dist-server/service/test-spec/test-spec-master-resolver.js.map +1 -1
  133. package/dist-server/service/test-spec/test-spec-query.js +7 -1
  134. package/dist-server/service/test-spec/test-spec-query.js.map +1 -1
  135. package/dist-server/service/test-spec/test-spec-revision-resolver.d.ts +53 -0
  136. package/dist-server/service/test-spec/test-spec-revision-resolver.js +76 -0
  137. package/dist-server/service/test-spec/test-spec-revision-resolver.js.map +1 -0
  138. package/dist-server/service/test-spec/test-spec-revision-service.d.ts +138 -0
  139. package/dist-server/service/test-spec/test-spec-revision-service.js +538 -0
  140. package/dist-server/service/test-spec/test-spec-revision-service.js.map +1 -0
  141. package/dist-server/service/test-spec/test-spec-revision.d.ts +84 -0
  142. package/dist-server/service/test-spec/test-spec-revision.js +334 -0
  143. package/dist-server/service/test-spec/test-spec-revision.js.map +1 -0
  144. package/dist-server/service/test-spec/test-specification.d.ts +6 -0
  145. package/dist-server/service/test-spec/test-specification.js +15 -2
  146. package/dist-server/service/test-spec/test-specification.js.map +1 -1
  147. package/dist-server/tsconfig.tsbuildinfo +1 -1
  148. package/package.json +10 -6
  149. package/translations/en.json +148 -0
  150. package/translations/ko.json +148 -0
@@ -1,4 +1,5 @@
1
1
  export * from './pages/master/master-page-base';
2
+ export * from './master-change-approval';
2
3
  export * from './pages/master/personnel-class';
3
4
  export * from './pages/master/person';
4
5
  export * from './pages/master/equipment-class';
@@ -2,6 +2,7 @@
2
2
  * 마스터 화면은 축마다 하나다 — 이유는 pages/master/master-page-base.ts 에 적었다.
3
3
  */
4
4
  export * from './pages/master/master-page-base';
5
+ export * from './master-change-approval';
5
6
  export * from './pages/master/personnel-class';
6
7
  export * from './pages/master/person';
7
8
  export * from './pages/master/equipment-class';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,iCAAiC,CAAA;AAC/C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,uBAAuB,CAAA;AACrC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,qCAAqC,CAAA;AACnD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,oCAAoC,CAAA;AAClD,cAAc,qCAAqC,CAAA;AACnD,cAAc,qCAAqC,CAAA;AACnD,cAAc,mCAAmC,CAAA;AACjD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,kCAAkC,CAAA","sourcesContent":["/*\n * 마스터 화면은 축마다 하나다 — 이유는 pages/master/master-page-base.ts 에 적었다.\n */\nexport * from './pages/master/master-page-base'\nexport * from './pages/master/personnel-class'\nexport * from './pages/master/person'\nexport * from './pages/master/equipment-class'\nexport * from './pages/master/equipment'\nexport * from './pages/master/stop-reason'\nexport * from './pages/master/physical-asset-class'\nexport * from './pages/master/physical-asset'\nexport * from './pages/master/material-class'\nexport * from './pages/master/material-definition'\nexport * from './pages/master/operational-location'\nexport * from './pages/master/operation-definition'\nexport * from './pages/master/test-specification'\nexport * from './pages/master/route-definition'\nexport * from './pages/master/recipe-definition'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,iCAAiC,CAAA;AAC/C,cAAc,0BAA0B,CAAA;AACxC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,uBAAuB,CAAA;AACrC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,qCAAqC,CAAA;AACnD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,oCAAoC,CAAA;AAClD,cAAc,qCAAqC,CAAA;AACnD,cAAc,qCAAqC,CAAA;AACnD,cAAc,mCAAmC,CAAA;AACjD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,kCAAkC,CAAA","sourcesContent":["/*\n * 마스터 화면은 축마다 하나다 — 이유는 pages/master/master-page-base.ts 에 적었다.\n */\nexport * from './pages/master/master-page-base'\nexport * from './master-change-approval'\nexport * from './pages/master/personnel-class'\nexport * from './pages/master/person'\nexport * from './pages/master/equipment-class'\nexport * from './pages/master/equipment'\nexport * from './pages/master/stop-reason'\nexport * from './pages/master/physical-asset-class'\nexport * from './pages/master/physical-asset'\nexport * from './pages/master/material-class'\nexport * from './pages/master/material-definition'\nexport * from './pages/master/operational-location'\nexport * from './pages/master/operation-definition'\nexport * from './pages/master/test-specification'\nexport * from './pages/master/route-definition'\nexport * from './pages/master/recipe-definition'\n"]}
@@ -0,0 +1,14 @@
1
+ export interface MasterChangeApprovalRequest {
2
+ axis: string;
3
+ revisionId: string;
4
+ editGeneration: number;
5
+ }
6
+ export interface MasterChangeStatus {
7
+ state: 'pending' | 'approved' | 'rejected' | 'aborted' | 'unknown';
8
+ comment?: string;
9
+ who?: string;
10
+ open?: () => void;
11
+ }
12
+ export declare function masterChangeStatus(target: EventTarget, activityInstanceId: string): Promise<MasterChangeStatus>;
13
+ /** Products handle this event; the common editor never knows a product mutation name. */
14
+ export declare function requestMasterChangeApproval(target: EventTarget, request: MasterChangeApprovalRequest): Promise<unknown>;
@@ -0,0 +1,36 @@
1
+ export async function masterChangeStatus(target, activityInstanceId) {
2
+ let response;
3
+ target.dispatchEvent(new CustomEvent('master-change-status', {
4
+ bubbles: true,
5
+ composed: true,
6
+ detail: {
7
+ activityInstanceId,
8
+ respondWith(value) {
9
+ if (response)
10
+ throw new Error('Duplicate status provider');
11
+ response = value;
12
+ }
13
+ }
14
+ }));
15
+ return response ?? { state: 'unknown' };
16
+ }
17
+ /** Products handle this event; the common editor never knows a product mutation name. */
18
+ export async function requestMasterChangeApproval(target, request) {
19
+ let response;
20
+ target.dispatchEvent(new CustomEvent('master-change-approval', {
21
+ bubbles: true,
22
+ composed: true,
23
+ detail: {
24
+ ...request,
25
+ respondWith(value) {
26
+ if (response)
27
+ throw new Error('A master change approval request already has a handler.');
28
+ response = value;
29
+ }
30
+ }
31
+ }));
32
+ if (!response)
33
+ throw new Error('This product has not registered an approval handler for this master axis.');
34
+ return response;
35
+ }
36
+ //# sourceMappingURL=master-change-approval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"master-change-approval.js","sourceRoot":"","sources":["../client/master-change-approval.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAmB,EAAE,kBAA0B;IACtF,IAAI,QAAiD,CAAA;IACrD,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,sBAAsB,EAAE;QACtC,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE;YACN,kBAAkB;YAClB,WAAW,CAAC,KAAkC;gBAC5C,IAAI,QAAQ;oBAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAA;gBAC1D,QAAQ,GAAG,KAAK,CAAA;YAClB,CAAC;SACF;KACF,CAAC,CACH,CAAA;IACD,OAAO,QAAQ,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;AACzC,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,MAAmB,EACnB,OAAoC;IAEpC,IAAI,QAAsC,CAAA;IAC1C,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,wBAAwB,EAAE;QACxC,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE;YACN,GAAG,OAAO;YACV,WAAW,CAAC,KAAuB;gBACjC,IAAI,QAAQ;oBAAE,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAA;gBACxF,QAAQ,GAAG,KAAK,CAAA;YAClB,CAAC;SACF;KACF,CAAC,CACH,CAAA;IACD,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAA;IAC3G,OAAO,QAAQ,CAAA;AACjB,CAAC","sourcesContent":["export interface MasterChangeApprovalRequest {\n axis: string\n revisionId: string\n editGeneration: number\n}\n\nexport interface MasterChangeStatus {\n state: 'pending' | 'approved' | 'rejected' | 'aborted' | 'unknown'\n comment?: string\n who?: string\n open?: () => void\n}\nexport async function masterChangeStatus(target: EventTarget, activityInstanceId: string): Promise<MasterChangeStatus> {\n let response: Promise<MasterChangeStatus> | undefined\n target.dispatchEvent(\n new CustomEvent('master-change-status', {\n bubbles: true,\n composed: true,\n detail: {\n activityInstanceId,\n respondWith(value: Promise<MasterChangeStatus>) {\n if (response) throw new Error('Duplicate status provider')\n response = value\n }\n }\n })\n )\n return response ?? { state: 'unknown' }\n}\n\n/** Products handle this event; the common editor never knows a product mutation name. */\nexport async function requestMasterChangeApproval(\n target: EventTarget,\n request: MasterChangeApprovalRequest\n): Promise<unknown> {\n let response: Promise<unknown> | undefined\n target.dispatchEvent(\n new CustomEvent('master-change-approval', {\n bubbles: true,\n composed: true,\n detail: {\n ...request,\n respondWith(value: Promise<unknown>) {\n if (response) throw new Error('A master change approval request already has a handler.')\n response = value\n }\n }\n })\n )\n if (!response) throw new Error('This product has not registered an approval handler for this master axis.')\n return response\n}\n"]}
@@ -1,12 +1,5 @@
1
- import { MasterPageBase, MasterSpec } from './master-page-base.js';
2
- /**
3
- * 만들고 쓰는 하나하나 — 완제품 · 반제품 · 원자재.
4
- *
5
- * 작업지시가 「무엇을 얼마나」에서 이것을 가리키고, 레시피가 무엇으로 만드는지를 정한다.
6
- *
7
- * 화면 골격과 저장은 MasterPageBase 가 갖는다. 이 파일은 **이 화면이 무엇을 보이나**만 말한다 —
8
- * 자기 인터페이스가 필요해지면 여기서 render 를 덮어쓴다.
9
- */
10
- export declare class OpsMasterMaterialDefinition extends MasterPageBase {
11
- protected get spec(): MasterSpec;
1
+ import { RevisionWorkspace } from './revision-workspace.js';
2
+ import { RevisionAxis } from './revision-view.js';
3
+ export declare class OpsMasterMaterialDefinition extends RevisionWorkspace {
4
+ protected axis: RevisionAxis;
12
5
  }
@@ -1,58 +1,10 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { customElement } from 'lit/decorators.js';
3
- import { EFFECTIVE, IDENTITY, MasterPageBase } from './master-page-base.js';
4
- /**
5
- * 만들고 쓰는 것 하나하나 — 완제품 · 반제품 · 원자재.
6
- *
7
- * 작업지시가 「무엇을 얼마나」에서 이것을 가리키고, 레시피가 무엇으로 만드는지를 정한다.
8
- *
9
- * 화면 골격과 저장은 MasterPageBase 가 갖는다. 이 파일은 **이 화면이 무엇을 보이나**만 말한다 —
10
- * 자기 인터페이스가 필요해지면 여기서 render 를 덮어쓴다.
11
- */
12
- let OpsMasterMaterialDefinition = class OpsMasterMaterialDefinition extends MasterPageBase {
13
- get spec() {
14
- return {
15
- key: 'materialDefinition',
16
- title: 'material',
17
- help: 'ops-master/material-definition',
18
- query: 'materialDefinitions',
19
- mutation: 'updateMultipleMaterialDefinition',
20
- columns: [
21
- ...IDENTITY,
22
- /*
23
- * ── 무엇인가 ──────────────────────────────────────────────────────
24
- *
25
- * 「이 품목이 완제품인가 · 반제품인가 · 원재료인가」. 전에는 등급 이름 `MC-ECU-MECH` 만
26
- * 있어서, 그것이 원재료라는 것을 사람이 외우고 있어야 했다.
27
- *
28
- * 이 두 칸은 새 축이 아니라 **등급 상속을 걸어서 낸 것**이다. ISA-95 에는 그 구분을 담는
29
- * 전용 요소가 없고 표준이 그것을 두는 자리가 등급이다. 그래서 값의 주인은 등급이고, 여기서
30
- * 고칠 수 없다 — 유형을 바꾸려면 등급 화면에서 상위 등급을 바꾼다.
31
- *
32
- * 유형이 둘 이상 나오면 그대로 둘을 보인다. 「완제품이면서 원재료」는 등급이 잘못 얽혔다는
33
- * 뜻이고, 하나로 줄여 보이면 그 잘못이 화면에서 사라진다.
34
- */
35
- { name: 'rootClasses', label: 'material-type', type: 'list', width: 110, readonly: true },
36
- { name: 'classPath', label: 'class-lineage', type: 'list', width: 220, readonly: true },
37
- { name: 'materialClassIds', label: 'material-classes', type: 'reference-list', reference: { queryName: 'materialClasses' }, width: 180 },
38
- /*
39
- * ── BOM 으로 가는 문 ──────────────────────────────────────────────
40
- *
41
- * BOM 은 제조법에 있는데 이 화면에서 거기로 가는 문이 없었다. 완제품 한 줄을 보면서 「이 한
42
- * 대에 무엇이 들어가나」를 물을 수 없었다 — 제조법 화면을 따로 열고 이름으로 찾아야 했다.
43
- *
44
- * 「만드는 제조법」이 그 문이고, 「쓰이는 제조법」이 역전개다 — 이 나사를 바꾸면 무엇이 영향을
45
- * 받는지가 거기 있다.
46
- *
47
- * 둘 다 목록이다. 하나로 줄이면 같은 품목을 다른 라우팅으로 만드는 경우가 오류보고없이 사라진다.
48
- * 고칠 수 있는 칸이 아니다 — 이 값의 주인은 제조법이다.
49
- */
50
- { name: 'madeBy', label: 'made-by', type: 'list', width: 180, readonly: true },
51
- { name: 'usedIn', label: 'used-in', type: 'list', width: 200, readonly: true },
52
- { name: 'properties', label: 'properties', type: 'json', width: 240 },
53
- ...EFFECTIVE
54
- ]
55
- };
3
+ import { RevisionWorkspace } from './revision-workspace.js';
4
+ let OpsMasterMaterialDefinition = class OpsMasterMaterialDefinition extends RevisionWorkspace {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.axis = 'materialDefinition';
56
8
  }
57
9
  };
58
10
  OpsMasterMaterialDefinition = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"material-definition.js","sourceRoot":"","sources":["../../../client/pages/master/material-definition.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAc,MAAM,uBAAuB,CAAA;AAEvF;;;;;;;GAOG;AAEI,IAAM,2BAA2B,GAAjC,MAAM,2BAA4B,SAAQ,cAAc;IAC7D,IAAc,IAAI;QAChB,OAAO;YACL,GAAG,EAAE,oBAAoB;YACzB,KAAK,EAAE,UAAU;YACjB,IAAI,EAAE,gCAAgC;YACtC,KAAK,EAAE,qBAAqB;YAC5B,QAAQ,EAAE,kCAAkC;YAC5C,OAAO,EAAE;gBACP,GAAG,QAAQ;gBACX;;;;;;;;;;;;mBAYG;gBACH,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE;gBACzF,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE;gBACvF,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,gBAAgB,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;gBACxI;;;;;;;;;;;mBAWG;gBACH,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC9E,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC9E,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;gBACrE,GAAG,SAAS;aACb;SACF,CAAA;IACH,CAAC;CACF,CAAA;AA7CY,2BAA2B;IADvC,aAAa,CAAC,gCAAgC,CAAC;GACnC,2BAA2B,CA6CvC","sourcesContent":["import { customElement } from 'lit/decorators.js'\n\nimport { EFFECTIVE, IDENTITY, MasterPageBase, MasterSpec } from './master-page-base.js'\n\n/**\n * 만들고 쓰는 하나하나 — 완제품 · 반제품 · 원자재.\n *\n * 작업지시가 「무엇을 얼마나」에서 이것을 가리키고, 레시피가 무엇으로 만드는지를 정한다.\n *\n * 화면 골격과 저장은 MasterPageBase 가 갖는다. 이 파일은 **이 화면이 무엇을 보이나**만 말한다 —\n * 자기 인터페이스가 필요해지면 여기서 render 를 덮어쓴다.\n */\n@customElement('ops-master-material-definition')\nexport class OpsMasterMaterialDefinition extends MasterPageBase {\n protected get spec(): MasterSpec {\n return {\n key: 'materialDefinition',\n title: 'material',\n help: 'ops-master/material-definition',\n query: 'materialDefinitions',\n mutation: 'updateMultipleMaterialDefinition',\n columns: [\n ...IDENTITY,\n /*\n * ── 무엇인가 ──────────────────────────────────────────────────────\n *\n * 「이 품목이 완제품인가 · 반제품인가 · 원재료인가」. 전에는 등급 이름 `MC-ECU-MECH` 만\n * 있어서, 그것이 원재료라는 것을 사람이 외우고 있어야 했다.\n *\n * 이 두 칸은 새 축이 아니라 **등급 상속을 걸어서 낸 것**이다. ISA-95 에는 그 구분을 담는\n * 전용 요소가 없고 표준이 그것을 두는 자리가 등급이다. 그래서 값의 주인은 등급이고, 여기서\n * 고칠 수 없다 — 유형을 바꾸려면 등급 화면에서 상위 등급을 바꾼다.\n *\n * 유형이 둘 이상 나오면 그대로 둘을 보인다. 「완제품이면서 원재료」는 등급이 잘못 얽혔다는\n * 뜻이고, 하나로 줄여 보이면 그 잘못이 화면에서 사라진다.\n */\n { name: 'rootClasses', label: 'material-type', type: 'list', width: 110, readonly: true },\n { name: 'classPath', label: 'class-lineage', type: 'list', width: 220, readonly: true },\n { name: 'materialClassIds', label: 'material-classes', type: 'reference-list', reference: { queryName: 'materialClasses' }, width: 180 },\n /*\n * ── BOM 으로 가는 문 ──────────────────────────────────────────────\n *\n * BOM 은 제조법에 있는데 이 화면에서 거기로 가는 문이 없었다. 완제품 한 줄을 보면서 「이 한\n * 대에 무엇이 들어가나」를 물을 수 없었다 — 제조법 화면을 따로 열고 이름으로 찾아야 했다.\n *\n * 「만드는 제조법」이 그 문이고, 「쓰이는 제조법」이 역전개다 — 이 나사를 바꾸면 무엇이 영향을\n * 받는지가 거기 있다.\n *\n * 둘 다 목록이다. 하나로 줄이면 같은 품목을 다른 라우팅으로 만드는 경우가 오류보고없이 사라진다.\n * 고칠 수 있는 칸이 아니다 — 이 값의 주인은 제조법이다.\n */\n { name: 'madeBy', label: 'made-by', type: 'list', width: 180, readonly: true },\n { name: 'usedIn', label: 'used-in', type: 'list', width: 200, readonly: true },\n { name: 'properties', label: 'properties', type: 'json', width: 240 },\n ...EFFECTIVE\n ]\n }\n }\n}\n"]}
1
+ {"version":3,"file":"material-definition.js","sourceRoot":"","sources":["../../../client/pages/master/material-definition.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAIpD,IAAM,2BAA2B,GAAjC,MAAM,2BAA4B,SAAQ,iBAAiB;IAA3D;;QACK,SAAI,GAAiB,oBAAoB,CAAA;IACrD,CAAC;CAAA,CAAA;AAFY,2BAA2B;IADvC,aAAa,CAAC,gCAAgC,CAAC;GACnC,2BAA2B,CAEvC","sourcesContent":["import { customElement } from 'lit/decorators.js'\nimport { RevisionWorkspace } from './revision-workspace.js'\nimport { RevisionAxis } from './revision-view.js'\n\n@customElement('ops-master-material-definition')\nexport class OpsMasterMaterialDefinition extends RevisionWorkspace {\n protected axis: RevisionAxis = 'materialDefinition'\n}\n"]}
@@ -0,0 +1,2 @@
1
+ /** Shared structured contents for editing, approval and the immutable 360 snapshot. */
2
+ export declare function materialRevisionFields(value: any, change?: (field: string, value: any) => void): import("lit-html").TemplateResult<1>;
@@ -0,0 +1,43 @@
1
+ import { html, nothing } from 'lit';
2
+ import { i18next } from '@operato/i18n';
3
+ const t = (key) => i18next.t('revision-ui.' + key);
4
+ /** Shared structured contents for editing, approval and the immutable 360 snapshot. */
5
+ export function materialRevisionFields(value, change) {
6
+ const editable = !!change;
7
+ const properties = (rows, set, depth = 0) => html `
8
+ ${(rows ?? []).map((row, index) => html `<fieldset class="material-property">
9
+ <legend>${row.description || (row.id === 'perBaseUnit' ? t('unit-conversion') : row.id) || t('new-property')}</legend>
10
+ ${!editable ? html `<dl class="material-property-values">
11
+ <dt>${t('value')}</dt><dd>${row.value ?? '—'} ${row.uom ?? ''}</dd>
12
+ </dl><details><summary>${t('property-definition')}</summary>
13
+ <dl class="material-property-values">${['id', 'description', 'dataType', 'classPropertyId', 'source'].filter(field => row[field] != null && row[field] !== '').map(field => html `<dt>${t(field)}</dt><dd>${row[field]}</dd>`)}</dl>
14
+ </details>` : html `<div class="fields">
15
+ ${['id', 'description', 'value', 'uom', 'dataType', 'classPropertyId', 'source'].map(field => html `<label>
16
+ ${t(field)}
17
+ ${editable ? html `<input .value=${String(row[field] ?? '')} ?required=${field === 'id'}
18
+ @input=${(e) => {
19
+ const text = e.target.value;
20
+ const updated = { ...row, [field]: text };
21
+ if (field !== 'id' && !text)
22
+ delete updated[field];
23
+ set(rows.map((r, i) => i === index ? updated : r));
24
+ }} />` : html `<span>${row[field] ?? '—'}</span>`}
25
+ </label>`)}
26
+ </div>`}
27
+ ${row.children?.length ? properties(row.children, children => set(rows.map((r, i) => i === index ? { ...r, children } : r)), depth + 1) : nothing}
28
+ ${editable ? html `<button @click=${() => set(rows.filter((_, i) => i !== index))}>${t('remove')}</button>
29
+ <button ?disabled=${depth >= 31} @click=${() => set(rows.map((r, i) => i === index ? { ...r, children: [...(r.children ?? []), { id: '', value: '' }] } : r))}>${t('add-child-property')}</button>` : nothing}
30
+ </fieldset>`)}
31
+ ${editable ? html `<button @click=${() => set([...(rows ?? []), { id: '', value: '' }])}>${t('add-property')}</button>` : nothing}`;
32
+ return html `
33
+ ${['materialClassIds', 'testSpecificationIds'].map(field => html `<h3>${t(field)}</h3>
34
+ ${(value[field] ?? []).map((name, index) => html `<div class="bar">
35
+ ${editable ? html `<input required aria-label=${t(field) + ' ' + (index + 1)} .value=${name}
36
+ @input=${(e) => change(field, value[field].map((v, i) => i === index ? e.target.value : v))} />
37
+ <button @click=${() => change(field, value[field].filter((_, i) => i !== index))}>${t('remove')}</button>` : html `<span>${name}</span>`}
38
+ </div>`)}
39
+ ${editable ? html `<button @click=${() => change(field, [...(value[field] ?? []), ''])}>${t('add-reference')}</button>` : nothing}`)}
40
+ <h3>${t('properties')}</h3>
41
+ ${properties(value.properties ?? [], rows => change?.('properties', rows))}`;
42
+ }
43
+ //# sourceMappingURL=material-revision-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"material-revision-fields.js","sourceRoot":"","sources":["../../../client/pages/master/material-revision-fields.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, nothing } from 'lit'\nimport { i18next } from '@operato/i18n'\n\nconst t = (key: string) => i18next.t('revision-ui.' + key)\n\n/** Shared structured contents for editing, approval and the immutable 360 snapshot. */\nexport function materialRevisionFields(value: any, change?: (field: string, value: any) => void) {\n const editable = !!change\n const properties = (rows: any[], set: (rows: any[]) => void, depth = 0): any => html`\n ${(rows ?? []).map((row, index) => html`<fieldset class=\"material-property\">\n <legend>${row.description || (row.id === 'perBaseUnit' ? t('unit-conversion') : row.id) || t('new-property')}</legend>\n ${!editable ? html`<dl class=\"material-property-values\">\n <dt>${t('value')}</dt><dd>${row.value ?? '—'} ${row.uom ?? ''}</dd>\n </dl><details><summary>${t('property-definition')}</summary>\n <dl class=\"material-property-values\">${['id', 'description', 'dataType', 'classPropertyId', 'source'].filter(field => row[field] != null && row[field] !== '').map(field => html`<dt>${t(field)}</dt><dd>${row[field]}</dd>`)}</dl>\n </details>` : html`<div class=\"fields\">\n ${['id', 'description', 'value', 'uom', 'dataType', 'classPropertyId', 'source'].map(field => html`<label>\n ${t(field)}\n ${editable ? html`<input .value=${String(row[field] ?? '')} ?required=${field === 'id'}\n @input=${(e: Event) => {\n const text = (e.target as HTMLInputElement).value\n const updated = { ...row, [field]: text }\n if (field !== 'id' && !text) delete updated[field]\n set(rows.map((r, i) => i === index ? updated : r))\n }} />` : html`<span>${row[field] ?? '—'}</span>`}\n </label>`)}\n </div>`}\n ${row.children?.length ? properties(row.children, children => set(rows.map((r, i) => i === index ? { ...r, children } : r)), depth + 1) : nothing}\n ${editable ? html`<button @click=${() => set(rows.filter((_, i) => i !== index))}>${t('remove')}</button>\n <button ?disabled=${depth >= 31} @click=${() => set(rows.map((r, i) => i === index ? { ...r, children: [...(r.children ?? []), { id: '', value: '' }] } : r))}>${t('add-child-property')}</button>` : nothing}\n </fieldset>`)}\n ${editable ? html`<button @click=${() => set([...(rows ?? []), { id: '', value: '' }])}>${t('add-property')}</button>` : nothing}`\n return html`\n ${['materialClassIds', 'testSpecificationIds'].map(field => html`<h3>${t(field)}</h3>\n ${(value[field] ?? []).map((name: string, index: number) => html`<div class=\"bar\">\n ${editable ? html`<input required aria-label=${t(field) + ' ' + (index + 1)} .value=${name}\n @input=${(e: Event) => change!(field, value[field].map((v: string, i: number) => i === index ? (e.target as HTMLInputElement).value : v))} />\n <button @click=${() => change!(field, value[field].filter((_: string, i: number) => i !== index))}>${t('remove')}</button>` : html`<span>${name}</span>`}\n </div>`)}\n ${editable ? html`<button @click=${() => change!(field, [...(value[field] ?? []), ''])}>${t('add-reference')}</button>` : nothing}`)}\n <h3>${t('properties')}</h3>\n ${properties(value.properties ?? [], rows => change?.('properties', rows))}`\n}\n"]}
@@ -1,136 +1,5 @@
1
- import { FetchOption } from '@operato/data-grist';
2
- import { MasterPageBase, MasterSpec } from './master-page-base.js';
3
- /** 투입 · 산출 — 무엇을 얼마나, 그리고 어느 공정에서. */
4
- type RecipePart = {
5
- material?: string;
6
- qty?: number;
7
- operation?: string;
8
- };
9
- /**
10
- * 제조법 — **BOM 이 사는 자리.**
11
- *
12
- * ── 왜 이 화면이 있어야 하나 ───────────────────────────────────────────────
13
- * 서버에는 축도 목록 질의도 수정 연산도 있는데 **화면이 없었다.** 그래서 「이 완제품 한 대에 무엇이
14
- * 몇 개 들어가나」를 제품 안에서 볼 길이 없었다. 품목 화면은 이름과 등급과 유효기간만 보이고,
15
- * 소요는 여기 있는데 여기로 오는 문이 없었다.
16
- *
17
- * ── 왜 두 단인가 ───────────────────────────────────────────────────────────
18
- * 레시피 하나의 투입이 마흔아홉 줄이다(군산 ECU). 그것을 레시피 목록의 한 칸에 넣으면 아무것도
19
- * 읽을 수 없고, 레시피와 투입을 한 표에 섞으면 **무엇이 레시피이고 무엇이 그 안의 줄인지** 사라진다.
20
- *
21
- * 그래서 로케이션과 같은 결로 둔다 — 목록에서 하나를 고르면 그 안으로 들어가고, 어디에 있는지는
22
- * 빵가루가 말한다. **자리의 주인은 URL 이다**(`pageUpdated`). 그래야 붙여 보낼 수 있고, 뒤로 가기가
23
- * 한 단 올라가고, 새로 고쳐도 그 자리에 남는다.
24
- *
25
- * ── 투입 자재를 여기서 고친다 ──────────────────────────────────────────────
26
- * 안에 들어가면 그 레시피의 투입이 줄로 선다. 고치면 **레시피 한 건의 `inputs` 를 통째로 다시 쓴다** —
27
- * `RecipePart` 는 자기 식별자가 없어서 줄 단위로 저장할 수 없다. 그래서 저장은 언제나 그 레시피
28
- * 하나에 대한 한 번의 쓰기다.
29
- *
30
- * ── 무엇을 만드는가는 고정 칸이다 ──────────────────────────────────────────
31
- * `materialDefinitionName` 이 이 레시피가 만드는 품목이고, `route` 가 그것이 타고 갈 라우팅이다. 이
32
- * 둘이 **품목과 라우팅을 잇는 유일한 자리**다 — 품목에서 라우팅으로 바로 가는 길은 없고, 있어서도 안 된다.
33
- * 같은 품목을 다른 라우팅으로 만드는 일이 있기 때문이다(라인 증설 · 시제품).
34
- */
35
- export declare class OpsMasterRecipeDefinition extends MasterPageBase {
36
- static styles: import("lit").CSSResult[];
37
- /**
38
- * 지금 열어 본 레시피. 비어 있으면 목록을 보고 있다.
39
- *
40
- * **이 값의 주인은 URL 이다.** 여기 직접 넣지 않는다 — `enter` 는 주소만 바꾸고, 바뀐 주소를
41
- * `pageUpdated` 가 받아 이 값을 다시 세운다.
42
- */
43
- private opened?;
44
- protected get spec(): MasterSpec;
45
- /** 레시피 목록 — 무엇을 만드나 · 어느 라우팅으로 · 투입이 몇 줄인가. */
46
- private listSpec;
47
- /**
48
- * 이 제조법에 들어가는 자재들 — 안으로 들어왔을 때의 표.
49
- *
50
- * 저장은 이 화면이 스스로 한다(`save` 를 덮어쓴다). `key` 와 `mutation` 은 그대로 두어 화면
51
- * 골격이 같은 축을 가리키게 한다.
52
- */
53
- /**
54
- * 「투입 자재」 칸을 목록에 끼운다 — **스펙이 아니라 여기서.**
55
- *
56
- * `MasterColumn` 은 렌더러를 모르는 좁은 타입이다. 자리 화면도 같은 이유로 여기서 끼운다
57
- * (`operational-location` 의 `configOf`). 스펙에 억지로 넣으면 타입을 속여야 하고, 그러면 다음
58
- * 사람이 스펙에 무엇을 넣을 수 있는지 알 수 없게 된다.
59
- */
60
- protected configOf(): any;
61
- /**
62
- * ── 개수는 **문이다.** 죽은 숫자가 아니다 ───────────────────────────────
63
- *
64
- * 처음에는 그냥 못 고치는 숫자였다. 사용자가 물었다(2026-09-05): 「이게 뭐고 왜 편집이 안 되나」.
65
- * 둘 다 맞는 물음이었다 — 고칠 수 없는 칸이 **왜** 고칠 수 없는지 화면이 말하지 않으면, 보는
66
- * 사람은 그것을 망가진 칸으로 읽는다.
67
- *
68
- * 이 수는 값이 아니라 안에 든 것의 수다. 바꾸려면 안에 들어가 자재를 더하거나 빼야 한다. 그러니
69
- * 그 길을 이 칸이 직접 내야 한다 — 자리 화면의 「하위」가 이미 그렇게 한다.
70
- *
71
- * ```
72
- * 투입 자재
73
- * 3 › 셋이 들어간다. 누르면 그리로 간다
74
- * ― 아직 안 정했다. 누를 데가 없다
75
- * ```
76
- */
77
- private inputsColumn;
78
- private partsSpec;
79
- protected get pathSegmentNarrowsList(): boolean;
80
- pageInitialized(): Promise<void>;
81
- pageUpdated(changes: any, after: any, before: any): Promise<void>;
82
- /** 주소가 가리키는 레시피를 연다. 없으면 목록이다. */
83
- private syncOpened;
84
- /** 레시피 하나를 찾는다. 아이디로 찾고, 없으면 이름으로 찾는다 — 주소에는 사람이 읽는 이름이 온다. */
85
- private lookup;
86
- /** 레시피 자체를 읽는다 — 안에 들어와 있어도 이 질의는 레시피를 본다. */
87
- private fetchRecipes;
88
- /**
89
- * 목록일 때는 레시피를, 안에서는 그 레시피의 투입과 산출을 낸다.
90
- *
91
- * **투입 자재 줄에는 서버가 준 식별자가 없다.** `RecipePart` 는 자기 아이디가 없어서, 화면이 순번으로
92
- * 만들어 준다 — 그 값은 저장할 때 쓰지 않고 표가 줄을 가리키는 데만 쓴다.
93
- */
94
- fetchHandler(option: FetchOption): Promise<{
95
- total: number;
96
- records: {
97
- inputCount: number;
98
- id: string;
99
- name: string;
100
- materialDefinitionName?: string;
101
- route?: string;
102
- inputs?: RecipePart[];
103
- outputs?: RecipePart[];
104
- }[];
105
- } | {
106
- total: number;
107
- records: {
108
- material?: string;
109
- qty?: number;
110
- operation?: string;
111
- id: string;
112
- kind: string;
113
- }[];
114
- }>;
115
- protected renderScope(): import("lit-html").TemplateResult<1>;
116
- /**
117
- * 그 레시피로 들어간다. `null` 이면 목록으로 돌아간다.
118
- *
119
- * **주소만 바꾼다.** 셸이 주소를 물고 `pageUpdated` 를 부르고, 거기서 하나로 다시 선다.
120
- */
121
- private enter;
122
- /**
123
- * 저장 — **투입 자재 줄에는 자기 식별자가 없다.**
124
- *
125
- * `RecipePart` 는 아이디를 갖지 않아서 줄 단위로 저장할 수 없다. 그래서 안에서 고친 것은 표에
126
- * 서 있는 줄 전부를 모아 **그 레시피 한 건의 `inputs`·`outputs` 를 통째로 다시 쓴다.**
127
- *
128
- * 통째로 쓰는 것이 위험해 보이지만 그 반대가 더 위험하다 — 줄마다 쓰면 「셋째 줄」이 무엇인지
129
- * 서버가 알 방법이 없어서, 두 사람이 같은 레시피를 고칠 때 어느 줄이 어느 줄을 덮는지 정할 수
130
- * 없다. 한 번의 쓰기면 뒤엣사람이 앞엣사람의 것을 통째로 덮는 것이 눈에 보인다.
131
- *
132
- * 목록에서는 화면 골격의 저장을 그대로 쓴다 — 거기서는 레시피 한 줄이 곧 한 행이다.
133
- */
134
- protected save(): Promise<void>;
1
+ import { RevisionWorkspace } from './revision-workspace.js';
2
+ import { RevisionAxis } from './revision-view.js';
3
+ export declare class OpsMasterRecipeDefinition extends RevisionWorkspace {
4
+ protected axis: RevisionAxis;
135
5
  }
136
- export {};