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
@@ -3,13 +3,29 @@ import { FilterMatchMode } from '@primevue/core/api';
import { useToast } from 'primevue/usetoast';
import { onMounted, ref, watch } from 'vue';
import { TransactionService } from '@/service/TransactionService';
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 LoadingCheck from '@/components/LoadingCheck.vue';
import Popover from 'primevue/popover';
onMounted(() => {
const searchMethod = ref(null);
const loadSearchSetting = async () => {
try {
const setting = await SettingService.getSearchSettingByPage('transactions');
searchMethod.value = setting?.searchMethod || 'typesense';
} catch (e) {
console.warn('Failed to load search setting for transactions, defaulting to typesense', e);
searchMethod.value = 'typesense';
}
};
onMounted(async () => {
await loadSearchSetting();
loadData();
});
@@ -74,7 +90,7 @@ watch(
{ deep: true }
);
const handleRemoveSearch = () => {
removeFromQuery('searchPhrase'); // Ensure 'searchPhrase' is the correct key
removeFromQuery('query');
searchPhrase.value = '';
};
@@ -105,20 +121,27 @@ const onPageChange = (event) => {
}
};
const loadData = () => {
TransactionService.searchTransactions(route.query)
.then((response) => {
console.log('response', response);
transactions.value = response.transactions || response;
totalCount.value = response.totalCount || response.length || 0;
pagesCount.value = Math.ceil(totalCount.value / per_page.value);
})
.catch((error) => {
toast.add({ severity: 'error', summary: 'Error', detail: 'خطا در دریافت اطلاعات', life: 3000 });
console.error('Error loading data:', error);
});
const loadData = async () => {
try {
if (searchMethod.value === null) {
await loadSearchSetting();
}
let response;
if (searchMethod.value === 'mongo') {
response = await TransactionService.searchTransactionsMongo(route.query);
} else {
response = await TransactionService.searchTransactions(route.query);
}
transactions.value = response.transactions || response;
totalCount.value = response.totalCount || response.length || 0;
pagesCount.value = Math.ceil(totalCount.value / per_page.value);
} catch (error) {
toast.add({ severity: 'error', summary: 'Error', detail: 'خطا در دریافت اطلاعات', life: 3000 });
console.error('Error loading data:', error);
}
};
const loading = ref(false);
const indexingFinished = ref(false);
const indexingMessage = ref('در حال ایندکس...');
@@ -270,15 +293,27 @@ const toggle = (event, data) => {
:globalFilterFields="['type', 'status', 'belongingName', 'createdAt', 'description']"
>
<template #header>
<div class="">
<h4 class="m-0">مدیریت تراکنش‌ها</h4>
<div class="p-input-icon-right w-1/3 mt-2 lg:mt-0">
<InputText v-model="searchPhrase" placeholder="جستجو..." class="w-full" />
<div class="flex flex-wrap items-center justify-between gap-3">
<div class="flex items-center gap-3">
<h4 class="m-0 font-bold">مدیریت تراکنش‌ها</h4>
<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')"
/>
</div>
<div class="p-input-icon-right w-full sm:w-72 mt-2 lg:mt-0">
<InputText v-model="searchPhrase" placeholder="جستجو در تراکنش‌ها..." class="w-full" />
</div>
</div>
<Chip v-if="searchPhrase" class="mx-2 mt-2" :label="searchPhrase" removable @remove="handleRemoveSearch" />
</template>
<Column field="_id" header="شناسه" sortable style="width: 10%"></Column>
<Column field="belongingName" header="ملک" sortable style="width: 15%"></Column>