@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.
Files changed (65) hide show
  1. package/_index.html +4 -4
  2. package/assets/helps/index.md +1 -1
  3. package/assets/manifest.json +2 -2
  4. package/dist-client/components/kpi-boxplot-chart.d.ts +7 -0
  5. package/dist-client/components/kpi-boxplot-chart.js +20 -5
  6. package/dist-client/components/kpi-boxplot-chart.js.map +1 -1
  7. package/dist-client/components/kpi-lookup-chart.js +1 -17
  8. package/dist-client/components/kpi-lookup-chart.js.map +1 -1
  9. package/dist-client/components/kpi-radar-chart.js +2 -2
  10. package/dist-client/components/kpi-radar-chart.js.map +1 -1
  11. package/dist-client/components/kpi-single-boxplot-chart.d.ts +7 -0
  12. package/dist-client/components/kpi-single-boxplot-chart.js +27 -26
  13. package/dist-client/components/kpi-single-boxplot-chart.js.map +1 -1
  14. package/dist-client/components/kpi-step-lookup-chart.d.ts +33 -0
  15. package/dist-client/components/kpi-step-lookup-chart.js +181 -0
  16. package/dist-client/components/kpi-step-lookup-chart.js.map +1 -0
  17. package/dist-client/components/kpi-trend-chart.js +2 -12
  18. package/dist-client/components/kpi-trend-chart.js.map +1 -1
  19. package/dist-client/google-map/common-google-map.js +5 -1
  20. package/dist-client/google-map/common-google-map.js.map +1 -1
  21. package/dist-client/pages/kpi-admin/dssp-kpi-overview.d.ts +2 -1
  22. package/dist-client/pages/kpi-admin/dssp-kpi-overview.js +24 -9
  23. package/dist-client/pages/kpi-admin/dssp-kpi-overview.js.map +1 -1
  24. package/dist-client/pages/kpi-admin/kpi-system-guide.js +311 -158
  25. package/dist-client/pages/kpi-admin/kpi-system-guide.js.map +1 -1
  26. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.d.ts +6 -0
  27. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js +110 -50
  28. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js.map +1 -1
  29. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.d.ts +0 -9
  30. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js +6 -91
  31. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js.map +1 -1
  32. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.d.ts +2 -0
  33. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js +148 -68
  34. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js.map +1 -1
  35. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js +85 -41
  36. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js.map +1 -1
  37. package/dist-client/pages/kpi-dashboard/kpi-dashboard.js +15 -7
  38. package/dist-client/pages/kpi-dashboard/kpi-dashboard.js.map +1 -1
  39. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js +16 -25
  40. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js.map +1 -1
  41. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js +9 -13
  42. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js.map +1 -1
  43. package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.js +9 -15
  44. package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.js.map +1 -1
  45. package/dist-client/pages/sv-project-complete.js +7 -11
  46. package/dist-client/pages/sv-project-complete.js.map +1 -1
  47. package/dist-client/pages/sv-project-completed-list.js +4 -4
  48. package/dist-client/pages/sv-project-completed-list.js.map +1 -1
  49. package/dist-client/pages/sv-project-detail.d.ts +1 -0
  50. package/dist-client/pages/sv-project-detail.js +65 -51
  51. package/dist-client/pages/sv-project-detail.js.map +1 -1
  52. package/dist-client/pages/sv-project-list.js +15 -12
  53. package/dist-client/pages/sv-project-list.js.map +1 -1
  54. package/dist-client/tsconfig.tsbuildinfo +1 -1
  55. package/dist-client/viewparts/menu-tools.js +17 -3
  56. package/dist-client/viewparts/menu-tools.js.map +1 -1
  57. package/dist-server/service/kpi-stat/kpi-stat-query.js +20 -19
  58. package/dist-server/service/kpi-stat/kpi-stat-query.js.map +1 -1
  59. package/dist-server/tsconfig.tsbuildinfo +1 -1
  60. package/openapi/unstable.yaml +2 -2
  61. package/package.json +3 -3
  62. package/schema.graphql +20 -0
  63. package/translations/ko.json +2 -2
  64. package/views/auth-page.html +4 -4
  65. package/views/public/home.html +5 -5
