Skip to content

Commit

Permalink
Remove the second line for filters
Browse files Browse the repository at this point in the history
  • Loading branch information
apata committed Jan 27, 2025
1 parent 2a91c26 commit a0317c6
Show file tree
Hide file tree
Showing 13 changed files with 473 additions and 244 deletions.
27 changes: 26 additions & 1 deletion assets/js/dashboard/components/dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/** @format */

import React, {
CSSProperties,
DetailedHTMLProps,
forwardRef,
HTMLAttributes,
Expand All @@ -13,6 +14,24 @@ import {
AppNavigationLink,
AppNavigationTarget
} from '../navigation/use-app-navigate'
import { NavigateOptions } from 'react-router-dom'

export const DropdownSubtitle = ({
children,
className
}: {
children: ReactNode
className?: string
}) => (
<div
className={classNames(
'text-xs px-4 pt-2 pb-1 font-bold uppercase text-indigo-500 dark:text-indigo-400',
className
)}
>
{children}
</div>
)

export const ToggleDropdownButton = forwardRef<
HTMLDivElement,
Expand All @@ -23,6 +42,7 @@ export const ToggleDropdownButton = forwardRef<
currentOption: ReactNode
children: ReactNode
onClick: () => void
style?: CSSProperties
dropdownContainerProps: DetailedHTMLProps<
HTMLAttributes<HTMLButtonElement>,
HTMLButtonElement
Expand All @@ -37,6 +57,7 @@ export const ToggleDropdownButton = forwardRef<
children,
onClick,
dropdownContainerProps,
style,
...props
},
ref
Expand All @@ -53,7 +74,7 @@ export const ToggleDropdownButton = forwardRef<
}[variant]

