search_ui/pages/search/index.vue

2029 lines
73 KiB
Vue
Raw Normal View History

2025-02-01 11:06:10 +00:00
<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>