chore: remove plugin reorder functionality

This commit is contained in:
Junyan Qin
2025-08-21 10:47:53 +08:00
parent 53ade384eb
commit 9e9bc88473
2 changed files with 205 additions and 199 deletions

View File

@@ -3,7 +3,7 @@ import PluginInstalledComponent, {
PluginInstalledComponentRef,
} from '@/app/home/plugins/plugin-installed/PluginInstalledComponent';
import MarketPage from '@/app/home/plugins/plugin-market/PluginMarketComponent';
import PluginSortDialog from '@/app/home/plugins/plugin-sort/PluginSortDialog';
// import PluginSortDialog from '@/app/home/plugins/plugin-sort/PluginSortDialog';
import styles from './plugins.module.css';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Button } from '@/components/ui/button';
@@ -44,7 +44,7 @@ enum PluginInstallStatus {
export default function PluginConfigPage() {
const { t } = useTranslation();
const [modalOpen, setModalOpen] = useState(false);
const [sortModalOpen, setSortModalOpen] = useState(false);
// const [sortModalOpen, setSortModalOpen] = useState(false);
const [activeTab, setActiveTab] = useState('installed');
const [installSource, setInstallSource] = useState<string>('local');
const [installInfo, setInstallInfo] = useState<Record<string, any>>({}); // eslint-disable-line @typescript-eslint/no-explicit-any
@@ -219,15 +219,15 @@ export default function PluginConfigPage() {
</TabsList>
<div className="flex flex-row justify-end items-center">
<Button
{/* <Button
variant="outline"
className="px-6 py-4 cursor-pointer mr-2"
onClick={() => {
setSortModalOpen(true);
// setSortModalOpen(true);
}}
>
{t('plugins.arrange')}
</Button>
</Button> */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="default" className="px-6 py-4 cursor-pointer">
@@ -347,13 +347,13 @@ export default function PluginConfigPage() {
</div>
)}
<PluginSortDialog
{/* <PluginSortDialog
open={sortModalOpen}
onOpenChange={setSortModalOpen}
onSortComplete={() => {
pluginInstalledRef.current?.refreshPluginList();
}}
/>
/> */}
</div>
);
}

View File

@@ -1,209 +1,215 @@
'use client';
// 'use client';
import * as React from 'react';
import { useState, useEffect } from 'react';
import { PluginCardVO } from '@/app/home/plugins/plugin-installed/PluginCardVO';
import { httpClient } from '@/app/infra/http/HttpClient';
import { PluginReorderElement } from '@/app/infra/entities/api';
import { toast } from 'sonner';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import {
DndContext,
closestCenter,
KeyboardSensor,
PointerSensor,
useSensor,
useSensors,
DragEndEvent,
} from '@dnd-kit/core';
import {
arrayMove,
SortableContext,
sortableKeyboardCoordinates,
useSortable,
verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { useTranslation } from 'react-i18next';
import { extractI18nObject } from '@/i18n/I18nProvider';
// import * as React from 'react';
// import { useState, useEffect } from 'react';
// import { PluginCardVO } from '@/app/home/plugins/plugin-installed/PluginCardVO';
// import { httpClient } from '@/app/infra/http/HttpClient';
// import { PluginReorderElement } from '@/app/infra/entities/api';
// import { toast } from 'sonner';
// import {
// Dialog,
// DialogContent,
// DialogHeader,
// DialogTitle,
// DialogFooter,
// } from '@/components/ui/dialog';
// import { Button } from '@/components/ui/button';
// import {
// DndContext,
// closestCenter,
// KeyboardSensor,
// PointerSensor,
// useSensor,
// useSensors,
// DragEndEvent,
// } from '@dnd-kit/core';
// import {
// arrayMove,
// SortableContext,
// sortableKeyboardCoordinates,
// useSortable,
// verticalListSortingStrategy,
// } from '@dnd-kit/sortable';
// import { CSS } from '@dnd-kit/utilities';
// import { useTranslation } from 'react-i18next';
// import { extractI18nObject } from '@/i18n/I18nProvider';
interface PluginSortDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onSortComplete: () => void;
}
// interface PluginSortDialogProps {
// open: boolean;
// onOpenChange: (open: boolean) => void;
// onSortComplete: () => void;
// }
function SortablePluginItem({ plugin }: { plugin: PluginCardVO }) {
const { attributes, listeners, setNodeRef, transform, transition } =
useSortable({
id: `${plugin.author}-${plugin.name}`,
});
// function SortablePluginItem({ plugin }: { plugin: PluginCardVO }) {
// const { attributes, listeners, setNodeRef, transform, transition } =
// useSortable({
// id: `${plugin.author}-${plugin.name}`,
// });
const style = {
transform: CSS.Transform.toString(transform),
transition,
};
// const style = {
// transform: CSS.Transform.toString(transform),
// transition,
// };
return (
<div
ref={setNodeRef}
style={style}
{...attributes}
{...listeners}
className="bg-white dark:bg-gray-800 p-4 rounded-md shadow-sm border mb-2 cursor-move"
>
<div className="flex flex-col">
<div className="text-sm text-gray-600 dark:text-gray-400">
{plugin.author}
</div>
<div className="text-lg font-medium">{plugin.name}</div>
<div className="text-sm line-clamp-2 text-gray-500 dark:text-gray-400 mt-1">
{plugin.description}
</div>
</div>
</div>
);
}
// return (
// <div
// ref={setNodeRef}
// style={style}
// {...attributes}
// {...listeners}
// className="bg-white dark:bg-gray-800 p-4 rounded-md shadow-sm border mb-2 cursor-move"
// >
// <div className="flex flex-col">
// <div className="text-sm text-gray-600 dark:text-gray-400">
// {plugin.author}
// </div>
// <div className="text-lg font-medium">{plugin.name}</div>
// <div className="text-sm line-clamp-2 text-gray-500 dark:text-gray-400 mt-1">
// {plugin.description}
// </div>
// </div>
// </div>
// );
// }
export default function PluginSortDialog({
open,
onOpenChange,
onSortComplete,
}: PluginSortDialogProps) {
const { t } = useTranslation();
const [sortedPlugins, setSortedPlugins] = useState<PluginCardVO[]>([]);
const [isLoading, setIsLoading] = useState(false);
// export default function PluginSortDialog({
// open,
// onOpenChange,
// onSortComplete,
// }: PluginSortDialogProps) {
// const { t } = useTranslation();
// const [sortedPlugins, setSortedPlugins] = useState<PluginCardVO[]>([]);
// const [isLoading, setIsLoading] = useState(false);
function getPluginList() {
httpClient.getPlugins().then((value) => {
setSortedPlugins(
value.plugins.map((plugin) => {
return new PluginCardVO({
author: plugin.author,
description: extractI18nObject(plugin.description),
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,
});
}),
);
});
}
// function getPluginList() {
// httpClient.getPlugins().then((value) => {
// setSortedPlugins(
// value.plugins.map((plugin) => {
// return new PluginCardVO({
// author: plugin.manifest.manifest.metadata.author ?? '',
// description: extractI18nObject(
// plugin.manifest.manifest.metadata.description ?? {
// en_US: '',
// zh_Hans: '',
// },
// ),
// enabled: plugin.enabled,
// name: plugin.manifest.manifest.metadata.name,
// version: plugin.manifest.manifest.metadata.version ?? '',
// status: plugin.status,
// components: plugin.components,
// install_source: plugin.install_source,
// install_info: plugin.install_info,
// priority: plugin.priority,
// debug: plugin.debug,
// });
// }),
// );
// });
// }
useEffect(() => {
if (open) {
getPluginList();
}
}, [open]);
// useEffect(() => {
// if (open) {
// getPluginList();
// }
// }, [open]);
const sensors = useSensors(
useSensor(PointerSensor),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
}),
);
// const sensors = useSensors(
// useSensor(PointerSensor),
// useSensor(KeyboardSensor, {
// coordinateGetter: sortableKeyboardCoordinates,
// }),
// );
function handleDragEnd(event: DragEndEvent) {
const { active, over } = event;
console.log('Drag end event:', { active, over });
// function handleDragEnd(event: DragEndEvent) {
// const { active, over } = event;
// console.log('Drag end event:', { active, over });
if (over && active.id !== over.id) {
setSortedPlugins((items) => {
const oldIndex = items.findIndex(
(item) => `${item.author}-${item.name}` === active.id,
);
const newIndex = items.findIndex(
(item) => `${item.author}-${item.name}` === over.id,
);
// if (over && active.id !== over.id) {
// setSortedPlugins((items) => {
// const oldIndex = items.findIndex(
// (item) => `${item.author}-${item.name}` === active.id,
// );
// const newIndex = items.findIndex(
// (item) => `${item.author}-${item.name}` === over.id,
// );
const newItems = arrayMove(items, oldIndex, newIndex);
// const newItems = arrayMove(items, oldIndex, newIndex);
return newItems;
});
}
}
// return newItems;
// });
// }
// }
function handleSave() {
setIsLoading(true);
// function handleSave() {
// setIsLoading(true);
const reorderElements: PluginReorderElement[] = sortedPlugins.map(
(plugin, index) => ({
author: plugin.author,
name: plugin.name,
priority: index,
}),
);
// const reorderElements: PluginReorderElement[] = sortedPlugins.map(
// (plugin, index) => ({
// author: plugin.author,
// name: plugin.name,
// priority: index,
// }),
// );
httpClient
.reorderPlugins(reorderElements)
.then(() => {
toast.success(t('plugins.pluginSortSuccess'));
onSortComplete();
onOpenChange(false);
})
.catch((err) => {
toast.error(t('plugins.pluginSortError') + err.message);
})
.finally(() => {
setIsLoading(false);
});
}
// httpClient
// .reorderPlugins(reorderElements)
// .then(() => {
// toast.success(t('plugins.pluginSortSuccess'));
// onSortComplete();
// onOpenChange(false);
// })
// .catch((err) => {
// toast.error(t('plugins.pluginSortError') + err.message);
// })
// .finally(() => {
// setIsLoading(false);
// });
// }
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="w-[700px] max-h-[80vh] p-0 flex flex-col">
<DialogHeader className="px-6 pt-6 pb-0">
<DialogTitle>{t('plugins.pluginSort')}</DialogTitle>
</DialogHeader>
<div className="flex-1 overflow-y-auto px-6 py-0">
<p className="text-sm text-gray-500 mb-4">
{t('plugins.pluginSortDescription')}
</p>
<DndContext
sensors={sensors}
collisionDetection={closestCenter}
onDragEnd={handleDragEnd}
>
<SortableContext
items={sortedPlugins.map(
(plugin) => `${plugin.author}-${plugin.name}`,
)}
strategy={verticalListSortingStrategy}
>
{sortedPlugins.map((plugin) => (
<SortablePluginItem
key={`${plugin.author}-${plugin.name}`}
plugin={plugin}
/>
))}
</SortableContext>
</DndContext>
</div>
<DialogFooter className="px-6 py-4">
<Button
variant="outline"
onClick={() => onOpenChange(false)}
disabled={isLoading}
>
{t('common.cancel')}
</Button>
<Button onClick={handleSave} disabled={isLoading}>
{isLoading ? t('common.saving') : t('common.save')}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
// return (
// <Dialog open={open} onOpenChange={onOpenChange}>
// <DialogContent className="w-[700px] max-h-[80vh] p-0 flex flex-col">
// <DialogHeader className="px-6 pt-6 pb-0">
// <DialogTitle>{t('plugins.pluginSort')}</DialogTitle>
// </DialogHeader>
// <div className="flex-1 overflow-y-auto px-6 py-0">
// <p className="text-sm text-gray-500 mb-4">
// {t('plugins.pluginSortDescription')}
// </p>
// <DndContext
// sensors={sensors}
// collisionDetection={closestCenter}
// onDragEnd={handleDragEnd}
// >
// <SortableContext
// items={sortedPlugins.map(
// (plugin) => `${plugin.author}-${plugin.name}`,
// )}
// strategy={verticalListSortingStrategy}
// >
// {sortedPlugins.map((plugin) => (
// <SortablePluginItem
// key={`${plugin.author}-${plugin.name}`}
// plugin={plugin}
// />
// ))}
// </SortableContext>
// </DndContext>
// </div>
// <DialogFooter className="px-6 py-4">
// <Button
// variant="outline"
// onClick={() => onOpenChange(false)}
// disabled={isLoading}
// >
// {t('common.cancel')}
// </Button>
// <Button onClick={handleSave} disabled={isLoading}>
// {isLoading ? t('common.saving') : t('common.save')}
// </Button>
// </DialogFooter>
// </DialogContent>
// </Dialog>
// );
// }