@iservice365/layer-common 1.3.0 → 1.3.2
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/BuildingForm.vue +303 -0
- package/components/BuildingManagement/buildings.vue +395 -0
- package/components/BuildingManagement/units.vue +412 -0
- package/components/BuildingUnitFormAdd.vue +441 -0
- package/components/BuildingUnitFormEdit.vue +382 -0
- package/components/Chat/Information.vue +1 -1
- package/components/Input/NRICNumber.vue +12 -0
- package/components/TableMain.vue +5 -1
- package/components/VisitorForm.vue +114 -279
- package/components/VisitorManagement.vue +89 -169
- package/components/WorkOrder/Create.vue +5 -1
- package/composables/useBuilding.ts +1 -1
- package/composables/useCommonPermission.ts +77 -0
- package/composables/usePeople.ts +13 -5
- package/composables/useVisitor.ts +74 -51
- package/package.json +1 -1
- package/types/building.d.ts +6 -0
- package/types/people.d.ts +2 -1
- package/types/visitor.d.ts +1 -1
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-card width="100%">
|
|
3
|
+
<v-toolbar>
|
|
4
|
+
<v-row no-gutters class="fill-height px-6" align="center">
|
|
5
|
+
<span class="font-weight-bold text-h5"> Edit Unit </span>
|
|
6
|
+
</v-row>
|
|
7
|
+
</v-toolbar>
|
|
8
|
+
<v-card-text style="max-height: 100vh; overflow-y: auto">
|
|
9
|
+
<v-form v-model="validForm" :disabled="disable">
|
|
10
|
+
<v-row no-gutters>
|
|
11
|
+
<v-col cols="12">
|
|
12
|
+
<v-row>
|
|
13
|
+
<v-col cols="12" class="mt-2">
|
|
14
|
+
<v-row no-gutters>
|
|
15
|
+
<InputLabel
|
|
16
|
+
class="text-capitalize font-weight-bold"
|
|
17
|
+
title="Building"
|
|
18
|
+
/>
|
|
19
|
+
<v-col cols="12">
|
|
20
|
+
{{ buildingUnit.buildingName }}
|
|
21
|
+
</v-col>
|
|
22
|
+
</v-row>
|
|
23
|
+
</v-col>
|
|
24
|
+
</v-row>
|
|
25
|
+
</v-col>
|
|
26
|
+
|
|
27
|
+
<v-col cols="12">
|
|
28
|
+
<v-row>
|
|
29
|
+
<v-col cols="12" class="mt-2">
|
|
30
|
+
<v-row no-gutters>
|
|
31
|
+
<InputLabel
|
|
32
|
+
class="text-capitalize font-weight-bold"
|
|
33
|
+
title="Block"
|
|
34
|
+
/>
|
|
35
|
+
<v-col cols="12">
|
|
36
|
+
{{ buildingUnit.block }}
|
|
37
|
+
</v-col>
|
|
38
|
+
</v-row>
|
|
39
|
+
</v-col>
|
|
40
|
+
</v-row>
|
|
41
|
+
</v-col>
|
|
42
|
+
|
|
43
|
+
<v-col cols="12">
|
|
44
|
+
<v-row>
|
|
45
|
+
<v-col cols="12" class="mt-2">
|
|
46
|
+
<v-row no-gutters>
|
|
47
|
+
<InputLabel
|
|
48
|
+
class="text-capitalize font-weight-bold"
|
|
49
|
+
title="Unit Name"
|
|
50
|
+
/>
|
|
51
|
+
<v-col cols="12">
|
|
52
|
+
<v-text-field
|
|
53
|
+
v-model="buildingUnit.name"
|
|
54
|
+
density="comfortable"
|
|
55
|
+
:rules="[requiredRule]"
|
|
56
|
+
></v-text-field>
|
|
57
|
+
</v-col>
|
|
58
|
+
</v-row>
|
|
59
|
+
</v-col>
|
|
60
|
+
</v-row>
|
|
61
|
+
</v-col>
|
|
62
|
+
|
|
63
|
+
<v-col cols="12">
|
|
64
|
+
<v-row>
|
|
65
|
+
<v-col cols="12" class="mt-2">
|
|
66
|
+
<v-row no-gutters>
|
|
67
|
+
<InputLabel
|
|
68
|
+
class="text-capitalize"
|
|
69
|
+
title="Company Name"
|
|
70
|
+
required
|
|
71
|
+
/>
|
|
72
|
+
<v-col cols="12">
|
|
73
|
+
<v-text-field
|
|
74
|
+
v-model="buildingUnit.companyName"
|
|
75
|
+
density="comfortable"
|
|
76
|
+
:rules="[requiredRule]"
|
|
77
|
+
></v-text-field>
|
|
78
|
+
</v-col>
|
|
79
|
+
</v-row>
|
|
80
|
+
</v-col>
|
|
81
|
+
</v-row>
|
|
82
|
+
</v-col>
|
|
83
|
+
|
|
84
|
+
<v-col cols="12">
|
|
85
|
+
<v-row>
|
|
86
|
+
<v-col cols="12" class="mt-2">
|
|
87
|
+
<v-row no-gutters>
|
|
88
|
+
<InputLabel
|
|
89
|
+
class="text-capitalize"
|
|
90
|
+
title="Company Registration Number"
|
|
91
|
+
/>
|
|
92
|
+
<v-col cols="12">
|
|
93
|
+
<v-text-field
|
|
94
|
+
v-model="buildingUnit.companyRegistrationNumber"
|
|
95
|
+
density="comfortable"
|
|
96
|
+
></v-text-field>
|
|
97
|
+
</v-col>
|
|
98
|
+
</v-row>
|
|
99
|
+
</v-col>
|
|
100
|
+
</v-row>
|
|
101
|
+
</v-col>
|
|
102
|
+
|
|
103
|
+
<v-col cols="12">
|
|
104
|
+
<v-row>
|
|
105
|
+
<v-col cols="12" class="mt-2">
|
|
106
|
+
<v-row no-gutters>
|
|
107
|
+
<InputLabel
|
|
108
|
+
class="text-capitalize"
|
|
109
|
+
title="Lease Start"
|
|
110
|
+
required
|
|
111
|
+
/>
|
|
112
|
+
<v-col cols="12">
|
|
113
|
+
<InputDateTimePicker
|
|
114
|
+
ref="startDateRef"
|
|
115
|
+
v-model="buildingUnit.leaseStart"
|
|
116
|
+
:rules="[requiredRule]"
|
|
117
|
+
/>
|
|
118
|
+
</v-col>
|
|
119
|
+
</v-row>
|
|
120
|
+
</v-col>
|
|
121
|
+
</v-row>
|
|
122
|
+
</v-col>
|
|
123
|
+
|
|
124
|
+
<v-col cols="12">
|
|
125
|
+
<v-row>
|
|
126
|
+
<v-col cols="12" class="mt-2">
|
|
127
|
+
<v-row no-gutters>
|
|
128
|
+
<InputLabel
|
|
129
|
+
class="text-capitalize"
|
|
130
|
+
title="Lease End"
|
|
131
|
+
required
|
|
132
|
+
/>
|
|
133
|
+
<v-col cols="12">
|
|
134
|
+
<InputDateTimePicker
|
|
135
|
+
ref="endDateRef"
|
|
136
|
+
v-model="buildingUnit.leaseEnd"
|
|
137
|
+
:rules="[requiredRule]"
|
|
138
|
+
/>
|
|
139
|
+
</v-col>
|
|
140
|
+
</v-row>
|
|
141
|
+
</v-col>
|
|
142
|
+
</v-row>
|
|
143
|
+
</v-col>
|
|
144
|
+
|
|
145
|
+
<v-col cols="12" class="mt-2">
|
|
146
|
+
<v-row no-gutters>
|
|
147
|
+
<InputLabel
|
|
148
|
+
class="text-capitalize font-weight-bold"
|
|
149
|
+
title="Category"
|
|
150
|
+
required
|
|
151
|
+
/>
|
|
152
|
+
<v-col cols="12">
|
|
153
|
+
<v-autocomplete
|
|
154
|
+
v-model="buildingUnit.category"
|
|
155
|
+
:items="unitCategories"
|
|
156
|
+
density="comfortable"
|
|
157
|
+
:rules="[requiredRule]"
|
|
158
|
+
></v-autocomplete>
|
|
159
|
+
</v-col>
|
|
160
|
+
</v-row>
|
|
161
|
+
</v-col>
|
|
162
|
+
|
|
163
|
+
<v-col cols="12">
|
|
164
|
+
<v-row>
|
|
165
|
+
<v-col cols="6" class="mt-2">
|
|
166
|
+
<v-row no-gutters>
|
|
167
|
+
<InputLabel
|
|
168
|
+
class="text-capitalize font-weight-bold"
|
|
169
|
+
title="Level"
|
|
170
|
+
required
|
|
171
|
+
/>
|
|
172
|
+
<v-col cols="12">
|
|
173
|
+
<v-select
|
|
174
|
+
v-model="buildingUnit.level"
|
|
175
|
+
:items="buildingLevels"
|
|
176
|
+
density="comfortable"
|
|
177
|
+
:rules="[requiredRule]"
|
|
178
|
+
></v-select>
|
|
179
|
+
</v-col>
|
|
180
|
+
</v-row>
|
|
181
|
+
</v-col>
|
|
182
|
+
</v-row>
|
|
183
|
+
</v-col>
|
|
184
|
+
|
|
185
|
+
<v-col cols="12" class="mt-5">
|
|
186
|
+
<InputLabel
|
|
187
|
+
class="text-capitalize"
|
|
188
|
+
title="Upload Files (Lease of Contract, Cert. of Occupancy)"
|
|
189
|
+
/>
|
|
190
|
+
<InputFileV2
|
|
191
|
+
v-model="buildingUnit.buildingUnitFiles"
|
|
192
|
+
:multiple="false"
|
|
193
|
+
:max-length="10"
|
|
194
|
+
title="Upload PDF Files"
|
|
195
|
+
accept="application/pdf"
|
|
196
|
+
/>
|
|
197
|
+
</v-col>
|
|
198
|
+
|
|
199
|
+
<v-col cols="12" class="my-2">
|
|
200
|
+
<v-row no-gutters>
|
|
201
|
+
<v-col cols="12" class="text-center">
|
|
202
|
+
<span
|
|
203
|
+
class="text-none text-subtitle-2 font-weight-medium text-error"
|
|
204
|
+
>
|
|
205
|
+
{{ message }}
|
|
206
|
+
</span>
|
|
207
|
+
</v-col>
|
|
208
|
+
</v-row>
|
|
209
|
+
</v-col>
|
|
210
|
+
</v-row>
|
|
211
|
+
</v-form>
|
|
212
|
+
</v-card-text>
|
|
213
|
+
|
|
214
|
+
<v-toolbar density="compact">
|
|
215
|
+
<v-row no-gutters>
|
|
216
|
+
<v-col cols="6">
|
|
217
|
+
<v-btn
|
|
218
|
+
tile
|
|
219
|
+
block
|
|
220
|
+
variant="text"
|
|
221
|
+
class="text-none"
|
|
222
|
+
size="48"
|
|
223
|
+
@click="cancel"
|
|
224
|
+
>
|
|
225
|
+
Cancel
|
|
226
|
+
</v-btn>
|
|
227
|
+
</v-col>
|
|
228
|
+
|
|
229
|
+
<v-col cols="6">
|
|
230
|
+
<v-btn
|
|
231
|
+
tile
|
|
232
|
+
block
|
|
233
|
+
variant="flat"
|
|
234
|
+
color="black"
|
|
235
|
+
class="text-none"
|
|
236
|
+
size="48"
|
|
237
|
+
:disabled="!validForm || disable"
|
|
238
|
+
@click="submit"
|
|
239
|
+
:loading="disable"
|
|
240
|
+
>
|
|
241
|
+
Submit
|
|
242
|
+
</v-btn>
|
|
243
|
+
</v-col>
|
|
244
|
+
</v-row>
|
|
245
|
+
</v-toolbar>
|
|
246
|
+
</v-card>
|
|
247
|
+
</template>
|
|
248
|
+
|
|
249
|
+
<script setup lang="ts">
|
|
250
|
+
const prop = defineProps({
|
|
251
|
+
site: {
|
|
252
|
+
type: String,
|
|
253
|
+
default: "",
|
|
254
|
+
},
|
|
255
|
+
roomFacility: {
|
|
256
|
+
type: Object as PropType<TBuildingUnit>,
|
|
257
|
+
default: () => ({
|
|
258
|
+
_id: "",
|
|
259
|
+
site: "",
|
|
260
|
+
name: "",
|
|
261
|
+
building: "",
|
|
262
|
+
buildingName: "",
|
|
263
|
+
category: "",
|
|
264
|
+
block: null,
|
|
265
|
+
level: 0,
|
|
266
|
+
status: "active",
|
|
267
|
+
buildingUnitFiles: [],
|
|
268
|
+
companyName: "",
|
|
269
|
+
companyRegistrationNumber: "",
|
|
270
|
+
leaseStart: "",
|
|
271
|
+
leaseEnd: "",
|
|
272
|
+
}),
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
const buildingUnit = ref({
|
|
277
|
+
_id: "",
|
|
278
|
+
site: "",
|
|
279
|
+
name: "",
|
|
280
|
+
building: "",
|
|
281
|
+
buildingName: "",
|
|
282
|
+
level: 0,
|
|
283
|
+
category: "",
|
|
284
|
+
block: null,
|
|
285
|
+
status: "active",
|
|
286
|
+
buildingUnitFiles: [],
|
|
287
|
+
companyName: "",
|
|
288
|
+
companyRegistrationNumber: "",
|
|
289
|
+
leaseStart: "",
|
|
290
|
+
leaseEnd: "",
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
buildingUnit.value = JSON.parse(JSON.stringify(prop.roomFacility));
|
|
294
|
+
|
|
295
|
+
const emit = defineEmits(["cancel", "success", "success:create-more"]);
|
|
296
|
+
|
|
297
|
+
const validForm = ref(false);
|
|
298
|
+
|
|
299
|
+
const { getAll } = useBuilding();
|
|
300
|
+
|
|
301
|
+
const buildings = ref<Record<string, any>[]>([]);
|
|
302
|
+
|
|
303
|
+
const { data: getBuildingReq } = useLazyAsyncData(
|
|
304
|
+
"get-all-buildings",
|
|
305
|
+
async () => getAll({ site: prop.site, status: "active" })
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
watchEffect(() => {
|
|
309
|
+
if (getBuildingReq.value) {
|
|
310
|
+
buildings.value = getBuildingReq.value.items.map((building: TBuilding) => ({
|
|
311
|
+
title: building.name,
|
|
312
|
+
value: building._id,
|
|
313
|
+
levels: building.levels,
|
|
314
|
+
}));
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
buildingUnit.value.site = prop.site;
|
|
319
|
+
|
|
320
|
+
const selectedBuilding = computed(() => {
|
|
321
|
+
return buildings.value.find((b) => b.value === buildingUnit.value.building);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
const buildingLevels = computed(() => {
|
|
325
|
+
return Array.from(
|
|
326
|
+
{ length: selectedBuilding.value?.levels || 0 },
|
|
327
|
+
(_, i) => i + 1
|
|
328
|
+
);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
const disable = ref(false);
|
|
332
|
+
|
|
333
|
+
const { requiredRule } = useUtils();
|
|
334
|
+
|
|
335
|
+
const message = ref("");
|
|
336
|
+
|
|
337
|
+
const { updateById, categories: unitCategories } = useBuildingUnit();
|
|
338
|
+
|
|
339
|
+
function arraysAreEqual(a: any[], b: any[]): boolean {
|
|
340
|
+
return a.length === b.length && a.every((val, index) => val === b[index]);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const hasChanges = computed(() => {
|
|
344
|
+
return (
|
|
345
|
+
prop.roomFacility.name !== buildingUnit.value.name ||
|
|
346
|
+
prop.roomFacility.category !== buildingUnit.value.category ||
|
|
347
|
+
prop.roomFacility.level !== buildingUnit.value.level ||
|
|
348
|
+
!arraysAreEqual(
|
|
349
|
+
prop.roomFacility.buildingUnitFiles,
|
|
350
|
+
buildingUnit.value.buildingUnitFiles
|
|
351
|
+
)
|
|
352
|
+
);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
async function submit() {
|
|
356
|
+
disable.value = true;
|
|
357
|
+
try {
|
|
358
|
+
await updateById(buildingUnit.value._id ?? "", {
|
|
359
|
+
name: buildingUnit.value.name,
|
|
360
|
+
level: buildingUnit.value.level,
|
|
361
|
+
category: buildingUnit.value.category,
|
|
362
|
+
buildingUnitFiles: buildingUnit.value.buildingUnitFiles || [],
|
|
363
|
+
companyName: buildingUnit.value.companyName,
|
|
364
|
+
companyRegistrationNumber: buildingUnit.value.companyRegistrationNumber || "",
|
|
365
|
+
leaseStart: buildingUnit.value.leaseStart,
|
|
366
|
+
leaseEnd: buildingUnit.value.leaseEnd,
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
emit("success");
|
|
370
|
+
} catch (error: any) {
|
|
371
|
+
message.value =
|
|
372
|
+
error.response?._data?.message || "Failed to create building";
|
|
373
|
+
} finally {
|
|
374
|
+
disable.value = false;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function cancel() {
|
|
379
|
+
message.value = "";
|
|
380
|
+
emit("cancel");
|
|
381
|
+
}
|
|
382
|
+
</script>
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
:placeholder="placeholder"
|
|
7
7
|
:counter="maxlength"
|
|
8
8
|
@input="onInput"
|
|
9
|
+
:loading="loading"
|
|
9
10
|
outlined
|
|
10
11
|
clearable
|
|
11
12
|
/>
|
|
@@ -25,9 +26,15 @@ const props = defineProps({
|
|
|
25
26
|
maxlength: {
|
|
26
27
|
type: [Number, String],
|
|
27
28
|
default: false
|
|
29
|
+
},
|
|
30
|
+
loading: {
|
|
31
|
+
type: Boolean,
|
|
32
|
+
default: false
|
|
28
33
|
}
|
|
29
34
|
})
|
|
30
35
|
|
|
36
|
+
const emit = defineEmits(['update:modelValue'])
|
|
37
|
+
|
|
31
38
|
const model = defineModel({required: true, default: ""})
|
|
32
39
|
|
|
33
40
|
function onInput(event) {
|
|
@@ -38,4 +45,9 @@ function onInput(event) {
|
|
|
38
45
|
|
|
39
46
|
model.value = formatted
|
|
40
47
|
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
watch(model, (newVal) => {
|
|
51
|
+
emit('update:modelValue:', newVal)
|
|
52
|
+
})
|
|
41
53
|
</script>
|
package/components/TableMain.vue
CHANGED
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
<!-- Data Table -->
|
|
44
44
|
<v-data-table :headers="headers" :items="items" :item-value="itemValue" :items-per-page="itemsPerPage"
|
|
45
45
|
fixed-header hide-default-footer :hide-default-header="!showHeader"
|
|
46
|
-
@click:row="(_: any, data: any) => emits('row-click', data)" style="max-height: calc(100vh - (
|
|
46
|
+
@click:row="(_: any, data: any) => emits('row-click', data)" :style="`max-height: calc(100vh - (${offset}px))`">
|
|
47
47
|
<template v-for="(_, slotName) in $slots" #[slotName]="slotProps">
|
|
48
48
|
<slot :name="slotName" v-bind="slotProps" />
|
|
49
49
|
</template>
|
|
@@ -103,6 +103,10 @@ const props = defineProps({
|
|
|
103
103
|
extensionHeight: {
|
|
104
104
|
type: Number,
|
|
105
105
|
default: 50
|
|
106
|
+
},
|
|
107
|
+
offset: {
|
|
108
|
+
type: Number,
|
|
109
|
+
default: 200
|
|
106
110
|
}
|
|
107
111
|
});
|
|
108
112
|
|