@iservice365/layer-common 1.4.0 → 1.4.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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @iservice365/layer-common
2
2
 
3
+ ## 1.4.2
4
+
5
+ ### Patch Changes
6
+
7
+ - d71fd3b: Add new services
8
+
9
+ ## 1.4.1
10
+
11
+ ### Patch Changes
12
+
13
+ - 8290615: Add pool maintenance services
14
+
3
15
  ## 1.4.0
4
16
 
5
17
  ### Minor Changes
@@ -0,0 +1,226 @@
1
+ <template>
2
+ <v-card width="100%" :loading="processing">
3
+ <v-toolbar>
4
+ <v-row no-gutters class="fill-height px-6" align="center">
5
+ <span class="font-weight-bold text-h5 text-capitalize">
6
+ {{ prop.mode }} Facility
7
+ </span>
8
+ </v-row>
9
+ </v-toolbar>
10
+ <v-card-text style="max-height: 100vh; overflow-y: auto" class="pa-5 my-3">
11
+ <v-form ref="formRef" v-model="validForm" :disabled="processing" @click="errorMessage = ''">
12
+ <v-row no-gutters class="pt-4">
13
+
14
+ <v-col cols="12">
15
+ <v-expansion-panels v-model="panels">
16
+ <template v-for="section in sections" :key="section.value">
17
+ <v-expansion-panel :value="section.value" :color="panels.includes(section.value) ? 'primary-button' : 'grey-lighten-3'" elevation="3" >
18
+ <v-expansion-panel-title>
19
+ <span class="font-weight-bold">{{ section.label }}</span>
20
+ </v-expansion-panel-title>
21
+ <v-expansion-panel-text>
22
+ <component :is="section.component" class="" />
23
+ <!-- v-model="form[section.value]" -->
24
+ </v-expansion-panel-text>
25
+ </v-expansion-panel>
26
+ </template>
27
+ </v-expansion-panels>
28
+ </v-col>
29
+
30
+ <v-col v-if="prop.mode === 'add'" cols="12" class="mt-2">
31
+ <v-checkbox v-model="createMore" density="comfortable" hide-details>
32
+ <template #label>
33
+ <span class="text-subtitle-2 font-weight-bold">
34
+ Create more
35
+ </span>
36
+ </template>
37
+ </v-checkbox>
38
+ </v-col>
39
+
40
+ </v-row>
41
+ </v-form>
42
+ </v-card-text>
43
+
44
+ <v-row no-gutters class="w-100" v-if="errorMessage">
45
+ <p class="text-error w-100 text-center text-subtitle-2">{{ errorMessage }}</p>
46
+ </v-row>
47
+ <v-toolbar density="compact">
48
+ <v-row no-gutters>
49
+ <v-col cols="6">
50
+ <v-btn tile block variant="text" class="text-none" size="48" @click="close" text="Close" />
51
+ </v-col>
52
+ <v-col cols="6">
53
+ <v-btn tile block variant="flat" color="primary-button" class="text-none" size="48" :disabled="processing || !validForm" text="Submit" />
54
+ </v-col>
55
+ </v-row>
56
+ </v-toolbar>
57
+ </v-card>
58
+ </template>
59
+
60
+ <script setup lang="ts">
61
+ import FacilityFormInformation from './FacilityFormInformation.vue';
62
+ import FacilityFormAvailability from './FacilityFormAvailability.vue';
63
+ import FacilityFormDescription from './FacilityFormDescription.vue';
64
+ import FacilityFormRefund from './FacilityFormRefund.vue';
65
+ import FacilityFormBookingFee from './FacilityFormBookingFee.vue';
66
+ import FacilityFormDepositFee from './FacilityFormDepositFee.vue';
67
+ import FacilityFormBookingPolicy from './FacilityFormBookingPolicy.vue';
68
+ import FacilityFormSecurityChecklist from './FacilityFormSecurityChecklist.vue';
69
+ import FacilityFormRulesAndPolicies from './FacilityFormRulesAndPolicies.vue';
70
+
71
+
72
+
73
+ const prop = defineProps({
74
+ site: {
75
+ type: String,
76
+ required: true
77
+ },
78
+ mode: {
79
+ type: String as PropType<'add' | 'edit'>,
80
+ default: 'add'
81
+ },
82
+ activeId: {
83
+ type: String as PropType<string | null>, // id of person you are trying to update
84
+ default: null
85
+ },
86
+ people: {
87
+ type: Object as PropType<TPeople>,
88
+ required: false
89
+ }
90
+ });
91
+
92
+ const { requiredRule, formatDateISO8601 } = useUtils();
93
+ const { getSiteById, getSiteLevels, getSiteUnits } = useSiteSettings();
94
+ const { create, updateById } = usePeople();
95
+
96
+ const emit = defineEmits(['back', 'select', 'done', 'done:more', 'error', 'close']);
97
+ const panels = ref<string[]>(['facilityInformation'])
98
+
99
+ const sections = [
100
+ { label: "Facility Information", value: "facilityInformation", component: FacilityFormInformation },
101
+ { label: "Facility Availability", value: "facilityAvailability", component: FacilityFormAvailability },
102
+ { label: "Facility Description", value: "facilityDescription", component: FacilityFormDescription },
103
+ { label: "Refund", value: "refund", component: FacilityFormRefund },
104
+ { label: "Booking Fee", value: "bookingFee", component: FacilityFormBookingFee },
105
+ { label: "Deposit Fee", value: "depositFee", component: FacilityFormDepositFee },
106
+ { label: "Booking Policy", value: "bookingPolicy", component: FacilityFormBookingPolicy },
107
+ { label: "Security Checklist", value: "securityChecklist", component: FacilityFormSecurityChecklist },
108
+ { label: "Facility Rules and Policies", value: "facilityRulesAndPolicies", component: FacilityFormRulesAndPolicies },
109
+ ];
110
+
111
+ const form = reactive<Partial<TPeoplePayload>>({})
112
+
113
+
114
+ const validForm = ref(false);
115
+ const formRef = ref<HTMLFormElement | null>(null);
116
+ const processing = ref(false);
117
+ const message = ref('');
118
+ const errorMessage = ref('');
119
+ const createMore = ref(false)
120
+
121
+
122
+ const step = ref(1)
123
+
124
+
125
+
126
+ function dateToday() {
127
+ const today = new Date()
128
+ return today.toISOString()
129
+ }
130
+
131
+
132
+
133
+ function close(){
134
+ emit('close')
135
+ }
136
+
137
+
138
+ function resetForm() {
139
+ formRef.value?.resetValidation();
140
+ Object.assign(form, {
141
+ });
142
+
143
+ validForm.value = false;
144
+ }
145
+
146
+
147
+
148
+ async function submit() {
149
+ formRef.value!.validate()
150
+ errorMessage.value = '';
151
+ processing.value = true;
152
+
153
+ let payload: Partial<TPeoplePayload> = {}
154
+
155
+ if (prop.mode === 'add') {
156
+ payload = {
157
+ ...payload,
158
+ site: prop.site,
159
+ ...form,
160
+ }
161
+
162
+ } else if (prop.mode === 'edit') {
163
+ const { type, ...rest } = form
164
+ payload = {
165
+ ...payload,
166
+ ...rest
167
+ }
168
+
169
+ }
170
+ try {
171
+ if (prop.mode === 'add') {
172
+ await create(payload)
173
+ } else if (prop.mode === 'edit') {
174
+ const userId = prop.activeId
175
+ if (!userId) {
176
+ throw new Error('User Id prop is not defined')
177
+ }
178
+
179
+ await updateById(userId, payload)
180
+ }
181
+
182
+ if (createMore.value) {
183
+ resetForm()
184
+ step.value = 1;
185
+ errorMessage.value = ""
186
+ emit("done:more")
187
+ createMore.value = false
188
+ } else emit("done")
189
+
190
+ } catch (error: any) {
191
+ const err = error?.data?.message
192
+ errorMessage.value = err || `Failed to ${prop.mode === 'add' ? 'add' : 'update'}. Please try again.`;
193
+ } finally {
194
+ processing.value = false;
195
+ }
196
+ }
197
+
198
+
199
+ async function mountExistingData() {
200
+ setTimeout(() => {
201
+ const people = prop.people
202
+ if (!people) return
203
+
204
+ (Object.keys(form) as (keyof typeof form)[]).forEach((key) => {
205
+ if (key in people) {
206
+ form[key] = people[key as keyof TPeople]
207
+ }
208
+ })
209
+ }, 100)
210
+ }
211
+
212
+ onMounted(() => {
213
+ createMore.value = false;
214
+ if (prop.mode === 'edit') {
215
+ mountExistingData()
216
+ } else {
217
+ form.start = dateToday()
218
+ }
219
+ })
220
+
221
+ </script>
222
+ <style scoped>
223
+ .button-outline-class {
224
+ border: 1px solid rgba(var(--v-theme-primary));
225
+ }
226
+ </style>
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <div>
3
+ Im a Form
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+
9
+ </script>
10
+
11
+ <style scoped>
12
+
13
+ </style>
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <div>
3
+ Im a Form
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+
9
+ </script>
10
+
11
+ <style scoped>
12
+
13
+ </style>
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <div>
3
+ Im a Form
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+
9
+ </script>
10
+
11
+ <style scoped>
12
+
13
+ </style>
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <div>
3
+ Im a Form
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+
9
+ </script>
10
+
11
+ <style scoped>
12
+
13
+ </style>
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <div>
3
+ Im a Form
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+
9
+ </script>
10
+
11
+ <style scoped>
12
+
13
+ </style>
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <v-row no-gutters>
3
+ <v-col cols="12">
4
+ <InputLabel class="text-capitalize" title="Facility Name" required />
5
+ <v-text-field v-model.trim="form.name" density="compact" :rules="[requiredRule]" />
6
+ </v-col>
7
+
8
+ <v-col cols="12">
9
+ <InputLabel class="text-capitalize" title="Select Icon" required />
10
+ <v-select v-model="form.icon" :items="iconsArray" density="comfortable"
11
+ @update:model-value="handleChangeLevel" :rules="[requiredRule]" />
12
+ </v-col>
13
+
14
+ <v-col cols="12">
15
+ <InputLabel class="text-capitalize" title="Attach Image" />
16
+ <InputFileV2 v-model="form.gallery" multiple :max-length="3" />
17
+ </v-col>
18
+ </v-row>
19
+ </template>
20
+
21
+ <script setup lang="ts">
22
+ const { requiredRule } = useUtils()
23
+
24
+ const form = defineModel({
25
+ default: {
26
+ name: "",
27
+ icon: "",
28
+ gallery: [] as string[]
29
+ }
30
+ })
31
+
32
+ const iconsArray = ref([])
33
+
34
+ function handleChangeLevel(){
35
+
36
+ }
37
+
38
+ </script>
39
+
40
+ <style scoped></style>
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <div>
3
+ Im a Form
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+
9
+ </script>
10
+
11
+ <style scoped>
12
+
13
+ </style>
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <div>
3
+ Im a Form
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+
9
+ </script>
10
+
11
+ <style scoped>
12
+
13
+ </style>
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <div>
3
+ Im a Form
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+
9
+ </script>
10
+
11
+ <style scoped>
12
+
13
+ </style>
@@ -1,78 +1,73 @@
1
1
  <template>
