@dssp/dkpi 1.0.0-alpha.41 → 1.0.0-alpha.47

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 (54) hide show
  1. package/dist-client/components/{pagenation.d.ts → sv-pagenation-control.d.ts} +1 -1
  2. package/dist-client/components/{pagenation.js → sv-pagenation-control.js} +10 -10
  3. package/dist-client/components/sv-pagenation-control.js.map +1 -0
  4. package/dist-client/icons/menu-icons.d.ts +6 -0
  5. package/dist-client/icons/menu-icons.js +42 -0
  6. package/dist-client/icons/menu-icons.js.map +1 -1
  7. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.d.ts +12 -0
  8. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js +274 -0
  9. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js.map +1 -0
  10. package/dist-client/pages/project-complete-tabs/pc-tab2-final.d.ts +11 -0
  11. package/dist-client/pages/project-complete-tabs/pc-tab2-final.js +277 -0
  12. package/dist-client/pages/project-complete-tabs/pc-tab2-final.js.map +1 -0
  13. package/dist-client/pages/project-complete-tabs/pc-tab3-rating.d.ts +10 -0
  14. package/dist-client/pages/project-complete-tabs/pc-tab3-rating.js +230 -0
  15. package/dist-client/pages/project-complete-tabs/pc-tab3-rating.js.map +1 -0
  16. package/dist-client/pages/project-complete-tabs/pc-tab4-upload.d.ts +13 -0
  17. package/dist-client/pages/project-complete-tabs/pc-tab4-upload.js +217 -0
  18. package/dist-client/pages/project-complete-tabs/pc-tab4-upload.js.map +1 -0
  19. package/dist-client/pages/sv-project-complete.d.ts +26 -0
  20. package/dist-client/pages/sv-project-complete.js +299 -0
  21. package/dist-client/pages/sv-project-complete.js.map +1 -0
  22. package/dist-client/pages/sv-project-completed-list.d.ts +1 -1
  23. package/dist-client/pages/sv-project-completed-list.js +189 -168
  24. package/dist-client/pages/sv-project-completed-list.js.map +1 -1
  25. package/dist-client/pages/sv-project-detail.d.ts +13 -0
  26. package/dist-client/pages/sv-project-detail.js +486 -0
  27. package/dist-client/pages/sv-project-detail.js.map +1 -0
  28. package/dist-client/pages/sv-project-list.d.ts +6 -1
  29. package/dist-client/pages/sv-project-list.js +201 -186
  30. package/dist-client/pages/sv-project-list.js.map +1 -1
  31. package/dist-client/route.d.ts +1 -1
  32. package/dist-client/route.js +6 -0
  33. package/dist-client/route.js.map +1 -1
  34. package/dist-client/shared/complete-api.d.ts +3 -0
  35. package/dist-client/shared/complete-api.js +83 -0
  36. package/dist-client/shared/complete-api.js.map +1 -0
  37. package/dist-client/shared/func.d.ts +2 -0
  38. package/dist-client/shared/func.js +22 -0
  39. package/dist-client/shared/func.js.map +1 -0
  40. package/dist-client/tsconfig.tsbuildinfo +1 -1
  41. package/dist-client/viewparts/menu-tools.js +1 -0
  42. package/dist-client/viewparts/menu-tools.js.map +1 -1
  43. package/dist-server/service/index.d.ts +1 -1
  44. package/dist-server/service/kpi-metric-value/index.d.ts +2 -1
  45. package/dist-server/service/kpi-metric-value/index.js +2 -1
  46. package/dist-server/service/kpi-metric-value/index.js.map +1 -1
  47. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.d.ts +7 -0
  48. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +104 -0
  49. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -0
  50. package/dist-server/tsconfig.tsbuildinfo +1 -1
  51. package/package.json +4 -3
  52. package/schema.graphql +66 -3
  53. package/things-factory.config.js +3 -1
  54. package/dist-client/components/pagenation.js.map +0 -1
@@ -1,13 +1,13 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  import '@material/web/icon/icon.js';
3
- import { PageView } from '@operato/shell';
3
+ import { PageView, navigate } from '@operato/shell';
4
4
  import { css, html } from 'lit';
5
5
  import { customElement, state } from 'lit/decorators.js';
6
6
  import { ScopedElementsMixin } from '@open-wc/scoped-elements';
7
7
  import { client } from '@operato/graphql';
8
8
  import gql from 'graphql-tag';
