From 7cf1f913b0c8a951242402b5fe8d814312c25b45 Mon Sep 17 00:00:00 2001 From: Sammy Teillet Date: Mon, 24 Apr 2023 17:00:05 +0200 Subject: [PATCH 1/4] feature: add property isActive for dropdown buttons --- .../components/table/table-header/DropdownButton.tsx | 11 +++++++++-- .../src/components/table/table-header/TableHeader.tsx | 5 +++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/front/src/components/table/table-header/DropdownButton.tsx b/front/src/components/table/table-header/DropdownButton.tsx index df7c1f952..30d244846 100644 --- a/front/src/components/table/table-header/DropdownButton.tsx +++ b/front/src/components/table/table-header/DropdownButton.tsx @@ -8,6 +8,7 @@ import { SortType } from './SortAndFilterBar'; type OwnProps = { label: string; options: Array; + isActive: boolean; onSortSelect?: (id: string) => void; }; @@ -20,6 +21,7 @@ const StyledDropdownButtonContainer = styled.div` type StyledDropdownButtonProps = { isUnfolded: boolean; + isActive: boolean; }; const StyledDropdownButton = styled.div` @@ -27,6 +29,7 @@ const StyledDropdownButton = styled.div` margin-left: ${(props) => props.theme.spacing(3)}; cursor: pointer; background: ${(props) => props.theme.primaryBackground}; + color: ${(props) => (props.isActive ? props.theme.blue : 'none')}; padding: ${(props) => props.theme.spacing(1)}; border-radius: 4px; filter: ${(props) => (props.isUnfolded ? 'brightness(0.95)' : 'none')}; @@ -85,7 +88,7 @@ const StyledIcon = styled.div` margin-right: ${(props) => props.theme.spacing(1)}; `; -function DropdownButton({ label, options, onSortSelect }: OwnProps) { +function DropdownButton({ label, options, onSortSelect, isActive }: OwnProps) { const [isUnfolded, setIsUnfolded] = useState(false); const onButtonClick = () => { @@ -101,7 +104,11 @@ function DropdownButton({ label, options, onSortSelect }: OwnProps) { return ( - + {label} {isUnfolded && options.length > 0 && ( diff --git a/front/src/components/table/table-header/TableHeader.tsx b/front/src/components/table/table-header/TableHeader.tsx index 8c3077df0..7c7c4620e 100644 --- a/front/src/components/table/table-header/TableHeader.tsx +++ b/front/src/components/table/table-header/TableHeader.tsx @@ -86,13 +86,14 @@ function TableHeader({ {viewName} - + 0} /> - + {sorts.length > 0 && ( From 795f9e7af84f47132a5036088837c14b682022a9 Mon Sep 17 00:00:00 2001 From: Sammy Teillet Date: Mon, 24 Apr 2023 17:35:01 +0200 Subject: [PATCH 2/4] refactor: create SortDropdownButton --- .../table/table-header/SortDropdownButton.tsx | 38 +++++++++++++++++++ .../table/table-header/TableHeader.tsx | 30 ++++++--------- 2 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 front/src/components/table/table-header/SortDropdownButton.tsx diff --git a/front/src/components/table/table-header/SortDropdownButton.tsx b/front/src/components/table/table-header/SortDropdownButton.tsx new file mode 100644 index 000000000..0f6cbffb2 --- /dev/null +++ b/front/src/components/table/table-header/SortDropdownButton.tsx @@ -0,0 +1,38 @@ +import { useCallback } from 'react'; +import DropdownButton from './DropdownButton'; +import { SortType } from './SortAndFilterBar'; + +type OwnProps = { + sorts: SortType[]; + setSorts: any; + sortsAvailable: any; +}; + +export function SortDropdownButton({ + sortsAvailable, + setSorts, + sorts, +}: OwnProps) { + const onSortItemSelect = useCallback( + (sortId: string) => { + const newSorts = [ + { + label: 'Created at', + order: 'asc', + id: sortId, + } satisfies SortType, + ]; + setSorts(newSorts); + }, + [setSorts], + ); + + return ( + 0} + /> + ); +} diff --git a/front/src/components/table/table-header/TableHeader.tsx b/front/src/components/table/table-header/TableHeader.tsx index 7c7c4620e..a3ba9ac36 100644 --- a/front/src/components/table/table-header/TableHeader.tsx +++ b/front/src/components/table/table-header/TableHeader.tsx @@ -4,6 +4,7 @@ import DropdownButton from './DropdownButton'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import SortAndFilterBar, { SortType } from './SortAndFilterBar'; import { useCallback, useState } from 'react'; +import { SortDropdownButton } from './SortDropdownButton'; type OwnProps = { viewName: string; @@ -50,19 +51,12 @@ function TableHeader({ onSortsUpdate, sortsAvailable, }: OwnProps) { - const [sorts, setSorts] = useState([] as Array); + const [sorts, innerSetSorts] = useState([] as Array); - const onSortItemSelect = useCallback( - (sortId: string) => { - const newSorts = [ - { - label: 'Created at', - order: 'asc', - id: sortId, - } satisfies SortType, - ]; - setSorts(newSorts); - onSortsUpdate && onSortsUpdate(newSorts); + const setSorts = useCallback( + (sorts: SortType[]) => { + innerSetSorts(sorts); + onSortsUpdate && onSortsUpdate(sorts); }, [onSortsUpdate], ); @@ -70,7 +64,7 @@ function TableHeader({ const onSortItemUnSelect = useCallback( (sortId: string) => { const newSorts = [] as SortType[]; - setSorts(newSorts); + innerSetSorts(newSorts); onSortsUpdate && onSortsUpdate(newSorts); }, [onSortsUpdate], @@ -87,12 +81,12 @@ function TableHeader({ - 0} + + From 0f4dcc19579fb4e2207bc6486aba97180ec9a204 Mon Sep 17 00:00:00 2001 From: Sammy Teillet Date: Mon, 24 Apr 2023 18:05:29 +0200 Subject: [PATCH 3/4] refactor: extract dropdown for Sort dropdown --- .../table/table-header/DropdownButton.tsx | 43 ++++++++----------- .../table/table-header/SortDropdownButton.tsx | 28 ++++++++++-- .../table/table-header/TableHeader.tsx | 12 +++++- 3 files changed, 52 insertions(+), 31 deletions(-) diff --git a/front/src/components/table/table-header/DropdownButton.tsx b/front/src/components/table/table-header/DropdownButton.tsx index 30d244846..16eac92b4 100644 --- a/front/src/components/table/table-header/DropdownButton.tsx +++ b/front/src/components/table/table-header/DropdownButton.tsx @@ -1,6 +1,5 @@ import styled from '@emotion/styled'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { useState, useRef } from 'react'; +import { useRef, ReactNode } from 'react'; import { useOutsideAlerter } from '../../../hooks/useOutsideAlerter'; import { modalBackground } from '../../../layout/styles/themes'; import { SortType } from './SortAndFilterBar'; @@ -10,6 +9,9 @@ type OwnProps = { options: Array; isActive: boolean; onSortSelect?: (id: string) => void; + children?: ReactNode; + isUnfolded?: boolean; + setIsUnfolded?: React.Dispatch>; }; const StyledDropdownButtonContainer = styled.div` @@ -88,15 +90,20 @@ const StyledIcon = styled.div` margin-right: ${(props) => props.theme.spacing(1)}; `; -function DropdownButton({ label, options, onSortSelect, isActive }: OwnProps) { - const [isUnfolded, setIsUnfolded] = useState(false); - +function DropdownButton({ + label, + options, + isActive, + children, + isUnfolded = false, + setIsUnfolded, +}: OwnProps) { const onButtonClick = () => { - setIsUnfolded(!isUnfolded); + setIsUnfolded && setIsUnfolded(!isUnfolded); }; const onOutsideClick = () => { - setIsUnfolded(false); + setIsUnfolded && setIsUnfolded(false); }; const dropdownRef = useRef(null); @@ -112,27 +119,13 @@ function DropdownButton({ label, options, onSortSelect, isActive }: OwnProps) { {label} {isUnfolded && options.length > 0 && ( - - {options.map((option, index) => ( - { - setIsUnfolded(false); - if (onSortSelect) { - onSortSelect(option.id); - } - }} - > - - {option.icon && } - - {option.label} - - ))} - + {children} )} ); } +DropdownButton.StyledDropdownItem = StyledDropdownItem; +DropdownButton.StyledIcon = StyledIcon; + export default DropdownButton; diff --git a/front/src/components/table/table-header/SortDropdownButton.tsx b/front/src/components/table/table-header/SortDropdownButton.tsx index 0f6cbffb2..c0695dd8b 100644 --- a/front/src/components/table/table-header/SortDropdownButton.tsx +++ b/front/src/components/table/table-header/SortDropdownButton.tsx @@ -1,11 +1,12 @@ -import { useCallback } from 'react'; +import { useCallback, useState } from 'react'; import DropdownButton from './DropdownButton'; import { SortType } from './SortAndFilterBar'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; type OwnProps = { sorts: SortType[]; - setSorts: any; - sortsAvailable: any; + setSorts: (sorts: SortType[]) => void; + sortsAvailable: SortType[]; }; export function SortDropdownButton({ @@ -13,6 +14,8 @@ export function SortDropdownButton({ setSorts, sorts, }: OwnProps) { + const [isUnfolded, setIsUnfolded] = useState(false); + const onSortItemSelect = useCallback( (sortId: string) => { const newSorts = [ @@ -33,6 +36,23 @@ export function SortDropdownButton({ options={sortsAvailable} onSortSelect={onSortItemSelect} isActive={sorts.length > 0} - /> + isUnfolded={isUnfolded} + setIsUnfolded={setIsUnfolded} + > + {sortsAvailable.map((option, index) => ( + { + setIsUnfolded(false); + onSortItemSelect(option.id); + }} + > + + {option.icon && } + + {option.label} + + ))} + ); } diff --git a/front/src/components/table/table-header/TableHeader.tsx b/front/src/components/table/table-header/TableHeader.tsx index a3ba9ac36..98aa5d74e 100644 --- a/front/src/components/table/table-header/TableHeader.tsx +++ b/front/src/components/table/table-header/TableHeader.tsx @@ -80,14 +80,22 @@ function TableHeader({ {viewName} - + - + {sorts.length > 0 && ( From f7c53dbdeb2328b2bcb00ba0cc119a76c2f9c542 Mon Sep 17 00:00:00 2001 From: Sammy Teillet Date: Mon, 24 Apr 2023 18:17:01 +0200 Subject: [PATCH 4/4] feature: set the right sort on click --- .../table/table-header/DropdownButton.tsx | 6 +----- .../table/table-header/SortDropdownButton.tsx | 14 +++----------- .../components/table/table-header/TableHeader.tsx | 12 ++---------- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/front/src/components/table/table-header/DropdownButton.tsx b/front/src/components/table/table-header/DropdownButton.tsx index 16eac92b4..75469b77e 100644 --- a/front/src/components/table/table-header/DropdownButton.tsx +++ b/front/src/components/table/table-header/DropdownButton.tsx @@ -2,13 +2,10 @@ import styled from '@emotion/styled'; import { useRef, ReactNode } from 'react'; import { useOutsideAlerter } from '../../../hooks/useOutsideAlerter'; import { modalBackground } from '../../../layout/styles/themes'; -import { SortType } from './SortAndFilterBar'; type OwnProps = { label: string; - options: Array; isActive: boolean; - onSortSelect?: (id: string) => void; children?: ReactNode; isUnfolded?: boolean; setIsUnfolded?: React.Dispatch>; @@ -92,7 +89,6 @@ const StyledIcon = styled.div` function DropdownButton({ label, - options, isActive, children, isUnfolded = false, @@ -118,7 +114,7 @@ function DropdownButton({ > {label} - {isUnfolded && options.length > 0 && ( + {isUnfolded && ( {children} )} diff --git a/front/src/components/table/table-header/SortDropdownButton.tsx b/front/src/components/table/table-header/SortDropdownButton.tsx index c0695dd8b..35d1dcb2d 100644 --- a/front/src/components/table/table-header/SortDropdownButton.tsx +++ b/front/src/components/table/table-header/SortDropdownButton.tsx @@ -17,14 +17,8 @@ export function SortDropdownButton({ const [isUnfolded, setIsUnfolded] = useState(false); const onSortItemSelect = useCallback( - (sortId: string) => { - const newSorts = [ - { - label: 'Created at', - order: 'asc', - id: sortId, - } satisfies SortType, - ]; + (sort: SortType) => { + const newSorts = [sort]; setSorts(newSorts); }, [setSorts], @@ -33,8 +27,6 @@ export function SortDropdownButton({ return ( 0} isUnfolded={isUnfolded} setIsUnfolded={setIsUnfolded} @@ -44,7 +36,7 @@ export function SortDropdownButton({ key={index} onClick={() => { setIsUnfolded(false); - onSortItemSelect(option.id); + onSortItemSelect(option); }} > diff --git a/front/src/components/table/table-header/TableHeader.tsx b/front/src/components/table/table-header/TableHeader.tsx index 98aa5d74e..97f5a7384 100644 --- a/front/src/components/table/table-header/TableHeader.tsx +++ b/front/src/components/table/table-header/TableHeader.tsx @@ -80,22 +80,14 @@ function TableHeader({ {viewName} - + - + {sorts.length > 0 && (