2
2
  <v-row no-gutters>
3
3
  <v-col cols="12" class="mb-2">
4
- <v-row no-gutters>
4
+ <v-row no-gutters align="center" justify="space-between">
5
5
  <v-btn
6
6
  class="text-none text-capitalize"
7
7
  rounded="pill"
8
8
  variant="tonal"
9
- @click="showCreateDialog = true"
10
9
  size="large"
10
+ @click="showCreateDialog = true"
11
11
  v-if="canCreateFeedback"
12
12
  >
13
13
  Create Feedback
14
14
  </v-btn>
15
+
16
+ <v-text-field
17
+ v-model="searchText"
18
+ placeholder="Search feedback..."
19
+ variant="outlined"
20
+ density="comfortable"
21
+ clearable
22
+ hide-details
23
+ class="ml-2"
24
+ style="max-width: 250px"
25
+ />
15
26
  </v-row>
16
27
  </v-col>
17
28
 
18
29
  <v-col cols="12">
19
- <ListView
20
- :headers="headers"
21
- :items="items"
22
- :pages="pages"
23
- :page-range="pageRange"
24
- :loading="loading || onNextPrevPageLoading"
25
- :height="'calc(100vh - 175px)'"
26
- v-model:page="page"
27
- :selected="selected"
28
- @update:value="getAllReqRefresh"
29
- @update:selected="onSelectedUpdate"
30
- @click:create="showCreateDialog = true"
31
- :viewPage="{ name: 'org-site-feedbacks-id' }"
32
- :clickable-rows="true"
33
- :length="pages"
34
- @update:pagination="updatePage"
30
+ <v-card
31
+ width="100%"
32
+ variant="outlined"
33
+ border="thin"
34
+ rounded="lg"
35
+ :loading="loading"
35
36
  >
