diff --git a/TODO b/TODO new file mode 100644 index 0000000..9b2580c --- /dev/null +++ b/TODO @@ -0,0 +1,4 @@ + + +- Slice change on Actionable Chart +- Show more on Dashboard cards \ No newline at end of file diff --git a/dashboard/components/dashboard/BarsCard.vue b/dashboard/components/BarCard/Base.vue similarity index 99% rename from dashboard/components/dashboard/BarsCard.vue rename to dashboard/components/BarCard/Base.vue index 34a8225..c09f158 100644 --- a/dashboard/components/dashboard/BarsCard.vue +++ b/dashboard/components/BarCard/Base.vue @@ -127,7 +127,7 @@ function openExternalLink(link: string) { formatNumberK(element.count) }}
- No visits yet + No data yet
diff --git a/dashboard/components/BarCard/Browsers.vue b/dashboard/components/BarCard/Browsers.vue new file mode 100644 index 0000000..83e2a30 --- /dev/null +++ b/dashboard/components/BarCard/Browsers.vue @@ -0,0 +1,30 @@ + + + + diff --git a/dashboard/components/BarCard/Devices.vue b/dashboard/components/BarCard/Devices.vue new file mode 100644 index 0000000..8da28c0 --- /dev/null +++ b/dashboard/components/BarCard/Devices.vue @@ -0,0 +1,31 @@ + + + + diff --git a/dashboard/components/BarCard/Events.vue b/dashboard/components/BarCard/Events.vue new file mode 100644 index 0000000..cc67274 --- /dev/null +++ b/dashboard/components/BarCard/Events.vue @@ -0,0 +1,35 @@ + + + + diff --git a/dashboard/components/dashboard/GeolocationBarCard.vue b/dashboard/components/BarCard/Geolocations.vue similarity index 56% rename from dashboard/components/dashboard/GeolocationBarCard.vue rename to dashboard/components/BarCard/Geolocations.vue index 1542a3c..c7af0e3 100644 --- a/dashboard/components/dashboard/GeolocationBarCard.vue +++ b/dashboard/components/BarCard/Geolocations.vue @@ -1,6 +1,6 @@ diff --git a/dashboard/components/BarCard/OperatingSystems.vue b/dashboard/components/BarCard/OperatingSystems.vue new file mode 100644 index 0000000..7e0806a --- /dev/null +++ b/dashboard/components/BarCard/OperatingSystems.vue @@ -0,0 +1,30 @@ + + + + diff --git a/dashboard/components/BarCard/Referrers.vue b/dashboard/components/BarCard/Referrers.vue new file mode 100644 index 0000000..1ca69de --- /dev/null +++ b/dashboard/components/BarCard/Referrers.vue @@ -0,0 +1,44 @@ + + + + diff --git a/dashboard/components/BarCard/Websites.vue b/dashboard/components/BarCard/Websites.vue new file mode 100644 index 0000000..678a443 --- /dev/null +++ b/dashboard/components/BarCard/Websites.vue @@ -0,0 +1,59 @@ + + + + diff --git a/dashboard/components/dashboard/ActionableChart.vue b/dashboard/components/dashboard/ActionableChart.vue index 73a4718..68150b7 100644 --- a/dashboard/components/dashboard/ActionableChart.vue +++ b/dashboard/components/dashboard/ActionableChart.vue @@ -3,12 +3,8 @@ import { onMounted } from 'vue'; import DateService, { type Slice } from '@services/DateService'; import type { ChartData, ChartOptions, TooltipModel } from 'chart.js'; import { useLineChart, LineChart } from 'vue-chart-3'; -registerChartComponents(); -const errorData = ref<{ errored: boolean, text: string }>({ - errored: false, - text: '' -}) +const errorData = ref<{ errored: boolean, text: string }>({ errored: false, text: '' }) const chartOptions = ref>({ responsive: true, @@ -102,7 +98,6 @@ const chartData = ref>({ ], }); - const { lineChartProps, lineChartRef, update: updateChart } = useLineChart({ chartData: (chartData as any), options: chartOptions }); const externalTooltipElement = ref(null); @@ -135,8 +130,6 @@ function externalTooltipHandler(context: { chart: any, tooltip: TooltipModel<'li tooltipEl.style.padding = tooltip.options.padding + 'px ' + tooltip.options.padding + 'px'; } - - const selectLabels: { label: string, value: Slice }[] = [ { label: 'Hour', value: 'hour' }, { label: 'Day', value: 'day' }, @@ -144,14 +137,9 @@ const selectLabels: { label: string, value: Slice }[] = [ ]; const selectedLabelIndex = ref(1); - - -const activeProject = useActiveProject(); - -const { safeSnapshotDates } = useSnapshot() - const allDatesFull = ref([]); + function transformResponse(input: { _id: string, count: number }[]) { const data = input.map(e => e.count); const labels = input.map(e => DateService.getChartLabelFromISO(e._id, navigator.language, selectLabels[selectedLabelIndex.value].value)); @@ -159,50 +147,31 @@ function transformResponse(input: { _id: string, count: number }[]) { return { data, labels } } -const body = computed(() => { - return { - from: safeSnapshotDates.value.from, - to: safeSnapshotDates.value.to, - slice: selectLabels[selectedLabelIndex.value].value - } -}); - - function onResponseError(e: any) { - console.log('ON RESPONSE ERROR') errorData.value = { errored: true, text: e.response._data.message ?? 'Generic error' } } function onResponse(e: any) { - console.log('ON RESPONSE') if (e.response.status != 500) errorData.value = { errored: false, text: '' } } -const visitsData = useFetch(`/api/metrics/${activeProject.value?._id}/timeline/visits`, { - method: 'POST', ...signHeaders({ v2: 'true' }), body, transform: transformResponse, - lazy: true, immediate: false, - onResponseError, - onResponse + +const visitsData = useFetch('/api/timeline/visits', { + headers: useComputedHeaders({ slice: selectLabels[selectedLabelIndex.value].value }), lazy: true, + transform: transformResponse, onResponseError, onResponse }); -const eventsData = useFetch(`/api/metrics/${activeProject.value?._id}/timeline/events`, { - method: 'POST', ...signHeaders({ v2: 'true' }), body, transform: transformResponse, - lazy: true, immediate: false, - onResponseError, - onResponse +const sessionsData = useFetch('/api/timeline/sessions', { + headers: useComputedHeaders({ slice: selectLabels[selectedLabelIndex.value].value }), lazy: true, + transform: transformResponse, onResponseError, onResponse }); -const sessionsData = useFetch(`/api/metrics/${activeProject.value?._id}/timeline/sessions`, { - method: 'POST', ...signHeaders({ v2: 'true' }), body, transform: transformResponse, - lazy: true, immediate: false, - onResponseError, - onResponse +const eventsData = useFetch('/api/timeline/events', { + headers: useComputedHeaders({ slice: selectLabels[selectedLabelIndex.value].value }), lazy: true, + transform: transformResponse, onResponseError, onResponse }); - -const readyToDisplay = computed(() => { - return !visitsData.pending.value && !eventsData.pending.value && !sessionsData.pending.value; -}); +const readyToDisplay = computed(() => !visitsData.pending.value && !eventsData.pending.value && !sessionsData.pending.value); watch(readyToDisplay, () => { if (readyToDisplay.value === true) onDataReady(); @@ -226,14 +195,10 @@ function createGradient(startColor: string) { } function onDataReady() { - console.log('DATA READY'); - if (!visitsData.data.value) return; if (!eventsData.data.value) return; if (!sessionsData.data.value) return; - console.log('DATA READY 2'); - chartData.value.labels = visitsData.data.value.labels; const maxChartY = Math.max(...visitsData.data.value.data, ...sessionsData.data.value.data); @@ -250,9 +215,7 @@ function onDataReady() { chartData.value.datasets[1].backgroundColor = [createGradient('#4abde8')]; chartData.value.datasets[2].backgroundColor = [createGradient('#fbbf24')]; - console.log('UPDATE CHART'); updateChart(); - } const currentTooltipData = ref<{ visits: number, events: number, sessions: number, date: string }>({ @@ -268,19 +231,7 @@ function onLegendChange(dataset: any, index: number, checked: any) { dataset.hidden = !checked; } -const legendColors = [ - '#5655d7', - '#4abde8', - '#fbbf24' -] - - -onMounted(async () => { - visitsData.execute(); - eventsData.execute(); - sessionsData.execute(); -}); - +const legendColors = ['#5655d7', '#4abde8', '#fbbf24'] const inLiveDemo = isLiveDemo(); diff --git a/dashboard/components/dashboard/BrowsersBarCard.vue b/dashboard/components/dashboard/BrowsersBarCard.vue deleted file mode 100644 index ef3bff9..0000000 --- a/dashboard/components/dashboard/BrowsersBarCard.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - diff --git a/dashboard/components/dashboard/DevicesBarCard.vue b/dashboard/components/dashboard/DevicesBarCard.vue deleted file mode 100644 index cbb3ea1..0000000 --- a/dashboard/components/dashboard/DevicesBarCard.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - diff --git a/dashboard/components/dashboard/EventsBarCard.vue b/dashboard/components/dashboard/EventsBarCard.vue deleted file mode 100644 index dcee8ba..0000000 --- a/dashboard/components/dashboard/EventsBarCard.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - - diff --git a/dashboard/components/dashboard/OssBarCard.vue b/dashboard/components/dashboard/OssBarCard.vue deleted file mode 100644 index 191ba05..0000000 --- a/dashboard/components/dashboard/OssBarCard.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - - diff --git a/dashboard/components/dashboard/ReferrersBarCard.vue b/dashboard/components/dashboard/ReferrersBarCard.vue deleted file mode 100644 index 2e0566b..0000000 --- a/dashboard/components/dashboard/ReferrersBarCard.vue +++ /dev/null @@ -1,68 +0,0 @@ - - - - diff --git a/dashboard/components/dashboard/WebsitesBarCard.vue b/dashboard/components/dashboard/WebsitesBarCard.vue deleted file mode 100644 index 7125d27..0000000 --- a/dashboard/components/dashboard/WebsitesBarCard.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - - diff --git a/dashboard/composables/useCustomFetch.ts b/dashboard/composables/useCustomFetch.ts index 633ca68..6d10fe3 100644 --- a/dashboard/composables/useCustomFetch.ts +++ b/dashboard/composables/useCustomFetch.ts @@ -1,25 +1,47 @@ +import type { StringExpressionOperator } from "mongoose"; + +type RefOrPrimitive = T | Ref | ComputedRef export type CustomOptions = { useSnapshotDates?: boolean, useActivePid?: boolean, - slice?: string, + slice?: RefOrPrimitive, + limit?: RefOrPrimitive, + custom?: Record> } const { token } = useAccessToken(); const { projectId } = useProject(); const { safeSnapshotDates } = useSnapshot() +function getValueFromRefOrPrimitive(data?: T | Ref | ComputedRef) { + console.log('Getting value of', data); + if (!data) return; + if (isRef(data)) return data.value; + return data; +} + export function useComputedHeaders(customOptions?: CustomOptions) { const useSnapshotDates = customOptions?.useSnapshotDates || true; const useActivePid = customOptions?.useActivePid || true; const headers = computed>(() => { + + const parsedCustom: Record = {} + const customKeys = Object.keys(customOptions?.custom || {}); + for (const key of customKeys) { + console.log('key', key); + parsedCustom[key] = getValueFromRefOrPrimitive((customOptions?.custom || {})[key]) ?? '' + } + return { 'Authorization': `Bearer ${token.value}`, 'x-pid': useActivePid ? (projectId.value ?? '') : '', 'x-from': useSnapshotDates ? (safeSnapshotDates.value.from ?? '') : '', 'x-to': useSnapshotDates ? (safeSnapshotDates.value.to ?? '') : '', - 'x-slice': customOptions?.slice ?? '' + 'x-slice': getValueFromRefOrPrimitive(customOptions?.slice) ?? '', + 'x-limit': getValueFromRefOrPrimitive(customOptions?.limit)?.toString() ?? '', + ...parsedCustom } }) diff --git a/dashboard/pages/index.vue b/dashboard/pages/index.vue index 28e8776..5ebea4b 100644 --- a/dashboard/pages/index.vue +++ b/dashboard/pages/index.vue @@ -2,6 +2,10 @@ definePageMeta({ layout: 'dashboard' }); + +const { project } = useProject(); + + const { data: projects } = useProjectsList(); const activeProject = useActiveProject(); @@ -33,14 +37,14 @@ onMounted(async () => { }); }); - -const firstInteractionUrl = computed(() => { - return `/api/metrics/${activeProject.value?._id}/first_interaction` +const firstInteraction = useFetch('/api/project/first_interaction', { + lazy: true, headers: useComputedHeaders({ useSnapshotDates: false }) }); -const firstInteraction = useFetch(firstInteractionUrl, { - ...signHeaders(), - lazy: true + + +const showDashboard = computed(() => { + return project.value && firstInteraction.data.value }); const selectLabels = [ @@ -68,9 +72,97 @@ function goToUpgrade() {
-
- - +
+ +
+ + + + +
+ +
+ + +
+ +
+ +
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+