return (
<div className={className} ref={ref}>
<div className={className} ref={ref} style={style}>
<button
onClick={onClick}
className={classNames(sharedButtonClass, buttonClass)}
Expand Down Expand Up @@ -129,15 +150,19 @@ export const DropdownNavigationLink = ({
children,
active,
className,
navigateOptions,
...props
}: AppNavigationTarget & {
active?: boolean
children: ReactNode
className?: string
onClick?: () => void
onMouseEnter?: () => void
navigateOptions?: NavigateOptions
}) => (
<AppNavigationLink
{...props}
{...navigateOptions}
className={classNames(
className,
{ 'font-bold': !!active },
Expand Down
8 changes: 6 additions & 2 deletions assets/js/dashboard/datepicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,11 @@ function QueryPeriodsMenu({
)
}

export default function QueryPeriodPicker() {
export default function QueryPeriodPicker({
className
}: {
className?: string
}) {
const site = useSiteContext()
const { query } = useQueryContext()
const navigate = useAppNavigate()
Expand Down Expand Up @@ -352,7 +356,7 @@ export default function QueryPeriodPicker() {
}, [closeMenu, query])

return (
<div className="flex ml-auto pl-2">
<div className={classNames('flex shrink-0', className)}>
<MovePeriodArrows />
<ToggleDropdownButton
withDropdownIndicator
Expand Down
4 changes: 2 additions & 2 deletions assets/js/dashboard/filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,11 @@ function Filters() {

function renderDropDown() {
return (
<Menu as="div" className="md:relative ml-auto">
<Menu as="div" className="md:relative ml-auto shrink-0">
{({ open }) => (
<>
<div>
<Menu.Button onClick={trackFilterMenu} className="flex items-center text-xs md:text-sm font-medium leading-tight px-3 py-2 cursor-pointer ml-auto text-gray-500 dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-900 rounded">
<Menu.Button onClick={trackFilterMenu} className="flex items-center text-xs md:text-sm font-medium leading-tight px-3 py-2 cursor-pointer ml-auto text-gray-500 dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-900 rounded whitespace-nowrap w-fit">
{renderDropdownButton()}
</Menu.Button>
</div>
Expand Down
6 changes: 1 addition & 5 deletions assets/js/dashboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import Locations from './stats/locations'
import Devices from './stats/devices'
import { TopBar } from './nav-menu/top-bar'
import Behaviours from './stats/behaviours'
import { FiltersBar } from './nav-menu/filters-bar'
import { useQueryContext } from './query-context'
import { isRealTimeDashboard } from './util/filters'

Expand Down Expand Up @@ -61,10 +60,7 @@ function Dashboard() {

return (
<div className="mb-12">
<TopBar
showCurrentVisitors={!isRealTimeDashboard}
extraBar={<FiltersBar />}
/>
<TopBar showCurrentVisitors={!isRealTimeDashboard} />
<DashboardStats
importedDataInView={
isRealTimeDashboard ? undefined : importedDataInView
Expand Down
106 changes: 75 additions & 31 deletions assets/js/dashboard/nav-menu/filter-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,56 @@ import {
DropdownLinkGroup,
DropdownMenuWrapper,
DropdownNavigationLink,
DropdownSubtitle,
ToggleDropdownButton
} from '../components/dropdown'
import { MagnifyingGlassIcon } from '@heroicons/react/20/solid'
import {
FILTER_MODAL_TO_FILTER_GROUP,
formatFilterGroup
} from '../util/filters'
import { PlausibleSite, useSiteContext } from '../site-context'
import { filterRoute } from '../router'
import { useOnClickOutside } from '../util/use-on-click-outside'
import { PlusIcon } from '@heroicons/react/20/solid'
import { isModifierPressed, isTyping, Keybind } from '../keybinding'

export function getFilterListItems({
propsAvailable
}: Pick<PlausibleSite, 'propsAvailable'>): {
modalKey: string
label: string
}[] {
const allKeys = Object.keys(FILTER_MODAL_TO_FILTER_GROUP) as Array<
keyof typeof FILTER_MODAL_TO_FILTER_GROUP
>
const keysToOmit: Array<keyof typeof FILTER_MODAL_TO_FILTER_GROUP> =
propsAvailable ? [] : ['props']
return allKeys
.filter((k) => !keysToOmit.includes(k))
.map((modalKey) => ({ modalKey, label: formatFilterGroup(modalKey) }))
}: Pick<PlausibleSite, 'propsAvailable'>): Array<
Array<{
title: string
modals: Array<false | keyof typeof FILTER_MODAL_TO_FILTER_GROUP>
}>
> {
return [
[
{
title: 'URL',
modals: ['page', 'hostname']
},
{
title: 'Acquisition',
modals: ['source', 'utm']
}
],
[
{
title: 'Device',
modals: ['location', 'screen', 'browser', 'os']
},
{
title: 'Behaviour',
modals: ['goal', !!propsAvailable && 'props']
}
]
]
}

export const FilterMenu = () => {
const dropdownRef = useRef<HTMLDivElement>(null)
const [opened, setOpened] = useState(false)
const site = useSiteContext()
const filterListItems = useMemo(() => getFilterListItems(site), [site])
const columns = useMemo(() => getFilterListItems(site), [site])

useOnClickOutside({
ref: dropdownRef,
Expand All @@ -48,32 +66,58 @@ export const FilterMenu = () => {
<ToggleDropdownButton
ref={dropdownRef}
variant="ghost"
className="ml-auto md:relative"
className="shrink-0 md:relative"
dropdownContainerProps={{
['aria-controls']: 'filter-menu',
['aria-expanded']: opened
}}
onClick={() => setOpened((opened) => !opened)}
currentOption={
<span className="flex items-center">
<MagnifyingGlassIcon className="block h-4 w-4" />
<span className="block ml-1">Filter</span>
</span>
<div className="flex items-center gap-1 ">
<PlusIcon className="block h-4 w-4" />
Add filter
</div>
}
>
{opened && (
<DropdownMenuWrapper id="filter-menu" className="md:left-auto md:w-56">
<DropdownLinkGroup>
{filterListItems.map(({ modalKey, label }) => (
<DropdownNavigationLink
active={false}
key={modalKey}
path={filterRoute.path}
params={{ field: modalKey }}
search={(search) => search}
>
{label}
</DropdownNavigationLink>
<DropdownMenuWrapper id="filter-menu" className="md:left-auto md:w-80">
<Keybind
keyboardKey="Escape"
shouldIgnoreWhen={[isModifierPressed, isTyping]}
type="keyup"
handler={(event) => {
event.stopPropagation()
setOpened(false)
}}
target={dropdownRef.current}
/>

<DropdownLinkGroup className="flex flex-row">
{columns.map((filterGroups, index) => (
<div key={index} className="flex flex-col w-1/2">
{filterGroups.map(({ title, modals }) => (
<div key={title}>
<DropdownSubtitle className="pb-1">
{title}
</DropdownSubtitle>
{modals
.filter((m) => !!m)
.map((modalKey) => (
<DropdownNavigationLink
className={'text-xs'}
onClick={() => setOpened(false)}
active={false}
key={modalKey}
path={filterRoute.path}
params={{ field: modalKey }}
search={(search) => search}
>
{formatFilterGroup(modalKey)}
</DropdownNavigationLink>
))}
</div>
))}
</div>
))}
</DropdownLinkGroup>
</DropdownMenuWrapper>
Expand Down
Loading

0 comments on commit a0317c6

Please sign in to comment.