36
- <template #title>
37
- <span class="text-h6 font-weight-regular">Feedbacks</span>
38
- </template>
39
-
40
- <template #category="{ item }">
41
- <span class="text-capitalize">{{ item.category }}</span>
42
- </template>
43
-
44
- <template #status="{ item }">
45
- <v-chip
46
- :color="getColorStatus(item.status || 'No Status')"
47
- text-color="white"
48
- variant="flat"
49
- >
50
- {{ item.status || "No Status" }}
51
- </v-chip>
52
- </template>
53
-
54
- <template #action-table="{ item }">
55
- <v-menu
56
- v-model="item.menuOpen"
57
- :close-on-content-click="false"
58
- offset-y
59
- width="150"
60
- >
61
- <template v-slot:activator="{ props }">
62
- <v-icon v-bind="props">mdi-dots-horizontal-circle-outline</v-icon>
63
- </template>
64
- <v-list>
65
- <v-list-item @click="onViewFeedback(item)">View</v-list-item>
66
- <v-list-item @click="editFeedback(item)">Edit</v-list-item>
67
- <v-list-item
68
- @click="confirmDeleteFeedback(item)"
69
- v-if="canDeleteFeedback"
70
- >Delete</v-list-item
71
- >
72
- </v-list>
73
- </v-menu>
74
- </template>
75
- </ListView>
37
+ <v-toolbar density="compact" color="grey-lighten-4">
38
+ <template #prepend>
39
+ <v-btn fab icon density="comfortable" @click="updatePage">
40
+ <v-icon>mdi-refresh</v-icon>
41
+ </v-btn>
42
+ </template>
43
+
44
+ <template #append>
45
+ <v-row no-gutters justify="end" align="center">
46
+ <span class="mr-2 text-caption text-fontgray">
47
+ {{ pageRange }}
48
+ </span>
49
+ <local-pagination
50
+ v-model="page"
51
+ :length="pages"
52
+ @update:value="updatePage"
53
+ />
54
+ </v-row>
55
+ </template>
56
+ </v-toolbar>
57
+
58
+ <v-data-table
59
+ :headers="headers"
60
+ :items="items"
61
+ item-value="_id"
62
+ items-per-page="20"
63
+ fixed-header
64
+ hide-default-footer
65
+ hide-default-header
66
+ @click:row="tableRowClickHandler"
67
+ style="max-height: calc(100vh - (200px))"
68
+ >
69
+ </v-data-table>
70
+ </v-card>
76
71
  </v-col>
