-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🪟 🎉 Improved rendering of variable input fields in source/destination…
… and update custom transformations form. (#14514) * Show field names instead of index in ArraySection items * Update ArraySection to show description * Update EditorRow to show description as tooltip * Update ArrayOfObjectsEditor with render name and description props, fix base item interface * Update ToolTip so that cursor only changes if specified, make inline * Update form types from type to interface * Update EditorRow style to match new design * Update Add/Edit mode in ArrayOfObjectsEditor to use Modal * Add bottom margin to content card title to ensure drop shadow does not overlap bottom content * Cleanup spacing in Modal scss * Add width and height settings to ArrayOfObjectEditor Ensure that Transformation field edit modal and ArraySection edit modal have the right width and height * Move buttons outside of ArrayOfObjects editor and let TransformationField and ArraySection handle it * Move DBT command reference docs to links config * Move ArrayOfObjectsEditor to css module * Split variable input fields form into component, make editable via hidden field * Removed unfinished flow usage from ArraySection * Add button type to EditorRow buttons to prevent Formik warning * Fix path prop in ArraySection to not include "hidden" * Add validation to VariableInputFieldForm * Move default field from FromGroup to FormItemBase * Add Form validationSchema to Service Form Context * Update path in ArraySection to use correct path * Update VariableInputFieldForm to use form validatonSchema to determine if the data is valid or not * Add default values to VariableInputFieldForm item * Move EditorRow styles to scss and fix wrappig on small width * Add styles for tooltip in ArraySection * Update ArrayOfObjectsEditor component to match design * Update edit and close button icons * Fix spacing * Show item count * Show add / edit string on modal depending on mode * Update 0 items to No items in en file * Fix serviceForm 'should fill right values in array of objects field' test * Add testId field to Modal * Add testId to ArrayOfObjectsEditor modal * Cleanup test * Fix 'should fill all fields by right values' in serviceForm tests * Update addPriceListItem to a utility * Only use document.body for modal query * Cleanup mocks in serviceForm test * Update naming in DocumentationPanelContext * Fix stylings in EditorRow and ContentCard * Update EditorRow to always show a border between items regardless of having a description or not * Update VariableInputField field name such that it can be removed from formik values when done or cancelled * Update temp field name in variable input fields form and explain the reasons for it * Update ArrayOfObjectEditor to render form as prop instead of children Co-authored-by: Tim Roes <tim@airbyte.io>
- Loading branch information
Showing
22 changed files
with
535 additions
and
312 deletions.
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
airbyte-webapp/src/components/ArrayOfObjectsEditor/ArrayOfObjectsEditor.module.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
@use "../../scss/colors"; | ||
@use "../../scss/variables"; | ||
|
||
.container { | ||
margin-bottom: variables.$spacing-xl; | ||
} | ||
|
||
.list { | ||
background-color: colors.$grey-50; | ||
border-radius: 4px; | ||
} |
126 changes: 54 additions & 72 deletions
126
airbyte-webapp/src/components/ArrayOfObjectsEditor/ArrayOfObjectsEditor.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,111 +1,93 @@ | ||
import React from "react"; | ||
import { FormattedMessage } from "react-intl"; | ||
import styled from "styled-components"; | ||
|
||
import { Button } from "components"; | ||
import Modal, { ModalProps } from "components/Modal"; | ||
|
||
import { ConnectionFormMode } from "views/Connection/ConnectionForm/ConnectionForm"; | ||
|
||
import styles from "./ArrayOfObjectsEditor.module.scss"; | ||
import { EditorHeader } from "./components/EditorHeader"; | ||
import { EditorRow } from "./components/EditorRow"; | ||
|
||
const ItemsList = styled.div` | ||
background: ${({ theme }) => theme.greyColor0}; | ||
border-radius: 4px; | ||
`; | ||
|
||
const ButtonContainer = styled.div` | ||
display: flex; | ||
justify-content: flex-end; | ||
`; | ||
|
||
const SmallButton = styled(Button)` | ||
margin-left: 8px; | ||
padding: 6px 8px 7px; | ||
`; | ||
|
||
const Content = styled.div` | ||
margin-bottom: 20px; | ||
`; | ||
interface ItemBase { | ||
name?: string; | ||
description?: string; | ||
} | ||
|
||
export interface ArrayOfObjectsEditorProps<T extends { name: string }> { | ||
export interface ArrayOfObjectsEditorProps<T extends ItemBase> { | ||
items: T[]; | ||
editableItemIndex?: number | string | null; | ||
children: (item?: T) => React.ReactNode; | ||
mainTitle?: React.ReactNode; | ||
addButtonText?: React.ReactNode; | ||
renderItemName?: (item: T, index: number) => React.ReactNode | undefined; | ||
renderItemDescription?: (item: T, index: number) => React.ReactNode | undefined; | ||
renderItemEditorForm: (item?: T) => React.ReactNode; | ||
onStartEdit: (n: number) => void; | ||
onCancelEdit?: () => void; | ||
onDone?: () => void; | ||
onRemove: (index: number) => void; | ||
mode?: ConnectionFormMode; | ||
disabled?: boolean; | ||
editModalSize?: ModalProps["size"]; | ||
} | ||
|
||
export const ArrayOfObjectsEditor = <T extends { name: string } = { name: string }>({ | ||
export const ArrayOfObjectsEditor = <T extends ItemBase = ItemBase>({ | ||
onStartEdit, | ||
onDone, | ||
onRemove, | ||
onCancelEdit, | ||
renderItemName = (item) => item.name, | ||
renderItemDescription = (item) => item.description, | ||
renderItemEditorForm, | ||
items, | ||
editableItemIndex, | ||
children, | ||
mainTitle, | ||
addButtonText, | ||
mode, | ||
disabled, | ||
editModalSize, | ||
}: ArrayOfObjectsEditorProps<T>): JSX.Element => { | ||
const onAddItem = React.useCallback(() => onStartEdit(items.length), [onStartEdit, items]); | ||
|
||
const isEditable = editableItemIndex !== null && editableItemIndex !== undefined; | ||
|
||
if (mode !== "readonly" && isEditable) { | ||
const renderEditModal = () => { | ||
const item = typeof editableItemIndex === "number" ? items[editableItemIndex] : undefined; | ||
|
||
return ( | ||
<Content> | ||
{children(item)} | ||
{onCancelEdit || onDone ? ( | ||
<ButtonContainer> | ||
{onCancelEdit && ( | ||
<SmallButton onClick={onCancelEdit} type="button" secondary disabled={disabled}> | ||
<FormattedMessage id="form.cancel" /> | ||
</SmallButton> | ||
)} | ||
{onDone && ( | ||
<SmallButton onClick={onDone} type="button" data-testid="done-button" disabled={disabled}> | ||
<FormattedMessage id="form.done" /> | ||
</SmallButton> | ||
)} | ||
</ButtonContainer> | ||
) : null} | ||
</Content> | ||
<Modal | ||
title={<FormattedMessage id={item ? "form.edit" : "form.add"} />} | ||
size={editModalSize} | ||
testId="arrayOfObjects-editModal" | ||
> | ||
{renderItemEditorForm(item)} | ||
</Modal> | ||
); | ||
} | ||
}; | ||
|
||
return ( | ||
<Content> | ||
<EditorHeader | ||
itemsCount={items.length} | ||
onAddItem={onAddItem} | ||
mainTitle={mainTitle} | ||
addButtonText={addButtonText} | ||
mode={mode} | ||
disabled={disabled} | ||
/> | ||
{items.length ? ( | ||
<ItemsList> | ||
{items.map((item, key) => ( | ||
<EditorRow | ||
key={`form-item-${key}`} | ||
name={item.name} | ||
id={key} | ||
onEdit={onStartEdit} | ||
onRemove={onRemove} | ||
disabled={disabled} | ||
/> | ||
))} | ||
</ItemsList> | ||
) : null} | ||
</Content> | ||
<> | ||
<div className={styles.container}> | ||
<EditorHeader | ||
itemsCount={items.length} | ||
onAddItem={onAddItem} | ||
mainTitle={mainTitle} | ||
addButtonText={addButtonText} | ||
mode={mode} | ||
disabled={disabled} | ||
/> | ||
{items.length ? ( | ||
<div className={styles.list}> | ||
{items.map((item, index) => ( | ||
<EditorRow | ||
key={`form-item-${index}`} | ||
name={renderItemName(item, index)} | ||
description={renderItemDescription(item, index)} | ||
id={index} | ||
onEdit={onStartEdit} | ||
onRemove={onRemove} | ||
disabled={disabled} | ||
/> | ||
))} | ||
</div> | ||
) : null} | ||
</div> | ||
{mode !== "readonly" && isEditable && renderEditModal()} | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
airbyte-webapp/src/components/ArrayOfObjectsEditor/components/EditorRow.module.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
@use "../../../scss/colors"; | ||
@use "../../../scss/variables"; | ||
|
||
.container + .container { | ||
border-top: 1px solid colors.$white; | ||
} | ||
|
||
.body { | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
flex-direction: row; | ||
color: colors.$dark-blue; | ||
font-weight: 400; | ||
font-size: 12px; | ||
line-height: 17px; | ||
padding: variables.$spacing-md 8px; | ||
gap: variables.$spacing-md; | ||
} | ||
|
||
.name { | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
white-space: nowrap; | ||
} | ||
|
||
.actions { | ||
display: flex; | ||
flex-direction: row; | ||
flex-wrap: nowrap; | ||
gap: variables.$spacing-md; | ||
} |
71 changes: 32 additions & 39 deletions
71
airbyte-webapp/src/components/ArrayOfObjectsEditor/components/EditorRow.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,50 @@ | ||
import { faTimes } from "@fortawesome/free-solid-svg-icons"; | ||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||
import React from "react"; | ||
import { FormattedMessage, useIntl } from "react-intl"; | ||
import styled from "styled-components"; | ||
import { useIntl } from "react-intl"; | ||
|
||
import { Button } from "components"; | ||
import { CrossIcon } from "components/icons/CrossIcon"; | ||
import { PencilIcon } from "components/icons/PencilIcon"; | ||
import ToolTip from "components/ToolTip"; | ||
|
||
const Content = styled.div` | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
flex-direction: row; | ||
color: ${({ theme }) => theme.textColor}; | ||
font-weight: 500; | ||
font-size: 14px; | ||
line-height: 17px; | ||
padding: 5px 12px 6px 14px; | ||
border-bottom: 1px solid ${({ theme }) => theme.greyColor20}; | ||
&:last-child { | ||
border: none; | ||
} | ||
`; | ||
|
||
const DeleteButton = styled(Button)` | ||
margin-left: 7px; | ||
`; | ||
import styles from "./EditorRow.module.scss"; | ||
|
||
interface EditorRowProps { | ||
name: string; | ||
name?: React.ReactNode; | ||
description?: React.ReactNode; | ||
id: number; | ||
onEdit: (id: number) => void; | ||
onRemove: (id: number) => void; | ||
disabled?: boolean; | ||
} | ||
|
||
const EditorRow: React.FC<EditorRowProps> = ({ name, id, onEdit, onRemove, disabled }) => { | ||
export const EditorRow: React.FC<EditorRowProps> = ({ name, id, description, onEdit, onRemove, disabled }) => { | ||
const { formatMessage } = useIntl(); | ||
const buttonLabel = formatMessage({ id: "form.delete" }); | ||
|
||
return ( | ||
<Content> | ||
<div>{name || id}</div> | ||
<div> | ||
<Button secondary onClick={() => onEdit(id)} type="button" disabled={disabled}> | ||
<FormattedMessage id="form.edit" /> | ||
const body = ( | ||
<div className={styles.body}> | ||
<div className={styles.name}>{name || id}</div> | ||
<div className={styles.actions}> | ||
<Button | ||
type="button" | ||
iconOnly | ||
arial-label={formatMessage({ id: "form.edit" })} | ||
onClick={() => onEdit(id)} | ||
disabled={disabled} | ||
> | ||
<PencilIcon /> | ||
</Button> | ||
<Button | ||
type="button" | ||
iconOnly | ||
aria-label={formatMessage({ id: "form.delete" })} | ||
onClick={() => onRemove(id)} | ||
disabled={disabled} | ||
> | ||
<CrossIcon /> | ||
</Button> | ||
<DeleteButton iconOnly onClick={() => onRemove(id)} disabled={disabled} aria-label={buttonLabel}> | ||
<FontAwesomeIcon icon={faTimes} /> | ||
</DeleteButton> | ||
</div> | ||
</Content> | ||
</div> | ||
); | ||
}; | ||
|
||
export { EditorRow }; | ||
return <div className={styles.container}>{description ? <ToolTip control={body}>{description}</ToolTip> : body}</div>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
import Modal from "./Modal"; | ||
|
||
export * from "./Modal"; | ||
export * from "./ModalBody"; | ||
export * from "./ModalFooter"; | ||
|
||
export default Modal; | ||
export { Modal }; | ||
export default Modal; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
interface CrossIconProps { | ||
color?: string; | ||
} | ||
|
||
export const CrossIcon = ({ color = "currentColor" }: CrossIconProps) => ( | ||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none"> | ||
<path | ||
d="M9.20495 0.71967C8.91206 0.426777 8.43718 0.426777 8.14429 0.71967L4.96234 3.90162L1.7804 0.719679C1.48751 0.426786 1.01263 0.426786 0.71974 0.719679C0.426847 1.01257 0.426847 1.48745 0.71974 1.78034L3.90168 4.96228L0.71967 8.14429C0.426777 8.43718 0.426777 8.91206 0.71967 9.20495C1.01256 9.49784 1.48744 9.49784 1.78033 9.20495L4.96234 6.02294L8.14436 9.20496C8.43725 9.49785 8.91213 9.49785 9.20502 9.20496C9.49791 8.91207 9.49791 8.43719 9.20502 8.1443L6.023 4.96228L9.20495 1.78033C9.49784 1.48744 9.49784 1.01256 9.20495 0.71967Z" | ||
fill={color} | ||
/> | ||
</svg> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
interface PencilIconProps { | ||
color?: string; | ||
} | ||
|
||
export const PencilIcon = ({ color = "currentColor" }: PencilIconProps) => ( | ||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"> | ||
<path | ||
d="M7.675 3.14356L10.8565 6.32581L3.4315 13.7501H0.25V10.5678L7.675 3.14281V3.14356ZM8.7355 2.08306L10.3262 0.491563C10.4669 0.350959 10.6576 0.271973 10.8565 0.271973C11.0554 0.271973 11.2461 0.350959 11.3868 0.491563L13.5085 2.61331C13.6491 2.75396 13.7281 2.94469 13.7281 3.14356C13.7281 3.34244 13.6491 3.53317 13.5085 3.67381L11.917 5.26456L8.7355 2.08306Z" | ||
fill={color} | ||
/> | ||
</svg> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.