@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.
- package/client/pages/kpi/kpi-list-page.ts +339 -525
- package/client/pages/kpi/kpi-tree-page.ts +135 -207
- package/client/pages/kpi-metric/kpi-metric-list-page.ts +146 -226
- package/client/pages/kpi-metric-value/kpi-metric-value-editor-page.ts +187 -295
- package/client/pages/kpi-metric-value/kpi-metric-value-list-page.ts +123 -194
- package/client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.ts +57 -91
- package/client/pages/kpi-statistic/kpi-statistic-editor-page.ts +180 -278
- package/client/pages/kpi-statistic/kpi-statistic-list-page.ts +186 -286
- package/client/pages/kpi-value/kpi-value-editor-page.ts +189 -292
- package/client/pages/kpi-value/kpi-value-list-page.ts +170 -264
- package/dist-client/pages/kpi/kpi-list-page.d.ts +0 -6
- package/dist-client/pages/kpi/kpi-list-page.js +150 -282
- package/dist-client/pages/kpi/kpi-list-page.js.map +1 -1
- package/dist-client/pages/kpi/kpi-tree-page.d.ts +1 -7
- package/dist-client/pages/kpi/kpi-tree-page.js +76 -127
- package/dist-client/pages/kpi/kpi-tree-page.js.map +1 -1
- package/dist-client/pages/kpi-metric/kpi-metric-list-page.d.ts +0 -6
- package/dist-client/pages/kpi-metric/kpi-metric-list-page.js +62 -116
- package/dist-client/pages/kpi-metric/kpi-metric-list-page.js.map +1 -1
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.d.ts +1 -7
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js +82 -140
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js.map +1 -1
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +0 -6
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +54 -98
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -1
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.d.ts +1 -7
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js +30 -57
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js.map +1 -1
- package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.d.ts +1 -7
- package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js +91 -153
- package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js.map +1 -1
- package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.d.ts +0 -6
- package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js +81 -155
- package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js.map +1 -1
- package/dist-client/pages/kpi-value/kpi-value-editor-page.d.ts +1 -7
- package/dist-client/pages/kpi-value/kpi-value-editor-page.js +80 -136
- package/dist-client/pages/kpi-value/kpi-value-editor-page.js.map +1 -1
- package/dist-client/pages/kpi-value/kpi-value-list-page.d.ts +0 -6
- package/dist-client/pages/kpi-value/kpi-value-list-page.js +73 -134
- package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/service/index.d.ts +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +18 -18
- package/client/tsconfig.json +0 -11
- package/dist-server/tsconfig.json +0 -10
- package/server/@types/index.d.ts +0 -11
- package/server/calculator/evaluator.ts +0 -45
- package/server/calculator/functions.ts +0 -67
- package/server/calculator/index.ts +0 -4
- package/server/calculator/parser.ts +0 -137
- package/server/calculator/provider.ts +0 -10
- package/server/controllers/index.ts +0 -2
- package/server/controllers/kpi-metric-value-provider.ts +0 -79
- package/server/controllers/kpi-value-provider.ts +0 -51
- package/server/index.ts +0 -6
- package/server/migrations/1752190849680-seed-kpi-metrics.ts +0 -124
- package/server/migrations/1752190849681-seed-kpi.ts +0 -356
- package/server/migrations/1752192090123-add-grades-to-kpi.ts +0 -67
- package/server/migrations/1752192090124-add-kpi-statistics.ts +0 -719
- package/server/migrations/1752192090128-seed-kpi-org-scope.ts +0 -132
- package/server/migrations/1752192090129-seed-kpi-values.ts +0 -207
- package/server/migrations/grade-data/x11-performance-table.json +0 -962
- package/server/migrations/grade-data/x12-performance-table.json +0 -611
- package/server/migrations/grade-data/x14-performance-table.json +0 -42
- package/server/migrations/grade-data/x21-performance-table.json +0 -889
- package/server/migrations/grade-data/x22-performance-table.json +0 -1064
- package/server/migrations/grade-data/x23-performance-table.json +0 -42
- package/server/migrations/grade-data/x31-performance-table.json +0 -644
- package/server/migrations/grade-data/x32-performance-table.json +0 -993
- package/server/migrations/grade-data/x33-performance-table.json +0 -195
- package/server/migrations/grade-data/x34-performance-table.json +0 -12
- package/server/migrations/grade-data/x35-performance-table.json +0 -42
- package/server/migrations/grade-data/x41-performance-table.json +0 -825
- package/server/migrations/grade-data/x42-performance-table.json +0 -786
- package/server/migrations/grade-data/x43-performance-table.json +0 -12
- package/server/migrations/grade-data/x44-performance-table.json +0 -42
- package/server/migrations/grade-data/x51-performance-table.json +0 -924
- package/server/migrations/grade-data/x52-performance-table.json +0 -42
- package/server/migrations/grade-data/x61-performance-table.json +0 -261
- package/server/migrations/grade-data/x62-performance-table.json +0 -42
- package/server/migrations/index.ts +0 -9
- package/server/migrations/seed-data/kpi-metrics-seed.json +0 -454
- package/server/migrations/seed-data/kpi-org-scope-seed.json +0 -1676
- package/server/migrations/seed-data/kpi-scopes-seed.json +0 -121
- package/server/migrations/seed-data/kpi-values-seed.json +0 -402
- package/server/migrations/seed-data/kpis-seed.json +0 -488
- package/server/migrations/seed-data/scope-definitions-seed.json +0 -90
- package/server/routes.ts +0 -81
- package/server/service/index.ts +0 -51
- package/server/service/kpi/aggregate-kpi.ts +0 -103
- package/server/service/kpi/event-subscriber.ts +0 -29
- package/server/service/kpi/index.ts +0 -9
- package/server/service/kpi/kpi-formula.service.ts +0 -164
- package/server/service/kpi/kpi-grade.types.ts +0 -28
- package/server/service/kpi/kpi-history.ts +0 -126
- package/server/service/kpi/kpi-mutation.ts +0 -553
- package/server/service/kpi/kpi-query.ts +0 -224
- package/server/service/kpi/kpi-type.ts +0 -151
- package/server/service/kpi/kpi.ts +0 -254
- package/server/service/kpi-alert/index.ts +0 -3
- package/server/service/kpi-alert/kpi-alert-query.ts +0 -59
- package/server/service/kpi-alert/kpi-alert-type.ts +0 -20
- package/server/service/kpi-metric/aggregate-kpi-metric.ts +0 -132
- package/server/service/kpi-metric/index.ts +0 -7
- package/server/service/kpi-metric/kpi-metric-mutation.ts +0 -309
- package/server/service/kpi-metric/kpi-metric-query.ts +0 -70
- package/server/service/kpi-metric/kpi-metric-type.ts +0 -111
- package/server/service/kpi-metric/kpi-metric.ts +0 -134
- package/server/service/kpi-metric-value/index.ts +0 -7
- package/server/service/kpi-metric-value/kpi-metric-value-mutation.ts +0 -270
- package/server/service/kpi-metric-value/kpi-metric-value-query.ts +0 -62
- package/server/service/kpi-metric-value/kpi-metric-value-type.ts +0 -82
- package/server/service/kpi-metric-value/kpi-metric-value.ts +0 -93
- package/server/service/kpi-org-scope/index.ts +0 -6
- package/server/service/kpi-org-scope/kpi-org-scope-mutation.ts +0 -173
- package/server/service/kpi-org-scope/kpi-org-scope-query.ts +0 -127
- package/server/service/kpi-org-scope/kpi-org-scope-type.ts +0 -68
- package/server/service/kpi-org-scope/kpi-org-scope.ts +0 -123
- package/server/service/kpi-scope/index.ts +0 -11
- package/server/service/kpi-scope/kpi-scope-mutation.ts +0 -129
- package/server/service/kpi-scope/kpi-scope-query.ts +0 -63
- package/server/service/kpi-scope/kpi-scope-type.ts +0 -96
- package/server/service/kpi-scope/kpi-scope.ts +0 -143
- package/server/service/kpi-statistic/index.ts +0 -7
- package/server/service/kpi-statistic/kpi-statistic-batch.service.ts +0 -231
- package/server/service/kpi-statistic/kpi-statistic-calculation.service.ts +0 -410
- package/server/service/kpi-statistic/kpi-statistic-mutation.ts +0 -291
- package/server/service/kpi-statistic/kpi-statistic-query.ts +0 -146
- package/server/service/kpi-statistic/kpi-statistic-type.ts +0 -152
- package/server/service/kpi-statistic/kpi-statistic.ts +0 -199
- package/server/service/kpi-value/index.ts +0 -7
- package/server/service/kpi-value/kpi-value-mutation.ts +0 -432
- package/server/service/kpi-value/kpi-value-query.ts +0 -61
- package/server/service/kpi-value/kpi-value-score.service.ts +0 -106
- package/server/service/kpi-value/kpi-value-type.ts +0 -122
- package/server/service/kpi-value/kpi-value.ts +0 -160
- package/server/service/utils/value-date-util.ts +0 -119
- package/server/tsconfig.json +0 -10
- package/server/types/global.d.ts +0 -8
|
@@ -3,16 +3,15 @@ import '@material/web/icon/icon.js';
|
|
|
3
3
|
import '@material/web/button/elevated-button.js';
|
|
4
4
|
import '@material/web/textfield/outlined-text-field.js';
|
|
5
5
|
import { CommonButtonStyles, CommonHeaderStyles, ScrollbarStyles } from '@operato/styles';
|
|
6
|
-
import { PageView
|
|
6
|
+
import { PageView } from '@operato/shell';
|
|
7
7
|
import { css, html } from 'lit';
|
|
8
8
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
9
9
|
import { ScopedElementsMixin } from '@open-wc/scoped-elements';
|
|
10
10
|
import { client } from '@operato/graphql';
|
|
11
11
|
import { i18next, localize } from '@operato/i18n';
|
|
12
12
|
import { notify } from '@operato/layout';
|
|
13
|
-
import { connect } from 'pwa-helpers/connect-mixin';
|
|
14
13
|
import gql from 'graphql-tag';
|
|
15
|
-
let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends
|
|
14
|
+
let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends localize(i18next)(ScopedElementsMixin(PageView)) {
|
|
16
15
|
constructor() {
|
|
17
16
|
super(...arguments);
|
|
18
17
|
this.org = '';
|
|
@@ -29,84 +28,73 @@ let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends connect(st
|
|
|
29
28
|
CommonHeaderStyles,
|
|
30
29
|
ScrollbarStyles,
|
|
31
30
|
css `
|
|
32
|
-
:host {
|
|
33
|
-
display: flex;
|
|
31
|
+
:host { display: flex;
|
|
34
32
|
flex-direction: column;
|
|
35
33
|
padding: 20px;
|
|
36
34
|
overflow-x: auto;
|
|
37
|
-
|
|
35
|
+
}
|
|
38
36
|
|
|
39
|
-
.header {
|
|
40
|
-
display: flex;
|
|
37
|
+
.header { display: flex;
|
|
41
38
|
gap: 16px;
|
|
42
39
|
align-items: center;
|
|
43
40
|
margin-bottom: 20px;
|
|
44
41
|
padding: 16px;
|
|
45
42
|
background: var(--md-sys-color-surface-container);
|
|
46
43
|
border-radius: 8px;
|
|
47
|
-
|
|
44
|
+
}
|
|
48
45
|
|
|
49
|
-
.controls {
|
|
50
|
-
display: flex;
|
|
46
|
+
.controls { display: flex;
|
|
51
47
|
gap: 12px;
|
|
52
48
|
align-items: center;
|
|
53
|
-
|
|
49
|
+
}
|
|
54
50
|
|
|
55
|
-
.table-container {
|
|
56
|
-
flex: 1;
|
|
51
|
+
.table-container { flex: 1;
|
|
57
52
|
overflow: auto;
|
|
58
53
|
border: 1px solid var(--md-sys-color-outline);
|
|
59
54
|
border-radius: 8px;
|
|
60
|
-
|
|
55
|
+
}
|
|
61
56
|
|
|
62
|
-
table {
|
|
63
|
-
width: 100%;
|
|
57
|
+
table { width: 100%;
|
|
64
58
|
border-collapse: collapse;
|
|
65
59
|
min-width: max-content;
|
|
66
|
-
|
|
60
|
+
}
|
|
67
61
|
|
|
68
|
-
th {
|
|
69
|
-
background: var(--md-sys-color-surface-container-low);
|
|
62
|
+
th { background: var(--md-sys-color-surface-container-low);
|
|
70
63
|
font-weight: 500;
|
|
71
64
|
padding: 8px 12px;
|
|
72
65
|
border: 1px solid var(--md-sys-color-outline-variant);
|
|
73
66
|
min-width: 80px;
|
|
74
67
|
height: 120px;
|
|
75
68
|
vertical-align: middle;
|
|
76
|
-
|
|
69
|
+
}
|
|
77
70
|
|
|
78
|
-
td {
|
|
79
|
-
padding: 8px 12px;
|
|
71
|
+
td { padding: 8px 12px;
|
|
80
72
|
border: 1px solid var(--md-sys-color-outline-variant);
|
|
81
73
|
min-width: 80px;
|
|
82
74
|
height: 60px;
|
|
83
75
|
text-align: right;
|
|
84
76
|
vertical-align: middle;
|
|
85
|
-
|
|
77
|
+
}
|
|
86
78
|
|
|
87
|
-
.metric-header {
|
|
88
|
-
position: sticky;
|
|
79
|
+
.metric-header { position: sticky;
|
|
89
80
|
left: 0;
|
|
90
81
|
top: 0;
|
|
91
82
|
z-index: 3;
|
|
92
|
-
|
|
83
|
+
}
|
|
93
84
|
|
|
94
|
-
.metric-name {
|
|
95
|
-
position: sticky;
|
|
85
|
+
.metric-name { position: sticky;
|
|
96
86
|
left: 0;
|
|
97
87
|
background: var(--md-sys-color-surface);
|
|
98
88
|
font-weight: 500;
|
|
99
89
|
min-width: 200px;
|
|
100
90
|
text-align: left;
|
|
101
91
|
z-index: 2;
|
|
102
|
-
|
|
92
|
+
}
|
|
103
93
|
|
|
104
|
-
tr:hover {
|
|
105
|
-
|
|
106
|
-
}
|
|
94
|
+
tr:hover { background: var(--md-sys-color-surface-container-high);
|
|
95
|
+
}
|
|
107
96
|
|
|
108
|
-
th.date-header {
|
|
109
|
-
position: sticky;
|
|
97
|
+
th.date-header { position: sticky;
|
|
110
98
|
top: 0;
|
|
111
99
|
z-index: 2;
|
|
112
100
|
text-align: center;
|
|
@@ -118,103 +106,87 @@ let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends connect(st
|
|
|
118
106
|
display: flex;
|
|
119
107
|
align-items: center;
|
|
120
108
|
justify-content: center;
|
|
121
|
-
|
|
109
|
+
}
|
|
122
110
|
|
|
123
|
-
td.editable-cell {
|
|
124
|
-
cursor: pointer;
|
|
111
|
+
td.editable-cell { cursor: pointer;
|
|
125
112
|
background: var(--md-sys-color-primary-container);
|
|
126
113
|
color: var(--md-sys-color-on-primary-container);
|
|
127
|
-
|
|
114
|
+
}
|
|
128
115
|
|
|
129
|
-
td.editable-cell:hover {
|
|
130
|
-
|
|
131
|
-
}
|
|
116
|
+
td.editable-cell:hover { background: var(--md-sys-color-primary-container-high);
|
|
117
|
+
}
|
|
132
118
|
|
|
133
|
-
td.highlighted-cell {
|
|
134
|
-
background: var(--md-sys-color-secondary-container);
|
|
119
|
+
td.highlighted-cell { background: var(--md-sys-color-secondary-container);
|
|
135
120
|
color: var(--md-sys-color-on-secondary-container);
|
|
136
121
|
font-weight: 500;
|
|
137
|
-
|
|
122
|
+
}
|
|
138
123
|
|
|
139
|
-
td.highlighted-cell:hover {
|
|
140
|
-
|
|
141
|
-
}
|
|
124
|
+
td.highlighted-cell:hover { background: var(--md-sys-color-secondary-container-high);
|
|
125
|
+
}
|
|
142
126
|
|
|
143
|
-
td.disabled-cell {
|
|
144
|
-
background: var(--md-sys-color-surface-container);
|
|
127
|
+
td.disabled-cell { background: var(--md-sys-color-surface-container);
|
|
145
128
|
color: var(--md-sys-color-on-surface-variant);
|
|
146
129
|
cursor: not-allowed;
|
|
147
|
-
|
|
130
|
+
}
|
|
148
131
|
|
|
149
|
-
.value-input {
|
|
150
|
-
width: 100%;
|
|
132
|
+
.value-input { width: 100%;
|
|
151
133
|
text-align: center;
|
|
152
134
|
border: none;
|
|
153
135
|
background: transparent;
|
|
154
136
|
color: inherit;
|
|
155
137
|
font-size: 12px;
|
|
156
138
|
padding: 2px;
|
|
157
|
-
|
|
139
|
+
}
|
|
158
140
|
|
|
159
|
-
.value-input:focus {
|
|
160
|
-
outline: 2px solid var(--md-sys-color-primary);
|
|
141
|
+
.value-input:focus { outline: 2px solid var(--md-sys-color-primary);
|
|
161
142
|
border-radius: 4px;
|
|
162
|
-
|
|
143
|
+
}
|
|
163
144
|
|
|
164
|
-
.period-type-badge {
|
|
165
|
-
font-size: 10px;
|
|
145
|
+
.period-type-badge { font-size: 10px;
|
|
166
146
|
padding: 2px 6px;
|
|
167
147
|
border-radius: 4px;
|
|
168
148
|
background: var(--md-sys-color-tertiary-container);
|
|
169
149
|
color: var(--md-sys-color-on-tertiary-container);
|
|
170
150
|
margin-left: 8px;
|
|
171
|
-
|
|
151
|
+
}
|
|
172
152
|
|
|
173
|
-
.loading {
|
|
174
|
-
display: flex;
|
|
153
|
+
.loading { display: flex;
|
|
175
154
|
justify-content: center;
|
|
176
155
|
align-items: center;
|
|
177
156
|
height: 200px;
|
|
178
157
|
color: var(--md-sys-color-on-surface-variant);
|
|
179
|
-
|
|
158
|
+
}
|
|
180
159
|
|
|
181
|
-
.error {
|
|
182
|
-
color: var(--md-sys-color-error);
|
|
160
|
+
.error { color: var(--md-sys-color-error);
|
|
183
161
|
padding: 16px;
|
|
184
162
|
text-align: center;
|
|
185
|
-
|
|
163
|
+
}
|
|
186
164
|
|
|
187
|
-
.legend {
|
|
188
|
-
display: flex;
|
|
165
|
+
.legend { display: flex;
|
|
189
166
|
gap: 16px;
|
|
190
167
|
margin-top: 16px;
|
|
191
168
|
font-size: 12px;
|
|
192
|
-
|
|
169
|
+
}
|
|
193
170
|
|
|
194
|
-
.legend-item {
|
|
195
|
-
display: flex;
|
|
171
|
+
.legend-item { display: flex;
|
|
196
172
|
align-items: center;
|
|
197
173
|
gap: 4px;
|
|
198
|
-
|
|
174
|
+
}
|
|
199
175
|
|
|
200
|
-
.legend-color {
|
|
201
|
-
width: 16px;
|
|
176
|
+
.legend-color { width: 16px;
|
|
202
177
|
height: 16px;
|
|
203
178
|
border-radius: 2px;
|
|
204
|
-
|
|
179
|
+
}
|
|
205
180
|
`
|
|
206
181
|
]; }
|
|
207
182
|
get context() {
|
|
208
|
-
return {
|
|
209
|
-
title: i18next.t('title.kpi metric value editor'),
|
|
183
|
+
return { title: i18next.t('title.kpi metric value editor'),
|
|
210
184
|
actions: [
|
|
211
|
-
{
|
|
212
|
-
title: i18next.t('button.save'),
|
|
185
|
+
{ title: i18next.t('button.save'),
|
|
213
186
|
action: this._saveValues.bind(this),
|
|
214
187
|
...CommonButtonStyles.save
|
|
215
188
|
},
|
|
216
|
-
{
|
|
217
|
-
title: i18next.t('button.cancel'),
|
|
189
|
+
{ title: i18next.t('button.cancel'),
|
|
218
190
|
action: this._cancel.bind(this),
|
|
219
191
|
...CommonButtonStyles.cancel
|
|
220
192
|
}
|
|
@@ -337,32 +309,26 @@ let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends connect(st
|
|
|
337
309
|
const isEditing = this.editingCell?.metricId === metric.metricId && this.editingCell?.date === date;
|
|
338
310
|
// periodType에 따라 값을 가져오는 방식 결정
|
|
339
311
|
let value = null;
|
|
340
|
-
if (metric.periodType === 'DAY') {
|
|
341
|
-
// DAY인 경우 해당 날짜의 값을 사용
|
|
312
|
+
if (metric.periodType === 'DAY') { // DAY인 경우 해당 날짜의 값을 사용
|
|
342
313
|
value = metric.values[date]?.value;
|
|
343
314
|
}
|
|
344
|
-
else if (metric.periodType === 'WEEK') {
|
|
345
|
-
// WEEK인 경우 해당 주의 월요일의 값을 사용
|
|
315
|
+
else if (metric.periodType === 'WEEK') { // WEEK인 경우 해당 주의 월요일의 값을 사용
|
|
346
316
|
const weekKey = this._getWeekKey(date);
|
|
347
317
|
value = metric.values[weekKey]?.value;
|
|
348
318
|
}
|
|
349
|
-
else if (metric.periodType === 'MONTH') {
|
|
350
|
-
// MONTH인 경우 해당 월의 값을 사용
|
|
319
|
+
else if (metric.periodType === 'MONTH') { // MONTH인 경우 해당 월의 값을 사용
|
|
351
320
|
const monthKey = this._getMonthKey(date);
|
|
352
321
|
value = metric.values[monthKey]?.value;
|
|
353
322
|
}
|
|
354
|
-
else if (metric.periodType === 'QUARTER') {
|
|
355
|
-
// QUARTER인 경우 해당 분기의 값을 사용
|
|
323
|
+
else if (metric.periodType === 'QUARTER') { // QUARTER인 경우 해당 분기의 값을 사용
|
|
356
324
|
const quarterKey = this._getQuarterKey(date);
|
|
357
325
|
value = metric.values[quarterKey]?.value;
|
|
358
326
|
}
|
|
359
|
-
else if (metric.periodType === 'YEAR') {
|
|
360
|
-
// YEAR인 경우 해당 연도의 값을 사용
|
|
327
|
+
else if (metric.periodType === 'YEAR') { // YEAR인 경우 해당 연도의 값을 사용
|
|
361
328
|
const yearKey = this._getYearKey(date);
|
|
362
329
|
value = metric.values[yearKey]?.value;
|
|
363
330
|
}
|
|
364
|
-
else {
|
|
365
|
-
// 기본값: DAY와 동일
|
|
331
|
+
else { // 기본값: DAY와 동일
|
|
366
332
|
value = metric.values[date]?.value;
|
|
367
333
|
}
|
|
368
334
|
if (isEditing) {
|
|
@@ -396,8 +362,7 @@ let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends connect(st
|
|
|
396
362
|
}
|
|
397
363
|
_finishEdit(metricId, date, value) {
|
|
398
364
|
const metric = this.metrics.find(m => m.metricId === metricId);
|
|
399
|
-
if (metric) {
|
|
400
|
-
// periodType에 따라 저장할 키 결정
|
|
365
|
+
if (metric) { // periodType에 따라 저장할 키 결정
|
|
401
366
|
let storageKey = date;
|
|
402
367
|
if (metric.periodType === 'WEEK') {
|
|
403
368
|
storageKey = this._getWeekKey(date);
|
|
@@ -429,44 +394,33 @@ let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends connect(st
|
|
|
429
394
|
}
|
|
430
395
|
this.loading = true;
|
|
431
396
|
this.error = '';
|
|
432
|
-
try {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
query: gql `
|
|
436
|
-
query ($filters: [Filter!]) {
|
|
437
|
-
kpiMetrics(filters: $filters) {
|
|
438
|
-
items {
|
|
439
|
-
id
|
|
397
|
+
try { // KPI Metric 목록 조회
|
|
398
|
+
const metricsResponse = await client.query({ query: gql `
|
|
399
|
+
query ($filters: [Filter!]) { kpiMetrics(filters: $filters) { items { id
|
|
440
400
|
name
|
|
441
401
|
periodType
|
|
442
402
|
active
|
|
443
|
-
|
|
403
|
+
}
|
|
444
404
|
total
|
|
445
|
-
|
|
446
|
-
|
|
405
|
+
}
|
|
406
|
+
}
|
|
447
407
|
`,
|
|
448
|
-
variables: {
|
|
449
|
-
filters: [{ name: 'active', operator: 'eq', value: true }]
|
|
408
|
+
variables: { filters: [{ name: 'active', operator: 'eq', value: true }]
|
|
450
409
|
}
|
|
451
410
|
});
|
|
452
411
|
// KPI Metric Value 데이터 조회
|
|
453
|
-
const valuesResponse = await client.query({
|
|
454
|
-
|
|
455
|
-
query ($filters: [Filter!]) {
|
|
456
|
-
kpiMetricValues(filters: $filters) {
|
|
457
|
-
items {
|
|
458
|
-
id
|
|
412
|
+
const valuesResponse = await client.query({ query: gql `
|
|
413
|
+
query ($filters: [Filter!]) { kpiMetricValues(filters: $filters) { items { id
|
|
459
414
|
metricId
|
|
460
415
|
valueDate
|
|
461
416
|
value
|
|
462
417
|
org
|
|
463
|
-
|
|
418
|
+
}
|
|
464
419
|
total
|
|
465
|
-
|
|
466
|
-
|
|
420
|
+
}
|
|
421
|
+
}
|
|
467
422
|
`,
|
|
468
|
-
variables: {
|
|
469
|
-
filters: [
|
|
423
|
+
variables: { filters: [
|
|
470
424
|
...(this.org ? [{ name: 'org', operator: 'eq', value: this.org }] : []),
|
|
471
425
|
{ name: 'valueDate', operator: 'between', value: [this.startDate, this.endDate] }
|
|
472
426
|
]
|
|
@@ -475,8 +429,7 @@ let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends connect(st
|
|
|
475
429
|
// 날짜 배열 생성
|
|
476
430
|
this.dates = this._generateDateArray(this.startDate, this.endDate);
|
|
477
431
|
// KPI Metric 목록을 기준으로 데이터 구성
|
|
478
|
-
this.metrics = metricsResponse.data.kpiMetrics.items.map((metric) => ({
|
|
479
|
-
metricId: metric.id,
|
|
432
|
+
this.metrics = metricsResponse.data.kpiMetrics.items.map((metric) => ({ metricId: metric.id,
|
|
480
433
|
metricName: metric.name,
|
|
481
434
|
periodType: metric.periodType,
|
|
482
435
|
values: {}
|
|
@@ -487,8 +440,7 @@ let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends connect(st
|
|
|
487
440
|
valuesResponse.data.kpiMetricValues.items.forEach((value) => {
|
|
488
441
|
const metric = this.metrics.find(m => m.metricId === value.metricId);
|
|
489
442
|
if (metric) {
|
|
490
|
-
metric.values[value.valueDate] = {
|
|
491
|
-
value: value.value,
|
|
443
|
+
metric.values[value.valueDate] = { value: value.value,
|
|
492
444
|
isDirty: false
|
|
493
445
|
};
|
|
494
446
|
}
|
|
@@ -526,12 +478,10 @@ let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends connect(st
|
|
|
526
478
|
const patches = [];
|
|
527
479
|
this.metrics.forEach(metric => {
|
|
528
480
|
Object.entries(metric.values).forEach(([date, data]) => {
|
|
529
|
-
// dirty 상태인 데이터만 처리
|
|
530
481
|
if (data.isDirty && data.value !== null && data.value !== undefined) {
|
|
531
482
|
const existingValue = this._findExistingValue(metric.metricId, date);
|
|
532
483
|
if (existingValue) {
|
|
533
|
-
patches.push({
|
|
534
|
-
id: existingValue.id,
|
|
484
|
+
patches.push({ id: existingValue.id,
|
|
535
485
|
value: data.value,
|
|
536
486
|
org: this.org,
|
|
537
487
|
cuFlag: 'M'
|
|
@@ -541,8 +491,7 @@ let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends connect(st
|
|
|
541
491
|
console.log('Creating new value for metric:', metric.metricName, 'periodType:', metric.periodType, 'date:', date);
|
|
542
492
|
const normalizedDate = this._normalizeDateByPeriodType(date, metric.periodType);
|
|
543
493
|
console.log('Normalized date:', normalizedDate);
|
|
544
|
-
patches.push({
|
|
545
|
-
metricId: metric.metricId,
|
|
494
|
+
patches.push({ metricId: metric.metricId,
|
|
546
495
|
valueDate: normalizedDate,
|
|
547
496
|
value: data.value,
|
|
548
497
|
org: this.org,
|
|
@@ -559,21 +508,17 @@ let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends connect(st
|
|
|
559
508
|
// 디버깅: patches 내용 확인
|
|
560
509
|
console.log('Sending patches:', patches);
|
|
561
510
|
// 단일 mutation으로 생성과 업데이트 처리
|
|
562
|
-
const response = await client.mutate({
|
|
563
|
-
|
|
564
|
-
mutation ($patches: [KpiMetricValuePatch!]!) {
|
|
565
|
-
updateMultipleKpiMetricValue(patches: $patches) {
|
|
566
|
-
id
|
|
511
|
+
const response = await client.mutate({ mutation: gql `
|
|
512
|
+
mutation ($patches: [KpiMetricValuePatch!]!) { updateMultipleKpiMetricValue(patches: $patches) { id
|
|
567
513
|
value
|
|
568
514
|
valueDate
|
|
569
515
|
metricId
|
|
570
|
-
|
|
571
|
-
|
|
516
|
+
}
|
|
517
|
+
}
|
|
572
518
|
`,
|
|
573
519
|
variables: { patches }
|
|
574
520
|
});
|
|
575
|
-
if (!response.errors) {
|
|
576
|
-
// 저장 후 dirty 상태 해제
|
|
521
|
+
if (!response.errors) { // 저장 후 dirty 상태 해제
|
|
577
522
|
response.data.updateMultipleKpiMetricValue.forEach((savedValue) => {
|
|
578
523
|
const metric = this.metrics.find(m => m.metricId === savedValue.metricId);
|
|
579
524
|
if (metric && metric.values[savedValue.valueDate]) {
|
|
@@ -590,7 +535,6 @@ let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends connect(st
|
|
|
590
535
|
}
|
|
591
536
|
}
|
|
592
537
|
_findExistingValue(metricId, date) {
|
|
593
|
-
// 기존 로드된 KPI Metric Value 데이터에서 찾기
|
|
594
538
|
return this._existingValues?.find((v) => v.metricId === metricId && v.valueDate === date);
|
|
595
539
|
}
|
|
596
540
|
_getMonthKey(date) {
|
|
@@ -674,12 +618,10 @@ let KpiMetricValueEditorPage = class KpiMetricValueEditorPage extends connect(st
|
|
|
674
618
|
}
|
|
675
619
|
}
|
|
676
620
|
_cancel() {
|
|
677
|
-
// 편집 취소 로직
|
|
678
621
|
this.editingCell = null;
|
|
679
622
|
this._loadData(); // 원본 데이터로 복원
|
|
680
623
|
}
|
|
681
624
|
async pageInitialized(lifecycle) {
|
|
682
|
-
// 기본값 설정 - 지난 1개월
|
|
683
625
|
if (!this.startDate) {
|
|
684
626
|
const today = new Date();
|
|
685
627
|
const oneMonthAgo = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kpi-metric-value-editor-page.js","sourceRoot":"","sources":["../../../client/pages/kpi-metric-value/kpi-metric-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 KpiMetricValueData {\n metricId: string\n metricName: string\n periodType: string\n values: { [date: string]: { value: number | null; isDirty?: boolean } }\n}\n\ninterface EditorCell {\n date: string\n value: number | null\n isEditable: boolean\n isHighlighted: boolean\n}\n\n@customElement('kpi-metric-value-editor-page')\nexport class KpiMetricValueEditorPage 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 .metric-header {\n position: sticky;\n left: 0;\n top: 0;\n z-index: 3;\n }\n\n .metric-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 }) org: string = ''\n @property({ type: String }) startDate: string = ''\n @property({ type: String }) endDate: string = ''\n\n @state() private metrics: KpiMetricValueData[] = []\n @state() private dates: string[] = []\n @state() private loading: boolean = false\n @state() private error: string = ''\n @state() private editingCell: { metricId: string; date: string } | null = null\n @state() private _existingValues: any[] = []\n\n get context() {\n return {\n title: i18next.t('title.kpi metric 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 <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=\"metric-header\"\n >\n Metric명\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.metrics.map(\n metric => html`\n <tr>\n <td\n style=\"border: 1px solid #ccc; padding: 8px; background: #fff; min-width: 200px;\"\n class=\"metric-name\"\n >\n ${metric.metricName}\n <span\n style=\"font-size: 10px; padding: 2px 6px; background: #e0e0e0; border-radius: 4px; margin-left: 8px;\"\n >${metric.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(metric.metricId, date)}\n >\n ${this._renderCellContent(metric, 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 _renderCellContent(metric: KpiMetricValueData, date: string) {\n const isEditing = this.editingCell?.metricId === metric.metricId && this.editingCell?.date === date\n\n // periodType에 따라 값을 가져오는 방식 결정\n let value: number | null = null\n\n if (metric.periodType === 'DAY') {\n // DAY인 경우 해당 날짜의 값을 사용\n value = metric.values[date]?.value\n } else if (metric.periodType === 'WEEK') {\n // WEEK인 경우 해당 주의 월요일의 값을 사용\n const weekKey = this._getWeekKey(date)\n value = metric.values[weekKey]?.value\n } else if (metric.periodType === 'MONTH') {\n // MONTH인 경우 해당 월의 값을 사용\n const monthKey = this._getMonthKey(date)\n value = metric.values[monthKey]?.value\n } else if (metric.periodType === 'QUARTER') {\n // QUARTER인 경우 해당 분기의 값을 사용\n const quarterKey = this._getQuarterKey(date)\n value = metric.values[quarterKey]?.value\n } else if (metric.periodType === 'YEAR') {\n // YEAR인 경우 해당 연도의 값을 사용\n const yearKey = this._getYearKey(date)\n value = metric.values[yearKey]?.value\n } else {\n // 기본값: DAY와 동일\n value = metric.values[date]?.value\n }\n\n if (isEditing) {\n console.log('Rendering input for editing, value:', value)\n return html`\n <input\n type=\"number\"\n step=\"0.01\"\n .value=${(value || '').toString()}\n @blur=${(e: any) => this._finishEdit(metric.metricId, 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 </div>\n `\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(metricId: string, date: string) {\n this.editingCell = { metricId, date }\n }\n\n private _finishEdit(metricId: string, date: string, value: number) {\n const metric = this.metrics.find(m => m.metricId === metricId)\n if (metric) {\n // periodType에 따라 저장할 키 결정\n let storageKey = date\n\n if (metric.periodType === 'WEEK') {\n storageKey = this._getWeekKey(date)\n } else if (metric.periodType === 'MONTH') {\n storageKey = this._getMonthKey(date)\n } else if (metric.periodType === 'QUARTER') {\n storageKey = this._getQuarterKey(date)\n } else if (metric.periodType === 'YEAR') {\n storageKey = this._getYearKey(date)\n }\n\n if (!metric.values[storageKey]) {\n metric.values[storageKey] = { value: 0, isDirty: false }\n }\n\n // 값이 변경되었는지 확인\n const originalValue = this._findExistingValue(metricId, storageKey)?.value\n const isChanged = originalValue !== value\n\n metric.values[storageKey].value = value\n metric.values[storageKey].isDirty = isChanged\n }\n this.editingCell = null\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 Metric 목록 조회\n const metricsResponse = await client.query({\n query: gql`\n query ($filters: [Filter!]) {\n kpiMetrics(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 Metric Value 데이터 조회\n const valuesResponse = await client.query({\n query: gql`\n query ($filters: [Filter!]) {\n kpiMetricValues(filters: $filters) {\n items {\n id\n metricId\n valueDate\n value\n org\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\n // KPI Metric 목록을 기준으로 데이터 구성\n this.metrics = metricsResponse.data.kpiMetrics.items.map((metric: any) => ({\n metricId: metric.id,\n metricName: metric.name,\n periodType: metric.periodType,\n values: {}\n }))\n\n // 기존 KPI Metric Value 데이터 저장\n this._existingValues = valuesResponse.data.kpiMetricValues.items\n\n // KPI Metric Value 데이터를 해당 Metric에 매핑\n valuesResponse.data.kpiMetricValues.items.forEach((value: any) => {\n const metric = this.metrics.find(m => m.metricId === value.metricId)\n if (metric) {\n metric.values[value.valueDate] = {\n value: value.value,\n isDirty: false\n }\n }\n })\n\n // KPI Metric Value가 없는 Metric도 빈 값으로 초기화\n this.metrics.forEach(metric => {\n this.dates.forEach(date => {\n if (!metric.values[date]) {\n metric.values[date] = { value: null, isDirty: false }\n }\n })\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 // 일별로 생성 (기본)\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.metrics.forEach(metric => {\n Object.entries(metric.values).forEach(([date, data]) => {\n // dirty 상태인 데이터만 처리\n if (data.isDirty && data.value !== null && data.value !== undefined) {\n const existingValue = this._findExistingValue(metric.metricId, date)\n\n if (existingValue) {\n patches.push({\n id: existingValue.id,\n value: data.value,\n org: this.org,\n cuFlag: 'M'\n })\n } else {\n console.log(\n 'Creating new value for metric:',\n metric.metricName,\n 'periodType:',\n metric.periodType,\n 'date:',\n date\n )\n const normalizedDate = this._normalizeDateByPeriodType(date, metric.periodType)\n console.log('Normalized date:', normalizedDate)\n patches.push({\n metricId: metric.metricId,\n valueDate: normalizedDate,\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 // 디버깅: patches 내용 확인\n console.log('Sending patches:', patches)\n\n // 단일 mutation으로 생성과 업데이트 처리\n const response = await client.mutate({\n mutation: gql`\n mutation ($patches: [KpiMetricValuePatch!]!) {\n updateMultipleKpiMetricValue(patches: $patches) {\n id\n value\n valueDate\n metricId\n }\n }\n `,\n variables: { patches }\n })\n\n if (!response.errors) {\n // 저장 후 dirty 상태 해제\n response.data.updateMultipleKpiMetricValue.forEach((savedValue: any) => {\n const metric = this.metrics.find(m => m.metricId === savedValue.metricId)\n if (metric && metric.values[savedValue.valueDate]) {\n metric.values[savedValue.valueDate].isDirty = false\n }\n })\n\n notify({ message: 'KPI Metric 값이 성공적으로 저장되었습니다.' })\n this.requestUpdate()\n }\n } catch (error) {\n console.error('저장 중 오류:', error)\n notify({ message: '저장 중 오류가 발생했습니다.' })\n }\n }\n\n private _findExistingValue(metricId: string, date: string) {\n // 기존 로드된 KPI Metric Value 데이터에서 찾기\n return this._existingValues?.find((v: any) => v.metricId === metricId && v.valueDate === date)\n }\n\n private _getMonthKey(date: string): string {\n const dateObj = new Date(date)\n return `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, '0')}`\n }\n\n private _getQuarterKey(date: string): string {\n const dateObj = new Date(date)\n const quarter = Math.floor(dateObj.getMonth() / 3) + 1\n return `${dateObj.getFullYear()}-Q${quarter}`\n }\n\n private _getYearKey(date: string): string {\n const dateObj = new Date(date)\n return `${dateObj.getFullYear()}`\n }\n\n private _getWeekKey(date: string): string {\n const dateObj = new Date(date)\n const dayOfWeek = dateObj.getDay()\n const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1\n const monday = new Date(dateObj)\n monday.setDate(dateObj.getDate() - daysToMonday)\n return monday.toLocaleDateString('sv-SE')\n }\n\n private _getMondayOfWeek(date: string): string {\n const dateObj = new Date(date)\n const dayOfWeek = dateObj.getDay()\n const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1\n const monday = new Date(dateObj)\n monday.setDate(dateObj.getDate() - daysToMonday)\n return monday.toLocaleDateString('sv-SE')\n }\n\n private _getFirstDayOfMonth(date: string): string {\n const dateObj = new Date(date)\n return new Date(dateObj.getFullYear(), dateObj.getMonth(), 1).toLocaleDateString('sv-SE')\n }\n\n private _getFirstDayOfQuarter(date: string): string {\n const dateObj = new Date(date)\n const quarter = Math.floor(dateObj.getMonth() / 3)\n const firstMonthOfQuarter = quarter * 3\n return new Date(dateObj.getFullYear(), firstMonthOfQuarter, 1).toLocaleDateString('sv-SE')\n }\n\n private _getFirstDayOfYear(date: string): string {\n const dateObj = new Date(date)\n return new Date(dateObj.getFullYear(), 0, 1).toLocaleDateString('sv-SE')\n }\n\n private _normalizeDateByPeriodType(date: string, periodType: string): string {\n console.log('Normalizing date:', date, 'for periodType:', periodType)\n\n const dateObj = new Date(date)\n\n switch (periodType) {\n case 'DAY':\n console.log('DAY - returning original date:', date)\n return date // 그대로 사용\n case 'WEEK':\n // 해당 주의 월요일로 설정\n const dayOfWeek = dateObj.getDay()\n const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1 // 일요일이면 6일 전, 아니면 dayOfWeek - 1\n const monday = new Date(dateObj)\n monday.setDate(dateObj.getDate() - daysToMonday)\n const weeklyDate = monday.toLocaleDateString('sv-SE')\n console.log('WEEK - returning monday:', weeklyDate)\n return weeklyDate\n case 'MONTH':\n // 년-월 형식으로 설정 (예: \"2025-01\")\n const monthlyDate = `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, '0')}`\n console.log('MONTH - returning year-month format:', monthlyDate)\n return monthlyDate\n case 'QUARTER':\n // 분기 형식으로 설정 (예: \"2025-Q1\")\n const quarter = Math.floor(dateObj.getMonth() / 3) + 1\n const quarterlyDate = `${dateObj.getFullYear()}-Q${quarter}`\n console.log('QUARTER - returning quarter format:', quarterlyDate)\n return quarterlyDate\n case 'YEAR':\n // 년도 형식으로 설정 (예: \"2025\")\n const yearlyDate = `${dateObj.getFullYear()}`\n console.log('YEAR - returning year format:', yearlyDate)\n return yearlyDate\n default:\n console.log('DEFAULT - returning original date:', date)\n return date // 기본값\n }\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-metric-value-editor-page.js","sourceRoot":"","sources":["../../../client/pages/kpi-metric-value/kpi-metric-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 KpiMetricValueData { metricId: string\n metricName: string\n periodType: string\n values: { [date: string]: { value: number | null; isDirty?: boolean } }\n}\n\ninterface EditorCell { date: string\n value: number | null\n isEditable: boolean\n isHighlighted: boolean\n}\n\n@customElement('kpi-metric-value-editor-page')\nexport class KpiMetricValueEditorPage 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 .metric-header { position: sticky;\n left: 0;\n top: 0;\n z-index: 3;\n }\n\n .metric-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 }) org: string = ''\n @property({ type: String }) startDate: string = ''\n @property({ type: String }) endDate: string = ''\n\n @state() private metrics: KpiMetricValueData[] = []\n @state() private dates: string[] = []\n @state() private loading: boolean = false\n @state() private error: string = ''\n @state() private editingCell: { metricId: string; date: string } | null = null\n @state() private _existingValues: any[] = []\n\n get context() { return { title: i18next.t('title.kpi metric 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 <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=\"metric-header\"\n >\n Metric명\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.metrics.map(\n metric => html`\n <tr>\n <td\n style=\"border: 1px solid #ccc; padding: 8px; background: #fff; min-width: 200px;\"\n class=\"metric-name\"\n >\n ${metric.metricName}\n <span\n style=\"font-size: 10px; padding: 2px 6px; background: #e0e0e0; border-radius: 4px; margin-left: 8px;\"\n >${metric.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(metric.metricId, date)}\n >\n ${this._renderCellContent(metric, 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 _renderCellContent(metric: KpiMetricValueData, date: string) { const isEditing = this.editingCell?.metricId === metric.metricId && this.editingCell?.date === date\n\n // periodType에 따라 값을 가져오는 방식 결정\n let value: number | null = null\n\n if (metric.periodType === 'DAY') { // DAY인 경우 해당 날짜의 값을 사용\n value = metric.values[date]?.value\n } else if (metric.periodType === 'WEEK') { // WEEK인 경우 해당 주의 월요일의 값을 사용\n const weekKey = this._getWeekKey(date)\n value = metric.values[weekKey]?.value\n } else if (metric.periodType === 'MONTH') { // MONTH인 경우 해당 월의 값을 사용\n const monthKey = this._getMonthKey(date)\n value = metric.values[monthKey]?.value\n } else if (metric.periodType === 'QUARTER') { // QUARTER인 경우 해당 분기의 값을 사용\n const quarterKey = this._getQuarterKey(date)\n value = metric.values[quarterKey]?.value\n } else if (metric.periodType === 'YEAR') { // YEAR인 경우 해당 연도의 값을 사용\n const yearKey = this._getYearKey(date)\n value = metric.values[yearKey]?.value\n } else { // 기본값: DAY와 동일\n value = metric.values[date]?.value\n }\n\n if (isEditing) { console.log('Rendering input for editing, value:', value)\n return html`\n <input\n type=\"number\"\n step=\"0.01\"\n .value=${(value || '').toString()}\n @blur=${(e: any) => this._finishEdit(metric.metricId, 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 </div>\n `\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(metricId: string, date: string) { this.editingCell = { metricId, date }\n }\n\n private _finishEdit(metricId: string, date: string, value: number) { const metric = this.metrics.find(m => m.metricId === metricId)\n if (metric) { // periodType에 따라 저장할 키 결정\n let storageKey = date\n\n if (metric.periodType === 'WEEK') { storageKey = this._getWeekKey(date)\n } else if (metric.periodType === 'MONTH') { storageKey = this._getMonthKey(date)\n } else if (metric.periodType === 'QUARTER') { storageKey = this._getQuarterKey(date)\n } else if (metric.periodType === 'YEAR') { storageKey = this._getYearKey(date)\n }\n\n if (!metric.values[storageKey]) { metric.values[storageKey] = { value: 0, isDirty: false }\n }\n\n // 값이 변경되었는지 확인\n const originalValue = this._findExistingValue(metricId, storageKey)?.value\n const isChanged = originalValue !== value\n\n metric.values[storageKey].value = value\n metric.values[storageKey].isDirty = isChanged\n }\n this.editingCell = null\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 Metric 목록 조회\n const metricsResponse = await client.query({ query: gql`\n query ($filters: [Filter!]) { kpiMetrics(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 Metric Value 데이터 조회\n const valuesResponse = await client.query({ query: gql`\n query ($filters: [Filter!]) { kpiMetricValues(filters: $filters) { items { id\n metricId\n valueDate\n value\n org\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\n // KPI Metric 목록을 기준으로 데이터 구성\n this.metrics = metricsResponse.data.kpiMetrics.items.map((metric: any) => ({ metricId: metric.id,\n metricName: metric.name,\n periodType: metric.periodType,\n values: {}\n }))\n\n // 기존 KPI Metric Value 데이터 저장\n this._existingValues = valuesResponse.data.kpiMetricValues.items\n\n // KPI Metric Value 데이터를 해당 Metric에 매핑\n valuesResponse.data.kpiMetricValues.items.forEach((value: any) => { const metric = this.metrics.find(m => m.metricId === value.metricId)\n if (metric) { metric.values[value.valueDate] = { value: value.value,\n isDirty: false\n }\n }\n })\n\n // KPI Metric Value가 없는 Metric도 빈 값으로 초기화\n this.metrics.forEach(metric => { this.dates.forEach(date => { if (!metric.values[date]) { metric.values[date] = { value: null, isDirty: false }\n }\n })\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 // 일별로 생성 (기본)\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.metrics.forEach(metric => { Object.entries(metric.values).forEach(([date, data]) => { // dirty 상태인 데이터만 처리\n if (data.isDirty && data.value !== null && data.value !== undefined) { const existingValue = this._findExistingValue(metric.metricId, date)\n\n if (existingValue) { patches.push({ id: existingValue.id,\n value: data.value,\n org: this.org,\n cuFlag: 'M'\n })\n } else { console.log(\n 'Creating new value for metric:',\n metric.metricName,\n 'periodType:',\n metric.periodType,\n 'date:',\n date\n )\n const normalizedDate = this._normalizeDateByPeriodType(date, metric.periodType)\n console.log('Normalized date:', normalizedDate)\n patches.push({ metricId: metric.metricId,\n valueDate: normalizedDate,\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 // 디버깅: patches 내용 확인\n console.log('Sending patches:', patches)\n\n // 단일 mutation으로 생성과 업데이트 처리\n const response = await client.mutate({ mutation: gql`\n mutation ($patches: [KpiMetricValuePatch!]!) { updateMultipleKpiMetricValue(patches: $patches) { id\n value\n valueDate\n metricId\n }\n }\n `,\n variables: { patches }\n })\n\n if (!response.errors) { // 저장 후 dirty 상태 해제\n response.data.updateMultipleKpiMetricValue.forEach((savedValue: any) => { const metric = this.metrics.find(m => m.metricId === savedValue.metricId)\n if (metric && metric.values[savedValue.valueDate]) { metric.values[savedValue.valueDate].isDirty = false\n }\n })\n\n notify({ message: 'KPI Metric 값이 성공적으로 저장되었습니다.' })\n this.requestUpdate()\n }\n } catch (error) { console.error('저장 중 오류:', error)\n notify({ message: '저장 중 오류가 발생했습니다.' })\n }\n }\n\n private _findExistingValue(metricId: string, date: string) { // 기존 로드된 KPI Metric Value 데이터에서 찾기\n return this._existingValues?.find((v: any) => v.metricId === metricId && v.valueDate === date)\n }\n\n private _getMonthKey(date: string): string { const dateObj = new Date(date)\n return `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, '0')}`\n }\n\n private _getQuarterKey(date: string): string { const dateObj = new Date(date)\n const quarter = Math.floor(dateObj.getMonth() / 3) + 1\n return `${dateObj.getFullYear()}-Q${quarter}`\n }\n\n private _getYearKey(date: string): string { const dateObj = new Date(date)\n return `${dateObj.getFullYear()}`\n }\n\n private _getWeekKey(date: string): string { const dateObj = new Date(date)\n const dayOfWeek = dateObj.getDay()\n const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1\n const monday = new Date(dateObj)\n monday.setDate(dateObj.getDate() - daysToMonday)\n return monday.toLocaleDateString('sv-SE')\n }\n\n private _getMondayOfWeek(date: string): string { const dateObj = new Date(date)\n const dayOfWeek = dateObj.getDay()\n const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1\n const monday = new Date(dateObj)\n monday.setDate(dateObj.getDate() - daysToMonday)\n return monday.toLocaleDateString('sv-SE')\n }\n\n private _getFirstDayOfMonth(date: string): string { const dateObj = new Date(date)\n return new Date(dateObj.getFullYear(), dateObj.getMonth(), 1).toLocaleDateString('sv-SE')\n }\n\n private _getFirstDayOfQuarter(date: string): string { const dateObj = new Date(date)\n const quarter = Math.floor(dateObj.getMonth() / 3)\n const firstMonthOfQuarter = quarter * 3\n return new Date(dateObj.getFullYear(), firstMonthOfQuarter, 1).toLocaleDateString('sv-SE')\n }\n\n private _getFirstDayOfYear(date: string): string { const dateObj = new Date(date)\n return new Date(dateObj.getFullYear(), 0, 1).toLocaleDateString('sv-SE')\n }\n\n private _normalizeDateByPeriodType(date: string, periodType: string): string { console.log('Normalizing date:', date, 'for periodType:', periodType)\n\n const dateObj = new Date(date)\n\n switch (periodType) { case 'DAY':\n console.log('DAY - returning original date:', date)\n return date // 그대로 사용\n case 'WEEK':\n // 해당 주의 월요일로 설정\n const dayOfWeek = dateObj.getDay()\n const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1 // 일요일이면 6일 전, 아니면 dayOfWeek - 1\n const monday = new Date(dateObj)\n monday.setDate(dateObj.getDate() - daysToMonday)\n const weeklyDate = monday.toLocaleDateString('sv-SE')\n console.log('WEEK - returning monday:', weeklyDate)\n return weeklyDate\n case 'MONTH':\n // 년-월 형식으로 설정 (예: \"2025-01\")\n const monthlyDate = `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, '0')}`\n console.log('MONTH - returning year-month format:', monthlyDate)\n return monthlyDate\n case 'QUARTER':\n // 분기 형식으로 설정 (예: \"2025-Q1\")\n const quarter = Math.floor(dateObj.getMonth() / 3) + 1\n const quarterlyDate = `${dateObj.getFullYear()}-Q${quarter}`\n console.log('QUARTER - returning quarter format:', quarterlyDate)\n return quarterlyDate\n case 'YEAR':\n // 년도 형식으로 설정 (예: \"2025\")\n const yearlyDate = `${dateObj.getFullYear()}`\n console.log('YEAR - returning year format:', yearlyDate)\n return yearlyDate\n default:\n console.log('DEFAULT - returning original date:', date)\n return date // 기본값\n }\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"]}
|