Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fix: Fix showing selected state in sidebar navigation items in UI
Our `useMatchSubpath` hook uses these two react-router-dom hooks:

1. useResolvedPath
2. useMatch

After some investigation, I found that useMatch doesn't work with
relative or partial paths:
remix-run/react-router#8684 (comment).
Furthermore, in our Sidebar useResolvedPath doesn't include any parts of
the current page pathname in the result, resulting in just e.g.
/data-source, and thus useMatch doesn't return a match.

Not sure exactly why this happens, since we get a full resolved path
when calling useMatchSubpath in at least RegularFeatureInstance.tsx, but
it's probably related to where we render the components in the component
tree, and Sidebar is rendered outside the React Router Outlet component.

I found out these differences with some console.logs in useMatchSubpath.

The fix is to include the full path when calling useMatchSubpath in
Sidebar, so that it fully matches the current location used by useMatch.

Signed-off-by: Harri Lehtola <peruukki@hotmail.com>
  • Loading branch information
peruukki committed Jan 26, 2025
commit 877d1defadbdd010c527bba2bb9dbe1ab63f82ef
24 changes: 13 additions & 11 deletions ui/src/pages/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,58 +55,60 @@ const SideNav = () => {
: ""
}`;

const baseUrl = `${process.env.PUBLIC_URL || ""}/p/${projectName}`;

const sideNav = [
{
name: "Home",
id: htmlIdGenerator("basicExample")(),
onClick: () => {
navigate(`${process.env.PUBLIC_URL || ""}/p/${projectName}/`);
navigate(`${baseUrl}/`);
},
items: [
{
name: dataSourcesLabel,
id: htmlIdGenerator("dataSources")(),
icon: <EuiIcon type={DataSourceIcon} />,
onClick: () => {
navigate(`${process.env.PUBLIC_URL || ""}/p/${projectName}/data-source`);
navigate(`${baseUrl}/data-source`);
},
isSelected: useMatchSubpath("data-source"),
isSelected: useMatchSubpath(`${baseUrl}/data-source`),
},
{
name: entitiesLabel,
id: htmlIdGenerator("entities")(),
icon: <EuiIcon type={EntityIcon} />,
onClick: () => {
navigate(`${process.env.PUBLIC_URL || ""}/p/${projectName}/entity`);
navigate(`${baseUrl}/entity`);
},
isSelected: useMatchSubpath("entity"),
isSelected: useMatchSubpath(`${baseUrl}/entity`),
},
{
name: featureViewsLabel,
id: htmlIdGenerator("featureView")(),
icon: <EuiIcon type={FeatureViewIcon} />,
onClick: () => {
navigate(`${process.env.PUBLIC_URL || ""}/p/${projectName}/feature-view`);
navigate(`${baseUrl}/feature-view`);
},
isSelected: useMatchSubpath("feature-view"),
isSelected: useMatchSubpath(`${baseUrl}/feature-view`),
},
{
name: featureServicesLabel,
id: htmlIdGenerator("featureService")(),
icon: <EuiIcon type={FeatureServiceIcon} />,
onClick: () => {
navigate(`${process.env.PUBLIC_URL || ""}/p/${projectName}/feature-service`);
navigate(`${baseUrl}/feature-service`);
},
isSelected: useMatchSubpath("feature-service"),
isSelected: useMatchSubpath(`${baseUrl}/feature-service`),
},
{
name: savedDatasetsLabel,
id: htmlIdGenerator("savedDatasets")(),
icon: <EuiIcon type={DatasetIcon} />,
onClick: () => {
navigate(`${process.env.PUBLIC_URL || ""}/p/${projectName}/data-set`);
navigate(`${baseUrl}/data-set`);
},
isSelected: useMatchSubpath("data-set"),
isSelected: useMatchSubpath(`${baseUrl}/data-set`),
},
],
},
Expand Down