Skip to content

Commit

Permalink
enhancement: prevent esc on codeAreaModal (#3232)
Browse files Browse the repository at this point in the history
* add onEscapeKeyDown

* refactor: Add ConfirmationModal to CodeAreaModal for better user experience

* refactor: Update CodeAreaModal to use ReactAce for code editing

* fix closing o x modal

* refactor: Update CodeAreaModal to use ReactAce for code editing

* [autofix.ci] apply automated fixes

* decompose object

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
  • Loading branch information
3 people authored Aug 13, 2024
1 parent 46f7054 commit 6658426
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 13 deletions.
7 changes: 6 additions & 1 deletion src/frontend/src/modals/baseModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ interface BaseModalProps {
onChangeOpenModal?: (open?: boolean) => void;
type?: "modal" | "dialog";
onSubmit?: () => void;
onEscapeKeyDown?: (e: KeyboardEvent) => void;
}
function BaseModal({
open,
Expand All @@ -157,6 +158,7 @@ function BaseModal({
onChangeOpenModal,
type = "dialog",
onSubmit,
onEscapeKeyDown,
}: BaseModalProps) {
const headerChild = React.Children.toArray(children).find(
(child) => (child as React.ReactElement).type === Header,
Expand Down Expand Up @@ -204,7 +206,10 @@ function BaseModal({
) : (
<Dialog open={open} onOpenChange={setOpen}>
{triggerChild}
<DialogContent className={contentClasses}>
<DialogContent
onEscapeKeyDown={onEscapeKeyDown}
className={contentClasses}
>
{onSubmit ? (
<Form.Root
onSubmit={(event) => {
Expand Down
61 changes: 54 additions & 7 deletions src/frontend/src/modals/codeAreaModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import "ace-builds/src-noconflict/mode-python";
import "ace-builds/src-noconflict/theme-github";
import "ace-builds/src-noconflict/theme-twilight";
// import "ace-builds/webpack-resolver";
import { useEffect, useState } from "react";
import { useEffect, useRef, useState } from "react";
import AceEditor from "react-ace";
import ReactAce from "react-ace/lib/ace";
import IconComponent from "../../components/genericIconComponent";
import { Button } from "../../components/ui/button";
import { Input } from "../../components/ui/input";
Expand All @@ -26,6 +27,7 @@ import { useDarkStore } from "../../stores/darkStore";
import { CodeErrorDataTypeAPI } from "../../types/api";
import { codeAreaModalPropsType } from "../../types/components";
import BaseModal from "../baseModal";
import ConfirmationModal from "../confirmationModal";

export default function CodeAreaModal({
value,
Expand All @@ -47,6 +49,8 @@ export default function CodeAreaModal({
const [height, setHeight] = useState<string | null>(null);
const setSuccessData = useAlertStore((state) => state.setSuccessData);
const setErrorData = useAlertStore((state) => state.setErrorData);
const [openConfirmation, setOpenConfirmation] = useState(false);
const codeRef = useRef<ReactAce | null>(null);
const [error, setError] = useState<{
detail: CodeErrorDataTypeAPI;
} | null>(null);
Expand Down Expand Up @@ -123,10 +127,6 @@ export default function CodeAreaModal({
}
}

function handleClick() {
processCode();
}

useEffect(() => {
// Function to be executed after the state changes
const delayedFunction = setTimeout(() => {
Expand All @@ -143,12 +143,36 @@ export default function CodeAreaModal({
};
}, [error, setHeight]);

useEffect(() => {
if (!openConfirmation) {
codeRef.current?.editor.focus();
}
}, [openConfirmation]);

useEffect(() => {
setCode(value);
}, [value, open]);

return (
<BaseModal open={open} setOpen={setOpen}>
<BaseModal
onEscapeKeyDown={(e) => {
e.preventDefault();
if (code === value) {
setOpen(false);
} else {
if (
!(
codeRef.current?.editor.completer.popup &&
codeRef.current?.editor.completer.popup.isOpen
)
) {
setOpenConfirmation(true);
}
}
}}
open={open}
setOpen={setOpen}
>
<BaseModal.Trigger>{children}</BaseModal.Trigger>
<BaseModal.Header description={CODE_PROMPT_DIALOG_SUBTITLE}>
<span className="pr-2"> {EDIT_CODE_TITLE} </span>
Expand All @@ -168,6 +192,7 @@ export default function CodeAreaModal({
<div className="flex h-full w-full flex-col transition-all">
<div className="h-full w-full">
<AceEditor
ref={codeRef}
readOnly={readonly}
value={code}
mode="python"
Expand Down Expand Up @@ -209,7 +234,7 @@ export default function CodeAreaModal({
<div className="flex h-fit w-full justify-end">
<Button
className="mt-3"
onClick={handleClick}
onClick={processCode}
type="submit"
id="checkAndSaveBtn"
disabled={readonly}
Expand All @@ -218,6 +243,28 @@ export default function CodeAreaModal({
</Button>
</div>
</div>
<ConfirmationModal
onClose={setOpenConfirmation}
onEscapeKeyDown={(e) => {
e.stopPropagation();
setOpenConfirmation(false);
}}
size="x-small"
icon="AlertTriangle"
confirmationText="Check & Save"
cancelText="Discard Changes"
open={openConfirmation}
onCancel={() => setOpen(false)}
onConfirm={() => {
processCode();
setOpenConfirmation(false);
}}
title="Caution"
>
<ConfirmationModal.Content>
<p>Are you sure you want to exit without saving your changes?</p>
</ConfirmationModal.Content>
</ConfirmationModal>
</BaseModal.Content>
</BaseModal>
);
Expand Down
10 changes: 5 additions & 5 deletions src/frontend/src/modals/confirmationModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import GenericIconComponent from "@/components/genericIconComponent";
import React, { useEffect, useState } from "react";
import ShadTooltip from "../../components/shadTooltipComponent";
import { Button } from "../../components/ui/button";
Expand Down Expand Up @@ -38,12 +39,11 @@ function ConfirmationModal({
data,
index,
onConfirm,
size,
open,
onClose,
onCancel,
...props
}: ConfirmationModalType) {
const Icon: any = nodeIconsLucide[icon];
const [modalOpen, setModalOpen] = useState(open ?? false);
const [flag, setFlag] = useState(false);

Expand All @@ -67,12 +67,12 @@ function ConfirmationModal({
);

return (
<BaseModal size={size} open={modalOpen} setOpen={setModalOpen}>
<BaseModal {...props} open={open} setOpen={setModalOpen}>
<BaseModal.Trigger>{triggerChild}</BaseModal.Trigger>
<BaseModal.Header description={titleHeader ?? null}>
<span className="pr-2">{title}</span>
<Icon
name="icon"
<GenericIconComponent
name={icon}
className="h-6 w-6 pl-1 text-foreground"
aria-hidden="true"
/>
Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/types/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ export type ConfirmationModalType = {
| "large-h-full"
| "small-h-full"
| "medium-h-full";
onEscapeKeyDown?: (e: KeyboardEvent) => void;
};

export type UserManagementType = {
Expand Down

0 comments on commit 6658426

Please sign in to comment.