Skip to content

Commit

Permalink
improve memo in several components
Browse files Browse the repository at this point in the history
  • Loading branch information
Cristhianzl committed Dec 16, 2024
1 parent bc0dd7c commit 53a675e
Show file tree
Hide file tree
Showing 13 changed files with 1,642 additions and 1,122 deletions.
309 changes: 128 additions & 181 deletions src/frontend/src/CustomNodes/NoteNode/NoteToolbarComponent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,220 +1,167 @@
import ShadTooltip from "@/components/common/shadTooltipComponent";
import { Button } from "@/components/ui/button";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import {
Select,
SelectContentWithoutPortal,
SelectItem,
SelectTrigger,
} from "@/components/ui/select-custom";
import { Select, SelectTrigger } from "@/components/ui/select-custom";
import { COLOR_OPTIONS } from "@/constants/constants";
import ToolbarSelectItem from "@/pages/FlowPage/components/nodeToolbarComponent/toolbarSelectItem";
import useAlertStore from "@/stores/alertStore";
import useFlowStore from "@/stores/flowStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { useShortcutsStore } from "@/stores/shortcuts";
import { noteDataType } from "@/types/flow";
import { classNames, cn, openInNewTab } from "@/utils/utils";
import { cloneDeep } from "lodash";
import { memo, useCallback, useMemo } from "react";
import IconComponent from "../../../components/common/genericIconComponent";
import { ColorPickerButtons } from "../components/color-picker-buttons";
import { SelectItems } from "../components/select-items";

