Files
2026-03-23 00:51:38 +09:00

138 lines
6.0 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<AppLayout>
<template #header>
<div>
<Link :href="route('migrations.index')" class="inline-flex items-center text-primary hover:underline text-sm">
<i class="pi pi-arrow-left mr-1"></i> Назад к расписаниям
</Link>
<h2 class="text-xl font-bold mt-1">{{ schedule.name }}</h2>
</div>
</template>
<div class="grid gap-6">
<Card header="Информация о расписании">
<template #content>
<div class="grid grid-cols-2 gap-4">
<div>
<p class="text-sm text-muted-color">Исходная БД</p>
<p class="font-bold">{{ schedule.source_database?.name }}</p>
<p class="text-sm text-muted-color">{{ schedule.source_database?.host }}/{{ schedule.source_database?.database }}</p>
</div>
<div>
<p class="text-sm text-muted-color">Целевая БД</p>
<p class="font-bold">{{ schedule.target_database?.name }}</p>
<p class="text-sm text-muted-color">{{ schedule.target_database?.host }}/{{ schedule.target_database?.database }}</p>
</div>
<div>
<p class="text-sm text-muted-color">Расписание</p>
<p class="font-bold font-mono">{{ schedule.cron_expression }}</p>
<p class="text-sm text-muted-color">Часовой пояс: {{ schedule.timezone }}</p>
</div>
<div>
<p class="text-sm text-muted-color">Статус</p>
<Tag :value="schedule.is_active ? 'Активно' : 'Неактивно'"
:severity="schedule.is_active ? 'success' : 'secondary'" />
</div>
<div>
<p class="text-sm text-muted-color">Таблицы</p>
<p class="font-bold">{{ schedule.scheduled_tables?.length || 0 }} выбрано</p>
</div>
<div>
<p class="text-sm text-muted-color">Размер пакета</p>
<p class="font-bold">{{ schedule.batch_size }}</p>
</div>
</div>
<div class="flex gap-2 mt-6 pt-4 border-t border-surface">
<Button label="Запустить сейчас" icon="pi pi-play" severity="success"
@click="runNow" :loading="running" />
<Link :href="route('migrations.edit', schedule.id)">
<Button label="Редактировать" icon="pi pi-pencil" severity="secondary" />
</Link>
</div>
</template>
</Card>
<Card header="Запуски миграций">
<template #content>
<DataTable :value="runs" stripedRows>
<Column field="id" header="ID" sortable></Column>
<Column field="status" header="Статус">
<template #body="slotProps">
<Tag :value="getStatusLabel(slotProps.data.status)"
:severity="getStatusSeverity(slotProps.data.status)" />
</template>
</Column>
<Column field="total_tables" header="Таблиц"></Column>
<Column field="processed_tables" header="Обработано"></Column>
<Column field="migrated_rows" header="Строк мигрировано"></Column>
<Column field="started_at" header="Начало">
<template #body="slotProps">
{{ slotProps.data.started_at ? formatDate(slotProps.data.started_at) : '-' }}
</template>
</Column>
<Column field="completed_at" header="Завершение">
<template #body="slotProps">
{{ slotProps.data.completed_at ? formatDate(slotProps.data.completed_at) : '-' }}
</template>
</Column>
</DataTable>
</template>
</Card>
</div>
</AppLayout>
</template>
<script setup>
import { ref } from 'vue';
import { Link, router } from '@inertiajs/vue3';
import AppLayout from '@/Layouts/AppLayout.vue';
import Card from 'primevue/card';
import DataTable from 'primevue/datatable';
import Column from 'primevue/column';
import Button from 'primevue/button';
import Tag from 'primevue/tag';
const props = defineProps({
schedule: Object,
runs: Array,
});
const running = ref(false);
const getStatusLabel = (status) => {
const labels = {
pending: 'Ожидает',
running: 'Выполняется',
completed: 'Завершено',
failed: 'Ошибка',
};
return labels[status] || status;
};
const getStatusSeverity = (status) => {
const severityMap = {
pending: 'secondary',
running: 'info',
completed: 'success',
failed: 'danger',
};
return severityMap[status] || 'secondary';
};
const formatDate = (dateString) => {
return new Date(dateString).toLocaleString('ru-RU');
};
const runNow = () => {
if (confirm('Запустить эту миграцию сейчас?')) {
running.value = true;
router.post(route('migrations.run', props.schedule.id), {}, {
onFinish: () => {
running.value = false;
}
});
}
};
</script>