Refactor: Visual shortcut update with the settings configuration

This commit is contained in:
igorrCarvalho 2024-05-03 19:39:27 -03:00
commit c6869c2eb5
6 changed files with 118 additions and 93 deletions

View file

@ -33,10 +33,10 @@ const SelectContent = React.forwardRef<
<SelectPrimitive.Content <SelectPrimitive.Content
ref={ref} ref={ref}
className={cn( className={cn(
"relative z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", "relative z-50 min-w-[14rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
position === "popper" && position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className className,
)} )}
position={position} position={position}
{...props} {...props}
@ -45,7 +45,7 @@ const SelectContent = React.forwardRef<
className={cn( className={cn(
"p-1", "p-1",
position === "popper" && position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]" "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]",
)} )}
> >
{children} {children}
@ -75,7 +75,7 @@ const SelectItem = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-3 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", "relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-3 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className className,
)} )}
{...props} {...props}
> >

View file

@ -796,35 +796,35 @@ export const SAVE_DEBOUNCE_TIME = 300;
export const defaultShortcuts = [ export const defaultShortcuts = [
{ {
name: "Advanced Settings", name: "Advanced Settings",
shortcut: "Ctrl + Shift + a", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + Shift + A`,
}, },
{ {
name: "Minimize", name: "Minimize",
shortcut: "Ctrl + q", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + Q`,
}, },
{ {
name: "Code", name: "Code",
shortcut: "Ctrl + Shift + u", shortcut: `Space`,
}, },
{ {
name: "Copy", name: "Copy",
shortcut: "Ctrl + c", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + C`,
}, },
{ {
name: "Duplicate", name: "Duplicate",
shortcut: "Ctrl + d", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + D`,
}, },
{ {
name: "Share", name: "Share",
shortcut: "Ctrl + Shift + s", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + Shift + S`,
}, },
{ {
name: "Docs", name: "Docs",
shortcut: "Ctrl + Shift + d", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + Shift + D`,
}, },
{ {
name: "Save", name: "Save",
shortcut: "Ctrl + s", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + S`,
}, },
{ {
name: "Delete", name: "Delete",
@ -832,31 +832,39 @@ export const defaultShortcuts = [
}, },
{ {
name: "Open playground", name: "Open playground",
shortcut: "Ctrl + k", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + K`,
}, },
{ {
name: "Undo", name: "Undo",
shortcut: "Ctrl + z", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + Z`,
}, },
{ {
name: "Redo", name: "Redo",
shortcut: "Ctrl + y", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + Y`,
}, },
{ {
name: "Group", name: "Group",
shortcut: "Ctrl + g", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + G`,
}, },
{ {
name: "Cut", name: "Cut",
shortcut: "Ctrl + x", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + X`,
}, },
{ {
name: "Paste", name: "Paste",
shortcut: "Ctrl + v", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + V`,
}, },
{ {
name: "API", name: "API",
shortcut: "Ctrl + r", shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + R`,
},
{
name: "Download",
shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + J`,
},
{
name: "Update",
shortcut: `${navigator.userAgent.toUpperCase().includes("MAC") ? "Cmd" : "Ctrl"} + U`,
}, },
]; ];
@ -877,4 +885,5 @@ export const unavailableShortcutss = [
"CTRL + K", "CTRL + K",
"CTRL + Z", "CTRL + Z",
"CTRL + Y", "CTRL + Y",
"CTRL + J",
]; ];

View file

@ -64,10 +64,12 @@ export default function NodeToolbarComponent({
data.node.template[templateField].type === "dict" || data.node.template[templateField].type === "dict" ||
data.node.template[templateField].type === "NestedDict"), data.node.template[templateField].type === "NestedDict"),
).length; ).length;
const templates = useTypesStore((state) => state.templates); const templates = useTypesStore((state) => state.templates);
const hasStore = useStoreStore((state) => state.hasStore); const hasStore = useStoreStore((state) => state.hasStore);
const hasApiKey = useStoreStore((state) => state.hasApiKey); const hasApiKey = useStoreStore((state) => state.hasApiKey);
const validApiKey = useStoreStore((state) => state.validApiKey); const validApiKey = useStoreStore((state) => state.validApiKey);
const shortcuts = useShortcutsStore((state) => state.shortcuts);
function handleMinimizeWShortcut(e: KeyboardEvent) { function handleMinimizeWShortcut(e: KeyboardEvent) {
e.preventDefault(); e.preventDefault();
@ -479,10 +481,10 @@ export default function NodeToolbarComponent({
{hasCode && ( {hasCode && (
<SelectItem value={"code"}> <SelectItem value={"code"}>
<ToolbarSelectItem <ToolbarSelectItem
keyboardKey="Space" shortcut={
shortcuts.find((obj) => obj.name === "Code")?.shortcut!
}
isMac={navigator.userAgent.toUpperCase().includes("MAC")} isMac={navigator.userAgent.toUpperCase().includes("MAC")}
shift={false}
mod={false}
value={"Code"} value={"Code"}
icon={"Code"} icon={"Code"}
dataTestId="code-button-modal" dataTestId="code-button-modal"
@ -492,9 +494,11 @@ export default function NodeToolbarComponent({
{nodeLength > 0 && ( {nodeLength > 0 && (
<SelectItem value={nodeLength === 0 ? "disabled" : "advanced"}> <SelectItem value={nodeLength === 0 ? "disabled" : "advanced"}>
<ToolbarSelectItem <ToolbarSelectItem
keyboardKey="A" shortcut={
shortcuts.find((obj) => obj.name === "Advanced Settings")
?.shortcut!
}
isMac={navigator.userAgent.toUpperCase().includes("MAC")} isMac={navigator.userAgent.toUpperCase().includes("MAC")}
shift={true}
value={"Advanced"} value={"Advanced"}
icon={"Settings2"} icon={"Settings2"}
dataTestId="edit-button-modal" dataTestId="edit-button-modal"
@ -503,9 +507,10 @@ export default function NodeToolbarComponent({
)} )}
<SelectItem value={"save"}> <SelectItem value={"save"}>
<ToolbarSelectItem <ToolbarSelectItem
keyboardKey="S" shortcut={
shortcuts.find((obj) => obj.name === "Save")?.shortcut!
}
isMac={navigator.userAgent.toUpperCase().includes("MAC")} isMac={navigator.userAgent.toUpperCase().includes("MAC")}
shift={false}
value={"Save"} value={"Save"}
icon={"SaveAll"} icon={"SaveAll"}
dataTestId="save-button-modal" dataTestId="save-button-modal"
@ -513,19 +518,21 @@ export default function NodeToolbarComponent({
</SelectItem> </SelectItem>
<SelectItem value={"duplicate"}> <SelectItem value={"duplicate"}>
<ToolbarSelectItem <ToolbarSelectItem
keyboardKey="D" shortcut={
shortcuts.find((obj) => obj.name === "Duplicate")?.shortcut!
}
isMac={navigator.userAgent.toUpperCase().includes("MAC")} isMac={navigator.userAgent.toUpperCase().includes("MAC")}
shift={false}
value={"Duplicate"} value={"Duplicate"}
icon={"Copy"} icon={"Copy"}
dataTestId="duplicate-button-modal" dataTestId="copy-button-modal"
/> />
</SelectItem> </SelectItem>
<SelectItem value={"copy"}> <SelectItem value={"copy"}>
<ToolbarSelectItem <ToolbarSelectItem
keyboardKey="C" shortcut={
shortcuts.find((obj) => obj.name === "Copy")?.shortcut!
}
isMac={navigator.userAgent.toUpperCase().includes("MAC")} isMac={navigator.userAgent.toUpperCase().includes("MAC")}
shift={false}
value={"Copy"} value={"Copy"}
icon={"Clipboard"} icon={"Clipboard"}
dataTestId="copy-button-modal" dataTestId="copy-button-modal"
@ -534,9 +541,10 @@ export default function NodeToolbarComponent({
{isOutdated && ( {isOutdated && (
<SelectItem value={"update"}> <SelectItem value={"update"}>
<ToolbarSelectItem <ToolbarSelectItem
keyboardKey="U" shortcut={
shortcuts.find((obj) => obj.name === "Update")?.shortcut!
}
isMac={navigator.userAgent.toUpperCase().includes("MAC")} isMac={navigator.userAgent.toUpperCase().includes("MAC")}
shift={false}
value={"Update"} value={"Update"}
icon={"Code"} icon={"Code"}
dataTestId="update-button-modal" dataTestId="update-button-modal"
@ -550,14 +558,12 @@ export default function NodeToolbarComponent({
disabled={!hasApiKey || !validApiKey} disabled={!hasApiKey || !validApiKey}
> >
<ToolbarSelectItem <ToolbarSelectItem
keyboardKey="S" shortcut={
shortcuts.find((obj) => obj.name === "Share")?.shortcut!
}
isMac={navigator.userAgent.toUpperCase().includes("MAC")} isMac={navigator.userAgent.toUpperCase().includes("MAC")}
shift={true}
value={"Share"} value={"Share"}
icon={"Share3"} icon={"Share3"}
styleObj={{
iconClasses: "relative top-0.5 -m-1 mr-[0.25rem] h-6 w-6",
}}
dataTestId="share-button-modal" dataTestId="share-button-modal"
/> />
</SelectItem> </SelectItem>
@ -565,13 +571,14 @@ export default function NodeToolbarComponent({
{(!hasStore || !hasApiKey || !validApiKey) && ( {(!hasStore || !hasApiKey || !validApiKey) && (
<SelectItem value={"Download"}> <SelectItem value={"Download"}>
<ToolbarSelectItem <ToolbarSelectItem
value="Download" shortcut={
shift={false} shortcuts.find((obj) => obj.name === "Download")
?.shortcut!
}
isMac={navigator.userAgent.toUpperCase().includes("MAC")} isMac={navigator.userAgent.toUpperCase().includes("MAC")}
icon="Download" value={"Download"}
styleObj={{ iconClasses: "relative top-0.5 mr-2 h-4 w-4" }} icon={"Download"}
keyboardKey={"J"} dataTestId="Download-button-modal"
dataTestId={"Dowload-button-nodeToolbar"}
/> />
</SelectItem> </SelectItem>
)} )}
@ -580,9 +587,10 @@ export default function NodeToolbarComponent({
disabled={data.node?.documentation === ""} disabled={data.node?.documentation === ""}
> >
<ToolbarSelectItem <ToolbarSelectItem
keyboardKey="D" shortcut={
shortcuts.find((obj) => obj.name === "Docs")?.shortcut!
}
isMac={navigator.userAgent.toUpperCase().includes("MAC")} isMac={navigator.userAgent.toUpperCase().includes("MAC")}
shift={true}
value={"Docs"} value={"Docs"}
icon={"FileText"} icon={"FileText"}
dataTestId="docs-button-modal" dataTestId="docs-button-modal"
@ -591,12 +599,14 @@ export default function NodeToolbarComponent({
{isMinimal && ( {isMinimal && (
<SelectItem value={"show"}> <SelectItem value={"show"}>
<ToolbarSelectItem <ToolbarSelectItem
icon={showNode ? "Minimize2" : "Maximize2"} shortcut={
value={showNode ? "Minimize" : "Expand"} shortcuts.find((obj) => obj.name === "Minimize")
?.shortcut!
}
isMac={navigator.userAgent.toUpperCase().includes("MAC")} isMac={navigator.userAgent.toUpperCase().includes("MAC")}
shift={false} value={showNode ? "Minimize" : "Expand"}
keyboardKey={"Q"} icon={showNode ? "Minimize2" : "Maximize2"}
dataTestId={"minimize-button-nodeToolbar"} dataTestId="minimize-button-modal"
/> />
</SelectItem> </SelectItem>
)} )}

View file

@ -2,16 +2,27 @@ import ForwardedIconComponent from "../../../../../components/genericIconCompone
import { toolbarSelectItemProps } from "../../../../../types/components"; import { toolbarSelectItemProps } from "../../../../../types/components";
export default function ToolbarSelectItem({ export default function ToolbarSelectItem({
shift,
isMac,
mod = true,
keyboardKey,
value, value,
icon, icon,
styleObj, styleObj,
dataTestId, dataTestId,
ping, ping,
shortcut,
isMac,
}: toolbarSelectItemProps) { }: toolbarSelectItemProps) {
let hasShift = false;
const fixedShortcut = shortcut?.split("+");
fixedShortcut.forEach((key) => {
if (key.toLowerCase().includes("shift")) {
hasShift = true;
}
});
const filteredShortcut = fixedShortcut.filter(
(key) => !key.toLowerCase().includes("shift"),
);
let shortcutWPlus = "";
if (!hasShift) shortcutWPlus = filteredShortcut.join("+");
return ( return (
<div className="flex" data-testid={dataTestId}> <div className="flex" data-testid={dataTestId}>
<ForwardedIconComponent <ForwardedIconComponent
@ -21,32 +32,25 @@ export default function ToolbarSelectItem({
}`} }`}
/> />
<span className={styleObj?.valueClasses}>{value}</span> <span className={styleObj?.valueClasses}>{value}</span>
<span
{mod && className={`absolute right-2 top-[0.43em] flex ${styleObj?.keyClasses}`}
(isMac ? ( >
<ForwardedIconComponent {hasShift ? (
name="Command" <>
className={`absolute {filteredShortcut[0]}
${shift ? " right-[2rem] " : "right-[1.15rem]"} <ForwardedIconComponent
top-[0.65em] h-3.5 w-3.5 stroke-2 ${styleObj?.commandClasses}`} name="ArrowBigUp"
></ForwardedIconComponent> className="ml-1 h-5 w-5"
/>
{filteredShortcut.map((key, idx) => {
if (idx > 0) {
return <span className="ml-1"> {key.toUpperCase()} </span>;
}
})}
</>
) : ( ) : (
<span shortcutWPlus
className={`absolute ${ )}
shift ? " right-[2.15rem] " : "right-[1.15rem]"
} top-[0.43em] stroke-2 `}
>
{shift ? "Ctrl" : "Ctrl +"}
</span>
))}
{shift && (
<ForwardedIconComponent
name="ArrowBigUp"
className={`absolute right-[1.15rem] top-[0.65em] h-3.5 w-3.5 stroke-2 ${styleObj?.shiftClasses}`}
/>
)}
<span className={`absolute right-2 top-[0.43em] ${styleObj?.keyClasses}`}>
{keyboardKey}
</span> </span>
</div> </div>
); );

View file

@ -5,6 +5,7 @@ import ForwardedIconComponent from "../../../../../components/genericIconCompone
import { Button } from "../../../../../components/ui/button"; import { Button } from "../../../../../components/ui/button";
import BaseModal from "../../../../../modals/baseModal"; import BaseModal from "../../../../../modals/baseModal";
import { useShortcutsStore } from "../../../../../stores/shortcuts"; import { useShortcutsStore } from "../../../../../stores/shortcuts";
import { toTitleCase } from "../../../../../utils/utils";
export default function EditShortcutButton({ export default function EditShortcutButton({
children, children,
@ -24,11 +25,11 @@ export default function EditShortcutButton({
disable?: boolean; disable?: boolean;
}): JSX.Element { }): JSX.Element {
const isMac = navigator.userAgent.toUpperCase().includes("MAC"); const isMac = navigator.userAgent.toUpperCase().includes("MAC");
const [key, setKey] = useState<string>(isMac ? "Meta" : "Ctrl"); const [key, setKey] = useState<string>(isMac ? "Cmd" : "Ctrl");
const setSuccessData = useAlertStore((state) => state.setSuccessData); const setSuccessData = useAlertStore((state) => state.setSuccessData);
const setShortcuts = useShortcutsStore((state) => state.setShortcuts); const setShortcuts = useShortcutsStore((state) => state.setShortcuts);
const unavaliableShortcuts = useShortcutsStore( const unavaliableShortcuts = useShortcutsStore(
(state) => state.unavailableShortcuts (state) => state.unavailableShortcuts,
); );
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
@ -43,7 +44,7 @@ export default function EditShortcutButton({
} }
const setUniqueShortcut = useShortcutsStore( const setUniqueShortcut = useShortcutsStore(
(state) => state.updateUniqueShortcut (state) => state.updateUniqueShortcut,
); );
function editCombination(): void { function editCombination(): void {
@ -70,7 +71,7 @@ export default function EditShortcutButton({
setKey(isMac ? "META" : "CTRL"); setKey(isMac ? "META" : "CTRL");
localStorage.setItem( localStorage.setItem(
"langflow-shortcuts", "langflow-shortcuts",
JSON.stringify(newCombination) JSON.stringify(newCombination),
); );
localStorage.setItem("langflow-UShortcuts", JSON.stringify(unavailable)); localStorage.setItem("langflow-UShortcuts", JSON.stringify(unavailable));
return; return;
@ -82,7 +83,7 @@ export default function EditShortcutButton({
} }
useEffect(() => { useEffect(() => {
if (!open) setKey(isMac ? "META" : "CTRL"); if (!open) setKey(isMac ? "Cmd" : "Ctrl");
console.log(key); console.log(key);
}, [open, setOpen, key]); }, [open, setOpen, key]);
@ -90,7 +91,10 @@ export default function EditShortcutButton({
function onKeyDown(e: KeyboardEvent) { function onKeyDown(e: KeyboardEvent) {
e.preventDefault(); e.preventDefault();
if (key.toUpperCase().includes(e.key.toUpperCase())) return; if (key.toUpperCase().includes(e.key.toUpperCase())) return;
setKey((oldKey) => `${oldKey.toUpperCase()} + ${e.key.toUpperCase()}`); setKey(
(oldKey) =>
`${oldKey.length > 0 ? toTitleCase(oldKey) : oldKey.toUpperCase()} + ${e.key.length > 0 ? toTitleCase(e.key) : e.key.toUpperCase()}`,
);
} }
document.addEventListener("keydown", onKeyDown); document.addEventListener("keydown", onKeyDown);

View file

@ -513,7 +513,7 @@ export type nodeToolbarPropsType = {
updateNodeCode?: ( updateNodeCode?: (
newNodeClass: APIClassType, newNodeClass: APIClassType,
code: string, code: string,
name: string name: string,
) => void; ) => void;
setShowState: (show: boolean | SetStateAction<boolean>) => void; setShowState: (show: boolean | SetStateAction<boolean>) => void;
isOutdated?: boolean; isOutdated?: boolean;
@ -563,7 +563,7 @@ export type chatMessagePropsType = {
updateChat: ( updateChat: (
chat: ChatMessageType, chat: ChatMessageType,
message: string, message: string,
stream_url?: string stream_url?: string,
) => void; ) => void;
}; };
@ -654,12 +654,12 @@ export type codeTabsPropsType = {
getValue?: ( getValue?: (
value: string, value: string,
node: NodeType, node: NodeType,
template: TemplateVariableType template: TemplateVariableType,
) => string; ) => string;
buildTweakObject?: ( buildTweakObject?: (
tw: string, tw: string,
changes: string | string[] | boolean | number | Object[] | Object, changes: string | string[] | boolean | number | Object[] | Object,
template: TemplateVariableType template: TemplateVariableType,
) => string | void; ) => string | void;
}; };
}; };
@ -729,9 +729,6 @@ export type IOFileInputProps = {
export type toolbarSelectItemProps = { export type toolbarSelectItemProps = {
isMac: boolean; isMac: boolean;
shift: boolean;
keyboardKey: string;
mod?: boolean;
value: string; value: string;
icon: string; icon: string;
styleObj?: { styleObj?: {
@ -744,4 +741,5 @@ export type toolbarSelectItemProps = {
}; };
dataTestId: string; dataTestId: string;
ping?: boolean; ping?: boolean;
shortcut: string;
}; };