diff --git a/front/src/components/table/Table.tsx b/front/src/components/table/Table.tsx index fd3eec506..c6c86287d 100644 --- a/front/src/components/table/Table.tsx +++ b/front/src/components/table/Table.tsx @@ -17,6 +17,7 @@ type OwnProps = { viewName: string; viewIcon?: IconProp; onSortsUpdate?: (sorts: Array) => void; + sortsAvailable?: Array; }; const StyledTable = styled.table` @@ -68,6 +69,7 @@ function Table({ viewName, viewIcon, onSortsUpdate, + sortsAvailable, }: OwnProps) { const table = useReactTable({ data, @@ -81,6 +83,7 @@ function Table({ viewName={viewName} viewIcon={viewIcon} onSortsUpdate={onSortsUpdate} + sortsAvailable={sortsAvailable || []} /> diff --git a/front/src/components/table/table-header/DropdownButton.tsx b/front/src/components/table/table-header/DropdownButton.tsx index 2c1b85d52..df7c1f952 100644 --- a/front/src/components/table/table-header/DropdownButton.tsx +++ b/front/src/components/table/table-header/DropdownButton.tsx @@ -15,6 +15,7 @@ const StyledDropdownButtonContainer = styled.div` display: flex; flex-direction: column; position: relative; + z-index: 1; `; type StyledDropdownButtonProps = { @@ -36,16 +37,33 @@ const StyledDropdownButton = styled.div` `; const StyledDropdown = styled.ul` + --wraper-border: 1px; + --wraper-border-radius: 8px; + --outer-border-radius: calc(var(--wraper-border-radius) - 2px); + display: flex; + flex-direction: column; position: absolute; top: 14px; right: 0; - border: 1px solid ${(props) => props.theme.primaryBorder}; + border: var(--wraper-border) solid ${(props) => props.theme.primaryBorder}; box-shadow: 0px 3px 12px rgba(0, 0, 0, 0.09); - border-radius: 8px; + border-radius: var(--wraper-border-radius); padding: 0px; min-width: 160px; ${modalBackground} + li { + border-radius: 2px; + + &:first-child { + border-top-left-radius: var(--outer-border-radius); + border-top-right-radius: var(--outer-border-radius); + } + &:last-child { + border-bottom-left-radius: var(--outer-border-radius); + border-bottom-right-radius: var(--outer-border-radius); + } + } `; const StyledDropdownItem = styled.li` @@ -53,14 +71,12 @@ const StyledDropdownItem = styled.li` padding: ${(props) => props.theme.spacing(2)} calc(${(props) => props.theme.spacing(2)} - 2px); margin: 2px; - background: ${(props) => props.theme.primaryBackground}; + background: rgba(0, 0, 0, 0); cursor: pointer; - width: 100%; - border-radius: 4px; color: ${(props) => props.theme.text60}; &:hover { - filter: brightness(0.95); + background: rgba(0, 0, 0, 0.04); } `; diff --git a/front/src/components/table/table-header/SortAndFilterBar.tsx b/front/src/components/table/table-header/SortAndFilterBar.tsx index df2e09ab4..1e028fc3d 100644 --- a/front/src/components/table/table-header/SortAndFilterBar.tsx +++ b/front/src/components/table/table-header/SortAndFilterBar.tsx @@ -8,10 +8,10 @@ type OwnProps = { onRemoveSort: (sortId: string) => void; }; -export type SortType = { +export type SortType = { label: string; order: 'asc' | 'desc'; - id: string; + id: SortIds; icon?: IconProp; }; diff --git a/front/src/components/table/table-header/TableHeader.tsx b/front/src/components/table/table-header/TableHeader.tsx index 8253571bc..8c3077df0 100644 --- a/front/src/components/table/table-header/TableHeader.tsx +++ b/front/src/components/table/table-header/TableHeader.tsx @@ -2,14 +2,14 @@ import styled from '@emotion/styled'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import DropdownButton from './DropdownButton'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; -import { faCalendar } from '@fortawesome/pro-regular-svg-icons'; import SortAndFilterBar, { SortType } from './SortAndFilterBar'; -import { useEffect, useState } from 'react'; +import { useCallback, useState } from 'react'; type OwnProps = { viewName: string; viewIcon?: IconProp; onSortsUpdate?: (sorts: Array) => void; + sortsAvailable: Array; }; const StyledContainer = styled.div` @@ -44,34 +44,37 @@ const StyledFilters = styled.div` margin-right: ${(props) => props.theme.spacing(2)}; `; -function TableHeader({ viewName, viewIcon, onSortsUpdate }: OwnProps) { +function TableHeader({ + viewName, + viewIcon, + onSortsUpdate, + sortsAvailable, +}: OwnProps) { const [sorts, setSorts] = useState([] as Array); - const onSortItemSelect = (sortId: string) => { - setSorts([ - { - label: 'Created at', - order: 'asc', - id: sortId, - } as SortType, - ]); - }; - const onSortItemUnSelect = (sortId: string) => { - setSorts([]); - }; - - useEffect(() => { - onSortsUpdate && onSortsUpdate(sorts); - }, [sorts, onSortsUpdate]); - - const sortsAvailable: Array = [ - { - id: 'created_at', - label: 'Created at', - order: 'asc', - icon: faCalendar, + const onSortItemSelect = useCallback( + (sortId: string) => { + const newSorts = [ + { + label: 'Created at', + order: 'asc', + id: sortId, + } satisfies SortType, + ]; + setSorts(newSorts); + onSortsUpdate && onSortsUpdate(newSorts); }, - ]; + [onSortsUpdate], + ); + + const onSortItemUnSelect = useCallback( + (sortId: string) => { + const newSorts = [] as SortType[]; + setSorts(newSorts); + onSortsUpdate && onSortsUpdate(newSorts); + }, + [onSortsUpdate], + ); return ( diff --git a/front/src/components/table/table-header/__stories__/TableHeader.stories.tsx b/front/src/components/table/table-header/__stories__/TableHeader.stories.tsx index fa7f336ac..2862c0734 100644 --- a/front/src/components/table/table-header/__stories__/TableHeader.stories.tsx +++ b/front/src/components/table/table-header/__stories__/TableHeader.stories.tsx @@ -1,7 +1,8 @@ import TableHeader from '../TableHeader'; import { ThemeProvider } from '@emotion/react'; import { lightTheme } from '../../../../layout/styles/themes'; -import { faBuilding } from '@fortawesome/pro-regular-svg-icons'; +import { faBuilding, faCalendar } from '@fortawesome/pro-regular-svg-icons'; +import { SortType } from '../SortAndFilterBar'; const component = { title: 'TableHeader', @@ -11,9 +12,21 @@ const component = { export default component; export const RegularTableHeader = () => { + const sortsAvailable: Array = [ + { + id: 'created_at', + label: 'Created at', + order: 'asc', + icon: faCalendar, + }, + ]; return ( - + ); }; diff --git a/front/src/index.tsx b/front/src/index.tsx index ec84e70d6..b57549182 100644 --- a/front/src/index.tsx +++ b/front/src/index.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { StrictMode } from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; @@ -14,7 +14,9 @@ const root = ReactDOM.createRoot( root.render( - + + + , ); diff --git a/front/src/pages/people/People.tsx b/front/src/pages/people/People.tsx index b2bb656ed..f689bfc64 100644 --- a/front/src/pages/people/People.tsx +++ b/front/src/pages/people/People.tsx @@ -2,9 +2,9 @@ import { faUser, faList } from '@fortawesome/pro-regular-svg-icons'; import WithTopBarContainer from '../../layout/containers/WithTopBarContainer'; import Table from '../../components/table/Table'; import styled from '@emotion/styled'; -import { peopleColumns } from './people-table'; +import { peopleColumns, sortsAvailable } from './people-table'; import { mapPerson } from '../../interfaces/person.interface'; -import { useState } from 'react'; +import { useCallback, useState } from 'react'; import { SortType } from '../../components/table/table-header/SortAndFilterBar'; import { OrderBy, usePeopleQuery } from '../../services/people'; @@ -31,10 +31,10 @@ function People() { const [, setSorts] = useState([] as Array); const [orderBy, setOrderBy] = useState(defaultOrderBy); - const updateSorts = (sorts: Array) => { + const updateSorts = useCallback((sorts: Array) => { setSorts(sorts); setOrderBy(sorts.length ? reduceSortsToOrderBy(sorts) : defaultOrderBy); - }; + }, []); const { data } = usePeopleQuery(orderBy); @@ -48,6 +48,7 @@ function People() { viewName="All People" viewIcon={faList} onSortsUpdate={updateSorts} + sortsAvailable={sortsAvailable} /> } diff --git a/front/src/pages/people/people-table.tsx b/front/src/pages/people/people-table.tsx index f96ef1cbe..1a3eaad59 100644 --- a/front/src/pages/people/people-table.tsx +++ b/front/src/pages/people/people-table.tsx @@ -15,8 +15,26 @@ import Checkbox from '../../components/form/Checkbox'; import HorizontalyAlignedContainer from '../../layout/containers/HorizontalyAlignedContainer'; import CompanyChip from '../../components/chips/CompanyChip'; import PersonChip from '../../components/chips/PersonChip'; -import { Person } from '../../interfaces/person.interface'; +import { GraphqlPerson, Person } from '../../interfaces/person.interface'; import PipeChip from '../../components/chips/PipeChip'; +import { SortType } from '../../components/table/table-header/SortAndFilterBar'; + +export const sortsAvailable = [ + { + id: 'email', + label: 'Email', + order: 'asc', + icon: faEnvelope, + }, + { id: 'phone', label: 'Phone', order: 'asc', icon: faPhone }, + { + id: 'created_at', + label: 'Created at', + order: 'asc', + icon: faCalendar, + }, + { id: 'city', label: 'City', order: 'asc', icon: faMapPin }, +] satisfies Array>; const columnHelper = createColumnHelper(); export const peopleColumns = [