search_ui/pages/search/index.vue
2025-02-01 14:36:10 +03:30

2029 lines
73 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<NuxtLayout name="search-layout" :menu="sidbarMenu">
<!-- <Head> -->
<!-- <Title>{{ metaTitle }}</Title> -->
<!-- <Meta name="description" :content="title" /> -->
<!-- <Style type="text/css" children="body { background-color: green; }" ></Style> -->
<!-- </Head> -->
<div class="container-fluid">
<!-- #region header -->
<div :class="buildName() + '-header-color'" class="row align-items-end">
<!-- #region top-header -->
<div class="container">
<div class="col-12 pt-3">
<div class="row align-items-center mb-3">
<div class="col col-lg-auto order-1">
<div class="d-flex align-items-center">
<button
name="button"
type="button"
ref="buttonForTheSidebar"
class="toggle-mobile-nav dropdown-hamburger d-md-none"
@click.prevent="toggleSidebarMenu()"
>
<span class="sr-only">باز کردن منوی کنار</span>
<svg class="icon icon-Component-356--1">
<use xlink:href="#icon-Component-356--1"></use>
</svg>
</button>
<NuxtLink
:to="{
path: '/',
}"
classes="btn me-3"
>
<img
:src="logo"
:alt="appLongTitle()"
class="img-fluid logo"
style="max-width: 3.3em"
/>
</NuxtLink>
</div>
</div>
<div class="col-12 col-lg-7 order-3 order-lg-2">
<div class="search-container d-flex align-items-center">
<auto-complation
ref="autoComplationRef"
:contentKey="searchActiveTabGetter?.key"
:modeInit="modeInit"
:textSearch="textSearch"
:searchDomain="searchDomain"
:placeholder="
searchActiveTabGetter?.search_placeholder ??
'جستجو در هزاران محتوا'
"
@onSearchStart="searchStart"
@onSetDomainField="setDomainField"
:showAppend="true"
></auto-complation>
<div
class="search-logic position-relative align-self-end d-none d-lg-block col-3 col-xl-2 me-2"
>
<VMenu class="">
<label class="float-label" for="sort-type"
>منطق جستجو</label
>
<template #popper>
<div class="my-tooltip-content">منطق جستجو</div>
</template>
</VMenu>
<div class="my-dropdown">
<button
class="btn dropdown-toggle dropdown-toggle-color rounded-0 w-100 ms-2"
type="button"
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
id="dropdownSearchMenu"
>
<span class="navItemlabel">
{{
searchActiveTabGetter?.searchType.find(
(item) => item.key === searchType
)?.label || "نوع جستجو"
}}
</span>
</button>
<div
class="dropdown-menu"
aria-labelledby="dropdownSearchMenu"
>
<button
v-for="(
item, index
) in searchActiveTabGetter?.searchType"
:key="index"
type="button"
class="dropdown-item"
@click.prevent="
searchType = item.key;
searchTyping($event);
"
>
{{ item.label }}
</button>
</div>
</div>
</div>
<template v-if="searchTypeItem.item">
<button
v-if="searchTypeItem.item.type == 'bottom'"
v-tooltip="searchTypeItem.item.label"
class="btn btn-outline-primary me-2 no-wrap align-self-stretch d-none d-lg-block"
type="button"
@click.prevent="showSynonymModal"
>
<span class="navItemlabel">
{{ searchTypeItem.item?.label }}
</span>
</button>
<select
v-else-if="searchTypeItem.item.type == 'select'"
class="form-control w-auto me-2 align-self-stretch h-auto"
>
<!-- <option selected disabled value="undefined">
بدون انتخاب
</option> -->
<option
v-for="(opn, index) in searchTypeItem.item?.options"
:value="opn.value"
:key="index"
>
{{ opn.title }}
</option>
</select>
</template>
<!-- دکمه منو همبرگری -->
<button
class="btn d-lg-none"
data-bs-toggle="collapse"
href="#collapseExample"
role="button"
aria-expanded="false"
aria-controls="collapseExample"
>
<svg class="icon icon-filter-list">
<use xlink:href="#icon-filter-list"></use>
</svg>
</button>
<!-- <button
class="btn d-lg-none"
type="button"
data-bs-toggle="collapse"
data-bs-target="#hamburgerMenuLeft"
aria-controls="hamburgerMenuLeft"
aria-expanded="false"
aria-label="Toggle navigation"
>
<svg class="icon icon-filter-list">
<use xlink:href="#icon-filter-list"></use>
</svg> -->
<!-- </button> -->
</div>
</div>
<div class="col-auto col-lg order-2 order-lg-3">
<div class="d-flex justify-content-end" v-if="!isMajlesBuild()">
<user-avatar-dropdown class="justify-content-end">
</user-avatar-dropdown>
</div>
</div>
</div>
</div>
<!-- #endregion top-header -->
<!-- #region menu-header -->
<div class="menu-header col-12">
<div class="row row-nav">
<div class="col d-flex">
<ul
class="col-lg-8 col-12 nav nav-tabs justify-content-start align-items-center pe-0"
>
<div class="d-lg-none">
<button
class="btn pe-0"
type="button"
data-bs-toggle="offcanvas"
data-bs-target="#offcanvasScrolling"
aria-controls="offcanvasScrolling"
@click="currentPanel = 'filter'"
>
<svg class="icon icon-filter">
<use xlink:href="#icon-filter"></use>
</svg>
</button>
<div
:class="{
show:
currentPanel === 'advancedSearch' ||
currentPanel === 'filter',
}"
class="offcanvas offcanvas-end"
data-bs-scroll="true"
data-bs-backdrop="false"
tabindex="-1"
id="offcanvasScrolling"
aria-labelledby="offcanvasScrollingLabel"
>
<div class="offcanvas-header">
<h5
class="offcanvas-title"
id="offcanvasScrollingLabel"
>
محدود کردن
</h5>
<button
type="button"
class="btn-close"
data-bs-dismiss="offcanvas"
aria-label="Close"
@click="currentPanel = null"
></button>
</div>
<div class="filter-list-mobile">
<div
class=""
v-show="searchActiveTabGetter?.filter?.length"
>
<div v-show="currentPanel === 'filter'">
<!-- <filter-list-search
v-if="showMobileFilterList"
@filterUpdate="filterUpdate"
@changeHideFilter="changeHideFilter($event)"
ref="filterlist"
:lastSearchInListMode="lastSearchInListMode"
:changePageFilter="changePageFilter"
:activeTabGetter="searchActiveTabGetter"
class="filterList"
></filter-list-search> -->
</div>
<div v-show="currentPanel === 'advancedSearch'">
<!-- <AdvancedSearch
v-if="searchActiveTabGetter?.advance"
v-show="displayAdvanceSearch"
@onSearchStart="searchStart"
@closeAdvancedSearch="closeAdvancedSearch"
@set-query-advanced="setQueryAdvanced($event)"
></AdvancedSearch> -->
</div>
</div>
</div>
</div>
</div>
<li
class="nav-item desktop"
v-for="(navItem, index) in searchSchemaGetter"
:key="index"
>
<button
:title="navItem.label"
type="button"
@click.prevent="setNavbar(navItem, index)"
class="btn nav-link"
:class="{
active: navbarKey == getNavbarKey(navItem),
}"
>
{{ navItem.label }}
</button>
</li>
<li
class="nav-item mobile tabs-more-btn d-lg-none"
v-if="searchSchemaGetter?.length > 5"
>
<div class="dropdown">
<button
class="btn"
type="button"
id="dropdownMenuButton"
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<svg class="icon icon-Component-81--1">
<use xlink:href="#icon-Component-81--1"></use>
</svg>
</button>
<div
class="dropdown-menu"
aria-labelledby="dropdownMenuButton"
>
<template
v-for="(navItem, index) in searchSchemaGetter"
:key="index"
>
<a
class="dropdown-item"
v-if="canSee(navItem.key + '_view') && index > 3"
@click.prevent="setNavbar(navItem, index)"
:class="{
active: navbarKey == getNavbarKey(navItem),
}"
>{{ navItem.label }}</a
>
</template>
</div>
</div>
</li>
</ul>
<ul
class="col-4 nav nav-tabs d-flex justify-content-end align-content-center mb-2 d-none d-lg-flex"
>
<li
class="nav-item combo-list ms-2 position-relative mt-3 mt-md-0 ms-2 d-none d-lg-block"
>
<VMenu class="">
<label class="float-label" for="sort-type"
>مرتب سازی ؟</label
>
<template #popper>
<div
class="my-tooltip-content"
v-html="
getHtmlTooltip2(
'search',
'search_sort',
'SKVFBY8BPd2Jp_Xr9JoV'
)
"
></div>
</template>
</VMenu>
<!-- <label class="float-label" for="sort-type"
>مرتب سازی:</label
> -->
<div class="my-dropdown">
<button
v-tooltip="'انتخاب نوع مرتب‌سازی'"
class="btn dropdown-toggle dropdown-toggle-color rounded-0 w-100 ms-2"
type="button"
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
id="dropdownSortMenu"
>
<span class="navItemlabel">
{{
sortList.find((item) => item.list_key === sortKey)
?.title || "نوع مرتب‌سازی"
}}
</span>
</button>
<div
class="dropdown-menu"
aria-labelledby="dropdownSortMenu"
>
<button
v-for="(item, index) in sortList"
:key="index"
type="button"
class="dropdown-item"
@click.prevent="setSortListDropDown(item.list_key)"
>
{{ item.title }}
</button>
</div>
</div>
</li>
<li
class="nav-item combo-list position-relative d-none d-lg-block"
>
<switch-with-icon
v-if="searchActiveTabGetter?.showTableList"
@change-mode="switchViewMode($event)"
classes="btn d-inline-flex px-2 "
texts1="حالت جدولی"
texts2="حالت فهرستی"
:value="viewMode"
></switch-with-icon>
<!-- <div
class="switcher-container"
>
<button-component
@click="switchViewMode('table')"
:class="{ active: viewMode === 'table' }"
classes="btn d-inline-flex px-2 "
buttonText=""
title="حالت جدولی"
v-tooltip="'حالت جدولی'"
>
<span class="tavasi tavasi-table-view"></span>
</button-component>
<button-component
@click="switchViewMode('list')"
:class="{ active: viewMode === 'list' }"
classes="btn d-inline-flex px-2 "
buttonText=""
title="حالت فهرستی"
v-tooltip="'حالت فهرستی'"
>
<span class="tavasi tavasi-list-view"></span>
</button-component>
</div> -->
</li>
</ul>
</div>
</div>
</div>
<!-- #endregion menu-header -->
<!-- #region hamburger menu -->
<div class="collapse d-lg-none" id="collapseExample" ref="menu">
<div class="container-fluid hamburger-menu">
<!-- <div class="row align-items-center border-bottom my-2"> -->
<!-- <div class="col-6 text-end p-0"> -->
<!-- دکمه بستن سمت راست -->
<!-- <button
type="button"
class="btn"
data-bs-toggle="collapse"
data-bs-target="#hamburgerMenuLeft"
aria-expanded="false"
aria-label="Close"
>
<svg class="icon icon-Component-21--1">
<use xlink:href="#icon-Component-21--1"></use>
</svg>
</button>
</div>
<div class="col-6"> -->
<!-- متن سمت چپ -->
<!-- <p class="mb-0">تنظیمات جستجو</p> -->
<!-- </div> -->
<!-- </div> -->
<div class="row border-bottom mx-1">
<div class="d-flex justify-content-between">
<div
class="col-12 search-logic position-relative align-self-end"
>
<VMenu class="">
<label class="float-label" for="sort-type"
>منطق جستجو</label
>
<template #popper>
<div class="my-tooltip-content">منطق جستجو</div>
</template>
</VMenu>
<div class="my-dropdown">
<button
v-tooltip="'انتخاب نوع جستجو'"
class="btn dropdown-toggle dropdown-toggle-color rounded-0 w-100 ms-2"
type="button"
aria-haspopup="true"
aria-expanded="false"
id="dropdownSearchMenu"
data-bs-toggle="dropdown"
>
<span class="navItemlabel">
{{
searchActiveTabGetter?.searchType.find(
(item) => item.key === searchType
)?.label || "نوع جستجو"
}}
</span>
</button>
<div
class="dropdown-menu"
aria-labelledby="dropdownSearchMenu"
>
<button
v-for="(
item, index
) in searchActiveTabGetter?.searchType"
:key="index"
type="button"
class="dropdown-item"
@click.prevent="
searchType = item.key;
searchTyping($event);
"
>
{{ item.label }}
</button>
</div>
</div>
</div>
<button
v-if="searchTypeItem.item?.type == 'bottom'"
v-tooltip="searchTypeItem.item?.label"
class="btn btn-outline-primary me-2 no-wrap align-self-stretch my-2"
type="button"
@click.prevent="showSynonymModal"
>
<span class="navItemlabel">
{{ searchTypeItem.item?.label }}
</span>
</button>
<div
class="col-6 switch-with-icon d-flex justify-content-end"
>
<switch-with-icon
v-if="searchActiveTabGetter?.showTableList"
@change-mode="switchViewMode($event)"
classes="btn d-inline-flex px-2"
texts1="حالت جدولی"
texts2="حالت فهرستی"
:value="viewMode"
></switch-with-icon>
</div>
</div>
</div>
<div class="row border-bottom mx-1">
<div class="col-12 my-2">
<div class="search-logic position-relative align-self-end">
<VMenu class="">
<label class="float-label" for="sort-type"
>مرتب سازی ؟</label
>
<template #popper>
<div
class="my-tooltip-content"
v-html="
getHtmlTooltip2(
'search',
'search_sort',
'SKVFBY8BPd2Jp_Xr9JoV'
)
"
></div>
</template>
</VMenu>
<span class="my-dropdown">
<button
v-tooltip="'انتخاب نوع مرتب‌سازی'"
class="btn dropdown-toggle dropdown-toggle-color rounded-0 w-100 ms-2"
type="button"
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
id="dropdownSortMenu"
>
<span class="navItemlabel">
{{
sortList.find((item) => item.list_key === sortKey)
?.title || "نوع مرتب‌سازی"
}}
</span>
</button>
<div
class="dropdown-menu"
aria-labelledby="dropdownSortMenu"
>
<button
v-for="(item, index) in sortList"
:key="index"
type="button"
class="dropdown-item"
@click.prevent="setSortListDropDown(item.list_key)"
>
{{ item.title }}
</button>
</div>
</span>
</div>
</div>
</div>
</div>
</div>
<!-- #endregion hamburger menu -->
</div>
</div>
<!-- #endregion header -->
<!-- #region mian-content -->
<div class="row">
<div class="container mt-4 d-flex">
<div
v-if="showButton"
class="circle--button"
@click.prevent="changeHideFilter(0)"
ref="circle"
>
<svg
class="s12 icon-chevron-double-lg-left"
data-testid="chevron-double-lg-left-icon"
>
<use
href="assets/common/img/icons.svg#chevron-double-lg-left"
></use>
</svg>
</div>
<div class="row">
<div
v-if="searchActiveTabGetter?.filter?.length"
class="col col-lg-3 d-none d-lg-block filter-list-container position-relative"
ref="showFilter"
>
<!-- <div
class="mobile-mode mb-3"
:class="{ 'justify-content-end': showFilter }"
>
<button class="btn" @click.prevent="showFilter = !showFilter">
<svg
v-if="showFilter"
class="icon icon-chevron-double-right ms-1"
>
<use xlink:href="#icon-chevron-double-right"></use>
</svg>
<svg v-else class="icon icon-chevron-double-left">
<use xlink:href="#icon-chevron-double-left"></use>
</svg>
بستن فیلتر
</button>
</div> -->
<!-- #region filter-list -->
<filter-list-search
boxShadow="rgba(23, 23, 23, 0.24) 0px 1px 3px"
v-if="!showMobileFilterList"
@filterUpdate="filterUpdate"
@changeHideFilter="changeHideFilter($event)"
ref="filterlist"
:lastSearchInListMode="lastSearchInListMode"
:changePageFilter="changePageFilter"
:activeTabGetter="searchActiveTabGetter"
class="filterList"
></filter-list-search>
<!-- #endregion filter-list
#region advanced-search -->
<!-- <AdvancedSearch
v-if="searchActiveTabGetter?.advance"
v-show="displayAdvanceSearch"
@onSearchStart="searchStart"
@closeAdvancedSearch="closeAdvancedSearch"
@set-query-advanced="setQueryAdvanced($event)"
></AdvancedSearch> -->
<!-- #endregion advanced-search -->
</div>
<!-- #region content -->
<div class="col">
<suggestion-component
v-if="showSuggestion"
@on-select-suggestion="onSelectSuggestion"
:suggestions="lists?.data?.suggest?.result"
></suggestion-component>
<template v-if="!showNoAnswer()">
<component
:key="reRender"
:activeTabGetter="searchActiveTabGetter"
:is="contentComponentName"
:summeryKeys="['content', 'mindex', 'mintro']"
:courseKeys="['title', 'subtitle', 'mintro']"
:pagination="pagination"
:tq="textSearch"
:viewMode="viewMode"
:key_data="contentKey"
@changeCurrent="changeCurrent"
@changePage="changePaging"
:schemaItems="searchActiveTabGetter?.search_content"
:items="listAnswer"
:tableColumns="domainActiveGetter?.table_columns"
ref="content"
></component>
<template v-if="loading">
<the-content-loading
:loadingTitle="'در حال دریافت اطلاعات'"
class="table-loading"
></the-content-loading>
</template>
<template v-else>
<MyContent
:key="reRender"
:pagination="pagination"
:viewMode="viewMode"
@changeCurrent="changeCurrent"
@changePage="changePaging"
:schemaItems="searchActiveTabGetter?.search_content"
:items="listAnswer"
:tableColumns="domainActiveGetter?.table_columns"
:tableActions="domainActiveGetter?.table_actions"
ref="content"
>
</MyContent>
</template>
</template>
<no-data v-else>
<div class="d-flex justify-content-center align-items-center">
<div
class="alert alert-warning d-flex flex-column justify-content-center"
>
<div class="mb-3">پاسخی برای جستجوی شما یافت نشد.</div>
<div class="mb-3" v-if="textSearch">
<label>عبارت جستجو :</label>
<strong> {{ textSearch }}</strong>
</div>
<div class="mb-3" v-if="filterUrl">
<label>فیلتر :</label>
<strong> {{ filterUrl }}</strong>
</div>
<div class="mb-3" v-if="domain_lable">
<label>دامنه :</label>
<strong> {{ domain_lable }}</strong>
</div>
<div class="mb-3">
<label>نوع جستجو :</label>
<strong> {{ searchType_lable }}</strong>
</div>
</div>
</div>
</no-data>
</div>
</div>
<!-- #region summary -->
<div
v-if="showSummary"
class="col-8 col-lg-3 summary-container"
:class="{ expanded: showSummary }"
>
<SearchSummary
ref="summary"
:currentItem="currentItem"
:page="page"
@hideSummary="hideSummary"
></SearchSummary>
</div>
<!-- #endregion summary -->
</div>
<!-- #endregion content -->
</div>
<!-- #endregion mian-content -->
</div>
<base-modal-v2
v-if="showBaseModal"
modalSize="modal-lg"
minHeight="auto"
:hasFooter="false"
@close="closeModal"
modalTitle="جستجوی مترادفات"
>
<!-- <template v-slot:header>{{ entityContent_title }} </template> -->
<template v-slot:default>تنظیم بیشتر کلمات مترادف برای جستجو</template>
<template v-slot:body>
<synonym-search
:editCat="editCatItem"
@close="closeModal"
@search="onSearchSynonym"
></synonym-search>
</template>
<!-- <template v-slot:footer> This is a new modal footer. </template> -->
</base-modal-v2>
</NuxtLayout>
</template>
<script>
import { mapActions, mapState } from "pinia";
import { useSearchStore } from "~/stores/searchStore";
import { useCommonStore } from "~/stores/commonStore";
import searchApi from "~/apis/searchApi";
import adminApi from "~/apis/adminApi";
import sidbarMenuDefault from "~/json/search/json/menu.json";
import { useStorage } from "@vueuse/core";
export default {
name: "search",
setup() {
useHead({
title: import.meta.env.VITE_SEARCH_PAGE_TITLE,
meta: [{ name: "description", content: "My page description" }],
bodyAttrs: {
class: import.meta.env.VITE_SEARCH_SYSTEM,
},
});
definePageMeta({
layout: false,
name: "search",
});
},
props: ["modeInit"],
// mixins: [searchLineMixin],
watch: {
modeInit(newVal = 1) {
this.mode = newVal;
},
$route: {
handler: function (to, from) {
this.getSchemas();
this.setInputText(to.query.q);
this.state = 2;
setTimeout(() => {
this.searchStart(this.textSearch);
// if (this.textSearch != undefined && this.textSearch != "") {
// this.searchStart(this.textSearch);
// } else {
// this.getDefaultByFilter();
// }
}, 500);
},
},
// تکرار و خطای در جستجو وقتی تبها را عوض می کردیم داشت
//کار اضافه انجام می‌داد جاهای مختلف را بررسی کردم
// contentComponentName(newVal) {
// this.resetPagination();
// if (this.textSearch !== "" || this.tg !== undefined) {
// this.getQuery(false, true);
// } else {
// }
// },
// topRepeatInListMode(navItem) {
// if (navItem == true) {
// setTimeout(() => {
// this.$refs.dropdownSortlist.classList.remove("opacity");
// // this.$refs.circle.classList.remove("opacity");
// this.againsetlist(this.lists);
// }, 100);
// } else {
// setTimeout(() => {
// this.$refs.dropdownSortlist.classList.add("opacity");
// // this.$refs.circle.classList.add("opacity");
// }, 100);
// }
// },
searchActiveTabGetter(newVal) {
if (newVal?.domain) {
this.setSearchDomain(newVal);
}
},
// جستجوی پیشرفته انتخاب شده، بعد از اینکه ورودی خالی میشه، مرتب سازی هم ریست بشه.
textSearch(text) {
if (text?.length == 0 && this.sortKey == "searchsort")
this.setSortList("lasttitle");
},
},
created() {
this.httpService = useNuxtApp()["$http"];
},
beforeMount() {
if (buildName() == "monir" || window?.innerWidth < 575) {
this.viewMode = "list";
} else {
this.viewMode = "table";
}
},
async mounted() {
this.logo = (await logoPhoto()).default;
// this.logo = (await logoPhoto()).default;
// .then((img) => {
// this.logo = img;
// });
this.mode = this.modeInit;
if (this.$route.query.q) {
let q = this.$route.query.q ?? "";
let items = q.split("?");
if (items.length) q = items[0];
this.initText(q);
}
document.addEventListener("click", this.handleClickOutside);
// if (!this.isMajlesBuild) this.getEmplifyData();
let schemaExist = this.searchActiveTabGetter && this.searchSchemaGetter;
if (!schemaExist) this.getSchemas();
else this.setSearchDomain(this.searchActiveTabGetter);
if (window.outerWidth < 992) {
this.$store.commit("TOGGLE_SIDEBAR_MENU");
this.showMobileFilterList = true;
}
this.modetab = 0;
this.state = 2;
//////////////////////////////////////
setTimeout(() => {
let activeItem = this.searchSchemaGetter?.[0];
if (this.$route.query.key) {
let key = this.$route.query.key;
activeItem = this.searchSchemaGetter?.find((item) => item.key === key);
}
this.searchActiveTabSetter(activeItem);
//////////////////////////////////////
if (this.$route.query.q) {
this.setInputText(this.$route.query.q);
}
setTimeout(() => {
this.searchStart(this.textSearch);
// if (this.textSearch != undefined && this.textSearch != "") {
// this.searchStart(this.textSearch);
// } else {
// this.getDefaultByFilter();
// }
}, 500);
}, 300);
},
data() {
return {
httpService: {},
logo: "",
showMobileFilterList: false,
searchDomain: [],
showItem: 0,
mode: 1,
showSuggestion: false,
showBaseModal: false,
sysnonymSearchIsActive: false,
sysnonymSearchQuery: null,
setListItems: ["کد و شماره", "تاریخ", "عنوان قانون", "متن قانون"],
// activeSortItem: undefined,
tagLiSelected: null,
// showFilter: false,
ismultiWord: false,
showButton: false,
// topRepeatInListMode: true,
iscode: false,
lastSearchInListMode: true,
searchingState: false,
loading: false,
showSummary: false,
showTermSummary: false,
ismultword: true,
displayAdvanceSearch: false,
state: 2,
modetab: 0,
total_answer: 0,
amplifyIndex: -1,
countInPage: 10,
reRender: 1,
page: 0,
changePageFilter: "",
textSearch: "",
domain_key: "",
domain_lable: "",
filterUrl: "",
searchCodeKey: "all",
searchType: "normal",
searchTypeItem: {},
searchTypeItem_subItem: {},
searchType_lable: "عادی",
synonyms: {},
viewMode: null,
setQuery: "",
textAmplify: "",
lists: "",
listAnswer: [],
sortTitle: "",
sortKey: "lasttitle",
listAmplify: [],
currentItem: [],
sidbarMenuDefault: sidbarMenuDefault,
// sidbarMenuMin: sidbarMenuMin,
pagination: {
page: 1,
pages: 0,
total: 0,
offset: 0, // page * per_page
limit: 25, //per_page
},
currentPanel: null,
//بلا استفاده ها
// treeLists: "",
// rerenderChart: 1,
// addressBarUrl: null,
// filterNavigate: [],
// searchTab: "searchResult",
// windowWidth: window.innerWidth,
// meets: [],
// number: 0,
// showfilterCategory: true,
// activeListItem: undefined,
// showDropdown: false,
// showDropdownNavigateList: false,
// navigateListPart2: [],
// navigateListItem: "",
// listChangeItem: "",
// showListPanel: false,
// showSearchLine: true,
};
},
computed: {
...mapState(useSearchStore, [
"domainActiveGetter",
"searchActiveTabGetter",
"searchSchemaGetter",
"searchSynonymTitleGetter",
]),
...mapState(useCommonStore, [
"currentUser",
"organNameGetter",
"isSidebarCollapsed",
"userPermisionGetter",
]),
// metaTitle() {
// return import.meta.env.VITE_SEARCH_PAGE_TITLE;
// },
// bodyClass() {
// return import.meta.env.VITE_SEARCH_SYSTEM;
// },
isCategoryRoute() {
return this.$route.name == "searchCategory";
},
contentComponentName() {
if (this.searchActiveTabGetter?.searchContent)
return this.searchActiveTabGetter?.searchContent;
//بعد بروز رسانی کل این قسمت برداشته شود
// let key = this.contentKey;
// if (key == "qanon") return "QanonContent";
// else if (key == "mqanon" || key == "nqanon") return "MajlesQanonContent";
// else if (key == "qqanon") return "MajlesQavaninContent";
// else if (key == "mqsection") return "MajlesSectionContent";
// else if (key == "mashruh") return "MajlesMashruhContent";
// else if (key == "term") return "TermContent";
// else if (key == "emamain") return "EmamainContent";
// else if (key == "nesha") return "NeshaContent";
// else if (key == "qasection") return "MajlesQaSectionContent";
return "SearchContent";
},
summaryComponentName() {
let key = this.contentKey;
if (key == "term") return "TermSummary";
return "SearchSummary";
},
sidbarMenu() {
if (isMajlesBuild()) return sidbarMenuMin;
else return sidbarMenuDefault;
},
// sortTitle() {
// if (this.activeSortItem) {
// return this.activeSortItem.title;
// } else {
// if (this.searchActiveTabGetter?.lists?.length)
// return this.searchActiveTabGetter.lists[0].title;
// return "--";
// }
// },
// sortKey() {
// if (this.activeSortItem) {
// return this.activeSortItem.list_key;
// } else {
// if (this.searchActiveTabGetter?.lists?.length)
// return this.searchActiveTabGetter.lists[0].list_key;
// return undefined;
// }
// },
sortList() {
if (this.searchActiveTabGetter?.lists) {
if (!this.searchingState)
return this.searchActiveTabGetter?.lists.slice(
0,
this.searchActiveTabGetter?.lists.length - 1
);
else return this.searchActiveTabGetter?.lists;
}
return [];
},
isAdmin() {
return this.currentUser.user_level > 1;
},
hasVectorSearch() {
let key = this.contentKey;
return key == "mqsection" || key == "qasection";
},
navbarKey() {
if (this.searchActiveTabGetter?.key_navbar)
return this.searchActiveTabGetter?.key_navbar;
return this.searchActiveTabGetter?.key;
},
contentKey() {
// if (this.domainActiveGetter?.key_search)
// return this.domainActiveGetter?.key_search;
return this.searchActiveTabGetter?.key;
},
navigateList() {
// if (this.filterNavigate && this.filterNavigate.length > 0) {
// let result = [];
// this.schemasGetter.forEach((e) => {
// if (this.filterNavigate.includes(e.key)) result.push(e);
// });
// } else {
// result = this.schemasGetter;
// }
// if (result.length > 3) {
// return result.length > 3 ? result.slice(0, 3)
// }
// else {
// return result;
// }
// if (this.filterNavigate && this.filterNavigate.length > 0) {
// let result = [];
// this.schemasGetter.forEach((e) => {
// if (this.filterNavigate.includes(e.key)) result.push(e);
// });
// } else
// {
return this.searchSchemaGetter;
// }
},
},
methods: {
...mapActions(useCommonStore, [
"TOGGLE_SIDEBAR_MENU",
"sidebarCollapsedSetter",
]),
...mapActions(useSearchStore, [
"searchActiveTabSetter",
"searchSchemaSetter",
"domainActiveSetter",
"searchSynonymTitleSetter",
]),
setMode(item) {
this.mode = item;
},
initText(item) {
this.textSearch = item;
},
showSettingToggle() {
this.liSelected = null;
setTimeout(() => {
if (this.showItem == 0) this.showItem = 2;
else this.showItem = 0;
}, 100);
},
getHighlight(item) {
var find = this.textSearch;
var text = item.replaceAll(find, "<b>" + find + "</b>");
return text;
},
/**
* تنظیم دامنه جستجو.
* @param {Object} value - مقدار دامنه جستجوی جدید.
* @param {Object[]} value.domain - آرایه‌ای از اشیاء دامنه.
* @param {string} value.domain[].label - برچسب دامنه.
* @param {string} value.domain[].key - کلید دامنه.
*/
setSearchDomain(value) {
this.searchDomain = value.domain.domain;
let update = false;
if (this.searchDomain && this.searchDomain[0].key != "all") {
this.searchDomain.unshift({
label: "همه",
key: "all",
table_columns: this.searchDomain[0]?.table_columns,
});
update = true;
// this.searchDomain = [...this.searchDomain, ...value.domain.domain];
}
// if (update || !this.domainActiveGetter)
{
if (isMajlesBuild()) this.domainActiveSetter(this.searchDomain[1]);
else this.domainActiveSetter(this.searchDomain[0]);
}
},
onSelectSuggestion(data) {
this.searchStart(data);
this.showSuggestion = false;
},
// برای بستن div وقتی خارج از آن کلیک میشه
handleClickOutside(event) {
const isResponsiveOutside = window?.innerWidth <= 991;
if (!isResponsiveOutside) {
return; // خروج از تابع اگر کاربر در حال استفاده از موبایل یا تبلت است
}
const menuElement = this.$refs?.menu;
const sidebarElement = this.$refs.theSidebar?.$el;
const buttonForTheSidebar = this.$refs?.buttonForTheSidebar;
// to close left menu
if (menuElement && !menuElement.contains(event.target)) {
menuElement.classList.remove("show");
}
// to close theSidebar
if (
sidebarElement &&
!sidebarElement?.contains(event.target) &&
this.isSidebarCollapsed !== true
) {
if (!buttonForTheSidebar?.contains(event.target))
this.sidebarCollapsedSetter(true);
}
},
onSearchSynonym(synonyms) {
this.synonyms = synonyms;
this.closeModal();
this.getQuery();
},
editCatItem() {},
disableSynonymIsActive() {
this.sysnonymSearchQuery = null;
this.sysnonymSearchIsActive = false;
},
closeModal() {
this.showBaseModal = false;
// this.getCategories();
},
showSynonymModal() {
this.searchSynonymTitleSetter(this.textSearch);
this.showBaseModal = true;
this.sysnonymSearchIsActive = true;
},
getNavbarKey(item) {
if (item?.key_navbar) return item.key_navbar;
return item.key;
},
switchViewMode(viewMode) {
if (viewMode == "table") {
this.pagination.limit = 25;
} else {
this.pagination.limit = 10;
}
this.viewMode = viewMode;
this.searchStart(this.textSearch);
// if (this.textSearch != undefined && this.textSearch != "") {
// this.searchStart(this.textSearch);
// } else this.getDefaultByFilter();
},
toggleSidebarMenu() {
this.TOGGLE_SIDEBAR_MENU();
},
/**
* تنظیم مقدار متنی ورودی به عنوان متن جستجو.
* @event setInputText
* @param {string} text - مقدار متنی جدید برای تنظیم به عنوان متن جستجو.
*/
setInputText(text) {
this.textSearch = myEncodeQuery(text);
},
/**
* تنظیم آیتم انتخاب‌ شده و شروع جستجو.
* @param {Object} navItem - آیتم انتخاب‌شده.
*/
setDomainField(navItem) {
this.displayAdvanceSearch = navItem?.key == "advance";
if (this.displayAdvanceSearch) {
this.currentPanel = "advancedSearch";
}
// this.domainActiveSetter(navItem);
this.$refs.content?.setTableColumns();
this.$refs.autoComplationRef.prevSearchStart();
},
/**
* برای تنظیم آیتم طرح و به‌روز رسانی مسیر.
* @param {Object} item - آیتمی که باید تنظیم شود.
* @param {number} index - شاخص آیتم.
*/
setNavbar(item, index) {
this.modetab = index;
this.loading = true;
let full_path = this.$route.fullPath;
let newRoutePath = full_path;
let prevKey = this.$route.query.key;
if (prevKey)
newRoutePath = full_path.replace(`key=${prevKey}`, `key=${item.key}`);
else newRoutePath = full_path + `?key=${item.key}`;
this.$route.query.key = item.key;
history.pushState({}, document.title, newRoutePath);
this.searchActiveTabSetter(item);
setTimeout(() => {
this.searchStart(this.textSearch);
}, 300);
},
async getSchemas() {
let localStoageSearchSchema = useStorage("searchSchema", undefined).value;
if (localStoageSearchSchema) {
let searchSchema = JSON.parse(localStoageSearchSchema);
this.searchSchemaSetter(searchSchema);
this.searchActiveTabSetter(searchSchema[0]);
} else {
const payload = {
organ: this.organNameGetter,
system: "search",
build_state: buildState(),
};
const url = repoUrl() + searchApi.schema.list;
this.httpService
.postRequest(url, payload)
.then((res) => {
this.searchSchemaSetter(res.data.search);
this.searchActiveTabSetter(res.data.search[0]);
this.fetchingData = false;
})
.catch((err) => {
this.fetchingData = false;
});
}
},
/**
*تنظیم آیتم مرتب‌ سازی بر اساس کلید داده‌شده
* @param {string} [key="searchsort"] - کلید لیست مرتب‌ سازی. .
*/
setSortList(key = "searchsort") {
// let key = "lasttitle";
// if (this.searchActiveTabGetter?.lists) {
// let res = this.searchActiveTabGetter.lists.find(
// (item) => item.list_key == key
// );
// if (res) key = res.list_key;
// else key = this.searchActiveTabGetter.lists[0].list_key;
// }
// else this.activeSortItem = undefined;
this.sortKey = key;
},
//گشتم دیگه استفاده نداشت
// /**
// * تغییر حالت نمایش برای لیست.
// */
// changeDisplayMode() {
// this.topRepeatInListMode = !this.topRepeatInListMode;
// // ++this.rerenderChart;
// },
/**
* بررسی و انجام عملیات .لازم برای تغییر اندازه پنجره.
* @returns {boolean} اگر عرض پنجره کمتر از 992 پیکسل باشد، true برمی‌گرداند؛ در غیر این صورت false.
*/
handleResize() {
return window.outerWidth < 992;
// if (this.windowWidth < 990) {
// this.$store.commit("TOGGLE_SIDEBAR_MENU");
// }
},
// showFilterText(event) {
// this.changePageFilter = event;
// },
/**
* تنظیم لیست‌های درختی بر اساس رویداد موردنظر.
* @param {*} event رویدادی که می‌خواهید برای تنظیم لیست‌های درختی استفاده کنید.
*/
// treeListItem(event) {
// this.treeLists = event;
// },
/**
* تغییر وضعیت نمایش فیلترها بر اساس رویداد ورودی.
* @param {number} event ورودی که مشخص می‌کند کدام عملیات باید انجام شود؛ 0 برای نمایش فیلترها و 1 برای مخفی کردن آن‌ها.
*/
changeHideFilter(event) {
if (event === 0) {
this.$refs.axis.classList.remove("hiden");
this.$refs.showFilter.classList.toggle("d-none");
this.showButton = false;
// this.showFilter = true;
} else if (event === 1) {
this.$refs.axis.classList.add("hiden");
this.$refs.showFilter.classList.toggle("d-none");
this.showButton = true;
// this.showFilter = false;
}
},
changeType() {},
/**
* انجام عملیات مربوط به جستجو در حالت تایپ کردن.
*/
searchTyping(evt) {
this.searchTypeItem = {};
this.searchTypeItem_subItem = undefined;
let searchType = this.searchActiveTabGetter?.searchType.find(
(i) => i.key == this.searchType
);
if (searchType.item) {
this.searchTypeItem = searchType;
} else {
this.searchType_lable = "عادی";
if (this.searchType == "and") this.searchType_lable = "ترکیب عطفی";
else if (this.searchType == "phrase")
this.searchType_lable = "جستجوی عبارتی = عین عبارت";
else if (this.searchType == "vector")
this.searchType_lable + "جستجوی معنایی هوشمند";
this.$refs.autoComplationRef.prevSearchStart();
}
},
/**
* انجام عملیات مربوط به جستجو در حالت تایپ کردن.
*/
setSearchTypingItem(searchType) {
if (searchType.component == "SynonymSearch") this.showSynonymModal();
else if (searchType.key == "amplify") this.changeAmplify();
},
/**
* انجام عملیات مربوط به جستجو بر اساس کد.
*/
searchCoding() {
// this.searchCodeKey = code;
this.$refs.autoComplationRef.prevSearchStart();
},
/**
* دریافت داده‌های Emplify از سرور.
*/
async getEmplifyData() {
var vm = this;
let url = adminApi.admin.get.replace("{{system}}", "common");
url += "/search_amplify";
try {
const { $api } = useNuxtApp();
const res = await $api(url, {
baseURL: repoUrl(),
});
this.listAmplify = JSON.parse(res.data.hits.hits[0]._source.value);
} catch (err) {}
},
/**
* تغییر مقدار امپلیفای متناظر با انتخاب شده.
*/
changeAmplify() {
if (
this.amplifyIndex != -1 &&
this.amplifyIndex < this.listAmplify.length
) {
var text = this.listAmplify[this.amplifyIndex].keys;
this.textAmplify = text;
} else this.textAmplify = "";
this.filterUpdate(this.filterUrl);
},
/**
* جستجو بر اساس متن امپلیفای.
* @param {string} text متن جستجوی امپلیفای.
*/
searchAmplify(text) {
this.textAmplify = text;
this.filterUpdate(this.filterUrl);
},
/**
* بازنشانی گزینه‌ها به وضعیت اولیه.
*/
resetOptions() {
this.page = 0;
this.filterUrl = "";
this.$refs?.filterlist?.resetFilter();
},
/**
* نمایش فیلترها.
*/
showfilter() {
this.$refs?.filterlist?.showfilter();
},
/**
* بررسی وضعیت واژه‌های چند کلمه ای در رشته جستجوی ورودی.
* @param {string} query_string رشته جستجوی ورودی.
*/
checkMultiword(query_string) {
this.ismultword = true;
if (query_string == null || query_string == "") return;
var ww = query_string.split(" ");
this.iscode = /^\d+$/.test(query_string);
// if (this.iscode == false) this.ismultword = query_string.split(" ").length > 1;
// this.$refs.topheader?.setOptions(this.ismultword, this.iscode);
this.setOptions(this.ismultword, this.iscode);
},
/**
* تنظیم گزینه‌های جستجو.
* @param {boolean} isMulti وضعیت واژه‌های چندکلمه‌ای در رشته جستجوی ورودی.
* @param {boolean} isCode وضعیت کد بودن رشته جستجوی ورودی.
*/
setOptions(isMulti, isCode = false) {
this.ismultiWord = isMulti;
if (this.ismultiWord == false) this.searchType = "typeNormal";
this.iscode = isCode;
},
/**
* شروع عملیات جستجو با رشته جستجوی ورودی.
* @param {string|null} query_string رشته جستجوی ورودی. اگر نال یا خالی باشد، عملیات جستجو بر اساس پارامترهای فیلتر شروع می‌شود.
*/
searchStart(query_string = null) {
// وقتی از کامپوننت auto-complation فراخوانی بشه
if (typeof query_string == "object") {
query_string = query_string.textSearch;
}
if (query_string != null && query_string != "") {
query_string = query_string.trim();
this.setInputText(query_string);
this.checkMultiword(query_string);
history.pushState(
{},
document.title,
"/search" + "/?q=" + myEncodeQuery(query_string)
);
} else {
this.setInputText("");
this.setSortList("lasttitle");
}
// if (this.topRepeatInListMode)
// this.$refs?.content?.setTextSearch(query_string, this.countInPage);
this.resetOptions();
this.getQuery();
// کار جستجوی بدون متن جستجو و با متن جستجو در یک متود قابل جمع بود
// لذا این حالت بخاطر دوری از پیچیدگی حذف شد
// تست اولیه انجام شد و خوب کار میکرد
// else {
// this.setInputText("");
// this.searchingState = false;
// this.setSortList("lasttitle");
// this.getDefaultByFilter();
// }
// if (this.textSearch != "") {
// history.pushState(
// {},
// document.title,
// "/search" + "/?q=" + myEncodeQuery(this.textSearch)
// );
// } else history.pushState({}, document.title, "/search");
},
/**
* تنظیم کوئری پیشرفته برای جستجو.
* @param {string} query کوئری پیشرفته جستجو.
*/
setQueryAdvanced(query) {
this.initText(query);
// if (this.$refs.topheader) {
// this.$refs.topheader.setSearchLine(query);
// }
},
/**
* تغییر صفحه‌بندی.
* @param {number} item شماره صفحه جدید.
*/
changePaging: function (item) {
this.pagination = item;
this.getQuery(true, false, this.sortKey);
// if (this.searchingState) this.getQuery(true, false, this.sortKey);
// else this.getDefaultByFilter();
},
/**
* پنهان کردن خلاصه.
*/
hideSummary: function () {
this.showSummary = false;
// this.showTermSummary = false;
},
/**
* تغییر موقعیت فعلی.
* @param {any} item آیتم جدید.
*/
changeCurrent: function (item) {
this.showSummary = false;
// if (this.$route.name == "termResult") {
// this.changeCurrentTerm(item);
// }
// if (item == this.currentItem) this.showSummary = !this.showSummary;
// else this.showSummary = true;
this.$nextTick(() => {
this.showSummary = true;
});
this.currentItem = item;
if (this.$refs.summary) this.$refs.summary.setInfo(item);
},
/**
* به‌روزرسانی فیلترها و اجرای جستجو.
* @param {string} filter فیلتر جدید برای جستجو.
*/
filterUpdate: function (filter) {
this.filterUrl = filter;
this.page = 0;
this.getQuery(false, true);
// if (this.searchingState) this.getQuery(false, true);
// else this.getDefaultByFilter();
},
/**
* دریافت نتایج جستجو بر اساس متغیرهای فعلی.
* @param {boolean} pageOnly اگر صحیح باشد، تنها صفحه‌بندی بروزرسانی می‌شود و جستجوی جدید انجام نمی‌شود.
* @param {boolean} filteronly اگر صحیح باشد، تنها فیلترها بروزرسانی می‌شوند و جستجوی جدید انجام نمی‌شود.
* @param {string} _sortKey کلید مرتب‌سازی مورد نظر.
*/
async getQuery(pageOnly = false, filteronly = false, _sortKey = undefined) {
this.searchingState = false;
var vm = this;
this.loading = true;
let index_key = this.contentKey;
if (!index_key) return;
let query = "";
let payload = {};
//////////////// Synonym /////////////////////
if (this.searchType == "synonym") {
let newSynonym = {};
this.sysnonymSearchQuery = "";
if (this.synonyms) {
Object.keys(this.synonyms).forEach((key, index) => {
if (
!(
"isStopWord" in this.synonyms[key] &&
this.synonyms[key]["isStopWord"]
)
) {
newSynonym[key] = this.synonyms[key].value;
this.sysnonymSearchQuery += " " + key;
}
});
}
if (this.textSearch == "" || this.textSearch === undefined)
this.textSearch = this.sysnonymSearchQuery;
if (newSynonym) {
payload = {
synonym: newSynonym,
};
}
}
///////////////////////////////////////////////////////
if (!(this.textSearch == "" || this.textSearch === undefined)) {
query = myEncodeQuery(this.textSearch);
this.domain_key = this.domainActiveGetter?.key;
if (this.domain_key && this.domain_key != "all") {
this.domain_lable = this.domainActiveGetter?.label;
query =
encodeURIComponent("#") +
this.domainActiveGetter?.tag +
" " +
query;
}
}
if (_sortKey == undefined) {
if (query) this.setSortList("searchsort");
else this.setSortList("lasttitle");
}
// var suburl = appName + index_key + "/";
// if (this.iscode) {
// suburl += "code/" + this.searchCodeKey + "/";
// } else if (this.ismultword) {
// if (this.searchType == "and") suburl += "and/";
// else if (this.searchType == "phrase") suburl += "phrase/";
// else if (this.searchType == "vector") suburl += "vector/";
// }
let filter = this.filterUrl;
if (this.searchActiveTabGetter?.key_filter) {
filter += this.searchActiveTabGetter?.key_filter;
}
if (this.textAmplify != undefined && this.textAmplify != "") {
filter += "&o_am=" + this.textAmplify;
}
// if (this.sortKey != undefined) finalUrl += this.sortKey;
if (!pageOnly) {
this.resetPagination();
}
let filterFull = "";
if (query) filterFull += "q=" + query;
filterFull += filter;
if (filterFull == "") filterFull = "none";
let field_collapse = this.domainActiveGetter?.field_collapse ?? "normal";
let url = searchApi.search.queryNormal;
url = url.replace("{{appname}}", buildName());
url = url.replace("{{index_key}}", index_key);
url = url.replace("{{search_type}}", this.searchType);
url = url.replace("{{sortKey}}", this.sortKey);
url = url.replace("{{field_collapse}}", field_collapse);
url = url.replace("{{offset}}", this.pagination.offset);
url = url.replace("{{limit}}", this.pagination.limit);
url = url.replace("{{filter}}", filterFull);
//تعیین فیلد کد خاص برای جستجو استفاده نداشت حذف شد
// if (this.iscode) url = url.replace("{{sub_key}}", this.searchCodeKey);
// else url = url.replace("/{{sub_key}}", "");
//this.addressBarUrl = "/q=" + query + filter;
try {
const { $api } = useNuxtApp();
const response = await $api(url, {
baseURL: repoUrl(),
method: "POST",
body: payload,
});
this.lists = response;
this.listAnswer = [];
let sug_items = this.lists?.data?.suggest?.result.find((item) => {
return item?.options.length > 0;
});
this.showSuggestion = sug_items ? true : false;
this.searchingState = !(
this.textSearch == "" || this.textSearch === undefined
);
vm.loading = false;
vm.total_answer = response.hits.total.value;
this.$refs.filterlist?.setAnswer(response.aggregations);
this.listAnswer = response?.hits?.hits;
if (this.listAnswer.length) {
this.listAnswer.forEach((item) => {
if (
!item._source.qanon_etebar ||
item._source.qanon_etebar === ""
) {
item._source.qanon_etebar = "معتبر";
}
});
}
//vm.initNormalRespone(response, pageOnly, filteronly);
const total = response.hits.total.value;
let pages = Math.ceil(total / this.pagination.limit);
// pages = (total % this.pagination.limit == 0 && totla !=0 ) ? pages : pages-1;
const pagination = {
total: total,
pages: pages == 0 ? 1 : pages,
};
this.pagination = { ...this.pagination, ...pagination };
if (!pageOnly && vm.textSearch) {
LogService.index(
this.currentUser,
vm.textSearch,
vm.page,
vm.filterUrl,
response.took
);
}
} catch (err) {
vm.loading = false;
this.searchingState = false;
}
},
/**
* تنظیم مورد انتخابی مرتب‌سازی و اجرای عملیات مرتب‌سازی.
* @param {Object} item آیتم مرتب‌سازی انتخاب شده.
*/
setSortListDropDown(key, title = "") {
// کلید انتخاب شده از لیست
let item = key;
// در صورتی که کلید انتخاب نشده باشد، مقدار پیش‌فرض "lasttitle" تنظیم می‌شود
this.sortKey = item ?? "lasttitle";
// گرفتن مقادیر جدید بر اساس کلید انتخاب‌شده
this.getQuery(true, false, this.sortKey);
},
/**
* دریافت نتایج جستجو بر اساس فیلترها و مرتب‌سازی پیشفرض.
* @param {string|null} _sortKey کلید مرتب‌سازی مورد نظر. اگر مقداردهی نشود، از مرتب‌سازی پیشفرض استفاده می‌شود.
* @param {boolean} pageOnly اگر صحیح باشد، تنها صفحه‌بندی بروزرسانی می‌شود و جستجوی جدید انجام نمی‌شود.
* @param {boolean} filteronly اگر صحیح باشد، تنها فیلترها بروزرسانی می‌شوند و جستجوی جدید انجام نمی‌شود.
*/
/**
* پاسخ به درخواست جستجوی عادی را مقداردهی می‌کند.
* @param {Object} response پاسخ دریافتی از سرویس جستجو.
* @param {boolean} pageOnly اگر صحیح باشد، تنها صفحه‌بندی بروزرسانی می‌شود و اطلاعات نمایشی تغییر نمی‌کند.
* @param {boolean} filteronly اگر صحیح باشد، تنها فیلترها بروزرسانی می‌شوند و اطلاعات نمایشی تغییر نمی‌کند.
*/
initNormalRespone(response, pageOnly, filteronly) {
let listAnswer = response.data?.hits?.hits;
//در صورت خالی بودن qanon_etebar مقدار را مساوی معتبر میکنه
listAnswer.forEach((item) => {
if (!item._source.qanon_etebar || item._source.qanon_etebar === "") {
item._source.qanon_etebar = "معتبر";
}
});
if (pageOnly) {
this.$refs.content?.setAnswer(
listAnswer,
response.data.hits.total.value
);
} else if (filteronly) {
this.$refs.content?.setAnswer(
listAnswer,
response.data.hits.total.value,
response.data.hits.total.relation
);
this.$refs.filterlist?.setAnswer(response.data.aggregations);
} else {
this.$refs.content?.setAnswer(
listAnswer,
response.data.hits?.total.value,
response.data.hits?.total.relation
);
this.$refs.filterlist?.setAnswer(response.data.aggregations);
}
},
/**
* پاسخ به درخواست جستجوی مفهومی را مقداردهی می‌کند.
* @param {Object} response پاسخ دریافتی از سرویس جستجو.
* @param {boolean} pageOnly اگر صحیح باشد، تنها صفحه‌بندی بروزرسانی می‌شود و اطلاعات نمایشی تغییر نمی‌کند.
* @param {boolean} filteronly اگر صحیح باشد، تنها فیلترها بروزرسانی می‌شوند و اطلاعات نمایشی تغییر نمی‌کند.
*/
// initTermRespone(response, pageOnly, filteronly) {
// if (pageOnly) {
// this.$refs.content?.setAnswer(
// response.data.aggregations.branch.buckets,
// response.data.hits.total.value
// );
// } else if (filteronly) {
// this.$refs.content?.setAnswer(
// response.data.aggregations.branch.buckets,
// response.data.hits.total.value,
// response.data.hits.total.relation
// );
// this.$refs.filterlist?.setAnswer(response.data.aggregations);
// } else {
// this.$refs.content?.setAnswer(
// response.data.aggregations.branch.buckets,
// response.data.hits.total.value,
// response.data.hits.total.relation
// );
// response.data.aggregations.branch.buckets = [];
// this.$refs.filterlist?.setAnswer(response.data.aggregations);
// }
// },
/**
* تغییرات در لیست برچسب‌ها را اعمال می‌کند و فیلترهای مربوطه را تنظیم می‌کند.
* @param {string} tags رشته‌ای که شامل برچسب‌های مورد نظر است.
*/
listChanged(tags) {
let res = [];
tags.split(",").forEach((e) => {
let i = e.lastIndexOf("_");
if (i != -1) {
res.push(e.substring(0, i));
}
});
this.setFilterNavigate(res);
// this.$refs.topheader.setFilterNavigate(res);
},
/**
* بازنشانی مقادیر و نمایش مجدد لیست نتایج و فیلترها.
* @param {Object} list لیست دریافتی از سرویس جستجو.
*/
againsetlist(list) {
this.$refs.content?.setAnswer(
// this.lists.data.aggregations.branch.buckets,
this.lists.data.hits.hits,
this.lists.data.hits.total.value,
this.lists.data.hits.total.relation
);
this.$refs.filterlist?.setAnswer(this.lists.data.aggregations);
},
/**
* بازنشانی اطلاعات صفحه‌بندی به حالت اولیه.
*/
resetPagination() {
this.pagination = {
pages: 0,
total: 0,
page: 1,
offset: 0,
limit: this.viewMode == "table" ? 25 : 10,
};
},
/**
* بستن قسمت جستجوی پیشرفته.
*/
closeAdvancedSearch() {
this.displayAdvanceSearch = false;
this.currentPanel = null;
this.domainActiveSetter(this.searchDomain[0]);
},
/**
* نمایش یا مخفی کردن قسمت جستجوی پیشرفته بسته به وضعیت کنونی.
*/
showAdvancedSearch() {
if (this.displayAdvanceSearch) {
this.displayAdvanceSearch = false;
} else {
this.displayAdvanceSearch = true;
}
},
/**
* بررسی اینکه آیا هیچ پاسخی در نتیجه جستجو وجود دارد یا خیر.
* @returns {boolean} اگر در جستجو هیچ پاسخی وجود داشته باشد، true برگردانده می‌شود؛ در غیر این صورت false.
*/
showNoAnswer() {
if (this.searchingState) {
return this.total_answer == 0;
}
return false;
},
/**
* بررسی اینکه آیا کاربر می‌تواند یک عملیات خاص را انجام دهد یا خیر.
* @param {string} keyName نام کلید مربوطه که نشان دهنده مجوز عملیات است.
* @returns {boolean} اگر کاربر می‌تواند عملیات را انجام دهد، true برگردانده می‌شود؛ در غیر این صورت false.
*/
canSee(keyName) {
if (this.currentUser?.user_level > 1) return true;
return this.userPermisionGetter.includes(keyName);
},
/**
* تولید متن HTML برای نمایش توضیحات ابزار نشانگر براساس بخش و کلید داده شده.
* @param {string} section بخش مربوطه از توضیحات (مثلاً "search" یا "entity").
* @param {string} key کلید مربوطه به توضیحات (مثلاً "search_type" یا "search_sort").
* @param {string} id شناسه مربوط به توضیحات، اختیاری است.
* @returns {string} متن HTML نمایشی برای توضیحات ابزار نشانگر.
*/
getHtmlTooltip2(section, key, id) {
let res = "";
let link = "";
if (id) link = location.origin + "/pages/help/" + section + "/" + id;
if (section == "search") {
if (key == "search_type") {
res = `<p class="mb-2">برای یافتن بهترین پاسخ، روش جستجو را تعیین می‌کند</p>`;
} else if (key == "search_sort") {
res = `<p class="mb-2">ترتیب نمایش فهرست قبل و بعد از جستجو را تعیین می کند</p>`;
} else if (key == "search_advance") {
res = `<p class="mb-2">امکانات ویژه جهت جستجو در ویژگی های همراه متن در اختیار می گذارد </p>`;
}
}
if (section == "entity") {
}
if (res != "" && link != "")
res += `<a class="btn btn-link" target="_blank" href="${link}"> بیشتر ... </a>`;
return res;
},
},
components: {
MyContent: defineAsyncComponent(() =>
import("~/components/search/MyContent.vue")
),
FilterListSearch: defineAsyncComponent(() =>
import("~/components/search/view/FilterListSearch.vue")
),
SwitchComponent: defineAsyncComponent(() =>
import("~/components/global/SwitchComponent.vue")
),
SynonymSearch: defineAsyncComponent(() =>
import("~/components/search/forms/SynonymSearch.vue")
),
AdvancedSearch: defineAsyncComponent(() =>
import("~/components/research/components/AdvancedSearch.vue")
),
TripleSwitch: defineAsyncComponent(() =>
import("~/components/global/TripleSwitch.vue")
),
},
};
</script>