@things-factory/ops-master 10.0.18 → 10.0.19

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 (55) hide show
  1. package/dist-client/pages/master-axes.js +20 -7
  2. package/dist-client/pages/master-axes.js.map +1 -1
  3. package/dist-client/pages/master-list.d.ts +3 -3
  4. package/dist-client/pages/master-list.js +10 -38
  5. package/dist-client/pages/master-list.js.map +1 -1
  6. package/dist-client/tsconfig.tsbuildinfo +1 -1
  7. package/dist-server/service/index.d.ts +9 -2
  8. package/dist-server/service/index.js +11 -0
  9. package/dist-server/service/index.js.map +1 -1
  10. package/dist-server/service/master-axis.d.ts +1 -1
  11. package/dist-server/service/master-axis.js +16 -1
  12. package/dist-server/service/master-axis.js.map +1 -1
  13. package/dist-server/service/operation/index.d.ts +2 -1
  14. package/dist-server/service/operation/index.js +2 -1
  15. package/dist-server/service/operation/index.js.map +1 -1
  16. package/dist-server/service/operation/operation-readiness-resolver.d.ts +39 -0
  17. package/dist-server/service/operation/operation-readiness-resolver.js +111 -0
  18. package/dist-server/service/operation/operation-readiness-resolver.js.map +1 -0
  19. package/dist-server/service/operation/operation-readiness.d.ts +34 -0
  20. package/dist-server/service/operation/operation-readiness.js +133 -0
  21. package/dist-server/service/operation/operation-readiness.js.map +1 -0
  22. package/dist-server/service/personnel/personnel-class-readiness.d.ts +22 -0
  23. package/dist-server/service/personnel/personnel-class-readiness.js +98 -0
  24. package/dist-server/service/personnel/personnel-class-readiness.js.map +1 -0
  25. package/dist-server/service/personnel/qualification.d.ts +7 -0
  26. package/dist-server/service/personnel/qualification.js +25 -0
  27. package/dist-server/service/personnel/qualification.js.map +1 -1
  28. package/dist-server/service/recipe/index.d.ts +9 -0
  29. package/dist-server/service/recipe/index.js +14 -0
  30. package/dist-server/service/recipe/index.js.map +1 -0
  31. package/dist-server/service/recipe/recipe-definition.d.ts +71 -0
  32. package/dist-server/service/recipe/recipe-definition.js +130 -0
  33. package/dist-server/service/recipe/recipe-definition.js.map +1 -0
  34. package/dist-server/service/recipe/recipe-master-resolver.d.ts +28 -0
  35. package/dist-server/service/recipe/recipe-master-resolver.js +124 -0
  36. package/dist-server/service/recipe/recipe-master-resolver.js.map +1 -0
  37. package/dist-server/service/recipe/recipe-master.d.ts +37 -0
  38. package/dist-server/service/recipe/recipe-master.js +47 -0
  39. package/dist-server/service/recipe/recipe-master.js.map +1 -0
  40. package/dist-server/service/recipe/recipe-query.d.ts +13 -0
  41. package/dist-server/service/recipe/recipe-query.js +54 -0
  42. package/dist-server/service/recipe/recipe-query.js.map +1 -0
  43. package/dist-server/service/recipe/route-definition.d.ts +51 -0
  44. package/dist-server/service/recipe/route-definition.js +113 -0
  45. package/dist-server/service/recipe/route-definition.js.map +1 -0
  46. package/dist-server/service/status/master-status.d.ts +0 -7
  47. package/dist-server/service/status/master-status.js +5 -6
  48. package/dist-server/service/status/master-status.js.map +1 -1
  49. package/dist-server/tsconfig.tsbuildinfo +1 -1
  50. package/package.json +5 -5
  51. package/translations/en.json +3 -3
  52. package/translations/ja.json +5 -1
  53. package/translations/ko.json +3 -3
  54. package/translations/ms.json +5 -1
  55. package/translations/zh.json +5 -1
