From b824833b3332b53ba0d876c766583832c268286b Mon Sep 17 00:00:00 2001 From: Matthias Konitzny <konitzny@ibr.cs.tu-bs.de> Date: Mon, 18 Jul 2022 13:00:17 +0200 Subject: [PATCH] Partially implemented neighbor menu --- src/display/components/collapsible.css | 13 +++--- src/display/components/collapsible.tsx | 13 +++++- src/display/components/nodeinfo/neighbors.css | 0 src/display/components/nodeinfo/neighbors.tsx | 42 +++++++++++++++++++ .../components/nodeinfo/nodeinfobar.tsx | 19 ++------- 5 files changed, 64 insertions(+), 23 deletions(-) create mode 100644 src/display/components/nodeinfo/neighbors.css create mode 100644 src/display/components/nodeinfo/neighbors.tsx diff --git a/src/display/components/collapsible.css b/src/display/components/collapsible.css index 8bc1d8f..b61443e 100644 --- a/src/display/components/collapsible.css +++ b/src/display/components/collapsible.css @@ -4,8 +4,12 @@ border-bottom: 1px solid #dee2e6 !important; } +.collapsible-content-padding > ul { + margin: 0 0 0 2em; +} + .collapsible-content-padding { - padding: 20px 20px 20px 30px; + padding: 10px 0 10px 10px; } .collapsible-rotate-center { @@ -59,18 +63,17 @@ content: "\276E"; margin-left: auto; transition: all 0.2s linear; - transform: rotate(90deg); + transform: rotate(-90deg); } .collapsible-button:not(.collapsed)::after { - transform: rotate(-90deg); + transform: rotate(90deg); } .collapsible-card { - box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); transition: 0.3s; } .collapsible-card:hover { - box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1); } diff --git a/src/display/components/collapsible.tsx b/src/display/components/collapsible.tsx index b4dd7e4..3c3e6fc 100644 --- a/src/display/components/collapsible.tsx +++ b/src/display/components/collapsible.tsx @@ -5,10 +5,16 @@ interface CollapsibleProps { open?: boolean; header: string | React.ReactNode; children?: React.ReactNode | React.ReactNode[]; + color?: string; } -// Implementation details at nhttps://medium.com/edonec/build-a-react-collapsible-component-from-scratch-using-react-hooks-typescript-73dfd02c9208 -function Collapsible({ open, header, children }: CollapsibleProps) { +// Implementation details at https://medium.com/edonec/build-a-react-collapsible-component-from-scratch-using-react-hooks-typescript-73dfd02c9208 +function Collapsible({ + open, + header, + children, + color = "gray", +}: CollapsibleProps) { const [isOpen, setIsOpen] = useState(open); const [height, setHeight] = useState<number | undefined>( open ? undefined : 0 @@ -36,6 +42,8 @@ function Collapsible({ open, header, children }: CollapsibleProps) { else setHeight(0); }, [isOpen]); + const borderBottom = "1px solid " + color; + return ( <> <div className={"collapsible-card"}> @@ -46,6 +54,7 @@ function Collapsible({ open, header, children }: CollapsibleProps) { isOpen ? "" : "collapsed" }`} onClick={toggleOpen} + style={{ borderBottom }} > {header} </button> diff --git a/src/display/components/nodeinfo/neighbors.css b/src/display/components/nodeinfo/neighbors.css new file mode 100644 index 0000000..e69de29 diff --git a/src/display/components/nodeinfo/neighbors.tsx b/src/display/components/nodeinfo/neighbors.tsx new file mode 100644 index 0000000..36bf8c3 --- /dev/null +++ b/src/display/components/nodeinfo/neighbors.tsx @@ -0,0 +1,42 @@ +import React from "react"; +import { NodeData } from "../../graph"; +import FancyScrollbar from "../fancyscrollbar"; +import Collapsible from "../collapsible"; + +interface NeighborsProps { + neighbors: NodeData[]; + nodeClickedCallback?: (node: NodeData) => void; +} + +function Neighbors({ neighbors, nodeClickedCallback }: NeighborsProps) { + const classes = [...new Set<string>(neighbors.map((node) => node.type))]; + const categories = new Map<string, Array<NodeData>>(); + + for (const cls of classes) { + categories.set(cls, []); + } + + for (const neighbor of neighbors) { + categories.get(neighbor.type).push(neighbor); + } + + return ( + <div className={"neighbor-container"}> + <FancyScrollbar> + <Collapsible header={"Verwandte Inhalte"}> + {classes.map((cls) => ( + <Collapsible header={cls} key={cls}> + <ul> + {categories.get(cls).map((node) => ( + <li key={node.name}>{node.name}</li> + ))} + </ul> + </Collapsible> + ))} + </Collapsible> + </FancyScrollbar> + </div> + ); +} + +export default Neighbors; diff --git a/src/display/components/nodeinfo/nodeinfobar.tsx b/src/display/components/nodeinfo/nodeinfobar.tsx index 92cb560..d417092 100644 --- a/src/display/components/nodeinfo/nodeinfobar.tsx +++ b/src/display/components/nodeinfo/nodeinfobar.tsx @@ -3,6 +3,7 @@ import { NodeData } from "../../graph"; import TitleArea from "./titlearea"; import FancyScrollbar from "../fancyscrollbar"; import MediaArea from "./mediaarea"; +import Neighbors from "./neighbors"; interface InfoBarProps { height: number; @@ -11,22 +12,6 @@ interface InfoBarProps { } function NodeInfoBar({ height, node, nodeClosedCallback }: InfoBarProps) { - // const [isOpen, setIsOpen] = useState(open); - // const [height, setHeight] = useState<number | undefined>( - // open ? undefined : 0 - // ); - // - // const toggleOpen = () => { - // setIsOpen((prev) => !prev); - // }; - // - // const ref = useRef<HTMLDivElement>(null); - // - // useEffect(() => { - // if (isOpen) setHeight(targetHeight); - // else setHeight(0); - // }, [isOpen]); - return ( <div id={"infoOverlay"} className={"detail-view"} style={{ height }}> <div @@ -48,6 +33,8 @@ function NodeInfoBar({ height, node, nodeClosedCallback }: InfoBarProps) { /> </FancyScrollbar> </div> + + <Neighbors neighbors={node.neighbors} /> </div> ); } -- GitLab