875 lines
29 KiB
Vue
Executable File
875 lines
29 KiB
Vue
Executable File
<template>
|
|
<div class="my-content">
|
|
<template v-if="localViewMode == 'list'">
|
|
<div class="flex flex-wrap -mx-2">
|
|
<div
|
|
class="w-full px-2 main-content firefox-scrollbar"
|
|
:style="{ height: props.mainSchema.height }"
|
|
>
|
|
<template v-if="props.mainSchema.items.length">
|
|
<div
|
|
class="mb-3 border-b main-content-item p-3"
|
|
v-for="(itemData, i) in props.mainSchema.items"
|
|
:key="i"
|
|
@click="changeCurrent(itemData)"
|
|
@contextmenu.prevent="onRightClick(itemData, $event)"
|
|
>
|
|
<template v-if="itemData.inner_hits">
|
|
<div
|
|
class="flex flex-wrap -mx-2"
|
|
v-for="(collapseItem, indexCollapse) in props.mainSchema
|
|
.schemaItems.collapse_items?.items || []"
|
|
:key="indexCollapse"
|
|
>
|
|
<template v-if="collapseItem.array_key">
|
|
<div
|
|
class="w-full px-2"
|
|
v-for="(subItemData, s) in getArrayData(
|
|
itemData,
|
|
collapseItem,
|
|
)"
|
|
:key="s"
|
|
>
|
|
<lineContent
|
|
:lineSchema="collapseItem"
|
|
:itemData="subItemData"
|
|
:arrayItemData="props.mainSchema.items"
|
|
:textSearch="props.mainSchema.textSearch"
|
|
@openModalHandler="openModalHandler"
|
|
@click-item="onMyContentAction('click-item', $event)"
|
|
>
|
|
</lineContent>
|
|
</div>
|
|
</template>
|
|
<template v-else>
|
|
<lineContent
|
|
:lineSchema="collapseItem"
|
|
:itemData="itemData"
|
|
:arrayItemData="props.mainSchema.items"
|
|
:textSearch="props.mainSchema.textSearch"
|
|
@openModalHandler="openModalHandler"
|
|
@click-item="onMyContentAction('click-item', $event)"
|
|
>
|
|
</lineContent>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<template
|
|
v-else-if="
|
|
props.mainSchema.schemaItems &&
|
|
props.mainSchema.schemaItems.items
|
|
"
|
|
>
|
|
<div
|
|
class="flex flex-wrap -mx-2"
|
|
v-for="(lineSchema, index) in props.mainSchema.schemaItems
|
|
?.items"
|
|
:key="index"
|
|
>
|
|
<lineContent
|
|
:lineSchema="lineSchema"
|
|
:itemData="itemData"
|
|
:arrayItemData="props.mainSchema.items"
|
|
:textSearch="props.mainSchema.textSearch"
|
|
@openModalHandler="openModalHandler"
|
|
@click-item="onMyContentAction('click-item', $event)"
|
|
>
|
|
</lineContent>
|
|
</div>
|
|
</template>
|
|
|
|
<template v-if="props.mainSchema.isSearchingState">
|
|
<div class="flex items-center">
|
|
<label
|
|
class="whitespace-nowrap ml-1"
|
|
style="color: gray; font-family: sahel-semi-bold"
|
|
>
|
|
پاسخ را همراه امتیاز ذخیره کنید :
|
|
</label>
|
|
<NuxtRating
|
|
class="star-rating"
|
|
:read-only="false"
|
|
:rating-value="itemData.rate_value ?? 0"
|
|
border-color="#db8403"
|
|
active-color="#ffa41c"
|
|
inactive-color="#fff"
|
|
:rating-step="0.5"
|
|
:rounded-corners="true"
|
|
:border-width="5"
|
|
:rating-size="20"
|
|
@rating-selected="
|
|
saveRating(
|
|
$event,
|
|
i,
|
|
itemData,
|
|
props.mainSchema.schemaItems,
|
|
)
|
|
"
|
|
@rating-hovered="(event) => (rating.value = event)"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<div
|
|
class="search-item__actions"
|
|
v-if="props.mainSchema.schemaItems.actions?.length"
|
|
>
|
|
<span class="tavasi tavasi-more-vert"></span>
|
|
<template
|
|
v-for="(schema, indexIcon) in props.mainSchema.schemaItems
|
|
.actions"
|
|
:key="'action' + indexIcon"
|
|
>
|
|
<div class="search-item__actions flex gap-1 mt-2">
|
|
<UButton
|
|
v-for="(schema, index) in props.mainSchema.schemaItems
|
|
.actions"
|
|
:key="'action-' + index"
|
|
:title="schema.title"
|
|
variant="ghost"
|
|
size="xs"
|
|
:ui="{ icon: { base: 'w-4 h-4' }, padding: 'p-1.5' }"
|
|
@click.stop="handleActionClick(itemData, schema)"
|
|
>
|
|
<UIcon
|
|
v-if="schema.key === 'tbookmark'"
|
|
:name="
|
|
itemData._source.tbookmark == 1
|
|
? schema.toggle_icons?.icon1
|
|
: schema.toggle_icons?.icon2
|
|
"
|
|
class="w-4 h-4 text-dark-primary-800"
|
|
/>
|
|
<UIcon
|
|
v-else-if="schema.icon"
|
|
:name="schema.icon"
|
|
class="w-4 h-4 text-dark-primary-800"
|
|
/>
|
|
<span v-else class="text-xs">{{ schema.title }}</span>
|
|
</UButton>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template v-else>
|
|
<table-no-data></table-no-data>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="">
|
|
<myPagination
|
|
v-model:paginationInfo="localPagination"
|
|
:show-total-records="true"
|
|
:show-page-selection="true"
|
|
@pageChanged="fetchData"
|
|
@limitChanged="fetchData"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- viewMode = 'table' -->
|
|
<template v-if="localViewMode == 'table'">
|
|
<div class="flex flex-wrap -mx-2">
|
|
<div class="w-full px-0">
|
|
<MyTable
|
|
:table-columns="props.mainSchema.tableColumns"
|
|
:action-buttons="props.mainSchema.tableActions"
|
|
:raw-data="props.mainSchema.items"
|
|
:cell-menu-items="props.mainSchema.menuItems"
|
|
:show-search="false"
|
|
:tableBodyMaxHeight="props.mainSchema.height"
|
|
:pagination="localPagination"
|
|
@my-table-action="myTableAction"
|
|
/>
|
|
|
|
<myPagination
|
|
v-model:paginationInfo="localPagination"
|
|
:show-total-records="true"
|
|
:show-page-selection="true"
|
|
@pageChanged="fetchData"
|
|
@limitChanged="fetchData"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- viewMode = 'card' -->
|
|
<template v-if="localViewMode == 'card'">
|
|
<div class="flex flex-wrap -mx-2">
|
|
<div class="w-full px-2 main-content firefox-scrollbar">
|
|
<div
|
|
class="flex flex-wrap -mx-2"
|
|
v-if="props.mainSchema.items.length"
|
|
>
|
|
<div
|
|
v-for="(itemData, i) in props.mainSchema.items"
|
|
:key="i"
|
|
class="mb-4 w-full sm:w-1/2 md:w-1/3 lg:w-1/4 xl:w-1/5 px-2"
|
|
>
|
|
<div
|
|
class="main-content-item-card p-4 rounded-lg shadow-md border border-gray-200 bg-white flex flex-col h-full"
|
|
>
|
|
<div v-if="!itemData?._source" class="text-red-500 italic">
|
|
داده نامعتبر
|
|
</div>
|
|
|
|
<template v-else>
|
|
<div
|
|
v-if="props.mainSchema.schemaItems?.items?.length"
|
|
class="flex flex-col gap-2"
|
|
>
|
|
<template
|
|
v-for="(lineSchema, index) in props.mainSchema.schemaItems
|
|
.items"
|
|
:key="index"
|
|
>
|
|
<lineContent
|
|
:lineSchema="lineSchema"
|
|
:itemData="itemData"
|
|
:arrayItemData="props.mainSchema.items"
|
|
:textSearch="props.mainSchema.textSearch"
|
|
@openModalHandler="openModalHandler"
|
|
@click-item="onMyContentAction('click-item', $event)"
|
|
/>
|
|
</template>
|
|
</div>
|
|
|
|
<div
|
|
v-else-if="itemData._source.title"
|
|
class="font-semibold text-gray-800"
|
|
>
|
|
{{ itemData._source.title }}
|
|
</div>
|
|
<div v-else class="text-gray-500 text-sm italic">
|
|
بدون عنوان
|
|
</div>
|
|
</template>
|
|
|
|
<div
|
|
v-if="props.mainSchema.schemaItems.actions?.length"
|
|
class="mt-auto pt-3 border-t border-gray-100 flex gap-2"
|
|
>
|
|
<UButton
|
|
v-for="(schema, idx) in props.mainSchema.schemaItems
|
|
.actions"
|
|
:key="'action-' + idx"
|
|
:title="schema.title"
|
|
variant="ghost"
|
|
size="xs"
|
|
:ui="{ icon: { base: 'w-4 h-4' }, padding: 'p-1.5' }"
|
|
@click.stop="handleActionClick(itemData, schema)"
|
|
>
|
|
<UIcon
|
|
v-if="schema.key === 'tbookmark'"
|
|
:name="
|
|
itemData._source.tbookmark == 1
|
|
? schema.toggle_icons?.icon1
|
|
: schema.toggle_icons?.icon2
|
|
"
|
|
class="w-4 h-4 text-gray-800"
|
|
/>
|
|
<UIcon
|
|
v-else-if="schema.icon"
|
|
:name="schema.icon"
|
|
class="w-4 h-4 text-gray-800"
|
|
/>
|
|
<span v-else class="text-xs">{{ schema.title }}</span>
|
|
</UButton>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<template v-else>
|
|
<table-no-data />
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- viewMode = 'three-column-card' -->
|
|
<template v-if="localViewMode == 'three-column-card'">
|
|
<div class="flex flex-wrap -mx-2">
|
|
<div class="w-full px-2 main-content firefox-scrollbar">
|
|
<div
|
|
class="flex flex-wrap -mx-2"
|
|
v-if="props.mainSchema.items.length"
|
|
>
|
|
<div
|
|
class="mb-3 main-content-item p-3 w-full sm:w-1/3 px-2"
|
|
v-for="(itemData, i) in props.mainSchema.items"
|
|
:key="i"
|
|
>
|
|
<div class="flex justify-center"></div>
|
|
|
|
<template v-if="itemData.inner_hits">
|
|
<div
|
|
class="flex flex-wrap -mx-2"
|
|
v-for="(collapseItem, indexCollapse) in props.mainSchema
|
|
.schemaItems.collapse_items?.items || []"
|
|
:key="indexCollapse"
|
|
>
|
|
<template v-if="collapseItem.array_key">
|
|
<div
|
|
class="w-1/3 px-2"
|
|
v-for="(subItemData, s) in getArrayData(
|
|
itemData,
|
|
collapseItem,
|
|
)"
|
|
:key="s"
|
|
>
|
|
<lineContent
|
|
:lineSchema="collapseItem"
|
|
:itemData="subItemData"
|
|
:arrayItemData="props.mainSchema.items"
|
|
:textSearch="props.mainSchema.textSearch"
|
|
>
|
|
</lineContent>
|
|
</div>
|
|
</template>
|
|
<template v-else>
|
|
<lineContent
|
|
:lineSchema="collapseItem"
|
|
:itemData="itemData"
|
|
:arrayItemData="props.mainSchema.items"
|
|
:textSearch="props.mainSchema.textSearch"
|
|
>
|
|
</lineContent>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<template v-else>
|
|
<div
|
|
v-if="
|
|
props.mainSchema.schemaItems &&
|
|
props.mainSchema.schemaItems.items
|
|
"
|
|
class="flex flex-wrap -mx-2"
|
|
v-for="(lineSchema, index) in props.mainSchema.schemaItems
|
|
?.items || []"
|
|
:key="index"
|
|
>
|
|
<lineContent
|
|
:lineSchema="lineSchema"
|
|
:itemData="itemData"
|
|
:arrayItemData="props.mainSchema.items"
|
|
:textSearch="props.mainSchema.textSearch"
|
|
@openModalHandler="openModalHandler"
|
|
@click-item="onMyContentAction('click-item', $event)"
|
|
>
|
|
</lineContent>
|
|
</div>
|
|
</template>
|
|
|
|
<div
|
|
class="search-item__actions"
|
|
v-if="props.mainSchema.schemaItems.actions"
|
|
>
|
|
<span class="tavasi tavasi-more-vert"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<template v-else>
|
|
<table-no-data></table-no-data>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- viewMode = 'two-column-card' -->
|
|
<template v-if="localViewMode == 'two-column-card'">
|
|
<div class="flex flex-wrap -mx-2">
|
|
<div class="w-full sm:w-1/2 px-2 main-content firefox-scrollbar">
|
|
<template v-if="props.mainSchema.items.length">
|
|
<div
|
|
class="mb-3 border-b main-content-item p-3"
|
|
v-for="(itemData, i) in props.mainSchema.items"
|
|
:key="i"
|
|
>
|
|
<template v-if="itemData.inner_hits">
|
|
<div
|
|
class="flex flex-wrap -mx-2"
|
|
v-for="(collapseItem, indexCollapse) in props.mainSchema
|
|
.schemaItems.collapse_items?.items || []"
|
|
:key="indexCollapse"
|
|
>
|
|
<template v-if="collapseItem.array_key">
|
|
<div
|
|
class="w-full px-2"
|
|
v-for="(subItemData, s) in getArrayData(
|
|
itemData,
|
|
collapseItem,
|
|
)"
|
|
:key="s"
|
|
>
|
|
<lineContent
|
|
:lineSchema="collapseItem"
|
|
:itemData="subItemData"
|
|
:arrayItemData="props.mainSchema.items"
|
|
:textSearch="props.mainSchema.textSearch"
|
|
>
|
|
</lineContent>
|
|
</div>
|
|
</template>
|
|
<template v-else>
|
|
<lineContent
|
|
:lineSchema="collapseItem"
|
|
:itemData="itemData"
|
|
:arrayItemData="props.mainSchema.items"
|
|
:textSearch="props.mainSchema.textSearch"
|
|
>
|
|
</lineContent>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<template v-else>
|
|
<div
|
|
v-if="
|
|
props.mainSchema.schemaItems &&
|
|
props.mainSchema.schemaItems.items
|
|
"
|
|
class="flex flex-wrap -mx-2"
|
|
v-for="(lineSchema, index) in props.mainSchema.schemaItems
|
|
?.items || []"
|
|
:key="index"
|
|
>
|
|
<lineContent
|
|
:lineSchema="lineSchema"
|
|
:itemData="itemData"
|
|
:arrayItemData="props.mainSchema.items"
|
|
:textSearch="props.mainSchema.textSearch"
|
|
@openModalHandler="openModalHandler"
|
|
@click-item="onMyContentAction('click-item', $event)"
|
|
>
|
|
</lineContent>
|
|
</div>
|
|
</template>
|
|
|
|
<div
|
|
class="search-item__actions"
|
|
v-if="props.mainSchema.schemaItems.actions"
|
|
>
|
|
<span class="tavasi tavasi-more-vert"></span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template v-else>
|
|
<table-no-data></table-no-data>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, onBeforeMount, onMounted, onUnmounted } from "vue";
|
|
import { useNuxtApp, useRoute, useRouter } from "#app";
|
|
import lineContent from "@/components/lazy-load/global/lineContent.vue";
|
|
import MyTable from "@/components/lazy-load/global/MyTable.vue";
|
|
import { watch } from "vue";
|
|
|
|
// --- متغیرهای نمونه (برای تست) ---
|
|
const columns = []; // حذف شد چون استفاده نمیشود
|
|
const buttons = []; // حذف شد
|
|
const data = []; // حذف شد
|
|
const menuItems = []; // حذف شد
|
|
const props = defineProps({
|
|
mainSchema: {
|
|
type: Object,
|
|
required: true,
|
|
default: () => ({}),
|
|
},
|
|
pagination: {
|
|
// ✅ اضافه شد
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
});
|
|
const localPagination = ref({
|
|
// pages: 1000,
|
|
total: 0,
|
|
page: 1,
|
|
// offset: 0,
|
|
limit: 10,
|
|
});
|
|
watch(
|
|
() => props.mainSchema.pagination,
|
|
(newPagination) => {
|
|
if (newPagination) {
|
|
localPagination.value.total = newPagination.total ?? 0;
|
|
// page و limit معمولاً توسط fetchData ست شدن، ولی اگر Parent override کنه:
|
|
if (newPagination.page) localPagination.value.page = newPagination.page;
|
|
if (newPagination.limit)
|
|
localPagination.value.limit = newPagination.limit;
|
|
}
|
|
},
|
|
{ immediate: true, deep: true },
|
|
);
|
|
const fetchData = (newPagination) => {
|
|
// newPagination میتونه از myPagination بیاد
|
|
// مثلاً: { pageNumber: 3, limit: 20 }
|
|
|
|
const page = newPagination.pageNumber ?? localPagination.value.page;
|
|
const limit = newPagination.limit ?? localPagination.value.limit;
|
|
|
|
// state داخلی رو بهروز کن (صفحه و limit)
|
|
localPagination.value.page = page;
|
|
localPagination.value.limit = limit;
|
|
|
|
// ✅ فقط این دو مورد رو بفرست به Parent
|
|
onMyContentAction("pagination", { page, limit });
|
|
};
|
|
const myTableAction = ({ action, payload }) => {
|
|
// console.log("myTableAction :", action, payload);
|
|
onMyContentAction(action, payload);
|
|
};
|
|
|
|
const onMyContentAction = (action, payload) => {
|
|
emit("my-content-action", {
|
|
action: action,
|
|
payload: payload,
|
|
});
|
|
};
|
|
|
|
// --- Props و Emits ---
|
|
|
|
const localViewMode = ref(props.mainSchema.viewMode);
|
|
// ✅ فقط یک ایمیت واحد
|
|
const emit = defineEmits(["my-content-action"]);
|
|
|
|
// --- Composables ---
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
|
|
// --- Refs ---
|
|
const contextMenu = ref({ visible: false, x: 0, y: 0, node: null });
|
|
const rating = ref("");
|
|
const page = ref({ pages: 0, total: 0, page: 1, offset: 0, limit: 10 });
|
|
const reRender = ref(1);
|
|
const sorting = ref({ sortby: "created", sortorder: undefined });
|
|
|
|
// --- Methods ---
|
|
const contextMenuAction = (payload) =>
|
|
onMyContentAction("context-menu-action", payload);
|
|
|
|
const onRightClick = (node, event) => {
|
|
if (props.mainSchema.contextMenuItems?.length) {
|
|
contextMenu.value = {
|
|
x: event.clientX,
|
|
y: event.clientY,
|
|
visible: true,
|
|
node: node,
|
|
};
|
|
document.addEventListener("click", hideContextMenu);
|
|
}
|
|
};
|
|
|
|
const hideContextMenu = () => {
|
|
contextMenu.value.visible = false;
|
|
document.removeEventListener("click", hideContextMenu);
|
|
};
|
|
|
|
const saveRating = (rate_value, index, itemData, schemaItems) => {
|
|
let schema = undefined;
|
|
if (itemData?.inner_hits && schemaItems?.collapse_items?.items?.length)
|
|
schema = schemaItems.collapse_items.items[0];
|
|
else if (schemaItems?.items?.length) schema = schemaItems.items[0];
|
|
if (!schema) return;
|
|
const key_id = schema.link_id ?? "_id";
|
|
itemData.rate_value = rate_value;
|
|
props.mainSchema.items[index] = itemData;
|
|
const id_route = getSourceData(itemData, key_id);
|
|
onMyContentAction("rate-item", { id: id_route, rate: rate_value });
|
|
};
|
|
|
|
const openModalHandler = (item, isReadonly = true) =>
|
|
onMyContentAction("ModalHandler", { item, isReadonly });
|
|
|
|
const handlerActions = (event) => {
|
|
const { key } = event.rowAction;
|
|
if (key === "summary") {
|
|
onMyContentAction("show-summary", event.item);
|
|
} else if (key === "copy") {
|
|
copyToClipboard(
|
|
"",
|
|
urlResolver(event.item._id, event.rowAction.link_route, event.item),
|
|
);
|
|
} else if (key === "tbookmark") {
|
|
AddToFavorites(event.item, event.rowAction, event.index);
|
|
} else {
|
|
onMyContentAction("actionsHandler", { key, event });
|
|
}
|
|
};
|
|
|
|
const AddToFavorites = (item, icon, index) => {
|
|
onMyContentAction("myContent_addToFavorites", { item, icon, index });
|
|
};
|
|
|
|
const handlerActionsList = (item, key, icon) => {
|
|
if (key === "summary") {
|
|
onMyContentAction("show-summary", item);
|
|
} else if (key === "copy") {
|
|
copyToClipboard(
|
|
"",
|
|
urlResolver(
|
|
findvalueForKey(item, icon.link_route.id),
|
|
icon.link_route,
|
|
item,
|
|
),
|
|
);
|
|
} else if (key === "SubjectForm") {
|
|
onMyContentAction("SubjectForm", item);
|
|
} else if (key === "edit") {
|
|
onMyContentAction(icon.emit ? "edit" : "ModalHandler", {
|
|
item,
|
|
key,
|
|
icon,
|
|
isReadonly: !icon.emit,
|
|
});
|
|
} else if (key === "delete") {
|
|
onMyContentAction(icon.emit ? "delete" : "deleteResearch", item);
|
|
}
|
|
};
|
|
|
|
const urlResolver = (_id, route, item) => {
|
|
let query = {};
|
|
if (buildName?.() !== "majles")
|
|
query.searchtext = props.mainSchema.textSearch ?? undefined;
|
|
|
|
if (route?.query) {
|
|
if (typeof route.query === "string") {
|
|
const [query_key, query_value] = route.query.split("=");
|
|
if (query_key && query_value) query[query_key] = query_value;
|
|
} else {
|
|
for (const [key, value] of Object.entries(route.query)) {
|
|
query[key] = item[value] ?? item?._source[value];
|
|
}
|
|
}
|
|
}
|
|
|
|
const id_route = getSourceData(item, route?.id);
|
|
const id_route2 = route?.id2 ? getSourceData(item, route.id2) : undefined;
|
|
const key = getSourceData(item, route?.key_item) ?? route.key;
|
|
|
|
if (route.name === "navigation" || route.name === "navigationView")
|
|
query.ls = "list";
|
|
|
|
return router.resolve({
|
|
name: "navigationView",
|
|
params: { id: id_route, id2: id_route2, key },
|
|
query,
|
|
}).href;
|
|
};
|
|
|
|
const getSourceData = (itemData, key) => {
|
|
let sourceData = itemData;
|
|
key.split(".").forEach((k) => {
|
|
sourceData = sourceData?.[k] ?? sourceData?._source?.[k];
|
|
});
|
|
return sourceData;
|
|
};
|
|
|
|
const getArrayData = (itemData, collapseItem) => {
|
|
if (!collapseItem.array_key) return [itemData];
|
|
const sourceData = getSourceData(itemData, collapseItem.array_key);
|
|
return Array.isArray(sourceData) ? sourceData : [itemData];
|
|
};
|
|
|
|
const findvalueForKey = (item, keyName) =>
|
|
item[keyName] ?? item?._source[keyName];
|
|
|
|
const onLinkedTitleClick = ({ rowItem, tableColumn }) => {
|
|
let key = props.mainSchema.mainSchemaKey;
|
|
if (key === "qsection") key = "qasection";
|
|
else if (key === "rsection") key = "rgsection";
|
|
|
|
const title_value =
|
|
key === "qasection" || key === "rgsection"
|
|
? rowItem._source.qanon_title
|
|
: rowItem._source.title;
|
|
const valueId = findvalueForKey(rowItem, tableColumn.link_route?.id);
|
|
if (valueId) {
|
|
onMyContentAction("click-item", { id: valueId, title: title_value });
|
|
}
|
|
|
|
const href = urlResolver(valueId, tableColumn.link_route, rowItem);
|
|
const cloneList = props.mainSchema.items.map((item) => ({
|
|
_id: item._id,
|
|
_source: {
|
|
id: item._id,
|
|
title: item?._source?.title,
|
|
qanon_title: item?._source?.qanon_title,
|
|
qanon_id: item?._source?.qanon_id,
|
|
ref_key: key,
|
|
},
|
|
}));
|
|
|
|
localStorage.setItem("myList", JSON.stringify(cloneList));
|
|
localStorage.setItem("myItem", JSON.stringify(rowItem));
|
|
window.open(href, "_blank");
|
|
};
|
|
|
|
const pageLimitChanged = (paging) => {
|
|
resetPagination();
|
|
page.value.limit = paging.limit;
|
|
onMyContentAction("changePage", { ...page.value });
|
|
};
|
|
|
|
const pageChanged = (paging) => {
|
|
const p = paging.pageNumber - 1;
|
|
page.value.offset = p * paging.limit;
|
|
page.value.limit = paging.limit;
|
|
page.value.page = paging.pageNumber;
|
|
onMyContentAction("changePage", { ...page.value });
|
|
};
|
|
|
|
const sortChanged = (sortingInfo) => {
|
|
page.value.page = 0;
|
|
page.value.offset = 0;
|
|
sorting.value = sortingInfo;
|
|
onMyContentAction("changePage", { ...sorting.value });
|
|
};
|
|
|
|
const resetPagination = () => {
|
|
page.value = { pages: 0, total: 0, page: 1, offset: 0, limit: 10 };
|
|
};
|
|
|
|
const changeCurrent = (item) => {
|
|
onMyContentAction("changeCurrent", item);
|
|
};
|
|
|
|
const handleActionClick = (itemData, schema) => {
|
|
handlerActionsList(itemData, schema.key, schema);
|
|
};
|
|
|
|
// --- Lifecycle ---
|
|
onBeforeMount(() => {
|
|
if (props.mainSchema.items && route.params?.key === "qasection") {
|
|
props.mainSchema.items.forEach((item) => {
|
|
if (!item._source.qanon_etebar?.trim())
|
|
item._source.qanon_etebar = "معتبر";
|
|
});
|
|
}
|
|
});
|
|
|
|
onMounted(() => {
|
|
page.value = props.mainSchema.pagination || {
|
|
pages: 0,
|
|
total: 0,
|
|
page: 1,
|
|
offset: 0,
|
|
limit: 10,
|
|
};
|
|
fetchData({ pageNumber: 1, limit: 10 });
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
document.removeEventListener("click", hideContextMenu);
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
/* سبکها بدون تغییر */
|
|
.main-content-item {
|
|
position: relative;
|
|
overflow: hidden;
|
|
&:hover,
|
|
&.active {
|
|
background-color: #e8fcff;
|
|
.search-item__actions {
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.main-content-item-card {
|
|
box-shadow: rgba(191, 191, 191, 0.24) 0px 0px 3px 1px;
|
|
border-radius: 10px;
|
|
position: relative;
|
|
overflow: hidden;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
flex-direction: column;
|
|
&:hover,
|
|
&.active {
|
|
background-color: var(--list-background-color);
|
|
.search-item__actions {
|
|
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;
|
|
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: var(--color-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);
|
|
}
|
|
}
|
|
.star-rating-text {
|
|
float: left;
|
|
margin-left: 10px;
|
|
}
|
|
</style>
|
|
|
|
<style lang="scss">
|
|
.my-content {
|
|
&.refine-main-filter-enabled {
|
|
.my-content-table {
|
|
.table-responsive {
|
|
height: calc(-22.5em + 100vh) !important;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|