@7365admin1/layer-common 1.10.8 → 1.10.10
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/CHANGELOG.md +12 -0
- package/components/AccessCardAddForm.vue +1 -1
- package/components/AccessCardAssignToUnitForm.vue +1 -1
- package/components/AccessManagement.vue +1 -1
- package/components/BulletinBoardManagement.vue +18 -8
- package/components/Carousel.vue +474 -0
- package/components/DeliveryCompany.vue +240 -0
- package/components/DrawImage.vue +172 -0
- package/components/EntryPassInformation.vue +70 -10
- package/components/EquipmentItemMain.vue +9 -4
- package/components/Feedback/Form.vue +4 -4
- package/components/FeedbackMain.vue +734 -146
- package/components/FileInput.vue +289 -0
- package/components/IncidentReport/Authorities.vue +189 -151
- package/components/IncidentReport/IncidentInformation.vue +14 -10
- package/components/IncidentReport/IncidentInformationDownload.vue +212 -0
- package/components/IncidentReport/affectedEntities.vue +8 -57
- package/components/SiteSettings.vue +285 -0
- package/components/StockCard.vue +11 -7
- package/components/Tooltip/Info.vue +33 -0
- package/components/VisitorForm.vue +176 -45
- package/components/VisitorManagement.vue +23 -6
- package/composables/useAccessManagement.ts +60 -18
- package/composables/useBulletin.ts +8 -3
- package/composables/useBulletinBoardPermission.ts +48 -0
- package/composables/useCleaningPermission.ts +2 -0
- package/composables/useCommonPermission.ts +29 -1
- package/composables/useEquipmentManagement.ts +63 -0
- package/composables/useFeedback.ts +53 -21
- package/composables/useFile.ts +6 -0
- package/composables/useLocalAuth.ts +29 -1
- package/composables/useSiteSettings.ts +1 -1
- package/composables/useUploadFiles.ts +94 -0
- package/composables/useUtils.ts +152 -53
- package/composables/useVisitor.ts +9 -6
- package/constants/app.ts +12 -0
- package/nuxt.config.ts +2 -0
- package/package.json +3 -1
- package/plugins/vue-draggable-next.client.ts +5 -0
- package/types/feedback.d.ts +5 -2
- package/types/site.d.ts +2 -1
- package/types/user.d.ts +1 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<v-file-input
|
|
4
|
+
v-model="files"
|
|
5
|
+
:label="label"
|
|
6
|
+
accept="image/*"
|
|
7
|
+
:prepend-icon="prependIcon"
|
|
8
|
+
:loading="isFileUploading"
|
|
9
|
+
hide-details
|
|
10
|
+
chips
|
|
11
|
+
multiple
|
|
12
|
+
clearable
|
|
13
|
+
@update:modelValue="handleFileSelect"
|
|
14
|
+
@click:clear="handleClear"
|
|
15
|
+
:hide-input="hasHideInput"
|
|
16
|
+
>
|
|
17
|
+
<template v-slot:append v-if="hasLabel">
|
|
18
|
+
<slot name="append">
|
|
19
|
+
<v-btn color="primary" height="50px" @click="openCameraDialog">
|
|
20
|
+
<v-icon>mdi-camera</v-icon>
|
|
21
|
+
</v-btn>
|
|
22
|
+
</slot>
|
|
23
|
+
</template>
|
|
24
|
+
</v-file-input>
|
|
25
|
+
|
|
26
|
+
<!-- Camera Dialog -->
|
|
27
|
+
<v-dialog
|
|
28
|
+
v-model="showCameraDialog"
|
|
29
|
+
transition="dialog-bottom-transition"
|
|
30
|
+
width="800"
|
|
31
|
+
max-width="800"
|
|
32
|
+
persistent
|
|
33
|
+
@after-enter="startCamera"
|
|
34
|
+
>
|
|
35
|
+
<v-container
|
|
36
|
+
class="d-flex justify-center"
|
|
37
|
+
max-height="90vh"
|
|
38
|
+
width="800"
|
|
39
|
+
max-width="800"
|
|
40
|
+
>
|
|
41
|
+
<v-card elevation="2" class="d-flex flex-column align-center pa-2">
|
|
42
|
+
<v-toolbar>
|
|
43
|
+
<v-card-title class="text-h5">Take a Picture</v-card-title>
|
|
44
|
+
<v-spacer></v-spacer>
|
|
45
|
+
<v-btn
|
|
46
|
+
color="grey-darken-1"
|
|
47
|
+
icon="mdi-close"
|
|
48
|
+
@click="closeCameraDialog"
|
|
49
|
+
></v-btn>
|
|
50
|
+
</v-toolbar>
|
|
51
|
+
|
|
52
|
+
<div
|
|
53
|
+
id="reader"
|
|
54
|
+
class="d-flex justify-center align-center"
|
|
55
|
+
style="
|
|
56
|
+
position: relative;
|
|
57
|
+
width: 500px;
|
|
58
|
+
min-width: 400px;
|
|
59
|
+
height: 400px;
|
|
60
|
+
"
|
|
61
|
+
>
|
|
62
|
+
<video
|
|
63
|
+
ref="video"
|
|
64
|
+
style="flex: 1; height: 400px; min-width: 300px"
|
|
65
|
+
class="video-shutter"
|
|
66
|
+
autoplay
|
|
67
|
+
></video>
|
|
68
|
+
<canvas
|
|
69
|
+
ref="canvas"
|
|
70
|
+
style="flex: 1; height: 400px; min-width: 300px; display: none"
|
|
71
|
+
></canvas>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<v-row align="center" justify="center">
|
|
75
|
+
<v-col cols="6">
|
|
76
|
+
<v-btn color="primary" icon class="mt-4" @click="switchCamera">
|
|
77
|
+
<v-icon>mdi-camera-switch</v-icon>
|
|
78
|
+
</v-btn>
|
|
79
|
+
</v-col>
|
|
80
|
+
<v-col cols="6">
|
|
81
|
+
<v-btn
|
|
82
|
+
color="secondary"
|
|
83
|
+
icon
|
|
84
|
+
class="mt-4"
|
|
85
|
+
@click="captureImageFromCamera"
|
|
86
|
+
>
|
|
87
|
+
<v-icon large>mdi-camera-outline</v-icon>
|
|
88
|
+
</v-btn>
|
|
89
|
+
</v-col>
|
|
90
|
+
</v-row>
|
|
91
|
+
</v-card>
|
|
92
|
+
</v-container>
|
|
93
|
+
</v-dialog>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
|
|
97
|
+
</template>
|
|
98
|
+
|
|
99
|
+
<script setup lang="ts">
|
|
100
|
+
interface FileWithPreview {
|
|
101
|
+
name: string;
|
|
102
|
+
data: File;
|
|
103
|
+
progress: number;
|
|
104
|
+
url: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const props = defineProps({
|
|
108
|
+
label: {
|
|
109
|
+
type: String,
|
|
110
|
+
default: "Select File",
|
|
111
|
+
},
|
|
112
|
+
prependIcon: {
|
|
113
|
+
type: String,
|
|
114
|
+
default: "mdi-paperclip",
|
|
115
|
+
},
|
|
116
|
+
required: {
|
|
117
|
+
type: Boolean,
|
|
118
|
+
default: true,
|
|
119
|
+
},
|
|
120
|
+
initFiles: {
|
|
121
|
+
type: Array,
|
|
122
|
+
},
|
|
123
|
+
hasLabel: {
|
|
124
|
+
type: Boolean,
|
|
125
|
+
default: true,
|
|
126
|
+
},
|
|
127
|
+
hasHideInput: {
|
|
128
|
+
type: Boolean,
|
|
129
|
+
default: false,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const emit = defineEmits<{
|
|
134
|
+
(event: "onFileAttach", payload: Array<{ data: File }>): void;
|
|
135
|
+
(event: "update:files", files: FileWithPreview[]): void;
|
|
136
|
+
(event: "onFileRemoved", payload: { index: number; file: File }): void;
|
|
137
|
+
(event: "onClear"): void;
|
|
138
|
+
}>();
|
|
139
|
+
|
|
140
|
+
const { showUploadedFiles } = useUploadFiles();
|
|
141
|
+
const isFileUploading = ref<boolean>(false);
|
|
142
|
+
|
|
143
|
+
const files = ref<File[]>([]);
|
|
144
|
+
const showCameraDialog = ref(false);
|
|
145
|
+
const video = ref<HTMLVideoElement | null>(null);
|
|
146
|
+
const canvas = ref<HTMLCanvasElement | null>(null);
|
|
147
|
+
const cameraFacingMode = ref<"environment" | "user">("environment");
|
|
148
|
+
|
|
149
|
+
const message = ref("");
|
|
150
|
+
const messageColor = ref("");
|
|
151
|
+
const messageSnackbar = ref(false);
|
|
152
|
+
|
|
153
|
+
function showMessage(msg: string, color: string) {
|
|
154
|
+
message.value = msg;
|
|
155
|
+
messageColor.value = color;
|
|
156
|
+
messageSnackbar.value = true;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
watchEffect(() => {
|
|
160
|
+
files.value = [...(props.initFiles as typeof files.value)];
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const handleFileSelect = async () => {
|
|
164
|
+
if (files.value && files.value.length > 0) {
|
|
165
|
+
const newFiles = files.value.map((file: File) => ({
|
|
166
|
+
name: file.name,
|
|
167
|
+
data: file,
|
|
168
|
+
progress: 0,
|
|
169
|
+
url: URL.createObjectURL(file),
|
|
170
|
+
}));
|
|
171
|
+
|
|
172
|
+
// attachedFiles.value = [...newFiles];
|
|
173
|
+
showUploadedFiles(newFiles);
|
|
174
|
+
|
|
175
|
+
emit("update:files", newFiles);
|
|
176
|
+
} else {
|
|
177
|
+
files.value = [...(props.initFiles as typeof files.value)];
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const handleClear = () => {
|
|
182
|
+
files.value = [];
|
|
183
|
+
emit("onClear");
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const openCameraDialog = () => {
|
|
187
|
+
showCameraDialog.value = true;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const closeCameraDialog = () => {
|
|
191
|
+
showCameraDialog.value = false;
|
|
192
|
+
stopCamera();
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const startCamera = async () => {
|
|
196
|
+
try {
|
|
197
|
+
const constraints = {
|
|
198
|
+
video: {
|
|
199
|
+
facingMode: cameraFacingMode.value,
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
204
|
+
if (video.value) {
|
|
205
|
+
video.value.srcObject = stream;
|
|
206
|
+
video.value.play();
|
|
207
|
+
}
|
|
208
|
+
} catch (error: any) {
|
|
209
|
+
showMessage(error, "error");
|
|
210
|
+
closeCameraDialog();
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const stopCamera = () => {
|
|
215
|
+
if (video.value) {
|
|
216
|
+
const stream = video.value.srcObject as MediaStream;
|
|
217
|
+
if (stream) {
|
|
218
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
const switchCamera = async () => {
|
|
224
|
+
await stopCamera();
|
|
225
|
+
cameraFacingMode.value =
|
|
226
|
+
cameraFacingMode.value === "environment" ? "user" : "environment";
|
|
227
|
+
showMessage(
|
|
228
|
+
`Switched to ${
|
|
229
|
+
cameraFacingMode.value === "environment" ? "Back Camera" : "Front Camera"
|
|
230
|
+
}`,
|
|
231
|
+
"error"
|
|
232
|
+
);
|
|
233
|
+
startCamera();
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const captureImageFromCamera = () => {
|
|
237
|
+
if (!video.value || !canvas.value) return;
|
|
238
|
+
|
|
239
|
+
const context = canvas.value.getContext("2d");
|
|
240
|
+
if (!context) return;
|
|
241
|
+
|
|
242
|
+
// Set canvas dimensions to match video
|
|
243
|
+
canvas.value.width = video.value.videoWidth;
|
|
244
|
+
canvas.value.height = video.value.videoHeight;
|
|
245
|
+
|
|
246
|
+
// Capture the frame
|
|
247
|
+
context.drawImage(video.value, 0, 0, canvas.value.width, canvas.value.height);
|
|
248
|
+
|
|
249
|
+
// Convert to file
|
|
250
|
+
canvas.value.toBlob((blob) => {
|
|
251
|
+
if (!blob) return;
|
|
252
|
+
|
|
253
|
+
const file = new File([blob], `camera-capture-${Date.now()}.png`, {
|
|
254
|
+
type: "image/png",
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
files.value = [file];
|
|
258
|
+
handleFileSelect();
|
|
259
|
+
closeCameraDialog();
|
|
260
|
+
}, "image/png");
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const removeFile = (index) => {
|
|
264
|
+
const removedFile = files.value[index];
|
|
265
|
+
files.value = files.value.filter((_, i) => i !== index);
|
|
266
|
+
emit("onFileRemoved", { index, file: removedFile }); // Emit when a file is removed
|
|
267
|
+
// emit("onFilesUpdated", files.value); // Emit updated files list
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
// Cleanup
|
|
271
|
+
onUnmounted(() => {
|
|
272
|
+
stopCamera();
|
|
273
|
+
});
|
|
274
|
+
</script>
|
|
275
|
+
|
|
276
|
+
<style scoped>
|
|
277
|
+
.custom-chip {
|
|
278
|
+
max-width: 100%;
|
|
279
|
+
height: auto !important;
|
|
280
|
+
white-space: normal;
|
|
281
|
+
padding: 3px 20px;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.chip-text {
|
|
285
|
+
word-break: break-word;
|
|
286
|
+
white-space: normal;
|
|
287
|
+
line-height: 1.2;
|
|
288
|
+
}
|
|
289
|
+
</style>
|
|
@@ -25,158 +25,178 @@
|
|
|
25
25
|
>
|
|
26
26
|
</v-data-table>
|
|
27
27
|
</v-col>
|
|
28
|
+
<div class="w-100 my-8 mx-2">
|
|
29
|
+
<v-table class="responsive-table border elevation-0">
|
|
30
|
+
<thead>
|
|
31
|
+
<tr>
|
|
32
|
+
<th
|
|
33
|
+
v-for="(item, index) in concernHeader"
|
|
34
|
+
:key="index"
|
|
35
|
+
class="text-left font-weight-bold text-black border-e"
|
|
36
|
+
>
|
|
37
|
+
{{ item }}
|
|
38
|
+
</th>
|
|
39
|
+
</tr>
|
|
40
|
+
</thead>
|
|
41
|
+
<tbody>
|
|
42
|
+
<!-- 1 -->
|
|
43
|
+
<tr>
|
|
44
|
+
<td class="border-e">1.</td>
|
|
45
|
+
<td class="border-e">
|
|
46
|
+
What was done to address the incident thereafter?
|
|
47
|
+
</td>
|
|
48
|
+
<td class="border-e pa-2">
|
|
49
|
+
{{ authorities?.incidentThereAfter.actionTaken }}
|
|
50
|
+
</td>
|
|
51
|
+
<td class="border-e pa-2">
|
|
52
|
+
{{ authorities?.incidentThereAfter.status }}
|
|
53
|
+
</td>
|
|
54
|
+
<td class="pa-2">
|
|
55
|
+
{{ authorities?.incidentThereAfter.time }}
|
|
56
|
+
</td>
|
|
57
|
+
</tr>
|
|
28
58
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
</
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
<
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
</
|
|
143
|
-
<
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
</
|
|
149
|
-
</
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
<v-col cols="12" class="px-1">
|
|
171
|
-
<p class="mb-2" style="font-size: 17px; font-weight: 600">
|
|
172
|
-
Any security implication due to the incident?
|
|
173
|
-
</p>
|
|
174
|
-
<p class="mt-2 text-h6 text-capitalize">
|
|
175
|
-
{{ authorities?.securityImplication }}
|
|
176
|
-
</p>
|
|
177
|
-
</v-col>
|
|
178
|
-
</v-row>
|
|
179
|
-
</v-col>
|
|
59
|
+
<!-- 2 -->
|
|
60
|
+
<tr>
|
|
61
|
+
<td class="border-e">2.</td>
|
|
62
|
+
<td class="border-e">
|
|
63
|
+
Were the management notified and who was notified?
|
|
64
|
+
</td>
|
|
65
|
+
<td class="border-e pa-2">
|
|
66
|
+
{{ authorities?.managementNotified.actionTaken }}
|
|
67
|
+
</td>
|
|
68
|
+
<td class="border-e pa-2">
|
|
69
|
+
{{ authorities?.managementNotified.status }}
|
|
70
|
+
</td>
|
|
71
|
+
<td class="pa-2">
|
|
72
|
+
{{ authorities?.managementNotified.time }}
|
|
73
|
+
</td>
|
|
74
|
+
</tr>
|
|
75
|
+
|
|
76
|
+
<!-- 3 -->
|
|
77
|
+
<tr>
|
|
78
|
+
<td class="border-e">3.</td>
|
|
79
|
+
<td class="border-e">How was the incident resolved?</td>
|
|
80
|
+
<td class="border-e pa-2">
|
|
81
|
+
{{ authorities?.incidentResolved.actionTaken }}
|
|
82
|
+
</td>
|
|
83
|
+
<td class="border-e pa-2">
|
|
84
|
+
{{ authorities?.incidentResolved.status }}
|
|
85
|
+
</td>
|
|
86
|
+
<td class="pa-2">
|
|
87
|
+
{{ formatDate(authorities?.incidentResolved.time) }}
|
|
88
|
+
</td>
|
|
89
|
+
</tr>
|
|
90
|
+
|
|
91
|
+
<!-- 4 -->
|
|
92
|
+
<tr>
|
|
93
|
+
<td class="border-e">4.</td>
|
|
94
|
+
<td class="border-e">What was the cause of the incident?</td>
|
|
95
|
+
<td class="border-e pa-2">
|
|
96
|
+
{{ authorities?.causeOfIncident.actionTaken }}
|
|
97
|
+
</td>
|
|
98
|
+
<td class="border-e pa-2">
|
|
99
|
+
{{ authorities?.causeOfIncident.status }}
|
|
100
|
+
</td>
|
|
101
|
+
<td class="pa-2">
|
|
102
|
+
{{ authorities?.causeOfIncident.time }}
|
|
103
|
+
</td>
|
|
104
|
+
</tr>
|
|
105
|
+
|
|
106
|
+
<!-- 5 -->
|
|
107
|
+
<tr>
|
|
108
|
+
<td class="border-e">5.</td>
|
|
109
|
+
<td class="border-e">Any systems used to verify the incident?</td>
|
|
110
|
+
<td class="border-e pa-2">
|
|
111
|
+
{{ authorities?.systemUsed.actionTaken }}
|
|
112
|
+
</td>
|
|
113
|
+
<td class="border-e pa-2">
|
|
114
|
+
{{ authorities?.systemUsed.status }}
|
|
115
|
+
</td>
|
|
116
|
+
<td class="pa-2">
|
|
117
|
+
{{ formatDate(authorities?.systemUsed.time) }}
|
|
118
|
+
</td>
|
|
119
|
+
</tr>
|
|
120
|
+
|
|
121
|
+
<!-- 6 -->
|
|
122
|
+
<tr>
|
|
123
|
+
<td class="border-e">6.</td>
|
|
124
|
+
<td class="border-e">Any CCTV records or pictures taken?</td>
|
|
125
|
+
<td class="border-e pa-2">
|
|
126
|
+
{{ authorities?.cctvRecord.actionTaken }}
|
|
127
|
+
</td>
|
|
128
|
+
<td class="border-e pa-2">
|
|
129
|
+
{{ authorities?.cctvRecord.status }}
|
|
130
|
+
</td>
|
|
131
|
+
<td class="pa-2">
|
|
132
|
+
{{ formatDate(authorities?.cctvRecord.time) }}
|
|
133
|
+
</td>
|
|
134
|
+
</tr>
|
|
135
|
+
|
|
136
|
+
<!-- 7 -->
|
|
137
|
+
<tr>
|
|
138
|
+
<td class="border-e">7.</td>
|
|
139
|
+
<td class="border-e">Particulars of tenant / owner (if any)</td>
|
|
140
|
+
<td class="border-e pa-2">
|
|
141
|
+
{{ authorities?.particularsOwner.actionTaken }}
|
|
142
|
+
</td>
|
|
143
|
+
<td class="border-e pa-2">
|
|
144
|
+
{{ authorities?.particularsOwner.status }}
|
|
145
|
+
</td>
|
|
146
|
+
<td class="pa-2">
|
|
147
|
+
{{ authorities?.particularsOwner.time }}
|
|
148
|
+
</td>
|
|
149
|
+
</tr>
|
|
150
|
+
|
|
151
|
+
<!-- 8 -->
|
|
152
|
+
<tr>
|
|
153
|
+
<td class="border-e">8.</td>
|
|
154
|
+
<td class="border-e">When was the incident resolved?</td>
|
|
155
|
+
<td class="border-e pa-2">
|
|
156
|
+
{{ authorities?.whenIncidentResolve.actionTaken }}
|
|
157
|
+
</td>
|
|
158
|
+
<td class="border-e pa-2">
|
|
159
|
+
{{ authorities?.whenIncidentResolve.status }}
|
|
160
|
+
</td>
|
|
161
|
+
<td class="pa-2">
|
|
162
|
+
{{ authorities?.whenIncidentResolve.time }}
|
|
163
|
+
</td>
|
|
164
|
+
</tr>
|
|
165
|
+
|
|
166
|
+
<!-- 9 -->
|
|
167
|
+
<tr>
|
|
168
|
+
<td class="border-e">9.</td>
|
|
169
|
+
<td class="border-e">Name of Shift In charge</td>
|
|
170
|
+
<td class="border-e pa-2">
|
|
171
|
+
{{ authorities?.nameOfShiftIncharge.actionTaken }}
|
|
172
|
+
</td>
|
|
173
|
+
<td class="border-e pa-2">
|
|
174
|
+
{{ authorities?.nameOfShiftIncharge.status }}
|
|
175
|
+
</td>
|
|
176
|
+
<td class="pa-2">
|
|
177
|
+
{{ authorities?.nameOfShiftIncharge.time }}
|
|
178
|
+
</td>
|
|
179
|
+
</tr>
|
|
180
|
+
|
|
181
|
+
<!-- 10 -->
|
|
182
|
+
<tr>
|
|
183
|
+
<td class="border-e">10.</td>
|
|
184
|
+
<td class="border-e">
|
|
185
|
+
Any security implication due to the incident?
|
|
186
|
+
</td>
|
|
187
|
+
<td class="border-e pa-2">
|
|
188
|
+
{{ authorities?.securityImplication.actionTaken }}
|
|
189
|
+
</td>
|
|
190
|
+
<td class="border-e pa-2">
|
|
191
|
+
{{ authorities?.securityImplication.status }}
|
|
192
|
+
</td>
|
|
193
|
+
<td class="pa-2">
|
|
194
|
+
{{ formatDate(authorities?.securityImplication.time) }}
|
|
195
|
+
</td>
|
|
196
|
+
</tr>
|
|
197
|
+
</tbody>
|
|
198
|
+
</v-table>
|
|
199
|
+
</div>
|
|
180
200
|
</v-row>
|
|
181
201
|
</template>
|
|
182
202
|
|
|
@@ -223,4 +243,22 @@ const authoritiesTableHeader = [
|
|
|
223
243
|
value: "description",
|
|
224
244
|
},
|
|
225
245
|
];
|
|
246
|
+
|
|
247
|
+
const concernHeader = [
|
|
248
|
+
"S/No",
|
|
249
|
+
"Areas of Concern",
|
|
250
|
+
"Actions Taken",
|
|
251
|
+
"Status",
|
|
252
|
+
"Time",
|
|
253
|
+
];
|
|
254
|
+
|
|
255
|
+
const formatDate = (date: Date | string | null) => {
|
|
256
|
+
if (!date) return "";
|
|
257
|
+
|
|
258
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
259
|
+
|
|
260
|
+
if (isNaN(d.getTime())) return ""; // safeguard for invalid date
|
|
261
|
+
|
|
262
|
+
return new Intl.DateTimeFormat("en-GB").format(d);
|
|
263
|
+
};
|
|
226
264
|
</script>
|