chore: remove unused code and dependencies identified by knip (Vibe Kanban) (#1499)
* Here's a summary of what was cleaned up: ## Removed Unused Files (11 files) - `frontend/src/components/layout/ResponsiveTwoPane.tsx` - `frontend/src/components/OrgMemberAvatars.tsx` - `frontend/src/components/tasks/FollowUpStatusRow.tsx` - `frontend/src/components/tasks/TaskRelationshipCard.tsx` - `frontend/src/components/tasks/TaskRelationshipViewer.tsx` - `frontend/src/components/ui/image-upload-section.tsx` - `frontend/src/components/ui/tabs.tsx` - `frontend/src/components/ui/title-description-editor.tsx` - `frontend/src/lib/caretPosition.ts` - `frontend/src/utils/markdownImages.ts` - `remote-frontend/src/App.tsx` ## Removed Unused Dependencies (10 packages from frontend/package.json) - `@dnd-kit/modifiers` - `@lexical/utils` - `@radix-ui/react-tabs` - `@tailwindcss/typography` - `@tanstack/react-devtools` - `@tanstack/react-form-devtools` - `@types/react-window` - `react-use-websocket` - `react-window` - `zod` ## Removed Unused Exports - `useTabNavigation` hook from `TabNavigationContext.tsx` ## Not Removed (false positives or intentional) - `shared/types.ts` - auto-generated file used throughout the project - `@rjsf/shadcn` - used in tailwind.config.js content paths - `wa-sqlite` - used in vite.config.ts optimizeDeps - `eslint-plugin-prettier`, `vite` (root) - kept per user preference - Barrel re-exports in index.ts files (dialogs, hooks, ui) - intentional public APIs - Type exports - part of public API contracts * Done. Restored `remote-frontend/src/App.tsx` as a placeholder. * Update pnpm lockfile after removing unused dependencies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
b37672a475
commit
2366e4ad23
@@ -20,7 +20,6 @@
|
|||||||
"@codemirror/lint": "^6.8.5",
|
"@codemirror/lint": "^6.8.5",
|
||||||
"@codemirror/view": "^6.38.1",
|
"@codemirror/view": "^6.38.1",
|
||||||
"@dnd-kit/core": "^6.3.1",
|
"@dnd-kit/core": "^6.3.1",
|
||||||
"@dnd-kit/modifiers": "^9.0.0",
|
|
||||||
"@dnd-kit/utilities": "^3.2.2",
|
"@dnd-kit/utilities": "^3.2.2",
|
||||||
"@ebay/nice-modal-react": "^1.2.13",
|
"@ebay/nice-modal-react": "^1.2.13",
|
||||||
"@git-diff-view/file": "^0.0.30",
|
"@git-diff-view/file": "^0.0.30",
|
||||||
@@ -31,26 +30,20 @@
|
|||||||
"@lexical/markdown": "^0.36.2",
|
"@lexical/markdown": "^0.36.2",
|
||||||
"@lexical/react": "^0.36.2",
|
"@lexical/react": "^0.36.2",
|
||||||
"@lexical/rich-text": "^0.36.2",
|
"@lexical/rich-text": "^0.36.2",
|
||||||
"@lexical/utils": "^0.36.2",
|
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.15",
|
"@radix-ui/react-dropdown-menu": "^2.1.15",
|
||||||
"@radix-ui/react-label": "^2.1.7",
|
"@radix-ui/react-label": "^2.1.7",
|
||||||
"@radix-ui/react-select": "^2.2.5",
|
"@radix-ui/react-select": "^2.2.5",
|
||||||
"@radix-ui/react-slot": "^1.2.3",
|
"@radix-ui/react-slot": "^1.2.3",
|
||||||
"@radix-ui/react-switch": "^1.0.3",
|
"@radix-ui/react-switch": "^1.0.3",
|
||||||
"@radix-ui/react-tabs": "^1.1.12",
|
|
||||||
"@radix-ui/react-toggle-group": "^1.1.11",
|
"@radix-ui/react-toggle-group": "^1.1.11",
|
||||||
"@radix-ui/react-tooltip": "^1.2.7",
|
"@radix-ui/react-tooltip": "^1.2.7",
|
||||||
"@rjsf/shadcn": "6.1.1",
|
"@rjsf/shadcn": "6.1.1",
|
||||||
"@sentry/react": "^9.34.0",
|
"@sentry/react": "^9.34.0",
|
||||||
"@sentry/vite-plugin": "^3.5.0",
|
"@sentry/vite-plugin": "^3.5.0",
|
||||||
"@tailwindcss/typography": "^0.5.16",
|
|
||||||
"@tanstack/electric-db-collection": "^0.2.6",
|
"@tanstack/electric-db-collection": "^0.2.6",
|
||||||
"@tanstack/react-db": "^0.1.50",
|
"@tanstack/react-db": "^0.1.50",
|
||||||
"@tanstack/react-devtools": "^0.8.0",
|
|
||||||
"@tanstack/react-form": "^1.23.8",
|
"@tanstack/react-form": "^1.23.8",
|
||||||
"@tanstack/react-form-devtools": "^0.1.8",
|
|
||||||
"@tanstack/react-query": "^5.85.5",
|
"@tanstack/react-query": "^5.85.5",
|
||||||
"@types/react-window": "^1.8.8",
|
|
||||||
"@uiw/react-codemirror": "^4.25.1",
|
"@uiw/react-codemirror": "^4.25.1",
|
||||||
"@virtuoso.dev/message-list": "^1.13.3",
|
"@virtuoso.dev/message-list": "^1.13.3",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
@@ -72,16 +65,13 @@
|
|||||||
"react-i18next": "^15.7.3",
|
"react-i18next": "^15.7.3",
|
||||||
"react-resizable-panels": "^3.0.6",
|
"react-resizable-panels": "^3.0.6",
|
||||||
"react-router-dom": "^6.8.1",
|
"react-router-dom": "^6.8.1",
|
||||||
"react-use-websocket": "^4.7.0",
|
|
||||||
"react-virtuoso": "^4.14.0",
|
"react-virtuoso": "^4.14.0",
|
||||||
"react-window": "^1.8.11",
|
|
||||||
"rfc6902": "^5.1.2",
|
"rfc6902": "^5.1.2",
|
||||||
"simple-icons": "^15.16.0",
|
"simple-icons": "^15.16.0",
|
||||||
"tailwind-merge": "^2.2.0",
|
"tailwind-merge": "^2.2.0",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"vibe-kanban-web-companion": "^0.0.4",
|
"vibe-kanban-web-companion": "^0.0.4",
|
||||||
"wa-sqlite": "^1.0.0",
|
"wa-sqlite": "^1.0.0",
|
||||||
"zod": "^4.1.12",
|
|
||||||
"zustand": "^4.5.4"
|
"zustand": "^4.5.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
import { useOrganizationMembers } from '@/hooks/useOrganizationMembers';
|
|
||||||
import { UserAvatar } from '@/components/tasks/UserAvatar';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
interface OrgMemberAvatarsProps {
|
|
||||||
limit?: number;
|
|
||||||
className?: string;
|
|
||||||
organizationId?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function OrgMemberAvatars({
|
|
||||||
limit = 5,
|
|
||||||
className = '',
|
|
||||||
organizationId,
|
|
||||||
}: OrgMemberAvatarsProps) {
|
|
||||||
const { t } = useTranslation('common');
|
|
||||||
const { data: members, isPending } = useOrganizationMembers(organizationId);
|
|
||||||
|
|
||||||
if (!organizationId || isPending || !members || members.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const displayMembers = members.slice(0, limit);
|
|
||||||
const remainingCount = members.length - limit;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={`flex items-center ${className}`}>
|
|
||||||
<div className="flex -space-x-2">
|
|
||||||
{displayMembers.map((member) => (
|
|
||||||
<UserAvatar
|
|
||||||
key={member.user_id}
|
|
||||||
firstName={member.first_name}
|
|
||||||
lastName={member.last_name}
|
|
||||||
username={member.username}
|
|
||||||
imageUrl={member.avatar_url}
|
|
||||||
className="h-6 w-6 ring-2 ring-background"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
{remainingCount > 0 && (
|
|
||||||
<span className="ml-2 text-xs text-muted-foreground">
|
|
||||||
{t('orgMembers.moreCount', { count: remainingCount })}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
interface ResponsiveTwoPaneProps {
|
|
||||||
left: React.ReactNode;
|
|
||||||
right: React.ReactNode;
|
|
||||||
isRightOpen: boolean;
|
|
||||||
variant?: 'sidebar' | 'split';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ResponsiveTwoPane({
|
|
||||||
left,
|
|
||||||
right,
|
|
||||||
isRightOpen,
|
|
||||||
variant = 'sidebar',
|
|
||||||
}: ResponsiveTwoPaneProps) {
|
|
||||||
if (variant === 'split') {
|
|
||||||
return (
|
|
||||||
<div className="h-full min-h-0 grid grid-cols-2">
|
|
||||||
<div className="min-w-0 border-r overflow-auto">{left}</div>
|
|
||||||
<div className="min-w-0 overflow-auto">{right}</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="h-full min-h-0 overflow-hidden grid xl:grid-cols-[1fr_600px]">
|
|
||||||
<div className="min-w-0 min-h-0">{left}</div>
|
|
||||||
|
|
||||||
{isRightOpen && (
|
|
||||||
<div className="fixed inset-0 z-40 bg-background/80 backdrop-blur-sm xl:hidden" />
|
|
||||||
)}
|
|
||||||
|
|
||||||
<aside
|
|
||||||
className={[
|
|
||||||
'bg-background border-l min-h-0 min-w-0 flex flex-col overflow-hidden',
|
|
||||||
'xl:static xl:block xl:h-full',
|
|
||||||
isRightOpen
|
|
||||||
? 'fixed inset-y-0 right-0 left-auto w-full md:w-[600px] z-50 shadow-xl'
|
|
||||||
: 'hidden',
|
|
||||||
].join(' ')}
|
|
||||||
>
|
|
||||||
{right}
|
|
||||||
</aside>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ResponsiveTwoPane;
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
import { memo, useEffect, useRef, useState } from 'react';
|
|
||||||
import { CheckCircle2, Clock, Loader2, Send, WifiOff } from 'lucide-react';
|
|
||||||
import { cn } from '@/lib/utils';
|
|
||||||
|
|
||||||
export type SaveStatus = 'idle' | 'saving' | 'saved' | 'offline' | 'sent';
|
|
||||||
|
|
||||||
type Status = {
|
|
||||||
save: { state: SaveStatus; isSaving: boolean };
|
|
||||||
draft: { isLoaded: boolean; isSending: boolean };
|
|
||||||
queue: { isUnqueuing: boolean; isQueued: boolean };
|
|
||||||
};
|
|
||||||
|
|
||||||
type Props = { status: Status; pillBgClass?: string };
|
|
||||||
|
|
||||||
function FollowUpStatusRowImpl({ status, pillBgClass = 'bg-muted' }: Props) {
|
|
||||||
const { save, draft, queue } = status;
|
|
||||||
|
|
||||||
// Nonce keys to retrigger CSS animation; no JS timers.
|
|
||||||
const [savedNonce, setSavedNonce] = useState<number | null>(null);
|
|
||||||
const [sentNonce, setSentNonce] = useState<number | null>(null);
|
|
||||||
const prevIsSendingRef = useRef<boolean>(draft.isSending);
|
|
||||||
|
|
||||||
// Show "Draft saved" by bumping key to restart CSS animation
|
|
||||||
useEffect(() => {
|
|
||||||
if (save.state === 'saved') setSavedNonce(Date.now());
|
|
||||||
}, [save.state]);
|
|
||||||
|
|
||||||
// Show "Follow-up sent" on isSending rising edge
|
|
||||||
useEffect(() => {
|
|
||||||
const now = draft.isSending;
|
|
||||||
if (now && !prevIsSendingRef.current) {
|
|
||||||
setSentNonce(Date.now());
|
|
||||||
}
|
|
||||||
prevIsSendingRef.current = now;
|
|
||||||
}, [draft.isSending]);
|
|
||||||
return (
|
|
||||||
<div className="flex items-center justify-between text-xs min-h-6 h-6 px-0.5">
|
|
||||||
<div className="text-muted-foreground">
|
|
||||||
{save.state === 'saving' && save.isSaving ? (
|
|
||||||
<span
|
|
||||||
className={cn(
|
|
||||||
'inline-flex items-center gap-1.5 rounded-md border px-2 py-0.5 animate-in fade-in-0',
|
|
||||||
'italic',
|
|
||||||
pillBgClass
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Loader2 className="animate-spin h-3 w-3" /> Saving…
|
|
||||||
</span>
|
|
||||||
) : save.state === 'offline' ? (
|
|
||||||
<span
|
|
||||||
className={cn(
|
|
||||||
'inline-flex items-center gap-1.5 rounded-md border px-2 py-0.5 text-amber-700 animate-in fade-in-0',
|
|
||||||
pillBgClass
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<WifiOff className="h-3 w-3" /> Offline — changes pending
|
|
||||||
</span>
|
|
||||||
) : sentNonce ? (
|
|
||||||
<span
|
|
||||||
key={sentNonce}
|
|
||||||
className={cn(
|
|
||||||
'inline-flex items-center gap-1.5 rounded-md border px-2 py-0.5 text-emerald-700 animate-pill',
|
|
||||||
pillBgClass
|
|
||||||
)}
|
|
||||||
onAnimationEnd={() => setSentNonce(null)}
|
|
||||||
>
|
|
||||||
<Send className="h-3 w-3" /> Follow-up sent
|
|
||||||
</span>
|
|
||||||
) : savedNonce ? (
|
|
||||||
<span
|
|
||||||
key={savedNonce}
|
|
||||||
className={cn(
|
|
||||||
'inline-flex items-center gap-1.5 rounded-md border px-2 py-0.5 text-emerald-700 animate-pill',
|
|
||||||
pillBgClass
|
|
||||||
)}
|
|
||||||
onAnimationEnd={() => setSavedNonce(null)}
|
|
||||||
>
|
|
||||||
<CheckCircle2 className="h-3 w-3" /> Draft saved
|
|
||||||
</span>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
<div className="text-muted-foreground">
|
|
||||||
{queue.isUnqueuing ? (
|
|
||||||
<span
|
|
||||||
className={cn(
|
|
||||||
'inline-flex items-center gap-1.5 rounded-md border px-2 py-0.5 animate-in fade-in-0',
|
|
||||||
pillBgClass
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Loader2 className="animate-spin h-3 w-3" /> Unlocking…
|
|
||||||
</span>
|
|
||||||
) : !draft.isLoaded ? (
|
|
||||||
<span
|
|
||||||
className={cn(
|
|
||||||
'inline-flex items-center gap-1.5 rounded-md border px-2 py-0.5 animate-in fade-in-0',
|
|
||||||
pillBgClass
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Loader2 className="animate-spin h-3 w-3" /> Loading draft…
|
|
||||||
</span>
|
|
||||||
) : draft.isSending ? (
|
|
||||||
<span
|
|
||||||
className={cn(
|
|
||||||
'inline-flex items-center gap-1.5 rounded-md border px-2 py-0.5 animate-in fade-in-0',
|
|
||||||
pillBgClass
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Loader2 className="animate-spin h-3 w-3" /> Sending follow-up…
|
|
||||||
</span>
|
|
||||||
) : queue.isQueued ? (
|
|
||||||
<span
|
|
||||||
className={cn(
|
|
||||||
'inline-flex items-center gap-1.5 rounded-md border px-2 py-0.5 animate-in fade-in-0',
|
|
||||||
pillBgClass
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Clock className="h-3 w-3" /> Queued for next turn. Edits are
|
|
||||||
locked.
|
|
||||||
</span>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const FollowUpStatusRow = memo(FollowUpStatusRowImpl);
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
import { Card } from '@/components/ui/card';
|
|
||||||
import { Badge } from '@/components/ui/badge';
|
|
||||||
import { cn } from '@/lib/utils';
|
|
||||||
import type { Task } from 'shared/types';
|
|
||||||
|
|
||||||
interface TaskRelationshipCardProps {
|
|
||||||
task: Task;
|
|
||||||
isCurrentTask?: boolean;
|
|
||||||
onClick?: () => void;
|
|
||||||
className?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function TaskRelationshipCard({
|
|
||||||
task,
|
|
||||||
isCurrentTask = false,
|
|
||||||
onClick,
|
|
||||||
className,
|
|
||||||
}: TaskRelationshipCardProps) {
|
|
||||||
const getStatusBadgeVariant = (status: string) => {
|
|
||||||
switch (status) {
|
|
||||||
case 'todo':
|
|
||||||
return 'secondary';
|
|
||||||
case 'inprogress':
|
|
||||||
return 'default';
|
|
||||||
case 'inreview':
|
|
||||||
return 'outline';
|
|
||||||
case 'done':
|
|
||||||
return 'default';
|
|
||||||
case 'cancelled':
|
|
||||||
return 'destructive';
|
|
||||||
default:
|
|
||||||
return 'secondary';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const truncateTitle = (title: string, maxLength: number = 50) => {
|
|
||||||
return title.length > maxLength
|
|
||||||
? `${title.substring(0, maxLength)}...`
|
|
||||||
: title;
|
|
||||||
};
|
|
||||||
|
|
||||||
const truncateDescription = (
|
|
||||||
description: string | null,
|
|
||||||
maxLength: number = 120
|
|
||||||
) => {
|
|
||||||
if (!description) return null;
|
|
||||||
return description.length > maxLength
|
|
||||||
? `${description.substring(0, maxLength)}...`
|
|
||||||
: description;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Card
|
|
||||||
className={cn(
|
|
||||||
'p-4 transition-all duration-200 cursor-pointer hover:shadow-md border',
|
|
||||||
'min-h-[100px] w-full', // More spacious and responsive
|
|
||||||
isCurrentTask && 'bg-accent/10 border-accent ring-1 ring-accent/50',
|
|
||||||
!isCurrentTask && 'hover:bg-accent/5',
|
|
||||||
onClick && 'cursor-pointer',
|
|
||||||
!onClick && 'cursor-default',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
onClick={onClick}
|
|
||||||
>
|
|
||||||
<div className="flex flex-col space-y-3">
|
|
||||||
{/* Title and Status Row */}
|
|
||||||
<div className="flex items-start justify-between gap-3">
|
|
||||||
<h4
|
|
||||||
className="font-medium text-sm leading-relaxed flex-1 min-w-0"
|
|
||||||
title={task.title}
|
|
||||||
>
|
|
||||||
{truncateTitle(task.title)}
|
|
||||||
</h4>
|
|
||||||
<div className="flex items-center space-x-1 shrink-0">
|
|
||||||
<Badge
|
|
||||||
variant={getStatusBadgeVariant(task.status)}
|
|
||||||
className="text-xs px-2 py-1 h-auto"
|
|
||||||
>
|
|
||||||
{task.status}
|
|
||||||
</Badge>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Description */}
|
|
||||||
{task.description && (
|
|
||||||
<p
|
|
||||||
className="text-xs text-muted-foreground leading-relaxed"
|
|
||||||
title={task.description}
|
|
||||||
>
|
|
||||||
{truncateDescription(task.description)}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Current task indicator */}
|
|
||||||
{isCurrentTask && (
|
|
||||||
<div className="flex items-center gap-2 pt-1">
|
|
||||||
<div className="w-2 h-2 rounded-full bg-primary animate-pulse" />
|
|
||||||
<span className="text-xs text-primary font-medium">
|
|
||||||
Current Task
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { Card } from '@/components/ui/card';
|
|
||||||
import { TaskRelationshipCard } from './TaskRelationshipCard';
|
|
||||||
import { attemptsApi } from '@/lib/api';
|
|
||||||
import type {
|
|
||||||
TaskAttempt,
|
|
||||||
TaskRelationships,
|
|
||||||
TaskWithAttemptStatus,
|
|
||||||
} from 'shared/types';
|
|
||||||
import { ChevronDown, ChevronRight } from 'lucide-react';
|
|
||||||
|
|
||||||
interface TaskRelationshipViewerProps {
|
|
||||||
selectedAttempt: TaskAttempt | null;
|
|
||||||
onNavigateToTask?: (taskId: string) => void;
|
|
||||||
task?: TaskWithAttemptStatus | null;
|
|
||||||
tasksById?: Record<string, TaskWithAttemptStatus>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function TaskRelationshipViewer({
|
|
||||||
selectedAttempt,
|
|
||||||
onNavigateToTask,
|
|
||||||
task,
|
|
||||||
tasksById,
|
|
||||||
}: TaskRelationshipViewerProps) {
|
|
||||||
const [relationships, setRelationships] = useState<TaskRelationships | null>(
|
|
||||||
null
|
|
||||||
);
|
|
||||||
const [parentTask, setParentTask] = useState<TaskWithAttemptStatus | null>(
|
|
||||||
null
|
|
||||||
);
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [error, setError] = useState<string | null>(null);
|
|
||||||
const [childrenExpanded, setChildrenExpanded] = useState(true);
|
|
||||||
|
|
||||||
// Effect for attempt-based relationships (existing behavior)
|
|
||||||
useEffect(() => {
|
|
||||||
if (!selectedAttempt?.id) {
|
|
||||||
setRelationships(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchRelationships = async () => {
|
|
||||||
setLoading(true);
|
|
||||||
setError(null);
|
|
||||||
try {
|
|
||||||
const relationshipData = await attemptsApi.getChildren(
|
|
||||||
selectedAttempt.id
|
|
||||||
);
|
|
||||||
setRelationships(relationshipData);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Failed to fetch task relationships:', err);
|
|
||||||
setError('Failed to load task relationships');
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchRelationships();
|
|
||||||
}, [selectedAttempt?.id]);
|
|
||||||
|
|
||||||
// Effect for parent task when child has no attempts (one request + tasksById lookup)
|
|
||||||
useEffect(() => {
|
|
||||||
if (selectedAttempt?.id) {
|
|
||||||
// If we have an attempt, clear parent task since relationships will handle it
|
|
||||||
setParentTask(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (task?.parent_task_attempt && tasksById) {
|
|
||||||
attemptsApi
|
|
||||||
.get(task.parent_task_attempt)
|
|
||||||
.then((parentAttempt) => {
|
|
||||||
// Use existing tasksById instead of second API call
|
|
||||||
const parentTaskData = tasksById[parentAttempt.task_id];
|
|
||||||
setParentTask(parentTaskData || null);
|
|
||||||
})
|
|
||||||
.catch(() => setParentTask(null));
|
|
||||||
} else {
|
|
||||||
setParentTask(null);
|
|
||||||
}
|
|
||||||
}, [selectedAttempt?.id, task?.parent_task_attempt, tasksById]);
|
|
||||||
|
|
||||||
const displayParentTask = relationships?.parent_task || parentTask;
|
|
||||||
const childTasks = relationships?.children || [];
|
|
||||||
const hasParent = displayParentTask !== null;
|
|
||||||
const hasChildren = childTasks.length > 0;
|
|
||||||
|
|
||||||
// Don't render if no relationships and no current task
|
|
||||||
if (!hasParent && !hasChildren && !loading && !error) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Card className="bg-background p-3 border border-dashed text-sm">
|
|
||||||
Task Relationships
|
|
||||||
</Card>
|
|
||||||
<div className="p-3 space-y-6">
|
|
||||||
{loading ? (
|
|
||||||
<div className="text-sm text-muted-foreground py-8 text-center">
|
|
||||||
Loading relationships...
|
|
||||||
</div>
|
|
||||||
) : error ? (
|
|
||||||
<div className="text-sm text-destructive py-8 text-center">
|
|
||||||
{error}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="space-y-6">
|
|
||||||
{/* Parent Task Section */}
|
|
||||||
{hasParent && displayParentTask && (
|
|
||||||
<div className="space-y-3">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<h4 className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
|
|
||||||
Parent Task
|
|
||||||
</h4>
|
|
||||||
<div className="flex-1 h-px bg-border"></div>
|
|
||||||
</div>
|
|
||||||
<div className="flex justify-center">
|
|
||||||
<div className="w-full max-w-md">
|
|
||||||
<TaskRelationshipCard
|
|
||||||
task={displayParentTask}
|
|
||||||
isCurrentTask={false}
|
|
||||||
onClick={() => onNavigateToTask?.(displayParentTask.id)}
|
|
||||||
className="shadow-sm"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Child Tasks Section */}
|
|
||||||
{hasChildren && (
|
|
||||||
<div className="space-y-3">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<button
|
|
||||||
onClick={() => setChildrenExpanded(!childrenExpanded)}
|
|
||||||
className="flex items-center gap-1 text-xs font-medium text-muted-foreground uppercase tracking-wide hover:text-foreground transition-colors"
|
|
||||||
>
|
|
||||||
{childrenExpanded ? (
|
|
||||||
<ChevronDown className="w-3 h-3" />
|
|
||||||
) : (
|
|
||||||
<ChevronRight className="w-3 h-3" />
|
|
||||||
)}
|
|
||||||
Child Tasks ({childTasks.length})
|
|
||||||
</button>
|
|
||||||
<div className="flex-1 h-px bg-border"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{childrenExpanded && (
|
|
||||||
<div className="flex flex-col gap-4">
|
|
||||||
{childTasks.map((childTask) => (
|
|
||||||
<TaskRelationshipCard
|
|
||||||
key={childTask.id}
|
|
||||||
task={childTask}
|
|
||||||
isCurrentTask={false}
|
|
||||||
onClick={() => onNavigateToTask?.(childTask.id)}
|
|
||||||
className="shadow-sm hover:shadow-md transition-shadow"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,352 +0,0 @@
|
|||||||
import {
|
|
||||||
useState,
|
|
||||||
useCallback,
|
|
||||||
useRef,
|
|
||||||
useImperativeHandle,
|
|
||||||
useEffect,
|
|
||||||
forwardRef,
|
|
||||||
} from 'react';
|
|
||||||
import {
|
|
||||||
X,
|
|
||||||
Image as ImageIcon,
|
|
||||||
Upload,
|
|
||||||
ChevronRight,
|
|
||||||
AlertCircle,
|
|
||||||
} from 'lucide-react';
|
|
||||||
import { Button } from './button';
|
|
||||||
import { Alert, AlertDescription } from './alert';
|
|
||||||
import { cn, formatFileSize } from '@/lib/utils';
|
|
||||||
import { imagesApi } from '@/lib/api';
|
|
||||||
import type { ImageResponse } from 'shared/types';
|
|
||||||
|
|
||||||
interface ImageUploadSectionProps {
|
|
||||||
images: ImageResponse[];
|
|
||||||
onImagesChange: (images: ImageResponse[]) => void;
|
|
||||||
onUpload: (file: File) => Promise<ImageResponse>;
|
|
||||||
onDelete?: (imageId: string) => Promise<void>;
|
|
||||||
onImageUploaded?: (image: ImageResponse) => void; // Custom callback for upload success
|
|
||||||
isUploading?: boolean;
|
|
||||||
disabled?: boolean;
|
|
||||||
readOnly?: boolean;
|
|
||||||
collapsible?: boolean;
|
|
||||||
defaultExpanded?: boolean;
|
|
||||||
hideDropZone?: boolean; // Hide the drag and drop area
|
|
||||||
className?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ImageUploadSectionHandle {
|
|
||||||
addFiles: (files: FileList | File[] | null) => Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const MAX_SIZE_BYTES = 20 * 1024 * 1024; // 20MB
|
|
||||||
const VALID_TYPES = [
|
|
||||||
'image/png',
|
|
||||||
'image/jpeg',
|
|
||||||
'image/jpg',
|
|
||||||
'image/gif',
|
|
||||||
'image/webp',
|
|
||||||
'image/bmp',
|
|
||||||
'image/svg+xml',
|
|
||||||
];
|
|
||||||
|
|
||||||
export const ImageUploadSection = forwardRef<
|
|
||||||
ImageUploadSectionHandle,
|
|
||||||
ImageUploadSectionProps
|
|
||||||
>(
|
|
||||||
(
|
|
||||||
{
|
|
||||||
images,
|
|
||||||
onImagesChange,
|
|
||||||
onUpload,
|
|
||||||
onDelete,
|
|
||||||
onImageUploaded,
|
|
||||||
isUploading = false,
|
|
||||||
disabled = false,
|
|
||||||
readOnly = false,
|
|
||||||
collapsible = true,
|
|
||||||
defaultExpanded = false,
|
|
||||||
hideDropZone = false,
|
|
||||||
className,
|
|
||||||
},
|
|
||||||
ref
|
|
||||||
) => {
|
|
||||||
const [isExpanded, setIsExpanded] = useState(
|
|
||||||
defaultExpanded || images.length > 0
|
|
||||||
);
|
|
||||||
const [isDragging, setIsDragging] = useState(false);
|
|
||||||
const [uploadingFiles, setUploadingFiles] = useState<Set<string>>(
|
|
||||||
new Set()
|
|
||||||
);
|
|
||||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
||||||
const latestImagesRef = useRef(images);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
latestImagesRef.current = images;
|
|
||||||
}, [images]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (collapsible && images.length > 0 && !isExpanded) {
|
|
||||||
setIsExpanded(true);
|
|
||||||
}
|
|
||||||
}, [collapsible, images.length, isExpanded]);
|
|
||||||
|
|
||||||
const handleFiles = useCallback(
|
|
||||||
async (filesInput: FileList | File[] | null) => {
|
|
||||||
if (!filesInput || disabled || readOnly) return;
|
|
||||||
|
|
||||||
const files = Array.isArray(filesInput)
|
|
||||||
? filesInput
|
|
||||||
: Array.from(filesInput);
|
|
||||||
|
|
||||||
setErrorMessage(null);
|
|
||||||
|
|
||||||
const invalidFiles: string[] = [];
|
|
||||||
const oversizedFiles: string[] = [];
|
|
||||||
const validFiles: File[] = [];
|
|
||||||
|
|
||||||
files.forEach((file) => {
|
|
||||||
if (!VALID_TYPES.includes(file.type.toLowerCase())) {
|
|
||||||
invalidFiles.push(file.name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.size > MAX_SIZE_BYTES) {
|
|
||||||
oversizedFiles.push(
|
|
||||||
`${file.name} (${(file.size / 1048576).toFixed(1)} MB)`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
validFiles.push(file);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (invalidFiles.length > 0 || oversizedFiles.length > 0) {
|
|
||||||
const errors: string[] = [];
|
|
||||||
if (invalidFiles.length > 0) {
|
|
||||||
errors.push(`Unsupported file type: ${invalidFiles.join(', ')}`);
|
|
||||||
}
|
|
||||||
if (oversizedFiles.length > 0) {
|
|
||||||
errors.push(
|
|
||||||
`Files too large (max 20 MB): ${oversizedFiles.join(', ')}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
setErrorMessage(errors.join('. '));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const file of validFiles) {
|
|
||||||
const tempId = `uploading-${Date.now()}-${file.name}`;
|
|
||||||
setUploadingFiles((prev) => new Set(prev).add(tempId));
|
|
||||||
|
|
||||||
try {
|
|
||||||
const uploadedImage = await onUpload(file);
|
|
||||||
|
|
||||||
// Call custom upload callback if provided, otherwise use default behavior
|
|
||||||
if (onImageUploaded) {
|
|
||||||
onImageUploaded(uploadedImage);
|
|
||||||
} else {
|
|
||||||
const nextImages = [...latestImagesRef.current, uploadedImage];
|
|
||||||
latestImagesRef.current = nextImages;
|
|
||||||
onImagesChange(nextImages);
|
|
||||||
}
|
|
||||||
|
|
||||||
setErrorMessage(null);
|
|
||||||
} catch (error: unknown) {
|
|
||||||
console.error('Failed to upload image:', error);
|
|
||||||
const message =
|
|
||||||
error instanceof Error
|
|
||||||
? error.message
|
|
||||||
: 'Failed to upload image. Please try again.';
|
|
||||||
setErrorMessage(message);
|
|
||||||
} finally {
|
|
||||||
setUploadingFiles((prev) => {
|
|
||||||
const next = new Set(prev);
|
|
||||||
next.delete(tempId);
|
|
||||||
return next;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[disabled, readOnly, onUpload, onImageUploaded, onImagesChange]
|
|
||||||
);
|
|
||||||
|
|
||||||
useImperativeHandle(
|
|
||||||
ref,
|
|
||||||
() => ({
|
|
||||||
addFiles: async (files: FileList | File[] | null) => {
|
|
||||||
await handleFiles(files);
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
[handleFiles]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleDrop = useCallback(
|
|
||||||
(e: React.DragEvent) => {
|
|
||||||
e.preventDefault();
|
|
||||||
setIsDragging(false);
|
|
||||||
void handleFiles(e.dataTransfer.files);
|
|
||||||
},
|
|
||||||
[handleFiles]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleDragOver = useCallback((e: React.DragEvent) => {
|
|
||||||
e.preventDefault();
|
|
||||||
setIsDragging(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleDragLeave = useCallback((e: React.DragEvent) => {
|
|
||||||
e.preventDefault();
|
|
||||||
setIsDragging(false);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleRemoveImage = useCallback(
|
|
||||||
async (imageId: string) => {
|
|
||||||
if (onDelete) {
|
|
||||||
try {
|
|
||||||
await onDelete(imageId);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to delete image:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onImagesChange(images.filter((img) => img.id !== imageId));
|
|
||||||
},
|
|
||||||
[images, onImagesChange, onDelete]
|
|
||||||
);
|
|
||||||
|
|
||||||
const content = (
|
|
||||||
<div className={cn('space-y-3', className)}>
|
|
||||||
{/* Error message */}
|
|
||||||
{errorMessage && (
|
|
||||||
<Alert variant="destructive">
|
|
||||||
<AlertCircle className="h-4 w-4" />
|
|
||||||
<AlertDescription>{errorMessage}</AlertDescription>
|
|
||||||
</Alert>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Read-only message */}
|
|
||||||
{readOnly && images.length === 0 && (
|
|
||||||
<p className="text-sm text-muted-foreground">No images attached</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Drop zone - only show when not read-only and not hidden */}
|
|
||||||
{!readOnly && !hideDropZone && (
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
'border-2 border-dashed rounded-lg p-6 text-center transition-colors',
|
|
||||||
isDragging
|
|
||||||
? 'border-primary bg-primary/5'
|
|
||||||
: 'border-muted-foreground/25 hover:border-muted-foreground/50',
|
|
||||||
disabled && 'opacity-50 cursor-not-allowed'
|
|
||||||
)}
|
|
||||||
onDrop={handleDrop}
|
|
||||||
onDragOver={handleDragOver}
|
|
||||||
onDragLeave={handleDragLeave}
|
|
||||||
>
|
|
||||||
<Upload className="h-8 w-8 mx-auto mb-3 text-muted-foreground" />
|
|
||||||
<p className="text-sm text-muted-foreground mb-1">
|
|
||||||
Drag and drop images here, or click to select
|
|
||||||
</p>
|
|
||||||
<Button
|
|
||||||
variant="secondary"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => fileInputRef.current?.click()}
|
|
||||||
disabled={disabled || isUploading}
|
|
||||||
>
|
|
||||||
Select Images
|
|
||||||
</Button>
|
|
||||||
<input
|
|
||||||
ref={fileInputRef}
|
|
||||||
type="file"
|
|
||||||
accept="image/*"
|
|
||||||
multiple
|
|
||||||
className="hidden"
|
|
||||||
onChange={(e) => {
|
|
||||||
void handleFiles(e.target.files);
|
|
||||||
}}
|
|
||||||
disabled={disabled}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Image previews */}
|
|
||||||
{images.length > 0 && (
|
|
||||||
<div className="grid grid-cols-2 gap-2">
|
|
||||||
{images.map((image) => (
|
|
||||||
<div
|
|
||||||
key={image.id}
|
|
||||||
className="relative group border rounded-lg p-2 bg-background"
|
|
||||||
>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<img
|
|
||||||
src={imagesApi.getImageUrl(image.id)}
|
|
||||||
alt={image.original_name}
|
|
||||||
className="h-16 w-16 object-cover rounded"
|
|
||||||
/>
|
|
||||||
<div className="flex-1 min-w-0">
|
|
||||||
<p className="text-xs font-medium truncate">
|
|
||||||
{image.original_name}
|
|
||||||
</p>
|
|
||||||
<p className="text-xs text-muted-foreground">
|
|
||||||
{formatFileSize(image.size_bytes)}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{!disabled && !readOnly && (
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="icon"
|
|
||||||
className="absolute top-1 right-1 h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity"
|
|
||||||
onClick={() => handleRemoveImage(image.id)}
|
|
||||||
>
|
|
||||||
<X className="h-3 w-3" />
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Uploading indicators */}
|
|
||||||
{uploadingFiles.size > 0 && (
|
|
||||||
<div className="space-y-1">
|
|
||||||
{Array.from(uploadingFiles).map((tempId) => (
|
|
||||||
<div
|
|
||||||
key={tempId}
|
|
||||||
className="flex items-center gap-2 text-xs text-muted-foreground"
|
|
||||||
>
|
|
||||||
<div className="h-3 w-3 border-2 border-primary border-t-transparent rounded-full animate-spin" />
|
|
||||||
<span>Uploading...</span>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!collapsible) {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="space-y-2">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => setIsExpanded(!isExpanded)}
|
|
||||||
className="flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors"
|
|
||||||
>
|
|
||||||
<ChevronRight
|
|
||||||
className={cn(
|
|
||||||
'h-3 w-3 transition-transform',
|
|
||||||
isExpanded && 'rotate-90'
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<ImageIcon className="h-4 w-4" />
|
|
||||||
<span>Images {images.length > 0 && `(${images.length})`}</span>
|
|
||||||
</button>
|
|
||||||
{isExpanded && content}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
ImageUploadSection.displayName = 'ImageUploadSection';
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
||||||
|
|
||||||
import { cn } from '@/lib/utils';
|
|
||||||
|
|
||||||
const Tabs = TabsPrimitive.Root;
|
|
||||||
|
|
||||||
const TabsList = React.forwardRef<
|
|
||||||
React.ElementRef<typeof TabsPrimitive.List>,
|
|
||||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<TabsPrimitive.List
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
||||||
|
|
||||||
const TabsTrigger = React.forwardRef<
|
|
||||||
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
|
||||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<TabsPrimitive.Trigger
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
||||||
|
|
||||||
const TabsContent = React.forwardRef<
|
|
||||||
React.ElementRef<typeof TabsPrimitive.Content>,
|
|
||||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
|
|
||||||
>(({ className, ...props }, ref) => (
|
|
||||||
<TabsPrimitive.Content
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
||||||
|
|
||||||
export { Tabs, TabsList, TabsTrigger, TabsContent };
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
import { Input } from './input';
|
|
||||||
import WYSIWYGEditor from './wysiwyg';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
title: string;
|
|
||||||
description: string | null | undefined;
|
|
||||||
onTitleChange: (v: string) => void;
|
|
||||||
onDescriptionChange: (v: string) => void;
|
|
||||||
projectId?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const TitleDescriptionEditor = ({
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
onTitleChange,
|
|
||||||
onDescriptionChange,
|
|
||||||
projectId,
|
|
||||||
}: Props) => {
|
|
||||||
return (
|
|
||||||
<div className="space-y-3 flex-1">
|
|
||||||
<Input
|
|
||||||
className="text-2xl h-auto border-0 p-0"
|
|
||||||
placeholder="Title*"
|
|
||||||
value={title}
|
|
||||||
onChange={(e) => onTitleChange(e.target.value)}
|
|
||||||
/>
|
|
||||||
<WYSIWYGEditor
|
|
||||||
placeholder="Description"
|
|
||||||
value={description ?? ''}
|
|
||||||
onChange={onDescriptionChange}
|
|
||||||
projectId={projectId}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TitleDescriptionEditor;
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { createContext, useContext } from 'react';
|
import { createContext } from 'react';
|
||||||
import type { TabType } from '@/types/tabs';
|
import type { TabType } from '@/types/tabs';
|
||||||
|
|
||||||
interface TabNavContextType {
|
interface TabNavContextType {
|
||||||
@@ -7,11 +7,3 @@ interface TabNavContextType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const TabNavContext = createContext<TabNavContextType | null>(null);
|
export const TabNavContext = createContext<TabNavContextType | null>(null);
|
||||||
|
|
||||||
export const useTabNavigation = () => {
|
|
||||||
const context = useContext(TabNavContext);
|
|
||||||
if (!context) {
|
|
||||||
throw new Error('useTabNavigation must be used within TabNavContext');
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
const CARET_PROBE_CHARACTER = '\u200b';
|
|
||||||
|
|
||||||
const mirrorStyleProperties = [
|
|
||||||
'boxSizing',
|
|
||||||
'fontFamily',
|
|
||||||
'fontSize',
|
|
||||||
'fontStyle',
|
|
||||||
'fontWeight',
|
|
||||||
'letterSpacing',
|
|
||||||
'lineHeight',
|
|
||||||
'paddingTop',
|
|
||||||
'paddingRight',
|
|
||||||
'paddingBottom',
|
|
||||||
'paddingLeft',
|
|
||||||
'textAlign',
|
|
||||||
'textTransform',
|
|
||||||
'borderTopWidth',
|
|
||||||
'borderRightWidth',
|
|
||||||
'borderBottomWidth',
|
|
||||||
'borderLeftWidth',
|
|
||||||
'borderTopStyle',
|
|
||||||
'borderRightStyle',
|
|
||||||
'borderBottomStyle',
|
|
||||||
'borderLeftStyle',
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
type MirrorStyleProperty = (typeof mirrorStyleProperties)[number];
|
|
||||||
|
|
||||||
export const getCaretClientRect = (
|
|
||||||
textarea: HTMLTextAreaElement,
|
|
||||||
targetIndex?: number
|
|
||||||
) => {
|
|
||||||
if (typeof window === 'undefined') return null;
|
|
||||||
|
|
||||||
const selectionIndex =
|
|
||||||
typeof targetIndex === 'number'
|
|
||||||
? Math.min(Math.max(targetIndex, 0), textarea.value.length)
|
|
||||||
: (textarea.selectionEnd ?? textarea.value.length);
|
|
||||||
|
|
||||||
const textBeforeCaret = textarea.value.slice(0, selectionIndex);
|
|
||||||
const textareaRect = textarea.getBoundingClientRect();
|
|
||||||
const computedStyle = window.getComputedStyle(textarea);
|
|
||||||
|
|
||||||
const mirror = document.createElement('div');
|
|
||||||
mirror.setAttribute('data-caret-mirror', 'true');
|
|
||||||
mirror.style.position = 'absolute';
|
|
||||||
mirror.style.top = `${textareaRect.top + window.scrollY}px`;
|
|
||||||
mirror.style.left = `${textareaRect.left + window.scrollX}px`;
|
|
||||||
mirror.style.visibility = 'hidden';
|
|
||||||
mirror.style.whiteSpace = 'pre-wrap';
|
|
||||||
mirror.style.wordBreak = 'break-word';
|
|
||||||
mirror.style.overflow = 'hidden';
|
|
||||||
mirror.style.width = `${textareaRect.width}px`;
|
|
||||||
|
|
||||||
mirrorStyleProperties.forEach((property: MirrorStyleProperty) => {
|
|
||||||
const value = computedStyle[property];
|
|
||||||
if (value) {
|
|
||||||
mirror.style[property] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mirror.textContent = textBeforeCaret;
|
|
||||||
|
|
||||||
const probe = document.createElement('span');
|
|
||||||
probe.textContent = CARET_PROBE_CHARACTER;
|
|
||||||
mirror.appendChild(probe);
|
|
||||||
|
|
||||||
document.body.appendChild(mirror);
|
|
||||||
const caretRect = probe.getBoundingClientRect();
|
|
||||||
document.body.removeChild(mirror);
|
|
||||||
|
|
||||||
return caretRect;
|
|
||||||
};
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import type { ImageResponse } from 'shared/types';
|
|
||||||
|
|
||||||
export function imageToMarkdown(image: ImageResponse): string {
|
|
||||||
return ``;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function appendImageMarkdown(
|
|
||||||
prev: string,
|
|
||||||
image: ImageResponse
|
|
||||||
): string {
|
|
||||||
const markdownText = imageToMarkdown(image);
|
|
||||||
if (prev.trim() === '') return markdownText + '\n';
|
|
||||||
const needsNewline = !prev.endsWith('\n');
|
|
||||||
return prev + (needsNewline ? '\n' : '') + markdownText + '\n';
|
|
||||||
}
|
|
||||||
363
pnpm-lock.yaml
generated
363
pnpm-lock.yaml
generated
@@ -32,9 +32,6 @@ importers:
|
|||||||
'@dnd-kit/core':
|
'@dnd-kit/core':
|
||||||
specifier: ^6.3.1
|
specifier: ^6.3.1
|
||||||
version: 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
'@dnd-kit/modifiers':
|
|
||||||
specifier: ^9.0.0
|
|
||||||
version: 9.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
|
||||||
'@dnd-kit/utilities':
|
'@dnd-kit/utilities':
|
||||||
specifier: ^3.2.2
|
specifier: ^3.2.2
|
||||||
version: 3.2.2(react@18.3.1)
|
version: 3.2.2(react@18.3.1)
|
||||||
@@ -65,9 +62,6 @@ importers:
|
|||||||
'@lexical/rich-text':
|
'@lexical/rich-text':
|
||||||
specifier: ^0.36.2
|
specifier: ^0.36.2
|
||||||
version: 0.36.2
|
version: 0.36.2
|
||||||
'@lexical/utils':
|
|
||||||
specifier: ^0.36.2
|
|
||||||
version: 0.36.2
|
|
||||||
'@radix-ui/react-dropdown-menu':
|
'@radix-ui/react-dropdown-menu':
|
||||||
specifier: ^2.1.15
|
specifier: ^2.1.15
|
||||||
version: 2.1.15(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 2.1.15(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
@@ -83,9 +77,6 @@ importers:
|
|||||||
'@radix-ui/react-switch':
|
'@radix-ui/react-switch':
|
||||||
specifier: ^1.0.3
|
specifier: ^1.0.3
|
||||||
version: 1.2.6(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 1.2.6(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
'@radix-ui/react-tabs':
|
|
||||||
specifier: ^1.1.12
|
|
||||||
version: 1.1.12(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
|
||||||
'@radix-ui/react-toggle-group':
|
'@radix-ui/react-toggle-group':
|
||||||
specifier: ^1.1.11
|
specifier: ^1.1.11
|
||||||
version: 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
@@ -101,30 +92,18 @@ importers:
|
|||||||
'@sentry/vite-plugin':
|
'@sentry/vite-plugin':
|
||||||
specifier: ^3.5.0
|
specifier: ^3.5.0
|
||||||
version: 3.5.0
|
version: 3.5.0
|
||||||
'@tailwindcss/typography':
|
|
||||||
specifier: ^0.5.16
|
|
||||||
version: 0.5.16(tailwindcss@3.4.17)
|
|
||||||
'@tanstack/electric-db-collection':
|
'@tanstack/electric-db-collection':
|
||||||
specifier: ^0.2.6
|
specifier: ^0.2.6
|
||||||
version: 0.2.6(typescript@5.9.2)
|
version: 0.2.6(typescript@5.9.2)
|
||||||
'@tanstack/react-db':
|
'@tanstack/react-db':
|
||||||
specifier: ^0.1.50
|
specifier: ^0.1.50
|
||||||
version: 0.1.50(react@18.3.1)(typescript@5.9.2)
|
version: 0.1.50(react@18.3.1)(typescript@5.9.2)
|
||||||
'@tanstack/react-devtools':
|
|
||||||
specifier: ^0.8.0
|
|
||||||
version: 0.8.0(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(solid-js@1.9.10)
|
|
||||||
'@tanstack/react-form':
|
'@tanstack/react-form':
|
||||||
specifier: ^1.23.8
|
specifier: ^1.23.8
|
||||||
version: 1.23.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 1.23.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
'@tanstack/react-form-devtools':
|
|
||||||
specifier: ^0.1.8
|
|
||||||
version: 0.1.8(csstype@3.1.3)(react@18.3.1)(solid-js@1.9.10)
|
|
||||||
'@tanstack/react-query':
|
'@tanstack/react-query':
|
||||||
specifier: ^5.85.5
|
specifier: ^5.85.5
|
||||||
version: 5.85.5(react@18.3.1)
|
version: 5.85.5(react@18.3.1)
|
||||||
'@types/react-window':
|
|
||||||
specifier: ^1.8.8
|
|
||||||
version: 1.8.8
|
|
||||||
'@uiw/react-codemirror':
|
'@uiw/react-codemirror':
|
||||||
specifier: ^4.25.1
|
specifier: ^4.25.1
|
||||||
version: 4.25.1(@babel/runtime@7.27.6)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.11.2)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.11)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.38.1)(codemirror@6.0.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 4.25.1(@babel/runtime@7.27.6)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.11.2)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.11)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.38.1)(codemirror@6.0.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
@@ -188,15 +167,9 @@ importers:
|
|||||||
react-router-dom:
|
react-router-dom:
|
||||||
specifier: ^6.8.1
|
specifier: ^6.8.1
|
||||||
version: 6.30.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 6.30.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
react-use-websocket:
|
|
||||||
specifier: ^4.7.0
|
|
||||||
version: 4.13.0
|
|
||||||
react-virtuoso:
|
react-virtuoso:
|
||||||
specifier: ^4.14.0
|
specifier: ^4.14.0
|
||||||
version: 4.14.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 4.14.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
react-window:
|
|
||||||
specifier: ^1.8.11
|
|
||||||
version: 1.8.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
|
||||||
rfc6902:
|
rfc6902:
|
||||||
specifier: ^5.1.2
|
specifier: ^5.1.2
|
||||||
version: 5.1.2
|
version: 5.1.2
|
||||||
@@ -215,9 +188,6 @@ importers:
|
|||||||
wa-sqlite:
|
wa-sqlite:
|
||||||
specifier: ^1.0.0
|
specifier: ^1.0.0
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
zod:
|
|
||||||
specifier: ^4.1.12
|
|
||||||
version: 4.1.12
|
|
||||||
zustand:
|
zustand:
|
||||||
specifier: ^4.5.4
|
specifier: ^4.5.4
|
||||||
version: 4.5.7(@types/react@18.3.23)(react@18.3.1)
|
version: 4.5.7(@types/react@18.3.23)(react@18.3.1)
|
||||||
@@ -466,12 +436,6 @@ packages:
|
|||||||
react: '>=16.8.0'
|
react: '>=16.8.0'
|
||||||
react-dom: '>=16.8.0'
|
react-dom: '>=16.8.0'
|
||||||
|
|
||||||
'@dnd-kit/modifiers@9.0.0':
|
|
||||||
resolution: {integrity: sha512-ybiLc66qRGuZoC20wdSSG6pDXFikui/dCNGthxv4Ndy8ylErY0N3KVxY2bgo7AWwIbxDmXDg3ylAFmnrjcbVvw==}
|
|
||||||
peerDependencies:
|
|
||||||
'@dnd-kit/core': ^6.3.0
|
|
||||||
react: '>=16.8.0'
|
|
||||||
|
|
||||||
'@dnd-kit/utilities@3.2.2':
|
'@dnd-kit/utilities@3.2.2':
|
||||||
resolution: {integrity: sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==}
|
resolution: {integrity: sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -1414,19 +1378,6 @@ packages:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@radix-ui/react-tabs@1.1.12':
|
|
||||||
resolution: {integrity: sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw==}
|
|
||||||
peerDependencies:
|
|
||||||
'@types/react': '*'
|
|
||||||
'@types/react-dom': '*'
|
|
||||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
|
||||||
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
|
||||||
peerDependenciesMeta:
|
|
||||||
'@types/react':
|
|
||||||
optional: true
|
|
||||||
'@types/react-dom':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@radix-ui/react-toggle-group@1.1.11':
|
'@radix-ui/react-toggle-group@1.1.11':
|
||||||
resolution: {integrity: sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==}
|
resolution: {integrity: sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -1781,36 +1732,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-jUnpTdpicG8wefamw7eNo2uO+Q3KCbOAiF76xH4gfNHSW6TN2hBfOtmLu7J+ive4c0Al3+NEHz19bIPR0lkwWg==}
|
resolution: {integrity: sha512-jUnpTdpicG8wefamw7eNo2uO+Q3KCbOAiF76xH4gfNHSW6TN2hBfOtmLu7J+ive4c0Al3+NEHz19bIPR0lkwWg==}
|
||||||
engines: {node: '>= 14'}
|
engines: {node: '>= 14'}
|
||||||
|
|
||||||
'@solid-primitives/event-listener@2.4.3':
|
|
||||||
resolution: {integrity: sha512-h4VqkYFv6Gf+L7SQj+Y6puigL/5DIi7x5q07VZET7AWcS+9/G3WfIE9WheniHWJs51OEkRB43w6lDys5YeFceg==}
|
|
||||||
peerDependencies:
|
|
||||||
solid-js: ^1.6.12
|
|
||||||
|
|
||||||
'@solid-primitives/keyboard@1.3.3':
|
|
||||||
resolution: {integrity: sha512-9dQHTTgLBqyAI7aavtO+HnpTVJgWQA1ghBSrmLtMu1SMxLPDuLfuNr+Tk5udb4AL4Ojg7h9JrKOGEEDqsJXWJA==}
|
|
||||||
peerDependencies:
|
|
||||||
solid-js: ^1.6.12
|
|
||||||
|
|
||||||
'@solid-primitives/resize-observer@2.1.3':
|
|
||||||
resolution: {integrity: sha512-zBLje5E06TgOg93S7rGPldmhDnouNGhvfZVKOp+oG2XU8snA+GoCSSCz1M+jpNAg5Ek2EakU5UVQqL152WmdXQ==}
|
|
||||||
peerDependencies:
|
|
||||||
solid-js: ^1.6.12
|
|
||||||
|
|
||||||
'@solid-primitives/rootless@1.5.2':
|
|
||||||
resolution: {integrity: sha512-9HULb0QAzL2r47CCad0M+NKFtQ+LrGGNHZfteX/ThdGvKIg2o2GYhBooZubTCd/RTu2l2+Nw4s+dEfiDGvdrrQ==}
|
|
||||||
peerDependencies:
|
|
||||||
solid-js: ^1.6.12
|
|
||||||
|
|
||||||
'@solid-primitives/static-store@0.1.2':
|
|
||||||
resolution: {integrity: sha512-ReK+5O38lJ7fT+L6mUFvUr6igFwHBESZF+2Ug842s7fvlVeBdIVEdTCErygff6w7uR6+jrr7J8jQo+cYrEq4Iw==}
|
|
||||||
peerDependencies:
|
|
||||||
solid-js: ^1.6.12
|
|
||||||
|
|
||||||
'@solid-primitives/utils@6.3.2':
|
|
||||||
resolution: {integrity: sha512-hZ/M/qr25QOCcwDPOHtGjxTD8w2mNyVAYvcfgwzBHq2RwNqHNdDNsMZYap20+ruRwW4A3Cdkczyoz0TSxLCAPQ==}
|
|
||||||
peerDependencies:
|
|
||||||
solid-js: ^1.6.12
|
|
||||||
|
|
||||||
'@standard-schema/spec@1.0.0':
|
'@standard-schema/spec@1.0.0':
|
||||||
resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
|
resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
|
||||||
|
|
||||||
@@ -1819,11 +1740,6 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
tailwindcss: '>=3.2.0'
|
tailwindcss: '>=3.2.0'
|
||||||
|
|
||||||
'@tailwindcss/typography@0.5.16':
|
|
||||||
resolution: {integrity: sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==}
|
|
||||||
peerDependencies:
|
|
||||||
tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1'
|
|
||||||
|
|
||||||
'@tanstack/db-ivm@0.1.13':
|
'@tanstack/db-ivm@0.1.13':
|
||||||
resolution: {integrity: sha512-sBOWGY4tqMEym2ewjdWrDb5c5c8akvgnEbGVPAtkfFS3QVV0zfVb5RJAkAc8GSxb3ByVfYjyaShVr0kMJhMuow==}
|
resolution: {integrity: sha512-sBOWGY4tqMEym2ewjdWrDb5c5c8akvgnEbGVPAtkfFS3QVV0zfVb5RJAkAc8GSxb3ByVfYjyaShVr0kMJhMuow==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -1834,41 +1750,16 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.7'
|
typescript: '>=4.7'
|
||||||
|
|
||||||
'@tanstack/devtools-client@0.0.4':
|
|
||||||
resolution: {integrity: sha512-LefnH9KE9uRDEWifc3QDcooskA8ikfs41bybDTgpYQpyTUspZnaEdUdya9Hry0KYxZ8nos0S3nNbsP79KHqr6Q==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
|
|
||||||
'@tanstack/devtools-event-bus@0.3.3':
|
|
||||||
resolution: {integrity: sha512-lWl88uLAz7ZhwNdLH6A3tBOSEuBCrvnY9Fzr5JPdzJRFdM5ZFdyNWz1Bf5l/F3GU57VodrN0KCFi9OA26H5Kpg==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
|
|
||||||
'@tanstack/devtools-event-client@0.3.4':
|
'@tanstack/devtools-event-client@0.3.4':
|
||||||
resolution: {integrity: sha512-eq+PpuutUyubXu+ycC1GIiVwBs86NF/8yYJJAKSpPcJLWl6R/761F1H4F/9ziX6zKezltFUH1ah3Cz8Ah+KJrw==}
|
resolution: {integrity: sha512-eq+PpuutUyubXu+ycC1GIiVwBs86NF/8yYJJAKSpPcJLWl6R/761F1H4F/9ziX6zKezltFUH1ah3Cz8Ah+KJrw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
'@tanstack/devtools-ui@0.4.4':
|
|
||||||
resolution: {integrity: sha512-5xHXFyX3nom0UaNfiOM92o6ziaHjGo3mcSGe2HD5Xs8dWRZNpdZ0Smd0B9ddEhy0oB+gXyMzZgUJb9DmrZV0Mg==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
peerDependencies:
|
|
||||||
solid-js: '>=1.9.7'
|
|
||||||
|
|
||||||
'@tanstack/devtools@0.8.0':
|
|
||||||
resolution: {integrity: sha512-j6tBkMpAyTkiGH4ELiHzFSpV0f9fCYtAMEqTEiXEOVVfB57C36KR8LyIHtdeGzK6eQ5sKEdgLbHG9EU31L3Jng==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
peerDependencies:
|
|
||||||
solid-js: '>=1.9.7'
|
|
||||||
|
|
||||||
'@tanstack/electric-db-collection@0.2.6':
|
'@tanstack/electric-db-collection@0.2.6':
|
||||||
resolution: {integrity: sha512-3J5mLxQ+PWwAxwsJy3Paygfd8dwUcs/oy1RxWjkIowRkYc1JA9x2/KSzX7ovzmYWbD87juHeLb73leuaWmqhow==}
|
resolution: {integrity: sha512-3J5mLxQ+PWwAxwsJy3Paygfd8dwUcs/oy1RxWjkIowRkYc1JA9x2/KSzX7ovzmYWbD87juHeLb73leuaWmqhow==}
|
||||||
|
|
||||||
'@tanstack/form-core@1.24.4':
|
'@tanstack/form-core@1.24.4':
|
||||||
resolution: {integrity: sha512-+eIR7DiDamit1zvTVgaHxuIRA02YFgJaXMUGxsLRJoBpUjGl/g/nhUocQoNkRyfXqOlh8OCMTanjwDprWSRq6w==}
|
resolution: {integrity: sha512-+eIR7DiDamit1zvTVgaHxuIRA02YFgJaXMUGxsLRJoBpUjGl/g/nhUocQoNkRyfXqOlh8OCMTanjwDprWSRq6w==}
|
||||||
|
|
||||||
'@tanstack/form-devtools@0.1.8':
|
|
||||||
resolution: {integrity: sha512-r34PPx1f5QlkWMqFh8Vyw6ats+ValLrTJMhFTx66m1i0YZJ1D5vZ/1ZF62JWMUxsep0yJqDbXznr1629Qmrt8w==}
|
|
||||||
peerDependencies:
|
|
||||||
solid-js: '>=1.9.9'
|
|
||||||
|
|
||||||
'@tanstack/pacer-lite@0.1.0':
|
'@tanstack/pacer-lite@0.1.0':
|
||||||
resolution: {integrity: sha512-a5A0PI0H4npUy7u3VOjOhdynXnRBna+mDvpt8ghDCVzS3Tgn8DlGzHlRqS2rKJP8ZcLuVO2qxlIIblhcoaiv8Q==}
|
resolution: {integrity: sha512-a5A0PI0H4npUy7u3VOjOhdynXnRBna+mDvpt8ghDCVzS3Tgn8DlGzHlRqS2rKJP8ZcLuVO2qxlIIblhcoaiv8Q==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -1885,20 +1776,6 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: '>=16.8.0'
|
react: '>=16.8.0'
|
||||||
|
|
||||||
'@tanstack/react-devtools@0.8.0':
|
|
||||||
resolution: {integrity: sha512-0TsFICBPr68us3iWHFXCIBSEilTo8j1OdIJLW48LNQNjC/Puno82uqX4qFuaZWfZv6K37QnS6UeRxzWJItMFSA==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
peerDependencies:
|
|
||||||
'@types/react': '>=16.8'
|
|
||||||
'@types/react-dom': '>=16.8'
|
|
||||||
react: '>=16.8'
|
|
||||||
react-dom: '>=16.8'
|
|
||||||
|
|
||||||
'@tanstack/react-form-devtools@0.1.8':
|
|
||||||
resolution: {integrity: sha512-FwXYLzLIGpqhHcg3sv81ioBBP+3+d2DPS8F+srXBZHuaJAHh6yhwDPAjhe5FlCK8X8+RlVtEbbD+4JXyWao8EQ==}
|
|
||||||
peerDependencies:
|
|
||||||
react: ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
||||||
|
|
||||||
'@tanstack/react-form@1.23.8':
|
'@tanstack/react-form@1.23.8':
|
||||||
resolution: {integrity: sha512-ivfkiOHAI3aIWkCY4FnPWVAL6SkQWGWNVjtwIZpaoJE4ulukZWZ1KB8TQKs8f4STl+egjTsMHrWJuf2fv3Xh1w==}
|
resolution: {integrity: sha512-ivfkiOHAI3aIWkCY4FnPWVAL6SkQWGWNVjtwIZpaoJE4ulukZWZ1KB8TQKs8f4STl+egjTsMHrWJuf2fv3Xh1w==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -1960,9 +1837,6 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@types/react': ^18.0.0
|
'@types/react': ^18.0.0
|
||||||
|
|
||||||
'@types/react-window@1.8.8':
|
|
||||||
resolution: {integrity: sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==}
|
|
||||||
|
|
||||||
'@types/react@18.3.23':
|
'@types/react@18.3.23':
|
||||||
resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==}
|
resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==}
|
||||||
|
|
||||||
@@ -2275,9 +2149,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==}
|
resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==}
|
||||||
engines: {node: '>=0.11'}
|
engines: {node: '>=0.11'}
|
||||||
|
|
||||||
dayjs@1.11.19:
|
|
||||||
resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==}
|
|
||||||
|
|
||||||
debug@4.4.1:
|
debug@4.4.1:
|
||||||
resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
|
resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
|
||||||
engines: {node: '>=6.0'}
|
engines: {node: '>=6.0'}
|
||||||
@@ -2616,11 +2487,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
|
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
goober@2.1.18:
|
|
||||||
resolution: {integrity: sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==}
|
|
||||||
peerDependencies:
|
|
||||||
csstype: ^3.0.10
|
|
||||||
|
|
||||||
graphemer@1.4.0:
|
graphemer@1.4.0:
|
||||||
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
|
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
|
||||||
|
|
||||||
@@ -2789,12 +2655,6 @@ packages:
|
|||||||
lodash-es@4.17.21:
|
lodash-es@4.17.21:
|
||||||
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
|
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
|
||||||
|
|
||||||
lodash.castarray@4.4.0:
|
|
||||||
resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
|
|
||||||
|
|
||||||
lodash.isplainobject@4.0.6:
|
|
||||||
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
|
|
||||||
|
|
||||||
lodash.merge@4.6.2:
|
lodash.merge@4.6.2:
|
||||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||||
|
|
||||||
@@ -2837,9 +2697,6 @@ packages:
|
|||||||
react:
|
react:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
memoize-one@5.2.1:
|
|
||||||
resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==}
|
|
||||||
|
|
||||||
merge2@1.4.1:
|
merge2@1.4.1:
|
||||||
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@@ -3016,10 +2873,6 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.2.14
|
postcss: ^8.2.14
|
||||||
|
|
||||||
postcss-selector-parser@6.0.10:
|
|
||||||
resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
|
|
||||||
engines: {node: '>=4'}
|
|
||||||
|
|
||||||
postcss-selector-parser@6.1.2:
|
postcss-selector-parser@6.1.2:
|
||||||
resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
|
resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@@ -3188,22 +3041,12 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
react-use-websocket@4.13.0:
|
|
||||||
resolution: {integrity: sha512-anMuVoV//g2N76Wxqvqjjo1X48r9Np3y1/gMl7arX84tAPXdy5R7sB5lO5hvCzQRYjqXwV8XMAiEBOUbyrZFrw==}
|
|
||||||
|
|
||||||
react-virtuoso@4.14.0:
|
react-virtuoso@4.14.0:
|
||||||
resolution: {integrity: sha512-fR+eiCvirSNIRvvCD7ueJPRsacGQvUbjkwgWzBZXVq+yWypoH7mRUvWJzGHIdoRaCZCT+6mMMMwIG2S1BW3uwA==}
|
resolution: {integrity: sha512-fR+eiCvirSNIRvvCD7ueJPRsacGQvUbjkwgWzBZXVq+yWypoH7mRUvWJzGHIdoRaCZCT+6mMMMwIG2S1BW3uwA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: '>=16 || >=17 || >= 18 || >= 19'
|
react: '>=16 || >=17 || >= 18 || >= 19'
|
||||||
react-dom: '>=16 || >=17 || >= 18 || >=19'
|
react-dom: '>=16 || >=17 || >= 18 || >=19'
|
||||||
|
|
||||||
react-window@1.8.11:
|
|
||||||
resolution: {integrity: sha512-+SRbUVT2scadgFSWx+R1P754xHPEqvcfSfVX10QYg6POOz+WNgkN48pS+BtZNIMGiL1HYrSEiCkwsMS15QogEQ==}
|
|
||||||
engines: {node: '>8.0.0'}
|
|
||||||
peerDependencies:
|
|
||||||
react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
||||||
react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
||||||
|
|
||||||
react@18.3.1:
|
react@18.3.1:
|
||||||
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
|
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -3276,16 +3119,6 @@ packages:
|
|||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
seroval-plugins@1.3.3:
|
|
||||||
resolution: {integrity: sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==}
|
|
||||||
engines: {node: '>=10'}
|
|
||||||
peerDependencies:
|
|
||||||
seroval: ^1.0
|
|
||||||
|
|
||||||
seroval@1.3.2:
|
|
||||||
resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==}
|
|
||||||
engines: {node: '>=10'}
|
|
||||||
|
|
||||||
set-cookie-parser@2.7.2:
|
set-cookie-parser@2.7.2:
|
||||||
resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==}
|
resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==}
|
||||||
|
|
||||||
@@ -3313,9 +3146,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
solid-js@1.9.10:
|
|
||||||
resolution: {integrity: sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew==}
|
|
||||||
|
|
||||||
sorted-btree@1.8.1:
|
sorted-btree@1.8.1:
|
||||||
resolution: {integrity: sha512-395+XIP+wqNn3USkFSrNz7G3Ss/MXlZEqesxvzCRFwL14h6e8LukDHdLBePn5pwbm5OQ9vGu8mDyz2lLDIqamQ==}
|
resolution: {integrity: sha512-395+XIP+wqNn3USkFSrNz7G3Ss/MXlZEqesxvzCRFwL14h6e8LukDHdLBePn5pwbm5OQ9vGu8mDyz2lLDIqamQ==}
|
||||||
|
|
||||||
@@ -3637,18 +3467,6 @@ packages:
|
|||||||
wrappy@1.0.2:
|
wrappy@1.0.2:
|
||||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||||
|
|
||||||
ws@8.18.3:
|
|
||||||
resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==}
|
|
||||||
engines: {node: '>=10.0.0'}
|
|
||||||
peerDependencies:
|
|
||||||
bufferutil: ^4.0.1
|
|
||||||
utf-8-validate: '>=5.0.2'
|
|
||||||
peerDependenciesMeta:
|
|
||||||
bufferutil:
|
|
||||||
optional: true
|
|
||||||
utf-8-validate:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
y18n@5.0.8:
|
y18n@5.0.8:
|
||||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -3677,9 +3495,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
zod@4.1.12:
|
|
||||||
resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==}
|
|
||||||
|
|
||||||
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'}
|
||||||
@@ -3887,13 +3702,6 @@ snapshots:
|
|||||||
react-dom: 18.3.1(react@18.3.1)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
'@dnd-kit/modifiers@9.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
|
|
||||||
dependencies:
|
|
||||||
'@dnd-kit/core': 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
|
||||||
'@dnd-kit/utilities': 3.2.2(react@18.3.1)
|
|
||||||
react: 18.3.1
|
|
||||||
tslib: 2.8.1
|
|
||||||
|
|
||||||
'@dnd-kit/utilities@3.2.2(react@18.3.1)':
|
'@dnd-kit/utilities@3.2.2(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
@@ -4869,22 +4677,6 @@ snapshots:
|
|||||||
'@types/react': 18.3.23
|
'@types/react': 18.3.23
|
||||||
'@types/react-dom': 18.3.7(@types/react@18.3.23)
|
'@types/react-dom': 18.3.7(@types/react@18.3.23)
|
||||||
|
|
||||||
'@radix-ui/react-tabs@1.1.12(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
|
||||||
dependencies:
|
|
||||||
'@radix-ui/primitive': 1.1.2
|
|
||||||
'@radix-ui/react-context': 1.1.2(@types/react@18.3.23)(react@18.3.1)
|
|
||||||
'@radix-ui/react-direction': 1.1.1(@types/react@18.3.23)(react@18.3.1)
|
|
||||||
'@radix-ui/react-id': 1.1.1(@types/react@18.3.23)(react@18.3.1)
|
|
||||||
'@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
|
||||||
'@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
|
||||||
'@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
|
||||||
'@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.23)(react@18.3.1)
|
|
||||||
react: 18.3.1
|
|
||||||
react-dom: 18.3.1(react@18.3.1)
|
|
||||||
optionalDependencies:
|
|
||||||
'@types/react': 18.3.23
|
|
||||||
'@types/react-dom': 18.3.7(@types/react@18.3.23)
|
|
||||||
|
|
||||||
'@radix-ui/react-toggle-group@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
'@radix-ui/react-toggle-group@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/primitive': 1.1.3
|
'@radix-ui/primitive': 1.1.3
|
||||||
@@ -5221,54 +5013,12 @@ snapshots:
|
|||||||
- encoding
|
- encoding
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@solid-primitives/event-listener@2.4.3(solid-js@1.9.10)':
|
|
||||||
dependencies:
|
|
||||||
'@solid-primitives/utils': 6.3.2(solid-js@1.9.10)
|
|
||||||
solid-js: 1.9.10
|
|
||||||
|
|
||||||
'@solid-primitives/keyboard@1.3.3(solid-js@1.9.10)':
|
|
||||||
dependencies:
|
|
||||||
'@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10)
|
|
||||||
'@solid-primitives/rootless': 1.5.2(solid-js@1.9.10)
|
|
||||||
'@solid-primitives/utils': 6.3.2(solid-js@1.9.10)
|
|
||||||
solid-js: 1.9.10
|
|
||||||
|
|
||||||
'@solid-primitives/resize-observer@2.1.3(solid-js@1.9.10)':
|
|
||||||
dependencies:
|
|
||||||
'@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10)
|
|
||||||
'@solid-primitives/rootless': 1.5.2(solid-js@1.9.10)
|
|
||||||
'@solid-primitives/static-store': 0.1.2(solid-js@1.9.10)
|
|
||||||
'@solid-primitives/utils': 6.3.2(solid-js@1.9.10)
|
|
||||||
solid-js: 1.9.10
|
|
||||||
|
|
||||||
'@solid-primitives/rootless@1.5.2(solid-js@1.9.10)':
|
|
||||||
dependencies:
|
|
||||||
'@solid-primitives/utils': 6.3.2(solid-js@1.9.10)
|
|
||||||
solid-js: 1.9.10
|
|
||||||
|
|
||||||
'@solid-primitives/static-store@0.1.2(solid-js@1.9.10)':
|
|
||||||
dependencies:
|
|
||||||
'@solid-primitives/utils': 6.3.2(solid-js@1.9.10)
|
|
||||||
solid-js: 1.9.10
|
|
||||||
|
|
||||||
'@solid-primitives/utils@6.3.2(solid-js@1.9.10)':
|
|
||||||
dependencies:
|
|
||||||
solid-js: 1.9.10
|
|
||||||
|
|
||||||
'@standard-schema/spec@1.0.0': {}
|
'@standard-schema/spec@1.0.0': {}
|
||||||
|
|
||||||
'@tailwindcss/container-queries@0.1.1(tailwindcss@3.4.17)':
|
'@tailwindcss/container-queries@0.1.1(tailwindcss@3.4.17)':
|
||||||
dependencies:
|
dependencies:
|
||||||
tailwindcss: 3.4.17
|
tailwindcss: 3.4.17
|
||||||
|
|
||||||
'@tailwindcss/typography@0.5.16(tailwindcss@3.4.17)':
|
|
||||||
dependencies:
|
|
||||||
lodash.castarray: 4.4.0
|
|
||||||
lodash.isplainobject: 4.0.6
|
|
||||||
lodash.merge: 4.6.2
|
|
||||||
postcss-selector-parser: 6.0.10
|
|
||||||
tailwindcss: 3.4.17
|
|
||||||
|
|
||||||
'@tanstack/db-ivm@0.1.13(typescript@5.9.2)':
|
'@tanstack/db-ivm@0.1.13(typescript@5.9.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
fractional-indexing: 3.2.0
|
fractional-indexing: 3.2.0
|
||||||
@@ -5282,43 +5032,8 @@ snapshots:
|
|||||||
'@tanstack/pacer-lite': 0.1.0
|
'@tanstack/pacer-lite': 0.1.0
|
||||||
typescript: 5.9.2
|
typescript: 5.9.2
|
||||||
|
|
||||||
'@tanstack/devtools-client@0.0.4':
|
|
||||||
dependencies:
|
|
||||||
'@tanstack/devtools-event-client': 0.3.4
|
|
||||||
|
|
||||||
'@tanstack/devtools-event-bus@0.3.3':
|
|
||||||
dependencies:
|
|
||||||
ws: 8.18.3
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- bufferutil
|
|
||||||
- utf-8-validate
|
|
||||||
|
|
||||||
'@tanstack/devtools-event-client@0.3.4': {}
|
'@tanstack/devtools-event-client@0.3.4': {}
|
||||||
|
|
||||||
'@tanstack/devtools-ui@0.4.4(csstype@3.1.3)(solid-js@1.9.10)':
|
|
||||||
dependencies:
|
|
||||||
clsx: 2.1.1
|
|
||||||
goober: 2.1.18(csstype@3.1.3)
|
|
||||||
solid-js: 1.9.10
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- csstype
|
|
||||||
|
|
||||||
'@tanstack/devtools@0.8.0(csstype@3.1.3)(solid-js@1.9.10)':
|
|
||||||
dependencies:
|
|
||||||
'@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10)
|
|
||||||
'@solid-primitives/keyboard': 1.3.3(solid-js@1.9.10)
|
|
||||||
'@solid-primitives/resize-observer': 2.1.3(solid-js@1.9.10)
|
|
||||||
'@tanstack/devtools-client': 0.0.4
|
|
||||||
'@tanstack/devtools-event-bus': 0.3.3
|
|
||||||
'@tanstack/devtools-ui': 0.4.4(csstype@3.1.3)(solid-js@1.9.10)
|
|
||||||
clsx: 2.1.1
|
|
||||||
goober: 2.1.18(csstype@3.1.3)
|
|
||||||
solid-js: 1.9.10
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- bufferutil
|
|
||||||
- csstype
|
|
||||||
- utf-8-validate
|
|
||||||
|
|
||||||
'@tanstack/electric-db-collection@0.2.6(typescript@5.9.2)':
|
'@tanstack/electric-db-collection@0.2.6(typescript@5.9.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@electric-sql/client': 1.2.0
|
'@electric-sql/client': 1.2.0
|
||||||
@@ -5336,17 +5051,6 @@ snapshots:
|
|||||||
'@tanstack/pacer': 0.15.4
|
'@tanstack/pacer': 0.15.4
|
||||||
'@tanstack/store': 0.7.7
|
'@tanstack/store': 0.7.7
|
||||||
|
|
||||||
'@tanstack/form-devtools@0.1.8(csstype@3.1.3)(solid-js@1.9.10)':
|
|
||||||
dependencies:
|
|
||||||
'@tanstack/devtools-ui': 0.4.4(csstype@3.1.3)(solid-js@1.9.10)
|
|
||||||
'@tanstack/form-core': 1.24.4
|
|
||||||
clsx: 2.1.1
|
|
||||||
dayjs: 1.11.19
|
|
||||||
goober: 2.1.18(csstype@3.1.3)
|
|
||||||
solid-js: 1.9.10
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- csstype
|
|
||||||
|
|
||||||
'@tanstack/pacer-lite@0.1.0': {}
|
'@tanstack/pacer-lite@0.1.0': {}
|
||||||
|
|
||||||
'@tanstack/pacer@0.15.4':
|
'@tanstack/pacer@0.15.4':
|
||||||
@@ -5364,27 +5068,6 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- typescript
|
- typescript
|
||||||
|
|
||||||
'@tanstack/react-devtools@0.8.0(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(solid-js@1.9.10)':
|
|
||||||
dependencies:
|
|
||||||
'@tanstack/devtools': 0.8.0(csstype@3.1.3)(solid-js@1.9.10)
|
|
||||||
'@types/react': 18.3.23
|
|
||||||
'@types/react-dom': 18.3.7(@types/react@18.3.23)
|
|
||||||
react: 18.3.1
|
|
||||||
react-dom: 18.3.1(react@18.3.1)
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- bufferutil
|
|
||||||
- csstype
|
|
||||||
- solid-js
|
|
||||||
- utf-8-validate
|
|
||||||
|
|
||||||
'@tanstack/react-form-devtools@0.1.8(csstype@3.1.3)(react@18.3.1)(solid-js@1.9.10)':
|
|
||||||
dependencies:
|
|
||||||
'@tanstack/form-devtools': 0.1.8(csstype@3.1.3)(solid-js@1.9.10)
|
|
||||||
react: 18.3.1
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- csstype
|
|
||||||
- solid-js
|
|
||||||
|
|
||||||
'@tanstack/react-form@1.23.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
'@tanstack/react-form@1.23.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tanstack/form-core': 1.24.4
|
'@tanstack/form-core': 1.24.4
|
||||||
@@ -5453,10 +5136,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/react': 18.3.23
|
'@types/react': 18.3.23
|
||||||
|
|
||||||
'@types/react-window@1.8.8':
|
|
||||||
dependencies:
|
|
||||||
'@types/react': 18.3.23
|
|
||||||
|
|
||||||
'@types/react@18.3.23':
|
'@types/react@18.3.23':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/prop-types': 15.7.15
|
'@types/prop-types': 15.7.15
|
||||||
@@ -5827,8 +5506,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.27.6
|
'@babel/runtime': 7.27.6
|
||||||
|
|
||||||
dayjs@1.11.19: {}
|
|
||||||
|
|
||||||
debug@4.4.1:
|
debug@4.4.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
@@ -6197,10 +5874,6 @@ snapshots:
|
|||||||
merge2: 1.4.1
|
merge2: 1.4.1
|
||||||
slash: 3.0.0
|
slash: 3.0.0
|
||||||
|
|
||||||
goober@2.1.18(csstype@3.1.3):
|
|
||||||
dependencies:
|
|
||||||
csstype: 3.1.3
|
|
||||||
|
|
||||||
graphemer@1.4.0: {}
|
graphemer@1.4.0: {}
|
||||||
|
|
||||||
has-flag@4.0.0: {}
|
has-flag@4.0.0: {}
|
||||||
@@ -6341,10 +6014,6 @@ snapshots:
|
|||||||
|
|
||||||
lodash-es@4.17.21: {}
|
lodash-es@4.17.21: {}
|
||||||
|
|
||||||
lodash.castarray@4.4.0: {}
|
|
||||||
|
|
||||||
lodash.isplainobject@4.0.6: {}
|
|
||||||
|
|
||||||
lodash.merge@4.6.2: {}
|
lodash.merge@4.6.2: {}
|
||||||
|
|
||||||
lodash@4.17.21: {}
|
lodash@4.17.21: {}
|
||||||
@@ -6381,8 +6050,6 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
|
|
||||||
memoize-one@5.2.1: {}
|
|
||||||
|
|
||||||
merge2@1.4.1: {}
|
merge2@1.4.1: {}
|
||||||
|
|
||||||
micromatch@4.0.8:
|
micromatch@4.0.8:
|
||||||
@@ -6520,11 +6187,6 @@ snapshots:
|
|||||||
postcss: 8.5.6
|
postcss: 8.5.6
|
||||||
postcss-selector-parser: 6.1.2
|
postcss-selector-parser: 6.1.2
|
||||||
|
|
||||||
postcss-selector-parser@6.0.10:
|
|
||||||
dependencies:
|
|
||||||
cssesc: 3.0.0
|
|
||||||
util-deprecate: 1.0.2
|
|
||||||
|
|
||||||
postcss-selector-parser@6.1.2:
|
postcss-selector-parser@6.1.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
cssesc: 3.0.0
|
cssesc: 3.0.0
|
||||||
@@ -6671,20 +6333,11 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 18.3.23
|
'@types/react': 18.3.23
|
||||||
|
|
||||||
react-use-websocket@4.13.0: {}
|
|
||||||
|
|
||||||
react-virtuoso@4.14.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
react-virtuoso@4.14.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
react-dom: 18.3.1(react@18.3.1)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
|
||||||
react-window@1.8.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
|
||||||
dependencies:
|
|
||||||
'@babel/runtime': 7.27.6
|
|
||||||
memoize-one: 5.2.1
|
|
||||||
react: 18.3.1
|
|
||||||
react-dom: 18.3.1(react@18.3.1)
|
|
||||||
|
|
||||||
react@18.3.1:
|
react@18.3.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
loose-envify: 1.4.0
|
loose-envify: 1.4.0
|
||||||
@@ -6768,12 +6421,6 @@ snapshots:
|
|||||||
|
|
||||||
semver@7.7.2: {}
|
semver@7.7.2: {}
|
||||||
|
|
||||||
seroval-plugins@1.3.3(seroval@1.3.2):
|
|
||||||
dependencies:
|
|
||||||
seroval: 1.3.2
|
|
||||||
|
|
||||||
seroval@1.3.2: {}
|
|
||||||
|
|
||||||
set-cookie-parser@2.7.2: {}
|
set-cookie-parser@2.7.2: {}
|
||||||
|
|
||||||
shebang-command@2.0.0:
|
shebang-command@2.0.0:
|
||||||
@@ -6790,12 +6437,6 @@ snapshots:
|
|||||||
|
|
||||||
slash@3.0.0: {}
|
slash@3.0.0: {}
|
||||||
|
|
||||||
solid-js@1.9.10:
|
|
||||||
dependencies:
|
|
||||||
csstype: 3.1.3
|
|
||||||
seroval: 1.3.2
|
|
||||||
seroval-plugins: 1.3.3(seroval@1.3.2)
|
|
||||||
|
|
||||||
sorted-btree@1.8.1: {}
|
sorted-btree@1.8.1: {}
|
||||||
|
|
||||||
source-map-js@1.2.1: {}
|
source-map-js@1.2.1: {}
|
||||||
@@ -7066,8 +6707,6 @@ snapshots:
|
|||||||
|
|
||||||
wrappy@1.0.2: {}
|
wrappy@1.0.2: {}
|
||||||
|
|
||||||
ws@8.18.3: {}
|
|
||||||
|
|
||||||
y18n@5.0.8: {}
|
y18n@5.0.8: {}
|
||||||
|
|
||||||
yallist@3.1.1: {}
|
yallist@3.1.1: {}
|
||||||
@@ -7092,8 +6731,6 @@ snapshots:
|
|||||||
|
|
||||||
yocto-queue@0.1.0: {}
|
yocto-queue@0.1.0: {}
|
||||||
|
|
||||||
zod@4.1.12: {}
|
|
||||||
|
|
||||||
zustand@4.5.7(@types/react@18.3.23)(react@18.3.1):
|
zustand@4.5.7(@types/react@18.3.23)(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)
|
||||||
|
|||||||
Reference in New Issue
Block a user