import { Dropdown } from "@digdir/designsystemet-react"; import { canDeleteSavedFilter, canRenameSavedFilter, getLocalizedString, type SavedFilter, } from "@olenbetong/appframe-core"; import { ChevronDownIcon, ChevronRightIcon, FilesIcon, FileTextIcon, MenuElipsisVerticalIcon, PadlockLockedIcon, PencilIcon, StarIcon, TrashIcon, } from "@navikt/aksel-icons"; import clsx from "clsx"; import { useState } from "react"; import "./SavedFilterTree.css"; /** `null` is the "new filter" node, i.e. no saved filter selected. */ export type SavedFilterSelection = number | null; export type SavedFilterTreeProps = { mine: SavedFilter[]; shared: SavedFilter[]; /** `FilterID` of the selected filter, or `null` for "new filter". */ value: SavedFilterSelection; onChange: (filterId: SavedFilterSelection) => void; /** * Marks the selected filter as having unsaved changes; it is then rendered * in bold, like the Windows client does. */ dirty?: boolean; onRename?: (filter: SavedFilter) => void; onDelete?: (filter: SavedFilter) => void; /** Shows an "info" item in the context menu when supplied. */ onShowInfo?: (filter: SavedFilter) => void; loading?: boolean; className?: string; "data-size"?: "sm" | "md" | "lg"; }; /** * The saved-filter list of the filter builder: a "new filter" entry followed by * the user's own filters and the filters shared with them. * * Which actions a filter offers depends on the access the database resolved for * it — renaming and deleting are restricted to filters the user created, even * when they manage a filter someone else made. * * @example * ```jsx * let { mine, shared, rename, remove } = useSavedFilters({ dbObjectId: "aviw_Personnel_Persons" }); * * rename(filter.filterId, prompt("Name", filter.name))} * /> * ``` */ export function SavedFilterTree({ mine, shared, value, onChange, dirty, onRename, onDelete, onShowInfo, loading, className, "data-size": size = "sm", }: SavedFilterTreeProps) { let [expanded, setExpanded] = useState({ mine: true, shared: true }); function renderBranch(key: "mine" | "shared", label: string, icon: React.ReactNode, filters: SavedFilter[]) { let isExpanded = expanded[key]; return (
  • {isExpanded && ( )}
  • ); } return ( ); } type SavedFilterNodeProps = { filter: SavedFilter; selected: boolean; dirty?: boolean; onSelect: () => void; onRename?: (filter: SavedFilter) => void; onDelete?: (filter: SavedFilter) => void; onShowInfo?: (filter: SavedFilter) => void; }; function SavedFilterNode({ filter, selected, dirty, onSelect, onRename, onDelete, onShowInfo }: SavedFilterNodeProps) { let canRename = Boolean(onRename) && canRenameSavedFilter(filter); let canDelete = Boolean(onDelete) && canDeleteSavedFilter(filter); let hasMenu = canRename || canDelete || Boolean(onShowInfo); // A shared filter the user may not change; the Windows client shows a lock. let isReadOnly = !filter.createdByUser && filter.accessLevel === "Reader"; return (
  • {hasMenu && ( {canRename && ( onRename?.(filter)}> {getLocalizedString("Rename")} )} {onShowInfo && ( onShowInfo(filter)}> {getLocalizedString("Information")} )} {canDelete && ( onDelete?.(filter)}> {getLocalizedString("Delete")} )} )}
  • ); }