UI improvements (#240)
some UI improvements: - fixed password toggle button - extend conversion to kebab case - fixed outside click on the alert dropdown - update logspace ui reference
This commit is contained in:
commit
db951cde20
8 changed files with 136 additions and 123 deletions
|
|
@ -24,7 +24,7 @@ export default function App() {
|
|||
setShowSideBar(true);
|
||||
setIsStackedOpen(true);
|
||||
}, [location.pathname, setCurrent, setIsStackedOpen, setShowSideBar]);
|
||||
const {hardReset} = useContext(TabsContext)
|
||||
const { hardReset } = useContext(TabsContext);
|
||||
const {
|
||||
errorData,
|
||||
errorOpen,
|
||||
|
|
@ -108,7 +108,7 @@ export default function App() {
|
|||
onReset={() => {
|
||||
window.localStorage.removeItem("tabsData");
|
||||
window.localStorage.clear();
|
||||
hardReset()
|
||||
hardReset();
|
||||
window.location.href = window.location.href;
|
||||
}}
|
||||
FallbackComponent={CrashErrorComponent}
|
||||
|
|
@ -158,7 +158,7 @@ export default function App() {
|
|||
<a
|
||||
target={"_blank"}
|
||||
href="https://logspace.ai/"
|
||||
className="absolute bottom-1 left-1 text-gray-500 text-xs cursor-pointer font-sans tracking-wide"
|
||||
className="absolute bottom-2 left-6 text-gray-300 px-2 rounded-lg text-xs cursor-pointer font-sans tracking-wide bg-gray-800 dark:bg-gray-300 dark:text-gray-800 "
|
||||
>
|
||||
Created by Logspace
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import {
|
|||
classNames,
|
||||
nodeColors,
|
||||
nodeIcons,
|
||||
snakeToNormalCase,
|
||||
toNormalCase,
|
||||
} from "../../utils";
|
||||
import ParameterComponent from "./components/parameterComponent";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
|
|
@ -192,8 +192,8 @@ export default function GenericNode({
|
|||
data.node.template[t].display_name
|
||||
? data.node.template[t].display_name
|
||||
: data.node.template[t].name
|
||||
? snakeToNormalCase(data.node.template[t].name)
|
||||
: snakeToNormalCase(t)
|
||||
? toNormalCase(data.node.template[t].name)
|
||||
: toNormalCase(t)
|
||||
}
|
||||
name={t}
|
||||
tooltipTitle={
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ export default function InputComponent({
|
|||
<input
|
||||
value={myValue}
|
||||
className={classNames(
|
||||
"block w-full 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",
|
||||
"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 ? "password" : ""
|
||||
password && !pwdVisible && myValue!=="" ? "password" : ""
|
||||
)}
|
||||
placeholder="Type a text"
|
||||
onChange={(e) => {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { XMarkIcon } from "@heroicons/react/24/outline";
|
|||
import { Fragment, useContext, useRef, useState } from "react";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { NodeDataType } from "../../types/flow";
|
||||
import { nodeColors, nodeIcons, snakeToNormalCase } from "../../utils";
|
||||
import { nodeColors, nodeIcons, toNormalCase } from "../../utils";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import ModalField from "./components/ModalField";
|
||||
|
||||
|
|
@ -99,10 +99,10 @@ export default function NodeModal({ data }: { data: NodeDataType }) {
|
|||
data.node.template[t].display_name
|
||||
? data.node.template[t].display_name
|
||||
: data.node.template[t].name
|
||||
? snakeToNormalCase(
|
||||
? toNormalCase(
|
||||
data.node.template[t].name
|
||||
)
|
||||
: snakeToNormalCase(t)
|
||||
: toNormalCase(t)
|
||||
}
|
||||
required={data.node.template[t].required}
|
||||
id={
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { PopUpContext } from "../../contexts/popUpContext";
|
|||
import { FlowType, NodeType } from "../../types/flow";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { classNames, snakeToNormalCase } from "../../utils";
|
||||
import { toNormalCase } from "../../utils";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import ChatMessage from "./chatMessage";
|
||||
import { FaEraser } from "react-icons/fa";
|
||||
|
|
@ -230,7 +230,7 @@ export default function ChatModal({
|
|||
`${type} is missing ${
|
||||
template.display_name
|
||||
? template.display_name
|
||||
: snakeToNormalCase(template[t].name)
|
||||
: toNormalCase(template[t].name)
|
||||
}.`,
|
||||
]
|
||||
: []
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import { error } from "console";
|
|||
import { alertContext } from "../../contexts/alertContext";
|
||||
import LoadingComponent from "../../components/loadingComponent";
|
||||
import { FlowType } from "../../types/flow";
|
||||
import { classNames } from "../../utils";
|
||||
import { classNames, toNormalCase } from "../../utils";
|
||||
|
||||
export default function ImportModal() {
|
||||
const [open, setOpen] = useState(true);
|
||||
|
|
@ -215,7 +215,7 @@ export default function ImportModal() {
|
|||
setModalOpen(false);
|
||||
}}
|
||||
textColor="text-emerald-400"
|
||||
title={example.name}
|
||||
title={toNormalCase(example.name)}
|
||||
></ButtonBox>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ import { TabsContext } from "../../../../contexts/tabsContext";
|
|||
import FlowPage from "../..";
|
||||
import { darkContext } from "../../../../contexts/darkContext";
|
||||
import {
|
||||
ArrowDownTrayIcon,
|
||||
ArrowUpTrayIcon,
|
||||
BellIcon,
|
||||
MoonIcon,
|
||||
SunIcon,
|
||||
ArrowDownTrayIcon,
|
||||
ArrowUpTrayIcon,
|
||||
BellIcon,
|
||||
MoonIcon,
|
||||
SunIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { PopUpContext } from "../../../../contexts/popUpContext";
|
||||
import AlertDropdown from "../../../../alerts/alertDropDown";
|
||||
|
|
@ -22,96 +22,101 @@ export default function TabsManagerComponent() {
|
|||
const { flows, addFlow, tabIndex, setTabIndex, uploadFlow, downloadFlow } =
|
||||
useContext(TabsContext);
|
||||
const { openPopUp } = useContext(PopUpContext);
|
||||
const {templates} = useContext(typesContext)
|
||||
const { templates } = useContext(typesContext);
|
||||
const AlertWidth = 256;
|
||||
const { dark, setDark } = useContext(darkContext);
|
||||
const { notificationCenter, setNotificationCenter } =
|
||||
useContext(alertContext);
|
||||
useEffect(() => {
|
||||
//create the first flow
|
||||
if (flows.length === 0&& Object.keys(templates).length>0) {
|
||||
if (flows.length === 0 && Object.keys(templates).length > 0) {
|
||||
addFlow();
|
||||
}
|
||||
}, [addFlow, flows.length,templates]);
|
||||
}, [addFlow, flows.length, templates]);
|
||||
|
||||
return (
|
||||
<div className="h-full w-full flex flex-col">
|
||||
<div className="w-full flex pr-2 flex-row text-center items-center bg-gray-100 dark:bg-gray-800 px-2">
|
||||
{flows.map((flow, index) => {
|
||||
return (
|
||||
<TabComponent
|
||||
onClick={() => setTabIndex(index)}
|
||||
selected={index === tabIndex}
|
||||
key={index}
|
||||
flow={flow}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<TabComponent
|
||||
onClick={() => {
|
||||
addFlow();
|
||||
}}
|
||||
selected={false}
|
||||
flow={null}
|
||||
/>
|
||||
<div className="ml-auto mr-2 flex gap-3">
|
||||
<button
|
||||
onClick={() => openPopUp(<ImportModal />)}
|
||||
className="flex items-center gap-1 pr-2 border-gray-400 border-r text-sm text-gray-600 hover:text-gray-500"
|
||||
>
|
||||
Import <ArrowUpTrayIcon className="w-5 h-5" />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => openPopUp(<ExportModal />)}
|
||||
className="flex items-center gap-1 mr-2 text-sm text-gray-600 hover:text-gray-500"
|
||||
>
|
||||
Export <ArrowDownTrayIcon className="h-5 w-5" />
|
||||
</button>
|
||||
<button
|
||||
className="text-gray-600 hover:text-gray-500 "
|
||||
onClick={() => {
|
||||
setDark(!dark);
|
||||
}}
|
||||
>
|
||||
{dark ? (
|
||||
<SunIcon className="h-5 w-5" />
|
||||
) : (
|
||||
<MoonIcon className="h-5 w-5" />
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
className="text-gray-600 hover:text-gray-500 relative"
|
||||
onClick={(event: React.MouseEvent<HTMLElement>) => {
|
||||
setNotificationCenter(false);
|
||||
const top = (event.target as Element).getBoundingClientRect().top;
|
||||
const left = (event.target as Element).getBoundingClientRect()
|
||||
.left;
|
||||
openPopUp(
|
||||
<div
|
||||
className="z-10 absolute"
|
||||
style={{ top: top + 20, left: left - AlertWidth }}
|
||||
>
|
||||
<AlertDropdown />
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
>
|
||||
{notificationCenter && (
|
||||
<div className="absolute w-1.5 h-1.5 rounded-full bg-red-600 right-[3px]"></div>
|
||||
)}
|
||||
<BellIcon className="h-5 w-5" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full h-full">
|
||||
<ReactFlowProvider>
|
||||
{flows[tabIndex] ? (
|
||||
<FlowPage flow={flows[tabIndex]}></FlowPage>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</ReactFlowProvider>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className="h-full w-full flex flex-col">
|
||||
<div className="w-full flex pr-2 flex-row text-center items-center bg-gray-100 dark:bg-gray-800 px-2">
|
||||
{flows.map((flow, index) => {
|
||||
return (
|
||||
<TabComponent
|
||||
onClick={() => setTabIndex(index)}
|
||||
selected={index === tabIndex}
|
||||
key={index}
|
||||
flow={flow}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<TabComponent
|
||||
onClick={() => {
|
||||
addFlow();
|
||||
}}
|
||||
selected={false}
|
||||
flow={null}
|
||||
/>
|
||||
<div className="ml-auto mr-2 flex gap-3">
|
||||
<button
|
||||
onClick={() => openPopUp(<ImportModal />)}
|
||||
className="flex items-center gap-1 pr-2 border-gray-400 border-r text-sm text-gray-600 hover:text-gray-500"
|
||||
>
|
||||
Import <ArrowUpTrayIcon className="w-5 h-5" />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => openPopUp(<ExportModal />)}
|
||||
className="flex items-center gap-1 mr-2 text-sm text-gray-600 hover:text-gray-500"
|
||||
>
|
||||
Export <ArrowDownTrayIcon className="h-5 w-5" />
|
||||
</button>
|
||||
<button
|
||||
className="text-gray-600 hover:text-gray-500 "
|
||||
onClick={() => {
|
||||
setDark(!dark);
|
||||
}}
|
||||
>
|
||||
{dark ? (
|
||||
<SunIcon className="h-5 w-5" />
|
||||
) : (
|
||||
<MoonIcon className="h-5 w-5" />
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
className="text-gray-600 hover:text-gray-500 relative"
|
||||
onClick={(event: React.MouseEvent<HTMLElement>) => {
|
||||
setNotificationCenter(false);
|
||||
const top = (event.target as Element).getBoundingClientRect().top;
|
||||
const left = (event.target as Element).getBoundingClientRect()
|
||||
.left;
|
||||
openPopUp(
|
||||
<>
|
||||
<div
|
||||
className="z-10 absolute"
|
||||
style={{ top: top + 20, left: left - AlertWidth }}
|
||||
>
|
||||
<AlertDropdown />
|
||||
</div>
|
||||
<div className="h-screen w-screen fixed top-0 left-0">
|
||||
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}}
|
||||
>
|
||||
{notificationCenter && (
|
||||
<div className="absolute w-1.5 h-1.5 rounded-full bg-red-600 right-[3px]"></div>
|
||||
)}
|
||||
<BellIcon className="h-5 w-5" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full h-full">
|
||||
<ReactFlowProvider>
|
||||
{flows[tabIndex] ? (
|
||||
<FlowPage flow={flows[tabIndex]}></FlowPage>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</ReactFlowProvider>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -316,16 +316,25 @@ export function toFirstUpperCase(str: string) {
|
|||
.join("");
|
||||
}
|
||||
|
||||
export function snakeToNormalCase(str: string) {
|
||||
return str
|
||||
.split("_")
|
||||
.map((word, index) => {
|
||||
if (index === 0) {
|
||||
return word[0].toUpperCase() + word.slice(1).toLowerCase();
|
||||
}
|
||||
return word.toLowerCase();
|
||||
})
|
||||
.join(" ");
|
||||
export function toNormalCase(str: string) {
|
||||
let result = str
|
||||
.split("_")
|
||||
.map((word, index) => {
|
||||
if (index === 0) {
|
||||
return word[0].toUpperCase() + word.slice(1).toLowerCase();
|
||||
}
|
||||
return word.toLowerCase();
|
||||
})
|
||||
.join(" ");
|
||||
|
||||
return result.split("-")
|
||||
.map((word, index) => {
|
||||
if (index === 0) {
|
||||
return word[0].toUpperCase() + word.slice(1).toLowerCase();
|
||||
}
|
||||
return word.toLowerCase();
|
||||
})
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
export function normalCaseToSnakeCase(str: string) {
|
||||
|
|
@ -388,16 +397,15 @@ export function isValidConnection(
|
|||
}
|
||||
|
||||
export function removeApiKeys(flow: FlowType): FlowType {
|
||||
let cleanFLow = _.cloneDeep(flow);
|
||||
cleanFLow.data.nodes.forEach((node) => {
|
||||
for (const key in node.data.node.template) {
|
||||
if (key.includes("api")) {
|
||||
console.log(node.data.node.template[key]);
|
||||
node.data.node.template[key].value = "";
|
||||
}
|
||||
}
|
||||
});
|
||||
return cleanFLow;
|
||||
let cleanFLow = _.cloneDeep(flow);
|
||||
cleanFLow.data.nodes.forEach((node) => {
|
||||
for (const key in node.data.node.template) {
|
||||
if (key.includes("api")) {
|
||||
node.data.node.template[key].value = "";
|
||||
}
|
||||
}
|
||||
});
|
||||
return cleanFLow;
|
||||
}
|
||||
|
||||
export function updateObject<T extends Record<string, any>>(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue