feat(property): add save toasts, background autosave with bottom-right status popup, and configurable autosave interval in settings
deploy-chabokan / deploy (push) Canceled after 0s
deploy-chabokan / deploy (push) Canceled after 0s
This commit is contained in:
@@ -18,15 +18,68 @@ const seedStatus = ref({ isSeeded: false, seededAt: null });
|
||||
const isSeeding = ref(false);
|
||||
const seedLoading = ref(false);
|
||||
|
||||
// Auto-Save Settings State
|
||||
const autoSaveSettings = ref({ enabled: true, intervalSeconds: 60 });
|
||||
const autoSaveLoading = ref(false);
|
||||
const autoSaveSaving = ref(false);
|
||||
|
||||
const autoSaveIntervalOptions = [
|
||||
{ label: '۳۰ ثانیه (سریع)', value: 30 },
|
||||
{ label: '۱ دقیقه (پیشفرض)', value: 60 },
|
||||
{ label: '۲ دقیقه', value: 120 },
|
||||
{ label: '۳ دقیقه', value: 180 },
|
||||
{ label: '۵ دقیقه', value: 300 },
|
||||
{ label: '۱۰ دقیقه', value: 600 }
|
||||
];
|
||||
|
||||
const methodOptions = [
|
||||
{ label: 'Typesense', value: 'typesense', icon: 'pi pi-bolt', class: 'text-amber-500' },
|
||||
{ label: 'MongoDB', value: 'mongo', icon: 'pi pi-database', class: 'text-emerald-500' }
|
||||
];
|
||||
|
||||
onMounted(async () => {
|
||||
await Promise.all([loadSettings(), loadSeedStatus()]);
|
||||
await Promise.all([loadSettings(), loadSeedStatus(), loadAutoSaveSettings()]);
|
||||
});
|
||||
|
||||
const loadAutoSaveSettings = async () => {
|
||||
autoSaveLoading.value = true;
|
||||
try {
|
||||
const data = await SettingService.getAutoSaveSetting();
|
||||
if (data) {
|
||||
autoSaveSettings.value = {
|
||||
enabled: data.enabled !== undefined ? data.enabled : true,
|
||||
intervalSeconds: Number(data.intervalSeconds) || 60
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Failed to load autosave settings:', e);
|
||||
} finally {
|
||||
autoSaveLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const saveAutoSaveSettings = async () => {
|
||||
autoSaveSaving.value = true;
|
||||
try {
|
||||
await SettingService.updateAutoSaveSetting(autoSaveSettings.value);
|
||||
toast.add({
|
||||
severity: 'success',
|
||||
summary: 'موفقیتآمیز',
|
||||
detail: 'تنظیمات ذخیره خودکار با موفقیت ذخیره شد.',
|
||||
life: 3000
|
||||
});
|
||||
} catch (e) {
|
||||
toast.add({
|
||||
severity: 'error',
|
||||
summary: 'خطا',
|
||||
detail: 'خطا در ذخیره تنظیمات ذخیره خودکار',
|
||||
life: 3000
|
||||
});
|
||||
} finally {
|
||||
autoSaveSaving.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const loadSeedStatus = async () => {
|
||||
seedLoading.value = true;
|
||||
try {
|
||||
@@ -276,6 +329,63 @@ const navigateToModule = (routePath) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Auto-Save Settings Card ── -->
|
||||
<div class="card p-6 mb-6 shadow-sm border border-surface-200 dark:border-surface-700 bg-surface-0 dark:bg-surface-900 rounded-2xl">
|
||||
<div class="flex flex-col lg:flex-row lg:items-center justify-between gap-6">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="w-14 h-14 rounded-2xl flex items-center justify-center text-2xl flex-shrink-0 bg-emerald-100 text-emerald-600 dark:bg-emerald-950 dark:text-emerald-400 shadow-sm">
|
||||
<i class="pi pi-save"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center gap-2.5 flex-wrap">
|
||||
<h3 class="text-xl font-bold m-0 text-surface-900 dark:text-surface-0">
|
||||
تنظیمات ذخیره خودکار (Auto-Save)
|
||||
</h3>
|
||||
<Tag
|
||||
:value="autoSaveSettings.enabled ? 'فعال' : 'غیرفعال'"
|
||||
:severity="autoSaveSettings.enabled ? 'success' : 'secondary'"
|
||||
rounded
|
||||
class="px-2.5 text-xs font-bold"
|
||||
/>
|
||||
</div>
|
||||
<p class="text-surface-500 dark:text-surface-400 m-0 mt-1.5 text-sm leading-relaxed max-w-2xl">
|
||||
پیکربندی ذخیره پسزمینه خودکار فرمها و املاک. در صورت فعال بودن، تغییرات شما بدون نیاز به فشردن دستی دکمه ذخیره، در بازههای مشخص ذخیره شده و اعلان آن در گوشه صفحه نمایش داده میشود.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap items-center gap-4 flex-shrink-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-xs font-medium text-surface-600 dark:text-surface-300">فعال بودن:</span>
|
||||
<ToggleSwitch v-model="autoSaveSettings.enabled" />
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-xs font-medium text-surface-600 dark:text-surface-300">بازه زمانی:</span>
|
||||
<Dropdown
|
||||
v-model="autoSaveSettings.intervalSeconds"
|
||||
:options="autoSaveIntervalOptions"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
:disabled="!autoSaveSettings.enabled"
|
||||
class="!rounded-xl text-xs w-44"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
label="ذخیره تنظیمات"
|
||||
icon="pi pi-check"
|
||||
severity="primary"
|
||||
rounded
|
||||
size="small"
|
||||
:loading="autoSaveSaving"
|
||||
@click="saveAutoSaveSettings"
|
||||
class="px-4 font-semibold"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Quick Actions Toolbar ── -->
|
||||
<div class="card p-4 mb-6 flex flex-wrap items-center justify-between gap-4">
|
||||
<div class="flex flex-wrap items-center gap-3">
|
||||
|
||||
Reference in New Issue
Block a user