@things-factory/kpi 9.0.28 → 9.0.29

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 (83) hide show
  1. package/client/pages/kpi-statistic/kpi-statistic-editor-page.ts +761 -0
  2. package/client/pages/kpi-statistic/kpi-statistic-importer.ts +90 -0
  3. package/client/pages/kpi-statistic/kpi-statistic-list-page.ts +505 -0
  4. package/client/route.ts +8 -0
  5. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.d.ts +53 -0
  6. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js +718 -0
  7. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js.map +1 -0
  8. package/dist-client/pages/kpi-statistic/kpi-statistic-importer.d.ts +23 -0
  9. package/dist-client/pages/kpi-statistic/kpi-statistic-importer.js +92 -0
  10. package/dist-client/pages/kpi-statistic/kpi-statistic-importer.js.map +1 -0
  11. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.d.ts +66 -0
  12. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js +487 -0
  13. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js.map +1 -0
  14. package/dist-client/route.d.ts +1 -1
  15. package/dist-client/route.js +6 -0
  16. package/dist-client/route.js.map +1 -1
  17. package/dist-client/tsconfig.tsbuildinfo +1 -1
  18. package/dist-server/service/index.d.ts +3 -2
  19. package/dist-server/service/index.js +4 -0
  20. package/dist-server/service/index.js.map +1 -1
  21. package/dist-server/service/kpi/kpi-mutation.js +9 -0
  22. package/dist-server/service/kpi/kpi-mutation.js.map +1 -1
  23. package/dist-server/service/kpi/kpi-query.js +2 -0
  24. package/dist-server/service/kpi/kpi-query.js.map +1 -1
  25. package/dist-server/service/kpi-alert/kpi-alert-query.js +1 -0
  26. package/dist-server/service/kpi-alert/kpi-alert-query.js.map +1 -1
  27. package/dist-server/service/kpi-category/kpi-category-mutation.js +4 -0
  28. package/dist-server/service/kpi-category/kpi-category-mutation.js.map +1 -1
  29. package/dist-server/service/kpi-category/kpi-category-query.js +2 -0
  30. package/dist-server/service/kpi-category/kpi-category-query.js.map +1 -1
  31. package/dist-server/service/kpi-metric/kpi-metric-mutation.js +6 -0
  32. package/dist-server/service/kpi-metric/kpi-metric-mutation.js.map +1 -1
  33. package/dist-server/service/kpi-metric/kpi-metric-query.js +2 -0
  34. package/dist-server/service/kpi-metric/kpi-metric-query.js.map +1 -1
  35. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +7 -0
  36. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -1
  37. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js +2 -0
  38. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js.map +1 -1
  39. package/dist-server/service/kpi-statistic/index.d.ts +6 -0
  40. package/dist-server/service/kpi-statistic/index.js +10 -0
  41. package/dist-server/service/kpi-statistic/index.js.map +1 -0
  42. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.d.ts +10 -0
  43. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.js +198 -0
  44. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.js.map +1 -0
  45. package/dist-server/service/kpi-statistic/kpi-statistic-query.d.ts +13 -0
  46. package/dist-server/service/kpi-statistic/kpi-statistic-query.js +92 -0
  47. package/dist-server/service/kpi-statistic/kpi-statistic-query.js.map +1 -0
  48. package/dist-server/service/kpi-statistic/kpi-statistic-type.d.ts +59 -0
  49. package/dist-server/service/kpi-statistic/kpi-statistic-type.js +200 -0
  50. package/dist-server/service/kpi-statistic/kpi-statistic-type.js.map +1 -0
  51. package/dist-server/service/kpi-statistic/kpi-statistic.d.ts +38 -0
  52. package/dist-server/service/kpi-statistic/kpi-statistic.js +177 -0
  53. package/dist-server/service/kpi-statistic/kpi-statistic.js.map +1 -0
  54. package/dist-server/service/kpi-value/kpi-value-mutation.js +9 -0
  55. package/dist-server/service/kpi-value/kpi-value-mutation.js.map +1 -1
  56. package/dist-server/service/kpi-value/kpi-value-query.js +2 -0
  57. package/dist-server/service/kpi-value/kpi-value-query.js.map +1 -1
  58. package/dist-server/tsconfig.tsbuildinfo +1 -1
  59. package/helps/kpi/kpi-statistic.md +160 -0
  60. package/package.json +2 -2
  61. package/server/service/index.ts +8 -0
  62. package/server/service/kpi/kpi-mutation.ts +9 -0
  63. package/server/service/kpi/kpi-query.ts +2 -0
  64. package/server/service/kpi-alert/kpi-alert-query.ts +2 -1
  65. package/server/service/kpi-category/kpi-category-mutation.ts +4 -0
  66. package/server/service/kpi-category/kpi-category-query.ts +2 -0
  67. package/server/service/kpi-metric/kpi-metric-mutation.ts +6 -0
  68. package/server/service/kpi-metric/kpi-metric-query.ts +2 -0
  69. package/server/service/kpi-metric-value/kpi-metric-value-mutation.ts +7 -0
  70. package/server/service/kpi-metric-value/kpi-metric-value-query.ts +3 -1
  71. package/server/service/kpi-statistic/index.ts +7 -0
  72. package/server/service/kpi-statistic/kpi-statistic-mutation.ts +194 -0
  73. package/server/service/kpi-statistic/kpi-statistic-query.ts +59 -0
  74. package/server/service/kpi-statistic/kpi-statistic-type.ts +152 -0
  75. package/server/service/kpi-statistic/kpi-statistic.ts +167 -0
  76. package/server/service/kpi-value/kpi-value-mutation.ts +9 -0
  77. package/server/service/kpi-value/kpi-value-query.ts +2 -0
  78. package/things-factory.config.js +3 -1
  79. package/translations/en.json +23 -1
  80. package/translations/ja.json +42 -20
  81. package/translations/ko.json +29 -7
  82. package/translations/ms.json +34 -12
  83. package/translations/zh.json +38 -16
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-statistic-editor-page.js","sourceRoot":"","sources":["../../../client/pages/kpi-statistic/kpi-statistic-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 KpiStatisticData {\n kpi: {\n id: string\n name: string\n }\n valueDate: string\n periodType: string\n statistics: {\n count?: number\n sum?: number\n range?: number\n mean?: number\n median?: number\n minimum?: number\n maximum?: number\n standardDeviation?: number\n variance?: number\n percentile25?: number\n percentile75?: number\n iqr?: number\n lowerFence?: number\n upperFence?: number\n isDirty?: boolean\n }\n}\n\ninterface EditorCell {\n field: string\n value: number | null\n isEditable: boolean\n isHighlighted: boolean\n}\n\n@customElement('kpi-statistic-editor-page')\nexport class KpiStatisticEditorPage 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 flex-wrap: wrap;\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: 120px;\n height: 60px;\n vertical-align: middle;\n text-align: center;\n }\n\n td {\n padding: 8px 12px;\n border: 1px solid var(--md-sys-color-outline-variant);\n min-width: 120px;\n height: 60px;\n text-align: center;\n vertical-align: middle;\n }\n\n .kpi-header {\n position: sticky;\n left: 0;\n top: 0;\n z-index: 3;\n min-width: 200px;\n text-align: left;\n }\n\n .field-header {\n position: sticky;\n left: 0;\n top: 0;\n z-index: 2;\n min-width: 200px;\n text-align: center;\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 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-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 .field-group {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .field-name {\n font-size: 10px;\n color: var(--md-sys-color-on-surface-variant);\n font-weight: 500;\n }\n\n .field-value {\n font-size: 12px;\n font-weight: 500;\n }\n `\n ]\n\n @property({ type: String }) periodType: string = 'MONTH'\n @property({ type: String }) valueDate: string = ''\n @property({ type: String }) targetDate: string = '' // 기준 날짜 (예: 2025-08-03)\n\n @state() private kpis: KpiStatisticData[] = []\n @state() private loading: boolean = false\n @state() private error: string = ''\n @state() private editingCell: { kpi: { id: string }; field: string } | null = null\n @state() private _existingStatistics: any[] = []\n\n // 통계 필드 정의\n private readonly statisticFields = [\n { name: 'count', label: 'Count', group: 'basic' },\n { name: 'sum', label: 'Sum', group: 'basic' },\n { name: 'range', label: 'Range', group: 'basic' },\n { name: 'mean', label: 'Mean', group: 'central' },\n { name: 'median', label: 'Median', group: 'central' },\n { name: 'minimum', label: 'Min', group: 'range' },\n { name: 'maximum', label: 'Max', group: 'range' },\n { name: 'standardDeviation', label: 'Std Dev', group: 'dispersion' },\n { name: 'variance', label: 'Variance', group: 'dispersion' },\n { name: 'percentile25', label: 'P25', group: 'percentile' },\n { name: 'percentile75', label: 'P75', group: 'percentile' },\n { name: 'iqr', label: 'IQR', group: 'percentile' },\n { name: 'lowerFence', label: 'Lower Fence', group: 'fence' },\n { name: 'upperFence', label: 'Upper Fence', group: 'fence' }\n ]\n\n get context() {\n return {\n title: i18next.t('title.kpi statistic editor'),\n actions: [\n {\n title: i18next.t('button.save'),\n action: this._saveStatistics.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.periodType}\n @input=${(e: any) => this._onPeriodChange(e.target.value)}\n style=\"width: 120px;\"\n ></md-outlined-text-field>\n\n <md-outlined-text-field\n label=\"기준 날짜\"\n type=\"date\"\n .value=${this.targetDate}\n @input=${(e: any) => this._onTargetDateChange(e.target.value)}\n style=\"width: 150px;\"\n ></md-outlined-text-field>\n\n <md-outlined-text-field\n label=\"값 날짜\"\n .value=${this.valueDate}\n @input=${(e: any) => (this.valueDate = e.target.value)}\n style=\"width: 150px;\"\n readonly\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 <table>\n <thead>\n <tr>\n <th class=\"kpi-header\">KPI명</th>\n ${this.statisticFields.map(\n field => html`\n <th class=\"field-header\">\n <div class=\"field-group\">\n <div class=\"field-name\">${field.label}</div>\n <div class=\"field-value\">${field.name}</div>\n </div>\n </th>\n `\n )}\n </tr>\n </thead>\n <tbody>\n ${this.kpis.map(\n kpi => html`\n <tr>\n <td class=\"kpi-name\">\n ${kpi.kpi.name}\n <span class=\"period-badge\">${kpi.periodType}</span>\n </td>\n ${this.statisticFields.map(\n field => html`\n <td\n class=${this._getCellClass(kpi, field.name)}\n @click=${() => this._startEdit(kpi.kpi.id, field.name)}\n >\n ${this._renderCellContent(kpi, field.name)}\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>하이라이트 (중요 필드)</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 _getCellClass(kpi: KpiStatisticData, fieldName: string): string {\n const isEditable = this._isFieldEditable(fieldName)\n const isHighlighted = this._isFieldHighlighted(fieldName)\n\n if (!isEditable) {\n return 'disabled-cell'\n }\n if (isHighlighted) {\n return 'highlighted-cell'\n }\n return 'editable-cell'\n }\n\n private _isFieldEditable(fieldName: string): boolean {\n // 모든 필드를 편집 가능하게 설정 (필요에 따라 제한 가능)\n return true\n }\n\n private _isFieldHighlighted(fieldName: string): boolean {\n // 중요 필드들을 하이라이트\n const importantFields = ['count', 'mean', 'median', 'minimum', 'maximum', 'standardDeviation']\n return importantFields.includes(fieldName)\n }\n\n private _renderCellContent(kpi: KpiStatisticData, fieldName: string) {\n const isEditing = this.editingCell?.kpi?.id === kpi.kpi.id && this.editingCell?.field === fieldName\n const value = kpi.statistics[fieldName]\n\n if (isEditing) {\n return html`\n <input\n class=\"value-input\"\n type=\"number\"\n step=\"0.01\"\n .value=${(value || '').toString()}\n @blur=${(e: any) => this._finishEdit(kpi.kpi.id, fieldName, parseFloat(e.target.value) || null)}\n @keydown=${(e: any) => e.key === 'Enter' && e.target.blur()}\n autofocus\n />\n `\n }\n\n return html`\n <span style=\"color: ${value !== null && value !== undefined ? 'inherit' : '#999'};\">\n ${value !== null && value !== undefined ? value.toLocaleString() : '클릭하여 입력'}\n </span>\n `\n }\n\n private _startEdit(kpiId: string, fieldName: string) {\n this.editingCell = { kpi: { id: kpiId }, field: fieldName }\n }\n\n private _finishEdit(kpiId: string, fieldName: string, value: number | null) {\n const kpi = this.kpis.find(k => k.kpi.id === kpiId)\n if (kpi) {\n const originalValue = this._findExistingStatistic(kpiId)?.[fieldName]\n const isChanged = originalValue !== value\n\n kpi.statistics[fieldName] = value\n kpi.statistics.isDirty = isChanged\n }\n this.editingCell = null\n }\n\n private async _loadData() {\n if (!this.valueDate) {\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 categoryId\n category {\n id\n name\n }\n }\n total\n }\n }\n `,\n variables: {\n filters: [{ name: 'active', operator: 'eq', value: true }]\n }\n })\n\n // 기존 KPI Statistic 데이터 조회\n const statisticsResponse = await client.query({\n query: gql`\n query ($filters: [Filter!]) {\n kpiStatistics(filters: $filters) {\n items {\n id\n kpi {\n id\n name\n }\n valueDate\n periodType\n count\n sum\n range\n mean\n median\n minimum\n maximum\n standardDeviation\n variance\n percentile25\n percentile75\n iqr\n lowerFence\n upperFence\n additionalStatistics\n metadata\n }\n total\n }\n }\n `,\n variables: {\n filters: [\n { name: 'valueDate', operator: 'eq', value: this.valueDate },\n { name: 'periodType', operator: 'eq', value: this.periodType }\n ]\n }\n })\n\n // KPI 목록을 기준으로 데이터 구성 (카테고리별로 필터링)\n console.log('KPI 원본 데이터:', kpisResponse.data.kpis.items)\n\n const filteredKpis = kpisResponse.data.kpis.items\n console.log('모든 KPI 포함:', filteredKpis)\n\n console.log('필터링된 KPI:', filteredKpis)\n\n this.kpis = filteredKpis.map((kpi: any) => ({\n kpi: kpi,\n valueDate: this.valueDate,\n periodType: this.periodType,\n statistics: {\n count: null,\n sum: null,\n range: null,\n mean: null,\n median: null,\n minimum: null,\n maximum: null,\n standardDeviation: null,\n variance: null,\n percentile25: null,\n percentile75: null,\n iqr: null,\n lowerFence: null,\n upperFence: null,\n isDirty: false\n }\n }))\n\n // 기존 KPI Statistic 데이터 저장\n this._existingStatistics = statisticsResponse.data.kpiStatistics.items\n console.log('기존 통계 데이터:', this._existingStatistics)\n\n // 기존 통계 데이터를 해당 KPI에 매핑\n statisticsResponse.data.kpiStatistics.items.forEach((statistic: any) => {\n const kpi = this.kpis.find(k => k.kpi.id === statistic.kpi.id) // KPI ID로 매칭\n console.log(`통계 데이터 매핑: statistic.kpi.id=${statistic.kpi.id}, 찾은 KPI:`, kpi?.kpi.name || '없음')\n if (kpi) {\n kpi.statistics = {\n count: statistic.count,\n sum: statistic.sum,\n range: statistic.range,\n mean: statistic.mean,\n median: statistic.median,\n minimum: statistic.minimum,\n maximum: statistic.maximum,\n standardDeviation: statistic.standardDeviation,\n variance: statistic.variance,\n percentile25: statistic.percentile25,\n percentile75: statistic.percentile75,\n iqr: statistic.iqr,\n lowerFence: statistic.lowerFence,\n upperFence: statistic.upperFence,\n isDirty: false\n }\n }\n })\n\n console.log('KPI 총 개수:', kpisResponse.data.kpis.total)\n console.log('KPI 목록:', kpisResponse.data.kpis.items)\n console.log('기존 통계 데이터:', this._existingStatistics)\n console.log('구성된 KPI 통계 데이터:', this.kpis)\n console.log('최종 KPI 배열 길이:', this.kpis.length)\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 async _saveStatistics() {\n try {\n const patches: any[] = []\n\n this.kpis.forEach(kpi => {\n // dirty 상태인 데이터만 처리\n if (kpi.statistics.isDirty) {\n const existingStatistic = this._findExistingStatistic(kpi.kpi.id)\n\n if (existingStatistic) {\n // 기존 데이터 업데이트\n const { isDirty, ...statisticsWithoutDirty } = kpi.statistics\n patches.push({\n id: existingStatistic.id,\n ...statisticsWithoutDirty,\n cuFlag: 'M'\n })\n } else {\n // 새로운 데이터 생성\n const { isDirty, ...statisticsWithoutDirty } = kpi.statistics\n patches.push({\n kpi: {\n id: kpi.kpi.id\n },\n valueDate: kpi.valueDate,\n periodType: kpi.periodType,\n ...statisticsWithoutDirty,\n additionalStatistics: {},\n metadata: {\n calculationMethod: 'manual',\n lastCalculated: new Date(),\n dataCount: kpi.statistics.count || 0\n },\n cuFlag: '+'\n })\n }\n }\n })\n\n if (patches.length === 0) {\n notify({ message: '저장할 데이터가 없습니다.' })\n return\n }\n\n const response = await client.mutate({\n mutation: gql`\n mutation ($patches: [KpiStatisticPatch!]!) {\n updateMultipleKpiStatistic(patches: $patches) {\n id\n kpi {\n id\n name\n }\n valueDate\n periodType\n }\n }\n `,\n variables: { patches }\n })\n\n if (!response.errors) {\n // 저장 후 dirty 상태 해제\n this.kpis.forEach(kpi => {\n kpi.statistics.isDirty = false\n })\n\n notify({ message: 'KPI 통계값이 성공적으로 저장되었습니다.' })\n this.requestUpdate()\n }\n } catch (error) {\n console.error('저장 중 오류:', error)\n notify({ message: '저장 중 오류가 발생했습니다.' })\n }\n }\n\n private _findExistingStatistic(kpiId: string) {\n return this._existingStatistics?.find((s: any) => s.kpi === kpiId)\n }\n\n private _onTargetDateChange(targetDate: string) {\n this.targetDate = targetDate\n this._calculateDateRange()\n }\n\n private _onPeriodChange(periodType: string) {\n this.periodType = periodType\n this._calculateDateRange()\n }\n\n private _calculateDateRange() {\n if (!this.targetDate || !this.periodType) return\n\n const target = new Date(this.targetDate)\n let valueDate: string\n\n switch (this.periodType) {\n case 'DAY':\n valueDate = target.toISOString().split('T')[0]\n break\n case 'WEEK':\n // 해당 주의 월요일\n const dayOfWeek = target.getDay()\n const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1\n const monday = new Date(target)\n monday.setDate(target.getDate() - daysToMonday)\n valueDate = monday.toISOString().split('T')[0]\n break\n case 'MONTH':\n valueDate = `${target.getFullYear()}-${String(target.getMonth() + 1).padStart(2, '0')}`\n break\n case 'QUARTER':\n const quarter = Math.floor(target.getMonth() / 3) + 1\n valueDate = `${target.getFullYear()}-Q${quarter}`\n break\n case 'YEAR':\n valueDate = target.getFullYear().toString()\n break\n default:\n valueDate = target.toISOString().split('T')[0]\n }\n\n this.valueDate = valueDate\n }\n\n private _cancel() {\n this.editingCell = null\n this._loadData() // 원본 데이터로 복원\n }\n\n async pageInitialized(lifecycle: any) {\n // 기본값 설정 - 현재 날짜를 기준으로\n if (!this.targetDate) {\n this.targetDate = new Date().toLocaleDateString('sv-SE')\n }\n\n // 기간 유형에 따라 날짜 범위 계산\n this._calculateDateRange()\n\n await this._loadData()\n }\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import '@material/web/icon/icon.js';
2
+ import '@operato/data-grist';
3
+ import { LitElement } from 'lit';
4
+ export declare class KpiStatisticImporter extends LitElement {
5
+ static styles: import("lit").CSSResult[];
6
+ kpiStatistics: any[];
7
+ columns: {
8
+ list: {
9
+ fields: string[];
10
+ };
11
+ pagination: {
12
+ infinite: boolean;
13
+ };
14
+ columns: {
15
+ type: string;
16
+ name: string;
17
+ header: string;
18
+ width: number;
19
+ }[];
20
+ };
21
+ render(): import("lit-html").TemplateResult<1>;
22
+ save(): Promise<void>;
23
+ }
@@ -0,0 +1,92 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import '@material/web/icon/icon.js';
3
+ import '@operato/data-grist';
4
+ import gql from 'graphql-tag';
5
+ import { css, html, LitElement } from 'lit';
6
+ import { property } from 'lit/decorators.js';
7
+ import { client } from '@operato/graphql';
8
+ import { i18next } from '@operato/i18n';
9
+ import { isMobileDevice } from '@operato/utils';
10
+ import { ButtonContainerStyles } from '@operato/styles';
11
+ export class KpiStatisticImporter extends LitElement {
12
+ constructor() {
13
+ super(...arguments);
14
+ this.kpiStatistics = [];
15
+ this.columns = {
16
+ list: { fields: ['name', 'description'] },
17
+ pagination: { infinite: true },
18
+ columns: [
19
+ {
20
+ type: 'string',
21
+ name: 'name',
22
+ header: i18next.t('field.name'),
23
+ width: 150
24
+ },
25
+ {
26
+ type: 'string',
27
+ name: 'description',
28
+ header: i18next.t('field.description'),
29
+ width: 200
30
+ },
31
+ {
32
+ type: 'checkbox',
33
+ name: 'active',
34
+ header: i18next.t('field.active'),
35
+ width: 60
36
+ }
37
+ ]
38
+ };
39
+ }
40
+ static { this.styles = [
41
+ ButtonContainerStyles,
42
+ css `
43
+ :host {
44
+ display: flex;
45
+ flex-direction: column;
46
+
47
+ background-color: #fff;
48
+ }
49
+
50
+ ox-grist {
51
+ flex: 1;
52
+ }
53
+ `
54
+ ]; }
55
+ render() {
56
+ return html `
57
+ <ox-grist
58
+ .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
59
+ .config=${this.columns}
60
+ .data=${{
61
+ records: this.kpiStatistics
62
+ }}
63
+ ></ox-grist>
64
+
65
+ <div class="button-container">
66
+ <button @click="${this.save.bind(this)}"><md-icon>save</md-icon>${i18next.t('button.save')}</button>
67
+ </div>
68
+ `;
69
+ }
70
+ async save() {
71
+ const response = await client.mutate({
72
+ mutation: gql `
73
+ mutation importKpiStatistics($kpiStatistics: [KpiStatisticPatch!]!) {
74
+ importKpiStatistics(kpiStatistics: $kpiStatistics)
75
+ }
76
+ `,
77
+ variables: { kpiStatistics: this.kpiStatistics }
78
+ });
79
+ if (response.errors?.length)
80
+ return;
81
+ this.dispatchEvent(new CustomEvent('imported'));
82
+ }
83
+ }
84
+ __decorate([
85
+ property({ type: Array }),
86
+ __metadata("design:type", Array)
87
+ ], KpiStatisticImporter.prototype, "kpiStatistics", void 0);
88
+ __decorate([
89
+ property({ type: Object }),
90
+ __metadata("design:type", Object)
91
+ ], KpiStatisticImporter.prototype, "columns", void 0);
92
+ //# sourceMappingURL=kpi-statistic-importer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-statistic-importer.js","sourceRoot":"","sources":["../../../client/pages/kpi-statistic/kpi-statistic-importer.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,qBAAqB,CAAA;AAE5B,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE5C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAEvD,MAAM,OAAO,oBAAqB,SAAQ,UAAU;IAApD;;QAiB6B,kBAAa,GAAU,EAAE,CAAA;QACxB,YAAO,GAAG;YACpC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE;YACzC,UAAU,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC9B,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,MAAM;oBACZ,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC;oBAC/B,KAAK,EAAE,GAAG;iBACX;gBACD;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,aAAa;oBACnB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;oBACtC,KAAK,EAAE,GAAG;iBACX;gBACD;oBACE,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;oBACjC,KAAK,EAAE,EAAE;iBACV;aACF;SACF,CAAA;IAmCH,CAAC;aA3EQ,WAAM,GAAG;QACd,qBAAqB;QACrB,GAAG,CAAA;;;;;;;;;;;KAWF;KACF,AAdY,CAcZ;IA6BD,MAAM;QACJ,OAAO,IAAI,CAAA;;gBAEC,cAAc,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;kBAChC,IAAI,CAAC,OAAO;gBAEpB;YACE,OAAO,EAAE,IAAI,CAAC,aAAa;SAE/B;;;;0BAIkB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,4BAA4B,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;;KAE7F,CAAA;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;YACnC,QAAQ,EAAE,GAAG,CAAA;;;;OAIZ;YACD,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE;SACjD,CAAC,CAAA;QAEF,IAAI,QAAQ,CAAC,MAAM,EAAE,MAAM;YAAE,OAAM;QAEnC,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,UAAU,CAAC,CAAC,CAAA;IACjD,CAAC;;AA1D0B;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;2DAA0B;AACxB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;qDAuB1B","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/data-grist'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { isMobileDevice } from '@operato/utils'\nimport { ButtonContainerStyles } from '@operato/styles'\n\nexport class KpiStatisticImporter extends LitElement {\n static styles = [\n ButtonContainerStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n background-color: #fff;\n }\n\n ox-grist {\n flex: 1;\n }\n `\n ]\n\n @property({ type: Array }) kpiStatistics: any[] = []\n @property({ type: Object }) columns = {\n list: { fields: ['name', 'description'] },\n pagination: { infinite: true },\n columns: [\n {\n type: 'string',\n name: 'name',\n header: i18next.t('field.name'),\n width: 150\n },\n {\n type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n width: 200\n },\n {\n type: 'checkbox',\n name: 'active',\n header: i18next.t('field.active'),\n width: 60\n }\n ]\n }\n\n\n render() {\n return html`\n <ox-grist\n .mode=${isMobileDevice() ? 'LIST' : 'GRID'}\n .config=${this.columns}\n .data=${\n { \n records: this.kpiStatistics \n }\n }\n ></ox-grist>\n\n <div class=\"button-container\">\n <button @click=\"${this.save.bind(this)}\"><md-icon>save</md-icon>${i18next.t('button.save')}</button>\n </div>\n `\n }\n\n async save() {\n const response = await client.mutate({\n mutation: gql`\n mutation importKpiStatistics($kpiStatistics: [KpiStatisticPatch!]!) {\n importKpiStatistics(kpiStatistics: $kpiStatistics)\n }\n `,\n variables: { kpiStatistics: this.kpiStatistics }\n })\n\n if (response.errors?.length) return\n\n this.dispatchEvent(new CustomEvent('imported'))\n }\n}\n\n"]}
@@ -0,0 +1,66 @@
1
+ import '@material/web/icon/icon.js';
2
+ import '@material/web/button/elevated-button.js';
3
+ import '@operato/data-grist/ox-grist.js';
4
+ import '@operato/data-grist/ox-filters-form.js';
5
+ import '@operato/data-grist/ox-record-creator.js';
6
+ import { PageView } from '@operato/shell';
7
+ import { FetchOption } from '@operato/data-grist';
8
+ import { KpiStatisticImporter } from './kpi-statistic-importer.js';
9
+ declare const KpiStatisticListPage_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[]) => import("lit").LitElement) & typeof PageView & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types/src/types.js").ScopedElementsHost>;
16
+ export declare class KpiStatisticListPage extends KpiStatisticListPage_base {
17
+ static styles: import("lit").CSSResult[];
18
+ static get scopedElements(): {
19
+ 'kpi-statistic-importer': typeof KpiStatisticImporter;
20
+ };
21
+ gristConfig: any;
22
+ mode: 'CARD' | 'GRID' | 'LIST';
23
+ private grist;
24
+ get context(): {
25
+ title: string;
26
+ search: {
27
+ handler: (search: string) => void;
28
+ value: string;
29
+ };
30
+ filter: {
31
+ handler: () => void;
32
+ };
33
+ help: string;
34
+ actions: {
35
+ icon: string;
36
+ emphasis: {
37
+ raised: boolean;
38
+ outlined: boolean;
39
+ dense: boolean;
40
+ danger: boolean;
41
+ };
42
+ title: string;
43
+ action: () => Promise<void>;
44
+ }[];
45
+ exportable: {
46
+ name: string;
47
+ data: () => Promise<{}[]>;
48
+ };
49
+ importable: {
50
+ handler: (records: any) => Promise<void>;
51
+ };
52
+ };
53
+ render(): import("lit-html").TemplateResult<1>;
54
+ pageInitialized(lifecycle: any): Promise<void>;
55
+ pageUpdated(changes: any, lifecycle: any): Promise<void>;
56
+ fetchHandler({ page, limit, sortings, filters }: FetchOption): Promise<{
57
+ total: any;
58
+ records: any;
59
+ }>;
60
+ _deleteKpiStatistic(): Promise<void>;
61
+ _updateKpiStatistic(): Promise<void>;
62
+ creationCallback(kpiStatistic: any): Promise<boolean>;
63
+ exportHandler(): Promise<{}[]>;
64
+ importHandler(records: any): Promise<void>;
65
+ }
66
+ export {};