Skip to content

Commit

Permalink
feat: add FiltersBarViewDropdown
Browse files Browse the repository at this point in the history
  • Loading branch information
asabotovich committed Mar 13, 2024
1 parent 103df0f commit 96881b0
Show file tree
Hide file tree
Showing 15 changed files with 227 additions and 28 deletions.
128 changes: 124 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"@sentry/nextjs": "7.92.0",
"@tanstack/react-query": "4.29.5",
"@tanstack/react-query-devtools": "4.29.6",
"@taskany/bricks": "5.19.0",
"@taskany/bricks": "5.20.0",
"@taskany/colors": "1.11.0",
"@taskany/icons": "2.0.1",
"@tippyjs/react": "4.2.6",
Expand Down
2 changes: 1 addition & 1 deletion src/components/EstimateDropdown/EstimateDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const EstimateDropdown = ({ onChange, value, ...props }: EstimateDropdown
);

return (
<Dropdown>
<Dropdown arrow>
<DropdownTrigger {...props}>
{nullable(value, (v) => (
<Text size="s" as="span">
Expand Down
5 changes: 5 additions & 0 deletions src/components/FilteredPage/FilteredPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ interface FilteredPageProps {
filterPreset?: FilterById;
userFilters?: React.ComponentProps<typeof PresetDropdown>['presets'];
filterControls?: React.ReactNode;
setGroupBy?: React.ComponentProps<typeof FiltersPanel>['setGroupBy'];
}

export const FilteredPage: React.FC<React.PropsWithChildren<FilteredPageProps>> = ({
Expand All @@ -35,6 +36,7 @@ export const FilteredPage: React.FC<React.PropsWithChildren<FilteredPageProps>>
isLoading,
filterPreset,
filterControls,
setGroupBy,
}) => {
const router = useRouter();

Expand All @@ -47,6 +49,7 @@ export const FilteredPage: React.FC<React.PropsWithChildren<FilteredPageProps>>
setPreset,
batchQueryState,
queryFilterState,
groupBy,
} = useUrlFilterParams({
preset: filterPreset,
});
Expand Down Expand Up @@ -98,6 +101,8 @@ export const FilteredPage: React.FC<React.PropsWithChildren<FilteredPageProps>>
queryFilterState={queryFilterState}
onFilterApply={batchQueryState}
onFilterReset={resetQueryState}
setGroupBy={setGroupBy}
groupBy={groupBy}
>
{filterControls}
</FiltersPanel>
Expand Down
27 changes: 27 additions & 0 deletions src/components/FiltersBar/FiltersBar.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,30 @@
align-items: center;
color: var(--text-secondary);
}

.FiltersBarViewDropdownDrigger {
display: flex;
align-items: center;
gap: var(--gap-s);
}

.FiltersBarDropdownPanelContainer {
display: flex;
flex-direction: column;
gap: var(--gap-sm);
}

.FiltersBarDropdownTitle {
color: var(--text-secondary);
width: 100%;
padding-bottom: var(--gap-s);
border-bottom: 1px solid var(--gray-900);
}
.FiltersBarDropdownPanel {
padding: var(--gap-sm);
}
.FiltersBarDropdownContent {
display: flex;
flex-wrap: wrap;
gap: var(--gap-s);
}
41 changes: 31 additions & 10 deletions src/components/FiltersBar/FiltersBar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FC, HTMLAttributes } from 'react';
import { ComponentProps, FC, HTMLAttributes, ReactNode, useState } from 'react';
import cn from 'classnames';
import { nullable } from '@taskany/bricks';
import { Text, Button, Switch, SwitchControl } from '@taskany/bricks/harmony';
import { Text, Switch, SwitchControl, Dropdown, DropdownPanel, DropdownTrigger } from '@taskany/bricks/harmony';
import { IconAdjustHorizontalSolid, IconAlignTopSolid, IconListUnorderedOutline } from '@taskany/icons';

import s from './FiltersBar.module.css';
Expand Down Expand Up @@ -83,11 +83,32 @@ export const FiltersBarControlGroup: FC<HTMLAttributes<HTMLDivElement>> = ({ chi
</div>
);

export const FiltersBarViewDropdown: FC = () => (
<Button
disabled
text={tr('View')}
className={s.FiltersBarButton}
iconLeft={<IconAdjustHorizontalSolid size="xxs" />}
/>
);
export const FiltersBarViewDropdown: FC<{ children?: ReactNode }> = ({ children }) => {
const [isOpen, setIsOpen] = useState(false);

return (
<Dropdown isOpen={isOpen} onClose={() => setIsOpen(false)}>
<DropdownTrigger className={s.FiltersBarViewDropdownDrigger} view="fill" onClick={() => setIsOpen(true)}>
<div className={s.FiltersBarViewDropdownDrigger}>
<IconAdjustHorizontalSolid size="xxs" />
<Text size="s">{tr('View')}</Text>
</div>
</DropdownTrigger>
<DropdownPanel width={335} placement="bottom-start" className={s.FiltersBarDropdownPanel}>
<div className={s.FiltersBarDropdownPanelContainer}>{children}</div>
</DropdownPanel>
</Dropdown>
);
};

export const FiltersBarDropdownTitle: FC<ComponentProps<typeof Text>> = ({ children }) => {
return (
<Text className={s.FiltersBarDropdownTitle} weight="bold">
{children}
</Text>
);
};

export const FiltersBarDropdownContent: FC<HTMLAttributes<HTMLDivElement>> = ({ children }) => {
return <div className={s.FiltersBarDropdownContent}>{children}</div>;
};
3 changes: 2 additions & 1 deletion src/components/FiltersPanel/FiltersPanel.i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
"Issuer": "Issuer",
"Participant": "Participant",
"Filter": "Filter",
"Reset": "Reset"
"Reset": "Reset",
"Grouping": "Grouping"
}
3 changes: 2 additions & 1 deletion src/components/FiltersPanel/FiltersPanel.i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
"Issuer": "Автор",
"Participant": "Участник",
"Filter": "Фильтр",
"Reset": "Сбросить"
"Reset": "Сбросить",
"Grouping": "Группировка"
}
31 changes: 27 additions & 4 deletions src/components/FiltersPanel/FiltersPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { FC, useCallback, memo, useState, useEffect, useMemo, useRef, ReactNode } from 'react';
import { Button } from '@taskany/bricks/harmony';
import { IconAddOutline } from '@taskany/icons';
import { nullable } from '@taskany/bricks';

import { filtersTakeCount } from '../../utils/filters';
import { FilterQueryState, QueryState, buildURLSearchParams } from '../../hooks/useUrlFilterParams';
Expand All @@ -27,6 +28,8 @@ import {
FiltersBarTitle,
LayoutType,
layoutType,
FiltersBarDropdownTitle,
FiltersBarDropdownContent,
} from '../FiltersBar/FiltersBar';
import { SearchFilter } from '../SearchFilter';
import { Separator } from '../Separator/Separator';
Expand Down Expand Up @@ -65,6 +68,8 @@ export const FiltersPanel: FC<{
onSearchChange: (search: string) => void;
onFilterApply?: (state: Partial<QueryState>) => void;
onFilterReset: () => void;
setGroupBy?: (groupBy: QueryState['groupBy']) => void;
groupBy?: QueryState['groupBy'];
children?: ReactNode;
}> = memo(
({
Expand All @@ -77,6 +82,8 @@ export const FiltersPanel: FC<{
queryState,
queryFilterState,
onFilterApply,
setGroupBy,
groupBy,
}) => {
const [layout] = useState<LayoutType>(layoutType.table);
const filterTriggerRef = useRef<HTMLButtonElement>(null);
Expand Down Expand Up @@ -165,6 +172,8 @@ export const FiltersPanel: FC<{
[queryFilterState],
);

const groupedByProject = groupBy === 'project';

return (
<>
<FiltersBar {...filtersPanel.attr}>
Expand Down Expand Up @@ -198,10 +207,24 @@ export const FiltersPanel: FC<{
<FiltersBarLayoutSwitch value={layout} />
</FiltersBarItem>
<Separator />
<FiltersBarItem>
<FiltersBarViewDropdown />
</FiltersBarItem>
<Separator />
{nullable(setGroupBy, (setter) => (
<>
<FiltersBarItem>
<FiltersBarViewDropdown>
<FiltersBarDropdownTitle>{tr('Grouping')}</FiltersBarDropdownTitle>
<FiltersBarDropdownContent>
<Button
text={tr('Project')}
view={groupedByProject ? 'checked' : 'default'}
onClick={() => setter(groupedByProject ? undefined : 'project')}
/>
</FiltersBarDropdownContent>
</FiltersBarViewDropdown>
</FiltersBarItem>
<Separator />
</>
))}

<FiltersBarItem>
<SearchFilter defaultValue={queryState?.query} onChange={onSearchChange} />
</FiltersBarItem>
Expand Down
2 changes: 1 addition & 1 deletion src/components/GoalParentDropdown/GoalParentDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const GoalParentDropdown = ({
}, []);

return (
<Dropdown>
<Dropdown arrow>
<DropdownTrigger label={label} {...props} readOnly={disabled}>
{nullable(value, ({ title }) => (
<Text size="s" ellipsis className={s.DropdownTriggerValue} title={title}>
Expand Down
3 changes: 2 additions & 1 deletion src/components/GoalsPage/GoalsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const GoalsPage = ({ user, ssrTime, defaultPresetFallback }: ExternalPage
defaultPresetFallback,
});

const { currentPreset, queryState, groupBy, setTagsFilterOutside } = useUrlFilterParams({
const { currentPreset, queryState, groupBy, setTagsFilterOutside, setGroupBy } = useUrlFilterParams({
preset,
});

Expand Down Expand Up @@ -48,6 +48,7 @@ export const GoalsPage = ({ user, ssrTime, defaultPresetFallback }: ExternalPage
userFilters={userFilters}
onFilterStar={onFilterStar}
isLoading={false}
setGroupBy={setGroupBy}
>
{nullable(
groupedView,
Expand Down
Loading

0 comments on commit 96881b0

Please sign in to comment.