77
72
  </v-row>
78
73
 
@@ -123,6 +118,82 @@
123
118
  </ConfirmDialog>
124
119
 
125
120
  <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
121
+
122
+ <!-- Preview Dialog -->
123
+ <v-dialog v-model="dialogPreview" width="450" persistent>
124
+ <v-card width="100%">
125
+ <v-card-text style="max-height: 100vh; overflow-y: auto" class="pb-0">
126
+ <v-row no-gutters v-if="selectedFeedback" class="mb-4">
127
+ <v-col cols="12">
128
+ <strong>Subject:</strong> {{ selectedFeedback.subject }}
129
+ </v-col>
130
+ <v-col cols="12">
131
+ <strong>Category:</strong>
132
+ {{ selectedFeedback.category }}
133
+ </v-col>
134
+ <v-col cols="12">
135
+ <strong>Status:</strong>
136
+ {{ selectedFeedback.status }}
137
+ </v-col>
138
+ </v-row>
139
+ </v-card-text>
140
+ <v-toolbar class="pa-0" density="compact">
141
+ <v-row no-gutters>
142
+ <v-col cols="6" class="pa-0">
143
+ <v-btn
144
+ block
145
+ variant="text"
146
+ class="text-none"
147
+ size="large"
148
+ @click="dialogPreview = false"
149
+ height="48"
150
+ >
151
+ Close
152
+ </v-btn>
153
+ </v-col>
154
+ <v-col cols="6" class="pa-0">
155
+ <v-menu>
156
+ <template #activator="{ props }">
157
+ <v-btn
158
+ block
159
+ variant="flat"
160
+ color="black"
161
+ class="text-none"
162
+ height="48"
163
+ v-bind="props"
164
+ tile
165
+ >
166
+ More actions
167
+ </v-btn>
168
+ </template>
169
+
170
+ <v-list class="pa-0">
171
+ <v-list-item @click="onViewFeedback(selectedFeedback)">
172
+ <v-list-item-title class="text-subtitle-2">
173
+ View
174
+ </v-list-item-title>
175
+ </v-list-item>
176
+ <v-list-item @click="editFeedback(selectedFeedback)">
177
+ <v-list-item-title class="text-subtitle-2">
178
+ Edit
179
+ </v-list-item-title>
180
+ </v-list-item>
181
+
182
+ <v-list-item
183
+ @click="confirmDeleteFeedback(selectedFeedback)"
184
+ class="text-red"
185
+ >
186
+ <v-list-item-title class="text-subtitle-2">
187
+ Delete
188
+ </v-list-item-title>
189
+ </v-list-item>
190
+ </v-list>
191
+ </v-menu>
192
+ </v-col>
193
+ </v-row>
194
+ </v-toolbar>
195
+ </v-card></v-dialog
196
+ >
126
197
  </template>
