fix reactivity

This commit is contained in:
Emily
2024-08-07 15:06:06 +02:00
parent 0c8ec73722
commit 4c9efda9ca
13 changed files with 257 additions and 266 deletions

View File

@@ -256,7 +256,7 @@ watch(selected, () => {
<div v-if="(!entry.adminOnly || (isAdmin && !isAdminHidden))"
class="bg-lyx-background cursor-pointer text-lyx-text-dark py-[.35rem] px-2 rounded-lg text-[.95rem] flex items-center"
:class="{
'text-gray-700 pointer-events-none': entry.disabled,
'!text-lyx-text-darker pointer-events-none': entry.disabled,
'bg-lyx-background-lighter !text-lyx-text/90': route.path == (entry.to || '#'),
'hover:bg-lyx-background-light hover:!text-lyx-text/90': route.path != (entry.to || '#'),
}">

View File

@@ -2,8 +2,6 @@
import type { IconProvider } from './BarsCard.vue';
const { data: countries, pending, refresh } = useGeolocationData(10);
function iconProvider(id: string): ReturnType<IconProvider> {
if (id === 'self') return ['icon', 'fas fa-link'];
return [
@@ -14,32 +12,51 @@ function iconProvider(id: string): ReturnType<IconProvider> {
const customIconStyle = `width: 2rem; padding: 1px;`
const activeProject = useActiveProject();
const { safeSnapshotDates } = useSnapshot()
const isShowMore = ref<boolean>(false);
const headers = computed(() => {
return {
'x-from': safeSnapshotDates.value.from,
'x-to': safeSnapshotDates.value.to,
Authorization: authorizationHeaderComputed.value,
limit: isShowMore.value === true ? '200' : '10'
}
});
const geolocationData = useFetch(`/api/metrics/${activeProject.value?._id}/data/countries`, {
method: 'POST', headers, lazy: true, immediate: false
});
const { showDialog, dialogBarData, isDataLoading } = useBarCardDialog();
function showMore() {
isShowMore.value = true;
showDialog.value = true;
dialogBarData.value = [];
isDataLoading.value = true;
const moreRes = useGeolocationData(200);
moreRes.onResponse(data => {
dialogBarData.value = data.value?.map(e => {
return { ...e, icon: iconProvider(e._id) }
}) || [];
isDataLoading.value = false;
})
dialogBarData.value = geolocationData.data.value?.map(e => {
return { ...e, icon: iconProvider(e._id) }
}) || [];
isDataLoading.value = false;
}
onMounted(async () => {
geolocationData.execute();
});
</script>
<template>
<div class="flex flex-col gap-2">
<DashboardBarsCard @showMore="showMore()" @dataReload="refresh" :data="countries || []" :dataIcons="false"
:loading="pending" label="Top Countries" sub-label="Countries" :iconProvider="iconProvider"
<DashboardBarsCard @showMore="showMore()" @dataReload="geolocationData.refresh()" :data="geolocationData.data.value || []" :dataIcons="false"
:loading="geolocationData.pending.value" label="Top Countries" sub-label="Countries" :iconProvider="iconProvider"
:customIconStyle="customIconStyle" desc=" Lists the countries where users access your website.">
</DashboardBarsCard>
</div>

View File

@@ -34,11 +34,11 @@ const referrersData = useFetch(`/api/metrics/${activeProject.value?._id}/data/re
const { showDialog, dialogBarData, isDataLoading } = useBarCardDialog();
const customDialog = useCustomDialog();
// const customDialog = useCustomDialog();
function onShowDetails(referrer: string) {
customDialog.openDialog(ReferrerBarChart, { slice: 'day', referrer });
}
// function onShowDetails(referrer: string) {
// customDialog.openDialog(ReferrerBarChart, { slice: 'day', referrer });
// }
function showMore() {
@@ -59,10 +59,10 @@ onMounted(async () => {
<template>
<div class="flex flex-col gap-2">
<DashboardBarsCard @showDetails="onShowDetails" @showMore="showMore()"
<DashboardBarsCard @showMore="showMore()"
:elementTextTransformer="elementTextTransformer" :iconProvider="iconProvider"
@dataReload="referrersData.refresh()" :showLink=true :data="referrersData.data.value || []"
:interactive="true" desc="Where users find your website." :dataIcons="true" :loading="referrersData.pending.value"
:interactive="false" desc="Where users find your website." :dataIcons="true" :loading="referrersData.pending.value"
label="Top Referrers" sub-label="Referrers"></DashboardBarsCard>
</div>
</template>

View File

@@ -112,7 +112,7 @@ onMounted(async () => {
<template>
<div class="gap-6 px-6 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-2 m-cards-wrap:grid-cols-4" v-if="metricsInfo">
<div class="gap-6 px-6 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-2 m-cards-wrap:grid-cols-4">
<DashboardCountCard :ready="!visitsData.pending.value" icon="far fa-earth" text="Total page visits"
:value="formatNumberK(visitsData.data.value?.data.reduce((a, e) => a + e, 0) || '...')"

View File

@@ -2,41 +2,57 @@
import type { VisitsWebsiteAggregated } from '~/server/api/metrics/[project_id]/data/websites';
const { data: websites, pending, refresh } = useWebsitesData();
const activeProject = useActiveProject();
const currentViewData = ref<(VisitsWebsiteAggregated[] | undefined)>(websites.value);
const { safeSnapshotDates } = useSnapshot()
const isShowMore = ref<boolean>(false);
const currentWebsite = ref<string>("");
const websitesHeaders = computed(() => {
return {
'x-from': safeSnapshotDates.value.from,
'x-to': safeSnapshotDates.value.to,
Authorization: authorizationHeaderComputed.value,
limit: isShowMore.value === true ? '200' : '10'
}
});
const pagesHeaders = computed(() => {
return {
'x-from': safeSnapshotDates.value.from,
'x-to': safeSnapshotDates.value.to,
Authorization: authorizationHeaderComputed.value,
limit: isShowMore.value === true ? '200' : '10',
'x-website-name': currentWebsite.value
}
});
const websitesData = useFetch(`/api/metrics/${activeProject.value?._id}/data/websites`, {
method: 'POST', headers: websitesHeaders, lazy: true, immediate: false
});
const pagesData = useFetch(`/api/metrics/${activeProject.value?._id}/data/pages`, {
method: 'POST', headers: pagesHeaders, lazy: true, immediate: false
});
const isPagesView = ref<boolean>(false);
const isLoading = ref<boolean>(false);
const { snapshot } = useSnapshot()
watch(pending, () => {
isLoading.value = true;
currentViewData.value = websites.value;
isLoading.value = false;
});
watch(snapshot, () => {
refresh();
});
const currentData = computed(() => {
return isPagesView.value ? pagesData : websitesData
})
async function showDetails(website: string) {
if (isPagesView.value == true) return;
isLoading.value = true;
currentWebsite.value = website;
pagesData.execute();
isPagesView.value = true;
}
const { data: pagesData, pending } = usePagesData(website, 10);
watch(pending, () => {
isLoading.value = true;
currentViewData.value = pagesData.value as any;
isLoading.value = false;
})
async function showGeneral() {
websitesData.execute();
isPagesView.value = false;
}
const router = useRouter();
@@ -45,26 +61,18 @@ function goToView() {
router.push('/dashboard/visits');
}
function setDefaultData() {
currentViewData.value = websites.value;
isPagesView.value = false;
}
async function dataReload() {
await refresh();
setDefaultData();
}
onMounted(()=>{
websitesData.execute();
})
</script>
<template>
<div class="flex flex-col gap-2 h-full">
<DashboardBarsCard :hideShowMore="true" @showGeneral="setDefaultData()" @showRawData="goToView()"
@dataReload="dataReload()" @showDetails="showDetails" :data="currentViewData || []"
:loading="pending || isLoading" :label="isPagesView ? 'Top pages' : 'Top Websites'"
<DashboardBarsCard :hideShowMore="true" @showGeneral="showGeneral()" @showRawData="goToView()"
@dataReload="currentData.refresh()" @showDetails="showDetails" :data="currentData.data.value || []"
:loading="currentData.pending.value" :label="isPagesView ? 'Top pages' : 'Top Websites'"
:sub-label="isPagesView ? 'Page' : 'Website'"
:desc="isPagesView ? 'Most visited pages' : 'Most visited website in this project'"
:interactive="!isPagesView" :rawButton="!isLiveDemo()" :isDetailView="isPagesView">

View File

@@ -14,7 +14,6 @@ const body = computed(() => {
from: safeSnapshotDates.value.from,
to: safeSnapshotDates.value.to,
slice: slice.value,
Authorization: authorizationHeaderComputed.value,
}
});
@@ -54,7 +53,7 @@ function transformResponse(input: { _id: string, name: string, count: number }[]
}
const eventsStackedData = useFetch(`/api/metrics/${activeProject.value?._id}/timeline/events_stacked`, {
method: 'POST', body, lazy: true, immediate: false, transform: transformResponse
method: 'POST', body, lazy: true, immediate: false, transform: transformResponse, ...signHeaders()
});

View File

@@ -2,30 +2,30 @@
import { onMounted } from 'vue';
import DateService, { type Slice } from '@services/DateService';
const data = ref<number[]>([]);
const labels = ref<string[]>([]);
const ready = ref<boolean>(false);
// const data = ref<number[]>([]);
// const labels = ref<string[]>([]);
// const ready = ref<boolean>(false);
const props = defineProps<{ slice: Slice, referrer: string }>();
// const props = defineProps<{ slice: Slice, referrer: string }>();
async function loadData() {
const response = await useReferrersTimeline(props.referrer, props.slice);
if (!response) return;
data.value = response.map(e => e.count);
labels.value = response.map(e => DateService.getChartLabelFromISO(e._id, navigator.language, props.slice));
ready.value = true;
}
// async function loadData() {
// const response = await useReferrersTimeline(props.referrer, props.slice);
// if (!response) return;
// data.value = response.map(e => e.count);
// labels.value = response.map(e => DateService.getChartLabelFromISO(e._id, navigator.language, props.slice));
// ready.value = true;
// }
onMounted(async () => {
await loadData();
watch(props, async () => { await loadData(); });
})
// onMounted(async () => {
// await loadData();
// watch(props, async () => { await loadData(); });
// })
</script>
<template>
<div>
<AdvancedBarChart v-if="ready" :data="data" :labels="labels" color="#5680f8">
</AdvancedBarChart>
<!-- <AdvancedBarChart v-if="ready" :data="data" :labels="labels" color="#5680f8">
</AdvancedBarChart> -->
</div>
</template>