@dssp/project 1.0.0-alpha.7 → 1.0.0-alpha.74

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 (149) hide show
  1. package/dist-client/index.d.ts +1 -0
  2. package/dist-client/index.js +1 -1
  3. package/dist-client/index.js.map +1 -1
  4. package/dist-client/pages/lib/chatbot-widget.d.ts +53 -0
  5. package/dist-client/pages/lib/chatbot-widget.js +631 -0
  6. package/dist-client/pages/lib/chatbot-widget.js.map +1 -0
  7. package/dist-client/pages/lib/select2-component.d.ts +1 -1
  8. package/dist-client/pages/lib/select2-component.js +35 -35
  9. package/dist-client/pages/lib/select2-component.js.map +1 -1
  10. package/dist-client/pages/project/component/pagenation.d.ts +18 -0
  11. package/dist-client/pages/project/component/pagenation.js +142 -0
  12. package/dist-client/pages/project/component/pagenation.js.map +1 -0
  13. package/dist-client/pages/project/component/project-update-header.js +26 -3
  14. package/dist-client/pages/project/component/project-update-header.js.map +1 -1
  15. package/dist-client/pages/project/popup/checklist/task-checklist-attachment-list-popup.d.ts +1 -0
  16. package/dist-client/pages/project/popup/checklist/task-checklist-attachment-list-popup.js +308 -0
  17. package/dist-client/pages/project/popup/checklist/task-checklist-attachment-list-popup.js.map +1 -0
  18. package/dist-client/pages/project/popup/checklist/task-checklist-comment-list-popup.d.ts +1 -0
  19. package/dist-client/pages/project/popup/checklist/task-checklist-comment-list-popup.js +356 -0
  20. package/dist-client/pages/project/popup/checklist/task-checklist-comment-list-popup.js.map +1 -0
  21. package/dist-client/pages/project/popup/checklist/task-checklist-create-popup.d.ts +1 -0
  22. package/dist-client/pages/project/popup/checklist/task-checklist-create-popup.js +681 -0
  23. package/dist-client/pages/project/popup/checklist/task-checklist-create-popup.js.map +1 -0
  24. package/dist-client/pages/project/popup/checklist/task-checklist-view.d.ts +32 -0
  25. package/dist-client/pages/project/popup/checklist/task-checklist-view.js +620 -0
  26. package/dist-client/pages/project/popup/checklist/task-checklist-view.js.map +1 -0
  27. package/dist-client/pages/project/popup/popup-plan-export.js +8 -2
  28. package/dist-client/pages/project/popup/popup-plan-export.js.map +1 -1
  29. package/dist-client/pages/project/popup/{popup-schedule-upload.d.ts → popup-task-upload.d.ts} +1 -1
  30. package/dist-client/pages/project/popup/{popup-schedule-upload.js → popup-task-upload.js} +9 -9
  31. package/dist-client/pages/project/popup/popup-task-upload.js.map +1 -0
  32. package/dist-client/pages/project/project-completed-list.d.ts +5 -0
  33. package/dist-client/pages/project/project-completed-list.js +32 -3
  34. package/dist-client/pages/project/project-completed-list.js.map +1 -1
  35. package/dist-client/pages/project/project-detail.d.ts +6 -0
  36. package/dist-client/pages/project/project-detail.js +366 -159
  37. package/dist-client/pages/project/project-detail.js.map +1 -1
  38. package/dist-client/pages/project/project-list.d.ts +57 -0
  39. package/dist-client/pages/project/project-list.js +80 -9
  40. package/dist-client/pages/project/project-list.js.map +1 -1
  41. package/dist-client/pages/project/project-plan-management.js +3 -1
  42. package/dist-client/pages/project/project-plan-management.js.map +1 -1
  43. package/dist-client/pages/project/project-setting-list.d.ts +7 -0
  44. package/dist-client/pages/project/project-setting-list.js +61 -7
  45. package/dist-client/pages/project/project-setting-list.js.map +1 -1
  46. package/dist-client/pages/project/{project-schedule-list.d.ts → project-task-list.d.ts} +2 -2
  47. package/dist-client/pages/project/{project-schedule-list.js → project-task-list.js} +11 -11
  48. package/dist-client/pages/project/project-task-list.js.map +1 -0
  49. package/dist-client/pages/project/{project-schedule.d.ts → project-task.d.ts} +17 -4
  50. package/dist-client/pages/project/project-task.js +686 -0
  51. package/dist-client/pages/project/project-task.js.map +1 -0
  52. package/dist-client/pages/project/project-update.d.ts +8 -0
  53. package/dist-client/pages/project/project-update.js +333 -33
  54. package/dist-client/pages/project/project-update.js.map +1 -1
  55. package/dist-client/pages/resource/construction-type-management.js +14 -0
  56. package/dist-client/pages/resource/construction-type-management.js.map +1 -1
  57. package/dist-client/pages/resource/resource-list-page.d.ts +1 -2
  58. package/dist-client/pages/resource/resource-list-page.js +1 -2
  59. package/dist-client/pages/resource/resource-list-page.js.map +1 -1
  60. package/dist-client/pages/task/task-list-page.d.ts +1 -2
  61. package/dist-client/pages/task/task-list-page.js +1 -2
  62. package/dist-client/pages/task/task-list-page.js.map +1 -1
  63. package/dist-client/pages/task-resource/task-resource-list-page.d.ts +1 -2
  64. package/dist-client/pages/task-resource/task-resource-list-page.js +1 -2
  65. package/dist-client/pages/task-resource/task-resource-list-page.js.map +1 -1
  66. package/dist-client/route.d.ts +1 -1
  67. package/dist-client/route.js +4 -4
  68. package/dist-client/route.js.map +1 -1
  69. package/dist-client/tsconfig.tsbuildinfo +1 -1
  70. package/dist-server/controllers/parse-excel.js.map +1 -1
  71. package/dist-server/migrations/1723861466414-seed-codes.js +1 -1
  72. package/dist-server/migrations/1723861466414-seed-codes.js.map +1 -1
  73. package/dist-server/service/construction-type/construction-type-query.d.ts +2 -2
  74. package/dist-server/service/construction-type/construction-type-query.js +5 -10
  75. package/dist-server/service/construction-type/construction-type-query.js.map +1 -1
  76. package/dist-server/service/construction-type/construction-type-type.d.ts +1 -0
  77. package/dist-server/service/construction-type/construction-type-type.js +4 -0
  78. package/dist-server/service/construction-type/construction-type-type.js.map +1 -1
  79. package/dist-server/service/construction-type/construction-type.d.ts +1 -0
  80. package/dist-server/service/construction-type/construction-type.js +5 -0
  81. package/dist-server/service/construction-type/construction-type.js.map +1 -1
  82. package/dist-server/service/index.d.ts +2 -2
  83. package/dist-server/service/index.js +5 -2
  84. package/dist-server/service/index.js.map +1 -1
  85. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-query.d.ts +2 -2
  86. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-query.js +5 -10
  87. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-query.js.map +1 -1
  88. package/dist-server/service/manager/manager-query.d.ts +1 -1
  89. package/dist-server/service/manager/manager-query.js +2 -6
  90. package/dist-server/service/manager/manager-query.js.map +1 -1
  91. package/dist-server/service/project/issue-project-code.d.ts +7 -0
  92. package/dist-server/service/project/issue-project-code.js +27 -0
  93. package/dist-server/service/project/issue-project-code.js.map +1 -0
  94. package/dist-server/service/project/project-mutation.d.ts +2 -0
  95. package/dist-server/service/project/project-mutation.js +96 -9
  96. package/dist-server/service/project/project-mutation.js.map +1 -1
  97. package/dist-server/service/project/project-query.d.ts +13 -2
  98. package/dist-server/service/project/project-query.js +138 -13
  99. package/dist-server/service/project/project-query.js.map +1 -1
  100. package/dist-server/service/project/project-type.d.ts +8 -1
  101. package/dist-server/service/project/project-type.js +27 -1
  102. package/dist-server/service/project/project-type.js.map +1 -1
  103. package/dist-server/service/project/project.d.ts +22 -0
  104. package/dist-server/service/project/project.js +80 -2
  105. package/dist-server/service/project/project.js.map +1 -1
  106. package/dist-server/service/resource/resource-mutation.js +5 -6
  107. package/dist-server/service/resource/resource-mutation.js.map +1 -1
  108. package/dist-server/service/resource/resource-query.d.ts +2 -2
  109. package/dist-server/service/resource/resource-query.js +5 -10
  110. package/dist-server/service/resource/resource-query.js.map +1 -1
  111. package/dist-server/service/task/task-query.d.ts +2 -0
  112. package/dist-server/service/task/task-query.js +11 -0
  113. package/dist-server/service/task/task-query.js.map +1 -1
  114. package/dist-server/service/task/task.d.ts +2 -0
  115. package/dist-server/service/task/task.js +6 -0
  116. package/dist-server/service/task/task.js.map +1 -1
  117. package/dist-server/service/task-checklist-binding/index.d.ts +5 -0
  118. package/dist-server/service/task-checklist-binding/index.js +9 -0
  119. package/dist-server/service/task-checklist-binding/index.js.map +1 -0
  120. package/dist-server/service/task-checklist-binding/task-checklist-binding-mutation.d.ts +5 -0
  121. package/dist-server/service/task-checklist-binding/task-checklist-binding-mutation.js +186 -0
  122. package/dist-server/service/task-checklist-binding/task-checklist-binding-mutation.js.map +1 -0
  123. package/dist-server/service/task-checklist-binding/task-checklist-binding-query.d.ts +8 -0
  124. package/dist-server/service/task-checklist-binding/task-checklist-binding-query.js +61 -0
  125. package/dist-server/service/task-checklist-binding/task-checklist-binding-query.js.map +1 -0
  126. package/dist-server/service/task-checklist-binding/task-checklist-binding-type.d.ts +15 -0
  127. package/dist-server/service/task-checklist-binding/task-checklist-binding-type.js +57 -0
  128. package/dist-server/service/task-checklist-binding/task-checklist-binding-type.js.map +1 -0
  129. package/dist-server/service/task-checklist-binding/task-checklist-binding.d.ts +22 -0
  130. package/dist-server/service/task-checklist-binding/task-checklist-binding.js +106 -0
  131. package/dist-server/service/task-checklist-binding/task-checklist-binding.js.map +1 -0
  132. package/dist-server/service/task-resource/task-resource-query.d.ts +2 -2
  133. package/dist-server/service/task-resource/task-resource-query.js +4 -9
  134. package/dist-server/service/task-resource/task-resource-query.js.map +1 -1
  135. package/dist-server/service/worker-type/worker-type-query.d.ts +2 -2
  136. package/dist-server/service/worker-type/worker-type-query.js +5 -10
  137. package/dist-server/service/worker-type/worker-type-query.js.map +1 -1
  138. package/dist-server/tsconfig.tsbuildinfo +1 -1
  139. package/package.json +15 -13
  140. package/things-factory.config.js +3 -3
  141. package/translations/en.json +10 -9
  142. package/translations/ja.json +15 -1
  143. package/translations/ko.json +3 -0
  144. package/translations/ms.json +15 -1
  145. package/translations/zh.json +15 -1
  146. package/dist-client/pages/project/popup/popup-schedule-upload.js.map +0 -1
  147. package/dist-client/pages/project/project-schedule-list.js.map +0 -1
  148. package/dist-client/pages/project/project-schedule.js +0 -407
  149. package/dist-client/pages/project/project-schedule.js.map +0 -1
