706 lines
23 KiB
Vue
706 lines
23 KiB
Vue
<template>
|
|
<div>
|
|
<LayoutsBreadcrumb />
|
|
|
|
<!-- Header Section -->
|
|
<rs-card class="mb-6">
|
|
<template #header>
|
|
<div class="flex items-center">
|
|
<Icon class="mr-2 text-primary" name="ic:outline-batch-prediction"></Icon>
|
|
<h1 class="text-xl font-bold text-primary">Batch Processing</h1>
|
|
</div>
|
|
</template>
|
|
<template #body>
|
|
<p class="text-gray-600">
|
|
Schedule or trigger the processing of large groups of messages in one go.
|
|
Ideal for sending newsletters, campaigns, or system-wide alerts to thousands/millions of users.
|
|
</p>
|
|
</template>
|
|
</rs-card>
|
|
|
|
<!-- Quick Actions -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
|
|
<rs-card class="cursor-pointer transition-all duration-300 hover:shadow-lg" @click="showCreateBatchModal = true">
|
|
<div class="pt-5 pb-3 px-5 flex items-center gap-4">
|
|
<div class="p-4 flex justify-center items-center bg-blue-100 rounded-2xl">
|
|
<Icon class="text-blue-600 text-2xl" name="ic:outline-add"></Icon>
|
|
</div>
|
|
<div class="flex-1">
|
|
<span class="block font-bold text-lg text-blue-600">Create New Batch</span>
|
|
<span class="text-sm text-gray-600">Start a new batch processing job</span>
|
|
</div>
|
|
</div>
|
|
</rs-card>
|
|
|
|
<rs-card class="cursor-pointer transition-all duration-300 hover:shadow-lg" @click="showScheduleModal = true">
|
|
<div class="pt-5 pb-3 px-5 flex items-center gap-4">
|
|
<div class="p-4 flex justify-center items-center bg-green-100 rounded-2xl">
|
|
<Icon class="text-green-600 text-2xl" name="ic:outline-schedule"></Icon>
|
|
</div>
|
|
<div class="flex-1">
|
|
<span class="block font-bold text-lg text-green-600">Schedule Batch</span>
|
|
<span class="text-sm text-gray-600">Schedule for later execution</span>
|
|
</div>
|
|
</div>
|
|
</rs-card>
|
|
|
|
<rs-card class="cursor-pointer transition-all duration-300 hover:shadow-lg" @click="showTemplatesModal = true">
|
|
<div class="pt-5 pb-3 px-5 flex items-center gap-4">
|
|
<div class="p-4 flex justify-center items-center bg-purple-100 rounded-2xl">
|
|
<Icon class="text-purple-600 text-2xl" name="ic:outline-library-books"></Icon>
|
|
</div>
|
|
<div class="flex-1">
|
|
<span class="block font-bold text-lg text-purple-600">Batch Templates</span>
|
|
<span class="text-sm text-gray-600">Use predefined batch configurations</span>
|
|
</div>
|
|
</div>
|
|
</rs-card>
|
|
</div>
|
|
|
|
<!-- Batch Statistics -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-4 gap-6 mb-6">
|
|
<rs-card
|
|
v-for="(stat, index) in batchStats"
|
|
:key="index"
|
|
class="transition-all duration-300 hover:shadow-lg"
|
|
>
|
|
<div class="pt-5 pb-3 px-5 flex items-center gap-4">
|
|
<div
|
|
class="p-4 flex justify-center items-center rounded-2xl"
|
|
:class="stat.bgColor"
|
|
>
|
|
<Icon class="text-2xl" :class="stat.iconColor" :name="stat.icon"></Icon>
|
|
</div>
|
|
<div class="flex-1 truncate">
|
|
<span class="block font-bold text-xl leading-tight" :class="stat.textColor">
|
|
{{ stat.value }}
|
|
</span>
|
|
<span class="text-sm font-medium text-gray-600">
|
|
{{ stat.title }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</rs-card>
|
|
</div>
|
|
|
|
<!-- Active Batches -->
|
|
<rs-card class="mb-6">
|
|
<template #header>
|
|
<div class="flex items-center justify-between">
|
|
<h3 class="text-lg font-semibold text-primary">Active Batches</h3>
|
|
<rs-button variant="outline" size="sm" @click="refreshBatches">
|
|
<Icon class="mr-1" name="ic:outline-refresh"></Icon>
|
|
Refresh
|
|
</rs-button>
|
|
</div>
|
|
</template>
|
|
<template #body>
|
|
<div class="space-y-4">
|
|
<div
|
|
v-for="(batch, index) in activeBatches"
|
|
:key="index"
|
|
class="border border-gray-200 rounded-lg p-4"
|
|
>
|
|
<div class="flex items-center justify-between mb-3">
|
|
<div class="flex items-center">
|
|
<div
|
|
class="w-3 h-3 rounded-full mr-3"
|
|
:class="{
|
|
'bg-blue-500': batch.status === 'pending',
|
|
'bg-yellow-500': batch.status === 'processing',
|
|
'bg-green-500': batch.status === 'completed',
|
|
'bg-red-500': batch.status === 'failed',
|
|
'bg-gray-500': batch.status === 'paused'
|
|
}"
|
|
></div>
|
|
<div>
|
|
<h4 class="font-semibold">{{ batch.name }}</h4>
|
|
<p class="text-sm text-gray-600">{{ batch.description }}</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<rs-badge :variant="getBatchStatusVariant(batch.status)">
|
|
{{ batch.status }}
|
|
</rs-badge>
|
|
<rs-dropdown>
|
|
<template #trigger>
|
|
<rs-button variant="outline" size="sm">
|
|
<Icon name="ic:outline-more-vert"></Icon>
|
|
</rs-button>
|
|
</template>
|
|
<rs-dropdown-item @click="viewBatchDetails(batch)">
|
|
<Icon class="mr-2" name="ic:outline-visibility"></Icon>
|
|
View Details
|
|
</rs-dropdown-item>
|
|
<rs-dropdown-item v-if="batch.status === 'processing'" @click="pauseBatch(batch)">
|
|
<Icon class="mr-2" name="ic:outline-pause"></Icon>
|
|
Pause
|
|
</rs-dropdown-item>
|
|
<rs-dropdown-item v-if="batch.status === 'paused'" @click="resumeBatch(batch)">
|
|
<Icon class="mr-2" name="ic:outline-play-arrow"></Icon>
|
|
Resume
|
|
</rs-dropdown-item>
|
|
<rs-dropdown-item v-if="['pending', 'paused'].includes(batch.status)" @click="cancelBatch(batch)" class="text-red-600">
|
|
<Icon class="mr-2" name="ic:outline-cancel"></Icon>
|
|
Cancel
|
|
</rs-dropdown-item>
|
|
</rs-dropdown>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Progress Bar -->
|
|
<div class="mb-3">
|
|
<div class="flex justify-between text-sm text-gray-600 mb-1">
|
|
<span>Progress: {{ batch.processed }}/{{ batch.total }}</span>
|
|
<span>{{ Math.round((batch.processed / batch.total) * 100) }}%</span>
|
|
</div>
|
|
<rs-progress-bar
|
|
:value="(batch.processed / batch.total) * 100"
|
|
:variant="batch.status === 'failed' ? 'danger' : 'primary'"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Batch Info -->
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
|
|
<div>
|
|
<span class="text-gray-600">Type:</span>
|
|
<span class="ml-1 font-medium">{{ batch.type }}</span>
|
|
</div>
|
|
<div>
|
|
<span class="text-gray-600">Chunk Size:</span>
|
|
<span class="ml-1 font-medium">{{ batch.chunkSize }}</span>
|
|
</div>
|
|
<div>
|
|
<span class="text-gray-600">Started:</span>
|
|
<span class="ml-1 font-medium">{{ batch.startedAt }}</span>
|
|
</div>
|
|
<div>
|
|
<span class="text-gray-600">ETA:</span>
|
|
<span class="ml-1 font-medium">{{ batch.eta }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</rs-card>
|
|
|
|
<!-- Batch History -->
|
|
<rs-card>
|
|
<template #header>
|
|
<h3 class="text-lg font-semibold text-primary">Batch History</h3>
|
|
</template>
|
|
<template #body>
|
|
<rs-table
|
|
:field="historyTableFields"
|
|
:data="batchHistory"
|
|
:options="{ striped: true, hover: true }"
|
|
:optionsAdvanced="{ sortable: true, filterable: true }"
|
|
advanced
|
|
/>
|
|
</template>
|
|
</rs-card>
|
|
|
|
<!-- Create Batch Modal -->
|
|
<rs-modal v-model="showCreateBatchModal" size="lg">
|
|
<template #header>
|
|
<h3 class="text-lg font-semibold">Create New Batch</h3>
|
|
</template>
|
|
<template #body>
|
|
<form @submit.prevent="createBatch" class="space-y-4">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">Batch Name</label>
|
|
<input
|
|
v-model="newBatch.name"
|
|
type="text"
|
|
class="w-full p-2 border border-gray-300 rounded-md"
|
|
placeholder="Enter batch name"
|
|
required
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">Message Type</label>
|
|
<select v-model="newBatch.type" class="w-full p-2 border border-gray-300 rounded-md" required>
|
|
<option value="">Select type</option>
|
|
<option value="email">Email</option>
|
|
<option value="sms">SMS</option>
|
|
<option value="push">Push Notification</option>
|
|
<option value="webhook">Webhook</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">Description</label>
|
|
<textarea
|
|
v-model="newBatch.description"
|
|
class="w-full p-2 border border-gray-300 rounded-md"
|
|
rows="3"
|
|
placeholder="Describe this batch processing job"
|
|
></textarea>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">Chunk Size</label>
|
|
<input
|
|
v-model.number="newBatch.chunkSize"
|
|
type="number"
|
|
class="w-full p-2 border border-gray-300 rounded-md"
|
|
placeholder="500"
|
|
min="1"
|
|
max="10000"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">Priority</label>
|
|
<select v-model="newBatch.priority" class="w-full p-2 border border-gray-300 rounded-md">
|
|
<option value="low">Low</option>
|
|
<option value="medium">Medium</option>
|
|
<option value="high">High</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">Delay Between Chunks (ms)</label>
|
|
<input
|
|
v-model.number="newBatch.delay"
|
|
type="number"
|
|
class="w-full p-2 border border-gray-300 rounded-md"
|
|
placeholder="1000"
|
|
min="0"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">Target Criteria</label>
|
|
<textarea
|
|
v-model="newBatch.criteria"
|
|
class="w-full p-2 border border-gray-300 rounded-md"
|
|
rows="3"
|
|
placeholder="JSON criteria for selecting recipients (e.g., user type, timezone, preferences)"
|
|
></textarea>
|
|
</div>
|
|
</form>
|
|
</template>
|
|
<template #footer>
|
|
<div class="flex justify-end gap-2">
|
|
<rs-button variant="outline" @click="showCreateBatchModal = false">Cancel</rs-button>
|
|
<rs-button @click="createBatch" variant="primary">Create Batch</rs-button>
|
|
</div>
|
|
</template>
|
|
</rs-modal>
|
|
|
|
<!-- Schedule Modal -->
|
|
<rs-modal v-model="showScheduleModal" size="md">
|
|
<template #header>
|
|
<h3 class="text-lg font-semibold">Schedule Batch</h3>
|
|
</template>
|
|
<template #body>
|
|
<div class="space-y-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">Select Batch Template</label>
|
|
<select v-model="scheduleBatch.templateId" class="w-full p-2 border border-gray-300 rounded-md">
|
|
<option value="">Choose a template</option>
|
|
<option value="newsletter">Newsletter Campaign</option>
|
|
<option value="birthday">Birthday Reminders</option>
|
|
<option value="system">System Notifications</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">Schedule Date</label>
|
|
<input
|
|
v-model="scheduleBatch.date"
|
|
type="date"
|
|
class="w-full p-2 border border-gray-300 rounded-md"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">Schedule Time</label>
|
|
<input
|
|
v-model="scheduleBatch.time"
|
|
type="time"
|
|
class="w-full p-2 border border-gray-300 rounded-md"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">Timezone</label>
|
|
<select v-model="scheduleBatch.timezone" class="w-full p-2 border border-gray-300 rounded-md">
|
|
<option value="UTC">UTC</option>
|
|
<option value="Asia/Kuala_Lumpur">Asia/Kuala_Lumpur</option>
|
|
<option value="America/New_York">America/New_York</option>
|
|
<option value="Europe/London">Europe/London</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="flex items-center">
|
|
<input
|
|
v-model="scheduleBatch.recurring"
|
|
type="checkbox"
|
|
class="mr-2"
|
|
/>
|
|
<label class="text-sm font-medium text-gray-700">Recurring batch</label>
|
|
</div>
|
|
|
|
<div v-if="scheduleBatch.recurring">
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">Recurrence Pattern</label>
|
|
<select v-model="scheduleBatch.recurrencePattern" class="w-full p-2 border border-gray-300 rounded-md">
|
|
<option value="daily">Daily</option>
|
|
<option value="weekly">Weekly</option>
|
|
<option value="monthly">Monthly</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template #footer>
|
|
<div class="flex justify-end gap-2">
|
|
<rs-button variant="outline" @click="showScheduleModal = false">Cancel</rs-button>
|
|
<rs-button @click="scheduleNewBatch" variant="primary">Schedule</rs-button>
|
|
</div>
|
|
</template>
|
|
</rs-modal>
|
|
|
|
<!-- Templates Modal -->
|
|
<rs-modal v-model="showTemplatesModal" size="lg">
|
|
<template #header>
|
|
<h3 class="text-lg font-semibold">Batch Templates</h3>
|
|
</template>
|
|
<template #body>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div
|
|
v-for="(template, index) in batchTemplates"
|
|
:key="index"
|
|
class="border border-gray-200 rounded-lg p-4 cursor-pointer hover:border-primary transition-colors"
|
|
@click="useBatchTemplate(template)"
|
|
>
|
|
<div class="flex items-center mb-3">
|
|
<Icon class="mr-2 text-primary" :name="template.icon"></Icon>
|
|
<h4 class="font-semibold">{{ template.name }}</h4>
|
|
</div>
|
|
<p class="text-sm text-gray-600 mb-3">{{ template.description }}</p>
|
|
<div class="space-y-1 text-xs text-gray-500">
|
|
<div>Type: {{ template.type }}</div>
|
|
<div>Chunk Size: {{ template.chunkSize }}</div>
|
|
<div>Priority: {{ template.priority }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template #footer>
|
|
<div class="flex justify-end">
|
|
<rs-button variant="outline" @click="showTemplatesModal = false">Close</rs-button>
|
|
</div>
|
|
</template>
|
|
</rs-modal>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
definePageMeta({
|
|
title: "Batch Processing",
|
|
middleware: ["auth"],
|
|
requiresAuth: true,
|
|
breadcrumb: [
|
|
{
|
|
name: "Notification",
|
|
path: "/notification",
|
|
},
|
|
{
|
|
name: "Queue & Scheduler",
|
|
path: "/notification/queue-scheduler",
|
|
},
|
|
{
|
|
name: "Batch Processing",
|
|
path: "/notification/queue-scheduler/batch",
|
|
},
|
|
],
|
|
});
|
|
|
|
// Reactive data
|
|
const showCreateBatchModal = ref(false);
|
|
const showScheduleModal = ref(false);
|
|
const showTemplatesModal = ref(false);
|
|
|
|
// New batch form
|
|
const newBatch = ref({
|
|
name: '',
|
|
type: '',
|
|
description: '',
|
|
chunkSize: 500,
|
|
priority: 'medium',
|
|
delay: 1000,
|
|
criteria: ''
|
|
});
|
|
|
|
// Schedule batch form
|
|
const scheduleBatch = ref({
|
|
templateId: '',
|
|
date: '',
|
|
time: '',
|
|
timezone: 'UTC',
|
|
recurring: false,
|
|
recurrencePattern: 'daily'
|
|
});
|
|
|
|
// Batch statistics
|
|
const batchStats = ref([
|
|
{
|
|
title: "Active Batches",
|
|
value: "12",
|
|
icon: "ic:outline-play-circle",
|
|
bgColor: "bg-blue-100",
|
|
iconColor: "text-blue-600",
|
|
textColor: "text-blue-600"
|
|
},
|
|
{
|
|
title: "Scheduled",
|
|
value: "8",
|
|
icon: "ic:outline-schedule",
|
|
bgColor: "bg-green-100",
|
|
iconColor: "text-green-600",
|
|
textColor: "text-green-600"
|
|
},
|
|
{
|
|
title: "Completed Today",
|
|
value: "45",
|
|
icon: "ic:outline-check-circle",
|
|
bgColor: "bg-purple-100",
|
|
iconColor: "text-purple-600",
|
|
textColor: "text-purple-600"
|
|
},
|
|
{
|
|
title: "Total Messages",
|
|
value: "2.3M",
|
|
icon: "ic:outline-email",
|
|
bgColor: "bg-orange-100",
|
|
iconColor: "text-orange-600",
|
|
textColor: "text-orange-600"
|
|
}
|
|
]);
|
|
|
|
// Active batches
|
|
const activeBatches = ref([
|
|
{
|
|
id: 'batch_001',
|
|
name: 'Newsletter Campaign Q1',
|
|
description: 'Quarterly newsletter to all subscribers',
|
|
status: 'processing',
|
|
type: 'email',
|
|
processed: 15000,
|
|
total: 50000,
|
|
chunkSize: 500,
|
|
startedAt: '2024-01-15 09:00:00',
|
|
eta: '2 hours'
|
|
},
|
|
{
|
|
id: 'batch_002',
|
|
name: 'Birthday Reminders',
|
|
description: 'Daily birthday notifications',
|
|
status: 'completed',
|
|
type: 'push',
|
|
processed: 1200,
|
|
total: 1200,
|
|
chunkSize: 100,
|
|
startedAt: '2024-01-15 08:00:00',
|
|
eta: 'Completed'
|
|
},
|
|
{
|
|
id: 'batch_003',
|
|
name: 'SMS OTP Batch',
|
|
description: 'OTP messages for verification',
|
|
status: 'paused',
|
|
type: 'sms',
|
|
processed: 800,
|
|
total: 2000,
|
|
chunkSize: 200,
|
|
startedAt: '2024-01-15 10:30:00',
|
|
eta: 'Paused'
|
|
}
|
|
]);
|
|
|
|
// Batch history table fields
|
|
const historyTableFields = ref([
|
|
{ key: 'name', label: 'Batch Name', sortable: true },
|
|
{ key: 'type', label: 'Type', sortable: true },
|
|
{ key: 'status', label: 'Status', sortable: true },
|
|
{ key: 'total', label: 'Total Messages', sortable: true },
|
|
{ key: 'processed', label: 'Processed', sortable: true },
|
|
{ key: 'startedAt', label: 'Started', sortable: true },
|
|
{ key: 'completedAt', label: 'Completed', sortable: true },
|
|
{ key: 'duration', label: 'Duration', sortable: true }
|
|
]);
|
|
|
|
// Batch history data
|
|
const batchHistory = ref([
|
|
{
|
|
name: 'Welcome Email Series',
|
|
type: 'email',
|
|
status: 'completed',
|
|
total: 25000,
|
|
processed: 25000,
|
|
startedAt: '2024-01-14 14:00:00',
|
|
completedAt: '2024-01-14 16:30:00',
|
|
duration: '2h 30m'
|
|
},
|
|
{
|
|
name: 'Product Update Push',
|
|
type: 'push',
|
|
status: 'completed',
|
|
total: 100000,
|
|
processed: 98500,
|
|
startedAt: '2024-01-13 10:00:00',
|
|
completedAt: '2024-01-13 12:45:00',
|
|
duration: '2h 45m'
|
|
},
|
|
{
|
|
name: 'Security Alert SMS',
|
|
type: 'sms',
|
|
status: 'failed',
|
|
total: 5000,
|
|
processed: 2300,
|
|
startedAt: '2024-01-12 16:00:00',
|
|
completedAt: '2024-01-12 16:45:00',
|
|
duration: '45m'
|
|
}
|
|
]);
|
|
|
|
// Batch templates
|
|
const batchTemplates = ref([
|
|
{
|
|
name: 'Newsletter Campaign',
|
|
description: 'Standard newsletter template for marketing campaigns',
|
|
type: 'email',
|
|
chunkSize: 1000,
|
|
priority: 'medium',
|
|
icon: 'ic:outline-email'
|
|
},
|
|
{
|
|
name: 'Birthday Reminders',
|
|
description: 'Daily birthday notification template',
|
|
type: 'push',
|
|
chunkSize: 100,
|
|
priority: 'low',
|
|
icon: 'ic:outline-cake'
|
|
},
|
|
{
|
|
name: 'System Notifications',
|
|
description: 'Critical system alerts and updates',
|
|
type: 'push',
|
|
chunkSize: 500,
|
|
priority: 'high',
|
|
icon: 'ic:outline-notification-important'
|
|
},
|
|
{
|
|
name: 'SMS Verification',
|
|
description: 'OTP and verification SMS template',
|
|
type: 'sms',
|
|
chunkSize: 200,
|
|
priority: 'high',
|
|
icon: 'ic:outline-sms'
|
|
}
|
|
]);
|
|
|
|
// Methods
|
|
function getBatchStatusVariant(status) {
|
|
const variants = {
|
|
pending: 'info',
|
|
processing: 'warning',
|
|
completed: 'success',
|
|
failed: 'danger',
|
|
paused: 'secondary'
|
|
};
|
|
return variants[status] || 'default';
|
|
}
|
|
|
|
function viewBatchDetails(batch) {
|
|
// Navigate to batch details page or show detailed modal
|
|
console.log('Viewing batch details:', batch);
|
|
}
|
|
|
|
function pauseBatch(batch) {
|
|
batch.status = 'paused';
|
|
batch.eta = 'Paused';
|
|
}
|
|
|
|
function resumeBatch(batch) {
|
|
batch.status = 'processing';
|
|
batch.eta = '1.5 hours';
|
|
}
|
|
|
|
function cancelBatch(batch) {
|
|
batch.status = 'cancelled';
|
|
batch.eta = 'Cancelled';
|
|
}
|
|
|
|
function createBatch() {
|
|
// Mock batch creation
|
|
const batch = {
|
|
id: `batch_${Date.now()}`,
|
|
name: newBatch.value.name,
|
|
description: newBatch.value.description,
|
|
status: 'pending',
|
|
type: newBatch.value.type,
|
|
processed: 0,
|
|
total: 10000, // Mock total
|
|
chunkSize: newBatch.value.chunkSize,
|
|
startedAt: new Date().toLocaleString(),
|
|
eta: 'Pending'
|
|
};
|
|
|
|
activeBatches.value.unshift(batch);
|
|
showCreateBatchModal.value = false;
|
|
|
|
// Reset form
|
|
newBatch.value = {
|
|
name: '',
|
|
type: '',
|
|
description: '',
|
|
chunkSize: 500,
|
|
priority: 'medium',
|
|
delay: 1000,
|
|
criteria: ''
|
|
};
|
|
}
|
|
|
|
function scheduleNewBatch() {
|
|
// Mock batch scheduling
|
|
console.log('Scheduling batch:', scheduleBatch.value);
|
|
showScheduleModal.value = false;
|
|
|
|
// Reset form
|
|
scheduleBatch.value = {
|
|
templateId: '',
|
|
date: '',
|
|
time: '',
|
|
timezone: 'UTC',
|
|
recurring: false,
|
|
recurrencePattern: 'daily'
|
|
};
|
|
}
|
|
|
|
function useBatchTemplate(template) {
|
|
newBatch.value = {
|
|
name: template.name,
|
|
type: template.type,
|
|
description: template.description,
|
|
chunkSize: template.chunkSize,
|
|
priority: template.priority,
|
|
delay: 1000,
|
|
criteria: ''
|
|
};
|
|
|
|
showTemplatesModal.value = false;
|
|
showCreateBatchModal.value = true;
|
|
}
|
|
|
|
function refreshBatches() {
|
|
// Mock refresh
|
|
console.log('Refreshing batches...');
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped></style> |