Refactor Accordion Component for Shared Usage (#653)

This pull request aims to refactor the Accordion Component to enable its
shared usage by both the formModal (chat) component and the Tweaks
component. By making the necessary modifications, we can eliminate code
duplication and improve maintainability across the application.
This commit is contained in:
anovazzi1 2023-07-18 16:15:31 -03:00 committed by GitHub
commit 8d4031dec0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 199 additions and 129 deletions

View file

@ -147,9 +147,9 @@
}
},
"node_modules/@babel/compat-data": {
"version": "7.22.6",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz",
"integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==",
"version": "7.22.9",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz",
"integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==",
"engines": {
"node": ">=6.9.0"
}
@ -194,6 +194,14 @@
"node": ">=6.9.0"
}
},
"node_modules/@babel/core/node_modules/@nicolo-ribaudo/semver-v6": {
"version": "6.3.3",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
"integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/generator": {
"version": "7.22.7",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.7.tgz",
@ -226,6 +234,14 @@
"@babel/core": "^7.0.0"
}
},
"node_modules/@babel/helper-compilation-targets/node_modules/@nicolo-ribaudo/semver-v6": {
"version": "6.3.3",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
"integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/helper-environment-visitor": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz",
@ -1175,9 +1191,9 @@
}
},
"node_modules/@mui/private-theming/node_modules/@babel/runtime": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz",
"integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==",
"version": "7.22.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
"integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
"dependencies": {
"regenerator-runtime": "^0.13.11"
},
@ -1338,14 +1354,6 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/@nicolo-ribaudo/semver-v6": {
"version": "6.3.3",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
"integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",

View file

