mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-30 17:13:15 +00:00
294 lines
12 KiB
TypeScript
294 lines
12 KiB
TypeScript
import React from 'react';
|
|
|
|
import userService from '../api/services/userService';
|
|
import ArrowLeft from '../assets/arrow-left.svg';
|
|
import Input from '../components/Input';
|
|
import { UserTool } from './types';
|
|
|
|
export default function ToolConfig({
|
|
tool,
|
|
setTool,
|
|
handleGoBack,
|
|
}: {
|
|
tool: UserTool;
|
|
setTool: (tool: UserTool) => void;
|
|
handleGoBack: () => void;
|
|
}) {
|
|
const [authKey, setAuthKey] = React.useState<string>(
|
|
tool.config?.token || '',
|
|
);
|
|
|
|
const handleCheckboxChange = (actionIndex: number, property: string) => {
|
|
setTool({
|
|
...tool,
|
|
actions: tool.actions.map((action, index) => {
|
|
if (index === actionIndex) {
|
|
return {
|
|
...action,
|
|
parameters: {
|
|
...action.parameters,
|
|
properties: {
|
|
...action.parameters.properties,
|
|
[property]: {
|
|
...action.parameters.properties[property],
|
|
filled_by_llm:
|
|
!action.parameters.properties[property].filled_by_llm,
|
|
},
|
|
},
|
|
},
|
|
};
|
|
}
|
|
return action;
|
|
}),
|
|
});
|
|
};
|
|
|
|
const handleSaveChanges = () => {
|
|
userService
|
|
.updateTool({
|
|
id: tool.id,
|
|
name: tool.name,
|
|
displayName: tool.displayName,
|
|
description: tool.description,
|
|
config: { token: authKey },
|
|
actions: tool.actions,
|
|
status: tool.status,
|
|
})
|
|
.then(() => {
|
|
handleGoBack();
|
|
});
|
|
};
|
|
return (
|
|
<div className="mt-8 flex flex-col gap-4">
|
|
<div className="mb-4 flex items-center gap-3 text-eerie-black dark:text-bright-gray text-sm">
|
|
<button
|
|
className="text-sm text-gray-400 dark:text-gray-500 border dark:border-0 dark:bg-[#28292D] dark:hover:bg-[#2E2F34] p-3 rounded-full"
|
|
onClick={handleGoBack}
|
|
>
|
|
<img src={ArrowLeft} alt="left-arrow" className="w-3 h-3" />
|
|
</button>
|
|
<p className="mt-px">Back to all tools</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-sm font-semibold text-eerie-black dark:text-bright-gray">
|
|
Type
|
|
</p>
|
|
<p className="mt-1 text-base font-normal text-eerie-black dark:text-bright-gray font-sans">
|
|
{tool.name}
|
|
</p>
|
|
</div>
|
|
<div className="mt-1">
|
|
{Object.keys(tool?.config).length !== 0 && (
|
|
<p className="text-sm font-semibold text-eerie-black dark:text-bright-gray">
|
|
Authentication
|
|
</p>
|
|
)}
|
|
<div className="mt-4 flex items-center gap-2">
|
|
{Object.keys(tool?.config).length !== 0 && (
|
|
<div className="relative w-96">
|
|
<span className="absolute left-5 -top-2 bg-white px-2 text-xs text-gray-4000 dark:bg-[#26272E] dark:text-silver">
|
|
API Key / Oauth
|
|
</span>
|
|
<Input
|
|
type="text"
|
|
value={authKey}
|
|
onChange={(e) => setAuthKey(e.target.value)}
|
|
borderVariant="thin"
|
|
placeholder="Enter API Key / Oauth"
|
|
></Input>
|
|
</div>
|
|
)}
|
|
<button
|
|
className="rounded-full h-10 w-36 bg-purple-30 text-white hover:bg-[#6F3FD1] text-nowrap text-sm"
|
|
onClick={handleSaveChanges}
|
|
>
|
|
Save changes
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div className="flex flex-col gap-4">
|
|
<div className="mx-1 my-2 h-[0.8px] w-full rounded-full bg-[#C4C4C4]/40 lg:w-[95%] "></div>
|
|
<p className="text-base font-semibold text-eerie-black dark:text-bright-gray">
|
|
Actions
|
|
</p>
|
|
<div className="flex flex-col gap-10">
|
|
{tool.actions.map((action, actionIndex) => {
|
|
return (
|
|
<div
|
|
key={actionIndex}
|
|
className="w-full border border-silver dark:border-silver/40 rounded-xl"
|
|
>
|
|
<div className="h-10 bg-[#F9F9F9] dark:bg-[#28292D] rounded-t-xl border-b border-silver dark:border-silver/40 flex items-center justify-between px-5">
|
|
<p className="font-semibold text-eerie-black dark:text-bright-gray">
|
|
{action.name}
|
|
</p>
|
|
<label
|
|
htmlFor={`actionToggle-${actionIndex}`}
|
|
className="relative inline-block h-6 w-10 cursor-pointer rounded-full bg-gray-300 dark:bg-[#D2D5DA33]/20 transition [-webkit-tap-highlight-color:_transparent] has-[:checked]:bg-[#0C9D35CC] has-[:checked]:dark:bg-[#0C9D35CC]"
|
|
>
|
|
<input
|
|
type="checkbox"
|
|
id={`actionToggle-${actionIndex}`}
|
|
className="peer sr-only"
|
|
checked={action.active}
|
|
onChange={() => {
|
|
setTool({
|
|
...tool,
|
|
actions: tool.actions.map((act, index) => {
|
|
if (index === actionIndex) {
|
|
return { ...act, active: !act.active };
|
|
}
|
|
return act;
|
|
}),
|
|
});
|
|
}}
|
|
/>
|
|
<span className="absolute inset-y-0 start-0 m-[3px] size-[18px] rounded-full bg-white transition-all peer-checked:start-4"></span>
|
|
</label>
|
|
</div>
|
|
<div className="mt-5 relative px-5 w-96">
|
|
<Input
|
|
type="text"
|
|
placeholder="Enter description"
|
|
value={action.description}
|
|
onChange={(e) => {
|
|
setTool({
|
|
...tool,
|
|
actions: tool.actions.map((act, index) => {
|
|
if (index === actionIndex) {
|
|
return {
|
|
...act,
|
|
description: e.target.value,
|
|
};
|
|
}
|
|
return act;
|
|
}),
|
|
});
|
|
}}
|
|
borderVariant="thin"
|
|
></Input>
|
|
</div>
|
|
<div className="px-5 py-4">
|
|
<table className="table-default">
|
|
<thead>
|
|
<tr>
|
|
<th>Field Name</th>
|
|
<th>Field Type</th>
|
|
<th>Filled by LLM</th>
|
|
<th>FIeld description</th>
|
|
<th>Value</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{Object.entries(action.parameters?.properties).map(
|
|
(param, index) => {
|
|
const uniqueKey = `${actionIndex}-${param[0]}`;
|
|
return (
|
|
<tr key={index} className="text-nowrap font-normal">
|
|
<td>{param[0]}</td>
|
|
<td>{param[1].type}</td>
|
|
<td>
|
|
<label
|
|
htmlFor={uniqueKey}
|
|
className="ml-[10px] flex cursor-pointer items-start gap-4"
|
|
>
|
|
<div className="flex items-center">
|
|
​
|
|
<input
|
|
checked={param[1].filled_by_llm}
|
|
id={uniqueKey}
|
|
type="checkbox"
|
|
className="size-4 rounded border-gray-300 bg-transparent"
|
|
onChange={() =>
|
|
handleCheckboxChange(
|
|
actionIndex,
|
|
param[0],
|
|
)
|
|
}
|
|
/>
|
|
</div>
|
|
</label>
|
|
</td>
|
|
<td className="w-10">
|
|
<input
|
|
key={uniqueKey}
|
|
value={param[1].description}
|
|
className="bg-transparent border border-silver dark:border-silver/40 outline-none px-2 py-1 rounded-lg text-sm"
|
|
onChange={(e) => {
|
|
setTool({
|
|
...tool,
|
|
actions: tool.actions.map(
|
|
(act, index) => {
|
|
if (index === actionIndex) {
|
|
return {
|
|
...act,
|
|
parameters: {
|
|
...act.parameters,
|
|
properties: {
|
|
...act.parameters.properties,
|
|
[param[0]]: {
|
|
...act.parameters
|
|
.properties[param[0]],
|
|
description: e.target.value,
|
|
},
|
|
},
|
|
},
|
|
};
|
|
}
|
|
return act;
|
|
},
|
|
),
|
|
});
|
|
}}
|
|
></input>
|
|
</td>
|
|
<td>
|
|
<input
|
|
value={param[1].value}
|
|
key={uniqueKey}
|
|
disabled={param[1].filled_by_llm}
|
|
className={`bg-transparent border border-silver dark:border-silver/40 outline-none px-2 py-1 rounded-lg text-sm ${param[1].filled_by_llm ? 'opacity-50' : ''}`}
|
|
onChange={(e) => {
|
|
setTool({
|
|
...tool,
|
|
actions: tool.actions.map(
|
|
(act, index) => {
|
|
if (index === actionIndex) {
|
|
return {
|
|
...act,
|
|
parameters: {
|
|
...act.parameters,
|
|
properties: {
|
|
...act.parameters.properties,
|
|
[param[0]]: {
|
|
...act.parameters
|
|
.properties[param[0]],
|
|
value: e.target.value,
|
|
},
|
|
},
|
|
},
|
|
};
|
|
}
|
|
return act;
|
|
},
|
|
),
|
|
});
|
|
}}
|
|
></input>
|
|
</td>
|
|
</tr>
|
|
);
|
|
},
|
|
)}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|