@dssp/supervision 1.0.0-alpha.76 → 1.0.0-alpha.77

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 (58) hide show
  1. package/dist-client/pages/building-inspection/building-inspection-list.js +2 -2
  2. package/dist-client/pages/building-inspection/building-inspection-list.js.map +1 -1
  3. package/dist-client/pages/building-inspection/building-inspection-management.d.ts +8 -0
  4. package/dist-client/pages/building-inspection/building-inspection-management.js +297 -45
  5. package/dist-client/pages/building-inspection/building-inspection-management.js.map +1 -1
  6. package/dist-client/pages/building-inspection/component/field-document/field-document-constants.d.ts +18 -0
  7. package/dist-client/pages/building-inspection/component/field-document/field-document-constants.js +630 -0
  8. package/dist-client/pages/building-inspection/component/field-document/field-document-constants.js.map +1 -0
  9. package/dist-client/pages/building-inspection/component/field-document/field-document-detail-popup.d.ts +10 -0
  10. package/dist-client/pages/building-inspection/component/field-document/field-document-detail-popup.js +219 -0
  11. package/dist-client/pages/building-inspection/component/field-document/field-document-detail-popup.js.map +1 -0
  12. package/dist-client/pages/building-inspection/component/field-document/field-document-list-panel.d.ts +22 -0
  13. package/dist-client/pages/building-inspection/component/field-document/field-document-list-panel.js +472 -0
  14. package/dist-client/pages/building-inspection/component/field-document/field-document-list-panel.js.map +1 -0
  15. package/dist-client/pages/building-inspection/component/field-document/field-document-popup.d.ts +38 -0
  16. package/dist-client/pages/building-inspection/component/field-document/field-document-popup.js +651 -0
  17. package/dist-client/pages/building-inspection/component/field-document/field-document-popup.js.map +1 -0
  18. package/dist-client/pages/building-inspection/component/inspection-event-provider.d.ts +3 -2
  19. package/dist-client/pages/building-inspection/component/inspection-event-provider.js +129 -34
  20. package/dist-client/pages/building-inspection/component/inspection-event-provider.js.map +1 -1
  21. package/dist-client/pages/checklist-template/construction-checklist-template-list.js +9 -14
  22. package/dist-client/pages/checklist-template/construction-checklist-template-list.js.map +1 -1
  23. package/dist-client/pages/project-checklist/project-checklist-management.d.ts +2 -0
  24. package/dist-client/pages/project-checklist/project-checklist-management.js +24 -2
  25. package/dist-client/pages/project-checklist/project-checklist-management.js.map +1 -1
  26. package/dist-client/route.d.ts +1 -1
  27. package/dist-client/tsconfig.tsbuildinfo +1 -1
  28. package/dist-server/service/building-inspection/building-inspection-query.d.ts +5 -1
  29. package/dist-server/service/building-inspection/building-inspection-query.js +114 -0
  30. package/dist-server/service/building-inspection/building-inspection-query.js.map +1 -1
  31. package/dist-server/service/building-inspection/building-inspection-type.d.ts +4 -0
  32. package/dist-server/service/building-inspection/building-inspection-type.js +15 -1
  33. package/dist-server/service/building-inspection/building-inspection-type.js.map +1 -1
  34. package/dist-server/service/building-inspection/index.d.ts +1 -1
  35. package/dist-server/service/field-document/field-document-auto-file.d.ts +21 -0
  36. package/dist-server/service/field-document/field-document-auto-file.js +47 -0
  37. package/dist-server/service/field-document/field-document-auto-file.js.map +1 -0
  38. package/dist-server/service/field-document/field-document-mutation.d.ts +9 -0
  39. package/dist-server/service/field-document/field-document-mutation.js +136 -0
  40. package/dist-server/service/field-document/field-document-mutation.js.map +1 -0
  41. package/dist-server/service/field-document/field-document-query.d.ts +13 -0
  42. package/dist-server/service/field-document/field-document-query.js +107 -0
  43. package/dist-server/service/field-document/field-document-query.js.map +1 -0
  44. package/dist-server/service/field-document/field-document-summary-service.d.ts +2 -0
  45. package/dist-server/service/field-document/field-document-summary-service.js +55 -0
  46. package/dist-server/service/field-document/field-document-summary-service.js.map +1 -0
  47. package/dist-server/service/field-document/field-document-type.d.ts +22 -0
  48. package/dist-server/service/field-document/field-document-type.js +83 -0
  49. package/dist-server/service/field-document/field-document-type.js.map +1 -0
  50. package/dist-server/service/field-document/field-document.d.ts +28 -0
  51. package/dist-server/service/field-document/field-document.js +123 -0
  52. package/dist-server/service/field-document/field-document.js.map +1 -0
  53. package/dist-server/service/field-document/index.d.ts +5 -0
  54. package/dist-server/service/field-document/index.js +9 -0
  55. package/dist-server/service/field-document/index.js.map +1 -0
  56. package/dist-server/service/index.d.ts +1 -1
  57. package/dist-server/tsconfig.tsbuildinfo +1 -1
  58. package/package.json +2 -2
