Files
NSG_PORTAL_V2/components/dynamic-page/page-component/templates/sections/articles/Default.vue
T
2024-07-08 17:03:33 +07:00

198 lines
5.3 KiB
Vue

<script setup lang="ts">
import DynamicComponent from "~/components/dynamic-page/page-component/templates/index.vue";
import { getInputValue } from "@/utils/parseSQL";
import { enumPageComponentTemplates } from "@/definitions/enum";
const router = useRouter();
const route = useRoute();
import { useScroll } from '@vueuse/core';
const _props = defineProps<{
dataResult?: any[];
dataQuery?: string;
component?: any;
label?: string;
}>();
const SETTING_OPTIONS = {
MAX_ELEMENT: 5,
TEMPLATE: "TYPE:Card",
LAYOUT: "TYPE:Card_Default",
};
const COMPONENT = {
taxonomy: enumPageComponentTemplates.ARTICLE,
};
const page = ref(1);
const limit = ref(5);
const totals = ref(2);
const type = "Article";
const listArticlePaging = ref([]);
const listArticleByCategory = computed(() => {
const data = getInputValue(_props.dataResult, "OBJECT");
if (data && Object.keys(data)?.length > 0) {
totals.value = data.Total;
return data?.Data;
}
return [];
});
const designObject = computed(() => {
return _props.label ? getInputValue(_props.label, "OBJECT") : {};
});
//?cpn_1=page:2&cpn_2=page:1
// Get[Article] Top[5] With[Categories:1]
const select = async (pageActive: number) => {
const componentId = _props.component?.id;
if (componentId) {
router.push({
query: {
...route.query,
[`cpn_${componentId}`]: `page:${pageActive}`,
},
});
}
page.value = Number(pageActive);
await loadPage(Number(pageActive));
};
const handleRouteChange = async (query: any) => {
const param = query[`cpn_${_props.component?.id}`];
if (param) {
const [_, value] = param.split(":") || [];
page.value = Number(value);
await loadPage(value);
}
};
const loadPage = async (page: number) => {
let newDataQuery = "";
const regex = /Page\[(.*?)\]/;
const match = _props.component?.settings?.dataQuery?.match(regex);
if (match) {
const [pageData] = match;
newDataQuery = _props.component?.settings?.dataQuery.replace(pageData, `Page[${page}]`);
} else {
newDataQuery = _props.component?.settings?.dataQuery + ` Page[${page}]`;
}
const {item} = await store.component.getOverviewPageComponentById(Number(_props.component?.id), newDataQuery);
const data = getInputValue(item?.settings?.dataResult, "OBJECT");
if (Object.keys(data).length > 0) {
totals.value = data.Total;
listArticlePaging.value = data?.Data || [];
}
};
if (route.query[`cpn_${_props.component?.id}`]) handleRouteChange(route.query);
const handleNextPrev = (type: "+" | "-") => {
if (listArticleByCategory.value?.length > 0) {
if (type === "+") {
page.value += 1;
} else if (type === "-") {
page.value -= 1;
}
select(page.value);
}
};
const mapActivesToItems = (index: number) => {
if (designObject.value && designObject.value.listCss) {
return designObject.value.listCss[index] || {};
}
return {};
};
</script>
<template>
<section :id="`cpn_[${_props.component.id}]`" v-if="listArticleByCategory?.length > 0">
<div class="section-container">
<div class="section-layout" :style="designObject['div.section']">
<template v-for="(component, index) in listArticlePaging?.length > 0 ? listArticlePaging : listArticleByCategory" :key="index">
<DynamicComponent
:settings="{
template: SETTING_OPTIONS.TEMPLATE,
layout: SETTING_OPTIONS.LAYOUT,
dataResult: { ...component },
label: mapActivesToItems(Number(index)),
}"
:component="COMPONENT"
/>
</template>
<div class="button-page flex">
<a :href="`#cpn_[${_props.component.id}]`" class="btn-page prev-page" @click.stop="() => handleNextPrev('-')" v-if="page > 1">
<Icon name="ooui:previous-ltr"></Icon>
</a>
<a :href="`#cpn_[${_props.component.id}]`" :class="['btn-page', page === index + 1 && 'active']" @click.stop="() => select(index + 1)" v-for="(_, index) in Math.ceil(totals / limit)" :key="index">{{ index + 1 }}</a>
<a :href="`#cpn_[${_props.component.id}]`" class="btn-page next-page" @click.stop="() => handleNextPrev('+')" v-if="page < Math.ceil(totals / limit)">
<Icon name="ooui:previous-rtl"></Icon>
</a>
</div>
</div>
</div>
<div v-html="designObject.styleClasses" style="display: none" v-if="designObject.styles"></div>
</section>
</template>
<style lang="scss" scoped>
.section-container {
.section-layout {
display: flex;
flex-direction: column;
/* gap: 10px; */
&.border-custom {
border-color: #e5e5e5 !important;
}
}
.basic-article {
&.article {
margin-bottom: 10px;
display: flex;
pointer-events: none;
}
}
.flex {
display: flex;
margin-top: 10px;
justify-content: center;
overflow-x: auto;
}
.button-page {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.btn-page {
width: 40px;
height: 40px;
padding: 9px 16px;
text-align: center;
line-height: 36px;
border-radius: 4px;
margin-left: 10px;
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
flex-shrink: 0;
background: #f2f2f2;
cursor: pointer;
color: #222222;
&.active {
background: #ed1c24;
color: white;
}
}
}
.el-empty {
padding: 12px 0;
}
</style>