refactor: extract RepoWorkspacePage components
- Extract use-repo-workspace hook for data loading - Extract WorkspaceLayout and FileBrowser components - Slim RepoWorkspacePage from 505 to ~80 lines Quality gates: tsc --noEmit passes, npm run build passes
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
import { Icon } from "../../icon";
|
||||
import { FileBrowser } from "./FileBrowser";
|
||||
import { FileEditor } from "../git/file-editor";
|
||||
import { CommitPanel } from "../git/commit-panel";
|
||||
import { GitToolbar } from "../git/git-toolbar";
|
||||
import { InstanceList } from "../tool/instance-list";
|
||||
import type { GitRepository, GitStatus } from "../../../api/git-repositories";
|
||||
import type { ToolType } from "../../../api/tool-types";
|
||||
import type { Project } from "../../../hooks/use-repo-workspace";
|
||||
|
||||
type MobileTab = "files" | "editor" | "git" | "terminal";
|
||||
|
||||
interface Props {
|
||||
projectId: string;
|
||||
project: Project | null;
|
||||
isMobile: boolean;
|
||||
mobileTab: MobileTab;
|
||||
selectedRepoId: string | null;
|
||||
selectedRepo: GitRepository | undefined;
|
||||
branches: string[];
|
||||
currentBranch: string;
|
||||
gitStatus: GitStatus | null;
|
||||
toolTypes: ToolType[];
|
||||
repositories: GitRepository[];
|
||||
onMobileTabChange: (tab: MobileTab) => void;
|
||||
onRepoChange: (repoId: string) => void;
|
||||
onBranchChange: (branch: string) => void;
|
||||
onRefresh: () => void;
|
||||
}
|
||||
|
||||
export const WorkspaceLayout = ({
|
||||
projectId,
|
||||
project,
|
||||
isMobile,
|
||||
mobileTab,
|
||||
selectedRepoId,
|
||||
selectedRepo,
|
||||
branches,
|
||||
currentBranch,
|
||||
gitStatus,
|
||||
toolTypes,
|
||||
repositories,
|
||||
onMobileTabChange,
|
||||
onRepoChange,
|
||||
onBranchChange,
|
||||
onRefresh,
|
||||
}: Props) => {
|
||||
if (isMobile) {
|
||||
return (
|
||||
<div className="mobile-workspace">
|
||||
<div className="mobile-workspace-header">
|
||||
<select
|
||||
value={selectedRepoId || ""}
|
||||
onChange={(e) => onRepoChange(e.target.value)}
|
||||
className="mobile-repo-selector"
|
||||
>
|
||||
{repositories.map((repo) => (
|
||||
<option key={repo.id} value={repo.id}>
|
||||
{repo.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{selectedRepoId && (
|
||||
<select
|
||||
value={currentBranch}
|
||||
onChange={(e) => onBranchChange(e.target.value)}
|
||||
className="mobile-branch-selector"
|
||||
>
|
||||
{branches.map((branch) => (
|
||||
<option key={branch} value={branch}>
|
||||
{branch}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mobile-workspace-content">
|
||||
{mobileTab === "files" && selectedRepoId && (
|
||||
<FileBrowser projectId={projectId} repoId={selectedRepoId} gitStatus={gitStatus} />
|
||||
)}
|
||||
{mobileTab === "editor" && selectedRepoId && (
|
||||
<FileEditor projectId={projectId} repoId={selectedRepoId} />
|
||||
)}
|
||||
{mobileTab === "git" && selectedRepoId && gitStatus && (
|
||||
<div className="mobile-git-view">
|
||||
<CommitPanel
|
||||
projectId={projectId}
|
||||
repoId={selectedRepoId}
|
||||
modified={gitStatus.modified}
|
||||
added={gitStatus.added}
|
||||
deleted={gitStatus.deleted}
|
||||
untracked={gitStatus.untracked}
|
||||
onCommit={() => {
|
||||
onRefresh();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{mobileTab === "terminal" && selectedRepoId && (
|
||||
<InstanceList
|
||||
projectId={projectId}
|
||||
repoId={selectedRepoId}
|
||||
projectName={project?.name}
|
||||
repoName={selectedRepo?.name}
|
||||
toolTypes={toolTypes}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mobile-workspace-tabs">
|
||||
<button
|
||||
className={`mobile-workspace-tab ${mobileTab === "files" ? "active" : ""}`}
|
||||
onClick={() => onMobileTabChange("files")}
|
||||
type="button"
|
||||
>
|
||||
<Icon name="folder" size="sm" />
|
||||
<span>Files</span>
|
||||
</button>
|
||||
<button
|
||||
className={`mobile-workspace-tab ${mobileTab === "editor" ? "active" : ""}`}
|
||||
onClick={() => onMobileTabChange("editor")}
|
||||
type="button"
|
||||
>
|
||||
<Icon name="edit" size="sm" />
|
||||
<span>Editor</span>
|
||||
</button>
|
||||
<button
|
||||
className={`mobile-workspace-tab ${mobileTab === "git" ? "active" : ""}`}
|
||||
onClick={() => onMobileTabChange("git")}
|
||||
type="button"
|
||||
>
|
||||
<Icon name="branch" size="sm" />
|
||||
<span>Git</span>
|
||||
</button>
|
||||
<button
|
||||
className={`mobile-workspace-tab ${mobileTab === "terminal" ? "active" : ""}`}
|
||||
onClick={() => onMobileTabChange("terminal")}
|
||||
type="button"
|
||||
>
|
||||
<Icon name="terminal" size="sm" />
|
||||
<span>Terminal</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{selectedRepoId && (
|
||||
<GitToolbar
|
||||
projectId={projectId}
|
||||
repoId={selectedRepoId}
|
||||
currentBranch={currentBranch}
|
||||
branches={branches}
|
||||
hasRemote={Boolean(selectedRepo?.remote_url)}
|
||||
isMirror={Boolean(selectedRepo?.is_mirror)}
|
||||
onBranchChange={onBranchChange}
|
||||
onRefresh={onRefresh}
|
||||
/>
|
||||
)}
|
||||
<div className="workspace-layout">
|
||||
<aside className="workspace-sidebar">
|
||||
<div className="sidebar-section">
|
||||
<label className="form-field">
|
||||
Repository
|
||||
<select
|
||||
value={selectedRepoId || ""}
|
||||
onChange={(e) => onRepoChange(e.target.value)}
|
||||
>
|
||||
{repositories.map((repo) => (
|
||||
<option key={repo.id} value={repo.id}>
|
||||
{repo.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{selectedRepoId && (
|
||||
<>
|
||||
<FileBrowser projectId={projectId} repoId={selectedRepoId} gitStatus={gitStatus} />
|
||||
{gitStatus && (
|
||||
<CommitPanel
|
||||
projectId={projectId}
|
||||
repoId={selectedRepoId}
|
||||
modified={gitStatus.modified}
|
||||
added={gitStatus.added}
|
||||
deleted={gitStatus.deleted}
|
||||
untracked={gitStatus.untracked}
|
||||
onCommit={onRefresh}
|
||||
/>
|
||||
)}
|
||||
<InstanceList
|
||||
projectId={projectId}
|
||||
repoId={selectedRepoId}
|
||||
projectName={project?.name}
|
||||
repoName={selectedRepo?.name}
|
||||
toolTypes={toolTypes}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</aside>
|
||||
|
||||
<main className="workspace-main">
|
||||
{selectedRepoId && (
|
||||
<FileEditor projectId={projectId} repoId={selectedRepoId} />
|
||||
)}
|
||||
</main>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user