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

688 lines
20 KiB
Vue
Raw Permalink 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>
<div class="">
<div class="">
<div class="search-items firefox-scrollbar">
<div
class="search-items__item"
v-for="(item, i) in listAnswer"
:key="i"
>
<div class="search-items__header">
<a
v-if="item._source.main_type"
class="search-items__label text__13 text__dark-gray"
>
{{ item._source.main_type }}</a
>
<a
@click.prevent="showtext(item._source, listAnswer, i, item)"
@auxclick.prevent.stop="
showtext(item._source, listAnswer, i, item)
"
target="_blank"
class="search-items__title text__15 text__blue"
v-html="highlightKey(item, 'title')"
>
</a>
</div>
<div class="text__15 search-items__code">
<span v-if="item._source.ts_ref" style="color: #4B5567;margin-left: 10px"
><span class="text__dark-gray">مرجع تصویب :</span>
{{ item._source.ts_ref }}</span
>
<span v-if="item._source.ref_date" style="color: #4B5567;margin-left: 10px"
><span class="text__dark-gray">تاریخ در منبع :</span>
{{ item._source.ref_date }}</span
>
<span v-if="item._source.ts_date" style="color: #4B5567;margin-left: 10px"
><span class="text__dark-gray">تاریخ تصویب :</span>
{{ item._source.ts_date }}</span
>
<span v-if="item._source.eb_date" style="color: #4B5567;margin-left: 10px"
><span class="text__dark-gray">تاریخ ابلاغ :</span>
{{ item._source.eb_date }}</span
>
</div>
<div
v-html="highlightKey(item, 'content')"
class="search-items__detail text__15 line-clamp__2"
></div>
<div
v-if="item._source.exceuter_organs?.length"
class="search-items__content"
>
<div class="text__15 line-clamp__2">
<span style="margin-left: 10px">مجریان : </span>
<span class="text__dark-gray">{{ textExceuter(item) }} </span>
</div>
</div>
<div
v-if="item._source.receiver_organs?.length"
class="search-items__content"
>
<div class="text__15 line-clamp__2">
<span style="margin-left: 10px">گیرندگان : </span>
<span class="text__dark-gray">{{ textReceiver(item) }} </span>
</div>
</div>
<div class="search-items__content">
<div
v-if="item._source.tags?.length"
class="text__15 line-clamp__2"
>
<span style="margin-left: 10px">برچسب : </span>
<span class="text__dark-gray">{{ textTags(item) }} </span>
</div>
</div>
<div class="search-items__content">
<div
v-if="item._source.categories?.length"
class="text__15 line-clamp__2"
>
<span style="margin-left: 10px">دسته‌ها : </span>
<span class="text__dark-gray">{{ textCategories(item) }} </span>
</div>
</div>
<!-- <div v-if="showActionMenu" class="search-item__actions"> -->
<div class="search-item__actions" v-if="!isMajlesBuild">
<span class="tavasi tavasi-more-vert"></span>
<button
v-can="'favorite_create'"
@click.pevent="AddToFavorites(item, i)"
title="علاقه مندی ها"
class="btn show-detail-btn favorites"
type="button"
>
<svg
class="icon"
:class="
item._source.tbookmark == 1
? 'icon-bookmark-1'
: 'icon-bookmark-4'
"
>
<use
:xlink:href="
item._source.tbookmark == 1
? '#icon-bookmark-1'
: '#icon-bookmark-4'
"
></use>
</svg>
</button>
<!-- <button
v-can="'search_analyze'"
@click="showDetails(item)"
title="نمایش جزییات"
class="btn show-detail-btn"
type="button"
>
<span class="tavasi tavasi-eye"></span>
</button> -->
<button
v-can="'search_summary'"
@click="changeCurrent(i)"
title="مشخصات"
class="btn show-detail-btn -rotate-180"
type="button"
>
<span class="tavasi tavasi-Component-71--1"></span>
</button>
<button-component
title=" کپی لینک"
buttonText=""
class="btn show-detail-btn px-1"
@click="copyToClipboard('', urlResolver(item._id))"
>
<svg class="icon icon-copy2 fz-8">
<use xlink:href="#icon-copy2"></use>
</svg>
</button-component>
</div>
</div>
</div>
<jahat-pagination
style="font-size: 13px"
v-if="pag.total"
:paginationInfo="pag"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
</jahat-pagination>
</div>
</div>
</template>
<script>
import searchApis from "~/apis/searchApi";
/**
* @vue-prop {Array} [summeryKeys=] - کلیدهای خلاصه
* @vue-prop {Object} [pagination=] - صفحه بندی
*
* @vue-data {undefined} httpService - سرویس HTTP برای درخواست‌های شبکه‌ای (ممکن است تعریف نشده باشد).
* @vue-data {Object} pag - پیکربندی صفحه‌بندی.
* @vue-data {Array} listAnswer - آرایه‌ای برای ذخیره لیست پاسخ‌ها.
* @vue-data {Array} listPage - آرایه‌ای برای ذخیره شماره صفحات.
* @vue-data {number} totalCount - تعداد کل آیتم‌ها.
* @vue-data {number} countInPage - تعداد آیتم‌ها در هر صفحه.
* @vue-data {number} maxPage - حداکثر تعداد صفحات.
* @vue-data {number} currentPage - شماره صفحه فعلی.
* @vue-data {number} beginPage - شماره صفحه شروع.
* @vue-data {number} endPage - شماره صفحه پایان.
* @vue-data {number} maxLength - حداکثر طول مجاز.
* @vue-data {string} typeCount - رشته‌ای که نوع شمارش را نشان می‌دهد.
* @vue-data {string} textSearch - متن جستجو.
* @vue-data {Object} sorting - تنظیمات مرتب‌سازی.
* @vue-data {string} sorting.sortby - فیلدی که بر اساس آن مرتب‌سازی انجام می‌شود.
* @vue-data {string|undefined} sorting.sortorder - ترتیب مرتب‌سازی (صعودی، نزولی یا هیچ).
* @vue-data {Array} [currentItem = []] - آیتم فعلی.
*
* @vue-computed {Object} [mapState.userPermisionGetter] - دریافت مجوزهای کاربر
* @vue-computed {Object} [mapState.currentUser] - کاربر فعلی
* @vue-computed {Object} [mapState.searchActiveTabGetter] - دریافت تب فعال جستجو
* @vue-computed {Boolean} [showActionMenu] - نمایش منوی اقدام
*
* @vue-event {Function} mapActions.SET_LIST_ENTITY - تنظیم لیست انتیتی
* @vue-event {Function} mapActions.SET_ITEM_ENTITY - تنظیم ایتم انتیتی
*/
import favoriteApi from "~/apis/favoriteApi";
import { mapState, mapActions } from "pinia";
export default {
props: ["summeryKeys", "pagination"],
name: "MajlesQavaninContent",
data() {
return {
httpService: undefined,
pag: this.pagination,
listAnswer: [],
listPage: [],
totalCount: 0,
countInPage: 0,
maxPage: 0,
currentPage: 1,
beginPage: 1,
endPage: 1,
maxLength: 250,
typeCount: "",
textSearch: "",
sorting: {
sortby: "created",
sortorder: undefined, // asc | desc | none
},
// بلا استفاده ها
// navigationOptions: [],
// selectedItem: undefined,
// iscode: true,
// showModal: false,
// listId: undefined,
// projectId: undefined,
};
},
beforeMount() {
this.httpService = new HttpService(import.meta.env.VITE_REPO_BASE_URL);
},
computed: {
...mapState([
"userPermisionGetter",
"currentUser",
"selectedlists",
]),
...mapState(useSearchStore,[
"searchActiveTabGetter",
]),
showActionMenu() {
let show = false;
if (this.userPermisionGetter?.length)
["search_analyze", "search_summary"].forEach(
(item) =>
(show =
this.currentUser.user_level > 1 ||
this.userPermisionGetter.includes(item))
);
return show;
},
},
mounted() {
window.scrollTo(0, 0);
if (this.$route.query.q) this.searchText = this.$route.query.q;
},
methods: {
...mapActions("entity", ["SET_ITEM_ENTITY", "SET_LIST_ENTITY"]),
/**
* اضافه کردن به علاقه‌مندی‌ها
* @param {Object} item - آیتم
* @param {Number} index - اندیس
*/
AddToFavorites(item, index) {
if (item._source.tbookmark == 0) {
let url = favoriteApi.favorite.add;
url = url.replace("{{data_type}}", "bookmark");
url = url.replace("{{ref_key}}", this.searchActiveTabGetter.key);
const formData = {
ref_id: item._id,
title: item._source.title,
};
this.httpService.postRequest(url, formData).then((res) => {
// this.UpdateList();
//refresh After removing or adding favorites
//this.$emit("UpdateList", item.tbookmark);
this.updateListAnswer(index, "tbookmark", 1);
});
} else {
let url = favoriteApi.favorite.deleteByRefid;
url = url.replace("{{data_type}}", "bookmark");
url = url.replace("{{index_key}}", this.searchActiveTabGetter.key);
url = url.replace("{{ref_id}}", item._id);
const formData = {
ref_id: item._id,
title: item._source.title,
};
this.httpService.postRequest(url, formData).then((res) => {
//refresh After removing or adding favorites
//this.$emit("UpdateList", item.tbookmark);
this.updateListAnswer(index, "tbookmark", 0);
});
}
},
/**
* بروزرسانی لیست پاسخ‌ها
* @param {Number} index - اندیس
* @param {String} key - کلید
* @param {Number} value - مقدار
*/
updateListAnswer(index, key, value) {
if (index in this.listAnswer) {
if (key in this.listAnswer[index]["_source"])
this.listAnswer[index]["_source"][key] = value;
}
},
/**
* تبدیل به تاریخ شمسی
* @param {String} item - آیتم ورودی
* @returns {String} تاریخ شمسی
*/
datefa(item) {
var m = item;
var d = new Date(m).toLocaleDateString("fa-IR");
return d;
},
/**
* برجسته‌سازی یک کلید خاص.
* @param {Object} item - مورد برای برجسته‌سازی.
* @param {String} key - کلید برای برجسته‌سازی.
* @returns {String} متن برجسته‌شده.
*/
highlightKey(item, key) {
var text = "";
if (item.highlight) {
if (item.highlight[key])
if (Array.isArray(item.highlight[key]))
text = item.highlight[key].join("... ");
else text = item.highlight[key];
}
if (text == "") {
text = item._source[key];
if (text.length > this.maxLength) text = text.substr(0, this.maxLength);
}
return text;
},
/**
* برجسته‌سازی متن محتوای یک مورد.
* @param {Object} item - مورد برای برجسته‌سازی.
* @returns {String} متن برجسته‌شده.
*/
highlightText(item) {
var text = "";
if (item.highlight) {
if (item.highlight.content) text = item.highlight.content.join("... ");
}
text = item._source.content;
if (text.length > this.maxLength) text = text.substr(0, this.maxLength);
return text;
},
urlResolver(_id) {
const routeData = this.$router.resolve({
name: "navigationView",
params: {
id: _id,
key: this.searchActiveTabGetter.key,
},
query: {},
});
return routeData.href;
},
showtext(item, listAnswer, i, t) {
let cloneList = structuredClone(listAnswer);
cloneList.forEach((item, index) => {
cloneList[index] = { ...item, ...item._source };
});
let items = t._id;
let cloneItem = structuredClone(item);
cloneItem = { ...item, _id: items };
this.SET_ITEM_ENTITY(cloneItem);
this.SET_LIST_ENTITY(cloneList);
localStorage.setItem("myList", JSON.stringify(cloneList));
localStorage.setItem("myItem", JSON.stringify(cloneItem));
const domainName = buildName() + "";
let _name = "navigation";
const routeData = this.$router.resolve({
name: _name,
params: {
id: cloneItem._id,
key: this.searchActiveTabGetter.key,
},
query: {
searchtext: this.textSearch ?? undefined,
},
});
window.open(routeData.href, "_blank");
},
setAnswer: function (list, count = -1, _typeCount = "") {
if (count != -1) {
this.totalCount = count;
this.typeCount = _typeCount == "eq" ? "مساوی با " : "بیشتر از ";
this.maxPage =
this.totalCount == 0
? 0
: Math.floor(this.totalCount / this.countInPage) + 1;
this.currentPage = 1;
this.beginPage = 2;
this.endPage = this.beginPage + 3;
if (this.endPage > this.maxPage - 1) {
this.endPage = this.maxPage - 1;
if (this.beginPage > 2) this.beginPage = this.beginPage - 1;
}
this.updateListPage();
}
const total = count;
const pages = Math.ceil(total / this.pag.limit);
const pagination = {
total: total,
pages: pages == 0 ? 1 : pages,
};
this.pag = { ...this.pagination, ...pagination };
this.listAnswer = list;
this.scrollToTop();
localStorage.setItem("answer", JSON.stringify(this.listAnswer));
},
updateListPage: function () {
this.listPage = [];
for (let i = this.endPage; i >= this.beginPage; i--) {
this.listPage.push(i);
}
setTimeout(() => {
this.scrollToTop();
}, 700);
},
nextPage: function (item) {
if (item > 0) this.setPage(this.currentPage + 1);
else this.setPage(this.currentPage - 1);
},
setPage: function (item) {
if (item == -1) {
// begin ...
item = 3;
this.beginPage = 2;
this.endPage = 5;
} else if (item == -2) {
// end ...
item = this.maxPage - 3;
this.beginPage = this.maxPage - 5;
this.endPage = this.maxPage - 1;
} else if (item == this.beginPage) {
this.beginPage--;
if (this.beginPage > 5) {
this.beginPage--;
this.endPage--;
} else {
this.beginPage = 2;
this.endPage = 5;
}
} else if (item == this.endPage) {
if (this.endPage < this.maxPage - 5) {
this.endPage++;
this.beginPage++;
} else {
this.beginPage = this.maxPage - 5;
this.endPage = this.maxPage - 1;
}
}
this.updateListPage();
this.currentPage = item;
this.$emit("changePage", item - 1);
},
changeCurrent: function (i) {
this.$emit("changeCurrent", this.listAnswer[i]);
},
setTextSearch(item, countInPage) {
this.textSearch = item;
this.countInPage = countInPage;
},
scrollToTop() {
window.scrollTo(0, 0);
},
textCategories(item) {
let text = "";
if (item._source.categories) {
if (Array.isArray(item._source.categories))
text = item._source.categories.join("، ");
else text = item._source.categories;
}
return text;
},
textTags(item) {
let text = "";
if (item._source.tags) {
if (Array.isArray(item._source.tags))
text = item._source.tags.join("، ");
else text = item._source.tags;
}
return text;
},
textExceuter(item) {
let text = "";
if (item._source.exceuter_organs)
item._source.exceuter_organs.forEach((element) => {
text += element.title + ",";
});
return text;
},
textReceiver(item) {
let text = "";
if (item._source.receiver_organs)
item._source.receiver_organs.forEach((element) => {
text += element.title + ",";
});
return text;
},
//mehdi
pageLimitChanged(paging) {
this.resetPagination();
this.pag.limit = paging.limit;
this.$emit("changePage", this.pag);
},
pageChanged(paging) {
let page = paging.pageNumber;
page -= 1;
this.pag.offset = page * paging.limit;
this.pag.limit = paging.limit;
this.pag.page = paging.pageNumber;
this.$emit("changePage", this.pag);
},
sortChanged(sorting) {
this.pag.page = this.pag.offset = 0;
this.sorting = sorting;
this.$emit("changePage", this.sorting);
},
resetPagination() {
this.pag = {
pages: 0,
total: 0,
page: 1,
offset: 0,
limit: 10,
};
},
getList(_entityType) {
if (this.fetchingData) return;
this.fetchingData = true;
this.entity_type = _entityType;
let url =
searchApi.Farhanghestan.search_normal +
`/${this.pag.offset}/${this.pag.limit}`;
this.httpService.getRequest(url).then((res) => {
this.listEntity = res.hits.hits;
const total = res.hits.total.value;
const pages = Math.ceil(total / this.pag.limit);
const pagination = {
total: total,
pages: pages == 0 ? 1 : pages,
};
this.pag = { ...this.pagination, ...pagination };
this.fetchingData = false;
});
},
},
};
</script>
<style lang="scss" scoped>
.main_page {
right: 23rem;
}
.detail-page__tab-content {
margin-right: 0 !important;
position: relative;
&.serve-majles {
width: 100%;
}
}
// .search-items {
//height: calc(100vh - 17em);
// border-left: 1px solid #f2f2e6;
// }
.search-items__item {
position: relative;
padding: 1em;
overflow: hidden;
&:not(:last-child) {
margin-bottom: 30px;
}
&:hover,
&.active {
background-color: var(--list-background-color);
.search-item__actions {
// width: 6.5em;
width: auto;
transition: width 0.5s;
background: #fff;
border-radius: 0 0.5em 0.5em 0;
.tavasi-more-vert {
transition: all 0.2s;
display: none;
}
}
}
}
.search-item__actions {
position: absolute;
left: 0;
width: 1.6em;
top: 1em;
// overflow: hidden;
transition: all 0.5s;
display: flex;
align-items: center;
.btn {
display: flex;
align-items: center;
justify-content: center;
padding: 0.175rem 0.35rem;
&:hover {
filter: brightness(0.7);
}
.tavasi,
.icon-copy2 {
color: #929497;
}
.icon-copy2 {
font-size: 0.8rem;
}
&.favorites {
color: calc(--primary-color);
.icon-bookmark-1,
.icon-bookmark-4 {
height: 1.3em;
}
}
}
}
.detail-page__content {
// top: 35px !important;
}
// @media only screen and (min-width: 576px) and (max-width: 767.98px) {
// .detail-page__content {
// top: 170px !important;
// }
// }
// @media (max-width: 575.98px) {
// .detail-page__content {
// top: 170px !important;
// }
// }
@media (max-width: 575.98px) {
}
@media only screen and (min-width: 576px) and (max-width: 767.98px) {
}
@media only screen and (min-width: 768px) and (max-width: 900.98px) {
}
@media only screen and (min-width: 901px) and (max-width: 1049.98px) {
}
@media (min-width: 1050px) {
}
</style>