refactor: remove unused buttons and enhance API and Tools display in Settings component
This commit is contained in:
@@ -107,37 +107,6 @@ function APIsDropdownList({
|
|||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
</NavigationMenuLink>
|
</NavigationMenuLink>
|
||||||
<div className="mt-2 flex justify-between">
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
const name = prompt(`Give **${label}** template a name`);
|
|
||||||
if (!name) return;
|
|
||||||
t.name = name;
|
|
||||||
ctx.setTemplateAPIs(structuredClone(ctx.templateAPIs));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
if (
|
|
||||||
!confirm(
|
|
||||||
`Are you sure to delete this **${label}** template?`
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ctx.templateAPIs.splice(index, 1);
|
|
||||||
ctx.setTemplateAPIs(structuredClone(ctx.templateAPIs));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -3,12 +3,7 @@ import { themeChange } from "theme-change";
|
|||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
import { useContext, useEffect, useState, Dispatch } from "react";
|
import { useContext, useEffect, useState, Dispatch } from "react";
|
||||||
import { clearTotalCost, getTotalCost } from "@/utils/totalCost";
|
import { clearTotalCost, getTotalCost } from "@/utils/totalCost";
|
||||||
import {
|
import { ChatStore, TemplateChatStore, TemplateTools } from "@/types/chatstore";
|
||||||
ChatStore,
|
|
||||||
TemplateChatStore,
|
|
||||||
TemplateAPI,
|
|
||||||
TemplateTools,
|
|
||||||
} from "@/types/chatstore";
|
|
||||||
import { models } from "@/types/models";
|
import { models } from "@/types/models";
|
||||||
import { tr, Tr, langCodeContext, LANG_OPTIONS } from "@/translate";
|
import { tr, Tr, langCodeContext, LANG_OPTIONS } from "@/translate";
|
||||||
import { isVailedJSON } from "@/utils/isVailedJSON";
|
import { isVailedJSON } from "@/utils/isVailedJSON";
|
||||||
@@ -62,13 +57,13 @@ import {
|
|||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from "@/components/ui/dialog";
|
} from "@/components/ui/dialog";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import {
|
import {
|
||||||
BanIcon,
|
BanIcon,
|
||||||
CheckIcon,
|
CheckIcon,
|
||||||
CircleEllipsisIcon,
|
CircleEllipsisIcon,
|
||||||
CogIcon,
|
CogIcon,
|
||||||
Ellipsis,
|
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
InfoIcon,
|
InfoIcon,
|
||||||
KeyIcon,
|
KeyIcon,
|
||||||
@@ -478,6 +473,151 @@ const Choice = (props: {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const APIShowBlock = (props: {
|
||||||
|
ctx: any;
|
||||||
|
index: number;
|
||||||
|
label: string;
|
||||||
|
type: string;
|
||||||
|
apiField: string;
|
||||||
|
keyField: string;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div className="border-b border-gray-200 pb-4 pt-4">
|
||||||
|
<Badge variant="outline">{props.type}</Badge> <Label>{props.label}</Label>
|
||||||
|
<div className="mt-4">
|
||||||
|
<div className="grid w-full max-w-sm items-center gap-1.5 mt-2">
|
||||||
|
<Label>Endpoint</Label> {props.apiField}
|
||||||
|
</div>
|
||||||
|
<div className="grid w-full max-w-sm items-center gap-1.5 mt-2">
|
||||||
|
<Label>Key</Label>
|
||||||
|
{props.keyField ? (
|
||||||
|
props.keyField
|
||||||
|
) : (
|
||||||
|
<span className="text-gray-500 italic">empty</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="mt-2 mr-2"
|
||||||
|
onClick={() => {
|
||||||
|
const name = prompt(`Give template ${props.label} a new name`);
|
||||||
|
if (!name) return;
|
||||||
|
if (props.type === "Chat") {
|
||||||
|
props.ctx.templateAPIs[props.index].name = name;
|
||||||
|
props.ctx.setTemplateAPIs(structuredClone(props.ctx.templateAPIs));
|
||||||
|
} else if (props.type === "Whisper") {
|
||||||
|
props.ctx.templateAPIsWhisper[props.index].name = name;
|
||||||
|
props.ctx.setTemplateAPIsWhisper(
|
||||||
|
structuredClone(props.ctx.templateAPIsWhisper)
|
||||||
|
);
|
||||||
|
} else if (props.type === "TTS") {
|
||||||
|
props.ctx.templateAPIsTTS[props.index].name = name;
|
||||||
|
props.ctx.setTemplateAPIsTTS(
|
||||||
|
structuredClone(props.ctx.templateAPIsTTS)
|
||||||
|
);
|
||||||
|
} else if (props.type === "ImgGen") {
|
||||||
|
props.ctx.templateAPIsImageGen[props.index].name = name;
|
||||||
|
props.ctx.setTemplateAPIsImageGen(
|
||||||
|
structuredClone(props.ctx.templateAPIsImageGen)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Change Name
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="destructive"
|
||||||
|
size="sm"
|
||||||
|
className="mt-2"
|
||||||
|
onClick={() => {
|
||||||
|
if (!props.ctx) return;
|
||||||
|
if (
|
||||||
|
!confirm(
|
||||||
|
`Are you sure to delete ${props.label}(${props.type}) API?`
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (props.type === "Chat") {
|
||||||
|
props.ctx.templateAPIs.splice(props.index, 1);
|
||||||
|
props.ctx.setTemplateAPIs(structuredClone(props.ctx.templateAPIs));
|
||||||
|
} else if (props.type === "Whisper") {
|
||||||
|
props.ctx.templateAPIsWhisper.splice(props.index, 1);
|
||||||
|
props.ctx.setTemplateAPIsWhisper(
|
||||||
|
structuredClone(props.ctx.templateAPIsWhisper)
|
||||||
|
);
|
||||||
|
} else if (props.type === "TTS") {
|
||||||
|
props.ctx.templateAPIsTTS.splice(props.index, 1);
|
||||||
|
props.ctx.setTemplateAPIsTTS(
|
||||||
|
structuredClone(props.ctx.templateAPIsTTS)
|
||||||
|
);
|
||||||
|
} else if (props.type === "ImgGen") {
|
||||||
|
props.ctx.templateAPIsImageGen.splice(props.index, 1);
|
||||||
|
props.ctx.setTemplateAPIsImageGen(
|
||||||
|
structuredClone(props.ctx.templateAPIsImageGen)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ToolsShowBlock = (props: {
|
||||||
|
ctx: any;
|
||||||
|
index: number;
|
||||||
|
label: string;
|
||||||
|
content: string;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div className="border-b border-gray-200 pb-4 pt-4">
|
||||||
|
<Badge variant="outline">Tool</Badge> <Label>{props.label}</Label>
|
||||||
|
<div className="mt-4">
|
||||||
|
<div className="grid w-full max-w-sm items-center gap-1.5 mt-2">
|
||||||
|
<Label>Content</Label>
|
||||||
|
<ScrollArea className="w-72 whitespace-nowrap rounded-md border">
|
||||||
|
<pre className="text-xs">
|
||||||
|
{JSON.stringify(JSON.parse(props.content), null, 2)}
|
||||||
|
</pre>
|
||||||
|
</ScrollArea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="mt-2 mr-2"
|
||||||
|
onClick={() => {
|
||||||
|
const name = prompt(`Give the tool ${props.label} a new name`);
|
||||||
|
if (!name) return;
|
||||||
|
props.ctx.templateTools[props.index].name = name;
|
||||||
|
props.ctx.setTemplateTools(structuredClone(props.ctx.templateTools));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="destructive"
|
||||||
|
size="sm"
|
||||||
|
className="mt-2"
|
||||||
|
onClick={() => {
|
||||||
|
if (!props.ctx) return;
|
||||||
|
if (!confirm(`Are you sure to delete ${props.label} Tool?`)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
props.ctx.templateTools.splice(props.index, 1);
|
||||||
|
props.ctx.setTemplateTools(structuredClone(props.ctx.templateTools));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default (props: {}) => {
|
export default (props: {}) => {
|
||||||
const ctx = useContext(AppContext);
|
const ctx = useContext(AppContext);
|
||||||
if (ctx === null) return <></>;
|
if (ctx === null) return <></>;
|
||||||
@@ -1174,6 +1314,69 @@ export default (props: {}) => {
|
|||||||
</Card>
|
</Card>
|
||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
|
<AccordionItem value="templates">
|
||||||
|
<AccordionTrigger>Saved Template</AccordionTrigger>
|
||||||
|
<AccordionContent>
|
||||||
|
{ctx.templateAPIs.map((template, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<APIShowBlock
|
||||||
|
ctx={ctx}
|
||||||
|
index={index}
|
||||||
|
label={template.name}
|
||||||
|
type="Chat"
|
||||||
|
apiField={template.endpoint}
|
||||||
|
keyField={template.key}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{ctx.templateAPIsWhisper.map((template, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<APIShowBlock
|
||||||
|
ctx={ctx}
|
||||||
|
index={index}
|
||||||
|
label={template.name}
|
||||||
|
type="Whisper"
|
||||||
|
apiField={template.endpoint}
|
||||||
|
keyField={template.key}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{ctx.templateAPIsTTS.map((template, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<APIShowBlock
|
||||||
|
ctx={ctx}
|
||||||
|
index={index}
|
||||||
|
label={template.name}
|
||||||
|
type="TTS"
|
||||||
|
apiField={template.endpoint}
|
||||||
|
keyField={template.key}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{ctx.templateAPIsImageGen.map((template, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<APIShowBlock
|
||||||
|
ctx={ctx}
|
||||||
|
index={index}
|
||||||
|
label={template.name}
|
||||||
|
type="ImgGen"
|
||||||
|
apiField={template.endpoint}
|
||||||
|
keyField={template.key}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{ctx.templateTools.map((template, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<ToolsShowBlock
|
||||||
|
ctx={ctx}
|
||||||
|
index={index}
|
||||||
|
label={template.name}
|
||||||
|
content={template.toolsString}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
<div className="pt-4 space-y-2">
|
<div className="pt-4 space-y-2">
|
||||||
<p className="text-sm text-muted-foreground text-center">
|
<p className="text-sm text-muted-foreground text-center">
|
||||||
|
|||||||
@@ -33,9 +33,7 @@ import {
|
|||||||
CornerDownLeftIcon,
|
CornerDownLeftIcon,
|
||||||
CornerLeftUpIcon,
|
CornerLeftUpIcon,
|
||||||
CornerRightUpIcon,
|
CornerRightUpIcon,
|
||||||
ImageIcon,
|
|
||||||
InfoIcon,
|
InfoIcon,
|
||||||
PaintBucketIcon,
|
|
||||||
ScissorsIcon,
|
ScissorsIcon,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { Switch } from "@/components/ui/switch";
|
import { Switch } from "@/components/ui/switch";
|
||||||
|
|||||||
Reference in New Issue
Block a user