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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/client/pages/kpi/kpi-list-page.ts +339 -525
  2. package/client/pages/kpi/kpi-tree-page.ts +135 -207
  3. package/client/pages/kpi-metric/kpi-metric-list-page.ts +146 -226
  4. package/client/pages/kpi-metric-value/kpi-metric-value-editor-page.ts +187 -295
  5. package/client/pages/kpi-metric-value/kpi-metric-value-list-page.ts +123 -194
  6. package/client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.ts +57 -91
  7. package/client/pages/kpi-statistic/kpi-statistic-editor-page.ts +180 -278
  8. package/client/pages/kpi-statistic/kpi-statistic-list-page.ts +186 -286
  9. package/client/pages/kpi-value/kpi-value-editor-page.ts +189 -292
  10. package/client/pages/kpi-value/kpi-value-list-page.ts +170 -264
  11. package/dist-client/pages/kpi/kpi-list-page.d.ts +0 -6
  12. package/dist-client/pages/kpi/kpi-list-page.js +150 -282
  13. package/dist-client/pages/kpi/kpi-list-page.js.map +1 -1
  14. package/dist-client/pages/kpi/kpi-tree-page.d.ts +1 -7
  15. package/dist-client/pages/kpi/kpi-tree-page.js +76 -127
  16. package/dist-client/pages/kpi/kpi-tree-page.js.map +1 -1
  17. package/dist-client/pages/kpi-metric/kpi-metric-list-page.d.ts +0 -6
  18. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js +62 -116
  19. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js.map +1 -1
  20. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.d.ts +1 -7
  21. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js +82 -140
  22. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js.map +1 -1
  23. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +0 -6
  24. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +54 -98
  25. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -1
  26. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.d.ts +1 -7
  27. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js +30 -57
  28. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js.map +1 -1
  29. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.d.ts +1 -7
  30. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js +91 -153
  31. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js.map +1 -1
  32. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.d.ts +0 -6
  33. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js +81 -155
  34. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js.map +1 -1
  35. package/dist-client/pages/kpi-value/kpi-value-editor-page.d.ts +1 -7
  36. package/dist-client/pages/kpi-value/kpi-value-editor-page.js +80 -136
  37. package/dist-client/pages/kpi-value/kpi-value-editor-page.js.map +1 -1
  38. package/dist-client/pages/kpi-value/kpi-value-list-page.d.ts +0 -6
  39. package/dist-client/pages/kpi-value/kpi-value-list-page.js +73 -134
  40. package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -1
  41. package/dist-client/tsconfig.tsbuildinfo +1 -1
  42. package/dist-server/service/index.d.ts +1 -1
  43. package/dist-server/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +18 -18
  45. package/client/tsconfig.json +0 -11
  46. package/dist-server/tsconfig.json +0 -10
  47. package/server/@types/index.d.ts +0 -11
  48. package/server/calculator/evaluator.ts +0 -45
  49. package/server/calculator/functions.ts +0 -67
  50. package/server/calculator/index.ts +0 -4
  51. package/server/calculator/parser.ts +0 -137
  52. package/server/calculator/provider.ts +0 -10
  53. package/server/controllers/index.ts +0 -2
  54. package/server/controllers/kpi-metric-value-provider.ts +0 -79
  55. package/server/controllers/kpi-value-provider.ts +0 -51
  56. package/server/index.ts +0 -6
  57. package/server/migrations/1752190849680-seed-kpi-metrics.ts +0 -124
  58. package/server/migrations/1752190849681-seed-kpi.ts +0 -356
  59. package/server/migrations/1752192090123-add-grades-to-kpi.ts +0 -67
  60. package/server/migrations/1752192090124-add-kpi-statistics.ts +0 -719
  61. package/server/migrations/1752192090128-seed-kpi-org-scope.ts +0 -132
  62. package/server/migrations/1752192090129-seed-kpi-values.ts +0 -207
  63. package/server/migrations/grade-data/x11-performance-table.json +0 -962
  64. package/server/migrations/grade-data/x12-performance-table.json +0 -611
  65. package/server/migrations/grade-data/x14-performance-table.json +0 -42
  66. package/server/migrations/grade-data/x21-performance-table.json +0 -889
  67. package/server/migrations/grade-data/x22-performance-table.json +0 -1064
  68. package/server/migrations/grade-data/x23-performance-table.json +0 -42
  69. package/server/migrations/grade-data/x31-performance-table.json +0 -644
  70. package/server/migrations/grade-data/x32-performance-table.json +0 -993
  71. package/server/migrations/grade-data/x33-performance-table.json +0 -195
  72. package/server/migrations/grade-data/x34-performance-table.json +0 -12
  73. package/server/migrations/grade-data/x35-performance-table.json +0 -42
  74. package/server/migrations/grade-data/x41-performance-table.json +0 -825
  75. package/server/migrations/grade-data/x42-performance-table.json +0 -786
  76. package/server/migrations/grade-data/x43-performance-table.json +0 -12
  77. package/server/migrations/grade-data/x44-performance-table.json +0 -42
  78. package/server/migrations/grade-data/x51-performance-table.json +0 -924
  79. package/server/migrations/grade-data/x52-performance-table.json +0 -42
  80. package/server/migrations/grade-data/x61-performance-table.json +0 -261
  81. package/server/migrations/grade-data/x62-performance-table.json +0 -42
  82. package/server/migrations/index.ts +0 -9
  83. package/server/migrations/seed-data/kpi-metrics-seed.json +0 -454
  84. package/server/migrations/seed-data/kpi-org-scope-seed.json +0 -1676
  85. package/server/migrations/seed-data/kpi-scopes-seed.json +0 -121
  86. package/server/migrations/seed-data/kpi-values-seed.json +0 -402
  87. package/server/migrations/seed-data/kpis-seed.json +0 -488
  88. package/server/migrations/seed-data/scope-definitions-seed.json +0 -90
  89. package/server/routes.ts +0 -81
  90. package/server/service/index.ts +0 -51
  91. package/server/service/kpi/aggregate-kpi.ts +0 -103
  92. package/server/service/kpi/event-subscriber.ts +0 -29
  93. package/server/service/kpi/index.ts +0 -9
  94. package/server/service/kpi/kpi-formula.service.ts +0 -164
  95. package/server/service/kpi/kpi-grade.types.ts +0 -28
  96. package/server/service/kpi/kpi-history.ts +0 -126
  97. package/server/service/kpi/kpi-mutation.ts +0 -553
  98. package/server/service/kpi/kpi-query.ts +0 -224
  99. package/server/service/kpi/kpi-type.ts +0 -151
  100. package/server/service/kpi/kpi.ts +0 -254
  101. package/server/service/kpi-alert/index.ts +0 -3
  102. package/server/service/kpi-alert/kpi-alert-query.ts +0 -59
  103. package/server/service/kpi-alert/kpi-alert-type.ts +0 -20
  104. package/server/service/kpi-metric/aggregate-kpi-metric.ts +0 -132
  105. package/server/service/kpi-metric/index.ts +0 -7
  106. package/server/service/kpi-metric/kpi-metric-mutation.ts +0 -309
  107. package/server/service/kpi-metric/kpi-metric-query.ts +0 -70
  108. package/server/service/kpi-metric/kpi-metric-type.ts +0 -111
  109. package/server/service/kpi-metric/kpi-metric.ts +0 -134
  110. package/server/service/kpi-metric-value/index.ts +0 -7
  111. package/server/service/kpi-metric-value/kpi-metric-value-mutation.ts +0 -270
  112. package/server/service/kpi-metric-value/kpi-metric-value-query.ts +0 -62
  113. package/server/service/kpi-metric-value/kpi-metric-value-type.ts +0 -82
  114. package/server/service/kpi-metric-value/kpi-metric-value.ts +0 -93
  115. package/server/service/kpi-org-scope/index.ts +0 -6
  116. package/server/service/kpi-org-scope/kpi-org-scope-mutation.ts +0 -173
  117. package/server/service/kpi-org-scope/kpi-org-scope-query.ts +0 -127
  118. package/server/service/kpi-org-scope/kpi-org-scope-type.ts +0 -68
  119. package/server/service/kpi-org-scope/kpi-org-scope.ts +0 -123
  120. package/server/service/kpi-scope/index.ts +0 -11
  121. package/server/service/kpi-scope/kpi-scope-mutation.ts +0 -129
  122. package/server/service/kpi-scope/kpi-scope-query.ts +0 -63
  123. package/server/service/kpi-scope/kpi-scope-type.ts +0 -96
  124. package/server/service/kpi-scope/kpi-scope.ts +0 -143
  125. package/server/service/kpi-statistic/index.ts +0 -7
  126. package/server/service/kpi-statistic/kpi-statistic-batch.service.ts +0 -231
  127. package/server/service/kpi-statistic/kpi-statistic-calculation.service.ts +0 -410
  128. package/server/service/kpi-statistic/kpi-statistic-mutation.ts +0 -291
  129. package/server/service/kpi-statistic/kpi-statistic-query.ts +0 -146
  130. package/server/service/kpi-statistic/kpi-statistic-type.ts +0 -152
  131. package/server/service/kpi-statistic/kpi-statistic.ts +0 -199
  132. package/server/service/kpi-value/index.ts +0 -7
  133. package/server/service/kpi-value/kpi-value-mutation.ts +0 -432
  134. package/server/service/kpi-value/kpi-value-query.ts +0 -61
  135. package/server/service/kpi-value/kpi-value-score.service.ts +0 -106
  136. package/server/service/kpi-value/kpi-value-type.ts +0 -122
  137. package/server/service/kpi-value/kpi-value.ts +0 -160
  138. package/server/service/utils/value-date-util.ts +0 -119
  139. package/server/tsconfig.json +0 -10
  140. package/server/types/global.d.ts +0 -8