127
198
 
128
199
  <script setup lang="ts">
@@ -225,7 +296,7 @@ const selected = ref<string[]>([]);
225
296
 
226
297
  const { getColorStatus } = useUtils();
227
298
 
228
- const headers = [
299
+ const headers: Array<Record<string, any>> = [
229
300
  { title: "Name", value: "createdByName", align: "start" },
230
301
  { title: "Subject", value: "subject", align: "start" },
231
302
  { title: "Category", value: "category", align: "start" },
@@ -311,6 +382,7 @@ async function editFeedback(item: any) {
311
382
  _feedbackId.value = item._id;
312
383
  isEditMode.value = true;
313
384
  showCreateDialog.value = true;
385
+ dialogPreview.value = false;
314
386
  } catch (error) {
315
387
  showMessage("Failed to load full feedback", "error");
316
388
  }
@@ -326,6 +398,7 @@ function onViewFeedback(item: any) {
326
398
  name: props.detailRoute,
327
399
  params: { org, site, id },
328
400
  });
401
+ dialogPreview.value = false;
329
402
  }
330
403
 
331
404
  function confirmDeleteFeedback(item: any) {
@@ -349,6 +422,7 @@ async function submitDelete() {
349
422
  submitting.value = false;
350
423
  showDeleteDialog.value = false;
351
424
  feedbackToDelete.value = null;
425
+ dialogPreview.value = false;
352
426
  }
353
427
  }
354
428
 
@@ -483,5 +557,15 @@ const categories = computed(() =>
483
557
  }))
484
558
  );
485
559
 
560
+ function tableRowClickHandler(_: any, data: any) {
561
+ console.log(data.item);
562
+ selectedFeedback.value = data.item;
563
+ dialogPreview.value = true;
564
+ }
565
+
566
+ const dialogPreview = ref(false);
567
+ const selectedFeedback = ref<TFeedback | null>(null);
568
+ const searchText = ref("")
569
+
486
570
  getServiceProviderCategories();
487
571
  </script>
@@ -235,6 +235,33 @@ const apps = computed(() => {
235
235
  });
236
236
  }
237
237
 
238
+ const _pestControl = "pest_control_services";
239
+
240
+ if (props.app === _pestControl || orgNature.value === _pestControl) {
241
+ items.push({
242
+ title: "Pest Control Services",
243
+ value: _pestControl,
244
+ });
245
+ }
246
+
247
+ const _landscaping = "landscaping_services";
248
+
249
+ if (props.app === _landscaping || orgNature.value === _landscaping) {
250
+ items.push({
251
+ title: "Landscaping Services",
252
+ value: _landscaping,
253
+ });
254
+ }
255
+
256
+ const _poolMaintenance = "pool_maintenance_services";
257
+
258
+ if (props.app === _poolMaintenance || orgNature.value === _poolMaintenance) {
259
+ items.push({
260
+ title: "Pool Maintenance Services",
261
+ value: _poolMaintenance,
262
+ });
263
+ }
264
+
238
265
  return items;
