@7365admin1/layer-common 1.11.54 → 3.0.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 CHANGED
@@ -1,5 +1,21 @@
1
1
  # @iservice365/layer-common
2
2
 
3
+ ## 3.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - f4ee57d: Refactor Building Management Module
8
+
9
+ ### Patch Changes
10
+
11
+ - 34bd7cf: Update on Building Unit Page
12
+
13
+ ## 2.0.0
14
+
15
+ ### Major Changes
16
+
17
+ - f4ee57d: Refactor Building Management Module
18
+
3
19
  ## 1.11.54
4
20
 
5
21
  ### Patch Changes
@@ -3,7 +3,7 @@
3
3
  <v-toolbar>
4
4
  <v-row no-gutters class="fill-height px-6" align="center">
5
5
  <span class="font-weight-bold text-h5 text-capitalize">
6
- {{ prop.mode }} Block
6
+ {{ prop.mode }} Block {{ (prop.mode === "edit" && building.block) ? `- ${building.block}` : "" }}
7
7
  </span>
8
8
  </v-row>
9
9
  </v-toolbar>
@@ -12,21 +12,21 @@
12
12
  <v-row no-gutters class="px-6 pt-4">
13
13
  <v-col cols="12" class="mt-2">
14
14
  <v-row no-gutters>
15
- <InputLabel class="text-capitalize font-weight-bold" title="Name" required />
15
+ <InputLabel class="text-capitalize font-weight-bold" title="Block Name" required />
16
16
  <v-col cols="12">
17
17
  <v-text-field v-model="building.name" density="comfortable" :rules="[requiredRule]"></v-text-field>
18
18
  </v-col>
19
19
  </v-row>
20
20
  </v-col>
21
21
 
22
- <v-col cols="12">
22
+ <v-col v-if="prop.mode === 'add'" cols="12">
23
23
  <v-row>
24
24
  <v-col cols="6" class="mt-2">
25
25
  <v-row no-gutters>
26
- <InputLabel class="text-capitalize font-weight-bold" title="Block" required />
26
+ <InputLabel class="text-capitalize font-weight-bold" title="Block No." required />
27
27
  <v-col cols="12">
28
28
  <v-select v-model.number="building.block" :items="blocks" item-title="label" item-value="value"
29
- density="comfortable" :disabled="prop.mode === 'edit'" :rules="[
29
+ density="comfortable" :rules="[
30
30
  requiredRule,
31
31
  () =>
32
32
  (building.block && building.block > 0) ||
@@ -43,7 +43,7 @@
43
43
 
44
44
  <v-col cols="6" class="mt-2">
45
45
  <v-row no-gutters>
46
- <InputLabel class="text-capitalize font-weight-bold" title="Levels" required />
46
+ <InputLabel class="text-capitalize font-weight-bold" title="No. of Levels" required />
47
47
  <v-col cols="12">
48
48
  <v-text-field v-model.number="buildingLevels" density="comfortable" :rules="[requiredRule]"
49
49
  type="number" @update:model-value="setBuildingLevels()"></v-text-field>
@@ -53,24 +53,33 @@
53
53
  </v-row>
54
54
  </v-col>
55
55
 
56
- <v-col v-if="buildingLevels" cols="12">
56
+ <!-- <v-col v-if="buildingLevels &&" cols="12">
57
57
  <v-row justify="center">
58
58
  <v-col cols="6">
59
59
  <v-btn block color="primary" variant="text" class="text-none font-weight-bold" text="Set level labels"
60
60
  @click="show = !show"></v-btn>
61
61
  </v-col>
62
62
  </v-row>
63
- </v-col>
63
+ </v-col> -->
64
+ </v-row>
65
+
66
+ <v-row no-gutters v-if="building.levels.length > 0 || newLevelsArray.length > 0" class="mt-2">
67
+ <InputLabel class="text-capitalize font-weight-bold px-6 mb-2" title="Levels" />
64
68
  </v-row>
65
69
 
66
70
  <v-expand-transition>
67
- <v-row v-show="show" no-gutters class="px-6">
71
+ <v-row v-if="prop.mode === 'edit'" no-gutters class="px-6">
68
72
  <template v-for="(level, levelIndex) in building.levels" :key="levelIndex">
69
73
  <v-col cols="12">
70
74
  <v-row no-gutters>
