mirror of
https://github.com/Litlyx/litlyx
synced 2025-12-10 07:48:37 +01:00
enchance ai
This commit is contained in:
@@ -9,10 +9,10 @@ const props = defineProps<{ title: string, sub?: string }>();
|
|||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="flex flex-col grow">
|
<div class="flex flex-col grow">
|
||||||
<div class="poppins font-semibold text-[1.1rem] md:text-[1.4rem] text-text">
|
<div class="poppins font-semibold text-[1rem] md:text-[1.3rem] text-text">
|
||||||
{{ props.title }}
|
{{ props.title }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="props.sub" class="poppins text-[.8rem] md:text-[1.1rem] text-text-sub">
|
<div v-if="props.sub" class="poppins text-[.7rem] md:text-[1rem] text-text-sub">
|
||||||
{{ props.sub }}
|
{{ props.sub }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ const emits = defineEmits<{
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<div class="flex gap-2 border-[1px] border-gray-400 p-1 md:p-2 rounded-xl">
|
<div class="flex gap-2 border-[1px] border-lyx-widget-lighter p-1 md:p-2 rounded-xl bg-lyx-widget">
|
||||||
<div @click="$emit('changeIndex', index)" v-for="(opt, index) of options"
|
<div @click="$emit('changeIndex', index)" v-for="(opt, index) of options"
|
||||||
class="hover:bg-white/10 select-btn-animated cursor-pointer rounded-lg poppins font-semibold px-2 md:px-3 py-1 text-[.8rem] md:text-[1rem]"
|
class="hover:bg-lyx-widget-lighter/60 select-btn-animated cursor-pointer rounded-lg poppins font-regular px-2 md:px-3 py-1 text-[.8rem] md:text-[1rem]"
|
||||||
:class="{ 'bg-accent hover:!bg-accent': currentIndex == index }">
|
:class="{ 'bg-lyx-widget-lighter hover:!bg-lyx-widget-lighter': currentIndex == index }">
|
||||||
{{ opt.label }}
|
{{ opt.label }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,14 +5,16 @@ import * as datefns from 'date-fns';
|
|||||||
|
|
||||||
registerChartComponents();
|
registerChartComponents();
|
||||||
|
|
||||||
|
const errored = ref<boolean>(false);
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
labels: string[],
|
labels: string[],
|
||||||
title:string,
|
title: string,
|
||||||
datasets: {
|
datasets: {
|
||||||
points: number[],
|
points: number[],
|
||||||
color: string,
|
color: string,
|
||||||
type: string,
|
chartType: string,
|
||||||
name:string
|
name: string
|
||||||
}[]
|
}[]
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
@@ -67,7 +69,11 @@ const chartOptions = ref<ChartOptions<'line'>>({
|
|||||||
|
|
||||||
const chartData = ref<ChartData<'line'>>({
|
const chartData = ref<ChartData<'line'>>({
|
||||||
labels: props.labels.map(e => {
|
labels: props.labels.map(e => {
|
||||||
return datefns.format(new Date(e), 'dd/MM');
|
try {
|
||||||
|
return datefns.format(new Date(e), 'dd/MM');
|
||||||
|
} catch (ex) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
datasets: props.datasets.map(e => ({
|
datasets: props.datasets.map(e => ({
|
||||||
data: e.points,
|
data: e.points,
|
||||||
@@ -82,7 +88,7 @@ const chartData = ref<ChartData<'line'>>({
|
|||||||
hoverBackgroundColor: e.color,
|
hoverBackgroundColor: e.color,
|
||||||
hoverBorderColor: 'white',
|
hoverBorderColor: 'white',
|
||||||
hoverBorderWidth: 2,
|
hoverBorderWidth: 2,
|
||||||
type: e.type
|
type: e.chartType
|
||||||
} as any))
|
} as any))
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -106,10 +112,18 @@ function createGradient(startColor: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
try {
|
||||||
chartData.value.datasets.forEach(dataset => {
|
chartData.value.datasets.forEach(dataset => {
|
||||||
dataset.backgroundColor = [createGradient(dataset.borderColor as string)]
|
if (dataset.borderColor && dataset.borderColor.toString().startsWith('#')) {
|
||||||
});
|
dataset.backgroundColor = [createGradient(dataset.borderColor as string)]
|
||||||
|
} else {
|
||||||
|
dataset.backgroundColor = [createGradient('#3d59a4')]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (ex) {
|
||||||
|
errored.value = true;
|
||||||
|
console.error(ex);
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -117,5 +131,8 @@ onMounted(async () => {
|
|||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<LineChart ref="lineChartRef" v-bind="lineChartProps"> </LineChart>
|
<div>
|
||||||
|
<div v-if="errored"> ERROR CREATING CHART </div>
|
||||||
|
<LineChart v-if="!errored" ref="lineChartRef" v-bind="lineChartProps"> </LineChart>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -262,17 +262,25 @@ onMounted(async () => {
|
|||||||
<template>
|
<template>
|
||||||
<CardTitled title="Trend chart" sub="Easily match Visits, Unique sessions and Events trends." class="w-full">
|
<CardTitled title="Trend chart" sub="Easily match Visits, Unique sessions and Events trends." class="w-full">
|
||||||
<template #header>
|
<template #header>
|
||||||
<SelectButton class="w-fit" @changeIndex="selectedLabelIndex = $event" :currentIndex="selectedLabelIndex"
|
<SelectButton class="w-fit" @changeIndex="selectedLabelIndex = $event"
|
||||||
:options="selectLabels">
|
:currentIndex="selectedLabelIndex" :options="selectLabels">
|
||||||
</SelectButton>
|
</SelectButton>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="flex gap-6 w-full justify-end">
|
<div class="flex gap-6 w-full justify-between">
|
||||||
<div v-for="(dataset, index) of chartData.datasets" class="flex gap-2 items-center text-[.9rem]">
|
<LyxUiButton type="secondary" to="/analyst">
|
||||||
<UCheckbox :ui="{
|
<div class="flex items-center gap-2 px-10">
|
||||||
color: `text-[${legendColors[index]}]`
|
<i class="far fa-sparkles text-yellow-400"></i>
|
||||||
}" :model-value="true" @change="onLegendChange(dataset, index, $event)"></UCheckbox>
|
<div class="poppins text-lyx-text"> Ask AI </div>
|
||||||
<label class="mt-[2px]"> {{ dataset.label }} </label>
|
</div>
|
||||||
|
</LyxUiButton>
|
||||||
|
<div class="flex gap-6">
|
||||||
|
<div v-for="(dataset, index) of chartData.datasets" class="flex gap-2 items-center text-[.9rem]">
|
||||||
|
<UCheckbox :ui="{
|
||||||
|
color: `text-[${legendColors[index]}]`
|
||||||
|
}" :model-value="true" @change="onLegendChange(dataset, index, $event)"></UCheckbox>
|
||||||
|
<label class="mt-[2px]"> {{ dataset.label }} </label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const sections: Section[] = [
|
|||||||
entries: [
|
entries: [
|
||||||
{ label: 'Dashboard', to: '/', icon: 'fal fa-table-layout' },
|
{ label: 'Dashboard', to: '/', icon: 'fal fa-table-layout' },
|
||||||
{ label: 'Events', to: '/events', icon: 'fal fa-square-bolt' },
|
{ label: 'Events', to: '/events', icon: 'fal fa-square-bolt' },
|
||||||
{ label: 'Analyst', to: '/analyst', icon: 'fal fa-microchip-ai' },
|
{ label: 'AI Analyst', to: '/analyst', icon: 'fal fa-sparkles' },
|
||||||
{ label: 'Insights (soon)', to: '#', icon: 'fal fa-lightbulb', disabled: true },
|
{ label: 'Insights (soon)', to: '#', icon: 'fal fa-lightbulb', disabled: true },
|
||||||
{ label: 'Links (soon)', to: '#', icon: 'fal fa-globe-pointer', disabled: true },
|
{ label: 'Links (soon)', to: '#', icon: 'fal fa-globe-pointer', disabled: true },
|
||||||
{ label: 'Integrations (soon)', to: '#', icon: 'fal fa-cube', disabled: true },
|
{ label: 'Integrations (soon)', to: '#', icon: 'fal fa-cube', disabled: true },
|
||||||
@@ -29,6 +29,7 @@ const sections: Section[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Slack support', icon: 'fab fa-slack',
|
label: 'Slack support', icon: 'fab fa-slack',
|
||||||
|
to:'#',
|
||||||
premiumOnly: true,
|
premiumOnly: true,
|
||||||
action() {
|
action() {
|
||||||
if (isGuest.value === true) return;
|
if (isGuest.value === true) return;
|
||||||
|
|||||||
@@ -35,11 +35,13 @@
|
|||||||
"v-calendar": "^3.1.2",
|
"v-calendar": "^3.1.2",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.4.21",
|
||||||
"vue-chart-3": "^3.1.8",
|
"vue-chart-3": "^3.1.8",
|
||||||
|
"vue-markdown-render": "^2.2.1",
|
||||||
"vue-router": "^4.3.0"
|
"vue-router": "^4.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/ui": "^2.15.2",
|
"@nuxt/ui": "^2.15.2",
|
||||||
"@types/jsonwebtoken": "^9.0.6",
|
"@types/jsonwebtoken": "^9.0.6",
|
||||||
|
"@types/markdown-it": "^14.1.2",
|
||||||
"@types/nodemailer": "^6.4.15",
|
"@types/nodemailer": "^6.4.15",
|
||||||
"@types/pdfkit": "^0.13.4",
|
"@types/pdfkit": "^0.13.4",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
import VueMarkdown from 'vue-markdown-render';
|
||||||
|
|
||||||
definePageMeta({ layout: 'dashboard' });
|
definePageMeta({ layout: 'dashboard' });
|
||||||
|
|
||||||
const activeProject = useActiveProject();
|
const activeProject = useActiveProject();
|
||||||
|
|
||||||
const { data: chatsList, refresh: reloadChatsList } = useFetch(`/api/ai/${activeProject.value?._id}/chats_list`, {
|
const { data: chatsList, refresh: reloadChatsList } = useFetch(`/api/ai/${activeProject.value?._id}/chats_list`, {
|
||||||
...signHeaders(),
|
...signHeaders()
|
||||||
transform: (data) => {
|
|
||||||
return data?.toReversed();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const viewChatsList = computed(() => (chatsList.value || []).toReversed());
|
||||||
|
|
||||||
const { data: chatsRemaining, refresh: reloadChatsRemaining } = useFetch(`/api/ai/${activeProject.value?._id}/chats_remaining`, signHeaders());
|
const { data: chatsRemaining, refresh: reloadChatsRemaining } = useFetch(`/api/ai/${activeProject.value?._id}/chats_remaining`, signHeaders());
|
||||||
|
|
||||||
const currentText = ref<string>("");
|
const currentText = ref<string>("");
|
||||||
@@ -72,8 +75,10 @@ async function sendMessage() {
|
|||||||
async function openChat(chat_id?: string) {
|
async function openChat(chat_id?: string) {
|
||||||
menuOpen.value = false;
|
menuOpen.value = false;
|
||||||
if (!activeProject.value) return;
|
if (!activeProject.value) return;
|
||||||
|
|
||||||
|
currentChatMessages.value = [];
|
||||||
|
|
||||||
if (!chat_id) {
|
if (!chat_id) {
|
||||||
currentChatMessages.value = [];
|
|
||||||
currentChatId.value = '';
|
currentChatId.value = '';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -105,10 +110,10 @@ function onKeyDown(e: KeyboardEvent) {
|
|||||||
const menuOpen = ref<boolean>(false);
|
const menuOpen = ref<boolean>(false);
|
||||||
|
|
||||||
const defaultPrompts = [
|
const defaultPrompts = [
|
||||||
'How many visits i got last week ?',
|
"Create a line chart with this data: \n[100, 200, 30, 300, 500, 40]",
|
||||||
'How many visits i got last month ?',
|
"Create a chart with Events (bar) and Visits (line) data from last week.",
|
||||||
'How many visits i got today ?',
|
"How many visits did I get last week?",
|
||||||
'How many events i got last week ?',
|
"Create a line chart of last week's visits."
|
||||||
]
|
]
|
||||||
|
|
||||||
async function deleteChat(chat_id: string) {
|
async function deleteChat(chat_id: string) {
|
||||||
@@ -123,6 +128,8 @@ async function deleteChat(chat_id: string) {
|
|||||||
await reloadChatsList();
|
await reloadChatsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { visible: pricingDrawerVisible } = usePricingDrawer()
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -144,7 +151,7 @@ async function deleteChat(chat_id: string) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 gap-4 mt-6" v-if="!isGuest">
|
<div class="grid grid-cols-2 gap-4 mt-6" v-if="!isGuest">
|
||||||
<div v-for="prompt of defaultPrompts" @click="currentText = prompt"
|
<div v-for="prompt of defaultPrompts" @click="currentText = prompt"
|
||||||
class="bg-lyx-widget-light hover:bg-lyx-widget-lighter cursor-pointer p-4 rounded-lg poppins text-center">
|
class="bg-lyx-widget-light hover:bg-lyx-widget-lighter cursor-pointer p-4 rounded-lg poppins text-center whitespace-pre-wrap flex items-center justify-center text-[.9rem]">
|
||||||
{{ prompt }}
|
{{ prompt }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -164,15 +171,20 @@ async function deleteChat(chat_id: string) {
|
|||||||
<div class="flex items-center justify-center shrink-0">
|
<div class="flex items-center justify-center shrink-0">
|
||||||
<img class="h-[3.5rem] w-auto" :src="'analyst.png'">
|
<img class="h-[3.5rem] w-auto" :src="'analyst.png'">
|
||||||
</div>
|
</div>
|
||||||
<div v-html="parseMessageContent(message.content)"
|
<div class="max-w-[70%] text-text/90 ai-message">
|
||||||
class="max-w-[70%] text-text/90 whitespace-pre-wrap">
|
<vue-markdown :source="message.content" :options="{
|
||||||
|
html: true,
|
||||||
|
breaks: true,
|
||||||
|
}" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="message.charts && message.charts.length > 0"
|
<div v-if="message.charts && message.charts.length > 0"
|
||||||
class="flex items-center gap-3 justify-start w-full poppins text-[1.1rem] flex-col mt-4">
|
class="flex items-center gap-3 justify-start w-full poppins text-[1.1rem] flex-col mt-4">
|
||||||
<div v-for="chart of message.charts" class="w-full">
|
<div v-for="chart of message.charts" class="w-full">
|
||||||
<AnalystComposableChart :datasets="chart.datasets" :labels="chart.labels" :title="chart.title">
|
<AnalystComposableChart :datasets="chart.datasets" :labels="chart.labels"
|
||||||
|
:title="chart.title">
|
||||||
</AnalystComposableChart>
|
</AnalystComposableChart>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -217,21 +229,26 @@ async function deleteChat(chat_id: string) {
|
|||||||
<i @click="menuOpen = false" class="fas fa-close cursor-pointer"></i>
|
<i @click="menuOpen = false" class="fas fa-close cursor-pointer"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="poppins font-semibold text-[1.5rem]">
|
<div class="poppins font-semibold text-[1.5rem]">
|
||||||
Lit, your AI Analyst is here!
|
What Lit can do for you?
|
||||||
</div>
|
</div>
|
||||||
<div class="poppins text-text/75">
|
<div class="poppins text-text/75">
|
||||||
Ask anything you want on your analytics,
|
Ask anything from your data history, visualize and overlap charts, explore events or metadata,
|
||||||
and understand more Trends and Key Points to take Strategic moves!
|
and enjoy a highly personalized data analysis experience.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex gap-2 items-center py-3">
|
<div class="flex gap-2 items-center pt-3">
|
||||||
<div class="bg-accent w-5 h-5 rounded-full animate-pulse">
|
<div class="bg-accent w-5 h-5 rounded-full animate-pulse">
|
||||||
</div>
|
</div>
|
||||||
<div class="manrope font-semibold"> {{ chatsRemaining }} remaining messages </div>
|
<div class="manrope font-semibold"> {{ chatsRemaining }} remaining AI requests </div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="poppins font-semibold text-[1.1rem]"> History: </div>
|
<LyxUiButton type="primary" class="text-[.9rem] text-center w-full"
|
||||||
|
@click="pricingDrawerVisible = true">
|
||||||
|
Upgrade plan for more requests
|
||||||
|
</LyxUiButton>
|
||||||
|
|
||||||
|
<div class="poppins font-semibold text-[1.1rem]"> History </div>
|
||||||
|
|
||||||
<div class="px-2">
|
<div class="px-2">
|
||||||
<div @click="openChat()"
|
<div @click="openChat()"
|
||||||
@@ -246,7 +263,7 @@ async function deleteChat(chat_id: string) {
|
|||||||
<div class="flex flex-col gap-2 px-2">
|
<div class="flex flex-col gap-2 px-2">
|
||||||
<div :class="{ '!bg-accent/60': chat._id.toString() === currentChatId }"
|
<div :class="{ '!bg-accent/60': chat._id.toString() === currentChatId }"
|
||||||
class="flex rounded-lg items-center gap-4 w-full px-4 bg-lyx-widget-lighter hover:bg-lyx-widget"
|
class="flex rounded-lg items-center gap-4 w-full px-4 bg-lyx-widget-lighter hover:bg-lyx-widget"
|
||||||
v-for="chat of chatsList">
|
v-for="chat of viewChatsList">
|
||||||
<i @click="deleteChat(chat._id.toString())"
|
<i @click="deleteChat(chat._id.toString())"
|
||||||
class="far fa-trash hover:text-gray-300 cursor-pointer"></i>
|
class="far fa-trash hover:text-gray-300 cursor-pointer"></i>
|
||||||
<div @click="openChat(chat._id.toString())"
|
<div @click="openChat(chat._id.toString())"
|
||||||
@@ -266,3 +283,82 @@ async function deleteChat(chat_id: string) {
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.ai-message {
|
||||||
|
|
||||||
|
/* Ensure headings stand out */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Paragraphs for better line spacing */
|
||||||
|
p {
|
||||||
|
line-height: 1.8;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
max-width: 750px;
|
||||||
|
/* Prevent very wide paragraphs for readability */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blockquotes */
|
||||||
|
blockquote {
|
||||||
|
margin: 1.5em 10px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
color: #555;
|
||||||
|
border-left: 5px solid #ccc;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code blocks */
|
||||||
|
pre {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
padding: 2px 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lists */
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
margin-left: 30px;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Links */
|
||||||
|
a {
|
||||||
|
color: #007acc;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Horizontal rules */
|
||||||
|
hr {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
margin: 2em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
111
dashboard/pnpm-lock.yaml
generated
111
dashboard/pnpm-lock.yaml
generated
@@ -74,6 +74,9 @@ importers:
|
|||||||
vue-chart-3:
|
vue-chart-3:
|
||||||
specifier: ^3.1.8
|
specifier: ^3.1.8
|
||||||
version: 3.1.8(chart.js@3.9.1)(vue@3.4.27(typescript@5.4.2))
|
version: 3.1.8(chart.js@3.9.1)(vue@3.4.27(typescript@5.4.2))
|
||||||
|
vue-markdown-render:
|
||||||
|
specifier: ^2.2.1
|
||||||
|
version: 2.2.1(vue@3.4.27(typescript@5.4.2))
|
||||||
vue-router:
|
vue-router:
|
||||||
specifier: ^4.3.0
|
specifier: ^4.3.0
|
||||||
version: 4.3.2(vue@3.4.27(typescript@5.4.2))
|
version: 4.3.2(vue@3.4.27(typescript@5.4.2))
|
||||||
@@ -84,6 +87,9 @@ importers:
|
|||||||
'@types/jsonwebtoken':
|
'@types/jsonwebtoken':
|
||||||
specifier: ^9.0.6
|
specifier: ^9.0.6
|
||||||
version: 9.0.6
|
version: 9.0.6
|
||||||
|
'@types/markdown-it':
|
||||||
|
specifier: ^14.1.2
|
||||||
|
version: 14.1.2
|
||||||
'@types/nodemailer':
|
'@types/nodemailer':
|
||||||
specifier: ^6.4.15
|
specifier: ^6.4.15
|
||||||
version: 6.4.15
|
version: 6.4.15
|
||||||
@@ -1171,9 +1177,18 @@ packages:
|
|||||||
'@types/jsonwebtoken@9.0.6':
|
'@types/jsonwebtoken@9.0.6':
|
||||||
resolution: {integrity: sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==}
|
resolution: {integrity: sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==}
|
||||||
|
|
||||||
|
'@types/linkify-it@5.0.0':
|
||||||
|
resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
|
||||||
|
|
||||||
'@types/lodash@4.17.7':
|
'@types/lodash@4.17.7':
|
||||||
resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==}
|
resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==}
|
||||||
|
|
||||||
|
'@types/markdown-it@14.1.2':
|
||||||
|
resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
|
||||||
|
|
||||||
|
'@types/mdurl@2.0.0':
|
||||||
|
resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
|
||||||
|
|
||||||
'@types/node-fetch@2.6.11':
|
'@types/node-fetch@2.6.11':
|
||||||
resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==}
|
resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==}
|
||||||
|
|
||||||
@@ -1431,20 +1446,20 @@ packages:
|
|||||||
'@vue/reactivity@3.4.27':
|
'@vue/reactivity@3.4.27':
|
||||||
resolution: {integrity: sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==}
|
resolution: {integrity: sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==}
|
||||||
|
|
||||||
'@vue/reactivity@3.5.5':
|
'@vue/reactivity@3.5.6':
|
||||||
resolution: {integrity: sha512-V4tTWElZQhT73PSK3Wnax9R9m4qvMX+LeKHnfylZc6SLh4Jc5/BPakp6e3zEhKWi5AN8TDzRkGnLkp8OqycYng==}
|
resolution: {integrity: sha512-shZ+KtBoHna5GyUxWfoFVBCVd7k56m6lGhk5e+J9AKjheHF6yob5eukssHRI+rzvHBiU1sWs/1ZhNbLExc5oYQ==}
|
||||||
|
|
||||||
'@vue/runtime-core@3.4.27':
|
'@vue/runtime-core@3.4.27':
|
||||||
resolution: {integrity: sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==}
|
resolution: {integrity: sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==}
|
||||||
|
|
||||||
'@vue/runtime-core@3.5.5':
|
'@vue/runtime-core@3.5.6':
|
||||||
resolution: {integrity: sha512-2/CFaRN17jgsXy4MpigWFBCAMmLkXPb4CjaHrndglwYSra7ajvkH2cat21dscuXaH91G8fXAeg5gCyxWJ+wCRA==}
|
resolution: {integrity: sha512-FpFULR6+c2lI+m1fIGONLDqPQO34jxV8g6A4wBOgne8eSRHP6PQL27+kWFIx5wNhhjkO7B4rgtsHAmWv7qKvbg==}
|
||||||
|
|
||||||
'@vue/runtime-dom@3.4.27':
|
'@vue/runtime-dom@3.4.27':
|
||||||
resolution: {integrity: sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==}
|
resolution: {integrity: sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==}
|
||||||
|
|
||||||
'@vue/runtime-dom@3.5.5':
|
'@vue/runtime-dom@3.5.6':
|
||||||
resolution: {integrity: sha512-0bQGgCuL+4Muz5PsCLgF4Ata9BTdhHi5VjsxtTDyI0Wy4MgoSvBGaA6bDc7W7CGgZOyirf9LNeetMYHQ05pgpw==}
|
resolution: {integrity: sha512-SDPseWre45G38ENH2zXRAHL1dw/rr5qp91lS4lt/nHvMr0MhsbCbihGAWLXNB/6VfFOJe2O+RBRkXU+CJF7/sw==}
|
||||||
|
|
||||||
'@vue/server-renderer@3.4.27':
|
'@vue/server-renderer@3.4.27':
|
||||||
resolution: {integrity: sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==}
|
resolution: {integrity: sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==}
|
||||||
@@ -1454,8 +1469,8 @@ packages:
|
|||||||
'@vue/shared@3.4.27':
|
'@vue/shared@3.4.27':
|
||||||
resolution: {integrity: sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==}
|
resolution: {integrity: sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==}
|
||||||
|
|
||||||
'@vue/shared@3.5.5':
|
'@vue/shared@3.5.6':
|
||||||
resolution: {integrity: sha512-0KyMXyEgnmFAs6rNUL+6eUHtUCqCaNrVd+AW3MX3LyA0Yry5SA0Km03CDKiOua1x1WWnIr+W9+S0GMFoSDWERQ==}
|
resolution: {integrity: sha512-eidH0HInnL39z6wAt6SFIwBrvGOpDWsDxlw3rCgo1B+CQ1781WzQUSU3YjxgdkcJo9Q8S6LmXTkvI+cLHGkQfA==}
|
||||||
|
|
||||||
'@vueuse/components@10.10.0':
|
'@vueuse/components@10.10.0':
|
||||||
resolution: {integrity: sha512-HiA10NQ9HJAGnju+8ZK4TyA8LIc0a6BnJmVWDa/k+TRhaYCVacSDU04k0BQ2otV+gghUDdwu98upf6TDRXpoeg==}
|
resolution: {integrity: sha512-HiA10NQ9HJAGnju+8ZK4TyA8LIc0a6BnJmVWDa/k+TRhaYCVacSDU04k0BQ2otV+gghUDdwu98upf6TDRXpoeg==}
|
||||||
@@ -2283,6 +2298,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==}
|
resolution: {integrity: sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==}
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
|
|
||||||
|
entities@3.0.1:
|
||||||
|
resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==}
|
||||||
|
engines: {node: '>=0.12'}
|
||||||
|
|
||||||
entities@4.5.0:
|
entities@4.5.0:
|
||||||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||||
engines: {node: '>=0.12'}
|
engines: {node: '>=0.12'}
|
||||||
@@ -3179,6 +3198,9 @@ packages:
|
|||||||
lines-and-columns@1.2.4:
|
lines-and-columns@1.2.4:
|
||||||
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
||||||
|
|
||||||
|
linkify-it@4.0.1:
|
||||||
|
resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==}
|
||||||
|
|
||||||
listhen@1.7.2:
|
listhen@1.7.2:
|
||||||
resolution: {integrity: sha512-7/HamOm5YD9Wb7CFgAZkKgVPA96WwhcTQoqtm2VTZGVbVVn3IWKRBTgrU7cchA3Q8k9iCsG8Osoi9GX4JsGM9g==}
|
resolution: {integrity: sha512-7/HamOm5YD9Wb7CFgAZkKgVPA96WwhcTQoqtm2VTZGVbVVn3IWKRBTgrU7cchA3Q8k9iCsG8Osoi9GX4JsGM9g==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -3281,12 +3303,19 @@ packages:
|
|||||||
resolution: {integrity: sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==}
|
resolution: {integrity: sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==}
|
||||||
engines: {node: ^16.14.0 || >=18.0.0}
|
engines: {node: ^16.14.0 || >=18.0.0}
|
||||||
|
|
||||||
|
markdown-it@13.0.2:
|
||||||
|
resolution: {integrity: sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
mdn-data@2.0.28:
|
mdn-data@2.0.28:
|
||||||
resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
|
resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
|
||||||
|
|
||||||
mdn-data@2.0.30:
|
mdn-data@2.0.30:
|
||||||
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
|
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
|
||||||
|
|
||||||
|
mdurl@1.0.1:
|
||||||
|
resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
|
||||||
|
|
||||||
media-typer@0.3.0:
|
media-typer@0.3.0:
|
||||||
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
|
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
@@ -4691,6 +4720,9 @@ packages:
|
|||||||
engines: {node: '>=14.17'}
|
engines: {node: '>=14.17'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
uc.micro@1.0.6:
|
||||||
|
resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==}
|
||||||
|
|
||||||
ufo@1.5.3:
|
ufo@1.5.3:
|
||||||
resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==}
|
resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==}
|
||||||
|
|
||||||
@@ -5045,6 +5077,11 @@ packages:
|
|||||||
vue-devtools-stub@0.1.0:
|
vue-devtools-stub@0.1.0:
|
||||||
resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==}
|
resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==}
|
||||||
|
|
||||||
|
vue-markdown-render@2.2.1:
|
||||||
|
resolution: {integrity: sha512-XkYnC0PMdbs6Vy6j/gZXSvCuOS0787Se5COwXlepRqiqPiunyCIeTPQAO2XnB4Yl04EOHXwLx5y6IuszMWSgyQ==}
|
||||||
|
peerDependencies:
|
||||||
|
vue: ^3.3.4
|
||||||
|
|
||||||
vue-observe-visibility@2.0.0-alpha.1:
|
vue-observe-visibility@2.0.0-alpha.1:
|
||||||
resolution: {integrity: sha512-flFbp/gs9pZniXR6fans8smv1kDScJ8RS7rEpMjhVabiKeq7Qz3D9+eGsypncjfIyyU84saU88XZ0zjbD6Gq/g==}
|
resolution: {integrity: sha512-flFbp/gs9pZniXR6fans8smv1kDScJ8RS7rEpMjhVabiKeq7Qz3D9+eGsypncjfIyyU84saU88XZ0zjbD6Gq/g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -6547,8 +6584,17 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.12.12
|
'@types/node': 20.12.12
|
||||||
|
|
||||||
|
'@types/linkify-it@5.0.0': {}
|
||||||
|
|
||||||
'@types/lodash@4.17.7': {}
|
'@types/lodash@4.17.7': {}
|
||||||
|
|
||||||
|
'@types/markdown-it@14.1.2':
|
||||||
|
dependencies:
|
||||||
|
'@types/linkify-it': 5.0.0
|
||||||
|
'@types/mdurl': 2.0.0
|
||||||
|
|
||||||
|
'@types/mdurl@2.0.0': {}
|
||||||
|
|
||||||
'@types/node-fetch@2.6.11':
|
'@types/node-fetch@2.6.11':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.12.12
|
'@types/node': 20.12.12
|
||||||
@@ -7001,7 +7047,7 @@ snapshots:
|
|||||||
'@volar/language-core': 1.11.1
|
'@volar/language-core': 1.11.1
|
||||||
'@volar/source-map': 1.11.1
|
'@volar/source-map': 1.11.1
|
||||||
'@vue/compiler-dom': 3.4.27
|
'@vue/compiler-dom': 3.4.27
|
||||||
'@vue/shared': 3.5.5
|
'@vue/shared': 3.5.6
|
||||||
computeds: 0.0.1
|
computeds: 0.0.1
|
||||||
minimatch: 9.0.4
|
minimatch: 9.0.4
|
||||||
muggle-string: 0.3.1
|
muggle-string: 0.3.1
|
||||||
@@ -7014,19 +7060,19 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@vue/shared': 3.4.27
|
'@vue/shared': 3.4.27
|
||||||
|
|
||||||
'@vue/reactivity@3.5.5':
|
'@vue/reactivity@3.5.6':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/shared': 3.5.5
|
'@vue/shared': 3.5.6
|
||||||
|
|
||||||
'@vue/runtime-core@3.4.27':
|
'@vue/runtime-core@3.4.27':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/reactivity': 3.4.27
|
'@vue/reactivity': 3.4.27
|
||||||
'@vue/shared': 3.4.27
|
'@vue/shared': 3.4.27
|
||||||
|
|
||||||
'@vue/runtime-core@3.5.5':
|
'@vue/runtime-core@3.5.6':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/reactivity': 3.5.5
|
'@vue/reactivity': 3.5.6
|
||||||
'@vue/shared': 3.5.5
|
'@vue/shared': 3.5.6
|
||||||
|
|
||||||
'@vue/runtime-dom@3.4.27':
|
'@vue/runtime-dom@3.4.27':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -7034,11 +7080,11 @@ snapshots:
|
|||||||
'@vue/shared': 3.4.27
|
'@vue/shared': 3.4.27
|
||||||
csstype: 3.1.3
|
csstype: 3.1.3
|
||||||
|
|
||||||
'@vue/runtime-dom@3.5.5':
|
'@vue/runtime-dom@3.5.6':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/reactivity': 3.5.5
|
'@vue/reactivity': 3.5.6
|
||||||
'@vue/runtime-core': 3.5.5
|
'@vue/runtime-core': 3.5.6
|
||||||
'@vue/shared': 3.5.5
|
'@vue/shared': 3.5.6
|
||||||
csstype: 3.1.3
|
csstype: 3.1.3
|
||||||
|
|
||||||
'@vue/server-renderer@3.4.27(vue@3.4.27(typescript@5.4.2))':
|
'@vue/server-renderer@3.4.27(vue@3.4.27(typescript@5.4.2))':
|
||||||
@@ -7049,7 +7095,7 @@ snapshots:
|
|||||||
|
|
||||||
'@vue/shared@3.4.27': {}
|
'@vue/shared@3.4.27': {}
|
||||||
|
|
||||||
'@vue/shared@3.5.5': {}
|
'@vue/shared@3.5.6': {}
|
||||||
|
|
||||||
'@vueuse/components@10.10.0(vue@3.4.27(typescript@5.4.2))':
|
'@vueuse/components@10.10.0(vue@3.4.27(typescript@5.4.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -7840,6 +7886,8 @@ snapshots:
|
|||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
tapable: 2.2.1
|
tapable: 2.2.1
|
||||||
|
|
||||||
|
entities@3.0.1: {}
|
||||||
|
|
||||||
entities@4.5.0: {}
|
entities@4.5.0: {}
|
||||||
|
|
||||||
env-paths@2.2.1: {}
|
env-paths@2.2.1: {}
|
||||||
@@ -8867,6 +8915,10 @@ snapshots:
|
|||||||
|
|
||||||
lines-and-columns@1.2.4: {}
|
lines-and-columns@1.2.4: {}
|
||||||
|
|
||||||
|
linkify-it@4.0.1:
|
||||||
|
dependencies:
|
||||||
|
uc.micro: 1.0.6
|
||||||
|
|
||||||
listhen@1.7.2:
|
listhen@1.7.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@parcel/watcher': 2.4.1
|
'@parcel/watcher': 2.4.1
|
||||||
@@ -8986,10 +9038,20 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
markdown-it@13.0.2:
|
||||||
|
dependencies:
|
||||||
|
argparse: 2.0.1
|
||||||
|
entities: 3.0.1
|
||||||
|
linkify-it: 4.0.1
|
||||||
|
mdurl: 1.0.1
|
||||||
|
uc.micro: 1.0.6
|
||||||
|
|
||||||
mdn-data@2.0.28: {}
|
mdn-data@2.0.28: {}
|
||||||
|
|
||||||
mdn-data@2.0.30: {}
|
mdn-data@2.0.30: {}
|
||||||
|
|
||||||
|
mdurl@1.0.1: {}
|
||||||
|
|
||||||
media-typer@0.3.0: {}
|
media-typer@0.3.0: {}
|
||||||
|
|
||||||
memory-pager@1.5.0: {}
|
memory-pager@1.5.0: {}
|
||||||
@@ -10643,6 +10705,8 @@ snapshots:
|
|||||||
|
|
||||||
typescript@5.4.2: {}
|
typescript@5.4.2: {}
|
||||||
|
|
||||||
|
uc.micro@1.0.6: {}
|
||||||
|
|
||||||
ufo@1.5.3: {}
|
ufo@1.5.3: {}
|
||||||
|
|
||||||
ultrahtml@1.5.3: {}
|
ultrahtml@1.5.3: {}
|
||||||
@@ -11042,8 +11106,8 @@ snapshots:
|
|||||||
|
|
||||||
vue-chart-3@3.1.8(chart.js@3.9.1)(vue@3.4.27(typescript@5.4.2)):
|
vue-chart-3@3.1.8(chart.js@3.9.1)(vue@3.4.27(typescript@5.4.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/runtime-core': 3.5.5
|
'@vue/runtime-core': 3.5.6
|
||||||
'@vue/runtime-dom': 3.5.5
|
'@vue/runtime-dom': 3.5.6
|
||||||
chart.js: 3.9.1
|
chart.js: 3.9.1
|
||||||
csstype: 3.1.3
|
csstype: 3.1.3
|
||||||
lodash-es: 4.17.21
|
lodash-es: 4.17.21
|
||||||
@@ -11055,6 +11119,11 @@ snapshots:
|
|||||||
|
|
||||||
vue-devtools-stub@0.1.0: {}
|
vue-devtools-stub@0.1.0: {}
|
||||||
|
|
||||||
|
vue-markdown-render@2.2.1(vue@3.4.27(typescript@5.4.2)):
|
||||||
|
dependencies:
|
||||||
|
markdown-it: 13.0.2
|
||||||
|
vue: 3.4.27(typescript@5.4.2)
|
||||||
|
|
||||||
vue-observe-visibility@2.0.0-alpha.1(vue@3.4.27(typescript@5.4.2)):
|
vue-observe-visibility@2.0.0-alpha.1(vue@3.4.27(typescript@5.4.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.4.27(typescript@5.4.2)
|
vue: 3.4.27(typescript@5.4.2)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export class AiComposableChart extends AIPlugin<['createComposableChart']> {
|
|||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Color used to represent the dataset'
|
description: 'Color used to represent the dataset in format "#RRGGBB"'
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { EventModel } from "@schema/metrics/EventSchema";
|
import { EventModel } from "@schema/metrics/EventSchema";
|
||||||
import { executeTimelineAggregation, fillAndMergeTimelineAggregationV2 } from "~/server/services/TimelineService";
|
import { AdvancedTimelineAggregationOptions, executeAdvancedTimelineAggregation, executeTimelineAggregation, fillAndMergeTimelineAggregationV2 } from "~/server/services/TimelineService";
|
||||||
import { Types } from "mongoose";
|
import { Types } from "mongoose";
|
||||||
import { AIPlugin, AIPlugin_TTool } from "../Plugin";
|
import { AIPlugin, AIPlugin_TTool } from "../Plugin";
|
||||||
|
|
||||||
@@ -32,6 +32,8 @@ const getEventsTimelineTool: AIPlugin_TTool<'getEventsTimeline'> = {
|
|||||||
properties: {
|
properties: {
|
||||||
from: { type: 'string', description: 'ISO string of start date including hours' },
|
from: { type: 'string', description: 'ISO string of start date including hours' },
|
||||||
to: { type: 'string', description: 'ISO string of end date including hours' },
|
to: { type: 'string', description: 'ISO string of end date including hours' },
|
||||||
|
name: { type: 'string', description: 'Name of the events to get' },
|
||||||
|
metadata: { type: 'object', description: 'Metadata of events to get' },
|
||||||
},
|
},
|
||||||
required: ['from', 'to']
|
required: ['from', 'to']
|
||||||
}
|
}
|
||||||
@@ -60,12 +62,17 @@ export class AiEvents extends AIPlugin<['getEventsCount', 'getEventsTimeline']>
|
|||||||
tool: getEventsCountTool
|
tool: getEventsCountTool
|
||||||
},
|
},
|
||||||
'getEventsTimeline': {
|
'getEventsTimeline': {
|
||||||
handler: async (data: { project_id: string, from: string, to: string }) => {
|
handler: async (data: { project_id: string, from: string, to: string, name?: string, metadata?: string }) => {
|
||||||
const timelineData = await executeTimelineAggregation({
|
const query: AdvancedTimelineAggregationOptions & { customMatch: Record<string, any> } = {
|
||||||
projectId: new Types.ObjectId(data.project_id) as any,
|
projectId: new Types.ObjectId(data.project_id) as any,
|
||||||
model: EventModel,
|
model: EventModel,
|
||||||
from: data.from, to: data.to, slice: 'day'
|
from: data.from, to: data.to, slice: 'day',
|
||||||
});
|
customMatch: {}
|
||||||
|
}
|
||||||
|
if (data.metadata) query.customMatch.metadata = data.metadata;
|
||||||
|
if (data.name) query.customMatch.name = data.name;
|
||||||
|
|
||||||
|
const timelineData = await executeAdvancedTimelineAggregation(query);
|
||||||
const timelineFilledMerged = fillAndMergeTimelineAggregationV2(timelineData, 'day', data.from, data.to);
|
const timelineFilledMerged = fillAndMergeTimelineAggregationV2(timelineData, 'day', data.from, data.to);
|
||||||
return { data: timelineFilledMerged };
|
return { data: timelineFilledMerged };
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ export async function sendMessageOnChat(text: string, pid: string, initial_chat_
|
|||||||
messages.push(...chatMessages);
|
messages.push(...chatMessages);
|
||||||
} else {
|
} else {
|
||||||
const roleMessage: OpenAI.Chat.Completions.ChatCompletionMessageParam = {
|
const roleMessage: OpenAI.Chat.Completions.ChatCompletionMessageParam = {
|
||||||
role: 'system', content: "Today is " + new Date().toISOString()
|
role: 'system',
|
||||||
|
content: + "Today is " + new Date().toISOString()
|
||||||
}
|
}
|
||||||
messages.push(roleMessage);
|
messages.push(roleMessage);
|
||||||
await addMessageToChat(roleMessage, chat_id);
|
await addMessageToChat(roleMessage, chat_id);
|
||||||
|
|||||||
Reference in New Issue
Block a user