@ -11,6 +11,7 @@ export default function AccordionComponent({
trigger,
children,
open = [],
keyValue,
}: AccordionComponentType) {
const [value, setValue] = useState(
open.length === 0 ? "" : getOpenAccordion()
@ -28,13 +29,18 @@ export default function AccordionComponent({
}
function handleClick() {
value == "" ? setValue(trigger) : setValue("");
value === "" ? setValue(keyValue) : setValue("");
}
return (
<>
<Accordion type="single" value={value} onValueChange={setValue}>
<AccordionItem value={trigger} className="border-none">
<Accordion
type="single"
className="w-full"
value={value}
onValueChange={setValue}
>
<AccordionItem value={keyValue} className="border-b">
<AccordionTrigger
onClick={() => {
handleClick();
@ -43,7 +49,9 @@ export default function AccordionComponent({
>
{trigger}
</AccordionTrigger>
<AccordionContent>{children}</AccordionContent>
<AccordionContent className="AccordionContent">
{children}
</AccordionContent>
</AccordionItem>
</Accordion>
</>

View file

@ -46,7 +46,7 @@ const AccordionContent = React.forwardRef<
<AccordionPrimitive.Content
ref={ref}
className={cn(
"overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
"data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm",
className
)}
{...props}

View file

@ -152,6 +152,34 @@ The cursor: default; property value restores the browser's default cursor style
cursor: default;
}
.AccordionContent {
overflow: hidden;
}
.AccordionContent[data-state='open'] {
animation: slideDown 300ms ease-out;
}
.AccordionContent[data-state='closed'] {
animation: slideUp 300ms ease-out;
}
@keyframes slideDown {
from {
height: 0;
}
to {
height: var(--radix-accordion-content-height);
}
}
@keyframes slideUp {
from {
height: var(--radix-accordion-content-height);
}
to {
height: 0;
}
}
@layer components {
.round-buttons-position {

View file

@ -340,6 +340,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
{tweaksList.current.includes(t["data"]["id"]) && (
<AccordionComponent
trigger={t["data"]["id"]}
keyValue={t["data"]["id"]}
open={openAccordion}
>
<div className="api-modal-table-arrangement">

View file

@ -81,7 +81,7 @@ export default function ChatMessage({
remarkPlugins={[remarkGfm, remarkMath]}
rehypePlugins={[rehypeMathjax]}
className="markdown prose inline-block break-words text-primary
dark:prose-invert sm:max-w-[30vw] lg:max-w-[40vw] sm:w-[30vw] lg:w-[40vw]"
dark:prose-invert sm:w-[30vw] sm:max-w-[30vw] lg:w-[40vw] lg:max-w-[40vw]"
components={{
code: ({
node,

View file

@ -10,13 +10,8 @@ import ChatInput from "./chatInput";
import ChatMessage from "./chatMessage";
import _ from "lodash";
import AccordionComponent from "../../components/AccordionComponent";
import ToggleShadComponent from "../../components/toggleShadComponent";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "../../components/ui/accordion";
import { Badge } from "../../components/ui/badge";
import {
Dialog,
@ -388,6 +383,7 @@ export default function FormModal({
setChatValue("");
}
}
return (
<Dialog open={open} onOpenChange={setModalOpen}>
<DialogTrigger className="hidden"></DialogTrigger>
@ -422,80 +418,127 @@ export default function FormModal({
</span>
</div>
</div>
<Accordion type="multiple" className="w-full">
{Object.keys(tabsState[id.current].formKeysData.input_keys).map(
(i, k) => (
<div className="file-component-accordion-div" key={k}>
<AccordionItem className="w-full" key={k} value={i}>
<AccordionTrigger className="flex gap-2">
<div className="file-component-badge-div">
<Badge variant="gray" size="md">
{i}
</Badge>
<div
className="-mb-1"
onClick={(event) => {
event.stopPropagation();
}}
>
<ToggleShadComponent
enabled={chatKey === i}
setEnabled={(value) =>
handleOnCheckedChange(value, i)
}
size="small"
disabled={tabsState[
id.current
].formKeysData.handle_keys.some((t) => t === i)}
/>
</div>
</div>
</AccordionTrigger>
<AccordionContent>
<div className="file-component-tab-column">
{tabsState[
id.current
].formKeysData.handle_keys.some((t) => t === i) && (
<div className="font-normal text-muted-foreground ">
Source: Component
</div>
)}
<Textarea
value={
tabsState[id.current].formKeysData.input_keys[i]
{Object.keys(tabsState[id.current].formKeysData.input_keys).map(
(i, k) => (
<div className="file-component-accordion-div" key={k}>
<AccordionComponent
trigger={
<div className="file-component-badge-div">
<Badge variant="gray" size="md">
{i}
</Badge>
<div
className="-mb-1"
onClick={(event) => {
event.stopPropagation();
}}
>
<ToggleShadComponent
enabled={chatKey === i}
setEnabled={(value) =>
handleOnCheckedChange(value, i)
}
onChange={(e) => {
setTabsState((old) => {
let newTabsState = _.cloneDeep(old);
newTabsState[
id.current
].formKeysData.input_keys[i] = e.target.value;
return newTabsState;
});
}}
disabled={chatKey === i}
placeholder="Enter text..."
></Textarea>
size="small"
disabled={tabsState[
id.current
].formKeysData.handle_keys.some((t) => t === i)}
/>
</div>
</AccordionContent>
</AccordionItem>
</div>
)
)}
{tabsState[id.current].formKeysData.memory_keys.map((i, k) => (
<AccordionItem key={k} value={i}>
<div className="tab-accordion-badge-div group">
<div className="group-hover:underline">
<Badge size="md" variant="gray">
</div>
}
key={k}
keyValue={i}
>
<div className="file-component-tab-column">
{tabsState[id.current].formKeysData.handle_keys.some(
(t) => t === i
) && (
<div className="font-normal text-muted-foreground ">
Source: Component
</div>
)}
<Textarea
className="custom-scroll"
value={
tabsState[id.current].formKeysData.input_keys[i]
}
onChange={(e) => {
setTabsState((old) => {
let newTabsState = _.cloneDeep(old);
newTabsState[id.current].formKeysData.input_keys[
i
] = e.target.value;
return newTabsState;
});
}}
disabled={chatKey === i}
placeholder="Enter text..."
></Textarea>
</div>
</AccordionComponent>
</div>
)
)}
{tabsState[id.current].formKeysData.memory_keys.map((i, k) => (
<div className="file-component-accordion-div" key={k}>
<AccordionComponent
trigger={
<div className="file-component-badge-div">
<Badge variant="gray" size="md">
{i}
</Badge>
<div
className="-mb-1"
onClick={(event) => {
event.stopPropagation();
}}
>
<ToggleShadComponent
enabled={chatKey === i}
setEnabled={(value) =>
handleOnCheckedChange(value, i)
}
size="small"
disabled={tabsState[
id.current
].formKeysData.handle_keys.some((t) => t === i)}
/>
</div>
</div>
Used as memory key
}
key={k}
keyValue={i}
>
<div className="file-component-tab-column">
{tabsState[id.current].formKeysData.handle_keys.some(
(t) => t === i
) && (
<div className="font-normal text-muted-foreground ">
Source: Component
</div>
)}
<Textarea
className="custom-scroll"
value={tabsState[id.current].formKeysData.input_keys[i]}
onChange={(e) => {
setTabsState((old) => {
let newTabsState = _.cloneDeep(old);
newTabsState[id.current].formKeysData.input_keys[
i
] = e.target.value;
return newTabsState;
});
}}
disabled={chatKey === i}
placeholder="Enter text..."
></Textarea>
</div>
</AccordionItem>
))}
</Accordion>
</AccordionComponent>
</div>
))}
</div>
<div className="eraser-column-arrangement">
<div className="eraser-size">

View file

@ -6,7 +6,11 @@ import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import { DialogTitle } from "../../components/ui/dialog";
import { Textarea } from "../../components/ui/textarea";
import { MAX_WORDS_HIGHLIGHT, PROMPT_DIALOG_SUBTITLE, TEXT_DIALOG_SUBTITLE } from "../../constants";
import {
MAX_WORDS_HIGHLIGHT,
PROMPT_DIALOG_SUBTITLE,
TEXT_DIALOG_SUBTITLE,
} from "../../constants";
import { alertContext } from "../../contexts/alertContext";
import { darkContext } from "../../contexts/darkContext";
import { PopUpContext } from "../../contexts/popUpContext";
@ -120,15 +124,16 @@ export default function GenericModal({
);
};
function getClassByNumberLength(){
function getClassByNumberLength() {
let sumOfCaracteres: number = 0;
wordsHighlight.forEach(element => {
sumOfCaracteres = sumOfCaracteres + element.replace(/[{}]/g, "").length
wordsHighlight.forEach((element) => {
sumOfCaracteres = sumOfCaracteres + element.replace(/[{}]/g, "").length;
});
return sumOfCaracteres > MAX_WORDS_HIGHLIGHT ? "code-highlight" : "code-nohighlight"
return sumOfCaracteres > MAX_WORDS_HIGHLIGHT
? "code-highlight"
: "code-nohighlight";
}
function validatePrompt(closeModal: boolean) {
postValidatePrompt(field_name, inputValue, nodeClass)
.then((apiReturn) => {
@ -234,7 +239,10 @@ export default function GenericModal({
<div className="mb-auto flex-1">
{type === TypeModal.PROMPT && (
<div className=" mr-2">
<div ref={divRef} className="max-h-20 overflow-y-auto custom-scroll">
<div
ref={divRef}
className="max-h-20 overflow-y-auto custom-scroll"
>
<div className="flex flex-wrap items-center">
<Variable className=" -ml-px mr-1 flex h-4 w-4 text-primary"></Variable>
<span className="text-md font-semibold text-primary">

View file

@ -130,7 +130,8 @@ export type RadialProgressType = {
export type AccordionComponentType = {
children?: ReactElement;
open?: string[];
trigger?: string;
trigger?: string | ReactElement;
keyValue?: string;
};
export type Side = "top" | "right" | "bottom" | "left";

View file

@ -28,20 +28,6 @@ module.exports = {
},
},
extend: {
keyframes: {
"accordion-down": {
from: { height: 0 },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: 0 },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
colors: {
connection: "var(--connection)",
"almost-dark-gray": "var(--almost-dark-gray)",
@ -129,20 +115,6 @@ module.exports = {
fontFamily: {
sans: ["var(--font-sans)", ...fontFamily.sans],
},
keyframes: {
slideDown: {
from: { height: 0 },
to: { height: 100 },
},
slideUp: {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: 0 },
},
},
animation: {
"accordion-down": "slideDown 300ms ease-out",
"accordion-up": "slideUp 300ms ease-in",
},
},
},
@ -214,6 +186,7 @@ module.exports = {
"&::-webkit-scrollbar-thumb:hover": {
backgroundColor: "#bbb",
},
"cursor": "auto"
},
".dark .theme-attribution .react-flow__attribution": {
backgroundColor: "rgba(255, 255, 255, 0.2)",