Skip to content

Add compact icon-based view switcher to the data page toolbar#530

Open
hdprajwal wants to merge 4 commits intomasterfrom
feat/icon-view-switcher
Open

Add compact icon-based view switcher to the data page toolbar#530
hdprajwal wants to merge 4 commits intomasterfrom
feat/icon-view-switcher

Conversation

@hdprajwal
Copy link
Contributor

Fixes #485, #486

Summary: Reworks the data page controls so view switching is faster and more compact. It replaces the text-based display selector with an icon-based control, pulls the sort selector into the top toolbar, and extracts the filter toggle into its own reusable component.

Changes

  • User experience
    • Replaces the display selector labels with recognizable icons and keeps the full view name in hover content.
    • Moves view switching and sort controls into the main data page toolbar for quicker access.
    • Keeps the filter toggle and result count grouped together to make the top controls easier to scan.
    • Formats result counts with toLocaleString() for better readability on large result sets.
  • Logical changes
    • Adds optionStyle support to the shared selector components so button-like selectors can customize layout without duplicating logic.
    • Adds an optional showLabel prop to SortBySelector so it can be reused in tighter toolbar layouts.
    • Extracts the filter panel button into src/widgets/controls/FilterPanelToggle.tsx.
  • Data
    • No data changes.
  • Refactors
    • Removes the old inline view selector from src/widgets/pathnav/PathNav.tsx.
    • Simplifies src/pages/DataPageBody.tsx by composing dedicated controls instead of inline toggle logic.

Out of scope/Future work: Add screenshots and manual QA notes after testing the updated toolbar across desktop and mobile layouts.

Test Plan and Screenshots

How to test the changes in this PR:

  1. Run npm run dev.
  2. Open the data page and confirm the top toolbar shows the filter toggle, result count, path navigation, sort selector, and icon-based view selector.
  3. Switch between Cards, Table, Hierarchy, Map, and Reports and verify the active icon updates correctly.
  4. Change sort options and confirm the selected sort is still applied.
  5. Toggle the filter panel open and closed and verify the button state still matches the panel state.
Page/View with link Description of Changes Screenshot Before Screenshot After
Data page Top toolbar now includes the extracted filter toggle, inline sort selector, and icon-based view switcher. image image
Data page - alternate views View switching now uses compact icons while preserving view labels in hover content, including beta labels for Map and Reports. image image

Checklist

Summary

  • Clear description of what and why
  • Scope kept focused; note follow-ups if any
  • Set yourself as assignee
  • Mention the issue (usually by writing "Fixes #ISSUE_NUMBER" or "Closes #ISSUE_NUMBER")

Testing

  • npm run lint
  • npm run build
  • npm run test
  • npm run dev -- tried out the website directly
    • Include screenshots as noted below
    • Write comments on manual testing

Internal changes

  • Logical changes
  • Refactors, moving files around
  • If you notice any changes that require explanations, make sure to include the explanations in the code as well.

Docs

  • Code is self-documenting, or if not, comments are added where needed.

Expose optionStyle on Selector and merge it into SelectorOption so
options can be styled. Add a compact icon-based ViewSelector (uses
lucide-react), place it in DataPageBody, and remove the inline
ViewSelector from PathNav.
Add optional showLabel prop to SortBySelector (defaults to true)
so callers can omit its label/description; DataPageBody now passes
showLabel={false} for the top toolbar. Adjust ViewSelector optionStyle
to use fit-content width and increased padding for better button sizing.
@hdprajwal hdprajwal self-assigned this Mar 11, 2026
@hdprajwal hdprajwal requested a review from a team as a code owner March 11, 2026 16:30
@hdprajwal hdprajwal changed the title Feat/icon view switcher Add compact icon-based view switcher to the data page toolbar Mar 11, 2026
Copy link
Collaborator

@conradarcturus conradarcturus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some style changes but the functionality generally looks good.

<Selector
selectorLabel="Sort By"
selectorDescription="Choose the order of items in the view."
selectorLabel={showLabel ? 'Sort By' : undefined}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When not showing the text maybe we should show ArrowDownUpIcon?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, now shows ArrowDownUpIcon as the label when showLabel is false

import usePageParams from '@features/params/usePageParams';
import FilterPath from '@features/transforms/filtering/FilterPath';

const PathNav: React.FC = () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PathNav component is almost completely empty now. It can probably be simplified.

Also can you remove the initial SlashIcon from FilterPath? It's not necessary since the selectors before it (Entity & View) have both been moved.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplified PathNav.tsx to only export PathContainer, DataPageBody now uses PathContainer + FilterPath directly.

return <Grid2x2Icon size="1.2em" />;
case View.Hierarchy:
return '/lang-nav/hierarchy.png';
return <GitBranchIcon size="1.2em" />;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NetworkIcon may be better? But I'll let you decide.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went with ListTreeIcon instead, feels more intuitive for a language hierarchy.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yes ListTreeIcon is even better! Good find.

</HoverableButton>
<ResultCount />
</div>
<PathNav />
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since PathNav is now just the "ActiveFilters" we should probably put it on the left side, not the right side.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved active filters to the left side.

<div
style={{
display: 'flex',
alignItems: 'center',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alignment doesn't line up between the right and left sides.


import useFilterPanel from './useFilterPanel';

const FilterPanelToggle: React.FC = () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is a good idea. I'm a bit confused why it wasn't part of your previously merged commit -- But I guess you merged before you could get it in.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it got left out before the merge. Added now.

Comment on lines +20 to +27
optionStyle={{
width: 'fit-content',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: '0.5rem',
}}
selectorStyle={{ gap: '0.25rem' }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO for me: check if we need all of these styles, I'm not certain (ideally it would come from SelectorDisplay so it scales better for more usages).

Nonetheless we don't need to get ahead of ourselves and scale things that we are only using in one place right now.

selected={view}
onChange={(nextView: View) => updatePageParams({ view: nextView })}
getOptionLabel={(option) => getViewIcon(option)}
getOptionDescription={(option) => getViewLabel(option)}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you removed the screenshots from the mouseover -- that was intentional because you want new screenshots?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added Screenshots back in the mouseover descriptions along with the view label.

Copy link
Collaborator

@conradarcturus conradarcturus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few singletons in fragments that you can remove the fragments <></>

Otherwise it looks good!

Comment on lines 201 to 205
return (
<>
<SlashIcon size="1em" />
<Deemphasized>No filters applied</Deemphasized>
</>
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove the <></> syntax since its only one component

Comment on lines 208 to -211
return (
<>
<SlashIcon size="1em" />
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Icon-Based View Switcher to Content Area

2 participants