From 18e210b29b992598bdec64d442754e83bb7e2ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tha=C3=AFs?= Date: Thu, 5 Oct 2023 22:19:08 +0200 Subject: [PATCH] feat: add active and disabled object tables to settings (#1885) * feat: add active and disabled object tables to settings Closes #1799, Closes #1800 * refactor: add align prop to TableCell --- front/src/modules/ui/icon/index.ts | 2 + .../src/modules/ui/table/components/Table.tsx | 5 +- .../modules/ui/table/components/TableCell.tsx | 22 +-- .../ui/table/components/TableHeader.tsx | 13 +- .../modules/ui/table/components/TableRow.tsx | 19 +++ .../ui/table/components/TableSection.tsx | 67 ++++---- .../components/__stories__/Table.stories.tsx | 31 ++-- front/src/modules/ui/tag/components/Tag.tsx | 9 +- front/src/pages/settings/SettingsObjects.tsx | 161 +++++++++++++++++- 9 files changed, 247 insertions(+), 82 deletions(-) create mode 100644 front/src/modules/ui/table/components/TableRow.tsx diff --git a/front/src/modules/ui/icon/index.ts b/front/src/modules/ui/icon/index.ts index 1cf545d93..d3ed9770f 100644 --- a/front/src/modules/ui/icon/index.ts +++ b/front/src/modules/ui/icon/index.ts @@ -54,6 +54,7 @@ export { IconLinkOff, IconList, IconLogout, + IconLuggage, IconMail, IconMap, IconMinus, @@ -61,6 +62,7 @@ export { IconNotes, IconPencil, IconPhone, + IconPlane, IconPlus, IconProgressCheck, IconSearch, diff --git a/front/src/modules/ui/table/components/Table.tsx b/front/src/modules/ui/table/components/Table.tsx index 84b3498a4..a03874fcc 100644 --- a/front/src/modules/ui/table/components/Table.tsx +++ b/front/src/modules/ui/table/components/Table.tsx @@ -1,8 +1,5 @@ import styled from '@emotion/styled'; -const StyledTable = styled.table` - border-collapse: collapse; - border-spacing: 0; -`; +const StyledTable = styled.div``; export { StyledTable as Table }; diff --git a/front/src/modules/ui/table/components/TableCell.tsx b/front/src/modules/ui/table/components/TableCell.tsx index c5679187e..13820ed50 100644 --- a/front/src/modules/ui/table/components/TableCell.tsx +++ b/front/src/modules/ui/table/components/TableCell.tsx @@ -1,18 +1,18 @@ -import { PropsWithChildren } from 'react'; import styled from '@emotion/styled'; -const StyledTableCell = styled.td` - padding: 0 ${({ theme }) => theme.spacing(2)}; -`; - -const StyledTableCellContent = styled.div` +const StyledTableCell = styled.div<{ align?: 'left' | 'center' | 'right' }>` align-items: center; + color: ${({ theme }) => theme.font.color.secondary}; display: flex; height: ${({ theme }) => theme.spacing(8)}; + justify-content: ${({ align }) => + align === 'right' + ? 'flex-end' + : align === 'center' + ? 'center' + : 'flex-start'}; + padding: 0 ${({ theme }) => theme.spacing(2)}; + text-align: ${({ align }) => align ?? 'left'}; `; -export const TableCell = ({ children }: PropsWithChildren) => ( - - {children} - -); +export { StyledTableCell as TableCell }; diff --git a/front/src/modules/ui/table/components/TableHeader.tsx b/front/src/modules/ui/table/components/TableHeader.tsx index c8f8c07ca..8f7d13c62 100644 --- a/front/src/modules/ui/table/components/TableHeader.tsx +++ b/front/src/modules/ui/table/components/TableHeader.tsx @@ -1,11 +1,20 @@ import styled from '@emotion/styled'; -const StyledTableHeader = styled.th` +const StyledTableHeader = styled.div<{ align?: 'left' | 'center' | 'right' }>` + align-items: center; + border-bottom: 1px solid ${({ theme }) => theme.border.color.light}; color: ${({ theme }) => theme.font.color.tertiary}; + display: flex; font-weight: ${({ theme }) => theme.font.weight.medium}; height: ${({ theme }) => theme.spacing(8)}; + justify-content: ${({ align }) => + align === 'right' + ? 'flex-end' + : align === 'center' + ? 'center' + : 'flex-start'}; padding: 0 ${({ theme }) => theme.spacing(2)}; - text-align: left; + text-align: ${({ align }) => align ?? 'left'}; `; export { StyledTableHeader as TableHeader }; diff --git a/front/src/modules/ui/table/components/TableRow.tsx b/front/src/modules/ui/table/components/TableRow.tsx new file mode 100644 index 000000000..f47dee01e --- /dev/null +++ b/front/src/modules/ui/table/components/TableRow.tsx @@ -0,0 +1,19 @@ +import styled from '@emotion/styled'; + +const StyledTableRow = styled.div<{ onClick?: () => void }>` + border-radius: ${({ theme }) => theme.border.radius.sm}; + display: grid; + grid-auto-columns: 1fr; + grid-auto-flow: column; + transition: background-color + ${({ theme }) => theme.animation.duration.normal}s; + width: 100%; + + &:hover { + background-color: ${({ onClick, theme }) => + onClick ? theme.background.transparent.light : 'transparent'}; + cursor: ${({ onClick }) => (onClick ? 'pointer' : 'default')}; + } +`; + +export { StyledTableRow as TableRow }; diff --git a/front/src/modules/ui/table/components/TableSection.tsx b/front/src/modules/ui/table/components/TableSection.tsx index d1f23bdd2..83132bc73 100644 --- a/front/src/modules/ui/table/components/TableSection.tsx +++ b/front/src/modules/ui/table/components/TableSection.tsx @@ -9,26 +9,6 @@ type TableSectionProps = { title: string; }; -const StyledTableBody = styled.tbody<{ isExpanded: boolean }>` - border-bottom: ${({ isExpanded, theme }) => - isExpanded ? `1px solid ${theme.border.color.light}` : 0}; - - &:first-of-type { - border-top: ${({ theme }) => `1px solid ${theme.border.color.light}`}; - } - - td > div { - ${({ isExpanded }) => (isExpanded ? '' : 'height: 0; opacity: 0;')}; - overflow: hidden; - transition: height ${({ theme }) => theme.animation.duration.normal}s, - opacity ${({ theme }) => theme.animation.duration.normal}s; - } -`; - -const StyledTh = styled.th` - padding: 0; -`; - const StyledSectionHeader = styled.div<{ isExpanded: boolean }>` align-items: center; background-color: ${({ theme }) => theme.background.transparent.lighter}; @@ -45,6 +25,19 @@ const StyledSectionHeader = styled.div<{ isExpanded: boolean }>` text-transform: uppercase; `; +const StyledSection = styled.div<{ isExpanded: boolean }>` + max-height: ${({ isExpanded }) => (isExpanded ? '1000px' : 0)}; + opacity: ${({ isExpanded }) => (isExpanded ? 1 : 0)}; + overflow: hidden; + transition: max-height ${({ theme }) => theme.animation.duration.normal}s, + opacity ${({ theme }) => theme.animation.duration.normal}s; +`; + +const StyledSectionContent = styled.div` + border-bottom: 1px solid ${({ theme }) => theme.border.color.light}; + padding: ${({ theme }) => theme.spacing(2)} 0; +`; + export const TableSection = ({ children, title }: TableSectionProps) => { const theme = useTheme(); const [isExpanded, setIsExpanded] = useState(true); @@ -53,23 +46,21 @@ export const TableSection = ({ children, title }: TableSectionProps) => { setIsExpanded((previousIsExpanded) => !previousIsExpanded); return ( - - - - - {title} - {isExpanded ? ( - - ) : ( - - )} - - - - {children} - + <> + + {title} + {isExpanded ? ( + + ) : ( + + )} + + + {children} + + ); }; diff --git a/front/src/modules/ui/table/components/__stories__/Table.stories.tsx b/front/src/modules/ui/table/components/__stories__/Table.stories.tsx index eb270fb7a..96019336c 100644 --- a/front/src/modules/ui/table/components/__stories__/Table.stories.tsx +++ b/front/src/modules/ui/table/components/__stories__/Table.stories.tsx @@ -5,6 +5,7 @@ import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; import { Table } from '../Table'; import { TableCell } from '../TableCell'; import { TableHeader } from '../TableHeader'; +import { TableRow } from '../TableRow'; import { TableSection } from '../TableSection'; const meta: Meta = { @@ -23,31 +24,29 @@ type Story = StoryObj; export const Default: Story = { render: () => ( - - - Header 1 - Header 2 - Header 3 - - + + Header 1 + Header 2 + Numbers + - + Cell 1 Cell 2 - Cell 3 - - + 3 + + Cell 4 Cell 5 - Cell 6 - + 6 + - + Lorem ipsum dolor sit amet Lorem ipsum - Lorem ipsum - + 42 +
), diff --git a/front/src/modules/ui/tag/components/Tag.tsx b/front/src/modules/ui/tag/components/Tag.tsx index 7c572c287..7bd0548b6 100644 --- a/front/src/modules/ui/tag/components/Tag.tsx +++ b/front/src/modules/ui/tag/components/Tag.tsx @@ -41,13 +41,18 @@ const StyledTag = styled.h3<{ `; export type TagProps = { + className?: string; color: ThemeColor; text: string; onClick?: () => void; }; -export const Tag = ({ color, text, onClick }: TagProps) => ( - +export const Tag = ({ className, color, text, onClick }: TagProps) => ( + {text} ); diff --git a/front/src/pages/settings/SettingsObjects.tsx b/front/src/pages/settings/SettingsObjects.tsx index f1af24afd..ab3976c57 100644 --- a/front/src/pages/settings/SettingsObjects.tsx +++ b/front/src/pages/settings/SettingsObjects.tsx @@ -1,18 +1,161 @@ +import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { IconSettings } from '@/ui/icon'; +import { + IconBuildingSkyscraper, + IconChevronRight, + IconDotsVertical, + IconLuggage, + IconPlane, + IconSettings, + IconUser, +} from '@/ui/icon'; import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer'; +import { Table } from '@/ui/table/components/Table'; +import { TableCell } from '@/ui/table/components/TableCell'; +import { TableHeader } from '@/ui/table/components/TableHeader'; +import { TableRow } from '@/ui/table/components/TableRow'; +import { TableSection } from '@/ui/table/components/TableSection'; +import { Tag } from '@/ui/tag/components/Tag'; import { H1Title } from '@/ui/typography/components/H1Title'; +import { H2Title } from '@/ui/typography/components/H2Title'; const StyledContainer = styled.div` padding: ${({ theme }) => theme.spacing(8)}; - width: 350px; + width: 512px; `; -export const SettingsObjects = () => ( - - - - - -); +const StyledTableRow = styled(TableRow)` + grid-template-columns: 180px 98.7px 98.7px 98.7px 36px; +`; + +const StyledNameTableCell = styled(TableCell)` + color: ${({ theme }) => theme.font.color.primary}; + gap: ${({ theme }) => theme.spacing(2)}; +`; + +const StyledTag = styled(Tag)` + box-sizing: border-box; + height: ${({ theme }) => theme.spacing(4)}; +`; + +const StyledIconTableCell = styled(TableCell)` + justify-content: center; + padding-right: ${({ theme }) => theme.spacing(1)}; +`; + +const StyledIconChevronRight = styled(IconChevronRight)` + color: ${({ theme }) => theme.font.color.tertiary}; +`; + +const StyledIconDotsVertical = styled(IconDotsVertical)` + color: ${({ theme }) => theme.font.color.tertiary}; +`; + +const activeObjectItems = [ + { + name: 'Companies', + Icon: IconBuildingSkyscraper, + type: 'standard', + fields: 23, + instances: 165, + }, + { + name: 'People', + Icon: IconUser, + type: 'standard', + fields: 16, + instances: 462, + }, +]; + +const disabledObjectItems = [ + { + name: 'Travels', + Icon: IconLuggage, + type: 'custom', + fields: 23, + instances: 165, + }, + { + name: 'Flights', + Icon: IconPlane, + type: 'custom', + fields: 23, + instances: 165, + }, +]; + +export const SettingsObjects = () => { + const theme = useTheme(); + + return ( + + + + + + + Name + Type + Fields + Instances + + + + {activeObjectItems.map((objectItem) => ( + undefined}> + + + {objectItem.name} + + + {objectItem.type === 'standard' ? ( + + ) : ( + + )} + + {objectItem.fields} + {objectItem.instances} + + + + + ))} + + {!!disabledObjectItems.length && ( + + {disabledObjectItems.map((objectItem) => ( + + + + {objectItem.name} + + + {objectItem.type === 'standard' ? ( + + ) : ( + + )} + + {objectItem.fields} + {objectItem.instances} + + + + + ))} + + )} +
+
+
+ ); +};