@dssp/dkpi 1.0.0-alpha.5 → 1.0.0-alpha.50

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 (128) hide show
  1. package/assets/favicon.ico +0 -0
  2. package/assets/manifest/apple-1024.png +0 -0
  3. package/assets/manifest/apple-120.png +0 -0
  4. package/assets/manifest/apple-152.png +0 -0
  5. package/assets/manifest/apple-167.png +0 -0
  6. package/assets/manifest/apple-180.png +0 -0
  7. package/assets/manifest/apple-touch-icon.png +0 -0
  8. package/assets/manifest/badge-128x128.png +0 -0
  9. package/assets/manifest/chrome-splashscreen-icon-384x384.png +0 -0
  10. package/assets/manifest/chrome-touch-icon-192x192.png +0 -0
  11. package/assets/manifest/icon-128x128.png +0 -0
  12. package/assets/manifest/icon-192x192.png +0 -0
  13. package/assets/manifest/icon-512x512.png +0 -0
  14. package/assets/manifest/icon-72x72.png +0 -0
  15. package/assets/manifest/icon-96x96.png +0 -0
  16. package/assets/manifest/image-metaog.png +0 -0
  17. package/assets/manifest/maskable_icon.png +0 -0
  18. package/assets/manifest/ms-icon-144x144.png +0 -0
  19. package/assets/manifest/ms-touch-icon-144x144-precomposed.png +0 -0
  20. package/assets/videos/intro.mp4 +0 -0
  21. package/dist-client/bootstrap.js +64 -4
  22. package/dist-client/bootstrap.js.map +1 -1
  23. package/dist-client/components/kpi-single-boxplot-chart.d.ts +24 -0
  24. package/dist-client/components/kpi-single-boxplot-chart.js +317 -0
  25. package/dist-client/components/kpi-single-boxplot-chart.js.map +1 -0
  26. package/dist-client/components/sv-pagenation-control.d.ts +18 -0
  27. package/dist-client/components/sv-pagenation-control.js +142 -0
  28. package/dist-client/components/sv-pagenation-control.js.map +1 -0
  29. package/dist-client/icons/menu-icons.d.ts +6 -0
  30. package/dist-client/icons/menu-icons.js +42 -0
  31. package/dist-client/icons/menu-icons.js.map +1 -1
  32. package/dist-client/menu.d.ts +23 -1
  33. package/dist-client/menu.js +57 -2
  34. package/dist-client/menu.js.map +1 -1
  35. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.d.ts +58 -0
  36. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js +731 -0
  37. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js.map +1 -0
  38. package/dist-client/pages/kpi-metric-value/kpi-metric-value-importer.d.ts +23 -0
  39. package/dist-client/pages/kpi-metric-value/kpi-metric-value-importer.js +76 -0
  40. package/dist-client/pages/kpi-metric-value/kpi-metric-value-importer.js.map +1 -0
  41. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +69 -0
  42. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +385 -0
  43. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -0
  44. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.d.ts +12 -0
  45. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js +174 -0
  46. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js.map +1 -0
  47. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.d.ts +41 -0
  48. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js +191 -0
  49. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js.map +1 -0
  50. package/dist-client/pages/kpi-value/kpi-value-importer.d.ts +23 -0
  51. package/dist-client/pages/kpi-value/kpi-value-importer.js +93 -0
  52. package/dist-client/pages/kpi-value/kpi-value-importer.js.map +1 -0
  53. package/dist-client/pages/kpi-value/kpi-value-list-page.d.ts +72 -0
  54. package/dist-client/pages/kpi-value/kpi-value-list-page.js +465 -0
  55. package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -0
  56. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.d.ts +13 -0
  57. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js +248 -0
  58. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js.map +1 -0
  59. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.d.ts +10 -0
  60. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js +229 -0
  61. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js.map +1 -0
  62. package/dist-client/pages/project-complete-tabs/pc-tab3-upload.d.ts +12 -0
  63. package/dist-client/pages/project-complete-tabs/pc-tab3-upload.js +213 -0
  64. package/dist-client/pages/project-complete-tabs/pc-tab3-upload.js.map +1 -0
  65. package/dist-client/pages/sv-project-complete.d.ts +22 -0
  66. package/dist-client/pages/sv-project-complete.js +213 -0
  67. package/dist-client/pages/sv-project-complete.js.map +1 -0
  68. package/dist-client/pages/sv-project-completed-list.d.ts +24 -0
  69. package/dist-client/pages/sv-project-completed-list.js +357 -0
  70. package/dist-client/pages/sv-project-completed-list.js.map +1 -0
  71. package/dist-client/pages/sv-project-detail.d.ts +13 -0
  72. package/dist-client/pages/sv-project-detail.js +494 -0
  73. package/dist-client/pages/sv-project-detail.js.map +1 -0
  74. package/dist-client/pages/sv-project-list.d.ts +157 -0
  75. package/dist-client/pages/sv-project-list.js +431 -0
  76. package/dist-client/pages/sv-project-list.js.map +1 -0
  77. package/dist-client/route.d.ts +1 -1
  78. package/dist-client/route.js +22 -1
  79. package/dist-client/route.js.map +1 -1
  80. package/dist-client/shared/complete-api.d.ts +5 -0
  81. package/dist-client/shared/complete-api.js +125 -0
  82. package/dist-client/shared/complete-api.js.map +1 -0
  83. package/dist-client/shared/func.d.ts +2 -0
  84. package/dist-client/shared/func.js +22 -0
  85. package/dist-client/shared/func.js.map +1 -0
  86. package/dist-client/themes/dark.css +24 -24
  87. package/dist-client/themes/light.css +23 -23
  88. package/dist-client/tsconfig.tsbuildinfo +1 -1
  89. package/dist-client/viewparts/menu-tools.d.ts +37 -1
  90. package/dist-client/viewparts/menu-tools.js +348 -15
  91. package/dist-client/viewparts/menu-tools.js.map +1 -1
  92. package/dist-server/index.d.ts +2 -0
  93. package/dist-server/index.js +5 -0
  94. package/dist-server/index.js.map +1 -1
  95. package/dist-server/migrations/index.d.ts +1 -0
  96. package/dist-server/migrations/index.js +12 -0
  97. package/dist-server/migrations/index.js.map +1 -0
  98. package/dist-server/scripts/calculate-kpi-scores.d.ts +10 -0
  99. package/dist-server/scripts/calculate-kpi-scores.js +271 -0
  100. package/dist-server/scripts/calculate-kpi-scores.js.map +1 -0
  101. package/dist-server/scripts/load-grade-data-migration.d.ts +10 -0
  102. package/dist-server/scripts/load-grade-data-migration.js +194 -0
  103. package/dist-server/scripts/load-grade-data-migration.js.map +1 -0
  104. package/dist-server/scripts/propagate-parent-kpi-values.d.ts +10 -0
  105. package/dist-server/scripts/propagate-parent-kpi-values.js +440 -0
  106. package/dist-server/scripts/propagate-parent-kpi-values.js.map +1 -0
  107. package/dist-server/service/index.d.ts +6 -0
  108. package/dist-server/service/index.js +21 -0
  109. package/dist-server/service/index.js.map +1 -0
  110. package/dist-server/service/kpi-metric-value/index.d.ts +4 -0
  111. package/dist-server/service/kpi-metric-value/index.js +8 -0
  112. package/dist-server/service/kpi-metric-value/index.js.map +1 -0
  113. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.d.ts +7 -0
  114. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +112 -0
  115. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -0
  116. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.d.ts +7 -0
  117. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js +47 -0
  118. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js.map +1 -0
  119. package/dist-server/service/kpi-value/index.d.ts +3 -0
  120. package/dist-server/service/kpi-value/index.js +7 -0
  121. package/dist-server/service/kpi-value/index.js.map +1 -0
  122. package/dist-server/service/kpi-value/kpi-value-query.d.ts +7 -0
  123. package/dist-server/service/kpi-value/kpi-value-query.js +47 -0
  124. package/dist-server/service/kpi-value/kpi-value-query.js.map +1 -0
  125. package/dist-server/tsconfig.tsbuildinfo +1 -1
  126. package/package.json +62 -51
  127. package/schema.graphql +11497 -3215
  128. package/things-factory.config.js +7 -1
