mirror of
https://github.com/unraid/api.git
synced 2026-01-03 23:19:54 -06:00
119 lines
3.8 KiB
Vue
119 lines
3.8 KiB
Vue
<script setup lang="ts">
|
|
import { ref, computed } from 'vue';
|
|
import { useQuery } from '@vue/apollo-composable';
|
|
|
|
import { Button, Sheet, SheetContent, SheetTitle, Spinner } from '@unraid/ui';
|
|
|
|
import { BACKUP_JOB_CONFIGS_LIST_QUERY } from '~/components/Backup/backup-jobs.query';
|
|
import BackupJobConfigForm from '~/components/Backup/BackupJobConfigForm.vue';
|
|
import BackupJobItem from '~/components/Backup/BackupJobItem.vue';
|
|
|
|
const showConfigModal = ref(false);
|
|
const currentEditingConfigId = ref<string | null>(null);
|
|
|
|
const { result, loading, error, refetch } = useQuery(
|
|
BACKUP_JOB_CONFIGS_LIST_QUERY,
|
|
{},
|
|
{
|
|
fetchPolicy: 'cache-and-network',
|
|
pollInterval: 50000, // Much slower polling since we only need the list of configs
|
|
}
|
|
);
|
|
|
|
const backupConfigIds = computed(() => {
|
|
return result.value?.backup?.configs?.map((config) => config.id) || [];
|
|
});
|
|
|
|
function handleJobDeleted() {
|
|
refetch();
|
|
}
|
|
|
|
function openAddJobModal() {
|
|
currentEditingConfigId.value = null;
|
|
showConfigModal.value = true;
|
|
}
|
|
|
|
function openEditJobModal(configId: string) {
|
|
currentEditingConfigId.value = configId;
|
|
showConfigModal.value = true;
|
|
}
|
|
|
|
function onConfigComplete() {
|
|
showConfigModal.value = false;
|
|
currentEditingConfigId.value = null;
|
|
refetch();
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="backup-config">
|
|
<div class="flex items-center justify-between mb-6">
|
|
<h2 class="text-xl font-bold text-gray-900 dark:text-white">Scheduled Backup Jobs</h2>
|
|
<Button variant="primary" @click="openAddJobModal"> Add Backup Job </Button>
|
|
</div>
|
|
|
|
<div v-if="loading && !result" class="text-center py-8">
|
|
<Spinner class="mx-auto" />
|
|
<p class="mt-2 text-gray-600 dark:text-gray-400">Loading backup configurations...</p>
|
|
</div>
|
|
|
|
<div
|
|
v-else-if="error"
|
|
class="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4"
|
|
>
|
|
<div class="flex">
|
|
<div class="ml-3">
|
|
<h3 class="text-sm font-medium text-red-800 dark:text-red-200">
|
|
Error loading backup configurations
|
|
</h3>
|
|
<div class="mt-2 text-sm text-red-700 dark:text-red-300">
|
|
{{ error.message }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-else-if="!backupConfigIds?.length" class="text-center py-12">
|
|
<div class="text-gray-400 dark:text-gray-600 mb-4">
|
|
<svg class="w-12 h-12 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M8 7V3a4 4 0 118 0v4m-4 8l-4-4 4-4m0 8h8a2 2 0 002-2V5a2 2 0 00-2-2H4a2 2 0 002 2v10a2 2 0 002 2z"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<h3 class="text-lg font-medium text-gray-900 dark:text-white mb-2">No backup jobs configured</h3>
|
|
<p class="text-gray-600 dark:text-gray-400 mb-4">
|
|
Create your first scheduled backup job to automatically protect your data.
|
|
</p>
|
|
<Button variant="primary" @click="openAddJobModal"> Create First Backup Job </Button>
|
|
</div>
|
|
|
|
<div v-else class="space-y-4">
|
|
<BackupJobItem
|
|
v-for="configId in backupConfigIds"
|
|
:key="configId"
|
|
:config-id="configId"
|
|
@deleted="handleJobDeleted"
|
|
@edit="openEditJobModal"
|
|
/>
|
|
</div>
|
|
|
|
<Sheet v-model:open="showConfigModal">
|
|
<SheetContent class="w-full max-w-4xl max-h-[90vh] overflow-auto">
|
|
<SheetTitle class="text-xl font-semibold text-gray-900 dark:text-white mb-4">
|
|
{{ currentEditingConfigId ? 'Edit Backup Job' : 'Add New Backup Job' }}
|
|
</SheetTitle>
|
|
<div class="p-6">
|
|
<BackupJobConfigForm
|
|
:config-id="currentEditingConfigId"
|
|
@complete="onConfigComplete"
|
|
@cancel="showConfigModal = false" />
|
|
</div>
|
|
</SheetContent>
|
|
</Sheet>
|
|
</div>
|
|
</template>
|