Improved querystring import on paste (#110)

This commit is contained in:
Gregory Schier
2024-09-25 08:03:19 -07:00
committed by GitHub
parent de7097ff1d
commit 7d97404c11
5 changed files with 36 additions and 25 deletions

View File

@@ -323,10 +323,11 @@ export const RequestPane = memo(function RequestPane({
url={activeRequest.url} url={activeRequest.url}
method={activeRequest.method} method={activeRequest.method}
placeholder="https://example.com" placeholder="https://example.com"
onPaste={(text) => { onPasteOverwrite={(text) => {
if (text.startsWith('curl ')) { if (text.startsWith('curl ')) {
importCurl.mutate({ overwriteRequestId: activeRequestId, command: text }); importCurl.mutate({ overwriteRequestId: activeRequestId, command: text });
} else { } else {
// Only import query if pasted text contains entire querystring
importQuerystring.mutate(text); importQuerystring.mutate(text);
} }
}} }}

View File

@@ -17,6 +17,7 @@ type Props = Pick<HttpRequest, 'url'> & {
onSend: () => void; onSend: () => void;
onUrlChange: (url: string) => void; onUrlChange: (url: string) => void;
onPaste?: (v: string) => void; onPaste?: (v: string) => void;
onPasteOverwrite?: (v: string) => void;
onCancel: () => void; onCancel: () => void;
submitIcon?: IconProps['icon'] | null; submitIcon?: IconProps['icon'] | null;
onMethodChange?: (method: string) => void; onMethodChange?: (method: string) => void;
@@ -37,6 +38,7 @@ export const UrlBar = memo(function UrlBar({
onCancel, onCancel,
onMethodChange, onMethodChange,
onPaste, onPaste,
onPasteOverwrite,
submitIcon = 'send_horizontal', submitIcon = 'send_horizontal',
autocomplete, autocomplete,
rightSlot, rightSlot,
@@ -77,6 +79,7 @@ export const UrlBar = memo(function UrlBar({
onFocus={() => setIsFocused(true)} onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)} onBlur={() => setIsFocused(false)}
onPaste={onPaste} onPaste={onPaste}
onPasteOverwrite={onPasteOverwrite}
onChange={onUrlChange} onChange={onUrlChange}
defaultValue={url} defaultValue={url}
placeholder={placeholder} placeholder={placeholder}

View File

@@ -55,6 +55,7 @@ export interface EditorProps {
useTemplating?: boolean; useTemplating?: boolean;
onChange?: (value: string) => void; onChange?: (value: string) => void;
onPaste?: (value: string) => void; onPaste?: (value: string) => void;
onPasteOverwrite?: (value: string) => void;
onFocus?: () => void; onFocus?: () => void;
onBlur?: () => void; onBlur?: () => void;
onKeyDown?: (e: KeyboardEvent) => void; onKeyDown?: (e: KeyboardEvent) => void;
@@ -83,6 +84,7 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
forceUpdateKey, forceUpdateKey,
onChange, onChange,
onPaste, onPaste,
onPasteOverwrite,
onFocus, onFocus,
onBlur, onBlur,
onKeyDown, onKeyDown,
@@ -121,6 +123,12 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
handlePaste.current = onPaste; handlePaste.current = onPaste;
}, [onPaste]); }, [onPaste]);
// Use ref so we can update the handler without re-initializing the editor
const handlePasteOverwrite = useRef<EditorProps['onPasteOverwrite']>(onPaste);
useEffect(() => {
handlePasteOverwrite.current = onPasteOverwrite;
}, [onPasteOverwrite]);
// Use ref so we can update the handler without re-initializing the editor // Use ref so we can update the handler without re-initializing the editor
const handleFocus = useRef<EditorProps['onFocus']>(onFocus); const handleFocus = useRef<EditorProps['onFocus']>(onFocus);
useEffect(() => { useEffect(() => {
@@ -303,6 +311,7 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
singleLine, singleLine,
onChange: handleChange, onChange: handleChange,
onPaste: handlePaste, onPaste: handlePaste,
onPasteOverwrite: handlePasteOverwrite,
onFocus: handleFocus, onFocus: handleFocus,
onBlur: handleBlur, onBlur: handleBlur,
onKeyDown: handleKeyDown, onKeyDown: handleKeyDown,
@@ -420,6 +429,7 @@ function getExtensions({
singleLine, singleLine,
onChange, onChange,
onPaste, onPaste,
onPasteOverwrite,
onFocus, onFocus,
onBlur, onBlur,
onKeyDown, onKeyDown,
@@ -427,6 +437,7 @@ function getExtensions({
container: HTMLDivElement | null; container: HTMLDivElement | null;
onChange: MutableRefObject<EditorProps['onChange']>; onChange: MutableRefObject<EditorProps['onChange']>;
onPaste: MutableRefObject<EditorProps['onPaste']>; onPaste: MutableRefObject<EditorProps['onPaste']>;
onPasteOverwrite: MutableRefObject<EditorProps['onPasteOverwrite']>;
onFocus: MutableRefObject<EditorProps['onFocus']>; onFocus: MutableRefObject<EditorProps['onFocus']>;
onBlur: MutableRefObject<EditorProps['onBlur']>; onBlur: MutableRefObject<EditorProps['onBlur']>;
onKeyDown: MutableRefObject<EditorProps['onKeyDown']>; onKeyDown: MutableRefObject<EditorProps['onKeyDown']>;
@@ -449,8 +460,12 @@ function getExtensions({
keydown: (e) => { keydown: (e) => {
onKeyDown.current?.(e); onKeyDown.current?.(e);
}, },
paste: (e) => { paste: (e, v) => {
onPaste.current?.(e.clipboardData?.getData('text/plain') ?? ''); const textData = e.clipboardData?.getData('text/plain') ?? '';
onPaste.current?.(textData);
if (v.state.selection.main.from === 0 && v.state.selection.main.to === v.state.doc.length) {
onPasteOverwrite.current?.(textData);
}
}, },
}), }),
tooltips({ parent }), tooltips({ parent }),

View File

@@ -35,6 +35,7 @@ export type InputProps = Omit<
onFocus?: () => void; onFocus?: () => void;
onBlur?: () => void; onBlur?: () => void;
onPaste?: (value: string) => void; onPaste?: (value: string) => void;
onPasteOverwrite?: (value: string) => void;
defaultValue?: string; defaultValue?: string;
leftSlot?: ReactNode; leftSlot?: ReactNode;
rightSlot?: ReactNode; rightSlot?: ReactNode;
@@ -62,6 +63,7 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
onChange, onChange,
onFocus, onFocus,
onPaste, onPaste,
onPasteOverwrite,
placeholder, placeholder,
require, require,
rightSlot, rightSlot,
@@ -179,6 +181,7 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
placeholder={placeholder} placeholder={placeholder}
onChange={handleChange} onChange={handleChange}
onPaste={onPaste} onPaste={onPaste}
onPasteOverwrite={onPasteOverwrite}
className={editorClassName} className={editorClassName}
onFocus={handleFocus} onFocus={handleFocus}
onBlur={handleBlur} onBlur={handleBlur}

View File

@@ -14,31 +14,20 @@ export function useImportQuerystring(requestId: string) {
return useMutation({ return useMutation({
mutationKey: ['import_querystring'], mutationKey: ['import_querystring'],
mutationFn: async (url: string) => { mutationFn: async (url: string) => {
const [baseUrl, ...rest] = url.split('?'); const split = url.split(/\?(.*)/s);
if (rest.length === 0) return; const baseUrl = split[0] ?? '';
const querystring = split[1] ?? '';
if (!querystring) return;
const request = await getHttpRequest(requestId); const request = await getHttpRequest(requestId);
if (request == null) return; if (request == null) return;
const querystring = rest.join('?');
const parsedParams = Array.from(new URLSearchParams(querystring).entries()); const parsedParams = Array.from(new URLSearchParams(querystring).entries());
const additionalUrlParameters: HttpUrlParameter[] = parsedParams.map( const urlParameters: HttpUrlParameter[] = parsedParams.map(([name, value]) => ({
([name, value]): HttpUrlParameter => ({ name,
name, value,
value, enabled: true,
enabled: true, }));
}),
);
const urlParameters: HttpUrlParameter[] = [...request.urlParameters];
for (const newParam of additionalUrlParameters) {
const index = urlParameters.findIndex((p) => p.name === newParam.name);
if (index >= 0) {
urlParameters[index]!.value = decodeURIComponent(newParam.value);
} else {
urlParameters.push(newParam);
}
}
await updateRequest.mutateAsync({ await updateRequest.mutateAsync({
id: requestId, id: requestId,
@@ -48,11 +37,11 @@ export function useImportQuerystring(requestId: string) {
}, },
}); });
if (additionalUrlParameters.length > 0) { if (urlParameters.length > 0) {
toast.show({ toast.show({
id: 'querystring-imported', id: 'querystring-imported',
color: 'info', color: 'info',
message: `Imported ${additionalUrlParameters.length} ${pluralize('param', additionalUrlParameters.length)} from URL`, message: `Extracted ${urlParameters.length} ${pluralize('parameter', urlParameters.length)} from URL`,
}); });
} }