📦 chore(frontend): add react18-json-view package to package.json dependencies

🎨 style(App.css): reformat CSS code for better readability and consistency
🚀 feat(App.css): add styles for json-view component
🔨 refactor(parameterComponent): extract DictComponent to a separate file for reusability
🔧 chore(constants): add constant for CODE_DICT_DIALOG_SUBTITLE
🔨 refactor(EditNodeModal): extract DictComponent to a separate file for reusability
🔧 chore(constants): add constant for CODE_DICT_DIALOG_SUBTITLE
🔨 refactor(codeAreaModal): remove unused isTweakPage variable

🚀 feat(dictAreaModal): add DictAreaModal component to allow editing of dictionaries
🔧 chore(styleUtils.ts): import and add BookMarked icon to nodeIconsLucide for future use
This commit is contained in:
Cristhian Zanforlin Lousa 2023-09-04 20:15:23 -03:00
commit 1beca4ed12
10 changed files with 267 additions and 7258 deletions

File diff suppressed because it is too large Load diff

View file

@ -53,6 +53,7 @@
"react-syntax-highlighter": "^15.5.0",
"react-tabs": "^6.0.2",
"react-tooltip": "^5.21.1",
"react18-json-view": "^0.2.3",
"reactflow": "^11.8.3",
"rehype-mathjax": "^4.0.3",
"remark-gfm": "^3.0.1",

View file

