OpenHands / frontend /src /routes /changes-tab.tsx
Backup-bdg's picture
Upload 565 files
b59aa07 verified
raw
history blame
3.21 kB
import { useTranslation } from "react-i18next";
import { useSelector } from "react-redux";
import React from "react";
import { FileDiffViewer } from "#/components/features/diff-viewer/file-diff-viewer";
import { retrieveAxiosErrorMessage } from "#/utils/retrieve-axios-error-message";
import { useGetGitChanges } from "#/hooks/query/use-get-git-changes";
import { I18nKey } from "#/i18n/declaration";
import { RootState } from "#/store";
import { RUNTIME_INACTIVE_STATES } from "#/types/agent-state";
import { RandomTip } from "#/components/features/tips/random-tip";
// Error message patterns
const GIT_REPO_ERROR_PATTERN = /not a git repository/i;
function StatusMessage({ children }: React.PropsWithChildren) {
return (
<div className="w-full h-full flex flex-col items-center text-center justify-center text-2xl text-tertiary-light">
{children}
</div>
);
}
function GitChanges() {
const { t } = useTranslation();
const {
data: gitChanges,
isSuccess,
isError,
error,
isLoading: loadingGitChanges,
} = useGetGitChanges();
const [statusMessage, setStatusMessage] = React.useState<string[] | null>(
null,
);
const { curAgentState } = useSelector((state: RootState) => state.agent);
const runtimeIsActive = !RUNTIME_INACTIVE_STATES.includes(curAgentState);
const isNotGitRepoError =
error && GIT_REPO_ERROR_PATTERN.test(retrieveAxiosErrorMessage(error));
React.useEffect(() => {
if (!runtimeIsActive) {
setStatusMessage([I18nKey.DIFF_VIEWER$WAITING_FOR_RUNTIME]);
} else if (error) {
const errorMessage = retrieveAxiosErrorMessage(error);
if (GIT_REPO_ERROR_PATTERN.test(errorMessage)) {
setStatusMessage([
I18nKey.DIFF_VIEWER$NOT_A_GIT_REPO,
I18nKey.DIFF_VIEWER$ASK_OH,
]);
} else {
setStatusMessage([errorMessage]);
}
} else if (loadingGitChanges) {
setStatusMessage([I18nKey.DIFF_VIEWER$LOADING]);
} else {
setStatusMessage(null);
}
}, [
runtimeIsActive,
isNotGitRepoError,
loadingGitChanges,
error,
setStatusMessage,
]);
return (
<main className="h-full overflow-y-scroll px-4 py-3 gap-3 flex flex-col items-center">
{!isSuccess || !gitChanges.length ? (
<div className="relative flex h-full w-full items-center">
<div className="absolute inset-x-0 top-1/2 -translate-y-1/2">
{statusMessage && (
<StatusMessage>
{statusMessage.map((msg) => (
<span key={msg}>{t(msg)}</span>
))}
</StatusMessage>
)}
</div>
<div className="absolute inset-x-0 bottom-0">
{!isError && gitChanges?.length === 0 && (
<div className="max-w-2xl mb-4 text-m bg-tertiary rounded-xl p-4 text-left mx-auto">
<RandomTip />
</div>
)}
</div>
</div>
) : (
gitChanges.map((change) => (
<FileDiffViewer
key={change.path}
path={change.path}
type={change.status}
/>
))
)}
</main>
);
}
export default GitChanges;