@things-factory/kpi 9.1.19 → 10.0.0-beta.2

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 (140) hide show
  1. package/client/pages/kpi/kpi-list-page.ts +339 -525
  2. package/client/pages/kpi/kpi-tree-page.ts +135 -207
  3. package/client/pages/kpi-metric/kpi-metric-list-page.ts +146 -226
  4. package/client/pages/kpi-metric-value/kpi-metric-value-editor-page.ts +187 -295
  5. package/client/pages/kpi-metric-value/kpi-metric-value-list-page.ts +123 -194
  6. package/client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.ts +57 -91
  7. package/client/pages/kpi-statistic/kpi-statistic-editor-page.ts +180 -278
  8. package/client/pages/kpi-statistic/kpi-statistic-list-page.ts +186 -286
  9. package/client/pages/kpi-value/kpi-value-editor-page.ts +189 -292
  10. package/client/pages/kpi-value/kpi-value-list-page.ts +170 -264
  11. package/dist-client/pages/kpi/kpi-list-page.d.ts +0 -6
  12. package/dist-client/pages/kpi/kpi-list-page.js +150 -282
  13. package/dist-client/pages/kpi/kpi-list-page.js.map +1 -1
  14. package/dist-client/pages/kpi/kpi-tree-page.d.ts +1 -7
  15. package/dist-client/pages/kpi/kpi-tree-page.js +76 -127
  16. package/dist-client/pages/kpi/kpi-tree-page.js.map +1 -1
  17. package/dist-client/pages/kpi-metric/kpi-metric-list-page.d.ts +0 -6
  18. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js +62 -116
  19. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js.map +1 -1
  20. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.d.ts +1 -7
  21. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js +82 -140
  22. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js.map +1 -1
  23. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +0 -6
  24. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +54 -98
  25. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -1
  26. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.d.ts +1 -7
  27. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js +30 -57
  28. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js.map +1 -1
  29. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.d.ts +1 -7
  30. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js +91 -153
  31. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js.map +1 -1
  32. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.d.ts +0 -6
  33. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js +81 -155
  34. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js.map +1 -1
  35. package/dist-client/pages/kpi-value/kpi-value-editor-page.d.ts +1 -7
  36. package/dist-client/pages/kpi-value/kpi-value-editor-page.js +80 -136
  37. package/dist-client/pages/kpi-value/kpi-value-editor-page.js.map +1 -1
  38. package/dist-client/pages/kpi-value/kpi-value-list-page.d.ts +0 -6
  39. package/dist-client/pages/kpi-value/kpi-value-list-page.js +73 -134
  40. package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -1
  41. package/dist-client/tsconfig.tsbuildinfo +1 -1
  42. package/dist-server/service/index.d.ts +1 -1
  43. package/dist-server/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +18 -18
  45. package/client/tsconfig.json +0 -11
  46. package/dist-server/tsconfig.json +0 -10
  47. package/server/@types/index.d.ts +0 -11
  48. package/server/calculator/evaluator.ts +0 -45
  49. package/server/calculator/functions.ts +0 -67
  50. package/server/calculator/index.ts +0 -4
  51. package/server/calculator/parser.ts +0 -137
  52. package/server/calculator/provider.ts +0 -10
  53. package/server/controllers/index.ts +0 -2
  54. package/server/controllers/kpi-metric-value-provider.ts +0 -79
  55. package/server/controllers/kpi-value-provider.ts +0 -51
  56. package/server/index.ts +0 -6
  57. package/server/migrations/1752190849680-seed-kpi-metrics.ts +0 -124
  58. package/server/migrations/1752190849681-seed-kpi.ts +0 -356
  59. package/server/migrations/1752192090123-add-grades-to-kpi.ts +0 -67
  60. package/server/migrations/1752192090124-add-kpi-statistics.ts +0 -719
  61. package/server/migrations/1752192090128-seed-kpi-org-scope.ts +0 -132
  62. package/server/migrations/1752192090129-seed-kpi-values.ts +0 -207
  63. package/server/migrations/grade-data/x11-performance-table.json +0 -962
  64. package/server/migrations/grade-data/x12-performance-table.json +0 -611
  65. package/server/migrations/grade-data/x14-performance-table.json +0 -42
  66. package/server/migrations/grade-data/x21-performance-table.json +0 -889
  67. package/server/migrations/grade-data/x22-performance-table.json +0 -1064
  68. package/server/migrations/grade-data/x23-performance-table.json +0 -42
  69. package/server/migrations/grade-data/x31-performance-table.json +0 -644
  70. package/server/migrations/grade-data/x32-performance-table.json +0 -993
  71. package/server/migrations/grade-data/x33-performance-table.json +0 -195
  72. package/server/migrations/grade-data/x34-performance-table.json +0 -12
  73. package/server/migrations/grade-data/x35-performance-table.json +0 -42
  74. package/server/migrations/grade-data/x41-performance-table.json +0 -825
  75. package/server/migrations/grade-data/x42-performance-table.json +0 -786
  76. package/server/migrations/grade-data/x43-performance-table.json +0 -12
  77. package/server/migrations/grade-data/x44-performance-table.json +0 -42
  78. package/server/migrations/grade-data/x51-performance-table.json +0 -924
  79. package/server/migrations/grade-data/x52-performance-table.json +0 -42
  80. package/server/migrations/grade-data/x61-performance-table.json +0 -261
  81. package/server/migrations/grade-data/x62-performance-table.json +0 -42
  82. package/server/migrations/index.ts +0 -9
  83. package/server/migrations/seed-data/kpi-metrics-seed.json +0 -454
  84. package/server/migrations/seed-data/kpi-org-scope-seed.json +0 -1676
  85. package/server/migrations/seed-data/kpi-scopes-seed.json +0 -121
  86. package/server/migrations/seed-data/kpi-values-seed.json +0 -402
  87. package/server/migrations/seed-data/kpis-seed.json +0 -488
  88. package/server/migrations/seed-data/scope-definitions-seed.json +0 -90
  89. package/server/routes.ts +0 -81
  90. package/server/service/index.ts +0 -51
  91. package/server/service/kpi/aggregate-kpi.ts +0 -103
  92. package/server/service/kpi/event-subscriber.ts +0 -29
  93. package/server/service/kpi/index.ts +0 -9
  94. package/server/service/kpi/kpi-formula.service.ts +0 -164
  95. package/server/service/kpi/kpi-grade.types.ts +0 -28
  96. package/server/service/kpi/kpi-history.ts +0 -126
  97. package/server/service/kpi/kpi-mutation.ts +0 -553
  98. package/server/service/kpi/kpi-query.ts +0 -224
  99. package/server/service/kpi/kpi-type.ts +0 -151
  100. package/server/service/kpi/kpi.ts +0 -254
  101. package/server/service/kpi-alert/index.ts +0 -3
  102. package/server/service/kpi-alert/kpi-alert-query.ts +0 -59
  103. package/server/service/kpi-alert/kpi-alert-type.ts +0 -20
  104. package/server/service/kpi-metric/aggregate-kpi-metric.ts +0 -132
  105. package/server/service/kpi-metric/index.ts +0 -7
  106. package/server/service/kpi-metric/kpi-metric-mutation.ts +0 -309
  107. package/server/service/kpi-metric/kpi-metric-query.ts +0 -70
  108. package/server/service/kpi-metric/kpi-metric-type.ts +0 -111
  109. package/server/service/kpi-metric/kpi-metric.ts +0 -134
  110. package/server/service/kpi-metric-value/index.ts +0 -7
  111. package/server/service/kpi-metric-value/kpi-metric-value-mutation.ts +0 -270
  112. package/server/service/kpi-metric-value/kpi-metric-value-query.ts +0 -62
  113. package/server/service/kpi-metric-value/kpi-metric-value-type.ts +0 -82
  114. package/server/service/kpi-metric-value/kpi-metric-value.ts +0 -93
  115. package/server/service/kpi-org-scope/index.ts +0 -6
  116. package/server/service/kpi-org-scope/kpi-org-scope-mutation.ts +0 -173
  117. package/server/service/kpi-org-scope/kpi-org-scope-query.ts +0 -127
  118. package/server/service/kpi-org-scope/kpi-org-scope-type.ts +0 -68
  119. package/server/service/kpi-org-scope/kpi-org-scope.ts +0 -123
  120. package/server/service/kpi-scope/index.ts +0 -11
  121. package/server/service/kpi-scope/kpi-scope-mutation.ts +0 -129
  122. package/server/service/kpi-scope/kpi-scope-query.ts +0 -63
  123. package/server/service/kpi-scope/kpi-scope-type.ts +0 -96
  124. package/server/service/kpi-scope/kpi-scope.ts +0 -143
  125. package/server/service/kpi-statistic/index.ts +0 -7
  126. package/server/service/kpi-statistic/kpi-statistic-batch.service.ts +0 -231
  127. package/server/service/kpi-statistic/kpi-statistic-calculation.service.ts +0 -410
  128. package/server/service/kpi-statistic/kpi-statistic-mutation.ts +0 -291
  129. package/server/service/kpi-statistic/kpi-statistic-query.ts +0 -146
  130. package/server/service/kpi-statistic/kpi-statistic-type.ts +0 -152
  131. package/server/service/kpi-statistic/kpi-statistic.ts +0 -199
  132. package/server/service/kpi-value/index.ts +0 -7
  133. package/server/service/kpi-value/kpi-value-mutation.ts +0 -432
  134. package/server/service/kpi-value/kpi-value-query.ts +0 -61
  135. package/server/service/kpi-value/kpi-value-score.service.ts +0 -106
  136. package/server/service/kpi-value/kpi-value-type.ts +0 -122
  137. package/server/service/kpi-value/kpi-value.ts +0 -160
  138. package/server/service/utils/value-date-util.ts +0 -119
  139. package/server/tsconfig.json +0 -10
  140. package/server/types/global.d.ts +0 -8
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-value-editor-page.js","sourceRoot":"","sources":["../../../client/pages/kpi-value/kpi-value-editor-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/elevated-button.js'\nimport '@material/web/textfield/outlined-text-field.js'\n\nimport { CommonButtonStyles, CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'\nimport { PageView, store } from '@operato/shell'\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { notify } from '@operato/layout'\nimport { connect } from 'pwa-helpers/connect-mixin'\nimport gql from 'graphql-tag'\n\ninterface KpiValueData {\n kpiId: string\n kpiName: string\n periodType: string\n values: { [date: string]: { value: number | null; score?: number; isDirty?: boolean } }\n}\n\ninterface EditorCell {\n date: string\n value: number | null\n score?: number\n isEditable: boolean\n isHighlighted: boolean\n}\n\n@customElement('kpi-value-editor-page')\nexport class KpiValueEditorPage extends connect(store)(localize(i18next)(ScopedElementsMixin(PageView))) {\n static styles = [\n CommonHeaderStyles,\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n padding: 20px;\n overflow-x: auto;\n }\n\n .header {\n display: flex;\n gap: 16px;\n align-items: center;\n margin-bottom: 20px;\n padding: 16px;\n background: var(--md-sys-color-surface-container);\n border-radius: 8px;\n }\n\n .controls {\n display: flex;\n gap: 12px;\n align-items: center;\n }\n\n .table-container {\n flex: 1;\n overflow: auto;\n border: 1px solid var(--md-sys-color-outline);\n border-radius: 8px;\n }\n\n table {\n width: 100%;\n border-collapse: collapse;\n min-width: max-content;\n }\n\n th {\n background: var(--md-sys-color-surface-container-low);\n font-weight: 500;\n padding: 8px 12px;\n border: 1px solid var(--md-sys-color-outline-variant);\n min-width: 80px;\n height: 120px;\n vertical-align: middle;\n }\n\n td {\n padding: 8px 12px;\n border: 1px solid var(--md-sys-color-outline-variant);\n min-width: 80px;\n height: 60px;\n text-align: right;\n vertical-align: middle;\n }\n\n .kpi-header {\n position: sticky;\n left: 0;\n top: 0;\n z-index: 3;\n }\n\n .kpi-name {\n position: sticky;\n left: 0;\n background: var(--md-sys-color-surface);\n font-weight: 500;\n min-width: 200px;\n text-align: left;\n z-index: 2;\n }\n\n tr:hover {\n background: var(--md-sys-color-surface-container-high);\n }\n\n th.date-header {\n position: sticky;\n top: 0;\n z-index: 2;\n text-align: center;\n font-size: 11px;\n color: var(--md-sys-color-on-surface-variant);\n writing-mode: vertical-rl;\n text-orientation: mixed;\n min-height: 120px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n td.editable-cell {\n cursor: pointer;\n background: var(--md-sys-color-primary-container);\n color: var(--md-sys-color-on-primary-container);\n }\n\n td.editable-cell:hover {\n background: var(--md-sys-color-primary-container-high);\n }\n\n td.highlighted-cell {\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n font-weight: 500;\n }\n\n td.highlighted-cell:hover {\n background: var(--md-sys-color-secondary-container-high);\n }\n\n td.disabled-cell {\n background: var(--md-sys-color-surface-container);\n color: var(--md-sys-color-on-surface-variant);\n cursor: not-allowed;\n }\n\n .value-input {\n width: 100%;\n text-align: center;\n border: none;\n background: transparent;\n color: inherit;\n font-size: 12px;\n padding: 2px;\n }\n\n .value-input:focus {\n outline: 2px solid var(--md-sys-color-primary);\n border-radius: 4px;\n }\n\n .period-type-badge {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n background: var(--md-sys-color-tertiary-container);\n color: var(--md-sys-color-on-tertiary-container);\n margin-left: 8px;\n }\n\n .loading {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 200px;\n color: var(--md-sys-color-on-surface-variant);\n }\n\n .error {\n color: var(--md-sys-color-error);\n padding: 16px;\n text-align: center;\n }\n\n .legend {\n display: flex;\n gap: 16px;\n margin-top: 16px;\n font-size: 12px;\n }\n\n .legend-item {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .legend-color {\n width: 16px;\n height: 16px;\n border-radius: 2px;\n }\n `\n ]\n\n @property({ type: String }) kpiOrgScopeId: string = ''\n @property({ type: String }) org: string = '' // legacy support\n @property({ type: String }) startDate: string = ''\n @property({ type: String }) endDate: string = ''\n\n @state() private kpis: KpiValueData[] = []\n @state() private dates: string[] = []\n @state() private loading: boolean = false\n @state() private error: string = ''\n @state() private editingCell: { kpiId: string; date: string } | null = null\n @state() private _existingValues: any[] = []\n\n get context() {\n return {\n title: i18next.t('title.kpi value editor'),\n actions: [\n {\n title: i18next.t('button.save'),\n action: this._saveValues.bind(this),\n ...CommonButtonStyles.save\n },\n {\n title: i18next.t('button.cancel'),\n action: this._cancel.bind(this),\n ...CommonButtonStyles.cancel\n }\n ]\n }\n }\n\n render() {\n if (this.loading) {\n return html`\n <div class=\"loading\">\n <md-icon>hourglass_empty</md-icon>\n <span>데이터를 불러오는 중...</span>\n </div>\n `\n }\n\n if (this.error) {\n return html`\n <div class=\"error\">\n <md-icon>error</md-icon>\n <span>${this.error}</span>\n </div>\n `\n }\n\n return html`\n <div class=\"header\">\n <div class=\"controls\">\n <md-outlined-text-field\n label=\"그룹\"\n .value=${this.org}\n @input=${(e: any) => (this.org = e.target.value)}\n style=\"width: 150px;\"\n ></md-outlined-text-field>\n\n <md-outlined-text-field\n label=\"시작일\"\n type=\"date\"\n .value=${this.startDate}\n @input=${(e: any) => (this.startDate = e.target.value)}\n style=\"width: 150px;\"\n ></md-outlined-text-field>\n\n <md-outlined-text-field\n label=\"종료일\"\n type=\"date\"\n .value=${this.endDate}\n @input=${(e: any) => (this.endDate = e.target.value)}\n style=\"width: 150px;\"\n ></md-outlined-text-field>\n\n <md-elevated-button @click=${this._loadData}>\n <md-icon slot=\"icon\">refresh</md-icon>\n 새로고침\n </md-elevated-button>\n </div>\n </div>\n\n <div class=\"table-container\">\n <!-- 디버깅 정보 -->\n <table style=\"border-collapse: collapse; width: 100%;\">\n <thead>\n <tr>\n <th\n style=\"border: 1px solid #ccc; padding: 8px; background: #f5f5f5; min-width: 200px; left: 0; top: 0;\"\n class=\"kpi-header\"\n >\n KPI명\n </th>\n ${this.dates.map(\n date => html`\n <th\n style=\"border: 1px solid #ccc; padding: 8px; background: #f5f5f5; min-width: 80px; position: sticky; top: 0;\"\n >\n ${this._formatDate(date)}\n </th>\n `\n )}\n </tr>\n </thead>\n <tbody>\n ${this.kpis.map(\n kpi => html`\n <tr>\n <td\n style=\"border: 1px solid #ccc; padding: 8px; background: #fff; min-width: 200px;\"\n class=\"kpi-name\"\n >\n ${kpi.kpiName}\n <span\n style=\"font-size: 10px; padding: 2px 6px; background: #e0e0e0; border-radius: 4px; margin-left: 8px;\"\n >${kpi.periodType}</span\n >\n </td>\n ${this.dates.map(\n date => html`\n <td\n style=\"border: 1px solid #ccc; padding: 8px; background: #e3f2fd; text-align: center; min-width: 80px; cursor: pointer;\"\n @click=${() => this._startEdit(kpi.kpiId, date)}\n >\n ${this._renderCellContent(kpi, date)}\n </td>\n `\n )}\n </tr>\n `\n )}\n </tbody>\n </table>\n </div>\n\n <div class=\"legend\">\n <div class=\"legend-item\">\n <div class=\"legend-color\" style=\"background: var(--md-sys-color-primary-container);\"></div>\n <span>편집 가능</span>\n </div>\n <div class=\"legend-item\">\n <div class=\"legend-color\" style=\"background: var(--md-sys-color-secondary-container);\"></div>\n <span>하이라이트 (PeriodType에 따라)</span>\n </div>\n <div class=\"legend-item\">\n <div class=\"legend-color\" style=\"background: var(--md-sys-color-surface-container);\"></div>\n <span>편집 불가</span>\n </div>\n </div>\n `\n }\n\n private _renderKpiCells(kpi: KpiValueData) {\n const cells = this._getCellsForKpi(kpi)\n\n return cells.map(cell => {\n const isEditing = this.editingCell?.kpiId === kpi.kpiId && this.editingCell?.date === cell.date\n const cellClass = this._getCellClass(cell)\n\n return html`\n <div class=\"cell ${cellClass}\" @click=${() => this._startEdit(kpi.kpiId, cell.date)}>\n ${isEditing\n ? html`\n <input\n class=\"value-input\"\n type=\"number\"\n step=\"0.01\"\n .value=${(cell.value || '').toString()}\n @blur=${(e: any) => this._finishEdit(kpi.kpiId, cell.date, parseFloat(e.target.value) || 0)}\n @keydown=${(e: any) => e.key === 'Enter' && e.target.blur()}\n autofocus\n />\n `\n : html` <span>${cell.value !== null ? cell.value.toLocaleString() : '-'}</span> `}\n </div>\n `\n })\n }\n\n private _getCellsForKpi(kpi: KpiValueData): EditorCell[] {\n const cells: EditorCell[] = []\n const periodType = kpi.periodType\n\n this.dates.forEach(date => {\n const isEditable = this._isDateEditableForPeriodType(date, periodType)\n const isHighlighted = this._isDateHighlightedForPeriodType(date, periodType)\n\n cells.push({\n date,\n value: kpi.values[date]?.value || null,\n score: kpi.values[date]?.score,\n isEditable,\n isHighlighted\n })\n })\n\n return cells\n }\n\n private _isDateEditableForPeriodType(date: string, periodType: string): boolean {\n const targetDate = new Date(date)\n\n switch (periodType) {\n case 'DAY':\n return true // 모든 날짜 편집 가능\n case 'WEEK':\n // 해당 주의 첫 번째 날짜만 편집 가능\n const weekStart = new Date(targetDate)\n weekStart.setDate(targetDate.getDate() - targetDate.getDay())\n return date === weekStart.toISOString().split('T')[0]\n case 'MONTH':\n // 해당 월의 첫 번째 날짜만 편집 가능\n return targetDate.getDate() === 1\n case 'QUARTER':\n // 해당 분기의 첫 번째 날짜만 편집 가능\n const quarterStart = new Date(targetDate.getFullYear(), Math.floor(targetDate.getMonth() / 3) * 3, 1)\n return date === quarterStart.toISOString().split('T')[0]\n case 'YEAR':\n // 해당 연도의 첫 번째 날짜만 편집 가능\n const yearStart = new Date(targetDate.getFullYear(), 0, 1)\n return date === yearStart.toISOString().split('T')[0]\n default:\n return true\n }\n }\n\n private _isDateHighlightedForPeriodType(date: string, periodType: string): boolean {\n const targetDate = new Date(date)\n\n switch (periodType) {\n case 'DAY':\n return false // 하이라이트 없음\n case 'WEEK':\n // 해당 주의 모든 날짜 하이라이트\n const weekStart = new Date(targetDate)\n weekStart.setDate(targetDate.getDate() - targetDate.getDay())\n const weekEnd = new Date(weekStart)\n weekEnd.setDate(weekStart.getDate() + 6)\n return date >= weekStart.toISOString().split('T')[0] && date <= weekEnd.toISOString().split('T')[0]\n case 'MONTH':\n // 해당 월의 모든 날짜 하이라이트\n const monthStart = new Date(targetDate.getFullYear(), targetDate.getMonth(), 1)\n const monthEnd = new Date(targetDate.getFullYear(), targetDate.getMonth() + 1, 0)\n return date >= monthStart.toISOString().split('T')[0] && date <= monthEnd.toISOString().split('T')[0]\n case 'QUARTER':\n // 해당 분기의 모든 날짜 하이라이트\n const quarter = Math.floor(targetDate.getMonth() / 3)\n const quarterStart = new Date(targetDate.getFullYear(), quarter * 3, 1)\n const quarterEnd = new Date(targetDate.getFullYear(), (quarter + 1) * 3, 0)\n return date >= quarterStart.toISOString().split('T')[0] && date <= quarterEnd.toISOString().split('T')[0]\n case 'YEAR':\n // 해당 연도의 모든 날짜 하이라이트\n const yearStart = new Date(targetDate.getFullYear(), 0, 1)\n const yearEnd = new Date(targetDate.getFullYear(), 11, 31)\n return date >= yearStart.toISOString().split('T')[0] && date <= yearEnd.toISOString().split('T')[0]\n default:\n return false\n }\n }\n\n private _getCellClass(cell: EditorCell): string {\n if (!cell.isEditable) {\n return 'disabled-cell'\n }\n if (cell.isHighlighted) {\n return 'highlighted-cell'\n }\n if (cell.isEditable) {\n return 'editable-cell'\n }\n return ''\n }\n\n private _formatDate(date: string): string {\n const d = new Date(date)\n return d.toLocaleDateString('ko-KR', { month: 'numeric', day: 'numeric' })\n }\n\n private _startEdit(kpiId: string, date: string) {\n this.editingCell = { kpiId, date }\n }\n\n private _finishEdit(kpiId: string, date: string, value: number) {\n const kpi = this.kpis.find(k => k.kpiId === kpiId)\n if (kpi) {\n if (!kpi.values[date]) {\n kpi.values[date] = { value: 0, isDirty: false }\n }\n\n // 값이 변경되었는지 확인\n const originalValue = this._findExistingValue(kpiId, date)?.value\n const isChanged = originalValue !== value\n\n kpi.values[date].value = value\n kpi.values[date].isDirty = isChanged\n\n // score는 저장 시 서버에서 계산되므로 여기서는 제거\n delete kpi.values[date].score\n }\n this.editingCell = null\n }\n\n private _renderCellContent(kpi: KpiValueData, date: string) {\n const isEditing = this.editingCell?.kpiId === kpi.kpiId && this.editingCell?.date === date\n const value = kpi.values[date]?.value\n const score = kpi.values[date]?.score\n\n if (isEditing) {\n return html`\n <input\n type=\"number\"\n step=\"0.01\"\n .value=${(value || '').toString()}\n @blur=${(e: any) => this._finishEdit(kpi.kpiId, date, parseFloat(e.target.value) || 0)}\n @keydown=${(e: any) => e.key === 'Enter' && e.target.blur()}\n style=\"width: 100%; text-align: center; border: none; background: transparent;\"\n autofocus\n />\n `\n }\n\n return html`\n <div style=\"display: flex; flex-direction: column; gap: 2px;\">\n <span style=\"font-weight: 500; color: ${value !== null && value !== undefined ? 'inherit' : '#999'};\">\n ${value !== null && value !== undefined ? value.toLocaleString() : '클릭하여 입력'}\n </span>\n ${score !== null && score !== undefined\n ? html`<span style=\"font-size: 10px; color: #666;\">Score: ${score.toFixed(3)}</span>`\n : ''}\n </div>\n `\n }\n\n private _calculateScore(value: number, periodType: string): number {\n // 간단한 score 계산 로직 (0-1 범위)\n // 실제로는 KPI의 formula나 기준값을 사용해야 함\n if (value <= 0) return 0\n if (value >= 1000) return 1\n return Math.min(value / 1000, 1)\n }\n\n private async _loadData() {\n if (!this.startDate || !this.endDate) {\n this.error = '시작일, 종료일을 모두 입력해주세요.'\n return\n }\n\n this.loading = true\n this.error = ''\n\n try {\n // KPI 목록 조회\n const kpisResponse = await client.query({\n query: gql`\n query ($filters: [Filter!]) {\n kpis(filters: $filters) {\n items {\n id\n name\n periodType\n active\n }\n total\n }\n }\n `,\n variables: {\n filters: [{ name: 'active', operator: 'eq', value: true }]\n }\n })\n\n // KPI Value 데이터 조회\n const valuesResponse = await client.query({\n query: gql`\n query ($filters: [Filter!]) {\n kpiValues(filters: $filters) {\n items {\n id\n kpiId\n valueDate\n value\n score\n kpiOrgScope {\n id\n org\n }\n }\n total\n }\n }\n `,\n variables: {\n filters: [\n ...(this.org ? [{ name: 'org', operator: 'eq', value: this.org }] : []),\n { name: 'valueDate', operator: 'between', value: [this.startDate, this.endDate] }\n ]\n }\n })\n\n // 날짜 배열 생성\n this.dates = this._generateDateArray(this.startDate, this.endDate)\n console.log('시작일:', this.startDate)\n console.log('종료일:', this.endDate)\n console.log('생성된 날짜 배열:', this.dates)\n\n // KPI 목록을 기준으로 데이터 구성\n this.kpis = kpisResponse.data.kpis.items.map((kpi: any) => ({\n kpiId: kpi.id,\n kpiName: kpi.name,\n periodType: kpi.periodType,\n values: {}\n }))\n\n // 기존 KPI Value 데이터 저장\n this._existingValues = valuesResponse.data.kpiValues.items\n\n // KPI Value 데이터를 해당 KPI에 매핑\n valuesResponse.data.kpiValues.items.forEach((value: any) => {\n const kpi = this.kpis.find(k => k.kpiId === value.kpiId)\n if (kpi) {\n kpi.values[value.valueDate] = {\n value: value.value,\n score: value.score,\n isDirty: false\n }\n }\n })\n\n // KPI Value가 없는 KPI도 빈 값으로 초기화\n this.kpis.forEach(kpi => {\n this.dates.forEach(date => {\n if (!kpi.values[date]) {\n kpi.values[date] = { value: null, score: undefined, isDirty: false }\n }\n })\n })\n\n // 디버깅 정보 출력\n console.log('KPI 총 개수:', kpisResponse.data.kpis.total)\n console.log('KPI 목록:', kpisResponse.data.kpis.items)\n console.log('KPI Value 총 개수:', valuesResponse.data.kpiValues.total)\n console.log('KPI Value 목록:', valuesResponse.data.kpiValues.items)\n console.log('구성된 KPI 데이터:', this.kpis)\n console.log('날짜 배열:', this.dates)\n\n // 강제 업데이트\n this.requestUpdate()\n } catch (error) {\n console.error('데이터 로드 중 오류:', error)\n this.error = '데이터를 불러오는 중 오류가 발생했습니다.'\n } finally {\n this.loading = false\n }\n }\n\n private _generateDateArray(startDate: string, endDate: string): string[] {\n const dates: string[] = []\n const start = new Date(startDate)\n const end = new Date(endDate)\n\n for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {\n dates.push(d.toLocaleDateString('sv-SE'))\n }\n\n return dates\n }\n\n private async _saveValues() {\n try {\n const patches: any[] = []\n\n this.kpis.forEach(kpi => {\n Object.entries(kpi.values).forEach(([date, data]) => {\n // dirty 상태인 데이터만 처리\n if (data.isDirty && data.value !== null && data.value !== undefined) {\n const existingValue = this._findExistingValue(kpi.kpiId, date)\n\n if (existingValue) {\n // 기존 데이터 업데이트\n patches.push({\n id: existingValue.id,\n value: data.value,\n org: this.org,\n cuFlag: 'M'\n })\n } else {\n // 새로운 데이터 생성\n patches.push({\n kpiId: kpi.kpiId,\n valueDate: date,\n value: data.value,\n org: this.org,\n cuFlag: '+'\n })\n }\n }\n })\n })\n\n if (patches.length === 0) {\n notify({ message: '저장할 데이터가 없습니다.' })\n return\n }\n\n // 단일 mutation으로 생성과 업데이트 처리\n const response = await client.mutate({\n mutation: gql`\n mutation ($patches: [KpiValuePatch!]!) {\n updateMultipleKpiValue(patches: $patches) {\n id\n value\n score\n valueDate\n kpiId\n }\n }\n `,\n variables: { patches }\n })\n\n if (!response.errors) {\n // 서버에서 계산된 score로 UI 업데이트\n response.data.updateMultipleKpiValue.forEach((savedValue: any) => {\n const kpi = this.kpis.find(k => k.kpiId === savedValue.kpiId)\n if (kpi && kpi.values[savedValue.valueDate]) {\n kpi.values[savedValue.valueDate].score = savedValue.score\n kpi.values[savedValue.valueDate].isDirty = false // 저장 후 dirty 상태 해제\n }\n })\n\n notify({ message: 'KPI 값이 성공적으로 저장되었습니다.' })\n this.requestUpdate() // UI 강제 업데이트\n }\n } catch (error) {\n console.error('저장 중 오류:', error)\n notify({ message: '저장 중 오류가 발생했습니다.' })\n }\n }\n\n private _findExistingValue(kpiId: string, date: string) {\n // 기존 로드된 KPI Value 데이터에서 찾기\n return this._existingValues?.find((v: any) => v.kpiId === kpiId && v.valueDate === date)\n }\n\n private _cancel() {\n // 편집 취소 로직\n this.editingCell = null\n this._loadData() // 원본 데이터로 복원\n }\n\n async pageInitialized(lifecycle: any) {\n // 기본값 설정 - 지난 1개월\n if (!this.startDate) {\n const today = new Date()\n const oneMonthAgo = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate())\n this.startDate = oneMonthAgo.toLocaleDateString('sv-SE')\n }\n if (!this.endDate) {\n const today = new Date()\n this.endDate = today.toLocaleDateString('sv-SE')\n }\n\n // 페이지 초기화 시 자동으로 데이터 로드\n await this._loadData()\n }\n}\n"]}
1
+ {"version":3,"file":"kpi-value-editor-page.js","sourceRoot":"","sources":["../../../client/pages/kpi-value/kpi-value-editor-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/elevated-button.js'\nimport '@material/web/textfield/outlined-text-field.js'\n\nimport { CommonButtonStyles, CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'\nimport { PageView } from '@operato/shell'\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { notify } from '@operato/layout'\nimport gql from 'graphql-tag'\n\ninterface KpiValueData { kpiId: string\n kpiName: string\n periodType: string\n values: { [date: string]: { value: number | null; score?: number; isDirty?: boolean } }\n}\n\ninterface EditorCell { date: string\n value: number | null\n score?: number\n isEditable: boolean\n isHighlighted: boolean\n}\n\n@customElement('kpi-value-editor-page')\nexport class KpiValueEditorPage extends localize(i18next)(ScopedElementsMixin(PageView)) { static styles = [\n CommonHeaderStyles,\n ScrollbarStyles,\n css`\n :host { display: flex;\n flex-direction: column;\n padding: 20px;\n overflow-x: auto;\n }\n\n .header { display: flex;\n gap: 16px;\n align-items: center;\n margin-bottom: 20px;\n padding: 16px;\n background: var(--md-sys-color-surface-container);\n border-radius: 8px;\n }\n\n .controls { display: flex;\n gap: 12px;\n align-items: center;\n }\n\n .table-container { flex: 1;\n overflow: auto;\n border: 1px solid var(--md-sys-color-outline);\n border-radius: 8px;\n }\n\n table { width: 100%;\n border-collapse: collapse;\n min-width: max-content;\n }\n\n th { background: var(--md-sys-color-surface-container-low);\n font-weight: 500;\n padding: 8px 12px;\n border: 1px solid var(--md-sys-color-outline-variant);\n min-width: 80px;\n height: 120px;\n vertical-align: middle;\n }\n\n td { padding: 8px 12px;\n border: 1px solid var(--md-sys-color-outline-variant);\n min-width: 80px;\n height: 60px;\n text-align: right;\n vertical-align: middle;\n }\n\n .kpi-header { position: sticky;\n left: 0;\n top: 0;\n z-index: 3;\n }\n\n .kpi-name { position: sticky;\n left: 0;\n background: var(--md-sys-color-surface);\n font-weight: 500;\n min-width: 200px;\n text-align: left;\n z-index: 2;\n }\n\n tr:hover { background: var(--md-sys-color-surface-container-high);\n }\n\n th.date-header { position: sticky;\n top: 0;\n z-index: 2;\n text-align: center;\n font-size: 11px;\n color: var(--md-sys-color-on-surface-variant);\n writing-mode: vertical-rl;\n text-orientation: mixed;\n min-height: 120px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n td.editable-cell { cursor: pointer;\n background: var(--md-sys-color-primary-container);\n color: var(--md-sys-color-on-primary-container);\n }\n\n td.editable-cell:hover { background: var(--md-sys-color-primary-container-high);\n }\n\n td.highlighted-cell { background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n font-weight: 500;\n }\n\n td.highlighted-cell:hover { background: var(--md-sys-color-secondary-container-high);\n }\n\n td.disabled-cell { background: var(--md-sys-color-surface-container);\n color: var(--md-sys-color-on-surface-variant);\n cursor: not-allowed;\n }\n\n .value-input { width: 100%;\n text-align: center;\n border: none;\n background: transparent;\n color: inherit;\n font-size: 12px;\n padding: 2px;\n }\n\n .value-input:focus { outline: 2px solid var(--md-sys-color-primary);\n border-radius: 4px;\n }\n\n .period-type-badge { font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n background: var(--md-sys-color-tertiary-container);\n color: var(--md-sys-color-on-tertiary-container);\n margin-left: 8px;\n }\n\n .loading { display: flex;\n justify-content: center;\n align-items: center;\n height: 200px;\n color: var(--md-sys-color-on-surface-variant);\n }\n\n .error { color: var(--md-sys-color-error);\n padding: 16px;\n text-align: center;\n }\n\n .legend { display: flex;\n gap: 16px;\n margin-top: 16px;\n font-size: 12px;\n }\n\n .legend-item { display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .legend-color { width: 16px;\n height: 16px;\n border-radius: 2px;\n }\n `\n ]\n\n @property({ type: String }) kpiOrgScopeId: string = ''\n @property({ type: String }) org: string = '' // legacy support\n @property({ type: String }) startDate: string = ''\n @property({ type: String }) endDate: string = ''\n\n @state() private kpis: KpiValueData[] = []\n @state() private dates: string[] = []\n @state() private loading: boolean = false\n @state() private error: string = ''\n @state() private editingCell: { kpiId: string; date: string } | null = null\n @state() private _existingValues: any[] = []\n\n get context() { return { title: i18next.t('title.kpi value editor'),\n actions: [\n { title: i18next.t('button.save'),\n action: this._saveValues.bind(this),\n ...CommonButtonStyles.save\n },\n { title: i18next.t('button.cancel'),\n action: this._cancel.bind(this),\n ...CommonButtonStyles.cancel\n }\n ]\n }\n }\n\n render() { if (this.loading) { return html`\n <div class=\"loading\">\n <md-icon>hourglass_empty</md-icon>\n <span>데이터를 불러오는 중...</span>\n </div>\n `\n }\n\n if (this.error) { return html`\n <div class=\"error\">\n <md-icon>error</md-icon>\n <span>${this.error}</span>\n </div>\n `\n }\n\n return html`\n <div class=\"header\">\n <div class=\"controls\">\n <md-outlined-text-field\n label=\"그룹\"\n .value=${this.org}\n @input=${(e: any) => (this.org = e.target.value)}\n style=\"width: 150px;\"\n ></md-outlined-text-field>\n\n <md-outlined-text-field\n label=\"시작일\"\n type=\"date\"\n .value=${this.startDate}\n @input=${(e: any) => (this.startDate = e.target.value)}\n style=\"width: 150px;\"\n ></md-outlined-text-field>\n\n <md-outlined-text-field\n label=\"종료일\"\n type=\"date\"\n .value=${this.endDate}\n @input=${(e: any) => (this.endDate = e.target.value)}\n style=\"width: 150px;\"\n ></md-outlined-text-field>\n\n <md-elevated-button @click=${this._loadData}>\n <md-icon slot=\"icon\">refresh</md-icon>\n 새로고침\n </md-elevated-button>\n </div>\n </div>\n\n <div class=\"table-container\">\n <!-- 디버깅 정보 -->\n <table style=\"border-collapse: collapse; width: 100%;\">\n <thead>\n <tr>\n <th\n style=\"border: 1px solid #ccc; padding: 8px; background: #f5f5f5; min-width: 200px; left: 0; top: 0;\"\n class=\"kpi-header\"\n >\n KPI명\n </th>\n ${this.dates.map(\n date => html`\n <th\n style=\"border: 1px solid #ccc; padding: 8px; background: #f5f5f5; min-width: 80px; position: sticky; top: 0;\"\n >\n ${this._formatDate(date)}\n </th>\n `\n )}\n </tr>\n </thead>\n <tbody>\n ${this.kpis.map(\n kpi => html`\n <tr>\n <td\n style=\"border: 1px solid #ccc; padding: 8px; background: #fff; min-width: 200px;\"\n class=\"kpi-name\"\n >\n ${kpi.kpiName}\n <span\n style=\"font-size: 10px; padding: 2px 6px; background: #e0e0e0; border-radius: 4px; margin-left: 8px;\"\n >${kpi.periodType}</span\n >\n </td>\n ${this.dates.map(\n date => html`\n <td\n style=\"border: 1px solid #ccc; padding: 8px; background: #e3f2fd; text-align: center; min-width: 80px; cursor: pointer;\"\n @click=${() => this._startEdit(kpi.kpiId, date)}\n >\n ${this._renderCellContent(kpi, date)}\n </td>\n `\n )}\n </tr>\n `\n )}\n </tbody>\n </table>\n </div>\n\n <div class=\"legend\">\n <div class=\"legend-item\">\n <div class=\"legend-color\" style=\"background: var(--md-sys-color-primary-container);\"></div>\n <span>편집 가능</span>\n </div>\n <div class=\"legend-item\">\n <div class=\"legend-color\" style=\"background: var(--md-sys-color-secondary-container);\"></div>\n <span>하이라이트 (PeriodType에 따라)</span>\n </div>\n <div class=\"legend-item\">\n <div class=\"legend-color\" style=\"background: var(--md-sys-color-surface-container);\"></div>\n <span>편집 불가</span>\n </div>\n </div>\n `\n }\n\n private _renderKpiCells(kpi: KpiValueData) { const cells = this._getCellsForKpi(kpi)\n\n return cells.map(cell => { const isEditing = this.editingCell?.kpiId === kpi.kpiId && this.editingCell?.date === cell.date\n const cellClass = this._getCellClass(cell)\n\n return html`\n <div class=\"cell ${cellClass}\" @click=${() => this._startEdit(kpi.kpiId, cell.date)}>\n ${isEditing\n ? html`\n <input\n class=\"value-input\"\n type=\"number\"\n step=\"0.01\"\n .value=${(cell.value || '').toString()}\n @blur=${(e: any) => this._finishEdit(kpi.kpiId, cell.date, parseFloat(e.target.value) || 0)}\n @keydown=${(e: any) => e.key === 'Enter' && e.target.blur()}\n autofocus\n />\n `\n : html` <span>${cell.value !== null ? cell.value.toLocaleString() : '-'}</span> `}\n </div>\n `\n })\n }\n\n private _getCellsForKpi(kpi: KpiValueData): EditorCell[] { const cells: EditorCell[] = []\n const periodType = kpi.periodType\n\n this.dates.forEach(date => { const isEditable = this._isDateEditableForPeriodType(date, periodType)\n const isHighlighted = this._isDateHighlightedForPeriodType(date, periodType)\n\n cells.push({ date,\n value: kpi.values[date]?.value || null,\n score: kpi.values[date]?.score,\n isEditable,\n isHighlighted\n })\n })\n\n return cells\n }\n\n private _isDateEditableForPeriodType(date: string, periodType: string): boolean { const targetDate = new Date(date)\n\n switch (periodType) { case 'DAY':\n return true // 모든 날짜 편집 가능\n case 'WEEK':\n // 해당 주의 첫 번째 날짜만 편집 가능\n const weekStart = new Date(targetDate)\n weekStart.setDate(targetDate.getDate() - targetDate.getDay())\n return date === weekStart.toISOString().split('T')[0]\n case 'MONTH':\n // 해당 월의 첫 번째 날짜만 편집 가능\n return targetDate.getDate() === 1\n case 'QUARTER':\n // 해당 분기의 첫 번째 날짜만 편집 가능\n const quarterStart = new Date(targetDate.getFullYear(), Math.floor(targetDate.getMonth() / 3) * 3, 1)\n return date === quarterStart.toISOString().split('T')[0]\n case 'YEAR':\n // 해당 연도의 첫 번째 날짜만 편집 가능\n const yearStart = new Date(targetDate.getFullYear(), 0, 1)\n return date === yearStart.toISOString().split('T')[0]\n default:\n return true\n }\n }\n\n private _isDateHighlightedForPeriodType(date: string, periodType: string): boolean { const targetDate = new Date(date)\n\n switch (periodType) { case 'DAY':\n return false // 하이라이트 없음\n case 'WEEK':\n // 해당 주의 모든 날짜 하이라이트\n const weekStart = new Date(targetDate)\n weekStart.setDate(targetDate.getDate() - targetDate.getDay())\n const weekEnd = new Date(weekStart)\n weekEnd.setDate(weekStart.getDate() + 6)\n return date >= weekStart.toISOString().split('T')[0] && date <= weekEnd.toISOString().split('T')[0]\n case 'MONTH':\n // 해당 월의 모든 날짜 하이라이트\n const monthStart = new Date(targetDate.getFullYear(), targetDate.getMonth(), 1)\n const monthEnd = new Date(targetDate.getFullYear(), targetDate.getMonth() + 1, 0)\n return date >= monthStart.toISOString().split('T')[0] && date <= monthEnd.toISOString().split('T')[0]\n case 'QUARTER':\n // 해당 분기의 모든 날짜 하이라이트\n const quarter = Math.floor(targetDate.getMonth() / 3)\n const quarterStart = new Date(targetDate.getFullYear(), quarter * 3, 1)\n const quarterEnd = new Date(targetDate.getFullYear(), (quarter + 1) * 3, 0)\n return date >= quarterStart.toISOString().split('T')[0] && date <= quarterEnd.toISOString().split('T')[0]\n case 'YEAR':\n // 해당 연도의 모든 날짜 하이라이트\n const yearStart = new Date(targetDate.getFullYear(), 0, 1)\n const yearEnd = new Date(targetDate.getFullYear(), 11, 31)\n return date >= yearStart.toISOString().split('T')[0] && date <= yearEnd.toISOString().split('T')[0]\n default:\n return false\n }\n }\n\n private _getCellClass(cell: EditorCell): string { if (!cell.isEditable) { return 'disabled-cell'\n }\n if (cell.isHighlighted) { return 'highlighted-cell'\n }\n if (cell.isEditable) { return 'editable-cell'\n }\n return ''\n }\n\n private _formatDate(date: string): string { const d = new Date(date)\n return d.toLocaleDateString('ko-KR', { month: 'numeric', day: 'numeric' })\n }\n\n private _startEdit(kpiId: string, date: string) { this.editingCell = { kpiId, date }\n }\n\n private _finishEdit(kpiId: string, date: string, value: number) { const kpi = this.kpis.find(k => k.kpiId === kpiId)\n if (kpi) { if (!kpi.values[date]) { kpi.values[date] = { value: 0, isDirty: false }\n }\n\n // 값이 변경되었는지 확인\n const originalValue = this._findExistingValue(kpiId, date)?.value\n const isChanged = originalValue !== value\n\n kpi.values[date].value = value\n kpi.values[date].isDirty = isChanged\n\n // score는 저장 시 서버에서 계산되므로 여기서는 제거\n delete kpi.values[date].score\n }\n this.editingCell = null\n }\n\n private _renderCellContent(kpi: KpiValueData, date: string) { const isEditing = this.editingCell?.kpiId === kpi.kpiId && this.editingCell?.date === date\n const value = kpi.values[date]?.value\n const score = kpi.values[date]?.score\n\n if (isEditing) { return html`\n <input\n type=\"number\"\n step=\"0.01\"\n .value=${(value || '').toString()}\n @blur=${(e: any) => this._finishEdit(kpi.kpiId, date, parseFloat(e.target.value) || 0)}\n @keydown=${(e: any) => e.key === 'Enter' && e.target.blur()}\n style=\"width: 100%; text-align: center; border: none; background: transparent;\"\n autofocus\n />\n `\n }\n\n return html`\n <div style=\"display: flex; flex-direction: column; gap: 2px;\">\n <span style=\"font-weight: 500; color: ${value !== null && value !== undefined ? 'inherit' : '#999'};\">\n ${value !== null && value !== undefined ? value.toLocaleString() : '클릭하여 입력'}\n </span>\n ${score !== null && score !== undefined\n ? html`<span style=\"font-size: 10px; color: #666;\">Score: ${score.toFixed(3)}</span>`\n : ''}\n </div>\n `\n }\n\n private _calculateScore(value: number, periodType: string): number { // 간단한 score 계산 로직 (0-1 범위)\n // 실제로는 KPI의 formula나 기준값을 사용해야 함\n if (value <= 0) return 0\n if (value >= 1000) return 1\n return Math.min(value / 1000, 1)\n }\n\n private async _loadData() { if (!this.startDate || !this.endDate) { this.error = '시작일, 종료일을 모두 입력해주세요.'\n return\n }\n\n this.loading = true\n this.error = ''\n\n try { // KPI 목록 조회\n const kpisResponse = await client.query({ query: gql`\n query ($filters: [Filter!]) { kpis(filters: $filters) { items { id\n name\n periodType\n active\n }\n total\n }\n }\n `,\n variables: { filters: [{ name: 'active', operator: 'eq', value: true }]\n }\n })\n\n // KPI Value 데이터 조회\n const valuesResponse = await client.query({ query: gql`\n query ($filters: [Filter!]) { kpiValues(filters: $filters) { items { id\n kpiId\n valueDate\n value\n score\n kpiOrgScope { id\n org\n }\n }\n total\n }\n }\n `,\n variables: { filters: [\n ...(this.org ? [{ name: 'org', operator: 'eq', value: this.org }] : []),\n { name: 'valueDate', operator: 'between', value: [this.startDate, this.endDate] }\n ]\n }\n })\n\n // 날짜 배열 생성\n this.dates = this._generateDateArray(this.startDate, this.endDate)\n console.log('시작일:', this.startDate)\n console.log('종료일:', this.endDate)\n console.log('생성된 날짜 배열:', this.dates)\n\n // KPI 목록을 기준으로 데이터 구성\n this.kpis = kpisResponse.data.kpis.items.map((kpi: any) => ({ kpiId: kpi.id,\n kpiName: kpi.name,\n periodType: kpi.periodType,\n values: {}\n }))\n\n // 기존 KPI Value 데이터 저장\n this._existingValues = valuesResponse.data.kpiValues.items\n\n // KPI Value 데이터를 해당 KPI에 매핑\n valuesResponse.data.kpiValues.items.forEach((value: any) => { const kpi = this.kpis.find(k => k.kpiId === value.kpiId)\n if (kpi) { kpi.values[value.valueDate] = { value: value.value,\n score: value.score,\n isDirty: false\n }\n }\n })\n\n // KPI Value가 없는 KPI도 빈 값으로 초기화\n this.kpis.forEach(kpi => { this.dates.forEach(date => { if (!kpi.values[date]) { kpi.values[date] = { value: null, score: undefined, isDirty: false }\n }\n })\n })\n\n // 디버깅 정보 출력\n console.log('KPI 총 개수:', kpisResponse.data.kpis.total)\n console.log('KPI 목록:', kpisResponse.data.kpis.items)\n console.log('KPI Value 총 개수:', valuesResponse.data.kpiValues.total)\n console.log('KPI Value 목록:', valuesResponse.data.kpiValues.items)\n console.log('구성된 KPI 데이터:', this.kpis)\n console.log('날짜 배열:', this.dates)\n\n // 강제 업데이트\n this.requestUpdate()\n } catch (error) { console.error('데이터 로드 중 오류:', error)\n this.error = '데이터를 불러오는 중 오류가 발생했습니다.'\n } finally { this.loading = false\n }\n }\n\n private _generateDateArray(startDate: string, endDate: string): string[] { const dates: string[] = []\n const start = new Date(startDate)\n const end = new Date(endDate)\n\n for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) { dates.push(d.toLocaleDateString('sv-SE'))\n }\n\n return dates\n }\n\n private async _saveValues() { try { const patches: any[] = []\n\n this.kpis.forEach(kpi => { Object.entries(kpi.values).forEach(([date, data]) => { // dirty 상태인 데이터만 처리\n if (data.isDirty && data.value !== null && data.value !== undefined) { const existingValue = this._findExistingValue(kpi.kpiId, date)\n\n if (existingValue) { // 기존 데이터 업데이트\n patches.push({ id: existingValue.id,\n value: data.value,\n org: this.org,\n cuFlag: 'M'\n })\n } else { // 새로운 데이터 생성\n patches.push({ kpiId: kpi.kpiId,\n valueDate: date,\n value: data.value,\n org: this.org,\n cuFlag: '+'\n })\n }\n }\n })\n })\n\n if (patches.length === 0) { notify({ message: '저장할 데이터가 없습니다.' })\n return\n }\n\n // 단일 mutation으로 생성과 업데이트 처리\n const response = await client.mutate({ mutation: gql`\n mutation ($patches: [KpiValuePatch!]!) { updateMultipleKpiValue(patches: $patches) { id\n value\n score\n valueDate\n kpiId\n }\n }\n `,\n variables: { patches }\n })\n\n if (!response.errors) { // 서버에서 계산된 score로 UI 업데이트\n response.data.updateMultipleKpiValue.forEach((savedValue: any) => { const kpi = this.kpis.find(k => k.kpiId === savedValue.kpiId)\n if (kpi && kpi.values[savedValue.valueDate]) { kpi.values[savedValue.valueDate].score = savedValue.score\n kpi.values[savedValue.valueDate].isDirty = false // 저장 후 dirty 상태 해제\n }\n })\n\n notify({ message: 'KPI 값이 성공적으로 저장되었습니다.' })\n this.requestUpdate() // UI 강제 업데이트\n }\n } catch (error) { console.error('저장 중 오류:', error)\n notify({ message: '저장 중 오류가 발생했습니다.' })\n }\n }\n\n private _findExistingValue(kpiId: string, date: string) { // 기존 로드된 KPI Value 데이터에서 찾기\n return this._existingValues?.find((v: any) => v.kpiId === kpiId && v.valueDate === date)\n }\n\n private _cancel() { // 편집 취소 로직\n this.editingCell = null\n this._loadData() // 원본 데이터로 복원\n }\n\n async pageInitialized(lifecycle: any) { // 기본값 설정 - 지난 1개월\n if (!this.startDate) { const today = new Date()\n const oneMonthAgo = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate())\n this.startDate = oneMonthAgo.toLocaleDateString('sv-SE')\n }\n if (!this.endDate) { const today = new Date()\n this.endDate = today.toLocaleDateString('sv-SE')\n }\n\n // 페이지 초기화 시 자동으로 데이터 로드\n await this._loadData()\n }\n}\n"]}
@@ -7,12 +7,6 @@ import { PageView } from '@operato/shell';
7
7
  import { FetchOption } from '@operato/data-grist';
8
8
  import { KpiValueImporter } from './kpi-value-importer';
9
9
  declare const KpiValueListPage_base: (new (...args: any[]) => {
10
- _storeUnsubscribe: import("redux").Unsubscribe;
11
- connectedCallback(): void;
12
- disconnectedCallback(): void;
13
- stateChanged(_state: unknown): void;
14
- readonly isConnected: boolean;
15
- }) & (new (...args: any[]) => {
16
10
  __preferenceProviders: {
17
11
  [element: string]: import("@operato/p13n").PagePreferenceProvider;
18
12
  };
@@ -5,7 +5,7 @@ import '@operato/data-grist/ox-grist.js';
5
5
  import '@operato/data-grist/ox-filters-form.js';
6
6
  import '@operato/data-grist/ox-record-creator.js';
7
7
  import { CommonButtonStyles, CommonHeaderStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles';
8
- import { PageView, store } from '@operato/shell';
8
+ import { PageView } from '@operato/shell';
9
9
  import { css, html } from 'lit';
10
10
  import { customElement, property, query } from 'lit/decorators.js';
11
11
  import { ScopedElementsMixin } from '@open-wc/scoped-elements';
@@ -16,10 +16,9 @@ import { notify, openPopup } from '@operato/layout';
16
16
  import { OxPrompt } from '@operato/popup';
17
17
  import { isMobileDevice } from '@operato/utils';
18
18
  import { p13n } from '@operato/p13n';
19
- import { connect } from 'pwa-helpers/connect-mixin';
20
19
  import gql from 'graphql-tag';
21
20
  import { KpiValueImporter } from './kpi-value-importer';
22
- let KpiValueListPage = class KpiValueListPage extends connect(store)(p13n(localize(i18next)(ScopedElementsMixin(PageView)))) {
21
+ let KpiValueListPage = class KpiValueListPage extends p13n(localize(i18next)(ScopedElementsMixin(PageView))) {
23
22
  constructor() {
24
23
  super(...arguments);
25
24
  this.mode = isMobileDevice() ? 'CARD' : 'GRID';
@@ -29,71 +28,57 @@ let KpiValueListPage = class KpiValueListPage extends connect(store)(p13n(locali
29
28
  CommonGristStyles,
30
29
  CommonHeaderStyles,
31
30
  css `
32
- :host {
33
- display: flex;
31
+ :host { display: flex;
34
32
 
35
33
  width: 100%;
36
34
 
37
35
  --grid-record-emphasized-background-color: #8b0000;
38
36
  --grid-record-emphasized-color: #ff6b6b;
39
- }
37
+ }
40
38
 
41
- ox-grist {
42
- overflow-y: auto;
39
+ ox-grist { overflow-y: auto;
43
40
  flex: 1;
44
- }
41
+ }
45
42
 
46
- ox-filters-form {
47
- flex: 1;
48
- }
43
+ ox-filters-form { flex: 1;
44
+ }
49
45
  `
50
46
  ]; }
51
47
  static get scopedElements() {
52
- return {
53
- 'kpi-value-importer': KpiValueImporter
48
+ return { 'kpi-value-importer': KpiValueImporter
54
49
  };
55
50
  }
56
51
  get context() {
57
- return {
58
- title: i18next.t('title.kpi value list'),
59
- search: {
60
- handler: (search) => {
52
+ return { title: i18next.t('title.kpi value list'),
53
+ search: { handler: (search) => {
61
54
  this.grist.searchText = search;
62
55
  },
63
- value: this.grist.searchText
64
- },
65
- filter: {
66
- handler: () => {
56
+ value: this.grist.searchText },
57
+ filter: { handler: () => {
67
58
  this.grist.toggleHeadroom();
68
59
  }
69
60
  },
70
61
  help: 'kpi/kpi-value',
71
62
  actions: [
72
- {
73
- title: '일괄 편집',
63
+ { title: '일괄 편집',
74
64
  action: this._openEditor.bind(this),
75
65
  icon: 'edit',
76
66
  style: 'background: var(--md-sys-color-tertiary-container); color: var(--md-sys-color-on-tertiary-container);'
77
67
  },
78
- {
79
- title: i18next.t('button.save'),
68
+ { title: i18next.t('button.save'),
80
69
  action: this._updateKpiValue.bind(this),
81
70
  ...CommonButtonStyles.save
82
71
  },
83
- {
84
- title: i18next.t('button.delete'),
72
+ { title: i18next.t('button.delete'),
85
73
  action: this._deleteKpiValue.bind(this),
86
74
  ...CommonButtonStyles.delete
87
75
  }
88
76
  ],
89
- exportable: {
90
- name: i18next.t('title.kpi value list'),
77
+ exportable: { name: i18next.t('title.kpi value list'),
91
78
  data: this.exportHandler.bind(this)
92
79
  },
93
- importable: {
94
- handler: this.importHandler.bind(this)
95
- }
96
- };
80
+ importable: { handler: this.importHandler.bind(this)
81
+ } };
97
82
  }
98
83
  render() {
99
84
  const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID');
@@ -127,9 +112,7 @@ let KpiValueListPage = class KpiValueListPage extends connect(store)(p13n(locali
127
112
  `;
128
113
  }
129
114
  async pageInitialized(lifecycle) {
130
- this.gristConfig = {
131
- list: {
132
- fields: [
115
+ this.gristConfig = { list: { fields: [
133
116
  'kpi',
134
117
  'version',
135
118
  'valueDate',
@@ -164,19 +147,16 @@ let KpiValueListPage = class KpiValueListPage extends connect(store)(p13n(locali
164
147
  { type: 'gutter', gutterName: 'sequence' },
165
148
  { type: 'gutter', gutterName: 'row-selector', multiple: true },
166
149
  // KPI Value 재계산 버튼 추가
167
- {
168
- type: 'gutter',
150
+ { type: 'gutter',
169
151
  gutterName: 'button',
170
152
  icon: 'refresh',
171
153
  title: '재계산',
172
- handlers: {
173
- click: (columns, data, column, record, rowIndex) => {
154
+ handlers: { click: (columns, data, column, record, rowIndex) => {
174
155
  this._recalculateKpiValue(record);
175
156
  }
176
157
  }
177
158
  },
178
- {
179
- type: 'string',
159
+ { type: 'string',
180
160
  name: 'kpiOrgScope',
181
161
  header: '조직',
182
162
  record: { editable: false },
@@ -185,8 +165,7 @@ let KpiValueListPage = class KpiValueListPage extends connect(store)(p13n(locali
185
165
  return value?.entityName || value?.org || '';
186
166
  }
187
167
  },
188
- {
189
- type: 'string',
168
+ { type: 'string',
190
169
  name: 'kpi',
191
170
  header: 'KPI',
192
171
  record: { editable: false, renderer: (v, c, r) => r.kpi?.name },
@@ -201,46 +180,36 @@ let KpiValueListPage = class KpiValueListPage extends connect(store)(p13n(locali
201
180
  { type: 'object', name: 'meta', header: '메타', record: { editable: false }, width: 120 },
202
181
  { type: 'datetime', name: 'createdAt', header: '생성일', record: { editable: false }, width: 180 },
203
182
  { type: 'datetime', name: 'updatedAt', header: '수정일', record: { editable: false }, width: 180 },
204
- {
205
- type: 'resource-object',
183
+ { type: 'resource-object',
206
184
  name: 'creator',
207
185
  header: '생성자',
208
186
  record: { editable: false, renderer: (v, c, r) => r.creator?.name },
209
187
  width: 120
210
188
  },
211
- {
212
- type: 'resource-object',
189
+ { type: 'resource-object',
213
190
  name: 'updater',
214
191
  header: '수정자',
215
192
  record: { editable: false, renderer: (v, c, r) => r.updater?.name },
216
193
  width: 120
217
194
  }
218
195
  ],
219
- rows: {
220
- appendable: false,
221
- selectable: {
222
- multiple: true
196
+ rows: { appendable: false,
197
+ selectable: { multiple: true
223
198
  }
224
199
  },
225
200
  sorters: [{ name: 'valueDate' }]
226
201
  };
227
202
  }
228
203
  async pageUpdated(changes, lifecycle) {
229
- if (this.active) {
230
- // do something here when this page just became as active
204
+ if (this.active) { // do something here when this page just became as active
231
205
  }
232
206
  }
233
207
  async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }) {
234
- const response = await client.query({
235
- query: gql `
236
- query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
237
- responses: kpiValues(filters: $filters, pagination: $pagination, sortings: $sortings) {
238
- items {
239
- id
240
- kpi {
241
- id
208
+ const response = await client.query({ query: gql `
209
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) { responses: kpiValues(filters: $filters, pagination: $pagination, sortings: $sortings) { items { id
210
+ kpi { id
242
211
  name
243
- }
212
+ }
244
213
  version
245
214
  valueDate
246
215
  value
@@ -248,33 +217,28 @@ let KpiValueListPage = class KpiValueListPage extends connect(store)(p13n(locali
248
217
  inputType
249
218
  source
250
219
  meta
251
- kpiOrgScope {
252
- id
220
+ kpiOrgScope { id
253
221
  org
254
- }
255
- updater {
256
- id
222
+ }
223
+ updater { id
257
224
  name
258
- }
225
+ }
259
226
  updatedAt
260
- creator {
261
- id
227
+ creator { id
262
228
  name
263
- }
229
+ }
264
230
  createdAt
265
- }
231
+ }
266
232
  total
267
- }
268
- }
233
+ }
234
+ }
269
235
  `,
270
- variables: {
271
- filters,
236
+ variables: { filters,
272
237
  pagination: { page, limit },
273
238
  sortings
274
239
  }
275
240
  });
276
- return {
277
- total: response.data.responses.total || 0,
241
+ return { total: response.data.responses.total || 0,
278
242
  records: response.data.responses.items || []
279
243
  };
280
244
  }
@@ -285,28 +249,23 @@ let KpiValueListPage = class KpiValueListPage extends connect(store)(p13n(locali
285
249
  `);
286
250
  }
287
251
  async _deleteKpiValue() {
288
- if (await OxPrompt.open({
289
- title: i18next.t('text.are_you_sure'),
252
+ if (await OxPrompt.open({ title: i18next.t('text.are_you_sure'),
290
253
  text: i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }),
291
254
  confirmButton: { text: i18next.t('button.confirm') },
292
255
  cancelButton: { text: i18next.t('button.cancel') }
293
256
  })) {
294
257
  const ids = this.grist.selected.map(record => record.id);
295
258
  if (ids && ids.length > 0) {
296
- const response = await client.mutate({
297
- mutation: gql `
298
- mutation ($ids: [String!]!) {
299
- deleteKpiValues(ids: $ids)
300
- }
259
+ const response = await client.mutate({ mutation: gql `
260
+ mutation ($ids: [String!]!) { deleteKpiValues(ids: $ids)
261
+ }
301
262
  `,
302
- variables: {
303
- ids
263
+ variables: { ids
304
264
  }
305
265
  });
306
266
  if (!response.errors) {
307
267
  this.grist.fetch();
308
- notify({
309
- message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
268
+ notify({ message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
310
269
  });
311
270
  }
312
271
  }
@@ -324,24 +283,19 @@ let KpiValueListPage = class KpiValueListPage extends connect(store)(p13n(locali
324
283
  patchField.cuFlag = patch.__dirty__;
325
284
  return patchField;
326
285
  });
327
- const response = await client.mutate({
328
- mutation: gql `
329
- mutation ($patches: [KpiValuePatch!]!) {
330
- updateMultipleKpiValue(patches: $patches) {
331
- id
332
- kpi {
333
- id
286
+ const response = await client.mutate({ mutation: gql `
287
+ mutation ($patches: [KpiValuePatch!]!) { updateMultipleKpiValue(patches: $patches) { id
288
+ kpi { id
334
289
  name
335
- }
290
+ }
336
291
  version
337
292
  valueDate
338
293
  value
339
294
  score
340
- }
341
- }
295
+ }
296
+ }
342
297
  `,
343
- variables: {
344
- patches
298
+ variables: { patches
345
299
  }
346
300
  });
347
301
  if (!response.errors) {
@@ -351,24 +305,19 @@ let KpiValueListPage = class KpiValueListPage extends connect(store)(p13n(locali
351
305
  }
352
306
  async _recalculateKpiValue(kpiValue) {
353
307
  try {
354
- const response = await client.mutate({
355
- mutation: gql `
356
- mutation ($id: String!) {
357
- recalculateKpiValue(id: $id) {
358
- id
308
+ const response = await client.mutate({ mutation: gql `
309
+ mutation ($id: String!) { recalculateKpiValue(id: $id) { id
359
310
  value
360
311
  score
361
312
  valueDate
362
- kpiOrgScope {
363
- id
313
+ kpiOrgScope { id
364
314
  entityName
365
315
  org
366
- }
367
- }
368
- }
316
+ }
317
+ }
318
+ }
369
319
  `,
370
- variables: {
371
- id: kpiValue.id
320
+ variables: { id: kpiValue.id
372
321
  }
373
322
  });
374
323
  if (!response.errors) {
@@ -382,26 +331,19 @@ let KpiValueListPage = class KpiValueListPage extends connect(store)(p13n(locali
382
331
  }
383
332
  async creationCallback(kpiValue) {
384
333
  try {
385
- const response = await client.query({
386
- query: gql `
387
- mutation ($kpiValue: NewKpiValue!) {
388
- createKpiValue(kpiValue: $kpiValue) {
389
- id
390
- }
391
- }
334
+ const response = await client.query({ query: gql `
335
+ mutation ($kpiValue: NewKpiValue!) { createKpiValue(kpiValue: $kpiValue) { id
336
+ }
337
+ }
392
338
  `,
393
- variables: {
394
- kpiValue
339
+ variables: { kpiValue
395
340
  },
396
- context: {
397
- hasUpload: true
341
+ context: { hasUpload: true
398
342
  }
399
343
  });
400
344
  if (!response.errors) {
401
345
  this.grist.fetch();
402
- document.dispatchEvent(new CustomEvent('notify', {
403
- detail: {
404
- message: i18next.t('text.data_created_successfully')
346
+ document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.data_created_successfully')
405
347
  }
406
348
  }));
407
349
  }
@@ -409,9 +351,7 @@ let KpiValueListPage = class KpiValueListPage extends connect(store)(p13n(locali
409
351
  }
410
352
  catch (ex) {
411
353
  console.error(ex);
412
- document.dispatchEvent(new CustomEvent('notify', {
413
- detail: {
414
- type: 'error',
354
+ document.dispatchEvent(new CustomEvent('notify', { detail: { type: 'error',
415
355
  message: i18next.t('text.error')
416
356
  }
417
357
  }));
@@ -438,8 +378,7 @@ let KpiValueListPage = class KpiValueListPage extends connect(store)(p13n(locali
438
378
  this.grist.fetch();
439
379
  }}
440
380
  ></kpi-value-importer>
441
- `, {
442
- backdrop: true,
381
+ `, { backdrop: true,
443
382
  size: 'large',
444
383
  title: i18next.t('title.import kpi-value')
445
384
  });