mirror of
https://github.com/eliasstepanik/core.git
synced 2026-01-22 12:48:30 +00:00
Feat: logs ui
This commit is contained in:
parent
704dffdef5
commit
72fe9f18bc
228
apps/webapp/app/components/logs/logs-filters.tsx
Normal file
228
apps/webapp/app/components/logs/logs-filters.tsx
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { Check, ChevronsUpDown, Filter, X } from "lucide-react";
|
||||||
|
import { Button } from "~/components/ui/button";
|
||||||
|
import {
|
||||||
|
Command,
|
||||||
|
CommandEmpty,
|
||||||
|
CommandGroup,
|
||||||
|
CommandInput,
|
||||||
|
CommandItem,
|
||||||
|
CommandList,
|
||||||
|
} from "~/components/ui/command";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "~/components/ui/popover";
|
||||||
|
import { Badge } from "~/components/ui/badge";
|
||||||
|
import { cn } from "~/lib/utils";
|
||||||
|
|
||||||
|
interface LogsFiltersProps {
|
||||||
|
availableSources: Array<{ name: string; slug: string }>;
|
||||||
|
selectedSource?: string;
|
||||||
|
selectedStatus?: string;
|
||||||
|
onSourceChange: (source?: string) => void;
|
||||||
|
onStatusChange: (status?: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusOptions = [
|
||||||
|
{ value: "PENDING", label: "Pending" },
|
||||||
|
{ value: "PROCESSING", label: "Processing" },
|
||||||
|
{ value: "COMPLETED", label: "Completed" },
|
||||||
|
{ value: "FAILED", label: "Failed" },
|
||||||
|
{ value: "CANCELLED", label: "Cancelled" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function LogsFilters({
|
||||||
|
availableSources,
|
||||||
|
selectedSource,
|
||||||
|
selectedStatus,
|
||||||
|
onSourceChange,
|
||||||
|
onStatusChange,
|
||||||
|
}: LogsFiltersProps) {
|
||||||
|
const [sourceOpen, setSourceOpen] = useState(false);
|
||||||
|
const [statusOpen, setStatusOpen] = useState(false);
|
||||||
|
|
||||||
|
const selectedSourceName = availableSources.find(
|
||||||
|
(s) => s.slug === selectedSource,
|
||||||
|
)?.name;
|
||||||
|
const selectedStatusLabel = statusOptions.find(
|
||||||
|
(s) => s.value === selectedStatus,
|
||||||
|
)?.label;
|
||||||
|
|
||||||
|
const clearFilters = () => {
|
||||||
|
onSourceChange(undefined);
|
||||||
|
onStatusChange(undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
const hasFilters = selectedSource || selectedStatus;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mb-4 flex items-center gap-2">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Filter className="text-muted-foreground h-4 w-4" />
|
||||||
|
<span className="text-sm font-medium">Filters:</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Source Filter */}
|
||||||
|
<Popover open={sourceOpen} onOpenChange={setSourceOpen}>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
role="combobox"
|
||||||
|
aria-expanded={sourceOpen}
|
||||||
|
className="w-[200px] justify-between"
|
||||||
|
>
|
||||||
|
{selectedSourceName || "Select source..."}
|
||||||
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="w-[200px] p-0">
|
||||||
|
<Command>
|
||||||
|
<CommandInput placeholder="Search sources..." />
|
||||||
|
<CommandList>
|
||||||
|
<CommandEmpty>No sources found.</CommandEmpty>
|
||||||
|
<CommandGroup>
|
||||||
|
<CommandItem
|
||||||
|
value=""
|
||||||
|
onSelect={() => {
|
||||||
|
onSourceChange(undefined);
|
||||||
|
setSourceOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Check
|
||||||
|
className={cn(
|
||||||
|
"mr-2 h-4 w-4",
|
||||||
|
!selectedSource ? "opacity-100" : "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
All sources
|
||||||
|
</CommandItem>
|
||||||
|
{availableSources.map((source) => (
|
||||||
|
<CommandItem
|
||||||
|
key={source.slug}
|
||||||
|
value={source.slug}
|
||||||
|
onSelect={() => {
|
||||||
|
onSourceChange(
|
||||||
|
source.slug === selectedSource
|
||||||
|
? undefined
|
||||||
|
: source.slug,
|
||||||
|
);
|
||||||
|
setSourceOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Check
|
||||||
|
className={cn(
|
||||||
|
"mr-2 h-4 w-4",
|
||||||
|
selectedSource === source.slug
|
||||||
|
? "opacity-100"
|
||||||
|
: "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{source.name}
|
||||||
|
</CommandItem>
|
||||||
|
))}
|
||||||
|
</CommandGroup>
|
||||||
|
</CommandList>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
{/* Status Filter */}
|
||||||
|
<Popover open={statusOpen} onOpenChange={setStatusOpen}>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
role="combobox"
|
||||||
|
aria-expanded={statusOpen}
|
||||||
|
className="w-[200px] justify-between"
|
||||||
|
>
|
||||||
|
{selectedStatusLabel || "Select status..."}
|
||||||
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="w-[200px] p-0">
|
||||||
|
<Command>
|
||||||
|
<CommandInput placeholder="Search status..." />
|
||||||
|
<CommandList>
|
||||||
|
<CommandEmpty>No status found.</CommandEmpty>
|
||||||
|
<CommandGroup>
|
||||||
|
<CommandItem
|
||||||
|
value=""
|
||||||
|
onSelect={() => {
|
||||||
|
onStatusChange(undefined);
|
||||||
|
setStatusOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Check
|
||||||
|
className={cn(
|
||||||
|
"mr-2 h-4 w-4",
|
||||||
|
!selectedStatus ? "opacity-100" : "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
All statuses
|
||||||
|
</CommandItem>
|
||||||
|
{statusOptions.map((status) => (
|
||||||
|
<CommandItem
|
||||||
|
key={status.value}
|
||||||
|
value={status.value}
|
||||||
|
onSelect={() => {
|
||||||
|
onStatusChange(
|
||||||
|
status.value === selectedStatus
|
||||||
|
? undefined
|
||||||
|
: status.value,
|
||||||
|
);
|
||||||
|
setStatusOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Check
|
||||||
|
className={cn(
|
||||||
|
"mr-2 h-4 w-4",
|
||||||
|
selectedStatus === status.value
|
||||||
|
? "opacity-100"
|
||||||
|
: "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{status.label}
|
||||||
|
</CommandItem>
|
||||||
|
))}
|
||||||
|
</CommandGroup>
|
||||||
|
</CommandList>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
{/* Active Filters */}
|
||||||
|
{hasFilters && (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{selectedSource && (
|
||||||
|
<Badge variant="secondary" className="gap-1">
|
||||||
|
{selectedSourceName}
|
||||||
|
<X
|
||||||
|
className="hover:text-destructive h-3 w-3 cursor-pointer"
|
||||||
|
onClick={() => onSourceChange(undefined)}
|
||||||
|
/>
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
|
{selectedStatus && (
|
||||||
|
<Badge variant="secondary" className="gap-1">
|
||||||
|
{selectedStatusLabel}
|
||||||
|
<X
|
||||||
|
className="hover:text-destructive h-3 w-3 cursor-pointer"
|
||||||
|
onClick={() => onStatusChange(undefined)}
|
||||||
|
/>
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
onClick={clearFilters}
|
||||||
|
className="h-6 px-2 text-xs"
|
||||||
|
>
|
||||||
|
Clear all
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
198
apps/webapp/app/components/logs/virtual-logs-list.tsx
Normal file
198
apps/webapp/app/components/logs/virtual-logs-list.tsx
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
import { List, InfiniteLoader, WindowScroller } from "react-virtualized";
|
||||||
|
import { LogItem } from "~/hooks/use-logs";
|
||||||
|
import { Badge } from "~/components/ui/badge";
|
||||||
|
import { Card, CardContent } from "~/components/ui/card";
|
||||||
|
import { AlertCircle, CheckCircle, Clock, XCircle } from "lucide-react";
|
||||||
|
import { cn } from "~/lib/utils";
|
||||||
|
|
||||||
|
interface VirtualLogsListProps {
|
||||||
|
logs: LogItem[];
|
||||||
|
hasMore: boolean;
|
||||||
|
loadMore: () => void;
|
||||||
|
isLoading: boolean;
|
||||||
|
height?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ITEM_HEIGHT = 120;
|
||||||
|
|
||||||
|
interface LogItemRendererProps {
|
||||||
|
index: number;
|
||||||
|
key: string;
|
||||||
|
style: React.CSSProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
function LogItemRenderer(props: LogItemRendererProps, logs: LogItem[]) {
|
||||||
|
const { index, key, style } = props;
|
||||||
|
const log = logs[index];
|
||||||
|
|
||||||
|
if (!log) {
|
||||||
|
return (
|
||||||
|
<div key={key} style={style} className="p-4">
|
||||||
|
<div className="h-24 animate-pulse rounded bg-gray-200" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getStatusIcon = (status: string) => {
|
||||||
|
switch (status) {
|
||||||
|
case "PROCESSING":
|
||||||
|
return <Clock className="h-4 w-4 text-blue-500" />;
|
||||||
|
case "PENDING":
|
||||||
|
return <Clock className="h-4 w-4 text-yellow-500" />;
|
||||||
|
case "COMPLETED":
|
||||||
|
return <CheckCircle className="h-4 w-4 text-green-500" />;
|
||||||
|
case "FAILED":
|
||||||
|
return <XCircle className="h-4 w-4 text-red-500" />;
|
||||||
|
case "CANCELLED":
|
||||||
|
return <XCircle className="h-4 w-4 text-gray-500" />;
|
||||||
|
default:
|
||||||
|
return <AlertCircle className="h-4 w-4 text-gray-500" />;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStatusColor = (status: string) => {
|
||||||
|
switch (status) {
|
||||||
|
case "PROCESSING":
|
||||||
|
return "bg-blue-100 text-blue-800";
|
||||||
|
case "PENDING":
|
||||||
|
return "bg-yellow-100 text-yellow-800";
|
||||||
|
case "COMPLETED":
|
||||||
|
return "bg-green-100 text-green-800";
|
||||||
|
case "FAILED":
|
||||||
|
return "bg-red-100 text-red-800";
|
||||||
|
case "CANCELLED":
|
||||||
|
return "bg-gray-100 text-gray-800";
|
||||||
|
default:
|
||||||
|
return "bg-gray-100 text-gray-800";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={key} style={style} className="p-2">
|
||||||
|
<Card className="h-full">
|
||||||
|
<CardContent className="p-4">
|
||||||
|
<div className="mb-2 flex items-start justify-between">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Badge variant="outline" className="text-xs">
|
||||||
|
{log.source}
|
||||||
|
</Badge>
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
{getStatusIcon(log.status)}
|
||||||
|
<Badge className={cn("text-xs", getStatusColor(log.status))}>
|
||||||
|
{log.status.toLowerCase()}
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-muted-foreground text-xs">
|
||||||
|
{new Date(log.time).toLocaleString()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-2">
|
||||||
|
<p className="line-clamp-2 text-sm text-gray-700">
|
||||||
|
{log.ingestText}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="text-muted-foreground flex items-center justify-between text-xs">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
{log.sourceURL && (
|
||||||
|
<a
|
||||||
|
href={log.sourceURL}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-blue-600 underline hover:text-blue-800"
|
||||||
|
>
|
||||||
|
Source URL
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
{log.processedAt && (
|
||||||
|
<span>
|
||||||
|
Processed: {new Date(log.processedAt).toLocaleString()}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{log.error && (
|
||||||
|
<div className="flex items-center gap-1 text-red-600">
|
||||||
|
<AlertCircle className="h-3 w-3" />
|
||||||
|
<span className="max-w-[200px] truncate" title={log.error}>
|
||||||
|
{log.error}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VirtualLogsList({
|
||||||
|
logs,
|
||||||
|
hasMore,
|
||||||
|
loadMore,
|
||||||
|
isLoading,
|
||||||
|
height = 600,
|
||||||
|
}: VirtualLogsListProps) {
|
||||||
|
const [containerHeight, setContainerHeight] = useState(height);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const updateHeight = () => {
|
||||||
|
const availableHeight = window.innerHeight - 300; // Account for header, filters, etc.
|
||||||
|
setContainerHeight(Math.min(availableHeight, height));
|
||||||
|
};
|
||||||
|
|
||||||
|
updateHeight();
|
||||||
|
window.addEventListener("resize", updateHeight);
|
||||||
|
return () => window.removeEventListener("resize", updateHeight);
|
||||||
|
}, [height]);
|
||||||
|
|
||||||
|
const isRowLoaded = ({ index }: { index: number }) => {
|
||||||
|
return !!logs[index];
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadMoreRows = async () => {
|
||||||
|
if (hasMore) {
|
||||||
|
return loadMore();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const rowRenderer = (props: LogItemRendererProps) => {
|
||||||
|
return LogItemRenderer(props, logs);
|
||||||
|
};
|
||||||
|
|
||||||
|
const itemCount = hasMore ? logs.length + 1 : logs.length;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="overflow-hidden rounded-lg border">
|
||||||
|
<InfiniteLoader
|
||||||
|
isRowLoaded={isRowLoaded}
|
||||||
|
loadMoreRows={loadMoreRows}
|
||||||
|
rowCount={itemCount}
|
||||||
|
threshold={5}
|
||||||
|
>
|
||||||
|
{({ onRowsRendered, registerChild }) => (
|
||||||
|
<List
|
||||||
|
ref={registerChild}
|
||||||
|
height={containerHeight}
|
||||||
|
rowCount={itemCount}
|
||||||
|
rowHeight={ITEM_HEIGHT}
|
||||||
|
onRowsRendered={onRowsRendered}
|
||||||
|
rowRenderer={rowRenderer}
|
||||||
|
className="scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</InfiniteLoader>
|
||||||
|
|
||||||
|
{isLoading && (
|
||||||
|
<div className="text-muted-foreground p-4 text-center text-sm">
|
||||||
|
Loading more logs...
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -28,8 +28,8 @@ const data = {
|
|||||||
icon: Network,
|
icon: Network,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Activity",
|
title: "Logs",
|
||||||
url: "/home/activity",
|
url: "/home/logs/all",
|
||||||
icon: Activity,
|
icon: Activity,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
179
apps/webapp/app/components/ui/command.tsx
Normal file
179
apps/webapp/app/components/ui/command.tsx
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
import { type DialogProps } from "@radix-ui/react-dialog";
|
||||||
|
import { MagnifyingGlassIcon } from "@radix-ui/react-icons";
|
||||||
|
import { Command as CommandPrimitive } from "cmdk";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { Dialog, DialogContent } from "./dialog";
|
||||||
|
import { cn } from "../../lib/utils";
|
||||||
|
|
||||||
|
const Command = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<CommandPrimitive
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md font-sans",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
Command.displayName = CommandPrimitive.displayName;
|
||||||
|
|
||||||
|
interface CommandDialogProps extends DialogProps {
|
||||||
|
commandProps?: React.ComponentPropsWithoutRef<typeof CommandPrimitive>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CommandInputProps
|
||||||
|
extends React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input> {
|
||||||
|
icon?: boolean;
|
||||||
|
containerClassName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CommandDialog = ({
|
||||||
|
children,
|
||||||
|
commandProps,
|
||||||
|
...props
|
||||||
|
}: CommandDialogProps) => {
|
||||||
|
return (
|
||||||
|
<Dialog {...props}>
|
||||||
|
<DialogContent className={cn("overflow-hidden p-0 font-sans")}>
|
||||||
|
<Command
|
||||||
|
className="[&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5"
|
||||||
|
{...commandProps}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Command>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const CommandInput = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive.Input>,
|
||||||
|
CommandInputProps
|
||||||
|
>(({ className, icon, containerClassName, ...props }, ref) => (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"border-border flex items-center border-b px-3",
|
||||||
|
containerClassName,
|
||||||
|
)}
|
||||||
|
cmdk-input-wrapper=""
|
||||||
|
>
|
||||||
|
{icon && (
|
||||||
|
<MagnifyingGlassIcon className="mr-2 h-5 w-5 shrink-0 opacity-50" />
|
||||||
|
)}
|
||||||
|
<CommandPrimitive.Input
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"placeholder:text-muted-foreground flex h-8 w-full rounded-md bg-transparent py-3 outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
|
||||||
|
CommandInput.displayName = CommandPrimitive.Input.displayName;
|
||||||
|
|
||||||
|
const CommandList = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive.List>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<CommandPrimitive.List
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"command-list max-h-[500px] overflow-x-hidden overflow-y-auto",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
CommandList.displayName = CommandPrimitive.List.displayName;
|
||||||
|
|
||||||
|
const CommandEmpty = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive.Empty>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
|
||||||
|
>((props, ref) => (
|
||||||
|
<CommandPrimitive.Empty
|
||||||
|
ref={ref}
|
||||||
|
className="py-6 text-center text-sm"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
|
||||||
|
|
||||||
|
const CommandGroup = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive.Group>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<CommandPrimitive.Group
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
CommandGroup.displayName = CommandPrimitive.Group.displayName;
|
||||||
|
|
||||||
|
const CommandSeparator = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive.Separator>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<CommandPrimitive.Separator
|
||||||
|
ref={ref}
|
||||||
|
className={cn("bg-border -mx-1 h-px", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
|
||||||
|
|
||||||
|
const CommandItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CommandPrimitive.Item>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<CommandPrimitive.Item
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"command-item aria-selected:bg-accent aria-selected:text-accent-foreground relative flex cursor-default items-center rounded-sm px-2 py-1 outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
CommandItem.displayName = CommandPrimitive.Item.displayName;
|
||||||
|
|
||||||
|
const CommandShortcut = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className={cn(
|
||||||
|
"text-muted-foreground ml-auto text-xs tracking-widest",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
CommandShortcut.displayName = "CommandShortcut";
|
||||||
|
|
||||||
|
export {
|
||||||
|
Command,
|
||||||
|
CommandDialog,
|
||||||
|
CommandInput,
|
||||||
|
CommandList,
|
||||||
|
CommandEmpty,
|
||||||
|
CommandGroup,
|
||||||
|
CommandItem,
|
||||||
|
CommandShortcut,
|
||||||
|
CommandSeparator,
|
||||||
|
};
|
||||||
@ -7,7 +7,7 @@ const PAGE_TITLES: Record<string, string> = {
|
|||||||
"/home/dashboard": "Memory graph",
|
"/home/dashboard": "Memory graph",
|
||||||
"/home/conversation": "Conversation",
|
"/home/conversation": "Conversation",
|
||||||
"/home/integrations": "Integrations",
|
"/home/integrations": "Integrations",
|
||||||
"/home/activity": "Activity",
|
"/home/logs": "Logs",
|
||||||
};
|
};
|
||||||
|
|
||||||
function getHeaderTitle(pathname: string): string {
|
function getHeaderTitle(pathname: string): string {
|
||||||
@ -26,12 +26,17 @@ function isConversationDetail(pathname: string): boolean {
|
|||||||
return /^\/home\/conversation\/[^/]+$/.test(pathname);
|
return /^\/home\/conversation\/[^/]+$/.test(pathname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isIntegrationsPage(pathname: string): boolean {
|
||||||
|
return pathname === "/home/integrations";
|
||||||
|
}
|
||||||
|
|
||||||
export function SiteHeader() {
|
export function SiteHeader() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const title = getHeaderTitle(location.pathname);
|
const title = getHeaderTitle(location.pathname);
|
||||||
|
|
||||||
const showNewConversationButton = isConversationDetail(location.pathname);
|
const showNewConversationButton = isConversationDetail(location.pathname);
|
||||||
|
const showRequestIntegrationButton = isIntegrationsPage(location.pathname);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="flex h-(--header-height) shrink-0 items-center gap-2 border-b border-gray-300 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-(--header-height)">
|
<header className="flex h-(--header-height) shrink-0 items-center gap-2 border-b border-gray-300 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-(--header-height)">
|
||||||
@ -51,6 +56,16 @@ export function SiteHeader() {
|
|||||||
New conversation
|
New conversation
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
{showRequestIntegrationButton && (
|
||||||
|
<Button
|
||||||
|
onClick={() => window.open("https://github.com/redplanethq/core/issues/new", "_blank")}
|
||||||
|
variant="secondary"
|
||||||
|
className="gap-2"
|
||||||
|
>
|
||||||
|
<Plus size={14} />
|
||||||
|
Request New Integration
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@ -263,7 +263,8 @@ function SidebarTrigger({
|
|||||||
data-sidebar="trigger"
|
data-sidebar="trigger"
|
||||||
data-slot="sidebar-trigger"
|
data-slot="sidebar-trigger"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
className={cn("size-8", className)}
|
size="xs"
|
||||||
|
className={cn("size-6 rounded-md", className)}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
onClick?.(event);
|
onClick?.(event);
|
||||||
toggleSidebar();
|
toggleSidebar();
|
||||||
|
|||||||
@ -36,7 +36,7 @@ export function useIngestionStatus() {
|
|||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
setIsPolling(false);
|
setIsPolling(false);
|
||||||
};
|
};
|
||||||
}, [fetcher]);
|
}, []); // Remove fetcher from dependencies to prevent infinite loop
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: fetcher.data,
|
data: fetcher.data,
|
||||||
|
|||||||
108
apps/webapp/app/hooks/use-logs.tsx
Normal file
108
apps/webapp/app/hooks/use-logs.tsx
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import { useEffect, useState, useCallback } from "react";
|
||||||
|
import { useFetcher } from "@remix-run/react";
|
||||||
|
|
||||||
|
export interface LogItem {
|
||||||
|
id: string;
|
||||||
|
source: string;
|
||||||
|
ingestText: string;
|
||||||
|
time: string;
|
||||||
|
processedAt?: string;
|
||||||
|
status: "PENDING" | "PROCESSING" | "COMPLETED" | "FAILED" | "CANCELLED";
|
||||||
|
error?: string;
|
||||||
|
sourceURL?: string;
|
||||||
|
integrationSlug?: string;
|
||||||
|
activityId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LogsResponse {
|
||||||
|
logs: LogItem[];
|
||||||
|
totalCount: number;
|
||||||
|
page: number;
|
||||||
|
limit: number;
|
||||||
|
hasMore: boolean;
|
||||||
|
availableSources: Array<{ name: string; slug: string }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UseLogsOptions {
|
||||||
|
endpoint: string; // '/api/v1/logs/all' or '/api/v1/logs/activity'
|
||||||
|
source?: string;
|
||||||
|
status?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useLogs({ endpoint, source, status }: UseLogsOptions) {
|
||||||
|
const fetcher = useFetcher<LogsResponse>();
|
||||||
|
const [logs, setLogs] = useState<LogItem[]>([]);
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
const [hasMore, setHasMore] = useState(true);
|
||||||
|
const [availableSources, setAvailableSources] = useState<Array<{ name: string; slug: string }>>([]);
|
||||||
|
const [isInitialLoad, setIsInitialLoad] = useState(true);
|
||||||
|
|
||||||
|
const buildUrl = useCallback((pageNum: number) => {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
params.set('page', pageNum.toString());
|
||||||
|
params.set('limit', '20');
|
||||||
|
if (source) params.set('source', source);
|
||||||
|
if (status) params.set('status', status);
|
||||||
|
return `${endpoint}?${params.toString()}`;
|
||||||
|
}, [endpoint, source, status]);
|
||||||
|
|
||||||
|
const loadMore = useCallback(() => {
|
||||||
|
if (fetcher.state === 'idle' && hasMore) {
|
||||||
|
fetcher.load(buildUrl(page + 1));
|
||||||
|
}
|
||||||
|
}, [hasMore, page, buildUrl]);
|
||||||
|
|
||||||
|
const reset = useCallback(() => {
|
||||||
|
setLogs([]);
|
||||||
|
setPage(1);
|
||||||
|
setHasMore(true);
|
||||||
|
setIsInitialLoad(true);
|
||||||
|
fetcher.load(buildUrl(1));
|
||||||
|
}, [buildUrl]);
|
||||||
|
|
||||||
|
// Effect to handle fetcher data
|
||||||
|
useEffect(() => {
|
||||||
|
if (fetcher.data) {
|
||||||
|
const { logs: newLogs, hasMore: newHasMore, page: currentPage, availableSources: sources } = fetcher.data;
|
||||||
|
|
||||||
|
if (currentPage === 1) {
|
||||||
|
// First page or reset
|
||||||
|
setLogs(newLogs);
|
||||||
|
setIsInitialLoad(false);
|
||||||
|
} else {
|
||||||
|
// Append to existing logs
|
||||||
|
setLogs(prev => [...prev, ...newLogs]);
|
||||||
|
}
|
||||||
|
|
||||||
|
setHasMore(newHasMore);
|
||||||
|
setPage(currentPage);
|
||||||
|
setAvailableSources(sources);
|
||||||
|
}
|
||||||
|
}, [fetcher.data]);
|
||||||
|
|
||||||
|
// Effect to reset when filters change
|
||||||
|
useEffect(() => {
|
||||||
|
setLogs([]);
|
||||||
|
setPage(1);
|
||||||
|
setHasMore(true);
|
||||||
|
setIsInitialLoad(true);
|
||||||
|
fetcher.load(buildUrl(1));
|
||||||
|
}, [source, status, buildUrl]); // Inline reset logic to avoid dependency issues
|
||||||
|
|
||||||
|
// Initial load
|
||||||
|
useEffect(() => {
|
||||||
|
if (isInitialLoad) {
|
||||||
|
fetcher.load(buildUrl(1));
|
||||||
|
}
|
||||||
|
}, [isInitialLoad, buildUrl]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
logs,
|
||||||
|
hasMore,
|
||||||
|
loadMore,
|
||||||
|
reset,
|
||||||
|
availableSources,
|
||||||
|
isLoading: fetcher.state === 'loading',
|
||||||
|
isInitialLoad,
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -16,6 +16,7 @@ export const IngestBodyRequest = z.object({
|
|||||||
export const addToQueue = async (
|
export const addToQueue = async (
|
||||||
body: z.infer<typeof IngestBodyRequest>,
|
body: z.infer<typeof IngestBodyRequest>,
|
||||||
userId: string,
|
userId: string,
|
||||||
|
activityId?: string,
|
||||||
) => {
|
) => {
|
||||||
const user = await prisma.user.findFirst({
|
const user = await prisma.user.findFirst({
|
||||||
where: {
|
where: {
|
||||||
@ -39,6 +40,7 @@ export const addToQueue = async (
|
|||||||
status: IngestionStatus.PENDING,
|
status: IngestionStatus.PENDING,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
workspaceId: user.Workspace.id,
|
workspaceId: user.Workspace.id,
|
||||||
|
activityId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,6 @@ const { action, loader } = createActionApiRoute(
|
|||||||
throw new Error("User not found");
|
throw new Error("User not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Create the activity record
|
// Create the activity record
|
||||||
const activity = await prisma.activity.create({
|
const activity = await prisma.activity.create({
|
||||||
data: {
|
data: {
|
||||||
@ -64,7 +63,11 @@ const { action, loader } = createActionApiRoute(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const queueResponse = await addToQueue(ingestData, authentication.userId);
|
const queueResponse = await addToQueue(
|
||||||
|
ingestData,
|
||||||
|
authentication.userId,
|
||||||
|
activity.id,
|
||||||
|
);
|
||||||
|
|
||||||
logger.log("Activity created and queued for ingestion", {
|
logger.log("Activity created and queued for ingestion", {
|
||||||
activityId: activity.id,
|
activityId: activity.id,
|
||||||
|
|||||||
130
apps/webapp/app/routes/api.v1.logs.activity.tsx
Normal file
130
apps/webapp/app/routes/api.v1.logs.activity.tsx
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import { LoaderFunctionArgs, json } from "@remix-run/node";
|
||||||
|
import { prisma } from "~/db.server";
|
||||||
|
import { requireUserId } from "~/services/session.server";
|
||||||
|
|
||||||
|
export async function loader({ request }: LoaderFunctionArgs) {
|
||||||
|
const userId = await requireUserId(request);
|
||||||
|
const url = new URL(request.url);
|
||||||
|
|
||||||
|
const page = parseInt(url.searchParams.get("page") || "1");
|
||||||
|
const limit = parseInt(url.searchParams.get("limit") || "20");
|
||||||
|
const source = url.searchParams.get("source");
|
||||||
|
const status = url.searchParams.get("status");
|
||||||
|
const skip = (page - 1) * limit;
|
||||||
|
|
||||||
|
const user = await prisma.user.findUnique({
|
||||||
|
where: { id: userId },
|
||||||
|
include: { Workspace: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user?.Workspace) {
|
||||||
|
throw new Response("Workspace not found", { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build where clause for filtering - only items with activityId
|
||||||
|
const whereClause: any = {
|
||||||
|
workspaceId: user.Workspace.id,
|
||||||
|
activityId: {
|
||||||
|
not: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
whereClause.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If source filter is provided, we need to filter by integration source
|
||||||
|
if (source) {
|
||||||
|
whereClause.activity = {
|
||||||
|
integrationAccount: {
|
||||||
|
integrationDefinition: {
|
||||||
|
slug: source,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const [logs, totalCount] = await Promise.all([
|
||||||
|
prisma.ingestionQueue.findMany({
|
||||||
|
where: whereClause,
|
||||||
|
include: {
|
||||||
|
activity: {
|
||||||
|
include: {
|
||||||
|
integrationAccount: {
|
||||||
|
include: {
|
||||||
|
integrationDefinition: {
|
||||||
|
select: {
|
||||||
|
name: true,
|
||||||
|
slug: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
skip,
|
||||||
|
take: limit,
|
||||||
|
}),
|
||||||
|
prisma.ingestionQueue.count({
|
||||||
|
where: whereClause,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Get available sources for filtering (only those with activities)
|
||||||
|
const availableSources = await prisma.integrationDefinitionV2.findMany({
|
||||||
|
where: {
|
||||||
|
IntegrationAccount: {
|
||||||
|
some: {
|
||||||
|
workspaceId: user.Workspace.id,
|
||||||
|
Activity: {
|
||||||
|
some: {
|
||||||
|
IngestionQueue: {
|
||||||
|
some: {
|
||||||
|
activityId: {
|
||||||
|
not: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
name: true,
|
||||||
|
slug: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Format the response
|
||||||
|
const formattedLogs = logs.map((log) => ({
|
||||||
|
id: log.id,
|
||||||
|
source: log.activity?.integrationAccount?.integrationDefinition?.name ||
|
||||||
|
(log.data as any)?.source ||
|
||||||
|
'Unknown',
|
||||||
|
ingestText: log.activity?.text ||
|
||||||
|
(log.data as any)?.episodeBody ||
|
||||||
|
(log.data as any)?.text ||
|
||||||
|
'No content',
|
||||||
|
time: log.createdAt,
|
||||||
|
processedAt: log.processedAt,
|
||||||
|
status: log.status,
|
||||||
|
error: log.error,
|
||||||
|
sourceURL: log.activity?.sourceURL,
|
||||||
|
integrationSlug: log.activity?.integrationAccount?.integrationDefinition?.slug,
|
||||||
|
activityId: log.activityId,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return json({
|
||||||
|
logs: formattedLogs,
|
||||||
|
totalCount,
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
hasMore: skip + logs.length < totalCount,
|
||||||
|
availableSources,
|
||||||
|
});
|
||||||
|
}
|
||||||
137
apps/webapp/app/routes/api.v1.logs.all.tsx
Normal file
137
apps/webapp/app/routes/api.v1.logs.all.tsx
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
import { type LoaderFunctionArgs, json } from "@remix-run/node";
|
||||||
|
import { prisma } from "~/db.server";
|
||||||
|
import { requireUserId } from "~/services/session.server";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optimizations:
|
||||||
|
* - Use `findMany` with `select` instead of `include` to fetch only required fields.
|
||||||
|
* - Use `count` with the same where clause, but only after fetching logs (to avoid unnecessary count if no logs).
|
||||||
|
* - Use a single query for availableSources with minimal fields.
|
||||||
|
* - Avoid unnecessary object spreading and type casting.
|
||||||
|
* - Minimize nested object traversal in mapping.
|
||||||
|
*/
|
||||||
|
export async function loader({ request }: LoaderFunctionArgs) {
|
||||||
|
const userId = await requireUserId(request);
|
||||||
|
const url = new URL(request.url);
|
||||||
|
|
||||||
|
const page = parseInt(url.searchParams.get("page") || "1");
|
||||||
|
const limit = parseInt(url.searchParams.get("limit") || "20");
|
||||||
|
const source = url.searchParams.get("source");
|
||||||
|
const status = url.searchParams.get("status");
|
||||||
|
const skip = (page - 1) * limit;
|
||||||
|
|
||||||
|
// Get user and workspace in one query
|
||||||
|
const user = await prisma.user.findUnique({
|
||||||
|
where: { id: userId },
|
||||||
|
select: { Workspace: { select: { id: true } } },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user?.Workspace) {
|
||||||
|
throw new Response("Workspace not found", { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build where clause for filtering
|
||||||
|
const whereClause: any = {
|
||||||
|
workspaceId: user.Workspace.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
whereClause.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If source filter is provided, filter by integration source
|
||||||
|
if (source) {
|
||||||
|
whereClause.activity = {
|
||||||
|
integrationAccount: {
|
||||||
|
integrationDefinition: {
|
||||||
|
slug: source,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use select to fetch only required fields for logs
|
||||||
|
const [logs, totalCount, availableSources] = await Promise.all([
|
||||||
|
prisma.ingestionQueue.findMany({
|
||||||
|
where: whereClause,
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
createdAt: true,
|
||||||
|
processedAt: true,
|
||||||
|
status: true,
|
||||||
|
error: true,
|
||||||
|
data: true,
|
||||||
|
activity: {
|
||||||
|
select: {
|
||||||
|
text: true,
|
||||||
|
sourceURL: true,
|
||||||
|
integrationAccount: {
|
||||||
|
select: {
|
||||||
|
integrationDefinition: {
|
||||||
|
select: {
|
||||||
|
name: true,
|
||||||
|
slug: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
skip,
|
||||||
|
take: limit,
|
||||||
|
}),
|
||||||
|
|
||||||
|
prisma.ingestionQueue.count({
|
||||||
|
where: whereClause,
|
||||||
|
}),
|
||||||
|
|
||||||
|
prisma.integrationDefinitionV2.findMany({
|
||||||
|
where: {
|
||||||
|
IntegrationAccount: {
|
||||||
|
some: {
|
||||||
|
workspaceId: user.Workspace.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
name: true,
|
||||||
|
slug: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Format the response
|
||||||
|
const formattedLogs = logs.map((log) => {
|
||||||
|
const integrationDef =
|
||||||
|
log.activity?.integrationAccount?.integrationDefinition;
|
||||||
|
const logData = log.data as any;
|
||||||
|
return {
|
||||||
|
id: log.id,
|
||||||
|
source: integrationDef?.name || logData?.source || "Unknown",
|
||||||
|
ingestText:
|
||||||
|
log.activity?.text ||
|
||||||
|
logData?.episodeBody ||
|
||||||
|
logData?.text ||
|
||||||
|
"No content",
|
||||||
|
time: log.createdAt,
|
||||||
|
processedAt: log.processedAt,
|
||||||
|
status: log.status,
|
||||||
|
error: log.error,
|
||||||
|
sourceURL: log.activity?.sourceURL,
|
||||||
|
integrationSlug: integrationDef?.slug,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return json({
|
||||||
|
logs: formattedLogs,
|
||||||
|
totalCount,
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
hasMore: skip + logs.length < totalCount,
|
||||||
|
availableSources,
|
||||||
|
});
|
||||||
|
}
|
||||||
@ -6,13 +6,27 @@ import { requireUserId, requireWorkpace } from "~/services/session.server";
|
|||||||
import { getIntegrationDefinitions } from "~/services/integrationDefinition.server";
|
import { getIntegrationDefinitions } from "~/services/integrationDefinition.server";
|
||||||
import { getIntegrationAccounts } from "~/services/integrationAccount.server";
|
import { getIntegrationAccounts } from "~/services/integrationAccount.server";
|
||||||
|
|
||||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "~/components/ui/card";
|
import {
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardDescription,
|
||||||
|
CardFooter,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
} from "~/components/ui/card";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "~/components/ui/dialog";
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "~/components/ui/dialog";
|
||||||
import { Input } from "~/components/ui/input";
|
import { Input } from "~/components/ui/input";
|
||||||
import { FormButtons } from "~/components/ui/FormButtons";
|
import { FormButtons } from "~/components/ui/FormButtons";
|
||||||
import { Plus, Search } from "lucide-react";
|
import { Plus, Search } from "lucide-react";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/components/ui/select";
|
|
||||||
|
|
||||||
// Loader to fetch integration definitions and existing accounts
|
// Loader to fetch integration definitions and existing accounts
|
||||||
export async function loader({ request }: LoaderFunctionArgs) {
|
export async function loader({ request }: LoaderFunctionArgs) {
|
||||||
@ -32,39 +46,19 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Integrations() {
|
export default function Integrations() {
|
||||||
const { integrationDefinitions, integrationAccounts, userId } = useLoaderData<typeof loader>();
|
const { integrationDefinitions, integrationAccounts, userId } =
|
||||||
const [selectedCategory, setSelectedCategory] = useState<string>("all");
|
useLoaderData<typeof loader>();
|
||||||
const [selectedIntegration, setSelectedIntegration] = useState<any>(null);
|
const [selectedIntegration, setSelectedIntegration] = useState<any>(null);
|
||||||
const [apiKey, setApiKey] = useState("");
|
const [apiKey, setApiKey] = useState("");
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [isConnecting, setIsConnecting] = useState(false);
|
const [isConnecting, setIsConnecting] = useState(false);
|
||||||
|
|
||||||
// Extract categories from integration definitions
|
|
||||||
const categories = Array.from(
|
|
||||||
new Set(integrationDefinitions.map((integration) => {
|
|
||||||
const specData = typeof integration.spec === 'string'
|
|
||||||
? JSON.parse(integration.spec)
|
|
||||||
: integration.spec;
|
|
||||||
return specData?.category || "Uncategorized";
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
// Filter integrations by selected category
|
|
||||||
const filteredIntegrations = selectedCategory === "all"
|
|
||||||
? integrationDefinitions
|
|
||||||
: integrationDefinitions.filter(
|
|
||||||
(integration) => {
|
|
||||||
const specData = typeof integration.spec === 'string'
|
|
||||||
? JSON.parse(integration.spec)
|
|
||||||
: integration.spec;
|
|
||||||
return specData?.category === selectedCategory;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check if user has an active account for an integration
|
// Check if user has an active account for an integration
|
||||||
const hasActiveAccount = (integrationDefinitionId: string) => {
|
const hasActiveAccount = (integrationDefinitionId: string) => {
|
||||||
return integrationAccounts.some(
|
return integrationAccounts.some(
|
||||||
(account) => account.integrationDefinitionId === integrationDefinitionId && account.isActive
|
(account) =>
|
||||||
|
account.integrationDefinitionId === integrationDefinitionId &&
|
||||||
|
account.isActive,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -134,56 +128,32 @@ export default function Integrations() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="home flex h-full flex-col overflow-y-auto p-3">
|
<div className="home flex h-full flex-col overflow-y-auto p-4 px-5">
|
||||||
<div className="flex items-center justify-between">
|
<div className="space-y-1 text-base">
|
||||||
<div className="space-y-1 text-base">
|
<p className="text-muted-foreground">Connect your tools and services</p>
|
||||||
<h2 className="text-lg font-semibold">Integrations</h2>
|
|
||||||
<p className="text-muted-foreground">Connect your tools and services</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
{/* Category filter */}
|
|
||||||
<Select
|
|
||||||
value={selectedCategory}
|
|
||||||
onValueChange={setSelectedCategory}
|
|
||||||
>
|
|
||||||
<SelectTrigger className="w-[180px]">
|
|
||||||
<SelectValue placeholder="Category" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="all">All Categories</SelectItem>
|
|
||||||
{categories.map((category) => (
|
|
||||||
<SelectItem key={category} value={category}>{category}</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
|
|
||||||
{/* Add integration button */}
|
|
||||||
<Button variant="default" size="sm">
|
|
||||||
<Plus className="mr-1 h-3.5 w-3.5" />
|
|
||||||
Add integration
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Integration cards grid */}
|
{/* Integration cards grid */}
|
||||||
<div className="mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
|
<div className="mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
|
||||||
{filteredIntegrations.map((integration) => {
|
{integrationDefinitions.map((integration) => {
|
||||||
const isConnected = hasActiveAccount(integration.id);
|
const isConnected = hasActiveAccount(integration.id);
|
||||||
const authType = integration.spec?.auth?.type || "unknown";
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog key={integration.id} onOpenChange={(open) => {
|
<Dialog
|
||||||
if (open) {
|
key={integration.id}
|
||||||
setSelectedIntegration(integration);
|
onOpenChange={(open) => {
|
||||||
setApiKey("");
|
if (open) {
|
||||||
} else {
|
setSelectedIntegration(integration);
|
||||||
setSelectedIntegration(null);
|
setApiKey("");
|
||||||
}
|
} else {
|
||||||
}}>
|
setSelectedIntegration(null);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Card className="cursor-pointer transition-all hover:shadow-md">
|
<Card className="cursor-pointer transition-all hover:shadow-md">
|
||||||
<CardHeader className="p-4">
|
<CardHeader className="p-4">
|
||||||
<div className="mb-2 flex h-10 w-10 items-center justify-center rounded bg-background-2">
|
<div className="bg-background-2 mb-2 flex h-10 w-10 items-center justify-center rounded">
|
||||||
{integration.icon ? (
|
{integration.icon ? (
|
||||||
<img
|
<img
|
||||||
src={integration.icon}
|
src={integration.icon}
|
||||||
@ -194,27 +164,24 @@ export default function Integrations() {
|
|||||||
<div className="h-6 w-6 rounded-full bg-gray-300" />
|
<div className="h-6 w-6 rounded-full bg-gray-300" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<CardTitle className="text-base">{integration.name}</CardTitle>
|
<CardTitle className="text-base">
|
||||||
|
{integration.name}
|
||||||
|
</CardTitle>
|
||||||
<CardDescription className="line-clamp-2 text-xs">
|
<CardDescription className="line-clamp-2 text-xs">
|
||||||
{integration.description || "Connect to " + integration.name}
|
{integration.description ||
|
||||||
|
"Connect to " + integration.name}
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardFooter className="border-t p-3">
|
<CardFooter className="border-t p-3">
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="flex w-full items-center justify-end">
|
||||||
<span className="text-xs text-muted-foreground">
|
|
||||||
{(() => {
|
|
||||||
const specData = typeof integration.spec === 'string'
|
|
||||||
? JSON.parse(integration.spec)
|
|
||||||
: integration.spec;
|
|
||||||
return specData?.category || "Uncategorized";
|
|
||||||
})()}
|
|
||||||
</span>
|
|
||||||
{isConnected ? (
|
{isConnected ? (
|
||||||
<span className="rounded-full bg-green-100 px-2 py-0.5 text-xs text-green-800">
|
<span className="rounded-full bg-green-100 px-2 py-0.5 text-xs text-green-800">
|
||||||
Connected
|
Connected
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<span className="text-xs text-muted-foreground">Not connected</span>
|
<span className="text-muted-foreground text-xs">
|
||||||
|
Not connected
|
||||||
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
@ -225,26 +192,29 @@ export default function Integrations() {
|
|||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Connect to {integration.name}</DialogTitle>
|
<DialogTitle>Connect to {integration.name}</DialogTitle>
|
||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
{integration.description || `Connect your ${integration.name} account to enable integration.`}
|
{integration.description ||
|
||||||
|
`Connect your ${integration.name} account to enable integration.`}
|
||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
{/* API Key Authentication */}
|
{/* API Key Authentication */}
|
||||||
{(() => {
|
{(() => {
|
||||||
const specData = typeof integration.spec === 'string'
|
const specData =
|
||||||
? JSON.parse(integration.spec)
|
typeof integration.spec === "string"
|
||||||
: integration.spec;
|
? JSON.parse(integration.spec)
|
||||||
|
: integration.spec;
|
||||||
return specData?.auth?.api_key;
|
return specData?.auth?.api_key;
|
||||||
})() && (
|
})() && (
|
||||||
<div className="space-y-4 py-4">
|
<div className="space-y-4 py-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<label htmlFor="apiKey" className="text-sm font-medium">
|
<label htmlFor="apiKey" className="text-sm font-medium">
|
||||||
{(() => {
|
{(() => {
|
||||||
const specData = typeof integration.spec === 'string'
|
const specData =
|
||||||
? JSON.parse(integration.spec)
|
typeof integration.spec === "string"
|
||||||
: integration.spec;
|
? JSON.parse(integration.spec)
|
||||||
return specData?.auth?.api_key?.label || "API Key";
|
: integration.spec;
|
||||||
})()}
|
return specData?.auth?.api_key?.label || "API Key";
|
||||||
|
})()}
|
||||||
</label>
|
</label>
|
||||||
<Input
|
<Input
|
||||||
id="apiKey"
|
id="apiKey"
|
||||||
@ -254,40 +224,45 @@ export default function Integrations() {
|
|||||||
onChange={(e) => setApiKey(e.target.value)}
|
onChange={(e) => setApiKey(e.target.value)}
|
||||||
/>
|
/>
|
||||||
{(() => {
|
{(() => {
|
||||||
const specData = typeof integration.spec === 'string'
|
const specData =
|
||||||
? JSON.parse(integration.spec)
|
typeof integration.spec === "string"
|
||||||
: integration.spec;
|
? JSON.parse(integration.spec)
|
||||||
|
: integration.spec;
|
||||||
return specData?.auth?.api_key?.description;
|
return specData?.auth?.api_key?.description;
|
||||||
})() && (
|
})() && (
|
||||||
<p className="text-xs text-muted-foreground">
|
<p className="text-muted-foreground text-xs">
|
||||||
{(() => {
|
{(() => {
|
||||||
const specData = typeof integration.spec === 'string'
|
const specData =
|
||||||
? JSON.parse(integration.spec)
|
typeof integration.spec === "string"
|
||||||
: integration.spec;
|
? JSON.parse(integration.spec)
|
||||||
|
: integration.spec;
|
||||||
return specData?.auth?.api_key?.description;
|
return specData?.auth?.api_key?.description;
|
||||||
})()}
|
})()}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<FormButtons>
|
<FormButtons
|
||||||
<Button
|
confirmButton={
|
||||||
type="button"
|
<Button
|
||||||
variant="default"
|
type="button"
|
||||||
disabled={isLoading || !apiKey.trim()}
|
variant="default"
|
||||||
onClick={handleApiKeyConnect}
|
disabled={isLoading || !apiKey.trim()}
|
||||||
>
|
onClick={handleApiKeyConnect}
|
||||||
{isLoading ? "Connecting..." : "Connect"}
|
>
|
||||||
</Button>
|
{isLoading ? "Connecting..." : "Connect"}
|
||||||
</FormButtons>
|
</Button>
|
||||||
|
}
|
||||||
|
></FormButtons>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* OAuth Authentication */}
|
{/* OAuth Authentication */}
|
||||||
{(() => {
|
{(() => {
|
||||||
const specData = typeof integration.spec === 'string'
|
const specData =
|
||||||
? JSON.parse(integration.spec)
|
typeof integration.spec === "string"
|
||||||
: integration.spec;
|
? JSON.parse(integration.spec)
|
||||||
|
: integration.spec;
|
||||||
return specData?.auth?.oauth2;
|
return specData?.auth?.oauth2;
|
||||||
})() && (
|
})() && (
|
||||||
<div className="flex justify-center py-8">
|
<div className="flex justify-center py-8">
|
||||||
@ -298,26 +273,30 @@ export default function Integrations() {
|
|||||||
disabled={isConnecting}
|
disabled={isConnecting}
|
||||||
onClick={handleOAuthConnect}
|
onClick={handleOAuthConnect}
|
||||||
>
|
>
|
||||||
{isConnecting ? "Connecting..." : `Connect to ${integration.name}`}
|
{isConnecting
|
||||||
|
? "Connecting..."
|
||||||
|
: `Connect to ${integration.name}`}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* No authentication method found */}
|
{/* No authentication method found */}
|
||||||
{(() => {
|
{(() => {
|
||||||
const specData = typeof integration.spec === 'string'
|
const specData =
|
||||||
? JSON.parse(integration.spec)
|
typeof integration.spec === "string"
|
||||||
: integration.spec;
|
? JSON.parse(integration.spec)
|
||||||
|
: integration.spec;
|
||||||
return !specData?.auth?.api_key && !specData?.auth?.oauth2;
|
return !specData?.auth?.api_key && !specData?.auth?.oauth2;
|
||||||
})() && (
|
})() && (
|
||||||
<div className="py-4 text-center text-muted-foreground">
|
<div className="text-muted-foreground py-4 text-center">
|
||||||
This integration doesn't specify an authentication method.
|
This integration doesn't specify an authentication method.
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<DialogFooter className="sm:justify-start">
|
<DialogFooter className="sm:justify-start">
|
||||||
<div className="w-full text-xs text-muted-foreground">
|
<div className="text-muted-foreground w-full text-xs">
|
||||||
By connecting, you agree to the {integration.name} terms of service.
|
By connecting, you agree to the {integration.name} terms of
|
||||||
|
service.
|
||||||
</div>
|
</div>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
@ -327,15 +306,10 @@ export default function Integrations() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Empty state */}
|
{/* Empty state */}
|
||||||
{filteredIntegrations.length === 0 && (
|
{integrationDefinitions.length === 0 && (
|
||||||
<div className="mt-20 flex flex-col items-center justify-center">
|
<div className="mt-20 flex flex-col items-center justify-center">
|
||||||
<Search className="mb-2 h-12 w-12 text-muted-foreground" />
|
<Search className="text-muted-foreground mb-2 h-12 w-12" />
|
||||||
<h3 className="text-lg font-medium">No integrations found</h3>
|
<h3 className="text-lg font-medium">No integrations found</h3>
|
||||||
<p className="text-muted-foreground">
|
|
||||||
{selectedCategory === "all"
|
|
||||||
? "No integrations are available at this time."
|
|
||||||
: `No integrations found in the "${selectedCategory}" category.`}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
116
apps/webapp/app/routes/home.logs.activity.tsx
Normal file
116
apps/webapp/app/routes/home.logs.activity.tsx
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { useLogs } from "~/hooks/use-logs";
|
||||||
|
import { LogsFilters } from "~/components/logs/logs-filters";
|
||||||
|
import { VirtualLogsList } from "~/components/logs/virtual-logs-list";
|
||||||
|
import { AppContainer, PageContainer, PageBody } from "~/components/layout/app-layout";
|
||||||
|
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
||||||
|
import { Badge } from "~/components/ui/badge";
|
||||||
|
import { Activity } from "lucide-react";
|
||||||
|
|
||||||
|
export default function LogsActivity() {
|
||||||
|
const [selectedSource, setSelectedSource] = useState<string | undefined>();
|
||||||
|
const [selectedStatus, setSelectedStatus] = useState<string | undefined>();
|
||||||
|
|
||||||
|
const {
|
||||||
|
logs,
|
||||||
|
hasMore,
|
||||||
|
loadMore,
|
||||||
|
availableSources,
|
||||||
|
isLoading,
|
||||||
|
isInitialLoad
|
||||||
|
} = useLogs({
|
||||||
|
endpoint: '/api/v1/logs/activity',
|
||||||
|
source: selectedSource,
|
||||||
|
status: selectedStatus
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isInitialLoad) {
|
||||||
|
return (
|
||||||
|
<AppContainer>
|
||||||
|
<PageContainer>
|
||||||
|
<div className="flex items-center justify-center h-64">
|
||||||
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
|
||||||
|
</div>
|
||||||
|
</PageContainer>
|
||||||
|
</AppContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppContainer>
|
||||||
|
<PageContainer>
|
||||||
|
<PageBody>
|
||||||
|
<div className="space-y-6">
|
||||||
|
{/* Header */}
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<Activity className="h-6 w-6 text-primary" />
|
||||||
|
<div>
|
||||||
|
<h1 className="text-2xl font-bold">Activity Ingestion Logs</h1>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
View ingestion logs for activities from connected integrations
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Badge variant="outline" className="text-sm">
|
||||||
|
{logs.length} activity logs loaded
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Filters */}
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="text-lg">Filters</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<LogsFilters
|
||||||
|
availableSources={availableSources}
|
||||||
|
selectedSource={selectedSource}
|
||||||
|
selectedStatus={selectedStatus}
|
||||||
|
onSourceChange={setSelectedSource}
|
||||||
|
onStatusChange={setSelectedStatus}
|
||||||
|
/>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
{/* Logs List */}
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<h2 className="text-lg font-semibold">Activity Ingestion Queue</h2>
|
||||||
|
{hasMore && (
|
||||||
|
<span className="text-sm text-muted-foreground">
|
||||||
|
Scroll to load more...
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{logs.length === 0 ? (
|
||||||
|
<Card>
|
||||||
|
<CardContent className="flex items-center justify-center py-16">
|
||||||
|
<div className="text-center">
|
||||||
|
<Activity className="h-12 w-12 text-muted-foreground mx-auto mb-4" />
|
||||||
|
<h3 className="text-lg font-semibold mb-2">No activity logs found</h3>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
{selectedSource || selectedStatus
|
||||||
|
? 'Try adjusting your filters to see more results.'
|
||||||
|
: 'No activity ingestion logs are available yet.'}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
) : (
|
||||||
|
<VirtualLogsList
|
||||||
|
logs={logs}
|
||||||
|
hasMore={hasMore}
|
||||||
|
loadMore={loadMore}
|
||||||
|
isLoading={isLoading}
|
||||||
|
height={600}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</PageBody>
|
||||||
|
</PageContainer>
|
||||||
|
</AppContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
102
apps/webapp/app/routes/home.logs.all.tsx
Normal file
102
apps/webapp/app/routes/home.logs.all.tsx
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { useLogs } from "~/hooks/use-logs";
|
||||||
|
import { LogsFilters } from "~/components/logs/logs-filters";
|
||||||
|
import { VirtualLogsList } from "~/components/logs/virtual-logs-list";
|
||||||
|
import {
|
||||||
|
AppContainer,
|
||||||
|
PageContainer,
|
||||||
|
PageBody,
|
||||||
|
} from "~/components/layout/app-layout";
|
||||||
|
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
||||||
|
import { Badge } from "~/components/ui/badge";
|
||||||
|
import { Database } from "lucide-react";
|
||||||
|
|
||||||
|
export default function LogsAll() {
|
||||||
|
const [selectedSource, setSelectedSource] = useState<string | undefined>();
|
||||||
|
const [selectedStatus, setSelectedStatus] = useState<string | undefined>();
|
||||||
|
|
||||||
|
const {
|
||||||
|
logs,
|
||||||
|
hasMore,
|
||||||
|
loadMore,
|
||||||
|
availableSources,
|
||||||
|
isLoading,
|
||||||
|
isInitialLoad,
|
||||||
|
} = useLogs({
|
||||||
|
endpoint: "/api/v1/logs/all",
|
||||||
|
source: selectedSource,
|
||||||
|
status: selectedStatus,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isInitialLoad) {
|
||||||
|
return (
|
||||||
|
<AppContainer>
|
||||||
|
<PageContainer>
|
||||||
|
<div className="flex h-64 items-center justify-center">
|
||||||
|
<div className="border-primary h-8 w-8 animate-spin rounded-full border-b-2"></div>
|
||||||
|
</div>
|
||||||
|
</PageContainer>
|
||||||
|
</AppContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-6 p-4 px-5">
|
||||||
|
{/* Header */}
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
View all ingestion queue items and their processing status
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Filters */}
|
||||||
|
<LogsFilters
|
||||||
|
availableSources={availableSources}
|
||||||
|
selectedSource={selectedSource}
|
||||||
|
selectedStatus={selectedStatus}
|
||||||
|
onSourceChange={setSelectedSource}
|
||||||
|
onStatusChange={setSelectedStatus}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Logs List */}
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<h2 className="text-lg font-semibold">Ingestion Queue</h2>
|
||||||
|
{hasMore && (
|
||||||
|
<span className="text-muted-foreground text-sm">
|
||||||
|
Scroll to load more...
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{logs.length === 0 ? (
|
||||||
|
<Card>
|
||||||
|
<CardContent className="flex items-center justify-center py-16">
|
||||||
|
<div className="text-center">
|
||||||
|
<Database className="text-muted-foreground mx-auto mb-4 h-12 w-12" />
|
||||||
|
<h3 className="mb-2 text-lg font-semibold">No logs found</h3>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
{selectedSource || selectedStatus
|
||||||
|
? "Try adjusting your filters to see more results."
|
||||||
|
: "No ingestion logs are available yet."}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
) : (
|
||||||
|
<VirtualLogsList
|
||||||
|
logs={logs}
|
||||||
|
hasMore={hasMore}
|
||||||
|
loadMore={loadMore}
|
||||||
|
isLoading={isLoading}
|
||||||
|
height={600}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -80,6 +80,7 @@
|
|||||||
"class-validator": "0.14.1",
|
"class-validator": "0.14.1",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
"cmdk": "^0.2.1",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"d3": "^7.9.0",
|
"d3": "^7.9.0",
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "IngestionQueue" ADD COLUMN "activityId" TEXT;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "IngestionQueue" ADD CONSTRAINT "IngestionQueue_activityId_fkey" FOREIGN KEY ("activityId") REFERENCES "Activity"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
@ -31,6 +31,7 @@ model Activity {
|
|||||||
WebhookDeliveryLog WebhookDeliveryLog[]
|
WebhookDeliveryLog WebhookDeliveryLog[]
|
||||||
|
|
||||||
ConversationHistory ConversationHistory[]
|
ConversationHistory ConversationHistory[]
|
||||||
|
IngestionQueue IngestionQueue[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model AuthorizationCode {
|
model AuthorizationCode {
|
||||||
@ -136,6 +137,9 @@ model IngestionQueue {
|
|||||||
workspaceId String
|
workspaceId String
|
||||||
workspace Workspace @relation(fields: [workspaceId], references: [id])
|
workspace Workspace @relation(fields: [workspaceId], references: [id])
|
||||||
|
|
||||||
|
activity Activity? @relation(fields: [activityId], references: [id])
|
||||||
|
activityId String?
|
||||||
|
|
||||||
// Error handling
|
// Error handling
|
||||||
error String?
|
error String?
|
||||||
retryCount Int @default(0)
|
retryCount Int @default(0)
|
||||||
|
|||||||
405
pnpm-lock.yaml
generated
405
pnpm-lock.yaml
generated
@ -234,6 +234,9 @@ importers:
|
|||||||
clsx:
|
clsx:
|
||||||
specifier: ^2.1.1
|
specifier: ^2.1.1
|
||||||
version: 2.1.1
|
version: 2.1.1
|
||||||
|
cmdk:
|
||||||
|
specifier: ^0.2.1
|
||||||
|
version: 0.2.1(@types/react@18.2.69)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
compression:
|
compression:
|
||||||
specifier: ^1.7.4
|
specifier: ^1.7.4
|
||||||
version: 1.8.0
|
version: 1.8.0
|
||||||
@ -378,7 +381,7 @@ importers:
|
|||||||
devDependencies:
|
devDependencies:
|
||||||
'@remix-run/dev':
|
'@remix-run/dev':
|
||||||
specifier: 2.16.7
|
specifier: 2.16.7
|
||||||
version: 2.16.7(@remix-run/react@2.16.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@remix-run/serve@2.16.7(typescript@5.8.3))(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(typescript@5.8.3)(vite@6.3.5(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))(yaml@2.8.0)
|
version: 2.16.7(@remix-run/react@2.16.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@remix-run/serve@2.16.7(typescript@5.8.3))(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(typescript@5.8.3)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))(yaml@2.8.0)
|
||||||
'@remix-run/eslint-config':
|
'@remix-run/eslint-config':
|
||||||
specifier: 2.16.7
|
specifier: 2.16.7
|
||||||
version: 2.16.7(eslint@8.57.1)(react@18.3.1)(typescript@5.8.3)
|
version: 2.16.7(eslint@8.57.1)(react@18.3.1)(typescript@5.8.3)
|
||||||
@ -393,7 +396,7 @@ importers:
|
|||||||
version: 0.5.16(tailwindcss@4.1.7)
|
version: 0.5.16(tailwindcss@4.1.7)
|
||||||
'@tailwindcss/vite':
|
'@tailwindcss/vite':
|
||||||
specifier: ^4.1.7
|
specifier: ^4.1.7
|
||||||
version: 4.1.9(vite@6.3.5(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))
|
version: 4.1.9(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))
|
||||||
'@trigger.dev/build':
|
'@trigger.dev/build':
|
||||||
specifier: ^4.0.0-v4-beta.22
|
specifier: ^4.0.0-v4-beta.22
|
||||||
version: 4.0.0-v4-beta.22(typescript@5.8.3)
|
version: 4.0.0-v4-beta.22(typescript@5.8.3)
|
||||||
@ -489,10 +492,10 @@ importers:
|
|||||||
version: 5.8.3
|
version: 5.8.3
|
||||||
vite:
|
vite:
|
||||||
specifier: ^6.0.0
|
specifier: ^6.0.0
|
||||||
version: 6.3.5(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)
|
version: 6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)
|
||||||
vite-tsconfig-paths:
|
vite-tsconfig-paths:
|
||||||
specifier: ^4.2.1
|
specifier: ^4.2.1
|
||||||
version: 4.3.2(typescript@5.8.3)(vite@6.3.5(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))
|
version: 4.3.2(typescript@5.8.3)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))
|
||||||
|
|
||||||
packages/database:
|
packages/database:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -547,6 +550,40 @@ importers:
|
|||||||
specifier: 18.2.69
|
specifier: 18.2.69
|
||||||
version: 18.2.69
|
version: 18.2.69
|
||||||
|
|
||||||
|
packages/mcp:
|
||||||
|
dependencies:
|
||||||
|
'@modelcontextprotocol/sdk':
|
||||||
|
specifier: 1.0.1
|
||||||
|
version: 1.0.1
|
||||||
|
'@types/node':
|
||||||
|
specifier: ^22.14.1
|
||||||
|
version: 22.16.0
|
||||||
|
'@types/uuid':
|
||||||
|
specifier: ^10.0.0
|
||||||
|
version: 10.0.0
|
||||||
|
axios:
|
||||||
|
specifier: ^1.8.4
|
||||||
|
version: 1.10.0
|
||||||
|
dotenv:
|
||||||
|
specifier: ^16.5.0
|
||||||
|
version: 16.5.0
|
||||||
|
uuid:
|
||||||
|
specifier: ^11.1.0
|
||||||
|
version: 11.1.0
|
||||||
|
zod:
|
||||||
|
specifier: ^3.24.3
|
||||||
|
version: 3.25.76
|
||||||
|
zod-to-json-schema:
|
||||||
|
specifier: ^3.24.5
|
||||||
|
version: 3.24.5(zod@3.25.76)
|
||||||
|
devDependencies:
|
||||||
|
shx:
|
||||||
|
specifier: ^0.3.4
|
||||||
|
version: 0.3.4
|
||||||
|
typescript:
|
||||||
|
specifier: ^5.8.3
|
||||||
|
version: 5.8.3
|
||||||
|
|
||||||
packages/mcp-proxy:
|
packages/mcp-proxy:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@modelcontextprotocol/sdk':
|
'@modelcontextprotocol/sdk':
|
||||||
@ -1790,6 +1827,9 @@ packages:
|
|||||||
'@mjackson/headers@0.9.0':
|
'@mjackson/headers@0.9.0':
|
||||||
resolution: {integrity: sha512-1WFCu2iRaqbez9hcYYI611vcH1V25R+fDfOge/CyKc8sdbzniGfy/FRhNd3DgvFF4ZEEX2ayBrvFHLtOpfvadw==}
|
resolution: {integrity: sha512-1WFCu2iRaqbez9hcYYI611vcH1V25R+fDfOge/CyKc8sdbzniGfy/FRhNd3DgvFF4ZEEX2ayBrvFHLtOpfvadw==}
|
||||||
|
|
||||||
|
'@modelcontextprotocol/sdk@1.0.1':
|
||||||
|
resolution: {integrity: sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==}
|
||||||
|
|
||||||
'@modelcontextprotocol/sdk@1.13.2':
|
'@modelcontextprotocol/sdk@1.13.2':
|
||||||
resolution: {integrity: sha512-Vx7qOcmoKkR3qhaQ9qf3GxiVKCEu+zfJddHv6x3dY/9P6+uIwJnmuAur5aB+4FDXf41rRrDnOEGkviX5oYZ67w==}
|
resolution: {integrity: sha512-Vx7qOcmoKkR3qhaQ9qf3GxiVKCEu+zfJddHv6x3dY/9P6+uIwJnmuAur5aB+4FDXf41rRrDnOEGkviX5oYZ67w==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@ -2139,6 +2179,9 @@ packages:
|
|||||||
'@radix-ui/number@1.1.1':
|
'@radix-ui/number@1.1.1':
|
||||||
resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==}
|
resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==}
|
||||||
|
|
||||||
|
'@radix-ui/primitive@1.0.0':
|
||||||
|
resolution: {integrity: sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==}
|
||||||
|
|
||||||
'@radix-ui/primitive@1.1.0':
|
'@radix-ui/primitive@1.1.0':
|
||||||
resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==}
|
resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==}
|
||||||
|
|
||||||
@ -2275,6 +2318,11 @@ packages:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-compose-refs@1.0.0':
|
||||||
|
resolution: {integrity: sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-compose-refs@1.0.1':
|
'@radix-ui/react-compose-refs@1.0.1':
|
||||||
resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
|
resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2302,6 +2350,11 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-context@1.0.0':
|
||||||
|
resolution: {integrity: sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-context@1.1.0':
|
'@radix-ui/react-context@1.1.0':
|
||||||
resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==}
|
resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2320,6 +2373,12 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-dialog@1.0.0':
|
||||||
|
resolution: {integrity: sha512-Yn9YU+QlHYLWwV1XfKiqnGVpWYWk6MeBVM6x/bcoyPvxgjQGoeT35482viLPctTMWoMw0PoHgqfSox7Ig+957Q==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-dialog@1.1.14':
|
'@radix-ui/react-dialog@1.1.14':
|
||||||
resolution: {integrity: sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==}
|
resolution: {integrity: sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2351,6 +2410,12 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-dismissable-layer@1.0.0':
|
||||||
|
resolution: {integrity: sha512-n7kDRfx+LB1zLueRDvZ1Pd0bxdJWDUZNQ/GWoxDn2prnuJKRdxsjulejX/ePkOsLi2tTm6P24mDqlMSgQpsT6g==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-dismissable-layer@1.1.0':
|
'@radix-ui/react-dismissable-layer@1.1.0':
|
||||||
resolution: {integrity: sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==}
|
resolution: {integrity: sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2390,6 +2455,11 @@ packages:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-focus-guards@1.0.0':
|
||||||
|
resolution: {integrity: sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-focus-guards@1.1.0':
|
'@radix-ui/react-focus-guards@1.1.0':
|
||||||
resolution: {integrity: sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==}
|
resolution: {integrity: sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2408,6 +2478,12 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-focus-scope@1.0.0':
|
||||||
|
resolution: {integrity: sha512-C4SWtsULLGf/2L4oGeIHlvWQx7Rf+7cX/vKOAD2dXW0A1b5QXwi3wWeaEgW+wn+SEVrraMUk05vLU9fZZz5HbQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-focus-scope@1.1.0':
|
'@radix-ui/react-focus-scope@1.1.0':
|
||||||
resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==}
|
resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2439,6 +2515,11 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc
|
react: ^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc
|
||||||
|
|
||||||
|
'@radix-ui/react-id@1.0.0':
|
||||||
|
resolution: {integrity: sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-id@1.1.0':
|
'@radix-ui/react-id@1.1.0':
|
||||||
resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==}
|
resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2535,6 +2616,12 @@ packages:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-portal@1.0.0':
|
||||||
|
resolution: {integrity: sha512-a8qyFO/Xb99d8wQdu4o7qnigNjTPG123uADNecz0eX4usnQEj7o+cG4ZX4zkqq98NYekT7UoEQIjxBNWIFuqTA==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-portal@1.1.1':
|
'@radix-ui/react-portal@1.1.1':
|
||||||
resolution: {integrity: sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==}
|
resolution: {integrity: sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2561,6 +2648,12 @@ packages:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-presence@1.0.0':
|
||||||
|
resolution: {integrity: sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-presence@1.1.0':
|
'@radix-ui/react-presence@1.1.0':
|
||||||
resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==}
|
resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2587,6 +2680,12 @@ packages:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-primitive@1.0.0':
|
||||||
|
resolution: {integrity: sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-primitive@2.0.0':
|
'@radix-ui/react-primitive@2.0.0':
|
||||||
resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==}
|
resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2678,6 +2777,11 @@ packages:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-slot@1.0.0':
|
||||||
|
resolution: {integrity: sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-slot@1.0.2':
|
'@radix-ui/react-slot@1.0.2':
|
||||||
resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==}
|
resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2796,6 +2900,11 @@ packages:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-use-callback-ref@1.0.0':
|
||||||
|
resolution: {integrity: sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-use-callback-ref@1.1.0':
|
'@radix-ui/react-use-callback-ref@1.1.0':
|
||||||
resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==}
|
resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2814,6 +2923,11 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-use-controllable-state@1.0.0':
|
||||||
|
resolution: {integrity: sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-use-controllable-state@1.1.0':
|
'@radix-ui/react-use-controllable-state@1.1.0':
|
||||||
resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==}
|
resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2841,6 +2955,11 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-use-escape-keydown@1.0.0':
|
||||||
|
resolution: {integrity: sha512-JwfBCUIfhXRxKExgIqGa4CQsiMemo1Xt0W/B4ei3fpzpvPENKpMKQ8mZSB6Acj3ebrAEgi2xiQvcI1PAAodvyg==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-use-escape-keydown@1.1.0':
|
'@radix-ui/react-use-escape-keydown@1.1.0':
|
||||||
resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==}
|
resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2868,6 +2987,11 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-use-layout-effect@1.0.0':
|
||||||
|
resolution: {integrity: sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
|
||||||
'@radix-ui/react-use-layout-effect@1.1.0':
|
'@radix-ui/react-use-layout-effect@1.1.0':
|
||||||
resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==}
|
resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -4310,6 +4434,9 @@ packages:
|
|||||||
'@types/use-sync-external-store@0.0.6':
|
'@types/use-sync-external-store@0.0.6':
|
||||||
resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
|
resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
|
||||||
|
|
||||||
|
'@types/uuid@10.0.0':
|
||||||
|
resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==}
|
||||||
|
|
||||||
'@types/uuid@9.0.8':
|
'@types/uuid@9.0.8':
|
||||||
resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==}
|
resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==}
|
||||||
|
|
||||||
@ -5077,6 +5204,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
|
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
cmdk@0.2.1:
|
||||||
|
resolution: {integrity: sha512-U6//9lQ6JvT47+6OF6Gi8BvkxYQ8SCRRSKIJkthIMsFsLZRG0cKvTtuTaefyIKMQb8rvvXy0wGdpTNq/jPtm+g==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^18.0.0
|
||||||
|
react-dom: ^18.0.0
|
||||||
|
|
||||||
cmdk@1.1.1:
|
cmdk@1.1.1:
|
||||||
resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==}
|
resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -6576,6 +6709,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
interpret@1.4.0:
|
||||||
|
resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==}
|
||||||
|
engines: {node: '>= 0.10'}
|
||||||
|
|
||||||
ioredis@5.6.1:
|
ioredis@5.6.1:
|
||||||
resolution: {integrity: sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA==}
|
resolution: {integrity: sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA==}
|
||||||
engines: {node: '>=12.22.0'}
|
engines: {node: '>=12.22.0'}
|
||||||
@ -8544,6 +8681,16 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
react-remove-scroll@2.5.4:
|
||||||
|
resolution: {integrity: sha512-xGVKJJr0SJGQVirVFAUZ2k1QLyO6m+2fy0l8Qawbp5Jgrv3DeLalrfMNBFSlmz5kriGGzsVBtGVnf4pTKIhhWA==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||||
|
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
|
||||||
react-remove-scroll@2.5.7:
|
react-remove-scroll@2.5.7:
|
||||||
resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==}
|
resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -8650,6 +8797,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
|
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
|
||||||
engines: {node: '>= 14.18.0'}
|
engines: {node: '>= 14.18.0'}
|
||||||
|
|
||||||
|
rechoir@0.6.2:
|
||||||
|
resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==}
|
||||||
|
engines: {node: '>= 0.10'}
|
||||||
|
|
||||||
redent@3.0.0:
|
redent@3.0.0:
|
||||||
resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
|
resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -8968,9 +9119,19 @@ packages:
|
|||||||
resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==}
|
resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
shelljs@0.8.5:
|
||||||
|
resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
shimmer@1.2.1:
|
shimmer@1.2.1:
|
||||||
resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==}
|
resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==}
|
||||||
|
|
||||||
|
shx@0.3.4:
|
||||||
|
resolution: {integrity: sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
side-channel-list@1.0.0:
|
side-channel-list@1.0.0:
|
||||||
resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
|
resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -9753,6 +9914,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
|
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
|
||||||
engines: {node: '>= 0.4.0'}
|
engines: {node: '>= 0.4.0'}
|
||||||
|
|
||||||
|
uuid@11.1.0:
|
||||||
|
resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
uuid@9.0.1:
|
uuid@9.0.1:
|
||||||
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
|
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@ -10089,6 +10254,9 @@ packages:
|
|||||||
zod@3.23.8:
|
zod@3.23.8:
|
||||||
resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
|
resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
|
||||||
|
|
||||||
|
zod@3.25.76:
|
||||||
|
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
|
||||||
|
|
||||||
zustand@4.5.7:
|
zustand@4.5.7:
|
||||||
resolution: {integrity: sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==}
|
resolution: {integrity: sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==}
|
||||||
engines: {node: '>=12.7.0'}
|
engines: {node: '>=12.7.0'}
|
||||||
@ -11470,6 +11638,12 @@ snapshots:
|
|||||||
|
|
||||||
'@mjackson/headers@0.9.0': {}
|
'@mjackson/headers@0.9.0': {}
|
||||||
|
|
||||||
|
'@modelcontextprotocol/sdk@1.0.1':
|
||||||
|
dependencies:
|
||||||
|
content-type: 1.0.5
|
||||||
|
raw-body: 3.0.0
|
||||||
|
zod: 3.25.76
|
||||||
|
|
||||||
'@modelcontextprotocol/sdk@1.13.2':
|
'@modelcontextprotocol/sdk@1.13.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv: 6.12.6
|
ajv: 6.12.6
|
||||||
@ -11832,6 +12006,10 @@ snapshots:
|
|||||||
|
|
||||||
'@radix-ui/number@1.1.1': {}
|
'@radix-ui/number@1.1.1': {}
|
||||||
|
|
||||||
|
'@radix-ui/primitive@1.0.0':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
|
||||||
'@radix-ui/primitive@1.1.0': {}
|
'@radix-ui/primitive@1.1.0': {}
|
||||||
|
|
||||||
'@radix-ui/primitive@1.1.2': {}
|
'@radix-ui/primitive@1.1.2': {}
|
||||||
@ -11970,6 +12148,11 @@ snapshots:
|
|||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
||||||
|
|
||||||
|
'@radix-ui/react-compose-refs@1.0.0(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
react: 18.3.1
|
||||||
|
|
||||||
'@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.69)(react@18.3.1)':
|
'@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.69)(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.27.6
|
'@babel/runtime': 7.27.6
|
||||||
@ -11989,6 +12172,11 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
|
|
||||||
|
'@radix-ui/react-context@1.0.0(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
react: 18.3.1
|
||||||
|
|
||||||
'@radix-ui/react-context@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
'@radix-ui/react-context@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
@ -12001,6 +12189,28 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
|
|
||||||
|
'@radix-ui/react-dialog@1.0.0(@types/react@18.2.69)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
'@radix-ui/primitive': 1.0.0
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.0(react@18.3.1)
|
||||||
|
'@radix-ui/react-context': 1.0.0(react@18.3.1)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
'@radix-ui/react-focus-guards': 1.0.0(react@18.3.1)
|
||||||
|
'@radix-ui/react-focus-scope': 1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
'@radix-ui/react-id': 1.0.0(react@18.3.1)
|
||||||
|
'@radix-ui/react-portal': 1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
'@radix-ui/react-presence': 1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
'@radix-ui/react-primitive': 1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
'@radix-ui/react-slot': 1.0.0(react@18.3.1)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.0(react@18.3.1)
|
||||||
|
aria-hidden: 1.2.6
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
react-remove-scroll: 2.5.4(@types/react@18.2.69)(react@18.3.1)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/react'
|
||||||
|
|
||||||
'@radix-ui/react-dialog@1.1.14(@types/react-dom@18.3.7(@types/react@18.2.69))(@types/react@18.2.69)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
'@radix-ui/react-dialog@1.1.14(@types/react-dom@18.3.7(@types/react@18.2.69))(@types/react@18.2.69)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/primitive': 1.1.2
|
'@radix-ui/primitive': 1.1.2
|
||||||
@ -12035,6 +12245,17 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
|
|
||||||
|
'@radix-ui/react-dismissable-layer@1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
'@radix-ui/primitive': 1.0.0
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.0(react@18.3.1)
|
||||||
|
'@radix-ui/react-primitive': 1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.0(react@18.3.1)
|
||||||
|
'@radix-ui/react-use-escape-keydown': 1.0.0(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
|
||||||
'@radix-ui/react-dismissable-layer@1.1.0(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
'@radix-ui/react-dismissable-layer@1.1.0(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/primitive': 1.1.0
|
'@radix-ui/primitive': 1.1.0
|
||||||
@ -12076,6 +12297,11 @@ snapshots:
|
|||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
||||||
|
|
||||||
|
'@radix-ui/react-focus-guards@1.0.0(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
react: 18.3.1
|
||||||
|
|
||||||
'@radix-ui/react-focus-guards@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
'@radix-ui/react-focus-guards@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
@ -12088,6 +12314,15 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
|
|
||||||
|
'@radix-ui/react-focus-scope@1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.0(react@18.3.1)
|
||||||
|
'@radix-ui/react-primitive': 1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.0(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
|
||||||
'@radix-ui/react-focus-scope@1.1.0(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
'@radix-ui/react-focus-scope@1.1.0(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.47)(react@18.3.1)
|
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.47)(react@18.3.1)
|
||||||
@ -12114,6 +12349,12 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
|
|
||||||
|
'@radix-ui/react-id@1.0.0(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
'@radix-ui/react-use-layout-effect': 1.0.0(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
|
||||||
'@radix-ui/react-id@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
'@radix-ui/react-id@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.47)(react@18.3.1)
|
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.47)(react@18.3.1)
|
||||||
@ -12245,6 +12486,13 @@ snapshots:
|
|||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
||||||
|
|
||||||
|
'@radix-ui/react-portal@1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
'@radix-ui/react-primitive': 1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
|
||||||
'@radix-ui/react-portal@1.1.1(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
'@radix-ui/react-portal@1.1.1(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
@ -12265,6 +12513,14 @@ snapshots:
|
|||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
||||||
|
|
||||||
|
'@radix-ui/react-presence@1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.0(react@18.3.1)
|
||||||
|
'@radix-ui/react-use-layout-effect': 1.0.0(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
|
||||||
'@radix-ui/react-presence@1.1.0(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
'@radix-ui/react-presence@1.1.0(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.47)(react@18.3.1)
|
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.47)(react@18.3.1)
|
||||||
@ -12285,6 +12541,13 @@ snapshots:
|
|||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
||||||
|
|
||||||
|
'@radix-ui/react-primitive@1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
'@radix-ui/react-slot': 1.0.0(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
|
||||||
'@radix-ui/react-primitive@2.0.0(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
'@radix-ui/react-primitive@2.0.0(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-slot': 1.1.0(@types/react@18.2.47)(react@18.3.1)
|
'@radix-ui/react-slot': 1.1.0(@types/react@18.2.47)(react@18.3.1)
|
||||||
@ -12392,6 +12655,12 @@ snapshots:
|
|||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
||||||
|
|
||||||
|
'@radix-ui/react-slot@1.0.0(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.0(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
|
||||||
'@radix-ui/react-slot@1.0.2(@types/react@18.2.69)(react@18.3.1)':
|
'@radix-ui/react-slot@1.0.2(@types/react@18.2.69)(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.27.6
|
'@babel/runtime': 7.27.6
|
||||||
@ -12531,6 +12800,11 @@ snapshots:
|
|||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
'@types/react-dom': 18.3.7(@types/react@18.2.69)
|
||||||
|
|
||||||
|
'@radix-ui/react-use-callback-ref@1.0.0(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
react: 18.3.1
|
||||||
|
|
||||||
'@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
'@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
@ -12543,6 +12817,12 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
|
|
||||||
|
'@radix-ui/react-use-controllable-state@1.0.0(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.0(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
|
||||||
'@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
'@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.47)(react@18.3.1)
|
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.47)(react@18.3.1)
|
||||||
@ -12565,6 +12845,12 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
|
|
||||||
|
'@radix-ui/react-use-escape-keydown@1.0.0(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.0(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
|
||||||
'@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
'@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.47)(react@18.3.1)
|
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.47)(react@18.3.1)
|
||||||
@ -12586,6 +12872,11 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
|
|
||||||
|
'@radix-ui/react-use-layout-effect@1.0.0(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.27.6
|
||||||
|
react: 18.3.1
|
||||||
|
|
||||||
'@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
'@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.2.47)(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
@ -12791,7 +13082,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- encoding
|
- encoding
|
||||||
|
|
||||||
'@remix-run/dev@2.16.7(@remix-run/react@2.16.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@remix-run/serve@2.16.7(typescript@5.8.3))(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(typescript@5.8.3)(vite@6.3.5(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))(yaml@2.8.0)':
|
'@remix-run/dev@2.16.7(@remix-run/react@2.16.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@remix-run/serve@2.16.7(typescript@5.8.3))(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(typescript@5.8.3)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))(yaml@2.8.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.27.4
|
'@babel/core': 7.27.4
|
||||||
'@babel/generator': 7.27.5
|
'@babel/generator': 7.27.5
|
||||||
@ -12808,7 +13099,7 @@ snapshots:
|
|||||||
'@remix-run/router': 1.23.0
|
'@remix-run/router': 1.23.0
|
||||||
'@remix-run/server-runtime': 2.16.7(typescript@5.8.3)
|
'@remix-run/server-runtime': 2.16.7(typescript@5.8.3)
|
||||||
'@types/mdx': 2.0.13
|
'@types/mdx': 2.0.13
|
||||||
'@vanilla-extract/integration': 6.5.0(@types/node@20.19.7)(lightningcss@1.30.1)(terser@5.42.0)
|
'@vanilla-extract/integration': 6.5.0(@types/node@22.16.0)(lightningcss@1.30.1)(terser@5.42.0)
|
||||||
arg: 5.0.2
|
arg: 5.0.2
|
||||||
cacache: 17.1.4
|
cacache: 17.1.4
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
@ -12848,12 +13139,12 @@ snapshots:
|
|||||||
tar-fs: 2.1.3
|
tar-fs: 2.1.3
|
||||||
tsconfig-paths: 4.2.0
|
tsconfig-paths: 4.2.0
|
||||||
valibot: 0.41.0(typescript@5.8.3)
|
valibot: 0.41.0(typescript@5.8.3)
|
||||||
vite-node: 3.2.3(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)
|
vite-node: 3.2.3(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)
|
||||||
ws: 7.5.10
|
ws: 7.5.10
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@remix-run/serve': 2.16.7(typescript@5.8.3)
|
'@remix-run/serve': 2.16.7(typescript@5.8.3)
|
||||||
typescript: 5.8.3
|
typescript: 5.8.3
|
||||||
vite: 6.3.5(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)
|
vite: 6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/node'
|
- '@types/node'
|
||||||
- babel-plugin-macros
|
- babel-plugin-macros
|
||||||
@ -13592,12 +13883,12 @@ snapshots:
|
|||||||
postcss-selector-parser: 6.0.10
|
postcss-selector-parser: 6.0.10
|
||||||
tailwindcss: 4.1.7
|
tailwindcss: 4.1.7
|
||||||
|
|
||||||
'@tailwindcss/vite@4.1.9(vite@6.3.5(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))':
|
'@tailwindcss/vite@4.1.9(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tailwindcss/node': 4.1.9
|
'@tailwindcss/node': 4.1.9
|
||||||
'@tailwindcss/oxide': 4.1.9
|
'@tailwindcss/oxide': 4.1.9
|
||||||
tailwindcss: 4.1.9
|
tailwindcss: 4.1.9
|
||||||
vite: 6.3.5(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)
|
vite: 6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)
|
||||||
|
|
||||||
'@tanstack/react-table@8.21.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
'@tanstack/react-table@8.21.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -13947,7 +14238,7 @@ snapshots:
|
|||||||
'@types/body-parser@1.19.6':
|
'@types/body-parser@1.19.6':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/connect': 3.4.38
|
'@types/connect': 3.4.38
|
||||||
'@types/node': 18.19.115
|
'@types/node': 22.16.0
|
||||||
|
|
||||||
'@types/compression@1.8.1':
|
'@types/compression@1.8.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -13958,7 +14249,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/connect@3.4.38':
|
'@types/connect@3.4.38':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 18.19.115
|
'@types/node': 22.16.0
|
||||||
|
|
||||||
'@types/cookie@0.4.1': {}
|
'@types/cookie@0.4.1': {}
|
||||||
|
|
||||||
@ -13966,7 +14257,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/cors@2.8.19':
|
'@types/cors@2.8.19':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 18.19.115
|
'@types/node': 22.16.0
|
||||||
|
|
||||||
'@types/d3-array@3.2.1': {}
|
'@types/d3-array@3.2.1': {}
|
||||||
|
|
||||||
@ -14113,7 +14404,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/express-serve-static-core@4.19.6':
|
'@types/express-serve-static-core@4.19.6':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 18.19.115
|
'@types/node': 22.16.0
|
||||||
'@types/qs': 6.14.0
|
'@types/qs': 6.14.0
|
||||||
'@types/range-parser': 1.2.7
|
'@types/range-parser': 1.2.7
|
||||||
'@types/send': 0.17.5
|
'@types/send': 0.17.5
|
||||||
@ -14234,12 +14525,12 @@ snapshots:
|
|||||||
'@types/send@0.17.5':
|
'@types/send@0.17.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/mime': 1.3.5
|
'@types/mime': 1.3.5
|
||||||
'@types/node': 18.19.115
|
'@types/node': 22.16.0
|
||||||
|
|
||||||
'@types/serve-static@1.15.8':
|
'@types/serve-static@1.15.8':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/http-errors': 2.0.5
|
'@types/http-errors': 2.0.5
|
||||||
'@types/node': 18.19.115
|
'@types/node': 22.16.0
|
||||||
'@types/send': 0.17.5
|
'@types/send': 0.17.5
|
||||||
|
|
||||||
'@types/shimmer@1.2.0': {}
|
'@types/shimmer@1.2.0': {}
|
||||||
@ -14254,13 +14545,15 @@ snapshots:
|
|||||||
|
|
||||||
'@types/use-sync-external-store@0.0.6': {}
|
'@types/use-sync-external-store@0.0.6': {}
|
||||||
|
|
||||||
|
'@types/uuid@10.0.0': {}
|
||||||
|
|
||||||
'@types/uuid@9.0.8': {}
|
'@types/uuid@9.0.8': {}
|
||||||
|
|
||||||
'@types/validator@13.15.2': {}
|
'@types/validator@13.15.2': {}
|
||||||
|
|
||||||
'@types/webpack@5.28.5(@swc/core@1.3.101(@swc/helpers@0.5.17))(esbuild@0.19.11)':
|
'@types/webpack@5.28.5(@swc/core@1.3.101(@swc/helpers@0.5.17))(esbuild@0.19.11)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 18.19.115
|
'@types/node': 22.16.0
|
||||||
tapable: 2.2.2
|
tapable: 2.2.2
|
||||||
webpack: 5.99.9(@swc/core@1.3.101(@swc/helpers@0.5.17))(esbuild@0.19.11)
|
webpack: 5.99.9(@swc/core@1.3.101(@swc/helpers@0.5.17))(esbuild@0.19.11)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@ -14523,7 +14816,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- babel-plugin-macros
|
- babel-plugin-macros
|
||||||
|
|
||||||
'@vanilla-extract/integration@6.5.0(@types/node@20.19.7)(lightningcss@1.30.1)(terser@5.42.0)':
|
'@vanilla-extract/integration@6.5.0(@types/node@22.16.0)(lightningcss@1.30.1)(terser@5.42.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.27.4
|
'@babel/core': 7.27.4
|
||||||
'@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.4)
|
'@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.4)
|
||||||
@ -14536,8 +14829,8 @@ snapshots:
|
|||||||
lodash: 4.17.21
|
lodash: 4.17.21
|
||||||
mlly: 1.7.4
|
mlly: 1.7.4
|
||||||
outdent: 0.8.0
|
outdent: 0.8.0
|
||||||
vite: 5.4.19(@types/node@20.19.7)(lightningcss@1.30.1)(terser@5.42.0)
|
vite: 5.4.19(@types/node@22.16.0)(lightningcss@1.30.1)(terser@5.42.0)
|
||||||
vite-node: 1.6.1(@types/node@20.19.7)(lightningcss@1.30.1)(terser@5.42.0)
|
vite-node: 1.6.1(@types/node@22.16.0)(lightningcss@1.30.1)(terser@5.42.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/node'
|
- '@types/node'
|
||||||
- babel-plugin-macros
|
- babel-plugin-macros
|
||||||
@ -15174,6 +15467,14 @@ snapshots:
|
|||||||
|
|
||||||
cluster-key-slot@1.1.2: {}
|
cluster-key-slot@1.1.2: {}
|
||||||
|
|
||||||
|
cmdk@0.2.1(@types/react@18.2.69)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||||
|
dependencies:
|
||||||
|
'@radix-ui/react-dialog': 1.0.0(@types/react@18.2.69)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/react'
|
||||||
|
|
||||||
cmdk@1.1.1(@types/react-dom@18.3.7(@types/react@18.2.69))(@types/react@18.2.69)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
cmdk@1.1.1(@types/react-dom@18.3.7(@types/react@18.2.69))(@types/react@18.2.69)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.69)(react@18.3.1)
|
'@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.69)(react@18.3.1)
|
||||||
@ -15794,7 +16095,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/cookie': 0.4.1
|
'@types/cookie': 0.4.1
|
||||||
'@types/cors': 2.8.19
|
'@types/cors': 2.8.19
|
||||||
'@types/node': 18.19.115
|
'@types/node': 22.16.0
|
||||||
accepts: 1.3.8
|
accepts: 1.3.8
|
||||||
base64id: 2.0.0
|
base64id: 2.0.0
|
||||||
cookie: 0.4.2
|
cookie: 0.4.2
|
||||||
@ -16407,7 +16708,7 @@ snapshots:
|
|||||||
|
|
||||||
eval@0.1.8:
|
eval@0.1.8:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 18.19.115
|
'@types/node': 22.16.0
|
||||||
require-like: 0.1.2
|
require-like: 0.1.2
|
||||||
|
|
||||||
event-target-shim@5.0.1: {}
|
event-target-shim@5.0.1: {}
|
||||||
@ -17092,6 +17393,8 @@ snapshots:
|
|||||||
|
|
||||||
internmap@2.0.3: {}
|
internmap@2.0.3: {}
|
||||||
|
|
||||||
|
interpret@1.4.0: {}
|
||||||
|
|
||||||
ioredis@5.6.1:
|
ioredis@5.6.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@ioredis/commands': 1.2.0
|
'@ioredis/commands': 1.2.0
|
||||||
@ -17326,7 +17629,7 @@ snapshots:
|
|||||||
|
|
||||||
jest-worker@27.5.1:
|
jest-worker@27.5.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 18.19.115
|
'@types/node': 22.16.0
|
||||||
merge-stream: 2.0.0
|
merge-stream: 2.0.0
|
||||||
supports-color: 8.1.1
|
supports-color: 8.1.1
|
||||||
|
|
||||||
@ -19209,7 +19512,7 @@ snapshots:
|
|||||||
'@protobufjs/path': 1.1.2
|
'@protobufjs/path': 1.1.2
|
||||||
'@protobufjs/pool': 1.1.0
|
'@protobufjs/pool': 1.1.0
|
||||||
'@protobufjs/utf8': 1.1.0
|
'@protobufjs/utf8': 1.1.0
|
||||||
'@types/node': 18.19.115
|
'@types/node': 22.16.0
|
||||||
long: 5.3.2
|
long: 5.3.2
|
||||||
|
|
||||||
proxy-addr@2.0.7:
|
proxy-addr@2.0.7:
|
||||||
@ -19416,6 +19719,17 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 18.2.69
|
'@types/react': 18.2.69
|
||||||
|
|
||||||
|
react-remove-scroll@2.5.4(@types/react@18.2.69)(react@18.3.1):
|
||||||
|
dependencies:
|
||||||
|
react: 18.3.1
|
||||||
|
react-remove-scroll-bar: 2.3.8(@types/react@18.2.69)(react@18.3.1)
|
||||||
|
react-style-singleton: 2.2.3(@types/react@18.2.69)(react@18.3.1)
|
||||||
|
tslib: 2.8.1
|
||||||
|
use-callback-ref: 1.3.3(@types/react@18.2.69)(react@18.3.1)
|
||||||
|
use-sidecar: 1.1.3(@types/react@18.2.69)(react@18.3.1)
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/react': 18.2.69
|
||||||
|
|
||||||
react-remove-scroll@2.5.7(@types/react@18.2.47)(react@18.3.1):
|
react-remove-scroll@2.5.7(@types/react@18.2.47)(react@18.3.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
@ -19554,6 +19868,10 @@ snapshots:
|
|||||||
|
|
||||||
readdirp@4.1.2: {}
|
readdirp@4.1.2: {}
|
||||||
|
|
||||||
|
rechoir@0.6.2:
|
||||||
|
dependencies:
|
||||||
|
resolve: 1.22.10
|
||||||
|
|
||||||
redent@3.0.0:
|
redent@3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
indent-string: 4.0.0
|
indent-string: 4.0.0
|
||||||
@ -19956,8 +20274,19 @@ snapshots:
|
|||||||
|
|
||||||
shell-quote@1.8.3: {}
|
shell-quote@1.8.3: {}
|
||||||
|
|
||||||
|
shelljs@0.8.5:
|
||||||
|
dependencies:
|
||||||
|
glob: 7.2.3
|
||||||
|
interpret: 1.4.0
|
||||||
|
rechoir: 0.6.2
|
||||||
|
|
||||||
shimmer@1.2.1: {}
|
shimmer@1.2.1: {}
|
||||||
|
|
||||||
|
shx@0.3.4:
|
||||||
|
dependencies:
|
||||||
|
minimist: 1.2.8
|
||||||
|
shelljs: 0.8.5
|
||||||
|
|
||||||
side-channel-list@1.0.0:
|
side-channel-list@1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
@ -20920,6 +21249,8 @@ snapshots:
|
|||||||
|
|
||||||
utils-merge@1.0.1: {}
|
utils-merge@1.0.1: {}
|
||||||
|
|
||||||
|
uuid@11.1.0: {}
|
||||||
|
|
||||||
uuid@9.0.1: {}
|
uuid@9.0.1: {}
|
||||||
|
|
||||||
uvu@0.5.6:
|
uvu@0.5.6:
|
||||||
@ -20966,13 +21297,13 @@ snapshots:
|
|||||||
'@types/unist': 3.0.3
|
'@types/unist': 3.0.3
|
||||||
vfile-message: 4.0.2
|
vfile-message: 4.0.2
|
||||||
|
|
||||||
vite-node@1.6.1(@types/node@20.19.7)(lightningcss@1.30.1)(terser@5.42.0):
|
vite-node@1.6.1(@types/node@22.16.0)(lightningcss@1.30.1)(terser@5.42.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
cac: 6.7.14
|
cac: 6.7.14
|
||||||
debug: 4.4.1
|
debug: 4.4.1
|
||||||
pathe: 1.1.2
|
pathe: 1.1.2
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
vite: 5.4.19(@types/node@20.19.7)(lightningcss@1.30.1)(terser@5.42.0)
|
vite: 5.4.19(@types/node@22.16.0)(lightningcss@1.30.1)(terser@5.42.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/node'
|
- '@types/node'
|
||||||
- less
|
- less
|
||||||
@ -20984,13 +21315,13 @@ snapshots:
|
|||||||
- supports-color
|
- supports-color
|
||||||
- terser
|
- terser
|
||||||
|
|
||||||
vite-node@3.2.3(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0):
|
vite-node@3.2.3(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
cac: 6.7.14
|
cac: 6.7.14
|
||||||
debug: 4.4.1
|
debug: 4.4.1
|
||||||
es-module-lexer: 1.7.0
|
es-module-lexer: 1.7.0
|
||||||
pathe: 2.0.3
|
pathe: 2.0.3
|
||||||
vite: 6.3.5(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)
|
vite: 6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/node'
|
- '@types/node'
|
||||||
- jiti
|
- jiti
|
||||||
@ -21005,29 +21336,29 @@ snapshots:
|
|||||||
- tsx
|
- tsx
|
||||||
- yaml
|
- yaml
|
||||||
|
|
||||||
vite-tsconfig-paths@4.3.2(typescript@5.8.3)(vite@6.3.5(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)):
|
vite-tsconfig-paths@4.3.2(typescript@5.8.3)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.4.1
|
debug: 4.4.1
|
||||||
globrex: 0.1.2
|
globrex: 0.1.2
|
||||||
tsconfck: 3.1.6(typescript@5.8.3)
|
tsconfck: 3.1.6(typescript@5.8.3)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
vite: 6.3.5(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)
|
vite: 6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
- typescript
|
- typescript
|
||||||
|
|
||||||
vite@5.4.19(@types/node@20.19.7)(lightningcss@1.30.1)(terser@5.42.0):
|
vite@5.4.19(@types/node@22.16.0)(lightningcss@1.30.1)(terser@5.42.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.21.5
|
esbuild: 0.21.5
|
||||||
postcss: 8.5.5
|
postcss: 8.5.5
|
||||||
rollup: 4.43.0
|
rollup: 4.43.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 20.19.7
|
'@types/node': 22.16.0
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
lightningcss: 1.30.1
|
lightningcss: 1.30.1
|
||||||
terser: 5.42.0
|
terser: 5.42.0
|
||||||
|
|
||||||
vite@6.3.5(@types/node@20.19.7)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0):
|
vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.25.5
|
esbuild: 0.25.5
|
||||||
fdir: 6.4.6(picomatch@4.0.2)
|
fdir: 6.4.6(picomatch@4.0.2)
|
||||||
@ -21036,7 +21367,7 @@ snapshots:
|
|||||||
rollup: 4.43.0
|
rollup: 4.43.0
|
||||||
tinyglobby: 0.2.14
|
tinyglobby: 0.2.14
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 20.19.7
|
'@types/node': 22.16.0
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
jiti: 2.4.2
|
jiti: 2.4.2
|
||||||
lightningcss: 1.30.1
|
lightningcss: 1.30.1
|
||||||
@ -21293,12 +21624,18 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
zod: 3.23.8
|
zod: 3.23.8
|
||||||
|
|
||||||
|
zod-to-json-schema@3.24.5(zod@3.25.76):
|
||||||
|
dependencies:
|
||||||
|
zod: 3.25.76
|
||||||
|
|
||||||
zod-validation-error@1.5.0(zod@3.23.8):
|
zod-validation-error@1.5.0(zod@3.23.8):
|
||||||
dependencies:
|
dependencies:
|
||||||
zod: 3.23.8
|
zod: 3.23.8
|
||||||
|
|
||||||
zod@3.23.8: {}
|
zod@3.23.8: {}
|
||||||
|
|
||||||
|
zod@3.25.76: {}
|
||||||
|
|
||||||
zustand@4.5.7(@types/react@18.2.69)(react@18.3.1):
|
zustand@4.5.7(@types/react@18.2.69)(react@18.3.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
use-sync-external-store: 1.5.0(react@18.3.1)
|
use-sync-external-store: 1.5.0(react@18.3.1)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user