fix: lint code to build success

This commit is contained in:
HYana
2025-05-10 01:19:30 +08:00
parent 4031ff2835
commit 7a8102430f
48 changed files with 1657 additions and 1240 deletions
@@ -1,105 +1,108 @@
'use client';
import { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
import CreateCardComponent from '@/app/infra/basic-component/create-card-component/CreateCardComponent';
import { PluginCardVO } from '@/app/home/plugins/plugin-installed/PluginCardVO';
import PluginCardComponent from '@/app/home/plugins/plugin-installed/plugin-card/PluginCardComponent';
import PluginForm from '@/app/home/plugins/plugin-installed/plugin-form/PluginForm';
import styles from '@/app/home/plugins/plugins.module.css';
import { GithubIcon } from 'lucide-react';
import { httpClient } from '@/app/infra/http/HttpClient';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
} from '@/components/ui/dialog';
export interface PluginInstalledComponentRef {
refreshPluginList: () => void;
}
const PluginInstalledComponent = forwardRef<PluginInstalledComponentRef>((props, ref) => {
const [pluginList, setPluginList] = useState<PluginCardVO[]>([]);
const [modalOpen, setModalOpen] = useState<boolean>(false);
const [selectedPlugin, setSelectedPlugin] = useState<PluginCardVO | null>(null);
// eslint-disable-next-line react/display-name
const PluginInstalledComponent = forwardRef<PluginInstalledComponentRef>(
(props, ref) => {
const [pluginList, setPluginList] = useState<PluginCardVO[]>([]);
const [modalOpen, setModalOpen] = useState<boolean>(false);
const [selectedPlugin, setSelectedPlugin] = useState<PluginCardVO | null>(
null,
);
useEffect(() => {
initData();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
initData();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
function initData() {
getPluginList();
}
function initData() {
getPluginList();
}
function getPluginList() {
httpClient.getPlugins().then((value) => {
setPluginList(
value.plugins.map((plugin) => {
return new PluginCardVO({
author: plugin.author,
description: plugin.description.zh_CN,
enabled: plugin.enabled,
name: plugin.name,
version: plugin.version,
status: plugin.status,
tools: plugin.tools,
event_handlers: plugin.event_handlers,
repository: plugin.repository,
priority: plugin.priority,
});
}),
);
});
}
useImperativeHandle(ref, () => ({
refreshPluginList: getPluginList
}));
function handlePluginClick(plugin: PluginCardVO) {
setSelectedPlugin(plugin);
setModalOpen(true);
}
return (
<div className={`${styles.pluginListContainer}`}>
<Dialog open={modalOpen} onOpenChange={setModalOpen}>
<DialogContent className="w-[700px] max-h-[80vh] p-0 flex flex-col">
<DialogHeader className="px-6 pt-6 pb-2">
<DialogTitle></DialogTitle>
</DialogHeader>
<div className="flex-1 overflow-y-auto px-6">
{selectedPlugin && (
<PluginForm
pluginAuthor={selectedPlugin.author}
pluginName={selectedPlugin.name}
onFormSubmit={() => {
setModalOpen(false);
getPluginList();
}}
onFormCancel={() => {
setModalOpen(false);
}}
/>
)}
</div>
</DialogContent>
</Dialog>
{pluginList.map((vo, index) => {
return (
<div key={index}>
<PluginCardComponent cardVO={vo} onCardClick={() => handlePluginClick(vo)} />
</div>
function getPluginList() {
httpClient.getPlugins().then((value) => {
setPluginList(
value.plugins.map((plugin) => {
return new PluginCardVO({
author: plugin.author,
description: plugin.description.zh_CN,
enabled: plugin.enabled,
name: plugin.name,
version: plugin.version,
status: plugin.status,
tools: plugin.tools,
event_handlers: plugin.event_handlers,
repository: plugin.repository,
priority: plugin.priority,
});
}),
);
})}
</div>
);
});
});
}
useImperativeHandle(ref, () => ({
refreshPluginList: getPluginList,
}));
function handlePluginClick(plugin: PluginCardVO) {
setSelectedPlugin(plugin);
setModalOpen(true);
}
return (
<div className={`${styles.pluginListContainer}`}>
<Dialog open={modalOpen} onOpenChange={setModalOpen}>
<DialogContent className="w-[700px] max-h-[80vh] p-0 flex flex-col">
<DialogHeader className="px-6 pt-6 pb-2">
<DialogTitle></DialogTitle>
</DialogHeader>
<div className="flex-1 overflow-y-auto px-6">
{selectedPlugin && (
<PluginForm
pluginAuthor={selectedPlugin.author}
pluginName={selectedPlugin.name}
onFormSubmit={() => {
setModalOpen(false);
getPluginList();
}}
onFormCancel={() => {
setModalOpen(false);
}}
/>
)}
</div>
</DialogContent>
</Dialog>
{pluginList.map((vo, index) => {
return (
<div key={index}>
<PluginCardComponent
cardVO={vo}
onCardClick={() => handlePluginClick(vo)}
/>
</div>
);
})}
</div>
);
},
);
export default PluginInstalledComponent;
@@ -1,10 +1,9 @@
import { PluginCardVO } from '@/app/home/plugins/plugin-installed/PluginCardVO';
import { useState } from 'react';
import { httpClient } from '@/app/infra/http/HttpClient';
import { Badge } from "@/components/ui/badge"
import { Switch } from "@/components/ui/switch"
import { Button } from "@/components/ui/button"
import { toast } from "sonner"
import { Badge } from '@/components/ui/badge';
import { Switch } from '@/components/ui/switch';
import { toast } from 'sonner';
export default function PluginCardComponent({
cardVO,
@@ -25,39 +24,73 @@ export default function PluginCardComponent({
setEnabled(!enabled);
})
.catch((err) => {
toast.error("修改失败:" + err.message);
toast.error('修改失败:' + err.message);
})
.finally(() => {
setSwitchEnable(true);
});
}
return (
<div className="w-[26rem] h-[10rem] bg-white rounded-[10px] shadow-[0px_2px_2px_0_rgba(0,0,0,0.2)] p-[1.2rem] cursor-pointer" onClick={onCardClick}>
<div
className="w-[26rem] h-[10rem] bg-white rounded-[10px] shadow-[0px_2px_2px_0_rgba(0,0,0,0.2)] p-[1.2rem] cursor-pointer"
onClick={onCardClick}
>
<div className="w-full h-full flex flex-row items-start justify-start gap-[1.2rem]">
<svg className="w-16 h-16 text-[#2288ee]" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M8 4C8 2.34315 9.34315 1 11 1C12.6569 1 14 2.34315 14 4C14 4.35064 13.9398 4.68722 13.8293 5H18C18.5523 5 19 5.44772 19 6V10.1707C19.3128 10.0602 19.6494 10 20 10C21.6569 10 23 11.3431 23 13C23 14.6569 21.6569 16 20 16C19.6494 16 19.3128 15.9398 19 15.8293V20C19 20.5523 18.5523 21 18 21H4C3.44772 21 3 20.5523 3 20V6C3 5.44772 3.44772 5 4 5H8.17071C8.06015 4.68722 8 4.35064 8 4Z"></path></svg>
<svg
className="w-16 h-16 text-[#2288ee]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M8 4C8 2.34315 9.34315 1 11 1C12.6569 1 14 2.34315 14 4C14 4.35064 13.9398 4.68722 13.8293 5H18C18.5523 5 19 5.44772 19 6V10.1707C19.3128 10.0602 19.6494 10 20 10C21.6569 10 23 11.3431 23 13C23 14.6569 21.6569 16 20 16C19.6494 16 19.3128 15.9398 19 15.8293V20C19 20.5523 18.5523 21 18 21H4C3.44772 21 3 20.5523 3 20V6C3 5.44772 3.44772 5 4 5H8.17071C8.06015 4.68722 8 4.35064 8 4Z"></path>
</svg>
<div className="w-full h-full flex flex-col items-start justify-between gap-[0.6rem]">
<div className="flex flex-col items-start justify-start">
<div className="flex flex-col items-start justify-start">
<div className="text-[0.7rem] text-[#666]">{cardVO.author} / </div>
<div className="text-[0.7rem] text-[#666]">
{cardVO.author} /{' '}
</div>
<div className="flex flex-row items-center justify-start gap-[0.4rem]">
<div className="text-[1.2rem] text-black">{cardVO.name}</div>
<Badge variant="outline" className="text-[0.7rem]">v{cardVO.version}</Badge>
<Badge variant="outline" className="text-[0.7rem]">
v{cardVO.version}
</Badge>
</div>
</div>
<div className="text-[0.8rem] text-[#666] line-clamp-2">{cardVO.description}</div>
<div className="text-[0.8rem] text-[#666] line-clamp-2">
{cardVO.description}
</div>
</div>
<div className="w-full flex flex-row items-start justify-start gap-[0.6rem]">
<div className="flex h-full flex-row items-center justify-center gap-[0.4rem]">
<svg className="w-[1.2rem] h-[1.2rem] text-black" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M24 12L18.3431 17.6569L16.9289 16.2426L21.1716 12L16.9289 7.75736L18.3431 6.34315L24 12ZM2.82843 12L7.07107 16.2426L5.65685 17.6569L0 12L5.65685 6.34315L7.07107 7.75736L2.82843 12ZM9.78845 21H7.66009L14.2116 3H16.3399L9.78845 21Z"></path></svg>
<div className="text-base text-black font-medium"> {Object.keys(cardVO.event_handlers).length}</div>
<svg
className="w-[1.2rem] h-[1.2rem] text-black"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M24 12L18.3431 17.6569L16.9289 16.2426L21.1716 12L16.9289 7.75736L18.3431 6.34315L24 12ZM2.82843 12L7.07107 16.2426L5.65685 17.6569L0 12L5.65685 6.34315L7.07107 7.75736L2.82843 12ZM9.78845 21H7.66009L14.2116 3H16.3399L9.78845 21Z"></path>
</svg>
<div className="text-base text-black font-medium">
{Object.keys(cardVO.event_handlers).length}
</div>
</div>
<div className="flex h-full flex-row items-center justify-center gap-[0.4rem]">
<svg className="w-[1.2rem] h-[1.2rem] text-black" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5.32943 3.27158C6.56252 2.8332 7.9923 3.10749 8.97927 4.09446C10.1002 5.21537 10.3019 6.90741 9.5843 8.23385L20.293 18.9437L18.8788 20.3579L8.16982 9.64875C6.84325 10.3669 5.15069 10.1654 4.02952 9.04421C3.04227 8.05696 2.7681 6.62665 3.20701 5.39332L5.44373 7.63C6.02952 8.21578 6.97927 8.21578 7.56505 7.63C8.15084 7.04421 8.15084 6.09446 7.56505 5.50868L5.32943 3.27158ZM15.6968 5.15512L18.8788 3.38736L20.293 4.80157L18.5252 7.98355L16.7574 8.3371L14.6361 10.4584L13.2219 9.04421L15.3432 6.92289L15.6968 5.15512ZM8.97927 13.2868L10.3935 14.7011L5.09018 20.0044C4.69966 20.3949 4.06649 20.3949 3.67597 20.0044C3.31334 19.6417 3.28744 19.0699 3.59826 18.6774L3.67597 18.5902L8.97927 13.2868Z"></path></svg>
<div className="text-base text-black font-medium"> {cardVO.tools.length}</div>
<svg
className="w-[1.2rem] h-[1.2rem] text-black"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M5.32943 3.27158C6.56252 2.8332 7.9923 3.10749 8.97927 4.09446C10.1002 5.21537 10.3019 6.90741 9.5843 8.23385L20.293 18.9437L18.8788 20.3579L8.16982 9.64875C6.84325 10.3669 5.15069 10.1654 4.02952 9.04421C3.04227 8.05696 2.7681 6.62665 3.20701 5.39332L5.44373 7.63C6.02952 8.21578 6.97927 8.21578 7.56505 7.63C8.15084 7.04421 8.15084 6.09446 7.56505 5.50868L5.32943 3.27158ZM15.6968 5.15512L18.8788 3.38736L20.293 4.80157L18.5252 7.98355L16.7574 8.3371L14.6361 10.4584L13.2219 9.04421L15.3432 6.92289L15.6968 5.15512ZM8.97927 13.2868L10.3935 14.7011L5.09018 20.0044C4.69966 20.3949 4.06649 20.3949 3.67597 20.0044C3.31334 19.6417 3.28744 19.0699 3.59826 18.6774L3.67597 18.5902L8.97927 13.2868Z"></path>
</svg>
<div className="text-base text-black font-medium">
{cardVO.tools.length}
</div>
</div>
</div>
</div>
@@ -1,9 +1,8 @@
import { useState, useEffect } from 'react';
import { ApiRespPlugin, ApiRespPluginConfig, Plugin } from '@/app/infra/entities/api';
import { ApiRespPluginConfig, Plugin } from '@/app/infra/entities/api';
import { httpClient } from '@/app/infra/http/HttpClient';
import DynamicFormComponent from '@/app/home/components/dynamic-form/DynamicFormComponent';
import { IDynamicFormItemSchema } from '@/app/infra/entities/form/dynamic';
import { Button } from "@/components/ui/button";
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogContent,
@@ -11,8 +10,8 @@ import {
DialogHeader,
DialogTitle,
DialogFooter,
} from "@/components/ui/dialog";
import { toast } from "sonner";
} from '@/components/ui/dialog';
import { toast } from 'sonner';
enum PluginRemoveStatus {
WAIT_INPUT = 'WAIT_INPUT',
@@ -36,8 +35,11 @@ export default function PluginForm({
const [isSaving, setIsLoading] = useState(false);
const [showDeleteConfirmModal, setShowDeleteConfirmModal] = useState(false);
const [pluginRemoveStatus, setPluginRemoveStatus] = useState<PluginRemoveStatus>(PluginRemoveStatus.WAIT_INPUT);
const [pluginRemoveError, setPluginRemoveError] = useState<string | null>(null);
const [pluginRemoveStatus, setPluginRemoveStatus] =
useState<PluginRemoveStatus>(PluginRemoveStatus.WAIT_INPUT);
const [pluginRemoveError, setPluginRemoveError] = useState<string | null>(
null,
);
useEffect(() => {
// 获取插件信息
@@ -52,12 +54,16 @@ export default function PluginForm({
const handleSubmit = async (values: object) => {
setIsLoading(true);
httpClient.updatePluginConfig(pluginAuthor, pluginName, values).then(() => {
httpClient
.updatePluginConfig(pluginAuthor, pluginName, values)
.then(() => {
onFormSubmit();
toast.success("保存成功");
}).catch((error) => {
toast.error("保存失败:" + error.message);
}).finally(() => {
toast.success('保存成功');
})
.catch((error) => {
toast.error('保存失败:' + error.message);
})
.finally(() => {
setIsLoading(false);
});
};
@@ -68,36 +74,39 @@ export default function PluginForm({
function deletePlugin() {
setPluginRemoveStatus(PluginRemoveStatus.REMOVING);
httpClient.removePlugin(pluginAuthor, pluginName).then((res) => {
const taskId = res.task_id;
const interval = setInterval(() => {
httpClient.getAsyncTask(taskId).then((res) => {
if (res.runtime.done) {
clearInterval(interval);
if (res.runtime.exception) {
setPluginRemoveError(res.runtime.exception);
setPluginRemoveStatus(PluginRemoveStatus.ERROR);
} else {
setPluginRemoveStatus(PluginRemoveStatus.WAIT_INPUT);
setShowDeleteConfirmModal(false);
onFormSubmit();
}
}
});
}, 1000);
httpClient
.removePlugin(pluginAuthor, pluginName)
.then((res) => {
const taskId = res.task_id;
}).catch((error) => {
setPluginRemoveError(error.message);
setPluginRemoveStatus(PluginRemoveStatus.ERROR);
})
const interval = setInterval(() => {
httpClient.getAsyncTask(taskId).then((res) => {
if (res.runtime.done) {
clearInterval(interval);
if (res.runtime.exception) {
setPluginRemoveError(res.runtime.exception);
setPluginRemoveStatus(PluginRemoveStatus.ERROR);
} else {
setPluginRemoveStatus(PluginRemoveStatus.WAIT_INPUT);
setShowDeleteConfirmModal(false);
onFormSubmit();
}
}
});
}, 1000);
})
.catch((error) => {
setPluginRemoveError(error.message);
setPluginRemoveStatus(PluginRemoveStatus.ERROR);
});
}
return (
<div>
<Dialog open={showDeleteConfirmModal} onOpenChange={setShowDeleteConfirmModal}>
<Dialog
open={showDeleteConfirmModal}
onOpenChange={setShowDeleteConfirmModal}
>
<DialogContent>
<DialogHeader>
<DialogTitle></DialogTitle>
@@ -120,17 +129,23 @@ export default function PluginForm({
</DialogDescription>
<DialogFooter>
{pluginRemoveStatus === PluginRemoveStatus.WAIT_INPUT && (
<Button variant="outline" onClick={() => {
setShowDeleteConfirmModal(false);
setPluginRemoveStatus(PluginRemoveStatus.WAIT_INPUT);
}}>
</Button>
<Button
variant="outline"
onClick={() => {
setShowDeleteConfirmModal(false);
setPluginRemoveStatus(PluginRemoveStatus.WAIT_INPUT);
}}
>
</Button>
)}
{pluginRemoveStatus === PluginRemoveStatus.WAIT_INPUT && (
<Button variant="destructive" onClick={() => {
deletePlugin();
}}>
<Button
variant="destructive"
onClick={() => {
deletePlugin();
}}
>
</Button>
)}
@@ -140,10 +155,13 @@ export default function PluginForm({
</Button>
)}
{pluginRemoveStatus === PluginRemoveStatus.ERROR && (
<Button variant="default" onClick={() => {
setShowDeleteConfirmModal(false);
// setPluginRemoveStatus(PluginRemoveStatus.WAIT_INPUT);
}}>
<Button
variant="default"
onClick={() => {
setShowDeleteConfirmModal(false);
// setPluginRemoveStatus(PluginRemoveStatus.WAIT_INPUT);
}}
>
</Button>
)}
@@ -151,7 +169,6 @@ export default function PluginForm({
</DialogContent>
</Dialog>
<div className="space-y-2">
<div className="text-lg font-medium">{pluginInfo.name}</div>
<div className="text-sm text-gray-500 pb-2">
@@ -160,7 +177,7 @@ export default function PluginForm({
{pluginInfo.config_schema.length > 0 && (
<DynamicFormComponent
itemConfigList={pluginInfo.config_schema}
initialValues={pluginConfig.config}
initialValues={pluginConfig.config as Record<string, object>}
onSubmit={(values) => {
let config = pluginConfig.config;
config = {
@@ -174,15 +191,12 @@ export default function PluginForm({
/>
)}
{pluginInfo.config_schema.length === 0 && (
<div className="text-sm text-gray-500">
</div>
<div className="text-sm text-gray-500"></div>
)}
</div>
<div className="sticky bottom-0 left-0 right-0 bg-background border-t p-4 mt-4">
<div className="flex justify-end gap-2">
<Button
variant="destructive"
onClick={() => {
@@ -191,7 +205,9 @@ export default function PluginForm({
}}
disabled={pluginRemoveStatus === PluginRemoveStatus.REMOVING}
>
{pluginRemoveStatus === PluginRemoveStatus.REMOVING ? '删除中...' : '删除插件'}
{pluginRemoveStatus === PluginRemoveStatus.REMOVING
? '删除中...'
: '删除插件'}
</Button>
<Button
@@ -208,4 +224,4 @@ export default function PluginForm({
</div>
</div>
);
}
}