@@ -7,7 +7,7 @@ import '@operato/data-grist/ox-record-creator.js';
7
7
  import './kpi-viz-editor.js';
8
8
  import './kpi-grade-editor.js';
9
9
  import { CommonButtonStyles, CommonHeaderStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles';
10
- import { PageView, store } from '@operato/shell';
10
+ import { PageView } from '@operato/shell';
11
11
  import { css, html } from 'lit';
12
12
  import { customElement, property, query, state } from 'lit/decorators.js';
13
13
  import { ScopedElementsMixin } from '@open-wc/scoped-elements';
@@ -18,12 +18,11 @@ import { notify, openPopup } from '@operato/layout';
18
18
  import { OxPrompt } from '@operato/popup';
19
19
  import { isMobileDevice } from '@operato/utils';
20
20
  import { p13n } from '@operato/p13n';
21
- import { connect } from 'pwa-helpers/connect-mixin';
22
21
  import gql from 'graphql-tag';
23
22
  import { KpiImporter } from './kpi-importer';
24
23
  import { KpiGradeEditor } from './kpi-grade-editor';
25
24
  import { KpiVizEditor } from './kpi-viz-editor';
26
- let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next)(ScopedElementsMixin(PageView)))) {
25
+ let KpiListPage = class KpiListPage extends p13n(localize(i18next)(ScopedElementsMixin(PageView))) {
27
26
  constructor() {
28
27
  super(...arguments);
29
28
  this.mode = isMobileDevice() ? 'CARD' : 'GRID';
@@ -36,53 +35,43 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
36
35
  CommonGristStyles,
37
36
  CommonHeaderStyles,
38
37
  css `
39
- :host {
40
- display: flex;
38
+ :host { display: flex;
41
39
 
42
40
  width: 100%;
43
41
 
44
42
  --grid-record-emphasized-background-color: #8b0000;
45
43
  --grid-record-emphasized-color: #ff6b6b;
46
- }
44
+ }
47
45
 
48
- ox-grist {
49
- overflow-y: auto;
46
+ ox-grist { overflow-y: auto;
50
47
  flex: 1;
51
- }
48
+ }
52
49
 
53
- ox-filters-form {
54
- flex: 1;
55
- }
50
+ ox-filters-form { flex: 1;
51
+ }
56
52
  `
57
53
  ]; }
58
54
  static get scopedElements() {
59
- return {
60
- 'kpi-importer': KpiImporter,
55
+ return { 'kpi-importer': KpiImporter,
61
56
  'kpi-grade-editor': KpiGradeEditor,
62
57
  'kpi-viz-editor': KpiVizEditor
63
58
  };
64
59
  }
65
60
  async getAvailableKpiMetricVariables(currentKpi) {
66
- // Leaf KPI인 경우: kpi-metric을 변수로 사용
67
61
  if (!currentKpi || currentKpi.isLeaf) {
68
62
  if (this.availableVariablesLoaded) {
69
63
  return this.availableVariables;
70
64
  }
71
- const response = await client.query({
72
- query: gql `
73
- query {
74
- kpiMetrics {
75
- items {
76
- name
65
+ const response = await client.query({ query: gql `
66
+ query { kpiMetrics { items { name
77
67
  description
78
68
  unit
79
- }
80
- }
81
- }
69
+ }
70
+ }
71
+ }
82
72
  `
83
73
  });
84
- this.availableVariables = (response.data.kpiMetrics.items || []).map(metric => ({
85
- name: metric.name,
74
+ this.availableVariables = (response.data.kpiMetrics.items || []).map(metric => ({ name: metric.name,
86
75
  description: metric.description,
87
76
  type: 'kpi-metric',
88
77
  unit: metric.unit
@@ -92,24 +81,18 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
92
81
  }
93
82
  // 부모 KPI인 경우: 자식 KPI를 변수로 사용
94
83
  try {
95
- const response = await client.query({
96
- query: gql `
97
- query ($id: String!) {
98
- kpi(id: $id) {
99
- children {
100
- id
84
+ const response = await client.query({ query: gql `
85
+ query ($id: String!) { kpi(id: $id) { children { id
101
86
  name
102
87
  description
103
- }
104
- }
105
- }
88
+ }
89
+ }
90
+ }
106
91
  `,
107
- variables: {
108
- id: currentKpi.id
92
+ variables: { id: currentKpi.id
109
93
  }
110
94
  });
111
- return (response.data.kpi.children || []).map(childKpi => ({
112
- name: childKpi.name,
95
+ return (response.data.kpi.children || []).map(childKpi => ({ name: childKpi.name,
113
96
  description: childKpi.description,
114
97
  type: 'child-kpi'
115
98
  }));
@@ -120,45 +103,35 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
120
103
  }
121
104
  }
122
105
  get context() {
123
- return {
124
- title: i18next.t('title.kpi list'),
125
- search: {
126
- handler: (search) => {
106
+ return { title: i18next.t('title.kpi list'),
107
+ search: { handler: (search) => {
127
108
  this.grist.searchText = search;
128
109
  },
129
- value: this.grist.searchText
130
- },
131
- filter: {
132
- handler: () => {
110
+ value: this.grist.searchText },
111
+ filter: { handler: () => {
133
112
  this.grist.toggleHeadroom();
134
113
  }
135
114
  },
136
115
  help: 'kpi/kpi',
137
116
  actions: [
138
- {
139
- title: this.hierarchicalView ? 'List View' : 'Tree View',
117
+ { title: this.hierarchicalView ? 'List View' : 'Tree View',
140
118
  action: this._toggleHierarchicalView.bind(this),
141
119
  icon: this.hierarchicalView ? 'list' : 'account_tree'
142
120
  },
143
- {
144
- title: i18next.t('button.save'),
121
+ { title: i18next.t('button.save'),
145
122
  action: this._updateKpi.bind(this),
146
123
  ...CommonButtonStyles.save
147
124
  },
148
- {
149
- title: i18next.t('button.delete'),
125
+ { title: i18next.t('button.delete'),
150
126
  action: this._deleteKpi.bind(this),
151
127
  ...CommonButtonStyles.delete
152
128
  }
153
129
  ],
154
- exportable: {
155
- name: i18next.t('title.kpi list'),
130
+ exportable: { name: i18next.t('title.kpi list'),
156
131
  data: this.exportHandler.bind(this)
157
132
  },
158
- importable: {
159
- handler: this.importHandler.bind(this)
160
- }
161
- };
133
+ importable: { handler: this.importHandler.bind(this)
134
+ } };
162
135
  }
163
136
  render() {
164
137
  const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID');
@@ -196,9 +169,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
196
169
  this.fetchKpiMetrics();
197
170
  }
198
171
  async pageInitialized(lifecycle) {
199
- this.gristConfig = {
200
- list: {
201
- fields: ['name', 'description'],
172
+ this.gristConfig = { list: { fields: ['name', 'description'],
202
173
  details: [
203
174
  'name',
204
175
  'description',
@@ -221,19 +192,16 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
221
192
  { type: 'gutter', gutterName: 'sequence' },
222
193
  { type: 'gutter', gutterName: 'row-selector', multiple: true },
223
194
  // KPI 실적값 계산 버튼 추가
224
- {
225
- type: 'gutter',
195
+ { type: 'gutter',
226
196
  gutterName: 'button',
227
197
  icon: 'calculate',
228
198
  title: '실적값 계산',
229
- handlers: {
230
- click: (columns, data, column, record, rowIndex) => {
199
+ handlers: { click: (columns, data, column, record, rowIndex) => {
231
200
  this._calculateKpiValue(record);
232
201
  }
233
202
  }
234
203
  },
235
- {
236
- type: 'string',
204
+ { type: 'string',
237
205
  name: 'name',
238
206
  header: '이름',
239
207
  record: { editable: true },
@@ -241,66 +209,53 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
241
209
  sortable: true,
242
210
  width: 120
243
211
  },
244
- {
245
- type: 'string',
212
+ { type: 'string',
246
213
  name: 'description',
247
214
  header: i18next.t('field.description'),
248
215
  record: { editable: true },
249
216
  filter: 'search',
250
217
  width: 200
251
218
  },
252
- {
253
- type: 'resource-object',
219
+ { type: 'resource-object',
254
220
  name: 'parent',
255
221
  label: true,
256
222
  header: '상위 KPI',
257
- record: {
258
- editable: true,
259
- options: {
260
- title: i18next.t('title.lookup KPI'),
223
+ record: { editable: true,
224
+ options: { title: i18next.t('title.lookup KPI'),
261
225
  queryName: 'kpis',
262
- basicArgs: {
263
- filters: [{ name: 'isLeaf', operator: 'eq', value: false }]
226
+ basicArgs: { filters: [{ name: 'isLeaf', operator: 'eq', value: false }]
264
227
  }
265
228
  }
266
229
  },
267
230
  width: 200
268
231
  },
269
- {
270
- type: 'boolean',
232
+ { type: 'boolean',
271
233
  name: 'isLeaf',
272
234
  header: '리프 KPI',
273
235
  record: { editable: true },
274
236
  width: 100
275
237
  },
276
- {
277
- type: 'formula',
238
+ { type: 'formula',
278
239
  name: 'formula',
279
240
  header: '산식',
280
- record: {
281
- editable: true,
241
+ record: { editable: true,
282
242
  availableVariables: async (value, column, record) => {
283
- // Leaf KPI인 경우: kpi-metric을 변수로 사용
284
243
  if (!record || record.isLeaf) {
285
244
  return await this.getAvailableKpiMetricVariables(record);
286
245
  }
287
246
  // 부모 KPI인 경우: 자식 KPI를 변수로 사용
288
- return (record.children || []).map(child => ({
289
- name: child.name,
247
+ return (record.children || []).map(child => ({ name: child.name,
290
248
  description: child.description || child.name,
291
249
  type: 'child-kpi',
292
250
  unit: ''
293
251
  }));
294
252
  }
295
253
  },
296
- width: 320
297
- },
298
- {
299
- type: 'select',
254
+ width: 320 },
255
+ { type: 'select',
300
256
  name: 'periodType',
301
257
  header: '계산주기',
302
- record: {
303
- editable: true,
258
+ record: { editable: true,
304
259
  options: [
305
260
  { value: '', display: '' },
306
261
  { value: 'DAY', display: '일' },
@@ -314,18 +269,14 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
314
269
  },
315
270
  width: 80
316
271
  },
317
- {
318
- type: 'formula',
272
+ { type: 'formula',
319
273
  name: 'scoreFormula',
320
274
  header: '성과점수수식',
321
- record: {
322
- editable: true,
275
+ record: { editable: true,
323
276
  availableVariables: async (value, column, record) => {
324
- // leaf 이면 value를 사용
325
277
  if (record.isLeaf) {
326
278
  return [
327
- {
328
- name: 'value',
279
+ { name: 'value',
329
280
  description: 'KPI 실적값',
330
281
  type: 'kpi-value',
331
282
  unit: ''
@@ -333,8 +284,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
333
284
  ];
334
285
  }
335
286
  // 부모 이면 자식 KPI들을 변수로 사용
336
- return record.children.map(child => ({
337
- name: child.name,
287
+ return record.children.map(child => ({ name: child.name,
338
288
  description: child.description || child.name,
339
289
  type: 'kpi-score',
340
290
  unit: ''
@@ -342,8 +292,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
342
292
  },
343
293
  includeDefaultFunctions: false,
344
294
  availableFunctions: [
345
- {
346
- name: 'INTEGRATE()',
295
+ { name: 'INTEGRATE()',
347
296
  description: '수치 적분',
348
297
  template: 'INTEGRATE({func}, {a}, {b}, {n})',
349
298
  syntax: 'INTEGRATE(func, a, b, n)',
@@ -352,8 +301,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
352
301
  help: '사다리꼴 적분법을 사용하여 수치 적분을 계산합니다.',
353
302
  examples: ['INTEGRATE(x => x*x, 0, 1, 1000)', 'INTEGRATE([효율성], 0, 1)']
354
303
  },
355
- {
356
- name: 'BETA_FUNCTION()',
304
+ { name: 'BETA_FUNCTION()',
357
305
  description: '베타 함수',
358
306
  template: 'BETA_FUNCTION({x}, {alpha}, {beta})',
359
307
  syntax: 'BETA_FUNCTION(x, alpha, beta)',
@@ -362,8 +310,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
362
310
  help: '베타 분포 함수를 계산합니다. t^(α-1) × (1-t)^(β-1)',
363
311
  examples: ['BETA_FUNCTION(0.5, 2, 3)', 'BETA_FUNCTION([품질지수], 3, 2)']
364
312
  },
365
- {
366
- name: 'INCOMPLETE_BETA()',
313
+ { name: 'INCOMPLETE_BETA()',
367
314
  description: '불완전 베타 함수',
368
315
  template: 'INCOMPLETE_BETA({x}, {alpha}, {beta})',
369
316
  syntax: 'INCOMPLETE_BETA(x, alpha, beta)',
@@ -372,8 +319,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
372
319
  help: '불완전 베타 함수를 수치 적분으로 계산합니다.',
373
320
  examples: ['INCOMPLETE_BETA(0.7, 2, 3)', 'INCOMPLETE_BETA([목표달성률]/100, 2, 3)']
374
321
  },
375
- {
376
- name: 'COMPLETE_BETA()',
322
+ { name: 'COMPLETE_BETA()',
377
323
  description: '완전 베타 함수',
378
324
  template: 'COMPLETE_BETA({alpha}, {beta})',
379
325
  syntax: 'COMPLETE_BETA(alpha, beta)',
@@ -382,8 +328,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
382
328
  help: '완전 베타 함수 B(α,β)를 계산합니다.',
383
329
  examples: ['COMPLETE_BETA(2, 3)', 'COMPLETE_BETA(3, 2)']
384
330
  },
385
- {
386
- name: 'PERFORMANCE_INDEX()',
331
+ { name: 'PERFORMANCE_INDEX()',
387
332
  description: '성과 지수',
388
333
  template: 'PERFORMANCE_INDEX({x}, {alpha1}, {beta1}, {alpha2}, {beta2})',
389
334
  syntax: 'PERFORMANCE_INDEX(x, alpha1, beta1, alpha2, beta2)',
@@ -396,8 +341,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
396
341
  help: '성과 지수를 계산합니다: 1 - (불완전 베타 / 완전 베타)',
397
342
  examples: ['PERFORMANCE_INDEX(0.8, 2, 3, 2, 3)', 'PERFORMANCE_INDEX([성과점수]/100, 2, 3, 2, 3)']
398
343
  },
399
- {
400
- name: 'EXP()',
344
+ { name: 'EXP()',
401
345
  description: '지수 함수',
402
346
  template: 'EXP({x})',
403
347
  syntax: 'EXP(x)',
@@ -406,8 +350,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
406
350
  help: '자연상수 e의 x제곱을 계산합니다.',
407
351
  examples: ['EXP(1)', 'EXP([효율성])']
408
352
  },
409
- {
410
- name: 'LOG()',
353
+ { name: 'LOG()',
411
354
  description: '자연 로그',
412
355
  template: 'LOG({x})',
413
356
  syntax: 'LOG(x)',
@@ -416,8 +359,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
416
359
  help: '자연 로그 ln(x)를 계산합니다.',
417
360
  examples: ['LOG(2.718)', 'LOG([성과점수])']
418
361
  },
419
- {
420
- name: 'POW()',
362
+ { name: 'POW()',
421
363
  description: '거듭제곱',
422
364
  template: 'POW({x}, {y})',
423
365
  syntax: 'POW(x, y)',
@@ -426,8 +368,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
426
368
  help: 'x의 y제곱을 계산합니다.',
427
369
  examples: ['POW(2, 3)', 'POW([효율성], 2)']
428
370
  },
429
- {
430
- name: 'EXPONENTIAL_DECAY()',
371
+ { name: 'EXPONENTIAL_DECAY()',
431
372
  description: '지수 감쇠',
432
373
  template: 'EXPONENTIAL_DECAY({value}, {scale}, {power})',
433
374
  syntax: 'EXPONENTIAL_DECAY(value, scale, power)',
@@ -436,16 +377,12 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
436
377
  help: '지수 감쇠 함수 exp(-(value/scale)^power)를 계산합니다.',
437
378
  examples: ['EXPONENTIAL_DECAY(50, 100, 2)', 'EXPONENTIAL_DECAY([목표달성률], 50, 2)']
438
379
  }
439
- ]
440
- },
441
- width: 200
442
- },
443
- {
444
- type: 'string',
380
+ ] },
381
+ width: 200 },
382
+ { type: 'string',
445
383
  name: 'grades',
446
384
  header: '성과지수 Lookup',
447
- record: {
448
- editable: false,
385
+ record: { editable: false,
449
386
  renderer: (v, c, r) => {
450
387
  if (r.grades && r.grades.length > 0) {
451
388
  return html `<span style="color: #4caf50; cursor: pointer;" @click=${() => this._editGrades(r)}>
@@ -461,8 +398,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
461
398
  },
462
399
  width: 150
463
400
  },
464
- {
465
- type: 'number',
401
+ { type: 'number',
466
402
  name: 'weight',
467
403
  header: '가중치',
468
404
  record: { editable: true },
@@ -470,8 +406,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
470
406
  sortable: true,
471
407
  width: 80
472
408
  },
473
- {
474
- type: 'checkbox',
409
+ { type: 'checkbox',
475
410
  name: 'active',
476
411
  label: true,
477
412
  header: i18next.t('field.active'),
@@ -481,13 +416,11 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
481
416
  width: 60
482
417
  },
483
418
  { type: 'string', name: 'state', header: '상태', record: { editable: false }, width: 100 },
484
- {
485
- type: 'string',
419
+ { type: 'string',
486
420
  name: 'vizType',
487
421
  hidden: true,
488
422
  header: '시각화 설정',
489
- record: {
490
- editable: false,
423
+ record: { editable: false,
491
424
  renderer: (v, c, r) => {
492
425
  const vizType = r.vizType || 'CARD';
493
426
  const vizMeta = r.vizMeta || {};
@@ -510,23 +443,20 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
510
443
  { type: 'timezone', name: 'timezone', header: '타임존', record: { editable: true }, width: 120 },
511
444
  { type: 'number', name: 'version', header: '버전', record: { editable: false }, width: 80 },
512
445
  { type: 'datetime', name: 'createdAt', header: '생성일', record: { editable: false }, width: 180 },
513
- {
514
- type: 'datetime',
446
+ { type: 'datetime',
515
447
  name: 'updatedAt',
516
448
  header: i18next.t('field.updated_at'),
517
449
  record: { editable: false },
518
450
  sortable: true,
519
451
  width: 180
520
452
  },
521
- {
522
- type: 'resource-object',
453
+ { type: 'resource-object',
523
454
  name: 'creator',
524
455
  header: '생성자',
525
456
  record: { editable: false, renderer: (v, c, r) => r.creator?.name },
526
457
  width: 120
527
458
  },
528
- {
529
- type: 'resource-object',
459
+ { type: 'resource-object',
530
460
  name: 'updater',
531
461
  header: i18next.t('field.updater'),
532
462
  record: { editable: false, renderer: (v, c, r) => r.updater?.name },
@@ -535,30 +465,22 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
535
465
  },
536
466
  { type: 'string', name: 'thumbnail', header: '썸네일', record: { editable: false }, width: 120 }
537
467
  ],
538
- rows: {
539
- appendable: false,
540
- selectable: {
541
- multiple: true
468
+ rows: { appendable: false,
469
+ selectable: { multiple: true
542
470
  }
543
471
  },
544
- sorters: [{ name: 'name' }]
545
- };
472
+ sorters: [{ name: 'name' }] };
546
473
  }
547
474
  async pageUpdated(changes, lifecycle) {
548
- if (this.active) {
549
- // do something here when this page just became as active
475
+ if (this.active) { // do something here when this page just became as active
550
476
  }
551
477
  }
552
478
  async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }) {
553
479
  if (this.hierarchicalView) {
554
480
  return this.fetchHierarchicalData();
555
481
  }
556
- const response = await client.query({
557
- query: gql `
558
- query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
559
- responses: kpis(filters: $filters, pagination: $pagination, sortings: $sortings) {
560
- items {
561
- id
482
+ const response = await client.query({ query: gql `
483
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) { responses: kpis(filters: $filters, pagination: $pagination, sortings: $sortings) { items { id
562
484
  name
563
485
  description
564
486
  active
@@ -573,59 +495,48 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
573
495
  scheduleId
574
496
  timezone
575
497
  version
576
- parent {
577
- id
498
+ parent { id
578
499
  name
579
- }
580
- children {
581
- id
500
+ }
501
+ children { id
582
502
  name
583
503
  description
584
- }
504
+ }
585
505
  isLeaf
586
- updater {
587
- id
506
+ updater { id
588
507
  name
589
- }
508
+ }
590
509
  updatedAt
591
- creator {
592
- id
510
+ creator { id
593
511
  name
594
- }
512
+ }
595
513
  createdAt
596
- }
514
+ }
597
515
  total
598
- }
599
- }
516
+ }
517
+ }
600
518
  `,
601
- variables: {
602
- filters,
519
+ variables: { filters,
603
520
  pagination: { page, limit },
604
521
  sortings
605
522
  }
606
523
  });
607
- return {
608
- total: response.data.responses.total || 0,
524
+ return { total: response.data.responses.total || 0,
609
525
  records: response.data.responses.items || []
610
526
  };
611
527
  }
612
528
  async fetchKpiMetrics() {
613
- const response = await client.query({
614
- query: gql `
615
- query {
616
- kpiMetrics {
617
- items {
618
- name
529
+ const response = await client.query({ query: gql `
530
+ query { kpiMetrics { items { name
619
531
  description
620
532
  unit
621
- }
622
- }
623
- }
533
+ }
534
+ }
535
+ }
624
536
  `
625
537
  });
626
538
  if (!response.errors) {
627
- this.availableVariables = (response.data.kpiMetrics.items || []).map(metric => ({
628
- name: metric.name,
539
+ this.availableVariables = (response.data.kpiMetrics.items || []).map(metric => ({ name: metric.name,
629
540
  description: metric.description,
630
541
  type: 'kpi-metric',
631
542
  unit: metric.unit
@@ -633,28 +544,23 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
633
544
  }
634
545
  }
635
546
  async _deleteKpi() {
636
- if (await OxPrompt.open({
637
- title: i18next.t('text.are_you_sure'),
547
+ if (await OxPrompt.open({ title: i18next.t('text.are_you_sure'),
638
548
  text: i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }),
639
549
  confirmButton: { text: i18next.t('button.confirm') },
640
550
  cancelButton: { text: i18next.t('button.cancel') }
641
551
  })) {
642
552
  const ids = this.grist.selected.map(record => record.id);
643
553
  if (ids && ids.length > 0) {
644
- const response = await client.mutate({
645
- mutation: gql `
646
- mutation ($ids: [String!]!) {
647
- deleteKpis(ids: $ids)
648
- }
554
+ const response = await client.mutate({ mutation: gql `
555
+ mutation ($ids: [String!]!) { deleteKpis(ids: $ids)
556
+ }
649
557
  `,
650
- variables: {
651
- ids
558
+ variables: { ids
652
559
  }
653
560
  });
654
561
  if (!response.errors) {
655
562
  this.grist.fetch();
656
- notify({
657
- message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
563
+ notify({ message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
658
564
  });
659
565
  }
660
566
  }
@@ -672,16 +578,12 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
672
578
  patchField.cuFlag = patch.__dirty__;
673
579
  return patchField;
674
580
  });
675
- const response = await client.mutate({
676
- mutation: gql `
677
- mutation ($patches: [KpiPatch!]!) {
678
- updateMultipleKpi(patches: $patches) {
679
- name
680
- }
681
- }
581
+ const response = await client.mutate({ mutation: gql `
582
+ mutation ($patches: [KpiPatch!]!) { updateMultipleKpi(patches: $patches) { name
583
+ }
584
+ }
682
585
  `,
683
- variables: {
684
- patches
586
+ variables: { patches
685
587
  }
686
588
  });
687
589
  if (!response.errors) {
@@ -691,26 +593,19 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
691
593
  }
692
594
  async creationCallback(kpi) {
693
595
  try {
694
- const response = await client.query({
695
- query: gql `
696
- mutation ($kpi: NewKpi!) {
697
- createKpi(kpi: $kpi) {
698
- id
699
- }
700
- }
596
+ const response = await client.query({ query: gql `
597
+ mutation ($kpi: NewKpi!) { createKpi(kpi: $kpi) { id
598
+ }
599
+ }
701
600
  `,
702
- variables: {
703
- kpi
601
+ variables: { kpi
704
602
  },
705
- context: {
706
- hasUpload: true
603
+ context: { hasUpload: true
707
604
  }
708
605
  });
709
606
  if (!response.errors) {
710
607
  this.grist.fetch();
711
- document.dispatchEvent(new CustomEvent('notify', {
712
- detail: {
713
- message: i18next.t('text.data_created_successfully')
608
+ document.dispatchEvent(new CustomEvent('notify', { detail: { message: i18next.t('text.data_created_successfully')
714
609
  }
715
610
  }));
716
611
  }
@@ -718,9 +613,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
718
613
  }
719
614
  catch (ex) {
720
615
  console.error(ex);
721
- document.dispatchEvent(new CustomEvent('notify', {
722
- detail: {
723
- type: 'error',
616
+ document.dispatchEvent(new CustomEvent('notify', { detail: { type: 'error',
724
617
  message: i18next.t('text.error')
725
618
  }
726
619
  }));
@@ -747,8 +640,7 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
747
640
  this.grist.fetch();
748
641
  }}
749
642
  ></kpi-importer>
750
- `, {
751
- backdrop: true,
643
+ `, { backdrop: true,
752
644
  size: 'large',
753
645
  title: i18next.t('title.import kpi')
754
646
  });
@@ -758,13 +650,11 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
758
650
  }
759
651
  async _editGrades(kpi) {
760
652
  if (!kpi.id) {
761
- notify({
762
- message: 'KPI를 먼저 저장한 후에 등급 설정을 할 수 있습니다.'
653
+ notify({ message: 'KPI를 먼저 저장한 후에 등급 설정을 할 수 있습니다.'
763
654
  });
764
655
  return;
765
656
  }
766
- const popup = await openPopup(html ` <kpi-grade-editor .kpi=${kpi}></kpi-grade-editor> `, {
767
- title: `${kpi.name} - 등급 설정`,
657
+ const popup = await openPopup(html ` <kpi-grade-editor .kpi=${kpi}></kpi-grade-editor> `, { title: `${kpi.name} - 등급 설정`,
768
658
  size: 'large'
769
659
  });
770
660
  popup.onclosed = () => {
@@ -778,57 +668,46 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
778
668
  .onSave=${(vizType, vizMeta) => this._onVizUpdated(kpi.id, vizType, vizMeta)}
779
669
  .onCancel=${() => popup.close()}
780
670
  ></kpi-viz-editor>
781
- `, {
782
- title: `${kpi.name} - 시각화 설정`,
671
+ `, { title: `${kpi.name} - 시각화 설정`,
783
672
  size: 'large'
784
673
  });
785
674
  }
786
675
  async _onVizUpdated(kpiId, vizType, vizMeta) {
787
676
  try {
788
- const response = await client.mutate({
789
- mutation: gql `
790
- mutation ($id: String!, $patch: KpiPatch!) {
791
- updateKpi(id: $id, patch: $patch) {
792
- id
677
+ const response = await client.mutate({ mutation: gql `
678
+ mutation ($id: String!, $patch: KpiPatch!) { updateKpi(id: $id, patch: $patch) { id
793
679
  name
794
680
  vizType
795
681
  vizMeta
796
- }
797
- }
682
+ }
683
+ }
798
684
  `,
799
- variables: {
800
- id: kpiId,
685
+ variables: { id: kpiId,
801
686
  patch: { vizType, vizMeta }
802
687
  }
803
688
  });
804
689
  if (!response.errors) {
805
690
  this.grist.fetch();
806
- notify({
807
- message: '시각화 설정이 성공적으로 업데이트되었습니다.'
691
+ notify({ message: '시각화 설정이 성공적으로 업데이트되었습니다.'
808
692
  });
809
693
  }
810
694
  }
811
695
  catch (error) {
812
- notify({
813
- message: '시각화 설정 업데이트 중 오류가 발생했습니다.'
696
+ notify({ message: '시각화 설정 업데이트 중 오류가 발생했습니다.'
814
697
  });
815
698
  }
816
699
  }
817
700
  async _calculateKpiValue(kpi) {
818
701
  try {
819
- const response = await client.mutate({
820
- mutation: gql `
821
- mutation ($kpiId: String!) {
822
- calculateKpiValue(kpiId: $kpiId) {
823
- id
702
+ const response = await client.mutate({ mutation: gql `
703
+ mutation ($kpiId: String!) { calculateKpiValue(kpiId: $kpiId) { id
824
704
  value
825
705
  valueDate
826
706
  org
827
- }
828
- }
707
+ }
708
+ }
829
709
  `,
830
- variables: {
831
- kpiId: kpi.id
710
+ variables: { kpiId: kpi.id
832
711
  }
833
712
  });
834
713
  if (!response.errors) {
@@ -845,11 +724,8 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
845
724
  this.grist.fetch();
846
725
  }
847
726
  async fetchHierarchicalData() {
848
- const response = await client.query({
849
- query: gql `
850
- query {
851
- kpiTree {
852
- id
727
+ const response = await client.query({ query: gql `
728
+ query { kpiTree { id
853
729
  name
854
730
  description
855
731
  active
@@ -864,60 +740,52 @@ let KpiListPage = class KpiListPage extends connect(store)(p13n(localize(i18next
864
740
  scheduleId
865
741
  timezone
866
742
  version
867
- parent {
868
- id
743
+ parent { id
869
744
  name
870
- }
871
- children {
872
- id
745
+ }
746
+ children { id
873
747
  name
874
748
  description
875
749
  active
876
750
  isLeaf
877
751
  weight
878
- children {
879
- id
752
+ children { id
880
753
  name
881
754
  description
882
755
  active
883
756
  isLeaf
884
757
  weight
885
- children {
886
- id
758
+ children { id
887
759
  name
888
760
  description
889
761
  active
890
762
  isLeaf
891
763
  weight
892
- }
893
- }
894
- }
764
+ }
765
+ }
766
+ }
895
767
  isLeaf
896
- updater {
897
- id
768
+ updater { id
898
769
  name
899
- }
770
+ }
900
771
  updatedAt
901
- creator {
902
- id
772
+ creator { id
903
773
  name
904
- }
774
+ }
905
775
  createdAt
906
- }
907
- }
776
+ }
777
+ }
908
778
  `
909
779
  });
910
780
  const flattenedRecords = this.flattenTreeData(response.data.kpiTree);
911
- return {
912
- total: flattenedRecords.length,
781
+ return { total: flattenedRecords.length,
913
782
  records: flattenedRecords
914
783
  };
915
784
  }
916
785
  flattenTreeData(treeData, level = 0) {
917
786
  const flattened = [];
918
787
  for (const item of treeData) {
919
- const flattenedItem = {
920
- ...item,
788
+ const flattenedItem = { ...item,
921
789
  __level: level,
922
790
  __hasChildren: item.children && item.children.length > 0,
923
791
  __expanded: true