@7365admin1/layer-common 1.10.9 → 1.11.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.
- package/CHANGELOG.md +12 -0
- package/components/AccessCardAddForm.vue +1 -1
- package/components/AccessCardAssignToUnitForm.vue +10 -13
- package/components/AccessCardQrTagging.vue +2 -2
- package/components/BulletinBoardManagement.vue +18 -8
- package/components/Chat/SkeletonLoader.vue +71 -0
- package/components/DashboardMain.vue +176 -0
- package/components/DeliveryCompany.vue +240 -0
- package/components/EntryPassInformation.vue +38 -8
- package/components/FeedbackMain.vue +4 -19
- package/components/FileInputWithList.vue +304 -0
- package/components/IncidentReport/Authorities.vue +189 -151
- package/components/IncidentReport/IncidentInformation.vue +28 -12
- package/components/IncidentReport/IncidentInformationDownload.vue +225 -0
- package/components/IncidentReport/affectedEntities.vue +13 -57
- package/components/Signature.vue +133 -0
- package/components/SiteSettings.vue +285 -0
- package/components/SlideCardGroup.vue +194 -0
- package/components/Tooltip/Info.vue +33 -0
- package/components/VisitorForm.vue +65 -3
- package/components/VisitorManagement.vue +23 -6
- package/composables/useAccessManagement.ts +44 -6
- package/composables/useBulletin.ts +8 -3
- package/composables/useBulletinBoardPermission.ts +48 -0
- package/composables/useCleaningPermission.ts +2 -0
- package/composables/useComment.ts +147 -0
- package/composables/useCommonPermission.ts +29 -1
- package/composables/useFeedback.ts +79 -29
- package/composables/useFile.ts +6 -0
- package/composables/usePDFDownload.ts +1 -1
- package/composables/useSiteSettings.ts +1 -1
- package/composables/useVisitor.ts +6 -5
- package/composables/useWorkOrder.ts +61 -26
- 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/public/default-image.svg +4 -0
- package/public/placeholder-image.svg +6 -0
- package/types/comment.d.ts +38 -0
- package/types/dashboard.d.ts +12 -0
- package/types/feedback.d.ts +56 -20
- package/types/site.d.ts +2 -1
- package/types/work-order.d.ts +54 -18
- package/utils/data.ts +31 -0
|
@@ -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">
|
|
@@ -80,6 +27,7 @@
|
|
|
80
27
|
<div class="d-flex align-center">
|
|
81
28
|
NRIC
|
|
82
29
|
<v-icon
|
|
30
|
+
v-if="isShowEyeIcon"
|
|
83
31
|
class="cursor-pointer ml-1"
|
|
84
32
|
size="18"
|
|
85
33
|
color="blue"
|
|
@@ -143,6 +91,10 @@ const props = defineProps({
|
|
|
143
91
|
type: Object as PropType<Record<string, any> | null>,
|
|
144
92
|
required: true,
|
|
145
93
|
},
|
|
94
|
+
isShowEyeIcon: {
|
|
95
|
+
type: Boolean,
|
|
96
|
+
required: true,
|
|
97
|
+
},
|
|
146
98
|
});
|
|
147
99
|
|
|
148
100
|
// emits
|
|
@@ -161,6 +113,14 @@ const injuredTableHeader = [
|
|
|
161
113
|
title: "Contact Number",
|
|
162
114
|
value: "contact",
|
|
163
115
|
},
|
|
116
|
+
{
|
|
117
|
+
title: "Block / Level / Unit Location",
|
|
118
|
+
value: "incidentLocation",
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
title: "Remarks",
|
|
122
|
+
value: "remarks",
|
|
123
|
+
},
|
|
164
124
|
];
|
|
165
125
|
|
|
166
126
|
const damagePropertyTableHeader = [
|
|
@@ -180,10 +140,6 @@ const damagePropertyTableHeader = [
|
|
|
180
140
|
title: "Contact Number",
|
|
181
141
|
value: "contact",
|
|
182
142
|
},
|
|
183
|
-
{
|
|
184
|
-
title: "Action",
|
|
185
|
-
value: "action",
|
|
186
|
-
},
|
|
187
143
|
];
|
|
188
144
|
|
|
189
145
|
const isShowNRIC = ref(false);
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-dialog max-width="700" v-model="isDialogVisible" persistent>
|
|
3
|
+
<v-card>
|
|
4
|
+
<v-toolbar>
|
|
5
|
+
<v-toolbar-title>Signature </v-toolbar-title>
|
|
6
|
+
<v-spacer />
|
|
7
|
+
<v-btn icon="mdi-close" @click="hideModal"></v-btn>
|
|
8
|
+
</v-toolbar>
|
|
9
|
+
<v-card-text>
|
|
10
|
+
<v-row no-gutters>
|
|
11
|
+
<v-col cols="12">
|
|
12
|
+
<div class="text-subtitle-1 text-medium-emphasis ml-2">
|
|
13
|
+
Your signature here
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<NuxtSignaturePad
|
|
17
|
+
ref="signature"
|
|
18
|
+
:options="state.option"
|
|
19
|
+
:width="'100%'"
|
|
20
|
+
:height="'400px'"
|
|
21
|
+
:disabled="state.disabled"
|
|
22
|
+
class="border"
|
|
23
|
+
/>
|
|
24
|
+
</v-col>
|
|
25
|
+
|
|
26
|
+
<v-col cols="12" class="text-center">
|
|
27
|
+
<v-row class="d-flex">
|
|
28
|
+
<v-col class="w-50 px-3">
|
|
29
|
+
<v-btn
|
|
30
|
+
text="clear"
|
|
31
|
+
color="warning"
|
|
32
|
+
type="submit"
|
|
33
|
+
class="my-4 w-100 rounded-lg"
|
|
34
|
+
height="40px"
|
|
35
|
+
@click="clear()"
|
|
36
|
+
/>
|
|
37
|
+
</v-col>
|
|
38
|
+
|
|
39
|
+
<v-col class="w-50 px-3">
|
|
40
|
+
<v-btn
|
|
41
|
+
text="submit"
|
|
42
|
+
color="#1867C0"
|
|
43
|
+
type="submit"
|
|
44
|
+
class="my-4 w-100 rounded-lg"
|
|
45
|
+
height="40px"
|
|
46
|
+
:loading="loading"
|
|
47
|
+
@click="submit"
|
|
48
|
+
:disabled="loading"
|
|
49
|
+
/>
|
|
50
|
+
</v-col>
|
|
51
|
+
</v-row>
|
|
52
|
+
</v-col>
|
|
53
|
+
</v-row>
|
|
54
|
+
</v-card-text>
|
|
55
|
+
</v-card>
|
|
56
|
+
</v-dialog>
|
|
57
|
+
</template>
|
|
58
|
+
|
|
59
|
+
<script setup lang="ts">
|
|
60
|
+
const loading = ref(false);
|
|
61
|
+
// const { isValid } = useAudit();
|
|
62
|
+
// const { uiRequiredInput, uiSetSnackbar } = useUtils();
|
|
63
|
+
|
|
64
|
+
const message = ref("");
|
|
65
|
+
const messageColor = ref("");
|
|
66
|
+
const messageSnackbar = ref(false);
|
|
67
|
+
|
|
68
|
+
function showMessage(msg: string, color: string) {
|
|
69
|
+
message.value = msg;
|
|
70
|
+
messageColor.value = color;
|
|
71
|
+
messageSnackbar.value = true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const signature = ref(null);
|
|
75
|
+
const state = ref({
|
|
76
|
+
count: 0,
|
|
77
|
+
option: {
|
|
78
|
+
penColor: "rgb(0, 0, 0)",
|
|
79
|
+
backgroundColor: "rgb(255,255,255)",
|
|
80
|
+
},
|
|
81
|
+
disabled: false,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const emit = defineEmits<{
|
|
85
|
+
(event: "onSubmit", payload: string): void;
|
|
86
|
+
(event: "onCloseDialog"): void;
|
|
87
|
+
}>();
|
|
88
|
+
let props = defineProps({
|
|
89
|
+
isShowDialog: {
|
|
90
|
+
type: Boolean,
|
|
91
|
+
default: false,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const isDialogVisible = computed(() => props.isShowDialog);
|
|
96
|
+
|
|
97
|
+
const hideModal = () => {
|
|
98
|
+
emit("onCloseDialog");
|
|
99
|
+
};
|
|
100
|
+
const file = ref<File | null>(null);
|
|
101
|
+
const { addFile } = useFile();
|
|
102
|
+
const submit = async () => {
|
|
103
|
+
try {
|
|
104
|
+
loading.value = true;
|
|
105
|
+
const base64 = signature.value.saveSignature();
|
|
106
|
+
const blob = await (await fetch(base64)).blob();
|
|
107
|
+
|
|
108
|
+
file.value = new File([blob], "signature.jpg", { type: "image/jpeg" });
|
|
109
|
+
|
|
110
|
+
const uploadItem = {
|
|
111
|
+
data: file.value,
|
|
112
|
+
name: file.value.name,
|
|
113
|
+
url: URL.createObjectURL(file.value),
|
|
114
|
+
progress: 0,
|
|
115
|
+
type: file.value.type,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const response = await addFile(uploadItem.data);
|
|
119
|
+
|
|
120
|
+
if (response && response.length > 0) {
|
|
121
|
+
emit("onSubmit", response[0]._id);
|
|
122
|
+
}
|
|
123
|
+
} catch (error) {
|
|
124
|
+
showMessage("Error uploading signature. Please try again.", "error");
|
|
125
|
+
} finally {
|
|
126
|
+
loading.value = false;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const clear = () => {
|
|
131
|
+
signature.value.clearCanvas();
|
|
132
|
+
};
|
|
133
|
+
</script>
|
|
@@ -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>
|