diff --git a/airbyte-webapp/src/components/EntityTable/ConnectionTable.tsx b/airbyte-webapp/src/components/EntityTable/ConnectionTable.tsx index 9285818c30ce2..4784443111e43 100644 --- a/airbyte-webapp/src/components/EntityTable/ConnectionTable.tsx +++ b/airbyte-webapp/src/components/EntityTable/ConnectionTable.tsx @@ -11,10 +11,10 @@ import { FeatureItem, useFeature } from "hooks/services/Feature"; import { useQuery } from "hooks/useQuery"; import ConnectionSettingsCell from "./components/ConnectionSettingsCell"; -import ConnectorCell from "./components/ConnectorCell"; -import FrequencyCell from "./components/FrequencyCell"; -import LastSyncCell from "./components/LastSyncCell"; -import NameCell from "./components/NameCell"; +import { ConnectionStatusCell } from "./components/ConnectionStatusCell"; +import { ConnectorNameCell } from "./components/ConnectorNameCell"; +import { FrequencyCell } from "./components/FrequencyCell"; +import { LastSyncCell } from "./components/LastSyncCell"; import { StatusCell } from "./components/StatusCell"; import { ITableDataItem, SortOrderEnum } from "./types"; @@ -86,8 +86,13 @@ const ConnectionTable: React.FC = ({ data, entity, onClickRow, onSync }) headerHighlighted: true, accessor: "name", customWidth: 30, + responsive: true, Cell: ({ cell, row }: CellProps) => ( - + ), }, { @@ -104,13 +109,10 @@ const ConnectionTable: React.FC = ({ data, entity, onClickRow, onSync }) ), headerHighlighted: true, accessor: "entityName", + customWidth: 30, + responsive: true, Cell: ({ cell, row }: CellProps) => ( - + ), }, { @@ -124,11 +126,12 @@ const ConnectionTable: React.FC = ({ data, entity, onClickRow, onSync }) ), accessor: "connectorName", + customWidth: 30, + responsive: true, Cell: ({ cell, row }: CellProps) => ( - + ), }, - { Header: , accessor: "scheduleData", diff --git a/airbyte-webapp/src/components/EntityTable/ImplementationTable.tsx b/airbyte-webapp/src/components/EntityTable/ImplementationTable.tsx index ab55ba515206e..b17c926aa25de 100644 --- a/airbyte-webapp/src/components/EntityTable/ImplementationTable.tsx +++ b/airbyte-webapp/src/components/EntityTable/ImplementationTable.tsx @@ -4,15 +4,15 @@ import { FormattedMessage } from "react-intl"; import { useNavigate } from "react-router-dom"; import { CellProps } from "react-table"; +import { ConnectorNameCell } from "components/EntityTable/components/ConnectorNameCell"; import { Table, SortableTableHeader } from "components/ui/Table"; import { useQuery } from "hooks/useQuery"; import AllConnectionsStatusCell from "./components/AllConnectionsStatusCell"; import ConnectEntitiesCell from "./components/ConnectEntitiesCell"; -import ConnectorCell from "./components/ConnectorCell"; -import LastSyncCell from "./components/LastSyncCell"; -import NameCell from "./components/NameCell"; +import { EntityNameCell } from "./components/EntityNameCell"; +import { LastSyncCell } from "./components/LastSyncCell"; import styles from "./ImplementationTable.module.scss"; import { EntityTableDataItem, SortOrderEnum } from "./types"; @@ -80,7 +80,7 @@ const ImplementationTable: React.FC = ({ data, entity, onClickRow }) => accessor: "entityName", customWidth: 40, Cell: ({ cell, row }: CellProps) => ( - + ), }, { @@ -95,7 +95,7 @@ const ImplementationTable: React.FC = ({ data, entity, onClickRow }) => ), accessor: "connectorName", Cell: ({ cell, row }: CellProps) => ( - + ), }, { diff --git a/airbyte-webapp/src/components/EntityTable/components/ConnectionStatusCell.module.scss b/airbyte-webapp/src/components/EntityTable/components/ConnectionStatusCell.module.scss new file mode 100644 index 0000000000000..b2396bd7c243d --- /dev/null +++ b/airbyte-webapp/src/components/EntityTable/components/ConnectionStatusCell.module.scss @@ -0,0 +1,14 @@ +@use "scss/variables"; +@use "scss/colors"; + +$connector_icon_width: 20px; +$connector_icon_margin: 10px; + +.content { + display: flex; + align-items: center; +} + +.text { + width: calc(100% - #{$connector_icon_width + $connector_icon_margin}); +} diff --git a/airbyte-webapp/src/components/EntityTable/components/NameCell.tsx b/airbyte-webapp/src/components/EntityTable/components/ConnectionStatusCell.tsx similarity index 58% rename from airbyte-webapp/src/components/EntityTable/components/NameCell.tsx rename to airbyte-webapp/src/components/EntityTable/components/ConnectionStatusCell.tsx index f86ce6e1437a0..6c1b6c66f1c21 100644 --- a/airbyte-webapp/src/components/EntityTable/components/NameCell.tsx +++ b/airbyte-webapp/src/components/EntityTable/components/ConnectionStatusCell.tsx @@ -1,40 +1,20 @@ import React, { useMemo } from "react"; import { useIntl } from "react-intl"; -import styled from "styled-components"; -import { ConnectorIcon } from "components/common/ConnectorIcon"; import { StatusIcon } from "components/ui/StatusIcon"; import { StatusIconStatus } from "components/ui/StatusIcon/StatusIcon"; import { Status } from "../types"; +import styles from "./ConnectionStatusCell.module.scss"; +import { EntityNameCell } from "./EntityNameCell"; -interface Props { +interface ConnectionStatusCellProps { + status: string | null; value: string; - enabled?: boolean; - status?: string | null; - icon?: boolean; - img?: string; + enabled: boolean; } -const Content = styled.div` - display: flex; - align-items: center; - font-weight: 500; -`; - -const Name = styled.div<{ enabled?: boolean }>` - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - max-width: 500px; - color: ${({ theme, enabled }) => (!enabled ? theme.greyColor40 : "inherit")}; -`; - -const Image = styled(ConnectorIcon)` - margin-right: 6px; -`; - -const NameCell: React.FC = ({ value, enabled, status, icon, img }) => { +export const ConnectionStatusCell: React.FC = ({ status, value, enabled }) => { const { formatMessage } = useIntl(); const statusIconStatus = useMemo( () => @@ -73,12 +53,9 @@ const NameCell: React.FC = ({ value, enabled, status, icon, img }) => { }); return ( - - {status && } - {icon && } - {value} - +
+ + +
); }; - -export default NameCell; diff --git a/airbyte-webapp/src/components/EntityTable/components/ConnectorCell.tsx b/airbyte-webapp/src/components/EntityTable/components/ConnectorCell.tsx deleted file mode 100644 index c9515c835984d..0000000000000 --- a/airbyte-webapp/src/components/EntityTable/components/ConnectorCell.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React from "react"; -import styled from "styled-components"; - -import { ConnectorIcon } from "components/common/ConnectorIcon"; - -interface IProps { - value: string; - enabled?: boolean; - img?: string; -} - -const Content = styled.div<{ enabled?: boolean }>` - display: flex; - align-items: center; - color: ${({ theme, enabled }) => (!enabled ? theme.greyColor40 : "inheret")}; - font-weight: 500; -`; - -const Image = styled(ConnectorIcon)` - margin-right: 6px; -`; - -const ConnectorCell: React.FC = ({ value, enabled, img }) => { - return ( - - - {value} - - ); -}; - -export default ConnectorCell; diff --git a/airbyte-webapp/src/components/EntityTable/components/ConnectorNameCell.module.scss b/airbyte-webapp/src/components/EntityTable/components/ConnectorNameCell.module.scss new file mode 100644 index 0000000000000..7312f2cb7eceb --- /dev/null +++ b/airbyte-webapp/src/components/EntityTable/components/ConnectorNameCell.module.scss @@ -0,0 +1,14 @@ +@use "scss/variables"; +@use "scss/colors"; + +$status_icon_width: 25px; + +.content { + display: flex; + align-items: center; +} + +.text { + width: calc(100% - #{$status_icon_width}); + margin-left: variables.$spacing-md; +} diff --git a/airbyte-webapp/src/components/EntityTable/components/ConnectorNameCell.tsx b/airbyte-webapp/src/components/EntityTable/components/ConnectorNameCell.tsx new file mode 100644 index 0000000000000..c8ecffe918d91 --- /dev/null +++ b/airbyte-webapp/src/components/EntityTable/components/ConnectorNameCell.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +import { ConnectorIcon } from "components/common/ConnectorIcon"; + +import styles from "./ConnectorNameCell.module.scss"; +import { EntityNameCell } from "./EntityNameCell"; + +interface ConnectorNameCellProps { + enabled: boolean; + value: string; + icon: string | undefined; +} + +export const ConnectorNameCell: React.FC = ({ value, enabled, icon }) => { + return ( +
+ + +
+ ); +}; diff --git a/airbyte-webapp/src/components/EntityTable/components/EntityNameCell.module.scss b/airbyte-webapp/src/components/EntityTable/components/EntityNameCell.module.scss new file mode 100644 index 0000000000000..f54b4281cdff1 --- /dev/null +++ b/airbyte-webapp/src/components/EntityTable/components/EntityNameCell.module.scss @@ -0,0 +1,14 @@ +@use "scss/variables"; +@use "scss/colors"; + +.text { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + font-weight: 500; + color: colors.$grey; + + &.enabled { + color: colors.$dark-blue; + } +} diff --git a/airbyte-webapp/src/components/EntityTable/components/EntityNameCell.tsx b/airbyte-webapp/src/components/EntityTable/components/EntityNameCell.tsx new file mode 100644 index 0000000000000..99c73743f0f05 --- /dev/null +++ b/airbyte-webapp/src/components/EntityTable/components/EntityNameCell.tsx @@ -0,0 +1,20 @@ +import classNames from "classnames"; +import React from "react"; + +import { Text } from "components/ui/Text"; + +import styles from "./EntityNameCell.module.scss"; + +interface EntityNameCellProps { + value: string; + enabled: boolean; + className?: string; +} + +export const EntityNameCell: React.FC = ({ value, enabled, className }) => { + return ( + + {value} + + ); +}; diff --git a/airbyte-webapp/src/components/EntityTable/components/FrequencyCell.module.scss b/airbyte-webapp/src/components/EntityTable/components/FrequencyCell.module.scss new file mode 100644 index 0000000000000..d46751de19282 --- /dev/null +++ b/airbyte-webapp/src/components/EntityTable/components/FrequencyCell.module.scss @@ -0,0 +1,10 @@ +@use "scss/variables"; +@use "scss/colors"; + +.text { + color: colors.$grey; + + &.enabled { + color: colors.$dark-blue; + } +} diff --git a/airbyte-webapp/src/components/EntityTable/components/FrequencyCell.tsx b/airbyte-webapp/src/components/EntityTable/components/FrequencyCell.tsx index 4d5ed76615025..3a9e18f431cc3 100644 --- a/airbyte-webapp/src/components/EntityTable/components/FrequencyCell.tsx +++ b/airbyte-webapp/src/components/EntityTable/components/FrequencyCell.tsx @@ -1,36 +1,34 @@ +import classNames from "classnames"; import React from "react"; import { FormattedMessage } from "react-intl"; -import styled from "styled-components"; + +import { Text } from "components/ui/Text"; import { ConnectionScheduleData, ConnectionScheduleType } from "core/request/AirbyteClient"; +import styles from "./FrequencyCell.module.scss"; + interface FrequencyCellProps { value: ConnectionScheduleData; enabled?: boolean; scheduleType?: ConnectionScheduleType; } -const Content = styled.div<{ enabled?: boolean }>` - color: ${({ theme, enabled }) => (!enabled ? theme.greyColor40 : "inherit")}; -`; - -const FrequencyCell: React.FC = ({ value, enabled, scheduleType }) => { +export const FrequencyCell: React.FC = ({ value, enabled, scheduleType }) => { if (scheduleType === ConnectionScheduleType.cron || scheduleType === ConnectionScheduleType.manual) { return ( - + - + ); } return ( - + - + ); }; - -export default FrequencyCell; diff --git a/airbyte-webapp/src/components/EntityTable/components/LastSyncCell.module.scss b/airbyte-webapp/src/components/EntityTable/components/LastSyncCell.module.scss new file mode 100644 index 0000000000000..d46751de19282 --- /dev/null +++ b/airbyte-webapp/src/components/EntityTable/components/LastSyncCell.module.scss @@ -0,0 +1,10 @@ +@use "scss/variables"; +@use "scss/colors"; + +.text { + color: colors.$grey; + + &.enabled { + color: colors.$dark-blue; + } +} diff --git a/airbyte-webapp/src/components/EntityTable/components/LastSyncCell.tsx b/airbyte-webapp/src/components/EntityTable/components/LastSyncCell.tsx index 1bb2f5c26713a..3dac28390a86a 100644 --- a/airbyte-webapp/src/components/EntityTable/components/LastSyncCell.tsx +++ b/airbyte-webapp/src/components/EntityTable/components/LastSyncCell.tsx @@ -1,26 +1,24 @@ +import classNames from "classnames"; import React from "react"; import { FormattedRelativeTime } from "react-intl"; -import styled from "styled-components"; -const Content = styled.div<{ enabled?: boolean }>` - color: ${({ theme, enabled }) => (!enabled ? theme.greyColor40 : "inherit")}; -`; +import { Text } from "components/ui/Text"; -interface IProps { +import styles from "./LastSyncCell.module.scss"; + +interface LastSyncCellProps { timeInSecond: number; enabled?: boolean; } -const LastSyncCell: React.FC = ({ timeInSecond, enabled }) => { - if (!timeInSecond) { - return null; - } - +export const LastSyncCell: React.FC = ({ timeInSecond, enabled }) => { return ( - - - + <> + {timeInSecond ? ( + + + + ) : null} + ); }; - -export default LastSyncCell; diff --git a/airbyte-webapp/src/components/ui/Table/Table.module.scss b/airbyte-webapp/src/components/ui/Table/Table.module.scss new file mode 100644 index 0000000000000..297f790bf6177 --- /dev/null +++ b/airbyte-webapp/src/components/ui/Table/Table.module.scss @@ -0,0 +1,95 @@ +@use "scss/variables"; +@use "scss/colors"; + +.tableView { + border-spacing: 0; + width: 100%; + max-width: 100%; + border-radius: variables.$border-radius-lg; + box-shadow: 0 2px 4px rgb(26 25 77 / 12%); + + .light { + box-shadow: none; + } +} + +.tableHeader { + padding: variables.$spacing-md variables.$spacing-lg; + background-color: colors.$dark-blue; + text-align: left; + font-size: 10px; + border-bottom: none; + font-weight: 600; + text-transform: uppercase; + color: colors.$grey-300; + + &:first-child { + padding-left: variables.$spacing-2xl; + border-radius: variables.$border-radius-lg 0 0; + } + + &:last-child { + padding-left: variables.$spacing-lg; + border-radius: 0 variables.$border-radius-lg 0 0; + } + + &.highlighted { + color: colors.$white; + } + + &.light { + background: none; + font-size: 11px; + font-weight: 400; + text-transform: capitalize; + + &:first-child { + padding-left: variables.$spacing-lg; + } + } +} + +.tableData { + padding: variables.$spacing-lg; + font-size: 12px; + font-weight: normal; + color: colors.$dark-blue; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: none; + border-bottom: variables.$border-thin solid colors.$grey-100; + + &.responsive { + max-width: 0; + } +} + +.tableRow { + cursor: auto; + background-color: colors.$white; + + &.hasClick { + cursor: pointer; + } + + &.erroredRows { + background-color: colors.$red-50; + } + + &:hover { + background-color: colors.$grey-50; + } + + &:last-child > .tableData { + border-bottom: none; + + &:first-child { + border-radius: 0 0 0 variables.$border-radius-lg; + } + + &:last-child { + border-radius: 0 0 variables.$border-radius-lg 0; + } + } +} diff --git a/airbyte-webapp/src/components/ui/Table/Table.tsx b/airbyte-webapp/src/components/ui/Table/Table.tsx index 7300b9964ed8c..e7fa60665aa89 100644 --- a/airbyte-webapp/src/components/ui/Table/Table.tsx +++ b/airbyte-webapp/src/components/ui/Table/Table.tsx @@ -1,105 +1,20 @@ +import classNames from "classnames"; import React, { memo, useMemo } from "react"; import { Cell, Column, ColumnInstance, SortingRule, useSortBy, useTable } from "react-table"; -import styled from "styled-components"; -import { Card } from "../Card"; - -interface PaddingProps { - left?: number; - right?: number; -} +import styles from "./Table.module.scss"; interface HeaderProps extends ColumnInstance> { headerHighlighted?: boolean; collapse?: boolean; customWidth?: number; - customPadding?: PaddingProps; + responsive?: boolean; } interface CellProps extends Cell { column: HeaderProps; } -interface TableHeaderProps extends React.ThHTMLAttributes { - highlighted?: boolean; - collapse?: boolean; - customWidth?: number; - customPadding?: PaddingProps; - light?: boolean; -} - -const TableView = styled(Card).attrs({ as: "table" })<{ light?: boolean }>` - border-spacing: 0; - width: 100%; - max-width: 100%; - border-radius: 10px; - box-shadow: ${({ light, theme }) => (light ? "none" : `0 2px 4px ${theme.cardShadowColor}`)}; -}; -`; - -const Tr = styled.tr<{ - hasClick?: boolean; - erroredRows?: boolean; -}>` - background: ${({ theme, erroredRows }) => (erroredRows ? theme.dangerTransparentColor : theme.whiteColor)}; - cursor: ${({ hasClick }) => (hasClick ? "pointer" : "auto")}; - &:hover { - background-color: ${({ theme }) => `${theme.grey50}`}; - } -`; - -const Td = styled.td<{ - collapse?: boolean; - customWidth?: number; - customPadding?: PaddingProps; -}>` - padding: ${({ customPadding }) => `16px ${customPadding?.right ?? 13}px 16px ${customPadding?.left ?? 13}px`}; - font-size: 12px; - line-height: 15px; - font-weight: normal; - color: ${({ theme }) => theme.darkPrimaryColor}; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - border-bottom: 1px solid ${({ theme }) => theme.greyColor20}; - width: ${({ collapse, customWidth }) => (customWidth ? `${customWidth}%` : collapse ? "0.0000000001%" : "auto")}; - - tr:last-child > & { - border-bottom: none; - - &:first-child { - border-radius: 0 0 0 10px; - } - - &:last-child { - border-radius: 0 0 10px 0; - } - } -`; - -const Th = styled.th` - background: ${({ theme, light }) => (light ? "none" : theme.textColor)}; - padding: ${({ customPadding }) => `9px ${customPadding?.right ?? 13}px 10px ${customPadding?.left ?? 13}px`}; - text-align: left; - font-size: ${({ light }) => (light ? 11 : 10)}px; - line-height: 12px; - color: ${({ theme, highlighted }) => (highlighted ? theme.whiteColor : theme.lightTextColor)}; - border-bottom: none; - width: ${({ collapse, customWidth }) => (customWidth ? `${customWidth}%` : collapse ? "0.0000000001%" : "auto")}; - font-weight: ${({ light }) => (light ? 400 : 600)}; - text-transform: ${({ light }) => (light ? "capitalize" : "uppercase")}; - - &:first-child { - padding-left: ${({ light }) => (light ? 13 : 45)}px; - border-radius: 10px 0 0; - } - - &:last-child { - padding-left: 15px; - border-radius: 0 10px 0 0; - } -`; - interface TableProps { light?: boolean; columns: Array>>; @@ -134,22 +49,28 @@ export const Table: React.FC = memo(({ columns, data, onClickRow, er ); return ( - + {headerGroups.map((headerGroup, key) => ( {headerGroup.headers.map((column: HeaderProps, columnKey) => ( - + ))} ))} @@ -158,30 +79,37 @@ export const Table: React.FC = memo(({ columns, data, onClickRow, er {rows.map((row) => { prepareRow(row); return ( - onClickRow?.(row.original)} - erroredRows={erroredRows && !!row.original.error} + key={`table-row-${row.id}`} > {row.cells.map((cell: CellProps, key) => { return ( - + ); })} - + ); })} - +
{column.render("Header")} -
{cell.render("Cell")} -
); }); diff --git a/airbyte-webapp/src/components/ui/Text/Text.tsx b/airbyte-webapp/src/components/ui/Text/Text.tsx index 763356fcdf28d..ed259b8acf0b0 100644 --- a/airbyte-webapp/src/components/ui/Text/Text.tsx +++ b/airbyte-webapp/src/components/ui/Text/Text.tsx @@ -13,6 +13,7 @@ interface TextProps { size?: TextSize; bold?: boolean; inverseColor?: boolean; + title?: string; } const getTextClassNames = ({