@dssp/project 1.0.0-alpha.19 → 1.0.0-alpha.20

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 (44) hide show
  1. package/dist-client/pages/project/component/project-update-header.js +26 -3
  2. package/dist-client/pages/project/component/project-update-header.js.map +1 -1
  3. package/dist-client/pages/project/popup/checklist/task-checklist-view.d.ts +0 -1
  4. package/dist-client/pages/project/popup/checklist/task-checklist-view.js +4 -5
  5. package/dist-client/pages/project/popup/checklist/task-checklist-view.js.map +1 -1
  6. package/dist-client/pages/project/project-detail.js +47 -17
  7. package/dist-client/pages/project/project-detail.js.map +1 -1
  8. package/dist-client/pages/project/project-list.d.ts +1 -0
  9. package/dist-client/pages/project/project-list.js.map +1 -1
  10. package/dist-client/pages/project/project-task.d.ts +13 -2
  11. package/dist-client/pages/project/project-task.js +288 -24
  12. package/dist-client/pages/project/project-task.js.map +1 -1
  13. package/dist-client/pages/project/project-update.js +18 -1
  14. package/dist-client/pages/project/project-update.js.map +1 -1
  15. package/dist-client/tsconfig.tsbuildinfo +1 -1
  16. package/dist-server/service/index.d.ts +2 -2
  17. package/dist-server/service/index.js +5 -2
  18. package/dist-server/service/index.js.map +1 -1
  19. package/dist-server/service/project/project-query.d.ts +1 -0
  20. package/dist-server/service/project/project-query.js +18 -0
  21. package/dist-server/service/project/project-query.js.map +1 -1
  22. package/dist-server/service/task/task-query.d.ts +2 -0
  23. package/dist-server/service/task/task-query.js +11 -0
  24. package/dist-server/service/task/task-query.js.map +1 -1
  25. package/dist-server/service/task/task.d.ts +2 -0
  26. package/dist-server/service/task/task.js +6 -0
  27. package/dist-server/service/task/task.js.map +1 -1
  28. package/dist-server/service/task-checklist-binding/index.d.ts +5 -0
  29. package/dist-server/service/task-checklist-binding/index.js +9 -0
  30. package/dist-server/service/task-checklist-binding/index.js.map +1 -0
  31. package/dist-server/service/task-checklist-binding/task-checklist-binding-mutation.d.ts +5 -0
  32. package/dist-server/service/task-checklist-binding/task-checklist-binding-mutation.js +186 -0
  33. package/dist-server/service/task-checklist-binding/task-checklist-binding-mutation.js.map +1 -0
  34. package/dist-server/service/task-checklist-binding/task-checklist-binding-query.d.ts +8 -0
  35. package/dist-server/service/task-checklist-binding/task-checklist-binding-query.js +61 -0
  36. package/dist-server/service/task-checklist-binding/task-checklist-binding-query.js.map +1 -0
  37. package/dist-server/service/task-checklist-binding/task-checklist-binding-type.d.ts +15 -0
  38. package/dist-server/service/task-checklist-binding/task-checklist-binding-type.js +57 -0
  39. package/dist-server/service/task-checklist-binding/task-checklist-binding-type.js.map +1 -0
  40. package/dist-server/service/task-checklist-binding/task-checklist-binding.d.ts +22 -0
  41. package/dist-server/service/task-checklist-binding/task-checklist-binding.js +106 -0
  42. package/dist-server/service/task-checklist-binding/task-checklist-binding.js.map +1 -0
  43. package/dist-server/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +4 -3
@@ -10,12 +10,15 @@ import { customElement, query, state } from 'lit/decorators.js';
10
10
  import { ScopedElementsMixin } from '@open-wc/scoped-elements';
11
11
  import { client } from '@operato/graphql';
12
12
  import { i18next } from '@operato/i18n';
13
- import { openPopup } from '@operato/layout';
13
+ import { notify, openPopup } from '@operato/layout';
14
14
  import gql from 'graphql-tag';
15
15
  import { ScrollbarStyles } from '@operato/styles';
16
+ import { verifyBiometric } from '@things-factory/auth-base/dist-client';
17
+ import { BuildingInspectionStatus } from './popup/checklist/task-checklist-view';
16
18
  import '@operato/gantt/ox-gantt.js';
17
19
  import './popup/popup-task-upload';
18
20
  import './popup/checklist/task-checklist-create-popup';
21
+ import './popup/checklist/task-checklist-view';
19
22
  const TaskFragment = gql `
20
23
  fragment TaskFragment on Task {
21
24
  type
@@ -27,6 +30,10 @@ const TaskFragment = gql `
27
30
  dependsOn
28
31
  progress
29
32
  style
