125 lines
3.9 KiB
Vue
125 lines
3.9 KiB
Vue
<script lang="ts" setup>
|
|
import { enumPageComponentTemplates } from "@/definitions/enum";
|
|
import { DEFAULT_QUERY_DROP, getInputValue } from '@/utils/parseSQL';
|
|
|
|
const props = defineProps<{
|
|
dataResult?: any
|
|
dataType?: any
|
|
dataQuery?: any
|
|
layout?: string
|
|
}>()
|
|
|
|
const LAYOUT_PARSE = computed(() => {
|
|
const parseLayout = props.layout?.split('-')?.map((_layout : any) => {
|
|
const parseItem = _layout.split(':')
|
|
return {
|
|
[parseItem[0]]: parseItem[0] === 'HIDE' ? parseItem[1].split(',') : parseItem[1],
|
|
};
|
|
}) || [];
|
|
return Object.assign({}, ...parseLayout);
|
|
})
|
|
|
|
const emit = defineEmits(['selectComponent', 'dropData']);
|
|
|
|
const selectComponent = () => {
|
|
emit('selectComponent');
|
|
}
|
|
|
|
const parseData = computed(() => {
|
|
if(!props.dataResult) return
|
|
const result = getInputValue(props.dataResult, 'OBJECT');
|
|
return result
|
|
})
|
|
|
|
const drop = (e: any) => {
|
|
if (e.dataTransfer.getData(`${enumPageComponentTemplates.ARTICLE}`)) {
|
|
const data = e.dataTransfer.getData(`${enumPageComponentTemplates.ARTICLE}`);
|
|
const { dataType, dataResult } = JSON.parse(data);
|
|
const dataQuery = DEFAULT_QUERY_DROP(dataType, dataResult.id);
|
|
emit('dropData', {
|
|
dataType,
|
|
dataResult,
|
|
dataQuery: dataQuery,
|
|
});
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<article class="basic-article gap-x-4" :class="[LAYOUT_PARSE['LAYOUT'] || 'horizontal', !parseData && 'no-data', LAYOUT_PARSE['REVERSE'] ? 'reverse' : '']">
|
|
<div v-if="!LAYOUT_PARSE['HIDE'] || !LAYOUT_PARSE['HIDE'].includes('thumbnail')" class="basic-article_thumbnail">
|
|
<template v-if="parseData">
|
|
<img class="object-fit-cover" :src="parseData.thumbnail ? parseData.thumbnail : '/images/default-thumbnail.jpg'" :alt="parseData.title?.replace(/<[^>]+>/g, '')" />
|
|
</template>
|
|
</div>
|
|
<div class="basic-article_content" :class="[!parseData && 'no-data']">
|
|
<div>
|
|
<template v-if="parseData">
|
|
<nuxt-link :to="`/bai-viet/${parseData.slug}`">
|
|
<h3 v-if="!LAYOUT_PARSE['HIDE'] || !LAYOUT_PARSE['HIDE'].includes('title')" class="mb-1 line-clamp-2 text-base font-600 hover:text-primary-100 transition-all duration-300">
|
|
{{ parseData.title?.replace(/<[^>]+>/g, '') }}
|
|
</h3>
|
|
</nuxt-link>
|
|
</template>
|
|
<p v-if="!LAYOUT_PARSE['HIDE'] || !LAYOUT_PARSE['HIDE'].includes('paragraph')" class="mb-0 line-clamp-2">
|
|
<template v-if="parseData">
|
|
<template v-if="parseData.intro">
|
|
{{ parseData.intro?.replace(/<[^>]+>/g, '') }}
|
|
</template>
|
|
<template v-if="parseData.sub">
|
|
{{ parseData.sub?.replace(/<[^>]+>/g, '') }}
|
|
</template>
|
|
</template>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.basic-article {
|
|
display: grid;
|
|
height: 100%;
|
|
|
|
&.vertical {
|
|
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
.basic-article_content {
|
|
padding: 10px 0px;
|
|
}
|
|
}
|
|
|
|
&.horizontal {
|
|
grid-template-columns: 1fr 1fr;
|
|
.basic-article_content {
|
|
padding: 0px 0px;
|
|
}
|
|
|
|
&.reverse {
|
|
.basic-article_thumbnail {
|
|
grid-column: 2;
|
|
}
|
|
|
|
.basic-article_content {
|
|
grid-row: 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
&_thumbnail {
|
|
flex: 1;
|
|
|
|
img {
|
|
width: 100%;
|
|
border-radius: 6px;
|
|
aspect-ratio: 16/10;
|
|
}
|
|
}
|
|
|
|
.empty-block {
|
|
background-color: #409eff;
|
|
height: 100px;
|
|
display: block;
|
|
}
|
|
}
|
|
</style>
|