mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-22 16:48:30 +02:00
Fix selection of HTTP Request on create dropdown hotkey
This commit is contained in:
@@ -118,7 +118,7 @@ const ae = "curl", se = "cURL", ie = "cURL command line tool", H = ["d", "data",
|
|||||||
function oe(n) {
|
function oe(n) {
|
||||||
if (!n.match(/^\s*curl /))
|
if (!n.match(/^\s*curl /))
|
||||||
return null;
|
return null;
|
||||||
const s = [], e = n.replace(/([^\\])\n/g, "$1; ");
|
const s = [], e = n.replace(/\ncurl/g, "; curl");
|
||||||
let t = [];
|
let t = [];
|
||||||
const m = Z(e).flatMap((r) => typeof r == "string" && r.startsWith("-") && !r.startsWith("--") && r.length > 2 ? [r.slice(0, 2), r.slice(2)] : r);
|
const m = Z(e).flatMap((r) => typeof r == "string" && r.startsWith("-") && !r.startsWith("--") && r.length > 2 ? [r.slice(0, 2), r.slice(2)] : r);
|
||||||
for (const r of m) {
|
for (const r of m) {
|
||||||
@@ -158,13 +158,13 @@ function te(n, s) {
|
|||||||
for (let o = 1; o < n.length; o++) {
|
for (let o = 1; o < n.length; o++) {
|
||||||
let l = n[o];
|
let l = n[o];
|
||||||
if (typeof l == "string" && (l = l.trim()), typeof l == "string" && l.match(/^-{1,2}[\w-]+/)) {
|
if (typeof l == "string" && (l = l.trim()), typeof l == "string" && l.match(/^-{1,2}[\w-]+/)) {
|
||||||
const $ = l[0] === "-" && l[1] !== "-";
|
const y = l[0] === "-" && l[1] !== "-";
|
||||||
let h = l.replace(/^-{1,2}/, "");
|
let h = l.replace(/^-{1,2}/, "");
|
||||||
if (!ee.includes(h))
|
if (!ee.includes(h))
|
||||||
continue;
|
continue;
|
||||||
let y;
|
let $;
|
||||||
const S = n[o + 1];
|
const S = n[o + 1];
|
||||||
$ && h.length > 1 ? (y = h.slice(1), h = h.slice(0, 1)) : typeof S == "string" && !S.startsWith("-") ? (y = S, o++) : y = !0, e[h] = e[h] || [], e[h].push(y);
|
y && h.length > 1 ? ($ = h.slice(1), h = h.slice(0, 1)) : typeof S == "string" && !S.startsWith("-") ? ($ = S, o++) : $ = !0, e[h] = e[h] || [], e[h].push($);
|
||||||
} else
|
} else
|
||||||
l && t.push(l);
|
l && t.push(l);
|
||||||
}
|
}
|
||||||
@@ -181,10 +181,10 @@ function te(n, s) {
|
|||||||
...e.header || [],
|
...e.header || [],
|
||||||
...e.H || []
|
...e.H || []
|
||||||
].map((o) => {
|
].map((o) => {
|
||||||
const [l, $] = o.split(/:(.*)$/);
|
const [l, y] = o.split(/:(.*)$/);
|
||||||
return $ ? {
|
return y ? {
|
||||||
name: (l ?? "").trim(),
|
name: (l ?? "").trim(),
|
||||||
value: $.trim()
|
value: y.trim()
|
||||||
} : {
|
} : {
|
||||||
name: (l ?? "").trim().replace(/;$/, ""),
|
name: (l ?? "").trim().replace(/;$/, ""),
|
||||||
value: ""
|
value: ""
|
||||||
@@ -193,8 +193,8 @@ function te(n, s) {
|
|||||||
...e.cookie || [],
|
...e.cookie || [],
|
||||||
...e.b || []
|
...e.b || []
|
||||||
].map((o) => {
|
].map((o) => {
|
||||||
const l = o.split("=", 1)[0], $ = o.replace(`${l}=`, "");
|
const l = o.split("=", 1)[0], y = o.replace(`${l}=`, "");
|
||||||
return `${l}=${$}`;
|
return `${l}=${y}`;
|
||||||
}).join("; "), u = i.find((o) => o.name.toLowerCase() === "cookie");
|
}).join("; "), u = i.find((o) => o.name.toLowerCase() === "cookie");
|
||||||
b && u ? u.value += `; ${b}` : b && i.push({
|
b && u ? u.value += `; ${b}` : b && i.push({
|
||||||
name: "Cookie",
|
name: "Cookie",
|
||||||
@@ -204,11 +204,11 @@ function te(n, s) {
|
|||||||
...e.form || [],
|
...e.form || [],
|
||||||
...e.F || []
|
...e.F || []
|
||||||
].map((o) => {
|
].map((o) => {
|
||||||
const l = o.split("="), $ = l[0] ?? "", h = l[1] ?? "", y = {
|
const l = o.split("="), y = l[0] ?? "", h = l[1] ?? "", $ = {
|
||||||
name: $,
|
name: y,
|
||||||
enabled: !0
|
enabled: !0
|
||||||
};
|
};
|
||||||
return h.indexOf("@") === 0 ? y.file = h.slice(1) : y.value = h, y;
|
return h.indexOf("@") === 0 ? $.file = h.slice(1) : $.value = h, $;
|
||||||
});
|
});
|
||||||
let g = {}, I = null;
|
let g = {}, I = null;
|
||||||
const B = C(e, !1, ["G", "get"]);
|
const B = C(e, !1, ["G", "get"]);
|
||||||
|
|||||||
@@ -2,12 +2,15 @@ import { useCreateDropdownItems } from '../hooks/useCreateDropdownItems';
|
|||||||
import type { DropdownProps } from './core/Dropdown';
|
import type { DropdownProps } from './core/Dropdown';
|
||||||
import { Dropdown } from './core/Dropdown';
|
import { Dropdown } from './core/Dropdown';
|
||||||
|
|
||||||
interface Props {
|
interface Props extends Omit<DropdownProps, 'items'> {
|
||||||
hideFolder?: boolean;
|
hideFolder?: boolean;
|
||||||
children: DropdownProps['children'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CreateDropdown({ hideFolder, children }: Props) {
|
export function CreateDropdown({ hideFolder, children, ...props }: Props) {
|
||||||
const items = useCreateDropdownItems({ hideFolder, hideIcons: true });
|
const items = useCreateDropdownItems({ hideFolder, hideIcons: true });
|
||||||
return <Dropdown items={items}>{children}</Dropdown>;
|
return (
|
||||||
|
<Dropdown items={items} {...props}>
|
||||||
|
{children}
|
||||||
|
</Dropdown>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,13 +34,8 @@ export function SidebarActions() {
|
|||||||
hotkeyAction="sidebar.toggle"
|
hotkeyAction="sidebar.toggle"
|
||||||
icon={hidden ? 'leftPanelHidden' : 'leftPanelVisible'}
|
icon={hidden ? 'leftPanelHidden' : 'leftPanelVisible'}
|
||||||
/>
|
/>
|
||||||
<CreateDropdown>
|
<CreateDropdown hotKeyAction="http_request.create">
|
||||||
<IconButton
|
<IconButton size="sm" icon="plusCircle" title="Add Resource" />
|
||||||
size="sm"
|
|
||||||
icon="plusCircle"
|
|
||||||
title="Add Resource"
|
|
||||||
hotkeyAction="http_request.create"
|
|
||||||
/>
|
|
||||||
</CreateDropdown>
|
</CreateDropdown>
|
||||||
</HStack>
|
</HStack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import { HotKey } from './HotKey';
|
|||||||
import { Separator } from './Separator';
|
import { Separator } from './Separator';
|
||||||
import { HStack, VStack } from './Stacks';
|
import { HStack, VStack } from './Stacks';
|
||||||
import { Icon } from './Icon';
|
import { Icon } from './Icon';
|
||||||
|
import { useStateWithDeps } from '../../hooks/useStateWithDeps';
|
||||||
|
|
||||||
export type DropdownItemSeparator = {
|
export type DropdownItemSeparator = {
|
||||||
type: 'separator';
|
type: 'separator';
|
||||||
@@ -58,6 +59,7 @@ export interface DropdownProps {
|
|||||||
items: DropdownItem[];
|
items: DropdownItem[];
|
||||||
onOpen?: () => void;
|
onOpen?: () => void;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
|
hotKeyAction?: HotkeyAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DropdownRef {
|
export interface DropdownRef {
|
||||||
@@ -71,7 +73,7 @@ export interface DropdownRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const Dropdown = forwardRef<DropdownRef, DropdownProps>(function Dropdown(
|
export const Dropdown = forwardRef<DropdownRef, DropdownProps>(function Dropdown(
|
||||||
{ children, items, onOpen, onClose }: DropdownProps,
|
{ children, items, onOpen, onClose, hotKeyAction }: DropdownProps,
|
||||||
ref,
|
ref,
|
||||||
) {
|
) {
|
||||||
const [isOpen, _setIsOpen] = useState<boolean>(false);
|
const [isOpen, _setIsOpen] = useState<boolean>(false);
|
||||||
@@ -88,18 +90,33 @@ export const Dropdown = forwardRef<DropdownRef, DropdownProps>(function Dropdown
|
|||||||
[onClose, onOpen],
|
[onClose, onOpen],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleClose = useCallback(() => {
|
||||||
|
setIsOpen(false);
|
||||||
|
buttonRef.current?.focus();
|
||||||
|
// Reset so it triggers a render if opening sets to 0, for example
|
||||||
|
setDefaultSelectedIndex(undefined);
|
||||||
|
}, [setIsOpen]);
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
...menuRef.current,
|
...menuRef.current,
|
||||||
isOpen: isOpen,
|
isOpen: isOpen,
|
||||||
toggle() {
|
toggle() {
|
||||||
if (!isOpen) this.open();
|
if (!isOpen) this.open();
|
||||||
else setIsOpen(false);
|
else this.close();
|
||||||
},
|
},
|
||||||
open() {
|
open() {
|
||||||
setIsOpen(true);
|
setIsOpen(true);
|
||||||
},
|
},
|
||||||
|
close() {
|
||||||
|
handleClose();
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
useHotKey(hotKeyAction ?? null, () => {
|
||||||
|
setDefaultSelectedIndex(0);
|
||||||
|
setIsOpen(true);
|
||||||
|
});
|
||||||
|
|
||||||
const child = useMemo(() => {
|
const child = useMemo(() => {
|
||||||
const existingChild = Children.only(children);
|
const existingChild = Children.only(children);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
@@ -119,11 +136,6 @@ export const Dropdown = forwardRef<DropdownRef, DropdownProps>(function Dropdown
|
|||||||
return cloneElement(existingChild, props);
|
return cloneElement(existingChild, props);
|
||||||
}, [children, setIsOpen]);
|
}, [children, setIsOpen]);
|
||||||
|
|
||||||
const handleClose = useCallback(() => {
|
|
||||||
setIsOpen(false);
|
|
||||||
buttonRef.current?.focus();
|
|
||||||
}, [setIsOpen]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
buttonRef.current?.setAttribute('aria-expanded', isOpen.toString());
|
buttonRef.current?.setAttribute('aria-expanded', isOpen.toString());
|
||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
@@ -206,7 +218,10 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
|||||||
}: MenuProps,
|
}: MenuProps,
|
||||||
ref,
|
ref,
|
||||||
) {
|
) {
|
||||||
const [selectedIndex, setSelectedIndex] = useState<number | null>(defaultSelectedIndex ?? null);
|
const [selectedIndex, setSelectedIndex] = useStateWithDeps<number | null>(
|
||||||
|
defaultSelectedIndex ?? null,
|
||||||
|
[defaultSelectedIndex],
|
||||||
|
);
|
||||||
const [menuStyles, setMenuStyles] = useState<CSSProperties>({});
|
const [menuStyles, setMenuStyles] = useState<CSSProperties>({});
|
||||||
const [filter, setFilter] = useState<string>('');
|
const [filter, setFilter] = useState<string>('');
|
||||||
const [containerWidth, setContainerWidth] = useState<number | null>(null);
|
const [containerWidth, setContainerWidth] = useState<number | null>(null);
|
||||||
@@ -223,7 +238,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
|||||||
onClose();
|
onClose();
|
||||||
setSelectedIndex(null);
|
setSelectedIndex(null);
|
||||||
setFilter('');
|
setFilter('');
|
||||||
}, [onClose]);
|
}, [onClose, setSelectedIndex]);
|
||||||
|
|
||||||
// Close menu on space bar
|
// Close menu on space bar
|
||||||
const handleMenuKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
|
const handleMenuKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
|
||||||
@@ -265,7 +280,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
|||||||
}
|
}
|
||||||
return nextIndex;
|
return nextIndex;
|
||||||
});
|
});
|
||||||
}, [items]);
|
}, [items, setSelectedIndex]);
|
||||||
|
|
||||||
const handleNext = useCallback(() => {
|
const handleNext = useCallback(() => {
|
||||||
setSelectedIndex((currIndex) => {
|
setSelectedIndex((currIndex) => {
|
||||||
@@ -282,7 +297,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
|||||||
}
|
}
|
||||||
return nextIndex;
|
return nextIndex;
|
||||||
});
|
});
|
||||||
}, [items]);
|
}, [items, setSelectedIndex]);
|
||||||
|
|
||||||
useKey(
|
useKey(
|
||||||
'ArrowUp',
|
'ArrowUp',
|
||||||
@@ -316,7 +331,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
|||||||
i.onSelect();
|
i.onSelect();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[handleClose],
|
[handleClose, setSelectedIndex],
|
||||||
);
|
);
|
||||||
|
|
||||||
useImperativeHandle(
|
useImperativeHandle(
|
||||||
@@ -377,7 +392,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
|||||||
const index = filteredItems.findIndex((item) => item === i) ?? null;
|
const index = filteredItems.findIndex((item) => item === i) ?? null;
|
||||||
setSelectedIndex(index);
|
setSelectedIndex(index);
|
||||||
},
|
},
|
||||||
[filteredItems],
|
[filteredItems, setSelectedIndex],
|
||||||
);
|
);
|
||||||
|
|
||||||
if (items.length === 0) return null;
|
if (items.length === 0) return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user