33
+ taskChecklistBinding {
34
+ id
35
+ status
36
+ }
30
37
  resources {
31
38
  type
32
39
  allocated
@@ -53,8 +60,12 @@ let ProjectTask = class ProjectTask extends ScopedElementsMixin(PageView) {
53
60
  this.project = Object.assign({}, this.defaultProject);
54
61
  this.selectedBuildingIdx = 0;
55
62
  this.constructionTypeList = [];
63
+ this.selectedChecklist = {};
64
+ this.selectedConstructionTypeId = '';
56
65
  this.fromDate = '2024-01-01';
57
66
  this.toDate = '2026-12-31';
67
+ this.selectedFromDate = '';
68
+ this.selectedToDate = '';
58
69
  this.timeScale = 'week-day';
59
70
  this.extendGridLines = false;
60
71
  this.columnConfigProvider = function () {
@@ -93,7 +104,10 @@ let ProjectTask = class ProjectTask extends ScopedElementsMixin(PageView) {
93
104
  var _a;
94
105
  return html `
95
106
  <div header>
96
- <h2>${this.project.name}</h2>
107
+ <h2>
108
+ <md-icon slot="icon" back @click=${() => history.back()}>arrow_back</md-icon>
109
+ ${this.project.name}
110
+ </h2>
97
111
  <div button-container>
98
112
  <md-elevated-button @click=${this._openUploadSchedulePopup}>
99
113
  <md-icon slot="icon">event_note</md-icon>공정표 관리
@@ -128,9 +142,20 @@ let ProjectTask = class ProjectTask extends ScopedElementsMixin(PageView) {
128
142
  </div>
129
143
  </div>
130
144
  <div construction-list-container>
131
- ${(_a = this.constructionTypeList) === null || _a === void 0 ? void 0 : _a.map((constructionType) => html ` <md-outlined-button id=${constructionType.id} @click=${() => this.onConstructionTypeClick(constructionType)}
132
- >${constructionType.title}</md-outlined-button
133
- >`)}
145
+ ${(_a = this.constructionTypeList) === null || _a === void 0 ? void 0 : _a.map((constructionType) => {
146
+ var _a, _b, _c;
147
+ return html ` <md-outlined-button
148
+ id=${constructionType.id}
149
+ ?selected=${this.selectedConstructionTypeId === constructionType.id}
150
+ ?pass=${((_a = constructionType.taskChecklistBinding) === null || _a === void 0 ? void 0 : _a.status) === BuildingInspectionStatus.PASS}
151
+ ?fail=${((_b = constructionType.taskChecklistBinding) === null || _b === void 0 ? void 0 : _b.status) === BuildingInspectionStatus.FAIL}
152
+ @click=${() => this.onClickTaskChecklist(constructionType)}
153
+ >
154
+ <div icon-container>
155
+ ${this._getIconHtmlByStatus((_c = constructionType.taskChecklistBinding) === null || _c === void 0 ? void 0 : _c.status)} ${constructionType.title}
156
+ </div>
157
+ </md-outlined-button>`;
158
+ })}
134
159
  </div>
135
160
  </div>
136
161
  </div>
@@ -170,6 +195,10 @@ let ProjectTask = class ProjectTask extends ScopedElementsMixin(PageView) {
170
195
  id
171
196
  planXScale
172
197
  planYScale
198
+ taskConstructorEmails
199
+ overallConstructorEmails
200
+ taskSupervisoryEmails
201
+ overallSupervisoryEmails
173
202
  buildings {
174
203
  id
175
204
  name
@@ -203,15 +232,19 @@ let ProjectTask = class ProjectTask extends ScopedElementsMixin(PageView) {
203
232
  this.fromDate = this.project.startDate || '2024-01-01'; /* TODO default: start date of this year - 3 */
204
233
  this.toDate = this.project.endDate || '2026-12-31'; /* TODO defaule: end date of this year + 3 */
205
234
  }
206
- console.log('init project : ', this.project);
207
235
  }
208
236
  onChangePeriodRange() {
209
237
  this.fromDate = this.inputStartDate.value;
210
238
  this.toDate = this.inputEndDate.value;
211
239
  }
212
- onRangeSelected(e) {
213
- const selectedFromDate = new Date(e.detail.start + 'T00:00:00.000Z');
214
- const selectedToDate = new Date(e.detail.end + 'T23:59:59.000Z');
240
+ onRangeSelected(event) {
241
+ var _a, _b;
242
+ if (event) {
243
+ this.selectedFromDate = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.start;
244
+ this.selectedToDate = (_b = event.detail) === null || _b === void 0 ? void 0 : _b.end;
245
+ }
246
+ const selectedFromDate = new Date(this.selectedFromDate + 'T00:00:00.000Z');
247
+ const selectedToDate = new Date(this.selectedToDate + 'T23:59:59.000Z');
215
248
  this.constructionTypeList = this.tasks.filter(constuction => {
216
249
  const constuctionStartDate = new Date(constuction.startDate);
217
250
  const constuctionEndDate = new Date(constuction.endDate);
@@ -224,23 +257,174 @@ let ProjectTask = class ProjectTask extends ScopedElementsMixin(PageView) {
224
257
  .projectId=${this.projectId}
225
258
  .scheduleTable=${(_a = this.project) === null || _a === void 0 ? void 0 : _a.scheduleTable}
226
259
  @uploaded=${() => this.initProject(this.projectId)}
227
- ></popup-task-upload>`, {
228
- backdrop: true,
229
- size: 'medium',
230
- title: `공정표 업로드`
231
- });
260
+ ></popup-task-upload>`, { backdrop: true, size: 'medium', title: '공정표 업로드' });
232
261
  }
233
- onConstructionTypeClick(constructionType) {
262
+ async onClickTaskChecklist(constructionType) {
263
+ // 선택된 공종 설정
264
+ this.selectedConstructionTypeId = constructionType.id;
265
+ // 체크리스트가 있으면 수정 모드, 없으면 생성 모드
266
+ if (constructionType.taskChecklistBinding) {
267
+ const taskChecklistBinding = await this._getTaskChecklistBindingById(constructionType.taskChecklistBinding.id);
268
+ this.selectedChecklist = Object.assign(Object.assign({}, taskChecklistBinding.checklist), { status: taskChecklistBinding.status });
269
+ this._openUpdateTaskChecklistPopup(constructionType);
270
+ }
271
+ else {
272
+ this._openCreateChecklistPopup(constructionType);
273
+ }
274
+ }
275
+ _openCreateChecklistPopup(constructionType) {
234
276
  openPopup(html `<task-checklist-create-popup
235
277
  .projectId=${this.projectId}
236
278
  .taskCode=${constructionType.id}
237
- @requestRefresh="${() => this.initProject(this.projectId)}"
279
+ @requestRefresh="${async () => {
280
+ await this.initProject(this.projectId);
281
+ this.onRangeSelected(null);
282
+ }}"
238
283
  ></task-checklist-create-popup>`, {
239
284
  backdrop: true,
240
285
  size: 'large',
241
286
  title: `체크리스트 생성`
242
287
  });
243
- console.log('constructionType', constructionType);
288
+ }
289
+ _openUpdateTaskChecklistPopup(constructionType) {
290
+ var _a;
291
+ openPopup(html `
292
+ <div style="overflow-y: auto; height: 100%;">
293
+ <task-checklist-view
294
+ .mode=${"EDITOR" /* ChecklistMode.EDITOR */}
295
+ .status=${this.selectedChecklist.status}
296
+ .checklist=${this.selectedChecklist || {}}
297
+ .buildingComplex=${((_a = this.project) === null || _a === void 0 ? void 0 : _a.buildingComplex) || {}}
298
+ ></task-checklist-view>
299
+
300
+ <div style="text-align: right; margin-right: 20px; margin-bottom: 15px">
301
+ <md-elevated-button
302
+ ?disabled=${this.selectedChecklist.status == BuildingInspectionStatus.PASS}
303
+ @click=${this._onClickModifyChecklist.bind(this)}
304
+ >
305
+ <md-icon slot="icon">assignment</md-icon>등록
306
+ </md-elevated-button>
307
+ </div>
308
+ </div>
309
+ `, { backdrop: true, size: 'large', title: constructionType.title });
310
+ }
311
+ _onClickModifyChecklist() {
312
+ this.validateChecklist(this.selectedChecklist);
313
+ }
314
+ async validateChecklist(checklist) {
315
+ var _a, _b;
316
+ try {
317
+ const result = await verifyBiometric();
318
+ if (result.verified) {
319
+ console.log('Verification successful. Proceeding with sensitive action.');
320
+ }
321
+ else {
322
+ notify({ message: 'Verification failed:' + result.message });
323
+ return;
324
+ }
325
+ }
326
+ catch (error) {
327
+ notify({ message: 'Error during biometric verification:' + error });
328
+ return;
329
+ }
330
+ const response = await client.mutate({
331
+ mutation: gql `
332
+ mutation UpdateTaskChecklist($taskChecklist: UpdateTaskChecklistSubmitType!) {
333
+ updateTaskChecklist(taskChecklist: $taskChecklist)
334
+ }
335
+ `,
336
+ variables: {
337
+ taskChecklist: {
338
+ checklistId: checklist.id,
339
+ checklist: {
340
+ id: checklist.id,
341
+ overallConstructorSignature: checklist.overallConstructorSignature,
342
+ taskConstructorSignature: checklist.taskConstructorSignature,
343
+ overallSupervisorySignature: checklist.overallSupervisorySignature,
344
+ taskSupervisorySignature: checklist.taskSupervisorySignature
345
+ },
346
+ checklistItem: checklist.checklistItems.map(item => ({
347
+ id: item.id,
348
+ constructionConfirmStatus: item.constructionConfirmStatus,
349
+ supervisoryConfirmStatus: item.supervisoryConfirmStatus
350
+ }))
351
+ }
352
+ }
353
+ });
354
+ if (!response.errors) {
355
+ notify({ message: '검측 요청서를 등록하였습니다.' });
356
+ await this.initProject(this.projectId);
357
+ this.onRangeSelected(null);
358
+ history.back();
359
+ }
360
+ else {
361
+ notify({ message: ((_b = (_a = response.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) || '검측 요청서 등록에 실패하였습니다.', level: 'error' });
362
+ }
363
+ }
364
+ _getIconHtmlByStatus(status) {
365
+ if (!status)
366
+ return '';
367
+ if (status == BuildingInspectionStatus.WAIT || status == BuildingInspectionStatus.OVERALL_WAIT) {
368
+ return html `<md-icon request>frame_inspect</md-icon>`;
369
+ }
370
+ if (status == BuildingInspectionStatus.REQUEST || status == BuildingInspectionStatus.OVERALL_REQUEST) {
371
+ return html `<md-icon request>exclamation</md-icon>`;
372
+ }
373
+ if (status == BuildingInspectionStatus.PASS) {
374
+ return html `<md-icon pass>check</md-icon>`;
375
+ }
376
+ return html `<md-icon fail>close</md-icon>`;
377
+ }
378
+ async _getTaskChecklistBindingById(id) {
379
+ var _a;
380
+ const response = await client.query({
381
+ query: gql `
382
+ query TaskChecklistBinding($id: String!) {
383
+ taskChecklistBinding(id: $id) {
384
+ id
385
+ status
386
+
387
+ checklist {
388
+ id
389
+ name
390
+ constructionType
391
+ constructionDetailType
392
+ location
393
+ inspectionParts
394
+ documentNo
395
+ constructionInspectionDate
396
+ supervisorInspectionDate
397
+ overallConstructorSignature
398
+ taskConstructorSignature
399
+ overallSupervisorySignature
400
+ taskSupervisorySignature
401
+
402
+ checklistItems {
403
+ id
404
+ name
405
+ sequence
406
+ mainType
407
+ detailType
408
+ inspctionCriteria
409
+ constructionConfirmStatus
410
+ supervisoryConfirmStatus
411
+ checklistItemCommentCount
412
+ checklistItemAttachmentCount
413
+ }
414
+ }
415
+
416
+ manager {
417
+ userId
418
+ name
419
+ }
420
+ }
421
+ }
422
+ `,
423
+ variables: { id }
424
+ });
425
+ if (response.errors)
426
+ return;
427
+ return ((_a = response.data) === null || _a === void 0 ? void 0 : _a.taskChecklistBinding) || {};
244
428
  }
245
429
  };
246
430
  ProjectTask.styles = [
@@ -269,9 +453,28 @@ ProjectTask.styles = [
269
453
  margin: 0px var(--spacing-large, 12px);
270
454
 
271
455
  h2 {
456
+ display: flex;
457
+ gap: 7px;
272
458
  flex: 0.5;
273
459
  color: #3f71a0;
274
- font-size:18px;
460
+ font-size: 18px;
461
+
462
+ md-icon[back] {
463
+ background: linear-gradient(135deg, #3f71a0 0%, #5a8cc7 100%);
464
+ color: white;
465
+ padding: 8px;
466
+ border-radius: 50%;
467
+ cursor: pointer;
468
+ box-shadow: 0 2px 8px rgba(63, 113, 160, 0.3);
469
+ width: 14px;
470
+ height: 14px;
471
+ --md-icon-size: 20px;
472
+ }
473
+
474
+ md-icon[back]:hover {
475
+ background: linear-gradient(135deg, #2e5c89 0%, #4a7bb0 100%);
476
+ box-shadow: 0 4px 12px rgba(63, 113, 160, 0.4);
477
+ }
275
478
  }
276
479
 
277
480
  div[button-container] {
@@ -281,7 +484,8 @@ ProjectTask.styles = [
281
484
  flex: 0.5;
282
485
 
283
486
  md-elevated-button {
284
- margin: 0px margin-left: var(--spacing-small, 4px);
487
+ margin: 0px;
488
+ margin-left: var(--spacing-small, 4px);
285
489
 
286
490
  --md-elevated-button-container-height: 32px;
287
491
  --md-elevated-button-label-text-size: 16px;
@@ -305,7 +509,7 @@ ProjectTask.styles = [
305
509
  display: flex;
306
510
  flex-direction: column;
307
511
  margin: var(--spacing-large, 12px);
308
- margin-top:0;
512
+ margin-top: 0;
309
513
  gap: var(--spacing-medium, 8px);
310
514
  overflow: hidden;
311
515
 
@@ -347,9 +551,9 @@ ProjectTask.styles = [
347
551
  font-weight: bold;
348
552
  }
349
553
 
350
- input[type="date"] {
351
- border:1px solid rgba(51,51,51,.20);
352
- padding:var(--spacing-small, 4px) var(--spacing-medium, 8px);
554
+ input[type='date'] {
555
+ border: 1px solid rgba(51, 51, 51, 0.2);
556
+ padding: var(--spacing-small, 4px) var(--spacing-medium, 8px);
353
557
  border-radius: 5px;
354
558
  }
355
559
  }
@@ -369,10 +573,54 @@ ProjectTask.styles = [
369
573
  --md-outlined-button-trailing-space: var(--spacing-medium, 8px);
370
574
  --md-outlined-button-leading-space: var(--spacing-medium, 8px);
371
575
  --md-outlined-button-label-text-color: #586878;
372
- --md-sys-color-outline: rgba(51,51,51,.20);
576
+ --md-sys-color-outline: rgba(51, 51, 51, 0.2);
373
577
  box-shadow: 1px 1px 1px #0000001a;
374
578
  padding: var(--spacing-medium, 8px) var(--spacing-large, 12px);
375
579
  font-weight: 700;
580
+
581
+ &[selected] {
582
+ --md-outlined-button-label-text-color: #0595e5 !important;
583
+ --md-sys-color-outline: #0595e5 !important;
584
+ background-color: #0595e51a !important;
585
+ }
586
+
587
+ &[pass] {
588
+ --md-outlined-button-label-text-color: #4bbb4a;
589
+ --md-sys-color-outline: #4bbb4a;
590
+ background-color: #4bbb4a1a;
591
+ }
592
+ &[fail] {
593
+ --md-outlined-button-label-text-color: #ff4444;
594
+ --md-sys-color-outline: #ff4444;
595
+ background-color: #ff44441a;
596
+ }
597
+ }
598
+
599
+ div[icon-container] {
600
+ display: flex;
601
+ align-items: center;
602
+ gap: 4px;
603
+
604
+ md-icon[request],
605
+ md-icon[pass],
606
+ md-icon[fail] {
607
+ width: 16px;
608
+ height: 16px;
609
+ margin-right: 4px;
610
+ border-radius: 3px;
611
+ font-size: 14px;
612
+ font-weight: 700;
613
+ color: #fff;
614
+ }
615
+ md-icon[request] {
616
+ background-color: #4e5055;
617
+ }
618
+ md-icon[pass] {
619
+ background-color: #4bbb4a;
620
+ }
621
+ md-icon[fail] {
622
+ background-color: #ff4444;
623
+ }
376
624
  }
377
625
  }
378
626
  }
@@ -399,6 +647,14 @@ __decorate([
399
647
  state(),
400
648
  __metadata("design:type", Object)
401
649
  ], ProjectTask.prototype, "constructionTypeList", void 0);
650
+ __decorate([
651
+ state(),
652
+ __metadata("design:type", Object)
653
+ ], ProjectTask.prototype, "selectedChecklist", void 0);
654
+ __decorate([
655
+ state(),
656
+ __metadata("design:type", String)
657
+ ], ProjectTask.prototype, "selectedConstructionTypeId", void 0);
402
658
  __decorate([
403
659
  state(),
404
660
  __metadata("design:type", Object)
@@ -407,6 +663,14 @@ __decorate([
407
663
  state(),
408
664
  __metadata("design:type", Object)
409
665
  ], ProjectTask.prototype, "toDate", void 0);
666
+ __decorate([
667
+ state(),
668
+ __metadata("design:type", Object)
669
+ ], ProjectTask.prototype, "selectedFromDate", void 0);
670
+ __decorate([
671
+ state(),
672
+ __metadata("design:type", Object)
673
+ ], ProjectTask.prototype, "selectedToDate", void 0);
410
674
  __decorate([
411
675
  query('input[name="startDate"]'),
412
676
  __metadata("design:type", HTMLInputElement)
@@ -1 +1 @@
1
- {"version":3,"file":"project-task.js","sourceRoot":"","sources":["../../../client/pages/project/project-task.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/elevated-button.js'\nimport '@material/web/textfield/outlined-text-field.js'\nimport '@material/web/button/filled-button.js'\nimport '@material/web/button/outlined-button.js'\n\nimport { PageView } from '@operato/shell'\nimport { PageLifecycle } from '@operato/shell/dist/src/app/pages/page-view'\nimport { css, html } from 'lit'\nimport { customElement, query, state } from 'lit/decorators.js'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { openPopup } from '@operato/layout'\nimport gql from 'graphql-tag'\nimport { Project } from './project-list'\nimport { ScrollbarStyles } from '@operato/styles'\nimport '@operato/gantt/ox-gantt.js'\nimport './popup/popup-task-upload'\nimport './popup/checklist/task-checklist-create-popup'\n\nconst TaskFragment = gql`\n fragment TaskFragment on Task {\n type\n title: name\n id: code\n duration\n startDate\n endDate\n dependsOn\n progress\n style\n resources {\n type\n allocated\n }\n }\n`\n\n@customElement('project-task')\nexport class ProjectTask extends ScopedElementsMixin(PageView) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n color: #4e5055;\n\n width: 100%;\n background-color: var(--md-sys-color-background, #f6f6f6);\n overflow-y: auto;\n\n --grid-record-emphasized-background-color: red;\n --grid-record-emphasized-color: yellow;\n }\n\n *[bold] {\n font-weight: bold;\n }\n\n div[header] {\n display: flex;\n margin: 0px var(--spacing-large, 12px);\n\n h2 {\n flex: 0.5;\n color: #3f71a0;\n font-size:18px;\n }\n\n div[button-container] {\n display: flex;\n align-items: center;\n justify-content: end;\n flex: 0.5;\n\n md-elevated-button {\n margin: 0px margin-left: var(--spacing-small, 4px);\n\n --md-elevated-button-container-height: 32px;\n --md-elevated-button-label-text-size: 16px;\n --md-elevated-button-container-color: #0595e5;\n\n --md-elevated-button-label-text-color: var(--md-sys-color-on-primary);\n --md-elevated-button-hover-label-text-color: var(--md-sys-color-on-primary);\n --md-elevated-button-pressed-label-text-color: var(--md-sys-color-on-primary);\n --md-elevated-button-focus-label-text-color: var(--md-sys-color-on-primary);\n --md-elevated-button-icon-color: var(--md-sys-color-on-primary);\n --md-elevated-button-hover-icon-color: var(--md-sys-color-on-primary);\n --md-elevated-button-pressed-icon-color: var(--md-sys-color-on-primary);\n --md-elevated-button-focus-icon-color: var(--md-sys-color-on-primary);\n }\n }\n }\n\n div[body] {\n flex: 1;\n\n display: flex;\n flex-direction: column;\n margin: var(--spacing-large, 12px);\n margin-top:0;\n gap: var(--spacing-medium, 8px);\n overflow: hidden;\n\n h3 {\n color: #2e79be;\n font-size: 16px;\n margin: 0px;\n }\n\n & > div {\n display: flex;\n border-radius: 5px;\n }\n\n ox-gantt {\n flex: 1;\n box-sizing: border-box;\n overflow: hidden;\n\n background-color: var(--md-sys-color-primary-container);\n color: var(--md-sys-color-on-primary-container);\n }\n\n div[select-container] {\n gap: var(--spacing-medium, 8px);\n\n div[date] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n background-color: #2ea4df1a;\n border: 1px solid #2ea4df33;\n border-radius: 5px;\n gap: var(--spacing-medium, 8px);\n padding: 12px 36px 12px 15px;\n\n span[name] {\n font-size: 16px;\n font-weight: bold;\n }\n\n input[type=\"date\"] {\n border:1px solid rgba(51,51,51,.20);\n padding:var(--spacing-small, 4px) var(--spacing-medium, 8px);\n border-radius: 5px;\n }\n }\n\n div[construction-list-container] {\n flex: 1;\n display: flex;\n border-radius: 5px;\n border: 1px solid #cccccc80;\n background-color: #fff;\n padding: var(--spacing-medium, 8px) var(--spacing-large, 12px);\n gap: var(--spacing-medium, 8px);\n overflow-x: auto;\n\n md-outlined-button {\n --md-outlined-button-container-height: 30px;\n --md-outlined-button-trailing-space: var(--spacing-medium, 8px);\n --md-outlined-button-leading-space: var(--spacing-medium, 8px);\n --md-outlined-button-label-text-color: #586878;\n --md-sys-color-outline: rgba(51,51,51,.20);\n box-shadow: 1px 1px 1px #0000001a;\n padding: var(--spacing-medium, 8px) var(--spacing-large, 12px);\n font-weight: 700;\n }\n }\n }\n }\n `\n ]\n\n get context() {\n return {\n title: '공정표'\n }\n }\n\n private defaultProject = {\n name: '',\n buildingComplex: {\n address: '',\n area: 0,\n constructionCompany: '',\n clientCompany: '',\n supervisoryCompany: '',\n designCompany: '',\n constructionType: '',\n buildings: []\n }\n }\n @state() projectId: string = ''\n @state() project: Project = { ...this.defaultProject }\n @state() selectedBuildingIdx: number = 0\n @state() tasks\n @state() constructionTypeList = []\n\n @state() private fromDate = '2024-01-01'\n @state() private toDate = '2026-12-31'\n\n @query('input[name=\"startDate\"]') inputStartDate!: HTMLInputElement\n @query('input[name=\"endDate\"]') inputEndDate!: HTMLInputElement\n\n private timeScale = 'week-day'\n private extendGridLines = false\n\n private columnConfigProvider = function () {\n return [\n { name: 'title', label: i18next.t('label.gantt-task-title') || 'title', visible: true, width: 150, order: 1 },\n {\n name: 'startDate',\n label: i18next.t('label.gantt-task-start-date') || 'start date',\n visible: true,\n width: 100,\n order: 2\n },\n {\n name: 'resources',\n label: i18next.t('label.gantt-task-resources') || 'resources',\n visible: true,\n width: 100,\n order: 3\n },\n {\n name: 'duration',\n label: i18next.t('label.gantt-task-duration') || 'duration',\n visible: true,\n width: 30,\n order: 4\n }\n ]\n }\n\n render() {\n return html`\n <div header>\n <h2>${this.project.name}</h2>\n <div button-container>\n <md-elevated-button @click=${this._openUploadSchedulePopup}>\n <md-icon slot=\"icon\">event_note</md-icon>공정표 관리\n </md-elevated-button>\n </div>\n </div>\n\n <div body>\n <ox-gantt\n from-date=${new Date(this.fromDate).toISOString().split('T')[0]}\n to-date=${new Date(this.toDate).toISOString().split('T')[0]}\n .timeScale=${this.timeScale}\n .tasks=${this.tasks}\n @date-range-selected=${this.onRangeSelected}\n @task-clicked=${(e: CustomEvent) => {\n console.log('task-clicked', e.detail)\n }}\n ?extend-grid-lines=${this.extendGridLines}\n .columnConfigProvider=${this.columnConfigProvider}\n .colorProvider=${task => {\n return task.style || 'gray'\n }}\n >\n </ox-gantt>\n <div select-container>\n <div date>\n <span name>기간선택</span>\n <div @change=${() => this.onChangePeriodRange()}>\n <input type=\"date\" name=\"startDate\" project .value=${this.project.startDate || ''} max=\"9999-12-31\" />\n ~\n <input type=\"date\" name=\"endDate\" project .value=${this.project.endDate || ''} max=\"9999-12-31\" />\n </div>\n </div>\n <div construction-list-container>\n ${this.constructionTypeList?.map(\n (constructionType: any) =>\n html` <md-outlined-button id=${constructionType.id} @click=${() => this.onConstructionTypeClick(constructionType)}\n >${constructionType.title}</md-outlined-button\n >`\n )}\n </div>\n </div>\n </div>\n `\n }\n\n async pageInitialized(lifecycle: PageLifecycle) {}\n\n async pageUpdated(changes: any, lifecycle: PageLifecycle) {\n if (this.active) {\n this.projectId = lifecycle.resourceId || ''\n await this.initProject(this.projectId)\n }\n }\n\n async initProject(projectId: string = '') {\n const response = await client.query({\n query: gql`\n query Project($id: String!, $sortings: [Sorting!]) {\n project(id: $id) {\n id\n name\n startDate\n endDate\n rootTasks {\n ...TaskFragment\n children(sortings: $sortings) {\n ...TaskFragment\n children(sortings: $sortings) {\n ...TaskFragment\n }\n }\n }\n scheduleTable {\n id\n name\n }\n buildingComplex {\n id\n planXScale\n planYScale\n buildings {\n id\n name\n drawing {\n id\n name\n }\n buildingLevels {\n id\n floor\n mainDrawing {\n id\n name\n }\n }\n }\n }\n }\n }\n\n ${TaskFragment}\n `,\n variables: {\n id: projectId,\n sortings: [{ name: 'startDate' }]\n }\n })\n\n this.project = response.data?.project\n this.tasks = response.data?.project.rootTasks\n\n if (this.project) {\n this.fromDate = this.project.startDate || '2024-01-01' /* TODO default: start date of this year - 3 */\n this.toDate = this.project.endDate || '2026-12-31' /* TODO defaule: end date of this year + 3 */\n }\n\n console.log('init project : ', this.project)\n }\n\n onChangePeriodRange() {\n this.fromDate = this.inputStartDate.value\n this.toDate = this.inputEndDate.value\n }\n\n onRangeSelected(e: CustomEvent) {\n const selectedFromDate = new Date(e.detail.start + 'T00:00:00.000Z')\n const selectedToDate = new Date(e.detail.end + 'T23:59:59.000Z')\n\n this.constructionTypeList = this.tasks.filter(constuction => {\n const constuctionStartDate = new Date(constuction.startDate)\n const constuctionEndDate = new Date(constuction.endDate)\n\n return constuctionStartDate <= selectedToDate && constuctionEndDate >= selectedFromDate\n })\n }\n\n private _openUploadSchedulePopup() {\n openPopup(\n html`<popup-task-upload\n .projectId=${this.projectId}\n .scheduleTable=${this.project?.scheduleTable}\n @uploaded=${() => this.initProject(this.projectId)}\n ></popup-task-upload>`,\n {\n backdrop: true,\n size: 'medium',\n title: `공정표 업로드`\n }\n )\n }\n\n private onConstructionTypeClick(constructionType: any) {\n openPopup(\n html`<task-checklist-create-popup\n .projectId=${this.projectId}\n .taskCode=${constructionType.id}\n @requestRefresh=\"${() => this.initProject(this.projectId)}\"\n ></task-checklist-create-popup>`,\n {\n backdrop: true,\n size: 'large',\n title: `체크리스트 생성`\n }\n )\n\n console.log('constructionType', constructionType)\n }\n}\n"]}
1
+ {"version":3,"file":"project-task.js","sourceRoot":"","sources":["../../../client/pages/project/project-task.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,yCAAyC,CAAA;AAChD,OAAO,gDAAgD,CAAA;AACvD,OAAO,uCAAuC,CAAA;AAC9C,OAAO,yCAAyC,CAAA;AAEhD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,GAAG,MAAM,aAAa,CAAA;AAE7B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAA;AACvE,OAAO,EAAE,wBAAwB,EAAiB,MAAM,uCAAuC,CAAA;AAE/F,OAAO,4BAA4B,CAAA;AACnC,OAAO,2BAA2B,CAAA;AAClC,OAAO,+CAA+C,CAAA;AACtD,OAAO,uCAAuC,CAAA;AAE9C,MAAM,YAAY,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;CAoBvB,CAAA;AAGM,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,mBAAmB,CAAC,QAAQ,CAAC;IAAvD;;QAgNG,mBAAc,GAAG;YACvB,IAAI,EAAE,EAAE;YACR,eAAe,EAAE;gBACf,OAAO,EAAE,EAAE;gBACX,IAAI,EAAE,CAAC;gBACP,mBAAmB,EAAE,EAAE;gBACvB,aAAa,EAAE,EAAE;gBACjB,kBAAkB,EAAE,EAAE;gBACtB,aAAa,EAAE,EAAE;gBACjB,gBAAgB,EAAE,EAAE;gBACpB,SAAS,EAAE,EAAE;aACd;SACF,CAAA;QACQ,cAAS,GAAW,EAAE,CAAA;QACtB,YAAO,qBAAiB,IAAI,CAAC,cAAc,EAAE;QAC7C,wBAAmB,GAAW,CAAC,CAAA;QAE/B,yBAAoB,GAAG,EAAE,CAAA;QACzB,sBAAiB,GAAQ,EAAE,CAAA;QAC3B,+BAA0B,GAAW,EAAE,CAAA;QAE/B,aAAQ,GAAG,YAAY,CAAA;QACvB,WAAM,GAAG,YAAY,CAAA;QACrB,qBAAgB,GAAG,EAAE,CAAA;QACrB,mBAAc,GAAG,EAAE,CAAA;QAK5B,cAAS,GAAG,UAAU,CAAA;QACtB,oBAAe,GAAG,KAAK,CAAA;QAEvB,yBAAoB,GAAG;YAC7B,OAAO;gBACL,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,IAAI,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE;gBAC7G;oBACE,IAAI,EAAE,WAAW;oBACjB,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,6BAA6B,CAAC,IAAI,YAAY;oBAC/D,OAAO,EAAE,IAAI;oBACb,KAAK,EAAE,GAAG;oBACV,KAAK,EAAE,CAAC;iBACT;gBACD;oBACE,IAAI,EAAE,WAAW;oBACjB,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC,IAAI,WAAW;oBAC7D,OAAO,EAAE,IAAI;oBACb,KAAK,EAAE,GAAG;oBACV,KAAK,EAAE,CAAC;iBACT;gBACD;oBACE,IAAI,EAAE,UAAU;oBAChB,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC,IAAI,UAAU;oBAC3D,OAAO,EAAE,IAAI;oBACb,KAAK,EAAE,EAAE;oBACT,KAAK,EAAE,CAAC;iBACT;aACF,CAAA;QACH,CAAC,CAAA;IAgWH,CAAC;IA/ZC,IAAI,OAAO;QACT,OAAO;YACL,KAAK,EAAE,KAAK;SACb,CAAA;IACH,CAAC;IA6DD,MAAM;;QACJ,OAAO,IAAI,CAAA;;;6CAG8B,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE;YACrD,IAAI,CAAC,OAAO,CAAC,IAAI;;;uCAGU,IAAI,CAAC,wBAAwB;;;;;;;;sBAQ9C,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBACrD,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;uBAC9C,IAAI,CAAC,SAAS;mBAClB,IAAI,CAAC,KAAK;iCACI,IAAI,CAAC,eAAe;0BAC3B,CAAC,CAAc,EAAE,EAAE;YACjC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;QACvC,CAAC;+BACoB,IAAI,CAAC,eAAe;kCACjB,IAAI,CAAC,oBAAoB;2BAChC,IAAI,CAAC,EAAE;YACtB,OAAO,IAAI,CAAC,KAAK,IAAI,MAAM,CAAA;QAC7B,CAAC;;;;;;2BAMgB,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE;mEACQ,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE;;iEAE9B,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE;;;;cAI7E,MAAA,IAAI,CAAC,oBAAoB,0CAAE,GAAG,CAC9B,CAAC,gBAAqB,EAAE,EAAE;;YACxB,OAAA,IAAI,CAAA;uBACG,gBAAgB,CAAC,EAAE;8BACZ,IAAI,CAAC,0BAA0B,KAAK,gBAAgB,CAAC,EAAE;0BAC3D,CAAA,MAAA,gBAAgB,CAAC,oBAAoB,0CAAE,MAAM,MAAK,wBAAwB,CAAC,IAAI;0BAC/E,CAAA,MAAA,gBAAgB,CAAC,oBAAoB,0CAAE,MAAM,MAAK,wBAAwB,CAAC,IAAI;2BAC9E,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,gBAAgB,CAAC;;;sBAGtD,IAAI,CAAC,oBAAoB,CAAC,MAAA,gBAAgB,CAAC,oBAAoB,0CAAE,MAAM,CAAC,IAAI,gBAAgB,CAAC,KAAK;;sCAElF,CAAA;SAAA,CACzB;;;;KAIR,CAAA;IACH,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,SAAwB,IAAG,CAAC;IAElD,KAAK,CAAC,WAAW,CAAC,OAAY,EAAE,SAAwB;QACtD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,UAAU,IAAI,EAAE,CAAA;YAC3C,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACxC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,YAAoB,EAAE;;QACtC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAgDN,YAAY;OACf;YACD,SAAS,EAAE;gBACT,EAAE,EAAE,SAAS;gBACb,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;aAClC;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,OAAO,GAAG,MAAA,QAAQ,CAAC,IAAI,0CAAE,OAAO,CAAA;QACrC,IAAI,CAAC,KAAK,GAAG,MAAA,QAAQ,CAAC,IAAI,0CAAE,OAAO,CAAC,SAAS,CAAA;QAE7C,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,YAAY,CAAA,CAAC,+CAA+C;YACtG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,YAAY,CAAA,CAAC,6CAA6C;QAClG,CAAC;IACH,CAAC;IAED,mBAAmB;QACjB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAA;QACzC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAA;IACvC,CAAC;IAED,eAAe,CAAC,KAAyB;;QACvC,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,gBAAgB,GAAG,MAAA,KAAK,CAAC,MAAM,0CAAE,KAAK,CAAA;YAC3C,IAAI,CAAC,cAAc,GAAG,MAAA,KAAK,CAAC,MAAM,0CAAE,GAAG,CAAA;QACzC,CAAC;QAED,MAAM,gBAAgB,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,CAAA;QAC3E,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,gBAAgB,CAAC,CAAA;QAEvE,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE;YAC1D,MAAM,oBAAoB,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;YAC5D,MAAM,kBAAkB,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;YAExD,OAAO,oBAAoB,IAAI,cAAc,IAAI,kBAAkB,IAAI,gBAAgB,CAAA;QACzF,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,wBAAwB;;QAC9B,SAAS,CACP,IAAI,CAAA;qBACW,IAAI,CAAC,SAAS;yBACV,MAAA,IAAI,CAAC,OAAO,0CAAE,aAAa;oBAChC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC;4BAC9B,EACtB,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,CACrD,CAAA;IACH,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAAC,gBAAqB;QACtD,YAAY;QACZ,IAAI,CAAC,0BAA0B,GAAG,gBAAgB,CAAC,EAAE,CAAA;QAErD,8BAA8B;QAC9B,IAAI,gBAAgB,CAAC,oBAAoB,EAAE,CAAC;YAC1C,MAAM,oBAAoB,GAAG,MAAM,IAAI,CAAC,4BAA4B,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAA;YAC9G,IAAI,CAAC,iBAAiB,mCAAQ,oBAAoB,CAAC,SAAS,KAAE,MAAM,EAAE,oBAAoB,CAAC,MAAM,GAAE,CAAA;YAEnG,IAAI,CAAC,6BAA6B,CAAC,gBAAgB,CAAC,CAAA;QACtD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,yBAAyB,CAAC,gBAAgB,CAAC,CAAA;QAClD,CAAC;IACH,CAAC;IAEO,yBAAyB,CAAC,gBAAqB;QACrD,SAAS,CACP,IAAI,CAAA;qBACW,IAAI,CAAC,SAAS;oBACf,gBAAgB,CAAC,EAAE;2BACZ,KAAK,IAAI,EAAE;YAC5B,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YACtC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;QAC5B,CAAC;sCAC6B,EAChC;YACE,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,UAAU;SAClB,CACF,CAAA;IACH,CAAC;IAED,6BAA6B,CAAC,gBAAqB;;QACjD,SAAS,CACP,IAAI,CAAA;;;oBAGU,mCAAoB;sBAClB,IAAI,CAAC,iBAAiB,CAAC,MAAM;yBAC1B,IAAI,CAAC,iBAAiB,IAAI,EAAE;+BACtB,CAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,eAAe,KAAI,EAAE;;;;;0BAKxC,IAAI,CAAC,iBAAiB,CAAC,MAAM,IAAI,wBAAwB,CAAC,IAAI;uBACjE,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;OAMvD,EACD,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,gBAAgB,CAAC,KAAK,EAAE,CACjE,CAAA;IACH,CAAC;IAEO,uBAAuB;QAC7B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;IAChD,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,SAAc;;QAC5C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAA;YACtC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACpB,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAA;YAC3E,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,EAAE,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAA;gBAC5D,OAAM;YACR,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,EAAE,OAAO,EAAE,sCAAsC,GAAG,KAAK,EAAE,CAAC,CAAA;YACnE,OAAM;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;YACnC,QAAQ,EAAE,GAAG,CAAA;;;;OAIZ;YACD,SAAS,EAAE;gBACT,aAAa,EAAE;oBACb,WAAW,EAAE,SAAS,CAAC,EAAE;oBACzB,SAAS,EAAE;wBACT,EAAE,EAAE,SAAS,CAAC,EAAE;wBAChB,2BAA2B,EAAE,SAAS,CAAC,2BAA2B;wBAClE,wBAAwB,EAAE,SAAS,CAAC,wBAAwB;wBAC5D,2BAA2B,EAAE,SAAS,CAAC,2BAA2B;wBAClE,wBAAwB,EAAE,SAAS,CAAC,wBAAwB;qBAC7D;oBACD,aAAa,EAAE,SAAS,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;wBACnD,EAAE,EAAE,IAAI,CAAC,EAAE;wBACX,yBAAyB,EAAE,IAAI,CAAC,yBAAyB;wBACzD,wBAAwB,EAAE,IAAI,CAAC,wBAAwB;qBACxD,CAAC,CAAC;iBACJ;aACF;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,MAAM,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAA;YACvC,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YACtC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;YAC1B,OAAO,CAAC,IAAI,EAAE,CAAA;QAChB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,EAAE,OAAO,EAAE,CAAA,MAAA,MAAA,QAAQ,CAAC,MAAM,0CAAG,CAAC,CAAC,0CAAE,OAAO,KAAI,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;QAC7F,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,MAAc;QACzC,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAA;QAEtB,IAAI,MAAM,IAAI,wBAAwB,CAAC,IAAI,IAAI,MAAM,IAAI,wBAAwB,CAAC,YAAY,EAAE,CAAC;YAC/F,OAAO,IAAI,CAAA,0CAA0C,CAAA;QACvD,CAAC;QAED,IAAI,MAAM,IAAI,wBAAwB,CAAC,OAAO,IAAI,MAAM,IAAI,wBAAwB,CAAC,eAAe,EAAE,CAAC;YACrG,OAAO,IAAI,CAAA,wCAAwC,CAAA;QACrD,CAAC;QAED,IAAI,MAAM,IAAI,wBAAwB,CAAC,IAAI,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAA,+BAA+B,CAAA;QAC5C,CAAC;QAED,OAAO,IAAI,CAAA,+BAA+B,CAAA;IAC5C,CAAC;IAEO,KAAK,CAAC,4BAA4B,CAAC,EAAU;;QACnD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyCT;YACD,SAAS,EAAE,EAAE,EAAE,EAAE;SAClB,CAAC,CAAA;QAEF,IAAI,QAAQ,CAAC,MAAM;YAAE,OAAM;QAE3B,OAAO,CAAA,MAAA,QAAQ,CAAC,IAAI,0CAAE,oBAAoB,KAAI,EAAE,CAAA;IAClD,CAAC;;AAvmBM,kBAAM,GAAG;IACd,eAAe;IACf,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoMF;CACF,AAvMY,CAuMZ;AAqBQ;IAAR,KAAK,EAAE;;8CAAuB;AACtB;IAAR,KAAK,EAAE;;4CAA8C;AAC7C;IAAR,KAAK,EAAE;;wDAAgC;AAC/B;IAAR,KAAK,EAAE;;0CAAM;AACL;IAAR,KAAK,EAAE;;yDAA0B;AACzB;IAAR,KAAK,EAAE;;sDAA4B;AAC3B;IAAR,KAAK,EAAE;;+DAAwC;AAE/B;IAAhB,KAAK,EAAE;;6CAAgC;AACvB;IAAhB,KAAK,EAAE;;2CAA8B;AACrB;IAAhB,KAAK,EAAE;;qDAA8B;AACrB;IAAhB,KAAK,EAAE;;mDAA4B;AAEF;IAAjC,KAAK,CAAC,yBAAyB,CAAC;8BAAkB,gBAAgB;mDAAA;AACnC;IAA/B,KAAK,CAAC,uBAAuB,CAAC;8BAAgB,gBAAgB;iDAAA;AA3OpD,WAAW;IADvB,aAAa,CAAC,cAAc,CAAC;GACjB,WAAW,CAymBvB","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/elevated-button.js'\nimport '@material/web/textfield/outlined-text-field.js'\nimport '@material/web/button/filled-button.js'\nimport '@material/web/button/outlined-button.js'\n\nimport { PageView } from '@operato/shell'\nimport { PageLifecycle } from '@operato/shell/dist/src/app/pages/page-view'\nimport { css, html } from 'lit'\nimport { customElement, query, state } from 'lit/decorators.js'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { notify, openPopup } from '@operato/layout'\nimport gql from 'graphql-tag'\nimport { Project } from './project-list'\nimport { ScrollbarStyles } from '@operato/styles'\nimport { verifyBiometric } from '@things-factory/auth-base/dist-client'\nimport { BuildingInspectionStatus, ChecklistMode } from './popup/checklist/task-checklist-view'\n\nimport '@operato/gantt/ox-gantt.js'\nimport './popup/popup-task-upload'\nimport './popup/checklist/task-checklist-create-popup'\nimport './popup/checklist/task-checklist-view'\n\nconst TaskFragment = gql`\n fragment TaskFragment on Task {\n type\n title: name\n id: code\n duration\n startDate\n endDate\n dependsOn\n progress\n style\n taskChecklistBinding {\n id\n status\n }\n resources {\n type\n allocated\n }\n }\n`\n\n@customElement('project-task')\nexport class ProjectTask extends ScopedElementsMixin(PageView) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n color: #4e5055;\n\n width: 100%;\n background-color: var(--md-sys-color-background, #f6f6f6);\n overflow-y: auto;\n\n --grid-record-emphasized-background-color: red;\n --grid-record-emphasized-color: yellow;\n }\n\n *[bold] {\n font-weight: bold;\n }\n\n div[header] {\n display: flex;\n margin: 0px var(--spacing-large, 12px);\n\n h2 {\n display: flex;\n gap: 7px;\n flex: 0.5;\n color: #3f71a0;\n font-size: 18px;\n\n md-icon[back] {\n background: linear-gradient(135deg, #3f71a0 0%, #5a8cc7 100%);\n color: white;\n padding: 8px;\n border-radius: 50%;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(63, 113, 160, 0.3);\n width: 14px;\n height: 14px;\n --md-icon-size: 20px;\n }\n\n md-icon[back]:hover {\n background: linear-gradient(135deg, #2e5c89 0%, #4a7bb0 100%);\n box-shadow: 0 4px 12px rgba(63, 113, 160, 0.4);\n }\n }\n\n div[button-container] {\n display: flex;\n align-items: center;\n justify-content: end;\n flex: 0.5;\n\n md-elevated-button {\n margin: 0px;\n margin-left: var(--spacing-small, 4px);\n\n --md-elevated-button-container-height: 32px;\n --md-elevated-button-label-text-size: 16px;\n --md-elevated-button-container-color: #0595e5;\n\n --md-elevated-button-label-text-color: var(--md-sys-color-on-primary);\n --md-elevated-button-hover-label-text-color: var(--md-sys-color-on-primary);\n --md-elevated-button-pressed-label-text-color: var(--md-sys-color-on-primary);\n --md-elevated-button-focus-label-text-color: var(--md-sys-color-on-primary);\n --md-elevated-button-icon-color: var(--md-sys-color-on-primary);\n --md-elevated-button-hover-icon-color: var(--md-sys-color-on-primary);\n --md-elevated-button-pressed-icon-color: var(--md-sys-color-on-primary);\n --md-elevated-button-focus-icon-color: var(--md-sys-color-on-primary);\n }\n }\n }\n\n div[body] {\n flex: 1;\n\n display: flex;\n flex-direction: column;\n margin: var(--spacing-large, 12px);\n margin-top: 0;\n gap: var(--spacing-medium, 8px);\n overflow: hidden;\n\n h3 {\n color: #2e79be;\n font-size: 16px;\n margin: 0px;\n }\n\n & > div {\n display: flex;\n border-radius: 5px;\n }\n\n ox-gantt {\n flex: 1;\n box-sizing: border-box;\n overflow: hidden;\n\n background-color: var(--md-sys-color-primary-container);\n color: var(--md-sys-color-on-primary-container);\n }\n\n div[select-container] {\n gap: var(--spacing-medium, 8px);\n\n div[date] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n background-color: #2ea4df1a;\n border: 1px solid #2ea4df33;\n border-radius: 5px;\n gap: var(--spacing-medium, 8px);\n padding: 12px 36px 12px 15px;\n\n span[name] {\n font-size: 16px;\n font-weight: bold;\n }\n\n input[type='date'] {\n border: 1px solid rgba(51, 51, 51, 0.2);\n padding: var(--spacing-small, 4px) var(--spacing-medium, 8px);\n border-radius: 5px;\n }\n }\n\n div[construction-list-container] {\n flex: 1;\n display: flex;\n border-radius: 5px;\n border: 1px solid #cccccc80;\n background-color: #fff;\n padding: var(--spacing-medium, 8px) var(--spacing-large, 12px);\n gap: var(--spacing-medium, 8px);\n overflow-x: auto;\n\n md-outlined-button {\n --md-outlined-button-container-height: 30px;\n --md-outlined-button-trailing-space: var(--spacing-medium, 8px);\n --md-outlined-button-leading-space: var(--spacing-medium, 8px);\n --md-outlined-button-label-text-color: #586878;\n --md-sys-color-outline: rgba(51, 51, 51, 0.2);\n box-shadow: 1px 1px 1px #0000001a;\n padding: var(--spacing-medium, 8px) var(--spacing-large, 12px);\n font-weight: 700;\n\n &[selected] {\n --md-outlined-button-label-text-color: #0595e5 !important;\n --md-sys-color-outline: #0595e5 !important;\n background-color: #0595e51a !important;\n }\n\n &[pass] {\n --md-outlined-button-label-text-color: #4bbb4a;\n --md-sys-color-outline: #4bbb4a;\n background-color: #4bbb4a1a;\n }\n &[fail] {\n --md-outlined-button-label-text-color: #ff4444;\n --md-sys-color-outline: #ff4444;\n background-color: #ff44441a;\n }\n }\n\n div[icon-container] {\n display: flex;\n align-items: center;\n gap: 4px;\n\n md-icon[request],\n md-icon[pass],\n md-icon[fail] {\n width: 16px;\n height: 16px;\n margin-right: 4px;\n border-radius: 3px;\n font-size: 14px;\n font-weight: 700;\n color: #fff;\n }\n md-icon[request] {\n background-color: #4e5055;\n }\n md-icon[pass] {\n background-color: #4bbb4a;\n }\n md-icon[fail] {\n background-color: #ff4444;\n }\n }\n }\n }\n }\n `\n ]\n\n get context() {\n return {\n title: '공정표'\n }\n }\n\n private defaultProject = {\n name: '',\n buildingComplex: {\n address: '',\n area: 0,\n constructionCompany: '',\n clientCompany: '',\n supervisoryCompany: '',\n designCompany: '',\n constructionType: '',\n buildings: []\n }\n }\n @state() projectId: string = ''\n @state() project: Project = { ...this.defaultProject }\n @state() selectedBuildingIdx: number = 0\n @state() tasks\n @state() constructionTypeList = []\n @state() selectedChecklist: any = {}\n @state() selectedConstructionTypeId: string = ''\n\n @state() private fromDate = '2024-01-01'\n @state() private toDate = '2026-12-31'\n @state() private selectedFromDate = ''\n @state() private selectedToDate = ''\n\n @query('input[name=\"startDate\"]') inputStartDate!: HTMLInputElement\n @query('input[name=\"endDate\"]') inputEndDate!: HTMLInputElement\n\n private timeScale = 'week-day'\n private extendGridLines = false\n\n private columnConfigProvider = function () {\n return [\n { name: 'title', label: i18next.t('label.gantt-task-title') || 'title', visible: true, width: 150, order: 1 },\n {\n name: 'startDate',\n label: i18next.t('label.gantt-task-start-date') || 'start date',\n visible: true,\n width: 100,\n order: 2\n },\n {\n name: 'resources',\n label: i18next.t('label.gantt-task-resources') || 'resources',\n visible: true,\n width: 100,\n order: 3\n },\n {\n name: 'duration',\n label: i18next.t('label.gantt-task-duration') || 'duration',\n visible: true,\n width: 30,\n order: 4\n }\n ]\n }\n\n render() {\n return html`\n <div header>\n <h2>\n <md-icon slot=\"icon\" back @click=${() => history.back()}>arrow_back</md-icon>\n ${this.project.name}\n </h2>\n <div button-container>\n <md-elevated-button @click=${this._openUploadSchedulePopup}>\n <md-icon slot=\"icon\">event_note</md-icon>공정표 관리\n </md-elevated-button>\n </div>\n </div>\n\n <div body>\n <ox-gantt\n from-date=${new Date(this.fromDate).toISOString().split('T')[0]}\n to-date=${new Date(this.toDate).toISOString().split('T')[0]}\n .timeScale=${this.timeScale}\n .tasks=${this.tasks}\n @date-range-selected=${this.onRangeSelected}\n @task-clicked=${(e: CustomEvent) => {\n console.log('task-clicked', e.detail)\n }}\n ?extend-grid-lines=${this.extendGridLines}\n .columnConfigProvider=${this.columnConfigProvider}\n .colorProvider=${task => {\n return task.style || 'gray'\n }}\n >\n </ox-gantt>\n <div select-container>\n <div date>\n <span name>기간선택</span>\n <div @change=${() => this.onChangePeriodRange()}>\n <input type=\"date\" name=\"startDate\" project .value=${this.project.startDate || ''} max=\"9999-12-31\" />\n ~\n <input type=\"date\" name=\"endDate\" project .value=${this.project.endDate || ''} max=\"9999-12-31\" />\n </div>\n </div>\n <div construction-list-container>\n ${this.constructionTypeList?.map(\n (constructionType: any) =>\n html` <md-outlined-button\n id=${constructionType.id}\n ?selected=${this.selectedConstructionTypeId === constructionType.id}\n ?pass=${constructionType.taskChecklistBinding?.status === BuildingInspectionStatus.PASS}\n ?fail=${constructionType.taskChecklistBinding?.status === BuildingInspectionStatus.FAIL}\n @click=${() => this.onClickTaskChecklist(constructionType)}\n >\n <div icon-container>\n ${this._getIconHtmlByStatus(constructionType.taskChecklistBinding?.status)} ${constructionType.title}\n </div>\n </md-outlined-button>`\n )}\n </div>\n </div>\n </div>\n `\n }\n\n async pageInitialized(lifecycle: PageLifecycle) {}\n\n async pageUpdated(changes: any, lifecycle: PageLifecycle) {\n if (this.active) {\n this.projectId = lifecycle.resourceId || ''\n await this.initProject(this.projectId)\n }\n }\n\n async initProject(projectId: string = '') {\n const response = await client.query({\n query: gql`\n query Project($id: String!, $sortings: [Sorting!]) {\n project(id: $id) {\n id\n name\n startDate\n endDate\n rootTasks {\n ...TaskFragment\n children(sortings: $sortings) {\n ...TaskFragment\n children(sortings: $sortings) {\n ...TaskFragment\n }\n }\n }\n scheduleTable {\n id\n name\n }\n buildingComplex {\n id\n planXScale\n planYScale\n taskConstructorEmails\n overallConstructorEmails\n taskSupervisoryEmails\n overallSupervisoryEmails\n buildings {\n id\n name\n drawing {\n id\n name\n }\n buildingLevels {\n id\n floor\n mainDrawing {\n id\n name\n }\n }\n }\n }\n }\n }\n\n ${TaskFragment}\n `,\n variables: {\n id: projectId,\n sortings: [{ name: 'startDate' }]\n }\n })\n\n this.project = response.data?.project\n this.tasks = response.data?.project.rootTasks\n\n if (this.project) {\n this.fromDate = this.project.startDate || '2024-01-01' /* TODO default: start date of this year - 3 */\n this.toDate = this.project.endDate || '2026-12-31' /* TODO defaule: end date of this year + 3 */\n }\n }\n\n onChangePeriodRange() {\n this.fromDate = this.inputStartDate.value\n this.toDate = this.inputEndDate.value\n }\n\n onRangeSelected(event: CustomEvent | null) {\n if (event) {\n this.selectedFromDate = event.detail?.start\n this.selectedToDate = event.detail?.end\n }\n\n const selectedFromDate = new Date(this.selectedFromDate + 'T00:00:00.000Z')\n const selectedToDate = new Date(this.selectedToDate + 'T23:59:59.000Z')\n\n this.constructionTypeList = this.tasks.filter(constuction => {\n const constuctionStartDate = new Date(constuction.startDate)\n const constuctionEndDate = new Date(constuction.endDate)\n\n return constuctionStartDate <= selectedToDate && constuctionEndDate >= selectedFromDate\n })\n }\n\n private _openUploadSchedulePopup() {\n openPopup(\n html`<popup-task-upload\n .projectId=${this.projectId}\n .scheduleTable=${this.project?.scheduleTable}\n @uploaded=${() => this.initProject(this.projectId)}\n ></popup-task-upload>`,\n { backdrop: true, size: 'medium', title: '공정표 업로드' }\n )\n }\n\n private async onClickTaskChecklist(constructionType: any) {\n // 선택된 공종 설정\n this.selectedConstructionTypeId = constructionType.id\n\n // 체크리스트가 있으면 수정 모드, 없으면 생성 모드\n if (constructionType.taskChecklistBinding) {\n const taskChecklistBinding = await this._getTaskChecklistBindingById(constructionType.taskChecklistBinding.id)\n this.selectedChecklist = { ...taskChecklistBinding.checklist, status: taskChecklistBinding.status }\n\n this._openUpdateTaskChecklistPopup(constructionType)\n } else {\n this._openCreateChecklistPopup(constructionType)\n }\n }\n\n private _openCreateChecklistPopup(constructionType: any) {\n openPopup(\n html`<task-checklist-create-popup\n .projectId=${this.projectId}\n .taskCode=${constructionType.id}\n @requestRefresh=\"${async () => {\n await this.initProject(this.projectId)\n this.onRangeSelected(null)\n }}\"\n ></task-checklist-create-popup>`,\n {\n backdrop: true,\n size: 'large',\n title: `체크리스트 생성`\n }\n )\n }\n\n _openUpdateTaskChecklistPopup(constructionType: any) {\n openPopup(\n html`\n <div style=\"overflow-y: auto; height: 100%;\">\n <task-checklist-view\n .mode=${ChecklistMode.EDITOR}\n .status=${this.selectedChecklist.status}\n .checklist=${this.selectedChecklist || {}}\n .buildingComplex=${this.project?.buildingComplex || {}}\n ></task-checklist-view>\n\n <div style=\"text-align: right; margin-right: 20px; margin-bottom: 15px\">\n <md-elevated-button\n ?disabled=${this.selectedChecklist.status == BuildingInspectionStatus.PASS}\n @click=${this._onClickModifyChecklist.bind(this)}\n >\n <md-icon slot=\"icon\">assignment</md-icon>등록\n </md-elevated-button>\n </div>\n </div>\n `,\n { backdrop: true, size: 'large', title: constructionType.title }\n )\n }\n\n private _onClickModifyChecklist() {\n this.validateChecklist(this.selectedChecklist)\n }\n\n private async validateChecklist(checklist: any) {\n try {\n const result = await verifyBiometric()\n if (result.verified) {\n console.log('Verification successful. Proceeding with sensitive action.')\n } else {\n notify({ message: 'Verification failed:' + result.message })\n return\n }\n } catch (error) {\n notify({ message: 'Error during biometric verification:' + error })\n return\n }\n\n const response = await client.mutate({\n mutation: gql`\n mutation UpdateTaskChecklist($taskChecklist: UpdateTaskChecklistSubmitType!) {\n updateTaskChecklist(taskChecklist: $taskChecklist)\n }\n `,\n variables: {\n taskChecklist: {\n checklistId: checklist.id,\n checklist: {\n id: checklist.id,\n overallConstructorSignature: checklist.overallConstructorSignature,\n taskConstructorSignature: checklist.taskConstructorSignature,\n overallSupervisorySignature: checklist.overallSupervisorySignature,\n taskSupervisorySignature: checklist.taskSupervisorySignature\n },\n checklistItem: checklist.checklistItems.map(item => ({\n id: item.id,\n constructionConfirmStatus: item.constructionConfirmStatus,\n supervisoryConfirmStatus: item.supervisoryConfirmStatus\n }))\n }\n }\n })\n\n if (!response.errors) {\n notify({ message: '검측 요청서를 등록하였습니다.' })\n await this.initProject(this.projectId)\n this.onRangeSelected(null)\n history.back()\n } else {\n notify({ message: response.errors?.[0]?.message || '검측 요청서 등록에 실패하였습니다.', level: 'error' })\n }\n }\n\n private _getIconHtmlByStatus(status: string) {\n if (!status) return ''\n\n if (status == BuildingInspectionStatus.WAIT || status == BuildingInspectionStatus.OVERALL_WAIT) {\n return html`<md-icon request>frame_inspect</md-icon>`\n }\n\n if (status == BuildingInspectionStatus.REQUEST || status == BuildingInspectionStatus.OVERALL_REQUEST) {\n return html`<md-icon request>exclamation</md-icon>`\n }\n\n if (status == BuildingInspectionStatus.PASS) {\n return html`<md-icon pass>check</md-icon>`\n }\n\n return html`<md-icon fail>close</md-icon>`\n }\n\n private async _getTaskChecklistBindingById(id: string) {\n const response = await client.query({\n query: gql`\n query TaskChecklistBinding($id: String!) {\n taskChecklistBinding(id: $id) {\n id\n status\n\n checklist {\n id\n name\n constructionType\n constructionDetailType\n location\n inspectionParts\n documentNo\n constructionInspectionDate\n supervisorInspectionDate\n overallConstructorSignature\n taskConstructorSignature\n overallSupervisorySignature\n taskSupervisorySignature\n\n checklistItems {\n id\n name\n sequence\n mainType\n detailType\n inspctionCriteria\n constructionConfirmStatus\n supervisoryConfirmStatus\n checklistItemCommentCount\n checklistItemAttachmentCount\n }\n }\n\n manager {\n userId\n name\n }\n }\n }\n `,\n variables: { id }\n })\n\n if (response.errors) return\n\n return response.data?.taskChecklistBinding || {}\n }\n}\n"]}
@@ -41,7 +41,7 @@ let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
41
41
  };
