@7365admin1/layer-common 3.1.2-staging.38 → 3.1.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/.github/workflows/publish-staging.yml +0 -11
- package/CHANGELOG.md +6 -0
- package/components/AddEqupmentForm.vue +1 -52
- package/components/CameraMain.vue +6 -5
- package/components/DashboardMain.vue +87 -231
- package/components/EquipmentManagementMain.vue +0 -56
- package/components/InvitationMain.vue +3 -4
- package/components/ManageChecklistMain.vue +38 -44
- package/components/Nfc/NFCPatrolReportMain.vue +38 -146
- package/components/Nfc/PatrolReport/DailyReportTab.vue +6 -10
- package/components/Nfc/PatrolReport/MonthlyReportTab.vue +9 -19
- package/components/Nfc/PatrolReport/PatrolActivityTable.vue +0 -20
- package/components/Nfc/PatrolReport/PatrolReportTab.vue +3 -5
- package/components/Nfc/PatrolReport/ReportFilters.vue +20 -52
- package/components/Nfc/PatrolReport/SummaryReportTable.vue +0 -22
- package/components/PhotoUpload.vue +4 -19
- package/components/ServiceProviderMain.vue +25 -59
- package/components/VisitorForm.vue +18 -78
- package/components/VisitorManagement.vue +16 -12
- package/composables/useCleaningSchedulePermission.ts +51 -16
- package/composables/useEquipment.ts +0 -2
- package/composables/useLocalAuth.ts +1 -1
- package/composables/useNFCPatrolDailyReport.ts +4 -3
- package/composables/useNFCPatrolMonthlyReport.ts +30 -62
- package/composables/useNFCPatrolReport.ts +0 -2
- package/composables/useServiceProvider.ts +0 -21
- package/package.json +1 -1
- package/types/customer.d.ts +1 -2
- package/types/equipment.d.ts +1 -5
- package/types/nfc-patrol-report.ts +1 -19
- package/components/Nfc/PatrolReport/MonthlyReportTable.vue +0 -69
- package/components/Nfc/PatrolReport/ReportDatePicker.vue +0 -61
|
@@ -1,23 +1,58 @@
|
|
|
1
1
|
export function useCleaningSchedulePermission() {
|
|
2
|
+
const { hasPermission } = usePermission();
|
|
3
|
+
const { permissions } = useCleaningPermission();
|
|
4
|
+
|
|
2
5
|
const { userAppRole } = useLocalSetup();
|
|
3
6
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
const canViewSchedules = computed(() => {
|
|
8
|
+
if (!userAppRole.value) return false;
|
|
9
|
+
if (userAppRole.value.permissions.includes("*")) return true;
|
|
10
|
+
return hasPermission(userAppRole.value, permissions, "cleaning-schedule-mgmt", "see-all-schedules");
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const canViewScheduleDetails = computed(() => {
|
|
14
|
+
if (!userAppRole.value) return false;
|
|
15
|
+
if (userAppRole.value.permissions.includes("*")) return true;
|
|
16
|
+
return hasPermission(userAppRole.value, permissions, "cleaning-schedule-mgmt", "see-schedule-details");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const canDownloadSchedule = computed(() => {
|
|
20
|
+
if (!userAppRole.value) return false;
|
|
21
|
+
if (userAppRole.value.permissions.includes("*")) return true;
|
|
22
|
+
return hasPermission(userAppRole.value, permissions, "cleaning-schedule-mgmt", "download-schedule");
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const canManageScheduleTasks = computed(() => {
|
|
26
|
+
if (!userAppRole.value) return false;
|
|
27
|
+
if (userAppRole.value.permissions.includes("*")) return true;
|
|
28
|
+
return hasPermission(userAppRole.value, permissions, "cleaning-schedule-mgmt", "manage-schedule-tasks");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const canGenerateChecklist = computed(() => {
|
|
32
|
+
if (!userAppRole.value) return false;
|
|
33
|
+
if (userAppRole.value.permissions.includes("*")) return true;
|
|
34
|
+
return hasPermission(userAppRole.value, permissions, "cleaning-schedule-mgmt", "generate-checklist");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const canViewHistory = computed(() => {
|
|
38
|
+
if (!userAppRole.value) return false;
|
|
39
|
+
if (userAppRole.value.permissions.includes("*")) return true;
|
|
40
|
+
return hasPermission(userAppRole.value, permissions, "cleaning-schedule-mgmt", "view-history");
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const canAddRemarks = computed(() => {
|
|
44
|
+
if (!userAppRole.value) return false;
|
|
45
|
+
if (userAppRole.value.permissions.includes("*")) return true;
|
|
46
|
+
return hasPermission(userAppRole.value, permissions, "cleaning-schedule-mgmt", "add-remarks");
|
|
47
|
+
});
|
|
13
48
|
|
|
14
49
|
return {
|
|
15
|
-
canViewSchedules
|
|
16
|
-
canViewScheduleDetails
|
|
17
|
-
canDownloadSchedule
|
|
18
|
-
canManageScheduleTasks
|
|
19
|
-
canGenerateChecklist
|
|
20
|
-
canViewHistory
|
|
21
|
-
canAddRemarks
|
|
50
|
+
canViewSchedules,
|
|
51
|
+
canViewScheduleDetails,
|
|
52
|
+
canDownloadSchedule,
|
|
53
|
+
canManageScheduleTasks,
|
|
54
|
+
canGenerateChecklist,
|
|
55
|
+
canViewHistory,
|
|
56
|
+
canAddRemarks,
|
|
22
57
|
};
|
|
23
58
|
}
|
|
@@ -27,7 +27,6 @@ export default function useEquipment() {
|
|
|
27
27
|
name: payload.name,
|
|
28
28
|
unitOfMeasurement: payload.unitOfMeasurement,
|
|
29
29
|
serviceType,
|
|
30
|
-
...(payload.attachment ? { attachment: payload.attachment } : {}),
|
|
31
30
|
},
|
|
32
31
|
}
|
|
33
32
|
);
|
|
@@ -41,7 +40,6 @@ export default function useEquipment() {
|
|
|
41
40
|
body: {
|
|
42
41
|
name: payload.name,
|
|
43
42
|
unitOfMeasurement: payload.unitOfMeasurement,
|
|
44
|
-
...(payload.attachment ? { attachment: payload.attachment } : {}),
|
|
45
43
|
},
|
|
46
44
|
}
|
|
47
45
|
);
|
|
@@ -34,8 +34,6 @@ function mapLogToSummaryRow(log: Record<string, any>, index: number): NFCPatrolS
|
|
|
34
34
|
id: log._id,
|
|
35
35
|
routeName: `${index + 1}. ${log.route?.name ?? "-"}`,
|
|
36
36
|
securityCheckSchedule: log.route?.startTime ?? "-",
|
|
37
|
-
guardName: log.sign?.guardName,
|
|
38
|
-
guardSignatureFileId: log.sign?.guardSignatureFileId,
|
|
39
37
|
checked,
|
|
40
38
|
missed,
|
|
41
39
|
status: missed === 0 ? "Completed" : "Incomplete",
|
|
@@ -65,12 +63,15 @@ export function useNFCPatrolDailyReport(
|
|
|
65
63
|
|
|
66
64
|
try {
|
|
67
65
|
const [logsRes, siteInfo] = await Promise.all([
|
|
68
|
-
getPatrolLogs({
|
|
66
|
+
getPatrolLogs<NFCPatrolLogListResponse>({
|
|
69
67
|
page: 1,
|
|
70
68
|
limit: 100,
|
|
71
69
|
site,
|
|
72
70
|
date: filters.date,
|
|
73
71
|
routeId: filters.route,
|
|
72
|
+
routeStartTime: filters.timeRange
|
|
73
|
+
? filters.timeRange.split(" - ")[0]
|
|
74
|
+
: undefined,
|
|
74
75
|
}),
|
|
75
76
|
getSiteById(site),
|
|
76
77
|
]);
|
|
@@ -2,8 +2,6 @@ import type {
|
|
|
2
2
|
NFCPatrolReportFilters,
|
|
3
3
|
NFCPatrolSummaryReport,
|
|
4
4
|
NFCPatrolReportSummaryRow,
|
|
5
|
-
NFCPatrolMonthlyReportRow,
|
|
6
|
-
NFCPatrolMonthlyReport,
|
|
7
5
|
} from "../types/nfc-patrol-report";
|
|
8
6
|
import useNFCPatrolLog from "./useNFCPatrolLog";
|
|
9
7
|
import useSite from "./useSite";
|
|
@@ -14,55 +12,6 @@ interface NFCPatrolLogListResponse {
|
|
|
14
12
|
pageRange?: string;
|
|
15
13
|
}
|
|
16
14
|
|
|
17
|
-
const MONTHS = [
|
|
18
|
-
"January",
|
|
19
|
-
"February",
|
|
20
|
-
"March",
|
|
21
|
-
"April",
|
|
22
|
-
"May",
|
|
23
|
-
"June",
|
|
24
|
-
"July",
|
|
25
|
-
"August",
|
|
26
|
-
"September",
|
|
27
|
-
"October",
|
|
28
|
-
"November",
|
|
29
|
-
"December",
|
|
30
|
-
];
|
|
31
|
-
function mapLogsToMonthlyRows(
|
|
32
|
-
logs: Record<string, any>[],
|
|
33
|
-
): NFCPatrolMonthlyReportRow[] {
|
|
34
|
-
const rows = MONTHS.map((month) => ({
|
|
35
|
-
month,
|
|
36
|
-
checked: 0,
|
|
37
|
-
checkedPercentage: 0,
|
|
38
|
-
missed: 0,
|
|
39
|
-
missedPercentage: 0,
|
|
40
|
-
}));
|
|
41
|
-
|
|
42
|
-
logs.forEach((log) => {
|
|
43
|
-
const monthIndex = new Date(log.date).getMonth();
|
|
44
|
-
|
|
45
|
-
for (const checkpoint of log.checkPoints ?? []) {
|
|
46
|
-
if (checkpoint.status === "Completed") {
|
|
47
|
-
rows[monthIndex].checked++;
|
|
48
|
-
} else if (checkpoint.status === "Skipped") {
|
|
49
|
-
rows[monthIndex].missed++;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
rows.forEach((row) => {
|
|
55
|
-
const total = row.checked + row.missed;
|
|
56
|
-
|
|
57
|
-
if (total > 0) {
|
|
58
|
-
row.checkedPercentage = Math.round((row.checked / total) * 100);
|
|
59
|
-
row.missedPercentage = Math.round((row.missed / total) * 100);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
return rows;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
15
|
function buildAddress(address?: Record<string, string>) {
|
|
67
16
|
if (!address) return undefined;
|
|
68
17
|
|
|
@@ -78,7 +27,23 @@ function buildAddress(address?: Record<string, string>) {
|
|
|
78
27
|
return parts.length ? parts.join(", ") : undefined;
|
|
79
28
|
}
|
|
80
29
|
|
|
30
|
+
function mapLogToSummaryRow(
|
|
31
|
+
log: Record<string, any>,
|
|
32
|
+
index: number,
|
|
33
|
+
): NFCPatrolReportSummaryRow {
|
|
34
|
+
const checkpoints: Record<string, any>[] = log.checkPoints ?? [];
|
|
35
|
+
const checked = checkpoints.filter((cp) => cp.status === "Completed").length;
|
|
36
|
+
const missed = checkpoints.filter((cp) => cp.status === "Skipped").length;
|
|
81
37
|
|
|
38
|
+
return {
|
|
39
|
+
id: log._id,
|
|
40
|
+
routeName: `${index + 1}. ${log.route?.name ?? "-"}`,
|
|
41
|
+
securityCheckSchedule: log.route?.startTime ?? "-",
|
|
42
|
+
checked,
|
|
43
|
+
missed,
|
|
44
|
+
status: missed === 0 ? "Completed" : "Incomplete",
|
|
45
|
+
};
|
|
46
|
+
}
|
|
82
47
|
|
|
83
48
|
export function useNFCPatrolMonthlyReport(
|
|
84
49
|
filters: NFCPatrolReportFilters,
|
|
@@ -87,12 +52,12 @@ export function useNFCPatrolMonthlyReport(
|
|
|
87
52
|
const { getAll: getPatrolLogs } = useNFCPatrolLog();
|
|
88
53
|
const { getSiteById } = useSite();
|
|
89
54
|
|
|
90
|
-
const report = ref<
|
|
55
|
+
const report = ref<NFCPatrolSummaryReport | null>(null);
|
|
91
56
|
const loading = ref(false);
|
|
92
57
|
const notFound = ref(false);
|
|
93
58
|
|
|
94
59
|
async function fetchReport() {
|
|
95
|
-
if (!site || !filters.route) {
|
|
60
|
+
if (!site || !filters.date || !filters.route) {
|
|
96
61
|
report.value = null;
|
|
97
62
|
notFound.value = false;
|
|
98
63
|
return;
|
|
@@ -100,16 +65,19 @@ export function useNFCPatrolMonthlyReport(
|
|
|
100
65
|
|
|
101
66
|
loading.value = true;
|
|
102
67
|
notFound.value = false;
|
|
103
|
-
|
|
68
|
+
|
|
104
69
|
try {
|
|
105
70
|
const [logsRes, siteInfo] = await Promise.all([
|
|
106
|
-
getPatrolLogs({
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
71
|
+
getPatrolLogs<NFCPatrolLogListResponse>({
|
|
72
|
+
page: 1,
|
|
73
|
+
limit: 100,
|
|
74
|
+
site,
|
|
75
|
+
date: filters.date,
|
|
76
|
+
routeId: filters.route,
|
|
77
|
+
routeStartTime: filters.timeRange
|
|
78
|
+
? filters.timeRange.split(" - ")[0]
|
|
79
|
+
: undefined,
|
|
80
|
+
type: "month",
|
|
113
81
|
}),
|
|
114
82
|
getSiteById(site),
|
|
115
83
|
]);
|
|
@@ -125,7 +93,7 @@ export function useNFCPatrolMonthlyReport(
|
|
|
125
93
|
address: buildAddress(siteInfo.address),
|
|
126
94
|
},
|
|
127
95
|
title: `Patrol Route Summary: ${routeName}`,
|
|
128
|
-
rows:
|
|
96
|
+
rows: logs.map(mapLogToSummaryRow),
|
|
129
97
|
};
|
|
130
98
|
} else {
|
|
131
99
|
report.value = null;
|
|
@@ -51,8 +51,6 @@ function mapLogToPatrolReport(
|
|
|
51
51
|
const activities: NFCPatrolActivity[] = checkpoints.map((cp) => ({
|
|
52
52
|
id: cp.nfcTag_id,
|
|
53
53
|
checkpoint: cp.nfcTag_name,
|
|
54
|
-
guardName: log.sign?.guardName,
|
|
55
|
-
guardSignatureFileId: log.sign?.guardSignatureFileId,
|
|
56
54
|
startTime: formatTime(cp.startDateTime),
|
|
57
55
|
endTime: formatTime(cp.endDateTime),
|
|
58
56
|
actualTime: diffMinutes(cp.startDateTime, cp.endDateTime),
|
|
@@ -236,26 +236,6 @@ export default function useServiceProvider() {
|
|
|
236
236
|
);
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
-
async function getByEmail({
|
|
240
|
-
email = "",
|
|
241
|
-
orgId = "",
|
|
242
|
-
siteId = "",
|
|
243
|
-
serviceProviderOrgId = "",
|
|
244
|
-
} = {}) {
|
|
245
|
-
return useNuxtApp().$api<Record<string, any>>(
|
|
246
|
-
"/api/service-providers/email",
|
|
247
|
-
{
|
|
248
|
-
method: "GET",
|
|
249
|
-
query: {
|
|
250
|
-
email,
|
|
251
|
-
...(orgId ? { orgId } : {}),
|
|
252
|
-
...(siteId ? { siteId } : {}),
|
|
253
|
-
...(serviceProviderOrgId ? { serviceProviderOrgId } : {}),
|
|
254
|
-
},
|
|
255
|
-
}
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
239
|
return {
|
|
260
240
|
serviceProviders,
|
|
261
241
|
serviceProvider,
|
|
@@ -274,6 +254,5 @@ export default function useServiceProvider() {
|
|
|
274
254
|
add,
|
|
275
255
|
addViaInvite,
|
|
276
256
|
updateStatus,
|
|
277
|
-
getByEmail,
|
|
278
257
|
};
|
|
279
258
|
}
|
package/package.json
CHANGED
package/types/customer.d.ts
CHANGED
package/types/equipment.d.ts
CHANGED
|
@@ -6,10 +6,6 @@ declare type TEquipment = {
|
|
|
6
6
|
unitOfMeasurement: string;
|
|
7
7
|
createdAt: string;
|
|
8
8
|
updatedAt: string;
|
|
9
|
-
attachment?: string;
|
|
10
9
|
};
|
|
11
10
|
|
|
12
|
-
declare type TEquipmentCreate = Pick<
|
|
13
|
-
TEquipment,
|
|
14
|
-
"name" | "unitOfMeasurement" | "attachment"
|
|
15
|
-
>;
|
|
11
|
+
declare type TEquipmentCreate = Pick<TEquipment, "name" | "unitOfMeasurement">;
|
|
@@ -26,7 +26,7 @@ export interface NFCPatrolReportFilterOptions {
|
|
|
26
26
|
|
|
27
27
|
export interface NFCPatrolReportLocation {
|
|
28
28
|
name?: string;
|
|
29
|
-
address?: string;
|
|
29
|
+
address?: string;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export interface NFCPatrolRouteSummary {
|
|
@@ -47,8 +47,6 @@ export interface NFCPatrolRouteSummary {
|
|
|
47
47
|
export interface NFCPatrolActivity {
|
|
48
48
|
id: string;
|
|
49
49
|
checkpoint: string;
|
|
50
|
-
guardName?: string;
|
|
51
|
-
guardSignatureFileId?: string;
|
|
52
50
|
startTime: string;
|
|
53
51
|
endTime: string;
|
|
54
52
|
actualTime: string;
|
|
@@ -69,8 +67,6 @@ export interface NFCPatrolReportSummaryRow {
|
|
|
69
67
|
id: string;
|
|
70
68
|
routeName: string;
|
|
71
69
|
securityCheckSchedule: string;
|
|
72
|
-
guardName?: string;
|
|
73
|
-
guardSignatureFileId?: string;
|
|
74
70
|
checked: number;
|
|
75
71
|
missed: number;
|
|
76
72
|
status: NFCPatrolReportSummaryStatus;
|
|
@@ -81,17 +77,3 @@ export interface NFCPatrolSummaryReport {
|
|
|
81
77
|
title: string;
|
|
82
78
|
rows: NFCPatrolReportSummaryRow[];
|
|
83
79
|
}
|
|
84
|
-
|
|
85
|
-
export interface NFCPatrolMonthlyReportRow {
|
|
86
|
-
month: string;
|
|
87
|
-
checked: number;
|
|
88
|
-
checkedPercentage: number;
|
|
89
|
-
missed: number;
|
|
90
|
-
missedPercentage: number;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export interface NFCPatrolMonthlyReport {
|
|
94
|
-
location: NFCPatrolReportLocation;
|
|
95
|
-
title: string;
|
|
96
|
-
rows: NFCPatrolMonthlyReportRow[];
|
|
97
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="mt-6">
|
|
3
|
-
<div class="text-h6 font-weight-bold mb-4">
|
|
4
|
-
{{ title }}
|
|
5
|
-
</div>
|
|
6
|
-
|
|
7
|
-
<v-table class="border rounded-lg">
|
|
8
|
-
<thead>
|
|
9
|
-
<tr>
|
|
10
|
-
<th class="text-left font-weight-bold">Month</th>
|
|
11
|
-
<th class="text-center font-weight-bold">Checked</th>
|
|
12
|
-
<th class="text-center font-weight-bold">% Checked</th>
|
|
13
|
-
<th class="text-center font-weight-bold">Missed</th>
|
|
14
|
-
<th class="text-center font-weight-bold">% Missed</th>
|
|
15
|
-
</tr>
|
|
16
|
-
</thead>
|
|
17
|
-
|
|
18
|
-
<tbody>
|
|
19
|
-
<tr
|
|
20
|
-
v-for="row in rows"
|
|
21
|
-
:key="row.month"
|
|
22
|
-
>
|
|
23
|
-
<td>{{ row.month }}</td>
|
|
24
|
-
|
|
25
|
-
<td class="text-center">
|
|
26
|
-
{{ row.checked }}
|
|
27
|
-
</td>
|
|
28
|
-
|
|
29
|
-
<td class="text-center">
|
|
30
|
-
{{ row.checkedPercentage }}%
|
|
31
|
-
</td>
|
|
32
|
-
|
|
33
|
-
<td class="text-center">
|
|
34
|
-
{{ row.missed }}
|
|
35
|
-
</td>
|
|
36
|
-
|
|
37
|
-
<td class="text-center">
|
|
38
|
-
{{ row.missedPercentage }}%
|
|
39
|
-
</td>
|
|
40
|
-
</tr>
|
|
41
|
-
</tbody>
|
|
42
|
-
</v-table>
|
|
43
|
-
</div>
|
|
44
|
-
</template>
|
|
45
|
-
|
|
46
|
-
<script setup lang="ts">
|
|
47
|
-
import type { NFCPatrolMonthlyReportRow } from "../../../types/nfc-patrol-report";
|
|
48
|
-
|
|
49
|
-
defineProps<{
|
|
50
|
-
title: string;
|
|
51
|
-
rows: NFCPatrolMonthlyReportRow[];
|
|
52
|
-
}>();
|
|
53
|
-
</script>
|
|
54
|
-
|
|
55
|
-
<style scoped>
|
|
56
|
-
.v-table {
|
|
57
|
-
border: 1px solid rgb(var(--v-theme-outline));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
thead th {
|
|
61
|
-
background: transparent;
|
|
62
|
-
white-space: nowrap;
|
|
63
|
-
font-weight: 600;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
tbody td {
|
|
67
|
-
height: 56px;
|
|
68
|
-
}
|
|
69
|
-
</style>
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="d-flex flex-column">
|
|
3
|
-
<v-text-field
|
|
4
|
-
v-bind="$attrs"
|
|
5
|
-
:model-value="formattedDate"
|
|
6
|
-
autocomplete="off"
|
|
7
|
-
placeholder="DD/MM/YY"
|
|
8
|
-
readonly
|
|
9
|
-
@click="openDatePicker"
|
|
10
|
-
>
|
|
11
|
-
<template #append-inner>
|
|
12
|
-
<v-icon icon="mdi-calendar" @click.stop="openDatePicker" />
|
|
13
|
-
</template>
|
|
14
|
-
</v-text-field>
|
|
15
|
-
|
|
16
|
-
<input
|
|
17
|
-
ref="dateInput"
|
|
18
|
-
v-model="date"
|
|
19
|
-
class="native-date-input"
|
|
20
|
-
type="date"
|
|
21
|
-
/>
|
|
22
|
-
</div>
|
|
23
|
-
</template>
|
|
24
|
-
|
|
25
|
-
<script setup lang="ts">
|
|
26
|
-
defineOptions({ inheritAttrs: false });
|
|
27
|
-
|
|
28
|
-
const date = defineModel<string>({ default: "" });
|
|
29
|
-
const dateInput = ref<HTMLInputElement | null>(null);
|
|
30
|
-
|
|
31
|
-
const formattedDate = computed(() => {
|
|
32
|
-
const match = date.value.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
33
|
-
|
|
34
|
-
if (!match) return "";
|
|
35
|
-
|
|
36
|
-
const [, year, month, day] = match;
|
|
37
|
-
return `${day}/${month}/${year.slice(-2)}`;
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
function openDatePicker() {
|
|
41
|
-
const input = dateInput.value;
|
|
42
|
-
|
|
43
|
-
if (!input) return;
|
|
44
|
-
|
|
45
|
-
if (input.showPicker) {
|
|
46
|
-
input.showPicker();
|
|
47
|
-
} else {
|
|
48
|
-
input.click();
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
</script>
|
|
52
|
-
|
|
53
|
-
<style scoped>
|
|
54
|
-
.native-date-input {
|
|
55
|
-
position: absolute;
|
|
56
|
-
width: 1px;
|
|
57
|
-
height: 1px;
|
|
58
|
-
opacity: 0;
|
|
59
|
-
pointer-events: none;
|
|
60
|
-
}
|
|
61
|
-
</style>
|