835 lines
25 KiB
Vue
835 lines
25 KiB
Vue
<template>
|
|
<div>
|
|
<LayoutsBreadcrumb />
|
|
|
|
<!-- Page Info Card -->
|
|
<rs-card class="mb-6">
|
|
<template #header>
|
|
<div class="flex items-center">
|
|
<Icon class="mr-2 text-primary" name="ic:outline-file-download"></Icon>
|
|
<h1 class="text-xl font-bold text-primary">Reports & Export</h1>
|
|
</div>
|
|
</template>
|
|
<template #body>
|
|
<p class="text-gray-600">
|
|
Generate comprehensive reports and export log data for compliance, auditing, and
|
|
analysis purposes. Create custom reports, schedule automated exports, and ensure
|
|
regulatory compliance.
|
|
</p>
|
|
</template>
|
|
</rs-card>
|
|
|
|
<!-- Quick Export Actions -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-4 gap-6 mb-6">
|
|
<rs-card
|
|
v-for="(action, index) in quickExportActions"
|
|
:key="index"
|
|
class="transition-all duration-300 hover:shadow-lg cursor-pointer"
|
|
@click="quickExport(action.type)"
|
|
>
|
|
<div class="pt-5 pb-3 px-5 text-center">
|
|
<div
|
|
class="p-5 flex justify-center items-center bg-primary/20 rounded-2xl transition-all duration-300 hover:bg-primary/30 mx-auto mb-4 w-fit"
|
|
>
|
|
<Icon class="text-primary text-3xl" :name="action.icon"></Icon>
|
|
</div>
|
|
<span class="block font-bold text-lg leading-tight text-primary mb-2">
|
|
{{ action.title }}
|
|
</span>
|
|
<span class="text-sm text-gray-600">
|
|
{{ action.description }}
|
|
</span>
|
|
</div>
|
|
</rs-card>
|
|
</div>
|
|
|
|
<!-- Custom Report Builder -->
|
|
<rs-card class="mb-6">
|
|
<template #header>
|
|
<div class="flex items-center">
|
|
<Icon name="ic:outline-build" class="mr-2 text-primary" />
|
|
<h3 class="text-lg font-semibold text-primary">Custom Report Builder</h3>
|
|
</div>
|
|
</template>
|
|
<template #body>
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
<!-- Report Configuration -->
|
|
<div class="space-y-4">
|
|
<FormKit
|
|
type="text"
|
|
label="Report Name"
|
|
v-model="customReport.name"
|
|
placeholder="Enter report name"
|
|
/>
|
|
|
|
<FormKit
|
|
type="select"
|
|
label="Report Type"
|
|
v-model="customReport.type"
|
|
:options="reportTypeOptions"
|
|
placeholder="Select report type"
|
|
/>
|
|
|
|
<FormKit
|
|
type="select"
|
|
label="Date Range"
|
|
v-model="customReport.dateRange"
|
|
:options="dateRangeOptions"
|
|
placeholder="Select date range"
|
|
/>
|
|
|
|
<FormKit
|
|
type="select"
|
|
label="Export Format"
|
|
v-model="customReport.format"
|
|
:options="exportFormatOptions"
|
|
placeholder="Select format"
|
|
/>
|
|
|
|
<FormKit
|
|
type="checkbox"
|
|
label="Include Channels"
|
|
v-model="customReport.channels"
|
|
:options="channelOptions"
|
|
/>
|
|
|
|
<FormKit
|
|
type="checkbox"
|
|
label="Include Status"
|
|
v-model="customReport.statuses"
|
|
:options="statusOptions"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Report Preview -->
|
|
<div class="space-y-4">
|
|
<h4 class="text-lg font-semibold">Report Preview</h4>
|
|
<div class="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg min-h-64">
|
|
<div class="space-y-3">
|
|
<div class="flex justify-between items-center">
|
|
<span class="font-medium">Report Name:</span>
|
|
<span class="text-primary">{{
|
|
customReport.name || "Untitled Report"
|
|
}}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="font-medium">Type:</span>
|
|
<span>{{ getReportTypeLabel(customReport.type) }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="font-medium">Date Range:</span>
|
|
<span>{{ getDateRangeLabel(customReport.dateRange) }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="font-medium">Format:</span>
|
|
<span>{{ getFormatLabel(customReport.format) }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-start">
|
|
<span class="font-medium">Channels:</span>
|
|
<div class="text-right">
|
|
<div v-if="customReport.channels.length === 0" class="text-gray-500">
|
|
All channels
|
|
</div>
|
|
<div v-else class="space-y-1">
|
|
<div
|
|
v-for="channel in customReport.channels"
|
|
:key="channel"
|
|
class="text-sm"
|
|
>
|
|
{{ channel }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="flex justify-between items-start">
|
|
<span class="font-medium">Status:</span>
|
|
<div class="text-right">
|
|
<div v-if="customReport.statuses.length === 0" class="text-gray-500">
|
|
All statuses
|
|
</div>
|
|
<div v-else class="space-y-1">
|
|
<div
|
|
v-for="status in customReport.statuses"
|
|
:key="status"
|
|
class="text-sm"
|
|
>
|
|
{{ status }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex gap-2">
|
|
<rs-button
|
|
@click="generateCustomReport"
|
|
variant="primary"
|
|
:disabled="!customReport.name || !customReport.type"
|
|
class="flex-1"
|
|
>
|
|
<Icon name="ic:outline-play-arrow" class="mr-1" /> Generate Report
|
|
</rs-button>
|
|
<rs-button @click="saveReportTemplate" variant="secondary-outline">
|
|
<Icon name="ic:outline-save" class="mr-1" /> Save Template
|
|
</rs-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</rs-card>
|
|
|
|
<!-- Compliance Reports -->
|
|
<rs-card class="mb-6">
|
|
<template #header>
|
|
<div class="flex items-center">
|
|
<Icon name="ic:outline-verified-user" class="mr-2 text-primary" />
|
|
<h3 class="text-lg font-semibold text-primary">Compliance Reports</h3>
|
|
</div>
|
|
</template>
|
|
<template #body>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
<rs-card
|
|
v-for="(compliance, index) in complianceReports"
|
|
:key="index"
|
|
class="transition-all duration-300 hover:shadow-lg"
|
|
>
|
|
<template #header>
|
|
<div class="flex items-center">
|
|
<Icon :name="compliance.icon" class="mr-2 text-primary" />
|
|
<h4 class="font-semibold">{{ compliance.title }}</h4>
|
|
</div>
|
|
</template>
|
|
<template #body>
|
|
<p class="text-sm text-gray-600 mb-4">{{ compliance.description }}</p>
|
|
<div class="space-y-2 text-sm">
|
|
<div
|
|
v-for="(feature, idx) in compliance.features"
|
|
:key="idx"
|
|
class="flex items-center"
|
|
>
|
|
<Icon name="ic:outline-check" class="mr-2 text-green-500 text-xs" />
|
|
<span>{{ feature }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="mt-4 p-3 bg-blue-50 dark:bg-blue-900/20 rounded">
|
|
<div class="flex items-center justify-between text-sm">
|
|
<span>Last Generated:</span>
|
|
<span class="font-medium">{{ compliance.lastGenerated }}</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template #footer>
|
|
<rs-button
|
|
@click="generateComplianceReport(compliance.type)"
|
|
variant="primary"
|
|
size="sm"
|
|
class="w-full"
|
|
>
|
|
<Icon name="ic:outline-file-download" class="mr-1" /> Generate Report
|
|
</rs-button>
|
|
</template>
|
|
</rs-card>
|
|
</div>
|
|
</template>
|
|
</rs-card>
|
|
|
|
<!-- Scheduled Reports -->
|
|
<rs-card class="mb-6">
|
|
<template #header>
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center">
|
|
<Icon name="ic:outline-schedule" class="mr-2 text-primary" />
|
|
<h3 class="text-lg font-semibold text-primary">Scheduled Reports</h3>
|
|
</div>
|
|
<rs-button variant="primary" size="sm" @click="openScheduleModal">
|
|
<Icon name="ic:outline-add" class="mr-1" /> Schedule Report
|
|
</rs-button>
|
|
</div>
|
|
</template>
|
|
<template #body>
|
|
<rs-table
|
|
v-if="scheduledReports.length > 0"
|
|
:data="scheduledReports"
|
|
:field="scheduledReportFields"
|
|
:options="{
|
|
variant: 'default',
|
|
striped: true,
|
|
borderless: false,
|
|
hover: true,
|
|
}"
|
|
:options-advanced="{
|
|
sortable: true,
|
|
responsive: true,
|
|
outsideBorder: true,
|
|
}"
|
|
advanced
|
|
>
|
|
<template #status="{ value }">
|
|
<rs-badge
|
|
:variant="
|
|
value.status === 'Active'
|
|
? 'success'
|
|
: value.status === 'Paused'
|
|
? 'warning'
|
|
: 'secondary'
|
|
"
|
|
size="sm"
|
|
>
|
|
{{ value.status }}
|
|
</rs-badge>
|
|
</template>
|
|
|
|
<template #actions="{ value }">
|
|
<div class="flex gap-2">
|
|
<rs-button
|
|
variant="primary-text"
|
|
size="sm"
|
|
@click="editScheduledReport(value)"
|
|
>
|
|
<Icon name="ic:outline-edit" class="mr-1" /> Edit
|
|
</rs-button>
|
|
<rs-button
|
|
variant="danger-text"
|
|
size="sm"
|
|
@click="deleteScheduledReport(value)"
|
|
>
|
|
<Icon name="ic:outline-delete" class="mr-1" /> Delete
|
|
</rs-button>
|
|
</div>
|
|
</template>
|
|
</rs-table>
|
|
|
|
<div v-else class="text-center py-8 text-gray-500">
|
|
<Icon name="ic:outline-schedule" class="text-4xl mb-2 mx-auto" />
|
|
<p>No scheduled reports configured</p>
|
|
<rs-button variant="primary-outline" @click="openScheduleModal" class="mt-4">
|
|
<Icon name="ic:outline-add" class="mr-1" /> Schedule Your First Report
|
|
</rs-button>
|
|
</div>
|
|
</template>
|
|
</rs-card>
|
|
|
|
<!-- Export History -->
|
|
<rs-card>
|
|
<template #header>
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center">
|
|
<Icon name="ic:outline-history" class="mr-2 text-primary" />
|
|
<h3 class="text-lg font-semibold text-primary">Export History</h3>
|
|
</div>
|
|
<rs-button variant="outline" size="sm" @click="clearExportHistory">
|
|
<Icon name="ic:outline-clear" class="mr-1" /> Clear History
|
|
</rs-button>
|
|
</div>
|
|
</template>
|
|
<template #body>
|
|
<div class="space-y-3">
|
|
<div
|
|
v-for="(export_, index) in exportHistory"
|
|
:key="index"
|
|
class="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800 rounded-lg"
|
|
>
|
|
<div class="flex items-center">
|
|
<Icon
|
|
:name="
|
|
export_.format === 'pdf'
|
|
? 'ic:outline-picture-as-pdf'
|
|
: export_.format === 'csv'
|
|
? 'ic:outline-table-chart'
|
|
: 'ic:outline-grid-on'
|
|
"
|
|
class="mr-3 text-primary text-xl"
|
|
/>
|
|
<div>
|
|
<p class="font-medium">{{ export_.name }}</p>
|
|
<p class="text-sm text-gray-600">{{ export_.description }}</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center gap-4">
|
|
<div class="text-right">
|
|
<p class="text-sm font-medium">{{ export_.size }}</p>
|
|
<p class="text-xs text-gray-500">{{ export_.timestamp }}</p>
|
|
</div>
|
|
<rs-badge
|
|
:variant="
|
|
export_.status === 'completed'
|
|
? 'success'
|
|
: export_.status === 'processing'
|
|
? 'warning'
|
|
: 'danger'
|
|
"
|
|
size="sm"
|
|
>
|
|
{{ export_.status }}
|
|
</rs-badge>
|
|
<div class="flex gap-1">
|
|
<rs-button
|
|
v-if="export_.status === 'completed'"
|
|
variant="primary-text"
|
|
size="sm"
|
|
@click="downloadExport(export_)"
|
|
>
|
|
<Icon name="ic:outline-download" />
|
|
</rs-button>
|
|
<rs-button variant="danger-text" size="sm" @click="deleteExport(index)">
|
|
<Icon name="ic:outline-delete" />
|
|
</rs-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="exportHistory.length === 0" class="text-center py-8 text-gray-500">
|
|
<Icon name="ic:outline-folder-open" class="text-4xl mb-2 mx-auto" />
|
|
<p>No export history available</p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</rs-card>
|
|
|
|
<!-- Schedule Report Modal -->
|
|
<rs-modal
|
|
v-model="isScheduleModalOpen"
|
|
title="Schedule Report"
|
|
size="lg"
|
|
:overlay-close="true"
|
|
>
|
|
<template #body>
|
|
<div class="space-y-4">
|
|
<FormKit
|
|
type="text"
|
|
label="Report Name"
|
|
v-model="scheduleForm.name"
|
|
placeholder="Enter report name"
|
|
/>
|
|
|
|
<FormKit
|
|
type="select"
|
|
label="Report Type"
|
|
v-model="scheduleForm.type"
|
|
:options="reportTypeOptions"
|
|
placeholder="Select report type"
|
|
/>
|
|
|
|
<FormKit
|
|
type="select"
|
|
label="Frequency"
|
|
v-model="scheduleForm.frequency"
|
|
:options="frequencyOptions"
|
|
placeholder="Select frequency"
|
|
/>
|
|
|
|
<FormKit
|
|
type="select"
|
|
label="Export Format"
|
|
v-model="scheduleForm.format"
|
|
:options="exportFormatOptions"
|
|
placeholder="Select format"
|
|
/>
|
|
|
|
<FormKit
|
|
type="email"
|
|
label="Email Recipients"
|
|
v-model="scheduleForm.recipients"
|
|
placeholder="Enter email addresses (comma separated)"
|
|
help="Enter multiple email addresses separated by commas"
|
|
/>
|
|
|
|
<FormKit
|
|
type="checkbox"
|
|
label="Include in export history"
|
|
v-model="scheduleForm.includeInHistory"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<template #footer>
|
|
<div class="flex gap-2">
|
|
<rs-button @click="isScheduleModalOpen = false" variant="secondary-outline">
|
|
Cancel
|
|
</rs-button>
|
|
<rs-button @click="createScheduledReport" variant="primary">
|
|
<Icon name="ic:outline-schedule" class="mr-1" /> Schedule Report
|
|
</rs-button>
|
|
</div>
|
|
</template>
|
|
</rs-modal>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
definePageMeta({
|
|
title: "Reports & Export",
|
|
middleware: ["auth"],
|
|
requiresAuth: true,
|
|
breadcrumb: [
|
|
{
|
|
name: "Dashboard",
|
|
path: "/dashboard",
|
|
},
|
|
{
|
|
name: "Notification",
|
|
path: "/notification",
|
|
},
|
|
{
|
|
name: "Logs & Audit Trail",
|
|
path: "/notification/log-audit",
|
|
},
|
|
{
|
|
name: "Reports",
|
|
path: "/notification/log-audit/reports",
|
|
type: "current",
|
|
},
|
|
],
|
|
});
|
|
|
|
import { ref, computed } from "vue";
|
|
|
|
// Quick export actions
|
|
const quickExportActions = ref([
|
|
{
|
|
title: "CSV Export",
|
|
description: "Export current data to CSV format",
|
|
icon: "ic:outline-table-chart",
|
|
type: "csv",
|
|
},
|
|
{
|
|
title: "PDF Report",
|
|
description: "Generate comprehensive PDF report",
|
|
icon: "ic:outline-picture-as-pdf",
|
|
type: "pdf",
|
|
},
|
|
{
|
|
title: "Excel Export",
|
|
description: "Export data to Excel spreadsheet",
|
|
icon: "ic:outline-grid-on",
|
|
type: "excel",
|
|
},
|
|
{
|
|
title: "JSON Export",
|
|
description: "Export raw data in JSON format",
|
|
icon: "ic:outline-code",
|
|
type: "json",
|
|
},
|
|
]);
|
|
|
|
// Custom report builder
|
|
const customReport = ref({
|
|
name: "",
|
|
type: "",
|
|
dateRange: "",
|
|
format: "",
|
|
channels: [],
|
|
statuses: [],
|
|
});
|
|
|
|
const reportTypeOptions = [
|
|
{ label: "Delivery Report", value: "delivery" },
|
|
{ label: "Performance Analytics", value: "performance" },
|
|
{ label: "Error Analysis", value: "errors" },
|
|
{ label: "User Engagement", value: "engagement" },
|
|
{ label: "Channel Comparison", value: "channels" },
|
|
{ label: "Audit Trail", value: "audit" },
|
|
];
|
|
|
|
const dateRangeOptions = [
|
|
{ label: "Last 24 Hours", value: "1d" },
|
|
{ label: "Last 7 Days", value: "7d" },
|
|
{ label: "Last 30 Days", value: "30d" },
|
|
{ label: "Last 90 Days", value: "90d" },
|
|
{ label: "Last 12 Months", value: "12m" },
|
|
{ label: "Custom Range", value: "custom" },
|
|
];
|
|
|
|
const exportFormatOptions = [
|
|
{ label: "CSV", value: "csv" },
|
|
{ label: "PDF", value: "pdf" },
|
|
{ label: "Excel", value: "excel" },
|
|
{ label: "JSON", value: "json" },
|
|
];
|
|
|
|
const channelOptions = [
|
|
{ label: "Email", value: "Email" },
|
|
{ label: "SMS", value: "SMS" },
|
|
{ label: "Push Notification", value: "Push Notification" },
|
|
{ label: "Webhook", value: "Webhook" },
|
|
];
|
|
|
|
const statusOptions = [
|
|
{ label: "Sent", value: "Sent" },
|
|
{ label: "Failed", value: "Failed" },
|
|
{ label: "Bounced", value: "Bounced" },
|
|
{ label: "Opened", value: "Opened" },
|
|
{ label: "Queued", value: "Queued" },
|
|
{ label: "Created", value: "Created" },
|
|
{ label: "Updated", value: "Updated" },
|
|
];
|
|
|
|
// Compliance reports
|
|
const complianceReports = ref([
|
|
{
|
|
title: "GDPR Compliance",
|
|
description:
|
|
"General Data Protection Regulation compliance report including data processing activities and user consent tracking.",
|
|
icon: "ic:outline-security",
|
|
type: "gdpr",
|
|
lastGenerated: "2 days ago",
|
|
features: [
|
|
"Data processing logs",
|
|
"User consent tracking",
|
|
"Data deletion records",
|
|
"Cross-border transfers",
|
|
],
|
|
},
|
|
{
|
|
title: "SOC2 Audit",
|
|
description:
|
|
"Service Organization Control 2 audit report covering security, availability, and processing integrity.",
|
|
icon: "ic:outline-shield",
|
|
type: "soc2",
|
|
lastGenerated: "1 week ago",
|
|
features: [
|
|
"Security controls assessment",
|
|
"Availability monitoring",
|
|
"Processing integrity",
|
|
"Confidentiality measures",
|
|
],
|
|
},
|
|
{
|
|
title: "HIPAA Compliance",
|
|
description:
|
|
"Health Insurance Portability and Accountability Act compliance report for healthcare-related notifications.",
|
|
icon: "ic:outline-local-hospital",
|
|
type: "hipaa",
|
|
lastGenerated: "3 days ago",
|
|
features: [
|
|
"PHI access logs",
|
|
"Encryption compliance",
|
|
"Audit trail integrity",
|
|
"Risk assessment",
|
|
],
|
|
},
|
|
]);
|
|
|
|
// Scheduled reports
|
|
const isScheduleModalOpen = ref(false);
|
|
const scheduleForm = ref({
|
|
name: "",
|
|
type: "",
|
|
frequency: "",
|
|
format: "",
|
|
recipients: "",
|
|
includeInHistory: true,
|
|
});
|
|
|
|
const frequencyOptions = [
|
|
{ label: "Daily", value: "daily" },
|
|
{ label: "Weekly", value: "weekly" },
|
|
{ label: "Monthly", value: "monthly" },
|
|
{ label: "Quarterly", value: "quarterly" },
|
|
];
|
|
|
|
const scheduledReports = ref([
|
|
{
|
|
name: "Daily Delivery Report",
|
|
type: "Delivery Analytics",
|
|
frequency: "Daily",
|
|
format: "PDF",
|
|
recipients: "admin@company.com",
|
|
status: "Active",
|
|
nextRun: "Tomorrow 9:00 AM",
|
|
},
|
|
{
|
|
name: "Weekly Performance Summary",
|
|
type: "Performance Analytics",
|
|
frequency: "Weekly",
|
|
format: "Excel",
|
|
recipients: "team@company.com",
|
|
status: "Active",
|
|
nextRun: "Monday 8:00 AM",
|
|
},
|
|
{
|
|
name: "Monthly Compliance Report",
|
|
type: "Audit Trail",
|
|
frequency: "Monthly",
|
|
format: "PDF",
|
|
recipients: "compliance@company.com",
|
|
status: "Paused",
|
|
nextRun: "1st of next month",
|
|
},
|
|
]);
|
|
|
|
const scheduledReportFields = [
|
|
"name",
|
|
"type",
|
|
"frequency",
|
|
"format",
|
|
"status",
|
|
"nextRun",
|
|
"actions",
|
|
];
|
|
|
|
// Export history
|
|
const exportHistory = ref([
|
|
{
|
|
name: "Notification Analytics Report",
|
|
description: "Monthly performance analysis",
|
|
format: "pdf",
|
|
size: "2.4 MB",
|
|
timestamp: "2 hours ago",
|
|
status: "completed",
|
|
},
|
|
{
|
|
name: "Delivery Logs Export",
|
|
description: "Last 30 days delivery data",
|
|
format: "csv",
|
|
size: "856 KB",
|
|
timestamp: "1 day ago",
|
|
status: "completed",
|
|
},
|
|
{
|
|
name: "GDPR Compliance Report",
|
|
description: "Quarterly compliance audit",
|
|
format: "pdf",
|
|
size: "1.2 MB",
|
|
timestamp: "3 days ago",
|
|
status: "completed",
|
|
},
|
|
{
|
|
name: "Error Analysis Report",
|
|
description: "Failed notification analysis",
|
|
format: "excel",
|
|
size: "1.8 MB",
|
|
timestamp: "5 days ago",
|
|
status: "completed",
|
|
},
|
|
]);
|
|
|
|
// Helper functions
|
|
const getReportTypeLabel = (value) => {
|
|
const option = reportTypeOptions.find((opt) => opt.value === value);
|
|
return option ? option.label : "Not selected";
|
|
};
|
|
|
|
const getDateRangeLabel = (value) => {
|
|
const option = dateRangeOptions.find((opt) => opt.value === value);
|
|
return option ? option.label : "Not selected";
|
|
};
|
|
|
|
const getFormatLabel = (value) => {
|
|
const option = exportFormatOptions.find((opt) => opt.value === value);
|
|
return option ? option.label : "Not selected";
|
|
};
|
|
|
|
// Methods
|
|
const quickExport = (type) => {
|
|
console.log(`Quick export: ${type}`);
|
|
alert(`Exporting data in ${type} format. (Implementation pending)`);
|
|
};
|
|
|
|
const generateCustomReport = () => {
|
|
console.log("Generating custom report:", customReport.value);
|
|
alert(`Generating custom report: ${customReport.value.name}. (Implementation pending)`);
|
|
};
|
|
|
|
const saveReportTemplate = () => {
|
|
console.log("Saving report template:", customReport.value);
|
|
alert(`Saving report template: ${customReport.value.name}. (Implementation pending)`);
|
|
};
|
|
|
|
const generateComplianceReport = (type) => {
|
|
console.log(`Generating ${type} compliance report`);
|
|
alert(`Generating ${type} compliance report. (Implementation pending)`);
|
|
};
|
|
|
|
const openScheduleModal = () => {
|
|
scheduleForm.value = {
|
|
name: "",
|
|
type: "",
|
|
frequency: "",
|
|
format: "",
|
|
recipients: "",
|
|
includeInHistory: true,
|
|
};
|
|
isScheduleModalOpen.value = true;
|
|
};
|
|
|
|
const createScheduledReport = () => {
|
|
console.log("Creating scheduled report:", scheduleForm.value);
|
|
scheduledReports.value.push({
|
|
...scheduleForm.value,
|
|
status: "Active",
|
|
nextRun: "Tomorrow 9:00 AM",
|
|
});
|
|
isScheduleModalOpen.value = false;
|
|
};
|
|
|
|
const editScheduledReport = (report) => {
|
|
console.log("Editing scheduled report:", report);
|
|
alert(`Editing scheduled report: ${report.name}. (Implementation pending)`);
|
|
};
|
|
|
|
const deleteScheduledReport = (report) => {
|
|
const index = scheduledReports.value.findIndex((r) => r.name === report.name);
|
|
if (index !== -1) {
|
|
scheduledReports.value.splice(index, 1);
|
|
}
|
|
};
|
|
|
|
const clearExportHistory = () => {
|
|
exportHistory.value = [];
|
|
};
|
|
|
|
const downloadExport = (export_) => {
|
|
console.log("Downloading export:", export_);
|
|
alert(`Downloading ${export_.name}. (Implementation pending)`);
|
|
};
|
|
|
|
const deleteExport = (index) => {
|
|
exportHistory.value.splice(index, 1);
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
// Custom styles for FormKit consistency
|
|
:deep(.formkit-outer) {
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
:deep(.formkit-label) {
|
|
font-weight: 500;
|
|
color: rgb(107 114 128);
|
|
font-size: 0.875rem;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
:deep(.formkit-input) {
|
|
border-radius: 0.5rem;
|
|
}
|
|
|
|
// Badge component styles (if RsBadge doesn't exist, these can be adjusted)
|
|
.rs-badge {
|
|
@apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium;
|
|
}
|
|
|
|
.rs-badge.variant-success {
|
|
@apply bg-green-100 text-green-800;
|
|
}
|
|
|
|
.rs-badge.variant-danger {
|
|
@apply bg-red-100 text-red-800;
|
|
}
|
|
|
|
.rs-badge.variant-warning {
|
|
@apply bg-yellow-100 text-yellow-800;
|
|
}
|
|
|
|
.rs-badge.variant-info {
|
|
@apply bg-blue-100 text-blue-800;
|
|
}
|
|
|
|
.rs-badge.variant-secondary {
|
|
@apply bg-gray-100 text-gray-800;
|
|
}
|
|
</style>
|