239
266
  });
240
267
 
@@ -4,11 +4,18 @@
4
4
  <v-col cols="12" class="mb-2" v-if="(canCreate || $slots.actions)">
5
5
  <v-row no-gutters>
6
6
  <slot name="actions">
7
- <v-btn v-if="canCreate" class="text-none" rounded="pill" variant="tonal" size="large"
8
- @click="emits('create')">
9
- {{ createLabel }}
10
- </v-btn>
7
+ <v-col cols="12">
8
+ <v-row no-gutters justify="space-between">
9
+ <v-btn v-if="canCreate" class="text-none" rounded="pill" variant="tonal" size="large"
10
+ @click="emits('create')">
11
+ {{ createLabel }}
12
+ </v-btn>
13
+ <v-text-field v-if="props.canSearch" v-model="searchInput" density="compact" placeholder="Search" clearable max-width="300"
14
+ append-inner-icon="mdi-magnify" hide-details />
15
+ </v-row>
16
+ </v-col>
11
17
  </slot>
18
+
12
19
  </v-row>
13
20
  </v-col>
14
21
 
@@ -35,7 +42,7 @@
35
42
  </template>
36
43
 
37
44
  <template v-if="$slots.extension" #extension>
38
- <slot name="extension"/>
45
+ <slot name="extension" />
39
46
  </template>
40
47
  </v-toolbar>
41
48
 
@@ -43,12 +50,13 @@
43
50
  <!-- Data Table -->
44
51
  <v-data-table :headers="headers" :items="items" :item-value="itemValue" :items-per-page="itemsPerPage"
45
52
  fixed-header hide-default-footer :hide-default-header="!showHeader"
46
- @click:row="(_: any, data: any) => emits('row-click', data)" :style="`max-height: calc(100vh - (${offset}px))`">
53
+ @click:row="(_: any, data: any) => emits('row-click', data)"
54
+ :style="`max-height: calc(100vh - (${offset}px))`">
47
55
  <template v-for="(_, slotName) in $slots" #[slotName]="slotProps">
48
56
  <slot :name="slotName" v-bind="slotProps" />
49
57
  </template>
50
58
  </v-data-table>
51
- <slot name="footer"/>
59
+ <slot name="footer" />
52
60
  </v-card>
53
61
  </v-col>
54
62
  </v-row>
@@ -72,6 +80,10 @@ const props = defineProps({
72
80
  type: Boolean,
73
81
  default: false,
74
82
  },
83
+ canSearch: {
84
+ type: Boolean,
85
+ default: false,
86
+ },
75
87
  createLabel: {
76
88
  type: String,
77
89
  default: "Add",
@@ -112,6 +124,8 @@ const props = defineProps({
112
124
 
113
125
  const emits = defineEmits(["create", "refresh", "update:page", "row-click"]);
114
126
 
127
+ const searchInput = defineModel('search', { default: "" })
128
+
115
129
  const internalPage = ref(props.page);
116
130
  watch(
117
131
  () => props.page,
@@ -121,4 +135,8 @@ watch(
121
135
  );
122
136
  </script>
123
137
 
124
- <style scoped></style>
138
+ <style scoped>
139
+ .v-data-table :deep(thead th) {
140
+ font-weight: bold !important;
141
+ }
142
+ </style>
@@ -47,6 +47,7 @@ export default function useLocal() {
47
47
  { title: "Cleaning Services", value: "cleaning_services" },
48
48
  { title: "Pest Control Services", value: "pest_control_services" },
49
49
  { title: "Landscaping Services", value: "landscaping_services" },
50
+ { title: "Pool Maintenance Services", value: "pool_maintenance_services" },
50
51
  ];
51
52
 
52
53
  const landingPage = useCookie("landing-page", cookieConfig);
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@iservice365/layer-common",
3
3
  "license": "MIT",
4
4
  "type": "module",
5
- "version": "1.4.0",
5
+ "version": "1.4.2",
6
6
  "main": "./nuxt.config.ts",
7
7
  "scripts": {
8
8
  "dev": "nuxi dev .playground",