@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,114 +3,99 @@ import '@material/web/button/elevated-button.js'
|
|
|
3
3
|
import '@material/web/textfield/outlined-text-field.js'
|
|
4
4
|
|
|
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
14
|
|
|
16
|
-
interface KpiMetricValueData {
|
|
17
|
-
metricId: string
|
|
15
|
+
interface KpiMetricValueData { metricId: string
|
|
18
16
|
metricName: string
|
|
19
17
|
periodType: string
|
|
20
18
|
values: { [date: string]: { value: number | null; isDirty?: boolean } }
|
|
21
19
|
}
|
|
22
20
|
|
|
23
|
-
interface EditorCell {
|
|
24
|
-
date: string
|
|
21
|
+
interface EditorCell { date: string
|
|
25
22
|
value: number | null
|
|
26
23
|
isEditable: boolean
|
|
27
24
|
isHighlighted: boolean
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
@customElement('kpi-metric-value-editor-page')
|
|
31
|
-
export class KpiMetricValueEditorPage extends
|
|
32
|
-
static styles = [
|
|
28
|
+
export class KpiMetricValueEditorPage extends localize(i18next)(ScopedElementsMixin(PageView)) { static styles = [
|
|
33
29
|
CommonHeaderStyles,
|
|
34
30
|
ScrollbarStyles,
|
|
35
31
|
css`
|
|
36
|
-
:host {
|
|
37
|
-
display: flex;
|
|
32
|
+
:host { display: flex;
|
|
38
33
|
flex-direction: column;
|
|
39
34
|
padding: 20px;
|
|
40
35
|
overflow-x: auto;
|
|
41
|
-
|
|
36
|
+
}
|
|
42
37
|
|
|
43
|
-
.header {
|
|
44
|
-
display: flex;
|
|
38
|
+
.header { display: flex;
|
|
45
39
|
gap: 16px;
|
|
46
40
|
align-items: center;
|
|
47
41
|
margin-bottom: 20px;
|
|
48
42
|
padding: 16px;
|
|
49
43
|
background: var(--md-sys-color-surface-container);
|
|
50
44
|
border-radius: 8px;
|
|
51
|
-
|
|
45
|
+
}
|
|
52
46
|
|
|
53
|
-
.controls {
|
|
54
|
-
display: flex;
|
|
47
|
+
.controls { display: flex;
|
|
55
48
|
gap: 12px;
|
|
56
49
|
align-items: center;
|
|
57
|
-
|
|
50
|
+
}
|
|
58
51
|
|
|
59
|
-
.table-container {
|
|
60
|
-
flex: 1;
|
|
52
|
+
.table-container { flex: 1;
|
|
61
53
|
overflow: auto;
|
|
62
54
|
border: 1px solid var(--md-sys-color-outline);
|
|
63
55
|
border-radius: 8px;
|
|
64
|
-
|
|
56
|
+
}
|
|
65
57
|
|
|
66
|
-
table {
|
|
67
|
-
width: 100%;
|
|
58
|
+
table { width: 100%;
|
|
68
59
|
border-collapse: collapse;
|
|
69
60
|
min-width: max-content;
|
|
70
|
-
|
|
61
|
+
}
|
|
71
62
|
|
|
72
|
-
th {
|
|
73
|
-
background: var(--md-sys-color-surface-container-low);
|
|
63
|
+
th { background: var(--md-sys-color-surface-container-low);
|
|
74
64
|
font-weight: 500;
|
|
75
65
|
padding: 8px 12px;
|
|
76
66
|
border: 1px solid var(--md-sys-color-outline-variant);
|
|
77
67
|
min-width: 80px;
|
|
78
68
|
height: 120px;
|
|
79
69
|
vertical-align: middle;
|
|
80
|
-
|
|
70
|
+
}
|
|
81
71
|
|
|
82
|
-
td {
|
|
83
|
-
padding: 8px 12px;
|
|
72
|
+
td { padding: 8px 12px;
|
|
84
73
|
border: 1px solid var(--md-sys-color-outline-variant);
|
|
85
74
|
min-width: 80px;
|
|
86
75
|
height: 60px;
|
|
87
76
|
text-align: right;
|
|
88
77
|
vertical-align: middle;
|
|
89
|
-
|
|
78
|
+
}
|
|
90
79
|
|
|
91
|
-
.metric-header {
|
|
92
|
-
position: sticky;
|
|
80
|
+
.metric-header { position: sticky;
|
|
93
81
|
left: 0;
|
|
94
82
|
top: 0;
|
|
95
83
|
z-index: 3;
|
|
96
|
-
|
|
84
|
+
}
|
|
97
85
|
|
|
98
|
-
.metric-name {
|
|
99
|
-
position: sticky;
|
|
86
|
+
.metric-name { position: sticky;
|
|
100
87
|
left: 0;
|
|
101
88
|
background: var(--md-sys-color-surface);
|
|
102
89
|
font-weight: 500;
|
|
103
90
|
min-width: 200px;
|
|
104
91
|
text-align: left;
|
|
105
92
|
z-index: 2;
|
|
106
|
-
|
|
93
|
+
}
|
|
107
94
|
|
|
108
|
-
tr:hover {
|
|
109
|
-
|
|
110
|
-
}
|
|
95
|
+
tr:hover { background: var(--md-sys-color-surface-container-high);
|
|
96
|
+
}
|
|
111
97
|
|
|
112
|
-
th.date-header {
|
|
113
|
-
position: sticky;
|
|
98
|
+
th.date-header { position: sticky;
|
|
114
99
|
top: 0;
|
|
115
100
|
z-index: 2;
|
|
116
101
|
text-align: center;
|
|
@@ -122,90 +107,77 @@ export class KpiMetricValueEditorPage extends connect(store)(localize(i18next)(S
|
|
|
122
107
|
display: flex;
|
|
123
108
|
align-items: center;
|
|
124
109
|
justify-content: center;
|
|
125
|
-
|
|
110
|
+
}
|
|
126
111
|
|
|
127
|
-
td.editable-cell {
|
|
128
|
-
cursor: pointer;
|
|
112
|
+
td.editable-cell { cursor: pointer;
|
|
129
113
|
background: var(--md-sys-color-primary-container);
|
|
130
114
|
color: var(--md-sys-color-on-primary-container);
|
|
131
|
-
|
|
115
|
+
}
|
|
132
116
|
|
|
133
|
-
td.editable-cell:hover {
|
|
134
|
-
|
|
135
|
-
}
|
|
117
|
+
td.editable-cell:hover { background: var(--md-sys-color-primary-container-high);
|
|
118
|
+
}
|
|
136
119
|
|
|
137
|
-
td.highlighted-cell {
|
|
138
|
-
background: var(--md-sys-color-secondary-container);
|
|
120
|
+
td.highlighted-cell { background: var(--md-sys-color-secondary-container);
|
|
139
121
|
color: var(--md-sys-color-on-secondary-container);
|
|
140
122
|
font-weight: 500;
|
|
141
|
-
|
|
123
|
+
}
|
|
142
124
|
|
|
143
|
-
td.highlighted-cell:hover {
|
|
144
|
-
|
|
145
|
-
}
|
|
125
|
+
td.highlighted-cell:hover { background: var(--md-sys-color-secondary-container-high);
|
|
126
|
+
}
|
|
146
127
|
|
|
147
|
-
td.disabled-cell {
|
|
148
|
-
background: var(--md-sys-color-surface-container);
|
|
128
|
+
td.disabled-cell { background: var(--md-sys-color-surface-container);
|
|
149
129
|
color: var(--md-sys-color-on-surface-variant);
|
|
150
130
|
cursor: not-allowed;
|
|
151
|
-
|
|
131
|
+
}
|
|
152
132
|
|
|
153
|
-
.value-input {
|
|
154
|
-
width: 100%;
|
|
133
|
+
.value-input { width: 100%;
|
|
155
134
|
text-align: center;
|
|
156
135
|
border: none;
|
|
157
136
|
background: transparent;
|
|
158
137
|
color: inherit;
|
|
159
138
|
font-size: 12px;
|
|
160
139
|
padding: 2px;
|
|
161
|
-
|
|
140
|
+
}
|
|
162
141
|
|
|
163
|
-
.value-input:focus {
|
|
164
|
-
outline: 2px solid var(--md-sys-color-primary);
|
|
142
|
+
.value-input:focus { outline: 2px solid var(--md-sys-color-primary);
|
|
165
143
|
border-radius: 4px;
|
|
166
|
-
|
|
144
|
+
}
|
|
167
145
|
|
|
168
|
-
.period-type-badge {
|
|
169
|
-
font-size: 10px;
|
|
146
|
+
.period-type-badge { font-size: 10px;
|
|
170
147
|
padding: 2px 6px;
|
|
171
148
|
border-radius: 4px;
|
|
172
149
|
background: var(--md-sys-color-tertiary-container);
|
|
173
150
|
color: var(--md-sys-color-on-tertiary-container);
|
|
174
151
|
margin-left: 8px;
|
|
175
|
-
|
|
152
|
+
}
|
|
176
153
|
|
|
177
|
-
.loading {
|
|
178
|
-
display: flex;
|
|
154
|
+
.loading { display: flex;
|
|
179
155
|
justify-content: center;
|
|
180
156
|
align-items: center;
|
|
181
157
|
height: 200px;
|
|
182
158
|
color: var(--md-sys-color-on-surface-variant);
|
|
183
|
-
|
|
159
|
+
}
|
|
184
160
|
|
|
185
|
-
.error {
|
|
186
|
-
color: var(--md-sys-color-error);
|
|
161
|
+
.error { color: var(--md-sys-color-error);
|
|
187
162
|
padding: 16px;
|
|
188
163
|
text-align: center;
|
|
189
|
-
|
|
164
|
+
}
|
|
190
165
|
|
|
191
|
-
.legend {
|
|
192
|
-
display: flex;
|
|
166
|
+
.legend { display: flex;
|
|
193
167
|
gap: 16px;
|
|
194
168
|
margin-top: 16px;
|
|
195
169
|
font-size: 12px;
|
|
196
|
-
|
|
170
|
+
}
|
|
197
171
|
|
|
198
|
-
.legend-item {
|
|
199
|
-
display: flex;
|
|
172
|
+
.legend-item { display: flex;
|
|
200
173
|
align-items: center;
|
|
201
174
|
gap: 4px;
|
|
202
|
-
|
|
175
|
+
}
|
|
203
176
|
|
|
204
|
-
.legend-color {
|
|
205
|
-
width: 16px;
|
|
177
|
+
.legend-color { width: 16px;
|
|
206
178
|
height: 16px;
|
|
207
179
|
border-radius: 2px;
|
|
208
|
-
|
|
180
|
+
}
|
|
209
181
|
`
|
|
210
182
|
]
|
|
211
183
|
|
|
@@ -220,42 +192,35 @@ export class KpiMetricValueEditorPage extends connect(store)(localize(i18next)(S
|
|
|
220
192
|
@state() private editingCell: { metricId: string; date: string } | null = null
|
|
221
193
|
@state() private _existingValues: any[] = []
|
|
222
194
|
|
|
223
|
-
get context() {
|
|
224
|
-
return {
|
|
225
|
-
title: i18next.t('title.kpi metric value editor'),
|
|
195
|
+
get context() { return { title: i18next.t('title.kpi metric value editor'),
|
|
226
196
|
actions: [
|
|
227
|
-
{
|
|
228
|
-
title: i18next.t('button.save'),
|
|
197
|
+
{ title: i18next.t('button.save'),
|
|
229
198
|
action: this._saveValues.bind(this),
|
|
230
199
|
...CommonButtonStyles.save
|
|
231
|
-
|
|
232
|
-
{
|
|
233
|
-
title: i18next.t('button.cancel'),
|
|
200
|
+
},
|
|
201
|
+
{ title: i18next.t('button.cancel'),
|
|
234
202
|
action: this._cancel.bind(this),
|
|
235
203
|
...CommonButtonStyles.cancel
|
|
236
|
-
|
|
204
|
+
}
|
|
237
205
|
]
|
|
238
|
-
|
|
239
|
-
|
|
206
|
+
}
|
|
207
|
+
}
|
|
240
208
|
|
|
241
|
-
render() {
|
|
242
|
-
if (this.loading) {
|
|
243
|
-
return html`
|
|
209
|
+
render() { if (this.loading) { return html`
|
|
244
210
|
<div class="loading">
|
|
245
211
|
<md-icon>hourglass_empty</md-icon>
|
|
246
212
|
<span>데이터를 불러오는 중...</span>
|
|
247
213
|
</div>
|
|
248
214
|
`
|
|
249
|
-
|
|
215
|
+
}
|
|
250
216
|
|
|
251
|
-
if (this.error) {
|
|
252
|
-
return html`
|
|
217
|
+
if (this.error) { return html`
|
|
253
218
|
<div class="error">
|
|
254
219
|
<md-icon>error</md-icon>
|
|
255
220
|
<span>${this.error}</span>
|
|
256
221
|
</div>
|
|
257
222
|
`
|
|
258
|
-
|
|
223
|
+
}
|
|
259
224
|
|
|
260
225
|
return html`
|
|
261
226
|
<div class="header">
|
|
@@ -357,40 +322,32 @@ export class KpiMetricValueEditorPage extends connect(store)(localize(i18next)(S
|
|
|
357
322
|
</div>
|
|
358
323
|
</div>
|
|
359
324
|
`
|
|
360
|
-
|
|
325
|
+
}
|
|
361
326
|
|
|
362
|
-
private _renderCellContent(metric: KpiMetricValueData, date: string) {
|
|
363
|
-
const isEditing = this.editingCell?.metricId === metric.metricId && this.editingCell?.date === date
|
|
327
|
+
private _renderCellContent(metric: KpiMetricValueData, date: string) { const isEditing = this.editingCell?.metricId === metric.metricId && this.editingCell?.date === date
|
|
364
328
|
|
|
365
329
|
// periodType에 따라 값을 가져오는 방식 결정
|
|
366
330
|
let value: number | null = null
|
|
367
331
|
|
|
368
|
-
if (metric.periodType === 'DAY') {
|
|
369
|
-
// DAY인 경우 해당 날짜의 값을 사용
|
|
332
|
+
if (metric.periodType === 'DAY') { // DAY인 경우 해당 날짜의 값을 사용
|
|
370
333
|
value = metric.values[date]?.value
|
|
371
|
-
|
|
372
|
-
// WEEK인 경우 해당 주의 월요일의 값을 사용
|
|
334
|
+
} else if (metric.periodType === 'WEEK') { // WEEK인 경우 해당 주의 월요일의 값을 사용
|
|
373
335
|
const weekKey = this._getWeekKey(date)
|
|
374
336
|
value = metric.values[weekKey]?.value
|
|
375
|
-
|
|
376
|
-
// MONTH인 경우 해당 월의 값을 사용
|
|
337
|
+
} else if (metric.periodType === 'MONTH') { // MONTH인 경우 해당 월의 값을 사용
|
|
377
338
|
const monthKey = this._getMonthKey(date)
|
|
378
339
|
value = metric.values[monthKey]?.value
|
|
379
|
-
|
|
380
|
-
// QUARTER인 경우 해당 분기의 값을 사용
|
|
340
|
+
} else if (metric.periodType === 'QUARTER') { // QUARTER인 경우 해당 분기의 값을 사용
|
|
381
341
|
const quarterKey = this._getQuarterKey(date)
|
|
382
342
|
value = metric.values[quarterKey]?.value
|
|
383
|
-
|
|
384
|
-
// YEAR인 경우 해당 연도의 값을 사용
|
|
343
|
+
} else if (metric.periodType === 'YEAR') { // YEAR인 경우 해당 연도의 값을 사용
|
|
385
344
|
const yearKey = this._getYearKey(date)
|
|
386
345
|
value = metric.values[yearKey]?.value
|
|
387
|
-
|
|
388
|
-
// 기본값: DAY와 동일
|
|
346
|
+
} else { // 기본값: DAY와 동일
|
|
389
347
|
value = metric.values[date]?.value
|
|
390
|
-
|
|
348
|
+
}
|
|
391
349
|
|
|
392
|
-
if (isEditing) {
|
|
393
|
-
console.log('Rendering input for editing, value:', value)
|
|
350
|
+
if (isEditing) { console.log('Rendering input for editing, value:', value)
|
|
394
351
|
return html`
|
|
395
352
|
<input
|
|
396
353
|
type="number"
|
|
@@ -402,7 +359,7 @@ export class KpiMetricValueEditorPage extends connect(store)(localize(i18next)(S
|
|
|
402
359
|
autofocus
|
|
403
360
|
/>
|
|
404
361
|
`
|
|
405
|
-
|
|
362
|
+
}
|
|
406
363
|
|
|
407
364
|
return html`
|
|
408
365
|
<div style="display: flex; flex-direction: column; gap: 2px;">
|
|
@@ -411,36 +368,27 @@ export class KpiMetricValueEditorPage extends connect(store)(localize(i18next)(S
|
|
|
411
368
|
</span>
|
|
412
369
|
</div>
|
|
413
370
|
`
|
|
414
|
-
|
|
371
|
+
}
|
|
415
372
|
|
|
416
|
-
private _formatDate(date: string): string {
|
|
417
|
-
const d = new Date(date)
|
|
373
|
+
private _formatDate(date: string): string { const d = new Date(date)
|
|
418
374
|
return d.toLocaleDateString('ko-KR', { month: 'numeric', day: 'numeric' })
|
|
419
|
-
|
|
375
|
+
}
|
|
420
376
|
|
|
421
|
-
private _startEdit(metricId: string, date: string) {
|
|
422
|
-
|
|
423
|
-
}
|
|
377
|
+
private _startEdit(metricId: string, date: string) { this.editingCell = { metricId, date }
|
|
378
|
+
}
|
|
424
379
|
|
|
425
|
-
private _finishEdit(metricId: string, date: string, value: number) {
|
|
426
|
-
|
|
427
|
-
if (metric) {
|
|
428
|
-
// periodType에 따라 저장할 키 결정
|
|
380
|
+
private _finishEdit(metricId: string, date: string, value: number) { const metric = this.metrics.find(m => m.metricId === metricId)
|
|
381
|
+
if (metric) { // periodType에 따라 저장할 키 결정
|
|
429
382
|
let storageKey = date
|
|
430
383
|
|
|
431
|
-
if (metric.periodType === 'WEEK') {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
storageKey = this._getQuarterKey(date)
|
|
437
|
-
} else if (metric.periodType === 'YEAR') {
|
|
438
|
-
storageKey = this._getYearKey(date)
|
|
439
|
-
}
|
|
384
|
+
if (metric.periodType === 'WEEK') { storageKey = this._getWeekKey(date)
|
|
385
|
+
} else if (metric.periodType === 'MONTH') { storageKey = this._getMonthKey(date)
|
|
386
|
+
} else if (metric.periodType === 'QUARTER') { storageKey = this._getQuarterKey(date)
|
|
387
|
+
} else if (metric.periodType === 'YEAR') { storageKey = this._getYearKey(date)
|
|
388
|
+
}
|
|
440
389
|
|
|
441
|
-
if (!metric.values[storageKey]) {
|
|
442
|
-
|
|
443
|
-
}
|
|
390
|
+
if (!metric.values[storageKey]) { metric.values[storageKey] = { value: 0, isDirty: false }
|
|
391
|
+
}
|
|
444
392
|
|
|
445
393
|
// 값이 변경되었는지 확인
|
|
446
394
|
const originalValue = this._findExistingValue(metricId, storageKey)?.value
|
|
@@ -448,139 +396,107 @@ export class KpiMetricValueEditorPage extends connect(store)(localize(i18next)(S
|
|
|
448
396
|
|
|
449
397
|
metric.values[storageKey].value = value
|
|
450
398
|
metric.values[storageKey].isDirty = isChanged
|
|
451
|
-
|
|
399
|
+
}
|
|
452
400
|
this.editingCell = null
|
|
453
|
-
|
|
401
|
+
}
|
|
454
402
|
|
|
455
|
-
private async _loadData() {
|
|
456
|
-
if (!this.startDate || !this.endDate) {
|
|
457
|
-
this.error = '시작일, 종료일을 모두 입력해주세요.'
|
|
403
|
+
private async _loadData() { if (!this.startDate || !this.endDate) { this.error = '시작일, 종료일을 모두 입력해주세요.'
|
|
458
404
|
return
|
|
459
|
-
|
|
405
|
+
}
|
|
460
406
|
|
|
461
407
|
this.loading = true
|
|
462
408
|
this.error = ''
|
|
463
409
|
|
|
464
|
-
try {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
query: gql`
|
|
468
|
-
query ($filters: [Filter!]) {
|
|
469
|
-
kpiMetrics(filters: $filters) {
|
|
470
|
-
items {
|
|
471
|
-
id
|
|
410
|
+
try { // KPI Metric 목록 조회
|
|
411
|
+
const metricsResponse = await client.query({ query: gql`
|
|
412
|
+
query ($filters: [Filter!]) { kpiMetrics(filters: $filters) { items { id
|
|
472
413
|
name
|
|
473
414
|
periodType
|
|
474
415
|
active
|
|
475
|
-
|
|
416
|
+
}
|
|
476
417
|
total
|
|
477
|
-
|
|
478
|
-
|
|
418
|
+
}
|
|
419
|
+
}
|
|
479
420
|
`,
|
|
480
|
-
variables: {
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
})
|
|
421
|
+
variables: { filters: [{ name: 'active', operator: 'eq', value: true }]
|
|
422
|
+
}
|
|
423
|
+
})
|
|
484
424
|
|
|
485
425
|
// KPI Metric Value 데이터 조회
|
|
486
|
-
const valuesResponse = await client.query({
|
|
487
|
-
|
|
488
|
-
query ($filters: [Filter!]) {
|
|
489
|
-
kpiMetricValues(filters: $filters) {
|
|
490
|
-
items {
|
|
491
|
-
id
|
|
426
|
+
const valuesResponse = await client.query({ query: gql`
|
|
427
|
+
query ($filters: [Filter!]) { kpiMetricValues(filters: $filters) { items { id
|
|
492
428
|
metricId
|
|
493
429
|
valueDate
|
|
494
430
|
value
|
|
495
431
|
org
|
|
496
|
-
|
|
432
|
+
}
|
|
497
433
|
total
|
|
498
|
-
|
|
499
|
-
|
|
434
|
+
}
|
|
435
|
+
}
|
|
500
436
|
`,
|
|
501
|
-
variables: {
|
|
502
|
-
filters: [
|
|
437
|
+
variables: { filters: [
|
|
503
438
|
...(this.org ? [{ name: 'org', operator: 'eq', value: this.org }] : []),
|
|
504
439
|
{ name: 'valueDate', operator: 'between', value: [this.startDate, this.endDate] }
|
|
505
440
|
]
|
|
506
|
-
|
|
507
|
-
|
|
441
|
+
}
|
|
442
|
+
})
|
|
508
443
|
|
|
509
444
|
// 날짜 배열 생성
|
|
510
445
|
this.dates = this._generateDateArray(this.startDate, this.endDate)
|
|
511
446
|
|
|
512
447
|
// KPI Metric 목록을 기준으로 데이터 구성
|
|
513
|
-
this.metrics = metricsResponse.data.kpiMetrics.items.map((metric: any) => ({
|
|
514
|
-
metricId: metric.id,
|
|
448
|
+
this.metrics = metricsResponse.data.kpiMetrics.items.map((metric: any) => ({ metricId: metric.id,
|
|
515
449
|
metricName: metric.name,
|
|
516
450
|
periodType: metric.periodType,
|
|
517
451
|
values: {}
|
|
518
|
-
|
|
452
|
+
}))
|
|
519
453
|
|
|
520
454
|
// 기존 KPI Metric Value 데이터 저장
|
|
521
455
|
this._existingValues = valuesResponse.data.kpiMetricValues.items
|
|
522
456
|
|
|
523
457
|
// KPI Metric Value 데이터를 해당 Metric에 매핑
|
|
524
|
-
valuesResponse.data.kpiMetricValues.items.forEach((value: any) => {
|
|
525
|
-
|
|
526
|
-
if (metric) {
|
|
527
|
-
metric.values[value.valueDate] = {
|
|
528
|
-
value: value.value,
|
|
458
|
+
valuesResponse.data.kpiMetricValues.items.forEach((value: any) => { const metric = this.metrics.find(m => m.metricId === value.metricId)
|
|
459
|
+
if (metric) { metric.values[value.valueDate] = { value: value.value,
|
|
529
460
|
isDirty: false
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
})
|
|
533
464
|
|
|
534
465
|
// KPI Metric Value가 없는 Metric도 빈 값으로 초기화
|
|
535
|
-
this.metrics.forEach(metric => {
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
}
|
|
540
|
-
})
|
|
541
|
-
})
|
|
466
|
+
this.metrics.forEach(metric => { this.dates.forEach(date => { if (!metric.values[date]) { metric.values[date] = { value: null, isDirty: false }
|
|
467
|
+
}
|
|
468
|
+
})
|
|
469
|
+
})
|
|
542
470
|
|
|
543
471
|
this.requestUpdate()
|
|
544
|
-
|
|
545
|
-
console.error('데이터 로드 중 오류:', error)
|
|
472
|
+
} catch (error) { console.error('데이터 로드 중 오류:', error)
|
|
546
473
|
this.error = '데이터를 불러오는 중 오류가 발생했습니다.'
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
}
|
|
474
|
+
} finally { this.loading = false
|
|
475
|
+
}
|
|
476
|
+
}
|
|
551
477
|
|
|
552
|
-
private _generateDateArray(startDate: string, endDate: string): string[] {
|
|
553
|
-
const dates: string[] = []
|
|
478
|
+
private _generateDateArray(startDate: string, endDate: string): string[] { const dates: string[] = []
|
|
554
479
|
const start = new Date(startDate)
|
|
555
480
|
const end = new Date(endDate)
|
|
556
481
|
|
|
557
482
|
// 일별로 생성 (기본)
|
|
558
|
-
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
|
|
559
|
-
|
|
560
|
-
}
|
|
483
|
+
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) { dates.push(d.toLocaleDateString('sv-SE'))
|
|
484
|
+
}
|
|
561
485
|
|
|
562
486
|
return dates
|
|
563
|
-
|
|
487
|
+
}
|
|
564
488
|
|
|
565
|
-
private async _saveValues() {
|
|
566
|
-
try {
|
|
567
|
-
const patches: any[] = []
|
|
489
|
+
private async _saveValues() { try { const patches: any[] = []
|
|
568
490
|
|
|
569
|
-
this.metrics.forEach(metric => {
|
|
570
|
-
|
|
571
|
-
// dirty 상태인 데이터만 처리
|
|
572
|
-
if (data.isDirty && data.value !== null && data.value !== undefined) {
|
|
573
|
-
const existingValue = this._findExistingValue(metric.metricId, date)
|
|
491
|
+
this.metrics.forEach(metric => { Object.entries(metric.values).forEach(([date, data]) => { // dirty 상태인 데이터만 처리
|
|
492
|
+
if (data.isDirty && data.value !== null && data.value !== undefined) { const existingValue = this._findExistingValue(metric.metricId, date)
|
|
574
493
|
|
|
575
|
-
if (existingValue) {
|
|
576
|
-
patches.push({
|
|
577
|
-
id: existingValue.id,
|
|
494
|
+
if (existingValue) { patches.push({ id: existingValue.id,
|
|
578
495
|
value: data.value,
|
|
579
496
|
org: this.org,
|
|
580
497
|
cuFlag: 'M'
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
console.log(
|
|
498
|
+
})
|
|
499
|
+
} else { console.log(
|
|
584
500
|
'Creating new value for metric:',
|
|
585
501
|
metric.metricName,
|
|
586
502
|
'periodType:',
|
|
@@ -590,122 +506,102 @@ export class KpiMetricValueEditorPage extends connect(store)(localize(i18next)(S
|
|
|
590
506
|
)
|
|
591
507
|
const normalizedDate = this._normalizeDateByPeriodType(date, metric.periodType)
|
|
592
508
|
console.log('Normalized date:', normalizedDate)
|
|
593
|
-
patches.push({
|
|
594
|
-
metricId: metric.metricId,
|
|
509
|
+
patches.push({ metricId: metric.metricId,
|
|
595
510
|
valueDate: normalizedDate,
|
|
596
511
|
value: data.value,
|
|
597
512
|
org: this.org,
|
|
598
513
|
cuFlag: '+'
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
if (patches.length === 0) {
|
|
606
|
-
notify({ message: '저장할 데이터가 없습니다.' })
|
|
514
|
+
})
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
})
|
|
518
|
+
})
|
|
519
|
+
|
|
520
|
+
if (patches.length === 0) { notify({ message: '저장할 데이터가 없습니다.' })
|
|
607
521
|
return
|
|
608
|
-
|
|
522
|
+
}
|
|
609
523
|
|
|
610
524
|
// 디버깅: patches 내용 확인
|
|
611
525
|
console.log('Sending patches:', patches)
|
|
612
526
|
|
|
613
527
|
// 단일 mutation으로 생성과 업데이트 처리
|
|
614
|
-
const response = await client.mutate({
|
|
615
|
-
|
|
616
|
-
mutation ($patches: [KpiMetricValuePatch!]!) {
|
|
617
|
-
updateMultipleKpiMetricValue(patches: $patches) {
|
|
618
|
-
id
|
|
528
|
+
const response = await client.mutate({ mutation: gql`
|
|
529
|
+
mutation ($patches: [KpiMetricValuePatch!]!) { updateMultipleKpiMetricValue(patches: $patches) { id
|
|
619
530
|
value
|
|
620
531
|
valueDate
|
|
621
532
|
metricId
|
|
622
|
-
|
|
623
|
-
|
|
533
|
+
}
|
|
534
|
+
}
|
|
624
535
|
`,
|
|
625
536
|
variables: { patches }
|
|
626
|
-
|
|
537
|
+
})
|
|
627
538
|
|
|
628
|
-
if (!response.errors) {
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
metric.values[savedValue.valueDate].isDirty = false
|
|
634
|
-
}
|
|
635
|
-
})
|
|
539
|
+
if (!response.errors) { // 저장 후 dirty 상태 해제
|
|
540
|
+
response.data.updateMultipleKpiMetricValue.forEach((savedValue: any) => { const metric = this.metrics.find(m => m.metricId === savedValue.metricId)
|
|
541
|
+
if (metric && metric.values[savedValue.valueDate]) { metric.values[savedValue.valueDate].isDirty = false
|
|
542
|
+
}
|
|
543
|
+
})
|
|
636
544
|
|
|
637
545
|
notify({ message: 'KPI Metric 값이 성공적으로 저장되었습니다.' })
|
|
638
546
|
this.requestUpdate()
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
console.error('저장 중 오류:', error)
|
|
547
|
+
}
|
|
548
|
+
} catch (error) { console.error('저장 중 오류:', error)
|
|
642
549
|
notify({ message: '저장 중 오류가 발생했습니다.' })
|
|
643
|
-
|
|
644
|
-
|
|
550
|
+
}
|
|
551
|
+
}
|
|
645
552
|
|
|
646
|
-
private _findExistingValue(metricId: string, date: string) {
|
|
647
|
-
// 기존 로드된 KPI Metric Value 데이터에서 찾기
|
|
553
|
+
private _findExistingValue(metricId: string, date: string) { // 기존 로드된 KPI Metric Value 데이터에서 찾기
|
|
648
554
|
return this._existingValues?.find((v: any) => v.metricId === metricId && v.valueDate === date)
|
|
649
|
-
|
|
555
|
+
}
|
|
650
556
|
|
|
651
|
-
private _getMonthKey(date: string): string {
|
|
652
|
-
const dateObj = new Date(date)
|
|
557
|
+
private _getMonthKey(date: string): string { const dateObj = new Date(date)
|
|
653
558
|
return `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, '0')}`
|
|
654
|
-
|
|
559
|
+
}
|
|
655
560
|
|
|
656
|
-
private _getQuarterKey(date: string): string {
|
|
657
|
-
const dateObj = new Date(date)
|
|
561
|
+
private _getQuarterKey(date: string): string { const dateObj = new Date(date)
|
|
658
562
|
const quarter = Math.floor(dateObj.getMonth() / 3) + 1
|
|
659
563
|
return `${dateObj.getFullYear()}-Q${quarter}`
|
|
660
|
-
|
|
564
|
+
}
|
|
661
565
|
|
|
662
|
-
private _getYearKey(date: string): string {
|
|
663
|
-
const dateObj = new Date(date)
|
|
566
|
+
private _getYearKey(date: string): string { const dateObj = new Date(date)
|
|
664
567
|
return `${dateObj.getFullYear()}`
|
|
665
|
-
|
|
568
|
+
}
|
|
666
569
|
|
|
667
|
-
private _getWeekKey(date: string): string {
|
|
668
|
-
const dateObj = new Date(date)
|
|
570
|
+
private _getWeekKey(date: string): string { const dateObj = new Date(date)
|
|
669
571
|
const dayOfWeek = dateObj.getDay()
|
|
670
572
|
const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1
|
|
671
573
|
const monday = new Date(dateObj)
|
|
672
574
|
monday.setDate(dateObj.getDate() - daysToMonday)
|
|
673
575
|
return monday.toLocaleDateString('sv-SE')
|
|
674
|
-
|
|
576
|
+
}
|
|
675
577
|
|
|
676
|
-
private _getMondayOfWeek(date: string): string {
|
|
677
|
-
const dateObj = new Date(date)
|
|
578
|
+
private _getMondayOfWeek(date: string): string { const dateObj = new Date(date)
|
|
678
579
|
const dayOfWeek = dateObj.getDay()
|
|
679
580
|
const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1
|
|
680
581
|
const monday = new Date(dateObj)
|
|
681
582
|
monday.setDate(dateObj.getDate() - daysToMonday)
|
|
682
583
|
return monday.toLocaleDateString('sv-SE')
|
|
683
|
-
|
|
584
|
+
}
|
|
684
585
|
|
|
685
|
-
private _getFirstDayOfMonth(date: string): string {
|
|
686
|
-
const dateObj = new Date(date)
|
|
586
|
+
private _getFirstDayOfMonth(date: string): string { const dateObj = new Date(date)
|
|
687
587
|
return new Date(dateObj.getFullYear(), dateObj.getMonth(), 1).toLocaleDateString('sv-SE')
|
|
688
|
-
|
|
588
|
+
}
|
|
689
589
|
|
|
690
|
-
private _getFirstDayOfQuarter(date: string): string {
|
|
691
|
-
const dateObj = new Date(date)
|
|
590
|
+
private _getFirstDayOfQuarter(date: string): string { const dateObj = new Date(date)
|
|
692
591
|
const quarter = Math.floor(dateObj.getMonth() / 3)
|
|
693
592
|
const firstMonthOfQuarter = quarter * 3
|
|
694
593
|
return new Date(dateObj.getFullYear(), firstMonthOfQuarter, 1).toLocaleDateString('sv-SE')
|
|
695
|
-
|
|
594
|
+
}
|
|
696
595
|
|
|
697
|
-
private _getFirstDayOfYear(date: string): string {
|
|
698
|
-
const dateObj = new Date(date)
|
|
596
|
+
private _getFirstDayOfYear(date: string): string { const dateObj = new Date(date)
|
|
699
597
|
return new Date(dateObj.getFullYear(), 0, 1).toLocaleDateString('sv-SE')
|
|
700
|
-
|
|
598
|
+
}
|
|
701
599
|
|
|
702
|
-
private _normalizeDateByPeriodType(date: string, periodType: string): string {
|
|
703
|
-
console.log('Normalizing date:', date, 'for periodType:', periodType)
|
|
600
|
+
private _normalizeDateByPeriodType(date: string, periodType: string): string { console.log('Normalizing date:', date, 'for periodType:', periodType)
|
|
704
601
|
|
|
705
602
|
const dateObj = new Date(date)
|
|
706
603
|
|
|
707
|
-
switch (periodType) {
|
|
708
|
-
case 'DAY':
|
|
604
|
+
switch (periodType) { case 'DAY':
|
|
709
605
|
console.log('DAY - returning original date:', date)
|
|
710
606
|
return date // 그대로 사용
|
|
711
607
|
case 'WEEK':
|
|
@@ -736,28 +632,24 @@ export class KpiMetricValueEditorPage extends connect(store)(localize(i18next)(S
|
|
|
736
632
|
default:
|
|
737
633
|
console.log('DEFAULT - returning original date:', date)
|
|
738
634
|
return date // 기본값
|
|
739
|
-
|
|
740
|
-
|
|
635
|
+
}
|
|
636
|
+
}
|
|
741
637
|
|
|
742
|
-
private _cancel() {
|
|
743
|
-
// 편집 취소 로직
|
|
638
|
+
private _cancel() { // 편집 취소 로직
|
|
744
639
|
this.editingCell = null
|
|
745
640
|
this._loadData() // 원본 데이터로 복원
|
|
746
|
-
|
|
641
|
+
}
|
|
747
642
|
|
|
748
|
-
async pageInitialized(lifecycle: any) {
|
|
749
|
-
|
|
750
|
-
if (!this.startDate) {
|
|
751
|
-
const today = new Date()
|
|
643
|
+
async pageInitialized(lifecycle: any) { // 기본값 설정 - 지난 1개월
|
|
644
|
+
if (!this.startDate) { const today = new Date()
|
|
752
645
|
const oneMonthAgo = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate())
|
|
753
646
|
this.startDate = oneMonthAgo.toLocaleDateString('sv-SE')
|
|
754
|
-
|
|
755
|
-
if (!this.endDate) {
|
|
756
|
-
const today = new Date()
|
|
647
|
+
}
|
|
648
|
+
if (!this.endDate) { const today = new Date()
|
|
757
649
|
this.endDate = today.toLocaleDateString('sv-SE')
|
|
758
|
-
|
|
650
|
+
}
|
|
759
651
|
|
|
760
652
|
// 페이지 초기화 시 자동으로 데이터 로드
|
|
761
653
|
await this._loadData()
|
|
762
|
-
|
|
654
|
+
}
|
|
763
655
|
}
|