@dssp/supervision 1.0.0-alpha.47 → 1.0.0-alpha.49
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 +57 -0
- package/dist-client/pages/building-inspection/building-inspection-detail-ai-measurement.js +800 -0
- package/dist-client/pages/building-inspection/building-inspection-detail-ai-measurement.js.map +1 -0
- package/dist-client/pages/building-inspection/building-inspection-detail-camera.d.ts +6 -33
- package/dist-client/pages/building-inspection/building-inspection-detail-camera.js +58 -427
- package/dist-client/pages/building-inspection/building-inspection-detail-camera.js.map +1 -1
- package/dist-client/pages/building-inspection/component/building-inspection-detail-header.d.ts +3 -0
- package/dist-client/pages/building-inspection/component/building-inspection-detail-header.js +77 -8
- package/dist-client/pages/building-inspection/component/building-inspection-detail-header.js.map +1 -1
- package/dist-client/pages/building-inspection/component/inspection-document/photo-album-popup.js +21 -6
- package/dist-client/pages/building-inspection/component/inspection-document/photo-album-popup.js.map +1 -1
- package/dist-client/route.d.ts +1 -1
- package/dist-client/route.js +3 -0
- package/dist-client/route.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/service/checklist/checklist-query.d.ts +1 -0
- package/dist-server/service/checklist/checklist-query.js +20 -0
- package/dist-server/service/checklist/checklist-query.js.map +1 -1
- package/dist-server/service/checklist-template-item/index.d.ts +1 -1
- package/dist-server/service/index.d.ts +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/things-factory.config.js +1 -0
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
2
|
import '@material/web/icon/icon.js';
|
|
3
|
-
import '@operato/input/ox-input-switch.js';
|
|
4
|
-
import '@operato/mini-map/ox-zoomable-image.js';
|
|
5
3
|
import '@material/web/progress/circular-progress.js';
|
|
6
4
|
import gql from 'graphql-tag';
|
|
7
5
|
import { css, html } from 'lit';
|
|
@@ -9,77 +7,17 @@ import { customElement, state, query } from 'lit/decorators.js';
|
|
|
9
7
|
import { PageView } from '@operato/shell';
|
|
10
8
|
import { CommonGristStyles, ScrollbarStyles } from '@operato/styles';
|
|
11
9
|
import { client } from '@operato/graphql';
|
|
10
|
+
import { notify } from '@operato/layout';
|
|
12
11
|
import './component/building-inspection-detail-header';
|
|
13
12
|
let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
|
|
14
13
|
constructor() {
|
|
15
14
|
super(...arguments);
|
|
16
|
-
this.KEYPOINT_RULER_API_BASE_URL = 'https://hatiolab-korea-uni.ettisoft.com';
|
|
17
15
|
this.project = {};
|
|
18
16
|
this.buildingInspection = {};
|
|
19
17
|
this.buildingInspectionId = '';
|
|
20
|
-
this.
|
|
21
|
-
this.
|
|
22
|
-
this.
|
|
23
|
-
this.analyzing = false;
|
|
24
|
-
this.selectedPoints = {
|
|
25
|
-
x1: null,
|
|
26
|
-
y1: null,
|
|
27
|
-
x2: null,
|
|
28
|
-
y2: null
|
|
29
|
-
};
|
|
30
|
-
this.frameNaturalWidth = 0;
|
|
31
|
-
this.frameNaturalHeight = 0;
|
|
32
|
-
this.displayedImageRect = null;
|
|
33
|
-
this.distance = null;
|
|
34
|
-
this.unit = null;
|
|
35
|
-
this._onImageLoad = () => {
|
|
36
|
-
if (!this.frameImageEl || !this.imageWrapperEl)
|
|
37
|
-
return;
|
|
38
|
-
const img = this.frameImageEl;
|
|
39
|
-
const wrapperRect = this.imageWrapperEl.getBoundingClientRect();
|
|
40
|
-
const imgRect = img.getBoundingClientRect();
|
|
41
|
-
this.frameNaturalWidth = img.naturalWidth;
|
|
42
|
-
this.frameNaturalHeight = img.naturalHeight;
|
|
43
|
-
this.displayedImageRect = {
|
|
44
|
-
width: imgRect.width,
|
|
45
|
-
height: imgRect.height,
|
|
46
|
-
left: imgRect.left - wrapperRect.left,
|
|
47
|
-
top: imgRect.top - wrapperRect.top
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
this._onImageClick = (event) => {
|
|
51
|
-
if (!this.frameImageEl || !this.imageWrapperEl)
|
|
52
|
-
return;
|
|
53
|
-
const imgRect = this.frameImageEl.getBoundingClientRect();
|
|
54
|
-
const wrapperRect = this.imageWrapperEl.getBoundingClientRect();
|
|
55
|
-
const clientX = event.clientX;
|
|
56
|
-
const clientY = event.clientY;
|
|
57
|
-
// Ignore clicks outside the displayed image area
|
|
58
|
-
if (clientX < imgRect.left || clientX > imgRect.right || clientY < imgRect.top || clientY > imgRect.bottom) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
const relativeX = clientX - imgRect.left;
|
|
62
|
-
const relativeY = clientY - imgRect.top;
|
|
63
|
-
const xOnNatural = Math.round((relativeX * this.frameNaturalWidth) / imgRect.width);
|
|
64
|
-
const yOnNatural = Math.round((relativeY * this.frameNaturalHeight) / imgRect.height);
|
|
65
|
-
if (this.selectedPoints.x1 === null || this.selectedPoints.y1 === null) {
|
|
66
|
-
this.selectedPoints = Object.assign(Object.assign({}, this.selectedPoints), { x1: xOnNatural, y1: yOnNatural });
|
|
67
|
-
}
|
|
68
|
-
else if (this.selectedPoints.x2 === null || this.selectedPoints.y2 === null) {
|
|
69
|
-
this.selectedPoints = Object.assign(Object.assign({}, this.selectedPoints), { x2: xOnNatural, y2: yOnNatural });
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
// 세 번째 클릭부터는 초기화 후 첫 점으로 설정
|
|
73
|
-
this.selectedPoints = { x1: xOnNatural, y1: yOnNatural, x2: null, y2: null };
|
|
74
|
-
}
|
|
75
|
-
// Update displayed rect cache (in case layout changed)
|
|
76
|
-
this.displayedImageRect = {
|
|
77
|
-
width: imgRect.width,
|
|
78
|
-
height: imgRect.height,
|
|
79
|
-
left: imgRect.left - wrapperRect.left,
|
|
80
|
-
top: imgRect.top - wrapperRect.top
|
|
81
|
-
};
|
|
82
|
-
};
|
|
18
|
+
this.capturedImageUrl = null;
|
|
19
|
+
this.imageFile = null;
|
|
20
|
+
this.isSaved = false;
|
|
83
21
|
}
|
|
84
22
|
get context() {
|
|
85
23
|
return {
|
|
@@ -87,7 +25,7 @@ let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
|
|
|
87
25
|
};
|
|
88
26
|
}
|
|
89
27
|
render() {
|
|
90
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
28
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
91
29
|
return html `
|
|
92
30
|
<building-inspection-detail-header
|
|
93
31
|
.buildingInspectionId=${(_a = this.buildingInspection) === null || _a === void 0 ? void 0 : _a.id}
|
|
@@ -98,57 +36,25 @@ let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
|
|
|
98
36
|
></building-inspection-detail-header>
|
|
99
37
|
|
|
100
38
|
<div body>
|
|
101
|
-
<!-- Preview selected or recorded video -->
|
|
102
39
|
<div preview>
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
? html `<
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
</div>`
|
|
109
|
-
: // 동영상 분석 완료 단일 프레임 표시
|
|
110
|
-
this.frame
|
|
111
|
-
? html `
|
|
112
|
-
<div class="image-wrapper" @click=${this._onImageClick}>
|
|
113
|
-
<img
|
|
114
|
-
id="frameImage"
|
|
115
|
-
src="${this.KEYPOINT_RULER_API_BASE_URL + ((_j = this.frame) === null || _j === void 0 ? void 0 : _j.download_url)}"
|
|
116
|
-
alt="frame"
|
|
117
|
-
loading="eager"
|
|
118
|
-
@load=${this._onImageLoad}
|
|
119
|
-
/>
|
|
120
|
-
${this._renderMarkers()}
|
|
121
|
-
</div>
|
|
122
|
-
`
|
|
123
|
-
: // 동영상 선택 후 동영상 프리뷰
|
|
124
|
-
this.capturedVideoUrl
|
|
125
|
-
? html `<video src=${this.capturedVideoUrl} controls playsinline></video>`
|
|
126
|
-
: // 초기 상태, 동영상 선택 전
|
|
127
|
-
html `<md-icon>videocam</md-icon>`}
|
|
40
|
+
<div class="image-wrapper">
|
|
41
|
+
${this.capturedImageUrl
|
|
42
|
+
? html `<img id="imageImage" src="${this.capturedImageUrl}" alt="image" />`
|
|
43
|
+
: html `<md-icon>add_a_photo</md-icon>`}
|
|
44
|
+
</div>
|
|
128
45
|
</div>
|
|
129
46
|
|
|
130
47
|
<div controls>
|
|
131
|
-
<span class="controls-title"
|
|
48
|
+
<span class="controls-title">사진 촬영</span>
|
|
132
49
|
|
|
133
|
-
<!-- Camera shutter button (record video) -->
|
|
134
50
|
<div class="camera-shutter">
|
|
135
51
|
<md-icon>camera</md-icon>
|
|
136
|
-
<input id="
|
|
52
|
+
<input id="imageInput" type="file" accept="image/*" @change="${this._onImageSelected}" />
|
|
137
53
|
</div>
|
|
138
54
|
|
|
139
55
|
<!-- Action buttons -->
|
|
140
56
|
<div action-buttons>
|
|
141
|
-
|
|
142
|
-
? html `
|
|
143
|
-
<button class="photo" ?disabled=${this.analyzing || !this._hasTwoPoints()} @click=${this._onAnalyzePhoto}>
|
|
144
|
-
사진 분석
|
|
145
|
-
</button>
|
|
146
|
-
`
|
|
147
|
-
: html `
|
|
148
|
-
<button class="save" ?disabled=${this.analyzing || !this.capturedVideoUrl} @click=${this._onAnalyzeVideo}>
|
|
149
|
-
동영상 분석
|
|
150
|
-
</button>
|
|
151
|
-
`}
|
|
57
|
+
<button class="save" ?disabled=${!this.imageFile || this.isSaved} @click=${this._savePhoto}>사진 저장</button>
|
|
152
58
|
<button class="retry" @click=${this._onRetry}>초기화</button>
|
|
153
59
|
</div>
|
|
154
60
|
</div>
|
|
@@ -158,6 +64,7 @@ let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
|
|
|
158
64
|
async updated(changes) { }
|
|
159
65
|
async pageUpdated(changes, lifecycle) {
|
|
160
66
|
if (this.active) {
|
|
67
|
+
this._onRetry();
|
|
161
68
|
this.buildingInspectionId = lifecycle.resourceId || '';
|
|
162
69
|
await this.initBuildingInspection(this.buildingInspectionId);
|
|
163
70
|
}
|
|
@@ -171,20 +78,12 @@ let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
|
|
|
171
78
|
id
|
|
172
79
|
status
|
|
173
80
|
requestDate
|
|
174
|
-
drawingMarker
|
|
175
81
|
checklist {
|
|
176
|
-
|
|
177
|
-
inspectionDrawingType
|
|
82
|
+
id
|
|
178
83
|
}
|
|
179
84
|
buildingLevel {
|
|
180
85
|
id
|
|
181
86
|
floor
|
|
182
|
-
mainDrawing {
|
|
183
|
-
id
|
|
184
|
-
name
|
|
185
|
-
fullpath
|
|
186
|
-
}
|
|
187
|
-
mainDrawingImage
|
|
188
87
|
building {
|
|
189
88
|
id
|
|
190
89
|
name
|
|
@@ -223,163 +122,62 @@ let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
|
|
|
223
122
|
return;
|
|
224
123
|
this.project = response.data.project;
|
|
225
124
|
}
|
|
226
|
-
|
|
125
|
+
_onImageSelected(event) {
|
|
227
126
|
var _a;
|
|
228
127
|
const input = event.target;
|
|
229
128
|
const file = (_a = input === null || input === void 0 ? void 0 : input.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
230
129
|
if (!file)
|
|
231
130
|
return;
|
|
232
131
|
// Only allow video files
|
|
233
|
-
if (!file.type.startsWith('
|
|
234
|
-
console.warn('선택된 파일이
|
|
132
|
+
if (!file.type.startsWith('image/')) {
|
|
133
|
+
console.warn('선택된 파일이 이미지가 아닙니다.');
|
|
235
134
|
return;
|
|
236
135
|
}
|
|
237
136
|
// Revoke old object URL if exists
|
|
238
|
-
if (this.
|
|
239
|
-
URL.revokeObjectURL(this.
|
|
240
|
-
}
|
|
241
|
-
this.videoFile = file;
|
|
242
|
-
this.capturedVideoUrl = URL.createObjectURL(file);
|
|
243
|
-
}
|
|
244
|
-
async _onAnalyzeVideo() {
|
|
245
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
246
|
-
if (!this.videoFile) {
|
|
247
|
-
console.warn('선택된 동영상이 없습니다.');
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
try {
|
|
251
|
-
this.analyzing = true;
|
|
252
|
-
const form = new FormData();
|
|
253
|
-
form.append('files', this.videoFile, this.videoFile.name);
|
|
254
|
-
const response = await fetch(`${this.KEYPOINT_RULER_API_BASE_URL}/api/run/keypoint-ruler`, {
|
|
255
|
-
method: 'POST',
|
|
256
|
-
headers: { Authorization: `Basic ${btoa('admin:admin1234')}` },
|
|
257
|
-
body: form
|
|
258
|
-
});
|
|
259
|
-
const data = await response.json();
|
|
260
|
-
this.frame = {
|
|
261
|
-
file_id: (_b = (_a = data === null || data === void 0 ? void 0 : data.result) === null || _a === void 0 ? void 0 : _a.output_files[0]) === null || _b === void 0 ? void 0 : _b.file_id,
|
|
262
|
-
download_url: (_d = (_c = data === null || data === void 0 ? void 0 : data.result) === null || _c === void 0 ? void 0 : _c.output_files[0]) === null || _d === void 0 ? void 0 : _d.download_url,
|
|
263
|
-
file_path: (_f = (_e = data === null || data === void 0 ? void 0 : data.result) === null || _e === void 0 ? void 0 : _e.frames[0]) === null || _f === void 0 ? void 0 : _f.file_path,
|
|
264
|
-
calibration: (_g = data === null || data === void 0 ? void 0 : data.result) === null || _g === void 0 ? void 0 : _g.calibration
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
catch (error) {
|
|
268
|
-
console.error('동영상 업로드 실패:', error);
|
|
269
|
-
}
|
|
270
|
-
finally {
|
|
271
|
-
this.analyzing = false;
|
|
137
|
+
if (this.capturedImageUrl) {
|
|
138
|
+
URL.revokeObjectURL(this.capturedImageUrl);
|
|
272
139
|
}
|
|
140
|
+
this.imageFile = file;
|
|
141
|
+
this.capturedImageUrl = URL.createObjectURL(file);
|
|
142
|
+
this.isSaved = false; // 새 이미지 선택 시 저장 상태 초기화
|
|
273
143
|
}
|
|
274
144
|
_onRetry() {
|
|
275
145
|
// Clear current selection and reopen camera
|
|
276
|
-
if (this.
|
|
277
|
-
URL.revokeObjectURL(this.
|
|
146
|
+
if (this.capturedImageUrl) {
|
|
147
|
+
URL.revokeObjectURL(this.capturedImageUrl);
|
|
278
148
|
}
|
|
279
|
-
this.
|
|
280
|
-
this.
|
|
281
|
-
this.
|
|
282
|
-
this.
|
|
283
|
-
this.displayedImageRect = null;
|
|
284
|
-
this.frameNaturalWidth = 0;
|
|
285
|
-
this.frameNaturalHeight = 0;
|
|
286
|
-
this.cameraInputEl.value = '';
|
|
287
|
-
this.distance = null;
|
|
288
|
-
this.unit = null;
|
|
289
|
-
}
|
|
290
|
-
_hasTwoPoints() {
|
|
291
|
-
const { x1, y1, x2, y2 } = this.selectedPoints;
|
|
292
|
-
return x1 !== null && y1 !== null && x2 !== null && y2 !== null;
|
|
293
|
-
}
|
|
294
|
-
_renderMarkers() {
|
|
295
|
-
if (!this.displayedImageRect)
|
|
296
|
-
return html ``;
|
|
297
|
-
const { left, top, width, height } = this.displayedImageRect;
|
|
298
|
-
const { x1, y1, x2, y2 } = this.selectedPoints;
|
|
299
|
-
const toDisplay = (x, y) => {
|
|
300
|
-
const dx = left + (x * width) / (this.frameNaturalWidth || 1);
|
|
301
|
-
const dy = top + (y * height) / (this.frameNaturalHeight || 1);
|
|
302
|
-
return { dx, dy };
|
|
303
|
-
};
|
|
304
|
-
return html `
|
|
305
|
-
${x1 !== null && y1 !== null
|
|
306
|
-
? (() => {
|
|
307
|
-
const p = toDisplay(x1, y1);
|
|
308
|
-
return html `<div class="point-marker point-1" style="left:${p.dx}px; top:${p.dy}px;"></div>`;
|
|
309
|
-
})()
|
|
310
|
-
: ''}
|
|
311
|
-
${x2 !== null && y2 !== null
|
|
312
|
-
? (() => {
|
|
313
|
-
const p = toDisplay(x2, y2);
|
|
314
|
-
return html `<div class="point-marker point-2" style="left:${p.dx}px; top:${p.dy}px;"></div>`;
|
|
315
|
-
})()
|
|
316
|
-
: ''}
|
|
317
|
-
${this._hasTwoPoints()
|
|
318
|
-
? (() => {
|
|
319
|
-
const p1 = toDisplay(x1, y1);
|
|
320
|
-
const p2 = toDisplay(x2, y2);
|
|
321
|
-
const x = Math.min(p1.dx, p2.dx);
|
|
322
|
-
const y = Math.min(p1.dy, p2.dy);
|
|
323
|
-
const w = Math.abs(p1.dx - p2.dx);
|
|
324
|
-
const h = Math.abs(p1.dy - p2.dy);
|
|
325
|
-
const cx = (p1.dx + p2.dx) / 2;
|
|
326
|
-
const cy = (p1.dy + p2.dy) / 2;
|
|
327
|
-
return html `
|
|
328
|
-
<svg class="line-overlay" style="left:${x}px; top:${y}px; width:${w}px; height:${h}px;">
|
|
329
|
-
<line
|
|
330
|
-
x1=${p1.dx < p2.dx ? 0 : w}
|
|
331
|
-
y1=${p1.dy < p2.dy ? 0 : h}
|
|
332
|
-
x2=${p1.dx < p2.dx ? w : 0}
|
|
333
|
-
y2=${p1.dy < p2.dy ? h : 0}
|
|
334
|
-
stroke="#ff9800"
|
|
335
|
-
stroke-width="3"
|
|
336
|
-
/>
|
|
337
|
-
</svg>
|
|
338
|
-
${this.distance !== null && this.unit
|
|
339
|
-
? html `<div class="distance-label" style="left:${cx}px; top:${cy}px;">${this.distance} ${this.unit}</div>`
|
|
340
|
-
: ''}
|
|
341
|
-
`;
|
|
342
|
-
})()
|
|
343
|
-
: ''}
|
|
344
|
-
`;
|
|
149
|
+
this.capturedImageUrl = null;
|
|
150
|
+
this.imageFile = null;
|
|
151
|
+
this.isSaved = false; // 초기화 시 저장 상태도 리셋
|
|
152
|
+
this.imageInputEl.value = '';
|
|
345
153
|
}
|
|
346
|
-
async
|
|
347
|
-
|
|
348
|
-
|
|
154
|
+
async _savePhoto() {
|
|
155
|
+
var _a, _b, _c;
|
|
156
|
+
if (!this.imageFile) {
|
|
157
|
+
notify({ message: '사진을 선택한 후 저장할 수 있습니다.', level: 'warn' });
|
|
349
158
|
return;
|
|
350
159
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
y1: this.selectedPoints.y1,
|
|
360
|
-
x2: this.selectedPoints.x2,
|
|
361
|
-
y2: this.selectedPoints.y2,
|
|
362
|
-
file_path: this.frame.file_path,
|
|
363
|
-
calibration: this.frame.calibration
|
|
364
|
-
};
|
|
365
|
-
const form = new FormData();
|
|
366
|
-
form.append('input', JSON.stringify(payload));
|
|
367
|
-
const response = await fetch(`${this.KEYPOINT_RULER_API_BASE_URL}/api/run/keypoint-ruler`, {
|
|
368
|
-
method: 'POST',
|
|
369
|
-
headers: { Authorization: `Basic ${btoa('admin:admin1234')}` },
|
|
370
|
-
body: form
|
|
371
|
-
});
|
|
372
|
-
const result = await response.json();
|
|
373
|
-
const { distance, unit } = result.result || {};
|
|
374
|
-
this.distance = distance;
|
|
375
|
-
this.unit = unit;
|
|
376
|
-
}
|
|
377
|
-
catch (error) {
|
|
378
|
-
console.error('사진 분석 실패:', error);
|
|
160
|
+
const checklistId = (_b = (_a = this.buildingInspection) === null || _a === void 0 ? void 0 : _a.checklist) === null || _b === void 0 ? void 0 : _b.id;
|
|
161
|
+
const file = this.imageFile;
|
|
162
|
+
const response = await client.mutate({
|
|
163
|
+
mutation: gql `
|
|
164
|
+
mutation ($attachments: [NewAttachment!]!) {
|
|
165
|
+
createAttachments(attachments: $attachments) {
|
|
166
|
+
id
|
|
167
|
+
}
|
|
379
168
|
}
|
|
380
|
-
|
|
381
|
-
|
|
169
|
+
`,
|
|
170
|
+
variables: {
|
|
171
|
+
attachments: [{ file, refBy: checklistId, refType: 'Checklist', description: (_c = this.buildingInspection) === null || _c === void 0 ? void 0 : _c.status }]
|
|
172
|
+
},
|
|
173
|
+
context: { hasUpload: true }
|
|
174
|
+
});
|
|
175
|
+
if (!response.errors) {
|
|
176
|
+
notify({ message: '사진 대지를 저장하였습니다.', level: 'info' });
|
|
177
|
+
this.isSaved = true; // 저장 성공 시 상태 업데이트
|
|
178
|
+
return;
|
|
382
179
|
}
|
|
180
|
+
return response.data.createAttachments;
|
|
383
181
|
}
|
|
384
182
|
};
|
|
385
183
|
BuildingInspectionCamera.styles = [
|
|
@@ -431,119 +229,12 @@ BuildingInspectionCamera.styles = [
|
|
|
431
229
|
--md-icon-size: 160px;
|
|
432
230
|
}
|
|
433
231
|
|
|
434
|
-
.loading-container {
|
|
435
|
-
display: flex;
|
|
436
|
-
flex-direction: column;
|
|
437
|
-
align-items: center;
|
|
438
|
-
justify-content: center;
|
|
439
|
-
gap: 12px;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
.loading-text {
|
|
443
|
-
font-size: 14px;
|
|
444
|
-
color: #666;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
.frame-container {
|
|
448
|
-
width: 100%;
|
|
449
|
-
height: 100%;
|
|
450
|
-
max-height: 100%;
|
|
451
|
-
min-height: 0;
|
|
452
|
-
overflow-y: auto;
|
|
453
|
-
display: flex;
|
|
454
|
-
flex-direction: column;
|
|
455
|
-
gap: 12px;
|
|
456
|
-
padding: 12px;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
.frames-header {
|
|
460
|
-
display: flex;
|
|
461
|
-
align-items: center;
|
|
462
|
-
justify-content: center;
|
|
463
|
-
gap: 12px;
|
|
464
|
-
font-size: 20px;
|
|
465
|
-
font-weight: 700;
|
|
466
|
-
color: #333;
|
|
467
|
-
text-align: center;
|
|
468
|
-
padding-block: 8px;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
.frames-count {
|
|
472
|
-
font-size: 16px;
|
|
473
|
-
color: #777;
|
|
474
|
-
font-weight: 600;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
.frames-grid {
|
|
478
|
-
display: grid;
|
|
479
|
-
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
|
|
480
|
-
gap: 12px;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
.frame-item {
|
|
484
|
-
border: 1px solid #ddd;
|
|
485
|
-
border-radius: 8px;
|
|
486
|
-
overflow: hidden;
|
|
487
|
-
background: #fff;
|
|
488
|
-
cursor: pointer;
|
|
489
|
-
transition:
|
|
490
|
-
box-shadow 0.2s,
|
|
491
|
-
transform 0.1s;
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
.frame-item:hover {
|
|
495
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
496
|
-
transform: translateY(-1px);
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
.frame-item img {
|
|
500
|
-
display: block;
|
|
501
|
-
width: 100%;
|
|
502
|
-
height: 120px;
|
|
503
|
-
object-fit: cover;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
232
|
.image-wrapper {
|
|
507
233
|
position: relative;
|
|
508
234
|
width: 100%;
|
|
509
235
|
height: 100%;
|
|
510
236
|
align-content: center;
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
.point-marker {
|
|
514
|
-
position: absolute;
|
|
515
|
-
width: 14px;
|
|
516
|
-
height: 14px;
|
|
517
|
-
border-radius: 50%;
|
|
518
|
-
border: 2px solid #fff;
|
|
519
|
-
transform: translate(-50%, -50%);
|
|
520
|
-
pointer-events: none;
|
|
521
|
-
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.25);
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
.point-1 {
|
|
525
|
-
background-color: #e53935;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
.point-2 {
|
|
529
|
-
background-color: #1e88e5;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
.line-overlay {
|
|
533
|
-
position: absolute;
|
|
534
|
-
pointer-events: none;
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
.distance-label {
|
|
538
|
-
position: absolute;
|
|
539
|
-
background: rgba(0, 0, 0, 0.7);
|
|
540
|
-
color: #fff;
|
|
541
|
-
font-size: 14px;
|
|
542
|
-
padding: 2px 6px;
|
|
543
|
-
border-radius: 4px;
|
|
544
|
-
transform: translate(-50%, -120%);
|
|
545
|
-
pointer-events: none;
|
|
546
|
-
white-space: nowrap;
|
|
237
|
+
text-align: center;
|
|
547
238
|
}
|
|
548
239
|
|
|
549
240
|
div[controls] {
|
|
@@ -561,20 +252,6 @@ BuildingInspectionCamera.styles = [
|
|
|
561
252
|
gap: 15px;
|
|
562
253
|
}
|
|
563
254
|
|
|
564
|
-
.switch-container {
|
|
565
|
-
display: flex;
|
|
566
|
-
align-items: center;
|
|
567
|
-
gap: 10px;
|
|
568
|
-
font-size: 24px;
|
|
569
|
-
font-weight: bold;
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
ox-input-switch {
|
|
573
|
-
--ox-simple-switch-fullwidth: 68px;
|
|
574
|
-
--ox-simple-switch-fullheight: 34px;
|
|
575
|
-
--ox-simple-switch-thumbnail-size: 34px;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
255
|
.camera-shutter {
|
|
579
256
|
display: flex;
|
|
580
257
|
justify-content: center;
|
|
@@ -627,16 +304,6 @@ BuildingInspectionCamera.styles = [
|
|
|
627
304
|
background-color: #f0ad4e;
|
|
628
305
|
color: white;
|
|
629
306
|
}
|
|
630
|
-
|
|
631
|
-
button.photo {
|
|
632
|
-
background-color: #1e88e5;
|
|
633
|
-
color: white;
|
|
634
|
-
|
|
635
|
-
&:disabled {
|
|
636
|
-
background-color: #ccc;
|
|
637
|
-
cursor: default;
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
307
|
`
|
|
641
308
|
];
|
|
642
309
|
__decorate([
|
|
@@ -654,55 +321,19 @@ __decorate([
|
|
|
654
321
|
__decorate([
|
|
655
322
|
state(),
|
|
656
323
|
__metadata("design:type", Object)
|
|
657
|
-
], BuildingInspectionCamera.prototype, "
|
|
658
|
-
__decorate([
|
|
659
|
-
state(),
|
|
660
|
-
__metadata("design:type", Object)
|
|
661
|
-
], BuildingInspectionCamera.prototype, "videoFile", void 0);
|
|
324
|
+
], BuildingInspectionCamera.prototype, "capturedImageUrl", void 0);
|
|
662
325
|
__decorate([
|
|
663
326
|
state(),
|
|
664
327
|
__metadata("design:type", Object)
|
|
665
|
-
], BuildingInspectionCamera.prototype, "
|
|
328
|
+
], BuildingInspectionCamera.prototype, "imageFile", void 0);
|
|
666
329
|
__decorate([
|
|
667
330
|
state(),
|
|
668
331
|
__metadata("design:type", Boolean)
|
|
669
|
-
], BuildingInspectionCamera.prototype, "
|
|
670
|
-
__decorate([
|
|
671
|
-
state(),
|
|
672
|
-
__metadata("design:type", Object)
|
|
673
|
-
], BuildingInspectionCamera.prototype, "selectedPoints", void 0);
|
|
674
|
-
__decorate([
|
|
675
|
-
state(),
|
|
676
|
-
__metadata("design:type", Number)
|
|
677
|
-
], BuildingInspectionCamera.prototype, "frameNaturalWidth", void 0);
|
|
678
|
-
__decorate([
|
|
679
|
-
state(),
|
|
680
|
-
__metadata("design:type", Number)
|
|
681
|
-
], BuildingInspectionCamera.prototype, "frameNaturalHeight", void 0);
|
|
682
|
-
__decorate([
|
|
683
|
-
state(),
|
|
684
|
-
__metadata("design:type", Object)
|
|
685
|
-
], BuildingInspectionCamera.prototype, "displayedImageRect", void 0);
|
|
686
|
-
__decorate([
|
|
687
|
-
state(),
|
|
688
|
-
__metadata("design:type", Object)
|
|
689
|
-
], BuildingInspectionCamera.prototype, "distance", void 0);
|
|
690
|
-
__decorate([
|
|
691
|
-
state(),
|
|
692
|
-
__metadata("design:type", Object)
|
|
693
|
-
], BuildingInspectionCamera.prototype, "unit", void 0);
|
|
694
|
-
__decorate([
|
|
695
|
-
query('img#frameImage'),
|
|
696
|
-
__metadata("design:type", HTMLImageElement)
|
|
697
|
-
], BuildingInspectionCamera.prototype, "frameImageEl", void 0);
|
|
698
|
-
__decorate([
|
|
699
|
-
query('div.image-wrapper'),
|
|
700
|
-
__metadata("design:type", HTMLDivElement)
|
|
701
|
-
], BuildingInspectionCamera.prototype, "imageWrapperEl", void 0);
|
|
332
|
+
], BuildingInspectionCamera.prototype, "isSaved", void 0);
|
|
702
333
|
__decorate([
|
|
703
|
-
query('#
|
|
334
|
+
query('#imageInput'),
|
|
704
335
|
__metadata("design:type", HTMLInputElement)
|
|
705
|
-
], BuildingInspectionCamera.prototype, "
|
|
336
|
+
], BuildingInspectionCamera.prototype, "imageInputEl", void 0);
|
|
706
337
|
BuildingInspectionCamera = __decorate([
|
|
707
338
|
customElement('building-inspection-detail-camera')
|
|
708
339
|
], BuildingInspectionCamera);
|