fix: 트리 노드에서 부모와 겹치는 경로 접두사만 제거
/about/press → /press (부모 /about 제거) /about → /about (루트 직속은 전체 경로) / → / Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -26,28 +26,40 @@ interface PageTreeNodeProps {
|
|||||||
onSelectPage: (url: string) => void;
|
onSelectPage: (url: string) => void;
|
||||||
/** 들여쓰기 레벨 */
|
/** 들여쓰기 레벨 */
|
||||||
level: number;
|
level: number;
|
||||||
|
/** 부모 노드의 경로 (중복 경로 제거용) */
|
||||||
|
parentPath?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL에서 마지막 경로 세그먼트만 반환.
|
* URL에서 부모 경로와 겹치는 앞부분을 제거하여 표시명 반환.
|
||||||
* 루트는 "/", 나머지는 마지막 세그먼트만 표시.
|
* 예: parentPath="/about", url="/about/press" → "/press"
|
||||||
* 예: "https://example.com/" -> "/"
|
* parentPath="/", url="/about" → "/about"
|
||||||
* "https://example.com/about" -> "about"
|
* parentPath=undefined, url="/" → "/"
|
||||||
* "https://example.com/about/press" -> "press"
|
|
||||||
*/
|
*/
|
||||||
function getDisplayName(url: string): string {
|
function getDisplayName(url: string, parentPath?: string): string {
|
||||||
try {
|
try {
|
||||||
const parsed = new URL(url);
|
const parsed = new URL(url);
|
||||||
const path = parsed.pathname;
|
const path = parsed.pathname || "/";
|
||||||
if (path === "/" || path === "") return "/";
|
if (path === "/" || path === "") return "/";
|
||||||
const clean = path.endsWith("/") ? path.slice(0, -1) : path;
|
|
||||||
const segments = clean.split("/").filter(Boolean);
|
if (parentPath && parentPath !== "/" && path.startsWith(parentPath)) {
|
||||||
return segments[segments.length - 1] || "/";
|
return path.slice(parentPath.length) || path;
|
||||||
|
}
|
||||||
|
return path;
|
||||||
} catch {
|
} catch {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** URL에서 pathname만 추출 */
|
||||||
|
function getPathFromUrl(url: string): string {
|
||||||
|
try {
|
||||||
|
return new URL(url).pathname || "/";
|
||||||
|
} catch {
|
||||||
|
return "/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 페이지 트리 노드 (재귀 컴포넌트) */
|
/** 페이지 트리 노드 (재귀 컴포넌트) */
|
||||||
export function PageTreeNode({
|
export function PageTreeNode({
|
||||||
page,
|
page,
|
||||||
@ -56,12 +68,14 @@ export function PageTreeNode({
|
|||||||
selectedUrl,
|
selectedUrl,
|
||||||
onSelectPage,
|
onSelectPage,
|
||||||
level,
|
level,
|
||||||
|
parentPath,
|
||||||
}: PageTreeNodeProps) {
|
}: PageTreeNodeProps) {
|
||||||
const [isExpanded, setIsExpanded] = useState(level < 2);
|
const [isExpanded, setIsExpanded] = useState(level < 2);
|
||||||
const children = childrenPages.get(page.url) || [];
|
const children = childrenPages.get(page.url) || [];
|
||||||
const hasChildren = children.length > 0;
|
const hasChildren = children.length > 0;
|
||||||
const isSelected = selectedUrl === page.url;
|
const isSelected = selectedUrl === page.url;
|
||||||
const displayPath = getDisplayName(page.url);
|
const currentPath = getPathFromUrl(page.url);
|
||||||
|
const displayPath = getDisplayName(page.url, parentPath);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -137,6 +151,7 @@ export function PageTreeNode({
|
|||||||
selectedUrl={selectedUrl}
|
selectedUrl={selectedUrl}
|
||||||
onSelectPage={onSelectPage}
|
onSelectPage={onSelectPage}
|
||||||
level={level + 1}
|
level={level + 1}
|
||||||
|
parentPath={currentPath}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user