mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
105 lines
3.1 KiB
TypeScript
105 lines
3.1 KiB
TypeScript
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;
|