@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
|
@@ -89,6 +89,19 @@
|
|
|
89
89
|
</v-row>
|
|
90
90
|
</v-col>
|
|
91
91
|
</v-row>
|
|
92
|
+
<v-row no-gutters class="mt-5">
|
|
93
|
+
<v-col cols="12" sm="3" md="3">
|
|
94
|
+
<InputLabel
|
|
95
|
+
class="text-capitalize"
|
|
96
|
+
title="Time of Response (1st Contact)"
|
|
97
|
+
/>
|
|
98
|
+
<p class="my-1 text-h6">
|
|
99
|
+
{{
|
|
100
|
+
incidentInformation?.incidentTypeAndTime?.timeOfResponse || "NA"
|
|
101
|
+
}}
|
|
102
|
+
</p>
|
|
103
|
+
</v-col>
|
|
104
|
+
</v-row>
|
|
92
105
|
</v-col>
|
|
93
106
|
|
|
94
107
|
<!-- Response/Submission From (1st Contact) -->
|
|
@@ -103,15 +116,6 @@
|
|
|
103
116
|
{{ incidentInformation?.submissionForm?.time || "NA" }}
|
|
104
117
|
</p>
|
|
105
118
|
</v-col>
|
|
106
|
-
<v-col cols="12" sm="4" md="3">
|
|
107
|
-
<InputLabel
|
|
108
|
-
class="text-capitalize"
|
|
109
|
-
title="Time of Report Submission"
|
|
110
|
-
/>
|
|
111
|
-
<p class="my-1 text-h6">
|
|
112
|
-
{{ incidentInformation?.submissionForm?.timeOfResponse || "NA" }}
|
|
113
|
-
</p>
|
|
114
|
-
</v-col>
|
|
115
119
|
<v-col cols="12" sm="4" md="3">
|
|
116
120
|
<InputLabel class="text-capitalize" title="Date" />
|
|
117
121
|
<p class="my-1 text-h6">
|
|
@@ -140,7 +144,7 @@
|
|
|
140
144
|
<div>
|
|
141
145
|
<InputLabel class="text-capitalize mr-1" title="NRIC/WP Number" />
|
|
142
146
|
<v-icon
|
|
143
|
-
|
|
147
|
+
v-if="incidentInformation?.complaintInfo?.nric"
|
|
144
148
|
size="small"
|
|
145
149
|
color="blue"
|
|
146
150
|
class="cursor-pointer"
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters class="px-5 pt-4">
|
|
3
|
+
<!-- Site Information -->
|
|
4
|
+
<p
|
|
5
|
+
class="text-uppercase text-center w-100 text-h6"
|
|
6
|
+
style="background: #aa212a; color: #fff; padding: 10px"
|
|
7
|
+
>
|
|
8
|
+
Incident Report
|
|
9
|
+
</p>
|
|
10
|
+
<v-row no-gutters class="mt-5 border pb-5">
|
|
11
|
+
<p
|
|
12
|
+
class="w-100 text-h6 pa-2 text-white text-center"
|
|
13
|
+
style="background: #fcbf49"
|
|
14
|
+
>
|
|
15
|
+
Incident Information
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<v-col cols="6" class="pa-3 border-b border-e">
|
|
19
|
+
<p class="font-weight-bold">Site</p>
|
|
20
|
+
<p>{{ siteName || "-" }}</p>
|
|
21
|
+
</v-col>
|
|
22
|
+
<v-col cols="6" class="pa-3 border-b">
|
|
23
|
+
<p class="font-weight-bold">Reference</p>
|
|
24
|
+
<p>{{ incidentInformation?.siteInfo?.irNumber || "-" }}</p>
|
|
25
|
+
</v-col>
|
|
26
|
+
|
|
27
|
+
<v-col cols="6" class="pa-3 border-b border-e">
|
|
28
|
+
<p class="font-weight-bold">Place of Incident</p>
|
|
29
|
+
<p>
|
|
30
|
+
{{ incidentInformation?.placeOfIncident?.incidentLocation || "-" }}
|
|
31
|
+
</p>
|
|
32
|
+
</v-col>
|
|
33
|
+
<v-col cols="6" class="pa-3 border-b">
|
|
34
|
+
<p class="font-weight-bold">Type of Incident</p>
|
|
35
|
+
<p>
|
|
36
|
+
{{ incidentInformation?.incidentTypeAndTime?.typeOfIncident || "-" }}
|
|
37
|
+
</p>
|
|
38
|
+
</v-col>
|
|
39
|
+
|
|
40
|
+
<v-col cols="6" class="pa-3 border-b border-e">
|
|
41
|
+
<p class="font-weight-bold">Date of Incident</p>
|
|
42
|
+
<p>
|
|
43
|
+
{{
|
|
44
|
+
toLocalDate(
|
|
45
|
+
incidentInformation?.incidentTypeAndTime?.dateOfIncident
|
|
46
|
+
) || "NA"
|
|
47
|
+
}}
|
|
48
|
+
</p>
|
|
49
|
+
</v-col>
|
|
50
|
+
<v-col cols="6" class="pa-3 border-b">
|
|
51
|
+
<p class="font-weight-bold">Incident Start Time</p>
|
|
52
|
+
<p>
|
|
53
|
+
{{ incidentInformation?.incidentTypeAndTime?.incidentStart || "-" }}
|
|
54
|
+
</p>
|
|
55
|
+
</v-col>
|
|
56
|
+
|
|
57
|
+
<v-col cols="6" class="pa-3 border-b border-e">
|
|
58
|
+
<p class="font-weight-bold">Time of Response (From 1st Contact)</p>
|
|
59
|
+
<p>
|
|
60
|
+
{{ incidentInformation?.incidentTypeAndTime?.timeOfResponse || "-" }}
|
|
61
|
+
</p>
|
|
62
|
+
</v-col>
|
|
63
|
+
<v-col cols="6" class="pa-3 border-b">
|
|
64
|
+
<p class="font-weight-bold">Incident End Time</p>
|
|
65
|
+
<p>
|
|
66
|
+
{{ incidentInformation?.incidentTypeAndTime?.incidentEnd || "-" }}
|
|
67
|
+
</p>
|
|
68
|
+
</v-col>
|
|
69
|
+
|
|
70
|
+
<v-col cols="6" class="pa-3 border-b border-e">
|
|
71
|
+
<p class="font-weight-bold">Date of Report Submission</p>
|
|
72
|
+
{{
|
|
73
|
+
toLocalDate(incidentInformation?.submissionForm?.dateOfReport) || "NA"
|
|
74
|
+
}}
|
|
75
|
+
</v-col>
|
|
76
|
+
<v-col cols="6" class="pa-3 border-b">
|
|
77
|
+
<p class="font-weight-bold">Time of Report Submission</p>
|
|
78
|
+
<p>{{ incidentInformation?.submissionForm?.time || "-" }}</p>
|
|
79
|
+
</v-col>
|
|
80
|
+
|
|
81
|
+
<v-col cols="6" class="pa-3 border-b border-e">
|
|
82
|
+
<p class="font-weight-bold">Report Submitted By</p>
|
|
83
|
+
<p>{{ incidentInformation?.siteInfo?.submittedBy || "-" }}</p>
|
|
84
|
+
</v-col>
|
|
85
|
+
<v-col cols="6" class="pa-3 border-b">
|
|
86
|
+
<p class="font-weight-bold">Designation</p>
|
|
87
|
+
<p>{{ incidentInformation?.siteInfo?.designation || "-" }}</p>
|
|
88
|
+
</v-col>
|
|
89
|
+
|
|
90
|
+
<v-col cols="4" class="pa-3 border-b border-e">
|
|
91
|
+
<p class="font-weight-bold">Name of Informant/Complainant</p>
|
|
92
|
+
<p>{{ incidentInformation?.complaintInfo?.complainant || "-" }}</p>
|
|
93
|
+
</v-col>
|
|
94
|
+
<v-col cols="4" class="pa-3 border-b border-e">
|
|
95
|
+
<p class="font-weight-bold">Contact No.</p>
|
|
96
|
+
<p>{{ incidentInformation?.complaintInfo?.contact || "-" }}</p>
|
|
97
|
+
</v-col>
|
|
98
|
+
<v-col cols="4" class="pa-3 border-b">
|
|
99
|
+
<p class="font-weight-bold">NRIC/WP No.</p>
|
|
100
|
+
<p>
|
|
101
|
+
<v-icon
|
|
102
|
+
v-if="incidentInformation?.complaintInfo?.nric"
|
|
103
|
+
size="small"
|
|
104
|
+
color="blue"
|
|
105
|
+
class="cursor-pointer"
|
|
106
|
+
@click="showNRICComplainant = !showNRICComplainant"
|
|
107
|
+
>
|
|
108
|
+
{{ showNRICComplainant ? "mdi-eye-off" : "mdi-eye" }}
|
|
109
|
+
</v-icon>
|
|
110
|
+
</p>
|
|
111
|
+
</v-col>
|
|
112
|
+
|
|
113
|
+
<v-col cols="4" class="pa-3 border-b border-e">
|
|
114
|
+
<p class="font-weight-bold">
|
|
115
|
+
Name of Recipient of Complaint (1st Contact)
|
|
116
|
+
</p>
|
|
117
|
+
<p>{{ incidentInformation?.recipientOfComplaint?.recipient || "-" }}</p>
|
|
118
|
+
</v-col>
|
|
119
|
+
<v-col cols="4" class="pa-3 border-b border-e">
|
|
120
|
+
<p class="font-weight-bold">Contact No.</p>
|
|
121
|
+
<p>{{ incidentInformation?.recipientOfComplaint?.contact || "-" }}</p>
|
|
122
|
+
</v-col>
|
|
123
|
+
<v-col cols="4" class="pa-3 border-b">
|
|
124
|
+
<p class="font-weight-bold">NRIC/WP No.</p>
|
|
125
|
+
<p>
|
|
126
|
+
{{
|
|
127
|
+
showNRICRecipient
|
|
128
|
+
? incidentInformation?.recipientOfComplaint?.nric || "-"
|
|
129
|
+
: maskNRIC(incidentInformation?.recipientOfComplaint?.nric)
|
|
130
|
+
}}
|
|
131
|
+
</p>
|
|
132
|
+
</v-col>
|
|
133
|
+
|
|
134
|
+
<v-col cols="12" class="pa-3 border-b border-e">
|
|
135
|
+
<p class="font-weight-bold">Complaint Received through</p>
|
|
136
|
+
<p
|
|
137
|
+
v-if="
|
|
138
|
+
incidentInformation?.complaintReceivedTo?.receivedVia != 'others'
|
|
139
|
+
"
|
|
140
|
+
>
|
|
141
|
+
{{ incidentInformation?.complaintReceivedTo?.receivedVia || "-" }}
|
|
142
|
+
</p>
|
|
143
|
+
|
|
144
|
+
<p v-else>
|
|
145
|
+
{{
|
|
146
|
+
incidentInformation?.complaintReceivedTo?.otherDescription || "-"
|
|
147
|
+
}}
|
|
148
|
+
</p>
|
|
149
|
+
</v-col>
|
|
150
|
+
<v-col cols="6" class="pa-3">
|
|
151
|
+
<p class="font-weight-bold">Brief Description</p>
|
|
152
|
+
<p>
|
|
153
|
+
{{
|
|
154
|
+
incidentInformation?.complaintReceivedTo?.briefDescription || "-"
|
|
155
|
+
}}
|
|
156
|
+
</p>
|
|
157
|
+
</v-col>
|
|
158
|
+
</v-row>
|
|
159
|
+
</v-row>
|
|
160
|
+
</template>
|
|
161
|
+
|
|
162
|
+
<script lang="ts" setup>
|
|
163
|
+
definePageMeta({
|
|
164
|
+
middleware: ["01-auth", "02-org"],
|
|
165
|
+
memberOnly: true,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// props
|
|
169
|
+
const props = defineProps({
|
|
170
|
+
incidentInformation: {
|
|
171
|
+
type: Object as PropType<Record<string, any> | null>,
|
|
172
|
+
required: true,
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// utilities
|
|
177
|
+
const { getSiteById } = useSiteSettings();
|
|
178
|
+
|
|
179
|
+
// state
|
|
180
|
+
const siteName = ref("");
|
|
181
|
+
|
|
182
|
+
const siteId = computed(() => props.incidentInformation?.siteInfo?.site);
|
|
183
|
+
|
|
184
|
+
const showNRICComplainant = ref(false);
|
|
185
|
+
const showNRICRecipient = ref(false);
|
|
186
|
+
|
|
187
|
+
watch(
|
|
188
|
+
siteId,
|
|
189
|
+
async (newSiteId) => {
|
|
190
|
+
if (!newSiteId) return;
|
|
191
|
+
|
|
192
|
+
const siteDataValue = await getSiteById(newSiteId);
|
|
193
|
+
|
|
194
|
+
siteName.value = siteDataValue?.name ?? "";
|
|
195
|
+
},
|
|
196
|
+
{ immediate: true }
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
function toLocalDate(utcString: string) {
|
|
200
|
+
return new Date(utcString).toLocaleString("en-US", {
|
|
201
|
+
year: "numeric",
|
|
202
|
+
month: "2-digit",
|
|
203
|
+
day: "2-digit",
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const maskNRIC = (value: any) => {
|
|
208
|
+
if (!value) return "NA";
|
|
209
|
+
|
|
210
|
+
return value.replace(/.(?=.{3})/g, "*");
|
|
211
|
+
};
|
|
212
|
+
</script>
|
|
@@ -1,58 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters class="px-5 pt-4">
|
|
3
|
-
<!-- Any unit affected -->
|
|
4
|
-
<v-col cols="12" class="border-b pb-5 mb-5 mt-1">
|
|
5
|
-
<p class="mb-2" style="font-size: 17px; font-weight: 600">
|
|
6
|
-
Any unit affected?
|
|
7
|
-
</p>
|
|
8
|
-
<p
|
|
9
|
-
v-if="affectedEntities?.anyUnitAffectedValue == 'no'"
|
|
10
|
-
class="mt-2 text-h6 text-capitalize"
|
|
11
|
-
>
|
|
12
|
-
{{ affectedEntities?.anyUnitAffectedValue }}
|
|
13
|
-
</p>
|
|
14
|
-
<!-- Block Level Unit Section -->
|
|
15
|
-
<v-row v-else no-gutters class="d-flex align-center mt-5">
|
|
16
|
-
<v-row
|
|
17
|
-
v-if="affectedEntities?.affectedUnit.hasOwnProperty('block')"
|
|
18
|
-
no-gutters
|
|
19
|
-
>
|
|
20
|
-
<v-col cols="12" sm="4">
|
|
21
|
-
<InputLabel class="text-capitalize" title="Block" />
|
|
22
|
-
<p class="my-1 text-h6">
|
|
23
|
-
{{ affectedEntities?.affectedUnit?.block }}
|
|
24
|
-
</p>
|
|
25
|
-
</v-col>
|
|
26
|
-
<v-col cols="12" sm="4">
|
|
27
|
-
<InputLabel class="text-capitalize" title="Level" />
|
|
28
|
-
<p class="my-1 text-h6">
|
|
29
|
-
{{ affectedEntities?.affectedUnit?.level }}
|
|
30
|
-
</p>
|
|
31
|
-
</v-col>
|
|
32
|
-
<v-col cols="12" sm="4">
|
|
33
|
-
<InputLabel class="text-capitalize" title="Unit" />
|
|
34
|
-
<p class="my-1 text-h6">
|
|
35
|
-
{{ affectedEntities?.affectedUnit?.unit }}
|
|
36
|
-
</p>
|
|
37
|
-
</v-col>
|
|
38
|
-
</v-row>
|
|
39
|
-
|
|
40
|
-
<v-col v-else cols="12" class="px-1 mb-0">
|
|
41
|
-
<InputLabel class="text-capitalize" title="Location" />
|
|
42
|
-
<p class="my-1 text-h6 text-capitalize">
|
|
43
|
-
{{ affectedEntities?.affectedUnit?.other }}
|
|
44
|
-
</p>
|
|
45
|
-
</v-col>
|
|
46
|
-
|
|
47
|
-
<v-col cols="12" class="px-1 mb-0 mt-5">
|
|
48
|
-
<InputLabel class="text-capitalize" title="Remarks" />
|
|
49
|
-
<p class="my-1 text-h6 text-capitalize">
|
|
50
|
-
{{ affectedEntities?.affectedUnit?.remarks }}
|
|
51
|
-
</p>
|
|
52
|
-
</v-col>
|
|
53
|
-
</v-row>
|
|
54
|
-
</v-col>
|
|
55
|
-
|
|
56
3
|
<!-- Anyone affected/injured -->
|
|
57
4
|
<v-col cols="12" class="border-b pb-5 mb-5 mt-1">
|
|
58
5
|
<p class="mb-2" style="font-size: 17px; font-weight: 600">
|
|
@@ -161,6 +108,14 @@ const injuredTableHeader = [
|
|
|
161
108
|
title: "Contact Number",
|
|
162
109
|
value: "contact",
|
|
163
110
|
},
|
|
111
|
+
{
|
|
112
|
+
title: "Block / Level / Unit Location",
|
|
113
|
+
value: "incidentLocation",
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
title: "Remarks",
|
|
117
|
+
value: "remarks",
|
|
118
|
+
},
|
|
164
119
|
];
|
|
165
120
|
|
|
166
121
|
const damagePropertyTableHeader = [
|
|
@@ -180,10 +135,6 @@ const damagePropertyTableHeader = [
|
|
|
180
135
|
title: "Contact Number",
|
|
181
136
|
value: "contact",
|
|
182
137
|
},
|
|
183
|
-
{
|
|
184
|
-
title: "Action",
|
|
185
|
-
value: "action",
|
|
186
|
-
},
|
|
187
138
|
];
|
|
188
139
|
|
|
189
140
|
const isShowNRIC = ref(false);
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters>
|
|
3
|
+
<v-expansion-panels multiple v-model="openPanels" >
|
|
4
|
+
|
|
5
|
+
<!-- SITE SETTINGS -->
|
|
6
|
+
<v-expansion-panel color="primary">
|
|
7
|
+
<v-expansion-panel-title>
|
|
8
|
+
<v-icon class="mr-2">mdi-cog</v-icon>
|
|
9
|
+
Site Settings
|
|
10
|
+
</v-expansion-panel-title>
|
|
11
|
+
|
|
12
|
+
<v-expansion-panel-text>
|
|
13
|
+
<v-row no-gutters class="d-flex justify-center">
|
|
14
|
+
<v-col cols="12">
|
|
15
|
+
<v-row no-gutters>
|
|
16
|
+
<v-col cols="12">
|
|
17
|
+
<span class="text-h4 font-weight-bold"> Site Settings </span>
|
|
18
|
+
</v-col>
|
|
19
|
+
|
|
20
|
+
<v-col cols="12">
|
|
21
|
+
<v-row no-gutters>
|
|
22
|
+
<v-col cols="12" lg="4" class="mt-2">
|
|
23
|
+
<NumberSettingField v-model="blocks" title="No. of blocks" type="blocks"
|
|
24
|
+
:read-only="!canManageSiteSettings"
|
|
25
|
+
:existing-block-number="existingBlockNumber" :site-id="siteId"
|
|
26
|
+
:disabled="existingBlockNumber === blocks" @success="refreshSiteData" />
|
|
27
|
+
</v-col>
|
|
28
|
+
</v-row>
|
|
29
|
+
</v-col>
|
|
30
|
+
|
|
31
|
+
<v-col cols="12">
|
|
32
|
+
<v-row no-gutters>
|
|
33
|
+
<v-col cols="12" lg="4" class="mt-2">
|
|
34
|
+
<NumberSettingField v-model="guardPosts" title="No. of guard posts"
|
|
35
|
+
type="guard_posts" :read-only="!canManageSiteSettings"
|
|
36
|
+
:existing-guard-posts-number="existingGuardPostNumber" :site-id="siteId"
|
|
37
|
+
:disabled="existingGuardPostNumber === guardPosts"
|
|
38
|
+
@success="refreshSiteData" />
|
|
39
|
+
</v-col>
|
|
40
|
+
</v-row>
|
|
41
|
+
</v-col>
|
|
42
|
+
|
|
43
|
+
<v-col cols="12">
|
|
44
|
+
<v-row no-gutters>
|
|
45
|
+
<v-col cols="12" lg="4" class="mt-2">
|
|
46
|
+
<v-row no-gutters>
|
|
47
|
+
<v-form v-model="gracePeriodValid">
|
|
48
|
+
<v-row>
|
|
49
|
+
<v-col cols="6">
|
|
50
|
+
<InputLabel class="text-capitalize font-weight-bold"
|
|
51
|
+
title="Grace Period" required />
|
|
52
|
+
<v-text-field v-model="gracePeriod" type="number"
|
|
53
|
+
density="comfortable" :readonly="!canManageSiteSettings"
|
|
54
|
+
:rules="[requiredRule]" />
|
|
55
|
+
</v-col>
|
|
56
|
+
|
|
57
|
+
<v-col cols="6">
|
|
58
|
+
<v-btn v-if="canManageSiteSettings" color="primary"
|
|
59
|
+
class="text-none mt-6" size="large" variant="flat"
|
|
60
|
+
:disabled="!gracePeriodValid ||
|
|
61
|
+
existingGracePeriodNumber === gracePeriod
|
|
62
|
+
" :loading="gracePeriodLoading" text="Save"
|
|
63
|
+
@click="handleSaveGracePeriod" />
|
|
64
|
+
</v-col>
|
|
65
|
+
</v-row>
|
|
66
|
+
</v-form>
|
|
67
|
+
</v-row>
|
|
68
|
+
</v-col>
|
|
69
|
+
</v-row>
|
|
70
|
+
</v-col>
|
|
71
|
+
|
|
72
|
+
</v-row>
|
|
73
|
+
</v-col>
|
|
74
|
+
</v-row>
|
|
75
|
+
</v-expansion-panel-text>
|
|
76
|
+
</v-expansion-panel>
|
|
77
|
+
|
|
78
|
+
<!-- ANPR CAMERA -->
|
|
79
|
+
<v-expansion-panel color="primary">
|
|
80
|
+
<v-expansion-panel-title>
|
|
81
|
+
<v-icon class="mr-2">mdi-camera</v-icon>
|
|
82
|
+
ANPR Camera
|
|
83
|
+
</v-expansion-panel-title>
|
|
84
|
+
|
|
85
|
+
<v-expansion-panel-text>
|
|
86
|
+
<CameraMain :site="siteId" :read-only="!canManageSiteSettings"
|
|
87
|
+
:guard-posts="siteData?.metadata?.guardPosts" />
|
|
88
|
+
</v-expansion-panel-text>
|
|
89
|
+
</v-expansion-panel>
|
|
90
|
+
|
|
91
|
+
<!-- CCTV CAMERA -->
|
|
92
|
+
<v-expansion-panel color="primary">
|
|
93
|
+
<v-expansion-panel-title>
|
|
94
|
+
<v-icon class="mr-2">mdi-cctv</v-icon>
|
|
95
|
+
CCTV Camera
|
|
96
|
+
</v-expansion-panel-title>
|
|
97
|
+
|
|
98
|
+
<v-expansion-panel-text>
|
|
99
|
+
<CameraMain :site="siteId" type="ip" :read-only="!canManageSiteSettings" />
|
|
100
|
+
</v-expansion-panel-text>
|
|
101
|
+
</v-expansion-panel>
|
|
102
|
+
|
|
103
|
+
<v-expansion-panel color="primary">
|
|
104
|
+
<v-expansion-panel-title>
|
|
105
|
+
<v-icon class="mr-2">mdi-format-list-numbered</v-icon>
|
|
106
|
+
Work Order Settings
|
|
107
|
+
</v-expansion-panel-title>
|
|
108
|
+
|
|
109
|
+
<v-expansion-panel-text>
|
|
110
|
+
<v-text-field v-model="prefix" label="Prefix" :disabled="isLoading || !canManageSiteSettings"
|
|
111
|
+
@input="handleInput" />
|
|
112
|
+
|
|
113
|
+
<v-select v-model="noOfDigits" :items="[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" label="No. of Digits"
|
|
114
|
+
:disabled="isLoading || !canManageSiteSettings" />
|
|
115
|
+
|
|
116
|
+
<v-text-field v-model="orderNumberPreview" label="Preview" readonly />
|
|
117
|
+
|
|
118
|
+
<v-btn v-if="canManageSiteSettings" class="mt-2" :loading="isLoading" @click="save">
|
|
119
|
+
Save
|
|
120
|
+
</v-btn>
|
|
121
|
+
</v-expansion-panel-text>
|
|
122
|
+
</v-expansion-panel>
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
<v-expansion-panel color="primary">
|
|
126
|
+
<v-expansion-panel-title>
|
|
127
|
+
<v-icon class="mr-2">mdi-truck</v-icon>
|
|
128
|
+
Delivery Companies
|
|
129
|
+
</v-expansion-panel-title>
|
|
130
|
+
<v-expansion-panel-text class="">
|
|
131
|
+
<DeliveryCompany :site="siteId" v-model:initial="deliveryCompanies" @refresh-site="refreshSiteData" @update:companiesValue="handleUpdateCompanies"
|
|
132
|
+
:read-only="!canManageSiteSettings" />
|
|
133
|
+
</v-expansion-panel-text>
|
|
134
|
+
|
|
135
|
+
</v-expansion-panel>
|
|
136
|
+
|
|
137
|
+
</v-expansion-panels>
|
|
138
|
+
|
|
139
|
+
<Snackbar v-model="toast.show" :text="toast.message" :color="toast.color" />
|
|
140
|
+
</v-row>
|
|
141
|
+
</template>
|
|
142
|
+
|
|
143
|
+
<script setup lang="ts">
|
|
144
|
+
const props = defineProps({
|
|
145
|
+
siteId: { type: String, required: true },
|
|
146
|
+
canManageSiteSettings: { type: Boolean, default: false }
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
const openPanels = ref([0]) // default open first
|
|
150
|
+
|
|
151
|
+
const { getSiteById, updateSitebyId } = useSiteSettings()
|
|
152
|
+
const { requiredRule } = useUtils()
|
|
153
|
+
const { getFileUrl } = useFile()
|
|
154
|
+
const { getWorkOrderSettings, createWorkOrderSettings } = useWorkOrder()
|
|
155
|
+
|
|
156
|
+
const blocks = ref(0)
|
|
157
|
+
const guardPosts = ref(0)
|
|
158
|
+
const gracePeriod = ref(0)
|
|
159
|
+
|
|
160
|
+
const existingBlockNumber = ref(0)
|
|
161
|
+
const existingGuardPostNumber = ref(0)
|
|
162
|
+
const existingGracePeriodNumber = ref(0)
|
|
163
|
+
|
|
164
|
+
const gracePeriodValid = ref(false)
|
|
165
|
+
const gracePeriodLoading = ref(false)
|
|
166
|
+
const deliveryCompanies = ref<string[]>([])
|
|
167
|
+
|
|
168
|
+
const siteLogo = ref<any[]>([])
|
|
169
|
+
const uploadedSiteLogo = ref("")
|
|
170
|
+
|
|
171
|
+
const prefix = ref("")
|
|
172
|
+
const noOfDigits = ref(1)
|
|
173
|
+
const isLoading = ref(false)
|
|
174
|
+
|
|
175
|
+
const toast = reactive({
|
|
176
|
+
show: false,
|
|
177
|
+
message: "",
|
|
178
|
+
color: ""
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
const { data: siteData, refresh: refreshSiteData } = await useLazyAsyncData(
|
|
182
|
+
`site-${props.siteId}`,
|
|
183
|
+
() => getSiteById(props.siteId)
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
watch(siteData, (val: TSite) => {
|
|
187
|
+
if (!val) return
|
|
188
|
+
|
|
189
|
+
blocks.value = val.metadata?.block || 0
|
|
190
|
+
guardPosts.value = val.metadata?.guardPosts || 0
|
|
191
|
+
gracePeriod.value = val.metadata?.gracePeriod || 0
|
|
192
|
+
|
|
193
|
+
existingBlockNumber.value = blocks.value
|
|
194
|
+
existingGuardPostNumber.value = guardPosts.value
|
|
195
|
+
existingGracePeriodNumber.value = gracePeriod.value
|
|
196
|
+
deliveryCompanies.value = Array.isArray(val.deliveryCompanyList) ? [...val.deliveryCompanyList] : []
|
|
197
|
+
|
|
198
|
+
uploadedSiteLogo.value = val.metadata?.incidentLogo || ""
|
|
199
|
+
}, { immediate: true })
|
|
200
|
+
|
|
201
|
+
async function handleSaveGracePeriod() {
|
|
202
|
+
gracePeriodLoading.value = true
|
|
203
|
+
try {
|
|
204
|
+
await updateSitebyId(props.siteId, {
|
|
205
|
+
field: "metadata.gracePeriod",
|
|
206
|
+
value: gracePeriod.value
|
|
207
|
+
})
|
|
208
|
+
show("Grace period updated", "success")
|
|
209
|
+
refreshSiteData()
|
|
210
|
+
} catch (e: any) {
|
|
211
|
+
show(e?.data?.message || "Error updating grace period", "error")
|
|
212
|
+
} finally {
|
|
213
|
+
gracePeriodLoading.value = false
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function handleLogo(action: string) {
|
|
218
|
+
try {
|
|
219
|
+
await updateSitebyId(props.siteId, {
|
|
220
|
+
field: "metadata.incidentLogo",
|
|
221
|
+
value: action === "add" ? siteLogo.value[0] : 0
|
|
222
|
+
})
|
|
223
|
+
show("Logo updated", "success")
|
|
224
|
+
refreshSiteData()
|
|
225
|
+
} catch {
|
|
226
|
+
show("Error updating logo", "error")
|
|
227
|
+
} finally {
|
|
228
|
+
siteLogo.value = []
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const onUploadedLogoPreview = () => {
|
|
233
|
+
if (!uploadedSiteLogo.value) return ""
|
|
234
|
+
return getFileUrl(uploadedSiteLogo.value)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const { data: workOrderSetting } = await useLazyAsyncData(
|
|
238
|
+
`work-${props.siteId}`,
|
|
239
|
+
() => getWorkOrderSettings({ site: props.siteId, service: "Security" })
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
watchEffect(() => {
|
|
243
|
+
if (workOrderSetting.value) {
|
|
244
|
+
prefix.value = workOrderSetting.value.prefix
|
|
245
|
+
noOfDigits.value = workOrderSetting.value.noOfDigits
|
|
246
|
+
}
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
function handleInput(e: any) {
|
|
250
|
+
prefix.value = e.target.value
|
|
251
|
+
.replace(/[^A-Z]/g, "")
|
|
252
|
+
.toUpperCase()
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function handleUpdateCompanies(value: string[]) {
|
|
256
|
+
deliveryCompanies.value = value
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const orderNumberPreview = computed(() => {
|
|
260
|
+
return `${prefix.value}${"0".repeat(noOfDigits.value - 1)}1`
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
async function save() {
|
|
264
|
+
try {
|
|
265
|
+
isLoading.value = true
|
|
266
|
+
await createWorkOrderSettings({
|
|
267
|
+
site: props.siteId,
|
|
268
|
+
service: "Security",
|
|
269
|
+
prefix: prefix.value,
|
|
270
|
+
noOfDigits: noOfDigits.value
|
|
271
|
+
})
|
|
272
|
+
show("Saved successfully", "success")
|
|
273
|
+
} catch {
|
|
274
|
+
show("Error saving", "error")
|
|
275
|
+
} finally {
|
|
276
|
+
isLoading.value = false
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function show(message: string, color: string) {
|
|
281
|
+
toast.show = true
|
|
282
|
+
toast.message = message
|
|
283
|
+
toast.color = color
|
|
284
|
+
}
|
|
285
|
+
</script>
|
package/components/StockCard.vue
CHANGED
|
@@ -110,6 +110,10 @@
|
|
|
110
110
|
</template>
|
|
111
111
|
|
|
112
112
|
<script setup lang="ts">
|
|
113
|
+
import useEquipment from "../composables/useEquipment";
|
|
114
|
+
import useStock from "../composables/useStock";
|
|
115
|
+
import useUtils from "../composables/useUtils";
|
|
116
|
+
|
|
113
117
|
const props = defineProps({
|
|
114
118
|
orgId: { type: String, default: "" },
|
|
115
119
|
site: { type: String, default: "" },
|
|
@@ -126,18 +130,18 @@ const supply = ref({
|
|
|
126
130
|
remarks: "",
|
|
127
131
|
});
|
|
128
132
|
|
|
129
|
-
const {
|
|
133
|
+
const { getEquipmentById } = useEquipment();
|
|
130
134
|
|
|
131
135
|
const supplyId = useRoute().params.id as string;
|
|
132
136
|
|
|
133
|
-
const { data:
|
|
134
|
-
`get-
|
|
135
|
-
() =>
|
|
137
|
+
const { data: getEquipmentByIdReq } = await useLazyAsyncData(
|
|
138
|
+
`get-equipment-by-id-${supplyId}`,
|
|
139
|
+
() => getEquipmentById(supplyId)
|
|
136
140
|
);
|
|
137
141
|
|
|
138
142
|
watchEffect(() => {
|
|
139
|
-
if (
|
|
140
|
-
supply.value =
|
|
143
|
+
if (getEquipmentByIdReq?.value) {
|
|
144
|
+
supply.value = getEquipmentByIdReq.value as any;
|
|
141
145
|
}
|
|
142
146
|
});
|
|
143
147
|
|
|
@@ -163,7 +167,7 @@ const {
|
|
|
163
167
|
() => getStockBySupply(props.site, supplyId),
|
|
164
168
|
{
|
|
165
169
|
watch: [page, () => props.site, () => supplyId],
|
|
166
|
-
}
|
|
170
|
+
}
|
|
167
171
|
);
|
|
168
172
|
|
|
169
173
|
watchEffect(() => {
|