export default function NoteToolbarComponent({
const NoteToolbarComponent = memo(function NoteToolbarComponent({
data,
bgColor,
}: {
data: noteDataType;
bgColor: string;
}) {
const setNoticeData = useAlertStore((state) => state.setNoticeData);
const nodes = useFlowStore((state) => state.nodes);
const setLastCopiedSelection = useFlowStore(
(state) => state.setLastCopiedSelection,
);
const paste = useFlowStore((state) => state.paste);
const shortcuts = useShortcutsStore((state) => state.shortcuts);

// Combine multiple store selectors into one to reduce re-renders
const { nodes, setLastCopiedSelection, paste, setNode, deleteNode } =
useFlowStore(
useCallback(
(state) => ({
nodes: state.nodes,
setLastCopiedSelection: state.setLastCopiedSelection,
paste: state.paste,
setNode: state.setNode,
deleteNode: state.deleteNode,
}),
[],
),
);

const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
const deleteNode = useFlowStore((state) => state.deleteNode);
const setNode = useFlowStore((state) => state.setNode);
const shortcuts = useShortcutsStore((state) => state.shortcuts);

function openDocs() {
const openDocs = useCallback(() => {
if (data.node?.documentation) {
return openInNewTab(data.node?.documentation);
}
setNoticeData({
title: `${data.id} docs is not available at the moment.`,
});
}
}, [data.node?.documentation, data.id, setNoticeData]);

const handleSelectChange = useCallback(
(event: string) => {
switch (event) {
case "documentation":
openDocs();
break;
case "delete":
takeSnapshot();
deleteNode(data.id);
break;
case "copy":
const node = nodes.filter((node) => node.id === data.id);
setLastCopiedSelection({ nodes: cloneDeep(node), edges: [] });
break;
case "duplicate":
const targetNode = nodes.find((node) => node.id === data.id);
if (targetNode) {
paste(
{
nodes: [targetNode],
edges: [],
},
{
x: 50,
y: 10,
paneX: targetNode.position.x,
paneY: targetNode.position.y,
},
);
}
break;
}
},
[
openDocs,
takeSnapshot,
deleteNode,
data.id,
nodes,
setLastCopiedSelection,
paste,
],
);

// Memoize the color picker background style
const colorPickerStyle = useMemo(
() => ({
backgroundColor: COLOR_OPTIONS[bgColor] ?? "#00000000",
}),
[bgColor],
);

const handleSelectChange = (event) => {
switch (event) {
case "documentation":
openDocs();
break;
case "delete":
takeSnapshot();
deleteNode(data.id);
break;
case "copy":
const node = nodes.filter((node) => node.id === data.id);
setLastCopiedSelection({ nodes: cloneDeep(node), edges: [] });
break;
case "duplicate":
paste(
{
nodes: [nodes.find((node) => node.id === data.id)!],
edges: [],
},
{
x: 50,
y: 10,
paneX: nodes.find((node) => node.id === data.id)?.position.x,
paneY: nodes.find((node) => node.id === data.id)?.position.y,
},
);
break;
}
};
// the deafult value is allways the first one if none is provided
return (
<>
<div className="w-26 noflow nowheel nopan nodelete nodrag h-10">
<span className="isolate inline-flex rounded-md shadow-sm">
<Popover>
<ShadTooltip content="Pick Color">
<PopoverTrigger>
<div>
<div className="w-26 noflow nowheel nopan nodelete nodrag h-10">
<span className="isolate inline-flex rounded-md shadow-sm">
<Popover>
<ShadTooltip content="Pick Color">
<PopoverTrigger>
<div>
<div
data-testid="color_picker"
className="relative inline-flex items-center rounded-l-md bg-background px-2 py-2 text-foreground shadow-md transition-all duration-500 ease-in-out hover:bg-muted focus:z-10"
>
<div
data-testid="color_picker"
className="relative inline-flex items-center rounded-l-md bg-background px-2 py-2 text-foreground shadow-md transition-all duration-500 ease-in-out hover:bg-muted focus:z-10"
>
<div
style={{
backgroundColor: COLOR_OPTIONS[bgColor] ?? "#00000000",
}}
className={cn(
"h-4 w-4 rounded-full",
COLOR_OPTIONS[bgColor] === null && "border",
)}
></div>
</div>
</div>
</PopoverTrigger>
</ShadTooltip>
<PopoverContent side="top" className="w-fit px-2 py-2">
<div className="flew-row flex gap-3">
{Object.entries(COLOR_OPTIONS).map(([color, code]) => {
return (
<Button
data-testid={`color_picker_button_${color}`}
unstyled
key={color}
onClick={() => {
setNode(data.id, (old) => ({
...old,
data: {
...old.data,
node: {
...old.data.node,
template: {
...old.data.node?.template,
backgroundColor: color,
},
},
},
}));
}}
>
<div
className={cn(
"h-4 w-4 rounded-full hover:border hover:border-ring",
bgColor === color ? "border-2 border-blue-500" : "",
code === null && "border",
)}
style={{
backgroundColor: code ?? "#00000000",
}}
></div>
</Button>
);
})}
</div>
</PopoverContent>
</Popover>
<Select onValueChange={handleSelectChange} value="">
<SelectTrigger>
<ShadTooltip content="Show More" side="top">
<div>
<div
data-testid="more-options-modal"
className={classNames(
"relative -ml-px inline-flex h-8 w-[2rem] items-center rounded-r-md bg-background text-foreground shadow-md transition-all duration-500 ease-in-out hover:bg-muted focus:z-10",
style={colorPickerStyle}
className={cn(
"h-4 w-4 rounded-full",
COLOR_OPTIONS[bgColor] === null && "border",
)}
>
<IconComponent
name="MoreHorizontal"
className="relative left-2 h-4 w-4"
/>
</div>
/>
</div>
</ShadTooltip>
</SelectTrigger>
<SelectContentWithoutPortal>
<SelectItem value={"duplicate"}>
<ToolbarSelectItem
shortcut={
shortcuts.find((obj) => obj.name === "Duplicate")?.shortcut!
}
value={"Duplicate"}
icon={"Copy"}
dataTestId="copy-button-modal"
/>
</SelectItem>
<SelectItem value={"copy"}>
<ToolbarSelectItem
shortcut={
shortcuts.find((obj) => obj.name === "Copy")?.shortcut!
}
value={"Copy"}
icon={"Clipboard"}
dataTestId="copy-button-modal"
/>
</SelectItem>
<SelectItem
value={"documentation"}
disabled={data.node?.documentation === ""}
>
<ToolbarSelectItem
shortcut={
shortcuts.find((obj) => obj.name === "Docs")?.shortcut!
}
value={"Docs"}
icon={"FileText"}
dataTestId="docs-button-modal"
/>
</SelectItem>
<SelectItem value={"delete"} className="focus:bg-red-400/[.20]">
<div className="font-red flex text-status-red">
</div>
</PopoverTrigger>
</ShadTooltip>
<PopoverContent side="top" className="w-fit px-2 py-2">
<ColorPickerButtons
bgColor={bgColor}
data={data}
setNode={setNode}
/>
</PopoverContent>
</Popover>

<Select onValueChange={handleSelectChange} value="">
<SelectTrigger>
<ShadTooltip content="Show More" side="top">
<div>
<div
data-testid="more-options-modal"
className={classNames(
"relative -ml-px inline-flex h-8 w-[2rem] items-center rounded-r-md bg-background text-foreground shadow-md transition-all duration-500 ease-in-out hover:bg-muted focus:z-10",
)}
>
<IconComponent
name="Trash2"
className="relative top-0.5 mr-2 h-4 w-4"
/>{" "}
<span className="">Delete</span>{" "}
<span className="absolute right-2 top-2 flex items-center justify-center rounded-sm px-1 py-[0.2]">
<IconComponent
name="Delete"
className="h-4 w-4 stroke-2 text-red-400"
></IconComponent>
</span>
name="MoreHorizontal"
className="relative left-2 h-4 w-4"
/>
</div>
</SelectItem>
</SelectContentWithoutPortal>
</Select>
</span>
</div>
</>
</div>
</ShadTooltip>
</SelectTrigger>
<SelectItems shortcuts={shortcuts} data={data} />
</Select>
</span>
</div>
);
}
});

NoteToolbarComponent.displayName = "NoteToolbarComponent";

export default NoteToolbarComponent;
Loading

0 comments on commit 53a675e

Please sign in to comment.