File size: 4,484 Bytes
f909d7c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
import React from "react";
import { Menu, Flex, Text } from "@mantine/core";
import { useHotkeys } from "@mantine/hooks";
import ReactGA from "react-ga4";
import toast from "react-hot-toast";
import { CgChevronDown, CgArrowsShrinkH, CgArrowsMergeAltH } from "react-icons/cg";
import { VscExpandAll, VscCollapseAll, VscTarget } from "react-icons/vsc";
import useToggleHide from "src/hooks/useToggleHide";
import { getNextDirection } from "src/lib/utils/graph/getNextDirection";
import useGraph from "src/store/useGraph";
import * as Styles from "./styles";
function rotateLayout(direction: "LEFT" | "RIGHT" | "DOWN" | "UP") {
if (direction === "LEFT") return 90;
if (direction === "UP") return 180;
if (direction === "RIGHT") return 270;
return 360;
}
export const ViewMenu = () => {
const { validateHiddenNodes } = useToggleHide();
const [coreKey, setCoreKey] = React.useState("CTRL");
const toggleFold = useGraph(state => state.toggleFold);
const setDirection = useGraph(state => state.setDirection);
const direction = useGraph(state => state.direction);
const expandGraph = useGraph(state => state.expandGraph);
const collapseGraph = useGraph(state => state.collapseGraph);
const focusFirstNode = useGraph(state => state.focusFirstNode);
const foldNodes = useGraph(state => state.foldNodes);
const graphCollapsed = useGraph(state => state.graphCollapsed);
const toggleFoldNodes = () => {
toggleFold(!foldNodes);
toast(`${foldNodes ? "Unfolded" : "Folded"} nodes`);
};
const toggleDirection = () => {
const nextDirection = getNextDirection(direction || "RIGHT");
if (setDirection) setDirection(nextDirection);
};
const toggleExpandCollapseGraph = () => {
if (graphCollapsed) expandGraph();
else collapseGraph();
validateHiddenNodes();
toast(`${graphCollapsed ? "Expanded" : "Collapsed"} graph.`);
};
useHotkeys([
["mod+shift+d", toggleDirection],
["mod+shift+f", toggleFoldNodes],
["mod+shift+c", toggleExpandCollapseGraph],
[
"mod+f",
() => {
const input = document.querySelector("#search-node") as HTMLInputElement;
input.focus();
},
],
]);
React.useEffect(() => {
if (typeof window !== "undefined") {
setCoreKey(navigator.userAgent.indexOf("Mac OS X") ? "⌘" : "CTRL");
}
}, []);
return (
<Menu shadow="md" closeOnItemClick={false} withArrow>
<Menu.Target>
<Styles.StyledToolElement>
<Flex align="center" gap={3}>
View <CgChevronDown />
</Flex>
</Styles.StyledToolElement>
</Menu.Target>
<Menu.Dropdown>
<Menu.Item
fz={12}
onClick={() => {
toggleDirection();
ReactGA.event({
action: "toggle_layout_direction",
category: "User",
label: "Tools",
});
}}
leftSection={<Styles.StyledFlowIcon rotate={rotateLayout(direction || "RIGHT")} />}
rightSection={
<Text ml="md" fz={10} c="dimmed">
{coreKey} Shift D
</Text>
}
>
Rotate Layout
</Menu.Item>
<Menu.Item
fz={12}
onClick={() => {
toggleFoldNodes();
ReactGA.event({
action: "toggle_fold_nodes",
category: "User",
label: "Tools",
});
}}
leftSection={foldNodes ? <CgArrowsShrinkH /> : <CgArrowsMergeAltH />}
rightSection={
<Text ml="md" fz={10} c="dimmed">
{coreKey} Shift F
</Text>
}
>
{foldNodes ? "Unfold" : "Fold"} Nodes
</Menu.Item>
<Menu.Item
fz={12}
onClick={() => {
toggleExpandCollapseGraph();
ReactGA.event({
action: "toggle_collapse_nodes",
category: "User",
label: "Tools",
});
}}
leftSection={graphCollapsed ? <VscExpandAll /> : <VscCollapseAll />}
rightSection={
<Text ml="md" fz={10} c="dimmed">
{coreKey} Shift C
</Text>
}
>
{graphCollapsed ? "Expand" : "Collapse"} Nodes
</Menu.Item>
<Menu.Item fz={12} onClick={focusFirstNode} leftSection={<VscTarget />}>
Focus to First Node
</Menu.Item>
</Menu.Dropdown>
</Menu>
);
};
|