@things-factory/kpi 1.0.0-alpha.5 → 9.0.9
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.
- package/README.md +74 -0
- package/client/pages/kpi/kpi-list-page.ts +97 -47
- package/client/pages/kpi/kpi-overview-sample.ts +260 -0
- package/client/pages/kpi/kpi-overview.ts +271 -0
- package/client/pages/kpi-category/kpi-category-list-page.ts +39 -50
- package/client/pages/kpi-dashboard/kpi-alert-panel.ts +114 -0
- package/client/pages/kpi-dashboard/kpi-dashboard.ts +285 -0
- package/client/pages/kpi-dashboard/kpi-grade-visualization.ts +75 -0
- package/client/pages/kpi-dashboard/kpi-history-viewer.ts +58 -0
- package/client/pages/kpi-dashboard/kpi-list-summary.ts +100 -0
- package/client/pages/kpi-dashboard/kpi-performance-summary.ts +124 -0
- package/client/pages/kpi-dashboard/kpi-value-entry.ts +78 -0
- package/client/pages/kpi-grade/kpi-grade-list-page.ts +58 -68
- package/client/pages/kpi-history/kpi-history-list-page.ts +146 -0
- package/client/pages/kpi-metric/kpi-metric-list-page.ts +67 -63
- package/client/pages/kpi-value/kpi-value-list-page.ts +73 -72
- package/client/pages/kpi-value/kpi-value-manual-entry-form.ts +168 -0
- package/client/pages/kpi-value/kpi-value-manual-entry-page.ts +173 -0
- package/client/route.ts +35 -0
- package/dist-client/pages/kpi/kpi-importer.js +16 -17
- package/dist-client/pages/kpi/kpi-importer.js.map +1 -1
- package/dist-client/pages/kpi/kpi-list-page.js +128 -68
- package/dist-client/pages/kpi/kpi-list-page.js.map +1 -1
- package/dist-client/pages/kpi/kpi-overview-sample.d.ts +36 -0
- package/dist-client/pages/kpi/kpi-overview-sample.js +264 -0
- package/dist-client/pages/kpi/kpi-overview-sample.js.map +1 -0
- package/dist-client/pages/kpi/kpi-overview.d.ts +14 -0
- package/dist-client/pages/kpi/kpi-overview.js +290 -0
- package/dist-client/pages/kpi/kpi-overview.js.map +1 -0
- package/dist-client/pages/kpi-category/kpi-category-importer.js +16 -17
- package/dist-client/pages/kpi-category/kpi-category-importer.js.map +1 -1
- package/dist-client/pages/kpi-category/kpi-category-list-page.js +70 -71
- package/dist-client/pages/kpi-category/kpi-category-list-page.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/kpi-alert-panel.d.ts +18 -0
- package/dist-client/pages/kpi-dashboard/kpi-alert-panel.js +128 -0
- package/dist-client/pages/kpi-dashboard/kpi-alert-panel.js.map +1 -0
- package/dist-client/pages/kpi-dashboard/kpi-dashboard.d.ts +24 -0
- package/dist-client/pages/kpi-dashboard/kpi-dashboard.js +305 -0
- package/dist-client/pages/kpi-dashboard/kpi-dashboard.js.map +1 -0
- package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.d.ts +12 -0
- package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.js +82 -0
- package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.js.map +1 -0
- package/dist-client/pages/kpi-dashboard/kpi-history-viewer.d.ts +11 -0
- package/dist-client/pages/kpi-dashboard/kpi-history-viewer.js +65 -0
- package/dist-client/pages/kpi-dashboard/kpi-history-viewer.js.map +1 -0
- package/dist-client/pages/kpi-dashboard/kpi-list-summary.d.ts +13 -0
- package/dist-client/pages/kpi-dashboard/kpi-list-summary.js +115 -0
- package/dist-client/pages/kpi-dashboard/kpi-list-summary.js.map +1 -0
- package/dist-client/pages/kpi-dashboard/kpi-performance-summary.d.ts +15 -0
- package/dist-client/pages/kpi-dashboard/kpi-performance-summary.js +139 -0
- package/dist-client/pages/kpi-dashboard/kpi-performance-summary.js.map +1 -0
- package/dist-client/pages/kpi-dashboard/kpi-value-entry.d.ts +7 -0
- package/dist-client/pages/kpi-dashboard/kpi-value-entry.js +86 -0
- package/dist-client/pages/kpi-dashboard/kpi-value-entry.js.map +1 -0
- package/dist-client/pages/kpi-grade/kpi-grade-importer.js +16 -17
- package/dist-client/pages/kpi-grade/kpi-grade-importer.js.map +1 -1
- package/dist-client/pages/kpi-grade/kpi-grade-list-page.js +89 -89
- package/dist-client/pages/kpi-grade/kpi-grade-list-page.js.map +1 -1
- package/dist-client/pages/kpi-history/kpi-history-list-page.d.ts +16 -0
- package/dist-client/pages/kpi-history/kpi-history-list-page.js +155 -0
- package/dist-client/pages/kpi-history/kpi-history-list-page.js.map +1 -0
- package/dist-client/pages/kpi-metric/kpi-metric-importer.js +16 -17
- package/dist-client/pages/kpi-metric/kpi-metric-importer.js.map +1 -1
- package/dist-client/pages/kpi-metric/kpi-metric-list-page.js +98 -84
- package/dist-client/pages/kpi-metric/kpi-metric-list-page.js.map +1 -1
- package/dist-client/pages/kpi-value/kpi-value-importer.js +16 -17
- package/dist-client/pages/kpi-value/kpi-value-importer.js.map +1 -1
- package/dist-client/pages/kpi-value/kpi-value-list-page.js +104 -93
- package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -1
- package/dist-client/pages/kpi-value/kpi-value-manual-entry-form.d.ts +14 -0
- package/dist-client/pages/kpi-value/kpi-value-manual-entry-form.js +201 -0
- package/dist-client/pages/kpi-value/kpi-value-manual-entry-form.js.map +1 -0
- package/dist-client/pages/kpi-value/kpi-value-manual-entry-page.d.ts +41 -0
- package/dist-client/pages/kpi-value/kpi-value-manual-entry-page.js +180 -0
- package/dist-client/pages/kpi-value/kpi-value-manual-entry-page.js.map +1 -0
- package/dist-client/route.d.ts +1 -1
- package/dist-client/route.js +27 -0
- package/dist-client/route.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/index.d.ts +2 -1
- package/dist-server/index.js +2 -1
- package/dist-server/index.js.map +1 -1
- package/dist-server/migrations/1752188906708-SeedKpiCategory.d.ts +5 -0
- package/dist-server/migrations/1752188906708-SeedKpiCategory.js +56 -0
- package/dist-server/migrations/1752188906708-SeedKpiCategory.js.map +1 -0
- package/dist-server/migrations/1752190849681-SeedKpi.d.ts +5 -0
- package/dist-server/migrations/1752190849681-SeedKpi.js +107 -0
- package/dist-server/migrations/1752190849681-SeedKpi.js.map +1 -0
- package/dist-server/migrations/1752191090459-SeedKpiGrade.d.ts +5 -0
- package/dist-server/migrations/1752191090459-SeedKpiGrade.js +271 -0
- package/dist-server/migrations/1752191090459-SeedKpiGrade.js.map +1 -0
- package/dist-server/migrations/index.d.ts +1 -0
- package/dist-server/migrations/index.js +12 -0
- package/dist-server/migrations/index.js.map +1 -0
- package/dist-server/routes.d.ts +1 -0
- package/dist-server/routes.js +48 -0
- package/dist-server/routes.js.map +1 -1
- package/dist-server/service/index.d.ts +3 -4
- package/dist-server/service/index.js +4 -6
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/kpi/aggregate-kpi.d.ts +8 -0
- package/dist-server/service/kpi/aggregate-kpi.js +88 -0
- package/dist-server/service/kpi/aggregate-kpi.js.map +1 -0
- package/dist-server/service/kpi/event-subscriber.d.ts +2 -0
- package/dist-server/service/kpi/event-subscriber.js +10 -0
- package/dist-server/service/kpi/event-subscriber.js.map +1 -1
- package/dist-server/service/kpi/index.d.ts +2 -1
- package/dist-server/service/kpi/kpi-formula.service.d.ts +24 -0
- package/dist-server/service/kpi/kpi-formula.service.js +64 -0
- package/dist-server/service/kpi/kpi-formula.service.js.map +1 -0
- package/dist-server/service/kpi/kpi-history.d.ts +6 -2
- package/dist-server/service/kpi/kpi-history.js +29 -11
- package/dist-server/service/kpi/kpi-history.js.map +1 -1
- package/dist-server/service/kpi/kpi-mutation.d.ts +2 -0
- package/dist-server/service/kpi/kpi-mutation.js +215 -10
- package/dist-server/service/kpi/kpi-mutation.js.map +1 -1
- package/dist-server/service/kpi/kpi-query.d.ts +10 -0
- package/dist-server/service/kpi/kpi-query.js +87 -3
- package/dist-server/service/kpi/kpi-query.js.map +1 -1
- package/dist-server/service/kpi/kpi-type.d.ts +14 -3
- package/dist-server/service/kpi/kpi-type.js +81 -18
- package/dist-server/service/kpi/kpi-type.js.map +1 -1
- package/dist-server/service/kpi/kpi.d.ts +14 -3
- package/dist-server/service/kpi/kpi.js +96 -19
- package/dist-server/service/kpi/kpi.js.map +1 -1
- package/dist-server/service/kpi-alert/index.d.ts +2 -0
- package/dist-server/service/kpi-alert/index.js +6 -0
- package/dist-server/service/kpi-alert/index.js.map +1 -0
- package/dist-server/service/kpi-alert/kpi-alert-query.d.ts +4 -0
- package/dist-server/service/kpi-alert/kpi-alert-query.js +71 -0
- package/dist-server/service/kpi-alert/kpi-alert-query.js.map +1 -0
- package/dist-server/service/kpi-alert/kpi-alert-type.d.ts +8 -0
- package/dist-server/service/kpi-alert/kpi-alert-type.js +33 -0
- package/dist-server/service/kpi-alert/kpi-alert-type.js.map +1 -0
- package/dist-server/service/kpi-category/kpi-category-mutation.d.ts +1 -1
- package/dist-server/service/kpi-category/kpi-category-mutation.js +36 -10
- package/dist-server/service/kpi-category/kpi-category-mutation.js.map +1 -1
- package/dist-server/service/kpi-category/kpi-category-query.d.ts +2 -0
- package/dist-server/service/kpi-category/kpi-category-query.js +18 -2
- package/dist-server/service/kpi-category/kpi-category-query.js.map +1 -1
- package/dist-server/service/kpi-category/kpi-category-type.d.ts +3 -5
- package/dist-server/service/kpi-category/kpi-category-type.js +16 -20
- package/dist-server/service/kpi-category/kpi-category-type.js.map +1 -1
- package/dist-server/service/kpi-category/kpi-category.d.ts +7 -9
- package/dist-server/service/kpi-category/kpi-category.js +40 -38
- package/dist-server/service/kpi-category/kpi-category.js.map +1 -1
- package/dist-server/service/kpi-grade/index.d.ts +1 -2
- package/dist-server/service/kpi-grade/index.js +2 -4
- package/dist-server/service/kpi-grade/index.js.map +1 -1
- package/dist-server/service/kpi-grade/kpi-grade-mutation.d.ts +1 -1
- package/dist-server/service/kpi-grade/kpi-grade-mutation.js +33 -10
- package/dist-server/service/kpi-grade/kpi-grade-mutation.js.map +1 -1
- package/dist-server/service/kpi-grade/kpi-grade-query.js +2 -2
- package/dist-server/service/kpi-grade/kpi-grade-query.js.map +1 -1
- package/dist-server/service/kpi-grade/kpi-grade-type.d.ts +13 -4
- package/dist-server/service/kpi-grade/kpi-grade-type.js +54 -18
- package/dist-server/service/kpi-grade/kpi-grade-type.js.map +1 -1
- package/dist-server/service/kpi-grade/kpi-grade.d.ts +8 -8
- package/dist-server/service/kpi-grade/kpi-grade.js +48 -40
- package/dist-server/service/kpi-grade/kpi-grade.js.map +1 -1
- package/dist-server/service/kpi-metric/aggregate-kpi-metric.d.ts +8 -0
- package/dist-server/service/kpi-metric/aggregate-kpi-metric.js +134 -0
- package/dist-server/service/kpi-metric/aggregate-kpi-metric.js.map +1 -0
- package/dist-server/service/kpi-metric/index.d.ts +1 -2
- package/dist-server/service/kpi-metric/index.js +2 -4
- package/dist-server/service/kpi-metric/index.js.map +1 -1
- package/dist-server/service/kpi-metric/kpi-metric-mutation.d.ts +1 -1
- package/dist-server/service/kpi-metric/kpi-metric-mutation.js +139 -13
- package/dist-server/service/kpi-metric/kpi-metric-mutation.js.map +1 -1
- package/dist-server/service/kpi-metric/kpi-metric-query.js +3 -3
- package/dist-server/service/kpi-metric/kpi-metric-query.js.map +1 -1
- package/dist-server/service/kpi-metric/kpi-metric-type.d.ts +17 -4
- package/dist-server/service/kpi-metric/kpi-metric-type.js +69 -11
- package/dist-server/service/kpi-metric/kpi-metric-type.js.map +1 -1
- package/dist-server/service/kpi-metric/kpi-metric.d.ts +11 -8
- package/dist-server/service/kpi-metric/kpi-metric.js +62 -37
- package/dist-server/service/kpi-metric/kpi-metric.js.map +1 -1
- package/dist-server/service/kpi-value/kpi-value-mutation.js +66 -11
- package/dist-server/service/kpi-value/kpi-value-mutation.js.map +1 -1
- package/dist-server/service/kpi-value/kpi-value-query.d.ts +2 -0
- package/dist-server/service/kpi-value/kpi-value-query.js +15 -2
- package/dist-server/service/kpi-value/kpi-value-query.js.map +1 -1
- package/dist-server/service/kpi-value/kpi-value-type.d.ts +19 -10
- package/dist-server/service/kpi-value/kpi-value-type.js +87 -24
- package/dist-server/service/kpi-value/kpi-value-type.js.map +1 -1
- package/dist-server/service/kpi-value/kpi-value.d.ts +15 -9
- package/dist-server/service/kpi-value/kpi-value.js +86 -32
- package/dist-server/service/kpi-value/kpi-value.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/implement-plan/01-entity-type-resolver.md +57 -0
- package/implement-plan/02-dataset-integration.md +35 -0
- package/implement-plan/03-kpivalue-automation.md +34 -0
- package/implement-plan/04-version-history.md +33 -0
- package/implement-plan/05-grade-visualization.md +33 -0
- package/implement-plan/06-graphql-frontend.md +30 -0
- package/implement-plan/07-test-docs.md +35 -0
- package/implement-plan/TODO.md +41 -0
- package/package.json +18 -6
- package/server/index.ts +2 -1
- package/server/migrations/1752188906708-SeedKpiCategory.ts +61 -0
- package/server/migrations/1752190849681-SeedKpi.ts +112 -0
- package/server/migrations/1752191090459-SeedKpiGrade.ts +270 -0
- package/server/migrations/index.ts +9 -0
- package/server/routes.ts +55 -0
- package/server/service/index.ts +4 -6
- package/server/service/kpi/aggregate-kpi.ts +82 -0
- package/server/service/kpi/event-subscriber.ts +12 -0
- package/server/service/kpi/kpi-formula.service.ts +63 -0
- package/server/service/kpi/kpi-history.ts +29 -21
- package/server/service/kpi/kpi-mutation.ts +194 -12
- package/server/service/kpi/kpi-query.ts +57 -2
- package/server/service/kpi/kpi-type.ts +72 -19
- package/server/service/kpi/kpi.ts +96 -20
- package/server/service/kpi-alert/index.ts +3 -0
- package/server/service/kpi-alert/kpi-alert-query.ts +59 -0
- package/server/service/kpi-alert/kpi-alert-type.ts +20 -0
- package/server/service/kpi-category/kpi-category-mutation.ts +17 -4
- package/server/service/kpi-category/kpi-category-query.ts +20 -3
- package/server/service/kpi-category/kpi-category-type.ts +17 -19
- package/server/service/kpi-category/kpi-category.ts +39 -37
- package/server/service/kpi-grade/index.ts +2 -4
- package/server/service/kpi-grade/kpi-grade-mutation.ts +13 -4
- package/server/service/kpi-grade/kpi-grade-query.ts +5 -2
- package/server/service/kpi-grade/kpi-grade-type.ts +46 -19
- package/server/service/kpi-grade/kpi-grade.ts +44 -38
- package/server/service/kpi-metric/aggregate-kpi-metric.ts +128 -0
- package/server/service/kpi-metric/index.ts +2 -4
- package/server/service/kpi-metric/kpi-metric-mutation.ts +123 -7
- package/server/service/kpi-metric/kpi-metric-query.ts +9 -3
- package/server/service/kpi-metric/kpi-metric-type.ts +56 -13
- package/server/service/kpi-metric/kpi-metric.ts +55 -35
- package/server/service/kpi-value/kpi-value-mutation.ts +52 -14
- package/server/service/kpi-value/kpi-value-query.ts +12 -2
- package/server/service/kpi-value/kpi-value-type.ts +80 -25
- package/server/service/kpi-value/kpi-value.ts +81 -29
- package/things-factory.config.js +12 -4
- package/translations/en.json +12 -1
- package/translations/ja.json +12 -1
- package/translations/ko.json +12 -1
- package/translations/ms.json +12 -1
- package/translations/zh.json +12 -1
- package/client/pages/kpe-metric/kpe-metric-importer.ts +0 -90
- package/client/pages/kpe-metric/kpe-metric-list-page.ts +0 -398
- package/client/pages/kpi-formula/kpi-formula-importer.ts +0 -90
- package/client/pages/kpi-formula/kpi-formula-list-page.ts +0 -398
- package/client/pages/metric/metric-importer.ts +0 -90
- package/client/pages/metric/metric-list-page.ts +0 -398
- package/dist-client/pages/kpe-metric/kpe-metric-importer.d.ts +0 -23
- package/dist-client/pages/kpe-metric/kpe-metric-importer.js +0 -93
- package/dist-client/pages/kpe-metric/kpe-metric-importer.js.map +0 -1
- package/dist-client/pages/kpe-metric/kpe-metric-list-page.d.ts +0 -66
- package/dist-client/pages/kpe-metric/kpe-metric-list-page.js +0 -370
- package/dist-client/pages/kpe-metric/kpe-metric-list-page.js.map +0 -1
- package/dist-client/pages/kpi-formula/kpi-formula-importer.d.ts +0 -23
- package/dist-client/pages/kpi-formula/kpi-formula-importer.js +0 -93
- package/dist-client/pages/kpi-formula/kpi-formula-importer.js.map +0 -1
- package/dist-client/pages/kpi-formula/kpi-formula-list-page.d.ts +0 -66
- package/dist-client/pages/kpi-formula/kpi-formula-list-page.js +0 -370
- package/dist-client/pages/kpi-formula/kpi-formula-list-page.js.map +0 -1
- package/dist-client/pages/metric/metric-importer.d.ts +0 -23
- package/dist-client/pages/metric/metric-importer.js +0 -93
- package/dist-client/pages/metric/metric-importer.js.map +0 -1
- package/dist-client/pages/metric/metric-list-page.d.ts +0 -66
- package/dist-client/pages/metric/metric-list-page.js +0 -370
- package/dist-client/pages/metric/metric-list-page.js.map +0 -1
- package/dist-server/service/kpi-formula/event-subscriber.d.ts +0 -7
- package/dist-server/service/kpi-formula/event-subscriber.js +0 -21
- package/dist-server/service/kpi-formula/event-subscriber.js.map +0 -1
- package/dist-server/service/kpi-formula/index.d.ts +0 -7
- package/dist-server/service/kpi-formula/index.js +0 -12
- package/dist-server/service/kpi-formula/index.js.map +0 -1
- package/dist-server/service/kpi-formula/kpi-formula-history.d.ts +0 -25
- package/dist-server/service/kpi-formula/kpi-formula-history.js +0 -128
- package/dist-server/service/kpi-formula/kpi-formula-history.js.map +0 -1
- package/dist-server/service/kpi-formula/kpi-formula-mutation.d.ts +0 -10
- package/dist-server/service/kpi-formula/kpi-formula-mutation.js +0 -128
- package/dist-server/service/kpi-formula/kpi-formula-mutation.js.map +0 -1
- package/dist-server/service/kpi-formula/kpi-formula-query.d.ts +0 -11
- package/dist-server/service/kpi-formula/kpi-formula-query.js +0 -79
- package/dist-server/service/kpi-formula/kpi-formula-query.js.map +0 -1
- package/dist-server/service/kpi-formula/kpi-formula-type.d.ts +0 -20
- package/dist-server/service/kpi-formula/kpi-formula-type.js +0 -77
- package/dist-server/service/kpi-formula/kpi-formula-type.js.map +0 -1
- package/dist-server/service/kpi-formula/kpi-formula.d.ts +0 -24
- package/dist-server/service/kpi-formula/kpi-formula.js +0 -109
- package/dist-server/service/kpi-formula/kpi-formula.js.map +0 -1
- package/dist-server/service/kpi-grade/event-subscriber.d.ts +0 -7
- package/dist-server/service/kpi-grade/event-subscriber.js +0 -21
- package/dist-server/service/kpi-grade/event-subscriber.js.map +0 -1
- package/dist-server/service/kpi-grade/kpi-grade-history.d.ts +0 -25
- package/dist-server/service/kpi-grade/kpi-grade-history.js +0 -128
- package/dist-server/service/kpi-grade/kpi-grade-history.js.map +0 -1
- package/dist-server/service/kpi-metric/event-subscriber.d.ts +0 -7
- package/dist-server/service/kpi-metric/event-subscriber.js +0 -21
- package/dist-server/service/kpi-metric/event-subscriber.js.map +0 -1
- package/dist-server/service/kpi-metric/kpi-metric-history.d.ts +0 -25
- package/dist-server/service/kpi-metric/kpi-metric-history.js +0 -128
- package/dist-server/service/kpi-metric/kpi-metric-history.js.map +0 -1
- package/server/service/kpi-formula/event-subscriber.ts +0 -17
- package/server/service/kpi-formula/index.ts +0 -9
- package/server/service/kpi-formula/kpi-formula-history.ts +0 -116
- package/server/service/kpi-formula/kpi-formula-mutation.ts +0 -137
- package/server/service/kpi-formula/kpi-formula-query.ts +0 -48
- package/server/service/kpi-formula/kpi-formula-type.ts +0 -55
- package/server/service/kpi-formula/kpi-formula.ts +0 -95
- package/server/service/kpi-grade/event-subscriber.ts +0 -17
- package/server/service/kpi-grade/kpi-grade-history.ts +0 -116
- package/server/service/kpi-metric/event-subscriber.ts +0 -17
- package/server/service/kpi-metric/kpi-metric-history.ts +0 -116
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { __decorate, __metadata } from "tslib";
|
|
2
|
+
import { html, css } from 'lit';
|
|
3
|
+
import { customElement, state } from 'lit/decorators.js';
|
|
4
|
+
import { marked } from 'marked';
|
|
5
|
+
import { PageView } from '@operato/shell';
|
|
6
|
+
import { i18next } from '@operato/i18n';
|
|
7
|
+
let KpiOverview = class KpiOverview extends PageView {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
this.selectedGroup = 0;
|
|
11
|
+
this.selectedKpi = 0;
|
|
12
|
+
this.kpiGroups = [
|
|
13
|
+
{
|
|
14
|
+
name: '일정성과 지표',
|
|
15
|
+
kpis: ['연면적 대비 공사기간', '설계변경에 따른 공기 증감률', '일정 이탈 수준', '일정성과 수준 평가']
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: '비용성과 지표',
|
|
19
|
+
kpis: ['연면적 대비 공사비', '설계변경에 따른 공사비 증감률', '비용성과 수준 평가']
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: '품질성과 지표',
|
|
23
|
+
kpis: ['품질시험 불합격률', '검수재 불합격률', '검측 불합격률', '품질 SL-PA 결과값', '품질성과 수준 평가']
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: '안전성과 지표',
|
|
27
|
+
kpis: ['재해율', '재해강도율', '안전 SL-PA 결과값', '안전성과 수준 평가']
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: '환경성과 지표',
|
|
31
|
+
kpis: ['건설폐기물 발생량', '환경성과 수준 평가']
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: '생산성과 지표',
|
|
35
|
+
kpis: ['투입인력 생산성', '생산성과 수준 평가']
|
|
36
|
+
}
|
|
37
|
+
];
|
|
38
|
+
this.kpiDescriptions = {
|
|
39
|
+
'연면적 대비 공사기간': `# 연면적 대비 공사기간\n- 설명: 프로젝트의 전체 연면적 대비 실제 소요된 공사기간을 측정합니다.\n- 산식: 실제공사기간(개월) / (연면적/1000m2)\n- 데이터 표준형: 실제공사기간(개월) / (연면적/1000m2)\n- 활용: 대형 프로젝트의 일정 효율성 파악`,
|
|
40
|
+
'설계변경에 따른 공기 증감률': `# 설계변경에 따른 공기 증감률\n- 설명: 설계변경으로 인한 공기 단축 또는 증가 효과를 측정합니다.\n- 산식: (실제공사기간 - 계획공사기간) / 계획공사기간(개월)\n- 데이터 표준형: (실제공사기간 - 계획공사기간)(개월) / 계획공사기간(개월)`,
|
|
41
|
+
'일정 이탈 수준': `# 일정 이탈 수준\n- 설명: 계획 대비 실제 일정의 이탈 정도를 평가합니다.\n- 산식: Table(DART 등) 활용\n- 평가 방식: 1~5점 척도(감리자 평가)`,
|
|
42
|
+
'일정성과 수준 평가': `# 일정성과 수준 평가\n- 설명: 일정성과의 전반적인 수준을 감리자가 평가합니다.\n- 평가 방식: 감리자 1~5점 척도`,
|
|
43
|
+
'연면적 대비 공사비': `# 연면적 대비 공사비\n- 설명: 프로젝트의 전체 연면적 대비 실제 소요된 공사비를 측정합니다.\n- 산식: 실제공사비(억원) / (연면적/1000m2)\n- 데이터 표준형: 실제공사비(억원) / (연면적/1000m2)`,
|
|
44
|
+
'설계변경에 따른 공사비 증감률': `# 설계변경에 따른 공사비 증감률\n- 설명: 설계변경으로 인한 공사비 증감률을 측정합니다.\n- 산식: (실제공사비 - 계획공사비) / 계획공사비(억원)\n- 데이터 표준형: (실제공사비 - 계획공사비)(억원) / 계획공사비(억원)`,
|
|
45
|
+
'비용성과 수준 평가': `# 비용성과 수준 평가\n- 설명: 비용성과의 전반적인 수준을 감리자가 평가합니다.\n- 평가 방식: 감리자 1~5점 척도`,
|
|
46
|
+
'품질시험 불합격률': `# 품질시험 불합격률\n- 설명: 전체 품질시험 중 불합격 건수의 비율을 측정합니다.\n- 산식: 품질시험 불합격 건수(건) / (연면적/1000m2)`,
|
|
47
|
+
'검수재 불합격률': `# 검수재 불합격률\n- 설명: 검수재 중 불합격 건수의 비율을 측정합니다.\n- 산식: 검수재 불합격 건수(건) / (연면적/1000m2)`,
|
|
48
|
+
'검측 불합격률': `# 검측 불합격률\n- 설명: 전체 검측 중 불합격 건수의 비율을 측정합니다.\n- 산식: 품질검측 불합격 건수(건) / 품질검측 건수(건)`,
|
|
49
|
+
'품질 SL-PA 결과값': `# 품질 SL-PA 결과값\n- 설명: SL-PA(Safety Level - Performance Assessment)는 건설/안전 분야에서 안전관리 수준을 정량적으로 평가하는 대표 지표입니다.\n- 평가 방식: Python 활용 1~5점 척도`,
|
|
50
|
+
'품질성과 수준 평가': `# 품질성과 수준 평가\n- 설명: 품질성과의 전반적인 수준을 감리자가 평가합니다.\n- 평가 방식: 감리자 1~5점 척도`,
|
|
51
|
+
재해율: `# 재해율\n- 설명: 연간 근로자 수 대비 재해 발생 건수의 비율을 측정합니다.\n- 산식: (재해 건수(건) / 연간 근로자 수(명)) * 100`,
|
|
52
|
+
재해강도율: `# 재해강도율\n- 설명: 총 근로자 수와 연간 근로시간 대비 노동손실일수의 비율을 측정합니다.\n- 산식: (노동손실일수(일) / (총 근로자 수 * 1인당 연간 근로시간)) * 100`,
|
|
53
|
+
'안전 SL-PA 결과값': `# 안전 SL-PA 결과값\n- 설명: SL-PA(Safety Level - Performance Assessment)는 건설/안전 분야에서 **안전관리 수준**을 정량적으로 평가하는 대표 지표입니다.\n- 활용: 현장의 안전성과를 수치로 진단하고, 위험요소 개선 및 안전관리 정책 수립에 활용됩니다.\n- 평가 방식: Python 활용 1~5점 척도 (1점: 매우 미흡, 5점: 매우 우수)`,
|
|
54
|
+
'안전성과 수준 평가': `# 안전성과 수준 평가\n- 설명: 안전성과의 전반적인 수준을 감리자가 평가합니다.\n- 평가 방식: 감리자 1~5점 척도`,
|
|
55
|
+
'건설폐기물 발생량': `# 건설폐기물 발생량\n- 설명: 전체 건설폐기물 발생량을 측정합니다.\n- 산식: 총 건설 폐기물 발생량(ton) / (연면적/1000m2)`,
|
|
56
|
+
'환경성과 수준 평가': `# 환경성과 수준 평가\n- 설명: 환경성과의 전반적인 수준을 감리자가 평가합니다.\n- 평가 방식: 감리자 1~5점 척도`,
|
|
57
|
+
'투입인력 생산성': `# 투입인력 생산성\n- 설명: 투입 인력 대비 생산성을 측정합니다.\n- 산식: 투입인력(명) / (연면적/1000m2)`,
|
|
58
|
+
'생산성과 수준 평가': `# 생산성과 수준 평가\n- 설명: 생산성과의 전반적인 수준을 감리자가 평가합니다.\n- 평가 방식: 감리자 1~5점 척도`
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
static { this.styles = css `
|
|
62
|
+
.overview-container {
|
|
63
|
+
display: flex;
|
|
64
|
+
gap: 32px;
|
|
65
|
+
background: #f7f5fa;
|
|
66
|
+
border-radius: 20px;
|
|
67
|
+
padding: 32px;
|
|
68
|
+
margin-bottom: 24px;
|
|
69
|
+
align-items: stretch;
|
|
70
|
+
}
|
|
71
|
+
.overview-left {
|
|
72
|
+
flex: 1;
|
|
73
|
+
display: flex;
|
|
74
|
+
flex-direction: column;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
}
|
|
77
|
+
.overview-title {
|
|
78
|
+
font-size: 2.8rem;
|
|
79
|
+
font-weight: bold;
|
|
80
|
+
margin-bottom: 24px;
|
|
81
|
+
}
|
|
82
|
+
.overview-desc {
|
|
83
|
+
font-size: 1.2rem;
|
|
84
|
+
color: #222;
|
|
85
|
+
line-height: 1.6;
|
|
86
|
+
}
|
|
87
|
+
.overview-right {
|
|
88
|
+
flex: 1;
|
|
89
|
+
display: flex;
|
|
90
|
+
align-items: center;
|
|
91
|
+
justify-content: center;
|
|
92
|
+
}
|
|
93
|
+
.overview-img {
|
|
94
|
+
width: 100%;
|
|
95
|
+
max-width: 420px;
|
|
96
|
+
border-radius: 12px;
|
|
97
|
+
object-fit: cover;
|
|
98
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
|
99
|
+
}
|
|
100
|
+
.group-tabs {
|
|
101
|
+
display: flex;
|
|
102
|
+
gap: 8px;
|
|
103
|
+
margin: 0 0 16px 0;
|
|
104
|
+
justify-content: center;
|
|
105
|
+
}
|
|
106
|
+
.group-tab {
|
|
107
|
+
padding: 10px 28px;
|
|
108
|
+
border-radius: 16px 16px 0 0;
|
|
109
|
+
background: #eee;
|
|
110
|
+
cursor: pointer;
|
|
111
|
+
font-size: 1.1rem;
|
|
112
|
+
font-weight: 500;
|
|
113
|
+
border: none;
|
|
114
|
+
outline: none;
|
|
115
|
+
transition: background 0.2s;
|
|
116
|
+
}
|
|
117
|
+
.group-tab[selected] {
|
|
118
|
+
background: #d6d6f7;
|
|
119
|
+
color: #222;
|
|
120
|
+
font-weight: bold;
|
|
121
|
+
}
|
|
122
|
+
.kpi-list {
|
|
123
|
+
display: flex;
|
|
124
|
+
gap: 8px;
|
|
125
|
+
margin: 0 0 32px 0;
|
|
126
|
+
justify-content: center;
|
|
127
|
+
}
|
|
128
|
+
.kpi-item {
|
|
129
|
+
padding: 8px 20px;
|
|
130
|
+
border-radius: 12px;
|
|
131
|
+
background: #f5f5f5;
|
|
132
|
+
cursor: pointer;
|
|
133
|
+
font-size: 1rem;
|
|
134
|
+
border: none;
|
|
135
|
+
outline: none;
|
|
136
|
+
transition: background 0.2s;
|
|
137
|
+
}
|
|
138
|
+
.kpi-item[selected] {
|
|
139
|
+
background: #bdf;
|
|
140
|
+
color: #222;
|
|
141
|
+
font-weight: bold;
|
|
142
|
+
}
|
|
143
|
+
.main-content {
|
|
144
|
+
display: flex;
|
|
145
|
+
gap: 32px;
|
|
146
|
+
margin-top: 32px;
|
|
147
|
+
align-items: flex-start;
|
|
148
|
+
justify-content: center;
|
|
149
|
+
}
|
|
150
|
+
.markdown {
|
|
151
|
+
background: #fff;
|
|
152
|
+
border-radius: 12px;
|
|
153
|
+
padding: 40px 32px;
|
|
154
|
+
min-height: 240px;
|
|
155
|
+
flex: 2;
|
|
156
|
+
font-size: 2rem;
|
|
157
|
+
color: #222;
|
|
158
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
|
159
|
+
}
|
|
160
|
+
.toc {
|
|
161
|
+
flex: 1;
|
|
162
|
+
background: #faf9fd;
|
|
163
|
+
border-radius: 12px;
|
|
164
|
+
padding: 32px 24px;
|
|
165
|
+
font-size: 1.1rem;
|
|
166
|
+
color: #444;
|
|
167
|
+
min-width: 220px;
|
|
168
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
|
|
169
|
+
}
|
|
170
|
+
.toc-title {
|
|
171
|
+
font-weight: bold;
|
|
172
|
+
margin-bottom: 12px;
|
|
173
|
+
font-size: 1.2rem;
|
|
174
|
+
}
|
|
175
|
+
.toc-list {
|
|
176
|
+
margin: 0 0 16px 0;
|
|
177
|
+
padding: 0;
|
|
178
|
+
list-style: none;
|
|
179
|
+
}
|
|
180
|
+
.toc-list li {
|
|
181
|
+
margin-bottom: 6px;
|
|
182
|
+
}
|
|
183
|
+
.toc-btn {
|
|
184
|
+
display: block;
|
|
185
|
+
margin: 12px 0;
|
|
186
|
+
padding: 8px 16px;
|
|
187
|
+
border: 1px solid #aaa;
|
|
188
|
+
border-radius: 8px;
|
|
189
|
+
background: #fff;
|
|
190
|
+
color: #333;
|
|
191
|
+
cursor: pointer;
|
|
192
|
+
font-size: 1rem;
|
|
193
|
+
text-align: left;
|
|
194
|
+
transition: background 0.2s;
|
|
195
|
+
}
|
|
196
|
+
.toc-btn:hover {
|
|
197
|
+
background: #f0f0f0;
|
|
198
|
+
}
|
|
199
|
+
`; }
|
|
200
|
+
get context() {
|
|
201
|
+
return {
|
|
202
|
+
title: i18next.t('title.kpi overview')
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
render() {
|
|
206
|
+
const group = this.kpiGroups[this.selectedGroup];
|
|
207
|
+
const kpi = group.kpis[this.selectedKpi];
|
|
208
|
+
const md = this.kpiDescriptions[kpi] || '각 지표의 주요 소개 내용을 마크다운으로 입력하세요.';
|
|
209
|
+
return html `
|
|
210
|
+
<div class="overview-container">
|
|
211
|
+
<div class="overview-left">
|
|
212
|
+
<div class="overview-title">KPI개요</div>
|
|
213
|
+
<div class="overview-desc">
|
|
214
|
+
건설현장 KPI 관리 시스템은 프로젝트 성과를 측정하고 모니터링하여 효율적인 공정 관리를 지원합니다.<br />
|
|
215
|
+
주요 지표를 통해 현장 생산성, 품질, 안전 등을 실시간으로 파악할 수 있습니다.
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
<div class="overview-right">
|
|
219
|
+
<img
|
|
220
|
+
class="overview-img"
|
|
221
|
+
src="https://images.unsplash.com/photo-1464983953574-0892a716854b?auto=format&fit=crop&w=600&q=80"
|
|
222
|
+
alt="건설현장 안전"
|
|
223
|
+
/>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
<div class="group-tabs">
|
|
227
|
+
${this.kpiGroups.map((g, i) => html `
|
|
228
|
+
<button
|
|
229
|
+
class="group-tab"
|
|
230
|
+
?selected=${i === this.selectedGroup}
|
|
231
|
+
@click=${() => {
|
|
232
|
+
this.selectedGroup = i;
|
|
233
|
+
this.selectedKpi = 0;
|
|
234
|
+
}}
|
|
235
|
+
>
|
|
236
|
+
${g.name}
|
|
237
|
+
</button>
|
|
238
|
+
`)}
|
|
239
|
+
</div>
|
|
240
|
+
<div class="main-content">
|
|
241
|
+
<div class="markdown" .innerHTML=${marked(md)}></div>
|
|
242
|
+
<div class="toc">
|
|
243
|
+
<div class="toc-title">목차</div>
|
|
244
|
+
<ul class="toc-list">
|
|
245
|
+
${group.kpis.map((k, i) => html ` <li><button class="toc-btn" @click=${() => (this.selectedKpi = i)}>${k}</button></li> `)}
|
|
246
|
+
</ul>
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
`;
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
__decorate([
|
|
253
|
+
state(),
|
|
254
|
+
__metadata("design:type", Object)
|
|
255
|
+
], KpiOverview.prototype, "selectedGroup", void 0);
|
|
256
|
+
__decorate([
|
|
257
|
+
state(),
|
|
258
|
+
__metadata("design:type", Object)
|
|
259
|
+
], KpiOverview.prototype, "selectedKpi", void 0);
|
|
260
|
+
KpiOverview = __decorate([
|
|
261
|
+
customElement('kpi-overview')
|
|
262
|
+
], KpiOverview);
|
|
263
|
+
export { KpiOverview };
|
|
264
|
+
//# sourceMappingURL=kpi-overview-sample.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kpi-overview-sample.js","sourceRoot":"","sources":["../../../client/pages/kpi/kpi-overview-sample.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAc,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAE,QAAQ,EAAS,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAY,MAAM,eAAe,CAAA;AAG1C,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,QAAQ;IAAlC;;QAmJI,kBAAa,GAAG,CAAC,CAAA;QACjB,gBAAW,GAAG,CAAC,CAAA;QAExB,cAAS,GAAG;YACV;gBACE,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,CAAC,aAAa,EAAE,iBAAiB,EAAE,UAAU,EAAE,YAAY,CAAC;aACnE;YACD;gBACE,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,CAAC,YAAY,EAAE,kBAAkB,EAAE,YAAY,CAAC;aACvD;YACD;gBACE,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,CAAC;aACzE;YACD;gBACE,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,YAAY,CAAC;aACrD;YACD;gBACE,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC;aAClC;YACD;gBACE,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,CAAC,UAAU,EAAE,YAAY,CAAC;aACjC;SACF,CAAA;QAED,oBAAe,GAAG;YAChB,aAAa,EAAE,2JAA2J;YAC1K,iBAAiB,EAAE,gJAAgJ;YACnK,UAAU,EAAE,gGAAgG;YAC5G,YAAY,EAAE,sEAAsE;YACpF,YAAY,EAAE,6HAA6H;YAC3I,kBAAkB,EAAE,oIAAoI;YACxJ,YAAY,EAAE,sEAAsE;YACpF,WAAW,EAAE,sFAAsF;YACnG,UAAU,EAAE,gFAAgF;YAC5F,SAAS,EAAE,gFAAgF;YAC3F,cAAc,EAAE,0IAA0I;YAC1J,YAAY,EAAE,sEAAsE;YACpF,GAAG,EAAE,qFAAqF;YAC1F,KAAK,EAAE,0GAA0G;YACjH,cAAc,EAAE,6NAA6N;YAC7O,YAAY,EAAE,sEAAsE;YACpF,WAAW,EAAE,iFAAiF;YAC9F,YAAY,EAAE,sEAAsE;YACpF,UAAU,EAAE,sEAAsE;YAClF,YAAY,EAAE,sEAAsE;SACrF,CAAA;IAqDH,CAAC;aA1PQ,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0IlB,AA1IY,CA0IZ;IAED,IAAI,OAAO;QACT,OAAO;YACL,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC;SACvC,CAAA;IACH,CAAC;IAuDD,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;QAChD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACxC,MAAM,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,+BAA+B,CAAA;QAEvE,OAAO,IAAI,CAAA;;;;;;;;;;;;;;;;;;UAkBL,IAAI,CAAC,SAAS,CAAC,GAAG,CAClB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAA;;;0BAGE,CAAC,KAAK,IAAI,CAAC,aAAa;uBAC3B,GAAG,EAAE;YACZ,IAAI,CAAC,aAAa,GAAG,CAAC,CAAA;YACtB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;QACtB,CAAC;;gBAEC,CAAC,CAAC,IAAI;;WAEX,CACF;;;2CAGkC,MAAM,CAAC,EAAE,CAAC;;;;cAIvC,KAAK,CAAC,IAAI,CAAC,GAAG,CACd,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAA,uCAAuC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CACxG;;;;KAIR,CAAA;IACH,CAAC;;AAvGQ;IAAR,KAAK,EAAE;;kDAAkB;AACjB;IAAR,KAAK,EAAE;;gDAAgB;AApJb,WAAW;IADvB,aAAa,CAAC,cAAc,CAAC;GACjB,WAAW,CA2PvB","sourcesContent":["import { html, css, LitElement } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\nimport { marked } from 'marked'\n\nimport { PageView, store } from '@operato/shell'\nimport { i18next, localize } from '@operato/i18n'\n\n@customElement('kpi-overview')\nexport class KpiOverview extends PageView {\n static styles = css`\n .overview-container {\n display: flex;\n gap: 32px;\n background: #f7f5fa;\n border-radius: 20px;\n padding: 32px;\n margin-bottom: 24px;\n align-items: stretch;\n }\n .overview-left {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n }\n .overview-title {\n font-size: 2.8rem;\n font-weight: bold;\n margin-bottom: 24px;\n }\n .overview-desc {\n font-size: 1.2rem;\n color: #222;\n line-height: 1.6;\n }\n .overview-right {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .overview-img {\n width: 100%;\n max-width: 420px;\n border-radius: 12px;\n object-fit: cover;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n }\n .group-tabs {\n display: flex;\n gap: 8px;\n margin: 0 0 16px 0;\n justify-content: center;\n }\n .group-tab {\n padding: 10px 28px;\n border-radius: 16px 16px 0 0;\n background: #eee;\n cursor: pointer;\n font-size: 1.1rem;\n font-weight: 500;\n border: none;\n outline: none;\n transition: background 0.2s;\n }\n .group-tab[selected] {\n background: #d6d6f7;\n color: #222;\n font-weight: bold;\n }\n .kpi-list {\n display: flex;\n gap: 8px;\n margin: 0 0 32px 0;\n justify-content: center;\n }\n .kpi-item {\n padding: 8px 20px;\n border-radius: 12px;\n background: #f5f5f5;\n cursor: pointer;\n font-size: 1rem;\n border: none;\n outline: none;\n transition: background 0.2s;\n }\n .kpi-item[selected] {\n background: #bdf;\n color: #222;\n font-weight: bold;\n }\n .main-content {\n display: flex;\n gap: 32px;\n margin-top: 32px;\n align-items: flex-start;\n justify-content: center;\n }\n .markdown {\n background: #fff;\n border-radius: 12px;\n padding: 40px 32px;\n min-height: 240px;\n flex: 2;\n font-size: 2rem;\n color: #222;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n }\n .toc {\n flex: 1;\n background: #faf9fd;\n border-radius: 12px;\n padding: 32px 24px;\n font-size: 1.1rem;\n color: #444;\n min-width: 220px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);\n }\n .toc-title {\n font-weight: bold;\n margin-bottom: 12px;\n font-size: 1.2rem;\n }\n .toc-list {\n margin: 0 0 16px 0;\n padding: 0;\n list-style: none;\n }\n .toc-list li {\n margin-bottom: 6px;\n }\n .toc-btn {\n display: block;\n margin: 12px 0;\n padding: 8px 16px;\n border: 1px solid #aaa;\n border-radius: 8px;\n background: #fff;\n color: #333;\n cursor: pointer;\n font-size: 1rem;\n text-align: left;\n transition: background 0.2s;\n }\n .toc-btn:hover {\n background: #f0f0f0;\n }\n `\n\n get context() {\n return {\n title: i18next.t('title.kpi overview')\n }\n }\n\n @state() selectedGroup = 0\n @state() selectedKpi = 0\n\n kpiGroups = [\n {\n name: '일정성과 지표',\n kpis: ['연면적 대비 공사기간', '설계변경에 따른 공기 증감률', '일정 이탈 수준', '일정성과 수준 평가']\n },\n {\n name: '비용성과 지표',\n kpis: ['연면적 대비 공사비', '설계변경에 따른 공사비 증감률', '비용성과 수준 평가']\n },\n {\n name: '품질성과 지표',\n kpis: ['품질시험 불합격률', '검수재 불합격률', '검측 불합격률', '품질 SL-PA 결과값', '품질성과 수준 평가']\n },\n {\n name: '안전성과 지표',\n kpis: ['재해율', '재해강도율', '안전 SL-PA 결과값', '안전성과 수준 평가']\n },\n {\n name: '환경성과 지표',\n kpis: ['건설폐기물 발생량', '환경성과 수준 평가']\n },\n {\n name: '생산성과 지표',\n kpis: ['투입인력 생산성', '생산성과 수준 평가']\n }\n ]\n\n kpiDescriptions = {\n '연면적 대비 공사기간': `# 연면적 대비 공사기간\\n- 설명: 프로젝트의 전체 연면적 대비 실제 소요된 공사기간을 측정합니다.\\n- 산식: 실제공사기간(개월) / (연면적/1000m2)\\n- 데이터 표준형: 실제공사기간(개월) / (연면적/1000m2)\\n- 활용: 대형 프로젝트의 일정 효율성 파악`,\n '설계변경에 따른 공기 증감률': `# 설계변경에 따른 공기 증감률\\n- 설명: 설계변경으로 인한 공기 단축 또는 증가 효과를 측정합니다.\\n- 산식: (실제공사기간 - 계획공사기간) / 계획공사기간(개월)\\n- 데이터 표준형: (실제공사기간 - 계획공사기간)(개월) / 계획공사기간(개월)`,\n '일정 이탈 수준': `# 일정 이탈 수준\\n- 설명: 계획 대비 실제 일정의 이탈 정도를 평가합니다.\\n- 산식: Table(DART 등) 활용\\n- 평가 방식: 1~5점 척도(감리자 평가)`,\n '일정성과 수준 평가': `# 일정성과 수준 평가\\n- 설명: 일정성과의 전반적인 수준을 감리자가 평가합니다.\\n- 평가 방식: 감리자 1~5점 척도`,\n '연면적 대비 공사비': `# 연면적 대비 공사비\\n- 설명: 프로젝트의 전체 연면적 대비 실제 소요된 공사비를 측정합니다.\\n- 산식: 실제공사비(억원) / (연면적/1000m2)\\n- 데이터 표준형: 실제공사비(억원) / (연면적/1000m2)`,\n '설계변경에 따른 공사비 증감률': `# 설계변경에 따른 공사비 증감률\\n- 설명: 설계변경으로 인한 공사비 증감률을 측정합니다.\\n- 산식: (실제공사비 - 계획공사비) / 계획공사비(억원)\\n- 데이터 표준형: (실제공사비 - 계획공사비)(억원) / 계획공사비(억원)`,\n '비용성과 수준 평가': `# 비용성과 수준 평가\\n- 설명: 비용성과의 전반적인 수준을 감리자가 평가합니다.\\n- 평가 방식: 감리자 1~5점 척도`,\n '품질시험 불합격률': `# 품질시험 불합격률\\n- 설명: 전체 품질시험 중 불합격 건수의 비율을 측정합니다.\\n- 산식: 품질시험 불합격 건수(건) / (연면적/1000m2)`,\n '검수재 불합격률': `# 검수재 불합격률\\n- 설명: 검수재 중 불합격 건수의 비율을 측정합니다.\\n- 산식: 검수재 불합격 건수(건) / (연면적/1000m2)`,\n '검측 불합격률': `# 검측 불합격률\\n- 설명: 전체 검측 중 불합격 건수의 비율을 측정합니다.\\n- 산식: 품질검측 불합격 건수(건) / 품질검측 건수(건)`,\n '품질 SL-PA 결과값': `# 품질 SL-PA 결과값\\n- 설명: SL-PA(Safety Level - Performance Assessment)는 건설/안전 분야에서 안전관리 수준을 정량적으로 평가하는 대표 지표입니다.\\n- 평가 방식: Python 활용 1~5점 척도`,\n '품질성과 수준 평가': `# 품질성과 수준 평가\\n- 설명: 품질성과의 전반적인 수준을 감리자가 평가합니다.\\n- 평가 방식: 감리자 1~5점 척도`,\n 재해율: `# 재해율\\n- 설명: 연간 근로자 수 대비 재해 발생 건수의 비율을 측정합니다.\\n- 산식: (재해 건수(건) / 연간 근로자 수(명)) * 100`,\n 재해강도율: `# 재해강도율\\n- 설명: 총 근로자 수와 연간 근로시간 대비 노동손실일수의 비율을 측정합니다.\\n- 산식: (노동손실일수(일) / (총 근로자 수 * 1인당 연간 근로시간)) * 100`,\n '안전 SL-PA 결과값': `# 안전 SL-PA 결과값\\n- 설명: SL-PA(Safety Level - Performance Assessment)는 건설/안전 분야에서 **안전관리 수준**을 정량적으로 평가하는 대표 지표입니다.\\n- 활용: 현장의 안전성과를 수치로 진단하고, 위험요소 개선 및 안전관리 정책 수립에 활용됩니다.\\n- 평가 방식: Python 활용 1~5점 척도 (1점: 매우 미흡, 5점: 매우 우수)`,\n '안전성과 수준 평가': `# 안전성과 수준 평가\\n- 설명: 안전성과의 전반적인 수준을 감리자가 평가합니다.\\n- 평가 방식: 감리자 1~5점 척도`,\n '건설폐기물 발생량': `# 건설폐기물 발생량\\n- 설명: 전체 건설폐기물 발생량을 측정합니다.\\n- 산식: 총 건설 폐기물 발생량(ton) / (연면적/1000m2)`,\n '환경성과 수준 평가': `# 환경성과 수준 평가\\n- 설명: 환경성과의 전반적인 수준을 감리자가 평가합니다.\\n- 평가 방식: 감리자 1~5점 척도`,\n '투입인력 생산성': `# 투입인력 생산성\\n- 설명: 투입 인력 대비 생산성을 측정합니다.\\n- 산식: 투입인력(명) / (연면적/1000m2)`,\n '생산성과 수준 평가': `# 생산성과 수준 평가\\n- 설명: 생산성과의 전반적인 수준을 감리자가 평가합니다.\\n- 평가 방식: 감리자 1~5점 척도`\n }\n\n render() {\n const group = this.kpiGroups[this.selectedGroup]\n const kpi = group.kpis[this.selectedKpi]\n const md = this.kpiDescriptions[kpi] || '각 지표의 주요 소개 내용을 마크다운으로 입력하세요.'\n\n return html`\n <div class=\"overview-container\">\n <div class=\"overview-left\">\n <div class=\"overview-title\">KPI개요</div>\n <div class=\"overview-desc\">\n 건설현장 KPI 관리 시스템은 프로젝트 성과를 측정하고 모니터링하여 효율적인 공정 관리를 지원합니다.<br />\n 주요 지표를 통해 현장 생산성, 품질, 안전 등을 실시간으로 파악할 수 있습니다.\n </div>\n </div>\n <div class=\"overview-right\">\n <img\n class=\"overview-img\"\n src=\"https://images.unsplash.com/photo-1464983953574-0892a716854b?auto=format&fit=crop&w=600&q=80\"\n alt=\"건설현장 안전\"\n />\n </div>\n </div>\n <div class=\"group-tabs\">\n ${this.kpiGroups.map(\n (g, i) => html`\n <button\n class=\"group-tab\"\n ?selected=${i === this.selectedGroup}\n @click=${() => {\n this.selectedGroup = i\n this.selectedKpi = 0\n }}\n >\n ${g.name}\n </button>\n `\n )}\n </div>\n <div class=\"main-content\">\n <div class=\"markdown\" .innerHTML=${marked(md)}></div>\n <div class=\"toc\">\n <div class=\"toc-title\">목차</div>\n <ul class=\"toc-list\">\n ${group.kpis.map(\n (k, i) => html` <li><button class=\"toc-btn\" @click=${() => (this.selectedKpi = i)}>${k}</button></li> `\n )}\n </ul>\n </div>\n </div>\n `\n }\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { PageView } from '@operato/shell';
|
|
2
|
+
export declare class KpiOverview extends PageView {
|
|
3
|
+
static styles: import("lit").CSSResult;
|
|
4
|
+
get context(): {
|
|
5
|
+
title: string;
|
|
6
|
+
};
|
|
7
|
+
selectedGroup: number;
|
|
8
|
+
selectedKpi: number;
|
|
9
|
+
kpiCategories: any[];
|
|
10
|
+
loading: boolean;
|
|
11
|
+
error: Error | null;
|
|
12
|
+
firstUpdated(): Promise<void>;
|
|
13
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { __decorate, __metadata } from "tslib";
|
|
2
|
+
import { html, css } from 'lit';
|
|
3
|
+
import { customElement, state } from 'lit/decorators.js';
|
|
4
|
+
import { marked } from 'marked';
|
|
5
|
+
import { PageView } from '@operato/shell';
|
|
6
|
+
import { i18next } from '@operato/i18n';
|
|
7
|
+
import { client } from '@operato/graphql';
|
|
8
|
+
import gql from 'graphql-tag';
|
|
9
|
+
const GET_KPI_OVERVIEW = gql `
|
|
10
|
+
query {
|
|
11
|
+
kpiCategories {
|
|
12
|
+
items {
|
|
13
|
+
id
|
|
14
|
+
name
|
|
15
|
+
description
|
|
16
|
+
active
|
|
17
|
+
kpis {
|
|
18
|
+
id
|
|
19
|
+
name
|
|
20
|
+
description
|
|
21
|
+
formula
|
|
22
|
+
active
|
|
23
|
+
grades {
|
|
24
|
+
id
|
|
25
|
+
name
|
|
26
|
+
minValue
|
|
27
|
+
maxValue
|
|
28
|
+
score
|
|
29
|
+
color
|
|
30
|
+
description
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
37
|
+
let KpiOverview = class KpiOverview extends PageView {
|
|
38
|
+
constructor() {
|
|
39
|
+
super(...arguments);
|
|
40
|
+
this.selectedGroup = 0;
|
|
41
|
+
this.selectedKpi = 0;
|
|
42
|
+
this.kpiCategories = [];
|
|
43
|
+
this.loading = true;
|
|
44
|
+
this.error = null;
|
|
45
|
+
}
|
|
46
|
+
static { this.styles = css `
|
|
47
|
+
.overview-container {
|
|
48
|
+
display: flex;
|
|
49
|
+
gap: 32px;
|
|
50
|
+
background: #f7f5fa;
|
|
51
|
+
border-radius: 20px;
|
|
52
|
+
padding: 32px;
|
|
53
|
+
margin-bottom: 24px;
|
|
54
|
+
align-items: stretch;
|
|
55
|
+
}
|
|
56
|
+
.overview-left {
|
|
57
|
+
flex: 1;
|
|
58
|
+
display: flex;
|
|
59
|
+
flex-direction: column;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
}
|
|
62
|
+
.overview-title {
|
|
63
|
+
font-size: 2.8rem;
|
|
64
|
+
font-weight: bold;
|
|
65
|
+
margin-bottom: 24px;
|
|
66
|
+
}
|
|
67
|
+
.overview-desc {
|
|
68
|
+
font-size: 1.2rem;
|
|
69
|
+
color: #222;
|
|
70
|
+
line-height: 1.6;
|
|
71
|
+
}
|
|
72
|
+
.overview-right {
|
|
73
|
+
flex: 1;
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
justify-content: center;
|
|
77
|
+
}
|
|
78
|
+
.overview-img {
|
|
79
|
+
width: 100%;
|
|
80
|
+
max-width: 420px;
|
|
81
|
+
border-radius: 12px;
|
|
82
|
+
object-fit: cover;
|
|
83
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
|
84
|
+
}
|
|
85
|
+
.group-tabs {
|
|
86
|
+
display: flex;
|
|
87
|
+
gap: 8px;
|
|
88
|
+
margin: 0 0 16px 0;
|
|
89
|
+
justify-content: center;
|
|
90
|
+
}
|
|
91
|
+
.group-tab {
|
|
92
|
+
padding: 10px 28px;
|
|
93
|
+
border-radius: 16px 16px 0 0;
|
|
94
|
+
background: #eee;
|
|
95
|
+
cursor: pointer;
|
|
96
|
+
font-size: 1.1rem;
|
|
97
|
+
font-weight: 500;
|
|
98
|
+
border: none;
|
|
99
|
+
outline: none;
|
|
100
|
+
transition: background 0.2s;
|
|
101
|
+
}
|
|
102
|
+
.group-tab[selected] {
|
|
103
|
+
background: #d6d6f7;
|
|
104
|
+
color: #222;
|
|
105
|
+
font-weight: bold;
|
|
106
|
+
}
|
|
107
|
+
.kpi-list {
|
|
108
|
+
display: flex;
|
|
109
|
+
gap: 8px;
|
|
110
|
+
margin: 0 0 32px 0;
|
|
111
|
+
justify-content: center;
|
|
112
|
+
}
|
|
113
|
+
.kpi-item {
|
|
114
|
+
padding: 8px 20px;
|
|
115
|
+
border-radius: 12px;
|
|
116
|
+
background: #f5f5f5;
|
|
117
|
+
cursor: pointer;
|
|
118
|
+
font-size: 1rem;
|
|
119
|
+
border: none;
|
|
120
|
+
outline: none;
|
|
121
|
+
transition: background 0.2s;
|
|
122
|
+
}
|
|
123
|
+
.kpi-item[selected] {
|
|
124
|
+
background: #bdf;
|
|
125
|
+
color: #222;
|
|
126
|
+
font-weight: bold;
|
|
127
|
+
}
|
|
128
|
+
.main-content {
|
|
129
|
+
display: flex;
|
|
130
|
+
gap: 32px;
|
|
131
|
+
margin-top: 32px;
|
|
132
|
+
align-items: flex-start;
|
|
133
|
+
justify-content: center;
|
|
134
|
+
}
|
|
135
|
+
.markdown {
|
|
136
|
+
background: #fff;
|
|
137
|
+
border-radius: 12px;
|
|
138
|
+
padding: 40px 32px;
|
|
139
|
+
min-height: 240px;
|
|
140
|
+
flex: 2;
|
|
141
|
+
font-size: 2rem;
|
|
142
|
+
color: #222;
|
|
143
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
|
144
|
+
}
|
|
145
|
+
.toc {
|
|
146
|
+
flex: 1;
|
|
147
|
+
background: #faf9fd;
|
|
148
|
+
border-radius: 12px;
|
|
149
|
+
padding: 32px 24px;
|
|
150
|
+
font-size: 1.1rem;
|
|
151
|
+
color: #444;
|
|
152
|
+
min-width: 220px;
|
|
153
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
|
|
154
|
+
}
|
|
155
|
+
.toc-title {
|
|
156
|
+
font-weight: bold;
|
|
157
|
+
margin-bottom: 12px;
|
|
158
|
+
font-size: 1.2rem;
|
|
159
|
+
}
|
|
160
|
+
.toc-list {
|
|
161
|
+
margin: 0 0 16px 0;
|
|
162
|
+
padding: 0;
|
|
163
|
+
list-style: none;
|
|
164
|
+
}
|
|
165
|
+
.toc-list li {
|
|
166
|
+
margin-bottom: 6px;
|
|
167
|
+
}
|
|
168
|
+
.toc-btn {
|
|
169
|
+
display: block;
|
|
170
|
+
margin: 12px 0;
|
|
171
|
+
padding: 8px 16px;
|
|
172
|
+
border: 1px solid #aaa;
|
|
173
|
+
border-radius: 8px;
|
|
174
|
+
background: #fff;
|
|
175
|
+
color: #333;
|
|
176
|
+
cursor: pointer;
|
|
177
|
+
font-size: 1rem;
|
|
178
|
+
text-align: left;
|
|
179
|
+
transition: background 0.2s;
|
|
180
|
+
}
|
|
181
|
+
.toc-btn:hover {
|
|
182
|
+
background: #f0f0f0;
|
|
183
|
+
}
|
|
184
|
+
`; }
|
|
185
|
+
get context() {
|
|
186
|
+
return {
|
|
187
|
+
title: i18next.t('title.kpi overview')
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
async firstUpdated() {
|
|
191
|
+
try {
|
|
192
|
+
const { data } = await client.query({ query: GET_KPI_OVERVIEW });
|
|
193
|
+
this.kpiCategories = data.kpiCategories.items;
|
|
194
|
+
this.loading = false;
|
|
195
|
+
}
|
|
196
|
+
catch (e) {
|
|
197
|
+
this.error = e instanceof Error ? e : new Error(String(e));
|
|
198
|
+
this.loading = false;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
render() {
|
|
202
|
+
if (this.error)
|
|
203
|
+
return html `<div>에러: ${this.error?.message}</div>`;
|
|
204
|
+
if (!this.kpiCategories.length)
|
|
205
|
+
return html `<div>KPI 카테고리가 없습니다.</div>`;
|
|
206
|
+
const group = this.kpiCategories[this.selectedGroup];
|
|
207
|
+
const kpi = group?.kpis?.[this.selectedKpi];
|
|
208
|
+
const md = kpi?.description || '각 지표의 주요 소개 내용을 마크다운으로 입력하세요.';
|
|
209
|
+
return html `
|
|
210
|
+
<div class="overview-container">
|
|
211
|
+
<div class="overview-left">
|
|
212
|
+
<div class="overview-title">KPI개요</div>
|
|
213
|
+
<div class="overview-desc">
|
|
214
|
+
건설현장 KPI 관리 시스템은 프로젝트 성과를 측정하고 모니터링하여 효율적인 공정 관리를 지원합니다.<br />
|
|
215
|
+
주요 지표를 통해 현장 생산성, 품질, 안전 등을 실시간으로 파악할 수 있습니다.
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
<div class="overview-right">
|
|
219
|
+
<img
|
|
220
|
+
class="overview-img"
|
|
221
|
+
src="https://images.unsplash.com/photo-1464983953574-0892a716854b?auto=format&fit=crop&w=600&q=80"
|
|
222
|
+
alt="건설현장 안전"
|
|
223
|
+
/>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
<div class="group-tabs">
|
|
227
|
+
${this.kpiCategories.map((g, i) => html `
|
|
228
|
+
<button
|
|
229
|
+
class="group-tab"
|
|
230
|
+
?selected=${i === this.selectedGroup}
|
|
231
|
+
@click=${() => {
|
|
232
|
+
this.selectedGroup = i;
|
|
233
|
+
this.selectedKpi = 0;
|
|
234
|
+
}}
|
|
235
|
+
>
|
|
236
|
+
${g.name}
|
|
237
|
+
</button>
|
|
238
|
+
`)}
|
|
239
|
+
</div>
|
|
240
|
+
<div class="main-content">
|
|
241
|
+
<div class="markdown">
|
|
242
|
+
<div style="font-size:1.5rem;font-weight:bold;margin-bottom:16px;">${kpi?.name || ''}</div>
|
|
243
|
+
<div style="margin-bottom:16px;">${kpi?.formula ? html `<b>산식:</b> ${kpi.formula}` : ''}</div>
|
|
244
|
+
<div .innerHTML=${marked(md)}></div>
|
|
245
|
+
${kpi?.grades?.length
|
|
246
|
+
? html `<div style="margin-top:32px;">
|
|
247
|
+
<b>등급 구간</b>
|
|
248
|
+
<ul>
|
|
249
|
+
${kpi.grades.map(g => html `<li>${g.name}: ${g.minValue}~${g.maxValue} (${g.description || ''})</li>`)}
|
|
250
|
+
</ul>
|
|
251
|
+
</div>`
|
|
252
|
+
: ''}
|
|
253
|
+
</div>
|
|
254
|
+
<div class="toc">
|
|
255
|
+
<div class="toc-title">목차</div>
|
|
256
|
+
<ul class="toc-list">
|
|
257
|
+
${group?.kpis?.map((k, i) => html `
|
|
258
|
+
<li><button class="toc-btn" @click=${() => (this.selectedKpi = i)}>${k.name}</button></li>
|
|
259
|
+
`)}
|
|
260
|
+
</ul>
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
`;
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
__decorate([
|
|
267
|
+
state(),
|
|
268
|
+
__metadata("design:type", Object)
|
|
269
|
+
], KpiOverview.prototype, "selectedGroup", void 0);
|
|
270
|
+
__decorate([
|
|
271
|
+
state(),
|
|
272
|
+
__metadata("design:type", Object)
|
|
273
|
+
], KpiOverview.prototype, "selectedKpi", void 0);
|
|
274
|
+
__decorate([
|
|
275
|
+
state(),
|
|
276
|
+
__metadata("design:type", Array)
|
|
277
|
+
], KpiOverview.prototype, "kpiCategories", void 0);
|
|
278
|
+
__decorate([
|
|
279
|
+
state(),
|
|
280
|
+
__metadata("design:type", Object)
|
|
281
|
+
], KpiOverview.prototype, "loading", void 0);
|
|
282
|
+
__decorate([
|
|
283
|
+
state(),
|
|
284
|
+
__metadata("design:type", Object)
|
|
285
|
+
], KpiOverview.prototype, "error", void 0);
|
|
286
|
+
KpiOverview = __decorate([
|
|
287
|
+
customElement('kpi-overview')
|
|
288
|
+
], KpiOverview);
|
|
289
|
+
export { KpiOverview };
|
|
290
|
+
//# sourceMappingURL=kpi-overview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kpi-overview.js","sourceRoot":"","sources":["../../../client/pages/kpi/kpi-overview.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, LitElement } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\nimport { marked } from 'marked'\nimport { PageView, store } from '@operato/shell'\nimport { i18next, localize } from '@operato/i18n'\nimport { client } from '@operato/graphql'\nimport gql from 'graphql-tag'\n\nconst GET_KPI_OVERVIEW = gql`\n query {\n kpiCategories {\n items {\n id\n name\n description\n active\n kpis {\n id\n name\n description\n formula\n active\n grades {\n id\n name\n minValue\n maxValue\n score\n color\n description\n }\n }\n }\n }\n }\n`\n\n@customElement('kpi-overview')\nexport class KpiOverview extends PageView {\n static styles = css`\n .overview-container {\n display: flex;\n gap: 32px;\n background: #f7f5fa;\n border-radius: 20px;\n padding: 32px;\n margin-bottom: 24px;\n align-items: stretch;\n }\n .overview-left {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n }\n .overview-title {\n font-size: 2.8rem;\n font-weight: bold;\n margin-bottom: 24px;\n }\n .overview-desc {\n font-size: 1.2rem;\n color: #222;\n line-height: 1.6;\n }\n .overview-right {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .overview-img {\n width: 100%;\n max-width: 420px;\n border-radius: 12px;\n object-fit: cover;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n }\n .group-tabs {\n display: flex;\n gap: 8px;\n margin: 0 0 16px 0;\n justify-content: center;\n }\n .group-tab {\n padding: 10px 28px;\n border-radius: 16px 16px 0 0;\n background: #eee;\n cursor: pointer;\n font-size: 1.1rem;\n font-weight: 500;\n border: none;\n outline: none;\n transition: background 0.2s;\n }\n .group-tab[selected] {\n background: #d6d6f7;\n color: #222;\n font-weight: bold;\n }\n .kpi-list {\n display: flex;\n gap: 8px;\n margin: 0 0 32px 0;\n justify-content: center;\n }\n .kpi-item {\n padding: 8px 20px;\n border-radius: 12px;\n background: #f5f5f5;\n cursor: pointer;\n font-size: 1rem;\n border: none;\n outline: none;\n transition: background 0.2s;\n }\n .kpi-item[selected] {\n background: #bdf;\n color: #222;\n font-weight: bold;\n }\n .main-content {\n display: flex;\n gap: 32px;\n margin-top: 32px;\n align-items: flex-start;\n justify-content: center;\n }\n .markdown {\n background: #fff;\n border-radius: 12px;\n padding: 40px 32px;\n min-height: 240px;\n flex: 2;\n font-size: 2rem;\n color: #222;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n }\n .toc {\n flex: 1;\n background: #faf9fd;\n border-radius: 12px;\n padding: 32px 24px;\n font-size: 1.1rem;\n color: #444;\n min-width: 220px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);\n }\n .toc-title {\n font-weight: bold;\n margin-bottom: 12px;\n font-size: 1.2rem;\n }\n .toc-list {\n margin: 0 0 16px 0;\n padding: 0;\n list-style: none;\n }\n .toc-list li {\n margin-bottom: 6px;\n }\n .toc-btn {\n display: block;\n margin: 12px 0;\n padding: 8px 16px;\n border: 1px solid #aaa;\n border-radius: 8px;\n background: #fff;\n color: #333;\n cursor: pointer;\n font-size: 1rem;\n text-align: left;\n transition: background 0.2s;\n }\n .toc-btn:hover {\n background: #f0f0f0;\n }\n `\n\n get context() {\n return {\n title: i18next.t('title.kpi overview')\n }\n }\n\n @state() selectedGroup = 0\n @state() selectedKpi = 0\n @state() kpiCategories: any[] = []\n @state() loading = true\n @state() error: Error | null = null\n\n async firstUpdated() {\n try {\n const { data } = await client.query({ query: GET_KPI_OVERVIEW })\n this.kpiCategories = data.kpiCategories.items\n this.loading = false\n } catch (e) {\n this.error = e instanceof Error ? e : new Error(String(e))\n this.loading = false\n }\n }\n\n render() {\n if (this.error) return html`<div>에러: ${this.error?.message}</div>`\n if (!this.kpiCategories.length) return html`<div>KPI 카테고리가 없습니다.</div>`\n\n const group = this.kpiCategories[this.selectedGroup] as any\n const kpi = group?.kpis?.[this.selectedKpi] as any\n const md = kpi?.description || '각 지표의 주요 소개 내용을 마크다운으로 입력하세요.'\n\n return html`\n <div class=\"overview-container\">\n <div class=\"overview-left\">\n <div class=\"overview-title\">KPI개요</div>\n <div class=\"overview-desc\">\n 건설현장 KPI 관리 시스템은 프로젝트 성과를 측정하고 모니터링하여 효율적인 공정 관리를 지원합니다.<br />\n 주요 지표를 통해 현장 생산성, 품질, 안전 등을 실시간으로 파악할 수 있습니다.\n </div>\n </div>\n <div class=\"overview-right\">\n <img\n class=\"overview-img\"\n src=\"https://images.unsplash.com/photo-1464983953574-0892a716854b?auto=format&fit=crop&w=600&q=80\"\n alt=\"건설현장 안전\"\n />\n </div>\n </div>\n <div class=\"group-tabs\">\n ${this.kpiCategories.map(\n (g, i) => html`\n <button\n class=\"group-tab\"\n ?selected=${i === this.selectedGroup}\n @click=${() => {\n this.selectedGroup = i\n this.selectedKpi = 0\n }}\n >\n ${g.name}\n </button>\n `\n )}\n </div>\n <div class=\"main-content\">\n <div class=\"markdown\">\n <div style=\"font-size:1.5rem;font-weight:bold;margin-bottom:16px;\">${kpi?.name || ''}</div>\n <div style=\"margin-bottom:16px;\">${kpi?.formula ? html`<b>산식:</b> ${kpi.formula}` : ''}</div>\n <div .innerHTML=${marked(md)}></div>\n ${kpi?.grades?.length\n ? html`<div style=\"margin-top:32px;\">\n <b>등급 구간</b>\n <ul>\n ${kpi.grades.map(g => html`<li>${g.name}: ${g.minValue}~${g.maxValue} (${g.description || ''})</li>`)}\n </ul>\n </div>`\n : ''}\n </div>\n <div class=\"toc\">\n <div class=\"toc-title\">목차</div>\n <ul class=\"toc-list\">\n ${group?.kpis?.map(\n (k, i) => html`\n <li><button class=\"toc-btn\" @click=${() => (this.selectedKpi = i)}>${k.name}</button></li>\n `\n )}\n </ul>\n </div>\n </div>\n `\n }\n}\n"]}
|
|
@@ -37,6 +37,21 @@ export class KpiCategoryImporter extends LitElement {
|
|
|
37
37
|
]
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
+
static { this.styles = [
|
|
41
|
+
ButtonContainerStyles,
|
|
42
|
+
css `
|
|
43
|
+
:host {
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
|
|
47
|
+
background-color: #fff;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
ox-grist {
|
|
51
|
+
flex: 1;
|
|
52
|
+
}
|
|
53
|
+
`
|
|
54
|
+
]; }
|
|
40
55
|
render() {
|
|
41
56
|
return html `
|
|
42
57
|
<ox-grist
|
|
@@ -53,7 +68,6 @@ export class KpiCategoryImporter extends LitElement {
|
|
|
53
68
|
`;
|
|
54
69
|
}
|
|
55
70
|
async save() {
|
|
56
|
-
var _a;
|
|
57
71
|
const response = await client.mutate({
|
|
58
72
|
mutation: gql `
|
|
59
73
|
mutation importKpiCategories($kpiCategories: [KpiCategoryPatch!]!) {
|
|
@@ -62,26 +76,11 @@ export class KpiCategoryImporter extends LitElement {
|
|
|
62
76
|
`,
|
|
63
77
|
variables: { kpiCategories: this.kpiCategories }
|
|
64
78
|
});
|
|
65
|
-
if (
|
|
79
|
+
if (response.errors?.length)
|
|
66
80
|
return;
|
|
67
81
|
this.dispatchEvent(new CustomEvent('imported'));
|
|
68
82
|
}
|
|
69
83
|
}
|
|
70
|
-
KpiCategoryImporter.styles = [
|
|
71
|
-
ButtonContainerStyles,
|
|
72
|
-
css `
|
|
73
|
-
:host {
|
|
74
|
-
display: flex;
|
|
75
|
-
flex-direction: column;
|
|
76
|
-
|
|
77
|
-
background-color: #fff;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
ox-grist {
|
|
81
|
-
flex: 1;
|
|
82
|
-
}
|
|
83
|
-
`
|
|
84
|
-
];
|
|
85
84
|
__decorate([
|
|
86
85
|
property({ type: Array }),
|
|
87
86
|
__metadata("design:type", Array)
|