mirror of
https://github.com/Litlyx/litlyx
synced 2025-12-10 15:58:38 +01:00
testing events flow
This commit is contained in:
@@ -19,27 +19,48 @@ watch(selectedEventName, () => {
|
|||||||
getMetadataFields();
|
getMetadataFields();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(selectedMetadataField, () => {
|
||||||
|
getMetadataFieldGrouped();
|
||||||
|
});
|
||||||
|
|
||||||
async function getMetadataFields() {
|
async function getMetadataFields() {
|
||||||
metadataFields.value = await $fetch<string[]>(`/api/metrics/${activeProject.value?._id.toString()}/events/metadata_fields?name=${selectedEventName.value}`, signHeaders());
|
metadataFields.value = await $fetch<string[]>(`/api/metrics/${activeProject.value?._id.toString()}/events/metadata_fields?name=${selectedEventName.value}`, signHeaders());
|
||||||
selectedMetadataField.value = undefined;
|
selectedMetadataField.value = undefined;
|
||||||
|
currentSearchText.value = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getMetadataFieldGrouped() {
|
async function getMetadataFieldGrouped() {
|
||||||
|
if (!selectedMetadataField.value) return;
|
||||||
metadataFieldGrouped.value = await $fetch<string[]>(`/api/metrics/${activeProject.value?._id.toString()}/events/metadata_field_group?name=${selectedEventName.value}&field=${selectedMetadataField.value}`, signHeaders());
|
metadataFieldGrouped.value = await $fetch<string[]>(`/api/metrics/${activeProject.value?._id.toString()}/events/metadata_field_group?name=${selectedEventName.value}&field=${selectedMetadataField.value}`, signHeaders());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const metadataFieldGroupedFiltered = computed(() => {
|
||||||
|
if (currentSearchText.value.length == 0) return metadataFieldGrouped.value;
|
||||||
|
return metadataFieldGrouped.value.filter(e => {
|
||||||
|
const currentId: string = e._id || '';
|
||||||
|
const idToMatch = currentId.toLowerCase();
|
||||||
|
return idToMatch.includes(currentSearchText.value.toLowerCase());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentSearchText = ref<string>("");
|
||||||
|
|
||||||
|
const canSearch = computed(() => {
|
||||||
|
return selectedMetadataField.value != undefined;
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full h-full p-8 flex">
|
<div class="w-full h-full p-8 flex flex-col">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<CardTitled title="Event tracker" sub="Track users from you marketing links to inner events" class="w-full">
|
<CardTitled title="Event metadata analyzer" sub="Filter events metadata fields to analyze them" class="w-full p-4">
|
||||||
|
|
||||||
<div class="p-8">
|
<div class="p-2 flex flex-col">
|
||||||
|
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<USelectMenu searchable searchable-placeholder="Search an event..." class="w-full"
|
<USelectMenu searchable searchable-placeholder="Search an event..." class="w-full"
|
||||||
@@ -52,17 +73,34 @@ async function getMetadataFieldGrouped() {
|
|||||||
</USelectMenu>
|
</USelectMenu>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div @click="getMetadataFieldGrouped()"
|
<div v-if="canSearch" class="flex gap-4 mt-4 items-center">
|
||||||
class="bg-black/70 p-2 px-8 w-fit rounded-lg mt-4 hover:bg-black/40 cursor-pointer">
|
<div> Filter by name: </div>
|
||||||
Find
|
<div class="h-full flex items-center text-[1.2rem]">
|
||||||
</div>
|
<input v-model="currentSearchText"
|
||||||
|
class="bg-black/70 hover:bg-black/40 rounded-lg px-4 py-1 focus:outline-none" type="text">
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
|
||||||
{{ metadataFieldGrouped }}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</CardTitled>
|
</CardTitled>
|
||||||
|
|
||||||
|
<div class="mt-8 overflow-y-auto px-4 flex flex-col gap-3">
|
||||||
|
|
||||||
|
<div class="text-accent poppins font-semibold">
|
||||||
|
Search results: {{ metadataFieldGroupedFiltered.length }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div v-for="item of metadataFieldGroupedFiltered">
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<div> {{ item._id || 'OLD_EVENTS' }} </div>
|
||||||
|
<div> {{ item.count }} </div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
43
dashboard/pages/test2.vue
Normal file
43
dashboard/pages/test2.vue
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
definePageMeta({ layout: 'dashboard' });
|
||||||
|
|
||||||
|
const activeProject = useActiveProject();
|
||||||
|
|
||||||
|
|
||||||
|
const eventNames = ref<string[]>([]);
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
eventNames.value = await $fetch<string[]>(`/api/metrics/${activeProject.value?._id.toString()}/events/names`, signHeaders());
|
||||||
|
});
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
const res = $fetch(`/api/metrics/${activeProject.value?._id.toString()}/events/flow_from_name?name=docs_clicked`)
|
||||||
|
console.log(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="w-full h-full p-8 flex flex-col">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<CardTitled title="FLOW" sub="owo" class="w-full p-4">
|
||||||
|
<div class="p-2 flex flex-col">
|
||||||
|
|
||||||
|
<button @click="test">
|
||||||
|
TEST
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</CardTitled>
|
||||||
|
|
||||||
|
<div class="mt-8 overflow-y-auto px-4 flex flex-col gap-3">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import { getUserProjectFromId } from "~/server/LIVE_DEMO_DATA";
|
||||||
|
import { EventModel } from "@schema/metrics/EventSchema";
|
||||||
|
import { EVENT_METADATA_FIELDS_EXPIRE_TIME, Redis } from "~/server/services/CacheService";
|
||||||
|
import { PipelineStage } from "mongoose";
|
||||||
|
|
||||||
|
|
||||||
|
export default defineEventHandler(async event => {
|
||||||
|
|
||||||
|
const project_id = getRequestProjectId(event);
|
||||||
|
if (!project_id) return;
|
||||||
|
|
||||||
|
const user = getRequestUser(event);
|
||||||
|
|
||||||
|
const project = await getUserProjectFromId(project_id, user);
|
||||||
|
if (!project) return;
|
||||||
|
|
||||||
|
const { name: eventName } = getQuery(event);
|
||||||
|
if (!eventName) return [];
|
||||||
|
|
||||||
|
const aggregation: PipelineStage[] = [
|
||||||
|
{ $match: { project_id: project._id, name: eventName } },
|
||||||
|
{ $group: { _id: "$flowHash", count: { $sum: 1 } } },
|
||||||
|
{ $match: { _id: { $ne: null } } },
|
||||||
|
{
|
||||||
|
$lookup: {
|
||||||
|
from: "visits",
|
||||||
|
let: { flowHash: "$_id" },
|
||||||
|
pipeline: [
|
||||||
|
{ $match: { $expr: { $eq: ["$flowHash", "$$flowHash"] } } },
|
||||||
|
{ $group: { _id: "referrers", list: { $addToSet: "$referrer" } } },
|
||||||
|
{ $limit: 1 }
|
||||||
|
],
|
||||||
|
as: "referrers"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const flow: { _id: string, count: number, referrers: [{ list: string[] }] }[] = await EventModel.aggregate(aggregation);
|
||||||
|
|
||||||
|
return flow;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
import { getUserProjectFromId } from "~/server/LIVE_DEMO_DATA";
|
import { getUserProjectFromId } from "~/server/LIVE_DEMO_DATA";
|
||||||
import { EventModel } from "@schema/metrics/EventSchema";
|
import { EventModel } from "@schema/metrics/EventSchema";
|
||||||
import { EVENT_METADATA_FIELDS_EXPIRE_TIME, Redis } from "~/server/services/CacheService";
|
import { EVENT_METADATA_FIELDS_EXPIRE_TIME, Redis } from "~/server/services/CacheService";
|
||||||
|
import { PipelineStage } from "mongoose";
|
||||||
|
|
||||||
|
|
||||||
export default defineEventHandler(async event => {
|
export default defineEventHandler(async event => {
|
||||||
@@ -17,14 +18,14 @@ export default defineEventHandler(async event => {
|
|||||||
const { name: eventName, field } = getQuery(event);
|
const { name: eventName, field } = getQuery(event);
|
||||||
if (!eventName || !field) return [];
|
if (!eventName || !field) return [];
|
||||||
|
|
||||||
const aggregation = [
|
const aggregation: PipelineStage[] = [
|
||||||
{ $match: { project_id: project._id, name: eventName } },
|
{ $match: { project_id: project._id, name: eventName } },
|
||||||
{ $group: { _id: `$metadata.${field}`, count: { $sum: 1 } } }
|
{ $group: { _id: `$metadata.${field}`, count: { $sum: 1 } } },
|
||||||
|
{ $sort: { count: -1 } }
|
||||||
]
|
]
|
||||||
|
|
||||||
const metadataGrouped = await EventModel.aggregate(aggregation);
|
const metadataGrouped = await EventModel.aggregate(aggregation);
|
||||||
|
|
||||||
console.log(metadataGrouped);
|
|
||||||
return metadataGrouped;
|
return metadataGrouped;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user