Files
zui/frontend/src/app/recollections/layout/RecollectionFileMenu.tsx
2026-03-16 09:51:45 +01:00

103 lines
3.3 KiB
TypeScript

/**
* File menu for a recollection (emanation).
* Hosts Save, Rename, Import, Export that used to live under the title dropdown.
*/
import React, { useMemo, useState } from 'react'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuPortal,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { Kbd, KbdGroup } from '@/components/ui/kbd'
import { useRecollectionActions } from './RecollectionActionsContext'
import { usePlatform } from '@/app/kosmos/KosmosContext'
import { RenameRecollectionDialog } from './RenameRecollectionDialog'
import { Download, FolderOpen, Pencil, Save } from 'lucide-react'
import { useParams } from 'react-router-dom'
export function RecollectionFileMenu() {
const { activeSlot, onImport, onExport } = useRecollectionActions()
const { recollections, renameRecollection } = usePlatform()
const { recollectionId } = useParams<{ recollectionId: string }>()
const [renameModalOpen, setRenameModalOpen] = useState(false)
const onSave = activeSlot?.onSave
const canSave = activeSlot?.canSave ?? false
const recollectionName = useMemo(
() => (recollectionId ? recollections.find((p) => p.id === recollectionId)?.name ?? '' : ''),
[recollectionId, recollections]
)
const menuItems = useMemo(
() => (
<>
{recollectionId && onSave != null && (
<>
<DropdownMenuItem onClick={onSave} disabled={!canSave} className="gap-2">
<Save className="h-4 w-4" />
Save
<span className="ml-auto pl-4">
<KbdGroup>
<Kbd>S</Kbd>
</KbdGroup>
</span>
</DropdownMenuItem>
<DropdownMenuSeparator />
</>
)}
{recollectionId && (
<>
<DropdownMenuItem onClick={() => setRenameModalOpen(true)} className="gap-2">
<Pencil className="h-4 w-4" />
Rename
</DropdownMenuItem>
<DropdownMenuSeparator />
</>
)}
<DropdownMenuItem onClick={onImport} className="gap-2">
<FolderOpen className="h-4 w-4" />
Import
</DropdownMenuItem>
<DropdownMenuItem onClick={onExport} className="gap-2">
<Download className="h-4 w-4" />
Export
</DropdownMenuItem>
</>
),
[recollectionId, onSave, canSave, onImport, onExport]
)
return (
<>
<DropdownMenu>
<DropdownMenuTrigger className="rounded-sm px-2 py-1 text-sm font-normal text-muted-foreground outline-none focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground data-[state=open]:bg-accent">
File
</DropdownMenuTrigger>
<DropdownMenuPortal>
<DropdownMenuContent align="start" className="z-[200] min-w-[12rem]">
{menuItems}
</DropdownMenuContent>
</DropdownMenuPortal>
</DropdownMenu>
<RenameRecollectionDialog
open={renameModalOpen}
onOpenChange={setRenameModalOpen}
recollectionId={recollectionId ?? ''}
initialName={recollectionName}
recollections={recollections}
onRename={(id, newName) => {
renameRecollection(id, newName)
setRenameModalOpen(false)
}}
/>
</>
)
}