@@ -10,7 +10,7 @@ import { ScopedElementsMixin } from '@open-wc/scoped-elements';
10
10
  import { client } from '@operato/graphql';
11
11
  import { ScrollbarStyles } from '@operato/styles';
12
12
  import gql from 'graphql-tag';
13
- import { BUILDING_INSPECTION_STATUS, ProjectType } from './project-list';
13
+ import { BUILDING_INSPECTION_STATUS, BUILDING_INSPECTION_RE_STATUS, ProjectType } from './project-list';
14
14
  import _getWeather from '../lib/waether';
15
15
  import '@operato/chart/ox-progress-circle.js';
16
16
  let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
@@ -36,8 +36,11 @@ let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
36
36
  wait: 0,
37
37
  request: 0,
38
38
  pass: 0,
39
- fail: 0
39
+ fail: 0,
40
+ reWait: 0
40
41
  };
42
+ this.statusFilter = '';
43
+ this.configProjectType = '';
41
44
  this.weather = {
42
45
  rain: 0,
43
46
  temperature: 0,
@@ -52,38 +55,71 @@ let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
52
55
  };
53
56
  }
54
57
  render() {
55
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
58
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
56
59
  let totalInspectionCount = this.inspectionSummary.pass + this.inspectionSummary.fail + this.inspectionSummary.request + this.inspectionSummary.wait;
57
60
  return html `
58
61
  <div header>
59
- <h2>${this.project.name}</h2>
62
+ <h2>
63
+ <md-icon slot="icon" back @click=${() => history.back()}>arrow_back</md-icon>
64
+ ${this.project.name}
65
+ </h2>
60
66
  <div button-container>
61
- <md-elevated-button href=${`project-update/${this.project.id}`}>
62
- <md-icon slot="icon">assignment</md-icon>프로젝트 정보 수정
63
- </md-elevated-button>
64
- <md-elevated-button href=${`project-plan-management/${this.project.id}`}>
65
- <md-icon slot="icon">description</md-icon>도면 관리
66
- </md-elevated-button>
67
- <md-elevated-button href=${`project-schedule/${this.project.id}`}>
68
- <md-icon slot="icon">event_note</md-icon>공정표 관리
69
- </md-elevated-button>
67
+ ${this.configProjectType === ProjectType.DCSP
68
+ ? html `
69
+ <md-elevated-button href="employee-list"> <md-icon slot="icon">badge</md-icon>인력 관리 </md-elevated-button>
70
+ <md-elevated-button href=${`project-plan-management/${this.project.id}`}>
71
+ <md-icon slot="icon">description</md-icon>도면 관리
72
+ </md-elevated-button>
73
+ <md-elevated-button href=${`project-task/${this.project.id}`}>
74
+ <md-icon slot="icon">event_note</md-icon>공정표 관리
75
+ </md-elevated-button>
76
+ <md-elevated-button href=${`project-checklist-management/${this.project.id}`}>
77
+ <md-icon slot="icon">checklist</md-icon>체크리스트 관리
78
+ </md-elevated-button>
79
+ <md-elevated-button href=${`building-inspection-management/${this.project.id}`}>
80
+ <md-icon slot="icon">open_in_new</md-icon>업무 바로가기
81
+ </md-elevated-button>
82
+ `
83
+ : html `
84
+ <md-elevated-button
85
+ target="_blank"
86
+ href=${((_a = this.project.buildingComplex) === null || _a === void 0 ? void 0 : _a.virtualTourLink) || ''}
87
+ ?disabled=${!((_b = this.project.buildingComplex) === null || _b === void 0 ? void 0 : _b.virtualTourLink)}
88
+ >
89
+ <md-icon slot="icon">smart_toy</md-icon>Virtual Tour
90
+ </md-elevated-button>
91
+ <md-elevated-button href=${`project-update/${this.project.id}`}>
92
+ <md-icon slot="icon">assignment</md-icon>프로젝트 정보 수정
93
+ </md-elevated-button>
94
+ <md-elevated-button href=${`project-plan-management/${this.project.id}`}>
95
+ <md-icon slot="icon">description</md-icon>도면 관리
96
+ </md-elevated-button>
97
+ <md-elevated-button href=${`project-task/${this.project.id}`}>
98
+ <md-icon slot="icon">event_note</md-icon>공정표 관리
99
+ </md-elevated-button>
100
+ `}
70
101
  </div>
71
102
  </div>
72
103
 
73
104
  <div body>
74
105
  <div>
75
106
  <div left-top>
76
- <h3>기본 정보</h3>
107
+ <h3>
108
+ 기본 정보
109
+ <md-elevated-button href=${`project-update/${this.project.id}`}>
110
+ <md-icon slot="icon">assignment</md-icon>프로젝트 정보 수정
111
+ </md-elevated-button>
112
+ </h3>
77
113
  <div content-1>
78
114
  <img
79
- ?no-image=${!((_a = this.project.mainPhoto) === null || _a === void 0 ? void 0 : _a.fullpath)}
80
- src=${((_b = this.project.mainPhoto) === null || _b === void 0 ? void 0 : _b.fullpath) || '/assets/images/no-image.png'}
115
+ ?no-image=${!((_c = this.project.mainPhoto) === null || _c === void 0 ? void 0 : _c.fullpath)}
116
+ src=${((_d = this.project.mainPhoto) === null || _d === void 0 ? void 0 : _d.fullpath) || '/assets/images/no-image.png'}
81
117
  />
82
118
 
83
119
  <div>
84
120
  <div row>
85
121
  <span>- 면적 : </span>
86
- <span>${(_d = (_c = this.project.buildingComplex) === null || _c === void 0 ? void 0 : _c.area) === null || _d === void 0 ? void 0 : _d.toLocaleString()} ㎡</span>
122
+ <span>${(_f = (_e = this.project.buildingComplex) === null || _e === void 0 ? void 0 : _e.area) === null || _f === void 0 ? void 0 : _f.toLocaleString()} ㎡</span>
87
123
  </div>
88
124
  <div row>
89
125
  <span>- 착공~준공 : </span>
@@ -91,19 +127,19 @@ let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
91
127
  </div>
92
128
  <div row>
93
129
  <span>- 발주처 : </span>
94
- <span>${(_e = this.project.buildingComplex) === null || _e === void 0 ? void 0 : _e.clientCompany}</span>
130
+ <span>${(_g = this.project.buildingComplex) === null || _g === void 0 ? void 0 : _g.clientCompany}</span>
95
131
  </div>
96
132
  <div row>
97
133
  <span>- 건설사 : </span>
98
- <span>${(_f = this.project.buildingComplex) === null || _f === void 0 ? void 0 : _f.constructionCompany}</span>
134
+ <span>${(_h = this.project.buildingComplex) === null || _h === void 0 ? void 0 : _h.constructionCompany}</span>
99
135
  </div>
100
136
  <div row>
101
137
  <span>- 감리사 : </span>
102
- <span>${(_g = this.project.buildingComplex) === null || _g === void 0 ? void 0 : _g.supervisoryCompany}</span>
138
+ <span>${(_j = this.project.buildingComplex) === null || _j === void 0 ? void 0 : _j.supervisoryCompany}</span>
103
139
  </div>
104
140
  <div row>
105
141
  <span>- 설계사 : </span>
106
- <span>${(_h = this.project.buildingComplex) === null || _h === void 0 ? void 0 : _h.designCompany}</span>
142
+ <span>${(_k = this.project.buildingComplex) === null || _k === void 0 ? void 0 : _k.designCompany}</span>
107
143
  </div>
108
144
  </div>
109
145
  </div>
@@ -111,45 +147,109 @@ let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
111
147
  <div content-2>
112
148
  <div row>
113
149
  <span>- 건설구분 : </span>
114
- <span>${(_j = this.project.buildingComplex) === null || _j === void 0 ? void 0 : _j.constructionType}</span>
150
+ <span>${(_l = this.project.buildingComplex) === null || _l === void 0 ? void 0 : _l.constructionType}</span>
115
151
  </div>
116
152
  <div row>
117
153
  <span>- 공사금액 : </span>
118
- <span>${(_l = (_k = this.project.buildingComplex) === null || _k === void 0 ? void 0 : _k.constructionCost) === null || _l === void 0 ? void 0 : _l.toLocaleString()} 원</span>
154
+ <span>${(_o = (_m = this.project.buildingComplex) === null || _m === void 0 ? void 0 : _m.constructionCost) === null || _o === void 0 ? void 0 : _o.toLocaleString()} 억원</span>
119
155
  </div>
120
156
  <div row>
121
157
  <span>- 세대수 : </span>
122
- <span>${(_o = (_m = this.project.buildingComplex) === null || _m === void 0 ? void 0 : _m.householdCount) === null || _o === void 0 ? void 0 : _o.toLocaleString()}</span>
158
+ <span>${(_q = (_p = this.project.buildingComplex) === null || _p === void 0 ? void 0 : _p.householdCount) === null || _q === void 0 ? void 0 : _q.toLocaleString()}</span>
123
159
  </div>
124
160
  <div row>
125
161
  <span>- 기타 : </span>
126
- <span>${(_p = this.project.buildingComplex) === null || _p === void 0 ? void 0 : _p.etc}</span>
162
+ <span>${(_r = this.project.buildingComplex) === null || _r === void 0 ? void 0 : _r.etc}</span>
127
163
  </div>
128
164
  </div>
129
165
  </div>
130
166
 
131
167
  <div left-bottom>
132
- <h3>조감도(BIM도면)</h3>
133
- ${((_r = (_q = this.project.buildingComplex) === null || _q === void 0 ? void 0 : _q.drawing) === null || _r === void 0 ? void 0 : _r.fullpath)
168
+ <h3>
169
+ 조감도(BIM도면)
170
+ <md-elevated-button
171
+ target="_blank"
172
+ href=${((_s = this.project.buildingComplex) === null || _s === void 0 ? void 0 : _s.virtualTourLink) || ''}
173
+ ?disabled=${!((_t = this.project.buildingComplex) === null || _t === void 0 ? void 0 : _t.virtualTourLink)}
174
+ >
175
+ <md-icon slot="icon">smart_toy</md-icon>Virtual Tour
176
+ </md-elevated-button>
177
+ </h3>
178
+ ${((_v = (_u = this.project.buildingComplex) === null || _u === void 0 ? void 0 : _u.drawing) === null || _v === void 0 ? void 0 : _v.fullpath)
134
179
  ? html `<div building-complex-img></div>`
135
180
  : html `<img building-complex-img src="/assets/images/img-building-complex-default.jpg" />`}
136
- <div>
137
- <div subject bold>개별 단지 상세정보 바로가기</div>
138
- <div building-container>
139
- ${(_t = (_s = this.project.buildingComplex) === null || _s === void 0 ? void 0 : _s.buildings) === null || _t === void 0 ? void 0 : _t.map(building => {
140
- return html `<md-outlined-button href=${`building-complex-detail/${this.project.id}?buildingId=${building.id}`}>
141
- ${building.name}
142
- </md-outlined-button>`;
143
- })}
144
- </div>
145
- </div>
146
181
  </div>
147
182
  </div>
148
183
 
149
184
  <div>
150
185
  <div right-top>
151
186
  <h3>프로젝트 현황</h3>
187
+
188
+ <div kpi-header>
189
+ <span kpi-datetime
190
+ >${new Date().toLocaleDateString('ko-KR')}
191
+ ${new Date().toLocaleTimeString('ko-KR', { hour: '2-digit', minute: '2-digit', hour12: false })}</span
192
+ >
193
+ </div>
152
194
  <div state>
195
+ <div kpi-container>
196
+ <div kpi-info-item kpi>
197
+ <ox-progress-circle
198
+ .value=${this.project.kpi || 0}
199
+ fontColor="transparent"
200
+ borderStyle="none"
201
+ innerCircleSize="30%"
202
+ circleColor="#E15757"
203
+ background="#f6f6f6"
204
+ size="120px"
205
+ ></ox-progress-circle>
206
+
207
+ <div kpi-info-label>
208
+ <span kpi-info-label>KPI 지수</span>
209
+ <span kpi-info-value bold>${this.project.kpi || 0}%</span>
210
+ </div>
211
+ </div>
212
+ <div kpi-info-item>
213
+ <span kpi-info-label>검측 통과율</span>
214
+ <span kpi-info-value>
215
+ <span bold>${((_w = this.inspectionSummary.pass) === null || _w === void 0 ? void 0 : _w.toLocaleString()) || 0}</span>
216
+ <span small> / ${(totalInspectionCount === null || totalInspectionCount === void 0 ? void 0 : totalInspectionCount.toLocaleString()) || 0}</span>
217
+ </span>
218
+ </div>
219
+ <div kpi-info-item>
220
+ <span kpi-info-label>작업 중 로봇</span>
221
+ <span kpi-info-value>
222
+ <span bold>${((_x = this.project.robotCount) === null || _x === void 0 ? void 0 : _x.toLocaleString()) || 0}</span>
223
+ <span small> 대</span>
224
+ </span>
225
+ </div>
226
+ <div kpi-info-item weather>
227
+ <div>
228
+ <span><md-icon slot="icon">rainy</md-icon>강수확률</span>
229
+ <span bold>${this.weather.rain}%</span>
230
+ </div>
231
+ <div>
232
+ <span><md-icon slot="icon">humidity_percentage</md-icon> 습도</span>
233
+ <span bold>${this.weather.humidity}%</span>
234
+ </div>
235
+ <div>
236
+ <span><md-icon slot="icon">thermostat</md-icon> 온도</span>
237
+ <span bold>${this.weather.temperature}°C</span>
238
+ </div>
239
+
240
+ <!--
241
+ <div>
242
+ <span><md-icon slot="icon">arrows_output</md-icon> 풍향</span>
243
+ <span bold>${this.weather.windDirection}</span>
244
+ </div>
245
+ <div>
246
+ <span><md-icon slot="icon">air</md-icon> 풍속</span>
247
+ <span bold>${this.weather.windSpeed} m/s</span>
248
+ </div>
249
+ -->
250
+ </div>
251
+ </div>
252
+
153
253
  <div progress-container>
154
254
  <span progress>
155
255
  <ox-progress-circle
@@ -185,106 +285,70 @@ let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
185
285
  <span progress>
186
286
  <ox-progress-circle
187
287
  .value=${this.project.inspPassRate}
288
+ titleText="검측 통과"
188
289
  suffix="%"
189
290
  fontSize="27px"
190
291
  fontColor="#4E5055"
191
292
  borderStyle="none"
192
293
  innerCircleSize="28%"
193
- circleColor="#8B3F39"
294
+ circleColor="#1BB401"
194
295
  shadow="#00000026 4px 4px 4px"
195
- background="#DACCC7"
296
+ background="#e8f7e5"
196
297
  ></ox-progress-circle>
197
- <div insp-pass-rate>시공/구조 검측 통과 비율(%)</div>
298
+ <div insp-pass-rate>통과 비율(%)</div>
198
299
  </span>
199
300
  <span progress>
200
301
  <ox-progress-circle
201
302
  .value=${this.project.robotProgressRate}
303
+ titleText="로봇작업"
202
304
  suffix="%"
203
305
  fontSize="27px"
204
306
  fontColor="#4E5055"
205
307
  borderStyle="none"
206
308
  innerCircleSize="28%"
207
- circleColor="#4A899B"
309
+ circleColor="#8957D8"
208
310
  shadow="#00000026 4px 4px 4px"
209
- background="#C7DFE1"
311
+ background="#f3eefb"
210
312
  ></ox-progress-circle>
211
- <div robot-progress-rate>로봇 작업 진행률(%)</div>
212
- </span>
213
- </div>
214
-
215
- <div>
216
- <div>KPI</div>
217
-
218
- <div kpi-container>
219
- <div kpi-item>
220
- <span>KPI 지수</span>
221
- <span kpi-value kpi-index>${this.project.kpi || 0}%</span>
222
- </div>
223
- <div kpi-item>
224
- <span>검측 통과율</span>
225
- <span kpi-value pass-rate>${this.inspectionSummary.pass || 0} / ${totalInspectionCount || 0}</span>
226
- </div>
227
- <div kpi-item>
228
- <span>로봇 작업 대수</span>
229
- <span kpi-value robot-count>${this.project.robotCount || 0}</span>
230
- </div>
231
- </div>
232
-
233
- <span weather>
234
- <div bold>현장현황</div>
235
- <div>
236
- <span><md-icon slot="icon">rainy</md-icon>강수확률</span>
237
- <span bold>${this.weather.rain}%</span>
238
- </div>
239
- <div>
240
- <span><md-icon slot="icon">humidity_percentage</md-icon> 습도</span>
241
- <span bold>${this.weather.humidity}%</span>
242
- </div>
243
- <div>
244
- <span><md-icon slot="icon">thermostat</md-icon> 온도</span>
245
- <span bold>${this.weather.temperature}°C</span>
246
- </div>
247
- <div>
248
- <span><md-icon slot="icon">arrows_output</md-icon> 풍향</span>
249
- <span bold>${this.weather.windDirection}</span>
250
- </div>
251
- <div>
252
- <span><md-icon slot="icon">air</md-icon> 풍속</span>
253
- <span bold>${this.weather.windSpeed} m/s</span>
254
- </div>
313
+ <div robot-progress-rate>진행률(%)</div>
255
314
  </span>
256
315
  </div>
257
316
  </div>
317
+ <div notice>
318
+ <div name bold>공지사항</div>
319
+ <div content>${this.project.buildingComplex.notice}</div>
320
+ </div>
321
+
258
322
  <div inspection>
259
323
  <span name bold>
260
324
  <md-icon slot="icon">list_alt_add</md-icon>
261
- 시공검측<br />현황
325
+ 작업 현황
262
326
  </span>
263
- <span>
264
- <div>검측요청</div>
265
- <div bold>${this.inspectionSummary.wait}</div>
327
+ <span ?active=${this.statusFilter === 'WAIT'} @click=${() => this._onClickStatusFilter('WAIT')}>
328
+ <div>작업 완료</div>
329
+ <div bold wait>${(this.inspectionSummary.wait || 0) - (this.inspectionSummary.reWait || 0)}</div>
266
330
  </span>
267
- <span>
268
- <div>검측대기</div>
269
- <div bold>${this.inspectionSummary.request}</div>
331
+ <span ?active=${this.statusFilter === 'REQUEST'} @click=${() => this._onClickStatusFilter('REQUEST')}>
332
+ <div>감리 대기</div>
333
+ <div bold request>${this.inspectionSummary.request}</div>
270
334
  </span>
271
- <span>
272
- <div>합격</div>
273
- <div bold pass>${this.inspectionSummary.pass}</div>
274
- </span>
275
- <span>
276
- <div>불합격</div>
335
+ <span ?active=${this.statusFilter === 'FAIL'} @click=${() => this._onClickStatusFilter('FAIL')}>
336
+ <div>조치 필요</div>
277
337
  <div bold fail>${this.inspectionSummary.fail}</div>
278
338
  </span>
279
- </div>
280
- <div notice>
281
- <div name bold>공지사항</div>
282
- <div content>${this.project.buildingComplex.notice}</div>
339
+ <span ?active=${this.statusFilter === 'RE_WAIT'} @click=${() => this._onClickStatusFilter('RE_WAIT')}>
340
+ <div>재검측 대기</div>
341
+ <div bold re-wait>${this.inspectionSummary.reWait || 0}</div>
342
+ </span>
343
+ <span ?active=${this.statusFilter === 'PASS'} @click=${() => this._onClickStatusFilter('PASS')}>
344
+ <div>검측 완료</div>
345
+ <div bold pass>${this.inspectionSummary.pass}</div>
346
+ </span>
283
347
  </div>
284
348
  </div>
285
349
 
286
350
  <div right-bottom>
287
- <h3>검측 현황</h3>
351
+ <h3>검측 현황${this.statusFilter ? ` (${this._getStatusFilterLabel()} 목록)` : ''}</h3>
288
352
  <div table-container>
289
353
  <hr />
290
354
  <table>
@@ -295,7 +359,7 @@ let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
295
359
  <th width="10%">공종</th>
296
360
  <th width="22%">내용</th>
297
361
  <th width="15%">검측 요청일</th>
298
- <th width="10%">검측 결과</th>
362
+ <th width="10%">작업 상태</th>
299
363
  </tr>
300
364
  </thead>
301
365
  <tbody>
@@ -308,7 +372,8 @@ let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
308
372
  <td>${((_f = (_e = inspection.checklist) === null || _e === void 0 ? void 0 : _e.inspectionParts) === null || _f === void 0 ? void 0 : _f.join(', ')) || ''}</td>
309
373
  <td>${this._formatDate(inspection.requestDate)}</td>
310
374
  <td bold status=${inspection.status || ''}>
311
- ${inspection.status && BUILDING_INSPECTION_STATUS[inspection.status]}
375
+ ${inspection.status &&
376
+ ((inspection.failCount || 0) > 0 ? BUILDING_INSPECTION_RE_STATUS : BUILDING_INSPECTION_STATUS)[inspection.status]}
312
377
  </td>
313
378
  </tr>`;
314
379
  })}