@@ -0,0 +1,431 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import '@material/web/icon/icon.js';
3
+ import '../components/kpi-single-boxplot-chart';
4
+ import { navigate, PageView } from '@operato/shell';
5
+ import { css, html } from 'lit';
6
+ import { customElement, state } from 'lit/decorators.js';
7
+ import { ScopedElementsMixin } from '@open-wc/scoped-elements';
8
+ import { client } from '@operato/graphql';
9
+ import { openPopup } from '@operato/layout';
10
+ import gql from 'graphql-tag';
11
+ import '../components/sv-pagenation-control';
12
+ import '@dssp/project/dist-client/pages/project/popup/popup-project-create';
13
+ export var ProjectState;
14
+ (function (ProjectState) {
15
+ ProjectState["ONGOING"] = "10";
16
+ ProjectState["COMPLETED"] = "20";
17
+ })(ProjectState || (ProjectState = {}));
18
+ export const PROJECT_STATE = {
19
+ [ProjectState.ONGOING]: '진행중',
20
+ [ProjectState.COMPLETED]: '완료'
21
+ };
22
+ export var BuildingInspectionStatus;
23
+ (function (BuildingInspectionStatus) {
24
+ BuildingInspectionStatus["WAIT"] = "WAIT";
25
+ BuildingInspectionStatus["OVERALL_WAIT"] = "OVERALL_WAIT";
26
+ BuildingInspectionStatus["REQUEST"] = "REQUEST";
27
+ BuildingInspectionStatus["OVERALL_REQUEST"] = "OVERALL_REQUEST";
28
+ BuildingInspectionStatus["PASS"] = "PASS";
29
+ BuildingInspectionStatus["FAIL"] = "FAIL";
30
+ })(BuildingInspectionStatus || (BuildingInspectionStatus = {}));
31
+ export const BUILDING_INSPECTION_STATUS = {
32
+ [BuildingInspectionStatus.WAIT]: '검측 대기',
33
+ [BuildingInspectionStatus.OVERALL_WAIT]: '검측 대기',
34
+ [BuildingInspectionStatus.REQUEST]: '검측 요청',
35
+ [BuildingInspectionStatus.OVERALL_REQUEST]: '검측 요청',
36
+ [BuildingInspectionStatus.PASS]: '합격',
37
+ [BuildingInspectionStatus.FAIL]: '불합격'
38
+ };
39
+ export var ProjectType;
40
+ (function (ProjectType) {
41
+ ProjectType["DSSP"] = "DSSP";
42
+ ProjectType["DCSP"] = "DCSP";
43
+ ProjectType["DKPI"] = "DKPI";
44
+ })(ProjectType || (ProjectType = {}));
45
+ let SvProjectListPage = class SvProjectListPage extends ScopedElementsMixin(PageView) {
46
+ constructor() {
47
+ super(...arguments);
48
+ this.projectName = '';
49
+ this.projectList = [];
50
+ this.projectCount = 0;
51
+ this.currentPage = 1;
52
+ this.pageLimit = 20;
53
+ }
54
+ get context() {
55
+ return {
56
+ title: '진행중 프로젝트'
57
+ };
58
+ }
59
+ get totalPages() {
60
+ return Math.max(1, Math.ceil((this.projectCount || 0) / this.pageLimit));
61
+ }
62
+ render() {
63
+ var _a;
64
+ return html `
65
+ <div header>
66
+ <div search>
67
+ <md-icon>manage_search</md-icon>
68
+ <input
69
+ type="search"
70
+ name="projectName"
71
+ placeholder="프로젝트명"
72
+ .value=${this.projectName}
73
+ @input=${this._onInputChange}
74
+ @keypress=${this._onKeypress}
75
+ />
76
+ </div>
77
+
78
+ <span class="spacer"></span>
79
+ <div count>총 ${this.projectCount}건</div>
80
+
81
+ <button add-project @click=${this._openCreateProjectPopup}>
82
+ <md-icon>add</md-icon>
83
+ 신규 프로젝트 생성
84
+ </button>
85
+ </div>
86
+
87
+ <div table>
88
+ <div table-header>
89
+ <div col></div>
90
+ <div col>현장상태</div>
91
+ <div col>현장정보</div>
92
+ <div col>기타정보</div>
93
+ <div col>입력요청</div>
94
+ <div col>종합KPI</div>
95
+ </div>
96
+ <div table-body>
97
+ ${(_a = this.projectList) === null || _a === void 0 ? void 0 : _a.map((project) => {
98
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
99
+ const areaText = `연면적 : ${((_b = (_a = project === null || project === void 0 ? void 0 : project.buildingComplex) === null || _a === void 0 ? void 0 : _a.area) === null || _b === void 0 ? void 0 : _b.toLocaleString()) || '-'} ㎡`;
100
+ const costText = `공사비 : ${((_d = (_c = project === null || project === void 0 ? void 0 : project.buildingComplex) === null || _c === void 0 ? void 0 : _c.constructionCost) === null || _d === void 0 ? void 0 : _d.toLocaleString()) || '-'} 원`;
101
+ const householdCountText = `세대수 : ${((_f = (_e = project === null || project === void 0 ? void 0 : project.buildingComplex) === null || _e === void 0 ? void 0 : _e.householdCount) === null || _f === void 0 ? void 0 : _f.toLocaleString()) || '-'} 세대`;
102
+ return html `
103
+ <div tr @click=${() => navigate(`project-detail/${project.id}`)}>
104
+ <div td-pics>
105
+ <img pic src=${((_g = project.mainPhoto) === null || _g === void 0 ? void 0 : _g.fullpath) || '/assets/images/no-image.png'} alt="${project.name}" />
106
+ </div>
107
+ <div td-status>${PROJECT_STATE[project.state]}</div>
108
+ <div td-info>
109
+ <div class="name">${project.name}</div>
110
+ <div class="sub">주소 : ${((_h = project.buildingComplex) === null || _h === void 0 ? void 0 : _h.address) || ''}</div>
111
+ <div class="sub">착공~준공 : ${project.startDate} ~ ${project.endDate}</div>
112
+ </div>
113
+ <div td-etc>${areaText + '\n' + costText + '\n' + householdCountText}</div>
114
+ <div td-request>KPI입력 요청 -건</div>
115
+ <div td-kpi>
116
+ <kpi-single-boxplot-chart
117
+ .data=${{
118
+ min: 0,
119
+ max: 100,
120
+ mean: 50,
121
+ median: 60,
122
+ q1: 25,
123
+ q3: 75,
124
+ value: project.kpi
125
+ }}
126
+ ></kpi-single-boxplot-chart>
127
+ <span class="kpi-value">${(_k = (_j = project.kpi) === null || _j === void 0 ? void 0 : _j.toFixed(0)) !== null && _k !== void 0 ? _k : '-'}</span>
128
+ </div>
129
+ </div>
130
+ `;
131
+ })}
132
+ </div>
133
+ </div>
134
+ <sv-pagenation-control
135
+ .currentPage=${this.currentPage}
136
+ .totalItems=${this.projectCount}
137
+ .pageLimit=${this.pageLimit}
138
+ @page-change=${(e) => this._changePage(e.detail.page)}
139
+ ></sv-pagenation-control>
140
+ `;
141
+ }
142
+ async pageUpdated(changes, lifecycle) {
143
+ if (this.active) {
144
+ this.getProjectList();
145
+ }
146
+ }
147
+ async getProjectList() {
148
+ var _a, _b;
149
+ const response = await client.query({
150
+ query: gql `
151
+ query Projects($filters: [Filter!], $sortings: [Sorting!], $pagination: Pagination) {
152
+ projects(filters: $filters, sortings: $sortings, pagination: $pagination) {
153
+ items {
154
+ id
155
+ name
156
+ state
157
+ startDate
158
+ endDate
159
+ mainPhoto {
160
+ fullpath
161
+ }
162
+ totalProgress
163
+ weeklyProgress
164
+ kpi
165
+ inspPassRate
166
+ robotProgressRate
167
+ structuralSafetyRate
168
+ buildingComplex {
169
+ address
170
+ area
171
+ clientCompany
172
+ constructionCost
173
+ householdCount
174
+ }
175
+ }
176
+ total
177
+ }
178
+ }
179
+ `,
180
+ variables: {
181
+ filters: [
182
+ { name: 'name', operator: 'search', value: `%${this.projectName}%` },
183
+ { name: 'state', operator: 'eq', value: ProjectState.ONGOING }
184
+ ],
185
+ sortings: [{ name: 'createdAt', desc: true }],
186
+ pagination: { page: this.currentPage, limit: this.pageLimit }
187
+ }
188
+ });
189
+ this.projectList = ((_a = response.data.projects) === null || _a === void 0 ? void 0 : _a.items) || [];
190
+ this.projectCount = ((_b = response.data.projects) === null || _b === void 0 ? void 0 : _b.total) || 0;
191
+ }
192
+ // Input 요소의 값이 변경될 때 호출되는 콜백 함수
193
+ _onInputChange(event) {
194
+ const target = event.target;
195
+ this[target.name] = target.value;
196
+ if (target.name === 'projectName') {
197
+ this.currentPage = 1;
198
+ }
199
+ }
200
+ // 검색창에서 엔터입력시 검색
201
+ _onKeypress(event) {
202
+ if (event.code === 'Enter') {
203
+ this.currentPage = 1;
204
+ this.getProjectList();
205
+ }
206
+ }
207
+ _changePage(page) {
208
+ const nextPage = Math.min(Math.max(1, page), this.totalPages);
209
+ if (nextPage !== this.currentPage) {
210
+ this.currentPage = nextPage;
211
+ this.getProjectList();
212
+ }
213
+ }
214
+ _openCreateProjectPopup() {
215
+ openPopup(html `<popup-project-create .refreshFn=${this.getProjectList.bind(this)}></popup-project-create>`, {
216
+ backdrop: true,
217
+ size: 'small',
218
+ title: '신규 프로젝트 생성'
219
+ });
220
+ }
221
+ };
222
+ SvProjectListPage.styles = [
223
+ css `
224
+ :host {
225
+ display: flex;
226
+ flex-direction: column;
227
+ overflow-y: auto;
228
+
229
+ width: 100%;
230
+ height: 100%;
231
+ background-color: var(--md-sys-color-background, #f6f6f6);
232
+
233
+ --grid-record-emphasized-background-color: red;
234
+ --grid-record-emphasized-color: yellow;
235
+ }
236
+
237
+ /* Material Symbols Outlined (stroke style) */
238
+ md-icon {
239
+ font-variation-settings:
240
+ 'FILL' 0,
241
+ 'wght' 400,
242
+ 'GRAD' 0,
243
+ 'opsz' 24;
244
+ }
245
+
246
+ /* Search bar (Figma: content > search bar) */
247
+ div[header] {
248
+ display: flex;
249
+ align-items: center;
250
+ gap: 10px;
251
+ margin: var(--spacing-large, 12px);
252
+ margin-bottom: 0;
253
+ padding: 12px 11px;
254
+ border-radius: 7px;
255
+ background-color: rgba(46, 164, 223, 0.1);
256
+ border: 1px solid rgba(46, 164, 223, 0.3);
257
+ }
258
+ div[header] div[search] {
259
+ display: flex;
260
+ align-items: center;
261
+ gap: 6px;
262
+ min-width: 186px;
263
+ }
264
+ div[header] div[search] md-icon {
265
+ color: #212529;
266
+ }
267
+ div[header] div[search] input[type='search'] {
268
+ border: none;
269
+ outline: none;
270
+ background: transparent;
271
+ font-size: 16px;
272
+ color: #212529;
273
+ padding: 2px 0;
274
+ border-bottom: 1px solid rgba(0, 0, 0, 0.2);
275
+ }
276
+ div[header] .spacer {
277
+ flex: 1;
278
+ }
279
+ div[header] div[count] {
280
+ font-size: 16px;
281
+ color: #000000;
282
+ margin-right: 6px;
283
+ }
284
+ div[header] md-icon[view] {
285
+ color: #35618e;
286
+ cursor: pointer;
287
+ }
288
+ div[header] md-icon[add] {
289
+ color: #4cbb49;
290
+ cursor: pointer;
291
+ }
292
+ div[header] button[add-project] {
293
+ display: flex;
294
+ align-items: center;
295
+ gap: 4px;
296
+ padding: 8px 12px;
297
+ background-color: #24be7b;
298
+ color: white;
299
+ border: none;
300
+ border-radius: 7px;
301
+ font-size: 14px;
302
+ font-weight: bold;
303
+ cursor: pointer;
304
+ margin-left: 8px;
305
+ }
306
+ div[header] button[add-project]:hover {
307
+ background-color: #1fa968;
308
+ }
309
+ div[header] button[add-project] md-icon {
310
+ color: white;
311
+ font-size: 18px;
312
+ }
313
+
314
+ /* Table (Figma: content > table) */
315
+ div[table] {
316
+ margin: var(--spacing-large, 12px);
317
+ border: 1px solid rgba(0, 0, 0, 0.15);
318
+ border-top: 2px solid #0c4da2;
319
+ border-radius: var(--md-sys-shape-corner-small, 5px);
320
+ overflow: hidden;
321
+ background: #ffffff;
322
+ min-height: fit-content;
323
+ }
324
+ div[table-header] {
325
+ display: grid;
326
+ grid-template-columns: 150px 80px 1fr 220px 150px 100px;
327
+ align-items: center;
328
+ justify-items: center;
329
+ height: 35px;
330
+ background: #f3f3fa;
331
+ padding: 0 25px;
332
+ column-gap: 30px;
333
+ }
334
+ div[table-header] div[col] {
335
+ font-size: 16px;
336
+ color: #212529;
337
+ line-height: 1.875em;
338
+ }
339
+ div[table-body] {
340
+ display: block;
341
+ }
342
+ div[tr] {
343
+ display: grid;
344
+ grid-template-columns: 150px 80px 1fr 220px 150px 100px;
345
+ align-items: center;
346
+ justify-items: center;
347
+ column-gap: 30px;
348
+ padding: 12px 25px;
349
+ background: #ffffff;
350
+ border-top: 1px solid rgba(0, 0, 0, 0.15);
351
+ cursor: pointer;
352
+ }
353
+ /* 좌측 정렬 요구사항 */
354
+ div[td-info],
355
+ div[td-etc] {
356
+ justify-self: start;
357
+ text-align: left;
358
+ }
359
+ div[td-pics] img[pic] {
360
+ width: 150px;
361
+ height: 90px;
362
+ object-fit: fill;
363
+ background: #e5e7eb;
364
+ border-radius: 2px;
365
+ }
366
+ div[td-status] {
367
+ font-weight: 700;
368
+ font-size: 16px;
369
+ color: #35618e;
370
+ line-height: 1;
371
+ }
372
+ div[td-info] {
373
+ display: flex;
374
+ flex-direction: column;
375
+ gap: 4px;
376
+ }
377
+ div[td-info] .name {
378
+ font-weight: 700;
379
+ font-size: 14px;
380
+ color: #000000;
381
+ }
382
+ div[td-info] .sub {
383
+ font-size: 14px;
384
+ color: #000000;
385
+ line-height: 1.7;
386
+ }
387
+ div[td-etc] {
388
+ font-size: 16px;
389
+ color: #212529;
390
+ white-space: pre-line;
391
+ }
392
+ div[td-request] {
393
+ font-weight: 700;
394
+ font-size: 16px;
395
+ color: #35618e;
396
+ white-space: pre-line;
397
+ }
398
+ div[td-kpi] {
399
+ display: flex;
400
+ align-items: center;
401
+ height: 100%;
402
+ }
403
+ div[td-kpi] .kpi-value {
404
+ font-weight: 700;
405
+ font-size: 22px;
406
+ color: #35618e;
407
+ width: 30px;
408
+ }
409
+ `
410
+ ];
411
+ __decorate([
412
+ state(),
413
+ __metadata("design:type", String)
414
+ ], SvProjectListPage.prototype, "projectName", void 0);
415
+ __decorate([
416
+ state(),
417
+ __metadata("design:type", Array)
418
+ ], SvProjectListPage.prototype, "projectList", void 0);
419
+ __decorate([
420
+ state(),
421
+ __metadata("design:type", Number)
422
+ ], SvProjectListPage.prototype, "projectCount", void 0);
423
+ __decorate([
424
+ state(),
425
+ __metadata("design:type", Number)
426
+ ], SvProjectListPage.prototype, "currentPage", void 0);
427
+ SvProjectListPage = __decorate([
428
+ customElement('sv-project-list')
429
+ ], SvProjectListPage);
430
+ export { SvProjectListPage };
431
+ //# sourceMappingURL=sv-project-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sv-project-list.js","sourceRoot":"","sources":["../../client/pages/sv-project-list.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '../components/kpi-single-boxplot-chart'\n\nimport { navigate, PageView } from '@operato/shell'\nimport { css, html } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { client } from '@operato/graphql'\nimport { openPopup } from '@operato/layout'\nimport gql from 'graphql-tag'\nimport { Attachment } from '@things-factory/attachment-base'\nimport type { FileUpload } from 'graphql-upload/GraphQLUpload.js'\nimport '../components/sv-pagenation-control'\nimport '@dssp/project/dist-client/pages/project/popup/popup-project-create'\n\nexport enum ProjectState {\n 'ONGOING' = '10',\n 'COMPLETED' = '20'\n}\nexport const PROJECT_STATE = {\n [ProjectState.ONGOING]: '진행중',\n [ProjectState.COMPLETED]: '완료'\n}\nexport enum BuildingInspectionStatus {\n WAIT = 'WAIT',\n OVERALL_WAIT = 'OVERALL_WAIT',\n REQUEST = 'REQUEST',\n OVERALL_REQUEST = 'OVERALL_REQUEST',\n PASS = 'PASS',\n FAIL = 'FAIL'\n}\nexport const BUILDING_INSPECTION_STATUS = {\n [BuildingInspectionStatus.WAIT]: '검측 대기',\n [BuildingInspectionStatus.OVERALL_WAIT]: '검측 대기',\n [BuildingInspectionStatus.REQUEST]: '검측 요청',\n [BuildingInspectionStatus.OVERALL_REQUEST]: '검측 요청',\n [BuildingInspectionStatus.PASS]: '합격',\n [BuildingInspectionStatus.FAIL]: '불합격'\n}\n\nexport enum ProjectType {\n DSSP = 'DSSP',\n DCSP = 'DCSP',\n DKPI = 'DKPI'\n}\n\nexport interface Project {\n id?: string\n name: string\n state: ProjectState\n startDate?: string\n endDate?: string\n mainPhoto?: Attachment\n mainPhotoUpload?: FileUpload\n totalProgress?: number\n weeklyProgress?: number\n kpi?: number\n inspPassRate?: number\n robotProgressRate?: number\n structuralSafetyRate?: number\n robotCount?: number\n scheduleTable?: Attachment\n buildingComplex: BuildingComplex\n projectType?: ProjectType\n}\nexport interface BuildingComplex {\n id?: string\n address?: string\n latitude?: number\n longitude?: number\n area?: number\n constructionCompany?: string\n clientCompany?: string\n designCompany?: string\n supervisoryCompany?: string\n drawing?: Attachment\n drawingUpload?: FileUpload\n constructionType?: string\n constructionCost?: number\n etc?: string\n householdCount?: number\n buildingCount?: number\n notice?: string\n planXScale?: number\n planYScale?: number\n overallConstructorEmails?: string[]\n taskConstructorEmails?: string[]\n overallSupervisoryEmails?: string[]\n taskSupervisoryEmails?: string[]\n buildings?: Building[]\n}\nexport interface Building {\n id?: string\n name: string | undefined\n floorCount: number | undefined\n hasBasement?: boolean\n basementFloorCount?: number\n drawing?: Attachment\n drawingUpload?: FileUpload\n buildingLevels?: BuildingLevel[]\n}\n\nexport interface BuildingLevel {\n id?: string\n floor?: number\n floorDisplayName?: string\n mainDrawing?: Attachment\n mainDrawingImage?: string\n mainDrawingThumbnail?: string\n mainDrawingUpload?: FileUpload\n elevationDrawing?: Attachment\n elevationDrawingThumbnail?: string\n elevationDrawingUpload?: FileUpload\n rebarDistributionDrawing?: Attachment\n rebarDistributionDrawingThumbnail?: string\n rebarDistributionDrawingUpload?: FileUpload\n etcDrawings?: Attachment[]\n etcDrawingsUpload?: FileUpload[]\n building?: Building\n buildingInspections?: BuildingInspection[]\n}\n\nexport interface BuildingInspection {\n id?: string\n attatchments?: Attachment[]\n // buildingInspectionAttachments?: BuildingInspectionAttachment[]\n status?: BuildingInspectionStatus\n requestDate?: Date\n buildingLevel?: BuildingLevel\n checklist?: Checklist\n createdAt?: Date\n updatedAt?: Date\n deletedAt?: Date\n}\n\nexport interface Checklist {\n id: string\n name?: string\n documentNo?: string\n constructionType?: string\n constructionDetailType?: string\n location?: string\n constructionInspectorDate?: Date\n supervisorInspectorDate?: Date\n overallConstructorSignature?: string\n taskConstructorSignature?: string\n overallSupervisorySignature?: string\n taskSupervisorySignature?: string\n inspectionParts?: string[]\n // checklistItems?: ChecklistItem[]\n}\n\n@customElement('sv-project-list')\nexport class SvProjectListPage extends ScopedElementsMixin(PageView) {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n\n width: 100%;\n height: 100%;\n background-color: var(--md-sys-color-background, #f6f6f6);\n\n --grid-record-emphasized-background-color: red;\n --grid-record-emphasized-color: yellow;\n }\n\n /* Material Symbols Outlined (stroke style) */\n md-icon {\n font-variation-settings:\n 'FILL' 0,\n 'wght' 400,\n 'GRAD' 0,\n 'opsz' 24;\n }\n\n /* Search bar (Figma: content > search bar) */\n div[header] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: var(--spacing-large, 12px);\n margin-bottom: 0;\n padding: 12px 11px;\n border-radius: 7px;\n background-color: rgba(46, 164, 223, 0.1);\n border: 1px solid rgba(46, 164, 223, 0.3);\n }\n div[header] div[search] {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 186px;\n }\n div[header] div[search] md-icon {\n color: #212529;\n }\n div[header] div[search] input[type='search'] {\n border: none;\n outline: none;\n background: transparent;\n font-size: 16px;\n color: #212529;\n padding: 2px 0;\n border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n }\n div[header] .spacer {\n flex: 1;\n }\n div[header] div[count] {\n font-size: 16px;\n color: #000000;\n margin-right: 6px;\n }\n div[header] md-icon[view] {\n color: #35618e;\n cursor: pointer;\n }\n div[header] md-icon[add] {\n color: #4cbb49;\n cursor: pointer;\n }\n div[header] button[add-project] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 12px;\n background-color: #24be7b;\n color: white;\n border: none;\n border-radius: 7px;\n font-size: 14px;\n font-weight: bold;\n cursor: pointer;\n margin-left: 8px;\n }\n div[header] button[add-project]:hover {\n background-color: #1fa968;\n }\n div[header] button[add-project] md-icon {\n color: white;\n font-size: 18px;\n }\n\n /* Table (Figma: content > table) */\n div[table] {\n margin: var(--spacing-large, 12px);\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-top: 2px solid #0c4da2;\n border-radius: var(--md-sys-shape-corner-small, 5px);\n overflow: hidden;\n background: #ffffff;\n min-height: fit-content;\n }\n div[table-header] {\n display: grid;\n grid-template-columns: 150px 80px 1fr 220px 150px 100px;\n align-items: center;\n justify-items: center;\n height: 35px;\n background: #f3f3fa;\n padding: 0 25px;\n column-gap: 30px;\n }\n div[table-header] div[col] {\n font-size: 16px;\n color: #212529;\n line-height: 1.875em;\n }\n div[table-body] {\n display: block;\n }\n div[tr] {\n display: grid;\n grid-template-columns: 150px 80px 1fr 220px 150px 100px;\n align-items: center;\n justify-items: center;\n column-gap: 30px;\n padding: 12px 25px;\n background: #ffffff;\n border-top: 1px solid rgba(0, 0, 0, 0.15);\n cursor: pointer;\n }\n /* 좌측 정렬 요구사항 */\n div[td-info],\n div[td-etc] {\n justify-self: start;\n text-align: left;\n }\n div[td-pics] img[pic] {\n width: 150px;\n height: 90px;\n object-fit: fill;\n background: #e5e7eb;\n border-radius: 2px;\n }\n div[td-status] {\n font-weight: 700;\n font-size: 16px;\n color: #35618e;\n line-height: 1;\n }\n div[td-info] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n div[td-info] .name {\n font-weight: 700;\n font-size: 14px;\n color: #000000;\n }\n div[td-info] .sub {\n font-size: 14px;\n color: #000000;\n line-height: 1.7;\n }\n div[td-etc] {\n font-size: 16px;\n color: #212529;\n white-space: pre-line;\n }\n div[td-request] {\n font-weight: 700;\n font-size: 16px;\n color: #35618e;\n white-space: pre-line;\n }\n div[td-kpi] {\n display: flex;\n align-items: center;\n height: 100%;\n }\n div[td-kpi] .kpi-value {\n font-weight: 700;\n font-size: 22px;\n color: #35618e;\n width: 30px;\n }\n `\n ]\n\n get context() {\n return {\n title: '진행중 프로젝트'\n }\n }\n\n @state() private projectName: string = ''\n @state() private projectList: Project[] = []\n @state() private projectCount: number = 0\n @state() private currentPage: number = 1\n\n private readonly pageLimit: number = 20\n\n get totalPages(): number {\n return Math.max(1, Math.ceil((this.projectCount || 0) / this.pageLimit))\n }\n\n render() {\n return html`\n <div header>\n <div search>\n <md-icon>manage_search</md-icon>\n <input\n type=\"search\"\n name=\"projectName\"\n placeholder=\"프로젝트명\"\n .value=${this.projectName}\n @input=${this._onInputChange}\n @keypress=${this._onKeypress}\n />\n </div>\n\n <span class=\"spacer\"></span>\n <div count>총 ${this.projectCount}건</div>\n\n <button add-project @click=${this._openCreateProjectPopup}>\n <md-icon>add</md-icon>\n 신규 프로젝트 생성\n </button>\n </div>\n\n <div table>\n <div table-header>\n <div col></div>\n <div col>현장상태</div>\n <div col>현장정보</div>\n <div col>기타정보</div>\n <div col>입력요청</div>\n <div col>종합KPI</div>\n </div>\n <div table-body>\n ${this.projectList?.map((project: Project) => {\n const areaText = `연면적 : ${project?.buildingComplex?.area?.toLocaleString() || '-'} ㎡`\n const costText = `공사비 : ${project?.buildingComplex?.constructionCost?.toLocaleString() || '-'} 원`\n const householdCountText = `세대수 : ${project?.buildingComplex?.householdCount?.toLocaleString() || '-'} 세대`\n\n return html`\n <div tr @click=${() => navigate(`project-detail/${project.id}`)}>\n <div td-pics>\n <img pic src=${project.mainPhoto?.fullpath || '/assets/images/no-image.png'} alt=\"${project.name}\" />\n </div>\n <div td-status>${PROJECT_STATE[project.state]}</div>\n <div td-info>\n <div class=\"name\">${project.name}</div>\n <div class=\"sub\">주소 : ${project.buildingComplex?.address || ''}</div>\n <div class=\"sub\">착공~준공 : ${project.startDate} ~ ${project.endDate}</div>\n </div>\n <div td-etc>${areaText + '\\n' + costText + '\\n' + householdCountText}</div>\n <div td-request>KPI입력 요청 -건</div>\n <div td-kpi>\n <kpi-single-boxplot-chart\n .data=${{\n min: 0,\n max: 100,\n mean: 50,\n median: 60,\n q1: 25,\n q3: 75,\n value: project.kpi\n }}\n ></kpi-single-boxplot-chart>\n <span class=\"kpi-value\">${project.kpi?.toFixed(0) ?? '-'}</span>\n </div>\n </div>\n `\n })}\n </div>\n </div>\n <sv-pagenation-control\n .currentPage=${this.currentPage}\n .totalItems=${this.projectCount}\n .pageLimit=${this.pageLimit}\n @page-change=${(e: CustomEvent) => this._changePage(e.detail.page)}\n ></sv-pagenation-control>\n `\n }\n\n async pageUpdated(changes: any, lifecycle: any) {\n if (this.active) {\n this.getProjectList()\n }\n }\n\n async getProjectList() {\n const response = await client.query({\n query: gql`\n query Projects($filters: [Filter!], $sortings: [Sorting!], $pagination: Pagination) {\n projects(filters: $filters, sortings: $sortings, pagination: $pagination) {\n items {\n id\n name\n state\n startDate\n endDate\n mainPhoto {\n fullpath\n }\n totalProgress\n weeklyProgress\n kpi\n inspPassRate\n robotProgressRate\n structuralSafetyRate\n buildingComplex {\n address\n area\n clientCompany\n constructionCost\n householdCount\n }\n }\n total\n }\n }\n `,\n variables: {\n filters: [\n { name: 'name', operator: 'search', value: `%${this.projectName}%` },\n { name: 'state', operator: 'eq', value: ProjectState.ONGOING }\n ],\n sortings: [{ name: 'createdAt', desc: true }],\n pagination: { page: this.currentPage, limit: this.pageLimit }\n }\n })\n\n this.projectList = response.data.projects?.items || []\n this.projectCount = response.data.projects?.total || 0\n }\n\n // Input 요소의 값이 변경될 때 호출되는 콜백 함수\n private _onInputChange(event: InputEvent) {\n const target = event.target as HTMLInputElement\n this[target.name] = target.value\n if (target.name === 'projectName') {\n this.currentPage = 1\n }\n }\n\n // 검색창에서 엔터입력시 검색\n private _onKeypress(event: KeyboardEvent) {\n if (event.code === 'Enter') {\n this.currentPage = 1\n this.getProjectList()\n }\n }\n\n private _changePage(page: number) {\n const nextPage = Math.min(Math.max(1, page), this.totalPages)\n if (nextPage !== this.currentPage) {\n this.currentPage = nextPage\n this.getProjectList()\n }\n }\n\n private _openCreateProjectPopup() {\n openPopup(html`<popup-project-create .refreshFn=${this.getProjectList.bind(this)}></popup-project-create>`, {\n backdrop: true,\n size: 'small',\n title: '신규 프로젝트 생성'\n })\n }\n}\n"]}
@@ -1 +1 @@
1
- export default function route(page: string): "/dashboard" | "users" | undefined;
1
+ export default function route(page: string): "project-list" | "project-completed-list" | "kpi-value-list" | "kpi-metric-value-list" | "kpi-metric-value-manual-entry" | "users" | "/kpi-dashboard-map" | "project-detail" | "project-complete" | undefined;
@@ -1,10 +1,31 @@
1
1
  export default function route(page) {
2
2
  switch (page) {
3
3
  case '':
4
- return '/dashboard';
4
+ return '/kpi-dashboard-map';
5
5
  case 'users':
6
6
  import('./pages/sv-user-management');
7
7
  return page;
8
+ case 'project-list':
9
+ import('./pages/sv-project-list');
10
+ return page;
11
+ case 'project-completed-list':
12
+ import('./pages/sv-project-completed-list');
13
+ return page;
14
+ case 'project-detail':
15
+ import('./pages/sv-project-detail');
16
+ return page;
17
+ case 'project-complete':
18
+ import('./pages/sv-project-complete');
19
+ return page;
20
+ case 'kpi-value-list':
21
+ import('./pages/kpi-value/kpi-value-list-page');
22
+ return page;
23
+ case 'kpi-metric-value-list':
24
+ import('./pages/kpi-metric-value/kpi-metric-value-list-page');
25
+ return page;
26
+ case 'kpi-metric-value-manual-entry':
27
+ import('./pages/kpi-metric-value/kpi-metric-value-manual-entry-page');
28
+ return page;
8
29
  }
9
30
  }
