@things-factory/kpi 10.1.248 → 10.1.249

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 (409) hide show
  1. package/dist-client/bootstrap.d.ts +2 -0
  2. package/dist-client/bootstrap.js +7 -0
  3. package/dist-client/bootstrap.js.map +1 -0
  4. package/dist-client/charts/kpi-boxplot-chart.d.ts +24 -0
  5. package/dist-client/charts/kpi-boxplot-chart.js +324 -0
  6. package/dist-client/charts/kpi-boxplot-chart.js.map +1 -0
  7. package/dist-client/charts/kpi-mini-trend-chart.d.ts +14 -0
  8. package/dist-client/charts/kpi-mini-trend-chart.js +148 -0
  9. package/dist-client/charts/kpi-mini-trend-chart.js.map +1 -0
  10. package/dist-client/charts/kpi-radar-chart.d.ts +16 -0
  11. package/dist-client/charts/kpi-radar-chart.js +138 -0
  12. package/dist-client/charts/kpi-radar-chart.js.map +1 -0
  13. package/dist-client/charts/kpi-trend-chart.d.ts +25 -0
  14. package/dist-client/charts/kpi-trend-chart.js +186 -0
  15. package/dist-client/charts/kpi-trend-chart.js.map +1 -0
  16. package/dist-client/google-map/common-google-map.d.ts +34 -0
  17. package/dist-client/google-map/common-google-map.js +333 -0
  18. package/dist-client/google-map/common-google-map.js.map +1 -0
  19. package/dist-client/google-map/google-map-loader.d.ts +8 -0
  20. package/dist-client/google-map/google-map-loader.js +22 -0
  21. package/dist-client/google-map/google-map-loader.js.map +1 -0
  22. package/dist-client/index.d.ts +1 -0
  23. package/dist-client/index.js +2 -0
  24. package/dist-client/index.js.map +1 -0
  25. package/dist-client/pages/kpi/kpi-grade-editor.d.ts +35 -0
  26. package/dist-client/pages/kpi/kpi-grade-editor.js +165 -0
  27. package/dist-client/pages/kpi/kpi-grade-editor.js.map +1 -0
  28. package/dist-client/pages/kpi/kpi-importer.d.ts +23 -0
  29. package/dist-client/pages/kpi/kpi-importer.js +92 -0
  30. package/dist-client/pages/kpi/kpi-importer.js.map +1 -0
  31. package/dist-client/pages/kpi/kpi-list-page.d.ts +136 -0
  32. package/dist-client/pages/kpi/kpi-list-page.js +948 -0
  33. package/dist-client/pages/kpi/kpi-list-page.js.map +1 -0
  34. package/dist-client/pages/kpi/kpi-overview-sample.d.ts +36 -0
  35. package/dist-client/pages/kpi/kpi-overview-sample.js +264 -0
  36. package/dist-client/pages/kpi/kpi-overview-sample.js.map +1 -0
  37. package/dist-client/pages/kpi/kpi-overview.d.ts +14 -0
  38. package/dist-client/pages/kpi/kpi-overview.js +361 -0
  39. package/dist-client/pages/kpi/kpi-overview.js.map +1 -0
  40. package/dist-client/pages/kpi/kpi-tree-page.d.ts +51 -0
  41. package/dist-client/pages/kpi/kpi-tree-page.js +355 -0
  42. package/dist-client/pages/kpi/kpi-tree-page.js.map +1 -0
  43. package/dist-client/pages/kpi/kpi-view.d.ts +12 -0
  44. package/dist-client/pages/kpi/kpi-view.js +193 -0
  45. package/dist-client/pages/kpi/kpi-view.js.map +1 -0
  46. package/dist-client/pages/kpi/kpi-viz-editor.d.ts +19 -0
  47. package/dist-client/pages/kpi/kpi-viz-editor.js +562 -0
  48. package/dist-client/pages/kpi/kpi-viz-editor.js.map +1 -0
  49. package/dist-client/pages/kpi-dashboard/cards/kpi-level1-card.d.ts +17 -0
  50. package/dist-client/pages/kpi-dashboard/cards/kpi-level1-card.js +279 -0
  51. package/dist-client/pages/kpi-dashboard/cards/kpi-level1-card.js.map +1 -0
  52. package/dist-client/pages/kpi-dashboard/cards/kpi-level2-comparison.d.ts +19 -0
  53. package/dist-client/pages/kpi-dashboard/cards/kpi-level2-comparison.js +385 -0
  54. package/dist-client/pages/kpi-dashboard/cards/kpi-level2-comparison.js.map +1 -0
  55. package/dist-client/pages/kpi-dashboard/cards/kpi-level3-comparison.d.ts +23 -0
  56. package/dist-client/pages/kpi-dashboard/cards/kpi-level3-comparison.js +465 -0
  57. package/dist-client/pages/kpi-dashboard/cards/kpi-level3-comparison.js.map +1 -0
  58. package/dist-client/pages/kpi-dashboard/components/kpi-chart-toggle.d.ts +8 -0
  59. package/dist-client/pages/kpi-dashboard/components/kpi-chart-toggle.js +78 -0
  60. package/dist-client/pages/kpi-dashboard/components/kpi-chart-toggle.js.map +1 -0
  61. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.d.ts +24 -0
  62. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js +440 -0
  63. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js.map +1 -0
  64. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.d.ts +33 -0
  65. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js +444 -0
  66. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js.map +1 -0
  67. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.d.ts +23 -0
  68. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js +369 -0
  69. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js.map +1 -0
  70. package/dist-client/pages/kpi-dashboard/kpi-alert-panel.d.ts +18 -0
  71. package/dist-client/pages/kpi-dashboard/kpi-alert-panel.js +128 -0
  72. package/dist-client/pages/kpi-dashboard/kpi-alert-panel.js.map +1 -0
  73. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.d.ts +31 -0
  74. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js +493 -0
  75. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js.map +1 -0
  76. package/dist-client/pages/kpi-dashboard/kpi-dashboard.d.ts +50 -0
  77. package/dist-client/pages/kpi-dashboard/kpi-dashboard.js +884 -0
  78. package/dist-client/pages/kpi-dashboard/kpi-dashboard.js.map +1 -0
  79. package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.d.ts +12 -0
  80. package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.js +82 -0
  81. package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.js.map +1 -0
  82. package/dist-client/pages/kpi-dashboard/kpi-history-viewer.d.ts +11 -0
  83. package/dist-client/pages/kpi-dashboard/kpi-history-viewer.js +65 -0
  84. package/dist-client/pages/kpi-dashboard/kpi-history-viewer.js.map +1 -0
  85. package/dist-client/pages/kpi-dashboard/kpi-list-summary.d.ts +13 -0
  86. package/dist-client/pages/kpi-dashboard/kpi-list-summary.js +115 -0
  87. package/dist-client/pages/kpi-dashboard/kpi-list-summary.js.map +1 -0
  88. package/dist-client/pages/kpi-dashboard/kpi-performance-summary.d.ts +15 -0
  89. package/dist-client/pages/kpi-dashboard/kpi-performance-summary.js +146 -0
  90. package/dist-client/pages/kpi-dashboard/kpi-performance-summary.js.map +1 -0
  91. package/dist-client/pages/kpi-dashboard/kpi-value-entry.d.ts +7 -0
  92. package/dist-client/pages/kpi-dashboard/kpi-value-entry.js +86 -0
  93. package/dist-client/pages/kpi-dashboard/kpi-value-entry.js.map +1 -0
  94. package/dist-client/pages/kpi-history/kpi-history-list-page.d.ts +21 -0
  95. package/dist-client/pages/kpi-history/kpi-history-list-page.js +160 -0
  96. package/dist-client/pages/kpi-history/kpi-history-list-page.js.map +1 -0
  97. package/dist-client/pages/kpi-metric/kpi-metric-importer.d.ts +23 -0
  98. package/dist-client/pages/kpi-metric/kpi-metric-importer.js +92 -0
  99. package/dist-client/pages/kpi-metric/kpi-metric-importer.js.map +1 -0
  100. package/dist-client/pages/kpi-metric/kpi-metric-list-page.d.ts +65 -0
  101. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js +415 -0
  102. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js.map +1 -0
  103. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.d.ts +52 -0
  104. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js +678 -0
  105. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js.map +1 -0
  106. package/dist-client/pages/kpi-metric-value/kpi-metric-value-importer.d.ts +23 -0
  107. package/dist-client/pages/kpi-metric-value/kpi-metric-value-importer.js +75 -0
  108. package/dist-client/pages/kpi-metric-value/kpi-metric-value-importer.js.map +1 -0
  109. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +64 -0
  110. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +311 -0
  111. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -0
  112. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.d.ts +12 -0
  113. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js +175 -0
  114. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js.map +1 -0
  115. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.d.ts +35 -0
  116. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js +161 -0
  117. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js.map +1 -0
  118. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.d.ts +47 -0
  119. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js +655 -0
  120. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js.map +1 -0
  121. package/dist-client/pages/kpi-statistic/kpi-statistic-importer.d.ts +23 -0
  122. package/dist-client/pages/kpi-statistic/kpi-statistic-importer.js +92 -0
  123. package/dist-client/pages/kpi-statistic/kpi-statistic-importer.js.map +1 -0
  124. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.d.ts +65 -0
  125. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js +416 -0
  126. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js.map +1 -0
  127. package/dist-client/pages/kpi-value/kpi-value-editor-page.d.ts +50 -0
  128. package/dist-client/pages/kpi-value/kpi-value-editor-page.js +700 -0
  129. package/dist-client/pages/kpi-value/kpi-value-editor-page.js.map +1 -0
  130. package/dist-client/pages/kpi-value/kpi-value-importer.d.ts +23 -0
  131. package/dist-client/pages/kpi-value/kpi-value-importer.js +92 -0
  132. package/dist-client/pages/kpi-value/kpi-value-importer.js.map +1 -0
  133. package/dist-client/pages/kpi-value/kpi-value-list-page.d.ts +73 -0
  134. package/dist-client/pages/kpi-value/kpi-value-list-page.js +403 -0
  135. package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -0
  136. package/dist-client/route.d.ts +1 -0
  137. package/dist-client/route.js +47 -0
  138. package/dist-client/route.js.map +1 -0
  139. package/dist-client/tsconfig.tsbuildinfo +1 -0
  140. package/dist-client/viewparts/kpi-metric-input.d.ts +23 -0
  141. package/dist-client/viewparts/kpi-metric-input.js +140 -0
  142. package/dist-client/viewparts/kpi-metric-input.js.map +1 -0
  143. package/dist-client/viewparts/kpi-metric-meta-editor.d.ts +36 -0
  144. package/dist-client/viewparts/kpi-metric-meta-editor.js +321 -0
  145. package/dist-client/viewparts/kpi-metric-meta-editor.js.map +1 -0
  146. package/dist-client/viewparts/metric-input-hint.d.ts +26 -0
  147. package/dist-client/viewparts/metric-input-hint.js +19 -0
  148. package/dist-client/viewparts/metric-input-hint.js.map +1 -0
  149. package/dist-client/viewparts/metric-input.test.d.ts +1 -0
  150. package/dist-client/viewparts/metric-input.test.js +43 -0
  151. package/dist-client/viewparts/metric-input.test.js.map +1 -0
  152. package/dist-client/viewparts/metric-renderer-registry.d.ts +18 -0
  153. package/dist-client/viewparts/metric-renderer-registry.js +29 -0
  154. package/dist-client/viewparts/metric-renderer-registry.js.map +1 -0
  155. package/dist-client/viewparts/ox-grist-editor-metric-input-hint.d.ts +19 -0
  156. package/dist-client/viewparts/ox-grist-editor-metric-input-hint.js +76 -0
  157. package/dist-client/viewparts/ox-grist-editor-metric-input-hint.js.map +1 -0
  158. package/dist-server/calculator/calculator.test.d.ts +1 -0
  159. package/dist-server/calculator/calculator.test.js +126 -0
  160. package/dist-server/calculator/calculator.test.js.map +1 -0
  161. package/dist-server/calculator/evaluator.d.ts +8 -0
  162. package/dist-server/calculator/evaluator.js +42 -0
  163. package/dist-server/calculator/evaluator.js.map +1 -0
  164. package/dist-server/calculator/functions.d.ts +3 -0
  165. package/dist-server/calculator/functions.js +62 -0
  166. package/dist-server/calculator/functions.js.map +1 -0
  167. package/dist-server/calculator/index.d.ts +6 -0
  168. package/dist-server/calculator/index.js +10 -0
  169. package/dist-server/calculator/index.js.map +1 -0
  170. package/dist-server/calculator/parser.d.ts +34 -0
  171. package/dist-server/calculator/parser.js +185 -0
  172. package/dist-server/calculator/parser.js.map +1 -0
  173. package/dist-server/calculator/provider.d.ts +8 -0
  174. package/dist-server/calculator/provider.js +13 -0
  175. package/dist-server/calculator/provider.js.map +1 -0
  176. package/dist-server/calculator/score.d.ts +21 -0
  177. package/dist-server/calculator/score.js +36 -0
  178. package/dist-server/calculator/score.js.map +1 -0
  179. package/dist-server/calculator/score.test.d.ts +1 -0
  180. package/dist-server/calculator/score.test.js +47 -0
  181. package/dist-server/calculator/score.test.js.map +1 -0
  182. package/dist-server/calculator/validate.d.ts +15 -0
  183. package/dist-server/calculator/validate.js +30 -0
  184. package/dist-server/calculator/validate.js.map +1 -0
  185. package/dist-server/calculator/validate.test.d.ts +1 -0
  186. package/dist-server/calculator/validate.test.js +45 -0
  187. package/dist-server/calculator/validate.test.js.map +1 -0
  188. package/dist-server/controllers/index.d.ts +2 -0
  189. package/dist-server/controllers/index.js +6 -0
  190. package/dist-server/controllers/index.js.map +1 -0
  191. package/dist-server/controllers/kpi-metric-value-provider.d.ts +11 -0
  192. package/dist-server/controllers/kpi-metric-value-provider.js +97 -0
  193. package/dist-server/controllers/kpi-metric-value-provider.js.map +1 -0
  194. package/dist-server/controllers/kpi-value-provider.d.ts +11 -0
  195. package/dist-server/controllers/kpi-value-provider.js +50 -0
  196. package/dist-server/controllers/kpi-value-provider.js.map +1 -0
  197. package/dist-server/index.d.ts +5 -0
  198. package/dist-server/index.js +9 -0
  199. package/dist-server/index.js.map +1 -0
  200. package/dist-server/migrations/1752190849680-seed-kpi-metrics.d.ts +6 -0
  201. package/dist-server/migrations/1752190849680-seed-kpi-metrics.js +102 -0
  202. package/dist-server/migrations/1752190849680-seed-kpi-metrics.js.map +1 -0
  203. package/dist-server/migrations/1752190849681-seed-kpi.d.ts +5 -0
  204. package/dist-server/migrations/1752190849681-seed-kpi.js +315 -0
  205. package/dist-server/migrations/1752190849681-seed-kpi.js.map +1 -0
  206. package/dist-server/migrations/1752192090123-add-grades-to-kpi.d.ts +7 -0
  207. package/dist-server/migrations/1752192090123-add-grades-to-kpi.js +51 -0
  208. package/dist-server/migrations/1752192090123-add-grades-to-kpi.js.map +1 -0
  209. package/dist-server/migrations/1752192090124-add-kpi-statistics.d.ts +5 -0
  210. package/dist-server/migrations/1752192090124-add-kpi-statistics.js +710 -0
  211. package/dist-server/migrations/1752192090124-add-kpi-statistics.js.map +1 -0
  212. package/dist-server/migrations/1752192090128-seed-kpi-org-scope.d.ts +6 -0
  213. package/dist-server/migrations/1752192090128-seed-kpi-org-scope.js +111 -0
  214. package/dist-server/migrations/1752192090128-seed-kpi-org-scope.js.map +1 -0
  215. package/dist-server/migrations/1752192090129-seed-kpi-values.d.ts +6 -0
  216. package/dist-server/migrations/1752192090129-seed-kpi-values.js +187 -0
  217. package/dist-server/migrations/1752192090129-seed-kpi-values.js.map +1 -0
  218. package/dist-server/migrations/1752192090200-add-meta-to-kpi-metric.d.ts +10 -0
  219. package/dist-server/migrations/1752192090200-add-meta-to-kpi-metric.js +26 -0
  220. package/dist-server/migrations/1752192090200-add-meta-to-kpi-metric.js.map +1 -0
  221. package/dist-server/migrations/1752192090201-backfill-kpi-metric-meta.d.ts +11 -0
  222. package/dist-server/migrations/1752192090201-backfill-kpi-metric-meta.js +54 -0
  223. package/dist-server/migrations/1752192090201-backfill-kpi-metric-meta.js.map +1 -0
  224. package/dist-server/migrations/grade-data/x11-performance-table.json +962 -0
  225. package/dist-server/migrations/grade-data/x12-performance-table.json +611 -0
  226. package/dist-server/migrations/grade-data/x14-performance-table.json +42 -0
  227. package/dist-server/migrations/grade-data/x21-performance-table.json +889 -0
  228. package/dist-server/migrations/grade-data/x22-performance-table.json +1064 -0
  229. package/dist-server/migrations/grade-data/x23-performance-table.json +42 -0
  230. package/dist-server/migrations/grade-data/x31-performance-table.json +644 -0
  231. package/dist-server/migrations/grade-data/x32-performance-table.json +993 -0
  232. package/dist-server/migrations/grade-data/x33-performance-table.json +195 -0
  233. package/dist-server/migrations/grade-data/x34-performance-table.json +12 -0
  234. package/dist-server/migrations/grade-data/x35-performance-table.json +42 -0
  235. package/dist-server/migrations/grade-data/x41-performance-table.json +825 -0
  236. package/dist-server/migrations/grade-data/x42-performance-table.json +786 -0
  237. package/dist-server/migrations/grade-data/x43-performance-table.json +12 -0
  238. package/dist-server/migrations/grade-data/x44-performance-table.json +42 -0
  239. package/dist-server/migrations/grade-data/x51-performance-table.json +924 -0
  240. package/dist-server/migrations/grade-data/x52-performance-table.json +42 -0
  241. package/dist-server/migrations/grade-data/x61-performance-table.json +261 -0
  242. package/dist-server/migrations/grade-data/x62-performance-table.json +42 -0
  243. package/dist-server/migrations/index.d.ts +1 -0
  244. package/dist-server/migrations/index.js +12 -0
  245. package/dist-server/migrations/index.js.map +1 -0
  246. package/dist-server/migrations/seed-data/kpi-metrics-seed.json +517 -0
  247. package/dist-server/migrations/seed-data/kpi-org-scope-seed.json +1676 -0
  248. package/dist-server/migrations/seed-data/kpi-scopes-seed.json +121 -0
  249. package/dist-server/migrations/seed-data/kpi-values-seed.json +402 -0
  250. package/dist-server/migrations/seed-data/kpis-seed.json +488 -0
  251. package/dist-server/migrations/seed-data/scope-definitions-seed.json +90 -0
  252. package/dist-server/routes.d.ts +1 -0
  253. package/dist-server/routes.js +72 -0
  254. package/dist-server/routes.js.map +1 -0
  255. package/dist-server/service/index.d.ts +15 -0
  256. package/dist-server/service/index.js +49 -0
  257. package/dist-server/service/index.js.map +1 -0
  258. package/dist-server/service/kpi/aggregate-kpi.d.ts +8 -0
  259. package/dist-server/service/kpi/aggregate-kpi.js +123 -0
  260. package/dist-server/service/kpi/aggregate-kpi.js.map +1 -0
  261. package/dist-server/service/kpi/event-subscriber.d.ts +9 -0
  262. package/dist-server/service/kpi/event-subscriber.js +31 -0
  263. package/dist-server/service/kpi/event-subscriber.js.map +1 -0
  264. package/dist-server/service/kpi/index.d.ts +8 -0
  265. package/dist-server/service/kpi/index.js +12 -0
  266. package/dist-server/service/kpi/index.js.map +1 -0
  267. package/dist-server/service/kpi/kpi-formula.service.d.ts +49 -0
  268. package/dist-server/service/kpi/kpi-formula.service.js +165 -0
  269. package/dist-server/service/kpi/kpi-formula.service.js.map +1 -0
  270. package/dist-server/service/kpi/kpi-grade.types.d.ts +22 -0
  271. package/dist-server/service/kpi/kpi-grade.types.js +3 -0
  272. package/dist-server/service/kpi/kpi-grade.types.js.map +1 -0
  273. package/dist-server/service/kpi/kpi-history.d.ts +29 -0
  274. package/dist-server/service/kpi/kpi-history.js +148 -0
  275. package/dist-server/service/kpi/kpi-history.js.map +1 -0
  276. package/dist-server/service/kpi/kpi-mutation.d.ts +14 -0
  277. package/dist-server/service/kpi/kpi-mutation.js +553 -0
  278. package/dist-server/service/kpi/kpi-mutation.js.map +1 -0
  279. package/dist-server/service/kpi/kpi-query.d.ts +24 -0
  280. package/dist-server/service/kpi/kpi-query.js +309 -0
  281. package/dist-server/service/kpi/kpi-query.js.map +1 -0
  282. package/dist-server/service/kpi/kpi-type.d.ts +48 -0
  283. package/dist-server/service/kpi/kpi-type.js +221 -0
  284. package/dist-server/service/kpi/kpi-type.js.map +1 -0
  285. package/dist-server/service/kpi/kpi.d.ts +130 -0
  286. package/dist-server/service/kpi/kpi.js +356 -0
  287. package/dist-server/service/kpi/kpi.js.map +1 -0
  288. package/dist-server/service/kpi-alert/index.d.ts +2 -0
  289. package/dist-server/service/kpi-alert/index.js +6 -0
  290. package/dist-server/service/kpi-alert/index.js.map +1 -0
  291. package/dist-server/service/kpi-alert/kpi-alert-query.d.ts +4 -0
  292. package/dist-server/service/kpi-alert/kpi-alert-query.js +72 -0
  293. package/dist-server/service/kpi-alert/kpi-alert-query.js.map +1 -0
  294. package/dist-server/service/kpi-alert/kpi-alert-type.d.ts +8 -0
  295. package/dist-server/service/kpi-alert/kpi-alert-type.js +33 -0
  296. package/dist-server/service/kpi-alert/kpi-alert-type.js.map +1 -0
  297. package/dist-server/service/kpi-metric/aggregate-kpi-metric.d.ts +8 -0
  298. package/dist-server/service/kpi-metric/aggregate-kpi-metric.js +126 -0
  299. package/dist-server/service/kpi-metric/aggregate-kpi-metric.js.map +1 -0
  300. package/dist-server/service/kpi-metric/index.d.ts +6 -0
  301. package/dist-server/service/kpi-metric/index.js +10 -0
  302. package/dist-server/service/kpi-metric/index.js.map +1 -0
  303. package/dist-server/service/kpi-metric/kpi-metric-meta.d.ts +46 -0
  304. package/dist-server/service/kpi-metric/kpi-metric-meta.js +27 -0
  305. package/dist-server/service/kpi-metric/kpi-metric-meta.js.map +1 -0
  306. package/dist-server/service/kpi-metric/kpi-metric-meta.test.d.ts +1 -0
  307. package/dist-server/service/kpi-metric/kpi-metric-meta.test.js +43 -0
  308. package/dist-server/service/kpi-metric/kpi-metric-meta.test.js.map +1 -0
  309. package/dist-server/service/kpi-metric/kpi-metric-mutation.d.ts +10 -0
  310. package/dist-server/service/kpi-metric/kpi-metric-mutation.js +296 -0
  311. package/dist-server/service/kpi-metric/kpi-metric-mutation.js.map +1 -0
  312. package/dist-server/service/kpi-metric/kpi-metric-query.d.ts +14 -0
  313. package/dist-server/service/kpi-metric/kpi-metric-query.js +126 -0
  314. package/dist-server/service/kpi-metric/kpi-metric-query.js.map +1 -0
  315. package/dist-server/service/kpi-metric/kpi-metric-type.d.ts +45 -0
  316. package/dist-server/service/kpi-metric/kpi-metric-type.js +177 -0
  317. package/dist-server/service/kpi-metric/kpi-metric-type.js.map +1 -0
  318. package/dist-server/service/kpi-metric/kpi-metric.d.ts +39 -0
  319. package/dist-server/service/kpi-metric/kpi-metric.js +174 -0
  320. package/dist-server/service/kpi-metric/kpi-metric.js.map +1 -0
  321. package/dist-server/service/kpi-metric-value/index.d.ts +6 -0
  322. package/dist-server/service/kpi-metric-value/index.js +10 -0
  323. package/dist-server/service/kpi-metric-value/index.js.map +1 -0
  324. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.d.ts +11 -0
  325. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +283 -0
  326. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -0
  327. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.d.ts +13 -0
  328. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js +106 -0
  329. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js.map +1 -0
  330. package/dist-server/service/kpi-metric-value/kpi-metric-value-type.d.ts +26 -0
  331. package/dist-server/service/kpi-metric-value/kpi-metric-value-type.js +112 -0
  332. package/dist-server/service/kpi-metric-value/kpi-metric-value-type.js.map +1 -0
  333. package/dist-server/service/kpi-metric-value/kpi-metric-value.d.ts +23 -0
  334. package/dist-server/service/kpi-metric-value/kpi-metric-value.js +107 -0
  335. package/dist-server/service/kpi-metric-value/kpi-metric-value.js.map +1 -0
  336. package/dist-server/service/kpi-org-scope/index.d.ts +5 -0
  337. package/dist-server/service/kpi-org-scope/index.js +9 -0
  338. package/dist-server/service/kpi-org-scope/index.js.map +1 -0
  339. package/dist-server/service/kpi-org-scope/kpi-org-scope-mutation.d.ts +8 -0
  340. package/dist-server/service/kpi-org-scope/kpi-org-scope-mutation.js +170 -0
  341. package/dist-server/service/kpi-org-scope/kpi-org-scope-mutation.js.map +1 -0
  342. package/dist-server/service/kpi-org-scope/kpi-org-scope-query.d.ts +14 -0
  343. package/dist-server/service/kpi-org-scope/kpi-org-scope-query.js +152 -0
  344. package/dist-server/service/kpi-org-scope/kpi-org-scope-query.js.map +1 -0
  345. package/dist-server/service/kpi-org-scope/kpi-org-scope-type.d.ts +26 -0
  346. package/dist-server/service/kpi-org-scope/kpi-org-scope-type.js +101 -0
  347. package/dist-server/service/kpi-org-scope/kpi-org-scope-type.js.map +1 -0
  348. package/dist-server/service/kpi-org-scope/kpi-org-scope.d.ts +26 -0
  349. package/dist-server/service/kpi-org-scope/kpi-org-scope.js +135 -0
  350. package/dist-server/service/kpi-org-scope/kpi-org-scope.js.map +1 -0
  351. package/dist-server/service/kpi-scope/index.d.ts +9 -0
  352. package/dist-server/service/kpi-scope/index.js +14 -0
  353. package/dist-server/service/kpi-scope/index.js.map +1 -0
  354. package/dist-server/service/kpi-scope/kpi-scope-mutation.d.ts +9 -0
  355. package/dist-server/service/kpi-scope/kpi-scope-mutation.js +140 -0
  356. package/dist-server/service/kpi-scope/kpi-scope-mutation.js.map +1 -0
  357. package/dist-server/service/kpi-scope/kpi-scope-query.d.ts +11 -0
  358. package/dist-server/service/kpi-scope/kpi-scope-query.js +89 -0
  359. package/dist-server/service/kpi-scope/kpi-scope-query.js.map +1 -0
  360. package/dist-server/service/kpi-scope/kpi-scope-type.d.ts +35 -0
  361. package/dist-server/service/kpi-scope/kpi-scope-type.js +138 -0
  362. package/dist-server/service/kpi-scope/kpi-scope-type.js.map +1 -0
  363. package/dist-server/service/kpi-scope/kpi-scope.d.ts +38 -0
  364. package/dist-server/service/kpi-scope/kpi-scope.js +144 -0
  365. package/dist-server/service/kpi-scope/kpi-scope.js.map +1 -0
  366. package/dist-server/service/kpi-statistic/index.d.ts +6 -0
  367. package/dist-server/service/kpi-statistic/index.js +10 -0
  368. package/dist-server/service/kpi-statistic/index.js.map +1 -0
  369. package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.d.ts +43 -0
  370. package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.js +181 -0
  371. package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.js.map +1 -0
  372. package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.d.ts +50 -0
  373. package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.js +324 -0
  374. package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.js.map +1 -0
  375. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.d.ts +14 -0
  376. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.js +279 -0
  377. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.js.map +1 -0
  378. package/dist-server/service/kpi-statistic/kpi-statistic-query.d.ts +17 -0
  379. package/dist-server/service/kpi-statistic/kpi-statistic-query.js +183 -0
  380. package/dist-server/service/kpi-statistic/kpi-statistic-query.js.map +1 -0
  381. package/dist-server/service/kpi-statistic/kpi-statistic-type.d.ts +59 -0
  382. package/dist-server/service/kpi-statistic/kpi-statistic-type.js +200 -0
  383. package/dist-server/service/kpi-statistic/kpi-statistic-type.js.map +1 -0
  384. package/dist-server/service/kpi-statistic/kpi-statistic.d.ts +42 -0
  385. package/dist-server/service/kpi-statistic/kpi-statistic.js +210 -0
  386. package/dist-server/service/kpi-statistic/kpi-statistic.js.map +1 -0
  387. package/dist-server/service/kpi-value/index.d.ts +6 -0
  388. package/dist-server/service/kpi-value/index.js +10 -0
  389. package/dist-server/service/kpi-value/index.js.map +1 -0
  390. package/dist-server/service/kpi-value/kpi-value-mutation.d.ts +13 -0
  391. package/dist-server/service/kpi-value/kpi-value-mutation.js +447 -0
  392. package/dist-server/service/kpi-value/kpi-value-mutation.js.map +1 -0
  393. package/dist-server/service/kpi-value/kpi-value-query.d.ts +22 -0
  394. package/dist-server/service/kpi-value/kpi-value-query.js +149 -0
  395. package/dist-server/service/kpi-value/kpi-value-query.js.map +1 -0
  396. package/dist-server/service/kpi-value/kpi-value-score.service.d.ts +24 -0
  397. package/dist-server/service/kpi-value/kpi-value-score.service.js +61 -0
  398. package/dist-server/service/kpi-value/kpi-value-score.service.js.map +1 -0
  399. package/dist-server/service/kpi-value/kpi-value-type.d.ts +33 -0
  400. package/dist-server/service/kpi-value/kpi-value-type.js +156 -0
  401. package/dist-server/service/kpi-value/kpi-value-type.js.map +1 -0
  402. package/dist-server/service/kpi-value/kpi-value.d.ts +32 -0
  403. package/dist-server/service/kpi-value/kpi-value.js +175 -0
  404. package/dist-server/service/kpi-value/kpi-value.js.map +1 -0
  405. package/dist-server/service/utils/value-date-util.d.ts +4 -0
  406. package/dist-server/service/utils/value-date-util.js +117 -0
  407. package/dist-server/service/utils/value-date-util.js.map +1 -0
  408. package/dist-server/tsconfig.tsbuildinfo +1 -0
  409. package/package.json +3 -3
