refactor: update button labels and improve dialog for saving tools templates
This commit is contained in:
@@ -139,7 +139,7 @@ function ToolsDropdownList() {
|
|||||||
return (
|
return (
|
||||||
<NavigationMenuItem className="p-3">
|
<NavigationMenuItem className="p-3">
|
||||||
<NavigationMenuTrigger>
|
<NavigationMenuTrigger>
|
||||||
<span>{Tr(`Saved tools templates`)}</span>
|
<span>{Tr(`Tools`)}</span>
|
||||||
<Button
|
<Button
|
||||||
variant="link"
|
variant="link"
|
||||||
className="ml-2 text-sm"
|
className="ml-2 text-sm"
|
||||||
|
|||||||
@@ -244,44 +244,6 @@ export default function Message(props: { messageIndex: number }) {
|
|||||||
const [showEdit, setShowEdit] = useState(false);
|
const [showEdit, setShowEdit] = useState(false);
|
||||||
const [renderMarkdown, setRenderWorkdown] = useState(false);
|
const [renderMarkdown, setRenderWorkdown] = useState(false);
|
||||||
const [renderColor, setRenderColor] = useState(false);
|
const [renderColor, setRenderColor] = useState(false);
|
||||||
const DeleteIcon = () => (
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
chatStore.history[messageIndex].hide =
|
|
||||||
!chatStore.history[messageIndex].hide;
|
|
||||||
|
|
||||||
//chatStore.totalTokens =
|
|
||||||
chatStore.totalTokens = 0;
|
|
||||||
for (const i of chatStore.history
|
|
||||||
.filter(({ hide }) => !hide)
|
|
||||||
.slice(chatStore.postBeginIndex)
|
|
||||||
.map(({ token }) => token)) {
|
|
||||||
chatStore.totalTokens += i;
|
|
||||||
}
|
|
||||||
setChatStore({ ...chatStore });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
const CopiedHint = () => (
|
|
||||||
<div role="alert" className="alert">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
className="stroke-info h-6 w-6 shrink-0"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2"
|
|
||||||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
<span>{Tr("Message copied to clipboard!")}</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const copyToClipboard = async (text: string) => {
|
const copyToClipboard = async (text: string) => {
|
||||||
@@ -309,20 +271,6 @@ export default function Message(props: { messageIndex: number }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const CopyIcon = ({ textToCopy }: { textToCopy: string }) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
copyToClipboard(textToCopy);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Copy
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{chatStore.postBeginIndex !== 0 &&
|
{chatStore.postBeginIndex !== 0 &&
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import {
|
|||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
|
DialogClose,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogDescription,
|
DialogDescription,
|
||||||
DialogFooter,
|
DialogFooter,
|
||||||
@@ -73,6 +74,7 @@ import {
|
|||||||
KeyIcon,
|
KeyIcon,
|
||||||
ListIcon,
|
ListIcon,
|
||||||
MoveHorizontalIcon,
|
MoveHorizontalIcon,
|
||||||
|
SaveIcon,
|
||||||
TriangleAlertIcon,
|
TriangleAlertIcon,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { Separator } from "@/components/ui/separator";
|
import { Separator } from "@/components/ui/separator";
|
||||||
@@ -581,25 +583,68 @@ export default (props: {}) => {
|
|||||||
<div className="box">
|
<div className="box">
|
||||||
<div className="flex justify-evenly flex-wrap">
|
<div className="flex justify-evenly flex-wrap">
|
||||||
{ctx.chatStore.toolsString.trim() && (
|
{ctx.chatStore.toolsString.trim() && (
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button variant="outline">{Tr(`Save Tools`)}</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="sm:max-w-md">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Save the tool as Template</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
Once saved, you can easily access your tools from
|
||||||
|
the dropdown menu.
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<div className="grid flex-1 gap-2">
|
||||||
|
<Label htmlFor="toolsName" className="sr-only">
|
||||||
|
Name
|
||||||
|
</Label>
|
||||||
|
<Input
|
||||||
|
id="toolsName"
|
||||||
|
placeholder="Type Something..."
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
id="toolsNameError"
|
||||||
|
className="text-red-600"
|
||||||
|
></Label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<DialogFooter className="sm:justify-start">
|
||||||
|
<DialogClose asChild>
|
||||||
<Button
|
<Button
|
||||||
|
type="submit"
|
||||||
|
size="sm"
|
||||||
|
className="px-3"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const name = prompt(
|
const name = document.getElementById(
|
||||||
`Give this **Tools** template a name:`
|
"toolsName" as string
|
||||||
);
|
) as HTMLInputElement;
|
||||||
if (!name) {
|
if (!name.value) {
|
||||||
alert("No template name specified");
|
const errorLabel = document.getElementById(
|
||||||
|
"toolsNameError" as string
|
||||||
|
) as HTMLLabelElement;
|
||||||
|
if (errorLabel) {
|
||||||
|
errorLabel.textContent =
|
||||||
|
"Tool name is required.";
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const newToolsTmp: TemplateTools = {
|
const newToolsTmp: TemplateTools = {
|
||||||
name,
|
name: name.value,
|
||||||
toolsString: ctx.chatStore.toolsString,
|
toolsString: ctx.chatStore.toolsString,
|
||||||
};
|
};
|
||||||
ctx.templateTools.push(newToolsTmp);
|
ctx.templateTools.push(newToolsTmp);
|
||||||
ctx.setTemplateTools([...ctx.templateTools]);
|
ctx.setTemplateTools([...ctx.templateTools]);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{Tr(`Save Tools`)}
|
<SaveIcon className="w-4 h-4" /> Save
|
||||||
|
<span className="sr-only">Save</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
</DialogClose>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ import {
|
|||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { ModeToggle } from "@/components/ModeToggle";
|
import { ModeToggle } from "@/components/ModeToggle";
|
||||||
|
|
||||||
import Navbar from "@/components/navbar";
|
import Navbar from "@/components/Navbar";
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
// init selected index
|
// init selected index
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ const LANG_MAP: Record<string, string> = {
|
|||||||
cost: "消费",
|
cost: "消费",
|
||||||
stream: "流式返回",
|
stream: "流式返回",
|
||||||
fetch: "一次获取",
|
fetch: "一次获取",
|
||||||
|
Tools: "工具",
|
||||||
|
Clear: "清空",
|
||||||
"saved api templates": "已保存的 API 模板",
|
"saved api templates": "已保存的 API 模板",
|
||||||
"saved prompt templates": "已保存的提示模板",
|
"saved prompt templates": "已保存的提示模板",
|
||||||
"no chat history here": "暂无历史对话记录",
|
"no chat history here": "暂无历史对话记录",
|
||||||
|
|||||||
Reference in New Issue
Block a user