diff --git a/frontend/src/index.css b/frontend/src/index.css index 4c1bb30f..ee9aa0c2 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -46,6 +46,31 @@ body.dark { -ms-overflow-style: none; /* IE and Edge */ scrollbar-width: none; /* Firefox */ } + + /* Thin scrollbar utility */ + .scrollbar-thin::-webkit-scrollbar { + width: 6px; + height: 6px; + } + + .scrollbar-thin::-webkit-scrollbar-track { + background: transparent; + } + + .scrollbar-thin::-webkit-scrollbar-thumb { + background: rgba(156, 163, 175, 0.5); + border-radius: 3px; + } + + .scrollbar-thin::-webkit-scrollbar-thumb:hover { + background: rgba(156, 163, 175, 0.7); + } + + /* For Firefox */ + .scrollbar-thin { + scrollbar-width: thin; + scrollbar-color: rgba(156, 163, 175, 0.5) transparent; + } } @layer components { diff --git a/frontend/src/settings/ToolConfig.tsx b/frontend/src/settings/ToolConfig.tsx index 0908b78c..50b67d0d 100644 --- a/frontend/src/settings/ToolConfig.tsx +++ b/frontend/src/settings/ToolConfig.tsx @@ -10,6 +10,7 @@ import Dropdown from '../components/Dropdown'; import Input from '../components/Input'; import ToggleSwitch from '../components/ToggleSwitch'; import AddActionModal from '../modals/AddActionModal'; +import ConfirmationModal from '../modals/ConfirmationModal'; import { ActiveState } from '../models/misc'; import { selectToken } from '../preferences/preferenceSlice'; import { APIActionType, APIToolType, UserToolType } from './types'; @@ -118,7 +119,7 @@ export default function ToolConfig({ }); }; return ( -
+
- )}
{tool.name === 'api_tool' ? ( - + <> + +
+ +
+ ) : (
{'actions' in tool && @@ -388,6 +389,34 @@ function APIToolConfig({ setTool: (tool: APIToolType) => void; }) { const [apiTool, setApiTool] = React.useState(tool); + const { t } = useTranslation(); + const [actionToDelete, setActionToDelete] = React.useState( + null, + ); + const [deleteModalState, setDeleteModalState] = + React.useState('INACTIVE'); + + const handleDeleteActionClick = (actionName: string) => { + setActionToDelete(actionName); + setDeleteModalState('ACTIVE'); + }; + const handleConfirmedDelete = () => { + if (actionToDelete) { + setApiTool((prevApiTool) => { + const { [actionToDelete]: deletedAction, ...remainingActions } = + prevApiTool.config.actions; + return { + ...prevApiTool, + config: { + ...prevApiTool.config, + actions: remainingActions, + }, + }; + }); + setActionToDelete(null); + setDeleteModalState('INACTIVE'); + } + }; const handleActionChange = ( actionName: string, @@ -424,19 +453,31 @@ function APIToolConfig({ setTool(apiTool); }, [apiTool]); return ( -
+
+ {/* Actions list */} {apiTool.config.actions && Object.entries(apiTool.config.actions).map( - ([actionName, action], actionIndex) => { - return ( -
-
-

- {action.name} -

+ ([actionName, action], actionIndex) => ( +
+
+

+ {action.name} +

+
+ handleActionToggle(actionName)} @@ -444,117 +485,136 @@ function APIToolConfig({ id={`actionToggle-${actionIndex}`} />
-
-
- - URL - - { - setApiTool((prevApiTool) => { - const updatedActions = { - ...prevApiTool.config.actions, - }; - const updatedAction = { - ...updatedActions[actionName], - }; - updatedAction.url = e.target.value; - updatedActions[actionName] = updatedAction; - return { - ...prevApiTool, - config: { - ...prevApiTool.config, - actions: updatedActions, - }, - }; - }); - }} - borderVariant="thin" - placeholder="Enter url" - > -
+
+
+
+ + URL + + { + setApiTool((prevApiTool) => { + const updatedActions = { + ...prevApiTool.config.actions, + }; + const updatedAction = { + ...updatedActions[actionName], + }; + updatedAction.url = e.target.value; + updatedActions[actionName] = updatedAction; + return { + ...prevApiTool, + config: { + ...prevApiTool.config, + actions: updatedActions, + }, + }; + }); + }} + borderVariant="thin" + placeholder="Enter url" + >
-
-
- - Method - - { - setApiTool((prevApiTool) => { - const updatedActions = { - ...prevApiTool.config.actions, - }; - const updatedAction = { - ...updatedActions[actionName], - }; - updatedAction.method = value as - | 'GET' - | 'POST' - | 'PUT' - | 'DELETE'; - updatedActions[actionName] = updatedAction; - return { - ...prevApiTool, - config: { - ...prevApiTool.config, - actions: updatedActions, - }, - }; - }); - }} - size="w-56" - rounded="3xl" - border="border" - /> -
-
-
-
- - Description - - { - setApiTool((prevApiTool) => { - const updatedActions = { - ...prevApiTool.config.actions, - }; - const updatedAction = { - ...updatedActions[actionName], - }; - updatedAction.description = e.target.value; - updatedActions[actionName] = updatedAction; - return { - ...prevApiTool, - config: { - ...prevApiTool.config, - actions: updatedActions, - }, - }; - }); - }} - borderVariant="thin" - placeholder="Enter description" - > -
-
-
- +
+
+ + Method + + { + setApiTool((prevApiTool) => { + const updatedActions = { + ...prevApiTool.config.actions, + }; + const updatedAction = { + ...updatedActions[actionName], + }; + updatedAction.method = value as + | 'GET' + | 'POST' + | 'PUT' + | 'DELETE'; + updatedActions[actionName] = updatedAction; + return { + ...prevApiTool, + config: { + ...prevApiTool.config, + actions: updatedActions, + }, + }; + }); + }} + size="w-56" + rounded="3xl" + border="border" />
- ); - }, +
+
+ + Description + + { + setApiTool((prevApiTool) => { + const updatedActions = { + ...prevApiTool.config.actions, + }; + const updatedAction = { + ...updatedActions[actionName], + }; + updatedAction.description = e.target.value; + updatedActions[actionName] = updatedAction; + return { + ...prevApiTool, + config: { + ...prevApiTool.config, + actions: updatedActions, + }, + }; + }); + }} + borderVariant="thin" + placeholder="Enter description" + > +
+
+
+ +
+
+ ), )} + + {/* Confirmation Modal */} + {deleteModalState === 'ACTIVE' && actionToDelete && ( + { + setDeleteModalState('INACTIVE'); + setActionToDelete(null); + }} + submitLabel={t('convTile.delete')} + variant="danger" + /> + )}
); } @@ -883,7 +943,7 @@ function APIActionTable({ ); }; return ( -
+

Headers