@7365admin1/layer-common 3.0.1 → 3.0.3

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,44 @@
1
+ <template>
2
+ <v-card
3
+ flat
4
+ border
5
+ rounded="lg"
6
+ class="d-flex flex-column w-100"
7
+ style="min-height: 200px"
8
+ >
9
+ <div class="d-flex align-center justify-space-between pa-5 pb-3">
10
+ <h2 class="text-body-1 font-weight-black text-blue-grey-darken-4 mb-0">
11
+ {{ title }}
12
+ </h2>
13
+ <v-btn
14
+ v-if="actionLabel"
15
+ variant="text"
16
+ color="primary"
17
+ size="small"
18
+ class="text-none font-weight-bold"
19
+ @click="$emit('action')"
20
+ >
21
+ {{ actionLabel }}
22
+ </v-btn>
23
+ </div>
24
+
25
+ <div class="flex-1-1-100 overflow-y-auto pa-5 pt-0" style="max-height: 400px">
26
+ <slot />
27
+ </div>
28
+ </v-card>
29
+ </template>
30
+
31
+ <script setup lang="ts">
32
+ defineProps({
33
+ title: {
34
+ type: String,
35
+ required: true,
36
+ },
37
+ actionLabel: {
38
+ type: String,
39
+ default: '',
40
+ },
41
+ });
42
+
43
+ defineEmits(['action']);
44
+ </script>
@@ -125,17 +125,35 @@ const routeParentId = computed(() =>
125
125
  );
126
126
  const effectiveParentId = computed(() => prop.parentId || routeParentId.value);
127
127
 
128
+ function getAttachmentId(attachment: any): string {
129
+ if (!attachment) return "";
130
+ if (Array.isArray(attachment)) {
131
+ const first = attachment[0];
132
+ if (!first) return "";
133
+ if (typeof first === "string") return first;
134
+ return String(first?._id || first?.id || "");
135
+ }
136
+ if (typeof attachment === "string") return attachment;
137
+ return String(attachment?._id || attachment?.id || "");
138
+ }
139
+
128
140
  if (prop.mode === "edit") {
129
141
  document.value.name = prop.document.name;
130
- document.value.attachment = [prop.document.attachment];
142
+
143
+ const extractedId = getAttachmentId(prop.document.attachment);
144
+ document.value.attachment = extractedId ? [extractedId] : [];
145
+
131
146
  document.value.type = prop.document.type;
132
147
  }
133
148
 
