14 Commits

Author SHA1 Message Date
Duong Truong Phong 0ad19bbcfd phongdt:fix paging 2024-07-05 15:30:58 +07:00
phongdt 11ea05de83 Merge pull request 'phongdt' (#8) from phongdt into main
Reviewed-on: http://work.gct.com.vn/minhnt/NSG_PORTAL_V2/pulls/8
2024-07-05 15:13:26 +07:00
Duong Truong Phong e738cca263 Merge branch 'phongdt' of http://work.gct.com.vn/minhnt/NSG_PORTAL_V2 into phongdt 2024-07-05 15:13:00 +07:00
Duong Truong Phong b93f0218a5 phongdt:paging 2024-07-05 15:12:49 +07:00
Duong Truong Phong 3fe4da0ecb phongdt: paging component 2024-07-05 15:12:49 +07:00
Duong Truong Phong a9d6bea337 phongdt:paging 2024-07-05 15:12:16 +07:00
nguyen van thai df31b7bdef . 2024-07-05 15:03:50 +07:00
MoreStrive a1c6e2872f feat: full size 2024-07-05 15:01:01 +07:00
Duong Truong Phong 46b808cf9c phongdt: paging component 2024-07-05 14:51:25 +07:00
MoreStrive 367374863e Merge branch 'main' of http://work.gct.com.vn/minhnt/NSG_PORTAL_V2 2024-07-05 14:29:53 +07:00
MoreStrive 66b5a8ce6a feat: widget 2024-07-05 14:29:49 +07:00
nguyen van thai adecec9041 Layout Page Component 2024-07-05 14:17:41 +07:00
MoreStrive 984ec50a39 Merge branch 'main' of http://work.gct.com.vn/minhnt/NSG_PORTAL_V2 2024-07-05 13:05:28 +07:00
MoreStrive a756c91bd0 feat: widget 2024-07-05 13:05:21 +07:00
12 changed files with 269 additions and 179 deletions
@@ -1,31 +1,29 @@
<script setup lang="ts">
import { nanoid } from 'nanoid';
import JSWidget from '@/components/widget/JSwidget.vue';
const widgetOptions = {
"locale": "vi",
"width": "334px",
"height": "250px",
"price_line_color": "#71BDDF",
"grid_color": "#999999",
"label_color": "#999999",
"width": "350px",
"height": "250px"
}
</script>
<template>
<div>
<JSWidget
CONTAINER_ID="default_widget_[123123]"
SCRIPT_ID="12312312"
:CONTAINER_ID="nanoid(10)"
:SCRIPT_ID="nanoid(10)"
SCRIPT_SRC="https://www.fireant.vn/Scripts/web/widgets.js"
:options="widgetOptions"
:inside="false"
widgetKey="FireAnt"
/>
</div>
</template>
<style lang="scss" scoped>
div {
width: 100%;
height: 200px;
background-color: #ededed;
font-size: 24px;
display: flex;
align-items: center;
@@ -0,0 +1,56 @@
<script setup lang="ts">
import { nanoid } from 'nanoid';
import JSWidget from '@/components/widget/JSwidget.vue';
const widgetOptions = {
"symbols": [
{
"proName": "FOREXCOM:SPXUSD",
"title": "S&P 500 Index"
},
{
"proName": "FOREXCOM:NSXUSD",
"title": "US 100 Cash CFD"
},
{
"proName": "FX_IDC:EURUSD",
"title": "EUR to USD"
},
{
"proName": "BITSTAMP:BTCUSD",
"title": "Bitcoin"
},
{
"proName": "BITSTAMP:ETHUSD",
"title": "Ethereum"
}
],
"isTransparent": false,
"showSymbolLogo": true,
"colorTheme": "dark",
"locale": "en"
}
</script>
<template>
<div>
<JSWidget
:CONTAINER_ID="nanoid(10)"
:SCRIPT_ID="nanoid(10)"
SCRIPT_SRC="https://s3.tradingview.com/external-embedding/embed-widget-tickers.js"
:options="widgetOptions"
:inside="true"
widgetKey="TradingView"
/>
</div>
</template>
<style lang="scss" scoped>
div {
width: 100%;
font-size: 24px;
display: flex;
align-items: center;
justify-content: center;
}
</style>
@@ -1 +1,2 @@
export { default as Stock_Default } from './334x641.vue'
export { default as Stock_FullSize } from './Full.vue'
@@ -1,6 +1,6 @@
<script lang="ts" setup>
import { enumPageComponentTemplate, enumPageComponentKey, enumPageComponentLayouts } from "@/definitions/enum";
import { Stock_Default } from "./index";
import { Stock_Default, Stock_FullSize } from "./index";
const _props = defineProps<{
settings: any;
@@ -9,6 +9,7 @@ const _props = defineProps<{
}>();
const definedDynamicComponent: Record<string, any> = {
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.OTHER]['STOCK']]['STOCK_DEFAULT']]: Stock_Default,
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.OTHER]["STOCK"]]["STOCK_FULLSIZE"]]: Stock_FullSize,
};
const getCurrentComponent = computed(() => `${_props.settings.layout}`);
@@ -1,25 +1,29 @@
<script setup lang="ts">
import { isEmpty } from "@/utils/lodash";
import DynamicComponent from "~/components/dynamic-page/page-component/templates/index.vue";
import { COLLECTION_PAGING_QUERY_DROP, getInputValue } from "@/utils/parseSQL";
import { getInputValue } from "@/utils/parseSQL";
import { enumPageComponentTemplates } from "@/definitions/enum";
const router = useRouter();
const route = useRoute();
// const store = reactive({
// component: usePageComponentStore(),
// });
const store = reactive({
component: useDynamicPageStore(),
});
const _props = defineProps<{
dataResult?: any;
dataResult?: any[];
dataQuery?: string;
component?: any;
label?: any;
label?: string;
}>();
const SETTING_OPTIONS = {
MAX_ELEMENT: 5,
TEMPLATE: "Article",
LAYOUT: "TYPE:Card",
TEMPLATE: "TYPE:Card",
LAYOUT: "TYPE:Card_Default",
};
const COMPONENT = {
taxonomy: enumPageComponentTemplates.ARTICLE,
};
const page = ref(1);
@@ -60,14 +64,11 @@ const handleRouteChange = async (query: any) => {
const param = query[`cpn_${_props.component?.id}`];
if (param) {
const [_, value] = param.split(":") || [];
page.value = value;
page.value = Number(value);
await loadPage(value);
}
};
onBeforeMount(() => {
if (route.query[`cpn_${_props.component?.id}`]) handleRouteChange(route.query);
});
const loadPage = async (page: number) => {
let newDataQuery = "";
@@ -79,14 +80,17 @@ const loadPage = async (page: number) => {
} else {
newDataQuery = _props.component?.settings?.dataQuery + ` Page[${page}]`;
}
// const res = await store.component.getOverviewPageComponentById(Number(_props.component?.id), newDataQuery);
// const data = getInputValue(res?.settings?.dataResult, "OBJECT");
// if (Object.keys(data).length > 0) {
// totals.value = data.Total;
// listArticlePaging.value = data?.Data || [];
// }
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 === "+") {
@@ -107,51 +111,32 @@ const mapActivesToItems = (index: number) => {
</script>
<template>
<section>
<div class="section-container" :class="[listArticleByCategory && listArticleByCategory?.length > 0 ? '' : 'noData']">
<section v-if="listArticleByCategory?.length > 0">
<div class="section-container">
<div class="section-layout" :style="designObject['div.section']">
<template v-if="listArticleByCategory?.length > 0">
<template v-for="(component, index) in listArticlePaging?.length > 0 ? listArticlePaging : listArticleByCategory">
<template v-for="(component, index) in listArticlePaging?.length > 0 ? listArticlePaging : listArticleByCategory" :key="index">
<DynamicComponent
:key="index"
v-if="!isEmpty(component)"
:settings="{
template: SETTING_OPTIONS.TEMPLATE,
layout: SETTING_OPTIONS.LAYOUT,
dataResult: { ...component },
label: mapActivesToItems(Number(index)),
}"
:component="COMPONENT"
/>
</template>
</template>
<template v-else>
<div class="empty"><h6 class="px-2 text-center">Nội dung danh sách bài viết của danh mục sẽ đây</h6></div>
</template>
<div class="button-page flex">
<a class="btn-page prev-page" @click.stop="() => handleNextPrev('-')" v-if="page > 1">
<i class="el-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
<path
fill="currentColor"
d="M609.408 149.376 277.76 489.6a32 32 0 0 0 0 44.672l331.648 340.352a29.12 29.12 0 0 0 41.728 0 30.592 30.592 0 0 0 0-42.752L339.264 511.936l311.872-319.872a30.592 30.592 0 0 0 0-42.688 29.12 29.12 0 0 0-41.728 0z"
></path>
</svg>
</i>
</a>
<a v-if="listArticleByCategory?.length > 0" :class="['btn-page', page === index + 1 && 'active']" @click.stop="() => select(index + 1)" v-for="(_, index) in Math.ceil(totals / limit)">{{ index + 1 }}</a>
<a class="btn-page next-page" @click.stop="() => handleNextPrev('+')" v-if="page < Math.ceil(totals / limit)">
<i class="el-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
<path
fill="currentColor"
d="M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-44.672L382.592 149.376a29.12 29.12 0 0 0-41.728 0z"
></path>
</svg>
</i>
</a>
<span class="btn-page prev-page" @click.stop="() => handleNextPrev('-')" v-if="page > 1">
<Icon name="ooui:previous-ltr"></Icon>
</span>
<span :class="['btn-page', page === index + 1 && 'active']" @click.stop="() => select(index + 1)" v-for="(_, index) in Math.ceil(totals / limit)">{{ index + 1 }}</span>
<span class="btn-page next-page" @click.stop="() => handleNextPrev('+')" v-if="page < Math.ceil(totals / limit)">
<Icon name="ooui:previous-rtl"></Icon>
</span>
</div>
</div>
</div>
<div v-html="designObject.styleClasses" style="display: none" v-if="designObject.styles"></div>
</section>
</template>
@@ -161,35 +146,9 @@ const mapActivesToItems = (index: number) => {
display: flex;
flex-direction: column;
/* gap: 10px; */
overflow-x: scroll;
&.border-custom {
border-color: #e5e5e5 !important;
}
&.borderLeft {
border-left: 1px solid;
}
&.borderRight {
border-right: 1px solid;
}
&.borderTop {
border-top: 1px solid;
}
&.borderBottom {
border-bottom: 1px solid;
}
}
.empty {
width: 100%;
height: 100%;
min-height: 50px;
background-color: #409eff;
display: flex;
white-space: normal;
justify-content: center;
align-items: center;
h6 {
color: #fff;
}
}
.basic-article {
&.article {
@@ -198,9 +157,6 @@ const mapActivesToItems = (index: number) => {
pointer-events: none;
}
}
&.noData {
border-radius: 6px;
}
.flex {
display: flex;
@@ -218,17 +174,21 @@ const mapActivesToItems = (index: number) => {
.btn-page {
width: 40px;
height: 40px;
padding: 9px 16px;
text-align: center;
line-height: 36px;
border: 1px solid #409eff;
border-radius: 3px;
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: #409eff;
background: #ed1c24;
color: white;
}
}
+12 -7
View File
@@ -4,7 +4,7 @@
SCRIPT_SRC?: any,
CONTAINER_ID?: any,
options?: any,
inside?: boolean,
widgetKey?: any
}>()
@@ -48,7 +48,10 @@
script.async = true;
script.src = props.SCRIPT_SRC;
script.onload = onload;
document.getElementsByTagName('head')[0].appendChild(script);
if (props.inside) document.getElementById(props.CONTAINER_ID) && document.getElementById(props.CONTAINER_ID).appendChild(script);
else {
document.getElementsByTagName('body')[0].appendChild(script);
}
}
const initWidget = (key: any) => {
if (typeof widgets[key].key === 'undefined') {
@@ -60,16 +63,18 @@
onMounted(async () => {
await Object.assign(widgets, {
FireAnt: {
script: () => new window.FireAnt.MarketsWidget(Object.assign({ container_id: props.CONTAINER_ID }, props.options)),
script: () => new window.FireAnt.MarketsWidget({ container_id: props.CONTAINER_ID, ...props.options }),
key: window.FireAnt
}})
},
TradingView: {
script: () => new window.TradingView.widget({ container_id: props.CONTAINER_ID, ...props.options }),
key: window.TradingView
}
})
appendScript(initWidget(props.widgetKey));
// instance.proxy.$forceUpdate();
})
</script>
<template>
<ClientOnly>
<div :key="props.CONTAINER_ID" :id="props.CONTAINER_ID"></div>
</ClientOnly>
</template>
+33
View File
@@ -0,0 +1,33 @@
// <div class="tradingview-widget-container">
// <script type="text/javascript" src="https://s3.tradingview.com/external-embedding/embed-widget-ticker-tape.js" async>
// {
// "symbols": [
// {
// "proName": "FOREXCOM:SPXUSD",
// "title": "S&P 500 Index"
// },
// {
// "proName": "FOREXCOM:NSXUSD",
// "title": "US 100 Cash CFD"
// },
// {
// "proName": "FX_IDC:EURUSD",
// "title": "EUR to USD"
// },
// {
// "proName": "BITSTAMP:BTCUSD",
// "title": "Bitcoin"
// },
// {
// "proName": "BITSTAMP:ETHUSD",
// "title": "Ethereum"
// }
// ],
// "showSymbolLogo": true,
// "isTransparent": false,
// "displayMode": "adaptive",
// "colorTheme": "dark",
// "locale": "en"
// }
// </script>
// </div>
+2 -1
View File
@@ -294,6 +294,7 @@ export const pageComponentLayouts = {
{ title: "Thời tiết", value: enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.OTHER]['WEATHER']}`]['WEATHER_DEFAULT'] }
],
[`${enumPageComponentTemplate[enumPageComponentKey.OTHER]['STOCK']}`]: [
{ title: "Chứng khoán", value: enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.OTHER]['STOCK']}`]['STOCK_DEFAULT'] }
{ title: "Chứng khoán", value: enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.OTHER]['STOCK']}`]['STOCK_DEFAULT'] },
{ title: "Chứng khoán Full Size", value: enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.OTHER]['STOCK']}`]['STOCK_FULLSIZE'] }
],
};
+1
View File
@@ -382,6 +382,7 @@ export const enumPageComponentLayouts = {
},
[`${enumPageComponentTemplate[enumPageComponentKey.OTHER]['STOCK']}`]: {
'STOCK_DEFAULT': "TYPE:Stock_Default",
'STOCK_FULLSIZE': "TYPE:Stock_Fullsize",
},
};
+1
View File
@@ -26,6 +26,7 @@
"@vueuse/nuxt": "10.5.0",
"axios": "^1.5.1",
"cheerio": "^1.0.0-rc.12",
"nanoid": "^5.0.7",
"nuxt-delay-hydration": "latest",
"sass": "latest",
"sass-loader": "latest",
+17 -2
View File
@@ -97,7 +97,7 @@ interface Page extends Base {
sections?: PageSection[];
}
export const getDynamicPageByCode = async (event : any) => {
export const getDynamicPageByCode = async (event: any) => {
try {
const { apiUrl } = useRuntimeConfig().public
const slug = event.context.params.slug;
@@ -112,7 +112,7 @@ export const getDynamicPageByCode = async (event : any) => {
}
}
export const getDynamicPageById = async (event : any) => {
export const getDynamicPageById = async (event: any) => {
try {
const { apiUrl } = useRuntimeConfig().public
const id = event.context.params.id;
@@ -122,3 +122,18 @@ export const getDynamicPageById = async (event : any) => {
handleError(error);
}
}
export async function getOverviewPageComponentById(event: any) {
try {
const { apiUrl } = useRuntimeConfig().public
const { componentId, dataQuery } = getQuery(event)
return await $fetch(`${apiUrl}/cms/overview-page-component/${componentId}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: dataQuery,
});
} catch (err) {
handleError(err);
}
}
+18
View File
@@ -60,6 +60,23 @@ export const useDynamicPageStore = defineStore("dynamicPageStore", () => {
} catch (error: any) {}
}
async function getOverviewPageComponentById(componentId, dataQuery) {
try {
const { apiUrl } = useRuntimeConfig().public
const res = await $fetch(`${apiUrl}/cms/page-component/overview-page-component/${componentId}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(dataQuery),
});
return res
} catch (err) {
throw err;
}
}
return {
currentPage,
sectionPublished,
@@ -69,6 +86,7 @@ export const useDynamicPageStore = defineStore("dynamicPageStore", () => {
setSectionPublished,
setComponentPublished,
setDataQuery,
getOverviewPageComponentById
};
});