2024-06-13 17:24:46 +07:00
|
|
|
<script setup lang="ts">
|
|
|
|
|
import DynamicComponent from "~/components/dynamic-page/page-component/templates/index.vue";
|
2024-07-05 14:51:25 +07:00
|
|
|
import { getInputValue } from "@/utils/parseSQL";
|
|
|
|
|
import { enumPageComponentTemplates } from "@/definitions/enum";
|
2024-06-13 17:24:46 +07:00
|
|
|
const router = useRouter();
|
|
|
|
|
const route = useRoute();
|
2024-07-08 17:03:33 +07:00
|
|
|
import { useScroll } from '@vueuse/core';
|
2024-07-09 15:15:22 +07:00
|
|
|
const store = reactive({
|
|
|
|
|
component: useDynamicPageStore(),
|
|
|
|
|
});
|
2024-06-13 17:24:46 +07:00
|
|
|
const _props = defineProps<{
|
2024-07-05 14:51:25 +07:00
|
|
|
dataResult?: any[];
|
2024-06-13 17:24:46 +07:00
|
|
|
dataQuery?: string;
|
|
|
|
|
component?: any;
|
2024-07-05 14:51:25 +07:00
|
|
|
label?: string;
|
2024-06-13 17:24:46 +07:00
|
|
|
}>();
|
|
|
|
|
|
|
|
|
|
const SETTING_OPTIONS = {
|
|
|
|
|
MAX_ELEMENT: 5,
|
2024-07-05 14:51:25 +07:00
|
|
|
TEMPLATE: "TYPE:Card",
|
|
|
|
|
LAYOUT: "TYPE:Card_Default",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const COMPONENT = {
|
|
|
|
|
taxonomy: enumPageComponentTemplates.ARTICLE,
|
2024-06-13 17:24:46 +07:00
|
|
|
};
|
|
|
|
|
|
2024-06-28 15:39:26 +07:00
|
|
|
const page = ref(1);
|
|
|
|
|
const limit = ref(5);
|
|
|
|
|
const totals = ref(2);
|
2024-06-13 17:24:46 +07:00
|
|
|
const type = "Article";
|
2024-06-28 15:39:26 +07:00
|
|
|
const listArticlePaging = ref([]);
|
2024-06-13 17:24:46 +07:00
|
|
|
|
|
|
|
|
const listArticleByCategory = computed(() => {
|
2024-06-28 15:39:26 +07:00
|
|
|
const data = getInputValue(_props.dataResult, "OBJECT");
|
|
|
|
|
if (data && Object.keys(data)?.length > 0) {
|
|
|
|
|
totals.value = data.Total;
|
|
|
|
|
return data?.Data;
|
|
|
|
|
}
|
|
|
|
|
return [];
|
2024-06-13 17:24:46 +07:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
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]
|
2024-06-28 15:39:26 +07:00
|
|
|
const select = async (pageActive: number) => {
|
2024-06-13 17:24:46 +07:00
|
|
|
const componentId = _props.component?.id;
|
|
|
|
|
if (componentId) {
|
|
|
|
|
router.push({
|
|
|
|
|
query: {
|
|
|
|
|
...route.query,
|
2024-06-28 15:39:26 +07:00
|
|
|
[`cpn_${componentId}`]: `page:${pageActive}`,
|
2024-06-13 17:24:46 +07:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-06-28 15:39:26 +07:00
|
|
|
page.value = Number(pageActive);
|
|
|
|
|
await loadPage(Number(pageActive));
|
2024-06-13 17:24:46 +07:00
|
|
|
};
|
2024-06-28 15:39:26 +07:00
|
|
|
const handleRouteChange = async (query: any) => {
|
|
|
|
|
const param = query[`cpn_${_props.component?.id}`];
|
|
|
|
|
if (param) {
|
|
|
|
|
const [_, value] = param.split(":") || [];
|
2024-07-05 14:51:25 +07:00
|
|
|
page.value = Number(value);
|
2024-06-28 15:39:26 +07:00
|
|
|
await loadPage(value);
|
2024-06-13 17:24:46 +07:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2024-06-28 15:39:26 +07:00
|
|
|
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}]`;
|
|
|
|
|
}
|
2024-07-05 15:12:16 +07:00
|
|
|
const {item} = await store.component.getOverviewPageComponentById(Number(_props.component?.id), newDataQuery);
|
|
|
|
|
const data = getInputValue(item?.settings?.dataResult, "OBJECT");
|
2024-07-05 14:51:25 +07:00
|
|
|
|
|
|
|
|
if (Object.keys(data).length > 0) {
|
|
|
|
|
totals.value = data.Total;
|
|
|
|
|
listArticlePaging.value = data?.Data || [];
|
|
|
|
|
}
|
2024-06-28 15:39:26 +07:00
|
|
|
};
|
|
|
|
|
|
2024-07-05 15:30:58 +07:00
|
|
|
if (route.query[`cpn_${_props.component?.id}`]) handleRouteChange(route.query);
|
|
|
|
|
|
2024-06-28 15:39:26 +07:00
|
|
|
const handleNextPrev = (type: "+" | "-") => {
|
|
|
|
|
if (listArticleByCategory.value?.length > 0) {
|
|
|
|
|
if (type === "+") {
|
|
|
|
|
page.value += 1;
|
|
|
|
|
} else if (type === "-") {
|
|
|
|
|
page.value -= 1;
|
|
|
|
|
}
|
|
|
|
|
select(page.value);
|
|
|
|
|
}
|
2024-06-13 17:24:46 +07:00
|
|
|
};
|
|
|
|
|
|
2024-06-28 15:39:26 +07:00
|
|
|
const mapActivesToItems = (index: number) => {
|
|
|
|
|
if (designObject.value && designObject.value.listCss) {
|
|
|
|
|
return designObject.value.listCss[index] || {};
|
2024-06-13 17:24:46 +07:00
|
|
|
}
|
2024-06-28 15:39:26 +07:00
|
|
|
return {};
|
|
|
|
|
};
|
2024-07-08 17:03:33 +07:00
|
|
|
|
2024-06-13 17:24:46 +07:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
2024-07-08 17:03:33 +07:00
|
|
|
<section :id="`cpn_[${_props.component.id}]`" v-if="listArticleByCategory?.length > 0">
|
2024-07-05 14:51:25 +07:00
|
|
|
<div class="section-container">
|
2024-06-28 15:39:26 +07:00
|
|
|
<div class="section-layout" :style="designObject['div.section']">
|
2024-07-05 14:51:25 +07:00
|
|
|
<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"
|
|
|
|
|
/>
|
2024-06-28 15:39:26 +07:00
|
|
|
</template>
|
2024-06-13 17:24:46 +07:00
|
|
|
<div class="button-page flex">
|
2024-07-08 17:03:33 +07:00
|
|
|
<a :href="`#cpn_[${_props.component.id}]`" class="btn-page prev-page" @click.stop="() => handleNextPrev('-')" v-if="page > 1">
|
2024-07-05 15:30:58 +07:00
|
|
|
<Icon name="ooui:previous-ltr"></Icon>
|
2024-07-08 17:03:33 +07:00
|
|
|
</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)">
|
2024-07-05 15:30:58 +07:00
|
|
|
<Icon name="ooui:previous-rtl"></Icon>
|
2024-07-08 17:03:33 +07:00
|
|
|
</a>
|
2024-06-13 17:24:46 +07:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-07-05 14:51:25 +07:00
|
|
|
<div v-html="designObject.styleClasses" style="display: none" v-if="designObject.styles"></div>
|
2024-06-13 17:24:46 +07:00
|
|
|
</section>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.section-container {
|
2024-06-28 15:39:26 +07:00
|
|
|
.section-layout {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
2024-06-18 14:04:24 +07:00
|
|
|
/* gap: 10px; */
|
2024-06-13 17:24:46 +07:00
|
|
|
&.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;
|
2024-07-05 14:51:25 +07:00
|
|
|
padding: 9px 16px;
|
2024-06-13 17:24:46 +07:00
|
|
|
text-align: center;
|
|
|
|
|
line-height: 36px;
|
2024-07-05 14:51:25 +07:00
|
|
|
border-radius: 4px;
|
2024-06-13 17:24:46 +07:00
|
|
|
margin-left: 10px;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
2024-07-05 14:51:25 +07:00
|
|
|
gap: 8px;
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
background: #f2f2f2;
|
2024-06-28 15:39:26 +07:00
|
|
|
cursor: pointer;
|
2024-07-05 14:51:25 +07:00
|
|
|
color: #222222;
|
2024-06-28 15:39:26 +07:00
|
|
|
&.active {
|
2024-07-05 14:51:25 +07:00
|
|
|
background: #ed1c24;
|
2024-06-28 15:39:26 +07:00
|
|
|
color: white;
|
|
|
|
|
}
|
2024-06-13 17:24:46 +07:00
|
|
|
}
|
|
|
|
|
}
|
2024-06-28 15:39:26 +07:00
|
|
|
.el-empty {
|
|
|
|
|
padding: 12px 0;
|
|
|
|
|
}
|
2024-06-13 17:24:46 +07:00
|
|
|
</style>
|