Archived
Hide Git panel outside repositories
This commit is contained in:
@@ -67,6 +67,7 @@ export function parseWorkspace(value: unknown): Workspace {
|
|||||||
label: requireString(record, "label"),
|
label: requireString(record, "label"),
|
||||||
...(branch === undefined ? {} : { branch }),
|
...(branch === undefined ? {} : { branch }),
|
||||||
isMain: requireBoolean(record, "isMain"),
|
isMain: requireBoolean(record, "isMain"),
|
||||||
|
isGitRepo: requireBoolean(record, "isGitRepo"),
|
||||||
isGitWorktree: requireBoolean(record, "isGitWorktree"),
|
isGitWorktree: requireBoolean(record, "isGitWorktree"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { ProjectController } from "../controllers/projectController";
|
|||||||
import { SessionController } from "../controllers/sessionController";
|
import { SessionController } from "../controllers/sessionController";
|
||||||
import { WorkspaceController } from "../controllers/workspaceController";
|
import { WorkspaceController } from "../controllers/workspaceController";
|
||||||
import { KeyboardShortcutDispatcher } from "../keyboardShortcuts";
|
import { KeyboardShortcutDispatcher } from "../keyboardShortcuts";
|
||||||
import type { QualifiedContributionId, PluginRuntimeContext } from "../plugins/types";
|
import type { QualifiedContributionId, QualifiedWorkspacePanelContribution, PluginRuntimeContext } from "../plugins/types";
|
||||||
import { corePlugin } from "../plugins/core";
|
import { corePlugin } from "../plugins/core";
|
||||||
import { examplePlugin } from "../plugins/example";
|
import { examplePlugin } from "../plugins/example";
|
||||||
import { PluginRegistry } from "../plugins/registry";
|
import { PluginRegistry } from "../plugins/registry";
|
||||||
@@ -179,7 +179,12 @@ export class PiWebApp extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private renderWorkspacePanel() {
|
private renderWorkspacePanel() {
|
||||||
return html`<workspace-panel .workspace=${this.state.selectedWorkspace} .tool=${this.state.workspaceTool} .panels=${this.plugins.getWorkspacePanels()} .fileTree=${this.state.fileTree} .expandedDirs=${this.state.expandedDirs} .selectedFilePath=${this.state.selectedFilePath} .selectedFileContent=${this.state.selectedFileContent} .fileTreeStale=${this.state.fileTreeStale} .gitStatus=${this.state.gitStatus} .selectedDiffPath=${this.state.selectedDiffPath} .selectedDiff=${this.state.selectedDiff} .selectedStagedDiff=${this.state.selectedStagedDiff} .gitStale=${this.state.gitStale} .onSelectTool=${(tool: QualifiedContributionId) => { this.selectWorkspaceTool(tool); }} .onRefreshFiles=${() => this.files.refreshFiles()} .onExpandDir=${(path: string) => this.files.expandDir(path)} .onSelectFile=${(path: string) => this.files.selectFile(path)} .onRefreshGit=${() => this.git.refreshGit()} .onSelectDiff=${(path: string) => this.git.selectDiff(path)}></workspace-panel>`;
|
return html`<workspace-panel .workspace=${this.state.selectedWorkspace} .tool=${this.state.workspaceTool} .panels=${this.visibleWorkspacePanels()} .fileTree=${this.state.fileTree} .expandedDirs=${this.state.expandedDirs} .selectedFilePath=${this.state.selectedFilePath} .selectedFileContent=${this.state.selectedFileContent} .fileTreeStale=${this.state.fileTreeStale} .gitStatus=${this.state.gitStatus} .selectedDiffPath=${this.state.selectedDiffPath} .selectedDiff=${this.state.selectedDiff} .selectedStagedDiff=${this.state.selectedStagedDiff} .gitStale=${this.state.gitStale} .onSelectTool=${(tool: QualifiedContributionId) => { this.selectWorkspaceTool(tool); }} .onRefreshFiles=${() => this.files.refreshFiles()} .onExpandDir=${(path: string) => this.files.expandDir(path)} .onSelectFile=${(path: string) => this.files.selectFile(path)} .onRefreshGit=${() => this.git.refreshGit()} .onSelectDiff=${(path: string) => this.git.selectDiff(path)}></workspace-panel>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private visibleWorkspacePanels(): QualifiedWorkspacePanelContribution[] {
|
||||||
|
const workspace = this.state.selectedWorkspace;
|
||||||
|
return this.plugins.getWorkspacePanels().filter((panel) => workspace === undefined || (panel.visible?.(workspace) ?? true));
|
||||||
}
|
}
|
||||||
|
|
||||||
private getActions(): AppAction[] {
|
private getActions(): AppAction[] {
|
||||||
@@ -223,7 +228,7 @@ export class PiWebApp extends LitElement {
|
|||||||
<main class=${state.mainView === "chat" ? "chat-view" : "workspace-view"}>
|
<main class=${state.mainView === "chat" ? "chat-view" : "workspace-view"}>
|
||||||
<div class="mobile-tabs">
|
<div class="mobile-tabs">
|
||||||
<button class=${state.mainView === "chat" ? "selected" : ""} @click=${() => { this.selectMainView("chat"); }}>Chat</button>
|
<button class=${state.mainView === "chat" ? "selected" : ""} @click=${() => { this.selectMainView("chat"); }}>Chat</button>
|
||||||
${this.plugins.getWorkspacePanels().map((panel) => html`
|
${this.visibleWorkspacePanels().map((panel) => html`
|
||||||
<button class=${state.mainView === panel.id ? "selected" : ""} @click=${() => { this.selectMainView(panel.id); }}>${panel.title}</button>
|
<button class=${state.mainView === panel.id ? "selected" : ""} @click=${() => { this.selectMainView(panel.id); }}>${panel.title}</button>
|
||||||
`)}
|
`)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -28,11 +28,12 @@ export class WorkspacePanel extends LitElement {
|
|||||||
|
|
||||||
override render() {
|
override render() {
|
||||||
if (!this.workspace) return html`<section class="empty">Select a workspace.</section>`;
|
if (!this.workspace) return html`<section class="empty">Select a workspace.</section>`;
|
||||||
const selectedPanel = this.panels.find((panel) => panel.id === this.tool) ?? this.panels[0];
|
const visiblePanels = this.panels.filter((panel) => panel.visible?.(this.workspace as Workspace) ?? true);
|
||||||
|
const selectedPanel = visiblePanels.find((panel) => panel.id === this.tool) ?? visiblePanels[0];
|
||||||
return html`
|
return html`
|
||||||
<header>
|
<header>
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
${this.panels.map((panel) => html`
|
${visiblePanels.map((panel) => html`
|
||||||
<button class=${selectedPanel?.id === panel.id ? "selected" : ""} @click=${() => { this.onSelectTool(panel.id); }}>${panel.title}</button>
|
<button class=${selectedPanel?.id === panel.id ? "selected" : ""} @click=${() => { this.onSelectTool(panel.id); }}>${panel.title}</button>
|
||||||
`)}
|
`)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export function createCoreActions(): PluginAction[] {
|
|||||||
title: "Go to Git",
|
title: "Go to Git",
|
||||||
shortcut: "mod+3",
|
shortcut: "mod+3",
|
||||||
group: "Navigation",
|
group: "Navigation",
|
||||||
enabled: hasWorkspace,
|
enabled: hasGitWorkspace,
|
||||||
run: (context) => { context.selectMainView("core:workspace.git"); },
|
run: (context) => { context.selectMainView("core:workspace.git"); },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -61,7 +61,7 @@ export function createCoreActions(): PluginAction[] {
|
|||||||
title: "Refresh Git",
|
title: "Refresh Git",
|
||||||
shortcut: "mod+shift+g",
|
shortcut: "mod+shift+g",
|
||||||
group: "Workspace",
|
group: "Workspace",
|
||||||
enabled: hasWorkspace,
|
enabled: hasGitWorkspace,
|
||||||
run: (context) => context.refreshGit(),
|
run: (context) => context.refreshGit(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -70,7 +70,7 @@ export function createCoreActions(): PluginAction[] {
|
|||||||
shortcut: "mod+shift+r",
|
shortcut: "mod+shift+r",
|
||||||
group: "Workspace",
|
group: "Workspace",
|
||||||
enabled: hasWorkspace,
|
enabled: hasWorkspace,
|
||||||
run: (context) => context.state.workspaceTool === "core:workspace.git" ? context.refreshGit() : context.refreshFiles(),
|
run: (context) => context.state.workspaceTool === "core:workspace.git" && context.state.selectedWorkspace?.isGitRepo === true ? context.refreshGit() : context.refreshFiles(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "session.start",
|
id: "session.start",
|
||||||
@@ -103,6 +103,10 @@ function hasWorkspace(context: { state: AppState }): boolean {
|
|||||||
return context.state.selectedWorkspace !== undefined;
|
return context.state.selectedWorkspace !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasGitWorkspace(context: { state: AppState }): boolean {
|
||||||
|
return context.state.selectedWorkspace?.isGitRepo === true;
|
||||||
|
}
|
||||||
|
|
||||||
function isActive(status: AppState["status"]): boolean {
|
function isActive(status: AppState["status"]): boolean {
|
||||||
return status?.isStreaming === true || status?.isBashRunning === true || status?.isCompacting === true;
|
return status?.isStreaming === true || status?.isBashRunning === true || status?.isCompacting === true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ export function createCoreWorkspacePanels(): WorkspacePanelContribution[] {
|
|||||||
id: "workspace.git",
|
id: "workspace.git",
|
||||||
title: "Git",
|
title: "Git",
|
||||||
order: 20,
|
order: 20,
|
||||||
|
visible: (workspace) => workspace.isGitRepo,
|
||||||
render: renderGit,
|
render: renderGit,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -75,5 +75,5 @@ describe("PluginRegistry", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function testWorkspace(): AppState["selectedWorkspace"] {
|
function testWorkspace(): AppState["selectedWorkspace"] {
|
||||||
return { id: "w1", projectId: "p1", path: "/tmp/project", label: "main", isMain: true, isGitWorktree: false };
|
return { id: "w1", projectId: "p1", path: "/tmp/project", label: "main", isMain: true, isGitRepo: true, isGitWorktree: false };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ export interface WorkspacePanelContribution {
|
|||||||
id: LocalContributionId;
|
id: LocalContributionId;
|
||||||
title: string;
|
title: string;
|
||||||
order?: number;
|
order?: number;
|
||||||
|
visible?: (workspace: Workspace) => boolean;
|
||||||
render: (context: WorkspacePanelContext) => TemplateResult;
|
render: (context: WorkspacePanelContext) => TemplateResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ const idFor = (value: string) => createHash("sha1").update(value).digest("hex").
|
|||||||
|
|
||||||
export class WorkspaceService {
|
export class WorkspaceService {
|
||||||
async list(project: Project): Promise<Workspace[]> {
|
async list(project: Project): Promise<Workspace[]> {
|
||||||
if (!(await isGitRepository(project.path))) {
|
const isGitRepo = await isGitRepository(project.path);
|
||||||
return [this.single(project)];
|
if (!isGitRepo) {
|
||||||
|
return [this.single(project, false)];
|
||||||
}
|
}
|
||||||
|
|
||||||
const worktrees = await discoverGitWorktrees(project.path);
|
const worktrees = await discoverGitWorktrees(project.path);
|
||||||
if (worktrees.length === 0) return [this.single(project)];
|
if (worktrees.length === 0) return [this.single(project, true)];
|
||||||
|
|
||||||
return worktrees.map((worktree) => {
|
return worktrees.map((worktree) => {
|
||||||
const leafName = worktree.path.split("/").filter((part) => part !== "").at(-1);
|
const leafName = worktree.path.split("/").filter((part) => part !== "").at(-1);
|
||||||
@@ -23,18 +24,20 @@ export class WorkspaceService {
|
|||||||
label: worktree.branch ?? (worktree.detached === true ? "detached" : leafName ?? worktree.path),
|
label: worktree.branch ?? (worktree.detached === true ? "detached" : leafName ?? worktree.path),
|
||||||
...(worktree.branch === undefined ? {} : { branch: worktree.branch }),
|
...(worktree.branch === undefined ? {} : { branch: worktree.branch }),
|
||||||
isMain: worktree.path === project.path,
|
isMain: worktree.path === project.path,
|
||||||
|
isGitRepo: true,
|
||||||
isGitWorktree: true,
|
isGitWorktree: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private single(project: Project): Workspace {
|
private single(project: Project, isGitRepo: boolean): Workspace {
|
||||||
return {
|
return {
|
||||||
id: idFor(`${project.id}:${project.path}`),
|
id: idFor(`${project.id}:${project.path}`),
|
||||||
projectId: project.id,
|
projectId: project.id,
|
||||||
path: project.path,
|
path: project.path,
|
||||||
label: project.name,
|
label: project.name,
|
||||||
isMain: true,
|
isMain: true,
|
||||||
|
isGitRepo,
|
||||||
isGitWorktree: false,
|
isGitWorktree: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export interface Workspace {
|
|||||||
label: string;
|
label: string;
|
||||||
branch?: string;
|
branch?: string;
|
||||||
isMain: boolean;
|
isMain: boolean;
|
||||||
|
isGitRepo: boolean;
|
||||||
isGitWorktree: boolean;
|
isGitWorktree: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user