* Add global New workspace project picker * Clean up New workspace picker state
118 lines
3.6 KiB
TypeScript
118 lines
3.6 KiB
TypeScript
import type { WorkspaceDescriptor } from "@/stores/session-store";
|
|
import type { WorkspaceStructureProject } from "@/projects/workspace-structure";
|
|
|
|
export interface HostProjectListItem {
|
|
serverId: string;
|
|
projectKey: string;
|
|
projectName: string;
|
|
projectKind: WorkspaceDescriptor["projectKind"];
|
|
iconWorkingDir: string;
|
|
workspaceKeys: string[];
|
|
canCreateWorktree: boolean;
|
|
}
|
|
|
|
export interface HostProjectRouteContext {
|
|
serverId: string;
|
|
projectId?: string;
|
|
displayName?: string;
|
|
sourceDirectory?: string;
|
|
}
|
|
|
|
function trimOptional(value: string | undefined): string | undefined {
|
|
const trimmed = value?.trim() ?? "";
|
|
return trimmed.length > 0 ? trimmed : undefined;
|
|
}
|
|
|
|
export function canCreateWorktreeForProjectKind(
|
|
projectKind: WorkspaceDescriptor["projectKind"],
|
|
): boolean {
|
|
return projectKind === "git";
|
|
}
|
|
|
|
export function buildHostProjectList(input: {
|
|
serverId: string;
|
|
projects: readonly WorkspaceStructureProject[];
|
|
}): HostProjectListItem[] {
|
|
return input.projects.map((project) => ({
|
|
serverId: input.serverId,
|
|
projectKey: project.projectKey,
|
|
projectName: project.projectName,
|
|
projectKind: project.projectKind,
|
|
iconWorkingDir: project.iconWorkingDir,
|
|
workspaceKeys: project.workspaceKeys,
|
|
canCreateWorktree: canCreateWorktreeForProjectKind(project.projectKind),
|
|
}));
|
|
}
|
|
|
|
export function hostProjectFromRoute(route: HostProjectRouteContext): HostProjectListItem | null {
|
|
const projectKey = trimOptional(route.projectId);
|
|
const iconWorkingDir = trimOptional(route.sourceDirectory);
|
|
if (!projectKey || !iconWorkingDir) {
|
|
return null;
|
|
}
|
|
return {
|
|
serverId: route.serverId,
|
|
projectKey,
|
|
projectName: trimOptional(route.displayName) ?? projectKey,
|
|
projectKind: "git",
|
|
iconWorkingDir,
|
|
workspaceKeys: [],
|
|
canCreateWorktree: true,
|
|
};
|
|
}
|
|
|
|
export function hostProjectFromWorkspace(input: {
|
|
serverId: string;
|
|
workspace: WorkspaceDescriptor | null;
|
|
}): HostProjectListItem | null {
|
|
if (!input.workspace) {
|
|
return null;
|
|
}
|
|
const projectKey = input.workspace.projectId.trim();
|
|
const iconWorkingDir = input.workspace.projectRootPath.trim();
|
|
if (!projectKey || !iconWorkingDir) {
|
|
return null;
|
|
}
|
|
return {
|
|
serverId: input.serverId,
|
|
projectKey,
|
|
projectName: input.workspace.projectDisplayName || projectKey,
|
|
projectKind: input.workspace.projectKind,
|
|
iconWorkingDir,
|
|
workspaceKeys: [input.workspace.id],
|
|
canCreateWorktree: canCreateWorktreeForProjectKind(input.workspace.projectKind),
|
|
};
|
|
}
|
|
|
|
export function resolveInitialWorktreeProject(input: {
|
|
routeProject: HostProjectListItem | null;
|
|
lastActiveProject: HostProjectListItem | null;
|
|
projects: readonly HostProjectListItem[];
|
|
}): HostProjectListItem | null {
|
|
if (input.routeProject?.canCreateWorktree) {
|
|
return input.routeProject;
|
|
}
|
|
if (input.lastActiveProject?.canCreateWorktree) {
|
|
return input.lastActiveProject;
|
|
}
|
|
return input.projects.find((project) => project.canCreateWorktree) ?? null;
|
|
}
|
|
|
|
export function resolveSelectedHostProject(input: {
|
|
selectedProjectKey: string | null;
|
|
projects: readonly HostProjectListItem[];
|
|
routeProject: HostProjectListItem | null;
|
|
lastActiveProject: HostProjectListItem | null;
|
|
}): HostProjectListItem | null {
|
|
const selectedProjectKey = input.selectedProjectKey?.trim() ?? "";
|
|
if (!selectedProjectKey) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
input.projects.find((project) => project.projectKey === selectedProjectKey) ??
|
|
(input.routeProject?.projectKey === selectedProjectKey ? input.routeProject : null) ??
|
|
(input.lastActiveProject?.projectKey === selectedProjectKey ? input.lastActiveProject : null)
|
|
);
|
|
}
|