From f1007c64fcf445d48d295773684e14127feb7c22 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 26 Sep 2019 14:10:46 -0700 Subject: [PATCH] Update EditableText component (#299) * Fix some styling issues with react-markdown * Update EditableText to use React Refs instead of ref callbacks * Add configs for table and column description max lengths --- .../DetailList/DetailListItem/index.tsx | 5 +- .../DetailList/DetailListItem/styles.scss | 5 +- .../js/components/TableDetail/index.tsx | 1 + .../components/common/EditableText/index.tsx | 91 +++++++++---------- .../common/EditableText/styles.scss | 6 ++ .../static/js/config/config-default.ts | 10 +- .../static/js/config/config-types.ts | 25 ++++- 7 files changed, 82 insertions(+), 61 deletions(-) diff --git a/frontend/amundsen_application/static/js/components/TableDetail/DetailList/DetailListItem/index.tsx b/frontend/amundsen_application/static/js/components/TableDetail/DetailList/DetailListItem/index.tsx index 65b6717182..d18732d5ce 100644 --- a/frontend/amundsen_application/static/js/components/TableDetail/DetailList/DetailListItem/index.tsx +++ b/frontend/amundsen_application/static/js/components/TableDetail/DetailList/DetailListItem/index.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; -import moment from 'moment-timezone'; - import { OverlayTrigger, Popover } from 'react-bootstrap'; +import moment from 'moment-timezone'; +import AppConfig from 'config/config'; import ColumnDescEditableText from 'components/TableDetail/ColumnDescEditableText'; import { logClick } from 'ducks/utilMethods'; import { TableColumn } from 'interfaces'; @@ -132,6 +132,7 @@ class DetailListItem extends React.Component { diff --git a/frontend/amundsen_application/static/js/components/TableDetail/DetailList/DetailListItem/styles.scss b/frontend/amundsen_application/static/js/components/TableDetail/DetailList/DetailListItem/styles.scss index 2c618aa75f..5c131e7563 100644 --- a/frontend/amundsen_application/static/js/components/TableDetail/DetailList/DetailListItem/styles.scss +++ b/frontend/amundsen_application/static/js/components/TableDetail/DetailList/DetailListItem/styles.scss @@ -17,9 +17,8 @@ padding-right: 32px; } - // TODO - move to common styles - .truncated, - .truncated .editable-text { + .truncated .editable-text, + .truncated .editable-text p { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; diff --git a/frontend/amundsen_application/static/js/components/TableDetail/index.tsx b/frontend/amundsen_application/static/js/components/TableDetail/index.tsx index 98301c112f..db2f02bc45 100644 --- a/frontend/amundsen_application/static/js/components/TableDetail/index.tsx +++ b/frontend/amundsen_application/static/js/components/TableDetail/index.tsx @@ -356,6 +356,7 @@ export class TableDetail extends React.Component
diff --git a/frontend/amundsen_application/static/js/components/common/EditableText/index.tsx b/frontend/amundsen_application/static/js/components/common/EditableText/index.tsx index ac3d3e058e..45114f5cc6 100644 --- a/frontend/amundsen_application/static/js/components/common/EditableText/index.tsx +++ b/frontend/amundsen_application/static/js/components/common/EditableText/index.tsx @@ -1,11 +1,9 @@ +import autosize from 'autosize'; import * as React from 'react'; -import ReactDOM from 'react-dom'; +import { Overlay, Tooltip } from 'react-bootstrap'; import * as ReactMarkdown from 'react-markdown'; -import { Overlay, Popover, Tooltip } from 'react-bootstrap'; -import autosize from 'autosize'; // TODO: Use css-modules instead of 'import' -// TODO: Outdated approach (lines 148, 168). Replace with React.createRef(). See more at https://reactjs.org/docs/refs-and-the-dom.html import './styles.scss'; export interface StateFromProps { @@ -34,12 +32,12 @@ interface EditableTextState { } class EditableText extends React.Component { - private textAreaTarget: HTMLTextAreaElement; - private editAnchorTarget: HTMLAnchorElement; + private textAreaRef; + private editAnchorRef; public static defaultProps: EditableTextProps = { editable: true, - maxLength: 4000, + maxLength: 250, onSubmitValue: null, getLatestValue: null, value: '', @@ -52,6 +50,9 @@ class EditableText extends React.Component constructor(props) { super(props); + this.textAreaRef = React.createRef(); + this.editAnchorRef = React.createRef(); + this.state = { editable: props.editable, inEditMode: false, @@ -63,19 +64,16 @@ class EditableText extends React.Component componentDidUpdate() { const { isDisabled, inEditMode, refreshValue, value } = this.state; - if (inEditMode) { - autosize(this.textAreaTarget); - if (refreshValue && refreshValue !== value && !isDisabled) { - // disable the component if a refresh is needed - this.setState({ isDisabled: true }) - } - else { - // when entering edit mode, place focus in the textarea - const textArea = ReactDOM.findDOMNode(this.textAreaTarget); - if (textArea) { - textArea.focus(); - } - } + const textArea = this.textAreaRef.current; + if (!inEditMode) return; + + autosize(textArea); + if (refreshValue && refreshValue !== value && !isDisabled) { + // disable the component if a refresh is needed + this.setState({ isDisabled: true }) + } else if (textArea) { + // when entering edit mode, place focus in the textarea + textArea.focus(); } } @@ -97,28 +95,27 @@ class EditableText extends React.Component }; updateText = () => { - const newValue = ReactDOM.findDOMNode(this.textAreaTarget).value; + const newValue = this.textAreaRef.current.value; const onSuccessCallback = () => { this.setState({value: newValue, inEditMode: false, refreshValue: undefined }); }; const onFailureCallback = () => { this.exitEditMode(); }; this.props.onSubmitValue(newValue, onSuccessCallback, onFailureCallback); }; - getTarget(type) { - if (type === 'editAnchor') { - return ReactDOM.findDOMNode(this.editAnchorTarget); - } - if (type === 'textArea') { - return ReactDOM.findDOMNode(this.textAreaTarget) - } - } + getAnchorTarget = () => { + return this.editAnchorRef.current; + }; + + getTextAreaTarget = () => { + return this.textAreaRef.current; + }; render() { if (!this.state.editable) { return (
- +
); @@ -128,26 +125,24 @@ class EditableText extends React.Component
This text is out of date, please refresh the component -
-
- +
+ { - this.editAnchorTarget = anchor; - }} + ref={ this.editAnchorRef } > { this.state.value ? "edit" : "Add Description" @@ -163,21 +158,17 @@ class EditableText extends React.Component - + rows={ 2 } + maxLength={ this.props.maxLength } + ref={ this.textAreaRef } + defaultValue={ this.state.value } + /> - + diff --git a/frontend/amundsen_application/static/js/components/common/EditableText/styles.scss b/frontend/amundsen_application/static/js/components/common/EditableText/styles.scss index 9b88a02f85..83ffaf1ccc 100644 --- a/frontend/amundsen_application/static/js/components/common/EditableText/styles.scss +++ b/frontend/amundsen_application/static/js/components/common/EditableText/styles.scss @@ -25,6 +25,12 @@ .editable-text { flex-grow: 0.1; word-break: break-word; + + // React-Markdown wraps editable text with a paragraph + > p { + margin: 0; + display: inline; + } } .editable-textarea { diff --git a/frontend/amundsen_application/static/js/config/config-default.ts b/frontend/amundsen_application/static/js/config/config-default.ts index dbe3e0ec90..b424f7dbb3 100644 --- a/frontend/amundsen_application/static/js/config/config-default.ts +++ b/frontend/amundsen_application/static/js/config/config-default.ts @@ -5,11 +5,18 @@ const configDefault: AppConfig = { curatedTags: [], showAllTags: true, }, + editableText: { + tableDescLength: 750, + columnDescLength: 250, + }, google: { enabled: false, key: 'default-key', sampleRate: 100, }, + indexUsers: { + enabled: false, + }, logoPath: null, navLinks: [ { @@ -40,9 +47,6 @@ const configDefault: AppConfig = { return `https://DEFAULT_EXPLORE_URL?schema=${schema}&cluster=${cluster}&db=${database}&table=${table}`; } }, - indexUsers: { - enabled: false, - } }; export default configDefault; diff --git a/frontend/amundsen_application/static/js/config/config-types.ts b/frontend/amundsen_application/static/js/config/config-types.ts index 8d47b47731..64ae11bb83 100644 --- a/frontend/amundsen_application/static/js/config/config-types.ts +++ b/frontend/amundsen_application/static/js/config/config-types.ts @@ -6,22 +6,24 @@ export interface AppConfig { browse: BrowseConfig; + editableText: EditableTextConfig; google: GoogleAnalyticsConfig; + indexUsers: IndexUsersConfig; logoPath: string | null; navLinks: Array; tableLineage: TableLineageConfig; tableProfile: TableProfileConfig; - indexUsers: indexUsersConfig; } export interface AppConfigCustom { browse?: BrowseConfig; + editableText?: EditableTextConfig; google?: GoogleAnalyticsConfig + indexUsers?: IndexUsersConfig; logoPath?: string; navLinks?: Array; tableLineage?: TableLineageConfig; tableProfile?: TableProfileConfig; - indexUsers?: indexUsersConfig; } /** @@ -83,6 +85,23 @@ export interface LinkConfig { use_router: boolean; } -interface indexUsersConfig { +/** + * IndexUsersConfig - When enabled, the IndexUsers feature will index users as searchable resources. This requires + * user objects are ingested via Databuilder + * + * enabled - Enables/disables this feature in the frontend only + */ +interface IndexUsersConfig { enabled: boolean; } + +/** + * EditableTextConfig - Configure max length limits for editable fields + * + * tableDescLength - maxlength for table descriptions + * columnDescLength - maxlength for column descriptions + */ +interface EditableTextConfig { + tableDescLength: number; + columnDescLength: number; +}