@@ -0,0 +1,472 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import '@material/web/icon/icon.js';
3
+ import { ScrollbarStyles } from '@operato/styles';
4
+ import { css, html, LitElement } from 'lit';
5
+ import { customElement, property, state } from 'lit/decorators.js';
6
+ let FieldDocumentListPanel = class FieldDocumentListPanel extends LitElement {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.projectId = '';
10
+ this.code = '';
11
+ this.folderName = '';
12
+ this.documents = [];
13
+ this.selectedIds = new Set();
14
+ this.isDragOver = false;
15
+ this.selectedDoc = null;
16
+ }
17
+ render() {
18
+ return html `
19
+ <div panel-header>
20
+ <h3>문서 목록${this.folderName ? ` - ${this.folderName}` : ''}</h3>
21
+ <span doc-count>${this.documents.length}건</span>
22
+ </div>
23
+
24
+ ${this.code
25
+ ? html `
26
+ <div table-header>
27
+ <div>
28
+ <input
29
+ type="checkbox"
30
+ @change=${this._toggleAll}
31
+ .checked=${this.selectedIds.size > 0 && this.selectedIds.size === this.documents.length}
32
+ />
33
+ </div>
34
+ <div>문서번호</div>
35
+ <div style="justify-content:flex-start; padding-left:8px;">제 목</div>
36
+ <div>등록부서</div>
37
+ <div>등록자</div>
38
+ <div>자료분류</div>
39
+ <div>등록일자</div>
40
+ </div>
41
+
42
+ <div
43
+ doc-list
44
+ @dragover=${this._onListDragOver}
45
+ @dragleave=${this._onListDragLeave}
46
+ @drop=${this._onListDrop}
47
+ >
48
+ ${this.isDragOver ? html `<div drop-zone><span>여기에 파일을 놓으세요</span></div>` : ''}
49
+
50
+ ${this.documents.length > 0
51
+ ? this.documents.map((doc, idx) => {
52
+ var _a;
53
+ return html `
54
+ <div
55
+ doc-item
56
+ draggable="true"
57
+ ?selected=${this.selectedIds.has(doc.id)}
58
+ @dragstart=${(e) => this._onDocDragStart(e, doc)}
59
+ @click=${() => this._selectDoc(doc)}
60
+ >
61
+ <div>
62
+ <input
63
+ type="checkbox"
64
+ .checked=${this.selectedIds.has(doc.id)}
65
+ @change=${(e) => this._toggleDoc(e, doc.id)}
66
+ @click=${(e) => e.stopPropagation()}
67
+ />
68
+ </div>
69
+ <div>${doc.code}${String(idx + 1).padStart(2, '0')}</div>
70
+ <div name-cell>
71
+ ${doc.isFavorite ? html `<md-icon favorite>star</md-icon>` : ''}
72
+ <span>${doc.name}</span>
73
+ </div>
74
+ <div></div>
75
+ <div>${((_a = doc.creator) === null || _a === void 0 ? void 0 : _a.name) || ''}</div>
76
+ <div></div>
77
+ <div>${this._formatDate(doc.createdAt)}</div>
78
+ </div>
79
+ `;
80
+ })
81
+ : html `
82
+ <div empty-state>
83
+ <md-icon>folder_open</md-icon>
84
+ <div>등록된 문서가 없습니다.</div>
85
+ <div style="font-size:12px; margin-top:4px;">파일을 드래그하여 업로드하세요.</div>
86
+ </div>
87
+ `}
88
+ </div>
89
+
90
+ ${this.selectedDoc
91
+ ? html `
92
+ <div doc-detail>
93
+ <div detail-content>
94
+ <md-icon file-icon>description</md-icon>
95
+ <div detail-info>
96
+ <div file-name>${this.selectedDoc.name}</div>
97
+ <div file-meta>
98
+ 수정한 날짜: ${this._formatDateTime(this.selectedDoc.createdAt)}
99
+ </div>
100
+ ${this.selectedDoc.aiSummary
101
+ ? html `
102
+ <div ai-summary>
103
+ <md-icon>auto_awesome</md-icon>
104
+ <div>
105
+ <strong>AI 브리핑</strong><br />
106
+ ${this.selectedDoc.aiSummary}
107
+ </div>
108
+ </div>
109
+ `
110
+ : this.selectedDoc.aiSummaryStatus === '10'
111
+ ? html `
112
+ <div ai-badge status="10">
113
+ <md-icon style="--md-icon-size:14px;">hourglass_top</md-icon>
114
+ AI 요약 생성 중...
115
+ </div>
116
+ `
117
+ : ''}
118
+ </div>
119
+ </div>
120
+ </div>
121
+ `
122
+ : ''}
123
+ `
124
+ : html `
125
+ <div empty-state>
126
+ <md-icon>folder</md-icon>
127
+ <div>소분류 폴더를 선택해주세요.</div>
128
+ </div>
129
+ `}
130
+ `;
131
+ }
132
+ _selectDoc(doc) {
133
+ this.selectedDoc = doc;
134
+ this.dispatchEvent(new CustomEvent('open-detail', { detail: doc }));
135
+ }
136
+ _toggleDoc(e, id) {
137
+ const checked = e.target.checked;
138
+ const newSet = new Set(this.selectedIds);
139
+ if (checked) {
140
+ newSet.add(id);
141
+ }
142
+ else {
143
+ newSet.delete(id);
144
+ }
145
+ this.selectedIds = newSet;
146
+ this.dispatchEvent(new CustomEvent('document-selected', { detail: newSet }));
147
+ }
148
+ _toggleAll(e) {
149
+ const checked = e.target.checked;
150
+ if (checked) {
151
+ this.selectedIds = new Set(this.documents.map(d => d.id));
152
+ }
153
+ else {
154
+ this.selectedIds = new Set();
155
+ }
156
+ this.dispatchEvent(new CustomEvent('document-selected', { detail: this.selectedIds }));
157
+ }
158
+ /* Drag & Drop: 데스크톱 파일 업로드 */
159
+ _onListDragOver(e) {
160
+ var _a;
161
+ const types = ((_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.types) || [];
162
+ if (types.includes('Files')) {
163
+ e.preventDefault();
164
+ this.isDragOver = true;
165
+ }
166
+ }
167
+ _onListDragLeave() {
168
+ this.isDragOver = false;
169
+ }
170
+ _onListDrop(e) {
171
+ var _a;
172
+ e.preventDefault();
173
+ this.isDragOver = false;
174
+ const files = Array.from(((_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) || []);
175
+ if (files.length > 0) {
176
+ this.dispatchEvent(new CustomEvent('documents-changed', { detail: { files } }));
177
+ }
178
+ }
179
+ /* Drag: 문서 이동용 */
180
+ _onDocDragStart(e, doc) {
181
+ var _a;
182
+ const ids = this.selectedIds.has(doc.id) ? Array.from(this.selectedIds) : [doc.id];
183
+ (_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.setData('application/x-field-document-ids', JSON.stringify(ids));
184
+ e.dataTransfer.effectAllowed = 'move';
185
+ }
186
+ _formatDate(date) {
187
+ if (!date)
188
+ return '';
189
+ try {
190
+ const d = new Date(date);
191
+ return new Intl.DateTimeFormat('ko-KR', {
192
+ timeZone: 'Asia/Seoul',
193
+ year: 'numeric',
194
+ month: '2-digit',
195
+ day: '2-digit'
196
+ }).format(d);
197
+ }
198
+ catch (_a) {
199
+ return '';
200
+ }
201
+ }
202
+ _formatDateTime(date) {
203
+ if (!date)
204
+ return '';
205
+ try {
206
+ const d = new Date(date);
207
+ return new Intl.DateTimeFormat('ko-KR', {
208
+ timeZone: 'Asia/Seoul',
209
+ year: 'numeric',
210
+ month: '2-digit',
211
+ day: '2-digit',
212
+ hour: '2-digit',
213
+ minute: '2-digit',
214
+ hour12: true
215
+ }).format(d);
216
+ }
217
+ catch (_a) {
218
+ return '';
219
+ }
220
+ }
221
+ };
222
+ FieldDocumentListPanel.styles = [
223
+ ScrollbarStyles,
224
+ css `
225
+ :host {
226
+ display: flex;
227
+ flex-direction: column;
228
+ overflow: hidden;
229
+ }
230
+
231
+ div[panel-header] {
232
+ display: flex;
233
+ align-items: center;
234
+ padding: 10px 16px;
235
+ background: #fafafa;
236
+ border-bottom: 1px solid #e0e0e0;
237
+
238
+ h3 {
239
+ margin: 0;
240
+ font-size: 14px;
241
+ color: #333;
242
+ flex: 1;
243
+ }
244
+
245
+ span[doc-count] {
246
+ font-size: 12px;
247
+ color: #999;
248
+ }
249
+ }
250
+
251
+ div[table-header] {
252
+ display: grid;
253
+ grid-template-columns: 40px 80px 1fr 100px 80px 80px 100px;
254
+ padding: 8px 16px;
255
+ background: #f0e6e6;
256
+ font-size: 12px;
257
+ font-weight: bold;
258
+ color: #666;
259
+ border-bottom: 1px solid #ddd;
260
+
261
+ & > div {
262
+ display: flex;
263
+ align-items: center;
264
+ justify-content: center;
265
+ }
266
+ }
267
+
268
+ div[doc-list] {
269
+ flex: 1;
270
+ overflow-y: auto;
271
+ position: relative;
272
+ }
273
+
274
+ div[doc-item] {
275
+ display: grid;
276
+ grid-template-columns: 40px 80px 1fr 100px 80px 80px 100px;
277
+ padding: 8px 16px;
278
+ border-bottom: 1px solid #f0f0f0;
279
+ font-size: 13px;
280
+ cursor: pointer;
281
+ transition: background-color 0.15s;
282
+ align-items: center;
283
+
284
+ &:hover {
285
+ background-color: #f5f5f5;
286
+ }
287
+
288
+ & > div {
289
+ display: flex;
290
+ align-items: center;
291
+ justify-content: center;
292
+ overflow: hidden;
293
+ text-overflow: ellipsis;
294
+ white-space: nowrap;
295
+ }
296
+
297
+ div[name-cell] {
298
+ justify-content: flex-start;
299
+ gap: 6px;
300
+
301
+ md-icon[favorite] {
302
+ --md-icon-size: 16px;
303
+ color: #ffc107;
304
+ }
305
+
306
+ span {
307
+ overflow: hidden;
308
+ text-overflow: ellipsis;
309
+ }
310
+ }
311
+
312
+ input[type='checkbox'] {
313
+ cursor: pointer;
314
+ }
315
+ }
316
+
317
+ div[doc-item][selected] {
318
+ background-color: #e3f2fd;
319
+ }
320
+
321
+ div[doc-item][draggable='true'] {
322
+ cursor: grab;
323
+
324
+ &:active {
325
+ cursor: grabbing;
326
+ }
327
+ }
328
+
329
+ div[drop-zone] {
330
+ position: absolute;
331
+ inset: 0;
332
+ display: flex;
333
+ align-items: center;
334
+ justify-content: center;
335
+ background: rgba(33, 150, 243, 0.08);
336
+ border: 3px dashed #1976d2;
337
+ border-radius: 8px;
338
+ z-index: 10;
339
+ pointer-events: none;
340
+
341
+ span {
342
+ font-size: 16px;
343
+ color: #1976d2;
344
+ font-weight: bold;
345
+ }
346
+ }
347
+
348
+ div[empty-state] {
349
+ display: flex;
350
+ flex-direction: column;
351
+ align-items: center;
352
+ justify-content: center;
353
+ padding: 60px 20px;
354
+ color: #999;
355
+ flex: 1;
356
+
357
+ md-icon {
358
+ --md-icon-size: 48px;
359
+ color: #ddd;
360
+ margin-bottom: 12px;
361
+ }
362
+ }
363
+
364
+ div[ai-badge] {
365
+ display: inline-flex;
366
+ align-items: center;
367
+ gap: 3px;
368
+ font-size: 11px;
369
+ padding: 2px 6px;
370
+ border-radius: 4px;
371
+ }
372
+
373
+ div[ai-badge][status='20'] {
374
+ background: #e8f5e9;
375
+ color: #2e7d32;
376
+ }
377
+ div[ai-badge][status='10'] {
378
+ background: #fff3e0;
379
+ color: #ef6c00;
380
+ }
381
+ div[ai-badge][status='30'] {
382
+ background: #fbe9e7;
383
+ color: #c62828;
384
+ }
385
+
386
+ div[doc-detail] {
387
+ padding: 12px 16px;
388
+ background: #fafafa;
389
+ border-top: 1px solid #e0e0e0;
390
+
391
+ div[detail-content] {
392
+ display: flex;
393
+ align-items: flex-start;
394
+ gap: 12px;
395
+
396
+ md-icon[file-icon] {
397
+ --md-icon-size: 36px;
398
+ color: #0595e5;
399
+ background: #e3f2fd;
400
+ padding: 8px;
401
+ border-radius: 8px;
402
+ }
403
+
404
+ div[detail-info] {
405
+ flex: 1;
406
+
407
+ div[file-name] {
408
+ font-weight: bold;
409
+ font-size: 14px;
410
+ margin-bottom: 4px;
411
+ }
412
+
413
+ div[file-meta] {
414
+ font-size: 12px;
415
+ color: #666;
416
+ margin-bottom: 8px;
417
+ }
418
+
419
+ div[ai-summary] {
420
+ display: flex;
421
+ align-items: flex-start;
422
+ gap: 6px;
423
+ padding: 8px 12px;
424
+ background: #e8f5e9;
425
+ border-radius: 6px;
426
+ font-size: 12px;
427
+ color: #333;
428
+
429
+ md-icon {
430
+ --md-icon-size: 18px;
431
+ color: #4caf50;
432
+ flex-shrink: 0;
433
+ }
434
+ }
435
+ }
436
+ }
437
+ }
438
+ `
439
+ ];
440
+ __decorate([
441
+ property({ type: String }),
442
+ __metadata("design:type", String)
443
+ ], FieldDocumentListPanel.prototype, "projectId", void 0);
444
+ __decorate([
445
+ property({ type: String }),
446
+ __metadata("design:type", String)
447
+ ], FieldDocumentListPanel.prototype, "code", void 0);
448
+ __decorate([
449
+ property({ type: String }),
450
+ __metadata("design:type", String)
451
+ ], FieldDocumentListPanel.prototype, "folderName", void 0);
452
+ __decorate([
453
+ property({ type: Array }),
454
+ __metadata("design:type", Array)
455
+ ], FieldDocumentListPanel.prototype, "documents", void 0);
456
+ __decorate([
457
+ state(),
458
+ __metadata("design:type", Set)
459
+ ], FieldDocumentListPanel.prototype, "selectedIds", void 0);
460
+ __decorate([
461
+ state(),
462
+ __metadata("design:type", Boolean)
463
+ ], FieldDocumentListPanel.prototype, "isDragOver", void 0);
464
+ __decorate([
465
+ state(),
466
+ __metadata("design:type", Object)
467
+ ], FieldDocumentListPanel.prototype, "selectedDoc", void 0);
468
+ FieldDocumentListPanel = __decorate([
469
+ customElement('field-document-list-panel')
470
+ ], FieldDocumentListPanel);
471
+ export { FieldDocumentListPanel };
472
+ //# sourceMappingURL=field-document-list-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-document-list-panel.js","sourceRoot":"","sources":["../../../../../client/pages/building-inspection/component/field-document/field-document-list-panel.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { ScrollbarStyles } from '@operato/styles'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\n@customElement('field-document-list-panel')\nexport class FieldDocumentListPanel extends LitElement {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n div[panel-header] {\n display: flex;\n align-items: center;\n padding: 10px 16px;\n background: #fafafa;\n border-bottom: 1px solid #e0e0e0;\n\n h3 {\n margin: 0;\n font-size: 14px;\n color: #333;\n flex: 1;\n }\n\n span[doc-count] {\n font-size: 12px;\n color: #999;\n }\n }\n\n div[table-header] {\n display: grid;\n grid-template-columns: 40px 80px 1fr 100px 80px 80px 100px;\n padding: 8px 16px;\n background: #f0e6e6;\n font-size: 12px;\n font-weight: bold;\n color: #666;\n border-bottom: 1px solid #ddd;\n\n & > div {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n }\n\n div[doc-list] {\n flex: 1;\n overflow-y: auto;\n position: relative;\n }\n\n div[doc-item] {\n display: grid;\n grid-template-columns: 40px 80px 1fr 100px 80px 80px 100px;\n padding: 8px 16px;\n border-bottom: 1px solid #f0f0f0;\n font-size: 13px;\n cursor: pointer;\n transition: background-color 0.15s;\n align-items: center;\n\n &:hover {\n background-color: #f5f5f5;\n }\n\n & > div {\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n div[name-cell] {\n justify-content: flex-start;\n gap: 6px;\n\n md-icon[favorite] {\n --md-icon-size: 16px;\n color: #ffc107;\n }\n\n span {\n overflow: hidden;\n text-overflow: ellipsis;\n }\n }\n\n input[type='checkbox'] {\n cursor: pointer;\n }\n }\n\n div[doc-item][selected] {\n background-color: #e3f2fd;\n }\n\n div[doc-item][draggable='true'] {\n cursor: grab;\n\n &:active {\n cursor: grabbing;\n }\n }\n\n div[drop-zone] {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(33, 150, 243, 0.08);\n border: 3px dashed #1976d2;\n border-radius: 8px;\n z-index: 10;\n pointer-events: none;\n\n span {\n font-size: 16px;\n color: #1976d2;\n font-weight: bold;\n }\n }\n\n div[empty-state] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: #999;\n flex: 1;\n\n md-icon {\n --md-icon-size: 48px;\n color: #ddd;\n margin-bottom: 12px;\n }\n }\n\n div[ai-badge] {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n font-size: 11px;\n padding: 2px 6px;\n border-radius: 4px;\n }\n\n div[ai-badge][status='20'] {\n background: #e8f5e9;\n color: #2e7d32;\n }\n div[ai-badge][status='10'] {\n background: #fff3e0;\n color: #ef6c00;\n }\n div[ai-badge][status='30'] {\n background: #fbe9e7;\n color: #c62828;\n }\n\n div[doc-detail] {\n padding: 12px 16px;\n background: #fafafa;\n border-top: 1px solid #e0e0e0;\n\n div[detail-content] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n\n md-icon[file-icon] {\n --md-icon-size: 36px;\n color: #0595e5;\n background: #e3f2fd;\n padding: 8px;\n border-radius: 8px;\n }\n\n div[detail-info] {\n flex: 1;\n\n div[file-name] {\n font-weight: bold;\n font-size: 14px;\n margin-bottom: 4px;\n }\n\n div[file-meta] {\n font-size: 12px;\n color: #666;\n margin-bottom: 8px;\n }\n\n div[ai-summary] {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n padding: 8px 12px;\n background: #e8f5e9;\n border-radius: 6px;\n font-size: 12px;\n color: #333;\n\n md-icon {\n --md-icon-size: 18px;\n color: #4caf50;\n flex-shrink: 0;\n }\n }\n }\n }\n }\n `\n ]\n\n @property({ type: String }) projectId: string = ''\n @property({ type: String }) code: string = ''\n @property({ type: String }) folderName: string = ''\n @property({ type: Array }) documents: any[] = []\n\n @state() private selectedIds: Set<string> = new Set()\n @state() private isDragOver: boolean = false\n @state() private selectedDoc: any = null\n\n render() {\n return html`\n <div panel-header>\n <h3>문서 목록${this.folderName ? ` - ${this.folderName}` : ''}</h3>\n <span doc-count>${this.documents.length}건</span>\n </div>\n\n ${this.code\n ? html`\n <div table-header>\n <div>\n <input\n type=\"checkbox\"\n @change=${this._toggleAll}\n .checked=${this.selectedIds.size > 0 && this.selectedIds.size === this.documents.length}\n />\n </div>\n <div>문서번호</div>\n <div style=\"justify-content:flex-start; padding-left:8px;\">제 목</div>\n <div>등록부서</div>\n <div>등록자</div>\n <div>자료분류</div>\n <div>등록일자</div>\n </div>\n\n <div\n doc-list\n @dragover=${this._onListDragOver}\n @dragleave=${this._onListDragLeave}\n @drop=${this._onListDrop}\n >\n ${this.isDragOver ? html`<div drop-zone><span>여기에 파일을 놓으세요</span></div>` : ''}\n\n ${this.documents.length > 0\n ? this.documents.map(\n (doc, idx) => html`\n <div\n doc-item\n draggable=\"true\"\n ?selected=${this.selectedIds.has(doc.id)}\n @dragstart=${(e: DragEvent) => this._onDocDragStart(e, doc)}\n @click=${() => this._selectDoc(doc)}\n >\n <div>\n <input\n type=\"checkbox\"\n .checked=${this.selectedIds.has(doc.id)}\n @change=${(e: Event) => this._toggleDoc(e, doc.id)}\n @click=${(e: Event) => e.stopPropagation()}\n />\n </div>\n <div>${doc.code}${String(idx + 1).padStart(2, '0')}</div>\n <div name-cell>\n ${doc.isFavorite ? html`<md-icon favorite>star</md-icon>` : ''}\n <span>${doc.name}</span>\n </div>\n <div></div>\n <div>${doc.creator?.name || ''}</div>\n <div></div>\n <div>${this._formatDate(doc.createdAt)}</div>\n </div>\n `\n )\n : html`\n <div empty-state>\n <md-icon>folder_open</md-icon>\n <div>등록된 문서가 없습니다.</div>\n <div style=\"font-size:12px; margin-top:4px;\">파일을 드래그하여 업로드하세요.</div>\n </div>\n `}\n </div>\n\n ${this.selectedDoc\n ? html`\n <div doc-detail>\n <div detail-content>\n <md-icon file-icon>description</md-icon>\n <div detail-info>\n <div file-name>${this.selectedDoc.name}</div>\n <div file-meta>\n 수정한 날짜: ${this._formatDateTime(this.selectedDoc.createdAt)}\n </div>\n ${this.selectedDoc.aiSummary\n ? html`\n <div ai-summary>\n <md-icon>auto_awesome</md-icon>\n <div>\n <strong>AI 브리핑</strong><br />\n ${this.selectedDoc.aiSummary}\n </div>\n </div>\n `\n : this.selectedDoc.aiSummaryStatus === '10'\n ? html`\n <div ai-badge status=\"10\">\n <md-icon style=\"--md-icon-size:14px;\">hourglass_top</md-icon>\n AI 요약 생성 중...\n </div>\n `\n : ''}\n </div>\n </div>\n </div>\n `\n : ''}\n `\n : html`\n <div empty-state>\n <md-icon>folder</md-icon>\n <div>소분류 폴더를 선택해주세요.</div>\n </div>\n `}\n `\n }\n\n private _selectDoc(doc: any) {\n this.selectedDoc = doc\n this.dispatchEvent(new CustomEvent('open-detail', { detail: doc }))\n }\n\n private _toggleDoc(e: Event, id: string) {\n const checked = (e.target as HTMLInputElement).checked\n const newSet = new Set(this.selectedIds)\n if (checked) {\n newSet.add(id)\n } else {\n newSet.delete(id)\n }\n this.selectedIds = newSet\n this.dispatchEvent(new CustomEvent('document-selected', { detail: newSet }))\n }\n\n private _toggleAll(e: Event) {\n const checked = (e.target as HTMLInputElement).checked\n if (checked) {\n this.selectedIds = new Set(this.documents.map(d => d.id))\n } else {\n this.selectedIds = new Set()\n }\n this.dispatchEvent(new CustomEvent('document-selected', { detail: this.selectedIds }))\n }\n\n /* Drag & Drop: 데스크톱 파일 업로드 */\n private _onListDragOver(e: DragEvent) {\n const types = e.dataTransfer?.types || []\n if (types.includes('Files')) {\n e.preventDefault()\n this.isDragOver = true\n }\n }\n\n private _onListDragLeave() {\n this.isDragOver = false\n }\n\n private _onListDrop(e: DragEvent) {\n e.preventDefault()\n this.isDragOver = false\n\n const files = Array.from(e.dataTransfer?.files || [])\n if (files.length > 0) {\n this.dispatchEvent(new CustomEvent('documents-changed', { detail: { files } }))\n }\n }\n\n /* Drag: 문서 이동용 */\n private _onDocDragStart(e: DragEvent, doc: any) {\n const ids = this.selectedIds.has(doc.id) ? Array.from(this.selectedIds) : [doc.id]\n e.dataTransfer?.setData('application/x-field-document-ids', JSON.stringify(ids))\n e.dataTransfer!.effectAllowed = 'move'\n }\n\n private _formatDate(date: any): string {\n if (!date) return ''\n try {\n const d = new Date(date)\n return new Intl.DateTimeFormat('ko-KR', {\n timeZone: 'Asia/Seoul',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit'\n }).format(d)\n } catch {\n return ''\n }\n }\n\n private _formatDateTime(date: any): string {\n if (!date) return ''\n try {\n const d = new Date(date)\n return new Intl.DateTimeFormat('ko-KR', {\n timeZone: 'Asia/Seoul',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n hour12: true\n }).format(d)\n } catch {\n return ''\n }\n }\n}\n"]}
@@ -0,0 +1,38 @@
1
+ import '@material/web/icon/icon.js';
2
+ import '@material/web/button/filled-button.js';
3
+ import '@material/web/button/outlined-button.js';
4
+ import './field-document-list-panel';
5
+ import { LitElement } from 'lit';
6
+ import './field-document-detail-popup';
7
+ export declare class FieldDocumentPopup extends LitElement {
8
+ static styles: import("lit").CSSResult[];
9
+ projectId: string;
10
+ private selectedMajor;
11
+ private selectedMiddle;
12
+ private selectedMinor;
13
+ private documents;
14
+ private selectedDocIds;
15
+ private codeCounts;
16
+ private dragOverItem;
17
+ render(): import("lit-html").TemplateResult<1>;
18
+ firstUpdated(): Promise<void>;
19
+ private _selectMajor;
20
+ private _selectMiddle;
21
+ private _selectMinor;
22
+ private _loadDocuments;
23
+ private _loadCounts;
24
+ private _getMajorCount;
25
+ private _getMiddleCount;
26
+ private _shareDocuments;
27
+ private _openMoveDialog;
28
+ private _toggleFavorites;
29
+ private _triggerUpload;
30
+ private _onFileSelected;
31
+ private _uploadFiles;
32
+ private _deleteDocuments;
33
+ private _onFolderDragOver;
34
+ private _expandTimeout;
35
+ private _onFolderDrop;
36
+ private _onDocumentsChanged;
37
+ private _openDetail;
38
+ }