@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,441 @@
|
|
|
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"> Add 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" class="mt-2">
|
|
12
|
+
<v-row no-gutters>
|
|
13
|
+
<InputLabel class="text-capitalize" title="Name" required />
|
|
14
|
+
<v-col cols="12">
|
|
15
|
+
<v-text-field
|
|
16
|
+
v-model="buildingUnit.name"
|
|
17
|
+
density="comfortable"
|
|
18
|
+
:rules="[requiredRule]"
|
|
19
|
+
></v-text-field>
|
|
20
|
+
</v-col>
|
|
21
|
+
</v-row>
|
|
22
|
+
</v-col>
|
|
23
|
+
|
|
24
|
+
<v-col cols="12">
|
|
25
|
+
<v-row>
|
|
26
|
+
<v-col cols="12" class="mt-2">
|
|
27
|
+
<v-row no-gutters>
|
|
28
|
+
<InputLabel
|
|
29
|
+
class="text-capitalize"
|
|
30
|
+
title="Building"
|
|
31
|
+
required
|
|
32
|
+
/>
|
|
33
|
+
<v-col cols="12">
|
|
34
|
+
<v-autocomplete
|
|
35
|
+
v-model="buildingUnit.building"
|
|
36
|
+
:items="buildings"
|
|
37
|
+
item-title="name"
|
|
38
|
+
item-value="_id"
|
|
39
|
+
v-model:search="searchBuilding"
|
|
40
|
+
:hide-no-data="false"
|
|
41
|
+
density="comfortable"
|
|
42
|
+
:rules="[requiredRule]"
|
|
43
|
+
variant="outlined"
|
|
44
|
+
></v-autocomplete>
|
|
45
|
+
</v-col>
|
|
46
|
+
</v-row>
|
|
47
|
+
</v-col>
|
|
48
|
+
</v-row>
|
|
49
|
+
</v-col>
|
|
50
|
+
|
|
51
|
+
<v-col cols="12">
|
|
52
|
+
<v-row>
|
|
53
|
+
<v-col cols="12" class="mt-2">
|
|
54
|
+
<v-row no-gutters>
|
|
55
|
+
<InputLabel
|
|
56
|
+
class="text-capitalize"
|
|
57
|
+
title="Company Name"
|
|
58
|
+
required
|
|
59
|
+
/>
|
|
60
|
+
<v-col cols="12">
|
|
61
|
+
<v-text-field
|
|
62
|
+
v-model="buildingUnit.companyName"
|
|
63
|
+
density="comfortable"
|
|
64
|
+
:rules="[requiredRule]"
|
|
65
|
+
></v-text-field>
|
|
66
|
+
</v-col>
|
|
67
|
+
</v-row>
|
|
68
|
+
</v-col>
|
|
69
|
+
</v-row>
|
|
70
|
+
</v-col>
|
|
71
|
+
|
|
72
|
+
<v-col cols="12">
|
|
73
|
+
<v-row>
|
|
74
|
+
<v-col cols="12" class="mt-2">
|
|
75
|
+
<v-row no-gutters>
|
|
76
|
+
<InputLabel
|
|
77
|
+
class="text-capitalize"
|
|
78
|
+
title="Company Registration Number"
|
|
79
|
+
/>
|
|
80
|
+
<v-col cols="12">
|
|
81
|
+
<v-text-field
|
|
82
|
+
v-model="buildingUnit.companyRegistrationNumber"
|
|
83
|
+
density="comfortable"
|
|
84
|
+
:rules="[]"
|
|
85
|
+
></v-text-field>
|
|
86
|
+
</v-col>
|
|
87
|
+
</v-row>
|
|
88
|
+
</v-col>
|
|
89
|
+
</v-row>
|
|
90
|
+
</v-col>
|
|
91
|
+
|
|
92
|
+
<v-col cols="12">
|
|
93
|
+
<v-row>
|
|
94
|
+
<v-col cols="12" class="mt-2">
|
|
95
|
+
<v-row no-gutters>
|
|
96
|
+
<InputLabel
|
|
97
|
+
class="text-capitalize"
|
|
98
|
+
title="Lease Start"
|
|
99
|
+
required
|
|
100
|
+
/>
|
|
101
|
+
<v-col cols="12">
|
|
102
|
+
<InputDateTimePicker
|
|
103
|
+
ref="startDateRef"
|
|
104
|
+
v-model="buildingUnit.leaseStart"
|
|
105
|
+
:rules="[requiredRule]"
|
|
106
|
+
/>
|
|
107
|
+
</v-col>
|
|
108
|
+
</v-row>
|
|
109
|
+
</v-col>
|
|
110
|
+
</v-row>
|
|
111
|
+
</v-col>
|
|
112
|
+
|
|
113
|
+
<v-col cols="12">
|
|
114
|
+
<v-row>
|
|
115
|
+
<v-col cols="12" class="mt-2">
|
|
116
|
+
<v-row no-gutters>
|
|
117
|
+
<InputLabel
|
|
118
|
+
class="text-capitalize"
|
|
119
|
+
title="Lease End"
|
|
120
|
+
required
|
|
121
|
+
/>
|
|
122
|
+
<v-col cols="12">
|
|
123
|
+
<InputDateTimePicker
|
|
124
|
+
ref="endDateRef"
|
|
125
|
+
v-model="buildingUnit.leaseEnd"
|
|
126
|
+
:rules="[requiredRule]"
|
|
127
|
+
/>
|
|
128
|
+
</v-col>
|
|
129
|
+
</v-row>
|
|
130
|
+
</v-col>
|
|
131
|
+
</v-row>
|
|
132
|
+
</v-col>
|
|
133
|
+
|
|
134
|
+
<v-col cols="12" class="mt-2">
|
|
135
|
+
<v-row no-gutters>
|
|
136
|
+
<InputLabel class="text-capitalize" title="Category" required />
|
|
137
|
+
<v-col cols="12">
|
|
138
|
+
<v-autocomplete
|
|
139
|
+
v-model="buildingUnit.category"
|
|
140
|
+
:items="unitCategories"
|
|
141
|
+
density="comfortable"
|
|
142
|
+
:rules="[requiredRule]"
|
|
143
|
+
></v-autocomplete>
|
|
144
|
+
</v-col>
|
|
145
|
+
</v-row>
|
|
146
|
+
</v-col>
|
|
147
|
+
|
|
148
|
+
<v-col cols="12">
|
|
149
|
+
<v-row>
|
|
150
|
+
<v-col cols="6" class="mt-2">
|
|
151
|
+
<v-row no-gutters>
|
|
152
|
+
<InputLabel class="text-capitalize" title="Level" required />
|
|
153
|
+
<v-col cols="12">
|
|
154
|
+
<v-select
|
|
155
|
+
v-model="buildingUnit.level"
|
|
156
|
+
:items="buildingLevels"
|
|
157
|
+
density="comfortable"
|
|
158
|
+
:rules="[requiredRule]"
|
|
159
|
+
></v-select>
|
|
160
|
+
</v-col>
|
|
161
|
+
</v-row>
|
|
162
|
+
</v-col>
|
|
163
|
+
|
|
164
|
+
<v-col cols="6" class="mt-2">
|
|
165
|
+
<v-row no-gutters>
|
|
166
|
+
<InputLabel
|
|
167
|
+
class="text-capitalize"
|
|
168
|
+
title="No. of Units"
|
|
169
|
+
required
|
|
170
|
+
/>
|
|
171
|
+
<v-col cols="12">
|
|
172
|
+
<v-text-field
|
|
173
|
+
v-model.number="buildingUnitQty"
|
|
174
|
+
density="comfortable"
|
|
175
|
+
:rules="[requiredRule]"
|
|
176
|
+
type="number"
|
|
177
|
+
@update:model-value="setBuildingLevels()"
|
|
178
|
+
></v-text-field>
|
|
179
|
+
</v-col>
|
|
180
|
+
</v-row>
|
|
181
|
+
</v-col>
|
|
182
|
+
</v-row>
|
|
183
|
+
</v-col>
|
|
184
|
+
|
|
185
|
+
<v-col v-if="buildingLevels" cols="12">
|
|
186
|
+
<v-row justify="center">
|
|
187
|
+
<v-col cols="6">
|
|
188
|
+
<v-btn
|
|
189
|
+
block
|
|
190
|
+
color="primary"
|
|
191
|
+
variant="text"
|
|
192
|
+
class="text-none font-weight-bold"
|
|
193
|
+
text="Set unit labels"
|
|
194
|
+
@click="show = !show"
|
|
195
|
+
></v-btn>
|
|
196
|
+
</v-col>
|
|
197
|
+
</v-row>
|
|
198
|
+
</v-col>
|
|
199
|
+
|
|
200
|
+
<v-expand-transition>
|
|
201
|
+
<v-row v-show="show" no-gutters>
|
|
202
|
+
<template
|
|
203
|
+
v-for="(unitLabel, unitLabelIndex) in unitLabels"
|
|
204
|
+
:key="levelIndex"
|
|
205
|
+
>
|
|
206
|
+
<v-col cols="12">
|
|
207
|
+
<v-row no-gutters>
|
|
208
|
+
<InputLabel
|
|
209
|
+
class="text-capitalize font-weight-bold"
|
|
210
|
+
:title="`Unit ${unitLabelIndex + 1}`"
|
|
211
|
+
/>
|
|
212
|
+
<v-col cols="12">
|
|
213
|
+
<v-text-field
|
|
214
|
+
v-model.trim="unitLabels[unitLabelIndex]"
|
|
215
|
+
density="comfortable"
|
|
216
|
+
></v-text-field>
|
|
217
|
+
</v-col>
|
|
218
|
+
</v-row>
|
|
219
|
+
</v-col>
|
|
220
|
+
</template>
|
|
221
|
+
</v-row>
|
|
222
|
+
</v-expand-transition>
|
|
223
|
+
|
|
224
|
+
<v-col cols="12" class="mt-5">
|
|
225
|
+
<InputLabel
|
|
226
|
+
class="text-capitalize"
|
|
227
|
+
title="Upload Files (Lease of Contract, Cert. of Occupancy)"
|
|
228
|
+
/>
|
|
229
|
+
<InputFileV2
|
|
230
|
+
v-model="buildingUnit.buildingUnitFiles"
|
|
231
|
+
:multiple="false"
|
|
232
|
+
:max-length="10"
|
|
233
|
+
title="Upload PDF Files"
|
|
234
|
+
accept="application/pdf"
|
|
235
|
+
/>
|
|
236
|
+
</v-col>
|
|
237
|
+
|
|
238
|
+
<v-col cols="12" class="mt-2">
|
|
239
|
+
<v-checkbox v-model="createMore" density="comfortable" hide-details>
|
|
240
|
+
<template #label>
|
|
241
|
+
<span class="text-subtitle-2 font-weight-bold">
|
|
242
|
+
Create more
|
|
243
|
+
</span>
|
|
244
|
+
</template>
|
|
245
|
+
</v-checkbox>
|
|
246
|
+
</v-col>
|
|
247
|
+
|
|
248
|
+
<v-col cols="12" class="my-2">
|
|
249
|
+
<v-row no-gutters>
|
|
250
|
+
<v-col cols="12" class="text-center">
|
|
251
|
+
<span
|
|
252
|
+
class="text-none text-subtitle-2 font-weight-medium text-error"
|
|
253
|
+
>
|
|
254
|
+
{{ message }}
|
|
255
|
+
</span>
|
|
256
|
+
</v-col>
|
|
257
|
+
</v-row>
|
|
258
|
+
</v-col>
|
|
259
|
+
</v-row>
|
|
260
|
+
</v-form>
|
|
261
|
+
</v-card-text>
|
|
262
|
+
|
|
263
|
+
<v-toolbar density="compact">
|
|
264
|
+
<v-row no-gutters>
|
|
265
|
+
<v-col cols="6">
|
|
266
|
+
<v-btn
|
|
267
|
+
tile
|
|
268
|
+
block
|
|
269
|
+
variant="text"
|
|
270
|
+
class="text-none"
|
|
271
|
+
size="48"
|
|
272
|
+
@click="cancel"
|
|
273
|
+
:disabled="disable"
|
|
274
|
+
>
|
|
275
|
+
Cancel
|
|
276
|
+
</v-btn>
|
|
277
|
+
</v-col>
|
|
278
|
+
|
|
279
|
+
<v-col cols="6">
|
|
280
|
+
<v-btn
|
|
281
|
+
tile
|
|
282
|
+
block
|
|
283
|
+
variant="flat"
|
|
284
|
+
color="black"
|
|
285
|
+
class="text-none"
|
|
286
|
+
size="48"
|
|
287
|
+
:disabled="!validForm || disable"
|
|
288
|
+
@click="submit"
|
|
289
|
+
:loading="disable"
|
|
290
|
+
>
|
|
291
|
+
Submit
|
|
292
|
+
</v-btn>
|
|
293
|
+
</v-col>
|
|
294
|
+
</v-row>
|
|
295
|
+
</v-toolbar>
|
|
296
|
+
</v-card>
|
|
297
|
+
</template>
|
|
298
|
+
|
|
299
|
+
<script setup lang="ts">
|
|
300
|
+
const prop = defineProps({
|
|
301
|
+
site: {
|
|
302
|
+
type: String,
|
|
303
|
+
default: "",
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
const searchBuilding = ref("");
|
|
308
|
+
|
|
309
|
+
const emit = defineEmits(["cancel", "success", "success:create-more"]);
|
|
310
|
+
|
|
311
|
+
const validForm = ref(false);
|
|
312
|
+
|
|
313
|
+
const { getAll } = useBuilding();
|
|
314
|
+
|
|
315
|
+
const buildings = ref<TBuilding[]>([]);
|
|
316
|
+
|
|
317
|
+
const { data: getBuildingReq } = useLazyAsyncData(
|
|
318
|
+
"get-all-buildings",
|
|
319
|
+
async () => getAll({ site: prop.site, status: "active" })
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
watchEffect(() => {
|
|
323
|
+
if (getBuildingReq.value) {
|
|
324
|
+
buildings.value = getBuildingReq.value.items;
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
const buildingUnitQty = ref(1);
|
|
329
|
+
|
|
330
|
+
const buildingUnit = ref<TBuildingUnit>({
|
|
331
|
+
site: "",
|
|
332
|
+
name: "Unit",
|
|
333
|
+
building: "",
|
|
334
|
+
buildingName: "",
|
|
335
|
+
block: 0,
|
|
336
|
+
level: "",
|
|
337
|
+
category: "",
|
|
338
|
+
status: "active",
|
|
339
|
+
buildingUnitFiles: [],
|
|
340
|
+
companyName: "",
|
|
341
|
+
companyRegistrationNumber: "",
|
|
342
|
+
leaseStart: "",
|
|
343
|
+
leaseEnd: "",
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
const startDateRef = ref<HTMLInputElement | null>(null);
|
|
347
|
+
const expiryDateRef = ref<HTMLInputElement | null>(null);
|
|
348
|
+
|
|
349
|
+
buildingUnit.value.site = prop.site;
|
|
350
|
+
|
|
351
|
+
const selectedBuilding = computed(() => {
|
|
352
|
+
return buildings.value.find((b) => b._id === buildingUnit.value.building);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
watchEffect(() => {
|
|
356
|
+
if (buildingUnit.value.building) {
|
|
357
|
+
buildingUnit.value.buildingName = selectedBuilding.value?.name;
|
|
358
|
+
buildingUnit.value.block = selectedBuilding.value?.block || 0;
|
|
359
|
+
} else {
|
|
360
|
+
buildingUnit.value.buildingName = "";
|
|
361
|
+
buildingUnit.value.block = 0;
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
const buildingLevels = computed(() => {
|
|
366
|
+
return selectedBuilding.value?.levels || [];
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
const unitLabels = ref<string[]>([]);
|
|
370
|
+
unitLabels.value.push("Unit 1");
|
|
371
|
+
|
|
372
|
+
const show = ref(false);
|
|
373
|
+
|
|
374
|
+
function setBuildingLevels() {
|
|
375
|
+
unitLabels.value.length = 0;
|
|
376
|
+
for (let index = 0; index < buildingUnitQty.value; index++) {
|
|
377
|
+
unitLabels.value.push(`Unit ${index + 1}`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const name = ref("");
|
|
382
|
+
const directorName = ref("");
|
|
383
|
+
const createMore = ref(false);
|
|
384
|
+
const disable = ref(false);
|
|
385
|
+
|
|
386
|
+
const { requiredRule, validateDate } = useUtils();
|
|
387
|
+
|
|
388
|
+
const message = ref("");
|
|
389
|
+
|
|
390
|
+
const { add, categories: unitCategories } = useBuildingUnit();
|
|
391
|
+
|
|
392
|
+
function setBuildingUnit() {
|
|
393
|
+
buildingUnit.value.site = prop.site ?? "";
|
|
394
|
+
buildingUnit.value.name = "Unit";
|
|
395
|
+
buildingUnit.value.building = "";
|
|
396
|
+
buildingUnit.value.buildingName = "";
|
|
397
|
+
buildingUnit.value.level = "";
|
|
398
|
+
buildingUnit.value.category = "";
|
|
399
|
+
buildingUnit.value.status = "active";
|
|
400
|
+
buildingUnit.value.buildingUnitFiles = [];
|
|
401
|
+
buildingUnitQty.value = 1;
|
|
402
|
+
message.value = "";
|
|
403
|
+
buildingUnit.value.companyName = "";
|
|
404
|
+
buildingUnit.value.companyRegistrationNumber = "";
|
|
405
|
+
buildingUnit.value.leaseStart = "";
|
|
406
|
+
buildingUnit.value.leaseEnd = "";
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
async function submit() {
|
|
410
|
+
disable.value = true;
|
|
411
|
+
try {
|
|
412
|
+
await add({
|
|
413
|
+
labels: unitLabels.value,
|
|
414
|
+
unit: buildingUnit.value,
|
|
415
|
+
qty: buildingUnitQty.value,
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
if (createMore.value) {
|
|
419
|
+
setBuildingUnit();
|
|
420
|
+
message.value = "";
|
|
421
|
+
emit("success:create-more");
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
emit("success");
|
|
426
|
+
} catch (error: any) {
|
|
427
|
+
message.value =
|
|
428
|
+
error.response?._data?.message || "Failed to create building";
|
|
429
|
+
} finally {
|
|
430
|
+
disable.value = false;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function cancel() {
|
|
435
|
+
name.value = "";
|
|
436
|
+
directorName.value = "";
|
|
437
|
+
createMore.value = false;
|
|
438
|
+
message.value = "";
|
|
439
|
+
emit("cancel");
|
|
440
|
+
}
|
|
441
|
+
</script>
|