@@ -322,11 +387,40 @@ let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
322
387
  }
323
388
  async pageInitialized(lifecycle) { }
324
389
  async pageUpdated(changes, lifecycle) {
390
+ var _a, _b;
325
391
  if (this.active) {
326
392
  this.projectId = lifecycle.resourceId || '';
327
- await this.initProject(lifecycle.resourceId);
393
+ // resourceId 없이 진입한 경우 (프로젝트 테넌트 → / 접속)
394
+ if (!this.projectId) {
395
+ const res = await client.query({
396
+ query: gql `
397
+ query {
398
+ currentProject {
399
+ id
400
+ }
401
+ }
402
+ `
403
+ });
404
+ const projectId = (_b = (_a = res.data) === null || _a === void 0 ? void 0 : _a.currentProject) === null || _b === void 0 ? void 0 : _b.id;
405
+ if (projectId) {
406
+ navigate(`project-detail/${projectId}`);
407
+ return;
408
+ }
409
+ }
410
+ await Promise.all([this.initProject(lifecycle.resourceId), this._fetchProjectType()]);
328
411
  }
329
412
  }
413
+ async _fetchProjectType() {
414
+ var _a;
415
+ const response = await client.query({
416
+ query: gql `
417
+ query {
418
+ currentProjectType
419
+ }
420
+ `
421
+ });
422
+ this.configProjectType = ((_a = response.data) === null || _a === void 0 ? void 0 : _a.currentProjectType) || '';
423
+ }
330
424
  async initProject(projectId = '') {
331
425
  var _a, _b, _c, _d, _e;
332
426
  const response = await client.query({
@@ -369,6 +463,7 @@ let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
369
463
  notice
370
464
  householdCount
371
465
  buildingCount
466
+ virtualTourLink
372
467
  buildings {
373
468
  id
374
469
  name
@@ -382,12 +477,14 @@ let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
382
477
  request
383
478
  pass
384
479
  fail
480
+ reWait
385
481
  }
386
482
 
387
483
  buildingInspectionsOfProject(params: $params) {
388
484
  items {
389
485
  id
390
486
  status
487
+ failCount
391
488
  requestDate
392
489
  buildingLevel {
393
490
  id
@@ -412,10 +509,7 @@ let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
412
509
  variables: {
413
510
  id: projectId,
414
511
  projectId,
415
- params: {
416
- projectId,
417
- limit: 10
418
- }
512
+ params: Object.assign({ projectId, limit: 10 }, (this.statusFilter ? { statusFilter: this.statusFilter } : {}))
419
513
  }
420
514
  });
421
515
  if (response.errors)
@@ -428,6 +522,21 @@ let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
428
522
  this.weather = await _getWeather(latitude, longitude);
429
523
  }
430
524
  }
525
+ async _onClickStatusFilter(filter) {
526
+ // 같은 필터 클릭 시 해제
527
+ this.statusFilter = this.statusFilter === filter ? '' : filter;
528
+ await this.initProject(this.projectId);
529
+ }
530
+ _getStatusFilterLabel() {
531
+ const labels = {
532
+ WAIT: '작업 완료',
533
+ REQUEST: '감리 대기',
534
+ FAIL: '조치 필요',
535
+ RE_WAIT: '재검측 대기',
536
+ PASS: '검측 완료'
537
+ };
538
+ return labels[this.statusFilter] || '';
539
+ }
431
540
  _onClickInspection(buildingInspection) {
432
541
  var _a, _b, _c;
433
542
  console.log('buildingInspection :', buildingInspection);
@@ -439,14 +548,20 @@ let ProjectDetail = class ProjectDetail extends ScopedElementsMixin(PageView) {
439
548
  }
440
549
  }
441
550
  _formatDate(date) {
442
- return date
443
- ? new Intl.DateTimeFormat('en-CA', {
551
+ if (!date)
552
+ return '';
553
+ try {
554
+ const parsed = typeof date === 'string' && /^\d+$/.test(date) ? new Date(Number(date)) : new Date(date);
555
+ return new Intl.DateTimeFormat('en-CA', {
444
556
  timeZone: 'Asia/Seoul',
445
557
  year: 'numeric',
446
558
  month: '2-digit',
447
559
  day: '2-digit'
448
- }).format(new Date(date))
449
- : '';
560
+ }).format(parsed);
561
+ }
562
+ catch (_a) {
563
+ return String(date).split('T')[0] || '';
564
+ }
450
565
  }
451
566
  };
452
567
  ProjectDetail.styles = [
@@ -481,9 +596,28 @@ ProjectDetail.styles = [
481
596
  margin: 0px var(--spacing-large, 12px);
482
597
 
483
598
  h2 {
599
+ display: flex;
600
+ gap: 7px;
484
601
  flex: 0.5;
485
602
  color: #3f71a0;
486
603
  font-size: 18px;
604
+
605
+ md-icon[back] {
606
+ background: linear-gradient(135deg, #3f71a0 0%, #5a8cc7 100%);
607
+ color: white;
608
+ padding: 8px;
609
+ border-radius: 50%;
610
+ cursor: pointer;
611
+ box-shadow: 0 2px 8px rgba(63, 113, 160, 0.3);
612
+ width: 14px;
613
+ height: 14px;
614
+ --md-icon-size: 20px;
615
+ }
616
+
617
+ md-icon[back]:hover {
618
+ background: linear-gradient(135deg, #2e5c89 0%, #4a7bb0 100%);
619
+ box-shadow: 0 4px 12px rgba(63, 113, 160, 0.4);
620
+ }
487
621
  }
488
622
 
489
623
  div[button-container] {
@@ -518,6 +652,9 @@ ProjectDetail.styles = [
518
652
  gap: var(--spacing-medium, 8px);
519
653
 
520
654
  h3 {
655
+ display: flex;
656
+ align-items: center;
657
+ justify-content: space-between;
521
658
  color: #2e79be;
522
659
  font-size: 16px;
523
660
  margin: 0px;
@@ -526,6 +663,20 @@ ProjectDetail.styles = [
526
663
  text-decoration: none;
527
664
  color: #2e79be;
528
665
  }
666
+
667
+ md-elevated-button {
668
+ --md-elevated-button-container-height: 28px;
669
+ --md-elevated-button-label-text-size: 13px;
670
+ --md-elevated-button-container-color: #0595e5;
671
+ --md-elevated-button-label-text-color: var(--md-sys-color-on-primary);
672
+ --md-elevated-button-hover-label-text-color: var(--md-sys-color-on-primary);
673
+ --md-elevated-button-pressed-label-text-color: var(--md-sys-color-on-primary);
674
+ --md-elevated-button-focus-label-text-color: var(--md-sys-color-on-primary);
675
+ --md-elevated-button-icon-color: var(--md-sys-color-on-primary);
676
+ --md-elevated-button-hover-icon-color: var(--md-sys-color-on-primary);
677
+ --md-elevated-button-pressed-icon-color: var(--md-sys-color-on-primary);
678
+ --md-elevated-button-focus-icon-color: var(--md-sys-color-on-primary);
679
+ }
529
680
  }
530
681
 
531
682
  & > div {
@@ -584,65 +735,47 @@ ProjectDetail.styles = [
584
735
  img {
585
736
  opacity: 0.5;
586
737
  }
587
-
588
- div[subject] {
589
- margin-bottom: var(--spacing-small, 4px);
590
- }
591
-
592
- div[building-container] {
593
- display: block;
594
-
595
- & > * {
596
- margin-right: var(--spacing-medium, 8px);
597
- margin-bottom: var(--spacing-medium, 8px);
598
- }
599
- md-outlined-button {
600
- --md-outlined-button-container-height: 30px;
601
- --md-outlined-button-trailing-space: var(--spacing-medium, 8px);
602
- --md-outlined-button-leading-space: var(--spacing-medium, 8px);
603
- --md-sys-color-outline: rgba(51, 51, 51, 0.2);
604
- }
605
- }
606
738
  }
607
739
 
608
740
  div[right-top] {
609
741
  div[state] {
610
- display: grid;
611
- grid-template-columns: 1.9fr 1.1fr;
742
+ display: flex;
743
+ flex-direction: column;
612
744
  gap: var(--spacing-large, 12px);
613
745
 
614
746
  div[progress-container] {
615
- display: grid;
616
- grid-template-columns: 1fr 1fr;
617
- row-gap: 15px;
747
+ display: flex;
748
+ justify-content: space-around;
749
+ gap: 8px;
618
750
 
619
751
  span[progress] {
620
- max-width: 150px;
752
+ max-width: 165px;
621
753
  text-align: center;
622
754
  display: flex;
623
755
  justify-self: center;
624
756
  flex-direction: column;
625
757
  width: 100%;
758
+ margin-inline: 12px;
626
759
 
627
760
  & > div {
628
761
  font-weight: bold;
629
762
  color: #2e79be;
630
- font-size: 12px;
631
- margin-top: var(--spacing-small, 4px);
763
+ font-size: 16px;
764
+ margin-top: 9px;
632
765
  }
633
766
  & > div[week] {
634
767
  color: #06b5af;
635
768
  }
636
769
  & > div[insp-pass-rate] {
637
- color: #8b3f39;
770
+ color: #1bb401;
638
771
  }
639
772
  & > div[robot-progress-rate] {
640
- color: #4a899b;
773
+ color: #8957d8;
641
774
  }
642
775
  }
643
776
  }
644
777
 
645
- span[weather] {
778
+ div[weather] {
646
779
  display: flex;
647
780
  flex-direction: column;
648
781
  gap: var(--spacing-small, 4px);
@@ -665,8 +798,8 @@ ProjectDetail.styles = [
665
798
  }
666
799
  div[inspection] {
667
800
  display: grid;
668
- grid-template-columns: 1.4fr 0.9fr 0.9fr 0.9fr 0.9fr;
669
- margin-top: var(--spacing-small, 4px);
801
+ grid-template-columns: 1.4fr 0.9fr 0.9fr 0.9fr 0.9fr 0.9fr;
802
+ margin-top: 10px;
670
803
  background: #f6f6f6;
671
804
  border-radius: 7px;
672
805
  padding: var(--spacing-small, 4px) 0px;
@@ -676,6 +809,18 @@ ProjectDetail.styles = [
676
809
  flex-direction: column;
677
810
  align-items: center;
678
811
  justify-content: center;
812
+ border-radius: 5px;
813
+ padding: 4px 0;
814
+
815
+ &:not([name]) {
816
+ cursor: pointer;
817
+ }
818
+ &:not([name]):hover {
819
+ background: #e8e8e8;
820
+ }
821
+ &[active] {
822
+ background: #dceefb;
823
+ }
679
824
 
680
825
  div[wait] {
681
826
  color: #4e5055;
@@ -689,6 +834,9 @@ ProjectDetail.styles = [
689
834
  div[fail] {
690
835
  color: #ff4444;
691
836
  }
837
+ div[re-wait] {
838
+ color: #e89c0e;
839
+ }
692
840
  }
693
841
  & > span[name] {
694
842
  flex-direction: row;
@@ -707,26 +855,77 @@ ProjectDetail.styles = [
707
855
  }
708
856
  div[kpi-container] {
709
857
  display: flex;
710
- flex-direction: column;
711
- gap: var(--spacing-small, 4px);
712
- margin-bottom: var(--spacing-medium, 8px);
858
+ gap: 8px;
859
+ margin-bottom: 8px;
860
+ align-items: center;
713
861
 
714
- div[kpi-item] {
862
+ div[kpi-header] {
863
+ grid-column: 1 / -1;
715
864
  display: flex;
716
865
  justify-content: space-between;
717
- font-size: 14px;
866
+ align-items: center;
867
+ margin-bottom: var(--spacing-small, 4px);
718
868
 
719
- span[kpi-value] {
869
+ span[kpi-title] {
720
870
  font-weight: bold;
721
- }
722
- span[kpi-index] {
871
+ font-size: 16px;
723
872
  color: #2e79be;
724
873
  }
725
- span[pass-rate] {
726
- color: #1bb401;
874
+
875
+ span[kpi-datetime] {
876
+ font-size: 12px;
877
+ color: #666;
727
878
  }
728
- span[robot-count] {
729
- color: #4a899b;
879
+ }
880
+
881
+ div[kpi-info-item] {
882
+ display: flex;
883
+ flex: 1;
884
+ flex-direction: column;
885
+ align-items: center;
886
+ padding: 5px;
887
+ background: #f6f6f6;
888
+ border-radius: 4px;
889
+ min-height: 50px;
890
+ justify-content: center;
891
+ margin-inline: 12px;
892
+ border-radius: 7px;
893
+
894
+ span[kpi-info-label] {
895
+ font-size: 16px;
896
+ color: #4e5055;
897
+ margin-bottom: 2px;
898
+ }
899
+
900
+ span[kpi-info-value] {
901
+ font-size: 18px;
902
+
903
+ & > span[small] {
904
+ font-size: 17px;
905
+ }
906
+ }
907
+
908
+ &[weather] {
909
+ background: none;
910
+ align-items: flex-start;
911
+
912
+ & > div {
913
+ width: 100%;
914
+ }
915
+ }
916
+
917
+ &[kpi] {
918
+ flex-direction: row;
919
+ justify-content: space-around;
920
+
921
+ div[kpi-info-label] {
922
+ display: flex;
923
+ flex-direction: column;
924
+ }
925
+
926
+ ox-progress-circle {
927
+ width: 45px;
928
+ }
730
929
  }
731
930
  }
732
931
  }
@@ -842,6 +1041,14 @@ __decorate([
842
1041
  state(),
843
1042
  __metadata("design:type", Object)
844
1043
  ], ProjectDetail.prototype, "inspectionSummary", void 0);
1044
+ __decorate([
1045
+ state(),
1046
+ __metadata("design:type", String)
1047
+ ], ProjectDetail.prototype, "statusFilter", void 0);
1048
+ __decorate([
1049
+ state(),
1050
+ __metadata("design:type", String)
1051
+ ], ProjectDetail.prototype, "configProjectType", void 0);
845
1052
  __decorate([
846
1053
  state(),
847
1054
  __metadata("design:type", Object)