@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,25 +3,21 @@ 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 KpiStatisticData {
|
|
17
|
-
kpi: {
|
|
18
|
-
id: string
|
|
15
|
+
interface KpiStatisticData { kpi: { id: string
|
|
19
16
|
name: string
|
|
20
|
-
|
|
17
|
+
}
|
|
21
18
|
valueDate: string
|
|
22
19
|
periodType: string
|
|
23
|
-
statistics: {
|
|
24
|
-
count?: number
|
|
20
|
+
statistics: { count?: number
|
|
25
21
|
sum?: number
|
|
26
22
|
range?: number
|
|
27
23
|
mean?: number
|
|
@@ -36,61 +32,53 @@ interface KpiStatisticData {
|
|
|
36
32
|
lowerFence?: number
|
|
37
33
|
upperFence?: number
|
|
38
34
|
isDirty?: boolean
|
|
39
|
-
|
|
35
|
+
}
|
|
40
36
|
}
|
|
41
37
|
|
|
42
|
-
interface EditorCell {
|
|
43
|
-
field: string
|
|
38
|
+
interface EditorCell { field: string
|
|
44
39
|
value: number | null
|
|
45
40
|
isEditable: boolean
|
|
46
41
|
isHighlighted: boolean
|
|
47
42
|
}
|
|
48
43
|
|
|
49
44
|
@customElement('kpi-statistic-editor-page')
|
|
50
|
-
export class KpiStatisticEditorPage extends
|
|
51
|
-
static styles = [
|
|
45
|
+
export class KpiStatisticEditorPage extends localize(i18next)(ScopedElementsMixin(PageView)) { static styles = [
|
|
52
46
|
CommonHeaderStyles,
|
|
53
47
|
ScrollbarStyles,
|
|
54
48
|
css`
|
|
55
|
-
:host {
|
|
56
|
-
display: flex;
|
|
49
|
+
:host { display: flex;
|
|
57
50
|
flex-direction: column;
|
|
58
51
|
padding: 20px;
|
|
59
52
|
overflow-x: auto;
|
|
60
|
-
|
|
53
|
+
}
|
|
61
54
|
|
|
62
|
-
.header {
|
|
63
|
-
display: flex;
|
|
55
|
+
.header { display: flex;
|
|
64
56
|
gap: 16px;
|
|
65
57
|
align-items: center;
|
|
66
58
|
margin-bottom: 20px;
|
|
67
59
|
padding: 16px;
|
|
68
60
|
background: var(--md-sys-color-surface-container);
|
|
69
61
|
border-radius: 8px;
|
|
70
|
-
|
|
62
|
+
}
|
|
71
63
|
|
|
72
|
-
.controls {
|
|
73
|
-
display: flex;
|
|
64
|
+
.controls { display: flex;
|
|
74
65
|
gap: 12px;
|
|
75
66
|
align-items: center;
|
|
76
67
|
flex-wrap: wrap;
|
|
77
|
-
|
|
68
|
+
}
|
|
78
69
|
|
|
79
|
-
.table-container {
|
|
80
|
-
flex: 1;
|
|
70
|
+
.table-container { flex: 1;
|
|
81
71
|
overflow: auto;
|
|
82
72
|
border: 1px solid var(--md-sys-color-outline);
|
|
83
73
|
border-radius: 8px;
|
|
84
|
-
|
|
74
|
+
}
|
|
85
75
|
|
|
86
|
-
table {
|
|
87
|
-
width: 100%;
|
|
76
|
+
table { width: 100%;
|
|
88
77
|
border-collapse: collapse;
|
|
89
78
|
min-width: max-content;
|
|
90
|
-
|
|
79
|
+
}
|
|
91
80
|
|
|
92
|
-
th {
|
|
93
|
-
background: var(--md-sys-color-surface-container-low);
|
|
81
|
+
th { background: var(--md-sys-color-surface-container-low);
|
|
94
82
|
font-weight: 500;
|
|
95
83
|
padding: 8px 12px;
|
|
96
84
|
border: 1px solid var(--md-sys-color-outline-variant);
|
|
@@ -98,148 +86,127 @@ export class KpiStatisticEditorPage extends connect(store)(localize(i18next)(Sco
|
|
|
98
86
|
height: 60px;
|
|
99
87
|
vertical-align: middle;
|
|
100
88
|
text-align: center;
|
|
101
|
-
|
|
89
|
+
}
|
|
102
90
|
|
|
103
|
-
td {
|
|
104
|
-
padding: 8px 12px;
|
|
91
|
+
td { padding: 8px 12px;
|
|
105
92
|
border: 1px solid var(--md-sys-color-outline-variant);
|
|
106
93
|
min-width: 120px;
|
|
107
94
|
height: 60px;
|
|
108
95
|
text-align: center;
|
|
109
96
|
vertical-align: middle;
|
|
110
|
-
|
|
97
|
+
}
|
|
111
98
|
|
|
112
|
-
.kpi-header {
|
|
113
|
-
position: sticky;
|
|
99
|
+
.kpi-header { position: sticky;
|
|
114
100
|
left: 0;
|
|
115
101
|
top: 0;
|
|
116
102
|
z-index: 3;
|
|
117
103
|
min-width: 200px;
|
|
118
104
|
text-align: left;
|
|
119
|
-
|
|
105
|
+
}
|
|
120
106
|
|
|
121
|
-
.field-header {
|
|
122
|
-
position: sticky;
|
|
107
|
+
.field-header { position: sticky;
|
|
123
108
|
left: 0;
|
|
124
109
|
top: 0;
|
|
125
110
|
z-index: 2;
|
|
126
111
|
min-width: 200px;
|
|
127
112
|
text-align: center;
|
|
128
|
-
|
|
113
|
+
}
|
|
129
114
|
|
|
130
|
-
.kpi-name {
|
|
131
|
-
position: sticky;
|
|
115
|
+
.kpi-name { position: sticky;
|
|
132
116
|
left: 0;
|
|
133
117
|
background: var(--md-sys-color-surface);
|
|
134
118
|
font-weight: 500;
|
|
135
119
|
min-width: 200px;
|
|
136
120
|
text-align: left;
|
|
137
121
|
z-index: 2;
|
|
138
|
-
|
|
122
|
+
}
|
|
139
123
|
|
|
140
|
-
tr:hover {
|
|
141
|
-
|
|
142
|
-
}
|
|
124
|
+
tr:hover { background: var(--md-sys-color-surface-container-high);
|
|
125
|
+
}
|
|
143
126
|
|
|
144
|
-
td.editable-cell {
|
|
145
|
-
cursor: pointer;
|
|
127
|
+
td.editable-cell { cursor: pointer;
|
|
146
128
|
background: var(--md-sys-color-primary-container);
|
|
147
129
|
color: var(--md-sys-color-on-primary-container);
|
|
148
|
-
|
|
130
|
+
}
|
|
149
131
|
|
|
150
|
-
td.editable-cell:hover {
|
|
151
|
-
|
|
152
|
-
}
|
|
132
|
+
td.editable-cell:hover { background: var(--md-sys-color-primary-container-high);
|
|
133
|
+
}
|
|
153
134
|
|
|
154
|
-
td.highlighted-cell {
|
|
155
|
-
background: var(--md-sys-color-secondary-container);
|
|
135
|
+
td.highlighted-cell { background: var(--md-sys-color-secondary-container);
|
|
156
136
|
color: var(--md-sys-color-on-secondary-container);
|
|
157
137
|
font-weight: 500;
|
|
158
|
-
|
|
138
|
+
}
|
|
159
139
|
|
|
160
|
-
td.highlighted-cell:hover {
|
|
161
|
-
|
|
162
|
-
}
|
|
140
|
+
td.highlighted-cell:hover { background: var(--md-sys-color-secondary-container-high);
|
|
141
|
+
}
|
|
163
142
|
|
|
164
|
-
td.disabled-cell {
|
|
165
|
-
background: var(--md-sys-color-surface-container);
|
|
143
|
+
td.disabled-cell { background: var(--md-sys-color-surface-container);
|
|
166
144
|
color: var(--md-sys-color-on-surface-variant);
|
|
167
145
|
cursor: not-allowed;
|
|
168
|
-
|
|
146
|
+
}
|
|
169
147
|
|
|
170
|
-
.value-input {
|
|
171
|
-
width: 100%;
|
|
148
|
+
.value-input { width: 100%;
|
|
172
149
|
text-align: center;
|
|
173
150
|
border: none;
|
|
174
151
|
background: transparent;
|
|
175
152
|
color: inherit;
|
|
176
153
|
font-size: 12px;
|
|
177
154
|
padding: 2px;
|
|
178
|
-
|
|
155
|
+
}
|
|
179
156
|
|
|
180
|
-
.value-input:focus {
|
|
181
|
-
outline: 2px solid var(--md-sys-color-primary);
|
|
157
|
+
.value-input:focus { outline: 2px solid var(--md-sys-color-primary);
|
|
182
158
|
border-radius: 4px;
|
|
183
|
-
|
|
159
|
+
}
|
|
184
160
|
|
|
185
|
-
.period-badge {
|
|
186
|
-
font-size: 10px;
|
|
161
|
+
.period-badge { font-size: 10px;
|
|
187
162
|
padding: 2px 6px;
|
|
188
163
|
border-radius: 4px;
|
|
189
164
|
background: var(--md-sys-color-tertiary-container);
|
|
190
165
|
color: var(--md-sys-color-on-tertiary-container);
|
|
191
166
|
margin-left: 8px;
|
|
192
|
-
|
|
167
|
+
}
|
|
193
168
|
|
|
194
|
-
.loading {
|
|
195
|
-
display: flex;
|
|
169
|
+
.loading { display: flex;
|
|
196
170
|
justify-content: center;
|
|
197
171
|
align-items: center;
|
|
198
172
|
height: 200px;
|
|
199
173
|
color: var(--md-sys-color-on-surface-variant);
|
|
200
|
-
|
|
174
|
+
}
|
|
201
175
|
|
|
202
|
-
.error {
|
|
203
|
-
color: var(--md-sys-color-error);
|
|
176
|
+
.error { color: var(--md-sys-color-error);
|
|
204
177
|
padding: 16px;
|
|
205
178
|
text-align: center;
|
|
206
|
-
|
|
179
|
+
}
|
|
207
180
|
|
|
208
|
-
.legend {
|
|
209
|
-
display: flex;
|
|
181
|
+
.legend { display: flex;
|
|
210
182
|
gap: 16px;
|
|
211
183
|
margin-top: 16px;
|
|
212
184
|
font-size: 12px;
|
|
213
|
-
|
|
185
|
+
}
|
|
214
186
|
|
|
215
|
-
.legend-item {
|
|
216
|
-
display: flex;
|
|
187
|
+
.legend-item { display: flex;
|
|
217
188
|
align-items: center;
|
|
218
189
|
gap: 4px;
|
|
219
|
-
|
|
190
|
+
}
|
|
220
191
|
|
|
221
|
-
.legend-color {
|
|
222
|
-
width: 16px;
|
|
192
|
+
.legend-color { width: 16px;
|
|
223
193
|
height: 16px;
|
|
224
194
|
border-radius: 2px;
|
|
225
|
-
|
|
195
|
+
}
|
|
226
196
|
|
|
227
|
-
.field-group {
|
|
228
|
-
display: flex;
|
|
197
|
+
.field-group { display: flex;
|
|
229
198
|
flex-direction: column;
|
|
230
199
|
gap: 4px;
|
|
231
|
-
|
|
200
|
+
}
|
|
232
201
|
|
|
233
|
-
.field-name {
|
|
234
|
-
font-size: 10px;
|
|
202
|
+
.field-name { font-size: 10px;
|
|
235
203
|
color: var(--md-sys-color-on-surface-variant);
|
|
236
204
|
font-weight: 500;
|
|
237
|
-
|
|
205
|
+
}
|
|
238
206
|
|
|
239
|
-
.field-value {
|
|
240
|
-
font-size: 12px;
|
|
207
|
+
.field-value { font-size: 12px;
|
|
241
208
|
font-weight: 500;
|
|
242
|
-
|
|
209
|
+
}
|
|
243
210
|
`
|
|
244
211
|
]
|
|
245
212
|
|
|
@@ -271,42 +238,35 @@ export class KpiStatisticEditorPage extends connect(store)(localize(i18next)(Sco
|
|
|
271
238
|
{ name: 'upperFence', label: 'Upper Fence', group: 'fence' }
|
|
272
239
|
]
|
|
273
240
|
|
|
274
|
-
get context() {
|
|
275
|
-
return {
|
|
276
|
-
title: i18next.t('title.kpi statistic editor'),
|
|
241
|
+
get context() { return { title: i18next.t('title.kpi statistic editor'),
|
|
277
242
|
actions: [
|
|
278
|
-
{
|
|
279
|
-
title: i18next.t('button.save'),
|
|
243
|
+
{ title: i18next.t('button.save'),
|
|
280
244
|
action: this._saveStatistics.bind(this),
|
|
281
245
|
...CommonButtonStyles.save
|
|
282
|
-
|
|
283
|
-
{
|
|
284
|
-
title: i18next.t('button.cancel'),
|
|
246
|
+
},
|
|
247
|
+
{ title: i18next.t('button.cancel'),
|
|
285
248
|
action: this._cancel.bind(this),
|
|
286
249
|
...CommonButtonStyles.cancel
|
|
287
|
-
|
|
250
|
+
}
|
|
288
251
|
]
|
|
289
|
-
|
|
290
|
-
|
|
252
|
+
}
|
|
253
|
+
}
|
|
291
254
|
|
|
292
|
-
render() {
|
|
293
|
-
if (this.loading) {
|
|
294
|
-
return html`
|
|
255
|
+
render() { if (this.loading) { return html`
|
|
295
256
|
<div class="loading">
|
|
296
257
|
<md-icon>hourglass_empty</md-icon>
|
|
297
258
|
<span>데이터를 불러오는 중...</span>
|
|
298
259
|
</div>
|
|
299
260
|
`
|
|
300
|
-
|
|
261
|
+
}
|
|
301
262
|
|
|
302
|
-
if (this.error) {
|
|
303
|
-
return html`
|
|
263
|
+
if (this.error) { return html`
|
|
304
264
|
<div class="error">
|
|
305
265
|
<md-icon>error</md-icon>
|
|
306
266
|
<span>${this.error}</span>
|
|
307
267
|
</div>
|
|
308
268
|
`
|
|
309
|
-
|
|
269
|
+
}
|
|
310
270
|
|
|
311
271
|
return html`
|
|
312
272
|
<div class="header">
|
|
@@ -398,38 +358,31 @@ export class KpiStatisticEditorPage extends connect(store)(localize(i18next)(Sco
|
|
|
398
358
|
</div>
|
|
399
359
|
</div>
|
|
400
360
|
`
|
|
401
|
-
|
|
361
|
+
}
|
|
402
362
|
|
|
403
|
-
private _getCellClass(kpi: KpiStatisticData, fieldName: string): string {
|
|
404
|
-
const isEditable = this._isFieldEditable(fieldName)
|
|
363
|
+
private _getCellClass(kpi: KpiStatisticData, fieldName: string): string { const isEditable = this._isFieldEditable(fieldName)
|
|
405
364
|
const isHighlighted = this._isFieldHighlighted(fieldName)
|
|
406
365
|
|
|
407
|
-
if (!isEditable) {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
return 'highlighted-cell'
|
|
412
|
-
}
|
|
366
|
+
if (!isEditable) { return 'disabled-cell'
|
|
367
|
+
}
|
|
368
|
+
if (isHighlighted) { return 'highlighted-cell'
|
|
369
|
+
}
|
|
413
370
|
return 'editable-cell'
|
|
414
|
-
|
|
371
|
+
}
|
|
415
372
|
|
|
416
|
-
private _isFieldEditable(fieldName: string): boolean {
|
|
417
|
-
// 모든 필드를 편집 가능하게 설정 (필요에 따라 제한 가능)
|
|
373
|
+
private _isFieldEditable(fieldName: string): boolean { // 모든 필드를 편집 가능하게 설정 (필요에 따라 제한 가능)
|
|
418
374
|
return true
|
|
419
|
-
|
|
375
|
+
}
|
|
420
376
|
|
|
421
|
-
private _isFieldHighlighted(fieldName: string): boolean {
|
|
422
|
-
// 중요 필드들을 하이라이트
|
|
377
|
+
private _isFieldHighlighted(fieldName: string): boolean { // 중요 필드들을 하이라이트
|
|
423
378
|
const importantFields = ['count', 'mean', 'median', 'minimum', 'maximum', 'standardDeviation']
|
|
424
379
|
return importantFields.includes(fieldName)
|
|
425
|
-
|
|
380
|
+
}
|
|
426
381
|
|
|
427
|
-
private _renderCellContent(kpi: KpiStatisticData, fieldName: string) {
|
|
428
|
-
const isEditing = this.editingCell?.kpi?.id === kpi.kpi.id && this.editingCell?.field === fieldName
|
|
382
|
+
private _renderCellContent(kpi: KpiStatisticData, fieldName: string) { const isEditing = this.editingCell?.kpi?.id === kpi.kpi.id && this.editingCell?.field === fieldName
|
|
429
383
|
const value = kpi.statistics[fieldName]
|
|
430
384
|
|
|
431
|
-
if (isEditing) {
|
|
432
|
-
return html`
|
|
385
|
+
if (isEditing) { return html`
|
|
433
386
|
<input
|
|
434
387
|
class="value-input"
|
|
435
388
|
type="number"
|
|
@@ -440,76 +393,59 @@ export class KpiStatisticEditorPage extends connect(store)(localize(i18next)(Sco
|
|
|
440
393
|
autofocus
|
|
441
394
|
/>
|
|
442
395
|
`
|
|
443
|
-
|
|
396
|
+
}
|
|
444
397
|
|
|
445
398
|
return html`
|
|
446
399
|
<span style="color: ${value !== null && value !== undefined ? 'inherit' : '#999'};">
|
|
447
400
|
${value !== null && value !== undefined ? value.toLocaleString() : '클릭하여 입력'}
|
|
448
401
|
</span>
|
|
449
402
|
`
|
|
450
|
-
|
|
403
|
+
}
|
|
451
404
|
|
|
452
|
-
private _startEdit(kpiId: string, fieldName: string) {
|
|
453
|
-
|
|
454
|
-
}
|
|
405
|
+
private _startEdit(kpiId: string, fieldName: string) { this.editingCell = { kpi: { id: kpiId }, field: fieldName }
|
|
406
|
+
}
|
|
455
407
|
|
|
456
|
-
private _finishEdit(kpiId: string, fieldName: string, value: number | null) {
|
|
457
|
-
|
|
458
|
-
if (kpi) {
|
|
459
|
-
const originalValue = this._findExistingStatistic(kpiId)?.[fieldName]
|
|
408
|
+
private _finishEdit(kpiId: string, fieldName: string, value: number | null) { const kpi = this.kpis.find(k => k.kpi.id === kpiId)
|
|
409
|
+
if (kpi) { const originalValue = this._findExistingStatistic(kpiId)?.[fieldName]
|
|
460
410
|
const isChanged = originalValue !== value
|
|
461
411
|
|
|
462
412
|
kpi.statistics[fieldName] = value
|
|
463
413
|
kpi.statistics.isDirty = isChanged
|
|
464
|
-
|
|
414
|
+
}
|
|
465
415
|
this.editingCell = null
|
|
466
|
-
|
|
416
|
+
}
|
|
467
417
|
|
|
468
|
-
private async _loadData() {
|
|
469
|
-
if (!this.valueDate) {
|
|
470
|
-
this.error = '값 날짜를 입력해주세요.'
|
|
418
|
+
private async _loadData() { if (!this.valueDate) { this.error = '값 날짜를 입력해주세요.'
|
|
471
419
|
return
|
|
472
|
-
|
|
420
|
+
}
|
|
473
421
|
|
|
474
422
|
this.loading = true
|
|
475
423
|
this.error = ''
|
|
476
424
|
|
|
477
|
-
try {
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
query: gql`
|
|
481
|
-
query ($filters: [Filter!]) {
|
|
482
|
-
kpis(filters: $filters) {
|
|
483
|
-
items {
|
|
484
|
-
id
|
|
425
|
+
try { // KPI 목록 조회
|
|
426
|
+
const kpisResponse = await client.query({ query: gql`
|
|
427
|
+
query ($filters: [Filter!]) { kpis(filters: $filters) { items { id
|
|
485
428
|
name
|
|
486
429
|
periodType
|
|
487
430
|
active
|
|
488
|
-
category: parent {
|
|
489
|
-
id
|
|
431
|
+
category: parent { id
|
|
490
432
|
name
|
|
491
|
-
|
|
492
|
-
|
|
433
|
+
}
|
|
434
|
+
}
|
|
493
435
|
total
|
|
494
|
-
|
|
495
|
-
|
|
436
|
+
}
|
|
437
|
+
}
|
|
496
438
|
`,
|
|
497
|
-
variables: {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
})
|
|
439
|
+
variables: { filters: [{ name: 'active', operator: 'eq', value: true }]
|
|
440
|
+
}
|
|
441
|
+
})
|
|
501
442
|
|
|
502
443
|
// 기존 KPI Statistic 데이터 조회
|
|
503
|
-
const statisticsResponse = await client.query({
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
kpiStatistics(filters: $filters) {
|
|
507
|
-
items {
|
|
508
|
-
id
|
|
509
|
-
kpi {
|
|
510
|
-
id
|
|
444
|
+
const statisticsResponse = await client.query({ query: gql`
|
|
445
|
+
query ($filters: [Filter!]) { kpiStatistics(filters: $filters) { items { id
|
|
446
|
+
kpi { id
|
|
511
447
|
name
|
|
512
|
-
|
|
448
|
+
}
|
|
513
449
|
valueDate
|
|
514
450
|
periodType
|
|
515
451
|
count
|
|
@@ -528,18 +464,17 @@ export class KpiStatisticEditorPage extends connect(store)(localize(i18next)(Sco
|
|
|
528
464
|
upperFence
|
|
529
465
|
additionalStatistics
|
|
530
466
|
metadata
|
|
531
|
-
|
|
467
|
+
}
|
|
532
468
|
total
|
|
533
|
-
|
|
534
|
-
|
|
469
|
+
}
|
|
470
|
+
}
|
|
535
471
|
`,
|
|
536
|
-
variables: {
|
|
537
|
-
filters: [
|
|
472
|
+
variables: { filters: [
|
|
538
473
|
{ name: 'valueDate', operator: 'eq', value: this.valueDate },
|
|
539
474
|
{ name: 'periodType', operator: 'eq', value: this.periodType }
|
|
540
475
|
]
|
|
541
|
-
|
|
542
|
-
|
|
476
|
+
}
|
|
477
|
+
})
|
|
543
478
|
|
|
544
479
|
// KPI 목록을 기준으로 데이터 구성 (카테고리별로 필터링)
|
|
545
480
|
console.log('KPI 원본 데이터:', kpisResponse.data.kpis.items)
|
|
@@ -549,12 +484,10 @@ export class KpiStatisticEditorPage extends connect(store)(localize(i18next)(Sco
|
|
|
549
484
|
|
|
550
485
|
console.log('필터링된 KPI:', filteredKpis)
|
|
551
486
|
|
|
552
|
-
this.kpis = filteredKpis.map((kpi: any) => ({
|
|
553
|
-
kpi: kpi,
|
|
487
|
+
this.kpis = filteredKpis.map((kpi: any) => ({ kpi: kpi,
|
|
554
488
|
valueDate: this.valueDate,
|
|
555
489
|
periodType: this.periodType,
|
|
556
|
-
statistics: {
|
|
557
|
-
count: null,
|
|
490
|
+
statistics: { count: null,
|
|
558
491
|
sum: null,
|
|
559
492
|
range: null,
|
|
560
493
|
mean: null,
|
|
@@ -569,20 +502,17 @@ export class KpiStatisticEditorPage extends connect(store)(localize(i18next)(Sco
|
|
|
569
502
|
lowerFence: null,
|
|
570
503
|
upperFence: null,
|
|
571
504
|
isDirty: false
|
|
572
|
-
|
|
573
|
-
|
|
505
|
+
}
|
|
506
|
+
}))
|
|
574
507
|
|
|
575
508
|
// 기존 KPI Statistic 데이터 저장
|
|
576
509
|
this._existingStatistics = statisticsResponse.data.kpiStatistics.items
|
|
577
510
|
console.log('기존 통계 데이터:', this._existingStatistics)
|
|
578
511
|
|
|
579
512
|
// 기존 통계 데이터를 해당 KPI에 매핑
|
|
580
|
-
statisticsResponse.data.kpiStatistics.items.forEach((statistic: any) => {
|
|
581
|
-
const kpi = this.kpis.find(k => k.kpi.id === statistic.kpi.id) // KPI ID로 매칭
|
|
513
|
+
statisticsResponse.data.kpiStatistics.items.forEach((statistic: any) => { const kpi = this.kpis.find(k => k.kpi.id === statistic.kpi.id) // KPI ID로 매칭
|
|
582
514
|
console.log(`통계 데이터 매핑: statistic.kpi.id=${statistic.kpi.id}, 찾은 KPI:`, kpi?.kpi.name || '없음')
|
|
583
|
-
if (kpi) {
|
|
584
|
-
kpi.statistics = {
|
|
585
|
-
count: statistic.count,
|
|
515
|
+
if (kpi) { kpi.statistics = { count: statistic.count,
|
|
586
516
|
sum: statistic.sum,
|
|
587
517
|
range: statistic.range,
|
|
588
518
|
mean: statistic.mean,
|
|
@@ -597,9 +527,9 @@ export class KpiStatisticEditorPage extends connect(store)(localize(i18next)(Sco
|
|
|
597
527
|
lowerFence: statistic.lowerFence,
|
|
598
528
|
upperFence: statistic.upperFence,
|
|
599
529
|
isDirty: false
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
})
|
|
603
533
|
|
|
604
534
|
console.log('KPI 총 개수:', kpisResponse.data.kpis.total)
|
|
605
535
|
console.log('KPI 목록:', kpisResponse.data.kpis.items)
|
|
@@ -608,112 +538,87 @@ export class KpiStatisticEditorPage extends connect(store)(localize(i18next)(Sco
|
|
|
608
538
|
console.log('최종 KPI 배열 길이:', this.kpis.length)
|
|
609
539
|
|
|
610
540
|
this.requestUpdate()
|
|
611
|
-
|
|
612
|
-
console.error('데이터 로드 중 오류:', error)
|
|
541
|
+
} catch (error) { console.error('데이터 로드 중 오류:', error)
|
|
613
542
|
this.error = '데이터를 불러오는 중 오류가 발생했습니다.'
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
// dirty 상태인 데이터만 처리
|
|
625
|
-
if (kpi.statistics.isDirty) {
|
|
626
|
-
const existingStatistic = this._findExistingStatistic(kpi.kpi.id)
|
|
627
|
-
|
|
628
|
-
if (existingStatistic) {
|
|
629
|
-
// 기존 데이터 업데이트
|
|
543
|
+
} finally { this.loading = false
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
private async _saveStatistics() { try { const patches: any[] = []
|
|
548
|
+
|
|
549
|
+
this.kpis.forEach(kpi => { // dirty 상태인 데이터만 처리
|
|
550
|
+
if (kpi.statistics.isDirty) { const existingStatistic = this._findExistingStatistic(kpi.kpi.id)
|
|
551
|
+
|
|
552
|
+
if (existingStatistic) { // 기존 데이터 업데이트
|
|
630
553
|
const { isDirty, ...statisticsWithoutDirty } = kpi.statistics
|
|
631
|
-
patches.push({
|
|
632
|
-
id: existingStatistic.id,
|
|
554
|
+
patches.push({ id: existingStatistic.id,
|
|
633
555
|
...statisticsWithoutDirty,
|
|
634
556
|
cuFlag: 'M'
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
// 새로운 데이터 생성
|
|
557
|
+
})
|
|
558
|
+
} else { // 새로운 데이터 생성
|
|
638
559
|
const { isDirty, ...statisticsWithoutDirty } = kpi.statistics
|
|
639
|
-
patches.push({
|
|
640
|
-
|
|
641
|
-
id: kpi.kpi.id
|
|
642
|
-
},
|
|
560
|
+
patches.push({ kpi: { id: kpi.kpi.id
|
|
561
|
+
},
|
|
643
562
|
valueDate: kpi.valueDate,
|
|
644
563
|
periodType: kpi.periodType,
|
|
645
564
|
...statisticsWithoutDirty,
|
|
646
565
|
additionalStatistics: {},
|
|
647
|
-
metadata: {
|
|
648
|
-
calculationMethod: 'manual',
|
|
566
|
+
metadata: { calculationMethod: 'manual',
|
|
649
567
|
lastCalculated: new Date(),
|
|
650
568
|
dataCount: kpi.statistics.count || 0
|
|
651
|
-
|
|
569
|
+
},
|
|
652
570
|
cuFlag: '+'
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
571
|
+
})
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
})
|
|
657
575
|
|
|
658
|
-
if (patches.length === 0) {
|
|
659
|
-
notify({ message: '저장할 데이터가 없습니다.' })
|
|
576
|
+
if (patches.length === 0) { notify({ message: '저장할 데이터가 없습니다.' })
|
|
660
577
|
return
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
const response = await client.mutate({
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
updateMultipleKpiStatistic(patches: $patches) {
|
|
667
|
-
id
|
|
668
|
-
kpi {
|
|
669
|
-
id
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
const response = await client.mutate({ mutation: gql`
|
|
581
|
+
mutation ($patches: [KpiStatisticPatch!]!) { updateMultipleKpiStatistic(patches: $patches) { id
|
|
582
|
+
kpi { id
|
|
670
583
|
name
|
|
671
|
-
|
|
584
|
+
}
|
|
672
585
|
valueDate
|
|
673
586
|
periodType
|
|
674
|
-
|
|
675
|
-
|
|
587
|
+
}
|
|
588
|
+
}
|
|
676
589
|
`,
|
|
677
590
|
variables: { patches }
|
|
678
|
-
|
|
591
|
+
})
|
|
679
592
|
|
|
680
|
-
if (!response.errors) {
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
kpi.statistics.isDirty = false
|
|
684
|
-
})
|
|
593
|
+
if (!response.errors) { // 저장 후 dirty 상태 해제
|
|
594
|
+
this.kpis.forEach(kpi => { kpi.statistics.isDirty = false
|
|
595
|
+
})
|
|
685
596
|
|
|
686
597
|
notify({ message: 'KPI 통계값이 성공적으로 저장되었습니다.' })
|
|
687
598
|
this.requestUpdate()
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
console.error('저장 중 오류:', error)
|
|
599
|
+
}
|
|
600
|
+
} catch (error) { console.error('저장 중 오류:', error)
|
|
691
601
|
notify({ message: '저장 중 오류가 발생했습니다.' })
|
|
692
|
-
|
|
693
|
-
|
|
602
|
+
}
|
|
603
|
+
}
|
|
694
604
|
|
|
695
|
-
private _findExistingStatistic(kpiId: string) {
|
|
696
|
-
|
|
697
|
-
}
|
|
605
|
+
private _findExistingStatistic(kpiId: string) { return this._existingStatistics?.find((s: any) => s.kpi === kpiId)
|
|
606
|
+
}
|
|
698
607
|
|
|
699
|
-
private _onTargetDateChange(targetDate: string) {
|
|
700
|
-
this.targetDate = targetDate
|
|
608
|
+
private _onTargetDateChange(targetDate: string) { this.targetDate = targetDate
|
|
701
609
|
this._calculateDateRange()
|
|
702
|
-
|
|
610
|
+
}
|
|
703
611
|
|
|
704
|
-
private _onPeriodChange(periodType: string) {
|
|
705
|
-
this.periodType = periodType
|
|
612
|
+
private _onPeriodChange(periodType: string) { this.periodType = periodType
|
|
706
613
|
this._calculateDateRange()
|
|
707
|
-
|
|
614
|
+
}
|
|
708
615
|
|
|
709
|
-
private _calculateDateRange() {
|
|
710
|
-
if (!this.targetDate || !this.periodType) return
|
|
616
|
+
private _calculateDateRange() { if (!this.targetDate || !this.periodType) return
|
|
711
617
|
|
|
712
618
|
const target = new Date(this.targetDate)
|
|
713
619
|
let valueDate: string
|
|
714
620
|
|
|
715
|
-
switch (this.periodType) {
|
|
716
|
-
case 'DAY':
|
|
621
|
+
switch (this.periodType) { case 'DAY':
|
|
717
622
|
valueDate = target.toISOString().split('T')[0]
|
|
718
623
|
break
|
|
719
624
|
case 'WEEK':
|
|
@@ -736,25 +641,22 @@ export class KpiStatisticEditorPage extends connect(store)(localize(i18next)(Sco
|
|
|
736
641
|
break
|
|
737
642
|
default:
|
|
738
643
|
valueDate = target.toISOString().split('T')[0]
|
|
739
|
-
|
|
644
|
+
}
|
|
740
645
|
|
|
741
646
|
this.valueDate = valueDate
|
|
742
|
-
|
|
647
|
+
}
|
|
743
648
|
|
|
744
|
-
private _cancel() {
|
|
745
|
-
this.editingCell = null
|
|
649
|
+
private _cancel() { this.editingCell = null
|
|
746
650
|
this._loadData() // 원본 데이터로 복원
|
|
747
|
-
|
|
651
|
+
}
|
|
748
652
|
|
|
749
|
-
async pageInitialized(lifecycle: any) {
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
this.targetDate = new Date().toLocaleDateString('sv-SE')
|
|
753
|
-
}
|
|
653
|
+
async pageInitialized(lifecycle: any) { // 기본값 설정 - 현재 날짜를 기준으로
|
|
654
|
+
if (!this.targetDate) { this.targetDate = new Date().toLocaleDateString('sv-SE')
|
|
655
|
+
}
|
|
754
656
|
|
|
755
657
|
// 기간 유형에 따라 날짜 범위 계산
|
|
756
658
|
this._calculateDateRange()
|
|
757
659
|
|
|
758
660
|
await this._loadData()
|
|
759
|
-
|
|
661
|
+
}
|
|
760
662
|
}
|