This commit is contained in:
MoreStrive
2024-05-30 18:06:50 +07:00
parent 8ca31c6b18
commit 2aa5607c48
147 changed files with 5815 additions and 1 deletions
@@ -0,0 +1,86 @@
<script setup lang="ts">
import DynamicComponent from "~/components/dynamic-page/page-component/templates/index.vue";
import { COLLECTION_QUERY_DROP, getValueStringWithKeyAndColon, getInputValue } from '@/utils/parseSQL';
import { isEmpty } from "lodash";
const _props = defineProps<{
dataResult?: any[];
dataQuery?: string;
layout?: string;
}>();
const SETTING_OPTIONS = {
MAX_ELEMENT: 5,
TEMPLATE: "Article",
LAYOUT: "LAYOUT:vertical"
};
const LAYOUT_PARSE = computed(() => {
const parseLayout = _props.layout?.split("-")?.map((_layout: any) => {
const parseItem = _layout.split(":");
return {
[parseItem[0]]: parseItem[1],
};
});
return Object.assign({}, ...parseLayout);
});
const _dataResult = computed(() => {
let _components = Array(Number(LAYOUT_PARSE.value.MAX) || SETTING_OPTIONS.MAX_ELEMENT).fill(null);
const result = getInputValue(_props.dataResult, 'ARRAY');
result && result.length > 0 && _components.map((_ : any, index : any) => {
_components[index] = result[index] || null;
})
return _components;
});
</script>
<template>
<div>
<div class="collection-container p-2" :class="LAYOUT_PARSE['LAYOUT'] || 'horizontal'">
<div v-for="(component, index) in _dataResult" :key="index">
<template v-if="!isEmpty(component)">
<DynamicComponent
:settings="{
template: LAYOUT_PARSE.TYPE || SETTING_OPTIONS.TEMPLATE,
layout: `LAYOUT:${LAYOUT_PARSE.DATA.toLowerCase()}` || SETTING_OPTIONS.LAYOUT,
dataResult: { ...component },
}"
@drop-data="dropData"
/>
</template>
<template v-else>
<DynamicComponent
:settings="{
template: LAYOUT_PARSE.TYPE || SETTING_OPTIONS.TEMPLATE,
layout: `LAYOUT:${LAYOUT_PARSE.DATA.toLowerCase()}` || SETTING_OPTIONS.LAYOUT,
}"
@drop-data="dropData"
/>
</template>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.collection-container {
display: grid;
gap: 10px;
&.vertical {
grid-template-columns: repeat(1, minmax(0, 1fr));
}
&.horizontal {
grid-template-rows: auto;
grid-auto-flow: column;
}
.empty {
min-height: 100px;
border-radius: 6px;
background: #409eff;
}
&.noData {
border-radius: 6px;
}
}
</style>
@@ -0,0 +1,136 @@
<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" :class="[LAYOUT_PARSE['LAYOUT'] || 'horizontal', !parseData && 'no-data', LAYOUT_PARSE['REVERSE'] ? 'reverse' : '']" @click="selectComponent" @dragover.prevent @drop.stop.prevent="drop">
<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>
<span v-else class="empty-block" style="width: 100%; height: 100%; min-height: 50px;"></span>
</div>
<div class="basic-article_content" :class="[!parseData && 'no-data']">
<div>
<h3 v-if="!LAYOUT_PARSE['HIDE'] || !LAYOUT_PARSE['HIDE'].includes('title')" class="mb-1 text-truncate-two-lines">
<template v-if="parseData">
{{ parseData.title?.replace(/<[^>]+>/g, '') }}
</template>
<span v-else class="empty-block" style="height: 8px;"></span>
</h3>
<p v-if="!LAYOUT_PARSE['HIDE'] || !LAYOUT_PARSE['HIDE'].includes('paragraph')" class="mb-0 text-truncate-two-lines">
<template v-if="parseData">
{{ parseData.intro?.replace(/<[^>]+>/g, '') }}
</template>
<span v-else class="empty-block" style="height: 5px;"></span>
</p>
</div>
</div>
</article>
</template>
<style lang="scss" scoped>
.basic-article {
display: grid;
gap: 10px;
height: 100%;
&.no-data {
gap: 5px !important;
}
&.vertical {
grid-template-columns: repeat(1, minmax(0, 1fr));
}
&.horizontal {
grid-template-columns: 1fr 1fr;
&.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;
}
}
&_content {
padding: 10px 0px;
&.no-data {
padding: 0px;
}
h3 {
font-size: 15px;
}
p {
font-size: 12px;
margin-top: 10px;
}
}
.empty-block {
background-color: #409eff;
height: 100px;
display: block;
}
}
</style>