@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.
@@ -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>
@@ -299,7 +299,7 @@ watchEffect(() => {
299
299
  serviceProviders.value = getAllReq.value.map((i: any) => ({
300
300
  title: i.nature.replace(/_/g, " "),
301
301
  subtitle: i.title,
302
- value: i._id.org,
302
+ value: i.nature
303
303
  }));
304
304
  }
305
305
  });
@@ -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>
@@ -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 - (200px))">
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