feat(web): Home page ui upgrade
This commit is contained in:
@@ -33,92 +33,72 @@ export const useNavigationBreadcrumbs = (source: 'space' | 'manage' = 'manage')
|
||||
const currentPath = location.pathname;
|
||||
const menus = allMenus[source] || [];
|
||||
|
||||
/** Find matching menu item and build key path */
|
||||
const findMenuKeyPath = (menuList: any[], parentKeys: string[] = []): string[] | null => {
|
||||
let bestMatch: { path: string; parentId?: string; score: number } | null = null;
|
||||
|
||||
for (const menu of menuList) {
|
||||
/** Check submenus */
|
||||
if (menu.subs && menu.subs.length > 0) {
|
||||
const menuPath = menu.path ? (menu.path[0] !== '/' ? '/' + menu.path : menu.path) : '';
|
||||
for (const sub of menu.subs) {
|
||||
if (sub.path) {
|
||||
const subPath = sub.path[0] !== '/' ? '/' + sub.path : sub.path;
|
||||
|
||||
/** Exact match has priority */
|
||||
if (subPath === currentPath) {
|
||||
return [sub.path, `${menu.id}`];
|
||||
}
|
||||
console.log('menuPath', menuPath)
|
||||
/** Dynamic route matching */
|
||||
if (subPath.includes(':')) {
|
||||
/** Check if under parent menu */
|
||||
if (menuPath && currentPath.startsWith(menuPath + '/')) {
|
||||
const relativePath = currentPath.replace(menuPath, '');
|
||||
const pathSegments = subPath.split('/');
|
||||
const relativeSegments = relativePath.split('/');
|
||||
if (pathSegments.length === relativeSegments.length) {
|
||||
const pathPattern = subPath.replace(/:[\w-]+/g, '[^/]+').replace(/\[[\w-]+\]/g, '[^/]+');
|
||||
const regex = new RegExp(`^${pathPattern}$`);
|
||||
if (regex.test(relativePath)) {
|
||||
return [sub.path, `${menu.id}`];
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Direct match submenu path */
|
||||
const pathSegments = subPath.split('/');
|
||||
const currentSegments = currentPath.split('/');
|
||||
if (pathSegments.length === currentSegments.length) {
|
||||
const pathPattern = subPath.replace(/:[\w-]+/g, '[^/]+').replace(/\[[\w-]+\]/g, '[^/]+');
|
||||
const regex = new RegExp(`^${pathPattern}$`);
|
||||
if (regex.test(currentPath)) {
|
||||
return [sub.path, `${menu.id}`];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Check main menu */
|
||||
if (menu.path) {
|
||||
const menuPath = menu.path[0] !== '/' ? '/' + menu.path : menu.path;
|
||||
/** Exact match has priority */
|
||||
if (menuPath === currentPath) {
|
||||
return [menu.path, ...parentKeys].reverse();
|
||||
}
|
||||
/** Dynamic route matching */
|
||||
if (menuPath.includes(':')) {
|
||||
const pathSegments = menuPath.split('/');
|
||||
const currentSegments = currentPath.split('/');
|
||||
if (pathSegments.length === currentSegments.length) {
|
||||
const pathPattern = menuPath.replace(/:[\w-]+/g, '[^/]+').replace(/\[[\w-]+\]/g, '[^/]+');
|
||||
const regex = new RegExp(`^${pathPattern}$`);
|
||||
if (regex.test(currentPath)) {
|
||||
const score = menuPath.split('/').length;
|
||||
if (!bestMatch || score > bestMatch.score) {
|
||||
bestMatch = { path: menu.path, score };
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (currentPath.startsWith(menuPath + '/')) {
|
||||
const score = menuPath.split('/').length;
|
||||
if (!bestMatch || score > bestMatch.score) {
|
||||
bestMatch = { path: menu.path, score };
|
||||
}
|
||||
}
|
||||
}
|
||||
const pathMatches = (pattern: string, path: string): boolean => {
|
||||
const normalized = pattern[0] !== '/' ? '/' + pattern : pattern;
|
||||
if (normalized === path) return true;
|
||||
if (normalized.includes(':')) {
|
||||
const regex = new RegExp('^' + normalized.replace(/:[\\w-]+/g, '[^/]+') + '$');
|
||||
return regex.test(path);
|
||||
}
|
||||
|
||||
if (bestMatch) {
|
||||
return bestMatch.parentId ? [bestMatch.path, bestMatch.parentId] : [bestMatch.path];
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Recursively search menu tree, returns keyPath or null.
|
||||
* keyPath format:
|
||||
* - 1-level: [path]
|
||||
* - 2-level: [subPath, parentId]
|
||||
* - 3-level: [subSubPath, subId, parentId]
|
||||
*/
|
||||
/**
|
||||
* parentId: the group's id when recursing into group subs
|
||||
* keyPath format:
|
||||
* - 1-level: [path]
|
||||
* - 2-level: [subPath, parentId]
|
||||
* - 3-level: [subSubPath, subId, parentId]
|
||||
*/
|
||||
const findKeyPath = (menuList: any[], groupId?: string): string[] | null => {
|
||||
for (const menu of menuList) {
|
||||
/** Group menus: recurse into subs, passing group id */
|
||||
if (menu.type === 'group' && menu.subs?.length) {
|
||||
const result = findKeyPath(menu.subs, `${menu.id}`);
|
||||
if (result) return result;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (menu.subs?.length) {
|
||||
for (const sub of menu.subs) {
|
||||
/** Check third-level subs */
|
||||
if (sub.subs?.length) {
|
||||
for (const subSub of sub.subs) {
|
||||
if (subSub.path && pathMatches(subSub.path, currentPath)) {
|
||||
return [subSub.path, `${sub.id}`, `${menu.id}`];
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Second-level match: sub is a leaf under menu */
|
||||
if (sub.path && pathMatches(sub.path, currentPath)) {
|
||||
/** If menu is inside a group, return 3-level: [subPath, menuId, groupId] */
|
||||
return groupId
|
||||
? [sub.path, `${menu.id}`, groupId]
|
||||
: [sub.path, `${menu.id}`];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** First-level / group-child match */
|
||||
if (menu.path && pathMatches(menu.path, currentPath)) {
|
||||
return groupId ? [menu.path, groupId] : [menu.path];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const keyPath = findMenuKeyPath(menus);
|
||||
const keyPath = findKeyPath(menus);
|
||||
|
||||
console.log('keyPath', keyPath)
|
||||
if (keyPath) {
|
||||
updateBreadcrumbs(keyPath, source);
|
||||
}
|
||||
}, [location.pathname, allMenus, source, updateBreadcrumbs]);
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user