9
- import { ProjectState } from './sv-project-list';
10
- import '../components/pagenation';
9
+ import { PROJECT_STATE, ProjectState } from './sv-project-list';
10
+ import '../components/sv-pagenation-control';
11
11
  let SvProjectCompletedListPage = class SvProjectCompletedListPage extends ScopedElementsMixin(PageView) {
12
12
  constructor() {
13
13
  super(...arguments);
@@ -29,56 +29,57 @@ let SvProjectCompletedListPage = class SvProjectCompletedListPage extends Scoped
29
29
  var _a;
30
30
  return html `
31
31
  <div header>
32
- <label>프로젝트 이름</label>
33
- <md-filled-text-field
34
- name="projectName"
35
- type="search"
36
- label="프로젝트 이름"
37
- .value=${this.projectName}
38
- @input=${this._onInputChange}
39
- @keypress=${this._onKeypress}
40
- >
41
- <md-icon slot="leading-icon">search</md-icon>
42
- </md-filled-text-field>
32
+ <div search>
33
+ <md-icon>manage_search</md-icon>
34
+ <input
35
+ type="search"
36
+ name="projectName"
37
+ placeholder="프로젝트명"
38
+ .value=${this.projectName}
39
+ @input=${this._onInputChange}
40
+ @keypress=${this._onKeypress}
41
+ />
42
+ </div>
43
43
 
44
- <strong>총 ${this.projectCount}개</strong>
44
+ <span class="spacer"></span>
45
+ <div count>총 ${this.projectCount}건</div>
45
46
  </div>
46
47
 
47
- <div body>
48
- ${(_a = this.projectList) === null || _a === void 0 ? void 0 : _a.map((project) => {
49
- var _a, _b, _c, _d, _e, _f;
48
+ <div table>
49
+ <div table-header>
50
+ <div col></div>
51
+ <div col>현장상태</div>
52
+ <div col>현장정보</div>
53
+ <div col>기타정보</div>
54
+ <div col>입력요청</div>
55
+ <div col>종합KPI</div>
56
+ </div>
57
+ <div table-body>
58
+ ${(_a = this.projectList) === null || _a === void 0 ? void 0 : _a.map((project) => {
59
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
60
+ 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()) || '-'} ㎡`;
61
+ 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()) || '-'} 원`;
62
+ 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()) || '-'} 세대`;
50
63
  return html `
51
- <div project-container>
52
- <a href=${`kpi-dashboard?projectId=${project.id}`}>
53
- <img
54
- ?no-image=${!((_a = project.mainPhoto) === null || _a === void 0 ? void 0 : _a.fullpath)}
55
- project-img
56
- src=${((_b = project.mainPhoto) === null || _b === void 0 ? void 0 : _b.fullpath) || '/assets/images/no-image.png'}
57
- />
58
-
59
- <span project-info>
60
- <div name>${project.name}</div>
61
- <div content>${project.buildingComplex.address}</div>
62
- <div content>면적: ${((_d = (_c = project.buildingComplex) === null || _c === void 0 ? void 0 : _c.area) === null || _d === void 0 ? void 0 : _d.toLocaleString()) || ''}㎡</div>
63
- <div content>착공~준공: ${project.startDate} ~ ${project.endDate}</div>
64
- <div content>발주처: <strong>${project.buildingComplex.clientCompany}</strong></div>
65
- </span>
66
-
67
- <span project-state>
68
- <div progress>
69
- <md-linear-progress buffer="100" max="100" value=${project.totalProgress || 0}> </md-linear-progress>
70
- <span>전체</span>
71
- <span>${project.totalProgress || 0}%</span>
72
- </div>
73
- <div>시공사: ${project.buildingComplex.constructionCompany}</div>
74
- <div>건설구분: ${project.buildingComplex.constructionType}</div>
75
- <div>세대수: ${((_f = (_e = project.buildingComplex) === null || _e === void 0 ? void 0 : _e.householdCount) === null || _f === void 0 ? void 0 : _f.toLocaleString()) || ''}세대</div>
76
- <div>기타: ${project.buildingComplex.etc}</div>
77
- </span>
78
- </a>
79
- </div>
80
- `;
64
+ <div tr @click=${() => navigate(`project-detail/${project.id}`)}>
65
+ <div td-pics>
66
+ <img pic src=${((_g = project.mainPhoto) === null || _g === void 0 ? void 0 : _g.fullpath) || '/assets/images/no-image.png'} alt="${project.name}" />
67
+ </div>
68
+ <div td-status>${PROJECT_STATE[project.state]}</div>
69
+ <div td-info>
70
+ <div class="name">${project.name}</div>
71
+ <div class="sub">주소 : ${((_h = project.buildingComplex) === null || _h === void 0 ? void 0 : _h.address) || ''}</div>
72
+ <div class="sub">착공~준공 : ${project.startDate} ~ ${project.endDate}</div>
73
+ </div>
74
+ <div td-etc>${areaText + '\n' + costText + '\n' + householdCountText}</div>
75
+ <div td-request>KPI입력 요청 -</div>
76
+ <div td-kpi>
77
+ <span class="kpi-value">${(_j = project.kpi) !== null && _j !== void 0 ? _j : 0}</span>
78
+ </div>
79
+ </div>
80
+ `;
81
81
  })}
82
+ </div>
82
83
  </div>
83
84
  <pagenation-control
84
85
  .currentPage=${this.currentPage}
@@ -102,6 +103,7 @@ let SvProjectCompletedListPage = class SvProjectCompletedListPage extends Scoped
102
103
  items {
103
104
  id
104
105
  name
106
+ state
105
107
  startDate
106
108
  endDate
107
109
  mainPhoto {
@@ -117,10 +119,8 @@ let SvProjectCompletedListPage = class SvProjectCompletedListPage extends Scoped
117
119
  address
118
120
  area
119
121
  clientCompany
120
- constructionCompany
121
- constructionType
122
+ constructionCost
122
123
  householdCount
123
- etc
124
124
  }
125
125
  }
126
126
  total
@@ -129,16 +129,8 @@ let SvProjectCompletedListPage = class SvProjectCompletedListPage extends Scoped
129
129
  `,