10
31
  //# sourceMappingURL=route.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sourceRoot":"","sources":["../client/route.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,IAAY;IACxC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,EAAE;YACL,OAAO,YAAY,CAAA;QAErB,KAAK,OAAO;YACV,MAAM,CAAC,4BAA4B,CAAC,CAAA;YACpC,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC","sourcesContent":["export default function route(page: string) {\n switch (page) {\n case '':\n return '/dashboard'\n\n case 'users':\n import('./pages/sv-user-management')\n return page\n }\n}\n"]}
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../client/route.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,IAAY;IACxC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,EAAE;YACL,OAAO,oBAAoB,CAAA;QAE7B,KAAK,OAAO;YACV,MAAM,CAAC,4BAA4B,CAAC,CAAA;YACpC,OAAO,IAAI,CAAA;QAEb,KAAK,cAAc;YACjB,MAAM,CAAC,yBAAyB,CAAC,CAAA;YACjC,OAAO,IAAI,CAAA;QAEb,KAAK,wBAAwB;YAC3B,MAAM,CAAC,mCAAmC,CAAC,CAAA;YAC3C,OAAO,IAAI,CAAA;QAEb,KAAK,gBAAgB;YACnB,MAAM,CAAC,2BAA2B,CAAC,CAAA;YACnC,OAAO,IAAI,CAAA;QAEb,KAAK,kBAAkB;YACrB,MAAM,CAAC,6BAA6B,CAAC,CAAA;YACrC,OAAO,IAAI,CAAA;QAEb,KAAK,gBAAgB;YACnB,MAAM,CAAC,uCAAuC,CAAC,CAAA;YAC/C,OAAO,IAAI,CAAA;QAEb,KAAK,uBAAuB;YAC1B,MAAM,CAAC,qDAAqD,CAAC,CAAA;YAC7D,OAAO,IAAI,CAAA;QAEb,KAAK,+BAA+B;YAClC,MAAM,CAAC,6DAA6D,CAAC,CAAA;YACrE,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC","sourcesContent":["export default function route(page: string) {\n switch (page) {\n case '':\n return '/kpi-dashboard-map'\n\n case 'users':\n import('./pages/sv-user-management')\n return page\n\n case 'project-list':\n import('./pages/sv-project-list')\n return page\n\n case 'project-completed-list':\n import('./pages/sv-project-completed-list')\n return page\n\n case 'project-detail':\n import('./pages/sv-project-detail')\n return page\n\n case 'project-complete':\n import('./pages/sv-project-complete')\n return page\n\n case 'kpi-value-list':\n import('./pages/kpi-value/kpi-value-list-page')\n return page\n\n case 'kpi-metric-value-list':\n import('./pages/kpi-metric-value/kpi-metric-value-list-page')\n return page\n\n case 'kpi-metric-value-manual-entry':\n import('./pages/kpi-metric-value/kpi-metric-value-manual-entry-page')\n return page\n }\n}\n"]}
@@ -0,0 +1,5 @@
1
+ export declare const getProject: (projectId: string) => Promise<any>;
2
+ export declare const getKpiMetrics: () => Promise<any>;
3
+ export declare const getKpiMetricValues: (projectId: string) => Promise<any>;
4
+ export declare const updateProjectCompleteStep1: (patches: any) => Promise<import("@apollo/client").InteropMutateResult<any>>;
5
+ export declare const getKpiCategories: () => Promise<any>;
@@ -0,0 +1,125 @@
1
+ import { gql } from '@apollo/client';
2
+ import { client } from '@operato/graphql';
3
+ export const getProject = async (projectId) => {
4
+ const response = await client.query({
5
+ query: gql `
6
+ query Project($id: String!) {
7
+ project(id: $id) {
8
+ id
9
+ name
10
+ startDate
11
+ endDate
12
+ state
13
+
14
+ completeReports {
15
+ id
16
+ name
17
+ fullpath
18
+ }
19
+
20
+ buildingComplex {
21
+ id
22
+ coverageRatio
23
+ floorAreaRatio
24
+ workerCount
25
+ designChangeCount
26
+ constructionCost
27
+ area
28
+ }
29
+ }
30
+ }
31
+ `,
32
+ variables: { id: projectId }
33
+ });
34
+ if (response.errors) {
35
+ return {};
36
+ }
37
+ return response.data.project;
38
+ };
39
+ export const getKpiMetrics = async () => {
40
+ const response = await client.query({
41
+ query: gql `
42
+ query KpiMetrics {
43
+ kpiMetrics {
44
+ items {
45
+ id
46
+ name
47
+ unit
48
+ periodType
49
+ }
50
+ }
51
+ }
52
+ `
53
+ });
54
+ if (response.errors) {
55
+ return [];
56
+ }
57
+ return response.data.kpiMetrics.items;
58
+ };
59
+ export const getKpiMetricValues = async (projectId) => {
60
+ const filters = [{ name: 'org', operator: 'eq', value: projectId }];
61
+ const response = await client.query({
62
+ query: gql `
63
+ query KpiMetricValues($filters: [Filter!]) {
64
+ kpiMetricValues(filters: $filters) {
65
+ items {
66
+ id
67
+ value
68
+ unit
69
+ periodType
70
+ metricId
71
+ }
72
+ }
73
+ }
74
+ `,
75
+ variables: {
76
+ filters
77
+ }
78
+ });
79
+ if (response.errors) {
80
+ return [];
81
+ }
82
+ return response.data.kpiMetricValues.items;
83
+ };
84
+ export const updateProjectCompleteStep1 = async (patches) => {
85
+ const response = await client.mutate({
86
+ mutation: gql `
87
+ mutation UpdateKpiMetricValuesCumulative($patches: [KpiMetricValuePatch!]!) {
88
+ updateKpiMetricValuesCumulative(patches: $patches) {
89
+ id
90
+ }
91
+ }
92
+ `,
93
+ variables: {
94
+ patches
95
+ }
96
+ });
97
+ return response;
98
+ };
99
+ export const getKpiCategories = async () => {
100
+ const response = await client.query({
101
+ query: gql `
102
+ query {
103
+ kpiCategories: kpisLevel1 {
104
+ id
105
+ name
106
+ description
107
+ active
108
+ kpis: children {
109
+ id
110
+ name
111
+ description
112
+ formula
113
+ active
114
+ grades
115
+ }
116
+ }
117
+ }
118
+ `
119
+ });
120
+ if (response.errors) {
121
+ return [];
122
+ }
123
+ return response.data.kpiCategories;
124
+ };
125
+ //# sourceMappingURL=complete-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complete-api.js","sourceRoot":"","sources":["../../client/shared/complete-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAEzC,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,SAAiB,EAAE,EAAE;IACpD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;KA0BT;QACD,SAAS,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;KAC7B,CAAC,CAAA;IAEF,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpB,OAAO,EAAE,CAAA;IACX,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAA;AAC9B,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,IAAI,EAAE;IACtC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;KAWT;KACF,CAAC,CAAA;IAEF,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpB,OAAO,EAAE,CAAA;IACX,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAA;AACvC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EAAE,SAAiB,EAAE,EAAE;IAC5D,MAAM,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;IAEnE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;KAYT;QACD,SAAS,EAAE;YACT,OAAO;SACR;KACF,CAAC,CAAA;IAEF,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpB,OAAO,EAAE,CAAA;IACX,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAA;AAC5C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,0BAA0B,GAAG,KAAK,EAAE,OAAY,EAAE,EAAE;IAC/D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;QACnC,QAAQ,EAAE,GAAG,CAAA;;;;;;KAMZ;QACD,SAAS,EAAE;YACT,OAAO;SACR;KACF,CAAC,CAAA;IAEF,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;IACzC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;KAiBT;KACF,CAAC,CAAA;IAEF,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpB,OAAO,EAAE,CAAA;IACX,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAA;AACpC,CAAC,CAAA","sourcesContent":["import { gql } from '@apollo/client'\nimport { client } from '@operato/graphql'\n\nexport const getProject = async (projectId: string) => {\n const response = await client.query({\n query: gql`\n query Project($id: String!) {\n project(id: $id) {\n id\n name\n startDate\n endDate\n state\n\n completeReports {\n id\n name\n fullpath\n }\n\n buildingComplex {\n id\n coverageRatio\n floorAreaRatio\n workerCount\n designChangeCount\n constructionCost\n area\n }\n }\n }\n `,\n variables: { id: projectId }\n })\n\n if (response.errors) {\n return {}\n }\n\n return response.data.project\n}\n\nexport const getKpiMetrics = async () => {\n const response = await client.query({\n query: gql`\n query KpiMetrics {\n kpiMetrics {\n items {\n id\n name\n unit\n periodType\n }\n }\n }\n `\n })\n\n if (response.errors) {\n return []\n }\n\n return response.data.kpiMetrics.items\n}\n\nexport const getKpiMetricValues = async (projectId: string) => {\n const filters = [{ name: 'org', operator: 'eq', value: projectId }]\n\n const response = await client.query({\n query: gql`\n query KpiMetricValues($filters: [Filter!]) {\n kpiMetricValues(filters: $filters) {\n items {\n id\n value\n unit\n periodType\n metricId\n }\n }\n }\n `,\n variables: {\n filters\n }\n })\n\n if (response.errors) {\n return []\n }\n\n return response.data.kpiMetricValues.items\n}\n\nexport const updateProjectCompleteStep1 = async (patches: any) => {\n const response = await client.mutate({\n mutation: gql`\n mutation UpdateKpiMetricValuesCumulative($patches: [KpiMetricValuePatch!]!) {\n updateKpiMetricValuesCumulative(patches: $patches) {\n id\n }\n }\n `,\n variables: {\n patches\n }\n })\n\n return response\n}\n\nexport const getKpiCategories = async () => {\n const response = await client.query({\n query: gql`\n query {\n kpiCategories: kpisLevel1 {\n id\n name\n description\n active\n kpis: children {\n id\n name\n description\n formula\n active\n grades\n }\n }\n }\n `\n })\n\n if (response.errors) {\n return []\n }\n\n return response.data.kpiCategories\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare const calcDiff: (a: string, b: string) => number;
2
+ export declare const calcDateDiff: (a: string, b: string) => number;