<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>