@things-factory/ops-master 10.0.19 → 10.1.1

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 (247) hide show
  1. package/dist-client/bootstrap.d.ts +18 -0
  2. package/dist-client/bootstrap.js +36 -0
  3. package/dist-client/bootstrap.js.map +1 -0
  4. package/dist-client/index.d.ts +15 -1
  5. package/dist-client/index.js +18 -1
  6. package/dist-client/index.js.map +1 -1
  7. package/dist-client/pages/master/equipment-class.d.ts +12 -0
  8. package/dist-client/pages/master/equipment-class.js +42 -0
  9. package/dist-client/pages/master/equipment-class.js.map +1 -0
  10. package/dist-client/pages/master/equipment.d.ts +12 -0
  11. package/dist-client/pages/master/equipment.js +57 -0
  12. package/dist-client/pages/master/equipment.js.map +1 -0
  13. package/dist-client/pages/master/grist-iso-duration.d.ts +20 -0
  14. package/dist-client/pages/master/grist-iso-duration.js +70 -0
  15. package/dist-client/pages/master/grist-iso-duration.js.map +1 -0
  16. package/dist-client/pages/master/grist-reference.d.ts +91 -0
  17. package/dist-client/pages/master/grist-reference.js +419 -0
  18. package/dist-client/pages/master/grist-reference.js.map +1 -0
  19. package/dist-client/pages/master/import-rows.d.ts +35 -0
  20. package/dist-client/pages/master/import-rows.js +66 -0
  21. package/dist-client/pages/master/import-rows.js.map +1 -0
  22. package/dist-client/pages/master/iso-duration.d.ts +34 -0
  23. package/dist-client/pages/master/iso-duration.js +76 -0
  24. package/dist-client/pages/master/iso-duration.js.map +1 -0
  25. package/dist-client/pages/master/master-options.d.ts +33 -0
  26. package/dist-client/pages/master/master-options.js +47 -0
  27. package/dist-client/pages/master/master-options.js.map +1 -0
  28. package/dist-client/pages/master/master-page-base.d.ts +357 -0
  29. package/dist-client/pages/master/master-page-base.js +626 -0
  30. package/dist-client/pages/master/master-page-base.js.map +1 -0
  31. package/dist-client/pages/master/material-class.d.ts +12 -0
  32. package/dist-client/pages/master/material-class.js +42 -0
  33. package/dist-client/pages/master/material-class.js.map +1 -0
  34. package/dist-client/pages/master/material-definition.d.ts +12 -0
  35. package/dist-client/pages/master/material-definition.js +62 -0
  36. package/dist-client/pages/master/material-definition.js.map +1 -0
  37. package/dist-client/pages/master/operation-definition.d.ts +12 -0
  38. package/dist-client/pages/master/operation-definition.js +49 -0
  39. package/dist-client/pages/master/operation-definition.js.map +1 -0
  40. package/dist-client/pages/master/operational-location.d.ts +84 -0
  41. package/dist-client/pages/master/operational-location.js +426 -0
  42. package/dist-client/pages/master/operational-location.js.map +1 -0
  43. package/dist-client/pages/master/person.d.ts +12 -0
  44. package/dist-client/pages/master/person.js +41 -0
  45. package/dist-client/pages/master/person.js.map +1 -0
  46. package/dist-client/pages/master/personnel-class.d.ts +12 -0
  47. package/dist-client/pages/master/personnel-class.js +43 -0
  48. package/dist-client/pages/master/personnel-class.js.map +1 -0
  49. package/dist-client/pages/master/physical-asset-class.d.ts +12 -0
  50. package/dist-client/pages/master/physical-asset-class.js +40 -0
  51. package/dist-client/pages/master/physical-asset-class.js.map +1 -0
  52. package/dist-client/pages/master/physical-asset.d.ts +12 -0
  53. package/dist-client/pages/master/physical-asset.js +41 -0
  54. package/dist-client/pages/master/physical-asset.js.map +1 -0
  55. package/dist-client/pages/master/recipe-definition.d.ts +136 -0
  56. package/dist-client/pages/master/recipe-definition.js +404 -0
  57. package/dist-client/pages/master/recipe-definition.js.map +1 -0
  58. package/dist-client/pages/master/reference-targets.d.ts +42 -0
  59. package/dist-client/pages/master/reference-targets.js +82 -0
  60. package/dist-client/pages/master/reference-targets.js.map +1 -0
  61. package/dist-client/pages/master/route-definition.d.ts +19 -0
  62. package/dist-client/pages/master/route-definition.js +40 -0
  63. package/dist-client/pages/master/route-definition.js.map +1 -0
  64. package/dist-client/pages/master/stop-reason.d.ts +12 -0
  65. package/dist-client/pages/master/stop-reason.js +48 -0
  66. package/dist-client/pages/master/stop-reason.js.map +1 -0
  67. package/dist-client/pages/master/test-specification.d.ts +93 -0
  68. package/dist-client/pages/master/test-specification.js +449 -0
  69. package/dist-client/pages/master/test-specification.js.map +1 -0
  70. package/dist-client/pages/master-axes.d.ts +20 -29
  71. package/dist-client/pages/master-axes.js +32 -182
  72. package/dist-client/pages/master-axes.js.map +1 -1
  73. package/dist-client/route.d.ts +1 -1
  74. package/dist-client/route.js +76 -3
  75. package/dist-client/route.js.map +1 -1
  76. package/dist-client/tsconfig.tsbuildinfo +1 -1
  77. package/dist-server/service/asset/asset-lifecycle.d.ts +30 -7
  78. package/dist-server/service/asset/asset-lifecycle.js +33 -6
  79. package/dist-server/service/asset/asset-lifecycle.js.map +1 -1
  80. package/dist-server/service/asset/asset-master-resolver.d.ts +9 -0
  81. package/dist-server/service/asset/asset-master-resolver.js +41 -0
  82. package/dist-server/service/asset/asset-master-resolver.js.map +1 -1
  83. package/dist-server/service/asset/asset-master.js +1 -1
  84. package/dist-server/service/asset/asset-master.js.map +1 -1
  85. package/dist-server/service/asset/asset-query.d.ts +9 -1
  86. package/dist-server/service/asset/asset-query.js +28 -6
  87. package/dist-server/service/asset/asset-query.js.map +1 -1
  88. package/dist-server/service/asset/physical-asset-class.js +1 -1
  89. package/dist-server/service/asset/physical-asset-class.js.map +1 -1
  90. package/dist-server/service/asset/physical-asset.d.ts +17 -4
  91. package/dist-server/service/asset/physical-asset.js +6 -6
  92. package/dist-server/service/asset/physical-asset.js.map +1 -1
  93. package/dist-server/service/equipment/equipment-class.js +1 -1
  94. package/dist-server/service/equipment/equipment-class.js.map +1 -1
  95. package/dist-server/service/equipment/equipment-master-resolver.d.ts +9 -0
  96. package/dist-server/service/equipment/equipment-master-resolver.js +58 -0
  97. package/dist-server/service/equipment/equipment-master-resolver.js.map +1 -1
  98. package/dist-server/service/equipment/equipment-master.d.ts +3 -2
  99. package/dist-server/service/equipment/equipment-master.js +21 -4
  100. package/dist-server/service/equipment/equipment-master.js.map +1 -1
  101. package/dist-server/service/equipment/equipment-query.d.ts +9 -1
  102. package/dist-server/service/equipment/equipment-query.js +28 -6
  103. package/dist-server/service/equipment/equipment-query.js.map +1 -1
  104. package/dist-server/service/equipment/equipment.d.ts +27 -1
  105. package/dist-server/service/equipment/equipment.js +8 -3
  106. package/dist-server/service/equipment/equipment.js.map +1 -1
  107. package/dist-server/service/equipment/state-period-rules.d.ts +19 -0
  108. package/dist-server/service/equipment/state-period-rules.js +35 -1
  109. package/dist-server/service/equipment/state-period-rules.js.map +1 -1
  110. package/dist-server/service/index.d.ts +4 -1
  111. package/dist-server/service/index.js +11 -2
  112. package/dist-server/service/index.js.map +1 -1
  113. package/dist-server/service/location/location-master-resolver.d.ts +29 -0
  114. package/dist-server/service/location/location-master-resolver.js +228 -1
  115. package/dist-server/service/location/location-master-resolver.js.map +1 -1
  116. package/dist-server/service/location/location-query.d.ts +9 -1
  117. package/dist-server/service/location/location-query.js +24 -9
  118. package/dist-server/service/location/location-query.js.map +1 -1
  119. package/dist-server/service/location/operational-location.d.ts +37 -0
  120. package/dist-server/service/location/operational-location.js +22 -2
  121. package/dist-server/service/location/operational-location.js.map +1 -1
  122. package/dist-server/service/master-axis.js +2 -2
  123. package/dist-server/service/master-axis.js.map +1 -1
  124. package/dist-server/service/master-conformance-resolver.d.ts +34 -0
  125. package/dist-server/service/master-conformance-resolver.js +143 -0
  126. package/dist-server/service/master-conformance-resolver.js.map +1 -0
  127. package/dist-server/service/master-conformance.d.ts +80 -0
  128. package/dist-server/service/master-conformance.js +266 -0
  129. package/dist-server/service/master-conformance.js.map +1 -0
  130. package/dist-server/service/master-page-query.d.ts +33 -0
  131. package/dist-server/service/master-page-query.js +55 -0
  132. package/dist-server/service/master-page-query.js.map +1 -0
  133. package/dist-server/service/master-page.d.ts +85 -0
  134. package/dist-server/service/master-page.js +104 -0
  135. package/dist-server/service/master-page.js.map +1 -0
  136. package/dist-server/service/material/material-class.js +1 -1
  137. package/dist-server/service/material/material-class.js.map +1 -1
  138. package/dist-server/service/material/material-definition.js +2 -2
  139. package/dist-server/service/material/material-definition.js.map +1 -1
  140. package/dist-server/service/material/material-master-resolver.d.ts +62 -0
  141. package/dist-server/service/material/material-master-resolver.js +213 -0
  142. package/dist-server/service/material/material-master-resolver.js.map +1 -1
  143. package/dist-server/service/material/material-query.d.ts +9 -1
  144. package/dist-server/service/material/material-query.js +28 -6
  145. package/dist-server/service/material/material-query.js.map +1 -1
  146. package/dist-server/service/material/recipe-index.d.ts +23 -0
  147. package/dist-server/service/material/recipe-index.js +44 -0
  148. package/dist-server/service/material/recipe-index.js.map +1 -0
  149. package/dist-server/service/operation/operation-definition.d.ts +1 -1
  150. package/dist-server/service/operation/operation-definition.js +4 -4
  151. package/dist-server/service/operation/operation-definition.js.map +1 -1
  152. package/dist-server/service/operation/operation-master-resolver.d.ts +24 -0
  153. package/dist-server/service/operation/operation-master-resolver.js +107 -0
  154. package/dist-server/service/operation/operation-master-resolver.js.map +1 -1
  155. package/dist-server/service/operation/operation-query.d.ts +10 -2
  156. package/dist-server/service/operation/operation-query.js +25 -10
  157. package/dist-server/service/operation/operation-query.js.map +1 -1
  158. package/dist-server/service/personnel/person.js +3 -3
  159. package/dist-server/service/personnel/person.js.map +1 -1
  160. package/dist-server/service/personnel/personnel-class.d.ts +1 -1
  161. package/dist-server/service/personnel/personnel-class.js +2 -2
  162. package/dist-server/service/personnel/personnel-class.js.map +1 -1
  163. package/dist-server/service/personnel/personnel-master-resolver.d.ts +9 -0
  164. package/dist-server/service/personnel/personnel-master-resolver.js +43 -0
  165. package/dist-server/service/personnel/personnel-master-resolver.js.map +1 -1
  166. package/dist-server/service/personnel/personnel-master.js +1 -1
  167. package/dist-server/service/personnel/personnel-master.js.map +1 -1
  168. package/dist-server/service/personnel/personnel-query.d.ts +9 -1
  169. package/dist-server/service/personnel/personnel-query.js +28 -6
  170. package/dist-server/service/personnel/personnel-query.js.map +1 -1
  171. package/dist-server/service/recipe/recipe-definition.d.ts +3 -3
  172. package/dist-server/service/recipe/recipe-definition.js +3 -3
  173. package/dist-server/service/recipe/recipe-definition.js.map +1 -1
  174. package/dist-server/service/recipe/recipe-master-resolver.d.ts +1 -1
  175. package/dist-server/service/recipe/recipe-master-resolver.js +1 -1
  176. package/dist-server/service/recipe/recipe-master-resolver.js.map +1 -1
  177. package/dist-server/service/recipe/recipe-master.d.ts +1 -1
  178. package/dist-server/service/recipe/recipe-master.js +2 -2
  179. package/dist-server/service/recipe/recipe-master.js.map +1 -1
  180. package/dist-server/service/recipe/recipe-query.d.ts +11 -3
  181. package/dist-server/service/recipe/recipe-query.js +30 -9
  182. package/dist-server/service/recipe/recipe-query.js.map +1 -1
  183. package/dist-server/service/recipe/route-definition.d.ts +6 -6
  184. package/dist-server/service/recipe/route-definition.js +6 -6
  185. package/dist-server/service/recipe/route-definition.js.map +1 -1
  186. package/dist-server/service/resource/class-lineage.d.ts +46 -0
  187. package/dist-server/service/resource/class-lineage.js +80 -0
  188. package/dist-server/service/resource/class-lineage.js.map +1 -0
  189. package/dist-server/service/resource/class-members.d.ts +36 -0
  190. package/dist-server/service/resource/class-members.js +50 -0
  191. package/dist-server/service/resource/class-members.js.map +1 -0
  192. package/dist-server/service/resource/referrers.d.ts +54 -0
  193. package/dist-server/service/resource/referrers.js +99 -0
  194. package/dist-server/service/resource/referrers.js.map +1 -0
  195. package/dist-server/service/test-spec/criteria-check.d.ts +53 -0
  196. package/dist-server/service/test-spec/criteria-check.js +142 -0
  197. package/dist-server/service/test-spec/criteria-check.js.map +1 -0
  198. package/dist-server/service/test-spec/criteria-rows.d.ts +89 -0
  199. package/dist-server/service/test-spec/criteria-rows.js +139 -0
  200. package/dist-server/service/test-spec/criteria-rows.js.map +1 -0
  201. package/dist-server/service/test-spec/test-spec-master-resolver.d.ts +33 -7
  202. package/dist-server/service/test-spec/test-spec-master-resolver.js +137 -2
  203. package/dist-server/service/test-spec/test-spec-master-resolver.js.map +1 -1
  204. package/dist-server/service/test-spec/test-spec-query.d.ts +9 -1
  205. package/dist-server/service/test-spec/test-spec-query.js +23 -9
  206. package/dist-server/service/test-spec/test-spec-query.js.map +1 -1
  207. package/dist-server/service/test-spec/test-specification.js +1 -1
  208. package/dist-server/service/test-spec/test-specification.js.map +1 -1
  209. package/dist-server/tsconfig.tsbuildinfo +1 -1
  210. package/helps/ops-master/equipment-class.ko.md +11 -0
  211. package/helps/ops-master/equipment-class.md +11 -0
  212. package/helps/ops-master/equipment.ko.md +11 -0
  213. package/helps/ops-master/equipment.md +11 -0
  214. package/helps/ops-master/material-class.ko.md +11 -0
  215. package/helps/ops-master/material-class.md +11 -0
  216. package/helps/ops-master/material-definition.ko.md +11 -0
  217. package/helps/ops-master/material-definition.md +11 -0
  218. package/helps/ops-master/operation-definition.ko.md +11 -0
  219. package/helps/ops-master/operation-definition.md +11 -0
  220. package/helps/ops-master/operational-location.ko.md +11 -0
  221. package/helps/ops-master/operational-location.md +11 -0
  222. package/helps/ops-master/person.ko.md +11 -0
  223. package/helps/ops-master/person.md +11 -0
  224. package/helps/ops-master/personnel-class.ko.md +11 -0
  225. package/helps/ops-master/personnel-class.md +11 -0
  226. package/helps/ops-master/physical-asset-class.ko.md +11 -0
  227. package/helps/ops-master/physical-asset-class.md +11 -0
  228. package/helps/ops-master/physical-asset.ko.md +11 -0
  229. package/helps/ops-master/physical-asset.md +11 -0
  230. package/helps/ops-master/recipe-definition.ko.md +11 -0
  231. package/helps/ops-master/recipe-definition.md +11 -0
  232. package/helps/ops-master/route-definition.ko.md +11 -0
  233. package/helps/ops-master/route-definition.md +11 -0
  234. package/helps/ops-master/stop-reason.ko.md +11 -0
  235. package/helps/ops-master/stop-reason.md +11 -0
  236. package/helps/ops-master/test-specification.ko.md +11 -0
  237. package/helps/ops-master/test-specification.md +11 -0
  238. package/package.json +6 -6
  239. package/things-factory.config.js +22 -2
  240. package/translations/en.json +86 -3
  241. package/translations/ja.json +92 -1
  242. package/translations/ko.json +93 -10
  243. package/translations/ms.json +92 -1
  244. package/translations/zh.json +92 -1
  245. package/dist-client/pages/master-list.d.ts +0 -68
  246. package/dist-client/pages/master-list.js +0 -239
  247. package/dist-client/pages/master-list.js.map +0 -1
