From f0d331c547f3d8f80e8153290b567874a4534051 Mon Sep 17 00:00:00 2001 From: Teal Larson Date: Wed, 16 Nov 2022 11:20:59 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=AA=9F=20=F0=9F=8E=A8=20Streams=20table?= =?UTF-8?q?=20design=20pass=20[with=20fix]=20(#19431)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revert "Revert "🪟 🎨 Streams table design pass (#18908)" (#19397)" This reverts commit ebbe5a9a18a59973531d81d3edaf62db734ed323. * remove min-width 0 that broke the table * Update airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableRow.module.scss Co-authored-by: Edmundo Ruiz Ghanem <168664+edmundito@users.noreply.github.com> * fix styling for master table with (padding) * fix alignment somewhat on master view * fix padding differences between old/new tables * fix icon alignment in new table rows * update snapshots Co-authored-by: Edmundo Ruiz Ghanem <168664+edmundito@users.noreply.github.com> --- .../CreateConnectionForm.test.tsx.snap | 3 + .../SimpleTableComponents.tsx | 4 +- .../CatalogTree/CatalogTreeHeader.tsx | 2 +- .../CatalogTree/CatalogTreeSearch.module.scss | 13 ++++ .../CatalogTree/CatalogTreeSearch.tsx | 10 ++- .../CatalogTreeSubheader.module.scss | 1 - .../CatalogTree/CatalogTreeSubheader.tsx | 1 + .../next/CatalogTreeTableHeader.module.scss | 29 +++++++ .../next/CatalogTreeTableHeader.tsx | 65 +++++++++------- .../next/CatalogTreeTableRow.module.scss | 34 ++++++++- .../CatalogTree/next/CatalogTreeTableRow.tsx | 75 +++++++++---------- .../next/StreamConnectionHeader.module.scss | 27 ++++++- .../next/StreamConnectionHeader.tsx | 25 ++++++- .../next/StreamPathSelect.module.scss | 5 ++ .../CatalogTree/next/StreamPathSelect.tsx | 11 ++- .../next/SyncModeSelect.module.scss | 5 +- .../ConnectionReplicationTab.test.tsx.snap | 3 + airbyte-webapp/src/scss/_variables.scss | 1 + .../ConnectionFormFields.module.scss | 5 ++ .../ConnectionForm/ConnectionFormFields.tsx | 4 +- .../ConnectionForm/components/Section.tsx | 29 ++++--- .../components/SyncCatalogField.module.scss | 5 +- 22 files changed, 260 insertions(+), 97 deletions(-) create mode 100644 airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableHeader.module.scss create mode 100644 airbyte-webapp/src/components/connection/CatalogTree/next/StreamPathSelect.module.scss diff --git a/airbyte-webapp/src/components/CreateConnection/__snapshots__/CreateConnectionForm.test.tsx.snap b/airbyte-webapp/src/components/CreateConnection/__snapshots__/CreateConnectionForm.test.tsx.snap index b27da6f756ffb..6d04f054f3c73 100644 --- a/airbyte-webapp/src/components/CreateConnection/__snapshots__/CreateConnectionForm.test.tsx.snap +++ b/airbyte-webapp/src/components/CreateConnection/__snapshots__/CreateConnectionForm.test.tsx.snap @@ -583,6 +583,9 @@ exports[`CreateConnectionForm should render 1`] = `
+
diff --git a/airbyte-webapp/src/components/SimpleTableComponents/SimpleTableComponents.tsx b/airbyte-webapp/src/components/SimpleTableComponents/SimpleTableComponents.tsx index 041c8fa5a51f4..5fa8ce63af098 100644 --- a/airbyte-webapp/src/components/SimpleTableComponents/SimpleTableComponents.tsx +++ b/airbyte-webapp/src/components/SimpleTableComponents/SimpleTableComponents.tsx @@ -27,9 +27,11 @@ export const Cell = styled.div<{ light?: boolean; lighter?: boolean; ellipsis?: boolean; + flush?: boolean; }>` flex: ${({ flex }) => flex || 1} 0 0; - padding-right: 10px; + padding-right: ${({ flush }) => (flush ? 0 : 10)}px; + word-break: break-word; color: ${({ theme, light, lighter }) => (light ? theme.greyColor40 : lighter ? theme.greyColor60 : "inherit")}; font-weight: ${({ light, lighter }) => (light || lighter ? "normal" : "inherit")}; diff --git a/airbyte-webapp/src/components/connection/CatalogTree/CatalogTreeHeader.tsx b/airbyte-webapp/src/components/connection/CatalogTree/CatalogTreeHeader.tsx index 7d2749c9629a2..fed12680406bb 100644 --- a/airbyte-webapp/src/components/connection/CatalogTree/CatalogTreeHeader.tsx +++ b/airbyte-webapp/src/components/connection/CatalogTree/CatalogTreeHeader.tsx @@ -31,7 +31,7 @@ export const CatalogTreeHeader: React.FC = () => { /> )} - {mode !== "readonly" && } + {mode !== "readonly" && } diff --git a/airbyte-webapp/src/components/connection/CatalogTree/CatalogTreeSearch.module.scss b/airbyte-webapp/src/components/connection/CatalogTree/CatalogTreeSearch.module.scss index 769dd3277747d..115404633f4a6 100644 --- a/airbyte-webapp/src/components/connection/CatalogTree/CatalogTreeSearch.module.scss +++ b/airbyte-webapp/src/components/connection/CatalogTree/CatalogTreeSearch.module.scss @@ -1,3 +1,5 @@ +@use "scss/_variables"; + .searchInput { padding: 10px 8px 9px; } @@ -5,6 +7,17 @@ .searchContent { position: relative; width: 100%; + padding-left: variables.$spacing-xl; + + &::before { + content: attr(data-content); + } +} + +.searchContentNew { + position: relative; + width: 100%; + padding: 0 variables.$spacing-xl; &::before { content: attr(data-content); diff --git a/airbyte-webapp/src/components/connection/CatalogTree/CatalogTreeSearch.tsx b/airbyte-webapp/src/components/connection/CatalogTree/CatalogTreeSearch.tsx index 2c416ac94a9cf..05759fa614212 100644 --- a/airbyte-webapp/src/components/connection/CatalogTree/CatalogTreeSearch.tsx +++ b/airbyte-webapp/src/components/connection/CatalogTree/CatalogTreeSearch.tsx @@ -1,3 +1,4 @@ +import classnames from "classnames"; import React from "react"; import { useIntl } from "react-intl"; @@ -10,10 +11,17 @@ interface CatalogTreeSearchProps { } export const CatalogTreeSearch: React.FC = ({ onSearch }) => { + const isNewStreamsTableEnabled = process.env.REACT_APP_NEW_STREAMS_TABLE ?? false; + const { formatMessage } = useIntl(); + const searchStyles = classnames({ + [styles.searchContentNew]: isNewStreamsTableEnabled, + [styles.searchContent]: !isNewStreamsTableEnabled, + }); + return ( -
+
{ return (
+ diff --git a/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableHeader.module.scss b/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableHeader.module.scss new file mode 100644 index 0000000000000..df3831de37070 --- /dev/null +++ b/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableHeader.module.scss @@ -0,0 +1,29 @@ +@use "scss/_colors"; +@use "scss/_variables"; + +.cellText { + color: colors.$grey; +} + +.headerContainer { + margin: variables.$spacing-md variables.$spacing-md variables.$spacing-sm variables.$spacing-md; + gap: variables.$spacing-sm; + overflow: hidden; + scrollbar-gutter: stable; + min-height: 33px; +} + +.checkboxCell { + margin-right: variables.$spacing-sm; + max-width: 43px; + font-size: 10px; + line-height: 13px; + display: flex; + flex-direction: row; + justify-content: flex-end; + padding-left: calc(#{variables.$spacing-xl} + #{variables.$spacing-sm}); +} + +.arrowPlaceholder { + width: 20px; +} diff --git a/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableHeader.tsx b/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableHeader.tsx index 2d3f11682aabf..9d7991df24fa0 100644 --- a/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableHeader.tsx +++ b/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableHeader.tsx @@ -1,20 +1,34 @@ +import React from "react"; import { FormattedMessage } from "react-intl"; import { Cell, Header } from "components/SimpleTableComponents"; import { CheckBox } from "components/ui/CheckBox"; +import { Text } from "components/ui/Text"; import { InfoTooltip, TooltipLearnMoreLink } from "components/ui/Tooltip"; import { useBulkEditService } from "hooks/services/BulkEdit/BulkEditService"; import { useConnectionFormService } from "hooks/services/ConnectionForm/ConnectionFormService"; import { links } from "utils/links"; +import styles from "./CatalogTreeTableHeader.module.scss"; + +const TextCell: React.FC> = ({ flex, children }) => { + return ( + + + {children} + + + ); +}; + export const CatalogTreeTableHeader: React.FC = () => { const { mode } = useConnectionFormService(); const { onCheckAll, selectedBatchNodeIds, allChecked } = useBulkEditService(); return ( -
- +
+
{mode !== "readonly" && ( { checked={allChecked} /> )} - - +
+ - - + + {/* - - + */} + - - + + - - + + - - + + - - + + - - - + +
+ - - + + - - - - - - - - +
); }; diff --git a/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableRow.module.scss b/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableRow.module.scss index 557907278af4a..787f8b34bb1b8 100644 --- a/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableRow.module.scss +++ b/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableRow.module.scss @@ -17,6 +17,14 @@ .streamHeaderContent { background: colors.$white; border-bottom: 1px solid colors.$grey-50; + padding: 0 variables.$spacing-md; + margin-bottom: 1px; + gap: variables.$spacing-sm; + min-height: 50px; + height: 50px; + align-items: center; + overflow-y: auto; + scrollbar-gutter: stable; &:hover { background: colors.$grey-30; @@ -38,11 +46,35 @@ &.selected { background-color: colors.$blue-transparent; } + + &.disabled { + background-color: colors.$grey-50; + } } .streamRowCheckboxCell { + margin-right: variables.$spacing-sm; + max-width: 43px; + text-align: center; + font-size: 10px; + line-height: 13px; display: flex; flex-direction: row; justify-content: flex-end; - padding-left: 27px; + padding-left: variables.$spacing-xl + variables.$spacing-sm; +} + +.arrowCell { + width: 20px; +} + +.cellText { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.syncModeCell { + width: variables.$width-wide-menu; + min-width: variables.$width-wide-menu; } diff --git a/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableRow.tsx b/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableRow.tsx index def9f02938b2f..16708cd441845 100644 --- a/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableRow.tsx +++ b/airbyte-webapp/src/components/connection/CatalogTree/next/CatalogTreeTableRow.tsx @@ -7,15 +7,14 @@ import { FormattedMessage } from "react-intl"; import { Cell, Row } from "components/SimpleTableComponents"; import { CheckBox } from "components/ui/CheckBox"; import { Switch } from "components/ui/Switch"; +import { Text } from "components/ui/Text"; import { useBulkEditSelect } from "hooks/services/BulkEdit/BulkEditService"; import { StreamHeaderProps } from "../StreamHeader"; -import { HeaderCell } from "../styles"; import styles from "./CatalogTreeTableRow.module.scss"; import { StreamPathSelect } from "./StreamPathSelect"; import { SyncModeSelect } from "./SyncModeSelect"; - export const CatalogTreeTableRow: React.FC = ({ stream, destName, @@ -35,7 +34,7 @@ export const CatalogTreeTableRow: React.FC = ({ hasError, disabled, }) => { - const { primaryKey, syncMode, cursorField, destinationSyncMode } = stream.config ?? {}; + const { primaryKey, cursorField, syncMode, destinationSyncMode } = stream.config ?? {}; const isStreamEnabled = stream.config?.selected; const { defaultCursorField } = stream.stream ?? {}; @@ -63,14 +62,13 @@ export const CatalogTreeTableRow: React.FC = ({ [styles.disabledChange]: changedSelected && !isStreamEnabled, [styles.selected]: isSelected, [styles.error]: hasError, + [styles.disabled]: !changedSelected && !isStreamEnabled, }); - const checkboxCellCustomStyle = classnames(styles.checkboxCell, styles.streamRowCheckboxCell); - return ( {!disabled && ( -
+
{changedSelected && (
{isStreamEnabled ? ( @@ -83,24 +81,33 @@ export const CatalogTreeTableRow: React.FC = ({
)} - + - {fieldCount} - - {stream.stream?.namespace || } - - {stream.stream?.name} - + {/* {fieldCount} */} + + + {stream.stream?.namespace || } + + + + + {stream.stream?.name} + + +
{disabled ? ( - - {syncSchema.syncMode} - + + + {syncSchema.syncMode} + + ) : ( + // todo: SyncModeSelect should probably have a Tooltip, append/dedupe ends up ellipsing )} - - +
+ {cursorType && ( = ({ onPathChange={onCursorChange} /> )} - - + + {pkType && ( = ({ onPathChange={onPrimaryKeyChange} /> )} - - - - - {destNamespace} - - - {destName} - - - {disabled ? ( - - {syncSchema.destinationSyncMode} - - ) : ( - // TODO: Replace with Dropdown/Popout - syncSchema.destinationSyncMode - )} + + + + {destNamespace} + + + + + {destName} + ); diff --git a/airbyte-webapp/src/components/connection/CatalogTree/next/StreamConnectionHeader.module.scss b/airbyte-webapp/src/components/connection/CatalogTree/next/StreamConnectionHeader.module.scss index c2a9085a9b8e3..03ae22c7a92ae 100644 --- a/airbyte-webapp/src/components/connection/CatalogTree/next/StreamConnectionHeader.module.scss +++ b/airbyte-webapp/src/components/connection/CatalogTree/next/StreamConnectionHeader.module.scss @@ -5,16 +5,37 @@ $icon-size: 15px; .container { display: flex; flex-direction: row; - justify-content: space-between; - padding: variables.$spacing-lg calc(variables.$spacing-lg * 2); + padding: variables.$spacing-xl variables.$spacing-lg * 2 0; + height: 43px; + align-items: center; + overflow: hidden; + scrollbar-gutter: stable; } .connector { display: flex; flex-direction: row; + flex: none; + align-self: stretch; + align-items: center; + gap: variables.$spacing-sm; +} + +.source { + flex: 7.3 0 0; + min-width: 0; +} + +.destination { + flex: 2 0 0; + min-width: 0; } .icon { - height: $icon-size; width: $icon-size; + height: $icon-size; +} + +.arrowContainer { + width: 20px; } diff --git a/airbyte-webapp/src/components/connection/CatalogTree/next/StreamConnectionHeader.tsx b/airbyte-webapp/src/components/connection/CatalogTree/next/StreamConnectionHeader.tsx index cb65e0ca8f92d..b19b924b7cc8b 100644 --- a/airbyte-webapp/src/components/connection/CatalogTree/next/StreamConnectionHeader.tsx +++ b/airbyte-webapp/src/components/connection/CatalogTree/next/StreamConnectionHeader.tsx @@ -1,5 +1,9 @@ import { faArrowRight } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import classnames from "classnames"; +import { FormattedMessage } from "react-intl"; + +import { Heading } from "components/ui/Heading"; import { useConnectionEditService } from "hooks/services/ConnectionEdit/ConnectionEditService"; import { useDestinationDefinition } from "services/connector/DestinationDefinitionService"; @@ -16,12 +20,25 @@ export const StreamConnectionHeader: React.FC = () => { } = useConnectionEditService(); const sourceDefinition = useSourceDefinition(source.sourceDefinitionId); const destinationDefinition = useDestinationDefinition(destination.destinationDefinitionId); - + const sourceStyles = classnames(styles.connector, styles.source); + const destinationStyles = classnames(styles.connector, styles.destination); return (
-
{renderIcon(sourceDefinition.icon)} Source
- -
{renderIcon(destinationDefinition.icon)} Destination
+
+ {renderIcon(sourceDefinition.icon)}{" "} + + + +
+
+ +
+
+ {renderIcon(destinationDefinition.icon)}{" "} + + + +
); }; diff --git a/airbyte-webapp/src/components/connection/CatalogTree/next/StreamPathSelect.module.scss b/airbyte-webapp/src/components/connection/CatalogTree/next/StreamPathSelect.module.scss new file mode 100644 index 0000000000000..95e4d17efdeeb --- /dev/null +++ b/airbyte-webapp/src/components/connection/CatalogTree/next/StreamPathSelect.module.scss @@ -0,0 +1,5 @@ +.text { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} diff --git a/airbyte-webapp/src/components/connection/CatalogTree/next/StreamPathSelect.tsx b/airbyte-webapp/src/components/connection/CatalogTree/next/StreamPathSelect.tsx index 1e35e3adae499..86c006c9e31f7 100644 --- a/airbyte-webapp/src/components/connection/CatalogTree/next/StreamPathSelect.tsx +++ b/airbyte-webapp/src/components/connection/CatalogTree/next/StreamPathSelect.tsx @@ -2,10 +2,13 @@ import React from "react"; import { FormattedMessage } from "react-intl"; import { PillSelect } from "components/ui/PillSelect"; +import { Text } from "components/ui/Text"; import { Tooltip } from "components/ui/Tooltip"; import { Path } from "core/domain/catalog"; +import styles from "./StreamPathSelect.module.scss"; + export const pathDisplayName = (path: Path): string => path.join("."); export type IndexerType = null | "required" | "sourceDefined"; @@ -36,9 +39,11 @@ export const StreamPathSelect: React.FC = (props) => { const text = props.isMulti ? props.path.map(pathDisplayName).join(", ") : pathDisplayName(props.path); return ( - - {text} - + + + {text} + + ); } diff --git a/airbyte-webapp/src/components/connection/CatalogTree/next/SyncModeSelect.module.scss b/airbyte-webapp/src/components/connection/CatalogTree/next/SyncModeSelect.module.scss index af40c11fd7676..cc50a51fd525a 100644 --- a/airbyte-webapp/src/components/connection/CatalogTree/next/SyncModeSelect.module.scss +++ b/airbyte-webapp/src/components/connection/CatalogTree/next/SyncModeSelect.module.scss @@ -1,3 +1,6 @@ +@use "scss/variables"; + .pillSelect { - width: 100%; + width: variables.$width-wide-menu; + justify-content: space-between; } diff --git a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/__snapshots__/ConnectionReplicationTab.test.tsx.snap b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/__snapshots__/ConnectionReplicationTab.test.tsx.snap index 2c78822b81e53..0c78eeae15ad2 100644 --- a/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/__snapshots__/ConnectionReplicationTab.test.tsx.snap +++ b/airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/__snapshots__/ConnectionReplicationTab.test.tsx.snap @@ -530,6 +530,9 @@ exports[`ConnectionReplicationTab should render 1`] = `
+
diff --git a/airbyte-webapp/src/scss/_variables.scss b/airbyte-webapp/src/scss/_variables.scss index 09703db063204..13d753a91050f 100644 --- a/airbyte-webapp/src/scss/_variables.scss +++ b/airbyte-webapp/src/scss/_variables.scss @@ -18,6 +18,7 @@ $spacing-page-bottom: 150px; $main-page-content-min-width: 960px; $width-size-menu: 93px; +$width-wide-menu: 200px; $width-modal-sm: 492px; $width-modal-md: 585px; diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionFormFields.module.scss b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionFormFields.module.scss index 98bdfdb34a7e0..dfd8ac1afa226 100644 --- a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionFormFields.module.scss +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionFormFields.module.scss @@ -42,3 +42,8 @@ // used to control svg size font-size: 14px; } + +.flush { + padding: 0; + gap: 0; +} diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionFormFields.tsx b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionFormFields.tsx index ed798f7a2fef6..93ec5148a4ba8 100644 --- a/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionFormFields.tsx +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionFormFields.tsx @@ -46,6 +46,8 @@ export const ConnectionFormFields: React.FC = ({ valu clearFormChange(formId); }); + const isNewStreamsTableEnabled = process.env.REACT_APP_NEW_STREAMS_TABLE ?? false; + return ( <> {/* FormChangeTracker is here as it has access to everything it needs without being repeated */} @@ -116,7 +118,7 @@ export const ConnectionFormFields: React.FC = ({ valu )} -
+
> = ({ title, children }) => ( - -
- {title && ( - - {title} - - )} - {children} -
-
-); +export const Section: React.FC> = ({ title, children, className }) => { + return ( + +
+ {title && ( + + {title} + + )} + {children} +
+
+ ); +}; diff --git a/airbyte-webapp/src/views/Connection/ConnectionForm/components/SyncCatalogField.module.scss b/airbyte-webapp/src/views/Connection/ConnectionForm/components/SyncCatalogField.module.scss index c9d8c72bec068..1f766a1cbbb05 100644 --- a/airbyte-webapp/src/views/Connection/ConnectionForm/components/SyncCatalogField.module.scss +++ b/airbyte-webapp/src/views/Connection/ConnectionForm/components/SyncCatalogField.module.scss @@ -1,5 +1,7 @@ +@use "scss/_variables"; + .header { - margin: 10px 0 6px; + margin: variables.$spacing-md 0 0; display: flex; justify-content: space-between; align-items: center; @@ -7,4 +9,5 @@ font-weight: 500; font-size: 14px; line-height: 17px; + padding: variables.$spacing-md variables.$spacing-xl; }