From 30c8149008e776c7b7bc1a299d010a56bb57500e Mon Sep 17 00:00:00 2001 From: Kavehhn174 Date: Wed, 19 Aug 2026 07:27:09 +0330 Subject: [PATCH] feat(property): add save toasts, background autosave with bottom-right status popup, and configurable autosave interval in settings --- src/service/SettingService.js | 61 ++++++++ src/views/pages/Property/CreateProperty.vue | 164 +++++++++++++++++++- src/views/pages/Settings/SearchSettings.vue | 112 ++++++++++++- 3 files changed, 331 insertions(+), 6 deletions(-) diff --git a/src/service/SettingService.js b/src/service/SettingService.js index 6b74c62..8c5c40e 100644 --- a/src/service/SettingService.js +++ b/src/service/SettingService.js @@ -136,5 +136,66 @@ export const SettingService = { console.error('Error seeding database:', err); throw err; } + }, + + /** + * Get auto-save configuration + * @returns {Promise<{enabled: boolean, intervalSeconds: number}>} + */ + getAutoSaveSetting: async () => { + const config = { + method: 'get', + url: '/api/settings/autosave', + withCredentials: true, + headers: SettingService._getAuthHeader() + }; + try { + const response = await axios(config); + if (response.data?.data) { + if (typeof localStorage !== 'undefined') { + localStorage.setItem('bm-autosave-settings', JSON.stringify(response.data.data)); + } + return response.data.data; + } + } catch (err) { + console.warn('Error fetching autosave setting from server, using local fallback:', err); + } + if (typeof localStorage !== 'undefined') { + const cached = localStorage.getItem('bm-autosave-settings'); + if (cached) { + try { + return JSON.parse(cached); + } catch (e) {} + } + } + return { enabled: true, intervalSeconds: 60 }; + }, + + /** + * Update auto-save configuration + * @param {{enabled: boolean, intervalSeconds: number}} data + * @returns {Promise<{enabled: boolean, intervalSeconds: number}>} + */ + updateAutoSaveSetting: async (data) => { + const config = { + method: 'put', + url: '/api/settings/autosave', + withCredentials: true, + data, + headers: SettingService._getAuthHeader() + }; + try { + const response = await axios(config); + if (typeof localStorage !== 'undefined') { + localStorage.setItem('bm-autosave-settings', JSON.stringify(response.data.data)); + } + return response.data.data; + } catch (err) { + console.error('Error updating autosave setting:', err); + if (typeof localStorage !== 'undefined') { + localStorage.setItem('bm-autosave-settings', JSON.stringify(data)); + } + return data; + } } }; diff --git a/src/views/pages/Property/CreateProperty.vue b/src/views/pages/Property/CreateProperty.vue index 7e455db..e2cf6e5 100644 --- a/src/views/pages/Property/CreateProperty.vue +++ b/src/views/pages/Property/CreateProperty.vue @@ -1,10 +1,11 @@ + + diff --git a/src/views/pages/Settings/SearchSettings.vue b/src/views/pages/Settings/SearchSettings.vue index af20f72..2d84d38 100644 --- a/src/views/pages/Settings/SearchSettings.vue +++ b/src/views/pages/Settings/SearchSettings.vue @@ -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) => { + +
+
+
+
+ +
+
+
+

+ تنظیمات ذخیره خودکار (Auto-Save) +

+ +
+

+ پیکربندی ذخیره پس‌زمینه خودکار فرم‌ها و املاک. در صورت فعال بودن، تغییرات شما بدون نیاز به فشردن دستی دکمه ذخیره، در بازه‌های مشخص ذخیره شده و اعلان آن در گوشه صفحه نمایش داده می‌شود. +

+
+
+ +
+
+ فعال بودن: + +
+ +
+ بازه زمانی: + +
+ +
+
+
+