42
42
  }
43
43
  render() {
44
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
44
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33;
45
45
  return html `
46
46
  <project-update-header .projectId=${this.project.id || ''} title="프로젝트 정보 관리" @custom-click=${this._saveProject}>
47
47
  </project-update-header>
@@ -507,6 +507,22 @@ let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
507
507
  </span>
508
508
  </div>
509
509
  </div>
510
+
511
+ <div>
512
+ <h3>Virtual Tour Link</h3>
513
+ <div>
514
+ <span></span>
515
+ <span>
516
+ <md-outlined-text-field
517
+ type="text"
518
+ name="virtualTourLink"
519
+ building-complex
520
+ .value=${((_33 = (_32 = this.project) === null || _32 === void 0 ? void 0 : _32.buildingComplex) === null || _33 === void 0 ? void 0 : _33.virtualTourLink) || ''}
521
+ @input=${this._onInputChange}
522
+ ></md-outlined-text-field>
523
+ </span>
524
+ </div>
525
+ </div>
510
526
  </div>
511
527
  </div>
512
528
  `;
@@ -562,6 +578,7 @@ let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
562
578
  taskConstructorEmails
563
579
  overallSupervisoryEmails
564
580
  taskSupervisoryEmails
581
+ virtualTourLink
565
582
  buildings {
566
583
  id
567
584
  name