feat: add settings seed action and remove login credentials
SuperAdmins can seed once from Settings, and the login page no longer exposes default credentials.
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
<!-- /src/views/settings/SettingsView.vue -->
|
||||
<template>
|
||||
<div class="settings-view w-full max-w-3xl mx-auto">
|
||||
<PageHeader
|
||||
title="تنظیمات سیستم"
|
||||
subtitle="عملیات راهاندازی و پیکربندی اولیه پایگاه داده"
|
||||
/>
|
||||
|
||||
<div class="surface-card p-4 sm:p-5 border-round-xl border-1 border-color shadow-sm">
|
||||
<div class="flex align-items-start gap-3 mb-4">
|
||||
<div class="w-3rem h-3rem border-round-xl flex align-items-center justify-content-center flex-shrink-0 bg-primary-light text-primary">
|
||||
<i class="pi pi-database text-xl"></i>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<h2 class="text-lg font-bold text-color m-0 mb-1">راهاندازی پایگاه داده</h2>
|
||||
<p class="text-sm text-muted m-0 line-height-3">
|
||||
نقشهای سیستمی و حساب مدیر ارشد را یکبار ایجاد میکند. پس از اجرا، این دکمه برای همیشه مخفی میشود.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="isStatusLoading" class="flex align-items-center gap-2 text-muted text-sm">
|
||||
<i class="pi pi-spin pi-spinner"></i>
|
||||
<span>در حال بررسی وضعیت راهاندازی…</span>
|
||||
</div>
|
||||
|
||||
<div v-else-if="isLocked" class="flex align-items-center gap-2 p-3 border-round surface-ground border-1 border-color">
|
||||
<i class="pi pi-lock text-primary"></i>
|
||||
<div class="flex flex-column gap-1">
|
||||
<span class="font-semibold text-sm text-color">راهاندازی اولیه انجام شده است</span>
|
||||
<span v-if="lockedAtLabel" class="text-xs text-muted">{{ lockedAtLabel }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="flex flex-column sm:flex-row align-items-stretch sm:align-items-center gap-3">
|
||||
<Button
|
||||
label="اجرای راهاندازی پایگاه داده"
|
||||
icon="pi pi-play"
|
||||
class="font-bold"
|
||||
:loading="isSeeding"
|
||||
@click="confirmSeed"
|
||||
/>
|
||||
<span class="text-xs text-muted line-height-3">
|
||||
این عملیات فقط یکبار قابل اجرا است.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useConfirm } from 'primevue/useconfirm';
|
||||
import Button from 'primevue/button';
|
||||
import PageHeader from '@/components/common/PageHeader.vue';
|
||||
import { seedApi } from '@/api/seedApi';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
|
||||
const confirm = useConfirm();
|
||||
const { showSuccess, showError } = useToast();
|
||||
|
||||
const isStatusLoading = ref(true);
|
||||
const isSeeding = ref(false);
|
||||
const isLocked = ref(false);
|
||||
const lockedAt = ref(null);
|
||||
|
||||
const lockedAtLabel = computed(() => {
|
||||
if (!lockedAt.value) return '';
|
||||
const date = new Date(lockedAt.value);
|
||||
if (Number.isNaN(date.getTime())) return '';
|
||||
return `قفل شده در ${date.toLocaleString('fa-IR')}`;
|
||||
});
|
||||
|
||||
const applyStatus = (payload) => {
|
||||
const status = payload?.data || payload || {};
|
||||
isLocked.value = Boolean(status.locked);
|
||||
lockedAt.value = status.lockedAt || null;
|
||||
};
|
||||
|
||||
const loadStatus = async () => {
|
||||
isStatusLoading.value = true;
|
||||
try {
|
||||
const response = await seedApi.getStatus();
|
||||
applyStatus(response);
|
||||
} catch (err) {
|
||||
showError(err);
|
||||
} finally {
|
||||
isStatusLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const runSeed = async () => {
|
||||
isSeeding.value = true;
|
||||
try {
|
||||
const response = await seedApi.runSeed();
|
||||
applyStatus({ locked: true, lockedAt: new Date().toISOString(), ...(response?.data || response) });
|
||||
isLocked.value = true;
|
||||
showSuccess('راهاندازی پایگاه داده با موفقیت انجام شد.');
|
||||
} catch (err) {
|
||||
showError(err);
|
||||
await loadStatus();
|
||||
} finally {
|
||||
isSeeding.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const confirmSeed = () => {
|
||||
confirm.require({
|
||||
header: 'راهاندازی پایگاه داده',
|
||||
message: 'نقشهای سیستمی و حساب مدیر ارشد ایجاد یا بهروز میشوند. این دکمه پس از اجرا دیگر نمایش داده نمیشود. ادامه میدهید؟',
|
||||
icon: 'pi pi-exclamation-triangle',
|
||||
acceptLabel: 'اجرا',
|
||||
rejectLabel: 'انصراف',
|
||||
acceptClass: 'p-button-primary',
|
||||
accept: () => {
|
||||
runSeed();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(loadStatus);
|
||||
</script>
|
||||
Reference in New Issue
Block a user