mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-30 14:17:14 +00:00
chore: remove plugin reorder functionality
This commit is contained in:
@@ -3,7 +3,7 @@ import PluginInstalledComponent, {
|
|||||||
PluginInstalledComponentRef,
|
PluginInstalledComponentRef,
|
||||||
} from '@/app/home/plugins/plugin-installed/PluginInstalledComponent';
|
} from '@/app/home/plugins/plugin-installed/PluginInstalledComponent';
|
||||||
import MarketPage from '@/app/home/plugins/plugin-market/PluginMarketComponent';
|
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 styles from './plugins.module.css';
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
@@ -44,7 +44,7 @@ enum PluginInstallStatus {
|
|||||||
export default function PluginConfigPage() {
|
export default function PluginConfigPage() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [modalOpen, setModalOpen] = useState(false);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
const [sortModalOpen, setSortModalOpen] = useState(false);
|
// const [sortModalOpen, setSortModalOpen] = useState(false);
|
||||||
const [activeTab, setActiveTab] = useState('installed');
|
const [activeTab, setActiveTab] = useState('installed');
|
||||||
const [installSource, setInstallSource] = useState<string>('local');
|
const [installSource, setInstallSource] = useState<string>('local');
|
||||||
const [installInfo, setInstallInfo] = useState<Record<string, any>>({}); // eslint-disable-line @typescript-eslint/no-explicit-any
|
const [installInfo, setInstallInfo] = useState<Record<string, any>>({}); // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
@@ -219,15 +219,15 @@ export default function PluginConfigPage() {
|
|||||||
</TabsList>
|
</TabsList>
|
||||||
|
|
||||||
<div className="flex flex-row justify-end items-center">
|
<div className="flex flex-row justify-end items-center">
|
||||||
<Button
|
{/* <Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
className="px-6 py-4 cursor-pointer mr-2"
|
className="px-6 py-4 cursor-pointer mr-2"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSortModalOpen(true);
|
// setSortModalOpen(true);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t('plugins.arrange')}
|
{t('plugins.arrange')}
|
||||||
</Button>
|
</Button> */}
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button variant="default" className="px-6 py-4 cursor-pointer">
|
<Button variant="default" className="px-6 py-4 cursor-pointer">
|
||||||
@@ -347,13 +347,13 @@ export default function PluginConfigPage() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<PluginSortDialog
|
{/* <PluginSortDialog
|
||||||
open={sortModalOpen}
|
open={sortModalOpen}
|
||||||
onOpenChange={setSortModalOpen}
|
onOpenChange={setSortModalOpen}
|
||||||
onSortComplete={() => {
|
onSortComplete={() => {
|
||||||
pluginInstalledRef.current?.refreshPluginList();
|
pluginInstalledRef.current?.refreshPluginList();
|
||||||
}}
|
}}
|
||||||
/>
|
/> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,209 +1,215 @@
|
|||||||
'use client';
|
// 'use client';
|
||||||
|
|
||||||
import * as React from 'react';
|
// import * as React from 'react';
|
||||||
import { useState, useEffect } from 'react';
|
// import { useState, useEffect } from 'react';
|
||||||
import { PluginCardVO } from '@/app/home/plugins/plugin-installed/PluginCardVO';
|
// import { PluginCardVO } from '@/app/home/plugins/plugin-installed/PluginCardVO';
|
||||||
import { httpClient } from '@/app/infra/http/HttpClient';
|
// import { httpClient } from '@/app/infra/http/HttpClient';
|
||||||
import { PluginReorderElement } from '@/app/infra/entities/api';
|
// import { PluginReorderElement } from '@/app/infra/entities/api';
|
||||||
import { toast } from 'sonner';
|
// import { toast } from 'sonner';
|
||||||
import {
|
// import {
|
||||||
Dialog,
|
// Dialog,
|
||||||
DialogContent,
|
// DialogContent,
|
||||||
DialogHeader,
|
// DialogHeader,
|
||||||
DialogTitle,
|
// DialogTitle,
|
||||||
DialogFooter,
|
// DialogFooter,
|
||||||
} from '@/components/ui/dialog';
|
// } from '@/components/ui/dialog';
|
||||||
import { Button } from '@/components/ui/button';
|
// import { Button } from '@/components/ui/button';
|
||||||
import {
|
// import {
|
||||||
DndContext,
|
// DndContext,
|
||||||
closestCenter,
|
// closestCenter,
|
||||||
KeyboardSensor,
|
// KeyboardSensor,
|
||||||
PointerSensor,
|
// PointerSensor,
|
||||||
useSensor,
|
// useSensor,
|
||||||
useSensors,
|
// useSensors,
|
||||||
DragEndEvent,
|
// DragEndEvent,
|
||||||
} from '@dnd-kit/core';
|
// } from '@dnd-kit/core';
|
||||||
import {
|
// import {
|
||||||
arrayMove,
|
// arrayMove,
|
||||||
SortableContext,
|
// SortableContext,
|
||||||
sortableKeyboardCoordinates,
|
// sortableKeyboardCoordinates,
|
||||||
useSortable,
|
// useSortable,
|
||||||
verticalListSortingStrategy,
|
// verticalListSortingStrategy,
|
||||||
} from '@dnd-kit/sortable';
|
// } from '@dnd-kit/sortable';
|
||||||
import { CSS } from '@dnd-kit/utilities';
|
// import { CSS } from '@dnd-kit/utilities';
|
||||||
import { useTranslation } from 'react-i18next';
|
// import { useTranslation } from 'react-i18next';
|
||||||
import { extractI18nObject } from '@/i18n/I18nProvider';
|
// import { extractI18nObject } from '@/i18n/I18nProvider';
|
||||||
|
|
||||||
interface PluginSortDialogProps {
|
// interface PluginSortDialogProps {
|
||||||
open: boolean;
|
// open: boolean;
|
||||||
onOpenChange: (open: boolean) => void;
|
// onOpenChange: (open: boolean) => void;
|
||||||
onSortComplete: () => void;
|
// onSortComplete: () => void;
|
||||||
}
|
// }
|
||||||
|
|
||||||
function SortablePluginItem({ plugin }: { plugin: PluginCardVO }) {
|
// function SortablePluginItem({ plugin }: { plugin: PluginCardVO }) {
|
||||||
const { attributes, listeners, setNodeRef, transform, transition } =
|
// const { attributes, listeners, setNodeRef, transform, transition } =
|
||||||
useSortable({
|
// useSortable({
|
||||||
id: `${plugin.author}-${plugin.name}`,
|
// id: `${plugin.author}-${plugin.name}`,
|
||||||
});
|
// });
|
||||||
|
|
||||||
const style = {
|
// const style = {
|
||||||
transform: CSS.Transform.toString(transform),
|
// transform: CSS.Transform.toString(transform),
|
||||||
transition,
|
// transition,
|
||||||
};
|
// };
|
||||||
|
|
||||||
return (
|
// return (
|
||||||
<div
|
// <div
|
||||||
ref={setNodeRef}
|
// ref={setNodeRef}
|
||||||
style={style}
|
// style={style}
|
||||||
{...attributes}
|
// {...attributes}
|
||||||
{...listeners}
|
// {...listeners}
|
||||||
className="bg-white dark:bg-gray-800 p-4 rounded-md shadow-sm border mb-2 cursor-move"
|
// 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="flex flex-col">
|
||||||
<div className="text-sm text-gray-600 dark:text-gray-400">
|
// <div className="text-sm text-gray-600 dark:text-gray-400">
|
||||||
{plugin.author}
|
// {plugin.author}
|
||||||
</div>
|
// </div>
|
||||||
<div className="text-lg font-medium">{plugin.name}</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">
|
// <div className="text-sm line-clamp-2 text-gray-500 dark:text-gray-400 mt-1">
|
||||||
{plugin.description}
|
// {plugin.description}
|
||||||
</div>
|
// </div>
|
||||||
</div>
|
// </div>
|
||||||
</div>
|
// </div>
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
export default function PluginSortDialog({
|
// export default function PluginSortDialog({
|
||||||
open,
|
// open,
|
||||||
onOpenChange,
|
// onOpenChange,
|
||||||
onSortComplete,
|
// onSortComplete,
|
||||||
}: PluginSortDialogProps) {
|
// }: PluginSortDialogProps) {
|
||||||
const { t } = useTranslation();
|
// const { t } = useTranslation();
|
||||||
const [sortedPlugins, setSortedPlugins] = useState<PluginCardVO[]>([]);
|
// const [sortedPlugins, setSortedPlugins] = useState<PluginCardVO[]>([]);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
// const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
function getPluginList() {
|
// function getPluginList() {
|
||||||
httpClient.getPlugins().then((value) => {
|
// httpClient.getPlugins().then((value) => {
|
||||||
setSortedPlugins(
|
// setSortedPlugins(
|
||||||
value.plugins.map((plugin) => {
|
// value.plugins.map((plugin) => {
|
||||||
return new PluginCardVO({
|
// return new PluginCardVO({
|
||||||
author: plugin.author,
|
// author: plugin.manifest.manifest.metadata.author ?? '',
|
||||||
description: extractI18nObject(plugin.description),
|
// description: extractI18nObject(
|
||||||
enabled: plugin.enabled,
|
// plugin.manifest.manifest.metadata.description ?? {
|
||||||
name: plugin.name,
|
// en_US: '',
|
||||||
version: plugin.version,
|
// zh_Hans: '',
|
||||||
status: plugin.status,
|
// },
|
||||||
tools: plugin.tools,
|
// ),
|
||||||
event_handlers: plugin.event_handlers,
|
// enabled: plugin.enabled,
|
||||||
repository: plugin.repository,
|
// name: plugin.manifest.manifest.metadata.name,
|
||||||
priority: plugin.priority,
|
// 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(() => {
|
// useEffect(() => {
|
||||||
if (open) {
|
// if (open) {
|
||||||
getPluginList();
|
// getPluginList();
|
||||||
}
|
// }
|
||||||
}, [open]);
|
// }, [open]);
|
||||||
|
|
||||||
const sensors = useSensors(
|
// const sensors = useSensors(
|
||||||
useSensor(PointerSensor),
|
// useSensor(PointerSensor),
|
||||||
useSensor(KeyboardSensor, {
|
// useSensor(KeyboardSensor, {
|
||||||
coordinateGetter: sortableKeyboardCoordinates,
|
// coordinateGetter: sortableKeyboardCoordinates,
|
||||||
}),
|
// }),
|
||||||
);
|
// );
|
||||||
|
|
||||||
function handleDragEnd(event: DragEndEvent) {
|
// function handleDragEnd(event: DragEndEvent) {
|
||||||
const { active, over } = event;
|
// const { active, over } = event;
|
||||||
console.log('Drag end event:', { active, over });
|
// console.log('Drag end event:', { active, over });
|
||||||
|
|
||||||
if (over && active.id !== over.id) {
|
// if (over && active.id !== over.id) {
|
||||||
setSortedPlugins((items) => {
|
// setSortedPlugins((items) => {
|
||||||
const oldIndex = items.findIndex(
|
// const oldIndex = items.findIndex(
|
||||||
(item) => `${item.author}-${item.name}` === active.id,
|
// (item) => `${item.author}-${item.name}` === active.id,
|
||||||
);
|
// );
|
||||||
const newIndex = items.findIndex(
|
// const newIndex = items.findIndex(
|
||||||
(item) => `${item.author}-${item.name}` === over.id,
|
// (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() {
|
// function handleSave() {
|
||||||
setIsLoading(true);
|
// setIsLoading(true);
|
||||||
|
|
||||||
const reorderElements: PluginReorderElement[] = sortedPlugins.map(
|
// const reorderElements: PluginReorderElement[] = sortedPlugins.map(
|
||||||
(plugin, index) => ({
|
// (plugin, index) => ({
|
||||||
author: plugin.author,
|
// author: plugin.author,
|
||||||
name: plugin.name,
|
// name: plugin.name,
|
||||||
priority: index,
|
// priority: index,
|
||||||
}),
|
// }),
|
||||||
);
|
// );
|
||||||
|
|
||||||
httpClient
|
// httpClient
|
||||||
.reorderPlugins(reorderElements)
|
// .reorderPlugins(reorderElements)
|
||||||
.then(() => {
|
// .then(() => {
|
||||||
toast.success(t('plugins.pluginSortSuccess'));
|
// toast.success(t('plugins.pluginSortSuccess'));
|
||||||
onSortComplete();
|
// onSortComplete();
|
||||||
onOpenChange(false);
|
// onOpenChange(false);
|
||||||
})
|
// })
|
||||||
.catch((err) => {
|
// .catch((err) => {
|
||||||
toast.error(t('plugins.pluginSortError') + err.message);
|
// toast.error(t('plugins.pluginSortError') + err.message);
|
||||||
})
|
// })
|
||||||
.finally(() => {
|
// .finally(() => {
|
||||||
setIsLoading(false);
|
// setIsLoading(false);
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
return (
|
// return (
|
||||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
// <Dialog open={open} onOpenChange={onOpenChange}>
|
||||||
<DialogContent className="w-[700px] max-h-[80vh] p-0 flex flex-col">
|
// <DialogContent className="w-[700px] max-h-[80vh] p-0 flex flex-col">
|
||||||
<DialogHeader className="px-6 pt-6 pb-0">
|
// <DialogHeader className="px-6 pt-6 pb-0">
|
||||||
<DialogTitle>{t('plugins.pluginSort')}</DialogTitle>
|
// <DialogTitle>{t('plugins.pluginSort')}</DialogTitle>
|
||||||
</DialogHeader>
|
// </DialogHeader>
|
||||||
<div className="flex-1 overflow-y-auto px-6 py-0">
|
// <div className="flex-1 overflow-y-auto px-6 py-0">
|
||||||
<p className="text-sm text-gray-500 mb-4">
|
// <p className="text-sm text-gray-500 mb-4">
|
||||||
{t('plugins.pluginSortDescription')}
|
// {t('plugins.pluginSortDescription')}
|
||||||
</p>
|
// </p>
|
||||||
<DndContext
|
// <DndContext
|
||||||
sensors={sensors}
|
// sensors={sensors}
|
||||||
collisionDetection={closestCenter}
|
// collisionDetection={closestCenter}
|
||||||
onDragEnd={handleDragEnd}
|
// onDragEnd={handleDragEnd}
|
||||||
>
|
// >
|
||||||
<SortableContext
|
// <SortableContext
|
||||||
items={sortedPlugins.map(
|
// items={sortedPlugins.map(
|
||||||
(plugin) => `${plugin.author}-${plugin.name}`,
|
// (plugin) => `${plugin.author}-${plugin.name}`,
|
||||||
)}
|
// )}
|
||||||
strategy={verticalListSortingStrategy}
|
// strategy={verticalListSortingStrategy}
|
||||||
>
|
// >
|
||||||
{sortedPlugins.map((plugin) => (
|
// {sortedPlugins.map((plugin) => (
|
||||||
<SortablePluginItem
|
// <SortablePluginItem
|
||||||
key={`${plugin.author}-${plugin.name}`}
|
// key={`${plugin.author}-${plugin.name}`}
|
||||||
plugin={plugin}
|
// plugin={plugin}
|
||||||
/>
|
// />
|
||||||
))}
|
// ))}
|
||||||
</SortableContext>
|
// </SortableContext>
|
||||||
</DndContext>
|
// </DndContext>
|
||||||
</div>
|
// </div>
|
||||||
<DialogFooter className="px-6 py-4">
|
// <DialogFooter className="px-6 py-4">
|
||||||
<Button
|
// <Button
|
||||||
variant="outline"
|
// variant="outline"
|
||||||
onClick={() => onOpenChange(false)}
|
// onClick={() => onOpenChange(false)}
|
||||||
disabled={isLoading}
|
// disabled={isLoading}
|
||||||
>
|
// >
|
||||||
{t('common.cancel')}
|
// {t('common.cancel')}
|
||||||
</Button>
|
// </Button>
|
||||||
<Button onClick={handleSave} disabled={isLoading}>
|
// <Button onClick={handleSave} disabled={isLoading}>
|
||||||
{isLoading ? t('common.saving') : t('common.save')}
|
// {isLoading ? t('common.saving') : t('common.save')}
|
||||||
</Button>
|
// </Button>
|
||||||
</DialogFooter>
|
// </DialogFooter>
|
||||||
</DialogContent>
|
// </DialogContent>
|
||||||
</Dialog>
|
// </Dialog>
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|||||||
Reference in New Issue
Block a user