@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,562 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import '@material/web/button/elevated-button.js';
3
+ // import '@material/web/select/outlined-select.js'
4
+ import '@material/web/textfield/outlined-text-field.js';
5
+ import '@material/web/icon/icon.js';
6
+ import { css, html, svg, LitElement } from 'lit';
7
+ import { customElement, property } from 'lit/decorators.js';
8
+ import { i18next, localize } from '@operato/i18n';
9
+ import { CommonHeaderStyles, ScrollbarStyles } from '@operato/styles';
10
+ const VIZ_TYPES = [
11
+ { value: 'CARD', label: '카드', icon: 'dashboard' },
12
+ { value: 'GAUGE', label: '게이지', icon: 'speed' },
13
+ { value: 'PROGRESS', label: '진행률', icon: 'linear_scale' },
14
+ { value: 'BAR', label: '막대 차트', icon: 'bar_chart' },
15
+ { value: 'LINE', label: '선 차트', icon: 'show_chart' },
16
+ { value: 'PIE', label: '파이 차트', icon: 'pie_chart' },
17
+ { value: 'DONUT', label: '도넛 차트', icon: 'donut_large' },
18
+ { value: 'RADAR', label: '레이더 차트', icon: 'radar' },
19
+ { value: 'BULLET', label: '불릿 차트', icon: 'track_changes' },
20
+ { value: 'THERMOMETER', label: '온도계', icon: 'thermostat' },
21
+ { value: 'SPEEDOMETER', label: '속도계', icon: 'speed' },
22
+ { value: 'ICON', label: '아이콘', icon: 'emoji_events' },
23
+ { value: 'BADGE', label: '배지', icon: 'badge' },
24
+ { value: 'TEXT', label: '텍스트', icon: 'text_fields' },
25
+ { value: 'TABLE', label: '테이블', icon: 'table_chart' }
26
+ ];
27
+ let KpiVizEditor = class KpiVizEditor extends localize(i18next)(LitElement) {
28
+ constructor() {
29
+ super(...arguments);
30
+ this.kpi = null;
31
+ this.selectedVizType = 'CARD';
32
+ this.vizMeta = {};
33
+ this.onSave = () => { };
34
+ this.onCancel = () => { };
35
+ }
36
+ static { this.styles = [
37
+ CommonHeaderStyles,
38
+ ScrollbarStyles,
39
+ css `
40
+ :host {
41
+ display: flex;
42
+ flex-direction: column;
43
+ background-color: var(--md-sys-color-surface, #f4f6fa);
44
+ }
45
+
46
+ .viz-editor {
47
+ flex: 1;
48
+ display: flex;
49
+ flex-direction: column;
50
+ overflow-y: auto;
51
+
52
+ background: white;
53
+ padding: 24px;
54
+ }
55
+
56
+ .form-group {
57
+ margin-bottom: 20px;
58
+ }
59
+
60
+ .form-group label {
61
+ display: block;
62
+ margin-bottom: 8px;
63
+ font-weight: 500;
64
+ color: #555;
65
+ }
66
+
67
+ .form-options {
68
+ flex: 1;
69
+ display: flex;
70
+ flex-direction: row;
71
+ }
72
+
73
+ .viz-type-grid {
74
+ display: grid;
75
+ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
76
+ gap: 12px;
77
+ margin-bottom: 20px;
78
+ }
79
+
80
+ .viz-type-option {
81
+ display: flex;
82
+ flex-direction: column;
83
+ align-items: center;
84
+ padding: 16px 12px;
85
+ border: 2px solid #e0e0e0;
86
+ border-radius: 8px;
87
+ cursor: pointer;
88
+ transition: all 0.2s;
89
+ text-align: center;
90
+ }
91
+
92
+ .viz-type-option:hover {
93
+ border-color: #2196f3;
94
+ background: #f5f9ff;
95
+ }
96
+
97
+ .viz-type-option.selected {
98
+ border-color: #2196f3;
99
+ background: #e3f2fd;
100
+ }
101
+
102
+ .viz-type-option md-icon {
103
+ font-size: 24px;
104
+ margin-bottom: 8px;
105
+ color: #666;
106
+ }
107
+
108
+ .viz-type-option.selected md-icon {
109
+ color: #2196f3;
110
+ }
111
+
112
+ .viz-type-option .label {
113
+ font-size: 0.9rem;
114
+ font-weight: 500;
115
+ color: #333;
116
+ }
117
+
118
+ .viz-meta-section {
119
+ margin-top: 24px;
120
+ padding-top: 20px;
121
+ border-top: 1px solid #eee;
122
+ }
123
+
124
+ .color-picker {
125
+ display: flex;
126
+ gap: 12px;
127
+ align-items: center;
128
+ margin-bottom: 16px;
129
+ }
130
+
131
+ .color-input {
132
+ width: 60px;
133
+ height: 40px;
134
+ border: none;
135
+ border-radius: 6px;
136
+ cursor: pointer;
137
+ }
138
+
139
+ .buttons {
140
+ display: flex;
141
+ gap: 12px;
142
+ justify-content: flex-end;
143
+ margin-top: 24px;
144
+ padding-top: 20px;
145
+ border-top: 1px solid #eee;
146
+ }
147
+
148
+ .preview {
149
+ flex: 1;
150
+ margin: 30px 16px 16px 16px;
151
+ padding: 16px;
152
+ background: #f8f9fa;
153
+ border-radius: 8px;
154
+ border: 1px solid #e9ecef;
155
+ }
156
+
157
+ .preview h4 {
158
+ margin: 0 0 12px 0;
159
+ color: #495057;
160
+ font-size: 0.95rem;
161
+ }
162
+
163
+ .footer span {
164
+ font-size: 0.8em;
165
+ color: var(--md-sys-color-on-surface);
166
+ line-height: 1.5;
167
+ padding: 10px;
168
+ }
169
+ `
170
+ ]; }
171
+ connectedCallback() {
172
+ super.connectedCallback();
173
+ if (this.kpi) {
174
+ this.selectedVizType = this.kpi.vizType || 'CARD';
175
+ this.vizMeta = this.kpi.vizMeta || {};
176
+ }
177
+ }
178
+ _selectVizType(type) {
179
+ this.selectedVizType = type;
180
+ this.requestUpdate();
181
+ }
182
+ _updateVizMeta(key, value) {
183
+ this.vizMeta = { ...this.vizMeta, [key]: value };
184
+ this.requestUpdate();
185
+ }
186
+ _renderPreview() {
187
+ const kpiValue = this.kpi?.value?.value ?? 75;
188
+ const targetValue = this.kpi?.targetValue ?? 100;
189
+ const unit = this.kpi?.unit ?? '';
190
+ const color = this.vizMeta.color || '#2196f3';
191
+ const icon = this.vizMeta.icon || 'trending_up';
192
+ const min = this.vizMeta.minValue ?? 0;
193
+ const max = this.vizMeta.maxValue ?? 100;
194
+ switch (this.selectedVizType) {
195
+ case 'CARD':
196
+ return html `
197
+ <div
198
+ style="display:flex;align-items:center;gap:12px;padding:16px;background:white;border-radius:8px;border:1px solid #e0e0e0;"
199
+ >
200
+ <md-icon style="color:${color};font-size:32px;">${icon}</md-icon>
201
+ <div>
202
+ <div style="font-size:1.5rem;font-weight:bold;color:${color};">${kpiValue}${unit}</div>
203
+ <div style="font-size:0.9rem;color:#666;">목표: ${targetValue}${unit}</div>
204
+ </div>
205
+ </div>
206
+ `;
207
+ case 'GAUGE': {
208
+ const value = Math.max(min, Math.min(kpiValue, max));
209
+ const percent = max - min > 0 ? (value - min) / (max - min) : 0;
210
+ const r = 60;
211
+ const cx = 90;
212
+ const cy = 90;
213
+ const startX = cx - r;
214
+ const startY = cy;
215
+ const endX = cx + r * Math.cos(Math.PI * (1 - percent));
216
+ const endY = cy - r * Math.sin(Math.PI * (1 - percent));
217
+ const needleAngle = Math.PI - Math.PI * percent;
218
+ const needleX = cx + r * Math.cos(needleAngle);
219
+ const needleY = cy - r * Math.sin(needleAngle);
220
+ return html `
221
+ <div style="text-align:center;padding:16px;">
222
+ <svg width="180" height="110" viewBox="0 0 180 110">
223
+ <!-- 배경 arc -->
224
+ <path
225
+ d="M${startX},${startY} A${r},${r} 0 0,1 ${cx + r},${cy}"
226
+ fill="none"
227
+ stroke="#e0e0e0"
228
+ stroke-width="16"
229
+ />
230
+ <!-- 값 arc -->
231
+ <path
232
+ d="M${startX},${startY} A${r},${r} 0 0,1 ${endX},${endY}"
233
+ fill="none"
234
+ stroke="${color}"
235
+ stroke-width="16"
236
+ />
237
+ <!-- 바늘 -->
238
+ <line x1="${cx}" y1="${cy}" x2="${needleX}" y2="${needleY}" stroke="#333" stroke-width="4" />
239
+ <!-- 중심 원 -->
240
+ <circle cx="${cx}" cy="${cy}" r="7" fill="#333" />
241
+ <!-- 중앙값 -->
242
+ <text x="${cx}" y="${cy - 25}" text-anchor="middle" font-size="22" fill="${color}" font-weight="bold">
243
+ ${value}${unit}
244
+ </text>
245
+ <!-- min/max -->
246
+ <text x="${cx - r}" y="${cy + 20}" text-anchor="middle" font-size="12" fill="#888">${min}</text>
247
+ <text x="${cx + r}" y="${cy + 20}" text-anchor="middle" font-size="12" fill="#888">${max}</text>
248
+ </svg>
249
+ </div>
250
+ `;
251
+ }
252
+ case 'SPEEDOMETER': {
253
+ const value = Math.max(min, Math.min(kpiValue, max));
254
+ const percent = max - min > 0 ? (value - min) / (max - min) : 0;
255
+ const r = 60;
256
+ const cx = 90;
257
+ const cy = 90;
258
+ const startX = cx - r;
259
+ const startY = cy;
260
+ const endX = cx + r * Math.cos(Math.PI * (1 - percent));
261
+ const endY = cy - r * Math.sin(Math.PI * (1 - percent));
262
+ const needleAngle = Math.PI - Math.PI * percent;
263
+ const needleX = cx + r * Math.cos(needleAngle);
264
+ const needleY = cy - r * Math.sin(needleAngle);
265
+ // 중간 눈금 (5개)
266
+ const ticks = Array.from({ length: 6 }, (_, i) => {
267
+ const tickAngle = Math.PI - (Math.PI * i) / 5;
268
+ const tx1 = cx + (r - 8) * Math.cos(tickAngle);
269
+ const ty1 = cy - (r - 8) * Math.sin(tickAngle);
270
+ const tx2 = cx + (r + 8) * Math.cos(tickAngle);
271
+ const ty2 = cy - (r + 8) * Math.sin(tickAngle);
272
+ const label = Math.round(min + (max - min) * (i / 5));
273
+ const lx = cx + (r + 22) * Math.cos(tickAngle);
274
+ const ly = cy - (r + 22) * Math.sin(tickAngle) + 6;
275
+ return { tx1, ty1, tx2, ty2, label, lx, ly };
276
+ });
277
+ return html `
278
+ <div style="text-align:center;padding:16px;">
279
+ <svg width="200" height="120" viewBox="0 0 200 120">
280
+ <!-- 배경 arc (더 두껍게) -->
281
+ <path
282
+ d="M${startX + 10},${startY} A${r},${r} 0 0,1 ${cx + r + 10},${cy}"
283
+ fill="none"
284
+ stroke="#e0e0e0"
285
+ stroke-width="28"
286
+ />
287
+ <!-- 값 arc -->
288
+ <path
289
+ d="M${startX + 10},${startY} A${r},${r} 0 0,1 ${endX + 10},${endY}"
290
+ fill="none"
291
+ stroke="${color}"
292
+ stroke-width="28"
293
+ />
294
+ <!-- 눈금 -->
295
+ <!--
296
+ 조각은 svg 태그로 만든다 — html 로 만들면 HTML 이름공간의 노드가 되어 <svg> 안에서
297
+ **소리 없이 안 그려진다**(오류도 경고도 없다). 눈금과 눈금 숫자가 그래서 없었다.
298
+ -->
299
+ ${ticks.map(t => svg `<line
300
+ x1="${t.tx1 + 10}"
301
+ y1="${t.ty1}"
302
+ x2="${t.tx2 + 10}"
303
+ y2="${t.ty2}"
304
+ stroke="#888"
305
+ stroke-width="2"
306
+ />`)}
307
+ <!-- 눈금 숫자 -->
308
+ ${ticks.map(t => svg `<text
309
+ x="${t.lx + 10}"
310
+ y="${t.ly}"
311
+ text-anchor="middle"
312
+ font-size="14"
313
+ fill="#333"
314
+ font-weight="bold"
315
+ >${t.label}</text
316
+ >`)}
317
+ <!-- 바늘 (빨간색) -->
318
+ <line x1="${cx + 10}" y1="${cy}" x2="${needleX + 10}" y2="${needleY}" stroke="#d32f2f" stroke-width="6" />
319
+ <!-- 중심 원 -->
320
+ <circle cx="${cx + 10}" cy="${cy}" r="13" fill="#333" />
321
+ <!-- 중앙값 -->
322
+ <text
323
+ x="${cx + 10}"
324
+ y="${cy - 32}"
325
+ text-anchor="middle"
326
+ font-size="26"
327
+ fill="${color}"
328
+ font-weight="bold"
329
+ >
330
+ ${value}${unit}
331
+ </text>
332
+ <!-- min/max 포인트 -->
333
+ <circle cx="${startX + 10}" cy="${startY}" r="7" fill="#fff" stroke="#888" stroke-width="2" />
334
+ <circle cx="${cx + r + 10}" cy="${cy}" r="7" fill="#fff" stroke="#888" stroke-width="2" />
335
+ <!-- min/max 숫자 크게 -->
336
+ <text
337
+ x="${startX + 10}"
338
+ y="${startY + 32}"
339
+ text-anchor="middle"
340
+ font-size="16"
341
+ fill="#333"
342
+ font-weight="bold"
343
+ >
344
+ ${min}
345
+ </text>
346
+ <text
347
+ x="${cx + r + 10}"
348
+ y="${cy + 32}"
349
+ text-anchor="middle"
350
+ font-size="16"
351
+ fill="#333"
352
+ font-weight="bold"
353
+ >
354
+ ${max}
355
+ </text>
356
+ </svg>
357
+ </div>
358
+ `;
359
+ }
360
+ case 'PROGRESS':
361
+ const progressPercentage = Math.min((kpiValue / targetValue) * 100, 100);
362
+ return html `
363
+ <div style="padding:16px;">
364
+ <div style="background:#e0e0e0;height:20px;border-radius:10px;overflow:hidden;">
365
+ <div style="background:${color};height:100%;width:${progressPercentage}%;transition:width 0.3s;"></div>
366
+ </div>
367
+ <div style="text-align:center;margin-top:8px;font-weight:bold;color:${color};">
368
+ ${kpiValue}${unit} / ${targetValue}${unit}
369
+ </div>
370
+ </div>
371
+ `;
372
+ case 'THERMOMETER': {
373
+ const value = Math.max(min, Math.min(kpiValue, max));
374
+ const percent = max - min > 0 ? (value - min) / (max - min) : 0;
375
+ const barHeight = 120;
376
+ const barWidth = 24;
377
+ const x = 100;
378
+ const yTop = 30;
379
+ const yBottom = yTop + barHeight;
380
+ const fillY = yBottom - percent * barHeight;
381
+ return html `
382
+ <div style="text-align:center;padding:16px;">
383
+ <svg width="200" height="180" viewBox="0 0 200 180">
384
+ <!-- 바깥 테두리 -->
385
+ <rect
386
+ x="${x - barWidth / 2 - 4}"
387
+ y="${yTop - 4}"
388
+ width="${barWidth + 8}"
389
+ height="${barHeight + 8}"
390
+ rx="16"
391
+ fill="#f5f5f5"
392
+ stroke="#bbb"
393
+ stroke-width="2"
394
+ />
395
+ <!-- 빈 막대 -->
396
+ <rect
397
+ x="${x - barWidth / 2}"
398
+ y="${yTop}"
399
+ width="${barWidth}"
400
+ height="${barHeight}"
401
+ rx="12"
402
+ fill="#e0e0e0"
403
+ />
404
+ <!-- 채워진 부분 -->
405
+ <rect
406
+ x="${x - barWidth / 2}"
407
+ y="${fillY}"
408
+ width="${barWidth}"
409
+ height="${yBottom - fillY}"
410
+ rx="12"
411
+ fill="${color}"
412
+ />
413
+ <!-- 하단 구슬 -->
414
+ <circle cx="${x}" cy="${yBottom + 18}" r="22" fill="#e0e0e0" stroke="#bbb" stroke-width="2" />
415
+ <circle cx="${x}" cy="${yBottom + 18}" r="18" fill="${color}" />
416
+ <!-- 현재값 -->
417
+ <text x="${x}" y="${fillY - 12}" text-anchor="middle" font-size="22" fill="${color}" font-weight="bold">
418
+ ${value}${unit}
419
+ </text>
420
+ <!-- min/max -->
421
+ <text x="${x}" y="${yBottom + 52}" text-anchor="middle" font-size="16" fill="#333" font-weight="bold">
422
+ ${min}
423
+ </text>
424
+ <text x="${x}" y="${yTop - 12}" text-anchor="middle" font-size="16" fill="#333" font-weight="bold">
425
+ ${max}
426
+ </text>
427
+ </svg>
428
+ </div>
429
+ `;
430
+ }
431
+ case 'ICON':
432
+ return html `
433
+ <div style="text-align:center;padding:16px;">
434
+ <md-icon style="color:${color};font-size:48px;">${icon}</md-icon>
435
+ <div style="font-size:1.2rem;font-weight:bold;color:${color};margin-top:8px;">${kpiValue}${unit}</div>
436
+ </div>
437
+ `;
438
+ default:
439
+ return html ` <div style="padding:16px;text-align:center;color:#666;">${this.selectedVizType} 미리보기</div> `;
440
+ }
441
+ }
442
+ render() {
443
+ return html `
444
+ <div class="viz-editor">
445
+ <div class="form-group">
446
+ <label>시각화 타입 선택</label>
447
+ <div class="viz-type-grid">
448
+ ${VIZ_TYPES.map(type => html `
449
+ <div
450
+ class="viz-type-option ${this.selectedVizType === type.value ? 'selected' : ''}"
451
+ @click=${() => this._selectVizType(type.value)}
452
+ >
453
+ <md-icon>${type.icon}</md-icon>
454
+ <div class="label">${type.label}</div>
455
+ </div>
456
+ `)}
457
+ </div>
458
+ </div>
459
+
460
+ <div class="form-options">
461
+ <div class="viz-meta-section">
462
+ <label>시각화 옵션</label>
463
+
464
+ <div class="form-group">
465
+ <label>색상</label>
466
+ <div class="color-picker">
467
+ <input
468
+ type="color"
469
+ class="color-input"
470
+ .value=${this.vizMeta.color || '#2196f3'}
471
+ @change=${(e) => this._updateVizMeta('color', e.target.value)}
472
+ />
473
+ <md-outlined-text-field
474
+ label="색상 코드"
475
+ .value=${this.vizMeta.color || '#2196f3'}
476
+ @change=${(e) => this._updateVizMeta('color', e.target.value)}
477
+ ></md-outlined-text-field>
478
+ </div>
479
+ </div>
480
+
481
+ <div class="form-group">
482
+ <label>아이콘</label>
483
+ <md-outlined-text-field
484
+ label="Material Icons 이름"
485
+ .value=${this.vizMeta.icon || 'trending_up'}
486
+ @change=${(e) => this._updateVizMeta('icon', e.target.value)}
487
+ ></md-outlined-text-field>
488
+ </div>
489
+
490
+ <div class="form-group">
491
+ <label>최소값</label>
492
+ <md-outlined-text-field
493
+ type="number"
494
+ label="최소값"
495
+ .value=${this.vizMeta.minValue || 0}
496
+ @change=${(e) => this._updateVizMeta('minValue', parseFloat(e.target.value))}
497
+ ></md-outlined-text-field>
498
+ </div>
499
+
500
+ <div class="form-group">
501
+ <label>최대값</label>
502
+ <md-outlined-text-field
503
+ type="number"
504
+ label="최대값"
505
+ .value=${this.vizMeta.maxValue || 100}
506
+ @change=${(e) => this._updateVizMeta('maxValue', parseFloat(e.target.value))}
507
+ ></md-outlined-text-field>
508
+ </div>
509
+
510
+ <div class="form-group">
511
+ <label>소수점 자릿수</label>
512
+ <md-outlined-text-field
513
+ type="number"
514
+ label="소수점 자릿수"
515
+ .value=${this.vizMeta.decimalPlaces || 0}
516
+ @change=${(e) => this._updateVizMeta('decimalPlaces', parseInt(e.target.value))}
517
+ ></md-outlined-text-field>
518
+ </div>
519
+ </div>
520
+
521
+ <div class="preview">
522
+ <h4>미리보기</h4>
523
+ ${this._renderPreview()}
524
+ </div>
525
+ </div>
526
+ </div>
527
+
528
+ <div class="footer">
529
+ <div filler></div>
530
+ <button type="button" @click=${this.onCancel}><md-icon>cancel</md-icon>취소</button>
531
+ <button type="button" @click=${() => this.onSave(this.selectedVizType, this.vizMeta)} done>
532
+ <md-icon>save</md-icon>저장
533
+ </button>
534
+ </div>
535
+ `;
536
+ }
537
+ };
538
+ __decorate([
539
+ property({ type: Object }),
540
+ __metadata("design:type", Object)
541
+ ], KpiVizEditor.prototype, "kpi", void 0);
542
+ __decorate([
543
+ property({ type: String }),
544
+ __metadata("design:type", String)
545
+ ], KpiVizEditor.prototype, "selectedVizType", void 0);
546
+ __decorate([
547
+ property({ type: Object }),
548
+ __metadata("design:type", Object)
549
+ ], KpiVizEditor.prototype, "vizMeta", void 0);
550
+ __decorate([
551
+ property({ type: Object }),
552
+ __metadata("design:type", Function)
553
+ ], KpiVizEditor.prototype, "onSave", void 0);
554
+ __decorate([
555
+ property({ type: Object }),
556
+ __metadata("design:type", Function)
557
+ ], KpiVizEditor.prototype, "onCancel", void 0);
558
+ KpiVizEditor = __decorate([
559
+ customElement('kpi-viz-editor')
560
+ ], KpiVizEditor);
561
+ export { KpiVizEditor };
562
+ //# sourceMappingURL=kpi-viz-editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-viz-editor.js","sourceRoot":"","sources":["../../../client/pages/kpi/kpi-viz-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/button/elevated-button.js'\n// import '@material/web/select/outlined-select.js'\nimport '@material/web/textfield/outlined-text-field.js'\nimport '@material/web/icon/icon.js'\n\nimport { PageView } from '@operato/shell'\nimport { css, html, svg, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { notify } from '@operato/layout'\nimport { OxPopup } from '@operato/popup'\nimport gql from 'graphql-tag'\nimport { CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'\n\nconst VIZ_TYPES = [\n { value: 'CARD', label: '카드', icon: 'dashboard' },\n { value: 'GAUGE', label: '게이지', icon: 'speed' },\n { value: 'PROGRESS', label: '진행률', icon: 'linear_scale' },\n { value: 'BAR', label: '막대 차트', icon: 'bar_chart' },\n { value: 'LINE', label: '선 차트', icon: 'show_chart' },\n { value: 'PIE', label: '파이 차트', icon: 'pie_chart' },\n { value: 'DONUT', label: '도넛 차트', icon: 'donut_large' },\n { value: 'RADAR', label: '레이더 차트', icon: 'radar' },\n { value: 'BULLET', label: '불릿 차트', icon: 'track_changes' },\n { value: 'THERMOMETER', label: '온도계', icon: 'thermostat' },\n { value: 'SPEEDOMETER', label: '속도계', icon: 'speed' },\n { value: 'ICON', label: '아이콘', icon: 'emoji_events' },\n { value: 'BADGE', label: '배지', icon: 'badge' },\n { value: 'TEXT', label: '텍스트', icon: 'text_fields' },\n { value: 'TABLE', label: '테이블', icon: 'table_chart' }\n]\n\n@customElement('kpi-viz-editor')\nexport class KpiVizEditor extends localize(i18next)(LitElement) {\n static styles = [\n CommonHeaderStyles,\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n background-color: var(--md-sys-color-surface, #f4f6fa);\n }\n\n .viz-editor {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n\n background: white;\n padding: 24px;\n }\n\n .form-group {\n margin-bottom: 20px;\n }\n\n .form-group label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #555;\n }\n\n .form-options {\n flex: 1;\n display: flex;\n flex-direction: row;\n }\n\n .viz-type-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));\n gap: 12px;\n margin-bottom: 20px;\n }\n\n .viz-type-option {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 16px 12px;\n border: 2px solid #e0e0e0;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n text-align: center;\n }\n\n .viz-type-option:hover {\n border-color: #2196f3;\n background: #f5f9ff;\n }\n\n .viz-type-option.selected {\n border-color: #2196f3;\n background: #e3f2fd;\n }\n\n .viz-type-option md-icon {\n font-size: 24px;\n margin-bottom: 8px;\n color: #666;\n }\n\n .viz-type-option.selected md-icon {\n color: #2196f3;\n }\n\n .viz-type-option .label {\n font-size: 0.9rem;\n font-weight: 500;\n color: #333;\n }\n\n .viz-meta-section {\n margin-top: 24px;\n padding-top: 20px;\n border-top: 1px solid #eee;\n }\n\n .color-picker {\n display: flex;\n gap: 12px;\n align-items: center;\n margin-bottom: 16px;\n }\n\n .color-input {\n width: 60px;\n height: 40px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n }\n\n .buttons {\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n margin-top: 24px;\n padding-top: 20px;\n border-top: 1px solid #eee;\n }\n\n .preview {\n flex: 1;\n margin: 30px 16px 16px 16px;\n padding: 16px;\n background: #f8f9fa;\n border-radius: 8px;\n border: 1px solid #e9ecef;\n }\n\n .preview h4 {\n margin: 0 0 12px 0;\n color: #495057;\n font-size: 0.95rem;\n }\n\n .footer span {\n font-size: 0.8em;\n color: var(--md-sys-color-on-surface);\n line-height: 1.5;\n padding: 10px;\n }\n `\n ]\n\n @property({ type: Object }) kpi: any = null\n @property({ type: String }) selectedVizType: string = 'CARD'\n @property({ type: Object }) vizMeta: any = {}\n @property({ type: Object }) onSave: Function = () => {}\n @property({ type: Object }) onCancel: Function = () => {}\n\n connectedCallback() {\n super.connectedCallback()\n if (this.kpi) {\n this.selectedVizType = this.kpi.vizType || 'CARD'\n this.vizMeta = this.kpi.vizMeta || {}\n }\n }\n\n _selectVizType(type: string) {\n this.selectedVizType = type\n this.requestUpdate()\n }\n\n _updateVizMeta(key: string, value: any) {\n this.vizMeta = { ...this.vizMeta, [key]: value }\n this.requestUpdate()\n }\n\n _renderPreview() {\n const kpiValue = this.kpi?.value?.value ?? 75\n const targetValue = this.kpi?.targetValue ?? 100\n const unit = this.kpi?.unit ?? ''\n const color = this.vizMeta.color || '#2196f3'\n const icon = this.vizMeta.icon || 'trending_up'\n const min = this.vizMeta.minValue ?? 0\n const max = this.vizMeta.maxValue ?? 100\n\n switch (this.selectedVizType) {\n case 'CARD':\n return html`\n <div\n style=\"display:flex;align-items:center;gap:12px;padding:16px;background:white;border-radius:8px;border:1px solid #e0e0e0;\"\n >\n <md-icon style=\"color:${color};font-size:32px;\">${icon}</md-icon>\n <div>\n <div style=\"font-size:1.5rem;font-weight:bold;color:${color};\">${kpiValue}${unit}</div>\n <div style=\"font-size:0.9rem;color:#666;\">목표: ${targetValue}${unit}</div>\n </div>\n </div>\n `\n case 'GAUGE': {\n const value = Math.max(min, Math.min(kpiValue, max))\n const percent = max - min > 0 ? (value - min) / (max - min) : 0\n const r = 60\n const cx = 90\n const cy = 90\n const startX = cx - r\n const startY = cy\n const endX = cx + r * Math.cos(Math.PI * (1 - percent))\n const endY = cy - r * Math.sin(Math.PI * (1 - percent))\n const needleAngle = Math.PI - Math.PI * percent\n const needleX = cx + r * Math.cos(needleAngle)\n const needleY = cy - r * Math.sin(needleAngle)\n return html`\n <div style=\"text-align:center;padding:16px;\">\n <svg width=\"180\" height=\"110\" viewBox=\"0 0 180 110\">\n <!-- 배경 arc -->\n <path\n d=\"M${startX},${startY} A${r},${r} 0 0,1 ${cx + r},${cy}\"\n fill=\"none\"\n stroke=\"#e0e0e0\"\n stroke-width=\"16\"\n />\n <!-- 값 arc -->\n <path\n d=\"M${startX},${startY} A${r},${r} 0 0,1 ${endX},${endY}\"\n fill=\"none\"\n stroke=\"${color}\"\n stroke-width=\"16\"\n />\n <!-- 바늘 -->\n <line x1=\"${cx}\" y1=\"${cy}\" x2=\"${needleX}\" y2=\"${needleY}\" stroke=\"#333\" stroke-width=\"4\" />\n <!-- 중심 원 -->\n <circle cx=\"${cx}\" cy=\"${cy}\" r=\"7\" fill=\"#333\" />\n <!-- 중앙값 -->\n <text x=\"${cx}\" y=\"${cy - 25}\" text-anchor=\"middle\" font-size=\"22\" fill=\"${color}\" font-weight=\"bold\">\n ${value}${unit}\n </text>\n <!-- min/max -->\n <text x=\"${cx - r}\" y=\"${cy + 20}\" text-anchor=\"middle\" font-size=\"12\" fill=\"#888\">${min}</text>\n <text x=\"${cx + r}\" y=\"${cy + 20}\" text-anchor=\"middle\" font-size=\"12\" fill=\"#888\">${max}</text>\n </svg>\n </div>\n `\n }\n case 'SPEEDOMETER': {\n const value = Math.max(min, Math.min(kpiValue, max))\n const percent = max - min > 0 ? (value - min) / (max - min) : 0\n const r = 60\n const cx = 90\n const cy = 90\n const startX = cx - r\n const startY = cy\n const endX = cx + r * Math.cos(Math.PI * (1 - percent))\n const endY = cy - r * Math.sin(Math.PI * (1 - percent))\n const needleAngle = Math.PI - Math.PI * percent\n const needleX = cx + r * Math.cos(needleAngle)\n const needleY = cy - r * Math.sin(needleAngle)\n // 중간 눈금 (5개)\n const ticks = Array.from({ length: 6 }, (_, i) => {\n const tickAngle = Math.PI - (Math.PI * i) / 5\n const tx1 = cx + (r - 8) * Math.cos(tickAngle)\n const ty1 = cy - (r - 8) * Math.sin(tickAngle)\n const tx2 = cx + (r + 8) * Math.cos(tickAngle)\n const ty2 = cy - (r + 8) * Math.sin(tickAngle)\n const label = Math.round(min + (max - min) * (i / 5))\n const lx = cx + (r + 22) * Math.cos(tickAngle)\n const ly = cy - (r + 22) * Math.sin(tickAngle) + 6\n return { tx1, ty1, tx2, ty2, label, lx, ly }\n })\n return html`\n <div style=\"text-align:center;padding:16px;\">\n <svg width=\"200\" height=\"120\" viewBox=\"0 0 200 120\">\n <!-- 배경 arc (더 두껍게) -->\n <path\n d=\"M${startX + 10},${startY} A${r},${r} 0 0,1 ${cx + r + 10},${cy}\"\n fill=\"none\"\n stroke=\"#e0e0e0\"\n stroke-width=\"28\"\n />\n <!-- 값 arc -->\n <path\n d=\"M${startX + 10},${startY} A${r},${r} 0 0,1 ${endX + 10},${endY}\"\n fill=\"none\"\n stroke=\"${color}\"\n stroke-width=\"28\"\n />\n <!-- 눈금 -->\n <!--\n 조각은 svg 태그로 만든다 — html 로 만들면 HTML 이름공간의 노드가 되어 <svg> 안에서\n **소리 없이 안 그려진다**(오류도 경고도 없다). 눈금과 눈금 숫자가 그래서 없었다.\n -->\n ${ticks.map(\n t =>\n svg`<line\n x1=\"${t.tx1 + 10}\"\n y1=\"${t.ty1}\"\n x2=\"${t.tx2 + 10}\"\n y2=\"${t.ty2}\"\n stroke=\"#888\"\n stroke-width=\"2\"\n />`\n )}\n <!-- 눈금 숫자 -->\n ${ticks.map(\n t =>\n svg`<text\n x=\"${t.lx + 10}\"\n y=\"${t.ly}\"\n text-anchor=\"middle\"\n font-size=\"14\"\n fill=\"#333\"\n font-weight=\"bold\"\n >${t.label}</text\n >`\n )}\n <!-- 바늘 (빨간색) -->\n <line x1=\"${cx + 10}\" y1=\"${cy}\" x2=\"${needleX + 10}\" y2=\"${needleY}\" stroke=\"#d32f2f\" stroke-width=\"6\" />\n <!-- 중심 원 -->\n <circle cx=\"${cx + 10}\" cy=\"${cy}\" r=\"13\" fill=\"#333\" />\n <!-- 중앙값 -->\n <text\n x=\"${cx + 10}\"\n y=\"${cy - 32}\"\n text-anchor=\"middle\"\n font-size=\"26\"\n fill=\"${color}\"\n font-weight=\"bold\"\n >\n ${value}${unit}\n </text>\n <!-- min/max 포인트 -->\n <circle cx=\"${startX + 10}\" cy=\"${startY}\" r=\"7\" fill=\"#fff\" stroke=\"#888\" stroke-width=\"2\" />\n <circle cx=\"${cx + r + 10}\" cy=\"${cy}\" r=\"7\" fill=\"#fff\" stroke=\"#888\" stroke-width=\"2\" />\n <!-- min/max 숫자 크게 -->\n <text\n x=\"${startX + 10}\"\n y=\"${startY + 32}\"\n text-anchor=\"middle\"\n font-size=\"16\"\n fill=\"#333\"\n font-weight=\"bold\"\n >\n ${min}\n </text>\n <text\n x=\"${cx + r + 10}\"\n y=\"${cy + 32}\"\n text-anchor=\"middle\"\n font-size=\"16\"\n fill=\"#333\"\n font-weight=\"bold\"\n >\n ${max}\n </text>\n </svg>\n </div>\n `\n }\n case 'PROGRESS':\n const progressPercentage = Math.min((kpiValue / targetValue) * 100, 100)\n return html`\n <div style=\"padding:16px;\">\n <div style=\"background:#e0e0e0;height:20px;border-radius:10px;overflow:hidden;\">\n <div style=\"background:${color};height:100%;width:${progressPercentage}%;transition:width 0.3s;\"></div>\n </div>\n <div style=\"text-align:center;margin-top:8px;font-weight:bold;color:${color};\">\n ${kpiValue}${unit} / ${targetValue}${unit}\n </div>\n </div>\n `\n case 'THERMOMETER': {\n const value = Math.max(min, Math.min(kpiValue, max))\n const percent = max - min > 0 ? (value - min) / (max - min) : 0\n const barHeight = 120\n const barWidth = 24\n const x = 100\n const yTop = 30\n const yBottom = yTop + barHeight\n const fillY = yBottom - percent * barHeight\n return html`\n <div style=\"text-align:center;padding:16px;\">\n <svg width=\"200\" height=\"180\" viewBox=\"0 0 200 180\">\n <!-- 바깥 테두리 -->\n <rect\n x=\"${x - barWidth / 2 - 4}\"\n y=\"${yTop - 4}\"\n width=\"${barWidth + 8}\"\n height=\"${barHeight + 8}\"\n rx=\"16\"\n fill=\"#f5f5f5\"\n stroke=\"#bbb\"\n stroke-width=\"2\"\n />\n <!-- 빈 막대 -->\n <rect\n x=\"${x - barWidth / 2}\"\n y=\"${yTop}\"\n width=\"${barWidth}\"\n height=\"${barHeight}\"\n rx=\"12\"\n fill=\"#e0e0e0\"\n />\n <!-- 채워진 부분 -->\n <rect\n x=\"${x - barWidth / 2}\"\n y=\"${fillY}\"\n width=\"${barWidth}\"\n height=\"${yBottom - fillY}\"\n rx=\"12\"\n fill=\"${color}\"\n />\n <!-- 하단 구슬 -->\n <circle cx=\"${x}\" cy=\"${yBottom + 18}\" r=\"22\" fill=\"#e0e0e0\" stroke=\"#bbb\" stroke-width=\"2\" />\n <circle cx=\"${x}\" cy=\"${yBottom + 18}\" r=\"18\" fill=\"${color}\" />\n <!-- 현재값 -->\n <text x=\"${x}\" y=\"${fillY - 12}\" text-anchor=\"middle\" font-size=\"22\" fill=\"${color}\" font-weight=\"bold\">\n ${value}${unit}\n </text>\n <!-- min/max -->\n <text x=\"${x}\" y=\"${yBottom + 52}\" text-anchor=\"middle\" font-size=\"16\" fill=\"#333\" font-weight=\"bold\">\n ${min}\n </text>\n <text x=\"${x}\" y=\"${yTop - 12}\" text-anchor=\"middle\" font-size=\"16\" fill=\"#333\" font-weight=\"bold\">\n ${max}\n </text>\n </svg>\n </div>\n `\n }\n case 'ICON':\n return html`\n <div style=\"text-align:center;padding:16px;\">\n <md-icon style=\"color:${color};font-size:48px;\">${icon}</md-icon>\n <div style=\"font-size:1.2rem;font-weight:bold;color:${color};margin-top:8px;\">${kpiValue}${unit}</div>\n </div>\n `\n default:\n return html` <div style=\"padding:16px;text-align:center;color:#666;\">${this.selectedVizType} 미리보기</div> `\n }\n }\n\n render() {\n return html`\n <div class=\"viz-editor\">\n <div class=\"form-group\">\n <label>시각화 타입 선택</label>\n <div class=\"viz-type-grid\">\n ${VIZ_TYPES.map(\n type => html`\n <div\n class=\"viz-type-option ${this.selectedVizType === type.value ? 'selected' : ''}\"\n @click=${() => this._selectVizType(type.value)}\n >\n <md-icon>${type.icon}</md-icon>\n <div class=\"label\">${type.label}</div>\n </div>\n `\n )}\n </div>\n </div>\n\n <div class=\"form-options\">\n <div class=\"viz-meta-section\">\n <label>시각화 옵션</label>\n\n <div class=\"form-group\">\n <label>색상</label>\n <div class=\"color-picker\">\n <input\n type=\"color\"\n class=\"color-input\"\n .value=${this.vizMeta.color || '#2196f3'}\n @change=${(e: any) => this._updateVizMeta('color', e.target.value)}\n />\n <md-outlined-text-field\n label=\"색상 코드\"\n .value=${this.vizMeta.color || '#2196f3'}\n @change=${(e: any) => this._updateVizMeta('color', e.target.value)}\n ></md-outlined-text-field>\n </div>\n </div>\n\n <div class=\"form-group\">\n <label>아이콘</label>\n <md-outlined-text-field\n label=\"Material Icons 이름\"\n .value=${this.vizMeta.icon || 'trending_up'}\n @change=${(e: any) => this._updateVizMeta('icon', e.target.value)}\n ></md-outlined-text-field>\n </div>\n\n <div class=\"form-group\">\n <label>최소값</label>\n <md-outlined-text-field\n type=\"number\"\n label=\"최소값\"\n .value=${this.vizMeta.minValue || 0}\n @change=${(e: any) => this._updateVizMeta('minValue', parseFloat(e.target.value))}\n ></md-outlined-text-field>\n </div>\n\n <div class=\"form-group\">\n <label>최대값</label>\n <md-outlined-text-field\n type=\"number\"\n label=\"최대값\"\n .value=${this.vizMeta.maxValue || 100}\n @change=${(e: any) => this._updateVizMeta('maxValue', parseFloat(e.target.value))}\n ></md-outlined-text-field>\n </div>\n\n <div class=\"form-group\">\n <label>소수점 자릿수</label>\n <md-outlined-text-field\n type=\"number\"\n label=\"소수점 자릿수\"\n .value=${this.vizMeta.decimalPlaces || 0}\n @change=${(e: any) => this._updateVizMeta('decimalPlaces', parseInt(e.target.value))}\n ></md-outlined-text-field>\n </div>\n </div>\n\n <div class=\"preview\">\n <h4>미리보기</h4>\n ${this._renderPreview()}\n </div>\n </div>\n </div>\n\n <div class=\"footer\">\n <div filler></div>\n <button type=\"button\" @click=${this.onCancel}><md-icon>cancel</md-icon>취소</button>\n <button type=\"button\" @click=${() => this.onSave(this.selectedVizType, this.vizMeta)} done>\n <md-icon>save</md-icon>저장\n </button>\n </div>\n `\n }\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import { LitElement } from 'lit';
2
+ export declare class KpiLevel1Card extends LitElement {
3
+ static styles: import("lit").CSSResult;
4
+ loading: boolean;
5
+ error: string;
6
+ totalScore: number;
7
+ grade: string;
8
+ totalKpis: number;
9
+ totalCategories: number;
10
+ averageScore: number;
11
+ currentMonth: string;
12
+ connectedCallback(): void;
13
+ private getCurrentMonth;
14
+ private calculateGrade;
15
+ fetchTotalScore(): Promise<void>;
16
+ render(): import("lit-html").TemplateResult<1>;
17
+ }