Files
buzz/desktop/src/features/projects/useProjectRepositoryRefSelection.ts
thomaspblock 87f8ff82ae feat(desktop): refine repository-aware project workspaces (#6003)
## Summary
- Makes Projects repository-aware across browsing, branch and tag
selection, local and remote source management, work items, commits, and
contextual repository actions.
- Refines project details into consistent single-column reading surfaces
with a resizable, section-aware context pod, while keeping project
conversations available in the attached chat panel.
- Adds persistent sidebar project navigation, direct entity links,
repository discussion channels, contributor identity matching, and
consistent loading and activity presentation.
- Keeps branch-specific controls on code-oriented sections while Tasks,
Reviews, and Channels remain repository-scoped, reducing misleading
context and actions.

Replacement for #5981 with an identical final tree flattened into one
signed-off commit because the required DCO check suite remained stalled.

### Related issue
N/A

### Testing
- [x] Desktop pre-push checks, TypeScript typecheck, and unit tests
- [x] E2E production build with `pnpm build:e2e`
- [x] Focused Playwright smoke coverage for project workspace, task,
review, commit, sidebar, and contextual-panel behavior
- [ ] Attach final before/after screenshots after design review

---------

Signed-off-by: Thomas Petersen <thomasp@squareup.com>
Signed-off-by: Wintermute <165f0c871dd2586bb18b6aa109eeaf57bb2132ff4d27b10120f4368a0f627022@buzz.block.builderlab.xyz>
Co-authored-by: Wintermute <165f0c871dd2586bb18b6aa109eeaf57bb2132ff4d27b10120f4368a0f627022@buzz.block.builderlab.xyz>
2026-08-19 12:50:00 +01:00

79 lines
2.4 KiB
TypeScript

import * as React from "react";
export function useProjectRepositoryRefSelection(input: {
branchOptions: string[];
defaultBranch: string | null;
projectAvailable: boolean;
projectPending: boolean;
/** Identity of the repository the options describe. A switch to a
* different repository resets the selection even when the new repository
* happens to have a branch or tag with the same name — carrying `release`
* from repo A into repo B would silently retarget files, actions, and
* agent context at a ref the user never chose. */
repositoryId: string | null;
tags: Array<{ name: string }>;
}) {
const [selectedBranch, setSelectedBranch] = React.useState<string | null>(
null,
);
const [selectedTag, setSelectedTag] = React.useState<string | null>(null);
const [selectionRepositoryId, setSelectionRepositoryId] = React.useState(
input.repositoryId,
);
// Reset during render (not in an effect) so a repository switch can never
// paint one frame with the previous repository's same-named selection.
if (selectionRepositoryId !== input.repositoryId) {
setSelectionRepositoryId(input.repositoryId);
setSelectedBranch(null);
setSelectedTag(null);
}
const staleSelection = selectionRepositoryId !== input.repositoryId;
const activeBranch =
(staleSelection ? null : selectedBranch) ??
input.defaultBranch ??
input.branchOptions[0] ??
null;
React.useEffect(() => {
if (!input.projectAvailable) {
if (input.projectPending) return;
setSelectedBranch(null);
setSelectedTag(null);
return;
}
setSelectedBranch((currentBranch) => {
if (currentBranch && input.branchOptions.includes(currentBranch)) {
return currentBranch;
}
return input.defaultBranch ?? input.branchOptions[0] ?? null;
});
setSelectedTag((currentTag) => {
if (currentTag && input.tags.some((tag) => tag.name === currentTag)) {
return currentTag;
}
return null;
});
}, [
input.branchOptions,
input.defaultBranch,
input.projectAvailable,
input.projectPending,
input.tags,
]);
const selectBranch = React.useCallback((branch: string | null) => {
setSelectedBranch(branch);
setSelectedTag(null);
}, []);
const selectTag = React.useCallback((tag: string) => {
setSelectedTag(tag);
}, []);
return {
activeBranch,
selectBranch,
selectedTag: staleSelection ? null : selectedTag,
selectTag,
};
}