search_ui/components/search/view/SearchAdvancedSearch.vue
2025-02-01 14:36:10 +03:30

267 lines
8.1 KiB
Vue

<template>
<div class="advanced-search firefox-scrollbar">
<div class="container-fluid">
<div class="row">
<div class="col-12">
<form>
<div class="d-flex justify-content-between align-items-center header-advanced">
<h6 class="label-search">جست و جوی پیشرفته</h6>
<svg
title="بستن"
@click.prevent="closeAdvancedSearch"
class="icon icon-Component-21--1"
>
<use xlink:href="#icon-Component-21--1"></use>
</svg>
</div>
<component
v-for="(formElement, index) in localFormElements"
:key="index"
:formElement="getValueToFormElement(formElement)"
:inputClass="formElement.inputClass"
:labelClass="formElement.labelClass"
:is="returnComponentName(formElement.type)"
@tribute-on-search="remoteSearch"
@oninput="createQuery($event, index)"
class="inside-advanced-search"
></component>
<div class="d-flex justify-content-end align-items-baseline">
<!-- <div class="bottom-close-form ms-3">
<a @click.prevent="closeAdvancedSearch">بستن</a>
</div> -->
<div class="bottom-save-form flex-grow-1">
<button
type="submit"
class="btn advanced-bottom btn-primary w-100 h-20"
@click.prevent="searchStart()"
>
جستجو
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapState } from "pinia";
/**
*
* @vue-data {Object} listUpdatedText - متغیر برای نگه‌داری متن‌های به‌روزرسانی شده
* @vue-data {Array} localFormElements - آرایه‌ای از المان‌های فرم محلی
* @vue-data {String} value - مقدار فعلی
*
* @vue-computed {Object} [mapState.searchActiveTabGetter] - دریافت تب جستجو فعال
*/
export default {
data() {
return {
listUpdatedText: {},
localFormElements: [],
value: "",
};
},
computed: {
...mapState(useSearchStore, ["searchActiveTabGetter"]),
},
watch: {
searchActiveTabGetter: {
handler: function (newSchema) {
if (newSchema.advance)
this.localFormElements = structuredClone(newSchema.advance);
},
// deep: true,
immediate: true,
},
},
beforeMount() {
this.httpService = new HttpService(import.meta.env.VITE_BASE_URL);
},
mounted() {
this.localFormElements = structuredClone(
this.searchActiveTabGetter.advance
);
},
methods: {
/**
* بستن جستجوی پیشرفته.
*/
closeAdvancedSearch() {
this.$emit("closeAdvancedSearch");
},
/**
* جستجوی از راه دور.
* @param {Object} param0 - متغیرهای جستجو از راه دور
* @param {string} param0.text - متن جستجو
* @param {Function} param0.cb - بازگشت به تابع پس از دریافت نتایج
* @param {Object} param0.item - مورد جستجو
*/
remoteSearch({ text, cb, item }) {
// for clearing the query when user remove by keyboard backspace.
if (text == "") this.makeSearchParams(undefined, 1);
let url = item.completion;
text = text.trim();
url = url.replace("{{key}}", this.searchActiveTabGetter.key);
if (text == "") url = url.replace("/{{query}}", "");
else url = url.replace("{{query}}", text);
this.httpService.getRequest(url).then((response) => {
cb(response.data);
});
},
/**
* دریافت مقدار به عناصر فرم.
* @param {Object} elements - عناصر فرم
*/
getValueToFormElement(elements) {
Object.keys(elements).forEach((key, index) => {
elements["value"] = this.searchActiveTabGetter[elements.key];
});
return elements;
},
/**
* ذخیره مقدار مؤلفه.
* @param {*} value - مقدار
* @param {Object} formElement - مؤلفه فرم
*/
saveComponentValue(value, formElement) {
// در صورت تغییر نگهداری می شود تا وقتی کلید ثبت زد، ذخیره شود
if (this.searchActiveTabGetter[formElement.key] != value) {
this.listUpdatedText[formElement.key] = value;
}
},
/**
* بازگشت به نام مؤلفه براساس نوع.
* @param {string} type - نوع مؤلفه
* @returns {string} - نام مؤلفه
*/
returnComponentName(type) {
// if(!this.isEditable(searchActiveTabGetter?.key))
// return "LabelComponent";
if (type == "select") return "SelectComponent";
else if (type == "range_date") return "RangeDateComponent";
else if (type == "completion") return "TributeComponent";
else return "InputComponent";
},
// این لازم نیست ، در جستجوی پیشرفته استفاه نداره !!!!
// saveProperty() {
// let id = this.$route.params.id;
// let key = this.$route.params.key;
// let formData = {
// id: id,
// meta: JSON.stringify(this.listUpdatedText),
// };
// // let url = `monir/search/sanad/update/byid`;
// let url = "/public/{{index_key}}/update/{{id}}";
// url = url.replace("{{index_key}}", key).replace("{{id}}", id);
// this.httpService.postRequest(url, formData).then((res) => {
// this.getServerItem();
// });
// },
/**
* ایجاد کوئری.
* @param {*} evt - رویداد
* @param {number} index - اندیس
*/
createQuery(evt, index) {
// evt.target.value => from input component.
//evt => from datetime component.
let value = evt?.target?.value ?? evt;
this.$emit("set-query-advanced", this.makeSearchParams(value, index));
},
/**
* ایجاد پارامترهای جستجو.
* @param {*} value - مقدار
* @param {number} index - اندیس
* @returns {string} - پارامترهای جستجو
*/
makeSearchParams(value, index) {
if (value != undefined) this.localFormElements[index].value = value;
else this.localFormElements[index].value = undefined;
let query = "";
this.localFormElements.forEach((item, rowIndex, array) => {
if (item.value?.length)
query += "#" + item.tag + " " + item.value + " ";
});
return query;
},
/**
* شروع جستجو.
*/
searchStart() {
this.$emit("searchStart", this.searchStartValue());
this.closeAdvancedSearch();
},
/**
* دریافت مقدار شروع جستجو.
* @returns {string} - مقدار شروع جستجو
*/
searchStartValue() {
let query = "";
this.localFormElements.forEach((item, rowIndex, array) => {
if (item.value?.length)
query += "#" + item.tag + " " + item.value + " ";
});
return myEncodeQuery(query);
},
/**
* رمزنگاری متن برای جستجوی پیشرفته.
* @param {string} text - متن
* @returns {string} - متن رمزنگاری شده
*/
myEncodeQuery(text) {
let ch1 = encodeURIComponent("#");
let ch2 = encodeURIComponent("/");
let ch3 = encodeURIComponent("\\");
// let ch4 = encodeURIComponent(".");
text = text.replaceAll("#", ch1);
text = text.replaceAll("/", "\\");
text = text.replaceAll("\\", ch3);
// text = text.replaceAll(".", '%2E');
return text;
},
},
};
</script>
<style lang="scss" scoped>
.label-search {
font-family: sahel-semi-bold;
color:rgb(0, 0, 0);
}
.header-advanced {
border-bottom: 1px solid var(--primary-color);
margin-bottom: 1em;
padding: 0.5em;
}
.icon-Component-21--1 {
cursor: pointer;
font-size: 1.2rem;
&:hover {
color: var(--primary-color);
}
}
.advanced-bottom {
height: 2.6em;
margin-top: 2em;
}
</style>