fixed copy and paste bug (#286)

fixed bug on copy and paste
This commit is contained in:
anovazzi1 2023-05-11 21:50:20 -03:00 • committed by GitHub
commit 9faf392aca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 147 additions and 84 deletions

View file

@ -1,5 +1,6 @@
import { useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { FloatComponentType } from "../../types/components"; import { FloatComponentType } from "../../types/components";
import { TabsContext } from "../../contexts/tabsContext";
export default function FloatComponent({ export default function FloatComponent({
value, value,
@ -13,6 +14,7 @@ export default function FloatComponent({
onChange(""); onChange("");
} }
}, [disabled, onChange]); }, [disabled, onChange]);
const {setDisableCP} = useContext(TabsContext)
return ( return (
<div className={disabled ? "pointer-events-none cursor-not-allowed" : ""}> <div className={disabled ? "pointer-events-none cursor-not-allowed" : ""}>
<input <input
@ -27,6 +29,12 @@ export default function FloatComponent({
setMyValue(e.target.value); setMyValue(e.target.value);
onChange(e.target.value); onChange(e.target.value);
}} }}
onBlur={() => {
setDisableCP(false)
}}
onFocus={() => {
setDisableCP(true)
}}
/> />
</div> </div>
); );

View file

@ -1,6 +1,7 @@
import { useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { InputComponentType } from "../../types/components"; import { InputComponentType } from "../../types/components";
import { classNames } from "../../utils"; import { classNames } from "../../utils";
import { TabsContext } from "../../contexts/tabsContext";
export default function InputComponent({ export default function InputComponent({
value, value,
@ -8,79 +9,86 @@ export default function InputComponent({
disabled, disabled,
password, password,
}: InputComponentType) { }: InputComponentType) {
const [myValue, setMyValue] = useState(value ?? ""); const [myValue, setMyValue] = useState(value ?? "");
const [pwdVisible, setPwdVisible] = useState(false); const [pwdVisible, setPwdVisible] = useState(false);
useEffect(() => { const {setDisableCP} = useContext(TabsContext)
if (disabled) { useEffect(() => {
setMyValue(""); if (disabled) {
onChange(""); setMyValue("");
} onChange("");
}, [disabled, onChange]); }
return ( }, [disabled, onChange]);
<div return (
className={ <div
disabled className={
? "relative pointer-events-none cursor-not-allowed" disabled
: "relative" ? "relative pointer-events-none cursor-not-allowed"
} : "relative"
> }
<input >
value={myValue} <input
className={classNames( value={myValue}
"block w-full pr-12 form-input dark:bg-gray-900 dark:border-gray-600 rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm", onBlur={() => {
disabled ? " bg-gray-200 dark:bg-gray-700" : "", setDisableCP(false)
password && !pwdVisible && myValue!=="" ? "password" : "" }}
)} onFocus={() => {
placeholder="Type a text" setDisableCP(true)
onChange={(e) => { }}
setMyValue(e.target.value); className={classNames(
onChange(e.target.value); "block w-full pr-12 form-input dark:bg-gray-900 dark:border-gray-600 rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm",
}} disabled ? " bg-gray-200 dark:bg-gray-700" : "",
/> password && !pwdVisible && myValue !== "" ? "password" : ""
<button )}
className="absolute inset-y-0 right-0 items-center px-4 text-gray-600 dark:text-gray-300" placeholder="Type a text"
onClick={() => { onChange={(e) => {
setPwdVisible(!pwdVisible); setMyValue(e.target.value);
}} onChange(e.target.value);
> }}
{password && />
(pwdVisible ? ( <button
<svg className="absolute inset-y-0 right-0 items-center px-4 text-gray-600"
xmlns="http://www.w3.org/2000/svg" onClick={() => {
fill="none" setPwdVisible(!pwdVisible);
viewBox="0 0 24 24" }}
strokeWidth={1.5} >
stroke="currentColor" {password &&
className="w-5 h-5" (pwdVisible ? (
> <svg
<path xmlns="http://www.w3.org/2000/svg"
strokeLinecap="round" fill="none"
strokeLinejoin="round" viewBox="0 0 24 24"
d="M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88" strokeWidth={1.5}
/> stroke="currentColor"
</svg> className="w-5 h-5"
) : ( >
<svg <path
xmlns="http://www.w3.org/2000/svg" strokeLinecap="round"
fill="none" strokeLinejoin="round"
viewBox="0 0 24 24" d="M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"
strokeWidth={1.5} />
stroke="currentColor" </svg>
className="w-5 h-5" ) : (
> <svg
<path xmlns="http://www.w3.org/2000/svg"
strokeLinecap="round" fill="none"
strokeLinejoin="round" viewBox="0 0 24 24"
d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z" strokeWidth={1.5}
/> stroke="currentColor"
<path className="w-5 h-5"
strokeLinecap="round" >
strokeLinejoin="round" <path
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" strokeLinecap="round"
/> strokeLinejoin="round"
</svg> d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"
))} />
</button> <path
</div> strokeLinecap="round"
); strokeLinejoin="round"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
/>
</svg>
))}
</button>
</div>
);
} }

View file

@ -1,6 +1,7 @@
import { PlusIcon, XMarkIcon } from "@heroicons/react/24/outline"; import { PlusIcon, XMarkIcon } from "@heroicons/react/24/outline";
import { useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { InputListComponentType } from "../../types/components"; import { InputListComponentType } from "../../types/components";
import { TabsContext } from "../../contexts/tabsContext";
var _ = require("lodash"); var _ = require("lodash");
@ -16,6 +17,7 @@ export default function InputListComponent({
onChange([""]); onChange([""]);
} }
}, [disabled, onChange]); }, [disabled, onChange]);
const {setDisableCP} = useContext(TabsContext)
return ( return (
<div <div
className={ className={
@ -41,6 +43,12 @@ export default function InputListComponent({
}); });
onChange(inputList); onChange(inputList);
}} }}
onBlur={() => {
setDisableCP(false)
}}
onFocus={() => {
setDisableCP(true)
}}
/> />
{idx === inputList.length - 1 ? ( {idx === inputList.length - 1 ? (
<button <button

View file

@ -1,5 +1,6 @@
import { useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { FloatComponentType } from "../../types/components"; import { FloatComponentType } from "../../types/components";
import { TabsContext } from "../../contexts/tabsContext";
export default function IntComponent({ export default function IntComponent({
value, value,
@ -13,6 +14,7 @@ export default function IntComponent({
onChange(""); onChange("");
} }
}, [disabled, onChange]); }, [disabled, onChange]);
const {setDisableCP} =useContext(TabsContext)
return ( return (
<div <div
className={ className={
@ -43,7 +45,14 @@ export default function IntComponent({
setMyValue(e.target.value); setMyValue(e.target.value);
onChange(e.target.value); onChange(e.target.value);
}} }}
onBlur={() => {
setDisableCP(false)
}}
onFocus={() => {
setDisableCP(true)
}}
/> />
</div> </div>
); );
} }

View file

@ -26,6 +26,8 @@ const TabsContextInitialValue: TabsContextType = {
downloadFlow: (flow: FlowType) => {}, downloadFlow: (flow: FlowType) => {},
uploadFlow: () => {}, uploadFlow: () => {},
hardReset: () => {}, hardReset: () => {},
disableCP:false,
setDisableCP:(state:boolean)=>{},
}; };
export const TabsContext = createContext<TabsContextType>( export const TabsContext = createContext<TabsContextType>(
@ -212,10 +214,13 @@ export function TabsProvider({ children }: { children: ReactNode }) {
return newFlows; return newFlows;
}); });
} }
const [disableCP, setDisableCP] = useState(false);
return ( return (
<TabsContext.Provider <TabsContext.Provider
value={{ value={{
disableCP,
setDisableCP,
save, save,
hardReset, hardReset,
tabIndex, tabIndex,

View file

@ -16,7 +16,7 @@ export default function ExportModal() {
const { closePopUp } = useContext(PopUpContext); const { closePopUp } = useContext(PopUpContext);
const ref = useRef(); const ref = useRef();
const { setErrorData } = useContext(alertContext); const { setErrorData } = useContext(alertContext);
const { flows, tabIndex, updateFlow, downloadFlow } = useContext(TabsContext); const { flows, tabIndex, updateFlow, downloadFlow,setDisableCP } = useContext(TabsContext);
function setModalOpen(x: boolean) { function setModalOpen(x: boolean) {
setOpen(x); setOpen(x);
if (x === false) { if (x === false) {
@ -113,6 +113,12 @@ export default function ExportModal() {
placeholder="File name" placeholder="File name"
id="name" id="name"
className="focus:border focus:border-blue block w-full px-3 py-2 border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-800 dark:border-gray-600 dark:focus:border-blue-500 dark:focus:ring-blue-500 text-gray-900 dark:text-gray-100" className="focus:border focus:border-blue block w-full px-3 py-2 border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-800 dark:border-gray-600 dark:focus:border-blue-500 dark:focus:ring-blue-500 text-gray-900 dark:text-gray-100"
onBlur={() => {
setDisableCP(false);
}}
onFocus={() => {
setDisableCP(true);
}}
/> />
</div> </div>
<div className="w-full"> <div className="w-full">
@ -127,6 +133,12 @@ export default function ExportModal() {
</span> </span>
</label> </label>
<textarea <textarea
onBlur={() => {
setDisableCP(false);
}}
onFocus={() => {
setDisableCP(true);
}}
name="description" name="description"
id="description" id="description"
onChange={(event) => { onChange={(event) => {
@ -151,6 +163,12 @@ export default function ExportModal() {
id="checkbox" id="checkbox"
type="checkbox" type="checkbox"
className="h-4 w-4 text-blue-600 border-gray-300 rounded dark:bg-gray-800 dark:border-gray-600 dark:focus:border-blue-500 dark:focus:ring-blue-500" className="h-4 w-4 text-blue-600 border-gray-300 rounded dark:bg-gray-800 dark:border-gray-600 dark:focus:border-blue-500 dark:focus:ring-blue-500"
onBlur={() => {
setDisableCP(false);
}}
onFocus={() => {
setDisableCP(true);
}}
/> />
<span className="ml-2 font-medium text-gray-700 dark:text-white"> <span className="ml-2 font-medium text-gray-700 dark:text-white">
Save with my API keys Save with my API keys

View file

@ -14,7 +14,7 @@ export default function TabComponent({
selected: boolean; selected: boolean;
onClick: () => void; onClick: () => void;
}) { }) {
const { removeFlow, updateFlow, flows } = useContext(TabsContext); const { removeFlow, updateFlow, flows, setDisableCP } = useContext(TabsContext);
const [isRename, setIsRename] = useState(false); const [isRename, setIsRename] = useState(false);
const [value, setValue] = useState(""); const [value, setValue] = useState("");
return ( return (
@ -40,11 +40,15 @@ export default function TabComponent({
<div className="bg-white dark:text-white dark:bg-gray-700 flex select-none justify-between w-44 items-center border border-b-0 border-gray-300 dark:border-gray-600 px-4 py-1 rounded-t-xl -ml-px"> <div className="bg-white dark:text-white dark:bg-gray-700 flex select-none justify-between w-44 items-center border border-b-0 border-gray-300 dark:border-gray-600 px-4 py-1 rounded-t-xl -ml-px">
{isRename ? ( {isRename ? (
<input <input
onFocus={() => {
setDisableCP(true);
}}
autoFocus autoFocus
className="bg-transparent focus:border-none active:outline hover:outline focus:outline outline-gray-300 rounded-md w-28" className="bg-transparent focus:border-none active:outline hover:outline focus:outline outline-gray-300 rounded-md w-28"
onBlur={() => { onBlur={() => {
setIsRename(false); setIsRename(false);
if (value !== "") { if (value !== "") {
setDisableCP(false);
let newFlow = _.cloneDeep(flow); let newFlow = _.cloneDeep(flow);
newFlow.name = value; newFlow.name = value;
updateFlow(newFlow); updateFlow(newFlow);

View file

@ -37,7 +37,7 @@ const nodeTypes = {
var _ = require("lodash"); var _ = require("lodash");
export default function FlowPage({ flow }: { flow: FlowType }) { export default function FlowPage({ flow }: { flow: FlowType }) {
let { updateFlow, incrementNodeId } = let { updateFlow, incrementNodeId, disableCP} =
useContext(TabsContext); useContext(TabsContext);
const { types, reactFlowInstance, setReactFlowInstance, templates } = const { types, reactFlowInstance, setReactFlowInstance, templates } =
useContext(typesContext); useContext(typesContext);
@ -46,11 +46,11 @@ export default function FlowPage({ flow }: { flow: FlowType }) {
const { undo, redo, canUndo, canRedo, takeSnapshot } = useUndoRedo(); const { undo, redo, canUndo, canRedo, takeSnapshot } = useUndoRedo();
const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => { const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
if ((event.ctrlKey || event.metaKey) && (event.key === 'c') && lastSelection) { if ((event.ctrlKey || event.metaKey) && (event.key === 'c') && lastSelection && !disableCP) {
event.preventDefault(); event.preventDefault();
setLastCopiedSelection(lastSelection); setLastCopiedSelection(lastSelection);
} }
if ((event.ctrlKey || event.metaKey) && (event.key === 'v') && lastCopiedSelection) { if ((event.ctrlKey || event.metaKey) && (event.key === 'v') && lastCopiedSelection && !disableCP) {
event.preventDefault(); event.preventDefault();
paste(); paste();
} }

View file

@ -12,6 +12,9 @@ export type TabsContextType = {
downloadFlow: (flow: FlowType) => void; downloadFlow: (flow: FlowType) => void;
uploadFlow: () => void; uploadFlow: () => void;
hardReset: () => void; hardReset: () => void;
//disable CopyPaste
disableCP: boolean;
setDisableCP: (value: boolean) => void;
}; };
export type LangFlowState = { export type LangFlowState = {