|
@@ -1,5 +1,5 @@
|
|
|
import React from "react";
|
|
import React from "react";
|
|
|
-import { useSelector } from "react-redux";
|
|
|
|
|
|
|
+import { useDispatch, useSelector } from "react-redux";
|
|
|
import { useTranslation } from "react-i18next";
|
|
import { useTranslation } from "react-i18next";
|
|
|
import AgentState from "#/types/agent-state";
|
|
import AgentState from "#/types/agent-state";
|
|
|
import { ExplorerTree } from "#/components/features/file-explorer/explorer-tree";
|
|
import { ExplorerTree } from "#/components/features/file-explorer/explorer-tree";
|
|
@@ -14,6 +14,7 @@ import { Dropzone } from "./dropzone";
|
|
|
import { FileExplorerHeader } from "./file-explorer-header";
|
|
import { FileExplorerHeader } from "./file-explorer-header";
|
|
|
import { useVSCodeUrl } from "#/hooks/query/use-vscode-url";
|
|
import { useVSCodeUrl } from "#/hooks/query/use-vscode-url";
|
|
|
import { OpenVSCodeButton } from "#/components/shared/buttons/open-vscode-button";
|
|
import { OpenVSCodeButton } from "#/components/shared/buttons/open-vscode-button";
|
|
|
|
|
+import { addAssistantMessage } from "#/state/chat-slice";
|
|
|
|
|
|
|
|
interface FileExplorerProps {
|
|
interface FileExplorerProps {
|
|
|
isOpen: boolean;
|
|
isOpen: boolean;
|
|
@@ -22,15 +23,37 @@ interface FileExplorerProps {
|
|
|
|
|
|
|
|
export function FileExplorer({ isOpen, onToggle }: FileExplorerProps) {
|
|
export function FileExplorer({ isOpen, onToggle }: FileExplorerProps) {
|
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
|
|
|
+ const dispatch = useDispatch();
|
|
|
|
|
|
|
|
const fileInputRef = React.useRef<HTMLInputElement | null>(null);
|
|
const fileInputRef = React.useRef<HTMLInputElement | null>(null);
|
|
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
|
|
|
|
|
|
const { curAgentState } = useSelector((state: RootState) => state.agent);
|
|
const { curAgentState } = useSelector((state: RootState) => state.agent);
|
|
|
|
|
|
|
|
|
|
+ const agentIsReady =
|
|
|
|
|
+ curAgentState !== AgentState.INIT && curAgentState !== AgentState.LOADING;
|
|
|
|
|
+
|
|
|
const { data: paths, refetch, error } = useListFiles();
|
|
const { data: paths, refetch, error } = useListFiles();
|
|
|
const { mutate: uploadFiles } = useUploadFiles();
|
|
const { mutate: uploadFiles } = useUploadFiles();
|
|
|
- const { refetch: getVSCodeUrl } = useVSCodeUrl();
|
|
|
|
|
|
|
+ const { data: vscodeUrl } = useVSCodeUrl({ enabled: agentIsReady });
|
|
|
|
|
+
|
|
|
|
|
+ const handleOpenVSCode = () => {
|
|
|
|
|
+ if (vscodeUrl?.vscode_url) {
|
|
|
|
|
+ dispatch(
|
|
|
|
|
+ addAssistantMessage(
|
|
|
|
|
+ "You opened VS Code. Please inform the agent of any changes you made to the workspace or environment. To avoid conflicts, it's best to pause the agent before making any changes.",
|
|
|
|
|
+ ),
|
|
|
|
|
+ );
|
|
|
|
|
+ window.open(vscodeUrl.vscode_url, "_blank");
|
|
|
|
|
+ } else if (vscodeUrl?.error) {
|
|
|
|
|
+ toast.error(
|
|
|
|
|
+ `open-vscode-error-${new Date().getTime()}`,
|
|
|
|
|
+ t(I18nKey.EXPLORER$VSCODE_SWITCHING_ERROR_MESSAGE, {
|
|
|
|
|
+ error: vscodeUrl.error,
|
|
|
|
|
+ }),
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
const selectFileInput = () => {
|
|
const selectFileInput = () => {
|
|
|
fileInputRef.current?.click(); // Trigger the file browser
|
|
fileInputRef.current?.click(); // Trigger the file browser
|
|
@@ -142,11 +165,8 @@ export function FileExplorer({ isOpen, onToggle }: FileExplorerProps) {
|
|
|
)}
|
|
)}
|
|
|
{isOpen && (
|
|
{isOpen && (
|
|
|
<OpenVSCodeButton
|
|
<OpenVSCodeButton
|
|
|
- onClick={getVSCodeUrl}
|
|
|
|
|
- isDisabled={
|
|
|
|
|
- curAgentState === AgentState.INIT ||
|
|
|
|
|
- curAgentState === AgentState.LOADING
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ onClick={handleOpenVSCode}
|
|
|
|
|
+ isDisabled={!agentIsReady}
|
|
|
/>
|
|
/>
|
|
|
)}
|
|
)}
|
|
|
</div>
|
|
</div>
|