feat: dashboard v2, esm, upgrades (#211)

* esm

* wip

* wip

* wip

* wip

* wip

* wip

* subscription notice

* wip

* wip

* wip

* fix envs

* fix: update docker build

* fix

* esm/types

* delete dashboard :D

* add patches to dockerfiles

* update packages + catalogs + ts

* wip

* remove native libs

* ts

* improvements

* fix redirects and fetching session

* try fix favicon

* fixes

* fix

* order and resize reportds within a dashboard

* improvements

* wip

* added userjot to dashboard

* fix

* add op

* wip

* different cache key

* improve date picker

* fix table

* event details loading

* redo onboarding completely

* fix login

* fix

* fix

* extend session, billing and improve bars

* fix

* reduce price on 10M
This commit is contained in:
Carl-Gerhard Lindesvärd
2025-10-16 12:27:44 +02:00
committed by GitHub
parent 436e81ecc9
commit 81a7e5d62e
741 changed files with 32695 additions and 16996 deletions

View File

@@ -0,0 +1,171 @@
import { Button } from '@/components/ui/button';
import { pushModal } from '@/modals';
import type { IServiceDashboards } from '@openpanel/db';
import { useNavigate } from '@tanstack/react-router';
import { AnimatePresence, motion } from 'framer-motion';
import {
BellIcon,
BookOpenIcon,
ChartLineIcon,
ChevronDownIcon,
CogIcon,
GanttChartIcon,
Globe2Icon,
GridIcon,
LayersIcon,
LayoutDashboardIcon,
LayoutPanelTopIcon,
PlusIcon,
SparklesIcon,
UndoDotIcon,
UsersIcon,
WallpaperIcon,
} from 'lucide-react';
import { useEffect, useState } from 'react';
import { SidebarLink } from './sidebar-link';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from './ui/dropdown-menu';
interface SidebarProjectMenuProps {
dashboards: IServiceDashboards;
}
export default function SidebarProjectMenu({
dashboards,
}: SidebarProjectMenuProps) {
return (
<>
<div className="mb-2 font-medium text-muted-foreground">Insights</div>
<SidebarLink icon={WallpaperIcon} label="Overview" href={'/'} />
<SidebarLink
icon={LayoutPanelTopIcon}
label="Dashboards"
href={'/dashboards'}
/>
<SidebarLink icon={LayersIcon} label="Pages" href={'/pages'} />
<SidebarLink icon={Globe2Icon} label="Realtime" href={'/realtime'} />
<SidebarLink icon={GanttChartIcon} label="Events" href={'/events'} />
<SidebarLink icon={UsersIcon} label="Sessions" href={'/sessions'} />
<SidebarLink icon={UsersIcon} label="Profiles" href={'/profiles'} />
<div className="mt-4 mb-2 font-medium text-muted-foreground">Manage</div>
<SidebarLink
exact={false}
icon={CogIcon}
label="Settings"
href={'/settings'}
/>
<SidebarLink icon={GridIcon} label="References" href={'/references'} />
<SidebarLink
exact={false}
icon={BellIcon}
label="Notifications"
href={'/notifications'}
/>
<SidebarLink icon={UndoDotIcon} label="Back to workspace" href={'..'} />
</>
);
}
export function ActionCTAButton() {
const navigate = useNavigate();
const ACTIONS = [
{
label: 'Create report',
icon: ChartLineIcon,
onClick: () =>
navigate({
to: '/$organizationId/$projectId/reports',
from: '/$organizationId/$projectId',
}),
},
{
label: 'Create reference',
icon: BookOpenIcon,
onClick: () => pushModal('AddReference'),
},
{
label: 'Ask AI',
icon: SparklesIcon,
onClick: () =>
navigate({
to: '/$organizationId/$projectId/chat',
from: '/$organizationId/$projectId',
}),
},
{
label: 'Create dashboard',
icon: LayoutDashboardIcon,
onClick: () => pushModal('AddDashboard'),
},
{
label: 'Create notification rule',
icon: BellIcon,
onClick: () =>
navigate({
to: '/$organizationId/$projectId/notifications/rules',
from: '/$organizationId/$projectId',
}),
},
];
const [currentActionIndex, setCurrentActionIndex] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setCurrentActionIndex((prevIndex) => (prevIndex + 1) % ACTIONS.length);
}, 2000);
return () => clearInterval(interval);
}, []);
return (
<div className="mb-4">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button className="w-full justify-between" size="default">
<div className="flex items-center gap-2">
<PlusIcon size={16} />
<div className="relative h-5 flex items-center">
<AnimatePresence mode="popLayout">
<motion.span
key={currentActionIndex}
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
exit={{ y: -20, opacity: 0 }}
transition={{
type: 'spring',
stiffness: 300,
damping: 25,
duration: 0.3,
}}
className="absolute whitespace-nowrap"
>
{ACTIONS[currentActionIndex].label}
</motion.span>
</AnimatePresence>
</div>
</div>
<ChevronDownIcon size={16} />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56" align="start">
{ACTIONS.map((action) => (
<DropdownMenuItem
onClick={action.onClick}
className="cursor-pointer"
key={action.label}
>
<action.icon className="mr-2 h-4 w-4" />
{action.label}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
</div>
);
}