71
- <InputLabel class="text-capitalize font-weight-bold" :title="`Level ${levelIndex + 1}`" />
72
- <v-col cols="12">
73
- <v-text-field v-model.trim="building.levels[levelIndex]" density="comfortable"></v-text-field>
75
+ <v-col :cols="prop.mode === 'edit' ? 10 : 12">
76
+ <v-text-field v-model.trim="building.levels[levelIndex].name" density="comfortable"></v-text-field>
77
+ </v-col>
78
+ <v-col v-if="prop.mode === 'edit'" cols="2" class="d-flex align-center pb-5 justify-end">
79
+ <v-btn icon variant="text" color="error" :disabled="disable"
80
+ @click="openDeleteLevelPrompt(levelIndex)">
81
+ <v-icon icon="mdi-trash-can-outline"></v-icon>
82
+ </v-btn>
74
83
  </v-col>
75
84
  </v-row>
76
85
  </v-col>
@@ -78,9 +87,43 @@
78
87
  </v-row>
79
88
  </v-expand-transition>
80
89
 
90
+
91
+
92
+ <v-row no-gutters class="px-6 w-100">
93
+ <v-row no-gutters v-for="(newLevelsItem, index) in newLevelsArray" :key="index" :cols="12" class="w-100">
94
+ <v-text-field v-model.trim="newLevelsArray[index]" density="comfortable"></v-text-field>
95
+ <v-col cols="2" class="d-flex align-center pb-5 justify-end">
96
+ <v-btn icon variant="text" color="error" @click="newLevelsArray.splice(index, 1)">
97
+ <v-icon icon="mdi-trash-can-outline"></v-icon>
98
+ </v-btn>
99
+ </v-col>
100
+ </v-row>
101
+ </v-row>
102
+
103
+ <v-row v-if="prop.mode === 'edit'" no-gutters class="px-6 w-100">
104
+ <v-col cols="10">
105
+ <v-text-field v-model.trim="activeNewLevelInput" density="comfortable" class="w-100"
106
+ placeholder="Add new level" @click="addNewLevelErrorMessage = ''"></v-text-field>
107
+ </v-col>
108
+ <v-col cols="2" class="d-flex align-center pb-5 justify-end">
109
+ <v-btn icon variant="text" @click="addNewLevel()">
110
+ <v-icon icon="mdi-plus"></v-icon>
111
+ </v-btn>
112
+ </v-col>
113
+ </v-row>
114
+ <v-row v-if="prop.mode === 'edit'" no-gutters class="px-6 mb-2">
115
+ <span class="text-caption text-error">
116
+ {{ addNewLevelErrorMessage }}
117
+ </span>
118
+ </v-row>
119
+
120
+
121
+
122
+
81
123
  <v-col cols="12" class="px-6">
82
- <InputLabel class="text-capitalize" title="Building Floor plan" />
83
- <InputFileV2 v-model="building.buildingFiles" :multiple="true" accept="*" :max-length="10" title="Upload Files" />
124
+ <InputLabel class="text-capitalize font-weight-bold" title="Building Floor plan" />
125
+ <InputFileV2 v-model="building.buildingFiles" :multiple="true" accept="*" :max-length="10"
126
+ title="Upload Files" />
84
127
  </v-col>
85
128
 
86
129
  <v-col cols="12" class="mt-2">
@@ -121,10 +164,40 @@
121
164
  </v-col>
122
165
  </v-row>
123
166
  </v-toolbar>
167
+
168
+ <ConfirmDialog v-model="confirmDeleteLevelDialog" :loading="loading.deletingLevel" width="450" persistent>
169
+ <template #title>
170
+ Delete Level
171
+ </template>
172
+
173
+ <template #description>
174
+ Are you sure you want to delete {{ levelPendingDeleteName || "this level" }}?
175
+ </template>
176
+
177
+ <template #footer>
178
+ <v-row no-gutters class="w-100">
179
+ <v-col cols="6">
180
+ <v-btn tile block size="48" variant="text" class="text-none" :disabled="loading.deletingLevel"
181
+ @click="closeDeleteLevelPrompt">
182
+ Cancel
183
+ </v-btn>
184
+ </v-col>
185
+
186
+ <v-col cols="6">
187
+ <v-btn tile block size="48" variant="flat" color="error" class="text-none" :loading="loading.deletingLevel"
188
+ :disabled="loading.deletingLevel" @click="confirmDeleteLevel">
189
+ Delete
190
+ </v-btn>
191
+ </v-col>
192
+ </v-row>
193
+ </template>
194
+ </ConfirmDialog>
124
195
  </v-card>