134
149
  watch(
135
150
  () => document.value.attachment,
136
- async (newVal) => {
137
- if (newVal && prop.mode !== "edit") {
138
- const fileId = Array.isArray(newVal) ? newVal[0] : newVal;
151
+ async (newVal, oldVal) => {
152
+ const newId = Array.isArray(newVal) ? newVal[0] : newVal;
153
+ const oldId = Array.isArray(oldVal) ? oldVal[0] : oldVal;
154
+
155
+ if (newId && newId !== oldId) {
156
+ const fileId = newId;
139
157
  const fileData = await getFileById(fileId);
140
158
  if (fileData) {
141
159
  document.value.name = fileData.data.name;
@@ -177,6 +177,7 @@
177
177
  <!-- Create Dialog -->
178
178
  <v-dialog v-model="createDialog" width="450" persistent>
179
179
  <DocumentForm
180
+ v-if="createDialog"
180
181
  :parent-id="activeParentId"
181
182
  @cancel="createDialog = false"
182
183
  @success="successCreate()"
@@ -253,6 +254,7 @@
253
254
  <!-- Edit Dialog -->
254
255
  <v-dialog v-model="editDialog" width="450" persistent>
255
256
  <DocumentForm
257
+ v-if="editDialog"
256
258
  mode="edit"
257
259
  @cancel="editDialog = false"
258
260
  @success="successUpdate()"
@@ -277,13 +279,19 @@
277
279
  <v-col cols="6" class="text-right text-body-1">
278
280
  <NuxtLink
279
281
  v-if="selectedDocument?.attachment && isViewable"
280
- :to="getFileUrl(selectedDocument.attachment)"
282
+ :to="
283
+ getFileUrl(getAttachmentId(selectedDocument.attachment))
284
+ "
281
285
  external
282
286
  target="_blank"
283
287
  >
284
288
  View Document
285
289
  </NuxtLink>
286
- <span v-else-if="selectedDocument?.attachment" class="text-grey" style="opacity: 0.6; cursor: not-allowed;">
290
+ <span
291
+ v-else-if="selectedDocument?.attachment"
292
+ class="text-grey"
293
+ style="opacity: 0.6; cursor: not-allowed"
294
+ >
287
295
  View Document
288
296
  </span>
289
297
  <span v-else>N/A</span>
@@ -528,6 +536,20 @@ const {
528
536
  } = documentService;
529
537
  const { getFileUrl } = useFile();
530
538
 
539
+ function getAttachmentId(attachment: any): string {
540
+ if (!attachment) return "";
541
+
542
+ if (Array.isArray(attachment)) {
543
+ const first = attachment[0];
544
+ if (!first) return "";
545
+ if (typeof first === "string") return first;
546
+ return String(first?._id || first?.id || "");
547
+ }
548
+ if (typeof attachment === "string") return attachment;
549
+
550
+ return String(attachment?._id || attachment?.id || "");
551
+ }
552
+
531
553
  const router = useRouter();
532
554
  const route = useRoute();
533
555
 
@@ -627,11 +649,26 @@ function formatBytes(bytes = 0) {
627
649
  return `${parseFloat((b / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
628
650
  }
629
651
 
652
+ const KNOWN_FILE_TYPES = new Set(["pdf", "csv", "doc", "docx", "folder", "mixed"]);
653
+
654
+ function inferDisplayType(doc: any): string {
655
+ if (doc.type === "folder") return "Folder";
656
+ // If stored type is a known file format, use it directly
657
+ const t = String(doc.type || "").toLowerCase().trim();
658
+ if (t && KNOWN_FILE_TYPES.has(t)) return t;
659
+ // Otherwise infer from the document name (handles legacy "public" ACL type)
660
+ const name = String(doc.name || "").toLowerCase();
661
+ if (name.endsWith(".pdf")) return "pdf";
662
+ if (name.endsWith(".csv")) return "csv";
663
+ if (name.endsWith(".docx") || name.endsWith(".doc")) return "doc";
664
+ return t || "N/A";
665
+ }
666
+
630
667
  const tableItems = computed(() => {
631
668
  return items.value.map((doc: any) => ({
632
669
  ...doc,
633
670
  _raw: doc,
634
- file_type: doc.type === "folder" ? "Folder" : doc.type || "N/A",
671
+ file_type: inferDisplayType(doc),
635
672
  file_size:
636
673
  doc.type === "folder"
637
674
  ? "—"
@@ -664,8 +701,8 @@ const selectedDocument = ref<TDocument>({
664
701
  });
665
702
 
666
703
  const isViewable = computed(() => {
667
- const lowerType = String(selectedDocument.value?.type || "").trim().toLowerCase();
668
- return ["pdf", "doc", "csv"].includes(lowerType);
704
+ const effectiveType = inferDisplayType(selectedDocument.value as any).toLowerCase();
705
+ return ["pdf", "doc", "csv"].includes(effectiveType);
669
706
  });
670
707
 
671
708
  const previewDetails = computed(() => {
@@ -769,7 +806,7 @@ function downloadDocument(document?: TDocument) {
769
806
  return;
770
807
  }
771
808
 
772
- const fileUrl = getFileUrl(document.attachment);
809
+ const fileUrl = getFileUrl(getAttachmentId(document.attachment));
773
810
  if (fileUrl) {
774
811
  window.open(fileUrl, "_blank", "noopener,noreferrer");
775
812
  }
@@ -1,19 +1,25 @@
1
1
  <template>
2
2
  <ClientOnly>
3
3
  <v-row no-gutters class="ckeditor-container w-100">
4
- <ckeditor v-model="data" :editor="ClassicEditor" :config="config" @ready="onReady" :key="prop.readOnly" />
4
+ <ckeditor
5
+ v-model="data"
6
+ :editor="ClassicEditor"
7
+ :config="config"
8
+ @ready="onReady"
9
+ :key="prop.readOnly"
10
+ />
5
11
  </v-row>
6
12
  </ClientOnly>
7
13
  </template>
8
14
 
9
15
  <script setup>
10
-
11
16
  const prop = defineProps({
12
17
  readOnly: {
13
18
  type: Boolean,
14
- required: false
15
- }
16
- })
19
+ required: false,
20
+ default: false,
21
+ },
22
+ });
17
23
  import {
18
24
  ClassicEditor,
19
25
  Essentials,
@@ -25,28 +31,50 @@ import {
25
31
  Link,
26
32
  Alignment,
27
33
  Font,
28
- } from 'ckeditor5'
29
- import { Ckeditor } from '@ckeditor/ckeditor5-vue'
30
- import 'ckeditor5/ckeditor5.css';
34
+ } from "ckeditor5";
35
+ import { Ckeditor } from "@ckeditor/ckeditor5-vue";
36
+ import "ckeditor5/ckeditor5.css";
31
37
 
32
- import 'ckeditor5/ckeditor5.css'
38
+ import "ckeditor5/ckeditor5.css";
33
39
 
34
- const data = defineModel({ required: true, default: "" })
40
+ const data = defineModel({ required: true, default: "" });
35
41
 
36
42
  const editorInstance = ref(null);
37
43
 
38
44
  const config = computed(() => ({
39
- licenseKey: 'GPL',
40
- plugins: [Essentials, Paragraph, Bold, Italic, Heading, List, Alignment, Font],
45
+ licenseKey: "GPL",
46
+ plugins: [
47
+ Essentials,
48
+ Paragraph,
49
+ Bold,
50
+ Italic,
51
+ Heading,
52
+ List,
53
+ Alignment,
54
+ Font,
55
+ ],
41
56
  toolbar: [
42
- 'undo', 'redo',
43
- '|', 'bold', 'italic',
44
- '|', 'fontSize', 'fontColor', 'fontBackgroundColor',
45
- '|', 'bulletedList', 'numberedList',
46
- '|', 'heading', '|', 'alignment:left', 'alignment:center', 'alignment:right', 'alignment:justify',
57
+ "undo",
58
+ "redo",
59
+ "|",
60
+ "bold",
61
+ "italic",
62
+ "|",
63
+ "fontSize",
64
+ "fontColor",
65
+ "fontBackgroundColor",
66
+ "|",
67
+ "bulletedList",
68
+ "numberedList",
69
+ "|",
70
+ "heading",
71
+ "|",
72
+ "alignment:left",
73
+ "alignment:center",
74
+ "alignment:right",
75
+ "alignment:justify",
47
76
  ],
48
- }))
49
-
77
+ }));
50
78
 
51
79
  function onReady(editor) {
52
80
  editorInstance.value = editor;
@@ -56,7 +84,6 @@ function onReady(editor) {
56
84
  function toggleReadOnly(isReadOnly) {
57
85
  if (!editorInstance.value) return;
58
86
 
59
-
60
87
  if (isReadOnly) {
61
88
  editorInstance.value.enableReadOnlyMode("view-mode-lock");
62
89
  } else {
@@ -70,8 +97,6 @@ watch(
70
97
  toggleReadOnly(newVal);
71
98
  }
72
99
  );
73
-
74
-
75
100
  </script>
76
101
 
77
102
  <style scoped>
@@ -501,7 +501,7 @@
501
501
  </v-col>
502
502
  <v-col cols="3" class="d-flex align-center justify-end">
503
503
  <v-switch
504
- v-model="facility.isBookingUnitLimitEnabled"
504
+ v-model="isBookingUnitLimitEnabled"
505
505
  class="d-flex align-center"
506
506
  color="primary"
507
507
  hide-details
@@ -519,7 +519,7 @@
519
519
  :min="1"
520
520
  :max="500"
521
521
  hide-details
522
- :disabled="!facility.isBookingUnitLimitEnabled"
522
+ :disabled="!isBookingUnitLimitEnabled"
523
523
  />
524
524
  </v-col>
525
525
  </v-row>
@@ -539,7 +539,7 @@
539
539
  </v-col>
540
540
  <v-col cols="3" class="d-flex align-center justify-end">
541
541
  <v-switch
542
- v-model="facility.isMaxNumberGuestLimitEnabled"
542
+ v-model="isMaxNumberGuestLimitEnabled"
543
543
  class="d-flex align-center"
544
544
  color="primary"
545
545
  hide-details
@@ -557,7 +557,7 @@
557
557
  :min="1"
558
558
  :max="500"
559
559
  hide-details
560
- :disabled="!facility.isMaxNumberGuestLimitEnabled"
560
+ :disabled="!isMaxNumberGuestLimitEnabled"
561
561
  />
562
562
  </v-col>
563
563
  </v-row>
@@ -576,7 +576,7 @@
576
576
  </v-col>
577
577
  <v-col cols="3" class="d-flex align-center justify-end">
578
578
  <v-switch
579
- v-model="facility.isCancelAllowedLimitEnabled"
579
+ v-model="isCancelAllowedLimitEnabled"
580
580
  class="d-flex align-center"
581
581
  color="primary"
582
582
  hide-details
@@ -594,7 +594,7 @@
594
594
  :min="1"
595
595
  :max="500"
596
596
  hide-details
597
- :disabled="!facility.isCancelAllowedLimitEnabled"
597
+ :disabled="!isCancelAllowedLimitEnabled"
598
598
  />
599
599
  </v-col>
600
600
  </v-row>
@@ -1013,32 +1013,56 @@ const handlePolicy = (newContent: string) => {
1013
1013
  facility.value.bookingPolicy = newContent;
1014
1014
  };
1015
1015
 
1016
+ const isBookingUnitLimitEnabled = ref<boolean>(false);
1017
+ const isMaxNumberGuestLimitEnabled = ref<boolean>(false);
1018
+ const isCancelAllowedLimitEnabled = ref<boolean>(false);
1019
+
1020
+ watchEffect(() => {
1021
+ if (facility.value.bookingUnitLimit > 0) {
1022
+ isBookingUnitLimitEnabled.value = true;
1023
+ } else {
1024
+ isBookingUnitLimitEnabled.value = false;
1025
+ }
1026
+
1027
+ if (facility.value.maxNumberGuestLimit > 0) {
1028
+ isMaxNumberGuestLimitEnabled.value = true;
1029
+ } else {
1030
+ isMaxNumberGuestLimitEnabled.value = false;
1031
+ }
1032
+
1033
+ if (facility.value.daysAllowedCancel > 0) {
1034
+ isCancelAllowedLimitEnabled.value = true;
1035
+ } else {
1036
+ isCancelAllowedLimitEnabled.value = false;
1037
+ }
1038
+ });
1039
+
1016
1040
  function onToggleBookingUnitLimit(val: any) {
1017
1041
  if (val) {
1018
- facility.value.isBookingUnitLimitEnabled = true;
1042
+ isBookingUnitLimitEnabled.value = true;
1019
1043
  facility.value.bookingUnitLimit = 1;
1020
1044
  } else {
1021
- facility.value.isBookingUnitLimitEnabled = false;
1045
+ isBookingUnitLimitEnabled.value = false;
1022
1046
  facility.value.bookingUnitLimit = null;
1023
1047
  }
1024
1048
  }
1025
1049
 
1026
1050
  function onToggleMaxNumberGuestLimit(val: any) {
1027
1051
  if (val) {
1028
- facility.value.isMaxNumberGuestLimitEnabled = true;
1052
+ isMaxNumberGuestLimitEnabled.value = true;
1029
1053
  facility.value.maxNumberGuestLimit = 1;
1030
1054
  } else {
1031
- facility.value.isMaxNumberGuestLimitEnabled = false;
1055
+ isMaxNumberGuestLimitEnabled.value = false;
1032
1056
  facility.value.maxNumberGuestLimit = null;
1033
1057
  }
1034
1058
  }
1035
1059
 
1036
1060
  function onToggleCancelAllowedLimit(val: any) {
1037
1061
  if (val) {
1038
- facility.value.isCancelAllowedLimitEnabled = true;
1062
+ isCancelAllowedLimitEnabled.value = true;
1039
1063
  facility.value.daysAllowedCancel = 1;
1040
1064
  } else {
1041
- facility.value.isCancelAllowedLimitEnabled = false;
1065
+ isCancelAllowedLimitEnabled.value = false;
1042
1066
  facility.value.daysAllowedCancel = null;
1043
1067
  }
1044
1068
  }
@@ -62,7 +62,6 @@
62
62
  <AttendanceCheckInOutDialog
63
63
  v-model="dialogShowForm"
64
64
  :action="currentAction"
65
- :serviceType="props.serviceType"
66
65
  @saved="onAttendanceSaved"
67
66
  @close="dialogShowForm = false"
68
67
  />
@@ -203,7 +202,7 @@ const onAttendanceSaved = async (
203
202
  try {
204
203
  let response;
205
204
  if (currentAction.value === "checkIn") {
206
- response = await checkIn(props.site, payload as TAttendanceCheckIn);
205
+ response = await checkIn(props.site, payload as TAttendanceCheckIn, props.serviceType);
207
206
  } else {
208
207
  if (!todayAttendance.value?._id) {
209
208
  throw new Error("Attendance ID not found");
@@ -29,8 +29,8 @@
29
29
  </v-col>
30
30
 
31
31
  <v-col v-if="!visitorInfo.checkIn" cols="12">
32
- <InputLabel class="text-capitalize" title="NRIC/Passport/ID No." />
33
- <v-text-field
32
+ <InputLabel class="text-capitalize" title="NRIC" />
33
+ <!-- <v-text-field
34
34
  v-if="!visitorInfo.checkIn"
35
35
  v-model="visitorInfo.nric"
36
36
  density="comfortable"
@@ -43,7 +43,17 @@
43
43
  density="comfortable"
44
44
  hide-details
45
45
  readonly
46
- />
46
+ /> -->
47
+ <NRICNumber v-if="!visitorInfo.checkIn"
48
+ v-model="visitorInfo.nric"
49
+ density="comfortable"
50
+ hide-details
51
+ clearable />
52
+ <NRICNumber v-else
53
+ v-model="visitorNric"
54
+ density="comfortable"
55
+ hide-details
56
+ readonly />
47
57
  </v-col>
48
58
 
49
59
  <v-col v-if="!visitorInfo.checkIn" cols="12" class="mt-4">
@@ -222,6 +232,8 @@
222
232
  </v-card>
223
233
  </template>
224
234
  <script setup lang="ts">
235
+ import NRICNumber from './Input/NRICNumber.vue';
236
+
225
237
  const prop = defineProps({
226
238
  site: {
227
239
  type: String,
@@ -271,15 +283,15 @@ const location = computed({
271
283
  get: () => {
272
284
  if (
273
285
  visitorInfo.value &&
274
- visitorInfo.value.block &&
275
- visitorInfo.value.level &&
286
+ visitorInfo.value.block?.name &&
287
+ visitorInfo.value.level?.name &&
276
288
  visitorInfo.value.unitName
277
289
  ) {
278
- return `${visitorInfo.value.block} / ${visitorInfo.value.level} / ${visitorInfo.value.unitName}`;
290
+ return `${visitorInfo.value.block?.name} / ${visitorInfo.value.level?.name} / ${visitorInfo.value.unitName}`;
279
291
  } else if (
280
292
  visitorInfo.value &&
281
- visitorInfo.value.block &&
282
- !visitorInfo.value.level &&
293
+ visitorInfo.value.block?.name &&
294
+ !visitorInfo.value.level?.name &&
283
295
  !visitorInfo.value.unitName
284
296
  ) {
285
297
  return visitorInfo.value.block;
@@ -1446,8 +1446,8 @@ function generateCSVData(visitors: any[]): string {
1446
1446
  visitor.name || "",
1447
1447
  formatExportTypes(formatType(visitor)) || "",
1448
1448
  visitor.company || "",
1449
- visitor.block || "",
1450
- visitor.level || "",
1449
+ visitor.block?.name || "",
1450
+ visitor.level?.name || "",
1451
1451
  visitor.unitName || "",
1452
1452
  visitor.contact || "",
1453
1453
  visitor.plateNumber || "",
@@ -40,8 +40,8 @@
40
40
  <v-icon icon="mdi-storefront-outline" size="15" />
41
41
  <span class="text-capitalize" style="word-break: break-word;">{{
42
42
  formatLocation({
43
- block: item.block,
44
- level: item.level,
43
+ block: item.block?.name || "",
44
+ level: item.level?.name,
45
45
  unit: item.unitName,
46
46
  })
47
47
  }}</span>
@@ -182,10 +182,10 @@ watch(getSitesReq, (newData: any) => {
182
182
  }
183
183
  })
184
184
 
185
- const formatLocation = ({ block, level, unit }: { block: number, level: string, unit: string | TBuildingUnit }) => {
185
+ const formatLocation = ({ block, level, unit }: { block: string, level: string, unit: string | TBuildingUnit }) => {
186
186
  const parts = [];
187
187
 
188
- if (block) parts.push(`Block ${block}`);
188
+ if (block) parts.push(`${block}`);
189
189
  if (level) parts.push(level);
190
190
  if (unit) parts.push(unit);
191
191
 
@@ -37,12 +37,12 @@ export default function useAttendance() {
37
37
  });
38
38
  }
39
39
 
40
- function checkIn(site: string, payload: TAttendanceCheckIn) {
40
+ function checkIn(site: string, payload: TAttendanceCheckIn, serviceType: string = "") {
41
41
  return useNuxtApp().$api<Record<string, any>>(
42
42
  `/api/attendances/site/${site}/check-in`,
43
43
  {
44
44
  method: "POST",
45
- body: payload,
45
+ body: { ...payload, serviceType },
46
46
  }
47
47
  );
48
48
  }
@@ -1,31 +1,90 @@
1
- export default function(){
2
-
3
-
4
- type TGetAllParams = {
5
- site?: string;
1
+ export default function () {
2
+ function getDashboardHygiene(
3
+ site = "",
4
+ period: TDashboardValues = "today",
5
+ serviceType: TServiceType
6
+ ) {
7
+ return useNuxtApp().$api<THygieneDashboardData>(
8
+ `/api/dashboard/serviceType/${serviceType}/site/${site}`,
9
+ {
10
+ method: "GET",
11
+ query: {
12
+ period,
13
+ },
6
14
  }
15
+ );
16
+ }
7
17
 
18
+ function getDashboardHygieneWeeklyActivity(
19
+ site = "",
20
+ serviceType: TServiceType = "cleaning_services"
21
+ ) {
22
+ return useNuxtApp().$api<THygieneWeeklyActivityItem[]>(
23
+ `/api/dashboard/serviceType/${serviceType}/site/${site}/weekly-activity`,
24
+ {
25
+ method: "GET",
26
+ }
27
+ );
28
+ }
8
29
 
30
+ function getDashboardHygieneTaskSchedule(
31
+ site = "",
32
+ serviceType: TServiceType,
33
+ page = 1,
34
+ limit = 4
35
+ ) {
36
+ return useNuxtApp().$api<
37
+ THygienePaginatedResponse<THygieneTaskScheduleItem>
38
+ >(`/api/dashboard/serviceType/${serviceType}/site/${site}/task-schedule`, {
39
+ method: "GET",
40
+ query: {
41
+ page,
42
+ limit,
43
+ },
44
+ });
45
+ }
9
46
 
10
- async function getDashboardData({
11
- site
12
- } : TGetAllParams) {
13
- return await useNuxtApp().$api<Record<string, any>>(
14
- "/api/dashboard",
47
+ function getDashboardHygieneAttendance(
48
+ site = "",
49
+ serviceType: TServiceType,
50
+ page = 1,
51
+ limit = 4
52
+ ) {
53
+ return useNuxtApp().$api<THygienePaginatedResponse<THygieneAttendanceItem>>(
54
+ `/api/dashboard/serviceType/${serviceType}/site/${site}/attendance`,
15
55
  {
16
56
  method: "GET",
17
57
  query: {
18
-
58
+ page,
59
+ limit,
19
60
  },
20
61
  }
21
62
  );
22
63
  }
23
64
 
65
+ function getDashboardHygieneFeedbacks(
66
+ site = "",
67
+ serviceType: TServiceType,
68
+ page = 1,
69
+ limit = 4
70
+ ) {
71
+ return useNuxtApp().$api<THygienePaginatedResponse<THygieneFeedbackItem>>(
72
+ `/api/dashboard/serviceType/${serviceType}/site/${site}/feedbacks`,
73
+ {
74
+ method: "GET",
75
+ query: {
76
+ page,
77
+ limit,
78
+ },
79
+ }
80
+ );
81
+ }
24
82
 
25
-
26
-
27
- return {
28
- getDashboardData,
29
-
30
- }
31
- }
83
+ return {
84
+ getDashboardHygiene,
85
+ getDashboardHygieneWeeklyActivity,
86
+ getDashboardHygieneTaskSchedule,
87
+ getDashboardHygieneAttendance,
88
+ getDashboardHygieneFeedbacks,
89
+ };
90
+ }
@@ -18,6 +18,7 @@ export default function useDocument() {
18
18
  page,
19
19
  search,
20
20
  limit,
21
+ type,
21
22
  site,
22
23
  parentId,
23
24
  };