@dssp/supervision 1.0.0-alpha.9 → 1.0.0-y.0

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 (202) hide show
  1. package/dist-client/graphql/building-inspection.d.ts +1 -0
  2. package/dist-client/graphql/building-inspection.js +100 -0
  3. package/dist-client/graphql/building-inspection.js.map +1 -0
  4. package/dist-client/pages/building-inspection/building-inspection-detail-ai-defect.d.ts +22 -0
  5. package/dist-client/pages/building-inspection/building-inspection-detail-ai-defect.js +169 -0
  6. package/dist-client/pages/building-inspection/building-inspection-detail-ai-defect.js.map +1 -0
  7. package/dist-client/pages/building-inspection/building-inspection-detail-ai-measurement.d.ts +57 -0
  8. package/dist-client/pages/building-inspection/building-inspection-detail-ai-measurement.js +825 -0
  9. package/dist-client/pages/building-inspection/building-inspection-detail-ai-measurement.js.map +1 -0
  10. package/dist-client/pages/building-inspection/building-inspection-detail-camera.d.ts +8 -6
  11. package/dist-client/pages/building-inspection/building-inspection-detail-camera.js +115 -65
  12. package/dist-client/pages/building-inspection/building-inspection-detail-camera.js.map +1 -1
  13. package/dist-client/pages/building-inspection/building-inspection-detail-checklist.d.ts +9 -0
  14. package/dist-client/pages/building-inspection/building-inspection-detail-checklist.js +130 -72
  15. package/dist-client/pages/building-inspection/building-inspection-detail-checklist.js.map +1 -1
  16. package/dist-client/pages/building-inspection/building-inspection-detail-drawing.d.ts +1 -0
  17. package/dist-client/pages/building-inspection/building-inspection-detail-drawing.js +77 -14
  18. package/dist-client/pages/building-inspection/building-inspection-detail-drawing.js.map +1 -1
  19. package/dist-client/pages/building-inspection/building-inspection-list.d.ts +18 -2
  20. package/dist-client/pages/building-inspection/building-inspection-list.js +358 -27
  21. package/dist-client/pages/building-inspection/building-inspection-list.js.map +1 -1
  22. package/dist-client/pages/building-inspection/component/building-inspection-detail-header.d.ts +3 -0
  23. package/dist-client/pages/building-inspection/component/building-inspection-detail-header.js +104 -17
  24. package/dist-client/pages/building-inspection/component/building-inspection-detail-header.js.map +1 -1
  25. package/dist-client/pages/building-inspection/component/daily-worklog-popup.d.ts +27 -0
  26. package/dist-client/pages/building-inspection/component/daily-worklog-popup.js +542 -0
  27. package/dist-client/pages/building-inspection/component/daily-worklog-popup.js.map +1 -0
  28. package/dist-client/pages/building-inspection/component/image-preview-popup.d.ts +15 -0
  29. package/dist-client/pages/building-inspection/component/image-preview-popup.js +351 -0
  30. package/dist-client/pages/building-inspection/component/image-preview-popup.js.map +1 -0
  31. package/dist-client/pages/building-inspection/component/inspection-document/inspection-request-document.d.ts +20 -0
  32. package/dist-client/pages/building-inspection/component/inspection-document/inspection-request-document.js +432 -0
  33. package/dist-client/pages/building-inspection/component/inspection-document/inspection-request-document.js.map +1 -0
  34. package/dist-client/pages/building-inspection/component/inspection-document/inspection-result-notification.d.ts +30 -0
  35. package/dist-client/pages/building-inspection/component/inspection-document/inspection-result-notification.js +479 -0
  36. package/dist-client/pages/building-inspection/component/inspection-document/inspection-result-notification.js.map +1 -0
  37. package/dist-client/pages/building-inspection/component/inspection-document/photo-album-popup.d.ts +27 -0
  38. package/dist-client/pages/building-inspection/component/inspection-document/photo-album-popup.js +416 -0
  39. package/dist-client/pages/building-inspection/component/inspection-document/photo-album-popup.js.map +1 -0
  40. package/dist-client/pages/building-inspection/component/inspection-event-provider.d.ts +2 -1
  41. package/dist-client/pages/building-inspection/component/inspection-event-provider.js +39 -17
  42. package/dist-client/pages/building-inspection/component/inspection-event-provider.js.map +1 -1
  43. package/dist-client/pages/building-inspection/inspection-create-popup.js +18 -8
  44. package/dist-client/pages/building-inspection/inspection-create-popup.js.map +1 -1
  45. package/dist-client/pages/building-inspection-grid/building-inspection-grid-detail.d.ts +16 -2
  46. package/dist-client/pages/building-inspection-grid/building-inspection-grid-detail.js +245 -43
  47. package/dist-client/pages/building-inspection-grid/building-inspection-grid-detail.js.map +1 -1
  48. package/dist-client/pages/building-inspection-grid/component/grid-inspection-create-popup.js +9 -5
  49. package/dist-client/pages/building-inspection-grid/component/grid-inspection-create-popup.js.map +1 -1
  50. package/dist-client/pages/building-inspection-grid/component/grid-inspection-list-layer.d.ts +19 -0
  51. package/dist-client/pages/building-inspection-grid/component/grid-inspection-list-layer.js +205 -0
  52. package/dist-client/pages/building-inspection-grid/component/grid-inspection-list-layer.js.map +1 -0
  53. package/dist-client/pages/checklist/attachment-list-popup.d.ts +1 -0
  54. package/dist-client/pages/checklist/attachment-list-popup.js +250 -67
  55. package/dist-client/pages/checklist/attachment-list-popup.js.map +1 -1
  56. package/dist-client/pages/checklist/checklist-view.d.ts +5 -4
  57. package/dist-client/pages/checklist/checklist-view.js +95 -23
  58. package/dist-client/pages/checklist/checklist-view.js.map +1 -1
  59. package/dist-client/pages/checklist/comment-list-popup.js +14 -3
  60. package/dist-client/pages/checklist/comment-list-popup.js.map +1 -1
  61. package/dist-client/pages/checklist/file-preview-popup.js +0 -1
  62. package/dist-client/pages/checklist/file-preview-popup.js.map +1 -1
  63. package/dist-client/pages/checklist/inspection-info-popup.d.ts +50 -0
  64. package/dist-client/pages/checklist/inspection-info-popup.js +684 -0
  65. package/dist-client/pages/checklist/inspection-info-popup.js.map +1 -0
  66. package/dist-client/pages/checklist/inspection-tab-popup.d.ts +18 -0
  67. package/dist-client/pages/checklist/inspection-tab-popup.js +196 -0
  68. package/dist-client/pages/checklist/inspection-tab-popup.js.map +1 -0
  69. package/dist-client/pages/checklist-template/checklist-template-item.js +14 -3
  70. package/dist-client/pages/checklist-template/checklist-template-item.js.map +1 -1
  71. package/dist-client/pages/checklist-template/checklist-template-list.js +1 -1
  72. package/dist-client/pages/checklist-template/checklist-template-list.js.map +1 -1
  73. package/dist-client/route.d.ts +1 -1
  74. package/dist-client/route.js +6 -0
  75. package/dist-client/route.js.map +1 -1
  76. package/dist-client/tsconfig.tsbuildinfo +1 -1
  77. package/dist-server/service/building-inspection/building-inspection-mutation.d.ts +2 -3
  78. package/dist-server/service/building-inspection/building-inspection-mutation.js +63 -29
  79. package/dist-server/service/building-inspection/building-inspection-mutation.js.map +1 -1
  80. package/dist-server/service/building-inspection/building-inspection-query.d.ts +3 -5
  81. package/dist-server/service/building-inspection/building-inspection-query.js +16 -29
  82. package/dist-server/service/building-inspection/building-inspection-query.js.map +1 -1
  83. package/dist-server/service/building-inspection/building-inspection-type.d.ts +22 -10
  84. package/dist-server/service/building-inspection/building-inspection-type.js +77 -23
  85. package/dist-server/service/building-inspection/building-inspection-type.js.map +1 -1
  86. package/dist-server/service/building-inspection/building-inspection.d.ts +4 -0
  87. package/dist-server/service/building-inspection/building-inspection.js +17 -2
  88. package/dist-server/service/building-inspection/building-inspection.js.map +1 -1
  89. package/dist-server/service/building-inspection/index.d.ts +3 -4
  90. package/dist-server/service/building-inspection/index.js +10 -3
  91. package/dist-server/service/building-inspection/index.js.map +1 -1
  92. package/dist-server/service/building-inspection-daily-worklog/building-inspection-daily-worklog-mutation.d.ts +6 -0
  93. package/dist-server/service/building-inspection-daily-worklog/building-inspection-daily-worklog-mutation.js +56 -0
  94. package/dist-server/service/building-inspection-daily-worklog/building-inspection-daily-worklog-mutation.js.map +1 -0
  95. package/dist-server/service/building-inspection-daily-worklog/building-inspection-daily-worklog-query.d.ts +16 -0
  96. package/dist-server/service/building-inspection-daily-worklog/building-inspection-daily-worklog-query.js +171 -0
  97. package/dist-server/service/building-inspection-daily-worklog/building-inspection-daily-worklog-query.js.map +1 -0
  98. package/dist-server/service/building-inspection-daily-worklog/building-inspection-daily-worklog-type.d.ts +23 -0
  99. package/dist-server/service/building-inspection-daily-worklog/building-inspection-daily-worklog-type.js +90 -0
  100. package/dist-server/service/building-inspection-daily-worklog/building-inspection-daily-worklog-type.js.map +1 -0
  101. package/dist-server/service/building-inspection-daily-worklog/building-inspection-daily-worklog.d.ts +33 -0
  102. package/dist-server/service/building-inspection-daily-worklog/building-inspection-daily-worklog.js +132 -0
  103. package/dist-server/service/building-inspection-daily-worklog/building-inspection-daily-worklog.js.map +1 -0
  104. package/dist-server/service/building-inspection-daily-worklog/index.d.ts +5 -0
  105. package/dist-server/service/building-inspection-daily-worklog/index.js +9 -0
  106. package/dist-server/service/building-inspection-daily-worklog/index.js.map +1 -0
  107. package/dist-server/service/building-inspection-history/building-inspection-history-query.d.ts +16 -0
  108. package/dist-server/service/building-inspection-history/building-inspection-history-query.js +120 -0
  109. package/dist-server/service/building-inspection-history/building-inspection-history-query.js.map +1 -0
  110. package/dist-server/service/building-inspection-history/building-inspection-history-type.d.ts +5 -0
  111. package/dist-server/service/building-inspection-history/building-inspection-history-type.js +21 -0
  112. package/dist-server/service/building-inspection-history/building-inspection-history-type.js.map +1 -0
  113. package/dist-server/service/building-inspection-history/building-inspection-history.d.ts +34 -0
  114. package/dist-server/service/building-inspection-history/building-inspection-history.js +157 -0
  115. package/dist-server/service/building-inspection-history/building-inspection-history.js.map +1 -0
  116. package/dist-server/service/building-inspection-history/event-subscriber.d.ts +7 -0
  117. package/dist-server/service/building-inspection-history/event-subscriber.js +21 -0
  118. package/dist-server/service/building-inspection-history/event-subscriber.js.map +1 -0
  119. package/dist-server/service/building-inspection-history/index.d.ts +6 -0
  120. package/dist-server/service/building-inspection-history/index.js +10 -0
  121. package/dist-server/service/building-inspection-history/index.js.map +1 -0
  122. package/dist-server/service/checklist/checklist-mutation.d.ts +0 -5
  123. package/dist-server/service/checklist/checklist-mutation.js +1 -67
  124. package/dist-server/service/checklist/checklist-mutation.js.map +1 -1
  125. package/dist-server/service/checklist/checklist-query.d.ts +7 -0
  126. package/dist-server/service/checklist/checklist-query.js +83 -0
  127. package/dist-server/service/checklist/checklist-query.js.map +1 -1
  128. package/dist-server/service/checklist/checklist-type.d.ts +0 -13
  129. package/dist-server/service/checklist/checklist-type.js +1 -49
  130. package/dist-server/service/checklist/checklist-type.js.map +1 -1
  131. package/dist-server/service/checklist/checklist.d.ts +24 -7
  132. package/dist-server/service/checklist/checklist.js +75 -30
  133. package/dist-server/service/checklist/checklist.js.map +1 -1
  134. package/dist-server/service/checklist/event-subscriber.d.ts +7 -0
  135. package/dist-server/service/checklist/event-subscriber.js +21 -0
  136. package/dist-server/service/checklist/event-subscriber.js.map +1 -0
  137. package/dist-server/service/checklist/index.d.ts +1 -2
  138. package/dist-server/service/checklist/index.js +1 -2
  139. package/dist-server/service/checklist/index.js.map +1 -1
  140. package/dist-server/service/checklist-history/checklist-history-query.d.ts +11 -0
  141. package/dist-server/service/checklist-history/checklist-history-query.js +77 -0
  142. package/dist-server/service/checklist-history/checklist-history-query.js.map +1 -0
  143. package/dist-server/service/checklist-history/checklist-history-type.d.ts +5 -0
  144. package/dist-server/service/checklist-history/checklist-history-type.js +21 -0
  145. package/dist-server/service/checklist-history/checklist-history-type.js.map +1 -0
  146. package/dist-server/service/{checklist → checklist-history}/checklist-history.d.ts +19 -1
  147. package/dist-server/service/{checklist → checklist-history}/checklist-history.js +97 -14
  148. package/dist-server/service/checklist-history/checklist-history.js.map +1 -0
  149. package/dist-server/service/checklist-history/event-subscriber.d.ts +7 -0
  150. package/dist-server/service/checklist-history/event-subscriber.js +21 -0
  151. package/dist-server/service/checklist-history/event-subscriber.js.map +1 -0
  152. package/dist-server/service/checklist-history/index.d.ts +6 -0
  153. package/dist-server/service/checklist-history/index.js +10 -0
  154. package/dist-server/service/checklist-history/index.js.map +1 -0
  155. package/dist-server/service/checklist-item/checklist-item-query.d.ts +1 -1
  156. package/dist-server/service/checklist-item/checklist-item-query.js +5 -3
  157. package/dist-server/service/checklist-item/checklist-item-query.js.map +1 -1
  158. package/dist-server/service/checklist-item/index.d.ts +0 -1
  159. package/dist-server/service/checklist-item/index.js +1 -2
  160. package/dist-server/service/checklist-item/index.js.map +1 -1
  161. package/dist-server/service/checklist-item-comment/checklist-item-comment-mutation.d.ts +1 -0
  162. package/dist-server/service/checklist-item-comment/checklist-item-comment-mutation.js +33 -6
  163. package/dist-server/service/checklist-item-comment/checklist-item-comment-mutation.js.map +1 -1
  164. package/dist-server/service/checklist-item-history/checklist-item-history-query.d.ts +16 -0
  165. package/dist-server/service/checklist-item-history/checklist-item-history-query.js +123 -0
  166. package/dist-server/service/checklist-item-history/checklist-item-history-query.js.map +1 -0
  167. package/dist-server/service/checklist-item-history/checklist-item-history-type.d.ts +5 -0
  168. package/dist-server/service/checklist-item-history/checklist-item-history-type.js +21 -0
  169. package/dist-server/service/checklist-item-history/checklist-item-history-type.js.map +1 -0
  170. package/dist-server/service/checklist-item-history/checklist-item-history.d.ts +25 -0
  171. package/dist-server/service/checklist-item-history/checklist-item-history.js +123 -0
  172. package/dist-server/service/checklist-item-history/checklist-item-history.js.map +1 -0
  173. package/dist-server/service/checklist-item-history/event-subscriber.d.ts +7 -0
  174. package/dist-server/service/checklist-item-history/event-subscriber.js +21 -0
  175. package/dist-server/service/checklist-item-history/event-subscriber.js.map +1 -0
  176. package/dist-server/service/checklist-item-history/index.d.ts +6 -0
  177. package/dist-server/service/checklist-item-history/index.js +10 -0
  178. package/dist-server/service/checklist-item-history/index.js.map +1 -0
  179. package/dist-server/service/checklist-template-item/checklist-template-item-mutation.js +4 -1
  180. package/dist-server/service/checklist-template-item/checklist-template-item-mutation.js.map +1 -1
  181. package/dist-server/service/checklist-template-item/checklist-template-item-type.d.ts +2 -0
  182. package/dist-server/service/checklist-template-item/checklist-template-item-type.js +5 -0
  183. package/dist-server/service/checklist-template-item/checklist-template-item-type.js.map +1 -1
  184. package/dist-server/service/checklist-template-item/checklist-template-item.d.ts +6 -0
  185. package/dist-server/service/checklist-template-item/checklist-template-item.js +16 -1
  186. package/dist-server/service/checklist-template-item/checklist-template-item.js.map +1 -1
  187. package/dist-server/service/checklist-template-item/spec-matching-service.d.ts +2 -0
  188. package/dist-server/service/checklist-template-item/spec-matching-service.js +50 -0
  189. package/dist-server/service/checklist-template-item/spec-matching-service.js.map +1 -0
  190. package/dist-server/service/index.d.ts +4 -1
  191. package/dist-server/service/index.js +22 -3
  192. package/dist-server/service/index.js.map +1 -1
  193. package/dist-server/service/project-report/project-report.d.ts +0 -2
  194. package/dist-server/service/project-report/project-report.js +0 -6
  195. package/dist-server/service/project-report/project-report.js.map +1 -1
  196. package/dist-server/tsconfig.tsbuildinfo +1 -1
  197. package/package.json +7 -6
  198. package/things-factory.config.js +2 -0
  199. package/dist-server/service/building-inspection/building-inspection-history.d.ts +0 -17
  200. package/dist-server/service/building-inspection/building-inspection-history.js +0 -86
  201. package/dist-server/service/building-inspection/building-inspection-history.js.map +0 -1
  202. package/dist-server/service/checklist/checklist-history.js.map +0 -1
