diff --git a/consumer/src/index.ts b/consumer/src/index.ts index 6c1e33a..6e16ad1 100644 --- a/consumer/src/index.ts +++ b/consumer/src/index.ts @@ -112,7 +112,7 @@ async function process_visit(data: Record, sessionHash: string) async function process_keep_alive(data: Record, sessionHash: string) { - const { pid, instant, flowHash, timestamp } = data; + const { pid, instant, flowHash, timestamp, website } = data; const existingSession = await SessionModel.findOne({ project_id: pid, session: sessionHash }, { _id: 1 }); if (!existingSession) { @@ -123,13 +123,15 @@ async function process_keep_alive(data: Record, sessionHash: str await SessionModel.updateOne({ project_id: pid, session: sessionHash, }, { $inc: { duration: 0 }, flowHash, - updated_at: Date.now() + website, + updated_at: new Date(parseInt(timestamp)) }, { upsert: true }); } else { await SessionModel.updateOne({ project_id: pid, session: sessionHash, }, { $inc: { duration: 1 }, flowHash, - updated_at: Date.now() + website, + updated_at: new Date(parseInt(timestamp)) }, { upsert: true }); } @@ -137,7 +139,7 @@ async function process_keep_alive(data: Record, sessionHash: str async function process_event(data: Record, sessionHash: string) { - const { name, metadata, pid, flowHash, timestamp } = data; + const { name, metadata, pid, flowHash, timestamp, website } = data; let metadataObject; try { @@ -149,6 +151,7 @@ async function process_event(data: Record, sessionHash: string) await Promise.all([ EventModel.create({ project_id: pid, name, flowHash, metadata: metadataObject, session: sessionHash, + website, created_at: new Date(parseInt(timestamp)) }), ProjectCountModel.updateOne({ project_id: pid }, { $inc: { 'events': 1 } }, { upsert: true }), diff --git a/dashboard/components/FirstInteraction.vue b/dashboard/components/FirstInteraction.vue index 5debe10..a2a5f85 100644 --- a/dashboard/components/FirstInteraction.vue +++ b/dashboard/components/FirstInteraction.vue @@ -79,13 +79,13 @@ function reloadPage() { -
+
-
@@ -133,6 +133,28 @@ function reloadPage() {
+
+
+ + + +
+ + +
+
+
+
{ const filter = ref('{}'); -const { data: projectsInfo, pending: pendingProjects } = await useFetch<{ count: number, projects: TAdminProject[] }>( +const { data: projectsInfo, pending: pendingProjects } = useFetch<{ count: number, projects: TAdminProject[] }>( () => `/api/admin/projects?page=${page.value - 1}&limit=${limit.value}&sortQuery=${order.value}&filterQuery=${filter.value}&filterFrom=${selected.value.start.toISOString()}&filterTo=${selected.value.end.toISOString()}`, signHeaders() ); - +const { data: metrics, pending: pendingMetrics } = useFetch( + () => `/api/admin/metrics?filterFrom=${selected.value.start.toISOString()}&filterTo=${selected.value.end.toISOString()}`, + signHeaders() +); const { uiMenu } = useSelectMenuStyle(); @@ -136,7 +139,7 @@ const { uiMenu } = useSelectMenuStyle();
Page {{ page }}
{{ Math.min(limit, projectsInfo?.count || 0) }} of {{ projectsInfo?.count || 0 - }}
+ }}
@@ -165,6 +168,23 @@ const { uiMenu } = useSelectMenuStyle();
+ +
+
Loading...
+
+
Projects: {{ metrics.totalProjects }} ({{ metrics.premiumProjects }} premium)
+
+ Total visits: {{ formatNumberK(metrics.totalVisits) }} +
+
+ Active: {{ metrics.totalProjects - metrics.deadProjects }} | + Dead: {{ metrics.deadProjects }} +
+
+ Total events: {{ formatNumberK(metrics.totalEvents) }} +
+
+
diff --git a/dashboard/components/dashboard/ActionableChart.vue b/dashboard/components/dashboard/ActionableChart.vue index 111285c..91ccc78 100644 --- a/dashboard/components/dashboard/ActionableChart.vue +++ b/dashboard/components/dashboard/ActionableChart.vue @@ -198,11 +198,16 @@ const selectLabelsAvailable = computed<{ label: string, value: Slice, disabled: }) const selectedSlice = computed(() => { + console.log({ available: selectLabelsAvailable.value }) const targetValue = selectLabelsAvailable.value[selectedLabelIndex.value]; if (!targetValue) return 'day'; if (targetValue.disabled) { selectedLabelIndex.value = selectLabelsAvailable.value.findIndex(e => !e.disabled); } + if (selectedLabelIndex.value === -1) { + console.error('ERROR CANNOT FIND CORRECT SLICE') + return 'day'; + } return selectLabelsAvailable.value[selectedLabelIndex.value].value }); diff --git a/dashboard/components/dashboard/TopCards.vue b/dashboard/components/dashboard/TopCards.vue index 1c40339..be4f089 100644 --- a/dashboard/components/dashboard/TopCards.vue +++ b/dashboard/components/dashboard/TopCards.vue @@ -8,7 +8,7 @@ const { snapshot, safeSnapshotDates, snapshotDuration } = useSnapshot() const chartSlice = computed(() => { if (snapshotDuration.value <= 3) return 'hour' as Slice; - if (snapshotDuration.value <= 32) return 'day' as Slice; + if (snapshotDuration.value <= 31 * 3) return 'day' as Slice; return 'month' as Slice; }); diff --git a/dashboard/components/dialog/InviteManager.vue b/dashboard/components/dialog/InviteManager.vue new file mode 100644 index 0000000..3617946 --- /dev/null +++ b/dashboard/components/dialog/InviteManager.vue @@ -0,0 +1,56 @@ + + + \ No newline at end of file diff --git a/dashboard/components/dialog/PermissionManager.vue b/dashboard/components/dialog/PermissionManager.vue new file mode 100644 index 0000000..9bf4ac4 --- /dev/null +++ b/dashboard/components/dialog/PermissionManager.vue @@ -0,0 +1,110 @@ + + + + + \ No newline at end of file diff --git a/dashboard/components/layout/TopNavigation.vue b/dashboard/components/layout/TopNavigation.vue index 0e0cf32..0b8988f 100644 --- a/dashboard/components/layout/TopNavigation.vue +++ b/dashboard/components/layout/TopNavigation.vue @@ -5,6 +5,7 @@ import { DialogFeedback, DialogHelp } from '#components'; const modal = useModal(); const selfhosted = useSelfhosted(); +const { domain } = useDomain(); const colorMode = useColorMode() const isDark = computed({ @@ -16,47 +17,50 @@ const isDark = computed({ } }) -const {safeSnapshotDates} = useSnapshot(); +const { safeSnapshotDates } = useSnapshot();