Support rename/delete edge function & standardize output
This commit is contained in:
@@ -330,12 +330,20 @@ function ChatInputActions({
|
||||
}: ChatInputActionsProps) {
|
||||
const [autoApprove, setAutoApprove] = useState(false);
|
||||
const [isDetailsVisible, setIsDetailsVisible] = useState(false);
|
||||
|
||||
if (proposal.type === "tip-proposal") {
|
||||
return <div>Tip proposal</div>;
|
||||
}
|
||||
if (proposal.type === "action-proposal") {
|
||||
return <ActionProposalActions proposal={proposal}></ActionProposalActions>;
|
||||
}
|
||||
|
||||
// Split files into server functions and other files - only for CodeProposal
|
||||
const serverFunctions =
|
||||
proposal.filesChanged?.filter((f: FileChange) => f.isServerFunction) ?? [];
|
||||
const otherFilesChanged =
|
||||
proposal.filesChanged?.filter((f: FileChange) => !f.isServerFunction) ?? [];
|
||||
|
||||
return (
|
||||
<div className="border-b border-border">
|
||||
<div className="p-2">
|
||||
@@ -462,11 +470,30 @@ function ChatInputActions({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{proposal.filesChanged?.length > 0 && (
|
||||
{serverFunctions.length > 0 && (
|
||||
<div className="mb-3">
|
||||
<h4 className="font-semibold mb-1">Server Functions Changed</h4>
|
||||
<ul className="space-y-1">
|
||||
{serverFunctions.map((file: FileChange, index: number) => (
|
||||
<li key={index} className="flex items-center space-x-2">
|
||||
{getIconForFileChange(file)}
|
||||
<span title={file.path} className="truncate cursor-default">
|
||||
{file.name}
|
||||
</span>
|
||||
<span className="text-muted-foreground text-xs truncate">
|
||||
- {file.summary}
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{otherFilesChanged.length > 0 && (
|
||||
<div>
|
||||
<h4 className="font-semibold mb-1">Files Changed</h4>
|
||||
<ul className="space-y-1">
|
||||
{proposal.filesChanged.map((file, index) => (
|
||||
{otherFilesChanged.map((file: FileChange, index: number) => (
|
||||
<li key={index} className="flex items-center space-x-2">
|
||||
{getIconForFileChange(file)}
|
||||
<span title={file.path} className="truncate cursor-default">
|
||||
|
||||
@@ -11,6 +11,7 @@ import { CodeHighlight } from "./CodeHighlight";
|
||||
import { useAtomValue } from "jotai";
|
||||
import { isStreamingAtom } from "@/atoms/chatAtoms";
|
||||
import { CustomTagState } from "./stateTypes";
|
||||
import { DyadOutput } from "./DyadOutput";
|
||||
|
||||
interface DyadMarkdownParserProps {
|
||||
content: string;
|
||||
@@ -77,6 +78,7 @@ function preprocessUnclosedTags(content: string): {
|
||||
"dyad-add-dependency",
|
||||
"dyad-execute-sql",
|
||||
"dyad-add-integration",
|
||||
"dyad-output",
|
||||
];
|
||||
|
||||
let processedContent = content;
|
||||
@@ -137,6 +139,7 @@ function parseCustomTags(content: string): ContentPiece[] {
|
||||
"dyad-add-dependency",
|
||||
"dyad-execute-sql",
|
||||
"dyad-add-integration",
|
||||
"dyad-output",
|
||||
];
|
||||
|
||||
const tagPattern = new RegExp(
|
||||
@@ -303,6 +306,16 @@ function renderCustomTag(
|
||||
</DyadAddIntegration>
|
||||
);
|
||||
|
||||
case "dyad-output":
|
||||
return (
|
||||
<DyadOutput
|
||||
type={attributes.type as "warning" | "error"}
|
||||
message={attributes.message}
|
||||
>
|
||||
{content}
|
||||
</DyadOutput>
|
||||
);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
77
src/components/chat/DyadOutput.tsx
Normal file
77
src/components/chat/DyadOutput.tsx
Normal file
@@ -0,0 +1,77 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
ChevronsDownUp,
|
||||
ChevronsUpDown,
|
||||
AlertTriangle,
|
||||
XCircle,
|
||||
} from "lucide-react";
|
||||
|
||||
interface DyadOutputProps {
|
||||
type: "error" | "warning";
|
||||
message?: string;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const DyadOutput: React.FC<DyadOutputProps> = ({
|
||||
type,
|
||||
message,
|
||||
children,
|
||||
}) => {
|
||||
const [isContentVisible, setIsContentVisible] = useState(false);
|
||||
|
||||
// If the type is not warning, it is an error (in case LLM gives a weird "type")
|
||||
const isError = type !== "warning";
|
||||
const borderColor = isError ? "border-red-500" : "border-amber-500";
|
||||
const iconColor = isError ? "text-red-500" : "text-amber-500";
|
||||
const icon = isError ? (
|
||||
<XCircle size={16} className={iconColor} />
|
||||
) : (
|
||||
<AlertTriangle size={16} className={iconColor} />
|
||||
);
|
||||
const label = isError ? "Error" : "Warning";
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`relative bg-(--background-lightest) hover:bg-(--background-lighter) rounded-lg px-4 py-2 border my-2 cursor-pointer ${borderColor}`}
|
||||
onClick={() => setIsContentVisible(!isContentVisible)}
|
||||
>
|
||||
{/* Top-left label badge */}
|
||||
<div
|
||||
className={`absolute top-2 left-2 flex items-center gap-1 px-2 py-0.5 rounded text-xs font-semibold ${iconColor} bg-white dark:bg-gray-900`}
|
||||
style={{ zIndex: 1 }}
|
||||
>
|
||||
{icon}
|
||||
<span>{label}</span>
|
||||
</div>
|
||||
{/* Main content, padded to avoid label */}
|
||||
<div className="flex items-center justify-between pl-20">
|
||||
<div className="flex items-center gap-2">
|
||||
{message && (
|
||||
<span className="text-gray-700 dark:text-gray-300 font-medium text-sm">
|
||||
{message.slice(0, isContentVisible ? undefined : 80) +
|
||||
(!isContentVisible ? "..." : "")}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
{isContentVisible ? (
|
||||
<ChevronsDownUp
|
||||
size={20}
|
||||
className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
|
||||
/>
|
||||
) : (
|
||||
<ChevronsUpDown
|
||||
size={20}
|
||||
className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{isContentVisible && children && (
|
||||
<div className="text-sm mt-2 text-gray-800 dark:text-gray-200 pl-20">
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user