@ -3,45 +3,77 @@
@tailwind utilities;
.App {
text-align: center;
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@font-face {
font-family: text-security-disc;
src: url("assets/text-security-disc.woff") format("woff");
font-family: text-security-disc;
src: url("assets/text-security-disc.woff") format("woff");
}
.json-view {
height: 370px !important;
background-color: #2c2c2c !important;
border-radius: 10px !important;
}
.jv-indent {
overflow-y: auto !important;
max-height: 310px !important;
border-radius: 10px;
}
.jv-indent::-webkit-scrollbar {
width: 8px !important;
height: 8px !important;
border-radius: 10px;
}
.jv-indent::-webkit-scrollbar-track {
background-color: #f1f1f1 !important;
border-radius: 10px;
}
.jv-indent::-webkit-scrollbar-thumb {
background-color: #ccc !important;
border-radius: 999px !important;
}
.jv-indent::-webkit-scrollbar-thumb:hover {
background-color: #bbb !important;
}

View file

@ -32,6 +32,7 @@ import {
nodeNames,
} from "../../../../utils/styleUtils";
import { classNames, groupByFamily } from "../../../../utils/utils";
import DictComponent from "../../../../components/dictComponent";
export default function ParameterComponent({
left,
@ -109,6 +110,21 @@ export default function ParameterComponent({
setDictArr(convertObjToArray(dict));
}, [dict]);
const [obj, setObj] = useState({
arr: ["test", 123456, false, null],
boolean: false,
longString:
"long string long string long string long string long string long string",
number: 123456,
try: {
k1: 123,
k2: "123",
k3: false,
},
string: "string"
});
useEffect(() => {
if (name === "openai_api_base") console.log(info);
// @ts-ignore
@ -224,7 +240,20 @@ export default function ParameterComponent({
type === "int") &&
!optionalHandle ? (
<></>
) : left === true && type === "dict" ? (
)
: left === true && type === "str" ? (
<div className="mt-2 w-full">
<DictComponent
disabled={disabled}
editNode={false}
value={obj}
onChange={(newValue) => {
setDict(newValue);
}}
/>
</div>
)
: left === true && type === "dict" ? (
<div className="mt-2 w-full">
<KeypairListComponent
disabled={disabled}

View file

@ -0,0 +1,48 @@
import { useEffect } from "react";
import { KeyPairListComponent } from "../../types/components";
import { classNames } from "../../utils/utils";
import { Input } from "../ui/input";
import DictAreaModal from "../../modals/dictAreaModal";
export default function DictComponent({
value,
onChange,
disabled,
editNode = false,
}: KeyPairListComponent): JSX.Element {
useEffect(() => {
if (disabled) {
onChange([""]);
}
}, [disabled]);
return (
<div
className={classNames(
value.length > 1 && editNode ? "my-1" : "",
"flex flex-col gap-3"
)}
>
{
<div className="flex w-full gap-3">
<DictAreaModal
value={value}
onChange={(obj) => {
onChange(obj);
}}
>
<Input
disabled={true}
type="text"
className={
editNode ? "input-edit-node cursor-pointer" : "cursor-pointer"
}
placeholder="Click edit your dictionary..."
/>
</DictAreaModal>
</div>
}
</div>
);
}

View file

@ -115,6 +115,10 @@ export const EDIT_DIALOG_SUBTITLE =
export const CODE_PROMPT_DIALOG_SUBTITLE =
"Edit your Python code. This code snippet accepts module import and a single function definition. Make sure that your function returns a string.";
export const CODE_DICT_DIALOG_SUBTITLE =
"Edit your dictionary. This dialog allows you to create your own customized dictionary. You can add as many key-value pairs as you want.";
/**
* The base text for subtitle of Prompt Dialog
* @constant

View file

@ -34,6 +34,7 @@ import {
} from "../../utils/reactflowUtils";
import { classNames } from "../../utils/utils";
import BaseModal from "../baseModal";
import DictComponent from "../../components/dictComponent";
const EditNodeModal = forwardRef(
(
@ -99,30 +100,20 @@ const EditNodeModal = forwardRef(
setDictArr(convertObjToArray(dict));
}, [dict]);
const convertToArray = (singleObject) => {
let arrConverted: any = [];
for (const key in singleObject) {
if (singleObject.hasOwnProperty(key)) {
const newObj = {};
newObj[key] = singleObject[key];
arrConverted.push(newObj);
}
}
setDictArr(arrConverted);
};
const [obj, setObj] = useState({
arr: ["test", 123456, false, null],
boolean: false,
longString:
"long string long string long string long string long string long string",
number: 123456,
try: {
k1: 123,
k2: "123",
k3: false,
},
string: "string"
});
const convertToDict = (newValue): void => {
const flattenedObject = {};
for (const obj of newValue) {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
flattenedObject[key] = obj[key];
}
}
}
let newData = cloneDeep(flattenedObject);
setDict(newData);
};
return (
<BaseModal size="large-h-full" open={modalOpen} setOpen={setModalOpen}>
@ -213,7 +204,21 @@ const EditNodeModal = forwardRef(
handleOnNewValue(value, templateParam);
}}
/>
) : myData.node?.template[templateParam]
)
: myData.node?.template[templateParam]
.type === "str" ? (
<div className="mt-2 w-full">
<DictComponent
disabled={disabled}
editNode={false}
value={obj}
onChange={(newValue) => {
setDict(newValue);
}}
/>
</div>
)
: myData.node?.template[templateParam]
.type === "dict" ? (
<div className="mt-2 w-full">
<KeypairListComponent

View file

@ -28,7 +28,7 @@ export default function CodeAreaModal({
const { dark } = useContext(darkContext);
const { reactFlowInstance } = useContext(typesContext);
const [height, setHeight] = useState<string | null>(null);
const { setErrorData, setSuccessData, isTweakPage } =
const { setErrorData, setSuccessData } =
useContext(alertContext);
const [error, setError] = useState<{
detail: { error: string | undefined; traceback: string | undefined };

View file

@ -0,0 +1,63 @@
import "ace-builds/src-noconflict/ace";
import "ace-builds/src-noconflict/ext-language_tools";
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 { useState } from "react";
import JsonView from "react18-json-view";
import "react18-json-view/src/dark.css";
import "react18-json-view/src/style.css";
import IconComponent from "../../components/genericIconComponent";
import { Button } from "../../components/ui/button";
import { CODE_DICT_DIALOG_SUBTITLE } from "../../constants/constants";
import BaseModal from "../baseModal";
export default function DictAreaModal({
children,
onChange,
value,
}): JSX.Element {
const [open, setOpen] = useState(false);
const [dictObj, setDictObj] = useState(value);
return (
<BaseModal size="medium" open={open} setOpen={setOpen}>
<BaseModal.Trigger>{children}</BaseModal.Trigger>
<BaseModal.Header description={CODE_DICT_DIALOG_SUBTITLE}>
<span className="pr-2">Edit Dictionary</span>
<IconComponent
name="BookMarked"
className="h-6 w-6 pl-1 text-primary "
aria-hidden="true"
/>
</BaseModal.Header>
<BaseModal.Content>
<div className="flex h-full w-full flex-col transition-all">
<JsonView
theme="vscode"
dark={true}
editable
enableClipboard
onEdit={(edit) => {
setDictObj(edit["src"]);
}}
src={dictObj}
/>
<div className="flex h-fit w-full justify-end">
<Button
className="mt-3"
type="submit"
onClick={() => {
onChange(dictObj);
setOpen(false);
}}
>
Save
</Button>
</div>
</div>
</BaseModal.Content>
</BaseModal>
);
}

View file

@ -74,6 +74,7 @@ import {
X,
XCircle,
Zap,
BookMarked
} from "lucide-react";
import { FaApple, FaGithub } from "react-icons/fa";
import { AirbyteIcon } from "../icons/Airbyte";
@ -300,4 +301,5 @@ export const nodeIconsLucide: iconsType = {
UserCog2,
Key,
Unplug,
BookMarked
};