@@ -61,7 +61,12 @@ export const MASTER_AXIS_VIEWS = [
61
61
  title: 'equipment',
62
62
  columns: [
63
63
  ...IDENTITY,
64
- { name: 'equipmentClassIds', label: 'equipment-classes', type: 'list', width: 200 },
64
+ /*
65
+ * 설비의 등급은 **하나**이고 이름이 `kind` 다(표준 EquipmentClassID · 계약의 kind 자리).
66
+ * 전에는 `equipmentClassIds` 라는 배열 칸을 물었는데 그런 칸이 없다. GraphQL 은 칸 하나가
67
+ * 틀리면 질의를 통째로 오류로 내므로, 설비 마스터 화면이 전부 400 이었다.
68
+ */
69
+ { name: 'kind', label: 'equipment-class', type: 'string', width: 200 },
65
70
  { name: 'identity', label: 'identity', type: 'string', width: 200 },
66
71
  { name: 'homeLocation', label: 'home-location', type: 'string', width: 140 },
67
72
  /* 계획 조업 시간의 바탕. 비어 있으면 OEE 의 가동률이 「모름」이 된다. */
@@ -125,9 +130,15 @@ export const MASTER_AXIS_VIEWS = [
125
130
  columns: [
126
131
  ...IDENTITY,
127
132
  { name: 'materialClassIds', label: 'material-classes', type: 'list', width: 180 },
128
- { name: 'identity', label: 'gtin', type: 'string', width: 200 },
129
- { name: 'uom', label: 'uom', type: 'string', width: 90 },
130
- { name: 'locationType', label: 'location-type', type: 'string', width: 140 },
133
+ /*
134
+ * GTIN · 단위 · 보관처는 **API 가 내주지 않는다.** 전에는 `identity`·`uom`·`locationType` 을
135
+ * 물었는데 `MaterialDefinition` 에 그런 칸이 없다. GraphQL 은 칸 하나가 틀리면 질의를 통째로
136
+ * 오류로 내므로, 자재 마스터 화면이 전부 400 이었다.
137
+ *
138
+ * 그 값들이 어디에 사는지 모르는 채로 다른 칸을 대신 물지 않는다. 지금은 `properties` 로
139
+ * 있는 그대로 보이고, 제 칸이 생기면 그때 나눈다.
140
+ */
141
+ { name: 'properties', label: 'properties', type: 'json', width: 240 },
131
142
  ...EFFECTIVE
132
143
  ]
133
144
  },
@@ -138,9 +149,11 @@ export const MASTER_AXIS_VIEWS = [
138
149
  title: 'location',
139
150
  columns: [
140
151
  ...IDENTITY,
141
- { name: 'equipmentLevel', label: 'equipment-level', type: 'string', width: 140 },
142
- { name: 'parentName', label: 'parent-location', type: 'string', width: 150 },
143
- { name: 'identity', label: 'sgln', type: 'string', width: 200 },
152
+ /* 스키마의 이름은 `level`·`parentId` 다. 전에는 `equipmentLevel`·`parentName` 을 물어 화면이 400 이었다. */
153
+ { name: 'level', label: 'equipment-level', type: 'string', width: 140 },
154
+ { name: 'parentId', label: 'parent-location', type: 'string', width: 150 },
155
+ { name: 'type', label: 'location-type', type: 'string', width: 140 },
156
+ { name: 'capacity', label: 'capacity', type: 'number', width: 90 },
144
157
  ...EFFECTIVE
145
158
  ]
146
159
  },
@@ -1 +1 @@
1
- {"version":3,"file":"master-axes.js","sourceRoot":"","sources":["../../client/pages/master-axes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAyBH,yCAAyC;AACzC,MAAM,SAAS,GAAiB;IAC9B,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;IAC9E,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;CAC3E,CAAA;AAED,4BAA4B;AAC5B,MAAM,QAAQ,GAAiB;IAC7B,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;IAC3D,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;CAC1E,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAA8B;IAC1D;QACE,GAAG,EAAE,gBAAgB;QACrB,KAAK,EAAE,kBAAkB;QACzB,QAAQ,EAAE,8BAA8B;QACxC,KAAK,EAAE,iBAAiB;QACxB,OAAO,EAAE;YACP,GAAG,QAAQ;YACX,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;YACpE,+DAA+D;YAC/D,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;YACnF,GAAG,SAAS;SACb;KACF;IACD;QACE,GAAG,EAAE,QAAQ;QACb,KAAK,EAAE,SAAS;QAChB,QAAQ,EAAE,sBAAsB;QAChC,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE;YACP,GAAG,QAAQ;YACX,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;YACnF,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAC5E,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;YAC1E,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;YACxE,GAAG,SAAS;SACb;KACF;IACD;QACE,GAAG,EAAE,gBAAgB;QACrB,KAAK,EAAE,kBAAkB;QACzB,QAAQ,EAAE,8BAA8B;QACxC,KAAK,EAAE,iBAAiB;QACxB,OAAO,EAAE,CAAC,GAAG,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,SAAS,CAAC;KAC3G;IACD;QACE,GAAG,EAAE,WAAW;QAChB,KAAK,EAAE,eAAe;QACtB,QAAQ,EAAE,yBAAyB;QACnC,KAAK,EAAE,WAAW;QAClB,OAAO,EAAE;YACP,GAAG,QAAQ;YACX,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;YACnF,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YACnE,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAC5E,+CAA+C;YAC/C,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;YAC1E,GAAG,SAAS;SACb;KACF;IACD;QACE,GAAG,EAAE,YAAY;QACjB,KAAK,EAAE,gBAAgB;QACvB,QAAQ,EAAE,0BAA0B;QACpC,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE;YACP,GAAG,QAAQ;YACX,0CAA0C;YAC1C,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAC9D,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAC1E,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;YACjF,GAAG,SAAS;SACb;KACF;IACD;QACE,GAAG,EAAE,oBAAoB;QACzB,KAAK,EAAE,sBAAsB;QAC7B,QAAQ,EAAE,kCAAkC;QAC5C,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE;YACP,GAAG,QAAQ;YACX,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;YACpE,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;YACnF,GAAG,SAAS;SACb;KACF;IACD;QACE,GAAG,EAAE,eAAe;QACpB,KAAK,EAAE,gBAAgB;QACvB,QAAQ,EAAE,6BAA6B;QACvC,KAAK,EAAE,OAAO;QACd,OAAO,EAAE;YACP,GAAG,QAAQ;YACX,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;YAC3E,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAC/D,kCAAkC;YAClC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YACxE,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;YACxE,GAAG,SAAS;SACb;KACF;IACD;QACE,GAAG,EAAE,eAAe;QACpB,KAAK,EAAE,iBAAiB;QACxB,QAAQ,EAAE,6BAA6B;QACvC,KAAK,EAAE,gBAAgB;QACvB,OAAO,EAAE,CAAC,GAAG,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,SAAS,CAAC;KAC3G;IACD;QACE,GAAG,EAAE,oBAAoB;QACzB,KAAK,EAAE,qBAAqB;QAC5B,QAAQ,EAAE,kCAAkC;QAC5C,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE;YACP,GAAG,QAAQ;YACX,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;YACjF,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAC/D,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE;YACxD,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAC5E,GAAG,SAAS;SACb;KACF;IACD;QACE,GAAG,EAAE,qBAAqB;QAC1B,KAAK,EAAE,sBAAsB;QAC7B,QAAQ,EAAE,mCAAmC;QAC7C,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE;YACP,GAAG,QAAQ;YACX,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAChF,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAC5E,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAC/D,GAAG,SAAS;SACb;KACF;IACD;QACE,GAAG,EAAE,qBAAqB;QAC1B,KAAK,EAAE,sBAAsB;QAC7B,QAAQ,EAAE,mCAAmC;QAC7C,KAAK,EAAE,WAAW;QAClB,OAAO,EAAE;YACP,GAAG,QAAQ;YACX,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAC/D,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAC5E,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAC5E,0DAA0D;YAC1D,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YACnE,8BAA8B;YAC9B,EAAE,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;YACrF,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAClE,GAAG,SAAS;SACb;KACF;IACD;QACE,GAAG,EAAE,mBAAmB;QACxB,KAAK,EAAE,oBAAoB;QAC3B,QAAQ,EAAE,iCAAiC;QAC3C,KAAK,EAAE,oBAAoB;QAC3B,OAAO,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC;KACrC;CACF,CAAA;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,CAAA;AACzD,CAAC","sourcesContent":["/**\n * 마스터 열두 축의 **화면 쪽 선언** — 축마다 다른 것만 적는다.\n *\n * ── 왜 화면이 하나인가 ─────────────────────────────────────────────────────\n * 열두 축의 화면이 하는 일이 같다: 목록을 보이고, 그리드에서 고치고, 저장한다. 화면을 열둘 만들면\n * 규칙 하나를 고칠 때 열두 곳을 고쳐야 하고, 한 곳을 빠뜨리면 그 축만 다르게 동작한다.\n *\n * ── 왜 서버의 축 표와 따로 두나 ────────────────────────────────────────────\n * 서버가 아는 것은 「어느 표에서 읽나 · 무엇으로 찾나」이고, 화면이 아는 것은 「어느 칸을 어떤 모양으로\n * 보이나」다. 서로 다른 물음이라 한 표에 담으면 양쪽 다 지저분해진다. 축의 이름(`key`)만 같게 둔다.\n */\n\nexport type ColumnType = 'string' | 'number' | 'boolean' | 'date' | 'json' | 'list'\n\nexport interface AxisColumn {\n name: string\n /** 화면 문구 키. `field.<이것>`. */\n label: string\n type: ColumnType\n width?: number\n /** 고칠 수 없는 칸. 자동으로 붙는 값이 여기 온다. */\n readonly?: boolean\n}\n\nexport interface MasterAxisView {\n key: string\n /** GraphQL 조회 이름 — 서버가 낸 그대로. */\n query: string\n /** GraphQL 저장 이름. */\n mutation: string\n /** 제목 문구 키. `title.<이것>`. */\n title: string\n columns: AxisColumn[]\n}\n\n/** 열두 축이 공통으로 갖는 끝 칸들 — ISA-95 유효 기간. */\nconst EFFECTIVE: AxisColumn[] = [\n { name: 'effectiveStart', label: 'effective-start', type: 'date', width: 150 },\n { name: 'effectiveEnd', label: 'effective-end', type: 'date', width: 150 }\n]\n\n/** 이름과 설명은 열두 축이 모두 갖는다. */\nconst IDENTITY: AxisColumn[] = [\n { name: 'name', label: 'name', type: 'string', width: 160 },\n { name: 'description', label: 'description', type: 'string', width: 200 }\n]\n\nexport const MASTER_AXIS_VIEWS: readonly MasterAxisView[] = [\n {\n key: 'personnelClass',\n query: 'personnelClasses',\n mutation: 'updateMultiplePersonnelClass',\n title: 'personnel-class',\n columns: [\n ...IDENTITY,\n { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 },\n /* 이 등급이 요구하는 검사. 자격 인터록이 이 칸을 읽는다 — 비어 있으면 아무 검사도 요구하지 않는다. */\n { name: 'testSpecificationIds', label: 'required-tests', type: 'list', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'person',\n query: 'persons',\n mutation: 'updateMultiplePerson',\n title: 'person',\n columns: [\n ...IDENTITY,\n { name: 'personnelClassIds', label: 'personnel-classes', type: 'list', width: 200 },\n { name: 'homeLocation', label: 'home-location', type: 'string', width: 140 },\n { name: 'workCalendar', label: 'work-calendar', type: 'json', width: 200 },\n { name: 'testResults', label: 'test-results', type: 'json', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'equipmentClass',\n query: 'equipmentClasses',\n mutation: 'updateMultipleEquipmentClass',\n title: 'equipment-class',\n columns: [...IDENTITY, { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 }, ...EFFECTIVE]\n },\n {\n key: 'equipment',\n query: 'equipmentList',\n mutation: 'updateMultipleEquipment',\n title: 'equipment',\n columns: [\n ...IDENTITY,\n { name: 'equipmentClassIds', label: 'equipment-classes', type: 'list', width: 200 },\n { name: 'identity', label: 'identity', type: 'string', width: 200 },\n { name: 'homeLocation', label: 'home-location', type: 'string', width: 140 },\n /* 계획 조업 시간의 바탕. 비어 있으면 OEE 의 가동률이 「모름」이 된다. */\n { name: 'workCalendar', label: 'work-calendar', type: 'json', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'stopReason',\n query: 'stopReasonList',\n mutation: 'updateMultipleStopReason',\n title: 'stop-reason',\n columns: [\n ...IDENTITY,\n /* 어느 상태의 사유인가. 이 칸이 가동률을 깎느냐 마느냐를 가른다. */\n { name: 'status', label: 'state', type: 'string', width: 130 },\n { name: 'parentName', label: 'parent-reason', type: 'string', width: 150 },\n { name: 'detailRequired', label: 'detail-required', type: 'boolean', width: 110 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'physicalAssetClass',\n query: 'physicalAssetClasses',\n mutation: 'updateMultiplePhysicalAssetClass',\n title: 'asset-class',\n columns: [\n ...IDENTITY,\n { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 },\n { name: 'testSpecificationIds', label: 'required-tests', type: 'list', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'physicalAsset',\n query: 'physicalAssets',\n mutation: 'updateMultiplePhysicalAsset',\n title: 'asset',\n columns: [\n ...IDENTITY,\n { name: 'assetClassIds', label: 'asset-classes', type: 'list', width: 180 },\n { name: 'identity', label: 'grai', type: 'string', width: 200 },\n /* 정격 사용 횟수. 비어 있으면 횟수로 막지 않는다. */\n { name: 'cycleLimit', label: 'cycle-limit', type: 'number', width: 110 },\n { name: 'testResults', label: 'calibrations', type: 'json', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'materialClass',\n query: 'materialClasses',\n mutation: 'updateMultipleMaterialClass',\n title: 'material-class',\n columns: [...IDENTITY, { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 }, ...EFFECTIVE]\n },\n {\n key: 'materialDefinition',\n query: 'materialDefinitions',\n mutation: 'updateMultipleMaterialDefinition',\n title: 'material',\n columns: [\n ...IDENTITY,\n { name: 'materialClassIds', label: 'material-classes', type: 'list', width: 180 },\n { name: 'identity', label: 'gtin', type: 'string', width: 200 },\n { name: 'uom', label: 'uom', type: 'string', width: 90 },\n { name: 'locationType', label: 'location-type', type: 'string', width: 140 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'operationalLocation',\n query: 'operationalLocations',\n mutation: 'updateMultipleOperationalLocation',\n title: 'location',\n columns: [\n ...IDENTITY,\n { name: 'equipmentLevel', label: 'equipment-level', type: 'string', width: 140 },\n { name: 'parentName', label: 'parent-location', type: 'string', width: 150 },\n { name: 'identity', label: 'sgln', type: 'string', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'operationDefinition',\n query: 'operationDefinitions',\n mutation: 'updateMultipleOperationDefinition',\n title: 'operation',\n columns: [\n ...IDENTITY,\n { name: 'intent', label: 'intent', type: 'string', width: 110 },\n { name: 'locationType', label: 'location-type', type: 'string', width: 140 },\n { name: 'resourceType', label: 'resource-type', type: 'string', width: 140 },\n /* 품목당 표준 시간. 없으면 OEE 의 성능률이 「모름」이 된다. ISO 8601 기간 표기다. */\n { name: 'duration', label: 'duration', type: 'string', width: 110 },\n /* 요구 인원. 자격 인터록이 이 칸을 읽는다. */\n { name: 'personnelSpecification', label: 'personnel-spec', type: 'json', width: 200 },\n { name: 'bizStep', label: 'biz-step', type: 'string', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'testSpecification',\n query: 'testSpecifications',\n mutation: 'updateMultipleTestSpecification',\n title: 'test-specification',\n columns: [...IDENTITY, ...EFFECTIVE]\n }\n]\n\nexport function masterAxisViewOf(key: string): MasterAxisView | undefined {\n return MASTER_AXIS_VIEWS.find(axis => axis.key === key)\n}\n"]}
1
+ {"version":3,"file":"master-axes.js","sourceRoot":"","sources":["../../client/pages/master-axes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 마스터 열두 축의 **화면 쪽 선언** — 축마다 다른 것만 적는다.\n *\n * ── 왜 화면이 하나인가 ─────────────────────────────────────────────────────\n * 열두 축의 화면이 하는 일이 같다: 목록을 보이고, 그리드에서 고치고, 저장한다. 화면을 열둘 만들면\n * 규칙 하나를 고칠 때 열두 곳을 고쳐야 하고, 한 곳을 빠뜨리면 그 축만 다르게 동작한다.\n *\n * ── 왜 서버의 축 표와 따로 두나 ────────────────────────────────────────────\n * 서버가 아는 것은 「어느 표에서 읽나 · 무엇으로 찾나」이고, 화면이 아는 것은 「어느 칸을 어떤 모양으로\n * 보이나」다. 서로 다른 물음이라 한 표에 담으면 양쪽 다 지저분해진다. 축의 이름(`key`)만 같게 둔다.\n */\n\nexport type ColumnType = 'string' | 'number' | 'boolean' | 'date' | 'json' | 'list'\n\nexport interface AxisColumn {\n name: string\n /** 화면 문구 키. `field.<이것>`. */\n label: string\n type: ColumnType\n width?: number\n /** 고칠 수 없는 칸. 자동으로 붙는 값이 여기 온다. */\n readonly?: boolean\n}\n\nexport interface MasterAxisView {\n key: string\n /** GraphQL 조회 이름 — 서버가 낸 그대로. */\n query: string\n /** GraphQL 저장 이름. */\n mutation: string\n /** 제목 문구 키. `title.<이것>`. */\n title: string\n columns: AxisColumn[]\n}\n\n/** 열두 축이 공통으로 갖는 끝 칸들 — ISA-95 유효 기간. */\nconst EFFECTIVE: AxisColumn[] = [\n { name: 'effectiveStart', label: 'effective-start', type: 'date', width: 150 },\n { name: 'effectiveEnd', label: 'effective-end', type: 'date', width: 150 }\n]\n\n/** 이름과 설명은 열두 축이 모두 갖는다. */\nconst IDENTITY: AxisColumn[] = [\n { name: 'name', label: 'name', type: 'string', width: 160 },\n { name: 'description', label: 'description', type: 'string', width: 200 }\n]\n\nexport const MASTER_AXIS_VIEWS: readonly MasterAxisView[] = [\n {\n key: 'personnelClass',\n query: 'personnelClasses',\n mutation: 'updateMultiplePersonnelClass',\n title: 'personnel-class',\n columns: [\n ...IDENTITY,\n { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 },\n /* 이 등급이 요구하는 검사. 자격 인터록이 이 칸을 읽는다 — 비어 있으면 아무 검사도 요구하지 않는다. */\n { name: 'testSpecificationIds', label: 'required-tests', type: 'list', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'person',\n query: 'persons',\n mutation: 'updateMultiplePerson',\n title: 'person',\n columns: [\n ...IDENTITY,\n { name: 'personnelClassIds', label: 'personnel-classes', type: 'list', width: 200 },\n { name: 'homeLocation', label: 'home-location', type: 'string', width: 140 },\n { name: 'workCalendar', label: 'work-calendar', type: 'json', width: 200 },\n { name: 'testResults', label: 'test-results', type: 'json', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'equipmentClass',\n query: 'equipmentClasses',\n mutation: 'updateMultipleEquipmentClass',\n title: 'equipment-class',\n columns: [...IDENTITY, { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 }, ...EFFECTIVE]\n },\n {\n key: 'equipment',\n query: 'equipmentList',\n mutation: 'updateMultipleEquipment',\n title: 'equipment',\n columns: [\n ...IDENTITY,\n /*\n * 설비의 등급은 **하나**이고 이름이 `kind` 다(표준 EquipmentClassID · 계약의 kind 자리).\n * 전에는 `equipmentClassIds` 라는 배열 칸을 물었는데 그런 칸이 없다. GraphQL 은 칸 하나가\n * 틀리면 질의를 통째로 오류로 내므로, 설비 마스터 화면이 전부 400 이었다.\n */\n { name: 'kind', label: 'equipment-class', type: 'string', width: 200 },\n { name: 'identity', label: 'identity', type: 'string', width: 200 },\n { name: 'homeLocation', label: 'home-location', type: 'string', width: 140 },\n /* 계획 조업 시간의 바탕. 비어 있으면 OEE 의 가동률이 「모름」이 된다. */\n { name: 'workCalendar', label: 'work-calendar', type: 'json', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'stopReason',\n query: 'stopReasonList',\n mutation: 'updateMultipleStopReason',\n title: 'stop-reason',\n columns: [\n ...IDENTITY,\n /* 어느 상태의 사유인가. 이 칸이 가동률을 깎느냐 마느냐를 가른다. */\n { name: 'status', label: 'state', type: 'string', width: 130 },\n { name: 'parentName', label: 'parent-reason', type: 'string', width: 150 },\n { name: 'detailRequired', label: 'detail-required', type: 'boolean', width: 110 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'physicalAssetClass',\n query: 'physicalAssetClasses',\n mutation: 'updateMultiplePhysicalAssetClass',\n title: 'asset-class',\n columns: [\n ...IDENTITY,\n { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 },\n { name: 'testSpecificationIds', label: 'required-tests', type: 'list', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'physicalAsset',\n query: 'physicalAssets',\n mutation: 'updateMultiplePhysicalAsset',\n title: 'asset',\n columns: [\n ...IDENTITY,\n { name: 'assetClassIds', label: 'asset-classes', type: 'list', width: 180 },\n { name: 'identity', label: 'grai', type: 'string', width: 200 },\n /* 정격 사용 횟수. 비어 있으면 횟수로 막지 않는다. */\n { name: 'cycleLimit', label: 'cycle-limit', type: 'number', width: 110 },\n { name: 'testResults', label: 'calibrations', type: 'json', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'materialClass',\n query: 'materialClasses',\n mutation: 'updateMultipleMaterialClass',\n title: 'material-class',\n columns: [...IDENTITY, { name: 'baseIds', label: 'base-classes', type: 'list', width: 180 }, ...EFFECTIVE]\n },\n {\n key: 'materialDefinition',\n query: 'materialDefinitions',\n mutation: 'updateMultipleMaterialDefinition',\n title: 'material',\n columns: [\n ...IDENTITY,\n { name: 'materialClassIds', label: 'material-classes', type: 'list', width: 180 },\n /*\n * GTIN · 단위 · 보관처는 **API 가 내주지 않는다.** 전에는 `identity`·`uom`·`locationType` 을\n * 물었는데 `MaterialDefinition` 에 그런 칸이 없다. GraphQL 은 칸 하나가 틀리면 질의를 통째로\n * 오류로 내므로, 자재 마스터 화면이 전부 400 이었다.\n *\n * 그 값들이 어디에 사는지 모르는 채로 다른 칸을 대신 물지 않는다. 지금은 `properties` 로\n * 있는 그대로 보이고, 제 칸이 생기면 그때 나눈다.\n */\n { name: 'properties', label: 'properties', type: 'json', width: 240 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'operationalLocation',\n query: 'operationalLocations',\n mutation: 'updateMultipleOperationalLocation',\n title: 'location',\n columns: [\n ...IDENTITY,\n /* 스키마의 이름은 `level`·`parentId` 다. 전에는 `equipmentLevel`·`parentName` 을 물어 화면이 400 이었다. */\n { name: 'level', label: 'equipment-level', type: 'string', width: 140 },\n { name: 'parentId', label: 'parent-location', type: 'string', width: 150 },\n { name: 'type', label: 'location-type', type: 'string', width: 140 },\n { name: 'capacity', label: 'capacity', type: 'number', width: 90 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'operationDefinition',\n query: 'operationDefinitions',\n mutation: 'updateMultipleOperationDefinition',\n title: 'operation',\n columns: [\n ...IDENTITY,\n { name: 'intent', label: 'intent', type: 'string', width: 110 },\n { name: 'locationType', label: 'location-type', type: 'string', width: 140 },\n { name: 'resourceType', label: 'resource-type', type: 'string', width: 140 },\n /* 품목당 표준 시간. 없으면 OEE 의 성능률이 「모름」이 된다. ISO 8601 기간 표기다. */\n { name: 'duration', label: 'duration', type: 'string', width: 110 },\n /* 요구 인원. 자격 인터록이 이 칸을 읽는다. */\n { name: 'personnelSpecification', label: 'personnel-spec', type: 'json', width: 200 },\n { name: 'bizStep', label: 'biz-step', type: 'string', width: 200 },\n ...EFFECTIVE\n ]\n },\n {\n key: 'testSpecification',\n query: 'testSpecifications',\n mutation: 'updateMultipleTestSpecification',\n title: 'test-specification',\n columns: [...IDENTITY, ...EFFECTIVE]\n }\n]\n\nexport function masterAxisViewOf(key: string): MasterAxisView | undefined {\n return MASTER_AXIS_VIEWS.find(axis => axis.key === key)\n}\n"]}
@@ -31,8 +31,6 @@ export declare class OpsMasterList extends OpsMasterList_base {
31
31
  gristConfig: any;
32
32
  mode: 'CARD' | 'LIST' | 'GRID';
33
33
  private axis?;
34
- private total?;
35
- private loaded;
36
34
  private grist;
37
35
  get context(): {
38
36
  title: string;
@@ -47,6 +45,9 @@ export declare class OpsMasterList extends OpsMasterList_base {
47
45
  title: string;
48
46
  action: () => Promise<void>;
49
47
  icon: string;
48
+ emphasis: {
49
+ raised: boolean;
50
+ };
50
51
  }[];
51
52
  exportable: {
52
53
  name: string;
@@ -54,7 +55,6 @@ export declare class OpsMasterList extends OpsMasterList_base {
54
55
  };
55
56
  };
56
57
  render(): import("lit-html").TemplateResult<1>;
57
- private scaleNotice;
58
58
  /** 주소가 바뀌면 축이 바뀐다. 셸이 이 훅으로 알려 준다. */
59
59
  pageUpdated(changes: any, lifecycle: any): Promise<void>;
60
60
  private configOf;
@@ -35,7 +35,6 @@ let OpsMasterList = class OpsMasterList extends p13n(localize(i18next)(PageView)
35
35
  super(...arguments);
36
36
  this.active = false;
37
37
  this.mode = isMobileDevice() ? 'CARD' : 'GRID';
38
- this.loaded = 0;
39
38
  }
40
39
  static { this.styles = [
41
40
  CommonGristStyles,
@@ -53,14 +52,12 @@ let OpsMasterList = class OpsMasterList extends p13n(localize(i18next)(PageView)
53
52
  flex: 1;
54
53
  }
55
54
 
56
- .scale {
57
- padding: var(--spacing-small) var(--spacing-large);
58
- color: var(--md-sys-color-on-surface-variant);
59
- font-size: 0.85rem;
60
- }
61
-
62
- .scale[data-capped] {
63
- color: var(--status-warning-color);
55
+ /* 축을 못 찾았을 때의 한 줄. 빈 목록과 구별되어야 하므로 그리드 대신 이것만 그린다. */
56
+ .notice {
57
+ padding: 18px;
58
+ color: var(--ui-muted);
59
+ font-size: var(--ui-t-body);
60
+ word-break: keep-all;
64
61
  }
65
62
  `
66
63
  ]; }
@@ -82,7 +79,9 @@ let OpsMasterList = class OpsMasterList extends p13n(localize(i18next)(PageView)
82
79
  {
83
80
  title: i18next.t('button.save'),
84
81
  action: this.save.bind(this),
85
- icon: 'save'
82
+ icon: 'save',
83
+ /* 이 화면의 주 동작 — 채운 버튼으로 그려진다. 한 화면에 하나만 둔다. */
84
+ emphasis: { raised: true }
86
85
  }
87
86
  ],
88
87
  exportable: {
@@ -94,7 +93,7 @@ let OpsMasterList = class OpsMasterList extends p13n(localize(i18next)(PageView)
94
93
  render() {
95
94
  if (!this.axis) {
96
95
  /* 어느 축인지 모르면 빈 그리드를 보이지 않는다 — 빈 목록과 「축을 못 찾았다」가 구별되지 않는다. */
97
- return html `<div class="scale">${i18next.t('text.master-axis-unknown')}</div>`;
96
+ return html `<div class="notice">${i18next.t('text.master-axis-unknown')}</div>`;
98
97
  }
99
98
  return html `
100
99
  <ox-grist .mode=${this.mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>
@@ -103,21 +102,6 @@ let OpsMasterList = class OpsMasterList extends p13n(localize(i18next)(PageView)
103
102
  <ox-context-page-toolbar class="actions" .context=${this.context}></ox-context-page-toolbar>
104
103
  </div>
105
104
  </ox-grist>
106
-
107
- ${this.scaleNotice()}
108
- `;
109
- }
110
- scaleNotice() {
111
- if (this.total === undefined) {
112
- return html `<div class="scale">${i18next.t('text.loaded-count', { loaded: this.loaded })}</div>`;
113
- }
114
- const capped = this.loaded < this.total;
115
- return html `
116
- <div class="scale" ?data-capped=${capped}>
117
- ${capped
118
- ? i18next.t('text.loaded-of-total-more', { loaded: this.loaded, total: this.total })
119
- : i18next.t('text.loaded-of-total', { loaded: this.loaded, total: this.total })}
120
- </div>
121
105
  `;
122
106
  }
123
107
  /** 주소가 바뀌면 축이 바뀐다. 셸이 이 훅으로 알려 준다. */
@@ -128,8 +112,6 @@ let OpsMasterList = class OpsMasterList extends p13n(localize(i18next)(PageView)
128
112
  return;
129
113
  }
130
114
  this.axis = axis;
131
- this.total = undefined;
132
- this.loaded = 0;
133
115
  if (axis) {
134
116
  this.gristConfig = this.configOf(axis);
135
117
  await this.updateComplete;
@@ -201,8 +183,6 @@ let OpsMasterList = class OpsMasterList extends p13n(localize(i18next)(PageView)
201
183
  const payload = response.data?.[this.axis.query];
202
184
  const items = payload?.items ?? [];
203
185
  const total = payload?.total;
204
- this.loaded = items.length;
205
- this.total = typeof total === 'number' ? total : undefined;
206
186
  return { total: total ?? 0, records: items };
207
187
  }
208
188
  async save() {
@@ -248,14 +228,6 @@ __decorate([
248
228
  state(),
249
229
  __metadata("design:type", Object)
250
230
  ], OpsMasterList.prototype, "axis", void 0);
251
- __decorate([
252
- state(),
253
- __metadata("design:type", Number)
254
- ], OpsMasterList.prototype, "total", void 0);
255
- __decorate([
256
- state(),
257
- __metadata("design:type", Object)
258
- ], OpsMasterList.prototype, "loaded", void 0);
259
231
  __decorate([
260
232
  query('ox-grist'),
261
233
  __metadata("design:type", DataGrist)
@@ -1 +1 @@
1
- {"version":3,"file":"master-list.js","sourceRoot":"","sources":["../../client/pages/master-list.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport '@operato/data-grist/ox-grist.js'\nimport '@operato/data-grist/ox-filters-form.js'\nimport '@operato/context/ox-context-page-toolbar.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { notify } from '@operato/layout'\nimport { p13n } from '@operato/p13n'\nimport { PageView } from '@operato/shell'\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\n\nimport { AxisColumn, MASTER_AXIS_VIEWS, MasterAxisView, masterAxisViewOf } from './master-axes'\n\n/**\n * 마스터 화면 하나가 **열두 축을 다 맡는다.**\n *\n * 축은 주소의 질의로 받는다(`ops-master-list?axis=person`). 메뉴가 축마다 한 줄씩 걸고, 화면은 그\n * 하나다 — 규칙을 고칠 때 한 곳만 고치면 열두 축이 함께 바뀐다.\n *\n * ── 마스터는 그리드에서 고친다 ─────────────────────────────────────────────\n * 업무 기록(실적 · 검사 · 처분)은 조회 전용이다. 일어난 일을 나중에 고치면 「그때 무엇이 있었나」가\n * 사라진다. 마스터는 **선언**이라 다르다 — 지금의 규정이 무엇인지가 답이고, 규정은 바뀐다.\n *\n * ── 없앨 때 지우지 않는다 ──────────────────────────────────────────────────\n * 지운 행은 서버가 유효 기간의 끝을 채워 오늘부터 유효하지 않게 만든다. 실제로 지우면 그것을 가리키던\n * 지난 실적이 가리킬 것을 잃는다. 화면은 그 사실을 말해 준다 — 지운 줄 알았는데 목록에 남아 있으면\n * 사용자가 저장이 안 된 것으로 읽는다.\n */\n@customElement('ops-master-list')\nexport class OpsMasterList extends p13n(localize(i18next)(PageView)) {\n static styles = [\n CommonGristStyles,\n CommonHeaderStyles,\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n ox-grist {\n overflow-y: auto;\n flex: 1;\n }\n\n .scale {\n padding: var(--spacing-small) var(--spacing-large);\n color: var(--md-sys-color-on-surface-variant);\n font-size: 0.85rem;\n }\n\n .scale[data-capped] {\n color: var(--status-warning-color);\n }\n `\n ]\n\n @property({ type: Boolean }) active: boolean = false\n @property({ type: Object }) gristConfig: any\n @property({ type: String }) mode: 'CARD' | 'LIST' | 'GRID' = isMobileDevice() ? 'CARD' : 'GRID'\n\n @state() private axis?: MasterAxisView\n @state() private total?: number\n @state() private loaded = 0\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n title: this.axis ? i18next.t(`title.${this.axis.title}`) : i18next.t('title.master'),\n search: {\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n filter: {\n handler: () => {\n this.grist.toggleHeadroom()\n }\n },\n actions: [\n {\n title: i18next.t('button.save'),\n action: this.save.bind(this),\n icon: 'save'\n }\n ],\n exportable: {\n name: this.axis ? i18next.t(`title.${this.axis.title}`) : i18next.t('title.master'),\n data: () => this.grist.exportRecords()\n }\n }\n }\n\n render() {\n if (!this.axis) {\n /* 어느 축인지 모르면 빈 그리드를 보이지 않는다 — 빈 목록과 「축을 못 찾았다」가 구별되지 않는다. */\n return html`<div class=\"scale\">${i18next.t('text.master-axis-unknown')}</div>`\n }\n\n return html`\n <ox-grist .mode=${this.mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>\n <div slot=\"headroom\" class=\"header\">\n <div class=\"title\">${i18next.t(`title.${this.axis.title}`)}</div>\n <ox-context-page-toolbar class=\"actions\" .context=${this.context}></ox-context-page-toolbar>\n </div>\n </ox-grist>\n\n ${this.scaleNotice()}\n `\n }\n\n private scaleNotice() {\n if (this.total === undefined) {\n return html`<div class=\"scale\">${i18next.t('text.loaded-count', { loaded: this.loaded })}</div>`\n }\n\n const capped = this.loaded < this.total\n\n return html`\n <div class=\"scale\" ?data-capped=${capped}>\n ${capped\n ? i18next.t('text.loaded-of-total-more', { loaded: this.loaded, total: this.total })\n : i18next.t('text.loaded-of-total', { loaded: this.loaded, total: this.total })}\n </div>\n `\n }\n\n /** 주소가 바뀌면 축이 바뀐다. 셸이 이 훅으로 알려 준다. */\n async pageUpdated(changes: any, lifecycle: any) {\n const key = new URLSearchParams(lifecycle?.params ?? location.search).get('axis') ?? MASTER_AXIS_VIEWS[0].key\n const axis = masterAxisViewOf(key)\n\n if (axis?.key === this.axis?.key) {\n return\n }\n\n this.axis = axis\n this.total = undefined\n this.loaded = 0\n\n if (axis) {\n this.gristConfig = this.configOf(axis)\n await this.updateComplete\n this.grist?.fetch()\n }\n }\n\n private configOf(axis: MasterAxisView) {\n return {\n list: { fields: ['name', 'description'], details: [] },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'gutter', gutterName: 'row-selector', multiple: true },\n ...axis.columns.map(column => this.columnOf(column))\n ],\n /* 새 행을 만들 수 있다 — 마스터를 채우는 것이 이 화면의 일이다. */\n rows: { appendable: true, selectable: { multiple: true } },\n sorters: [{ name: 'name', desc: false }]\n }\n }\n\n private columnOf(column: AxisColumn) {\n const header = i18next.t(`field.${column.label}`)\n const editable = !column.readonly\n\n switch (column.type) {\n case 'number':\n return { type: 'float', name: column.name, header, record: { editable }, sortable: true, width: column.width }\n case 'boolean':\n return { type: 'boolean', name: column.name, header, record: { editable }, width: column.width }\n case 'date':\n return { type: 'datetime', name: column.name, header, record: { editable }, sortable: true, width: column.width }\n /*\n * 목록과 JSON 은 **글자로 고친다.** 전용 편집기를 만들면 축마다 다른 편집기가 생기고, 그 편집기가\n * 모르는 칸이 들어오면 값이 오류 보고 없이 사라진다. 지금은 있는 그대로 보이고 그대로 고친다.\n */\n case 'list':\n case 'json':\n return { type: 'string', name: column.name, header, record: { editable }, width: column.width }\n default:\n return {\n type: 'string',\n name: column.name,\n header,\n record: { editable },\n filter: 'search',\n sortable: true,\n width: column.width\n }\n }\n }\n\n async fetchHandler({ page = 1, limit = 50, sortings = [], filters = [] }: FetchOption) {\n if (!this.axis) {\n return { total: 0, records: [] }\n }\n\n const fields = this.axis.columns.map(column => column.name).join('\\n')\n\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n ${this.axis.query}(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n ${fields}\n }\n total\n }\n }\n `,\n variables: { filters, pagination: { page, limit }, sortings },\n fetchPolicy: 'no-cache'\n })\n\n const payload = response.data?.[this.axis.query]\n const items = payload?.items ?? []\n const total = payload?.total\n\n this.loaded = items.length\n this.total = typeof total === 'number' ? total : undefined\n\n return { total: total ?? 0, records: items }\n }\n\n private async save() {\n if (!this.axis) {\n return\n }\n\n const patches = this.grist.dirtyRecords\n\n if (!patches?.length) {\n notify({ message: i18next.t('text.nothing-changed'), level: 'info' })\n return\n }\n\n await client.mutate({\n mutation: gql`\n mutation ($patches: [ScalarObject!]!) {\n ${this.axis.mutation}(patches: $patches) {\n id\n name\n }\n }\n `,\n variables: { patches }\n })\n\n /* 지운 행은 사라지지 않고 유효 기간의 끝이 채워진다. 말해 주지 않으면 저장이 안 된 것으로 읽는다. */\n if (patches.some((patch: any) => String(patch.cuFlag).toUpperCase() === '-')) {\n notify({ message: i18next.t('text.retired-not-deleted'), level: 'info' })\n }\n\n this.grist.fetch()\n }\n}\n"]}
1
+ {"version":3,"file":"master-list.js","sourceRoot":"","sources":["../../client/pages/master-list.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport '@operato/data-grist/ox-grist.js'\nimport '@operato/data-grist/ox-filters-form.js'\nimport '@operato/context/ox-context-page-toolbar.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { notify } from '@operato/layout'\nimport { p13n } from '@operato/p13n'\nimport { PageView } from '@operato/shell'\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\n\nimport { AxisColumn, MASTER_AXIS_VIEWS, MasterAxisView, masterAxisViewOf } from './master-axes'\n\n/**\n * 마스터 화면 하나가 **열두 축을 다 맡는다.**\n *\n * 축은 주소의 질의로 받는다(`ops-master-list?axis=person`). 메뉴가 축마다 한 줄씩 걸고, 화면은 그\n * 하나다 — 규칙을 고칠 때 한 곳만 고치면 열두 축이 함께 바뀐다.\n *\n * ── 마스터는 그리드에서 고친다 ─────────────────────────────────────────────\n * 업무 기록(실적 · 검사 · 처분)은 조회 전용이다. 일어난 일을 나중에 고치면 「그때 무엇이 있었나」가\n * 사라진다. 마스터는 **선언**이라 다르다 — 지금의 규정이 무엇인지가 답이고, 규정은 바뀐다.\n *\n * ── 없앨 때 지우지 않는다 ──────────────────────────────────────────────────\n * 지운 행은 서버가 유효 기간의 끝을 채워 오늘부터 유효하지 않게 만든다. 실제로 지우면 그것을 가리키던\n * 지난 실적이 가리킬 것을 잃는다. 화면은 그 사실을 말해 준다 — 지운 줄 알았는데 목록에 남아 있으면\n * 사용자가 저장이 안 된 것으로 읽는다.\n */\n@customElement('ops-master-list')\nexport class OpsMasterList extends p13n(localize(i18next)(PageView)) {\n static styles = [\n CommonGristStyles,\n CommonHeaderStyles,\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n ox-grist {\n overflow-y: auto;\n flex: 1;\n }\n\n /* 축을 못 찾았을 때의 한 줄. 빈 목록과 구별되어야 하므로 그리드 대신 이것만 그린다. */\n .notice {\n padding: 18px;\n color: var(--ui-muted);\n font-size: var(--ui-t-body);\n word-break: keep-all;\n }\n `\n ]\n\n @property({ type: Boolean }) active: boolean = false\n @property({ type: Object }) gristConfig: any\n @property({ type: String }) mode: 'CARD' | 'LIST' | 'GRID' = isMobileDevice() ? 'CARD' : 'GRID'\n\n @state() private axis?: MasterAxisView\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n title: this.axis ? i18next.t(`title.${this.axis.title}`) : i18next.t('title.master'),\n search: {\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n filter: {\n handler: () => {\n this.grist.toggleHeadroom()\n }\n },\n actions: [\n {\n title: i18next.t('button.save'),\n action: this.save.bind(this),\n icon: 'save',\n /* 이 화면의 주 동작 — 채운 버튼으로 그려진다. 한 화면에 하나만 둔다. */\n emphasis: { raised: true }\n }\n ],\n exportable: {\n name: this.axis ? i18next.t(`title.${this.axis.title}`) : i18next.t('title.master'),\n data: () => this.grist.exportRecords()\n }\n }\n }\n\n render() {\n if (!this.axis) {\n /* 어느 축인지 모르면 빈 그리드를 보이지 않는다 — 빈 목록과 「축을 못 찾았다」가 구별되지 않는다. */\n return html`<div class=\"notice\">${i18next.t('text.master-axis-unknown')}</div>`\n }\n\n return html`\n <ox-grist .mode=${this.mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>\n <div slot=\"headroom\" class=\"header\">\n <div class=\"title\">${i18next.t(`title.${this.axis.title}`)}</div>\n <ox-context-page-toolbar class=\"actions\" .context=${this.context}></ox-context-page-toolbar>\n </div>\n </ox-grist>\n `\n }\n\n /** 주소가 바뀌면 축이 바뀐다. 셸이 이 훅으로 알려 준다. */\n async pageUpdated(changes: any, lifecycle: any) {\n const key = new URLSearchParams(lifecycle?.params ?? location.search).get('axis') ?? MASTER_AXIS_VIEWS[0].key\n const axis = masterAxisViewOf(key)\n\n if (axis?.key === this.axis?.key) {\n return\n }\n\n this.axis = axis\n\n if (axis) {\n this.gristConfig = this.configOf(axis)\n await this.updateComplete\n this.grist?.fetch()\n }\n }\n\n private configOf(axis: MasterAxisView) {\n return {\n list: { fields: ['name', 'description'], details: [] },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'gutter', gutterName: 'row-selector', multiple: true },\n ...axis.columns.map(column => this.columnOf(column))\n ],\n /* 새 행을 만들 수 있다 — 마스터를 채우는 것이 이 화면의 일이다. */\n rows: { appendable: true, selectable: { multiple: true } },\n sorters: [{ name: 'name', desc: false }]\n }\n }\n\n private columnOf(column: AxisColumn) {\n const header = i18next.t(`field.${column.label}`)\n const editable = !column.readonly\n\n switch (column.type) {\n case 'number':\n return { type: 'float', name: column.name, header, record: { editable }, sortable: true, width: column.width }\n case 'boolean':\n return { type: 'boolean', name: column.name, header, record: { editable }, width: column.width }\n case 'date':\n return { type: 'datetime', name: column.name, header, record: { editable }, sortable: true, width: column.width }\n /*\n * 목록과 JSON 은 **글자로 고친다.** 전용 편집기를 만들면 축마다 다른 편집기가 생기고, 그 편집기가\n * 모르는 칸이 들어오면 값이 오류 보고 없이 사라진다. 지금은 있는 그대로 보이고 그대로 고친다.\n */\n case 'list':\n case 'json':\n return { type: 'string', name: column.name, header, record: { editable }, width: column.width }\n default:\n return {\n type: 'string',\n name: column.name,\n header,\n record: { editable },\n filter: 'search',\n sortable: true,\n width: column.width\n }\n }\n }\n\n async fetchHandler({ page = 1, limit = 50, sortings = [], filters = [] }: FetchOption) {\n if (!this.axis) {\n return { total: 0, records: [] }\n }\n\n const fields = this.axis.columns.map(column => column.name).join('\\n')\n\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n ${this.axis.query}(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n ${fields}\n }\n total\n }\n }\n `,\n variables: { filters, pagination: { page, limit }, sortings },\n fetchPolicy: 'no-cache'\n })\n\n const payload = response.data?.[this.axis.query]\n const items = payload?.items ?? []\n const total = payload?.total\n\n return { total: total ?? 0, records: items }\n }\n\n private async save() {\n if (!this.axis) {\n return\n }\n\n const patches = this.grist.dirtyRecords\n\n if (!patches?.length) {\n notify({ message: i18next.t('text.nothing-changed'), level: 'info' })\n return\n }\n\n await client.mutate({\n mutation: gql`\n mutation ($patches: [ScalarObject!]!) {\n ${this.axis.mutation}(patches: $patches) {\n id\n name\n }\n }\n `,\n variables: { patches }\n })\n\n /* 지운 행은 사라지지 않고 유효 기간의 끝이 채워진다. 말해 주지 않으면 저장이 안 된 것으로 읽는다. */\n if (patches.some((patch: any) => String(patch.cuFlag).toUpperCase() === '-')) {\n notify({ message: i18next.t('text.retired-not-deleted'), level: 'info' })\n }\n\n this.grist.fetch()\n }\n}\n"]}