@@ -13,6 +13,7 @@ import '../components/kpi-boxplot-chart';
13
13
  import '../components/kpi-single-boxplot-chart';
14
14
  import '../components/kpi-radar-chart';
15
15
  import '../components/kpi-lookup-chart';
16
+ import '../components/kpi-step-lookup-chart';
16
17
  import '../components/kpi-2d-lookup-chart';
17
18
  let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(PageView) {
18
19
  constructor() {
@@ -35,7 +36,7 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
35
36
  };
36
37
  }
37
38
  render() {
38
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
39
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
39
40
  return html `
40
41
  <div content>
41
42
  <div left>
@@ -57,7 +58,7 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
57
58
  <div class="value">${this.project.startDate} ~ ${this.project.endDate}</div>
58
59
  </div>
59
60
  <div class="row">
60
- <div class="label">• 현장상태</div>
61
+ <div class="label">• 프로젝트 상태</div>
61
62
  <div class="value status-value">${PROJECT_STATE[this.project.state]}</div>
62
63
  </div>
63
64
  <div class="row">
@@ -97,7 +98,7 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
97
98
  <div class="value">${((_h = (_g = this.project.buildingComplex) === null || _g === void 0 ? void 0 : _g.floorAreaRatio) === null || _h === void 0 ? void 0 : _h.toLocaleString()) || '-'} %</div>
98
99
  </div>
99
100
  <div class="grid-item row">
100
- <div class="label">• 투입인력</div>
101
+ <div class="label">• 총 투입인력(M/M)</div>
101
102
  <div class="value">${((_k = (_j = this.project.buildingComplex) === null || _j === void 0 ? void 0 : _j.workerCount) === null || _k === void 0 ? void 0 : _k.toLocaleString()) || '-'} 명</div>
102
103
  </div>
103
104
  </div>
@@ -208,14 +209,13 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
208
209
  <div class="card group-box">
209
210
  <div class="kpi-header">
210
211
  <div>
211
- <div>그룹별 분포</div>
212
+ <div>성과영역별 KPI</div>
212
213
  <div class="triangle"></div>
213
214
  </div>
214
215
  </div>
215
216
  <div class="desc">
216
- Boxplot(박스플롯)은 카테고리별로 값의 분포(최소, 1사분위, 중앙값, 3사분위, 최대, 평균, 이상치 ) 보여줍니다.
217
- 박스는 중앙 50% 구간, 수염은 전체 범위, 굵은 검정색 가로선은 중앙값(메디안), 초록색 원은 평균값(Mean)을 의미합니다.
218
- 이 프로젝트의 값은 진한 오렌지색 원으로 별도 강조되어 표시되며, 중앙값/평균과 다를 수 있습니다.
217
+ Boxplot(박스플롯)은 박스는 중앙 50% 구간, 수염은 전체 범위, 굵은 파란색 가로선은 중앙값(median), 초록색 원은
218
+ 평균값(Mean)을 의미합니다. 당해 프로젝트의 값은 붉은색 원으로 표시됩니다.
219
219
  </div>
220
220
  <div class="group-chart">
221
221
  <sv-kpi-boxplot-chart .data=${this.getYKpiBoxplotData()}></sv-kpi-boxplot-chart>
@@ -225,7 +225,7 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
225
225
  <div class="metrics-card">
226
226
  <div class="metrics-header">
227
227
  <div class="title">
228
- <span>그룹별 상세 매트릭 데이터</span>
228
+ <span>성과영역별 KPI 측정값</span>
229
229
  <div class="triangle"></div>
230
230
  </div>
231
231
  </div>
@@ -270,8 +270,7 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
270
270
  ${this.selectedKpi.score !== undefined && this.selectedKpi.score !== null
271
271
  ? html `
272
272
  <div class="popup-score">
273
- <span class="score-value">${parseFloat(Number(this.selectedKpi.score).toFixed(4))}</span>
274
- <span class="score-label">점</span>
273
+ <span class="score-value">${parseFloat(Number(this.selectedKpi.score).toFixed(2))}</span>
275
274
  </div>
276
275
  `
277
276
  : ''}
@@ -290,18 +289,29 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
290
289
  * ASSESSMENT: 5단계 게이지 (kpi-lookup-chart 자동 감지)
291
290
  */ ''}
292
291
  ${
293
- // 2D lookup KPI (X13 ) 항상 등급 기준 + 히트맵 함께 표시 (value 가
294
- // 정수든 소수든 일관). _renderAssessmentGrades 안의 is2D 분기가 히트맵
295
- // 같이 그림. ASSESSMENT 도 등급 기준, LOOKUP 은 분포 커브.
296
- this.selectedKpi.scoreType === 'CUSTOM' || ((_l = this.selectedKpi.grades) === null || _l === void 0 ? void 0 : _l.type) === 'PROGRESS_DEVIATION_LOOKUP'
297
- ? this._renderAssessmentGrades()
298
- : this._isAssessmentOrIntegerScore()
299
- ? this._renderAssessmentGrades()
300
- : html `
292
+ // SL-PA 결과(X34 품질, X43 안전) 계단형 등급 분포 차트로 표시.
293
+ // (다른 KPI 차트 경로에는 영향 없음)
294
+ this.selectedKpi.pattern === 'X34' || this.selectedKpi.pattern === 'X43'
295
+ ? html `
296
+ <kpi-step-lookup-chart
297
+ .grades=${this.selectedKpi.grades || []}
298
+ .value=${this.selectedKpi.value}
299
+ .score=${(_l = this.selectedKpi.score) !== null && _l !== void 0 ? _l : null}
300
+ unit=${this.selectedKpi.unit || ''}
301
+ ></kpi-step-lookup-chart>
302
+ `
303
+ : // 2D lookup KPI (X13 등) 는 항상 등급 기준 + 히트맵 함께 표시 (value 가
304
+ // 정수든 소수든 일관). _renderAssessmentGrades 안의 is2D 분기가 히트맵
305
+ // 같이 그림. 그 외 ASSESSMENT 도 등급 기준, LOOKUP 은 분포 커브.
306
+ this.selectedKpi.scoreType === 'CUSTOM' || ((_m = this.selectedKpi.grades) === null || _m === void 0 ? void 0 : _m.type) === 'PROGRESS_DEVIATION_LOOKUP'
307
+ ? this._renderAssessmentGrades()
308
+ : this._isAssessmentOrIntegerScore()
309
+ ? this._renderAssessmentGrades()
310
+ : html `
301
311
  <kpi-lookup-chart
302
312
  .grades=${this.selectedKpi.grades || []}
303
313
  .value=${this.selectedKpi.value}
304
- .score=${(_m = this.selectedKpi.score) !== null && _m !== void 0 ? _m : null}
314
+ .score=${(_o = this.selectedKpi.score) !== null && _o !== void 0 ? _o : null}
305
315
  .scoreType=${this.selectedKpi.scoreType || ''}
306
316
  .valueType=${this.selectedKpi.valueType || ''}
307
317
  unit=${this.selectedKpi.unit || ''}
@@ -653,6 +663,7 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
653
663
  }
654
664
  this.selectedKpi = {
655
665
  kpiName: displayName,
666
+ pattern: kpiNamePattern, // X34/X43 등 — 계단형 차트 라우팅용
656
667
  grades: kpi.grades || [],
657
668
  scoreType: kpi.scoreType || '',
658
669
  valueType: kpi.valueType || '',
@@ -798,30 +809,30 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
798
809
  return {
799
810
  Y1: {
800
811
  name: '일정성과 (Y1)',
801
- score: this.getYKpiScoreFormatted('Y1. 일정성과'),
812
+ score: this.getYKpiScoreFormatted('일정성과(Y1)'),
802
813
  metrics: [
803
814
  { label: '연면적 대비 공사기간', pattern: 'X11', value: this.getMetricValue('X11') },
804
815
  { label: '설계변경 공기 증감률', pattern: 'X12', value: this.getMetricValue('X12') },
805
816
  { label: '일정 이탈 수준', pattern: 'X13', value: this.getMetricValue('X13') },
806
- { label: '일정성과 수준 평가', pattern: 'X14', value: this.getMetricValue('X14') }
817
+ { label: '일정성과 정성 평가', pattern: 'X14', value: this.getMetricValue('X14') }
807
818
  ]
808
819
  },
809
820
  Y2: {
810
821
  name: '비용성과 (Y2)',
811
- score: this.getYKpiScoreFormatted('Y2. 비용성과'),
822
+ score: this.getYKpiScoreFormatted('비용성과(Y2)'),
812
823
  metrics: [
813
824
  { label: '연면적 대비 공사비', pattern: 'X21', value: this.getMetricValue('X21') },
814
- { label: '설계변경 공사비 증감', pattern: 'X22', value: this.getMetricValue('X22') },
815
- { label: '비용성과 수준 평가', pattern: 'X23', value: this.getMetricValue('X23') }
825
+ { label: '설계변경 공사비 증감률', pattern: 'X22', value: this.getMetricValue('X22') },
826
+ { label: '비용성과 정성 평가', pattern: 'X23', value: this.getMetricValue('X23') }
816
827
  ]
817
828
  },
818
829
  Y3: {
819
830
  name: '품질성과 (Y3)',
820
- score: this.getYKpiScoreFormatted('Y3. 품질성과'),
831
+ score: this.getYKpiScoreFormatted('품질성과(Y3)'),
821
832
  metrics: [
822
833
  { label: '검측 불합격률', pattern: 'X33', value: this.getMetricValue('X33') },
823
834
  { label: '품질 SL-PA 결과', pattern: 'X34', value: this.getMetricValue('X34') },
824
- { label: '품질성과 수준 평가', pattern: 'X35', value: this.getMetricValue('X35') }
835
+ { label: '품질성과 정성 평가', pattern: 'X35', value: this.getMetricValue('X35') }
825
836
  ]
826
837
  },
827
838
  Y4: {
@@ -831,41 +842,43 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
831
842
  { label: '재해율', pattern: 'X41', value: this.getMetricValue('X41') },
832
843
  { label: '재해강도율', pattern: 'X42', value: this.getMetricValue('X42') },
833
844
  { label: '안전 SL-PA 결과', pattern: 'X43', value: this.getMetricValue('X43') },
834
- { label: '안전성과 수준 평가', pattern: 'X44', value: this.getMetricValue('X44') }
845
+ { label: '안전성과 정성 평가', pattern: 'X44', value: this.getMetricValue('X44') }
835
846
  ]
836
847
  },
837
848
  Y5: {
838
849
  name: '환경성과 (Y5)',
839
- score: this.getYKpiScoreFormatted('Y5. 환경성과'),
850
+ score: this.getYKpiScoreFormatted('환경성과(Y5)'),
840
851
  metrics: [
841
852
  { label: '건설폐기물 발생량', pattern: 'X51', value: this.getMetricValue('X51') },
842
- { label: '환경성과 수준 평가', pattern: 'X52', value: this.getMetricValue('X52') }
853
+ { label: '환경성과 정성 평가', pattern: 'X52', value: this.getMetricValue('X52') }
843
854
  ]
844
855
  },
845
856
  Y6: {
846
857
  name: '생산성 성과 (Y6)',
847
- score: this.getYKpiScoreFormatted('Y6. 생산성성과'),
858
+ score: this.getYKpiScoreFormatted('생산성성과(Y6)'),
848
859
  metrics: [
849
- { label: '투입인력 생산성', pattern: 'X61', value: this.getMetricValue('X61') },
850
- { label: '생산성성과 수준 평가', pattern: 'X62', value: this.getMetricValue('X62') }
860
+ { label: '투입인력(M/M) 생산성', pattern: 'X61', value: this.getMetricValue('X61') },
861
+ { label: '생산성성과 정성 평가', pattern: 'X62', value: this.getMetricValue('X62') }
851
862
  ]
852
863
  }
853
864
  };
854
865
  }
855
866
  getYKpiBoxplotData() {
856
- // KPI 카테고리 매핑 (Y-category KPI names to display categories)
857
- const categoryMapping = {
858
- Y01_productivity: '생산성과',
859
- Y02_schedule: '일정성과',
860
- Y03_cost: '비용성과',
861
- Y04_quality: '품질성과',
862
- Y05_safety: '안전성과',
863
- Y06_environment: '환경성과'
867
+ // kpiName 표기가 환경마다 다양('Y1. 일정성과' / 'Y1. 일정' / '일정성과(Y1)' 등)하므로
868
+ // Y1~Y6 코드만 추출해 짧은 X축 라벨로 매핑 — 전체 문자열에 의존하지 않아 견고함.
869
+ const yLabelByCode = {
870
+ Y1: '일정',
871
+ Y2: '비용',
872
+ Y3: '품질',
873
+ Y4: '안전',
874
+ Y5: '환경',
875
+ Y6: '생산성'
864
876
  };
865
877
  const data = [];
866
878
  // Y-KPI 카테고리별로 통합된 통계 생성
867
879
  this.kpiYComprehensiveStats.forEach(stat => {
868
- const category = categoryMapping[stat.kpiName] || stat.kpiName;
880
+ var _a, _b;
881
+ const category = yLabelByCode[(_b = (_a = (stat.kpiName || '').match(/Y[1-6]/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : ''] || stat.kpiName;
869
882
  data.push({
870
883
  org: category, // org 필드 사용 (boxplot 차트가 기대하는 필드명)
871
884
  min: stat.minVal * 100,
@@ -912,20 +925,21 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
912
925
  return (kpiValue === null || kpiValue === void 0 ? void 0 : kpiValue.value) || 0;
913
926
  }
914
927
  getRadarChartData() {
915
- // KPI 카테고리 매핑 (Y-category KPI names to display categories)
916
- const categoryMapping = {
917
- Y01_productivity: '생산성',
918
- Y02_schedule: '일정',
919
- Y03_cost: '비용',
920
- Y04_quality: '품질',
921
- Y05_safety: '안전',
922
- Y06_environment: '환경'
928
+ // kpiName 표기가 다양하므로 Y1~Y6 코드만 추출해 짧은 라벨로 매핑 (박스플롯과 동일 방식).
929
+ const yLabelByCode = {
930
+ Y1: '일정',
931
+ Y2: '비용',
932
+ Y3: '품질',
933
+ Y4: '안전',
934
+ Y5: '환경',
935
+ Y6: '생산성'
923
936
  };
924
937
  const data = [];
925
938
  const categories = [];
926
939
  // Create baseline data from comprehensive stats (using avgVal as baseline)
927
940
  this.kpiYComprehensiveStats.forEach(stat => {
928
- const category = categoryMapping[stat.kpiName] || stat.kpiName;
941
+ var _a, _b;
942
+ const category = yLabelByCode[(_b = (_a = (stat.kpiName || '').match(/Y[1-6]/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : ''] || stat.kpiName;
929
943
  if (!categories.includes(category)) {
930
944
  categories.push(category);
931
945
  }
@@ -946,7 +960,7 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
946
960
  data,
947
961
  categories: categories.length > 0
948
962
  ? categories
949
- : ['Y1. 일정성과', 'Y2. 비용성과', 'Y3. 품질성과', 'Y4. 안전성과', 'Y5. 환경성과', 'Y6. 생산성성과']
963
+ : ['일정', '비용', '품질', '안전', '환경', '생산성']
950
964
  };
951
965
  }
952
966
  getBoxPlotDataForProject(project) {