@iservice365/layer-common 1.2.0 → 1.3.1
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 +21 -0
- package/components/BuildingForm.vue +303 -0
- package/components/BuildingManagement/buildings.vue +395 -0
- package/components/BuildingManagement/units.vue +391 -0
- package/components/BuildingUnitFormAdd.vue +338 -0
- package/components/BuildingUnitFormEdit.vue +278 -0
- package/components/Chat/Information.vue +1 -1
- package/components/Input/DateTimePicker.vue +5 -4
- package/components/Input/FileV2.vue +0 -5
- package/components/Input/InputPhoneNumberV2.vue +0 -1
- package/components/Input/NRICNumber.vue +12 -0
- package/components/Input/VehicleNumber.vue +8 -0
- package/components/PeopleForm.vue +64 -32
- package/components/TableMain.vue +5 -1
- package/components/VisitorForm.vue +114 -279
- package/components/VisitorManagement.vue +95 -174
- package/components/WorkOrder/Create.vue +22 -4
- package/components/WorkOrder/Main.vue +7 -3
- package/composables/useBuilding.ts +1 -1
- package/composables/usePeople.ts +9 -1
- package/composables/useVisitor.ts +74 -50
- package/composables/useWorkOrder.ts +3 -3
- package/package.json +1 -1
- package/types/building.d.ts +2 -0
- package/types/people.d.ts +8 -7
- package/types/visitor.d.ts +1 -1
|
@@ -1,95 +1,33 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
|
-
<TableMain
|
|
4
|
-
:
|
|
5
|
-
:
|
|
6
|
-
|
|
7
|
-
:page="page"
|
|
8
|
-
:pages="pages"
|
|
9
|
-
:extension-height="110"
|
|
10
|
-
:pageRange="pageRange"
|
|
11
|
-
:canCreate="canAddVisitor"
|
|
12
|
-
@refresh="getVisitorRefresh"
|
|
13
|
-
@update:page="handleUpdatePage"
|
|
14
|
-
createLabel="Add Visitor"
|
|
15
|
-
show-header
|
|
16
|
-
@row-click="handleRowClick"
|
|
17
|
-
@create="dialog.showSelection = true"
|
|
18
|
-
>
|
|
3
|
+
<TableMain :headers="headers" :items="items" :loading="getVisitorPending" :page="page" :pages="pages"
|
|
4
|
+
:extension-height="110" :offset="300" :pageRange="pageRange" :canCreate="canAddVisitor"
|
|
5
|
+
@refresh="getVisitorRefresh" @update:page="handleUpdatePage" createLabel="Add Visitor" show-header
|
|
6
|
+
@row-click="handleRowClick" @create="dialog.showSelection = true">
|
|
19
7
|
<template #extension>
|
|
20
8
|
<v-row no-gutters class="w-100 d-flex flex-column">
|
|
21
|
-
<v-tabs
|
|
22
|
-
v-
|
|
23
|
-
color="primary"
|
|
24
|
-
:height="40"
|
|
25
|
-
@update:model-value="toRoute"
|
|
26
|
-
class="w-100"
|
|
27
|
-
>
|
|
28
|
-
<v-tab
|
|
29
|
-
v-for="tab in tabOptions"
|
|
30
|
-
:value="tab.type"
|
|
31
|
-
:key="tab.type"
|
|
32
|
-
class="text-capitalize"
|
|
33
|
-
>
|
|
9
|
+
<v-tabs v-model="activeTab" color="primary" :height="40" @update:model-value="toRoute" class="w-100">
|
|
10
|
+
<v-tab v-for="tab in tabOptions" :value="tab.status" :key="tab.status" class="text-capitalize">
|
|
34
11
|
{{ tab.name }}
|
|
35
12
|
</v-tab>
|
|
36
13
|
</v-tabs>
|
|
37
14
|
|
|
38
|
-
<v-card
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
>
|
|
43
|
-
<v-text-field
|
|
44
|
-
v-model="searchInput"
|
|
45
|
-
density="compact"
|
|
46
|
-
placeholder="Search"
|
|
47
|
-
clearable
|
|
48
|
-
max-width="300"
|
|
49
|
-
append-inner-icon="mdi-magnify"
|
|
50
|
-
hide-details
|
|
51
|
-
/>
|
|
52
|
-
<v-checkbox
|
|
53
|
-
v-model="displayCheckedOutOnly"
|
|
54
|
-
class="text-subtitle-2"
|
|
55
|
-
hide-details
|
|
56
|
-
>
|
|
15
|
+
<v-card class="w-100 px-3 d-flex align-center ga-5 py-2" flat :height="60">
|
|
16
|
+
<v-text-field v-model="searchInput" density="compact" placeholder="Search" clearable max-width="300"
|
|
17
|
+
append-inner-icon="mdi-magnify" hide-details />
|
|
18
|
+
<v-checkbox v-model="displayCheckedOutOnly" class="text-subtitle-2" hide-details>
|
|
57
19
|
<template #label>
|
|
58
20
|
<span class="text-caption">Not Checked Out</span>
|
|
59
21
|
</template>
|
|
60
22
|
</v-checkbox>
|
|
61
|
-
<InputDateTimePicker
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
hide-details
|
|
65
|
-
/>
|
|
66
|
-
<InputDateTimePicker
|
|
67
|
-
v-model:utc="dateTo"
|
|
68
|
-
density="compact"
|
|
69
|
-
hide-details
|
|
70
|
-
/>
|
|
71
|
-
<v-select
|
|
72
|
-
v-model="filterTypes"
|
|
73
|
-
label="Filter by types"
|
|
74
|
-
item-title="label"
|
|
75
|
-
item-value="value"
|
|
76
|
-
:items="visitorSelection"
|
|
77
|
-
density="compact"
|
|
78
|
-
clearable
|
|
79
|
-
multiple
|
|
80
|
-
max-width="200"
|
|
81
|
-
hide-details
|
|
82
|
-
>
|
|
23
|
+
<InputDateTimePicker v-model:utc="dateFrom" density="compact" hide-details />
|
|
24
|
+
<InputDateTimePicker v-model:utc="dateTo" density="compact" hide-details />
|
|
25
|
+
<v-select v-model="filterTypes" label="Filter by types" item-title="label" item-value="value"
|
|
26
|
+
:items="visitorSelection" density="compact" clearable multiple max-width="200" hide-details>
|
|
83
27
|
<template v-slot:selection="{ item, index }">
|
|
84
28
|
<div class="d-flex align-center text-caption text-nowrap">
|
|
85
|
-
<v-chip
|
|
86
|
-
|
|
87
|
-
color="error"
|
|
88
|
-
:text="filterTypeSelectionLabel()"
|
|
89
|
-
size="x-small"
|
|
90
|
-
variant="tonal"
|
|
91
|
-
class="ml-2"
|
|
92
|
-
/>
|
|
29
|
+
<v-chip v-if="index === 0" color="error" :text="filterTypeSelectionLabel()" size="x-small"
|
|
30
|
+
variant="tonal" class="ml-2" />
|
|
93
31
|
</div>
|
|
94
32
|
</template>
|
|
95
33
|
</v-select>
|
|
@@ -111,7 +49,7 @@
|
|
|
111
49
|
<v-icon icon="mdi-user" size="15" />
|
|
112
50
|
<span v-if="item.type === 'contractor'" class="text-capitalize">{{
|
|
113
51
|
formatCamelCaseToWords(item.contractorType)
|
|
114
|
-
|
|
52
|
+
}}</span>
|
|
115
53
|
<span v-else class="text-capitalize">{{ formatType(item) }}</span>
|
|
116
54
|
</span>
|
|
117
55
|
<span class="d-flex align-center ga-2">
|
|
@@ -149,100 +87,57 @@
|
|
|
149
87
|
<v-icon icon="mdi-clock-time-four-outline" color="green" size="20" />
|
|
150
88
|
<span class="text-capitalize">{{
|
|
151
89
|
UTCToLocalTIme(item.checkIn) || "-"
|
|
152
|
-
|
|
90
|
+
}}</span>
|
|
153
91
|
</span>
|
|
154
92
|
<span class="d-flex align-center ga-2">
|
|
155
93
|
<v-icon icon="mdi-clock-time-eight-outline" color="red" size="20" v-if="item.checkOut" />
|
|
156
94
|
<template v-if="item.checkOut">
|
|
157
95
|
<span class="text-capitalize">{{
|
|
158
96
|
UTCToLocalTIme(item.checkOut) || "_"
|
|
159
|
-
|
|
97
|
+
}}</span>
|
|
160
98
|
<span v-if="item?.manualCheckout">
|
|
161
|
-
<TooltipInfo
|
|
162
|
-
text="Manual Checkout"
|
|
163
|
-
density="compact"
|
|
164
|
-
size="x-small"
|
|
165
|
-
/>
|
|
99
|
+
<TooltipInfo text="Manual Checkout" density="compact" size="x-small" />
|
|
166
100
|
</span>
|
|
167
101
|
</template>
|
|
168
102
|
<span v-else>
|
|
169
|
-
<v-btn
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
color="red"
|
|
173
|
-
text="Checkout"
|
|
174
|
-
:loading="loading.checkingOut && item?._id === selectedVisitorId"
|
|
175
|
-
@click.stop="handleCheckout(item._id)"
|
|
176
|
-
v-if="canCheckoutVisitor"
|
|
177
|
-
/>
|
|
103
|
+
<v-btn size="x-small" class="text-capitalize" color="red" text="Checkout"
|
|
104
|
+
:loading="loading.checkingOut && item?._id === selectedVisitorId" @click.stop="handleCheckout(item._id)"
|
|
105
|
+
v-if="canCheckoutVisitor" />
|
|
178
106
|
</span>
|
|
179
107
|
</span>
|
|
180
108
|
</template>
|
|
181
109
|
</TableMain>
|
|
182
110
|
|
|
183
111
|
<v-dialog v-model="dialog.showSelection" width="450" persistent>
|
|
184
|
-
<VisitorFormSelection
|
|
185
|
-
@cancel="dialog.showSelection = false"
|
|
186
|
-
@select="handleSelectVisitorType"
|
|
187
|
-
/>
|
|
112
|
+
<VisitorFormSelection @cancel="dialog.showSelection = false" @select="handleSelectVisitorType" />
|
|
188
113
|
</v-dialog>
|
|
189
114
|
|
|
190
|
-
<v-dialog
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
width="450"
|
|
194
|
-
persistent
|
|
195
|
-
>
|
|
196
|
-
<VisitorForm
|
|
197
|
-
mode="add"
|
|
198
|
-
:org="orgId"
|
|
199
|
-
:site="siteId"
|
|
200
|
-
:type="activeVisitorFormType"
|
|
201
|
-
@back="handleClickBack"
|
|
202
|
-
@done="handleVisitorFormDone"
|
|
203
|
-
@done:more="handleVisitorFormCreateMore"
|
|
204
|
-
/>
|
|
115
|
+
<v-dialog v-model="dialog.addVisitor" v-if="activeVisitorFormType" width="450" persistent>
|
|
116
|
+
<VisitorForm mode="add" :org="orgId" :site="siteId" :type="activeVisitorFormType" @back="handleClickBack"
|
|
117
|
+
@done="handleVisitorFormDone" @done:more="handleVisitorFormCreateMore" />
|
|
205
118
|
</v-dialog>
|
|
206
119
|
|
|
207
120
|
<v-dialog v-model="dialog.viewVisitor" width="450" persistent>
|
|
208
|
-
<VehicleUpdateMoreAction
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
:can-delete="canDeleteVisitor"
|
|
212
|
-
@close="dialog.viewVisitor = false"
|
|
213
|
-
edit-button-label="Edit Visitor"
|
|
214
|
-
delete-button-label="Delete Visitor"
|
|
215
|
-
@delete="handleDeleteVisitor"
|
|
216
|
-
>
|
|
121
|
+
<VehicleUpdateMoreAction title="Preview" :can-update="canUpdateVisitor" :can-delete="canDeleteVisitor"
|
|
122
|
+
@close="dialog.viewVisitor = false" edit-button-label="Edit Visitor" delete-button-label="Delete Visitor"
|
|
123
|
+
@delete="handleDeleteVisitor">
|
|
217
124
|
<template v-slot:content>
|
|
218
125
|
<v-row no-gutters class="mb-4">
|
|
219
126
|
<v-col v-for="(label, key) in formattedFields" :key="key" cols="12">
|
|
220
|
-
<span
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
127
|
+
<span v-if="
|
|
128
|
+
key === 'checkOut' &&
|
|
129
|
+
!selectedVisitorObject[key] &&
|
|
130
|
+
canCheckoutVisitor
|
|
131
|
+
" class="d-flex align-center">
|
|
224
132
|
<strong>{{ label }}:</strong>
|
|
225
|
-
<v-btn
|
|
226
|
-
|
|
227
|
-
class="ml-3 text-capitalize"
|
|
228
|
-
color="red"
|
|
229
|
-
text="Checkout"
|
|
230
|
-
:disabled="loading.checkingOut"
|
|
231
|
-
@click="handleCheckout(selectedVisitorId as string)"
|
|
232
|
-
/>
|
|
133
|
+
<v-btn size="x-small" class="ml-3 text-capitalize" color="red" text="Checkout"
|
|
134
|
+
:disabled="loading.checkingOut" @click="handleCheckout(selectedVisitorId as string)" />
|
|
233
135
|
</span>
|
|
234
136
|
|
|
235
|
-
<span
|
|
236
|
-
|
|
237
|
-
class="d-flex ga-3 align-center"
|
|
238
|
-
><strong>{{ label }}:</strong>
|
|
137
|
+
<span v-else-if="selectedVisitorObject[key]" class="d-flex ga-3 align-center"><strong>{{ label
|
|
138
|
+
}}:</strong>
|
|
239
139
|
{{ formatValues(key, selectedVisitorObject[key]) }}
|
|
240
|
-
<TooltipInfo
|
|
241
|
-
v-if="key === 'checkOut'"
|
|
242
|
-
text="Manual Checkout"
|
|
243
|
-
density="compact"
|
|
244
|
-
size="x-small"
|
|
245
|
-
/>
|
|
140
|
+
<TooltipInfo v-if="key === 'checkOut'" text="Manual Checkout" density="compact" size="x-small" />
|
|
246
141
|
</span>
|
|
247
142
|
</v-col>
|
|
248
143
|
</v-row>
|
|
@@ -251,12 +146,9 @@
|
|
|
251
146
|
</v-dialog>
|
|
252
147
|
|
|
253
148
|
<v-dialog v-model="dialog.deleteConfirmation" width="450" persistent>
|
|
254
|
-
<CardDeleteConfirmation
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
@close="dialog.deleteConfirmation = false"
|
|
258
|
-
@delete="handleProceedDeleteVisitor"
|
|
259
|
-
/>
|
|
149
|
+
<CardDeleteConfirmation prompt-title="Are you sure want to delete this visitor?"
|
|
150
|
+
:loading="loading.deletingVisitor" @close="dialog.deleteConfirmation = false"
|
|
151
|
+
@delete="handleProceedDeleteVisitor" />
|
|
260
152
|
</v-dialog>
|
|
261
153
|
|
|
262
154
|
<Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
|
|
@@ -309,26 +201,29 @@ const {
|
|
|
309
201
|
const { debounce, formatCamelCaseToWords, formatDate, UTCToLocalTIme } =
|
|
310
202
|
useUtils();
|
|
311
203
|
const { formatLocation } = useSecurityUtils();
|
|
312
|
-
const {
|
|
313
|
-
|
|
204
|
+
// const { status: visitorStatus, search } = useRoute().query as { status: string, search: string};
|
|
205
|
+
|
|
206
|
+
const route = useRoute()
|
|
207
|
+
const router = useRouter()
|
|
208
|
+
const { org: orgId, site: siteId } = route.params as {
|
|
314
209
|
org: string;
|
|
315
210
|
site: string;
|
|
316
211
|
};
|
|
317
|
-
const routeName =
|
|
212
|
+
const routeName = route.name;
|
|
318
213
|
|
|
319
214
|
const items = ref<Array<Record<string, any>>>([]);
|
|
320
215
|
const page = ref(1);
|
|
321
216
|
const pages = ref(0);
|
|
322
217
|
const pageRange = ref("-- - -- of --");
|
|
323
|
-
const activeTab = ref(
|
|
218
|
+
const activeTab = ref("registered");
|
|
324
219
|
const activeVisitorFormType = ref<TVisitorType | null>(null);
|
|
325
220
|
const selectedVisitorId = ref<string | null>(""); // selected visitor for viewing/actions
|
|
326
221
|
|
|
327
222
|
//filter states
|
|
328
223
|
const searchInput = ref("");
|
|
329
|
-
const dateFrom = ref(
|
|
224
|
+
const dateFrom = ref("");
|
|
330
225
|
const dateTo = ref("");
|
|
331
|
-
const filterTypes = ref([]);
|
|
226
|
+
const filterTypes = ref<TVisitorType[]>([]);
|
|
332
227
|
const displayCheckedOutOnly = ref<boolean>(false);
|
|
333
228
|
|
|
334
229
|
const message = ref("");
|
|
@@ -349,8 +244,8 @@ const dialog = reactive({
|
|
|
349
244
|
});
|
|
350
245
|
|
|
351
246
|
const tabOptions = [
|
|
352
|
-
{ name: "Registered",
|
|
353
|
-
{ name: "Unregistered",
|
|
247
|
+
{ name: "Registered", status: "registered" },
|
|
248
|
+
{ name: "Unregistered", status: "unregistered" },
|
|
354
249
|
];
|
|
355
250
|
|
|
356
251
|
const formatType = (item: any) =>
|
|
@@ -374,8 +269,8 @@ function filterTypeSelectionLabel() {
|
|
|
374
269
|
return `${length} selected ${length === 1 ? "type" : "types"}` as string;
|
|
375
270
|
}
|
|
376
271
|
|
|
377
|
-
function toRoute(
|
|
378
|
-
const obj = tabOptions.find((x) => x.
|
|
272
|
+
function toRoute(status: any) {
|
|
273
|
+
const obj = tabOptions.find((x) => x.status === status);
|
|
379
274
|
if (!obj) return;
|
|
380
275
|
navigateTo({
|
|
381
276
|
name: routeName,
|
|
@@ -383,7 +278,7 @@ function toRoute(type: any) {
|
|
|
383
278
|
org: orgId,
|
|
384
279
|
},
|
|
385
280
|
query: {
|
|
386
|
-
|
|
281
|
+
status: obj.status,
|
|
387
282
|
},
|
|
388
283
|
});
|
|
389
284
|
}
|
|
@@ -393,20 +288,20 @@ const {
|
|
|
393
288
|
refresh: getVisitorRefresh,
|
|
394
289
|
pending: getVisitorPending,
|
|
395
290
|
} = await useLazyAsyncData(
|
|
396
|
-
`get-all-visitors-${
|
|
291
|
+
`get-all-visitors-${activeTab.value}-${page.value}`
|
|
292
|
+
,
|
|
397
293
|
() =>
|
|
398
294
|
getVisitors({
|
|
399
295
|
page: page.value,
|
|
400
|
-
org: orgId,
|
|
401
296
|
site: siteId,
|
|
402
297
|
search: searchInput.value,
|
|
403
298
|
dateTo: dateTo.value,
|
|
404
299
|
dateFrom: dateFrom.value,
|
|
405
300
|
type: filterTypes.value.filter(Boolean).join(","),
|
|
406
|
-
|
|
301
|
+
status: activeTab.value as string,
|
|
407
302
|
}),
|
|
408
303
|
{
|
|
409
|
-
watch: [page],
|
|
304
|
+
watch: [page, () => route.query],
|
|
410
305
|
}
|
|
411
306
|
);
|
|
412
307
|
|
|
@@ -419,9 +314,9 @@ watch(getVisitorReq, (newData: any) => {
|
|
|
419
314
|
});
|
|
420
315
|
|
|
421
316
|
const selectedVisitorObject = computed(() => {
|
|
422
|
-
const obj = items.value.find((x) => x?._id === selectedVisitorId.value);
|
|
317
|
+
const obj = items.value.find((x: any) => x?._id === selectedVisitorId.value);
|
|
423
318
|
if (!obj) return {};
|
|
424
|
-
const type = obj?.type;
|
|
319
|
+
const type = obj?.type as TVisitorType | undefined;
|
|
425
320
|
if (!type) return {};
|
|
426
321
|
let includedKeys: string[] = ["checkIn", "checkOut"];
|
|
427
322
|
includedKeys.unshift(...(typeFieldMap[type] ?? []));
|
|
@@ -553,16 +448,42 @@ function getUTCDates() {
|
|
|
553
448
|
return { dateYesterday, dateToday };
|
|
554
449
|
}
|
|
555
450
|
|
|
556
|
-
|
|
557
|
-
const
|
|
451
|
+
|
|
452
|
+
const updateRouteQuery = debounce(
|
|
453
|
+
(search: string, from: string, to: string, types: string[], status) => {
|
|
454
|
+
router.replace({
|
|
455
|
+
query: {
|
|
456
|
+
...route.query,
|
|
457
|
+
search: search || undefined,
|
|
458
|
+
dateFrom: from || undefined,
|
|
459
|
+
dateTo: to || undefined,
|
|
460
|
+
type: types.filter(Boolean).join(",") || undefined,
|
|
461
|
+
status: status || undefined,
|
|
462
|
+
},
|
|
463
|
+
});
|
|
464
|
+
},
|
|
465
|
+
500 // wait 500ms after last input
|
|
466
|
+
);
|
|
558
467
|
|
|
559
468
|
watch(
|
|
560
|
-
[searchInput,
|
|
561
|
-
([]) => {
|
|
562
|
-
|
|
469
|
+
[searchInput, dateFrom, dateTo, filterTypes, activeTab],
|
|
470
|
+
([search, from, to, types, status]) => {
|
|
471
|
+
updateRouteQuery(search, from, to, types, status)
|
|
472
|
+
|
|
563
473
|
},
|
|
564
|
-
{
|
|
474
|
+
{ deep: true }
|
|
565
475
|
);
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
onMounted(() => {
|
|
480
|
+
activeTab.value = (route.query.status as string) || "unregistered"
|
|
481
|
+
searchInput.value = (route.query.search as string) || "";
|
|
482
|
+
dateFrom.value = (route.query.dateFrom as string) || "";
|
|
483
|
+
dateTo.value = (route.query.dateTo as string) || "";
|
|
484
|
+
filterTypes.value = ((route.query.type as string)?.split(",") || []).filter(Boolean) as TVisitorType[];
|
|
485
|
+
|
|
486
|
+
})
|
|
566
487
|
</script>
|
|
567
488
|
|
|
568
489
|
<style scoped></style>
|
|
@@ -16,18 +16,27 @@
|
|
|
16
16
|
@errored="onImageError"
|
|
17
17
|
/>
|
|
18
18
|
|
|
19
|
-
<v-
|
|
19
|
+
<v-autocomplete
|
|
20
|
+
v-model="workOrder.subject"
|
|
21
|
+
:items="subjects"
|
|
22
|
+
item-title="title"
|
|
23
|
+
item-value="value"
|
|
24
|
+
item-props
|
|
20
25
|
label="Subject"
|
|
21
26
|
variant="outlined"
|
|
22
27
|
density="compact"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
class="mb-2"
|
|
29
|
+
:clearable="
|
|
30
|
+
props.createdFrom === 'feedback' && workOrder.subject !== ''
|
|
31
|
+
? false
|
|
32
|
+
: true
|
|
33
|
+
"
|
|
26
34
|
:readonly="
|
|
27
35
|
props.createdFrom === 'feedback' && workOrder.subject !== ''
|
|
28
36
|
? true
|
|
29
37
|
: false
|
|
30
38
|
"
|
|
39
|
+
:custom-filter="customFilter"
|
|
31
40
|
/>
|
|
32
41
|
|
|
33
42
|
<v-autocomplete
|
|
@@ -239,4 +248,13 @@ watch(workOrderUnit, (val: string) => {
|
|
|
239
248
|
}
|
|
240
249
|
}
|
|
241
250
|
});
|
|
251
|
+
|
|
252
|
+
const { subjects } = useLocal();
|
|
253
|
+
|
|
254
|
+
const customFilter = (value: string, query: string, item: any) => {
|
|
255
|
+
const title = item?.raw?.title?.toLowerCase() || "";
|
|
256
|
+
const subtitle = item?.raw?.subtitle?.toLowerCase() || "";
|
|
257
|
+
const search = query.toLowerCase();
|
|
258
|
+
return title.includes(search) || subtitle.includes(search);
|
|
259
|
+
};
|
|
242
260
|
</script>
|
|
@@ -133,6 +133,10 @@ const props = defineProps({
|
|
|
133
133
|
type: Boolean,
|
|
134
134
|
default: false,
|
|
135
135
|
},
|
|
136
|
+
category: {
|
|
137
|
+
type: String,
|
|
138
|
+
default: "",
|
|
139
|
+
},
|
|
136
140
|
});
|
|
137
141
|
|
|
138
142
|
const theme = useTheme().name;
|
|
@@ -193,11 +197,11 @@ const {
|
|
|
193
197
|
data: getAllWorkOrderReq,
|
|
194
198
|
refresh: getAllReqRefresh,
|
|
195
199
|
status: getAllReqStatus,
|
|
196
|
-
} = useLazyAsyncData("get-all-work-orders", () =>
|
|
200
|
+
} = useLazyAsyncData("get-all-work-orders-" + props.category, () =>
|
|
197
201
|
_getWorkOrders({
|
|
198
202
|
page: page.value,
|
|
199
|
-
organization: route.params.org as string,
|
|
200
203
|
site: route.params.site as string,
|
|
204
|
+
category: props.category,
|
|
201
205
|
})
|
|
202
206
|
);
|
|
203
207
|
|
|
@@ -286,7 +290,7 @@ watchEffect(() => {
|
|
|
286
290
|
serviceProviders.value = getAllReq.value.map((i: any) => ({
|
|
287
291
|
title: i.nature.replace(/_/g, " "),
|
|
288
292
|
subtitle: i.title,
|
|
289
|
-
value: i.
|
|
293
|
+
value: i.nature
|
|
290
294
|
}));
|
|
291
295
|
}
|
|
292
296
|
});
|
|
@@ -222,7 +222,7 @@ export default function useBuilding() {
|
|
|
222
222
|
|
|
223
223
|
function updateById(
|
|
224
224
|
id: string,
|
|
225
|
-
data: Pick<TBuilding, "name" | "block" | "levels">
|
|
225
|
+
data: Pick<TBuilding, "name" | "block" | "levels" | "buildingFloorPlan">
|
|
226
226
|
) {
|
|
227
227
|
return useNuxtApp().$api(`/api/buildings/id/${id}`, {
|
|
228
228
|
method: "PATCH",
|
package/composables/usePeople.ts
CHANGED
|
@@ -19,6 +19,12 @@ export default function(){
|
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
async function findPersonByNRIC(nric: string): Promise<null | Partial<TPeople>> {
|
|
23
|
+
return await $fetch<Record<string, any>>(`/api/people/nric/${nric}`, {
|
|
24
|
+
method: "GET",
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
22
28
|
async function create(payload: Partial<TPeoplePayload>){
|
|
23
29
|
return await useNuxtApp().$api<Record<string, any>>("/api/people", {
|
|
24
30
|
method: "POST",
|
|
@@ -39,10 +45,12 @@ export default function(){
|
|
|
39
45
|
});
|
|
40
46
|
}
|
|
41
47
|
|
|
48
|
+
|
|
42
49
|
return {
|
|
43
50
|
create,
|
|
44
51
|
getAll,
|
|
45
52
|
updateById,
|
|
46
|
-
deleteById
|
|
53
|
+
deleteById,
|
|
54
|
+
findPersonByNRIC
|
|
47
55
|
}
|
|
48
56
|
}
|