diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index 9486f24f7..8edc1affa 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -243,7 +243,6 @@ export default function ParameterComponent({ ) : ( @@ -311,7 +309,6 @@ export default function ParameterComponent({
diff --git a/src/frontend/src/components/EditFlowSettingsComponent/index.tsx b/src/frontend/src/components/EditFlowSettingsComponent/index.tsx index 349b151b5..390c3572e 100644 --- a/src/frontend/src/components/EditFlowSettingsComponent/index.tsx +++ b/src/frontend/src/components/EditFlowSettingsComponent/index.tsx @@ -51,7 +51,7 @@ export const EditFlowSettings: React.FC = ({ )}
{ - if (disableCopyPaste) setDisableCopyPaste(true); - }} - onBlur={() => { - if (disableCopyPaste) setDisableCopyPaste(false); - }} type="number" step={step} min={min} @@ -45,9 +35,10 @@ export default function FloatComponent({ max={max} value={value ?? ""} className={ - editNode + "nopan nodrag noundo nocopy " + + (editNode ? "input-edit-node" - : "input-primary" + (disabled ? " input-disable " : "") + : "input-primary" + (disabled ? " input-disable " : "")) } placeholder={ editNode ? "Number 0 to 1" : "Type a number from zero to one" diff --git a/src/frontend/src/components/inputComponent/index.tsx b/src/frontend/src/components/inputComponent/index.tsx index 7b33f18df..682d5716c 100644 --- a/src/frontend/src/components/inputComponent/index.tsx +++ b/src/frontend/src/components/inputComponent/index.tsx @@ -1,18 +1,15 @@ -import { useContext, useEffect, useState } from "react"; -import { TabsContext } from "../../contexts/tabsContext"; +import { useEffect, useState } from "react"; import { InputComponentType } from "../../types/components"; import { classNames } from "../../utils/utils"; export default function InputComponent({ value, onChange, - disableCopyPaste = false, disabled, password, editNode = false, }: InputComponentType) { const [pwdVisible, setPwdVisible] = useState(false); - const { setDisableCopyPaste } = useContext(TabsContext); // Clear component state useEffect(() => { @@ -25,18 +22,13 @@ export default function InputComponent({
{ - if (disableCopyPaste) setDisableCopyPaste(true); - }} - onBlur={() => { - if (disableCopyPaste) setDisableCopyPaste(false); - }} className={classNames( disabled ? " input-disable " : "", password && !pwdVisible && value !== "" ? " text-clip password " : "", editNode ? " input-edit-node " : " input-primary ", password && editNode ? "pr-8" : "", - password && !editNode ? "pr-10" : "" + password && !editNode ? "pr-10" : "", + "nopan nodrag noundo nocopy" )} placeholder={password && editNode ? "Key" : "Type something..."} onChange={(e) => { diff --git a/src/frontend/src/components/inputListComponent/index.tsx b/src/frontend/src/components/inputListComponent/index.tsx index d924095dd..a54b4151f 100644 --- a/src/frontend/src/components/inputListComponent/index.tsx +++ b/src/frontend/src/components/inputListComponent/index.tsx @@ -40,9 +40,10 @@ export default function InputListComponent({ type="text" value={i} className={ - editNode + "nopan nodrag noundo nocopy " + + (editNode ? "input-edit-node " - : "input-primary " + (disabled ? "input-disable" : "") + : "input-primary " + (disabled ? "input-disable" : "")) } placeholder="Type something..." onChange={(e) => { diff --git a/src/frontend/src/components/intComponent/index.tsx b/src/frontend/src/components/intComponent/index.tsx index c846fb772..24d28e4f5 100644 --- a/src/frontend/src/components/intComponent/index.tsx +++ b/src/frontend/src/components/intComponent/index.tsx @@ -1,15 +1,12 @@ -import { useContext, useEffect } from "react"; -import { TabsContext } from "../../contexts/tabsContext"; +import { useEffect } from "react"; import { FloatComponentType } from "../../types/components"; export default function IntComponent({ value, onChange, - disableCopyPaste = false, disabled, editNode = false, }: FloatComponentType) { - const { setDisableCopyPaste } = useContext(TabsContext); const min = 0; // Clear component state @@ -27,12 +24,6 @@ export default function IntComponent({ } > { - if (disableCopyPaste) setDisableCopyPaste(true); - }} - onBlur={() => { - if (disableCopyPaste) setDisableCopyPaste(false); - }} onKeyDown={(event) => { if ( event.key !== "Backspace" && @@ -61,9 +52,10 @@ export default function IntComponent({ }} value={value ?? ""} className={ - editNode + "nopan nodrag noundo nocopy " + + (editNode ? " input-edit-node " - : " input-primary " + (disabled ? " input-disable" : "") + : " input-primary " + (disabled ? " input-disable" : "")) } placeholder={editNode ? "Integer number" : "Type an integer number"} onChange={(e) => { diff --git a/src/frontend/src/components/textAreaComponent/index.tsx b/src/frontend/src/components/textAreaComponent/index.tsx index 0602fc7b6..2bead9a2d 100644 --- a/src/frontend/src/components/textAreaComponent/index.tsx +++ b/src/frontend/src/components/textAreaComponent/index.tsx @@ -1,6 +1,5 @@ -import { useContext, useEffect } from "react"; +import { useEffect } from "react"; import { TypeModal } from "../../constants/enums"; -import { TabsContext } from "../../contexts/tabsContext"; import GenericModal from "../../modals/genericModal"; import { TextAreaComponentType } from "../../types/components"; import IconComponent from "../genericIconComponent"; @@ -11,8 +10,6 @@ export default function TextAreaComponent({ disabled, editNode = false, }: TextAreaComponentType) { - const { setDisableCopyPaste } = useContext(TabsContext); - // Clear text area useEffect(() => { if (disabled) { @@ -25,17 +22,11 @@ export default function TextAreaComponent({
{ - setDisableCopyPaste(true); - }} - onBlur={() => { - setDisableCopyPaste(false); - }} className={ (editNode ? " input-edit-node " : " input-primary " + (disabled ? " input-disable" : "")) + - " w-full" + " nopan nodrag noundo nocopy w-full" } placeholder={"Type something..."} onChange={(e) => { diff --git a/src/frontend/src/components/ui/dialog.tsx b/src/frontend/src/components/ui/dialog.tsx index 54f261183..82641c063 100644 --- a/src/frontend/src/components/ui/dialog.tsx +++ b/src/frontend/src/components/ui/dialog.tsx @@ -44,7 +44,7 @@ const DialogContent = React.forwardRef< ( { diff --git a/src/frontend/src/contexts/tabsContext.tsx b/src/frontend/src/contexts/tabsContext.tsx index f60b92635..d12fa18ba 100644 --- a/src/frontend/src/contexts/tabsContext.tsx +++ b/src/frontend/src/contexts/tabsContext.tsx @@ -42,8 +42,6 @@ const TabsContextInitialValue: TabsContextType = { uploadFlow: () => {}, hardReset: () => {}, saveFlow: async (flow: FlowType) => {}, - disableCopyPaste: false, - setDisableCopyPaste: (state: boolean) => {}, lastCopiedSelection: null, setLastCopiedSelection: (selection: any) => {}, tabsState: {}, @@ -585,16 +583,12 @@ export function TabsProvider({ children }: { children: ReactNode }) { } } - const [disableCopyPaste, setDisableCopyPaste] = useState(false); - return ( { - undo: () => void; - redo: () => void; - takeSnapshot: () => void; - canUndo: boolean; - canRedo: boolean; -}; - type HistoryItem = { nodes: Node[]; edges: Edge[]; @@ -156,17 +149,21 @@ export function UndoRedoProvider({ children }) { } const keyDownHandler = (event: KeyboardEvent) => { - if ( - event.key === "z" && - (event.ctrlKey || event.metaKey) && - event.shiftKey - ) { - redo(); - } else if (event.key === "y" && (event.ctrlKey || event.metaKey)) { - event.preventDefault(); // prevent the default action - redo(); - } else if (event.key === "z" && (event.ctrlKey || event.metaKey)) { - undo(); + if (!isWrappedWithClass(event, "noundo")) { + if ( + event.key === "z" && + (event.ctrlKey || event.metaKey) && + event.shiftKey + ) { + event.preventDefault(); + redo(); + } else if (event.key === "y" && (event.ctrlKey || event.metaKey)) { + event.preventDefault(); // prevent the default action + redo(); + } else if (event.key === "z" && (event.ctrlKey || event.metaKey)) { + event.preventDefault(); + undo(); + } } }; diff --git a/src/frontend/src/index.css b/src/frontend/src/index.css index 05a099903..cde1ce040 100644 --- a/src/frontend/src/index.css +++ b/src/frontend/src/index.css @@ -241,8 +241,8 @@ The cursor: default; property value restores the browser's default cursor style @apply form-input block w-full truncate rounded-md border-border bg-background px-3 text-left shadow-sm placeholder:text-muted-foreground sm:text-sm; } - .input-edit-node { - @apply input-primary border-border pb-0.5 pt-0.5; + .input-edit-node{ + @apply input-primary border-border pt-0.5 pb-0.5 text-left w-full } .input-search { @apply input-primary mx-2 pr-7; diff --git a/src/frontend/src/modals/baseModal/index.tsx b/src/frontend/src/modals/baseModal/index.tsx index dc7ace755..870e8f948 100644 --- a/src/frontend/src/modals/baseModal/index.tsx +++ b/src/frontend/src/modals/baseModal/index.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useContext, useEffect, useState } from "react"; +import { ReactNode } from "react"; import React from "react"; import { @@ -9,7 +9,6 @@ import { DialogTitle, DialogTrigger, } from "../../components/ui/dialog"; -import { TabsContext } from "../../contexts/tabsContext"; type ContentProps = { children: ReactNode }; type HeaderProps = { children: ReactNode; description: string }; @@ -97,25 +96,9 @@ function BaseModal({ break; } - const { setDisableCopyPaste } = useContext(TabsContext); - const [openInner, setOpenInner] = useState(open ?? false); - - useEffect(() => { - setOpenInner(open); - }, [open]); - - useEffect(() => { - setOpen(openInner); - if (openInner) { - setDisableCopyPaste(true); - } else { - setDisableCopyPaste(false); - } - }, [openInner]); - //UPDATE COLORS AND STYLE CLASSSES return ( - + diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index f27002847..ac9aa1d01 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -27,6 +27,7 @@ import { undoRedoContext } from "../../../../contexts/undoRedoContext"; import { APIClassType } from "../../../../types/api"; import { FlowType, NodeType } from "../../../../types/flow"; import { isValidConnection } from "../../../../utils/reactflowUtils"; +import { isWrappedWithClass } from "../../../../utils/utils"; import ConnectionLineComponent from "../ConnectionLineComponent"; import ExtraSidebar from "../extraSidebarComponent"; @@ -38,7 +39,6 @@ export default function Page({ flow }: { flow: FlowType }) { let { updateFlow, uploadFlow, - disableCopyPaste, addFlow, getNodeId, paste, @@ -63,34 +63,34 @@ export default function Page({ flow }: { flow: FlowType }) { // this effect is used to attach the global event handlers const onKeyDown = (event: KeyboardEvent) => { - if ( - (event.ctrlKey || event.metaKey) && - event.key === "c" && - lastSelection && - !disableCopyPaste - ) { - event.preventDefault(); - setLastCopiedSelection(_.cloneDeep(lastSelection)); - } - if ( - (event.ctrlKey || event.metaKey) && - event.key === "v" && - lastCopiedSelection && - !disableCopyPaste - ) { - event.preventDefault(); - let bounds = reactFlowWrapper.current.getBoundingClientRect(); - paste(lastCopiedSelection, { - x: position.x - bounds.left, - y: position.y - bounds.top, - }); - } - if ( - (event.ctrlKey || event.metaKey) && - event.key === "g" && - lastSelection - ) { - event.preventDefault(); + if (!isWrappedWithClass(event, "nocopy")) { + if ( + (event.ctrlKey || event.metaKey) && + event.key === "c" && + lastSelection + ) { + event.preventDefault(); + setLastCopiedSelection(_.cloneDeep(lastSelection)); + } + if ( + (event.ctrlKey || event.metaKey) && + event.key === "v" && + lastCopiedSelection + ) { + event.preventDefault(); + let bounds = reactFlowWrapper.current.getBoundingClientRect(); + paste(lastCopiedSelection, { + x: position.x - bounds.left, + y: position.y - bounds.top, + }); + } + if ( + (event.ctrlKey || event.metaKey) && + event.key === "g" && + lastSelection + ) { + event.preventDefault(); + } } }; const handleMouseMove = (event) => { @@ -355,8 +355,6 @@ export default function Page({ flow }: { flow: FlowType }) { setLastSelection(flow); }, []); - const { setDisableCopyPaste } = useContext(TabsContext); - return (
@@ -378,15 +376,6 @@ export default function Page({ flow }: { flow: FlowType }) { }); }} edges={edges} - onPaneClick={() => { - setDisableCopyPaste(false); - }} - onPaneMouseLeave={() => { - setDisableCopyPaste(true); - }} - onPaneMouseEnter={() => { - setDisableCopyPaste(false); - }} onNodesChange={onNodesChangeMod} onEdgesChange={onEdgesChangeMod} onConnect={onConnect} @@ -407,9 +396,6 @@ export default function Page({ flow }: { flow: FlowType }) { onDrop={onDrop} onNodesDelete={onDelete} onSelectionChange={onSelectionChange} - nodesDraggable={!disableCopyPaste} - panOnDrag={!disableCopyPaste} - zoomOnDoubleClick={!disableCopyPaste} className="theme-attribution" minZoom={0.01} maxZoom={8} diff --git a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx index befaf798d..45aa67526 100644 --- a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx @@ -114,7 +114,7 @@ export default function ExtraSidebar() { name="search" id="search" placeholder="Search" - className="input-search" + className="nopan nodrag noundo nocopy input-search" onChange={(e) => { handleSearchInput(e.target.value); // Set search input state diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index bad739600..10f310905 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -7,7 +7,6 @@ export type InputComponentType = { disabled?: boolean; onChange: (value: string) => void; password: boolean; - disableCopyPaste?: boolean; editNode?: boolean; onChangePass?: (value: boolean | boolean) => void; showPass?: boolean; @@ -95,7 +94,6 @@ export type DisclosureComponentType = { export type FloatComponentType = { value: string; disabled?: boolean; - disableCopyPaste?: boolean; onChange: (value: string) => void; editNode?: boolean; }; diff --git a/src/frontend/src/types/tabs/index.ts b/src/frontend/src/types/tabs/index.ts index 82e75e4e4..1a873f651 100644 --- a/src/frontend/src/types/tabs/index.ts +++ b/src/frontend/src/types/tabs/index.ts @@ -20,9 +20,6 @@ export type TabsContextType = { uploadFlows: () => void; uploadFlow: (newFlow?: boolean, file?: File) => void; hardReset: () => void; - //disable CopyPaste - disableCopyPaste: boolean; - setDisableCopyPaste: (value: boolean) => void; getNodeId: (nodeType: string) => string; tabsState: TabsState; setTabsState: Dispatch>; diff --git a/src/frontend/src/utils/utils.ts b/src/frontend/src/utils/utils.ts index 3d846ff3b..8e6e14fda 100644 --- a/src/frontend/src/utils/utils.ts +++ b/src/frontend/src/utils/utils.ts @@ -85,6 +85,9 @@ export function checkUpperWords(str: string) { return words.join(" "); } +export const isWrappedWithClass = (event: any, className: string | undefined) => + event.target.closest(`.${className}`); + export function groupByFamily(data, baseClasses, left, type) { let parentOutput: string; let arrOfParent: string[] = [];