hadith_ui/components/hadith/SearchTopHeader.vue

901 lines
27 KiB
Vue
Raw Permalink Normal View History

2025-02-11 10:17:22 +00:00
<template>
<div class="my-content">
<template v-if="viewMode == 'list'">
<div class="row">
<div class="col-12 main-content firefox-scrollbar">
<template v-if="items.length">
<div
class="mb-3 border-bottom main-content-item p-3"
v-for="(itemData, i) in items"
:key="i"
>
<template v-if="itemData.inner_hits">
<div
class="row"
v-for="(collapseItem, indexCollapse) in schemaItems
.collapse_items?.items || []"
:key="indexCollapse"
>
<template v-if="collapseItem.array_key">
<div
class="col-12"
v-for="(subItemData, s) in getArrayData(
itemData,
collapseItem
)"
>
<lineContent
:lineSchema="collapseItem"
:itemData="subItemData"
:arrayItemData="items"
:textSearch="textSearch"
>
</lineContent>
</div>
</template>
<template v-else>
<lineContent
:lineSchema="collapseItem"
:itemData="itemData"
:arrayItemData="items"
:textSearch="textSearch"
>
</lineContent>
</template>
</div>
</template>
<template v-else>
<div
v-if="schemaItems && schemaItems.items"
class="row"
v-for="(lineSchema, index) in schemaItems?.items || []"
:key="index"
>
<lineContent
:lineSchema="lineSchema"
:itemData="itemData"
:arrayItemData="items"
:textSearch="textSearch"
@openPrevent="openPrevent"
>
</lineContent>
</div>
</template>
<div
class="search-item__actions"
v-if="schemaItems.actions?.length"
>
<span class="tavasi tavasi-more-vert"></span>
<template v-for="(schema, indexIcon) in schemaItems.actions">
<button
:key="'action' + indexIcon"
v-if="schema.key != 'tbookmark' || isRealUser"
:title="schema.title"
class="btn"
:type="schema.type"
>
<svg
v-if="schema.key == 'tbookmark'"
@click.pevent="AddToFavorites(itemData, schema, i)"
class=""
:class="
itemData._source[schema.key] == 1
? 'icon icon-' + schema.toggle_icons.icon1
: 'icon icon-' + schema.toggle_icons.icon2
"
>
<use
:xlink:href="
itemData._source[schema.key] == 1
? '#icon-' + schema.toggle_icons.icon1
: '#icon-' + schema.toggle_icons.icon2
"
></use>
</svg>
<svg
@click="handlerActionsList(itemData, schema.key, schema)"
v-else
:class="'icon icon-' + schema.icon"
>
<use :xlink:href="'#icon-' + schema.icon"></use>
</svg>
</button>
</template>
</div>
</div>
</template>
<template v-else>
<table-no-data> </table-no-data>
</template>
</div>
</div>
<div class="">
<jahat-pagination
class="border-0 w-100"
v-if="page.total"
:paginationInfo="page"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
</jahat-pagination>
</div>
</template>
<template v-if="viewMode == 'table'">
<div class="row">
<div class="col-12 px-0">
<my-table
:key="reRender"
:height="'calc(-16em + 100vh)'"
:items="items"
:tableColumns="tableColumns"
:tableActions="tableActions"
:paginationInfo="page"
:sortingInfo="sorting"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@show-details="showDetailsHandler"
@copy-link="copyLinkHandler"
@on-linked-title-click="onOnLinkedTitleClick"
@show-text="showTextPage"
@actions="handlerActions"
:showHeaderSortButton="false"
class="my-table px-0 my-content-table"
>
</my-table>
</div>
</div>
</template>
<template v-if="viewMode == 'three-column-card'">
<div class="row">
<div class="col-12 main-content firefox-scrollbar">
<div class="row" v-if="items.length">
<div
class="mb-3 main-content-item p-3 col-4"
v-for="(itemData, i) in items"
:key="i"
>
<div class="d-flex">
<img
class="img-fluid mx-auto w-50"
src="assets/common/img/default.svg"
alt=""
/>
</div>
<template v-if="itemData.inner_hits">
<div
class="row"
v-for="(collapseItem, indexCollapse) in schemaItems
.collapse_items?.items || []"
:key="indexCollapse"
>
<template v-if="collapseItem.array_key">
<div
class="col-3"
v-for="(subItemData, s) in getArrayData(
itemData,
collapseItem
)"
>
<lineContent
:lineSchema="collapseItem"
:itemData="subItemData"
:arrayItemData="items"
:textSearch="textSearch"
>
</lineContent>
</div>
</template>
<template v-else>
<lineContent
:lineSchema="collapseItem"
:itemData="itemData"
:arrayItemData="items"
:textSearch="textSearch"
>
</lineContent>
</template>
</div>
</template>
<template v-else>
<div
v-if="schemaItems && schemaItems.items"
class="row"
v-for="(lineSchema, index) in schemaItems?.items || []"
:key="index"
>
<lineContent
:lineSchema="lineSchema"
:itemData="itemData"
:arrayItemData="items"
:textSearch="textSearch"
@openPrevent="openPrevent"
>
</lineContent>
</div>
</template>
<div class="search-item__actions" v-if="schemaItems.actions">
<span class="tavasi tavasi-more-vert"></span>
<button
:key="'action' + indexIcon"
v-for="(schema, indexIcon) in schemaItems.actions"
v-if="schema.key != 'tbookmark' || isRealUser"
:title="schema.title"
class="btn"
:type="schema.type"
>
<svg
v-if="schema.key == 'tbookmark'"
@click.pevent="AddToFavorites(itemData, schema, i)"
class=""
:class="
itemData._source[schema.key] == 1
? 'icon icon-' + schema.toggle_icons.icon1
: 'icon icon-' + schema.toggle_icons.icon2
"
>
<use
:xlink:href="
itemData._source[schema.key] == 1
? '#icon-' + schema.toggle_icons.icon1
: '#icon-' + schema.toggle_icons.icon2
"
></use>
</svg>
<svg
@click="handlerActionsList(itemData, schema.key, schema)"
v-else
:class="'icon icon-' + schema.icon"
>
<use :xlink:href="'#icon-' + schema.icon"></use>
</svg>
</button>
</div>
</div>
</div>
<template v-else>
<table-no-data> </table-no-data>
</template>
</div>
</div>
<div class="">
<jahat-pagination
class="border-0 w-100"
v-if="page.total"
:paginationInfo="page"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
</jahat-pagination>
</div>
</template>
<template v-if="viewMode == 'two-column-card'">
<div class="row">
<div class="col-6 main-content firefox-scrollbar">
<template v-if="items.length">
<div
class="mb-3 border-bottom main-content-item p-3"
v-for="(itemData, i) in items"
:key="i"
>
<template v-if="itemData.inner_hits">
<div
class="row"
v-for="(collapseItem, indexCollapse) in schemaItems
.collapse_items?.items || []"
:key="indexCollapse"
>
<template v-if="collapseItem.array_key">
<div
class="col-12"
v-for="(subItemData, s) in getArrayData(
itemData,
collapseItem
)"
>
<lineContent
:lineSchema="collapseItem"
:itemData="subItemData"
:arrayItemData="items"
:textSearch="textSearch"
>
</lineContent>
</div>
</template>
<template v-else>
<lineContent
:lineSchema="collapseItem"
:itemData="itemData"
:arrayItemData="items"
:textSearch="textSearch"
>
</lineContent>
</template>
</div>
</template>
<template v-else>
<div
v-if="schemaItems && schemaItems.items"
class="row"
v-for="(lineSchema, index) in schemaItems?.items || []"
:key="index"
>
<lineContent
:lineSchema="lineSchema"
:itemData="itemData"
:arrayItemData="items"
:textSearch="textSearch"
@openPrevent="openPrevent"
>
</lineContent>
</div>
</template>
<div class="search-item__actions" v-if="schemaItems.actions">
<span class="tavasi tavasi-more-vert"></span>
<button
:key="'action' + indexIcon"
v-for="(schema, indexIcon) in schemaItems.actions"
v-if="schema.key != 'tbookmark' || isRealUser"
:title="schema.title"
class="btn"
:type="schema.type"
>
<svg
v-if="schema.key == 'tbookmark'"
@click.pevent="AddToFavorites(itemData, schema, i)"
class=""
:class="
itemData._source[schema.key] == 1
? 'icon icon-' + schema.toggle_icons.icon1
: 'icon icon-' + schema.toggle_icons.icon2
"
>
<use
:xlink:href="
itemData._source[schema.key] == 1
? '#icon-' + schema.toggle_icons.icon1
: '#icon-' + schema.toggle_icons.icon2
"
></use>
</svg>
<svg
@click="handlerActionsList(itemData, schema.key, schema)"
v-else
:class="'icon icon-' + schema.icon"
>
<use :xlink:href="'#icon-' + schema.icon"></use>
</svg>
</button>
</div>
</div>
</template>
<template v-else>
<table-no-data> </table-no-data>
</template>
</div>
</div>
<div class="">
<jahat-pagination
class="border-0 w-100"
v-if="page.total"
:paginationInfo="page"
@page-changed="pageChanged"
@page-limit-changed="pageLimitChanged"
@sort-changed="sortChanged"
>
</jahat-pagination>
</div>
</template>
</div>
</template>
<script>
// import HttpService from "@services/httpService";
// import tableActions from "@search/json/listTableContextMenu";
import favoriteApi from "~/apis/favoriteApi";
import researchApi from "~/apis/researchApi";
import { mapState, mapActions } from "pinia";
import { useSearchStore } from "~/stores/searchStore";
import { useEntityStore } from "@search/stores/entityStore";
import { useAuthStore } from "~/stores/authStore";
export default {
props: {
schemaItems: {
default() {
return [];
},
},
viewMode: {
default: "table",
},
items: {
default() {
return [];
},
},
pagination: {
default() {
return {};
},
},
tableColumns: {
default() {
return [];
},
},
tableActions: {
default() {
return [];
},
},
textSearch: {
default: "",
},
},
beforeMount() {
// this.httpService = new HttpService(process.env.VUE_APP_REPO_BASE_URL);
if (this.items) {
this.items.forEach((item) => {
if (
!item._source.qanon_etebar ||
item._source.qanon_etebar.trim() == ""
) {
item._source.qanon_etebar = "معتبر";
}
});
}
},
mounted() {
this.page = this.pagination;
this.setTableColumns();
},
watch: {
pagination(newVal) {
this.page = newVal;
},
},
data() {
return {
page: "",
curTableColumns: this.tableColumns,
// tableActions: tableActions,
reRender: 1,
sorting: {
sortby: "created",
sortorder: undefined, // asc | desc | none
},
};
},
computed: {
...mapState(useSearchStore, ["searchActiveTabGetter"]),
...mapState(useAuthStore, ["isRealUser"]),
},
methods: {
...mapActions(useEntityStore, ["SET_ITEM_ENTITY", "SET_LIST_ENTITY"]),
openPrevent(item, isReadonly = true) {
this.$emit("ModalHandler", { item, isReadonly });
},
handlerActions(event) {
let key = event.rowAction.key;
if (key == "summary") this.$emit("changeCurrent", event.item);
else if (key == "copy") {
this.copyToClipboard(
"",
this.urlResolver(
event.item._id,
event.rowAction.link_route,
event.item
)
);
} else if (key == "tbookmark") {
this.AddToFavorites(event.item, event.rowAction, event.index);
}
},
setTableColumns() {
if (this.tableColumns.length) this.curTableColumns = this.tableColumns;
else if (this.domainActiveGetter?.table_columns)
this.curTableColumns = this.domainActiveGetter?.table_columns;
},
async AddToFavorites(item, icon, index) {
let sourceData = item;
icon.api_items.title.split(".").forEach((key) => {
if (sourceData[key]) sourceData = sourceData[key];
});
if (item._source.tbookmark == 0) {
let url = favoriteApi.favorite.add;
url = url.replace("{{data_type}}", icon.api_items.data_type);
url = url.replace("{{ref_key}}", icon.api_items.ref_key);
const formData = {
ref_id: item[icon.api_items.id],
title: sourceData,
};
try {
const { $api } = useNuxtApp();
const res = await $api(url, {
baseURL: import.meta.env.VITE_REPO_BASE_URL,
body: formData,
method: "post",
});
this.updateListAnswer(index, "tbookmark", 1);
} catch (err) {}
// this.httpService.postRequest(url, formData).then((res) => {
// this.updateListAnswer(index, "tbookmark", 1);
// });
} else {
// let url = favoriteApi.favorite.delete;
let url = favoriteApi.favorite.deleteByRefid;
url = url.replace("{{data_type}}", icon.api_items.data_type);
// url = url.replace("{{id}}", item[icon.api_items.id]);
url = url.replace("{{index_key}}", this.searchActiveTabGetter?.key);
url = url.replace("{{ref_id}}", item[icon.api_items.id]);
[];
const formData = {
ref_id: item[icon.api_items.id],
title: sourceData,
};
try {
const { $api } = useNuxtApp();
const res = await $api(url, {
baseURL: import.meta.env.VITE_REPO_BASE_URL,
body: formData,
method: "post",
});
this.updateListAnswer(index, "tbookmark", 0);
} catch (err) {}
// this.httpService.postRequest(url, formData).then((res) => {
// this.updateListAnswer(index, "tbookmark", 0);
// });
}
},
updateListAnswer(index, key, value) {
if (index in this.items) {
if (key in this.items[index]["_source"])
this.items[index]["_source"][key] = value;
this.reRender++;
}
},
handlerActionsList(item, key, icon) {
if (key == "summary") this.$emit("changeCurrent", item);
else if (key == "copy") {
let keyid = icon.link_route.id;
let id = "";
id = this.findvalueForKey(item, keyid);
this.copyToClipboard("", this.urlResolver(id, icon.link_route, item));
} else if (key == "SubjectForm") {
this.$emit("SubjectForm", item);
} else if (key == "edit") {
this.openPrevent({ item }, false);
} else if (key == "delete") {
this.deleteResearch(item, false);
}
},
urlResolver(_id, route, item) {
let keyMain = "";
let query_key = "";
let query_value = "";
let keys = "";
let key = "";
let query = { searchtext: this.textSearch ?? undefined };
if (route?.query) {
let querys = route.query;
if (typeof querys === "string") {
keys = route?.query.split("=");
if (keys.length >= 2) {
query_key = keys[0];
query_value = keys[1];
}
if (query_key && query_value) {
query[query_key] = query_value; // کلید پویا و مقدار از قسمت بالایی
}
} else {
let newObject = {};
for (const [key, value] of Object.entries(querys)) {
if (value in item) {
newObject[key] = item[value];
} else {
newObject[key] = item?._source[value];
}
}
Object.assign(query, newObject);
}
}
if (route?.key_item || route.key) {
if (route?.key_item) key = this.getSourceData(item, route.key_item);
else key = route.key;
}
const routeData = this.$router.resolve({
path: "/search/show",
params: {
id: _id,
key: key,
},
query: query,
});
return routeData.href;
},
getSourceData(itemData, key) {
let sourceData = itemData;
key.split(".").forEach((key) => {
if (sourceData[key]) sourceData = sourceData[key];
});
return sourceData;
},
getArrayData(itemData, collapseItem) {
if (!collapseItem.array_key) return [itemData];
let sourceData = this.getSourceData(itemData, collapseItem.array_key);
if (!Array.isArray(sourceData)) return [itemData];
return sourceData;
},
showDetailsHandler(event) {
this.$emit("changeCurrent", this.items[event.index]);
},
copyLinkHandler(event) {
let id = this.items[event]._id;
this.copyToClipboard("", this.urlResolver(id));
},
findvalueForKey(item, keyName) {
let value = "";
if (keyName in item) {
value = item[keyName];
} else {
value = item?._source[keyName];
}
return value;
},
onOnLinkedTitleClick({ rowItem, tableColumn, index }) {
let valueId = this.findvalueForKey(rowItem, tableColumn.link_route.id);
let route = tableColumn.link_route;
// let href = this.urlResolver(valueId, tableColumn.link_route);
let keyMain = "";
let query_key = "";
let query_value = "";
let keys = "";
let key = "";
let query = { searchtext: this.textSearch ?? undefined };
if (route?.query) {
let querys = route.query;
if (typeof querys === "string") {
keys = route?.query.split("=");
if (keys.length >= 2) {
query_key = keys[0];
query_value = keys[1];
}
if (query_key && query_value) {
query[query_key] = query_value; // کلید پویا و مقدار از قسمت بالایی
}
} else {
let newObject = {};
for (const [key, value] of Object.entries(querys)) {
if (value in item) {
newObject[key] = item[value];
} else {
newObject[key] = item?._source[value];
}
}
Object.assign(query, newObject);
}
}
if (route?.key_item || route.key) {
if (route?.key_item) key = this.getSourceData(item, route.key_item);
else key = route.key;
}
this.$router.push({
path: `/search/${key}/${valueId}`,
params: {
id: valueId,
key: key,
name:tableColumn?.link_route?.name
},
query: query?.length ? query : undefined,
});
localStorage.setItem("myList", JSON.stringify(this.items));
localStorage.setItem("myItem", JSON.stringify(rowItem));
this.SET_ITEM_ENTITY(rowItem);
this.SET_LIST_ENTITY(this.items);
// window.open(href, "_blank");
},
showTextPage(event) {},
async deleteResearch(item) {
this.mySwalConfirm({
title: "هشدار!!!",
html: `از حذف <b>${item._source.text_subject}</b> اطمینان دارید؟ `,
icon: "warning",
}).then(async (result) => {
if (result.isConfirmed) {
let url = researchApi.research.deleteItem;
url = url.replace("{{index_key}}", item._source.ref_key);
url = url.replace("{{id}}", item._id);
try {
const { $api } = useNuxtApp();
const res = await $api(url, {
baseURL: import.meta.env.VITE_REPO_BASE_URL,
method: "post",
});
this.mySwalToast({
html: res.message,
});
setTimeout(() => {
this.$emit("updateForDeleteResearch");
}, 500);
} catch (err) {}
// this.httpService.postRequest(url).then((res) => {
// });
}
});
},
/**
* تغییر محدودیت صفحهبندی و ارسال آن با استفاده از رویداد
* @param {Object} paging - تنظیمات صفحهبندی
*/
pageLimitChanged(paging) {
this.resetPagination();
this.page.limit = paging.limit;
this.$emit("changePage", this.page);
},
/**
* تغییر صفحه فعلی و ارسال آن با استفاده از رویداد
* @param {Object} paging - تنظیمات صفحهبندی
*/
pageChanged(paging) {
let page = paging.pageNumber;
page -= 1;
this.page.offset = page * paging.limit;
this.page.limit = paging.limit;
this.page.page = paging.pageNumber;
this.$emit("changePage", this.page);
},
/**
* تغییر مرتبسازی و ارسال آن با استفاده از رویداد
* @param {Object} sorting - تنظیمات مرتبسازی
*/
sortChanged(sorting) {
this.page.page = this.page.offset = 0;
this.sorting = sorting;
this.$emit("changePage", this.sorting);
},
/**
* بازنشانی تنظیمات صفحهبندی به حالت اولیه
*/
resetPagination() {
this.page = {
pages: 0,
total: 0,
page: 1,
offset: 0,
limit: 10,
};
},
},
components: {
lineContent: defineAsyncComponent(() =>
import("@search/components/search/view/lineContent.vue")
),
},
};
</script>
<style lang="scss" scoped>
.main-content-item {
position: relative;
overflow: hidden;
&: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 {
.btn {
font-size: 0.8rem;
}
}
}
.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);
}
.icon-copy2 {
font-size: 0.8rem;
}
&.favorites {
color: calc(--primary-color);
.icon-bookmark-1,
.icon-bookmark-2 {
height: 1.3em;
}
}
}
}
.main-content {
height: calc(100dvh - 15em);
overflow: auto;
}
@media (max-width: 575.98px) {
.main-content {
height: calc(100dvh - 17em);
}
}
@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>