130
130
  variables: {
131
131
  filters: [
132
- {
133
- name: 'name',
134
- operator: 'search',
135
- value: `%${this.projectName}%`
136
- },
137
- {
138
- name: 'state',
139
- operator: 'eq',
140
- value: ProjectState.COMPLETED
141
- }
132
+ { name: 'name', operator: 'search', value: `%${this.projectName}%` },
133
+ { name: 'state', operator: 'eq', value: ProjectState.ONGOING }
142
134
  ],
143
135
  sortings: [{ name: 'createdAt', desc: true }],
144
136
  pagination: { page: this.currentPage, limit: this.pageLimit }
@@ -179,123 +171,152 @@ SvProjectCompletedListPage.styles = [
179
171
 
180
172
  width: 100%;
181
173
  height: 100%;
182
- background-color: #f7f7f7;
174
+ background-color: var(--md-sys-color-background, #f6f6f6);
183
175
 
184
176
  --grid-record-emphasized-background-color: red;
185
177
  --grid-record-emphasized-color: yellow;
186
178
  }
187
179
 
180
+ /* Search bar (Figma: content > search bar) */
188
181
  div[header] {
189
182
  display: flex;
190
183
  align-items: center;
191
- background-color: #2ea4df1a;
192
- border: 1px solid #2ea4df33;
193
- margin: 15px 23px;
194
- font-size: 18px;
195
- padding: 7px;
196
- border-radius: 5px;
197
-
198
- md-filled-text-field[type='search'] {
199
- margin-left: 5px;
200
- margin-right: 26px;
201
-
202
- --md-filled-text-field-container-shape: 0px;
203
- --md-sys-color-primary: #006a6a;
204
- --md-sys-color-surface-container-highest: transparent;
205
- --md-filled-text-field-label-text-color: #999999;
206
- --md-filled-text-field-input-text-color: #4e5055;
207
- }
208
-
209
- md-elevated-button[add-project] {
210
- font-weight: bold;
211
- font-size: 16px;
212
- margin-left: 17px;
213
- padding: 13px 20px;
214
-
215
- --md-sys-color-surface-container-low: #24be7b;
216
- --md-sys-color-primary: #ffffff;
217
- --md-elevated-button-container-shape: 7px;
218
- }
184
+ gap: 10px;
185
+ margin: var(--spacing-large, 12px);
186
+ margin-bottom: 0;
187
+ padding: 5px 11px;
188
+ border-radius: 7px;
189
+ background-color: rgba(46, 164, 223, 0.1);
190
+ border: 1px solid rgba(46, 164, 223, 0.3);
191
+ }
192
+ div[header] div[search] {
193
+ display: flex;
194
+ align-items: center;
195
+ gap: 6px;
196
+ min-width: 186px;
197
+ }
198
+ div[header] div[search] md-icon {
199
+ color: #212529;
200
+ }
201
+ div[header] div[search] input[type='search'] {
202
+ border: none;
203
+ outline: none;
204
+ background: transparent;
205
+ font-size: 16px;
206
+ color: #212529;
207
+ padding: 2px 0;
208
+ border-bottom: 1px solid rgba(0, 0, 0, 0.2);
209
+ }
210
+ div[header] .spacer {
211
+ flex: 1;
212
+ }
213
+ div[header] div[count] {
214
+ font-size: 16px;
215
+ color: #000000;
216
+ margin-right: 6px;
217
+ }
218
+ div[header] md-icon[view] {
219
+ color: #35618e;
220
+ cursor: pointer;
221
+ }
222
+ div[header] md-icon[add] {
223
+ color: #4cbb49;
224
+ cursor: pointer;
219
225
  }
220
226
 
221
- div[body] {
222
- div[project-container] {
223
- height: 140px;
224
- margin: 17px 23px;
225
- background-color: #ffffff;
226
- border: 1px solid #cccccc80;
227
- border-radius: 5px;
228
-
229
- & > a {
230
- display: flex;
231
- width: 100%;
232
- height: 100%;
233
- text-decoration: none;
234
- color: #000;
235
- }
236
-
237
- img[project-img] {
238
- width: 285px;
239
- background-color: #cccccc80;
240
- }
241
- img[project-img][no-image] {
242
- object-fit: contain;
243
- opacity: 0.5;
244
- }
245
-
246
- span[project-info] {
247
- flex: 0.45;
248
- padding: 6px 15px;
249
- font-size: 16px;
250
-
251
- white-space: nowrap;
252
- overflow: hidden;
253
- text-overflow: ellipsis;
254
-
255
- div[name] {
256
- color: #2e79be;
257
- font-weight: bold;
258
- font-size: 19px;
259
- margin-bottom: 2px;
260
- }
261
- }
262
-
263
- span[project-state] {
264
- flex: 0.55;
265
- padding: 10px 20px;
266
-
267
- & > div {
268
- margin-bottom: 3px;
269
- }
270
-
271
- div[progress] {
272
- position: relative;
273
-
274
- md-linear-progress {
275
- --md-linear-progress-track-height: 18px;
276
- --md-linear-progress-active-indicator-height: 18px;
277
- --md-linear-progress-track-shape: 5px;
278
- --md-sys-color-primary: #1bb40133;
279
- --md-sys-color-surface-container-highest: #0595e533;
280
- --md-linear-progress-track-color: #1bb4011a;
281
- }
282
-
283
- span {
284
- position: absolute;
285
- top: 0;
286
- left: 12px;
287
- font-size: 12px;
288
- font-weight: bold;
289
- color: #1bb401;
290
-
291
- &:last-child {
292
- left: unset;
293
- right: 12px;
294
- }
295
- }
296
- }
297
- }
298
- }
227
+ /* Table (Figma: content > table) */
228
+ div[table] {
229
+ margin: var(--spacing-large, 12px);
230
+ border: 1px solid rgba(0, 0, 0, 0.15);
231
+ border-top: 2px solid #0c4da2;
232
+ border-radius: var(--md-sys-shape-corner-small, 5px);
233
+ overflow: hidden;
234
+ background: #ffffff;
235
+ overflow-y: auto;
236
+ min-height: fit-content;
237
+ }
238
+ div[table-header] {
239
+ display: grid;
240
+ grid-template-columns: 150px 80px 1fr 220px 150px 100px;
241
+ align-items: center;
242
+ justify-items: center;
243
+ height: 35px;
244
+ background: #f3f3fa;
245
+ padding: 0 25px;
246
+ column-gap: 30px;
247
+ }
248
+ div[table-header] div[col] {
249
+ font-size: 16px;
250
+ color: #212529;
251
+ line-height: 1.875em;
252
+ }
253
+ div[table-body] {
254
+ display: block;
255
+ }
256
+ div[tr] {
257
+ display: grid;
258
+ grid-template-columns: 150px 80px 1fr 220px 150px 100px;
259
+ align-items: center;
260
+ justify-items: center;
261
+ column-gap: 30px;
262
+ padding: 12px 25px;
263
+ background: #ffffff;
264
+ border-top: 1px solid rgba(0, 0, 0, 0.15);
265
+ cursor: pointer;
266
+ }
267
+ /* 좌측 정렬 요구사항 */
268
+ div[td-info],
269
+ div[td-etc] {
270
+ justify-self: start;
271
+ text-align: left;
272
+ }
273
+ div[td-pics] img[pic] {
274
+ width: 150px;
275
+ height: 90px;
276
+ object-fit: cover;
277
+ background: #e5e7eb;
278
+ border-radius: 2px;
279
+ }
280
+ div[td-status] {
281
+ font-weight: 700;
282
+ font-size: 16px;
283
+ color: #4cbb49;
284
+ line-height: 1;
285
+ }
286
+ div[td-info] {
287
+ display: flex;
288
+ flex-direction: column;
289
+ gap: 4px;
290
+ }
291
+ div[td-info] .name {
292
+ font-weight: 700;
293
+ font-size: 14px;
294
+ color: #000000;
295
+ }
296
+ div[td-info] .sub {
297
+ font-size: 14px;
298
+ color: #000000;
299
+ line-height: 1.7;
300
+ }
301
+ div[td-etc] {
302
+ font-size: 16px;
303
+ color: #212529;
304
+ white-space: pre-line;
305
+ }
306
+ div[td-request] {
307
+ font-weight: 700;
308
+ font-size: 16px;
309
+ color: #35618e;
310
+ white-space: pre-line;
311
+ }
312
+ div[td-kpi] {
313
+ display: flex;
314
+ justify-content: flex-end;
315
+ }
316
+ div[td-kpi] .kpi-value {
317
+ font-weight: 700;
318
+ font-size: 22px;
319
+ color: #35618e;
299
320
  }
300
321
  `
301
322
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"sv-project-completed-list.js","sourceRoot":"","sources":["../../client/pages/sv-project-completed-list.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { 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 gql from 'graphql-tag'\nimport { Project, ProjectState } from './sv-project-list'\nimport '../components/pagenation'\n\n@customElement('sv-project-completed-list')\nexport class SvProjectCompletedListPage 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: #f7f7f7;\n\n --grid-record-emphasized-background-color: red;\n --grid-record-emphasized-color: yellow;\n }\n\n div[header] {\n display: flex;\n align-items: center;\n background-color: #2ea4df1a;\n border: 1px solid #2ea4df33;\n margin: 15px 23px;\n font-size: 18px;\n padding: 7px;\n border-radius: 5px;\n\n md-filled-text-field[type='search'] {\n margin-left: 5px;\n margin-right: 26px;\n\n --md-filled-text-field-container-shape: 0px;\n --md-sys-color-primary: #006a6a;\n --md-sys-color-surface-container-highest: transparent;\n --md-filled-text-field-label-text-color: #999999;\n --md-filled-text-field-input-text-color: #4e5055;\n }\n\n md-elevated-button[add-project] {\n font-weight: bold;\n font-size: 16px;\n margin-left: 17px;\n padding: 13px 20px;\n\n --md-sys-color-surface-container-low: #24be7b;\n --md-sys-color-primary: #ffffff;\n --md-elevated-button-container-shape: 7px;\n }\n }\n\n div[body] {\n div[project-container] {\n height: 140px;\n margin: 17px 23px;\n background-color: #ffffff;\n border: 1px solid #cccccc80;\n border-radius: 5px;\n\n & > a {\n display: flex;\n width: 100%;\n height: 100%;\n text-decoration: none;\n color: #000;\n }\n\n img[project-img] {\n width: 285px;\n background-color: #cccccc80;\n }\n img[project-img][no-image] {\n object-fit: contain;\n opacity: 0.5;\n }\n\n span[project-info] {\n flex: 0.45;\n padding: 6px 15px;\n font-size: 16px;\n\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n\n div[name] {\n color: #2e79be;\n font-weight: bold;\n font-size: 19px;\n margin-bottom: 2px;\n }\n }\n\n span[project-state] {\n flex: 0.55;\n padding: 10px 20px;\n\n & > div {\n margin-bottom: 3px;\n }\n\n div[progress] {\n position: relative;\n\n md-linear-progress {\n --md-linear-progress-track-height: 18px;\n --md-linear-progress-active-indicator-height: 18px;\n --md-linear-progress-track-shape: 5px;\n --md-sys-color-primary: #1bb40133;\n --md-sys-color-surface-container-highest: #0595e533;\n --md-linear-progress-track-color: #1bb4011a;\n }\n\n span {\n position: absolute;\n top: 0;\n left: 12px;\n font-size: 12px;\n font-weight: bold;\n color: #1bb401;\n\n &:last-child {\n left: unset;\n right: 12px;\n }\n }\n }\n }\n }\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 <label>프로젝트 이름</label>\n <md-filled-text-field\n name=\"projectName\"\n type=\"search\"\n label=\"프로젝트 이름\"\n .value=${this.projectName}\n @input=${this._onInputChange}\n @keypress=${this._onKeypress}\n >\n <md-icon slot=\"leading-icon\">search</md-icon>\n </md-filled-text-field>\n\n <strong>총 ${this.projectCount}개</strong>\n </div>\n\n <div body>\n ${this.projectList?.map((project: Project) => {\n return html`\n <div project-container>\n <a href=${`kpi-dashboard?projectId=${project.id}`}>\n <img\n ?no-image=${!project.mainPhoto?.fullpath}\n project-img\n src=${project.mainPhoto?.fullpath || '/assets/images/no-image.png'}\n />\n\n <span project-info>\n <div name>${project.name}</div>\n <div content>${project.buildingComplex.address}</div>\n <div content>면적: ${project.buildingComplex?.area?.toLocaleString() || ''}㎡</div>\n <div content>착공~준공: ${project.startDate} ~ ${project.endDate}</div>\n <div content>발주처: <strong>${project.buildingComplex.clientCompany}</strong></div>\n </span>\n\n <span project-state>\n <div progress>\n <md-linear-progress buffer=\"100\" max=\"100\" value=${project.totalProgress || 0}> </md-linear-progress>\n <span>전체</span>\n <span>${project.totalProgress || 0}%</span>\n </div>\n <div>시공사: ${project.buildingComplex.constructionCompany}</div>\n <div>건설구분: ${project.buildingComplex.constructionType}</div>\n <div>세대수: ${project.buildingComplex?.householdCount?.toLocaleString() || ''}세대</div>\n <div>기타: ${project.buildingComplex.etc}</div>\n </span>\n </a>\n </div>\n `\n })}\n </div>\n <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 ></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 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 constructionCompany\n constructionType\n householdCount\n etc\n }\n }\n total\n }\n }\n `,\n variables: {\n filters: [\n {\n name: 'name',\n operator: 'search',\n value: `%${this.projectName}%`\n },\n {\n name: 'state',\n operator: 'eq',\n value: ProjectState.COMPLETED\n }\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"]}
1
+ {"version":3,"file":"sv-project-completed-list.js","sourceRoot":"","sources":["../../client/pages/sv-project-completed-list.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { PageView, navigate } 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 gql from 'graphql-tag'\nimport { Project, PROJECT_STATE, ProjectState } from './sv-project-list'\nimport '../components/sv-pagenation-control'\n\n@customElement('sv-project-completed-list')\nexport class SvProjectCompletedListPage 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 /* 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: 5px 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\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 overflow-y: auto;\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: cover;\n background: #e5e7eb;\n border-radius: 2px;\n }\n div[td-status] {\n font-weight: 700;\n font-size: 16px;\n color: #4cbb49;\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 justify-content: flex-end;\n }\n div[td-kpi] .kpi-value {\n font-weight: 700;\n font-size: 22px;\n color: #35618e;\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 </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 <span class=\"kpi-value\">${project.kpi ?? 0}</span>\n </div>\n </div>\n `\n })}\n </div>\n </div>\n <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 ></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"]}
@@ -0,0 +1,13 @@
1
+ import { PageLifecycle, PageView } from '@operato/shell';
2
+ declare const SvProjectDetailPage_base: typeof PageView & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types/src/types").ScopedElementsHost>;
3
+ export declare class SvProjectDetailPage extends SvProjectDetailPage_base {
4
+ static styles: import("lit").CSSResult[];
5
+ get context(): {
6
+ title: string;
7
+ };
8
+ private project;
9
+ render(): import("lit-html").TemplateResult<1>;
10
+ pageUpdated(changes: any, lifecycle: PageLifecycle): Promise<void>;
11
+ initProject(projectId?: string): Promise<void>;
12
+ }
13
+ export {};