mirror of
https://github.com/aljazceru/claude-code-viewer.git
synced 2025-12-26 17:54:23 +01:00
feat: fix out of style
This commit is contained in:
@@ -84,7 +84,10 @@ export const MarkdownContent: FC<MarkdownContentProps> = ({
|
||||
},
|
||||
p({ children, ...props }) {
|
||||
return (
|
||||
<p className="mb-4 leading-7 text-foreground" {...props}>
|
||||
<p
|
||||
className="mb-4 leading-7 text-foreground break-all"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
@@ -117,7 +120,7 @@ export const MarkdownContent: FC<MarkdownContentProps> = ({
|
||||
if (isInline) {
|
||||
return (
|
||||
<code
|
||||
className="bg-muted/70 px-2 py-1 rounded-md text-sm font-mono text-foreground border"
|
||||
className="bg-muted/70 px-2 py-1 rounded-md text-sm font-mono text-foreground border break-all"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
@@ -175,8 +178,8 @@ export const MarkdownContent: FC<MarkdownContentProps> = ({
|
||||
// テーブルの改善
|
||||
table({ children, ...props }) {
|
||||
return (
|
||||
<div className="overflow-x-auto my-6 rounded-lg border border-border">
|
||||
<table className="min-w-full border-collapse" {...props}>
|
||||
<div className="overflow-x-auto my-6 rounded-lg border border-border max-w-full">
|
||||
<table className="w-full border-collapse" {...props}>
|
||||
{children}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@ export const useNewChatMutation = (
|
||||
},
|
||||
{
|
||||
init: {
|
||||
signal: AbortSignal.timeout(10 * 1000),
|
||||
signal: AbortSignal.timeout(20 * 1000),
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -53,7 +53,7 @@ export const useResumeChatMutation = (projectId: string, sessionId: string) => {
|
||||
},
|
||||
{
|
||||
init: {
|
||||
signal: AbortSignal.timeout(10 * 1000),
|
||||
signal: AbortSignal.timeout(20 * 1000),
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -19,7 +19,7 @@ export const NewChat: FC<{
|
||||
error={startNewChat.error}
|
||||
placeholder="Type your message here... (Start with / for commands, @ for files, Shift+Enter to send)"
|
||||
buttonText="Start Chat"
|
||||
minHeight="min-h-[100px]"
|
||||
minHeight="min-h-[200px]"
|
||||
containerClassName="space-y-4"
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,6 @@ import { Button } from "../../../../../components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
@@ -31,15 +30,12 @@ export const NewChatModal: FC<{
|
||||
</Button>
|
||||
)}
|
||||
</DialogTrigger>
|
||||
<DialogContent className="sm:max-w-[500px]">
|
||||
<DialogContent className="w-[95vw] md:w-[80vw]">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="flex items-center gap-2">
|
||||
<MessageSquareIcon className="w-5 h-5" />
|
||||
Start New Chat
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
Start a new conversation with Claude Code for this project
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<NewChat projectId={projectId} onSuccess={handleSuccess} />
|
||||
</DialogContent>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import {
|
||||
ArrowLeftIcon,
|
||||
ExternalLinkIcon,
|
||||
LoaderIcon,
|
||||
MenuIcon,
|
||||
PauseIcon,
|
||||
@@ -12,6 +12,7 @@ import Link from "next/link";
|
||||
import type { FC } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "../../../../../../components/ui/badge";
|
||||
import { honoClient } from "../../../../../../lib/api/client";
|
||||
import { useProject } from "../../../hooks/useProject";
|
||||
import { firstCommandToTitle } from "../../../services/firstCommandToTitle";
|
||||
@@ -70,7 +71,7 @@ export const SessionPageContent: FC<{
|
||||
}, [conversations, isRunningTask, isPausedTask, previousConversationLength]);
|
||||
|
||||
return (
|
||||
<div className="flex h-screen max-h-screen">
|
||||
<div className="flex h-screen max-h-screen overflow-hidden">
|
||||
<SessionSidebar
|
||||
currentSessionId={sessionId}
|
||||
projectId={projectId}
|
||||
@@ -78,57 +79,55 @@ export const SessionPageContent: FC<{
|
||||
onMobileOpenChange={setIsMobileSidebarOpen}
|
||||
/>
|
||||
|
||||
<div className="flex-1 flex flex-col min-h-0">
|
||||
<header className="px-2 sm:px-3 py-3 sticky top-0 z-10 bg-background w-full flex-shrink-0">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="md:hidden"
|
||||
onClick={() => setIsMobileSidebarOpen(true)}
|
||||
>
|
||||
<MenuIcon className="w-4 h-4" />
|
||||
</Button>
|
||||
|
||||
<Button asChild variant="ghost">
|
||||
<Link
|
||||
href={`/projects/${projectId}`}
|
||||
className="flex items-center gap-2"
|
||||
<div className="flex-1 flex flex-col min-h-0 min-w-0">
|
||||
<header className="px-2 sm:px-3 py-2 sm:py-3 sticky top-0 z-10 bg-background w-full flex-shrink-0 min-w-0">
|
||||
<div className="space-y-2 sm:space-y-3">
|
||||
<div className="flex items-center gap-2 sm:gap-3">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="md:hidden flex-shrink-0"
|
||||
onClick={() => setIsMobileSidebarOpen(true)}
|
||||
>
|
||||
<ArrowLeftIcon className="w-4 h-4" />
|
||||
<span className="hidden sm:inline">Back to Session List</span>
|
||||
<span className="sm:hidden">Back</span>
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center gap-3">
|
||||
<h1 className="text-xl sm:text-2xl md:text-3xl font-bold break-all overflow-ellipsis line-clamp-1 px-2 sm:px-5">
|
||||
<MenuIcon className="w-4 h-4" />
|
||||
</Button>
|
||||
<h1 className="text-lg sm:text-2xl md:text-3xl font-bold break-all overflow-ellipsis line-clamp-1 px-1 sm:px-5 min-w-0">
|
||||
{session.meta.firstCommand !== null
|
||||
? firstCommandToTitle(session.meta.firstCommand)
|
||||
: sessionId}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className="px-2 sm:px-5 space-y-1">
|
||||
<div className="px-1 sm:px-5 flex flex-wrap items-center gap-1 sm:gap-2">
|
||||
{project?.project.claudeProjectPath && (
|
||||
<p className="text-sm text-muted-foreground font-mono break-all">
|
||||
Project:{" "}
|
||||
{project.project.meta.projectPath ??
|
||||
project.project.claudeProjectPath}
|
||||
</p>
|
||||
<Link
|
||||
href={`/projects/${projectId}`}
|
||||
target="_blank"
|
||||
className="transition-all duration-200"
|
||||
>
|
||||
<Badge
|
||||
variant="secondary"
|
||||
className="h-6 sm:h-8 text-xs sm:text-sm flex items-center hover:bg-blue-50/60 hover:border-blue-300/60 hover:shadow-sm transition-all duration-200 cursor-pointer"
|
||||
>
|
||||
<ExternalLinkIcon className="w-3 h-3 sm:w-4 sm:h-4 mr-1" />
|
||||
{project.project.meta.projectPath ??
|
||||
project.project.claudeProjectPath}
|
||||
</Badge>
|
||||
</Link>
|
||||
)}
|
||||
<p className="text-sm text-muted-foreground font-mono">
|
||||
Session ID: {sessionId}
|
||||
</p>
|
||||
<Badge
|
||||
variant="secondary"
|
||||
className="h-6 sm:h-8 text-xs sm:text-sm flex items-center"
|
||||
>
|
||||
{sessionId}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
{isRunningTask && (
|
||||
<div className="flex items-center gap-2 p-3 bg-primary/10 border border-primary/20 rounded-lg">
|
||||
<LoaderIcon className="w-4 h-4 animate-spin" />
|
||||
<div className="flex items-center gap-1 sm:gap-2 p-1 bg-primary/10 border border-primary/20 rounded-lg mx-1 sm:mx-5">
|
||||
<LoaderIcon className="w-3 h-3 sm:w-4 sm:h-4 animate-spin" />
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-medium">
|
||||
<p className="text-xs sm:text-sm font-medium">
|
||||
Conversation is in progress...
|
||||
</p>
|
||||
</div>
|
||||
@@ -139,17 +138,17 @@ export const SessionPageContent: FC<{
|
||||
abortTask.mutate(sessionId);
|
||||
}}
|
||||
>
|
||||
<XIcon className="w-4 h-4" />
|
||||
Abort
|
||||
<XIcon className="w-3 h-3 sm:w-4 sm:h-4" />
|
||||
<span className="hidden sm:inline">Abort</span>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isPausedTask && (
|
||||
<div className="flex items-center gap-2 p-3 bg-primary/10 border border-primary/20 rounded-lg">
|
||||
<PauseIcon className="w-4 h-4" />
|
||||
<div className="flex items-center gap-1 sm:gap-2 p-1 bg-primary/10 border border-primary/20 rounded-lg mx-1 sm:mx-5">
|
||||
<PauseIcon className="w-3 h-3 sm:w-4 sm:h-4" />
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-medium">
|
||||
<p className="text-xs sm:text-sm font-medium">
|
||||
Conversation is paused...
|
||||
</p>
|
||||
</div>
|
||||
@@ -160,8 +159,8 @@ export const SessionPageContent: FC<{
|
||||
abortTask.mutate(sessionId);
|
||||
}}
|
||||
>
|
||||
<XIcon className="w-4 h-4" />
|
||||
Abort
|
||||
<XIcon className="w-3 h-3 sm:w-4 sm:h-4" />
|
||||
<span className="hidden sm:inline">Abort</span>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
@@ -170,9 +169,9 @@ export const SessionPageContent: FC<{
|
||||
|
||||
<div
|
||||
ref={scrollContainerRef}
|
||||
className="flex-1 overflow-y-auto min-h-0"
|
||||
className="flex-1 overflow-y-auto min-h-0 min-w-0"
|
||||
>
|
||||
<main className="w-full px-4 sm:px-8 md:px-12 lg:px-16 xl:px-20 pb-20 sm:pb-10 relative z-5">
|
||||
<main className="w-full px-4 sm:px-6 md:px-8 lg:px-12 xl:px-16 relative z-5 min-w-0">
|
||||
<ConversationList
|
||||
conversations={conversations}
|
||||
getToolResult={getToolResult}
|
||||
|
||||
@@ -37,7 +37,7 @@ const getConversationKey = (conversation: Conversation) => {
|
||||
const SchemaErrorDisplay: FC<{ errorLine: string }> = ({ errorLine }) => {
|
||||
return (
|
||||
<li className="w-full flex justify-start">
|
||||
<div className="w-full max-w-4xl sm:w-[90%] md:w-[85%] px-2">
|
||||
<div className="w-full max-w-3xl lg:max-w-4xl sm:w-[90%] md:w-[85%] px-2">
|
||||
<Collapsible>
|
||||
<CollapsibleTrigger asChild>
|
||||
<div className="flex items-center justify-between cursor-pointer hover:bg-muted/50 rounded p-2 -mx-2 border-l-2 border-red-400">
|
||||
@@ -146,7 +146,9 @@ export const ConversationList: FC<ConversationListProps> = ({
|
||||
}`}
|
||||
key={getConversationKey(conversation)}
|
||||
>
|
||||
<div className="w-full max-w-4xl sm:w-[90%] md:w-[85%]">{elm}</div>
|
||||
<div className="w-full max-w-3xl lg:max-w-4xl sm:w-[90%] md:w-[85%]">
|
||||
{elm}
|
||||
</div>
|
||||
</li>,
|
||||
];
|
||||
})}
|
||||
|
||||
@@ -12,7 +12,7 @@ export const MetaConversationContent: FC<PropsWithChildren> = ({
|
||||
return (
|
||||
<Collapsible>
|
||||
<CollapsibleTrigger asChild>
|
||||
<div className="flex items-center justify-between cursor-pointer hover:bg-muted/50 rounded p-2 -mx-2">
|
||||
<div className="flex items-center justify-between cursor-pointer hover:bg-muted/50 rounded p-2 -mx-2 mb-2">
|
||||
<h4 className="text-xs font-medium text-muted-foreground">
|
||||
Meta Information
|
||||
</h4>
|
||||
|
||||
@@ -12,7 +12,7 @@ export const SummaryConversationContent: FC<PropsWithChildren> = ({
|
||||
return (
|
||||
<Collapsible>
|
||||
<CollapsibleTrigger asChild>
|
||||
<div className="flex items-center justify-between cursor-pointer hover:bg-muted/50 rounded p-2 -mx-2">
|
||||
<div className="flex items-center justify-between cursor-pointer hover:bg-muted/50 rounded p-2 -mx-2 mb-2">
|
||||
<h4 className="text-xs font-medium text-muted-foreground">
|
||||
Summarized
|
||||
</h4>
|
||||
|
||||
@@ -42,7 +42,7 @@ export const UserTextContent: FC<{ text: string; id?: string }> = ({
|
||||
Arguments:
|
||||
</span>
|
||||
<div className="bg-background rounded border p-2 mt-1">
|
||||
<code className="text-xs whitespace-pre-line">
|
||||
<code className="text-xs whitespace-pre-line break-all">
|
||||
{parsed.commandArgs}
|
||||
</code>
|
||||
</div>
|
||||
@@ -54,7 +54,7 @@ export const UserTextContent: FC<{ text: string; id?: string }> = ({
|
||||
Message:
|
||||
</span>
|
||||
<div className="bg-background rounded border p-2 mt-1">
|
||||
<code className="text-xs whitespace-pre-line">
|
||||
<code className="text-xs whitespace-pre-line break-all">
|
||||
{parsed.commandMessage}
|
||||
</code>
|
||||
</div>
|
||||
|
||||
@@ -76,7 +76,7 @@ export const SidechainConversationModal: FC<
|
||||
</div>
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="!w-[1200px] !max-w-none max-h-[80vh] overflow-hidden flex flex-col">
|
||||
<DialogContent className="w-[95vw] md:w-[90vw] max-h-[80vh] overflow-hidden flex flex-col px-2 md:px-8">
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
{title.length > 100 ? `${title.slice(0, 100)}...` : title}
|
||||
|
||||
@@ -32,7 +32,7 @@ export const ResumeChat: FC<{
|
||||
error={resumeChat.error}
|
||||
placeholder="Type your message... (Start with / for commands, Shift+Enter to send)"
|
||||
buttonText={getButtonText()}
|
||||
minHeight="min-h-[60px]"
|
||||
minHeight="min-h-[100px]"
|
||||
containerClassName="space-y-2"
|
||||
buttonSize="default"
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { MessageSquareIcon, PlugIcon, SettingsIcon } from "lucide-react";
|
||||
import {
|
||||
MessageSquareIcon,
|
||||
PlugIcon,
|
||||
SettingsIcon,
|
||||
Undo2Icon,
|
||||
} from "lucide-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { type FC, useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useProject } from "../../../../hooks/useProject";
|
||||
@@ -22,6 +28,7 @@ export const SessionSidebar: FC<{
|
||||
isMobileOpen = false,
|
||||
onMobileOpenChange,
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
const {
|
||||
data: { sessions },
|
||||
} = useProject(projectId);
|
||||
@@ -70,6 +77,21 @@ export const SessionSidebar: FC<{
|
||||
{/* Vertical Icon Menu - Always Visible */}
|
||||
<div className="w-12 flex flex-col border-r border-sidebar-border bg-sidebar/50">
|
||||
<div className="flex flex-col p-2 space-y-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
router.push(`/projects/${projectId}`);
|
||||
}}
|
||||
className={cn(
|
||||
"w-8 h-8 flex items-center justify-center rounded-md transition-colors",
|
||||
"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
||||
"text-sidebar-foreground/70",
|
||||
)}
|
||||
title="Back to Project"
|
||||
>
|
||||
<Undo2Icon className="w-4 h-4" />
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleTabClick("sessions")}
|
||||
|
||||
@@ -60,7 +60,7 @@ function DialogContent({
|
||||
<DialogPrimitive.Content
|
||||
data-slot="dialog-content"
|
||||
className={cn(
|
||||
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
|
||||
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
Reference in New Issue
Block a user