Allow renaming URL path parameters from the Params tab (#528)

This commit is contained in:
Gregory Schier
2026-08-12 10:17:02 -07:00
committed by GitHub
parent 67a628d67a
commit a6be9dbaee
7 changed files with 458 additions and 64 deletions
+29 -17
View File
@@ -1,5 +1,5 @@
import type { HttpRequest } from "@yaakapp-internal/models";
import { patchModel } from "@yaakapp-internal/models";
import { getModel, patchModel } from "@yaakapp-internal/models";
import type { GenericCompletionOption } from "@yaakapp-internal/plugins";
import classNames from "classnames";
import { atom, useAtomValue } from "jotai";
@@ -19,7 +19,7 @@ import { useSendAnyHttpRequest } from "../hooks/useSendAnyHttpRequest";
import { deepEqualAtom } from "../lib/atoms";
import { languageFromContentType } from "../lib/contentType";
import { generateId } from "../lib/generateId";
import { extractPathPlaceholders } from "../lib/pathPlaceholders";
import { derivePathPlaceholderPairs, renamePathPlaceholder } from "../lib/pathPlaceholders";
import { convertRequestBody } from "../lib/requestBodyConversion";
import {
BODY_TYPE_BINARY,
@@ -42,7 +42,6 @@ import type { GenericCompletionConfig } from "./core/Editor/genericCompletion";
import { getUrlCompletionConfig } from "./core/Editor/url/completion";
import { Editor } from "./core/Editor/LazyEditor";
import { InlineCode } from "@yaakapp-internal/ui";
import type { Pair } from "./core/PairEditor";
import { PlainInput } from "./core/PlainInput";
import type { TabItem, TabsRef } from "./core/Tabs/Tabs";
import { setActiveTab, TabContent, Tabs } from "./core/Tabs/Tabs";
@@ -133,20 +132,33 @@ export function HttpRequestPane({ style, fullHeight, className, activeRequest }:
[activeRequest],
);
const { urlParameterPairs, urlParametersKey } = useMemo(() => {
const placeholderNames = extractPathPlaceholders(activeRequest.url);
const nonEmptyParameters = activeRequest.urlParameters.filter((p) => p.name || p.value);
const items: Pair[] = [...nonEmptyParameters];
for (const name of placeholderNames) {
const item = items.find((p) => p.name === name);
if (item) {
item.readOnlyName = true;
} else {
items.push({ name, value: "", enabled: true, readOnlyName: true, id: generateId() });
}
}
return { urlParameterPairs: items, urlParametersKey: placeholderNames.join(",") };
}, [activeRequest.url, activeRequest.urlParameters]);
// Renaming a path placeholder has to rewrite the URL and rename the parameter together, or the
// value detaches from the placeholder.
// NOTE: Reads the request fresh rather than closing over `activeRequest`. The row that calls this
// holds onto it until the URL's placeholders change, so a captured request would go stale and
// patch its parameter list back over newer edits.
const handleRenamePathPlaceholder = useCallback(
(oldName: string, newName: string) => {
const request = getModel("http_request", activeRequestId);
if (request == null) return false;
const patch = renamePathPlaceholder(request, oldName, newName);
if (patch == null) return false; // Unusable name, so the editor reverts the field
void patchModel(request, patch);
return true;
},
[activeRequestId],
);
const { urlParameterPairs, urlParametersKey } = useMemo(
() =>
derivePathPlaceholderPairs(
activeRequest.url,
activeRequest.urlParameters,
handleRenamePathPlaceholder,
),
[activeRequest.url, activeRequest.urlParameters, handleRenamePathPlaceholder],
);
let numParams = 0;
if (