@@ -0,0 +1,76 @@
1
+ import { parseIsoDuration } from '@operato/ops-contract';
2
+ /**
3
+ * ISO 8601 기간을 화면에서 다룬다 — **커널이 읽는 표기 그대로 저장한다.**
4
+ *
5
+ * ── 왜 있는 편집기를 안 썼나 ────────────────────────────────────────────────
6
+ * `@operato/grist-editor` 에 `duration` 편집기와 렌더러가 있다. 그런데 그것은 **초 숫자**를 받는다.
7
+ * 소스를 보면 첫 줄이 `Number(value) || 0` 이다. 우리 칸에는 `PT209S` 가 들어 있고 `Number('PT209S')`
8
+ * 는 NaN 이라 0 으로 떨어져서, 화면에 **아무것도 안 나왔다.** 붙여 놓고 확인하지 않았으면 「소요시간이
9
+ * 비어 있다」로 보였을 것이다. [확인함] 2026-09-04
10
+ *
11
+ * 더 나쁜 것은 쓰는 쪽이다. 그 편집기로 고치면 초 숫자가 저장되고, 커널은 그 칸을 ISO 8601 로
12
+ * 읽으므로 그때부터 이 공정의 소요시간이 「모른다」가 된다. 화면에는 값이 있는데.
13
+ *
14
+ * ── 읽는 쪽은 커널 것을 쓴다 ───────────────────────────────────────────────
15
+ * `parseIsoDuration` 이 계약에 있다. 해석 규칙을 여기서 다시 쓰면 두 곳에 생기고, 커널이 받아주지 않는 것을
16
+ * 화면이 받아들이는 날이 온다(연·월은 달력에 기대므로 커널이 받아주지 않는다).
17
+ *
18
+ * 쓰는 쪽은 계약에 없다. 여기서 만들고 아키텍트에게 올려 두었다 — 읽는 쪽을 가진 곳이 쓰는 쪽도
19
+ * 가지는 편이 맞다.
20
+ */
21
+ /** 초 → ISO 8601. 편집기가 저장할 때 쓴다. */
22
+ export function isoDurationOfSeconds(seconds) {
23
+ /*
24
+ * **`PT<초>S` 하나로만 쓴다.** 시·분으로 나눠 쓰면 보기에는 좋지만, 고칠 때마다 표기가 달라져서
25
+ * 같은 값인데 저장된 글자가 계속 바뀐다. 사람이 읽는 것은 렌더러가 맡는다.
26
+ *
27
+ * **소수를 반올림하지 않는다.** 처음에 `Math.round` 를 넣었더니 작업표준서의 6.5초가 7초로
28
+ * 저장됐다 — 화면에는 「6.5초」로 보이던 값을 열었다 닫기만 해도 0.5초가 늘어난다. 공정
29
+ * 스물넷이면 12초다. [확인함] 2026-09-04
30
+ *
31
+ * 밀리초 자리에서 끊는다. 커널의 해석기가 밀리초로 내주므로 그보다 잘게 적어 봐야 돌아오지
32
+ * 않고, 부동소수 찌꺼기(`0.30000000000000004`)만 글자에 남는다.
33
+ */
34
+ const rounded = Math.round(seconds * 1000) / 1000;
35
+ return `PT${rounded}S`;
36
+ }
37
+ /** ISO 8601 → 초. 해석할 수 없으면 `undefined` — 0 이 아니다. */
38
+ export function secondsOfIsoDuration(text) {
39
+ const ms = parseIsoDuration(text);
40
+ return ms === undefined ? undefined : ms / 1000;
41
+ }
42
+ /**
43
+ * 사람이 읽는 글자.
44
+ *
45
+ * **해석할 수 없으면 원문을 그대로 낸다.** 빈 칸으로 두면 「값이 없다」와 「값이 이상하다」가 같아
46
+ * 보인다. `PT30` 처럼 커널이 못 읽는 것이 들어 있으면 그것이 화면에 보여야 고칠 수 있다.
47
+ */
48
+ export function durationText(value, unit) {
49
+ if (!value) {
50
+ return '';
51
+ }
52
+ const seconds = secondsOfIsoDuration(value);
53
+ if (seconds === undefined) {
54
+ return value;
55
+ }
56
+ const negative = seconds < 0;
57
+ let rest = Math.abs(seconds);
58
+ const hours = Math.floor(rest / 3600);
59
+ rest -= hours * 3600;
60
+ const minutes = Math.floor(rest / 60);
61
+ /* 소수 초가 있을 수 있다 — `PT0.5S`. 버리지 않는다. */
62
+ const secs = Math.round((rest - minutes * 60) * 1000) / 1000;
63
+ const parts = [];
64
+ if (hours) {
65
+ parts.push(`${hours}${unit.hour}`);
66
+ }
67
+ if (minutes) {
68
+ parts.push(`${minutes}${unit.minute}`);
69
+ }
70
+ /* 0초는 「0초」라고 적는다 — 다른 자리가 하나도 없을 때만. 아니면 「1분 0초」가 된다. */
71
+ if (secs || parts.length === 0) {
72
+ parts.push(`${secs}${unit.second}`);
73
+ }
74
+ return `${negative ? '-' : ''}${parts.join(' ')}`;
75
+ }
76
+ //# sourceMappingURL=iso-duration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iso-duration.js","sourceRoot":"","sources":["../../../client/pages/master/iso-duration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExD;;;;;;;;;;;;;;;;;;GAkBG;AAEH,mCAAmC;AACnC,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD;;;;;;;;;;OAUG;IACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;IAEjD,OAAO,KAAK,OAAO,GAAG,CAAA;AACxB,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,oBAAoB,CAAC,IAAwB;IAC3D,MAAM,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAEjC,OAAO,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAA;AACjD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAyB,EAAE,IAAsD;IAC5G,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;IAE3C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,GAAG,CAAC,CAAA;IAC5B,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAE5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;IACrC,IAAI,IAAI,KAAK,GAAG,IAAI,CAAA;IACpB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,CAAA;IACrC,wCAAwC;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,OAAO,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;IAE5D,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,IAAI,KAAK,EAAE,CAAC;QACV,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IACpC,CAAC;IACD,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IACxC,CAAC;IACD,yDAAyD;IACzD,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IACrC,CAAC;IAED,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;AACnD,CAAC","sourcesContent":["import { parseIsoDuration } from '@operato/ops-contract'\n\n/**\n * ISO 8601 기간을 화면에서 다룬다 — **커널이 읽는 표기 그대로 저장한다.**\n *\n * ── 왜 있는 편집기를 안 썼나 ────────────────────────────────────────────────\n * `@operato/grist-editor` 에 `duration` 편집기와 렌더러가 있다. 그런데 그것은 **초 숫자**를 받는다.\n * 소스를 보면 첫 줄이 `Number(value) || 0` 이다. 우리 칸에는 `PT209S` 가 들어 있고 `Number('PT209S')`\n * 는 NaN 이라 0 으로 떨어져서, 화면에 **아무것도 안 나왔다.** 붙여 놓고 확인하지 않았으면 「소요시간이\n * 비어 있다」로 보였을 것이다. [확인함] 2026-09-04\n *\n * 더 나쁜 것은 쓰는 쪽이다. 그 편집기로 고치면 초 숫자가 저장되고, 커널은 그 칸을 ISO 8601 로\n * 읽으므로 그때부터 이 공정의 소요시간이 「모른다」가 된다. 화면에는 값이 있는데.\n *\n * ── 읽는 쪽은 커널 것을 쓴다 ───────────────────────────────────────────────\n * `parseIsoDuration` 이 계약에 있다. 해석 규칙을 여기서 다시 쓰면 두 곳에 생기고, 커널이 받아주지 않는 것을\n * 화면이 받아들이는 날이 온다(연·월은 달력에 기대므로 커널이 받아주지 않는다).\n *\n * 쓰는 쪽은 계약에 없다. 여기서 만들고 아키텍트에게 올려 두었다 — 읽는 쪽을 가진 곳이 쓰는 쪽도\n * 가지는 편이 맞다.\n */\n\n/** 초 → ISO 8601. 편집기가 저장할 때 쓴다. */\nexport function isoDurationOfSeconds(seconds: number): string {\n /*\n * **`PT<초>S` 하나로만 쓴다.** 시·분으로 나눠 쓰면 보기에는 좋지만, 고칠 때마다 표기가 달라져서\n * 같은 값인데 저장된 글자가 계속 바뀐다. 사람이 읽는 것은 렌더러가 맡는다.\n *\n * **소수를 반올림하지 않는다.** 처음에 `Math.round` 를 넣었더니 작업표준서의 6.5초가 7초로\n * 저장됐다 — 화면에는 「6.5초」로 보이던 값을 열었다 닫기만 해도 0.5초가 늘어난다. 공정\n * 스물넷이면 12초다. [확인함] 2026-09-04\n *\n * 밀리초 자리에서 끊는다. 커널의 해석기가 밀리초로 내주므로 그보다 잘게 적어 봐야 돌아오지\n * 않고, 부동소수 찌꺼기(`0.30000000000000004`)만 글자에 남는다.\n */\n const rounded = Math.round(seconds * 1000) / 1000\n\n return `PT${rounded}S`\n}\n\n/** ISO 8601 → 초. 해석할 수 없으면 `undefined` — 0 이 아니다. */\nexport function secondsOfIsoDuration(text: string | undefined): number | undefined {\n const ms = parseIsoDuration(text)\n\n return ms === undefined ? undefined : ms / 1000\n}\n\n/**\n * 사람이 읽는 글자.\n *\n * **해석할 수 없으면 원문을 그대로 낸다.** 빈 칸으로 두면 「값이 없다」와 「값이 이상하다」가 같아\n * 보인다. `PT30` 처럼 커널이 못 읽는 것이 들어 있으면 그것이 화면에 보여야 고칠 수 있다.\n */\nexport function durationText(value: string | undefined, unit: { hour: string; minute: string; second: string }): string {\n if (!value) {\n return ''\n }\n\n const seconds = secondsOfIsoDuration(value)\n\n if (seconds === undefined) {\n return value\n }\n\n const negative = seconds < 0\n let rest = Math.abs(seconds)\n\n const hours = Math.floor(rest / 3600)\n rest -= hours * 3600\n const minutes = Math.floor(rest / 60)\n /* 소수 초가 있을 수 있다 — `PT0.5S`. 버리지 않는다. */\n const secs = Math.round((rest - minutes * 60) * 1000) / 1000\n\n const parts: string[] = []\n\n if (hours) {\n parts.push(`${hours}${unit.hour}`)\n }\n if (minutes) {\n parts.push(`${minutes}${unit.minute}`)\n }\n /* 0초는 「0초」라고 적는다 — 다른 자리가 하나도 없을 때만. 아니면 「1분 0초」가 된다. */\n if (secs || parts.length === 0) {\n parts.push(`${secs}${unit.second}`)\n }\n\n return `${negative ? '-' : ''}${parts.join(' ')}`\n}\n"]}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 닫힌 값 집합 — **고르는 칸의 값은 커널에서 온다.**
3
+ *
4
+ * ── 왜 이 파일이 있나 ──────────────────────────────────────────────────────
5
+ * 마스터 화면의 칸이 거의 다 자유 텍스트였다. `level` 에 `WorkCel` 이라고 쳐도 아무 일도 안 나고,
6
+ * 저장되고, 그 뒤로 그 자리는 어떤 계산에도 안 잡힌다. 값이 정해져 있는 칸은 고르게 해야 한다.
7
+ *
8
+ * ── 목록을 여기에 손으로 적지 않는다 ────────────────────────────────────────
9
+ * 화면에 값을 베껴 적으면 커널이 값을 하나 늘렸을 때 화면만 옛 목록을 보인다. 그래서 **계약이
10
+ * 실행시 상수로 내주는 것은 그대로 가져다 쓴다.**
11
+ *
12
+ * 계약이 **타입으로만** 주는 것이 있다. 타입은 실행시에 사라지므로 목록을 만들 수 없다. 그때만
13
+ * 거울을 두고, **컴파일러가 그 거울을 계약에 묶는다** — 계약 쪽이 값을 더하거나 빼면 이 파일이
14
+ * 컴파일되지 않는다. 베껴 적은 것과 다른 점이 그것이다.
15
+ *
16
+ * 계약이 상수를 내주면 거울을 지운다. 아키텍트에게 올려 두었다(`EQUIPMENT_LEVEL` ·
17
+ * `DISPOSITION_DECISION` 처럼 `OPERATION_INTENT` 도 상수로).
18
+ */
19
+ /** 자리의 계층 — ISA-95 장비 계층. 계약이 실행시 상수로 준다. */
20
+ export declare const LEVEL_OPTIONS: readonly string[];
21
+ /**
22
+ * 공정의 의도 — 운반 · 가공 · 체류.
23
+ *
24
+ * 계약은 `OperationIntent` 를 **타입**으로만 낸다. 아래 두 줄이 이 배열을 그 타입에 묶는다.
25
+ */
26
+ export declare const INTENT_OPTIONS: readonly ["transport", "process", "dwell"];
27
+ /**
28
+ * 고르는 칸의 첫 줄은 **빈 값**이다.
29
+ *
30
+ * 안 넣으면 「아직 안 정했다」를 고를 수 없어서, 칸을 한 번 건드리면 되돌릴 수 없다. 비워 둘 수
31
+ * 있는 칸에만 붙인다.
32
+ */
33
+ export declare function withBlank(options: readonly string[]): string[];
@@ -0,0 +1,47 @@
1
+ import { EQUIPMENT_LEVEL } from '@operato/ops-contract';
2
+ /**
3
+ * 닫힌 값 집합 — **고르는 칸의 값은 커널에서 온다.**
4
+ *
5
+ * ── 왜 이 파일이 있나 ──────────────────────────────────────────────────────
6
+ * 마스터 화면의 칸이 거의 다 자유 텍스트였다. `level` 에 `WorkCel` 이라고 쳐도 아무 일도 안 나고,
7
+ * 저장되고, 그 뒤로 그 자리는 어떤 계산에도 안 잡힌다. 값이 정해져 있는 칸은 고르게 해야 한다.
8
+ *
9
+ * ── 목록을 여기에 손으로 적지 않는다 ────────────────────────────────────────
10
+ * 화면에 값을 베껴 적으면 커널이 값을 하나 늘렸을 때 화면만 옛 목록을 보인다. 그래서 **계약이
11
+ * 실행시 상수로 내주는 것은 그대로 가져다 쓴다.**
12
+ *
13
+ * 계약이 **타입으로만** 주는 것이 있다. 타입은 실행시에 사라지므로 목록을 만들 수 없다. 그때만
14
+ * 거울을 두고, **컴파일러가 그 거울을 계약에 묶는다** — 계약 쪽이 값을 더하거나 빼면 이 파일이
15
+ * 컴파일되지 않는다. 베껴 적은 것과 다른 점이 그것이다.
16
+ *
17
+ * 계약이 상수를 내주면 거울을 지운다. 아키텍트에게 올려 두었다(`EQUIPMENT_LEVEL` ·
18
+ * `DISPOSITION_DECISION` 처럼 `OPERATION_INTENT` 도 상수로).
19
+ */
20
+ /** 자리의 계층 — ISA-95 장비 계층. 계약이 실행시 상수로 준다. */
21
+ export const LEVEL_OPTIONS = EQUIPMENT_LEVEL;
22
+ /**
23
+ * 공정의 의도 — 운반 · 가공 · 체류.
24
+ *
25
+ * 계약은 `OperationIntent` 를 **타입**으로만 낸다. 아래 두 줄이 이 배열을 그 타입에 묶는다.
26
+ */
27
+ export const INTENT_OPTIONS = ['transport', 'process', 'dwell'];
28
+ /*
29
+ * **양쪽으로 묶는다.**
30
+ *
31
+ * 위 줄만 있으면 계약이 값을 하나 빼도 안 깨진다(우리 것이 더 넓어질 뿐이다). 아래 줄만 있으면
32
+ * 계약이 값을 하나 더해도 안 깨진다. 둘 다 있어야 어느 쪽이 움직여도 컴파일이 멈춘다.
33
+ */
34
+ const _intentIsInContract = [...INTENT_OPTIONS];
35
+ const _contractIsInIntent = ['transport', 'process', 'dwell'];
36
+ void _intentIsInContract;
37
+ void _contractIsInIntent;
38
+ /**
39
+ * 고르는 칸의 첫 줄은 **빈 값**이다.
40
+ *
41
+ * 안 넣으면 「아직 안 정했다」를 고를 수 없어서, 칸을 한 번 건드리면 되돌릴 수 없다. 비워 둘 수
42
+ * 있는 칸에만 붙인다.
43
+ */
44
+ export function withBlank(options) {
45
+ return ['', ...options];
46
+ }
47
+ //# sourceMappingURL=master-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"master-options.js","sourceRoot":"","sources":["../../../client/pages/master/master-options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAGvD;;;;;;;;;;;;;;;;;GAiBG;AAEH,6CAA6C;AAC7C,MAAM,CAAC,MAAM,aAAa,GAAsB,eAAe,CAAA;AAE/D;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAU,CAAA;AAExE;;;;;GAKG;AACH,MAAM,mBAAmB,GAAsB,CAAC,GAAG,cAAc,CAAC,CAAA;AAClE,MAAM,mBAAmB,GAAsC,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAsB,CAAA;AAErH,KAAK,mBAAmB,CAAA;AACxB,KAAK,mBAAmB,CAAA;AAExB;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,OAA0B;IAClD,OAAO,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,CAAA;AACzB,CAAC","sourcesContent":["import { EQUIPMENT_LEVEL } from '@operato/ops-contract'\nimport type { OperationIntent } from '@operato/ops-contract'\n\n/**\n * 닫힌 값 집합 — **고르는 칸의 값은 커널에서 온다.**\n *\n * ── 왜 이 파일이 있나 ──────────────────────────────────────────────────────\n * 마스터 화면의 칸이 거의 다 자유 텍스트였다. `level` 에 `WorkCel` 이라고 쳐도 아무 일도 안 나고,\n * 저장되고, 그 뒤로 그 자리는 어떤 계산에도 안 잡힌다. 값이 정해져 있는 칸은 고르게 해야 한다.\n *\n * ── 목록을 여기에 손으로 적지 않는다 ────────────────────────────────────────\n * 화면에 값을 베껴 적으면 커널이 값을 하나 늘렸을 때 화면만 옛 목록을 보인다. 그래서 **계약이\n * 실행시 상수로 내주는 것은 그대로 가져다 쓴다.**\n *\n * 계약이 **타입으로만** 주는 것이 있다. 타입은 실행시에 사라지므로 목록을 만들 수 없다. 그때만\n * 거울을 두고, **컴파일러가 그 거울을 계약에 묶는다** — 계약 쪽이 값을 더하거나 빼면 이 파일이\n * 컴파일되지 않는다. 베껴 적은 것과 다른 점이 그것이다.\n *\n * 계약이 상수를 내주면 거울을 지운다. 아키텍트에게 올려 두었다(`EQUIPMENT_LEVEL` ·\n * `DISPOSITION_DECISION` 처럼 `OPERATION_INTENT` 도 상수로).\n */\n\n/** 자리의 계층 — ISA-95 장비 계층. 계약이 실행시 상수로 준다. */\nexport const LEVEL_OPTIONS: readonly string[] = EQUIPMENT_LEVEL\n\n/**\n * 공정의 의도 — 운반 · 가공 · 체류.\n *\n * 계약은 `OperationIntent` 를 **타입**으로만 낸다. 아래 두 줄이 이 배열을 그 타입에 묶는다.\n */\nexport const INTENT_OPTIONS = ['transport', 'process', 'dwell'] as const\n\n/*\n * **양쪽으로 묶는다.**\n *\n * 위 줄만 있으면 계약이 값을 하나 빼도 안 깨진다(우리 것이 더 넓어질 뿐이다). 아래 줄만 있으면\n * 계약이 값을 하나 더해도 안 깨진다. 둘 다 있어야 어느 쪽이 움직여도 컴파일이 멈춘다.\n */\nconst _intentIsInContract: OperationIntent[] = [...INTENT_OPTIONS]\nconst _contractIsInIntent: (typeof INTENT_OPTIONS)[number][] = ['transport', 'process', 'dwell'] as OperationIntent[]\n\nvoid _intentIsInContract\nvoid _contractIsInIntent\n\n/**\n * 고르는 칸의 첫 줄은 **빈 값**이다.\n *\n * 안 넣으면 「아직 안 정했다」를 고를 수 없어서, 칸을 한 번 건드리면 되돌릴 수 없다. 비워 둘 수\n * 있는 칸에만 붙인다.\n */\nexport function withBlank(options: readonly string[]): string[] {\n return ['', ...options]\n}\n"]}
@@ -0,0 +1,357 @@
1
+ import '@material/web/icon/icon.js';
2
+ import '@operato/data-grist/ox-grist.js';
3
+ import { DataGrist, FetchOption } from '@operato/data-grist';
4
+ import type { ReferenceOptions } from './grist-reference.js';
5
+ import { PageView } from '@operato/shell';
6
+ /**
7
+ * 마스터 화면이 함께 쓰는 것 — **코드 재사용은 여기서, 화면은 각자.**
8
+ *
9
+ * ── 왜 화면을 갈랐나 (2026-09-01) ──────────────────────────────────────────
10
+ * 전에는 화면 하나가 `?axis=` 로 열두 축을 다 맡았다. 근거는 「열두 축이 하는 일이 같다」였는데, 그
11
+ * 말은 **지금 자리표시자라서 같아 보이는 것**이었다. 선언을 읽으면 이미 갈라져 있다.
12
+ *
13
+ * 정지 사유 · 위치 계층(parentName · parentId) — 표가 아니라 나무여야 한다
14
+ * 등급 넷 baseIds 다중 상속 — 쉼표 문자열로 편집 중이다
15
+ * 인원 · 설비 · 자산 근무 캘린더 · 검사 결과를 JSON 원문으로 보인다
16
+ * 자재 GTIN · 단위 · 보관처의 칸이 없어 properties JSON 이다
17
+ * 공정 duration 이 ISO 기간, bizStep 이 EPCIS 어휘다
18
+ * 검사 기준 컬럼이 0개다 — 항목 · 상하한 · 단위 · 방법이 들어와야 한다
19
+ *
20
+ * 그 자리표시자를 걷으면 열둘이 서로 다른 화면이 된다. 공용 화면에 「이 축만」 분기를 열둘 넣는 것은
21
+ * 화면 열둘보다 나쁘다.
22
+ *
23
+ * ── UX 일관성과 일괄 개발 편의는 다르다 ────────────────────────────────────
24
+ * 일관성은 **쓰는 사람이 겪는 것**이다. 같은 뜻이 같은 자리에, 같은 용어로, 같은 조작으로. 그것은
25
+ * 어휘와 배치와 부품을 공유해서 얻는다.
26
+ *
27
+ * 일괄 개발의 편의는 **만드는 쪽이 겪는 것**이고, 기반 클래스로 얻으면 된다. 그것을 얻으려고 서로 다른
28
+ * 대상을 한 화면에 묶으면 편의는 만드는 쪽이 가져가고 값은 쓰는 쪽이 치른다.
29
+ *
30
+ * ── MDI 에서도 갈려야 한다 ─────────────────────────────────────────────────
31
+ * MDI 탭은 페이지 **요소**로 나뉜다(`page-mdibar.ts`). 한 라우트면 인원과 설비를 나란히 열 수 없는데,
32
+ * 마스터 작업의 대부분이 두 항목을 비교하며 옮겨 적는 일이다. 품목을 보면서 품목 등급을 채운다.
33
+ *
34
+ * ── 이 클래스가 갖는 것과 갖지 않는 것 ─────────────────────────────────────
35
+ * 갖는 것: 화면 골격 · 컬럼 설정 · 가져오기 · 저장 · 컬럼 하나를 그리는 방식.
36
+ * 갖지 않는 것: **무엇을 보이나.** 그것은 각 화면이 `spec` 으로 말한다.
37
+ */
38
+ export type MasterColumnType = 'string' | 'number' | 'boolean' | 'date' | 'json' | 'list'
39
+ /** 정해진 값 중에서 고른다. `options` 를 함께 준다. */
40
+ | 'select'
41
+ /**
42
+ * ISO 8601 기간 — `PT30S`.
43
+ *
44
+ * 이름이 `duration` 이 아니다. 그 이름은 초 숫자용으로 이미 임자가 있다(`worklist`). 등록소를
45
+ * 앱 전체가 나눠 쓰므로, 이름이 겹치면 나중에 부팅한 쪽이 오류보고없이 이긴다.
46
+ */
47
+ | 'iso-duration'
48
+ /** 다른 표의 이름 하나. `reference` 를 함께 준다. */
49
+ | 'reference' | 'reference-list';
50
+ export interface MasterColumn {
51
+ name: string;
52
+ /** 화면 문구 키. `field.<이것>`. */
53
+ label: string;
54
+ type: MasterColumnType;
55
+ /**
56
+ * `select` 가 고를 값들.
57
+ *
58
+ * **여기에 손으로 적지 않는다.** `master-options.ts` 가 계약에서 가져오거나, 계약이 타입으로만
59
+ * 주는 것은 컴파일러가 계약에 묶은 거울에서 가져온다. 화면에 값을 베껴 적으면 커널이 값을 늘렸을
60
+ * 때 화면만 옛 목록을 보인다.
61
+ */
62
+ options?: readonly string[];
63
+ /**
64
+ * `reference` 가 어느 표에서 고르나.
65
+ *
66
+ * 저장되는 것은 **이름**이지 id 가 아니다 — 커널이 이름으로 주소를 잡는다.
67
+ */
68
+ reference?: ReferenceOptions;
69
+ width?: number;
70
+ /** 고칠 수 없는 칸. 자동으로 붙는 값이 여기 온다. */
71
+ readonly?: boolean;
72
+ /**
73
+ * 가로로 스크롤해도 화면에 남는 컬럼.
74
+ *
75
+ * 컬럼이 열 개를 넘고 폭 합이 1000px 을 넘는 축이 있다. 오른쪽 끝을 고치려고 스크롤하면 이름이 화면
76
+ * 밖으로 나가서 **어느 행을 고치는지 알 수 없다.**
77
+ */
78
+ fixed?: boolean;
79
+ /**
80
+ * 표에 그리지 않는다 — **검색에는 남는다.**
81
+ *
82
+ * 같은 사실을 두 번 보이지 않으려고 감추는 자리가 있다. 로케이션의 상위는 트리의 들여쓰기가 말하므로
83
+ * 컬럼으로 또 보일 필요가 없지만, 「LINE-1 아래 있는 것」을 찾는 일은 있다.
84
+ *
85
+ * `searchText` 는 `filter: 'search'` 를 선언한 컬럼마다 필터를 만들고 hidden 을 보지 않는다
86
+ * (`data-grist.ts` 의 `set searchText`). 그래서 감춘 컬럼도 검색에는 참여한다.
87
+ *
88
+ * 다만 컬럼 설정 목록에서는 **빠진다** — personalizer 가 페이지 설정의 hidden 을 걸러낸다
89
+ * (`ox-grist-personalizer.ts:51`). 사용자가 켜야 할 컬럼에는 쓰지 않는다.
90
+ */
91
+ hidden?: boolean;
92
+ }
93
+ /** 각 마스터 화면이 자기에 대해 말하는 것. */
94
+ export interface MasterSpec {
95
+ /** 컬럼 설정을 사람마다 따로 저장하는 키. 화면마다 달라야 한다. */
96
+ key: string;
97
+ /** 제목 문구 키. `title.<이것>`. */
98
+ title: string;
99
+ /**
100
+ * 도움말 문서 키 — `helps/<이것>.md`.
101
+ *
102
+ * `ox-page-title-bar` 가 이 값이 있으면 제목 옆에 도움말 아이콘을 그린다. 상세한 설명은 그 문서가
103
+ * 갖는다 — 화면에 형식적인 소개 문장을 붙이는 것은 자리만 차지하고 도움이 안 된다.
104
+ */
105
+ help: string;
106
+ /** GraphQL 조회 이름 — 서버가 낸 그대로. */
107
+ query: string;
108
+ /** GraphQL 저장 이름. */
109
+ mutation: string;
110
+ columns: MasterColumn[];
111
+ }
112
+ /** 열두 축이 공통으로 갖는 유효 기간 — ISA-95. */
113
+ export declare const EFFECTIVE: MasterColumn[];
114
+ /** 이름과 설명은 열두 축이 모두 갖는다. 이름은 스크롤해도 남는다. */
115
+ export declare const IDENTITY: MasterColumn[];
116
+ declare const MasterPageBase_base: (new (...args: any[]) => {
117
+ __preferenceProviders: {
118
+ [element: string]: import("@operato/p13n").PagePreferenceProvider;
119
+ };
120
+ getPagePreferenceProvider(element: string): import("@operato/p13n").PagePreferenceProvider | undefined;
121
+ }) & (new (...args: any[]) => import("lit").LitElement) & typeof PageView;
122
+ export declare abstract class MasterPageBase extends MasterPageBase_base {
123
+ static styles: import("lit").CSSResult[];
124
+ /** 이 화면이 자기에 대해 말하는 것. 화면마다 자기 것을 준다. */
125
+ protected abstract get spec(): MasterSpec;
126
+ active: boolean;
127
+ gristConfig: any;
128
+ mode: 'CARD' | 'LIST' | 'GRID';
129
+ protected ready: boolean;
130
+ protected grist: DataGrist;
131
+ get context(): {
132
+ title: string;
133
+ importable: {
134
+ handler: (records: any[]) => Promise<void>;
135
+ };
136
+ help: string;
137
+ search: {
138
+ handler: (search: string) => void;
139
+ value: string;
140
+ };
141
+ actions: {
142
+ title: string;
143
+ action: () => Promise<void>;
144
+ icon: string;
145
+ emphasis: {
146
+ raised: boolean;
147
+ };
148
+ }[];
149
+ exportable: {
150
+ name: string;
151
+ data: () => any[];
152
+ };
153
+ };
154
+ /**
155
+ * 지금 무엇을 보고 있는가 — 표 바로 위.
156
+ *
157
+ * 계층을 드릴다운으로 걷는 화면은 「어디를 보고 있나」를 말해야 한다. 대부분의 화면은 표 하나가 전부라
158
+ * 범위가 없다 — 그런 화면은 아무것도 그리지 않고, 그 줄이 접힌다.
159
+ */
160
+ protected renderScope(): import("lit-html").TemplateResult<1>;
161
+ /**
162
+ * 화면 골격 — 표 하나와 컬럼 설정.
163
+ *
164
+ * 자기 인터페이스가 필요한 화면은 이것을 덮어쓴다. 위치와 정지 사유는 계층이라 표가 아니라 나무여야
165
+ * 하고, 그때 이 render 를 쓰지 않는다.
166
+ */
167
+ render(): import("lit-html").TemplateResult<1>;
168
+ /**
169
+ * 주소 끝의 이름 조각을 **목록 좁히기**에 쓰나.
170
+ *
171
+ * 다른 화면의 참조 칸에서 걸어 들어오면 주소가 `.../ops-master-material-definition/M0161-0003` 이
172
+ * 된다. 그 조각을 아무도 안 읽으면 106줄짜리 목록 첫 장이 뜨고, 사람은 방금 누른 이름을 다시
173
+ * 찾아야 한다 — 걸어온 보람이 없다.
174
+ *
175
+ * 자리 화면과 제조법 화면은 그 조각을 **파고들기**에 이미 쓰고 있다(그 이름 아래를 보여 준다).
176
+ * 그 둘은 여기서 빠진다 — 두 뜻이 한 조각에 겹치면 어느 쪽도 제대로 안 된다.
177
+ */
178
+ protected get pathSegmentNarrowsList(): boolean;
179
+ pageInitialized(): Promise<void>;
180
+ /**
181
+ * 셸은 `(changes, after, before)` 를 넘긴다 — 인수 없는 모양으로 좁히면 주소를 읽어야 하는 화면이
182
+ * 이것을 덮어쓸 수 없다(`after.resourceId` 와 `before.resourceId` 를 비교하는 자리다).
183
+ */
184
+ pageUpdated(_changes?: any, _after?: any, _before?: any): Promise<void>;
185
+ protected configOf(): any;
186
+ protected columnOf(column: MasterColumn): {
187
+ type: string;
188
+ name: string;
189
+ header: string;
190
+ record: {
191
+ editable: boolean;
192
+ options?: undefined;
193
+ reference?: undefined;
194
+ editor?: undefined;
195
+ opensPopup?: undefined;
196
+ };
197
+ sortable: boolean;
198
+ width: number | undefined;
199
+ fixed: boolean | undefined;
200
+ hidden: boolean | undefined;
201
+ filter?: undefined;
202
+ } | {
203
+ type: string;
204
+ name: string;
205
+ header: string;
206
+ record: {
207
+ editable: boolean;
208
+ options?: undefined;
209
+ reference?: undefined;
210
+ editor?: undefined;
211
+ opensPopup?: undefined;
212
+ };
213
+ width: number | undefined;
214
+ fixed: boolean | undefined;
215
+ hidden: boolean | undefined;
216
+ sortable?: undefined;
217
+ filter?: undefined;
218
+ } | {
219
+ type: string;
220
+ name: string;
221
+ header: string;
222
+ record: {
223
+ editable: boolean;
224
+ options: readonly string[];
225
+ reference?: undefined;
226
+ editor?: undefined;
227
+ opensPopup?: undefined;
228
+ };
229
+ filter: string;
230
+ sortable: boolean;
231
+ width: number | undefined;
232
+ fixed: boolean | undefined;
233
+ hidden: boolean | undefined;
234
+ } | {
235
+ type: string;
236
+ name: string;
237
+ header: string;
238
+ record: {
239
+ editable: boolean;
240
+ reference: {
241
+ queryName?: string | undefined;
242
+ multiple?: boolean;
243
+ title: string;
244
+ columns?: {
245
+ name: string;
246
+ header?: string;
247
+ width?: number;
248
+ }[];
249
+ valueField?: string;
250
+ };
251
+ options?: undefined;
252
+ editor?: undefined;
253
+ opensPopup?: undefined;
254
+ };
255
+ filter: string;
256
+ sortable: boolean;
257
+ width: number | undefined;
258
+ fixed: boolean | undefined;
259
+ hidden: boolean | undefined;
260
+ } | {
261
+ type: string;
262
+ name: string;
263
+ header: string;
264
+ record: {
265
+ editable: boolean;
266
+ editor: import("@operato/data-grist").FieldEditor;
267
+ opensPopup: boolean;
268
+ reference: {
269
+ queryName?: string | undefined;
270
+ multiple: boolean;
271
+ title: string;
272
+ columns?: {
273
+ name: string;
274
+ header?: string;
275
+ width?: number;
276
+ }[];
277
+ valueField?: string;
278
+ };
279
+ options?: undefined;
280
+ };
281
+ sortable: boolean;
282
+ width: number | undefined;
283
+ fixed: boolean | undefined;
284
+ hidden: boolean | undefined;
285
+ filter?: undefined;
286
+ } | {
287
+ type: string;
288
+ name: string;
289
+ header: string;
290
+ record: {
291
+ editable: boolean;
292
+ options?: undefined;
293
+ reference?: undefined;
294
+ editor?: undefined;
295
+ opensPopup?: undefined;
296
+ };
297
+ filter: string;
298
+ sortable: boolean;
299
+ width: number | undefined;
300
+ fixed: boolean | undefined;
301
+ hidden: boolean | undefined;
302
+ };
303
+ fetchHandler({ page, limit, sortings, filters }: FetchOption): Promise<{
304
+ total: any;
305
+ records: any;
306
+ }>;
307
+ /**
308
+ * JSON 칸을 **사람이 고칠 수 있는 글자로 편다.**
309
+ *
310
+ * 서버는 구조를 구조로 낸다(`ScalarObject` 로 선언하지만 **스키마에 나가는 이름은 `Object`** 다) — 그것이
311
+ * 사실이고, 곧 붙을 전용 편집기가 원하는 모양이다.
312
+ * 그런데 지금 이 그리드의 JSON 칸은 글자 편집기라 객체를 그대로 주면 `[object Object]` 가 된다.
313
+ * 그래서 **화면에 들어올 때만** 편다. 스키마를 화면 사정에 맞추지 않고, 화면이 자기 몫을 한다.
314
+ *
315
+ * 이 옮김은 `packJson` 과 짝이다. 한쪽만 고치면 저장이 오류보고없이 망가진다.
316
+ */
317
+ protected spreadJson(item: any): any;
318
+ /**
319
+ * 저장하기 전에 JSON 칸의 글자를 **구조로 되읽는다.**
320
+ *
321
+ * 읽지 못하면 **보내지 않는다.** 그냥 보내면 글자가 통째로 값이 되어, 사람이 적은 구조가 사라진 채로
322
+ * 저장이 성공했다고 나온다. 어느 행 어느 칸인지 말해 주어야 고칠 수 있다.
323
+ */
324
+ protected packJson(patches: any[]): {
325
+ patches: any[];
326
+ problems: string[];
327
+ };
328
+ /**
329
+ * 파일로 올린 줄들을 이 화면의 마스터로 넣는다.
330
+ *
331
+ * ── 오류보고없이 버리지 않는다 ─────────────────────────────────────────────────
332
+ * 모르는 열 이름, 이름이 없는 줄, 중복된 이름을 **알린다.** 오류보고없이 빼면 사람은 다 올라간 줄 알고,
333
+ * 빠진 것은 나중에 「그 설비가 왜 없지」로 나타난다.
334
+ *
335
+ * ── 하나라도 틀리면 아무것도 안 보낸다 ───────────────────────────────────
336
+ * 절반만 들어가면 무엇이 들어갔는지 사람이 모른다. 파일을 고쳐 다시 올리는 편이 낫다.
337
+ *
338
+ * ── 새로 만들 것과 고칠 것을 이름으로 구분한다 ─────────────────────────────
339
+ * 서버는 `+`(새로)와 `M`(고침, id 필요)을 나눠 받는다. 그러니 **올리기 전에 그 이름들이 이미
340
+ * 있는지 물어야 한다.** 안 물으면 같은 이름이 두 벌 생긴다.
341
+ */
342
+ protected importHandler(records: any[]): Promise<void>;
343
+ /**
344
+ * 파일의 머리글을 이 화면의 열 이름으로 바꾼다.
345
+ *
346
+ * **두 가지를 다 받는다** — 열 이름 그대로(`homeLocation`)와 화면에 보이는 말(`홈 자리`).
347
+ * 사람이 이 화면에서 내려받아 고쳐 올리면 머리글이 화면의 말이고, 다른 시스템에서 뽑아 오면
348
+ * 열 이름이다. 한쪽만 받으면 다른 쪽이 통째로 「모르는 열」이 된다.
349
+ */
350
+ /** 무엇이 잘못됐는지를 사람에게 보일 문장으로 바꾼다. 줄 번호는 엑셀에서 보는 그 번호다. */
351
+ private sayProblem;
352
+ private headerIndex;
353
+ /** 이 이름들이 이미 있나 — 있으면 그 `id`. 없는 이름은 지도에 없다. */
354
+ private idsByName;
355
+ protected save(): Promise<void>;
356
+ }
357
+ export {};