mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-29 08:33:20 +00:00
(feat:config) custom name
This commit is contained in:
@@ -119,7 +119,10 @@
|
||||
"settingsIconAlt": "Settings icon",
|
||||
"configureToolAria": "Configure {toolName}",
|
||||
"toggleToolAria": "Toggle {toolName}",
|
||||
"manageTools": "Go to Tools"
|
||||
"manageTools": "Go to Tools",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"deleteWarning": "Are you sure you want to delete {toolName}?"
|
||||
}
|
||||
},
|
||||
"modals": {
|
||||
|
||||
@@ -28,6 +28,9 @@ export default function ToolConfig({
|
||||
const [authKey, setAuthKey] = React.useState<string>(
|
||||
'token' in tool.config ? tool.config.token : '',
|
||||
);
|
||||
const [customName, setCustomName] = React.useState<string>(
|
||||
tool.customName || '',
|
||||
);
|
||||
const [actionModalState, setActionModalState] =
|
||||
React.useState<ActiveState>('INACTIVE');
|
||||
const { t } = useTranslation();
|
||||
@@ -66,6 +69,7 @@ export default function ToolConfig({
|
||||
id: tool.id,
|
||||
name: tool.name,
|
||||
displayName: tool.displayName,
|
||||
customName: customName,
|
||||
description: tool.description,
|
||||
config: tool.name === 'api_tool' ? tool.config : { token: authKey },
|
||||
actions: 'actions' in tool ? tool.actions : [],
|
||||
@@ -132,6 +136,21 @@ export default function ToolConfig({
|
||||
{tool.name}
|
||||
</p>
|
||||
</div>
|
||||
{/* Custom name section */}
|
||||
<div className="mt-1">
|
||||
<p className="text-sm font-semibold text-eerie-black dark:text-bright-gray">
|
||||
Custom Name
|
||||
</p>
|
||||
<div className="relative mt-4 w-96">
|
||||
<Input
|
||||
type="text"
|
||||
value={customName}
|
||||
onChange={(e) => setCustomName(e.target.value)}
|
||||
borderVariant="thin"
|
||||
placeholder="Enter a custom name (optional)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-1">
|
||||
{Object.keys(tool?.config).length !== 0 && tool.name !== 'api_tool' && (
|
||||
<p className="text-sm font-semibold text-eerie-black dark:text-bright-gray">
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import userService from '../api/services/userService';
|
||||
import CogwheelIcon from '../assets/cogwheel.svg';
|
||||
import ThreeDotsIcon from '../assets/three-dots.svg';
|
||||
import NoFilesIcon from '../assets/no-files.svg';
|
||||
import NoFilesDarkIcon from '../assets/no-files-dark.svg';
|
||||
import Input from '../components/Input';
|
||||
@@ -15,6 +15,10 @@ import { ActiveState } from '../models/misc';
|
||||
import { selectToken } from '../preferences/preferenceSlice';
|
||||
import ToolConfig from './ToolConfig';
|
||||
import { APIToolType, UserToolType } from './types';
|
||||
import ContextMenu, { MenuOption } from '../components/ContextMenu';
|
||||
import Edit from '../assets/edit.svg';
|
||||
import Trash from '../assets/red-trash.svg';
|
||||
import ConfirmationModal from '../modals/ConfirmationModal';
|
||||
|
||||
export default function Tools() {
|
||||
const { t } = useTranslation();
|
||||
@@ -29,6 +33,57 @@ export default function Tools() {
|
||||
UserToolType | APIToolType | null
|
||||
>(null);
|
||||
const [loading, setLoading] = React.useState(false);
|
||||
const [activeMenuId, setActiveMenuId] = React.useState<string | null>(null);
|
||||
const menuRefs = React.useRef<{
|
||||
[key: string]: React.RefObject<HTMLDivElement>;
|
||||
}>({});
|
||||
const [deleteModalState, setDeleteModalState] =
|
||||
React.useState<ActiveState>('INACTIVE');
|
||||
const [toolToDelete, setToolToDelete] = React.useState<UserToolType | null>(
|
||||
null,
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
userTools.forEach((tool) => {
|
||||
if (!menuRefs.current[tool.id]) {
|
||||
menuRefs.current[tool.id] = React.createRef();
|
||||
}
|
||||
});
|
||||
}, [userTools]);
|
||||
|
||||
const handleDeleteTool = (tool: UserToolType) => {
|
||||
setToolToDelete(tool);
|
||||
setDeleteModalState('ACTIVE');
|
||||
};
|
||||
|
||||
const confirmDeleteTool = () => {
|
||||
if (toolToDelete) {
|
||||
userService.deleteTool({ id: toolToDelete.id }, token).then(() => {
|
||||
getUserTools();
|
||||
setDeleteModalState('INACTIVE');
|
||||
setToolToDelete(null);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const getMenuOptions = (tool: UserToolType): MenuOption[] => [
|
||||
{
|
||||
icon: Edit,
|
||||
label: t('settings.tools.edit'),
|
||||
onClick: () => handleSettingsClick(tool),
|
||||
variant: 'primary',
|
||||
iconWidth: 14,
|
||||
iconHeight: 14,
|
||||
},
|
||||
{
|
||||
icon: Trash,
|
||||
label: t('settings.tools.delete'),
|
||||
onClick: () => handleDeleteTool(tool),
|
||||
variant: 'danger',
|
||||
iconWidth: 18,
|
||||
iconHeight: 18,
|
||||
},
|
||||
];
|
||||
|
||||
const getUserTools = () => {
|
||||
setLoading(true);
|
||||
@@ -157,21 +212,34 @@ export default function Tools() {
|
||||
.map((tool, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="relative flex h-52 w-[300px] flex-col justify-between rounded-2xl border border-light-gainsboro bg-white-3000 p-6 dark:border-arsenic dark:bg-transparent"
|
||||
className="relative flex h-52 w-[300px] flex-col justify-between rounded-2xl bg-[#F5F5F5] p-6 hover:bg-[#ECECEC] dark:bg-[#383838] dark:hover:bg-[#303030]"
|
||||
>
|
||||
<button
|
||||
onClick={() => handleSettingsClick(tool)}
|
||||
aria-label={t('settings.tools.configureToolAria', {
|
||||
toolName: tool.displayName,
|
||||
})}
|
||||
className="absolute right-4 top-4"
|
||||
<div
|
||||
ref={menuRefs.current[tool.id]}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setActiveMenuId(
|
||||
activeMenuId === tool.id ? null : tool.id,
|
||||
);
|
||||
}}
|
||||
className="absolute right-4 top-4 z-10 cursor-pointer"
|
||||
>
|
||||
<img
|
||||
src={CogwheelIcon}
|
||||
src={ThreeDotsIcon}
|
||||
alt={t('settings.tools.settingsIconAlt')}
|
||||
className="h-[19px] w-[19px]"
|
||||
/>
|
||||
</button>
|
||||
<ContextMenu
|
||||
isOpen={activeMenuId === tool.id}
|
||||
setIsOpen={(isOpen) => {
|
||||
setActiveMenuId(isOpen ? tool.id : null);
|
||||
}}
|
||||
options={getMenuOptions(tool)}
|
||||
anchorRef={menuRefs.current[tool.id]}
|
||||
position="top-right"
|
||||
offset={{ x: 0, y: 0 }}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<div className="flex w-full items-center px-1">
|
||||
<img
|
||||
@@ -218,6 +286,16 @@ export default function Tools() {
|
||||
getUserTools={getUserTools}
|
||||
onToolAdded={handleToolAdded}
|
||||
/>
|
||||
<ConfirmationModal
|
||||
message={t('settings.tools.deleteWarning', {
|
||||
toolName: toolToDelete?.displayName || '',
|
||||
})}
|
||||
modalState={deleteModalState}
|
||||
setModalState={setDeleteModalState}
|
||||
handleSubmit={confirmDeleteTool}
|
||||
submitLabel={t('settings.tools.delete')}
|
||||
variant="danger"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -41,6 +41,7 @@ export type UserToolType = {
|
||||
id: string;
|
||||
name: string;
|
||||
displayName: string;
|
||||
customName?: string;
|
||||
description: string;
|
||||
status: boolean;
|
||||
config: {
|
||||
@@ -81,6 +82,7 @@ export type APIToolType = {
|
||||
id: string;
|
||||
name: string;
|
||||
displayName: string;
|
||||
customName?: string;
|
||||
description: string;
|
||||
status: boolean;
|
||||
config: { actions: { [key: string]: APIActionType } };
|
||||
|
||||
Reference in New Issue
Block a user