| ... | @@ -113,6 +113,7 @@ import { | ... | @@ -113,6 +113,7 @@ import { |
| 113 | canPickExternalProjectFavicon, | 113 | canPickExternalProjectFavicon, |
| 114 | ProjectFaviconPickerDialog, | 114 | ProjectFaviconPickerDialog, |
| 115 | } from "./ProjectFaviconPickerDialog"; | 115 | } from "./ProjectFaviconPickerDialog"; |
| | 116 | import { projectGroupTitleNeedsUpdate } from "./ProjectSettingsPanel.logic"; |
| 116 | | 117 | |
| 117 | export const PROJECT_GROUPING_MODE_LABELS: Record<SidebarProjectGroupingMode, string> = { | 118 | export const PROJECT_GROUPING_MODE_LABELS: Record<SidebarProjectGroupingMode, string> = { |
| 118 | repository: "Group by repository", | 119 | repository: "Group by repository", |
| ... | @@ -304,6 +305,7 @@ function ProjectDetail({ group }: { group: SidebarProjectSnapshot }) { | ... | @@ -304,6 +305,7 @@ function ProjectDetail({ group }: { group: SidebarProjectSnapshot }) { |
| 304 | const removeKeybinding = useAtomCommand(serverEnvironment.removeKeybinding, { | 305 | const removeKeybinding = useAtomCommand(serverEnvironment.removeKeybinding, { |
| 305 | reportFailure: false, | 306 | reportFailure: false, |
| 306 | }); | 307 | }); |
| | 308 | const projectNameEditedRef = useRef(false); |
| 307 | const { copyToClipboard: copyPathToClipboard } = useCopyToClipboard<{ path: string }>({ | 309 | const { copyToClipboard: copyPathToClipboard } = useCopyToClipboard<{ path: string }>({ |
| 308 | onCopy: ({ path }) => { | 310 | onCopy: ({ path }) => { |
| 309 | toastManager.add({ type: "success", title: "Path copied", description: path }); | 311 | toastManager.add({ type: "success", title: "Path copied", description: path }); |
| ... | @@ -392,17 +394,24 @@ function ProjectDetail({ group }: { group: SidebarProjectSnapshot }) { | ... | @@ -392,17 +394,24 @@ function ProjectDetail({ group }: { group: SidebarProjectSnapshot }) { |
| 392 | ); | 394 | ); |
| 393 | | 395 | |
| 394 | const renameGroup = useCallback( | 396 | const renameGroup = useCallback( |
| 395 | async (nextTitle: string) => { | 397 | async (nextTitle: string, wasEdited: boolean) => { |
| 396 | const title = nextTitle.trim(); | 398 | const title = nextTitle.trim(); |
| 397 | if (!title) { | 399 | if (!title) { |
| 398 | toastManager.add({ type: "warning", title: "Project title cannot be empty" }); | 400 | toastManager.add({ type: "warning", title: "Project title cannot be empty" }); |
| 399 | return; | 401 | return; |
| 400 | } | 402 | } |
| 401 | if (title === group.displayName) return; | 403 | if ( |
| 402 | if (group.memberProjects.every((member) => member.title === title)) return; | 404 | !projectGroupTitleNeedsUpdate( |
| | 405 | group.memberProjects.map((member) => member.title), |
| | 406 | title, |
| | 407 | wasEdited, |
| | 408 | ) |
| | 409 | ) { |
| | 410 | return; |
| | 411 | } |
| 403 | await updateAllMembers({ title }, "Failed to rename project"); | 412 | await updateAllMembers({ title }, "Failed to rename project"); |
| 404 | }, | 413 | }, |
| 405 | [group.displayName, group.memberProjects, updateAllMembers], | 414 | [group.memberProjects, updateAllMembers], |
| 406 | ); | 415 | ); |
| 407 | | 416 | |
| 408 | // ----- default model ----- | 417 | // ----- default model ----- |
| ... | @@ -767,8 +776,13 @@ function ProjectDetail({ group }: { group: SidebarProjectSnapshot }) { | ... | @@ -767,8 +776,13 @@ function ProjectDetail({ group }: { group: SidebarProjectSnapshot }) { |
| 767 | className="w-full sm:w-64" | 776 | className="w-full sm:w-64" |
| 768 | aria-label="Project name" | 777 | aria-label="Project name" |
| 769 | defaultValue={group.displayName} | 778 | defaultValue={group.displayName} |
| | 779 | onChange={() => { |
| | 780 | projectNameEditedRef.current = true; |
| | 781 | }} |
| 770 | onBlur={(event) => { | 782 | onBlur={(event) => { |
| 771 | void renameGroup(event.currentTarget.value); | 783 | const wasEdited = projectNameEditedRef.current; |
| | 784 | projectNameEditedRef.current = false; |
| | 785 | void renameGroup(event.currentTarget.value, wasEdited); |
| 772 | }} | 786 | }} |
| 773 | onKeyDown={(event) => { | 787 | onKeyDown={(event) => { |
| 774 | if (event.key === "Enter") event.currentTarget.blur(); | 788 | if (event.key === "Enter") event.currentTarget.blur(); |