fix: space deletion state cleanup and single-select for add document (#748)

fix: space deletion + new space not reflecting in selector

Deleting a space wasn't switching back to Nova Spaces because we were reading stale cache data

  New spaces created from the add-document modal weren't showing up in the dropdown

  Added single-select mode to the space selector in the add-document flow since you're picking one space, not multiple.
This commit is contained in:
Prasanna721 2026-02-19 07:09:47 +00:00
parent cc2dcaa306
commit 7339822997
4 changed files with 100 additions and 59 deletions

View file

@ -380,40 +380,42 @@ export function AddDocument({
<div
className={cn(
"overflow-auto flex flex-col justify-between px-1 scrollbar-thin flex-1",
"flex flex-col flex-1 min-h-0 px-1",
isMobile ? "w-full" : "w-2/3",
)}
>
{activeTab === "note" && (
<NoteContent
onSubmit={handleNoteSubmit}
onContentChange={handleNoteContentChange}
isSubmitting={noteMutation.isPending}
isOpen={isOpen}
/>
)}
{activeTab === "link" && (
<LinkContent
onSubmit={handleLinkSubmit}
onDataChange={handleLinkDataChange}
isSubmitting={linkMutation.isPending}
isOpen={isOpen}
/>
)}
{activeTab === "file" && (
<FileContent
onSubmit={handleFileSubmit}
onDataChange={handleFileDataChange}
isSubmitting={fileMutation.isPending}
isOpen={isOpen}
/>
)}
{activeTab === "connect" && (
<ConnectContent selectedProject={localSelectedProject} />
)}
<div className="overflow-auto flex-1 min-h-0 scrollbar-thin">
{activeTab === "note" && (
<NoteContent
onSubmit={handleNoteSubmit}
onContentChange={handleNoteContentChange}
isSubmitting={noteMutation.isPending}
isOpen={isOpen}
/>
)}
{activeTab === "link" && (
<LinkContent
onSubmit={handleLinkSubmit}
onDataChange={handleLinkDataChange}
isSubmitting={linkMutation.isPending}
isOpen={isOpen}
/>
)}
{activeTab === "file" && (
<FileContent
onSubmit={handleFileSubmit}
onDataChange={handleFileDataChange}
isSubmitting={fileMutation.isPending}
isOpen={isOpen}
/>
)}
{activeTab === "connect" && (
<ConnectContent selectedProject={localSelectedProject} />
)}
</div>
<div
className={cn(
"flex gap-2 pt-3",
"flex gap-2 pt-3 shrink-0",
isMobile ? "flex-col" : "justify-between",
)}
>
@ -424,6 +426,7 @@ export function AddDocument({
setLocalSelectedProject(projects[0] ?? localSelectedProject)
}
variant="insideOut"
singleSelect
/>
)}
<div

View file

@ -65,9 +65,11 @@ const EMOJI_LIST = [
export function AddSpaceModal({
isOpen,
onClose,
onCreated,
}: {
isOpen: boolean
onClose: () => void
onCreated?: (containerTag: string) => void
}) {
const [spaceName, setSpaceName] = useState("")
const [emoji, setEmoji] = useState("📁")
@ -87,8 +89,11 @@ export function AddSpaceModal({
createProjectMutation.mutate(
{ name: trimmedName, emoji: emoji || undefined },
{
onSuccess: () => {
onSuccess: (data) => {
analytics.spaceCreated()
if (data?.containerTag) {
onCreated?.(data.containerTag)
}
handleClose()
},
},

View file

@ -16,6 +16,7 @@ interface SelectSpacesModalProps {
selectedProjects: string[]
onApply: (selected: string[]) => void
projects: ContainerTagListType[]
singleSelect?: boolean
}
export function SelectSpacesModal({
@ -24,6 +25,7 @@ export function SelectSpacesModal({
selectedProjects,
onApply,
projects,
singleSelect = false,
}: SelectSpacesModalProps) {
const [searchQuery, setSearchQuery] = useState("")
const [localSelection, setLocalSelection] =
@ -44,6 +46,10 @@ export function SelectSpacesModal({
}
const handleToggle = (containerTag: string) => {
if (singleSelect) {
setLocalSelection([containerTag])
return
}
setLocalSelection((prev) => {
if (prev.includes(containerTag)) {
return prev.filter((tag) => tag !== containerTag)
@ -117,10 +123,12 @@ export function SelectSpacesModal({
dmSans125ClassName(),
)}
>
Select Spaces
Select Space{!singleSelect && "s"}
</p>
<p className="text-[#737373] font-medium text-[16px] leading-[1.35]">
Choose one or more spaces to filter your memories
{singleSelect
? "Choose a space for your memory"
: "Choose one or more spaces to filter your memories"}
</p>
</div>
<DialogPrimitive.Close
@ -173,16 +181,29 @@ export function SelectSpacesModal({
: "bg-transparent border border-transparent hover:bg-[#14161A]/50",
)}
>
<div
className={cn(
"w-5 h-5 rounded-md border-2 flex items-center justify-center shrink-0 transition-colors",
isSelected
? "bg-blue-500 border-blue-500"
: "border-[#737373]",
)}
>
{isSelected && <Check className="size-3 text-white" />}
</div>
{singleSelect ? (
<div
className={cn(
"w-5 h-5 rounded-full border-2 flex items-center justify-center shrink-0 transition-colors",
isSelected ? "border-blue-500" : "border-[#737373]",
)}
>
{isSelected && (
<div className="w-2.5 h-2.5 rounded-full bg-blue-500" />
)}
</div>
) : (
<div
className={cn(
"w-5 h-5 rounded-md border-2 flex items-center justify-center shrink-0 transition-colors",
isSelected
? "bg-blue-500 border-blue-500"
: "border-[#737373]",
)}
>
{isSelected && <Check className="size-3 text-white" />}
</div>
)}
<span className="text-lg">{project.emoji || "📁"}</span>
<span className="text-[#fafafa] text-sm font-medium truncate flex-1">
{project.name ?? project.containerTag}
@ -195,9 +216,13 @@ export function SelectSpacesModal({
<div className="flex items-center justify-between">
<p className="text-[#737373] text-sm">
{localSelection.length === 0
? "No spaces selected (showing all)"
: `${localSelection.length} space${localSelection.length > 1 ? "s" : ""} selected`}
{singleSelect
? localSelection.length === 0
? "No space selected"
: "1 space selected"
: localSelection.length === 0
? "No spaces selected (showing all)"
: `${localSelection.length} space${localSelection.length > 1 ? "s" : ""} selected`}
</p>
<div className="flex items-center gap-[22px]">
<button

View file

@ -53,6 +53,7 @@ export interface SpaceSelectorProps {
showNewSpace?: boolean
enableDelete?: boolean
compact?: boolean
singleSelect?: boolean
}
const triggerVariants = {
@ -70,6 +71,7 @@ export function SpaceSelector({
showNewSpace = true,
enableDelete = false,
compact = false,
singleSelect = false,
}: SpaceSelectorProps) {
const [isOpen, setIsOpen] = useState(false)
const [showCreateDialog, setShowCreateDialog] = useState(false)
@ -272,20 +274,24 @@ export function SpaceSelector({
>
<div className="flex flex-col gap-2">
<div className="flex flex-col">
<DropdownMenuItem
onClick={handleSelectNovaSpaces}
className={cn(
"flex items-center gap-2 px-3 py-2.5 rounded-md cursor-pointer text-white text-sm font-medium",
isNovaSpaces
? "bg-[#293952]/40"
: "opacity-60 hover:opacity-100 hover:bg-[#293952]/40",
)}
>
<Globe className="size-4" />
<span className="flex-1">Nova Spaces</span>
</DropdownMenuItem>
{!singleSelect && (
<>
<DropdownMenuItem
onClick={handleSelectNovaSpaces}
className={cn(
"flex items-center gap-2 px-3 py-2.5 rounded-md cursor-pointer text-white text-sm font-medium",
isNovaSpaces
? "bg-[#293952]/40"
: "opacity-60 hover:opacity-100 hover:bg-[#293952]/40",
)}
>
<Globe className="size-4" />
<span className="flex-1">Nova Spaces</span>
</DropdownMenuItem>
<DropdownMenuSeparator className="bg-[#2E3033] my-1" />
<DropdownMenuSeparator className="bg-[#2E3033] my-1" />
</>
)}
<div className="px-3 py-1">
<span className="text-[10px] uppercase tracking-wider text-[#737373] font-medium">
@ -362,7 +368,7 @@ export function SpaceSelector({
}}
>
<Layers className="size-4" />
<span>Select Spaces</span>
<span>Select Space{!singleSelect && "s"}</span>
</button>
{showNewSpace && (
@ -386,6 +392,7 @@ export function SpaceSelector({
<AddSpaceModal
isOpen={showCreateDialog}
onClose={() => setShowCreateDialog(false)}
onCreated={(containerTag) => onValueChange([containerTag])}
/>
<SelectSpacesModal
@ -394,6 +401,7 @@ export function SpaceSelector({
selectedProjects={selectedProjects}
onApply={handleSelectSpacesApply}
projects={allProjects}
singleSelect={singleSelect}
/>
<Dialog