refactor: string url path (#7335)
This commit is contained in:
parent
2f22ca0aea
commit
618fcf934f
2 changed files with 38 additions and 20 deletions
|
|
@ -319,14 +319,15 @@ export const copyTextToClipboard = async (text: string): Promise<void> => {
|
||||||
await navigator.clipboard.writeText(text);
|
await navigator.clipboard.writeText(text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Joins URL path segments properly, removing duplicate slashes
|
* @description Joins URL path segments properly, removing duplicate slashes using URL encoding
|
||||||
* @param {...string} segments - URL path segments to join
|
* @param {...string} segments - URL path segments to join
|
||||||
* @returns {string} Properly joined URL path
|
* @returns {string} Properly joined URL path
|
||||||
* @example
|
* @example
|
||||||
* joinUrlPath("/workspace", "/projects") => "/workspace/projects"
|
* joinUrlPath("/workspace", "/projects") => "/workspace/projects"
|
||||||
* joinUrlPath("/workspace", "projects") => "/workspace/projects"
|
* joinUrlPath("/workspace", "projects") => "/workspace/projects"
|
||||||
* joinUrlPath("workspace", "projects") => "workspace/projects"
|
* joinUrlPath("workspace", "projects") => "/workspace/projects"
|
||||||
* joinUrlPath("/workspace/", "/projects/") => "/workspace/projects/"
|
* joinUrlPath("/workspace/", "/projects/") => "/workspace/projects/"
|
||||||
*/
|
*/
|
||||||
export const joinUrlPath = (...segments: string[]): string => {
|
export const joinUrlPath = (...segments: string[]): string => {
|
||||||
|
|
@ -336,21 +337,38 @@ export const joinUrlPath = (...segments: string[]): string => {
|
||||||
const validSegments = segments.filter((segment) => segment !== "");
|
const validSegments = segments.filter((segment) => segment !== "");
|
||||||
if (validSegments.length === 0) return "";
|
if (validSegments.length === 0) return "";
|
||||||
|
|
||||||
// Join segments and normalize slashes
|
// Process segments to normalize slashes
|
||||||
const joined = validSegments
|
const processedSegments = validSegments.map((segment, index) => {
|
||||||
.map((segment, index) => {
|
let processed = segment;
|
||||||
// Remove leading slashes from all segments except the first
|
|
||||||
if (index > 0) {
|
|
||||||
segment = segment.replace(/^\/+/, "");
|
|
||||||
}
|
|
||||||
// Remove trailing slashes from all segments except the last
|
|
||||||
if (index < validSegments.length - 1) {
|
|
||||||
segment = segment.replace(/\/+$/, "");
|
|
||||||
}
|
|
||||||
return segment;
|
|
||||||
})
|
|
||||||
.join("/");
|
|
||||||
|
|
||||||
// Clean up any duplicate slashes that might have been created
|
// Remove leading slashes from all segments except the first
|
||||||
return joined.replace(/\/+/g, "/");
|
if (index > 0) {
|
||||||
};
|
while (processed.startsWith("/")) {
|
||||||
|
processed = processed.substring(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove trailing slashes from all segments except the last
|
||||||
|
if (index < validSegments.length - 1) {
|
||||||
|
while (processed.endsWith("/")) {
|
||||||
|
processed = processed.substring(0, processed.length - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return processed;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Join segments with single slash
|
||||||
|
const joined = processedSegments.join("/");
|
||||||
|
|
||||||
|
// Use URL constructor to normalize the path and handle double slashes
|
||||||
|
try {
|
||||||
|
// Create a dummy URL to leverage browser's URL normalization
|
||||||
|
const dummyUrl = new URL(`http://example.com/${joined}`);
|
||||||
|
return dummyUrl.pathname;
|
||||||
|
} catch {
|
||||||
|
// Fallback: manually handle double slashes by splitting and filtering
|
||||||
|
const pathParts = joined.split("/").filter((part) => part !== "");
|
||||||
|
return pathParts.length > 0 ? `/${pathParts.join("/")}` : "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -73,7 +73,7 @@ const SettingsSidebarNavItem = observer((props: TSettingsSidebarNavItemProps) =>
|
||||||
<div className={buttonClass}>{titleElement}</div>
|
<div className={buttonClass}>{titleElement}</div>
|
||||||
) : (
|
) : (
|
||||||
<Link
|
<Link
|
||||||
href={joinUrlPath("/", workspaceSlug, setting.href)}
|
href={joinUrlPath(workspaceSlug, setting.href)}
|
||||||
className={buttonClass}
|
className={buttonClass}
|
||||||
onClick={() => toggleSidebar(true)}
|
onClick={() => toggleSidebar(true)}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue