feat: add search settings page in dashboard, sidebar menu, and MongoDB search integration
deploy-chabokan / deploy (push) Canceled after 0s

This commit is contained in:
2026-08-19 05:50:18 +03:30
parent cf7e1ee45c
commit 859a86f1a5
8 changed files with 581 additions and 20 deletions
+37 -2
View File
@@ -3,8 +3,10 @@ import { FilterMatchMode } from '@primevue/core/api';
import { useToast } from 'primevue/usetoast';
import { onMounted, ref, watch, computed } from 'vue';
import { PropertyService } from '@/service/PropertyService';
import { SettingService } from '@/service/SettingService';
import { useRouter, useRoute } from 'vue-router';
import Chip from 'primevue/chip';
import Tag from 'primevue/tag';
import InputIcon from 'primevue/inputicon';
import IconField from 'primevue/iconfield';
import SelectButton from 'primevue/selectbutton';
@@ -34,6 +36,7 @@ const selectedPropertyId = ref(null);
const mapRef = ref(null);
const splitMapRef = ref(null);
const propertyCardRefs = ref({});
const searchMethod = ref(null); // 'typesense' | 'mongo'
const filters = ref({
global: { value: null, matchMode: FilterMatchMode.CONTAINS }
@@ -47,7 +50,18 @@ const pagesCount = ref(0);
const DEFAULT_IMAGE = 'https://cloud.mbmanager.ir/images/item-no-image.png';
onMounted(() => {
const loadSearchSetting = async () => {
try {
const setting = await SettingService.getSearchSettingByPage('properties');
searchMethod.value = setting?.searchMethod || 'typesense';
} catch (e) {
console.warn('Failed to load search setting, defaulting to typesense', e);
searchMethod.value = 'typesense';
}
};
onMounted(async () => {
await loadSearchSetting();
loadData();
});
@@ -112,7 +126,15 @@ const onPageChange = (event) => {
const loadData = async () => {
try {
const response = await PropertyService.searchProperties(route.query);
if (searchMethod.value === null) {
await loadSearchSetting();
}
let response;
if (searchMethod.value === 'mongo') {
response = await PropertyService.searchPropertiesMongo(route.query);
} else {
response = await PropertyService.searchProperties(route.query);
}
properties.value = response.properties || response.belongings || response || [];
totalCount.value = response.totalCount || (Array.isArray(response) ? response.length : 0);
pagesCount.value = Math.ceil(totalCount.value / per_page.value);
@@ -122,6 +144,7 @@ const loadData = async () => {
}
};
const loading = ref(false);
const indexingFinished = ref(false);
const indexingMessage = ref('در حال ایندکس...');
@@ -262,6 +285,18 @@ const onCardHover = (propertyId) => {
</IconField>
<Chip v-if="searchPhrase" class="mx-1" :label="searchPhrase" removable @remove="handleRemoveSearch" />
<!-- Search Engine Mode Tag -->
<Tag
v-if="searchMethod"
:value="searchMethod === 'mongo' ? 'جستجو: MongoDB' : 'جستجو: Typesense'"
:severity="searchMethod === 'mongo' ? 'success' : 'info'"
:icon="searchMethod === 'mongo' ? 'pi pi-database' : 'pi pi-bolt'"
class="cursor-pointer text-xs"
v-tooltip.bottom="'کلیک برای تغییر موتور جستجو در تنظیمات'"
@click="router.push('/settings/search-settings')"
/>
<!-- View Mode Selector -->
<SelectButton
v-model="viewMode"