@dssp/dkpi 1.0.0-alpha.87 → 1.0.0-alpha.88
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/_index.html +4 -4
- package/assets/helps/index.md +1 -1
- package/assets/manifest.json +2 -2
- package/dist-client/components/kpi-boxplot-chart.d.ts +7 -0
- package/dist-client/components/kpi-boxplot-chart.js +20 -5
- package/dist-client/components/kpi-boxplot-chart.js.map +1 -1
- package/dist-client/components/kpi-lookup-chart.js +1 -17
- package/dist-client/components/kpi-lookup-chart.js.map +1 -1
- package/dist-client/components/kpi-radar-chart.js +2 -2
- package/dist-client/components/kpi-radar-chart.js.map +1 -1
- package/dist-client/components/kpi-single-boxplot-chart.d.ts +7 -0
- package/dist-client/components/kpi-single-boxplot-chart.js +27 -26
- package/dist-client/components/kpi-single-boxplot-chart.js.map +1 -1
- package/dist-client/components/kpi-step-lookup-chart.d.ts +33 -0
- package/dist-client/components/kpi-step-lookup-chart.js +181 -0
- package/dist-client/components/kpi-step-lookup-chart.js.map +1 -0
- package/dist-client/components/kpi-trend-chart.js +2 -12
- package/dist-client/components/kpi-trend-chart.js.map +1 -1
- package/dist-client/google-map/common-google-map.js +5 -1
- package/dist-client/google-map/common-google-map.js.map +1 -1
- package/dist-client/pages/kpi-admin/dssp-kpi-overview.d.ts +2 -1
- package/dist-client/pages/kpi-admin/dssp-kpi-overview.js +24 -9
- package/dist-client/pages/kpi-admin/dssp-kpi-overview.js.map +1 -1
- package/dist-client/pages/kpi-admin/kpi-system-guide.js +311 -158
- package/dist-client/pages/kpi-admin/kpi-system-guide.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.d.ts +6 -0
- package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js +110 -50
- package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.d.ts +0 -9
- package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js +6 -91
- package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.d.ts +2 -0
- package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js +148 -68
- package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js +85 -41
- package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/kpi-dashboard.js +15 -7
- package/dist-client/pages/kpi-dashboard/kpi-dashboard.js.map +1 -1
- package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js +16 -25
- package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js.map +1 -1
- package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js +9 -13
- package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js.map +1 -1
- package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.js +9 -15
- package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.js.map +1 -1
- package/dist-client/pages/sv-project-complete.js +7 -11
- package/dist-client/pages/sv-project-complete.js.map +1 -1
- package/dist-client/pages/sv-project-completed-list.js +4 -4
- package/dist-client/pages/sv-project-completed-list.js.map +1 -1
- package/dist-client/pages/sv-project-detail.d.ts +1 -0
- package/dist-client/pages/sv-project-detail.js +65 -51
- package/dist-client/pages/sv-project-detail.js.map +1 -1
- package/dist-client/pages/sv-project-list.js +15 -12
- package/dist-client/pages/sv-project-list.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/viewparts/menu-tools.js +17 -3
- package/dist-client/viewparts/menu-tools.js.map +1 -1
- package/dist-server/service/kpi-stat/kpi-stat-query.js +20 -19
- package/dist-server/service/kpi-stat/kpi-stat-query.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/openapi/unstable.yaml +2 -2
- package/package.json +3 -3
- package/schema.graphql +20 -0
- package/translations/ko.json +2 -2
- package/views/auth-page.html +4 -4
- package/views/public/home.html +5 -5
|
@@ -58,7 +58,7 @@ const EXTERNAL_SYSTEM_URLS = {
|
|
|
58
58
|
'세움터(EAIS)': 'https://cloud.eais.go.kr',
|
|
59
59
|
'키스콘(KISCON)': 'https://www.kiscon.net',
|
|
60
60
|
'올바로(Allbaro)': 'https://www.allbaro.or.kr',
|
|
61
|
-
|
|
61
|
+
전자카드제: 'https://www.cw.or.kr'
|
|
62
62
|
};
|
|
63
63
|
const VALUE_TYPE_LABELS = {
|
|
64
64
|
MEASURED: { label: '외부 수집', color: '#1976d2', icon: '📡' },
|
|
@@ -98,7 +98,7 @@ let KpiSystemGuide = class KpiSystemGuide extends PageView {
|
|
|
98
98
|
for (const y of this.kpiRoot) {
|
|
99
99
|
if (y.active === false)
|
|
100
100
|
continue;
|
|
101
|
-
for (const x of
|
|
101
|
+
for (const x of y.kpis || []) {
|
|
102
102
|
if (x.active === false)
|
|
103
103
|
continue;
|
|
104
104
|
if ((_a = x.formula) === null || _a === void 0 ? void 0 : _a.includes(`[${metricName}]`)) {
|
|
@@ -122,8 +122,7 @@ let KpiSystemGuide = class KpiSystemGuide extends PageView {
|
|
|
122
122
|
return html `
|
|
123
123
|
<div class="page-title">KPI 시스템 가이드</div>
|
|
124
124
|
<div class="page-subtitle">
|
|
125
|
-
|
|
126
|
-
모든 정보는 DB에서 실시간 조회됩니다.
|
|
125
|
+
건축프로젝트 성과평가 KPI 체계의 전체 구조, 산식, 메트릭 연관관계를 확인합니다. 모든 정보는 DB에서 실시간 조회됩니다.
|
|
127
126
|
</div>
|
|
128
127
|
|
|
129
128
|
<!-- 범례 -->
|
|
@@ -140,44 +139,58 @@ let KpiSystemGuide = class KpiSystemGuide extends PageView {
|
|
|
140
139
|
<div class="section-title">📊 KPI 계층 구조 (Z → Y → X)</div>
|
|
141
140
|
|
|
142
141
|
<!-- Z 루트 -->
|
|
143
|
-
<div
|
|
142
|
+
<div
|
|
143
|
+
class="z-node"
|
|
144
|
+
@click=${() => this.showDetail({
|
|
145
|
+
name: 'Z. 전체스코어',
|
|
146
|
+
description: 'Y1~Y6 가중합',
|
|
147
|
+
formula: 'Y1×w1 + Y2×w2 + ... + Y6×w6',
|
|
148
|
+
scoreType: 'DIRECT',
|
|
149
|
+
valueType: 'CALCULATED'
|
|
150
|
+
}, 'kpi')}
|
|
151
|
+
>
|
|
144
152
|
<div class="z-name">Z. 전체스코어</div>
|
|
145
|
-
<div class="z-formula"
|
|
153
|
+
<div class="z-formula">
|
|
154
|
+
=
|
|
155
|
+
${this.kpiRoot
|
|
146
156
|
.filter((y) => y.active !== false)
|
|
147
157
|
.map((y) => `${y.name.split('.')[0]}×${y.weight}`)
|
|
148
|
-
.join(' + ')}
|
|
158
|
+
.join(' + ')}
|
|
159
|
+
</div>
|
|
149
160
|
</div>
|
|
150
161
|
|
|
151
162
|
<!-- Y 그룹들 (비활성 Y 제외) -->
|
|
152
|
-
${this.kpiRoot
|
|
163
|
+
${this.kpiRoot
|
|
164
|
+
.filter((y) => y.active !== false)
|
|
165
|
+
.map((y) => {
|
|
153
166
|
const activeKpis = (y.kpis || []).filter((x) => x.active !== false);
|
|
154
167
|
return html `
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
168
|
+
<div class="y-group">
|
|
169
|
+
<div class="y-header" @click=${() => this.showDetail(y, 'kpi')}>
|
|
170
|
+
<span class="y-name">${y.name}</span>
|
|
171
|
+
<span class="y-weight">가중치: ${y.weight}</span>
|
|
172
|
+
</div>
|
|
173
|
+
<div class="y-body">
|
|
174
|
+
${y.formula ? html `<div class="y-formula">${y.formula}</div>` : ''}
|
|
175
|
+
<div class="x-cards">
|
|
176
|
+
${activeKpis.map((x) => {
|
|
164
177
|
const st = SCORE_TYPE_LABELS[x.scoreType] || { label: x.scoreType || '미설정', color: '#999' };
|
|
165
178
|
const vt = VALUE_TYPE_LABELS[x.valueType] || { label: x.valueType || '미설정', color: '#999', icon: '?' };
|
|
166
179
|
return html `
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
180
|
+
<div class="x-card" @click=${() => this.showDetail(x, 'kpi')}>
|
|
181
|
+
<div class="x-name">${x.name}</div>
|
|
182
|
+
<div class="x-formula">${x.formula || '—'}</div>
|
|
183
|
+
<div class="x-badges">
|
|
184
|
+
<span class="badge badge-score">${st.label}</span>
|
|
185
|
+
<span class="badge badge-value">${vt.icon} ${vt.label}</span>
|
|
186
|
+
</div>
|
|
173
187
|
</div>
|
|
174
|
-
|
|
175
|
-
`;
|
|
188
|
+
`;
|
|
176
189
|
})}
|
|
190
|
+
</div>
|
|
177
191
|
</div>
|
|
178
192
|
</div>
|
|
179
|
-
|
|
180
|
-
`;
|
|
193
|
+
`;
|
|
181
194
|
})}
|
|
182
195
|
</div>
|
|
183
196
|
|
|
@@ -192,21 +205,26 @@ let KpiSystemGuide = class KpiSystemGuide extends PageView {
|
|
|
192
205
|
<div class="section-title">📋 원천 메트릭 (${usedMetrics.length}개 사용)</div>
|
|
193
206
|
<div class="metrics-grid">
|
|
194
207
|
${usedMetrics.map(({ m, usage }) => html `
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
208
|
+
<div class="metric-card" @click=${() => this.showDetail(m, 'metric')}>
|
|
209
|
+
<div class="metric-name">${m.name}</div>
|
|
210
|
+
<div class="metric-unit">
|
|
211
|
+
${m.unit || '—'} ·
|
|
212
|
+
${m.collectType === 'EXTERNAL' && m.source
|
|
200
213
|
? EXTERNAL_SYSTEM_URLS[m.source]
|
|
201
|
-
? html `<a
|
|
202
|
-
|
|
203
|
-
|
|
214
|
+
? html `<a
|
|
215
|
+
href="${EXTERNAL_SYSTEM_URLS[m.source]}"
|
|
216
|
+
target="_blank"
|
|
217
|
+
rel="noopener"
|
|
218
|
+
style="color:#1976d2;text-decoration:none;"
|
|
219
|
+
@click=${(e) => e.stopPropagation()}
|
|
220
|
+
>${m.source} ↗</a
|
|
221
|
+
>`
|
|
204
222
|
: m.source
|
|
205
223
|
: m.collectType || 'MANUAL'}
|
|
224
|
+
</div>
|
|
225
|
+
<div class="metric-used">→ ${usage.join(', ')}</div>
|
|
206
226
|
</div>
|
|
207
|
-
|
|
208
|
-
</div>
|
|
209
|
-
`)}
|
|
227
|
+
`)}
|
|
210
228
|
</div>
|
|
211
229
|
</div>
|
|
212
230
|
`;
|
|
@@ -221,15 +239,21 @@ let KpiSystemGuide = class KpiSystemGuide extends PageView {
|
|
|
221
239
|
<div style="font-size:0.85rem;color:#555;">X-level 지표</div>
|
|
222
240
|
</div>
|
|
223
241
|
<div style="flex:1;min-width:200px;background:#e8f5e9;padding:16px;border-radius:8px;text-align:center;">
|
|
224
|
-
<div style="font-size:2rem;font-weight:800;color:#2e7d32;"
|
|
242
|
+
<div style="font-size:2rem;font-weight:800;color:#2e7d32;">
|
|
243
|
+
${this.kpiRoot.filter((y) => y.active !== false).length}
|
|
244
|
+
</div>
|
|
225
245
|
<div style="font-size:0.85rem;color:#555;">Y-level 영역</div>
|
|
226
246
|
</div>
|
|
227
247
|
<div style="flex:1;min-width:200px;background:#fff3e0;padding:16px;border-radius:8px;text-align:center;">
|
|
228
|
-
<div style="font-size:2rem;font-weight:800;color:#e65100;"
|
|
248
|
+
<div style="font-size:2rem;font-weight:800;color:#e65100;">
|
|
249
|
+
${this.metrics.filter((m) => m.active && this.getMetricUsage(m.name).length > 0).length}
|
|
250
|
+
</div>
|
|
229
251
|
<div style="font-size:0.85rem;color:#555;">원천 메트릭</div>
|
|
230
252
|
</div>
|
|
231
253
|
<div style="flex:1;min-width:200px;background:#fce4ec;padding:16px;border-radius:8px;text-align:center;">
|
|
232
|
-
<div style="font-size:2rem;font-weight:800;color:#c62828;"
|
|
254
|
+
<div style="font-size:2rem;font-weight:800;color:#c62828;">
|
|
255
|
+
${allX.filter((x) => x.valueType === 'ASSESSED').length}
|
|
256
|
+
</div>
|
|
233
257
|
<div style="font-size:0.85rem;color:#555;">감리자 평가 항목</div>
|
|
234
258
|
</div>
|
|
235
259
|
</div>
|
|
@@ -250,83 +274,112 @@ let KpiSystemGuide = class KpiSystemGuide extends PageView {
|
|
|
250
274
|
<button class="popup-close" @click=${() => this.closeDetail()}>×</button>
|
|
251
275
|
</div>
|
|
252
276
|
|
|
253
|
-
${d.description
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
277
|
+
${d.description
|
|
278
|
+
? html `
|
|
279
|
+
<div class="popup-row">
|
|
280
|
+
<span class="popup-label">설명</span>
|
|
281
|
+
<span class="popup-value">${d.description}</span>
|
|
282
|
+
</div>
|
|
283
|
+
`
|
|
284
|
+
: ''}
|
|
285
|
+
${isKpi
|
|
286
|
+
? html `
|
|
287
|
+
${d.formula
|
|
288
|
+
? html `
|
|
289
|
+
<div class="popup-row"><span class="popup-label">산식</span></div>
|
|
290
|
+
<div class="popup-formula">${d.formula}</div>
|
|
291
|
+
`
|
|
292
|
+
: ''}
|
|
293
|
+
${d.scoreType
|
|
294
|
+
? html `
|
|
295
|
+
<div class="popup-row">
|
|
296
|
+
<span class="popup-label">Score 산정</span>
|
|
297
|
+
<span class="popup-value" style="color:${(SCORE_TYPE_LABELS[d.scoreType] || {}).color || '#333'}">
|
|
298
|
+
${(SCORE_TYPE_LABELS[d.scoreType] || {}).label || d.scoreType}
|
|
299
|
+
</span>
|
|
300
|
+
</div>
|
|
301
|
+
`
|
|
302
|
+
: ''}
|
|
303
|
+
${d.valueType
|
|
304
|
+
? html `
|
|
305
|
+
<div class="popup-row">
|
|
306
|
+
<span class="popup-label">Value 획득</span>
|
|
307
|
+
<span class="popup-value" style="color:${(VALUE_TYPE_LABELS[d.valueType] || {}).color || '#333'}">
|
|
308
|
+
${(VALUE_TYPE_LABELS[d.valueType] || {}).icon || ''}
|
|
309
|
+
${(VALUE_TYPE_LABELS[d.valueType] || {}).label || d.valueType}
|
|
310
|
+
</span>
|
|
311
|
+
</div>
|
|
312
|
+
`
|
|
313
|
+
: ''}
|
|
314
|
+
${d.weight
|
|
315
|
+
? html `
|
|
316
|
+
<div class="popup-row">
|
|
317
|
+
<span class="popup-label">가중치</span>
|
|
318
|
+
<span class="popup-value">${d.weight}</span>
|
|
319
|
+
</div>
|
|
320
|
+
`
|
|
321
|
+
: ''}
|
|
290
322
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
323
|
+
<div style="margin-top:16px;padding-top:12px;border-top:1px solid #eee;">
|
|
324
|
+
<span
|
|
325
|
+
class="popup-link"
|
|
326
|
+
@click=${() => {
|
|
327
|
+
this.closeDetail();
|
|
328
|
+
navigate('kpi-overview');
|
|
329
|
+
}}
|
|
330
|
+
>
|
|
331
|
+
→ KPI 개요에서 보기
|
|
332
|
+
</span>
|
|
333
|
+
|
|
334
|
+
<span
|
|
335
|
+
class="popup-link"
|
|
336
|
+
@click=${() => {
|
|
337
|
+
this.closeDetail();
|
|
338
|
+
navigate('kpi-admin');
|
|
339
|
+
}}
|
|
340
|
+
>
|
|
341
|
+
→ KPI 관리에서 편집
|
|
342
|
+
</span>
|
|
343
|
+
</div>
|
|
344
|
+
`
|
|
345
|
+
: html `
|
|
346
|
+
<div class="popup-row">
|
|
347
|
+
<span class="popup-label">단위</span>
|
|
348
|
+
<span class="popup-value">${d.unit || '—'}</span>
|
|
349
|
+
</div>
|
|
350
|
+
<div class="popup-row">
|
|
351
|
+
<span class="popup-label">수집 방식</span>
|
|
352
|
+
<span class="popup-value">${d.collectType || 'MANUAL'}</span>
|
|
353
|
+
</div>
|
|
354
|
+
<div class="popup-row">
|
|
355
|
+
<span class="popup-label">데이터 소스</span>
|
|
356
|
+
<span class="popup-value">
|
|
357
|
+
${d.source && EXTERNAL_SYSTEM_URLS[d.source]
|
|
358
|
+
? html `<a href="${EXTERNAL_SYSTEM_URLS[d.source]}" target="_blank" rel="noopener" style="color:#1976d2;"
|
|
359
|
+
>${d.source} ↗</a
|
|
360
|
+
>`
|
|
361
|
+
: d.source || '미설정'}
|
|
362
|
+
</span>
|
|
363
|
+
</div>
|
|
317
364
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
365
|
+
<div style="margin-top:12px;">
|
|
366
|
+
<div class="popup-label" style="margin-bottom:6px;">사용처:</div>
|
|
367
|
+
${this.getMetricUsage(d.name).map(kpi => html `<div style="font-size:0.85rem;color:#1976d2;margin-bottom:2px;">· ${kpi}</div>`)}
|
|
368
|
+
${this.getMetricUsage(d.name).length === 0 ? html `<div style="color:#ccc;font-size:0.85rem;">미사용</div>` : ''}
|
|
369
|
+
</div>
|
|
323
370
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
371
|
+
<div style="margin-top:16px;padding-top:12px;border-top:1px solid #eee;">
|
|
372
|
+
<span
|
|
373
|
+
class="popup-link"
|
|
374
|
+
@click=${() => {
|
|
375
|
+
this.closeDetail();
|
|
376
|
+
navigate('kpi-metric-value-list');
|
|
377
|
+
}}
|
|
378
|
+
>
|
|
379
|
+
→ 메트릭 값 관리
|
|
380
|
+
</span>
|
|
381
|
+
</div>
|
|
382
|
+
`}
|
|
330
383
|
</div>
|
|
331
384
|
</div>
|
|
332
385
|
`;
|
|
@@ -360,7 +413,7 @@ KpiSystemGuide.styles = [
|
|
|
360
413
|
border-radius: 12px;
|
|
361
414
|
padding: 24px;
|
|
362
415
|
margin-bottom: 24px;
|
|
363
|
-
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
|
|
416
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
|
364
417
|
}
|
|
365
418
|
.section-title {
|
|
366
419
|
font-size: 1.1rem;
|
|
@@ -381,9 +434,19 @@ KpiSystemGuide.styles = [
|
|
|
381
434
|
margin-bottom: 16px;
|
|
382
435
|
cursor: pointer;
|
|
383
436
|
}
|
|
384
|
-
.z-node:hover {
|
|
385
|
-
|
|
386
|
-
|
|
437
|
+
.z-node:hover {
|
|
438
|
+
opacity: 0.95;
|
|
439
|
+
}
|
|
440
|
+
.z-name {
|
|
441
|
+
font-size: 1.1rem;
|
|
442
|
+
font-weight: 700;
|
|
443
|
+
}
|
|
444
|
+
.z-formula {
|
|
445
|
+
font-size: 0.8rem;
|
|
446
|
+
opacity: 0.8;
|
|
447
|
+
margin-top: 4px;
|
|
448
|
+
font-family: monospace;
|
|
449
|
+
}
|
|
387
450
|
|
|
388
451
|
/* Y 그룹 */
|
|
389
452
|
.y-group {
|
|
@@ -401,15 +464,22 @@ KpiSystemGuide.styles = [
|
|
|
401
464
|
align-items: center;
|
|
402
465
|
cursor: pointer;
|
|
403
466
|
}
|
|
404
|
-
.y-header:hover {
|
|
405
|
-
|
|
467
|
+
.y-header:hover {
|
|
468
|
+
opacity: 0.95;
|
|
469
|
+
}
|
|
470
|
+
.y-name {
|
|
471
|
+
font-weight: 700;
|
|
472
|
+
font-size: 1rem;
|
|
473
|
+
}
|
|
406
474
|
.y-weight {
|
|
407
|
-
background: rgba(255,255,255,0.2);
|
|
475
|
+
background: rgba(255, 255, 255, 0.2);
|
|
408
476
|
padding: 2px 10px;
|
|
409
477
|
border-radius: 12px;
|
|
410
478
|
font-size: 0.8rem;
|
|
411
479
|
}
|
|
412
|
-
.y-body {
|
|
480
|
+
.y-body {
|
|
481
|
+
padding: 12px;
|
|
482
|
+
}
|
|
413
483
|
.y-formula {
|
|
414
484
|
font-size: 0.8rem;
|
|
415
485
|
color: #555;
|
|
@@ -422,7 +492,11 @@ KpiSystemGuide.styles = [
|
|
|
422
492
|
}
|
|
423
493
|
|
|
424
494
|
/* X 카드 */
|
|
425
|
-
.x-cards {
|
|
495
|
+
.x-cards {
|
|
496
|
+
display: flex;
|
|
497
|
+
flex-wrap: wrap;
|
|
498
|
+
gap: 8px;
|
|
499
|
+
}
|
|
426
500
|
.x-card {
|
|
427
501
|
flex: 1 1 220px;
|
|
428
502
|
background: #fff;
|
|
@@ -435,23 +509,42 @@ KpiSystemGuide.styles = [
|
|
|
435
509
|
}
|
|
436
510
|
.x-card:hover {
|
|
437
511
|
border-color: #1976d2;
|
|
438
|
-
box-shadow: 0 2px 8px rgba(25,118,210,0.15);
|
|
512
|
+
box-shadow: 0 2px 8px rgba(25, 118, 210, 0.15);
|
|
513
|
+
}
|
|
514
|
+
.x-name {
|
|
515
|
+
font-weight: 600;
|
|
516
|
+
font-size: 0.85rem;
|
|
517
|
+
color: #333;
|
|
518
|
+
margin-bottom: 4px;
|
|
439
519
|
}
|
|
440
|
-
.x-name { font-weight: 600; font-size: 0.85rem; color: #333; margin-bottom: 4px; }
|
|
441
520
|
.x-formula {
|
|
442
|
-
font-size: 0.75rem;
|
|
443
|
-
|
|
521
|
+
font-size: 0.75rem;
|
|
522
|
+
color: #888;
|
|
523
|
+
font-family: monospace;
|
|
524
|
+
white-space: nowrap;
|
|
525
|
+
overflow: hidden;
|
|
526
|
+
text-overflow: ellipsis;
|
|
444
527
|
margin-bottom: 6px;
|
|
445
528
|
}
|
|
446
|
-
.x-badges {
|
|
529
|
+
.x-badges {
|
|
530
|
+
display: flex;
|
|
531
|
+
gap: 4px;
|
|
532
|
+
flex-wrap: wrap;
|
|
533
|
+
}
|
|
447
534
|
.badge {
|
|
448
535
|
font-size: 0.65rem;
|
|
449
536
|
padding: 2px 6px;
|
|
450
537
|
border-radius: 4px;
|
|
451
538
|
font-weight: 600;
|
|
452
539
|
}
|
|
453
|
-
.badge-score {
|
|
454
|
-
|
|
540
|
+
.badge-score {
|
|
541
|
+
background: #e3f2fd;
|
|
542
|
+
color: #1565c0;
|
|
543
|
+
}
|
|
544
|
+
.badge-value {
|
|
545
|
+
background: #e8f5e9;
|
|
546
|
+
color: #2e7d32;
|
|
547
|
+
}
|
|
455
548
|
|
|
456
549
|
/* 메트릭 섹션 */
|
|
457
550
|
.metrics-grid {
|
|
@@ -466,58 +559,118 @@ KpiSystemGuide.styles = [
|
|
|
466
559
|
padding: 10px 14px;
|
|
467
560
|
transition: all 0.2s;
|
|
468
561
|
}
|
|
469
|
-
.metric-card:hover {
|
|
470
|
-
|
|
471
|
-
|
|
562
|
+
.metric-card:hover {
|
|
563
|
+
border-color: #4caf50;
|
|
564
|
+
}
|
|
565
|
+
.metric-name {
|
|
566
|
+
font-weight: 600;
|
|
567
|
+
font-size: 0.85rem;
|
|
568
|
+
color: #333;
|
|
569
|
+
}
|
|
570
|
+
.metric-unit {
|
|
571
|
+
font-size: 0.75rem;
|
|
572
|
+
color: #888;
|
|
573
|
+
}
|
|
472
574
|
.metric-used {
|
|
473
|
-
font-size: 0.7rem;
|
|
575
|
+
font-size: 0.7rem;
|
|
576
|
+
color: #1976d2;
|
|
577
|
+
margin-top: 4px;
|
|
474
578
|
}
|
|
475
579
|
|
|
476
580
|
/* 팝업 */
|
|
477
581
|
.popup-overlay {
|
|
478
|
-
position: fixed;
|
|
479
|
-
|
|
480
|
-
|
|
582
|
+
position: fixed;
|
|
583
|
+
top: 0;
|
|
584
|
+
left: 0;
|
|
585
|
+
right: 0;
|
|
586
|
+
bottom: 0;
|
|
587
|
+
background: rgba(0, 0, 0, 0.3);
|
|
588
|
+
z-index: 1000;
|
|
589
|
+
display: flex;
|
|
590
|
+
align-items: center;
|
|
591
|
+
justify-content: center;
|
|
481
592
|
}
|
|
482
593
|
.popup-box {
|
|
483
|
-
background: #fff;
|
|
484
|
-
|
|
485
|
-
|
|
594
|
+
background: #fff;
|
|
595
|
+
border-radius: 12px;
|
|
596
|
+
padding: 24px;
|
|
597
|
+
min-width: 400px;
|
|
598
|
+
max-width: 600px;
|
|
599
|
+
max-height: 80vh;
|
|
600
|
+
overflow-y: auto;
|
|
601
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
|
486
602
|
}
|
|
487
603
|
.popup-title {
|
|
488
|
-
font-size: 1.1rem;
|
|
489
|
-
|
|
604
|
+
font-size: 1.1rem;
|
|
605
|
+
font-weight: 700;
|
|
606
|
+
color: #1a237e;
|
|
607
|
+
margin-bottom: 16px;
|
|
608
|
+
display: flex;
|
|
609
|
+
justify-content: space-between;
|
|
490
610
|
}
|
|
491
611
|
.popup-close {
|
|
492
|
-
background: none;
|
|
493
|
-
|
|
612
|
+
background: none;
|
|
613
|
+
border: none;
|
|
614
|
+
font-size: 1.2rem;
|
|
615
|
+
cursor: pointer;
|
|
616
|
+
color: #999;
|
|
494
617
|
}
|
|
495
618
|
.popup-row {
|
|
496
|
-
display: flex;
|
|
619
|
+
display: flex;
|
|
620
|
+
gap: 8px;
|
|
621
|
+
margin-bottom: 8px;
|
|
497
622
|
font-size: 0.85rem;
|
|
498
623
|
}
|
|
499
|
-
.popup-label {
|
|
500
|
-
|
|
624
|
+
.popup-label {
|
|
625
|
+
color: #888;
|
|
626
|
+
min-width: 100px;
|
|
627
|
+
flex-shrink: 0;
|
|
628
|
+
}
|
|
629
|
+
.popup-value {
|
|
630
|
+
color: #333;
|
|
631
|
+
font-weight: 500;
|
|
632
|
+
}
|
|
501
633
|
.popup-formula {
|
|
502
|
-
background: #f5f5f5;
|
|
503
|
-
|
|
634
|
+
background: #f5f5f5;
|
|
635
|
+
padding: 10px;
|
|
636
|
+
border-radius: 6px;
|
|
637
|
+
font-family: monospace;
|
|
638
|
+
font-size: 0.85rem;
|
|
639
|
+
margin: 8px 0;
|
|
504
640
|
word-break: break-all;
|
|
505
641
|
}
|
|
506
642
|
.popup-link {
|
|
507
|
-
color: #1976d2;
|
|
643
|
+
color: #1976d2;
|
|
644
|
+
cursor: pointer;
|
|
645
|
+
text-decoration: underline;
|
|
508
646
|
font-size: 0.85rem;
|
|
509
647
|
}
|
|
510
|
-
.popup-link:hover {
|
|
648
|
+
.popup-link:hover {
|
|
649
|
+
color: #0d47a1;
|
|
650
|
+
}
|
|
511
651
|
|
|
512
652
|
/* 범례 */
|
|
513
653
|
.legend {
|
|
514
|
-
display: flex;
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
654
|
+
display: flex;
|
|
655
|
+
gap: 16px;
|
|
656
|
+
flex-wrap: wrap;
|
|
657
|
+
margin-bottom: 20px;
|
|
658
|
+
padding: 12px 16px;
|
|
659
|
+
background: #fff;
|
|
660
|
+
border-radius: 8px;
|
|
661
|
+
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04);
|
|
662
|
+
}
|
|
663
|
+
.legend-group {
|
|
664
|
+
display: flex;
|
|
665
|
+
align-items: center;
|
|
666
|
+
gap: 4px;
|
|
667
|
+
font-size: 0.8rem;
|
|
668
|
+
}
|
|
669
|
+
.legend-title {
|
|
670
|
+
font-weight: 700;
|
|
671
|
+
color: #555;
|
|
672
|
+
margin-right: 4px;
|
|
518
673
|
}
|
|
519
|
-
.legend-group { display: flex; align-items: center; gap: 4px; font-size: 0.8rem; }
|
|
520
|
-
.legend-title { font-weight: 700; color: #555; margin-right: 4px; }
|
|
521
674
|
`
|
|
522
675
|
];
|
|
523
676
|
__decorate([
|