mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-03 06:12:14 +08:00
feat: update skill settings
This commit is contained in:
4
frontend/TODO.md
Normal file
4
frontend/TODO.md
Normal file
@@ -0,0 +1,4 @@
|
||||
[ ] feat - Skills 页面根据 Category 分组展示
|
||||
[ ] fix - autoOpen
|
||||
[ ] fix - local settings
|
||||
[ ] feat - todo
|
||||
@@ -153,7 +153,7 @@ export function InputBox({
|
||||
: "text-muted-foreground",
|
||||
)}
|
||||
>
|
||||
Thinking
|
||||
{t.inputBox.thinking}
|
||||
</span>
|
||||
</>
|
||||
</PromptInputButton>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { SparklesIcon } from "lucide-react";
|
||||
import { useMemo, useState } from "react";
|
||||
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Empty,
|
||||
EmptyDescription,
|
||||
@@ -44,7 +45,13 @@ export function SkillSettingsPage() {
|
||||
}
|
||||
|
||||
function SkillSettingsList({ skills }: { skills: Skill[] }) {
|
||||
const { t } = useI18n();
|
||||
const [filter, setFilter] = useState<"public" | "custom">("public");
|
||||
const { mutate: enableSkill } = useEnableSkill();
|
||||
const filteredSkills = useMemo(
|
||||
() => skills.filter((skill) => skill.category === filter),
|
||||
[skills, filter],
|
||||
);
|
||||
if (skills.length === 0) {
|
||||
return (
|
||||
<Empty>
|
||||
@@ -63,29 +70,59 @@ function SkillSettingsList({ skills }: { skills: Skill[] }) {
|
||||
}
|
||||
return (
|
||||
<div className="flex w-full flex-col gap-4">
|
||||
{skills.map((skill) => (
|
||||
<Item className="w-full" variant="outline" key={skill.name}>
|
||||
<ItemContent>
|
||||
<ItemTitle>
|
||||
<div className="flex items-center gap-2">
|
||||
<div>{skill.name}</div>
|
||||
<Badge variant="outline">{skill.category}</Badge>
|
||||
</div>
|
||||
</ItemTitle>
|
||||
<ItemDescription className="line-clamp-4">
|
||||
{skill.description}
|
||||
</ItemDescription>
|
||||
</ItemContent>
|
||||
<ItemActions>
|
||||
<Switch
|
||||
checked={skill.enabled}
|
||||
onCheckedChange={(checked) =>
|
||||
enableSkill({ skillName: skill.name, enabled: checked })
|
||||
}
|
||||
/>
|
||||
</ItemActions>
|
||||
</Item>
|
||||
))}
|
||||
<header className="flex gap-2">
|
||||
<Button
|
||||
className="rounded-xl"
|
||||
size="sm"
|
||||
variant={filter === "public" ? "default" : "outline"}
|
||||
onClick={() => setFilter("public")}
|
||||
>
|
||||
{t.common.public}
|
||||
</Button>
|
||||
<Button
|
||||
className="rounded-xl"
|
||||
size="sm"
|
||||
variant={filter === "custom" ? "default" : "outline"}
|
||||
onClick={() => setFilter("custom")}
|
||||
>
|
||||
{t.common.custom}
|
||||
</Button>
|
||||
</header>
|
||||
{filteredSkills.length === 0 && (
|
||||
<Empty>
|
||||
<EmptyHeader>
|
||||
<EmptyMedia variant="icon">
|
||||
<SparklesIcon />
|
||||
</EmptyMedia>
|
||||
<EmptyTitle>No skill yet</EmptyTitle>
|
||||
<EmptyDescription>
|
||||
Put your skill folders under the `/skills/{filter}` folder under
|
||||
the root folder of DeerFlow.
|
||||
</EmptyDescription>
|
||||
</EmptyHeader>
|
||||
</Empty>
|
||||
)}
|
||||
{filteredSkills.length > 0 &&
|
||||
filteredSkills.map((skill) => (
|
||||
<Item className="w-full" variant="outline" key={skill.name}>
|
||||
<ItemContent>
|
||||
<ItemTitle>
|
||||
<div className="flex items-center gap-2">{skill.name}</div>
|
||||
</ItemTitle>
|
||||
<ItemDescription className="line-clamp-4">
|
||||
{skill.description}
|
||||
</ItemDescription>
|
||||
</ItemContent>
|
||||
<ItemActions>
|
||||
<Switch
|
||||
checked={skill.enabled}
|
||||
onCheckedChange={(checked) =>
|
||||
enableSkill({ skillName: skill.name, enabled: checked })
|
||||
}
|
||||
/>
|
||||
</ItemActions>
|
||||
</Item>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ export const enUS: Translations = {
|
||||
download: "Download",
|
||||
thinking: "Thinking",
|
||||
artifacts: "Artifacts",
|
||||
public: "Public",
|
||||
custom: "Custom",
|
||||
},
|
||||
|
||||
// Welcome
|
||||
@@ -37,6 +39,7 @@ export const enUS: Translations = {
|
||||
// Input Box
|
||||
inputBox: {
|
||||
placeholder: "How can I assist you today?",
|
||||
thinking: "Thinking",
|
||||
thinkingEnabled: "Thinking is enabled",
|
||||
thinkingDisabled: "Thinking is disabled",
|
||||
clickToDisableThinking: "Click to disable thinking",
|
||||
|
||||
@@ -16,6 +16,8 @@ export interface Translations {
|
||||
download: string;
|
||||
thinking: string;
|
||||
artifacts: string;
|
||||
public: string;
|
||||
custom: string;
|
||||
};
|
||||
|
||||
// Welcome
|
||||
@@ -34,6 +36,7 @@ export interface Translations {
|
||||
// Input Box
|
||||
inputBox: {
|
||||
placeholder: string;
|
||||
thinking: string;
|
||||
thinkingEnabled: string;
|
||||
thinkingDisabled: string;
|
||||
clickToDisableThinking: string;
|
||||
|
||||
@@ -18,6 +18,8 @@ export const zhCN: Translations = {
|
||||
download: "下载",
|
||||
thinking: "思考",
|
||||
artifacts: "文件",
|
||||
public: "公共",
|
||||
custom: "自定义",
|
||||
},
|
||||
|
||||
// Welcome
|
||||
@@ -37,6 +39,7 @@ export const zhCN: Translations = {
|
||||
// Input Box
|
||||
inputBox: {
|
||||
placeholder: "今天我能为你做些什么?",
|
||||
thinking: "思考",
|
||||
thinkingEnabled: "思考功能已启用",
|
||||
thinkingDisabled: "思考功能已禁用",
|
||||
clickToDisableThinking: "点击禁用思考功能",
|
||||
|
||||
Reference in New Issue
Block a user