@dssp/supervision 1.0.15 → 1.0.17
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.
- package/dist-client/pages/building-inspection/building-inspection-detail-ai-measurement.d.ts +7 -0
- package/dist-client/pages/building-inspection/building-inspection-detail-ai-measurement.js +170 -17
- package/dist-client/pages/building-inspection/building-inspection-detail-ai-measurement.js.map +1 -1
- package/dist-client/pages/building-inspection/inspection-create-popup.js +2 -2
- package/dist-client/pages/building-inspection/inspection-create-popup.js.map +1 -1
- package/dist-client/pages/building-inspection/inspection-with-checklist-create-popup.js +2 -2
- package/dist-client/pages/building-inspection/inspection-with-checklist-create-popup.js.map +1 -1
- package/dist-client/pages/checklist/checklist-view.js +3 -3
- package/dist-client/pages/checklist/checklist-view.js.map +1 -1
- package/dist-client/pages/checklist-template/checklist-template-list.js +1 -1
- package/dist-client/pages/checklist-template/checklist-template-list.js.map +1 -1
- package/dist-client/pages/project-checklist/project-checklist-management.d.ts +15 -6
- package/dist-client/pages/project-checklist/project-checklist-management.js +249 -109
- package/dist-client/pages/project-checklist/project-checklist-management.js.map +1 -1
- package/dist-client/route.d.ts +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/service/checklist-item/checklist-item.js +1 -1
- package/dist-server/service/checklist-item/checklist-item.js.map +1 -1
- package/dist-server/service/checklist-item-history/checklist-item-history.js +1 -1
- package/dist-server/service/checklist-item-history/checklist-item-history.js.map +1 -1
- package/dist-server/service/index.d.ts +1 -1
- package/dist-server/service/project-checklist/index.d.ts +1 -1
- package/dist-server/service/project-checklist/project-checklist-mutation.d.ts +4 -3
- package/dist-server/service/project-checklist/project-checklist-mutation.js +23 -12
- package/dist-server/service/project-checklist/project-checklist-mutation.js.map +1 -1
- package/dist-server/service/project-checklist/project-checklist-type.d.ts +4 -0
- package/dist-server/service/project-checklist/project-checklist-type.js +16 -1
- package/dist-server/service/project-checklist/project-checklist-type.js.map +1 -1
- package/dist-server/service/project-checklist/spec-matching-service.d.ts +16 -8
- package/dist-server/service/project-checklist/spec-matching-service.js +107 -52
- package/dist-server/service/project-checklist/spec-matching-service.js.map +1 -1
- package/dist-server/service/project-checklist-item/project-checklist-item.js +1 -1
- package/dist-server/service/project-checklist-item/project-checklist-item.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -31,8 +31,10 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
31
31
|
this.templateItems = [];
|
|
32
32
|
this.isEditMode = false;
|
|
33
33
|
this.selectedChecklistId = null;
|
|
34
|
-
|
|
35
|
-
this.
|
|
34
|
+
/** 프로젝트에 등록된 공사 시방서 첨부 목록 (여러 건, PDF·한글 혼합 가능) */
|
|
35
|
+
this.siteSpecFiles = [];
|
|
36
|
+
this.siteSpecSyncing = false;
|
|
37
|
+
this.siteSpecListOpen = false;
|
|
36
38
|
this.siteSpecDetail = null;
|
|
37
39
|
this.siteSpecDetailItem = '';
|
|
38
40
|
/** 뮤테이션 가능 여부('dcsp guest' 권한 보유 시 false) — 게스트에게는 생성/수정/삭제 버튼을 숨긴다 */
|
|
@@ -60,23 +62,57 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
60
62
|
<input
|
|
61
63
|
id="siteSpecFileInput"
|
|
62
64
|
type="file"
|
|
63
|
-
|
|
65
|
+
multiple
|
|
66
|
+
accept="application/pdf,.pdf,.hwp"
|
|
64
67
|
style="display: none"
|
|
65
|
-
@change=${this.
|
|
68
|
+
@change=${this._onUploadSiteSpecs}
|
|
66
69
|
/>
|
|
67
|
-
${
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
${
|
|
71
|
+
// 파일이 수십 개가 되어도 헤더가 밀리지 않도록 개수만 표시하고, 목록은 펼침 패널로 본다
|
|
72
|
+
this.siteSpecFiles.length
|
|
73
|
+
? html `<div site-spec-box>
|
|
74
|
+
<span site-spec-count @click=${() => (this.siteSpecListOpen = !this.siteSpecListOpen)}>
|
|
75
|
+
<md-icon>description</md-icon>
|
|
76
|
+
공사 시방서 ${this.siteSpecFiles.length}건
|
|
77
|
+
<md-icon>${this.siteSpecListOpen ? 'expand_less' : 'expand_more'}</md-icon>
|
|
78
|
+
</span>
|
|
79
|
+
${this.siteSpecListOpen
|
|
80
|
+
? html `<div site-spec-list>
|
|
81
|
+
${this.canMutate
|
|
82
|
+
? html `<div site-spec-tools>
|
|
83
|
+
<span delete-all @click=${this._removeAllSiteSpecs}>
|
|
84
|
+
<md-icon>delete_sweep</md-icon>전체 삭제
|
|
85
|
+
</span>
|
|
86
|
+
</div>`
|
|
87
|
+
: ''}
|
|
88
|
+
${this.siteSpecFiles.map(file => html `<div site-spec-row title=${file.name}>
|
|
89
|
+
<md-icon>description</md-icon>
|
|
90
|
+
<span filename>${file.name}</span>
|
|
91
|
+
${this.canMutate
|
|
92
|
+
? html `<md-icon clickable @click=${() => this._removeSiteSpec(file)}>close</md-icon>`
|
|
93
|
+
: ''}
|
|
94
|
+
</div>`)}
|
|
95
|
+
</div>`
|
|
96
|
+
: ''}
|
|
97
|
+
</div>`
|
|
73
98
|
: ''}
|
|
74
99
|
${this.canMutate
|
|
75
|
-
? html
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
100
|
+
? html `${this.siteSpecFiles.length
|
|
101
|
+
? html `<md-elevated-button
|
|
102
|
+
?disabled=${this.siteSpecSyncing}
|
|
103
|
+
title="첨부된 시방서를 매칭 엔진에 다시 등록합니다"
|
|
104
|
+
@click=${this._onReregisterSiteSpecs}
|
|
105
|
+
>
|
|
106
|
+
<md-icon slot="icon">sync</md-icon>시방서 재등록
|
|
107
|
+
</md-elevated-button>`
|
|
108
|
+
: ''}
|
|
109
|
+
<md-elevated-button
|
|
110
|
+
?disabled=${this.siteSpecSyncing}
|
|
111
|
+
@click=${() => { var _a; return (_a = this.renderRoot.querySelector('#siteSpecFileInput')) === null || _a === void 0 ? void 0 : _a.click(); }}
|
|
112
|
+
>
|
|
113
|
+
<md-icon slot="icon">upload_file</md-icon>
|
|
114
|
+
${this.siteSpecSyncing ? '시방서 등록 중...' : '공사 시방서 업로드'}
|
|
115
|
+
</md-elevated-button>`
|
|
80
116
|
: ''}
|
|
81
117
|
<md-elevated-button href=${`project-detail/${this.projectId}`}>
|
|
82
118
|
<md-icon slot="icon">home</md-icon>프로젝트 홈
|
|
@@ -154,7 +190,7 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
154
190
|
|
|
155
191
|
${this.siteSpecDetail
|
|
156
192
|
? html `<kcs-criteria-popup
|
|
157
|
-
.popupTitle=${'
|
|
193
|
+
.popupTitle=${'공사 시방서 기준'}
|
|
158
194
|
.kcs=${{ text: this.siteSpecDetail }}
|
|
159
195
|
.itemName=${this.siteSpecDetailItem}
|
|
160
196
|
@close=${() => (this.siteSpecDetail = null)}
|
|
@@ -178,7 +214,7 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
178
214
|
this._buildRightGristConfig();
|
|
179
215
|
}
|
|
180
216
|
async _fetchProjectName() {
|
|
181
|
-
var _a, _b
|
|
217
|
+
var _a, _b;
|
|
182
218
|
if (!this.projectId)
|
|
183
219
|
return;
|
|
184
220
|
const response = await client.query({
|
|
@@ -186,30 +222,29 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
186
222
|
query Project($id: String!) {
|
|
187
223
|
project(id: $id) {
|
|
188
224
|
name
|
|
189
|
-
siteSpecPdfUrl
|
|
190
225
|
}
|
|
191
226
|
}
|
|
192
227
|
`,
|
|
193
228
|
variables: { id: this.projectId }
|
|
194
229
|
});
|
|
195
230
|
this.projectName = ((_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.project) === null || _b === void 0 ? void 0 : _b.name) || '';
|
|
196
|
-
|
|
197
|
-
this.siteSpecPdfUrl = ((_d = (_c = response.data) === null || _c === void 0 ? void 0 : _c.project) === null || _d === void 0 ? void 0 : _d.siteSpecPdfUrl) || '';
|
|
198
|
-
this.siteSpecPdfName = this.siteSpecPdfUrl ? await this._fetchSiteSpecPdfName(this.siteSpecPdfUrl) : '';
|
|
231
|
+
await this._fetchSiteSpecs();
|
|
199
232
|
this.updateContext();
|
|
200
233
|
}
|
|
201
|
-
//
|
|
202
|
-
async
|
|
203
|
-
var _a, _b
|
|
204
|
-
|
|
234
|
+
// 프로젝트에 등록된 공사 시방서 첨부 목록 조회 (여러 건)
|
|
235
|
+
async _fetchSiteSpecs() {
|
|
236
|
+
var _a, _b;
|
|
237
|
+
if (!this.projectId)
|
|
238
|
+
return;
|
|
205
239
|
try {
|
|
206
240
|
const response = await client.query({
|
|
207
241
|
query: gql `
|
|
208
242
|
query ($filters: [Filter!]) {
|
|
209
243
|
attachments(filters: $filters) {
|
|
210
244
|
items {
|
|
245
|
+
id
|
|
211
246
|
name
|
|
212
|
-
|
|
247
|
+
fullpath
|
|
213
248
|
}
|
|
214
249
|
}
|
|
215
250
|
}
|
|
@@ -217,80 +252,128 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
217
252
|
variables: {
|
|
218
253
|
filters: [
|
|
219
254
|
{ name: 'refBy', value: this.projectId, operator: 'eq' },
|
|
220
|
-
{ name: 'refType', value: 'Project', operator: 'eq' }
|
|
255
|
+
{ name: 'refType', value: 'Project', operator: 'eq' },
|
|
256
|
+
{ name: 'description', value: 'site-spec', operator: 'eq' }
|
|
221
257
|
]
|
|
222
|
-
}
|
|
258
|
+
},
|
|
259
|
+
fetchPolicy: 'no-cache'
|
|
223
260
|
});
|
|
224
261
|
const items = ((_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.attachments) === null || _b === void 0 ? void 0 : _b.items) || [];
|
|
225
|
-
|
|
262
|
+
// fullpath 는 /attachment/... 상대경로 → location.origin 을 붙여 전체 URL 생성
|
|
263
|
+
this.siteSpecFiles = items.map(a => ({ id: a.id, name: a.name, url: `${location.origin}${a.fullpath}` }));
|
|
226
264
|
}
|
|
227
|
-
catch (
|
|
228
|
-
|
|
265
|
+
catch (_c) {
|
|
266
|
+
this.siteSpecFiles = [];
|
|
229
267
|
}
|
|
230
268
|
}
|
|
231
|
-
//
|
|
232
|
-
async
|
|
233
|
-
var _a, _b
|
|
269
|
+
// 공사 시방서 업로드 (여러 개 동시) → 첨부 저장 후 매칭 엔진에 재등록
|
|
270
|
+
async _onUploadSiteSpecs(e) {
|
|
271
|
+
var _a, _b;
|
|
234
272
|
const input = e.target;
|
|
235
|
-
const
|
|
236
|
-
|
|
273
|
+
const files = Array.from(input.files || []);
|
|
274
|
+
input.value = '';
|
|
275
|
+
if (!files.length)
|
|
237
276
|
return;
|
|
238
|
-
// 허용 확장자: PDF, 한글(hwp
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
277
|
+
// 허용 확장자: PDF, 한글(hwp). MIME 은 브라우저/OS 마다 달라 확장자로 판정
|
|
278
|
+
// hwpx 는 매칭 엔진 파서가 지원하지 않으므로 받지 않는다
|
|
279
|
+
const invalid = files.filter(f => !['pdf', 'hwp'].includes(f.name.toLowerCase().split('.').pop() || ''));
|
|
280
|
+
if (invalid.length) {
|
|
281
|
+
notify({ message: 'PDF 또는 한글(hwp) 파일만 업로드할 수 있습니다.', level: 'warn' });
|
|
243
282
|
return;
|
|
244
283
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
284
|
+
this.siteSpecSyncing = true;
|
|
285
|
+
try {
|
|
286
|
+
const response = await client.mutate({
|
|
287
|
+
mutation: gql `
|
|
288
|
+
mutation ($attachments: [NewAttachment!]!) {
|
|
289
|
+
createAttachments(attachments: $attachments) {
|
|
290
|
+
id
|
|
291
|
+
}
|
|
252
292
|
}
|
|
293
|
+
`,
|
|
294
|
+
variables: {
|
|
295
|
+
attachments: files.map(file => ({
|
|
296
|
+
file,
|
|
297
|
+
refBy: this.projectId,
|
|
298
|
+
refType: 'Project',
|
|
299
|
+
description: 'site-spec'
|
|
300
|
+
}))
|
|
301
|
+
},
|
|
302
|
+
context: { hasUpload: true }
|
|
303
|
+
});
|
|
304
|
+
if (!((_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.createAttachments) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
305
|
+
notify({ message: '업로드에 실패하였습니다.', level: 'error' });
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
await this._fetchSiteSpecs();
|
|
309
|
+
await this._syncSiteSpecsToEngine();
|
|
310
|
+
notify({ message: '공사 시방서를 업로드하였습니다.' });
|
|
253
311
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
attachments: [{ file, refBy: this.projectId, refType: 'Project', description: 'site-spec' }]
|
|
257
|
-
},
|
|
258
|
-
context: { hasUpload: true }
|
|
259
|
-
});
|
|
260
|
-
input.value = '';
|
|
261
|
-
const attachment = (_c = (_b = response.data) === null || _b === void 0 ? void 0 : _b.createAttachments) === null || _c === void 0 ? void 0 : _c[0];
|
|
262
|
-
if (!attachment) {
|
|
263
|
-
notify({ message: '업로드에 실패하였습니다.', level: 'error' });
|
|
264
|
-
return;
|
|
312
|
+
finally {
|
|
313
|
+
this.siteSpecSyncing = false;
|
|
265
314
|
}
|
|
266
|
-
// fullpath 는 /attachment/... 형태의 상대경로 → location.origin 을 붙여 https 전체 URL 생성
|
|
267
|
-
this.siteSpecPdfUrl = `${location.origin}${attachment.fullpath}`;
|
|
268
|
-
this.siteSpecPdfName = attachment.name || file.name;
|
|
269
|
-
await this._saveSiteSpecPdfToProject();
|
|
270
|
-
notify({ message: '현장 시방서를 업로드하였습니다.' });
|
|
271
315
|
}
|
|
272
|
-
async
|
|
273
|
-
if (!confirm('
|
|
316
|
+
async _removeSiteSpec(file) {
|
|
317
|
+
if (!confirm(`'${file.name}' 을(를) 삭제하시겠습니까?`))
|
|
274
318
|
return;
|
|
275
|
-
this.
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
319
|
+
await this._deleteSiteSpecs([file.id], '공사 시방서를 삭제하였습니다.');
|
|
320
|
+
}
|
|
321
|
+
async _removeAllSiteSpecs() {
|
|
322
|
+
const count = this.siteSpecFiles.length;
|
|
323
|
+
if (!count || !confirm(`공사 시방서 ${count}건을 모두 삭제하시겠습니까?`))
|
|
324
|
+
return;
|
|
325
|
+
await this._deleteSiteSpecs(this.siteSpecFiles.map(f => f.id), `공사 시방서 ${count}건을 삭제하였습니다.`);
|
|
326
|
+
}
|
|
327
|
+
// 첨부 삭제 후 목록 갱신 + 매칭 엔진 재등록 (개별/전체 공통)
|
|
328
|
+
async _deleteSiteSpecs(ids, message) {
|
|
329
|
+
this.siteSpecSyncing = true;
|
|
330
|
+
try {
|
|
331
|
+
const mutation = gql `
|
|
332
|
+
mutation ($id: String!) {
|
|
333
|
+
deleteAttachment(id: $id)
|
|
334
|
+
}
|
|
335
|
+
`;
|
|
336
|
+
// 건수가 많을 수 있어 10건씩 나눠 병렬 처리 (한 번에 다 보내면 서버 부하가 커진다)
|
|
337
|
+
for (let i = 0; i < ids.length; i += 10) {
|
|
338
|
+
await Promise.all(ids.slice(i, i + 10).map(id => client.mutate({ mutation, variables: { id } })));
|
|
339
|
+
}
|
|
340
|
+
await this._fetchSiteSpecs();
|
|
341
|
+
await this._syncSiteSpecsToEngine();
|
|
342
|
+
notify({ message });
|
|
343
|
+
}
|
|
344
|
+
finally {
|
|
345
|
+
this.siteSpecSyncing = false;
|
|
346
|
+
}
|
|
279
347
|
}
|
|
280
|
-
//
|
|
281
|
-
async
|
|
282
|
-
|
|
348
|
+
// 수동 재등록 — 이 기능 도입 전에 올린 시방서나, 엔진 데이터가 초기화된 경우에 사용
|
|
349
|
+
async _onReregisterSiteSpecs() {
|
|
350
|
+
this.siteSpecSyncing = true;
|
|
351
|
+
try {
|
|
352
|
+
await this._syncSiteSpecsToEngine();
|
|
353
|
+
notify({ message: '공사 시방서를 매칭 엔진에 재등록하였습니다.' });
|
|
354
|
+
}
|
|
355
|
+
finally {
|
|
356
|
+
this.siteSpecSyncing = false;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
// 현재 첨부 목록 전체를 매칭 엔진에 재등록한다 (엔진에 개별 삭제가 없어 전체 재등록 방식)
|
|
360
|
+
async _syncSiteSpecsToEngine() {
|
|
361
|
+
var _a;
|
|
362
|
+
const response = await client.mutate({
|
|
283
363
|
mutation: gql `
|
|
284
|
-
mutation ($
|
|
285
|
-
|
|
286
|
-
id
|
|
287
|
-
}
|
|
364
|
+
mutation ($projectId: String!, $specFiles: [SiteSpecFileInput!]!) {
|
|
365
|
+
syncProjectSiteSpecs(projectId: $projectId, specFiles: $specFiles)
|
|
288
366
|
}
|
|
289
367
|
`,
|
|
290
368
|
variables: {
|
|
291
|
-
|
|
369
|
+
projectId: this.projectId,
|
|
370
|
+
specFiles: this.siteSpecFiles.map(f => ({ url: f.url, name: f.name }))
|
|
292
371
|
}
|
|
293
372
|
});
|
|
373
|
+
const siteItems = ((_a = response.data) === null || _a === void 0 ? void 0 : _a.syncProjectSiteSpecs) || 0;
|
|
374
|
+
if (this.siteSpecFiles.length && !siteItems) {
|
|
375
|
+
notify({ message: '시방서에서 조항을 추출하지 못했습니다. (스캔본 PDF 등)', level: 'warn' });
|
|
376
|
+
}
|
|
294
377
|
}
|
|
295
378
|
async _fetchConstructionTypes() {
|
|
296
379
|
var _a, _b;
|
|
@@ -374,7 +457,7 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
374
457
|
{
|
|
375
458
|
type: 'string',
|
|
376
459
|
name: 'siteSpecCriteria',
|
|
377
|
-
header: '
|
|
460
|
+
header: '공사 시방서 기준',
|
|
378
461
|
record: {
|
|
379
462
|
editable: false,
|
|
380
463
|
// 본문 앞 20글자만 요약 표시 (클릭 시 팝업으로 전체 본문 확인)
|
|
@@ -557,7 +640,7 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
557
640
|
const items = ((_f = (_e = response.data) === null || _e === void 0 ? void 0 : _e.constructionChecklistTemplateItems) === null || _f === void 0 ? void 0 : _f.items) || [];
|
|
558
641
|
this.templateItems = items;
|
|
559
642
|
// 왼쪽 그리드에 데이터 셋팅 (recommendation 포함)
|
|
560
|
-
// KCS
|
|
643
|
+
// KCS/공사 시방서 기준은 저장(등록/수정) 시 서버에서 매칭되어 채워진다.
|
|
561
644
|
this.leftGrist.data = {
|
|
562
645
|
records: items.map(item => ({
|
|
563
646
|
mainType: item.mainType || '',
|
|
@@ -687,7 +770,7 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
687
770
|
notify({ message: '이름을 입력해주세요.', level: 'warn' });
|
|
688
771
|
return;
|
|
689
772
|
}
|
|
690
|
-
// 그리드에서 아이템 추출 (KCS
|
|
773
|
+
// 그리드에서 아이템 추출 (KCS/공사 시방서 기준은 서버에서 매칭하여 채운다)
|
|
691
774
|
const records = ((_d = this.leftGrist.dirtyData) === null || _d === void 0 ? void 0 : _d.records) || [];
|
|
692
775
|
const items = records.map((row, idx) => ({
|
|
693
776
|
mainType: row.mainType || null,
|
|
@@ -699,8 +782,8 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
699
782
|
// 수정
|
|
700
783
|
const response = await client.mutate({
|
|
701
784
|
mutation: gql `
|
|
702
|
-
mutation ($id: String!, $name: String!, $items: [ProjectChecklistItemInput!]
|
|
703
|
-
updateProjectChecklist(id: $id, name: $name, items: $items
|
|
785
|
+
mutation ($id: String!, $name: String!, $items: [ProjectChecklistItemInput!]!) {
|
|
786
|
+
updateProjectChecklist(id: $id, name: $name, items: $items) {
|
|
704
787
|
id
|
|
705
788
|
}
|
|
706
789
|
}
|
|
@@ -708,12 +791,11 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
708
791
|
variables: {
|
|
709
792
|
id: this.selectedChecklistId,
|
|
710
793
|
name,
|
|
711
|
-
items
|
|
712
|
-
siteSpecPdfUrl: this.siteSpecPdfUrl || null
|
|
794
|
+
items
|
|
713
795
|
}
|
|
714
796
|
});
|
|
715
797
|
if (!response.errors) {
|
|
716
|
-
// 검사 기준(KCS
|
|
798
|
+
// 검사 기준(KCS/공사 시방서)은 백그라운드에서 매칭되어 잠시 후 반영됨
|
|
717
799
|
notify({ message: '수정되었습니다. 검사 기준은 잠시 후 반영됩니다.' });
|
|
718
800
|
this.rightGrist.fetch();
|
|
719
801
|
}
|
|
@@ -731,7 +813,6 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
731
813
|
$constructionDetailTypeId: String!
|
|
732
814
|
$name: String!
|
|
733
815
|
$items: [ProjectChecklistItemInput!]!
|
|
734
|
-
$siteSpecPdfUrl: String
|
|
735
816
|
) {
|
|
736
817
|
createProjectChecklist(
|
|
737
818
|
projectId: $projectId
|
|
@@ -739,7 +820,6 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
739
820
|
constructionDetailTypeId: $constructionDetailTypeId
|
|
740
821
|
name: $name
|
|
741
822
|
items: $items
|
|
742
|
-
siteSpecPdfUrl: $siteSpecPdfUrl
|
|
743
823
|
) {
|
|
744
824
|
id
|
|
745
825
|
}
|
|
@@ -750,12 +830,11 @@ let ProjectChecklistManagement = class ProjectChecklistManagement extends PageVi
|
|
|
750
830
|
constructionTypeId: ctId,
|
|
751
831
|
constructionDetailTypeId: cdtId,
|
|
752
832
|
name,
|
|
753
|
-
items
|
|
754
|
-
siteSpecPdfUrl: this.siteSpecPdfUrl || null
|
|
833
|
+
items
|
|
755
834
|
}
|
|
756
835
|
});
|
|
757
836
|
if (!response.errors) {
|
|
758
|
-
// 검사 기준(KCS
|
|
837
|
+
// 검사 기준(KCS/공사 시방서)은 백그라운드에서 매칭되어 잠시 후 반영됨
|
|
759
838
|
notify({ message: '등록되었습니다. 검사 기준은 잠시 후 반영됩니다.' });
|
|
760
839
|
// 오른쪽 그리드 새로고침 + 왼쪽 초기화
|
|
761
840
|
await this.rightGrist.fetch();
|
|
@@ -908,11 +987,14 @@ ProjectChecklistManagement.styles = [
|
|
|
908
987
|
|
|
909
988
|
h2 {
|
|
910
989
|
display: flex;
|
|
990
|
+
align-items: center;
|
|
911
991
|
gap: 7px;
|
|
912
992
|
flex: 1;
|
|
913
993
|
margin-bottom: 8px;
|
|
914
994
|
color: #3f71a0;
|
|
915
995
|
font-size: 18px;
|
|
996
|
+
/* 우측 버튼이 늘어나도 제목이 세로로 쪼개지지 않도록 */
|
|
997
|
+
white-space: nowrap;
|
|
916
998
|
|
|
917
999
|
md-icon[back] {
|
|
918
1000
|
background: linear-gradient(135deg, #3f71a0 0%, #5a8cc7 100%);
|
|
@@ -936,25 +1018,79 @@ ProjectChecklistManagement.styles = [
|
|
|
936
1018
|
display: flex;
|
|
937
1019
|
align-items: center;
|
|
938
1020
|
justify-content: end;
|
|
939
|
-
flex:
|
|
1021
|
+
flex: none;
|
|
940
1022
|
padding-top: 8px;
|
|
941
1023
|
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
1024
|
+
/* 시방서가 수십 건이어도 헤더 폭을 차지하지 않도록 개수 배지 + 펼침 목록으로 표시 */
|
|
1025
|
+
div[site-spec-box] {
|
|
1026
|
+
position: relative;
|
|
1027
|
+
flex-shrink: 0;
|
|
946
1028
|
margin: 0 6px;
|
|
947
|
-
padding: 4px 8px;
|
|
948
|
-
font-size: 13px;
|
|
949
|
-
color: #3f71a0;
|
|
950
|
-
background-color: #eaf2fb;
|
|
951
|
-
border-radius: 4px;
|
|
952
|
-
max-width: 220px;
|
|
953
1029
|
|
|
954
|
-
span[
|
|
955
|
-
|
|
956
|
-
|
|
1030
|
+
span[site-spec-count] {
|
|
1031
|
+
display: inline-flex;
|
|
1032
|
+
align-items: center;
|
|
1033
|
+
gap: 2px;
|
|
1034
|
+
padding: 4px 8px;
|
|
1035
|
+
font-size: 13px;
|
|
957
1036
|
white-space: nowrap;
|
|
1037
|
+
color: #3f71a0;
|
|
1038
|
+
background-color: #eaf2fb;
|
|
1039
|
+
border-radius: 4px;
|
|
1040
|
+
cursor: pointer;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
div[site-spec-list] {
|
|
1044
|
+
position: absolute;
|
|
1045
|
+
top: calc(100% + 4px);
|
|
1046
|
+
right: 0;
|
|
1047
|
+
z-index: 10;
|
|
1048
|
+
width: 320px;
|
|
1049
|
+
max-height: 320px;
|
|
1050
|
+
overflow-y: auto;
|
|
1051
|
+
padding: 4px;
|
|
1052
|
+
background-color: #fff;
|
|
1053
|
+
border: 1px solid #ddd;
|
|
1054
|
+
border-radius: 6px;
|
|
1055
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
1056
|
+
|
|
1057
|
+
div[site-spec-tools] {
|
|
1058
|
+
display: flex;
|
|
1059
|
+
justify-content: flex-end;
|
|
1060
|
+
padding: 2px 6px 6px;
|
|
1061
|
+
border-bottom: 1px solid #eee;
|
|
1062
|
+
margin-bottom: 4px;
|
|
1063
|
+
|
|
1064
|
+
span[delete-all] {
|
|
1065
|
+
display: inline-flex;
|
|
1066
|
+
align-items: center;
|
|
1067
|
+
gap: 2px;
|
|
1068
|
+
font-size: 12px;
|
|
1069
|
+
color: #c0392b;
|
|
1070
|
+
cursor: pointer;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
div[site-spec-row] {
|
|
1075
|
+
display: flex;
|
|
1076
|
+
align-items: center;
|
|
1077
|
+
gap: 4px;
|
|
1078
|
+
padding: 5px 6px;
|
|
1079
|
+
font-size: 13px;
|
|
1080
|
+
color: #3f71a0;
|
|
1081
|
+
border-radius: 4px;
|
|
1082
|
+
|
|
1083
|
+
&:hover {
|
|
1084
|
+
background-color: #f4f8fd;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
span[filename] {
|
|
1088
|
+
flex: 1;
|
|
1089
|
+
overflow: hidden;
|
|
1090
|
+
text-overflow: ellipsis;
|
|
1091
|
+
white-space: nowrap;
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
958
1094
|
}
|
|
959
1095
|
|
|
960
1096
|
md-icon {
|
|
@@ -1128,12 +1264,16 @@ __decorate([
|
|
|
1128
1264
|
], ProjectChecklistManagement.prototype, "selectedChecklistId", void 0);
|
|
1129
1265
|
__decorate([
|
|
1130
1266
|
state(),
|
|
1131
|
-
__metadata("design:type",
|
|
1132
|
-
], ProjectChecklistManagement.prototype, "
|
|
1267
|
+
__metadata("design:type", Array)
|
|
1268
|
+
], ProjectChecklistManagement.prototype, "siteSpecFiles", void 0);
|
|
1133
1269
|
__decorate([
|
|
1134
1270
|
state(),
|
|
1135
|
-
__metadata("design:type",
|
|
1136
|
-
], ProjectChecklistManagement.prototype, "
|
|
1271
|
+
__metadata("design:type", Boolean)
|
|
1272
|
+
], ProjectChecklistManagement.prototype, "siteSpecSyncing", void 0);
|
|
1273
|
+
__decorate([
|
|
1274
|
+
state(),
|
|
1275
|
+
__metadata("design:type", Boolean)
|
|
1276
|
+
], ProjectChecklistManagement.prototype, "siteSpecListOpen", void 0);
|
|
1137
1277
|
__decorate([
|
|
1138
1278
|
state(),
|
|
1139
1279
|
__metadata("design:type", Object)
|