125
196
  </template>
126
197
 
127
198
  <script setup lang="ts">
199
+ import InputLabel from './InputLabel.vue';
200
+
128
201
  const prop = defineProps({
129
202
  site: {
130
203
  type: String,
@@ -152,6 +225,7 @@ const prop = defineProps({
152
225
 
153
226
  const { getSiteById } = useSite();
154
227
  const { getFileById } = useFile();
228
+ const { deleteById, batchUpdateLevels } = useBuildingLevel();
155
229
 
156
230
  const site = ref<TSite | null>(null);
157
231
 
@@ -184,21 +258,64 @@ const blocks = computed(() => {
184
258
  return formattedArray;
185
259
  });
186
260
 
187
- const emit = defineEmits(["cancel", "success", "success:create-more"]);
261
+ const emit = defineEmits(["cancel", "success", "success:create-more", "refresh"]);
188
262
 
189
263
  const validForm = ref(false);
190
264
 
191
265
  const buildingLevels = ref(0);
266
+ const newLevelsArray = ref<string[]>([])
267
+ const activeNewLevelInput = ref<string>("")
268
+ const addNewLevelErrorMessage = ref("");
269
+
270
+ const loading = reactive({
271
+ deletingLevel: false,
272
+ });
192
273
 
193
274
  const show = ref(false);
275
+ const confirmDeleteLevelDialog = ref(false);
276
+ const levelPendingDeleteIndex = ref<number | null>(null);
277
+ const levelActionLoading = ref(false);
278
+
279
+ const levelPendingDeleteName = computed(() => {
280
+ if (levelPendingDeleteIndex.value === null) return "";
281
+ return building.value.levels[levelPendingDeleteIndex.value]?.name ?? "";
282
+ });
194
283
 
195
284
  function setBuildingLevels() {
196
- building.value.levels.length = 0;
285
+ newLevelsArray.value = [];
197
286
  for (let index = 0; index < buildingLevels.value; index++) {
198
- building.value.levels.push(`Lvl${index + 1}`);
287
+ newLevelsArray.value.push(`Lvl${index + 1}`);
199
288
  }
200
289
  }
201
290
 
291
+ // function addNewLevels() {
292
+ // const levelsToAdd = newLevelsInput.value
293
+ // .split(/\r?\n|,/)
294
+ // .map((item) => item.trim())
295
+ // .filter(Boolean);
296
+
297
+ // if (!levelsToAdd.length) return;
298
+ // buildingLevels.value = building.value.levels.length;
299
+ // newLevelsInput.value = "";
300
+ // }
301
+
302
+ function openDeleteLevelPrompt(levelIndex: number) {
303
+ levelPendingDeleteIndex.value = levelIndex;
304
+ confirmDeleteLevelDialog.value = true;
305
+ }
306
+
307
+ function closeDeleteLevelPrompt() {
308
+ confirmDeleteLevelDialog.value = false;
309
+ levelPendingDeleteIndex.value = null;
310
+ }
311
+
312
+ async function deleteLevelPlaceholder(levelName: string, levelIndex: number) {
313
+ // Placeholder integration for future delete-level API call.
314
+ return { success: true, levelName, levelIndex };
315
+ }
316
+
317
+
318
+
202
319
  const building = ref<TBuilding>({
203
320
  site: "",
204
321
  name: "",
@@ -207,13 +324,17 @@ const building = ref<TBuilding>({
207
324
  buildingFiles: []
208
325
  });
209
326
 
327
+ const initialBuildingLevels = ref([])
328
+
210
329
  // Normalize buildingFiles: extract IDs for InputFileV2, keep names in a separate map
211
330
  const buildingFilesNames = ref<Record<string, string>>({});
212
331
 
213
332
  building.value.site = prop.site;
214
333
  if (prop.mode === "edit") {
215
334
  building.value = JSON.parse(JSON.stringify(prop.building));
335
+ building.value.levels = building.value.levels.map((level: any) => ({ _id: level._id, name: level.name })); //temporary
216
336
  buildingLevels.value = building.value.levels.length;
337
+ initialBuildingLevels.value = JSON.parse(JSON.stringify(building.value.levels));
217
338
 
218
339
  const rawFiles = building.value.buildingFiles as any[];
219
340
  if (rawFiles?.length && typeof rawFiles[0] === 'object') {
@@ -256,16 +377,34 @@ async function submit() {
256
377
  try {
257
378
  if (prop.mode === "add") {
258
379
  const buildingPayload = { ...building.value };
259
- buildingPayload.buildingFiles = (building.value.buildingFiles as string[] || []).map((id) => ({ id, name: buildingFilesNames.value[id] ?? "" }));
260
- await createBuilding(buildingPayload);
380
+
381
+ let payload: TBuildingPayload = {
382
+ site: buildingPayload.site,
383
+ name: buildingPayload.name,
384
+ block: buildingPayload.block,
385
+ levels: [...newLevelsArray.value],
386
+ buildingFiles: (building.value.buildingFiles as string[] || []).map((id) => ({ id, name: buildingFilesNames.value[id] ?? "" }))
387
+ };
388
+
389
+ await createBuilding(payload);
261
390
  }
262
391
 
263
392
  if (prop.mode === "edit") {
393
+
394
+ console.log('Updating building with levels:', building.value.levels);
395
+
396
+ if(JSON.stringify(initialBuildingLevels.value) !== JSON.stringify(building.value.levels)) {
397
+ await batchUpdateLevels(building.value.levels as { _id: string; name: string }[]);
398
+ }
399
+
400
+ const newLevels = [...newLevelsArray.value, ...(activeNewLevelInput.value.trim() ? [activeNewLevelInput.value.trim()] : [])];
401
+
264
402
  await updateById(building.value._id ?? "", {
265
403
  name: building.value.name,
266
404
  block: building.value.block,
267
- levels: building.value.levels,
268
- buildingFiles: (building.value.buildingFiles as string[] || []).map((id) => ({ id, name: buildingFilesNames.value[id] ?? "" }))
405
+ // levels: building.value.levels,
406
+ buildingFiles: (building.value.buildingFiles as string[] || []).map((id) => ({ id, name: buildingFilesNames.value[id] ?? "" })),
407
+ ...(newLevels.length > 0 ? { levels: newLevels } : {})
269
408
  });
270
409
  }
271
410
 
@@ -288,6 +427,49 @@ async function submit() {
288
427
  }
289
428
  }
290
429
 
430
+
431
+ const addNewLevel = () => {
432
+ if (!activeNewLevelInput.value.trim()) {
433
+ addNewLevelErrorMessage.value = "Please fill in the current new level before adding another.";
434
+ return;
435
+ }
436
+ newLevelsArray.value.push(activeNewLevelInput.value);
437
+ activeNewLevelInput.value = "";
438
+ }
439
+
440
+ const confirmDeleteLevel = async () => {
441
+ const levelIndex = levelPendingDeleteIndex.value;
442
+ if (levelIndex === null) {
443
+ console.error("No level selected for deletion.");
444
+ return;
445
+ }
446
+ const levelId = building.value.levels[levelIndex]._id;
447
+ if (!levelId) {
448
+ console.error("Level ID is missing. Cannot delete level.");
449
+ return;
450
+ }
451
+
452
+ try {
453
+ loading.deletingLevel = true;
454
+ await deleteById(levelId);
455
+ const index = building.value.levels.findIndex(level => level._id === levelId);
456
+ closeDeleteLevelPrompt();
457
+ if (index !== -1) {
458
+ building.value.levels.splice(index, 1);
459
+ buildingLevels.value = building.value.levels.length;
460
+ }
461
+ emit('refresh')
462
+ } catch (error: any) {
463
+ console.error("Failed to delete level:", error);
464
+ const message = error.response?._data?.message || "Failed to delete level";
465
+ message.value = message;
466
+ } finally {
467
+ loading.deletingLevel = false;
468
+ }
469
+
470
+
471
+ }
472
+
291
473
  watch(buildingLevels, (newVal) => {
292
474
  setTimeout(() => {
293
475
  show.value = newVal > 0 && !!newVal;
@@ -43,12 +43,12 @@
43
43
  <v-dialog v-model="createDialog" width="450" persistent>
44
44
  <BuildingForm :site="site" :blocks="items" @cancel="createDialog = false" @success="successCreate()"
45
45
  @success:create-more="getBuildings()" />
46
- </v-dialog>
46
+ </v-dialog>
47
47
 
48
48
  <!-- Edit Dialog -->
49
49
  <v-dialog v-model="editDialog" width="450" persistent>
50
50
  <BuildingForm :site="site" :blocks="items" mode="edit" @cancel="editDialog = false" @success="successUpdate()"
51
- :building="selectedBuilding" />
51
+ :building="selectedBuilding" @refresh="getBuildings()" />
52
52
  </v-dialog>
53
53
 
54
54
  <!-- Preview Dialog -->
@@ -103,12 +103,12 @@ const props = defineProps({
103
103
  },
104
104
  {
105
105
  title: "Level",
106
- value: "level",
107
- },
108
- {
109
- title: "Block",
110
- value: "block",
106
+ value: "level.name",
111
107
  },
108
+ // {
109
+ // title: "Block",
110
+ // value: "block",
111
+ // },
112
112
  {
113
113
  title: "Block Name",
114
114
  value: "buildingName",
@@ -31,12 +31,12 @@
31
31
  item-value="_id" v-model:search="searchBuilding" :hide-no-data="false" density="comfortable"
32
32
  :rules="[requiredRule]" variant="outlined">
33
33
  <template v-slot:item="{ props: itemProps, item }">
34
- <v-list-item v-bind="itemProps" :title="`Block ${item?.raw?.block} (${item?.raw?.name})`">
34
+ <v-list-item v-bind="itemProps" :title="item?.raw?.name">
35
35
 
36
36
  </v-list-item>
37
37
  </template>
38
38
  <template v-slot:selection="{ item }">
39
- {{ buildingUnit.building && `Block ${item?.raw?.block} (${item?.raw?.name})` }}
39
+ {{ buildingUnit.building && `${item?.raw?.name}` }}
40
40
  </template>
41
41
  </v-autocomplete>
42
42
  </v-col>
@@ -47,7 +47,7 @@
47
47
  <v-row no-gutters>
48
48
  <InputLabel class="text-capitalize" title="Level" required />
49
49
  <v-col cols="12">
50
- <v-select v-model="buildingUnit.level" :items="buildingLevels" density="comfortable"
50
+ <v-select v-model="buildingUnit.level" :items="buildingLevels" item-title="name" item-value="_id" density="comfortable"
51
51
  :rules="[requiredRule]"></v-select>
52
52
  </v-col>
53
53
  </v-row>
@@ -275,7 +275,7 @@ watchEffect(() => {
275
275
 
276
276
  const buildingUnitQty = ref(1);
277
277
 
278
- const buildingUnit = ref<TBuildingUnit>({
278
+ const buildingUnit = ref<TBuildingUnitPayload>({
279
279
  site: "",
280
280
  name: "Unit",
281
281
  building: "",
@@ -29,10 +29,11 @@
29
29
 
30
30
  <v-col cols="12" md="6" lg="4" class="mt-2">
31
31
  <v-row no-gutters>
32
- <InputLabel class="text-capitalize font-weight-bold" title="Level" required />
32
+ <InputLabel class="text-capitalize font-weight-bold" title="Level"/>
33
33
  <v-col cols="12">
34
- <v-select v-model="buildingUnit.level" :items="buildingLevels" density="comfortable"
35
- :rules="[requiredRule]"></v-select>
34
+ <!-- <v-select v-model="buildingUnit.level" :items="buildingLevels" readonly item-title="name" class="no-pointer" item-value="_id" density="comfortable"
35
+ :rules="[requiredRule]"></v-select> -->
36
+ <v-text-field :model-value="buildingUnit.level.name" density="comfortable" readonly class="no-pointer" />
36
37
  </v-col>
37
38
  </v-row>
38
39
  </v-col>
@@ -43,7 +44,7 @@
43
44
  <v-row no-gutters>
44
45
  <InputLabel class="text-capitalize font-weight-bold" title="Block Name" />
45
46
  <v-col cols="12">
46
- <v-text-field :model-value="`Block ${buildingUnit.block} (${buildingUnit.buildingName})`"
47
+ <v-text-field :model-value="buildingUnit.buildingName"
47
48
  density="comfortable" readonly class="no-pointer"></v-text-field>
48
49
  </v-col>
49
50
  </v-row>
@@ -328,7 +329,10 @@ const buildingUnit = ref({
328
329
  ownerName: "",
329
330
  building: "",
330
331
  buildingName: "",
331
- level: 0,
332
+ level: {
333
+ _id: "",
334
+ name: "",
335
+ },
332
336
  // category: "",
333
337
  block: null,
334
338
  status: "active",
@@ -457,13 +461,13 @@ const selectedBuilding = computed(() => {
457
461
  return buildings.value.find((b) => b.value === buildingUnit.value.building);
458
462
  });
459
463
 
460
- const buildingLevels = computed(() => {
461
- const levels = selectedBuilding.value?.levels ?? [];
462
- return levels.map((level: string) => ({
463
- title: level,
464
- value: level,
465
- }))
466
- });
464
+ // const buildingLevels = computed(() => {
465
+ // const levels = selectedBuilding.value?.levels ?? [];
466
+ // return levels.map((level: { name: string; _id: string }) => ({
467
+ // name: level.name,
468
+ // value: level._id,
469
+ // }))
470
+ // });
467
471
 
468
472
  const disable = ref(false);
469
473
 
@@ -500,7 +504,7 @@ async function submit() {
500
504
 
501
505
  await updateById(buildingUnit.value._id ?? "", {
502
506
  name: buildingUnit.value.name,
503
- level: buildingUnit.value.level,
507
+ level: buildingUnit.value.level._id,
504
508
  // category: buildingUnit.value.category,
505
509
  buildingUnitFiles: (buildingUnit.value.buildingUnitFiles as string[] || []).map((id) => ({ id, name: buildingUnitFilesNames.value[id] ?? "" })),
506
510
  companyName: buildingUnit.value.companyName,
@@ -276,13 +276,16 @@
276
276
  <v-col cols="6" class="text-body-1">Document</v-col>
277
277
  <v-col cols="6" class="text-right text-body-1">
278
278
  <NuxtLink
279
- v-if="selectedDocument?.attachment"
279
+ v-if="selectedDocument?.attachment && isViewable"
280
280
  :to="getFileUrl(selectedDocument.attachment)"
281
281
  external
282
282
  target="_blank"
283
283
  >
284
284
  View Document
285
285
  </NuxtLink>
286
+ <span v-else-if="selectedDocument?.attachment" class="text-grey" style="opacity: 0.6; cursor: not-allowed;">
287
+ View Document
288
+ </span>
286
289
  <span v-else>N/A</span>
287
290
  </v-col>
288
291
  </v-row>
@@ -660,6 +663,11 @@ const selectedDocument = ref<TDocument>({
660
663
  type: "",
661
664
  });
662
665
 
666
+ const isViewable = computed(() => {
667
+ const lowerType = String(selectedDocument.value?.type || "").trim().toLowerCase();
668
+ return ["pdf", "doc", "csv"].includes(lowerType);
669
+ });
670
+
663
671
  const previewDetails = computed(() => {
664
672
  const document = selectedDocument.value as Record<string, any>;
665
673
  const fileType =
@@ -548,7 +548,7 @@
548
548
  </v-col>
549
549
  <v-col cols="12" class="mt-4">
550
550
  <v-number-input
551
- v-model="facility.maxNumberGuest"
551
+ v-model="facility.maxNumberGuestLimit"
552
552
  :reverse="false"
553
553
  controlVariant="default"
554
554
  label="Maximum no. of guests"
@@ -1015,30 +1015,30 @@ const handlePolicy = (newContent: string) => {
1015
1015
 
1016
1016
  function onToggleBookingUnitLimit(val: any) {
1017
1017
  if (val) {
1018
- isBookingUnitLimitEnabled.value = true;
1018
+ facility.value.isBookingUnitLimitEnabled = true;
1019
1019
  facility.value.bookingUnitLimit = 1;
1020
1020
  } else {
1021
- isBookingUnitLimitEnabled.value = false;
1021
+ facility.value.isBookingUnitLimitEnabled = false;
1022
1022
  facility.value.bookingUnitLimit = null;
1023
1023
  }
1024
1024
  }
1025
1025
 
1026
1026
  function onToggleMaxNumberGuestLimit(val: any) {
1027
1027
  if (val) {
1028
- isMaxNumberGuestLimitEnabled.value = true;
1029
- facility.value.maxNumberGuest = 1;
1028
+ facility.value.isMaxNumberGuestLimitEnabled = true;
1029
+ facility.value.maxNumberGuestLimit = 1;
1030
1030
  } else {
1031
- isMaxNumberGuestLimitEnabled.value = false;
1032
- facility.value.maxNumberGuest = null;
1031
+ facility.value.isMaxNumberGuestLimitEnabled = false;
1032
+ facility.value.maxNumberGuestLimit = null;
1033
1033
  }
1034
1034
  }
1035
1035
 
1036
1036
  function onToggleCancelAllowedLimit(val: any) {
1037
1037
  if (val) {
1038
- isCancelAllowedLimitEnabled.value = true;
1038
+ facility.value.isCancelAllowedLimitEnabled = true;
1039
1039
  facility.value.daysAllowedCancel = 1;
1040
1040
  } else {
1041
- isCancelAllowedLimitEnabled.value = false;
1041
+ facility.value.isCancelAllowedLimitEnabled = false;
1042
1042
  facility.value.daysAllowedCancel = null;
1043
1043
  }
1044
1044
  }
@@ -267,7 +267,7 @@ const { create: _add, updateById: _update, getAll: _getAll } = useOnlineFormConf
267
267
 
268
268
  const { data: existingFormsData } = useLazyAsyncData(
269
269
  `online-form-configurations-filter-${siteId}-${Date.now()}`,
270
- () => _getAll({ site: siteId, org: orgId, limit: 100 })
270
+ () => _getAll({ site: siteId, org: orgId, status: "active", limit: 100 })
271
271
  );
272
272
 
273
273
  const availableTemplateNames = computed(() => {
@@ -32,6 +32,16 @@
32
32
  >
33
33
  <v-icon>mdi-refresh</v-icon>
34
34
  </v-btn>
35
+ <v-text-field
36
+ v-model="search"
37
+ density="compact"
38
+ variant="outlined"
39
+ placeholder="Search..."
40
+ prepend-inner-icon="mdi-magnify"
41
+ clearable
42
+ hide-details
43
+ style="width: 220px; margin-left: 12px;"
44
+ />
35
45
  </template>
36
46
 
37
47
  <template #append>
@@ -263,6 +273,8 @@
263
273
  <script setup lang="ts">
264
274
  import OnlineFormConfigurationForm from "./OnlineFormConfigurationForm.vue";
265
275
  import OnlineFormRenderPreview from "./OnlineFormRenderPreview.vue";
276
+ import useFile from "../composables/useFile";
277
+ import useOnlineFormConfiguration from "../composables/useOnlineFormConfiguration";
266
278
 
267
279
  definePageMeta({
268
280
  middleware: ["01-auth", "02-org"],
@@ -306,13 +318,13 @@ const props = defineProps({
306
318
  },
307
319
  });
308
320
 
309
- const { headerSearch } = useLocal();
310
321
  const { getAll: _getAll, deleteById: _deleteById } = useOnlineFormConfiguration();
311
322
  const { getFileUrl } = useFile();
312
323
 
313
324
  const page = ref(1);
314
325
  const pages = ref(0);
315
326
  const pageRange = ref("-- - -- of --");
327
+ const search = ref("");
316
328
 
317
329
  const message = ref("");
318
330
  const messageSnackbar = ref(false);
@@ -333,7 +345,8 @@ const {
333
345
  } = useLazyAsyncData("get-all-online-form-configuration", () =>
334
346
  _getAll({
335
347
  page: page.value,
336
- search: headerSearch.value,
348
+ search: search.value,
349
+ status: "active",
337
350
  org: orgId,
338
351
  site: siteId,
339
352
  })
@@ -341,6 +354,15 @@ const {
341
354
 
342
355
  const loading = computed(() => getAllReqStatus.value === "pending");
343
356
 
357
+ let searchDebounce: ReturnType<typeof setTimeout> | null = null;
358
+ watch(search, () => {
359
+ if (searchDebounce) clearTimeout(searchDebounce);
360
+ searchDebounce = setTimeout(() => {
361
+ page.value = 1;
362
+ getOnlineFormConfigurations();
363
+ }, 400);
364
+ });
365
+
344
366
  watchEffect(() => {
345
367
  if (getOnlineFormConfigurationReq.value) {
346
368
  items.value = getOnlineFormConfigurationReq.value.items;