History

fix(web): keep grouped project renames (#7831)

Mohtasham Murshid committed 2 months agov0.0.34-nightly.20260825.1185

Commit e67074f1 parent 5d766533 files · +49 −5Browse files

Unified · Split

3 files
  1. apps/web/src/components/settings/ProjectSettingsPanel.logic.test.ts +23 −0
  2. apps/web/src/components/settings/ProjectSettingsPanel.logic.ts +7 −0
  3. apps/web/src/components/settings/ProjectSettingsPanel.tsx +19 −5
apps/web/src/components/settings/ProjectSettingsPanel.logic.test.ts+23−0
@@ -0,0 +1,23 @@
1+import { describe, expect, it } from "vite-plus/test";
2+
3+import { projectGroupTitleNeedsUpdate } from "./ProjectSettingsPanel.logic";
4+
5+describe("projectGroupTitleNeedsUpdate", () => {
6+ it("updates divergent member titles even when the next title is the derived group label", () => {
7+ expect(
8+ projectGroupTitleNeedsUpdate(["local-title", "remote-title"], "Repository name", true),
9+ ).toBe(true);
10+ });
11+
12+ it("skips an untouched blur when the derived label differs from member titles", () => {
13+ expect(projectGroupTitleNeedsUpdate(["repo-slug", "repo-slug"], "Repository Name", false)).toBe(
14+ false,
15+ );
16+ });
17+
18+ it("skips an update when every member already has the next title", () => {
19+ expect(projectGroupTitleNeedsUpdate(["Shared name", "Shared name"], "Shared name", true)).toBe(
20+ false,
21+ );
22+ });
23+});
apps/web/src/components/settings/ProjectSettingsPanel.logic.ts+7−0
@@ -0,0 +1,7 @@
1+export function projectGroupTitleNeedsUpdate(
2+ memberTitles: ReadonlyArray<string>,
3+ nextTitle: string,
4+ wasEdited: boolean,
5+): boolean {
6+ return wasEdited && memberTitles.some((title) => title !== nextTitle);
7+}
apps/web/src/components/settings/ProjectSettingsPanel.tsx+19−5
@@ -113,6 +113,7 @@ import { · 112 unmodified lines
113113 canPickExternalProjectFavicon,
114114 ProjectFaviconPickerDialog,
115115 } from "./ProjectFaviconPickerDialog";
116+import { projectGroupTitleNeedsUpdate } from "./ProjectSettingsPanel.logic";
116117
117118 export const PROJECT_GROUPING_MODE_LABELS: Record<SidebarProjectGroupingMode, string> = {
118119 repository: "Group by repository",
@@ -304,6 +305,7 @@ function ProjectDetail({ group }: { group: SidebarProjectSnapshot }) { · 185 unmodified lines
304305 const removeKeybinding = useAtomCommand(serverEnvironment.removeKeybinding, {
305306 reportFailure: false,
306307 });
308+ const projectNameEditedRef = useRef(false);
307309 const { copyToClipboard: copyPathToClipboard } = useCopyToClipboard<{ path: string }>({
308310 onCopy: ({ path }) => {
309311 toastManager.add({ type: "success", title: "Path copied", description: path });
@@ -392,17 +394,24 @@ function ProjectDetail({ group }: { group: SidebarProjectSnapshot }) { · 82 unmodified lines
392394 );
393395
394396 const renameGroup = useCallback(
395− async (nextTitle: string) => {
397+ async (nextTitle: string, wasEdited: boolean) => {
396398 const title = nextTitle.trim();
397399 if (!title) {
398400 toastManager.add({ type: "warning", title: "Project title cannot be empty" });
399401 return;
400402 }
401− if (title === group.displayName) return;
402− if (group.memberProjects.every((member) => member.title === title)) return;
403+ if (
404+ !projectGroupTitleNeedsUpdate(
405+ group.memberProjects.map((member) => member.title),
406+ title,
407+ wasEdited,
408+ )
409+ ) {
410+ return;
411+ }
403412 await updateAllMembers({ title }, "Failed to rename project");
404413 },
405− [group.displayName, group.memberProjects, updateAllMembers],
414+ [group.memberProjects, updateAllMembers],
406415 );
407416
408417 // ----- default model -----
@@ -767,8 +776,13 @@ function ProjectDetail({ group }: { group: SidebarProjectSnapshot }) { · 358 unmodified lines
767776 className="w-full sm:w-64"
768777 aria-label="Project name"
769778 defaultValue={group.displayName}
779+ onChange={() => {
780+ projectNameEditedRef.current = true;
781+ }}
770782 onBlur={(event) => {
771− void renameGroup(event.currentTarget.value);
783+ const wasEdited = projectNameEditedRef.current;
784+ projectNameEditedRef.current = false;
785+ void renameGroup(event.currentTarget.value, wasEdited);
772786 }}
773787 onKeyDown={(event) => {
774788 if (event.key === "Enter") event.currentTarget.blur();