@@ -0,0 +1,948 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import '@material/web/icon/icon.js';
3
+ import '@material/web/button/elevated-button.js';
4
+ import '@operato/data-grist/ox-grist.js';
5
+ import '@operato/data-grist/ox-filters-form.js';
6
+ import '@operato/data-grist/ox-record-creator.js';
7
+ import './kpi-viz-editor.js';
8
+ import './kpi-grade-editor.js';
9
+ import { CommonButtonStyles, CommonHeaderStyles, CommonGristStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles';
10
+ import { PageView } from '@operato/shell';
11
+ import { css, html } from 'lit';
12
+ import { customElement, property, query, state } from 'lit/decorators.js';
13
+ import { ScopedElementsMixin } from '@open-wc/scoped-elements';
14
+ import { DataGrist } from '@operato/data-grist';
15
+ import { client } from '@operato/graphql';
16
+ import { i18next, localize } from '@operato/i18n';
17
+ import { notify, openPopup } from '@operato/layout';
18
+ import { OxPrompt } from '@operato/popup';
19
+ import { isMobileDevice } from '@operato/utils';
20
+ import { p13n } from '@operato/p13n';
21
+ import gql from 'graphql-tag';
22
+ /**
23
+ * KPI scoreType — value → score 변환 방식 (null이면 미설정)
24
+ *
25
+ * DIRECT — value = score, 변환 없음
26
+ * FORMULA — scoreFormula 수식으로 변환
27
+ * LOOKUP — grade table(1D)로 변환
28
+ * CUSTOM — 2D 룩업 등 특수 변환
29
+ */
30
+ export const KPI_SCORE_TYPE = {
31
+ DIRECT: 'DIRECT',
32
+ FORMULA: 'FORMULA',
33
+ LOOKUP: 'LOOKUP',
34
+ CUSTOM: 'CUSTOM'
35
+ };
36
+ /**
37
+ * KPI valueType — value 획득 방식
38
+ *
39
+ * MEASURED — 외부 시스템 수집 측정값
40
+ * ASSESSED — 감리자 직접 평가 (1~5)
41
+ * CALCULATED — formula 자동 계산
42
+ * COMPOSITE — 다차원 복합 입력
43
+ */
44
+ export const KPI_VALUE_TYPE = {
45
+ MEASURED: 'MEASURED',
46
+ ASSESSED: 'ASSESSED',
47
+ CALCULATED: 'CALCULATED',
48
+ COMPOSITE: 'COMPOSITE'
49
+ };
50
+ export function inferScoreType(kpi) {
51
+ if (kpi.scoreType)
52
+ return kpi.scoreType;
53
+ if (kpi.scoreFormula)
54
+ return KPI_SCORE_TYPE.FORMULA;
55
+ if (kpi.grades && typeof kpi.grades === 'object' && !Array.isArray(kpi.grades))
56
+ return KPI_SCORE_TYPE.CUSTOM;
57
+ if (Array.isArray(kpi.grades) && kpi.grades.length > 0)
58
+ return KPI_SCORE_TYPE.LOOKUP;
59
+ return KPI_SCORE_TYPE.DIRECT;
60
+ }
61
+ import { KpiImporter } from './kpi-importer';
62
+ import { KpiGradeEditor } from './kpi-grade-editor';
63
+ import { KpiVizEditor } from './kpi-viz-editor';
64
+ let KpiListPage = class KpiListPage extends p13n(localize(i18next)(ScopedElementsMixin(PageView))) {
65
+ constructor() {
66
+ super(...arguments);
67
+ this.mode = isMobileDevice() ? 'CARD' : 'GRID';
68
+ this.availableVariables = [];
69
+ this.availableVariablesLoaded = false;
70
+ this.hierarchicalView = false;
71
+ }
72
+ static { this.styles = [
73
+ /* The work surface frame for a list screen (ADR-0060 decision 8). */
74
+ WorkSurfacePageStyles,
75
+ ScrollbarStyles,
76
+ CommonGristStyles,
77
+ CommonHeaderStyles,
78
+ css `
79
+ :host {
80
+ --grid-record-emphasized-background-color: #8b0000;
81
+ --grid-record-emphasized-color: #ff6b6b;
82
+ }
83
+
84
+ ox-filters-form { flex: 1;
85
+ }
86
+ `
87
+ ]; }
88
+ static get scopedElements() {
89
+ return { 'kpi-importer': KpiImporter,
90
+ 'kpi-grade-editor': KpiGradeEditor,
91
+ 'kpi-viz-editor': KpiVizEditor
92
+ };
93
+ }
94
+ async getAvailableKpiMetricVariables(currentKpi) {
95
+ if (!currentKpi || currentKpi.isLeaf) {
96
+ if (this.availableVariablesLoaded) {
97
+ return this.availableVariables;
98
+ }
99
+ const response = await client.query({ query: gql `
100
+ query { kpiMetrics { items { name
101
+ description
102
+ unit
103
+ }
104
+ }
105
+ }
106
+ `
107
+ });
108
+ this.availableVariables = (response.data.kpiMetrics.items || []).map(metric => ({ name: metric.name,
109
+ description: metric.description,
110
+ type: 'kpi-metric',
111
+ unit: metric.unit
112
+ }));
113
+ this.availableVariablesLoaded = true;
114
+ return this.availableVariables;
115
+ }
116
+ // 부모 KPI인 경우: 자식 KPI를 변수로 사용
117
+ try {
118
+ const response = await client.query({ query: gql `
119
+ query ($id: String!) { kpi(id: $id) { children { id
120
+ name
121
+ description
122
+ }
123
+ }
124
+ }
125
+ `,
126
+ variables: { id: currentKpi.id
127
+ }
128
+ });
129
+ return (response.data.kpi.children || []).map(childKpi => ({ name: childKpi.name,
130
+ description: childKpi.description,
131
+ type: 'child-kpi'
132
+ }));
133
+ }
134
+ catch (error) {
135
+ console.error('Failed to fetch child KPIs:', error);
136
+ return [];
137
+ }
138
+ }
139
+ get context() {
140
+ return { title: i18next.t('title.kpi list'),
141
+ search: { handler: (search) => {
142
+ this.grist.searchText = search;
143
+ },
144
+ value: this.grist.searchText },
145
+ filter: { handler: () => {
146
+ this.grist.toggleHeadroom();
147
+ }
148
+ },
149
+ help: 'kpi/kpi',
150
+ actions: [
151
+ { title: this.hierarchicalView ? 'List View' : 'Tree View',
152
+ action: this._toggleHierarchicalView.bind(this),
153
+ icon: this.hierarchicalView ? 'list' : 'account_tree'
154
+ },
155
+ { title: i18next.t('button.save'),
156
+ action: this._updateKpi.bind(this),
157
+ ...CommonButtonStyles.save
158
+ },
159
+ { title: i18next.t('button.delete'),
160
+ action: this._deleteKpi.bind(this),
161
+ ...CommonButtonStyles.delete
162
+ }
163
+ ],
164
+ exportable: { name: i18next.t('title.kpi list'),
165
+ data: this.exportHandler.bind(this)
166
+ },
167
+ importable: { handler: this.importHandler.bind(this)
168
+ } };
169
+ }
170
+ render() {
171
+ const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID');
172
+ return html `
173
+ <ox-grist class="page-fill"
174
+ .mode=${mode}
175
+ .config=${this.gristConfig}
176
+ .fetchHandler=${this.fetchHandler.bind(this)}
177
+ .personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')}
178
+ >
179
+ <div slot="headroom" class="header">
180
+ <div class="filters">
181
+ <ox-filters-form autofocus without-search></ox-filters-form>
182
+
183
+ <div id="modes">
184
+ <md-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</md-icon>
185
+ <md-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</md-icon>
186
+ <md-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</md-icon>
187
+ </div>
188
+
189
+ <ox-record-creator id="add" .callback=${this.creationCallback.bind(this)}>
190
+ <button>
191
+ <md-icon>add</md-icon>
192
+ </button>
193
+ </ox-record-creator>
194
+ </div>
195
+ </div>
196
+
197
+ <ox-grist-personalizer slot="setting"></ox-grist-personalizer>
198
+ </ox-grist>
199
+ `;
200
+ }
201
+ connectedCallback() {
202
+ super.connectedCallback();
203
+ this.fetchKpiMetrics();
204
+ }
205
+ async pageInitialized(lifecycle) {
206
+ this.gristConfig = { list: { fields: ['name', 'description'],
207
+ details: [
208
+ 'name',
209
+ 'description',
210
+ 'formula',
211
+ 'active',
212
+ 'state',
213
+ 'vizType',
214
+ 'schedule',
215
+ 'scheduleId',
216
+ 'timezone',
217
+ 'version',
218
+ 'createdAt',
219
+ 'updatedAt',
220
+ 'creator',
221
+ 'updater',
222
+ 'thumbnail'
223
+ ]
224
+ },
225
+ columns: [
226
+ { type: 'gutter', gutterName: 'sequence' },
227
+ { type: 'gutter', gutterName: 'row-selector', multiple: true },
228
+ // KPI 실적값 계산 버튼 추가
229
+ { type: 'gutter',
230
+ gutterName: 'button',
231
+ icon: 'calculate',
232
+ title: '실적값 계산',
233
+ handlers: { click: (columns, data, column, record, rowIndex) => {
234
+ this._calculateKpiValue(record);
235
+ }
236
+ }
237
+ },
238
+ { type: 'string',
239
+ name: 'name',
240
+ header: '이름',
241
+ record: { editable: true },
242
+ filter: 'search',
243
+ sortable: true,
244
+ width: 120
245
+ },
246
+ { type: 'string',
247
+ name: 'description',
248
+ header: i18next.t('field.description'),
249
+ record: { editable: true },
250
+ filter: 'search',
251
+ width: 200
252
+ },
253
+ { type: 'resource-object',
254
+ name: 'parent',
255
+ label: true,
256
+ header: '상위 KPI',
257
+ record: { editable: true,
258
+ options: { title: i18next.t('title.lookup KPI'),
259
+ queryName: 'kpis',
260
+ basicArgs: { filters: [{ name: 'isLeaf', operator: 'eq', value: false }]
261
+ }
262
+ }
263
+ },
264
+ width: 200
265
+ },
266
+ { type: 'boolean',
267
+ name: 'isLeaf',
268
+ header: '리프 KPI',
269
+ record: { editable: true },
270
+ width: 100
271
+ },
272
+ { type: 'formula',
273
+ name: 'formula',
274
+ header: '산식',
275
+ record: { editable: true,
276
+ availableVariables: async (value, column, record) => {
277
+ if (!record || record.isLeaf) {
278
+ return await this.getAvailableKpiMetricVariables(record);
279
+ }
280
+ // 부모 KPI인 경우: 자식 KPI를 변수로 사용
281
+ return (record.children || []).map(child => ({ name: child.name,
282
+ description: child.description || child.name,
283
+ type: 'child-kpi',
284
+ unit: ''
285
+ }));
286
+ }
287
+ },
288
+ width: 320 },
289
+ { type: 'select',
290
+ name: 'periodType',
291
+ header: '계산주기',
292
+ record: { editable: true,
293
+ options: [
294
+ { value: '', display: '' },
295
+ { value: 'DAY', display: '일' },
296
+ { value: 'WEEK', display: '주' },
297
+ { value: 'MONTH', display: '월' },
298
+ { value: 'QUARTER', display: '분기' },
299
+ { value: 'YEAR', display: '년' },
300
+ { value: 'RANGE', display: '범위' },
301
+ { value: 'ALLTIME', display: '전체' }
302
+ ]
303
+ },
304
+ width: 80
305
+ },
306
+ { type: 'formula',
307
+ name: 'scoreFormula',
308
+ header: '성과점수수식',
309
+ record: { editable: true,
310
+ availableVariables: async (value, column, record) => {
311
+ if (record.isLeaf) {
312
+ return [
313
+ { name: 'value',
314
+ description: 'KPI 실적값',
315
+ type: 'kpi-value',
316
+ unit: ''
317
+ }
318
+ ];
319
+ }
320
+ // 부모 이면 자식 KPI들을 변수로 사용
321
+ return record.children.map(child => ({ name: child.name,
322
+ description: child.description || child.name,
323
+ type: 'kpi-score',
324
+ unit: ''
325
+ }));
326
+ },
327
+ includeDefaultFunctions: false,
328
+ availableFunctions: [
329
+ { name: 'INTEGRATE()',
330
+ description: '수치 적분',
331
+ template: 'INTEGRATE({func}, {a}, {b}, {n})',
332
+ syntax: 'INTEGRATE(func, a, b, n)',
333
+ parameters: ['func - 적분할 함수', 'a - 하한값', 'b - 상한값', 'n - 분할 수 (기본값: 1000)'],
334
+ returnType: 'number',
335
+ help: '사다리꼴 적분법을 사용하여 수치 적분을 계산합니다.',
336
+ examples: ['INTEGRATE(x => x*x, 0, 1, 1000)', 'INTEGRATE([효율성], 0, 1)']
337
+ },
338
+ { name: 'BETA_FUNCTION()',
339
+ description: '베타 함수',
340
+ template: 'BETA_FUNCTION({x}, {alpha}, {beta})',
341
+ syntax: 'BETA_FUNCTION(x, alpha, beta)',
342
+ parameters: ['x - 변수 (0 ≤ x ≤ 1)', 'alpha - 첫 번째 모수', 'beta - 두 번째 모수'],
343
+ returnType: 'number',
344
+ help: '베타 분포 함수를 계산합니다. t^(α-1) × (1-t)^(β-1)',
345
+ examples: ['BETA_FUNCTION(0.5, 2, 3)', 'BETA_FUNCTION([품질지수], 3, 2)']
346
+ },
347
+ { name: 'INCOMPLETE_BETA()',
348
+ description: '불완전 베타 함수',
349
+ template: 'INCOMPLETE_BETA({x}, {alpha}, {beta})',
350
+ syntax: 'INCOMPLETE_BETA(x, alpha, beta)',
351
+ parameters: ['x - 상한값 (0 ≤ x ≤ 1)', 'alpha - 첫 번째 모수', 'beta - 두 번째 모수'],
352
+ returnType: 'number',
353
+ help: '불완전 베타 함수를 수치 적분으로 계산합니다.',
354
+ examples: ['INCOMPLETE_BETA(0.7, 2, 3)', 'INCOMPLETE_BETA([목표달성률]/100, 2, 3)']
355
+ },
356
+ { name: 'COMPLETE_BETA()',
357
+ description: '완전 베타 함수',
358
+ template: 'COMPLETE_BETA({alpha}, {beta})',
359
+ syntax: 'COMPLETE_BETA(alpha, beta)',
360
+ parameters: ['alpha - 첫 번째 모수', 'beta - 두 번째 모수'],
361
+ returnType: 'number',
362
+ help: '완전 베타 함수 B(α,β)를 계산합니다.',
363
+ examples: ['COMPLETE_BETA(2, 3)', 'COMPLETE_BETA(3, 2)']
364
+ },
365
+ { name: 'PERFORMANCE_INDEX()',
366
+ description: '성과 지수',
367
+ template: 'PERFORMANCE_INDEX({x}, {alpha1}, {beta1}, {alpha2}, {beta2})',
368
+ syntax: 'PERFORMANCE_INDEX(x, alpha1, beta1, alpha2, beta2)',
369
+ parameters: [
370
+ 'x - 성과 값 (0 ≤ x ≤ 1)',
371
+ 'alpha1, beta1 - 분자 베타 함수 모수',
372
+ 'alpha2, beta2 - 분모 베타 함수 모수'
373
+ ],
374
+ returnType: 'number',
375
+ help: '성과 지수를 계산합니다: 1 - (불완전 베타 / 완전 베타)',
376
+ examples: ['PERFORMANCE_INDEX(0.8, 2, 3, 2, 3)', 'PERFORMANCE_INDEX([성과점수]/100, 2, 3, 2, 3)']
377
+ },
378
+ { name: 'EXP()',
379
+ description: '지수 함수',
380
+ template: 'EXP({x})',
381
+ syntax: 'EXP(x)',
382
+ parameters: ['x - 지수'],
383
+ returnType: 'number',
384
+ help: '자연상수 e의 x제곱을 계산합니다.',
385
+ examples: ['EXP(1)', 'EXP([효율성])']
386
+ },
387
+ { name: 'LOG()',
388
+ description: '자연 로그',
389
+ template: 'LOG({x})',
390
+ syntax: 'LOG(x)',
391
+ parameters: ['x - 로그를 취할 값'],
392
+ returnType: 'number',
393
+ help: '자연 로그 ln(x)를 계산합니다.',
394
+ examples: ['LOG(2.718)', 'LOG([성과점수])']
395
+ },
396
+ { name: 'POW()',
397
+ description: '거듭제곱',
398
+ template: 'POW({x}, {y})',
399
+ syntax: 'POW(x, y)',
400
+ parameters: ['x - 밑수', 'y - 지수'],
401
+ returnType: 'number',
402
+ help: 'x의 y제곱을 계산합니다.',
403
+ examples: ['POW(2, 3)', 'POW([효율성], 2)']
404
+ },
405
+ { name: 'EXPONENTIAL_DECAY()',
406
+ description: '지수 감쇠',
407
+ template: 'EXPONENTIAL_DECAY({value}, {scale}, {power})',
408
+ syntax: 'EXPONENTIAL_DECAY(value, scale, power)',
409
+ parameters: ['value - 입력 값', 'scale - 스케일 파라미터', 'power - 지수 파라미터'],
410
+ returnType: 'number',
411
+ help: '지수 감쇠 함수 exp(-(value/scale)^power)를 계산합니다.',
412
+ examples: ['EXPONENTIAL_DECAY(50, 100, 2)', 'EXPONENTIAL_DECAY([목표달성률], 50, 2)']
413
+ }
414
+ ] },
415
+ width: 200 },
416
+ { type: 'string',
417
+ name: 'grades',
418
+ header: '성과지수 Lookup',
419
+ record: { editable: false,
420
+ renderer: (v, c, r) => this.renderGradesCell(r)
421
+ },
422
+ width: 150
423
+ },
424
+ {
425
+ type: 'select',
426
+ name: 'scoreType',
427
+ header: 'Score 산정',
428
+ record: {
429
+ editable: true,
430
+ options: [
431
+ { value: '', display: '(미설정)' },
432
+ { value: 'DIRECT', display: 'DIRECT (변환없음)' },
433
+ { value: 'FORMULA', display: 'FORMULA (수식)' },
434
+ { value: 'LOOKUP', display: 'LOOKUP (등급표)' },
435
+ { value: 'CUSTOM', display: 'CUSTOM (특수)' }
436
+ ]
437
+ },
438
+ width: 130
439
+ },
440
+ {
441
+ type: 'select',
442
+ name: 'valueType',
443
+ header: 'Value 획득',
444
+ record: {
445
+ editable: true,
446
+ options: [
447
+ { value: '', display: '(미설정)' },
448
+ { value: 'MEASURED', display: 'MEASURED (외부수집)' },
449
+ { value: 'ASSESSED', display: 'ASSESSED (감리자평가)' },
450
+ { value: 'CALCULATED', display: 'CALCULATED (산식)' },
451
+ { value: 'COMPOSITE', display: 'COMPOSITE (복합)' }
452
+ ]
453
+ },
454
+ width: 140
455
+ },
456
+ { type: 'number',
457
+ name: 'weight',
458
+ header: '가중치',
459
+ record: { editable: true },
460
+ filter: true,
461
+ sortable: true,
462
+ width: 80
463
+ },
464
+ { type: 'checkbox',
465
+ name: 'active',
466
+ label: true,
467
+ header: i18next.t('field.active'),
468
+ record: { editable: true },
469
+ filter: true,
470
+ sortable: true,
471
+ width: 60
472
+ },
473
+ { type: 'string', name: 'state', header: '상태', record: { editable: false }, width: 100 },
474
+ { type: 'string',
475
+ name: 'vizType',
476
+ hidden: true,
477
+ header: '시각화 설정',
478
+ record: { editable: false,
479
+ renderer: (v, c, r) => {
480
+ const vizType = r.vizType || 'CARD';
481
+ const vizMeta = r.vizMeta || {};
482
+ const color = vizMeta.color || '#2196f3';
483
+ const icon = vizMeta.icon || 'dashboard';
484
+ return html `
485
+ <div style="display:flex;align-items:center;gap:8px;">
486
+ <span style="color:${color};cursor:pointer;" @click=${() => this._editViz(r)}> ${vizType} </span>
487
+ <md-icon style="color:${color};font-size:16px;cursor:pointer;" @click=${() => this._editViz(r)}>
488
+ ${icon}
489
+ </md-icon>
490
+ </div>
491
+ `;
492
+ }
493
+ },
494
+ width: 150
495
+ },
496
+ { type: 'crontab', name: 'schedule', header: '스케줄', record: { editable: true }, width: 120 },
497
+ { type: 'string', name: 'scheduleId', header: '스케줄ID', record: { editable: false }, width: 120 },
498
+ { type: 'timezone', name: 'timezone', header: '타임존', record: { editable: true }, width: 120 },
499
+ { type: 'number', name: 'version', header: '버전', record: { editable: false }, width: 80 },
500
+ { type: 'datetime', name: 'createdAt', header: '생성일', record: { editable: false }, width: 180 },
501
+ { type: 'datetime',
502
+ name: 'updatedAt',
503
+ header: i18next.t('field.updated_at'),
504
+ record: { editable: false },
505
+ sortable: true,
506
+ width: 180
507
+ },
508
+ { type: 'resource-object',
509
+ name: 'creator',
510
+ header: '생성자',
511
+ record: { editable: false, renderer: (v, c, r) => r.creator?.name },
512
+ width: 120
513
+ },
514
+ { type: 'resource-object',
515
+ name: 'updater',
516
+ header: i18next.t('field.updater'),
517
+ record: { editable: false, renderer: (v, c, r) => r.updater?.name },
518
+ sortable: true,
519
+ width: 120
520
+ },
521
+ { type: 'string', name: 'thumbnail', header: '썸네일', record: { editable: false }, width: 120 }
522
+ ],
523
+ rows: { appendable: false,
524
+ selectable: { multiple: true
525
+ }
526
+ },
527
+ sorters: [{ name: 'name' }] };
528
+ }
529
+ async pageUpdated(changes, lifecycle) {
530
+ if (this.active) { // do something here when this page just became as active
531
+ }
532
+ }
533
+ async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }) {
534
+ if (this.hierarchicalView) {
535
+ return this.fetchHierarchicalData();
536
+ }
537
+ const response = await client.query({ query: gql `
538
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) { responses: kpis(filters: $filters, pagination: $pagination, sortings: $sortings) { items { id
539
+ name
540
+ description
541
+ active
542
+ formula
543
+ periodType
544
+ scoreType
545
+ valueType
546
+ scoreFormula
547
+ grades
548
+ vizType
549
+ vizMeta
550
+ weight
551
+ schedule
552
+ scheduleId
553
+ timezone
554
+ version
555
+ parent { id
556
+ name
557
+ }
558
+ children { id
559
+ name
560
+ description
561
+ }
562
+ isLeaf
563
+ updater { id
564
+ name
565
+ }
566
+ updatedAt
567
+ creator { id
568
+ name
569
+ }
570
+ createdAt
571
+ }
572
+ total
573
+ }
574
+ }
575
+ `,
576
+ variables: { filters,
577
+ pagination: { page, limit },
578
+ sortings
579
+ }
580
+ });
581
+ return { total: response.data.responses.total || 0,
582
+ records: response.data.responses.items || []
583
+ };
584
+ }
585
+ async fetchKpiMetrics() {
586
+ const response = await client.query({ query: gql `
587
+ query { kpiMetrics { items { name
588
+ description
589
+ unit
590
+ }
591
+ }
592
+ }
593
+ `
594
+ });
595
+ if (!response.errors) {
596
+ this.availableVariables = (response.data.kpiMetrics.items || []).map(metric => ({ name: metric.name,
597
+ description: metric.description,
598
+ type: 'kpi-metric',
599
+ unit: metric.unit
600
+ }));
601
+ }
602
+ }
603
+ async _deleteKpi() {
604
+ if (await OxPrompt.open({ title: i18next.t('text.are_you_sure'),
605
+ text: i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }),
606
+ confirmButton: { text: i18next.t('button.confirm') },
607
+ cancelButton: { text: i18next.t('button.cancel') }
608
+ })) {
609
+ const ids = this.grist.selected.map(record => record.id);
610
+ if (ids && ids.length > 0) {
611
+ const response = await client.mutate({ mutation: gql `
612
+ mutation ($ids: [String!]!) { deleteKpis(ids: $ids)
613
+ }
614
+ `,
615
+ variables: { ids
616
+ }
617
+ });
618
+ if (!response.errors) {
619
+ this.grist.fetch();
620
+ notify({ message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
621
+ });
622
+ }
623
+ }
624
+ }
625
+ }
626
+ async _updateKpi() {
627
+ let patches = this.grist.dirtyRecords;
628
+ if (patches && patches.length) {
629
+ patches = patches.map(patch => {
630
+ let patchField = patch.id ? { id: patch.id } : {};
631
+ const dirtyFields = patch.__dirtyfields__;
632
+ for (let key in dirtyFields) {
633
+ patchField[key] = dirtyFields[key].after;
634
+ }
635
+ patchField.cuFlag = patch.__dirty__;
636
+ return patchField;
637
+ });
638
+ const response = await client.mutate({ mutation: gql `
639
+ mutation ($patches: [KpiPatch!]!) { updateMultipleKpi(patches: $patches) { name
640
+ }
641
+ }
642
+ `,
643
+ variables: { patches
644
+ }
645
+ });
646
+ if (!response.errors) {
647
+ this.grist.fetch();
648
+ }
649
+ }
650
+ }
651
+ async creationCallback(kpi) {
652
+ try {
653
+ const response = await client.query({ query: gql `
654
+ mutation ($kpi: NewKpi!) { createKpi(kpi: $kpi) { id
655
+ }
656
+ }
657
+ `,
658
+ variables: { kpi
659
+ },
660
+ context: { hasUpload: true
661
+ }
662
+ });
663
+ if (!response.errors) {
664
+ this.grist.fetch();
665
+ document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.data_created_successfully')
666
+ }
667
+ }));
668
+ }
669
+ return true;
670
+ }
671
+ catch (ex) {
672
+ console.error(ex);
673
+ document.dispatchEvent(new CustomEvent('notify', { detail: { type: 'error',
674
+ message: i18next.t('text.error')
675
+ }
676
+ }));
677
+ return false;
678
+ }
679
+ }
680
+ async exportHandler() {
681
+ const exportTargets = this.grist.selected.length ? this.grist.selected : this.grist.dirtyData.records;
682
+ const targetFieldSet = new Set(['id', 'name', 'description', 'active']);
683
+ return exportTargets.map(kpi => {
684
+ let tempObj = {};
685
+ for (const field of targetFieldSet) {
686
+ tempObj[field] = kpi[field];
687
+ }
688
+ return tempObj;
689
+ });
690
+ }
691
+ async importHandler(records) {
692
+ const popup = openPopup(html `
693
+ <kpi-importer
694
+ .kpis=${records}
695
+ @imported=${() => {
696
+ history.back();
697
+ this.grist.fetch();
698
+ }}
699
+ ></kpi-importer>
700
+ `, { backdrop: true,
701
+ size: 'large',
702
+ title: i18next.t('title.import kpi')
703
+ });
704
+ popup.onclosed = () => {
705
+ this.grist.fetch();
706
+ };
707
+ }
708
+ /**
709
+ * grades 셀 렌더러. 서브클래스에서 override 가능.
710
+ * CUSTOM scoreType은 renderCustomGradesCell()로 위임.
711
+ */
712
+ renderGradesCell(kpi) {
713
+ const scoreType = inferScoreType(kpi);
714
+ let label;
715
+ let hasGrades;
716
+ switch (scoreType) {
717
+ case KPI_SCORE_TYPE.LOOKUP:
718
+ hasGrades = Array.isArray(kpi.grades) && kpi.grades.length > 0;
719
+ label = hasGrades ? `${kpi.grades.length}개 등급 설정됨` : '등급 설정 없음';
720
+ break;
721
+ case KPI_SCORE_TYPE.DIRECT:
722
+ // valueType으로 세분화 표시
723
+ if (kpi.valueType === KPI_VALUE_TYPE.ASSESSED) {
724
+ return html `<span style="color:#2196f3">평가형 (1~5)</span>`;
725
+ }
726
+ if (kpi.valueType === KPI_VALUE_TYPE.CALCULATED) {
727
+ return html `<span style="color:#888">산식 계산</span>`;
728
+ }
729
+ return html `<span style="color:#888">직접 (value=score)</span>`;
730
+ case KPI_SCORE_TYPE.FORMULA:
731
+ return html `<span style="color:#888">산식 변환</span>`;
732
+ case KPI_SCORE_TYPE.CUSTOM:
733
+ return this.renderCustomGradesCell(kpi);
734
+ default:
735
+ if (!scoreType) {
736
+ return html `<span style="color:#ccc">미설정</span>`;
737
+ }
738
+ hasGrades = false;
739
+ label = '등급 설정 없음';
740
+ }
741
+ return html `<span
742
+ style="color:${hasGrades ? '#4caf50' : '#999'};cursor:pointer;"
743
+ @click=${() => this._editGrades(kpi)}
744
+ >${label}</span
745
+ >`;
746
+ }
747
+ /**
748
+ * CUSTOM scoreType의 grades 셀 렌더링. 서브클래스에서 override하여 구현.
749
+ */
750
+ renderCustomGradesCell(kpi) {
751
+ return html `<span style="color:#999;cursor:pointer;" @click=${() => this._editGrades(kpi)}>커스텀 설정됨</span>`;
752
+ }
753
+ /**
754
+ * 등급 편집 팝업. CUSTOM 타입은 _editCustomGrades()로 위임. 서브클래스에서 override 가능.
755
+ */
756
+ async _editGrades(kpi) {
757
+ if (!kpi.id) {
758
+ notify({ message: 'KPI를 먼저 저장한 후에 등급 설정을 할 수 있습니다.' });
759
+ return;
760
+ }
761
+ const scoreType = inferScoreType(kpi);
762
+ if (scoreType === KPI_SCORE_TYPE.CUSTOM) {
763
+ await this._editCustomGrades(kpi);
764
+ return;
765
+ }
766
+ if (scoreType !== KPI_SCORE_TYPE.LOOKUP)
767
+ return;
768
+ const popup = await openPopup(html ` <kpi-grade-editor .kpi=${kpi}></kpi-grade-editor> `, {
769
+ title: `${kpi.name} - 등급 설정`,
770
+ size: 'large'
771
+ });
772
+ popup.onclosed = () => { this.grist.fetch(); };
773
+ }
774
+ /**
775
+ * CUSTOM scoreType의 등급 편집 팝업. 서브클래스에서 override하여 구현.
776
+ */
777
+ async _editCustomGrades(kpi) {
778
+ notify({ message: '커스텀 등급 편집기가 필요합니다.' });
779
+ }
780
+ async _editViz(kpi) {
781
+ const popup = await openPopup(html `
782
+ <kpi-viz-editor
783
+ .kpi=${kpi}
784
+ .onSave=${(vizType, vizMeta) => this._onVizUpdated(kpi.id, vizType, vizMeta)}
785
+ .onCancel=${() => popup.close()}
786
+ ></kpi-viz-editor>
787
+ `, { title: `${kpi.name} - 시각화 설정`,
788
+ size: 'large'
789
+ });
790
+ }
791
+ async _onVizUpdated(kpiId, vizType, vizMeta) {
792
+ try {
793
+ const response = await client.mutate({ mutation: gql `
794
+ mutation ($id: String!, $patch: KpiPatch!) { updateKpi(id: $id, patch: $patch) { id
795
+ name
796
+ vizType
797
+ vizMeta
798
+ }
799
+ }
800
+ `,
801
+ variables: { id: kpiId,
802
+ patch: { vizType, vizMeta }
803
+ }
804
+ });
805
+ if (!response.errors) {
806
+ this.grist.fetch();
807
+ notify({ message: '시각화 설정이 성공적으로 업데이트되었습니다.'
808
+ });
809
+ }
810
+ }
811
+ catch (error) {
812
+ notify({ message: '시각화 설정 업데이트 중 오류가 발생했습니다.'
813
+ });
814
+ }
815
+ }
816
+ async _calculateKpiValue(kpi) {
817
+ try {
818
+ const response = await client.mutate({ mutation: gql `
819
+ mutation ($kpiId: String!) { calculateKpiValue(kpiId: $kpiId) { id
820
+ value
821
+ valueDate
822
+ org
823
+ }
824
+ }
825
+ `,
826
+ variables: { kpiId: kpi.id
827
+ }
828
+ });
829
+ if (!response.errors) {
830
+ notify({ message: 'KPI 실적값이 성공적으로 계산되었습니다.' });
831
+ this.grist.fetch();
832
+ }
833
+ }
834
+ catch (error) {
835
+ notify({ message: 'KPI 실적값 계산 중 오류가 발생했습니다.' });
836
+ }
837
+ }
838
+ _toggleHierarchicalView() {
839
+ this.hierarchicalView = !this.hierarchicalView;
840
+ this.grist.fetch();
841
+ }
842
+ async fetchHierarchicalData() {
843
+ const response = await client.query({ query: gql `
844
+ query { kpiTree { id
845
+ name
846
+ description
847
+ active
848
+ formula
849
+ periodType
850
+ scoreType
851
+ scoreFormula
852
+ grades
853
+ vizType
854
+ vizMeta
855
+ weight
856
+ schedule
857
+ scheduleId
858
+ timezone
859
+ version
860
+ parent { id
861
+ name
862
+ }
863
+ children { id
864
+ name
865
+ description
866
+ active
867
+ isLeaf
868
+ weight
869
+ children { id
870
+ name
871
+ description
872
+ active
873
+ isLeaf
874
+ weight
875
+ children { id
876
+ name
877
+ description
878
+ active
879
+ isLeaf
880
+ weight
881
+ }
882
+ }
883
+ }
884
+ isLeaf
885
+ updater { id
886
+ name
887
+ }
888
+ updatedAt
889
+ creator { id
890
+ name
891
+ }
892
+ createdAt
893
+ }
894
+ }
895
+ `
896
+ });
897
+ const flattenedRecords = this.flattenTreeData(response.data.kpiTree);
898
+ return { total: flattenedRecords.length,
899
+ records: flattenedRecords
900
+ };
901
+ }
902
+ flattenTreeData(treeData, level = 0) {
903
+ const flattened = [];
904
+ for (const item of treeData) {
905
+ const flattenedItem = { ...item,
906
+ __level: level,
907
+ __hasChildren: item.children && item.children.length > 0,
908
+ __expanded: true
909
+ };
910
+ // Add indentation to name for visual hierarchy
911
+ flattenedItem.name = ' '.repeat(level) + (level > 0 ? '└ ' : '') + item.name;
912
+ flattened.push(flattenedItem);
913
+ if (item.children && item.children.length > 0) {
914
+ flattened.push(...this.flattenTreeData(item.children, level + 1));
915
+ }
916
+ }
917
+ return flattened;
918
+ }
919
+ };
920
+ __decorate([
921
+ property({ type: Object }),
922
+ __metadata("design:type", Object)
923
+ ], KpiListPage.prototype, "gristConfig", void 0);
924
+ __decorate([
925
+ property({ type: String }),
926
+ __metadata("design:type", String)
927
+ ], KpiListPage.prototype, "mode", void 0);
928
+ __decorate([
929
+ query('ox-grist'),
930
+ __metadata("design:type", DataGrist)
931
+ ], KpiListPage.prototype, "grist", void 0);
932
+ __decorate([
933
+ state(),
934
+ __metadata("design:type", Array)
935
+ ], KpiListPage.prototype, "availableVariables", void 0);
936
+ __decorate([
937
+ state(),
938
+ __metadata("design:type", Object)
939
+ ], KpiListPage.prototype, "availableVariablesLoaded", void 0);
940
+ __decorate([
941
+ state(),
942
+ __metadata("design:type", Object)
943
+ ], KpiListPage.prototype, "hierarchicalView", void 0);
944
+ KpiListPage = __decorate([
945
+ customElement('kpi-list-page')
946
+ ], KpiListPage);
947
+ export { KpiListPage };
948
+ //# sourceMappingURL=kpi-list-page.js.map