@@ -0,0 +1,684 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import '@material/web/icon/icon.js';
3
+ import '@material/web/button/elevated-button.js';
4
+ import '@material/web/textfield/outlined-text-field.js';
5
+ import '@operato/input/ox-input-file.js';
6
+ import gql from 'graphql-tag';
7
+ import { client } from '@operato/graphql';
8
+ import { css, html, LitElement } from 'lit';
9
+ import { customElement, property, query, state } from 'lit/decorators.js';
10
+ import { ButtonContainerStyles, ScrollbarStyles } from '@operato/styles';
11
+ import { notify } from '@operato/layout';
12
+ import { store, User } from '@operato/shell';
13
+ import { connect } from 'pwa-helpers/connect-mixin.js';
14
+ import { OxPrompt } from '@operato/popup/ox-prompt.js';
15
+ import { openPopup } from '@operato/layout';
16
+ import './file-preview-popup';
17
+ import { BuildingInspectionStatus } from '../building-inspection/building-inspection-list';
18
+ let InspectionInfoPopup = class InspectionInfoPopup extends connect(store)(LitElement) {
19
+ constructor() {
20
+ super(...arguments);
21
+ this.buildingInspectionId = '';
22
+ this.status = BuildingInspectionStatus.WAIT;
23
+ this.mode = "VIEWER" /* ChecklistMode.VIEWER */;
24
+ this.memo = '';
25
+ this.attachments = [];
26
+ this.user = {};
27
+ this.isCapturing = false;
28
+ this.stream = null;
29
+ }
30
+ render() {
31
+ const canEdit = this.status !== BuildingInspectionStatus.PASS && this.mode === "EDITOR" /* ChecklistMode.EDITOR */;
32
+ const isCameraSupported = navigator.mediaDevices && 'mediaDevices' in navigator;
33
+ return html `
34
+ <div class="section">
35
+ <h3 class="section-title">검측 메모</h3>
36
+ <div class="memo-container">
37
+ <textarea
38
+ class="memo-textarea"
39
+ .value=${this.memo}
40
+ ?disabled=${!canEdit}
41
+ @input=${this._onMemoChange}
42
+ placeholder="검측과 관련된 메모를 입력하세요..."
43
+ ></textarea>
44
+ ${canEdit
45
+ ? html `
46
+ <div style="display: flex; justify-content: flex-end;">
47
+ <md-elevated-button @click=${this._saveMemo}> <md-icon slot="icon">save</md-icon>메모 저장 </md-elevated-button>
48
+ </div>
49
+ `
50
+ : ''}
51
+ </div>
52
+ </div>
53
+
54
+ <div class="section file-section">
55
+ <h3 class="section-title">첨부 자료</h3>
56
+
57
+ ${canEdit
58
+ ? html `
59
+ <div class="upload-controls">
60
+ ${isCameraSupported
61
+ ? html `
62
+ <button class="camera-button" @click=${this._toggleCamera} ?disabled=${this.isCapturing}>
63
+ <md-icon>camera_alt</md-icon>
64
+ ${this.isCapturing ? '촬영 중지' : '사진 촬영'}
65
+ </button>
66
+ `
67
+ : ''}
68
+
69
+ <ox-input-file accept="image/*,application/pdf,*/*" multiple="true" hide-filelist @change=${this._onFileSelect}>
70
+ <button class="file-button" slot="trigger">
71
+ <md-icon>attach_file</md-icon>
72
+ 파일 선택
73
+ </button>
74
+ </ox-input-file>
75
+ </div>
76
+
77
+ <div class="video-container ${this.isCapturing ? '' : 'hidden'}">
78
+ <video id="video" autoplay playsinline></video>
79
+ <div class="camera-controls">
80
+ <md-elevated-button @click=${this._capturePhoto}>
81
+ <md-icon slot="icon">camera</md-icon>촬영
82
+ </md-elevated-button>
83
+ <md-elevated-button @click=${this._stopCamera}> <md-icon slot="icon">close</md-icon>취소 </md-elevated-button>
84
+ </div>
85
+ </div>
86
+ `
87
+ : ''}
88
+
89
+ <div class="attachment-list">
90
+ ${this.attachments.length === 0
91
+ ? html ` <div class="empty-state" style="grid-column: 1 / -1;">첨부된 파일이 없습니다.</div> `
92
+ : this.attachments.map(attachment => html `
93
+ <div class="attachment-item" @click=${() => this._previewFile(attachment.fullpath)}>
94
+ <div class="attachment-preview">
95
+ ${this._isImageFile(attachment.name)
96
+ ? html `<img
97
+ src="${attachment.fullpath}"
98
+ alt="${attachment.name}"
99
+ loading="lazy"
100
+ @error=${(e) => this._onImageError(e, attachment.name)}
101
+ />`
102
+ : html `<md-icon>${this._getFileIcon(attachment.name)}</md-icon>`}
103
+ </div>
104
+ <div class="attachment-info">
105
+ <div class="attachment-name" title="${attachment.name}">${attachment.name}</div>
106
+ <div class="creator-info">${attachment.creator.name} • ${this._formatDate(attachment.createdAt)}</div>
107
+ </div>
108
+ <div class="attachment-actions" @click=${(e) => e.stopPropagation()}>
109
+ <a href="${attachment.fullpath}" download="${attachment.name}" title="다운로드">
110
+ <md-icon>download</md-icon>
111
+ </a>
112
+ ${attachment.creator.email === this.user.email && canEdit
113
+ ? html ` <a href="javascript:void(0)" title="삭제">
114
+ <md-icon @click=${() => this._deleteAttachment(attachment.id)} title="삭제">delete</md-icon>
115
+ </a>`
116
+ : ''}
117
+ </div>
118
+ </div>
119
+ `)}
120
+ </div>
121
+ </div>
122
+ `;
123
+ }
124
+ async firstUpdated() {
125
+ var _a;
126
+ this.user = (_a = store.getState().auth) === null || _a === void 0 ? void 0 : _a.user;
127
+ await this._loadInspectionInfo();
128
+ }
129
+ async _loadInspectionInfo() {
130
+ var _a;
131
+ const response = await client.query({
132
+ query: gql `
133
+ query BuildingInspection($id: String!) {
134
+ buildingInspection(id: $id) {
135
+ id
136
+ memo
137
+ attachments {
138
+ id
139
+ name
140
+ fullpath
141
+ creator {
142
+ id
143
+ name
144
+ email
145
+ }
146
+ createdAt
147
+ }
148
+ }
149
+ }
150
+ `,
151
+ variables: {
152
+ id: this.buildingInspectionId
153
+ }
154
+ });
155
+ if ((_a = response.data) === null || _a === void 0 ? void 0 : _a.buildingInspection) {
156
+ this.memo = response.data.buildingInspection.memo || '';
157
+ this.attachments = response.data.buildingInspection.attachments || [];
158
+ }
159
+ }
160
+ _onMemoChange(e) {
161
+ const target = e.target;
162
+ this.memo = target.value;
163
+ }
164
+ async _saveMemo() {
165
+ const response = await client.mutate({
166
+ mutation: gql `
167
+ mutation UpdateBuildingInspection($patch: UpdateBuildingInspection!) {
168
+ updateBuildingInspection(patch: $patch) {
169
+ id
170
+ memo
171
+ }
172
+ }
173
+ `,
174
+ variables: {
175
+ patch: {
176
+ id: this.buildingInspectionId,
177
+ memo: this.memo
178
+ }
179
+ }
180
+ });
181
+ if (!response.errors) {
182
+ notify({ message: '메모가 저장되었습니다.', level: 'info' });
183
+ this._requestRefresh();
184
+ }
185
+ else {
186
+ notify({ message: '메모 저장에 실패했습니다.', level: 'error' });
187
+ }
188
+ }
189
+ async _toggleCamera() {
190
+ if (this.isCapturing) {
191
+ this._stopCamera();
192
+ }
193
+ else {
194
+ await this._startCamera();
195
+ }
196
+ }
197
+ async _startCamera() {
198
+ try {
199
+ this.stream = await navigator.mediaDevices.getUserMedia({
200
+ video: { facingMode: 'environment' }, // 후면 카메라 우선
201
+ audio: false
202
+ });
203
+ this.isCapturing = true;
204
+ await this.updateComplete;
205
+ if (this.video) {
206
+ this.video.srcObject = this.stream;
207
+ }
208
+ }
209
+ catch (error) {
210
+ notify({ message: '카메라에 접근할 수 없습니다.', level: 'error' });
211
+ console.error('Camera access error:', error);
212
+ }
213
+ }
214
+ _stopCamera() {
215
+ if (this.stream) {
216
+ this.stream.getTracks().forEach(track => track.stop());
217
+ this.stream = null;
218
+ }
219
+ this.isCapturing = false;
220
+ }
221
+ async _capturePhoto() {
222
+ if (!this.video || !this.stream)
223
+ return;
224
+ const canvas = document.createElement('canvas');
225
+ const context = canvas.getContext('2d');
226
+ canvas.width = this.video.videoWidth;
227
+ canvas.height = this.video.videoHeight;
228
+ context.drawImage(this.video, 0, 0);
229
+ canvas.toBlob(async (blob) => {
230
+ if (blob) {
231
+ const now = new Date();
232
+ const koreaTime = new Date(now.getTime() + 9 * 60 * 60 * 1000); // UTC + 9시간
233
+ const timestamp = koreaTime.toISOString().slice(0, 19).replace('T', '_').replace(/:/g, '-');
234
+ const file = new File([blob], `photo-${timestamp}.jpg`, { type: 'image/jpeg' });
235
+ await this._uploadFiles([file]); // 단일 파일도 배열로 감싸서 전송
236
+ }
237
+ }, 'image/jpeg', 0.8);
238
+ this._stopCamera();
239
+ }
240
+ async _onFileSelect(e) {
241
+ const files = e.detail;
242
+ await this._uploadFiles(files);
243
+ }
244
+ async _uploadFiles(files) {
245
+ if (files.length === 0)
246
+ return;
247
+ try {
248
+ const response = await client.mutate({
249
+ mutation: gql `
250
+ mutation ($attachments: [NewAttachment!]!) {
251
+ createAttachments(attachments: $attachments) {
252
+ id
253
+ name
254
+ fullpath
255
+ creator {
256
+ id
257
+ name
258
+ email
259
+ }
260
+ createdAt
261
+ }
262
+ }
263
+ `,
264
+ variables: {
265
+ attachments: files.map(file => ({
266
+ file,
267
+ refBy: this.buildingInspectionId,
268
+ refType: 'BuildingInspection'
269
+ }))
270
+ },
271
+ context: {
272
+ hasUpload: true
273
+ }
274
+ });
275
+ if (!response.errors) {
276
+ const uploadedFiles = response.data.createAttachments;
277
+ this.attachments = [...this.attachments, ...uploadedFiles];
278
+ if (files.length === 1) {
279
+ notify({ message: '파일이 업로드되었습니다.', level: 'info' });
280
+ }
281
+ else {
282
+ notify({ message: `${files.length}개 파일이 모두 업로드되었습니다.`, level: 'info' });
283
+ }
284
+ this._requestRefresh();
285
+ }
286
+ else {
287
+ notify({ message: '파일 업로드에 실패했습니다.', level: 'error' });
288
+ }
289
+ }
290
+ catch (error) {
291
+ notify({ message: '파일 업로드 중 오류가 발생했습니다.', level: 'error' });
292
+ }
293
+ }
294
+ async _deleteAttachment(attachmentId) {
295
+ var _a, _b;
296
+ if (await OxPrompt.open({
297
+ title: '첨부 자료 삭제',
298
+ text: '첨부 자료를 삭제하시겠습니까?',
299
+ confirmButton: { text: '삭제' },
300
+ cancelButton: { text: '취소' }
301
+ })) {
302
+ const response = await client.mutate({
303
+ mutation: gql `
304
+ mutation DeleteAttachment($deleteAttachmentId: String!) {
305
+ deleteAttachment(id: $deleteAttachmentId)
306
+ }
307
+ `,
308
+ variables: {
309
+ deleteAttachmentId: attachmentId
310
+ }
311
+ });
312
+ if (!response.errors) {
313
+ this.attachments = this.attachments.filter(attachment => attachment.id !== attachmentId);
314
+ notify({ message: '첨부 자료를 삭제하였습니다.', level: 'info' });
315
+ this._requestRefresh();
316
+ }
317
+ else {
318
+ notify({ message: ((_b = (_a = response.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) || '첨부 자료 삭제에 실패하였습니다.', level: 'error' });
319
+ }
320
+ }
321
+ }
322
+ _previewFile(filepath) {
323
+ openPopup(html `<file-preview-popup .filepath=${filepath}></file-preview-popup>`, {
324
+ backdrop: true,
325
+ size: 'large',
326
+ title: '미리보기'
327
+ });
328
+ }
329
+ _isImageFile(filename) {
330
+ var _a;
331
+ const ext = (_a = filename.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
332
+ return ['jpg', 'jpeg', 'png', 'gif', 'webp'].includes(ext || '');
333
+ }
334
+ _onImageError(e, filename) {
335
+ const img = e.target;
336
+ const parent = img.parentElement;
337
+ if (parent) {
338
+ parent.innerHTML = `<md-icon>${this._getFileIcon(filename)}</md-icon>`;
339
+ }
340
+ }
341
+ _getFileIcon(filename) {
342
+ var _a;
343
+ const ext = (_a = filename.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
344
+ if (['jpg', 'jpeg', 'png', 'gif', 'webp'].includes(ext || '')) {
345
+ return 'image';
346
+ }
347
+ else if (ext === 'pdf') {
348
+ return 'picture_as_pdf';
349
+ }
350
+ else {
351
+ return 'description';
352
+ }
353
+ }
354
+ _formatDate(date) {
355
+ const _date = new Date(date);
356
+ return _date.toLocaleDateString('ko-KR', {
357
+ year: 'numeric',
358
+ month: '2-digit',
359
+ day: '2-digit',
360
+ hour: '2-digit',
361
+ minute: '2-digit'
362
+ });
363
+ }
364
+ _requestRefresh() {
365
+ this.dispatchEvent(new CustomEvent('requestRefresh', {
366
+ detail: { buildingInspectionId: this.buildingInspectionId }
367
+ }));
368
+ }
369
+ disconnectedCallback() {
370
+ super.disconnectedCallback();
371
+ this._stopCamera();
372
+ }
373
+ };
374
+ InspectionInfoPopup.styles = [
375
+ ButtonContainerStyles,
376
+ ScrollbarStyles,
377
+ css `
378
+ :host {
379
+ display: flex;
380
+ flex-direction: column;
381
+ padding: 15px 20px;
382
+ background-color: var(--md-sys-color-surface);
383
+ height: 100%;
384
+ gap: 16px;
385
+ overflow-y: auto;
386
+ }
387
+
388
+ .section {
389
+ display: flex;
390
+ flex-direction: column;
391
+ gap: 12px;
392
+ }
393
+
394
+ .section-title {
395
+ color: rgb(5, 149, 229);
396
+ font-size: 17px;
397
+ font-weight: 700;
398
+ margin: 0;
399
+ }
400
+
401
+ .memo-container {
402
+ display: flex;
403
+ flex-direction: column;
404
+ gap: 8px;
405
+ }
406
+
407
+ .memo-textarea {
408
+ min-height: 120px;
409
+ border: 1px solid #ccc;
410
+ border-radius: 8px;
411
+ padding: 12px;
412
+ font-family: inherit;
413
+ font-size: 14px;
414
+ resize: vertical;
415
+ }
416
+
417
+ .file-section {
418
+ flex: 1;
419
+ display: flex;
420
+ flex-direction: column;
421
+ gap: 12px;
422
+ }
423
+
424
+ .upload-controls {
425
+ display: flex;
426
+ gap: 8px;
427
+ flex-wrap: wrap;
428
+
429
+ ox-input-file {
430
+ flex: 1;
431
+ }
432
+ }
433
+
434
+ .camera-button,
435
+ .file-button {
436
+ display: flex;
437
+ align-items: center;
438
+ gap: 8px;
439
+ padding: 8px 16px;
440
+ border: 1px solid #ccc;
441
+ border-radius: 8px;
442
+ background: #fff;
443
+ cursor: pointer;
444
+ transition: background 0.2s;
445
+ }
446
+
447
+ .camera-button:hover,
448
+ .file-button:hover {
449
+ background: #f5f5f5;
450
+ color: #000;
451
+ }
452
+
453
+ .camera-button:disabled,
454
+ .file-button:disabled {
455
+ opacity: 0.6;
456
+ cursor: not-allowed;
457
+ }
458
+
459
+ .attachment-list {
460
+ flex: 1;
461
+ overflow-y: auto;
462
+ display: grid;
463
+ grid-template-columns: repeat(3, 1fr);
464
+ gap: 12px;
465
+ max-height: 400px;
466
+ border: 1px solid #eee;
467
+ border-radius: 8px;
468
+ padding: 12px;
469
+ }
470
+
471
+ .attachment-item {
472
+ display: flex;
473
+ flex-direction: column;
474
+ padding: 8px;
475
+ border: 1px solid #ddd;
476
+ border-radius: 8px;
477
+ background: #fafafa;
478
+ transition: all 0.2s;
479
+ cursor: pointer;
480
+ position: relative;
481
+ }
482
+
483
+ .attachment-item:hover {
484
+ transform: translateY(-2px);
485
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
486
+ }
487
+
488
+ .attachment-item:hover .attachment-actions {
489
+ opacity: 1;
490
+ }
491
+
492
+ .attachment-preview {
493
+ width: 100%;
494
+ height: 150px;
495
+ display: flex;
496
+ align-items: center;
497
+ justify-content: center;
498
+ border-radius: 6px;
499
+ background: #f8f9fa;
500
+ margin-bottom: 8px;
501
+ overflow: hidden;
502
+ }
503
+
504
+ .attachment-preview img {
505
+ width: 100%;
506
+ height: 100%;
507
+ object-fit: cover;
508
+ border-radius: 6px;
509
+ }
510
+
511
+ .attachment-preview md-icon {
512
+ font-size: 48px;
513
+ color: #666;
514
+ }
515
+
516
+ .attachment-info {
517
+ display: flex;
518
+ flex-direction: column;
519
+ gap: 4px;
520
+ flex: 1;
521
+ }
522
+
523
+ .attachment-name {
524
+ font-size: 13px;
525
+ font-weight: 500;
526
+ line-height: 1.2;
527
+ overflow: hidden;
528
+ text-overflow: ellipsis;
529
+ display: -webkit-box;
530
+ -webkit-line-clamp: 2;
531
+ -webkit-box-orient: vertical;
532
+ }
533
+
534
+ .attachment-actions {
535
+ position: absolute;
536
+ top: 4px;
537
+ right: 4px;
538
+ display: flex;
539
+ gap: 4px;
540
+ opacity: 0.7;
541
+ transition: opacity 0.2s;
542
+ background: rgba(255, 255, 255, 0.9);
543
+ border-radius: 4px;
544
+ padding: 2px;
545
+ backdrop-filter: blur(2px);
546
+ }
547
+
548
+ .attachment-actions a,
549
+ .attachment-actions md-icon {
550
+ cursor: pointer;
551
+ padding: 4px;
552
+ border-radius: 4px;
553
+ transition: background 0.2s;
554
+ color: #666;
555
+ display: flex;
556
+ align-items: center;
557
+ justify-content: center;
558
+ text-decoration: none;
559
+ }
560
+
561
+ .attachment-actions a:hover,
562
+ .attachment-actions md-icon:hover {
563
+ background: rgba(0, 0, 0, 0.1);
564
+ color: #000;
565
+ }
566
+
567
+ .creator-info {
568
+ font-size: 12px;
569
+ color: #666;
570
+ margin-top: 4px;
571
+ }
572
+
573
+ .empty-state {
574
+ text-align: center;
575
+ color: #666;
576
+ font-style: italic;
577
+ padding: 20px;
578
+ }
579
+
580
+ #cameraInput {
581
+ display: none;
582
+ }
583
+
584
+ .video-container {
585
+ position: relative;
586
+ margin-bottom: 12px;
587
+ }
588
+
589
+ #video {
590
+ width: 100%;
591
+ max-width: 400px;
592
+ height: auto;
593
+ border: 1px solid #ccc;
594
+ border-radius: 8px;
595
+ }
596
+
597
+ .camera-controls {
598
+ display: flex;
599
+ gap: 8px;
600
+ margin-top: 8px;
601
+ justify-content: center;
602
+ }
603
+
604
+ .hidden {
605
+ display: none;
606
+ }
607
+
608
+ /* 반응형 디자인 */
609
+ @media (max-width: 768px) {
610
+ .attachment-list {
611
+ grid-template-columns: repeat(2, 1fr);
612
+ gap: 8px;
613
+ padding: 8px;
614
+ }
615
+
616
+ .attachment-preview {
617
+ height: 100px;
618
+ }
619
+
620
+ .attachment-name {
621
+ font-size: 12px;
622
+ }
623
+
624
+ .creator-info {
625
+ font-size: 11px;
626
+ }
627
+ }
628
+
629
+ @media (max-width: 480px) {
630
+ .attachment-list {
631
+ grid-template-columns: 1fr;
632
+ }
633
+ }
634
+ `
635
+ ];
636
+ __decorate([
637
+ property({ type: String }),
638
+ __metadata("design:type", String)
639
+ ], InspectionInfoPopup.prototype, "buildingInspectionId", void 0);
640
+ __decorate([
641
+ property({ type: String }),
642
+ __metadata("design:type", String)
643
+ ], InspectionInfoPopup.prototype, "status", void 0);
644
+ __decorate([
645
+ property({ type: String }),
646
+ __metadata("design:type", String)
647
+ ], InspectionInfoPopup.prototype, "mode", void 0);
648
+ __decorate([
649
+ state(),
650
+ __metadata("design:type", String)
651
+ ], InspectionInfoPopup.prototype, "memo", void 0);
652
+ __decorate([
653
+ state(),
654
+ __metadata("design:type", Array)
655
+ ], InspectionInfoPopup.prototype, "attachments", void 0);
656
+ __decorate([
657
+ state(),
658
+ __metadata("design:type", User)
659
+ ], InspectionInfoPopup.prototype, "user", void 0);
660
+ __decorate([
661
+ state(),
662
+ __metadata("design:type", Boolean)
663
+ ], InspectionInfoPopup.prototype, "isCapturing", void 0);
664
+ __decorate([
665
+ state(),
666
+ __metadata("design:type", Object)
667
+ ], InspectionInfoPopup.prototype, "stream", void 0);
668
+ __decorate([
669
+ query('#video'),
670
+ __metadata("design:type", HTMLVideoElement)
671
+ ], InspectionInfoPopup.prototype, "video", void 0);
672
+ __decorate([
673
+ query('#cameraInput'),
674
+ __metadata("design:type", HTMLInputElement)
675
+ ], InspectionInfoPopup.prototype, "cameraInput", void 0);
676
+ __decorate([
677
+ query('ox-input-file'),
678
+ __metadata("design:type", Object)
679
+ ], InspectionInfoPopup.prototype, "fileInput", void 0);
680
+ InspectionInfoPopup = __decorate([
681
+ customElement('inspection-info-popup')
682
+ ], InspectionInfoPopup);
683
+ export { InspectionInfoPopup };
684
+ //# sourceMappingURL=inspection-info-popup.js.map