Polish Table Options (#11160)

* Clean up grid

* Polish threshold list

* Add empty state to table column options

* Improve appearance of custom time format

* Use clockface input within Draggable Column

* Use clockface input in table sidebar
pull/11185/head
alexpaxton 2019-01-16 15:33:34 -08:00 committed by GitHub
parent 2332f852e7
commit 6f2b3d9f25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 220 additions and 158 deletions

View File

@ -87,6 +87,7 @@
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*/ */
.form--box { .form--box {
width: 100%;
border-radius: $radius; border-radius: $radius;
background-color: $g4-onyx; background-color: $g4-onyx;
padding: $ix-marg-b 11px; padding: $ix-marg-b 11px;

View File

@ -2,7 +2,7 @@
import React, {SFC} from 'react' import React, {SFC} from 'react'
// Components // Components
import {Dropdown, ComponentStatus} from 'src/clockface' import {Dropdown, ComponentStatus, DropdownMenuColors} from 'src/clockface'
// Types // Types
import {ColorLabel} from 'src/types/colors' import {ColorLabel} from 'src/types/colors'
@ -29,6 +29,7 @@ const ColorDropdown: SFC<Props> = props => {
onChange={onChoose} onChange={onChoose}
status={status} status={status}
widthPixels={widthPixels} widthPixels={widthPixels}
menuColor={DropdownMenuColors.Onyx}
> >
{colors.map(color => ( {colors.map(color => (
<Dropdown.Item id={color.name} key={color.name} value={color}> <Dropdown.Item id={color.name} key={color.name} value={color}>

View File

@ -5,8 +5,6 @@
@import 'src/style/modules'; @import 'src/style/modules';
$time-machine--controls-height: 62px;
.time-machine { .time-machine {
height: 100%; height: 100%;
@include no-user-select(); @include no-user-select();
@ -38,22 +36,9 @@ $time-machine--controls-height: 62px;
flex: 0 0 100%; flex: 0 0 100%;
} }
.time-machine--controls {
height: $time-machine--controls-height;
width: 100%;
display: flex;
align-items: center;
padding: $ix-marg-c;
justify-content: space-between;
}
.time-machine--controls .slide-toggle {
margin-right: $ix-marg-b;
}
.time-machine--view { .time-machine--view {
position: absolute; position: absolute;
top: $time-machine--controls-height; top: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;

View File

@ -18,7 +18,7 @@
&.dragging { &.dragging {
border-radius: 4px; border-radius: 4px;
opacity: 0.25; opacity: 0.4;
@include gradient-h($c-pool, $c-star); @include gradient-h($c-pool, $c-star);
> * { > * {

View File

@ -4,7 +4,7 @@ import HTML5Backend from 'react-dnd-html5-backend'
// Components // Components
import DraggableColumn from 'src/shared/components/draggable_column/DraggableColumn' import DraggableColumn from 'src/shared/components/draggable_column/DraggableColumn'
import {Form} from 'src/clockface' import {ComponentSize, EmptyState, Grid, Form} from 'src/clockface'
// Types // Types
import {FieldOption} from 'src/types/v2/dashboards' import {FieldOption} from 'src/types/v2/dashboards'
@ -18,20 +18,22 @@ interface Props {
class ColumnsOptions extends Component<Props> { class ColumnsOptions extends Component<Props> {
public render() { public render() {
const {columns, className} = this.props const {className} = this.props
return ( return (
<Grid.Column>
<Form.Element label="Table Columns"> <Form.Element label="Table Columns">
<div className={className}> <div className={className}>{this.draggableColumns}</div>
{columns.map((c, i) => this.getDraggableColumn(c, i))}
</div>
</Form.Element> </Form.Element>
</Grid.Column>
) )
} }
private getDraggableColumn(column: FieldOption, i: number): JSX.Element { private get draggableColumns(): JSX.Element | JSX.Element[] {
const {onMoveColumn, onUpdateColumn} = this.props const {columns, onMoveColumn, onUpdateColumn} = this.props
return (
if (columns.length) {
return columns.map((column: FieldOption, i: number) => (
<DraggableColumn <DraggableColumn
key={column.internalName} key={column.internalName}
index={i} index={i}
@ -42,6 +44,15 @@ class ColumnsOptions extends Component<Props> {
onUpdateColumn={onUpdateColumn} onUpdateColumn={onUpdateColumn}
onMoveColumn={onMoveColumn} onMoveColumn={onMoveColumn}
/> />
))
}
return (
<Form.Box>
<EmptyState size={ComponentSize.Small}>
<EmptyState.Text text="This query returned no columns" />
</EmptyState>
</Form.Box>
) )
} }
} }

View File

@ -1,3 +1,4 @@
// Libraries
import React, {Component, ChangeEvent} from 'react' import React, {Component, ChangeEvent} from 'react'
import {findDOMNode} from 'react-dom' import {findDOMNode} from 'react-dom'
import { import {
@ -11,9 +12,17 @@ import {
ConnectDropTarget, ConnectDropTarget,
ConnectDragPreview, ConnectDragPreview,
} from 'react-dnd' } from 'react-dnd'
// Components
import {Input, ComponentStatus} from 'src/clockface'
// Decorators
import {ErrorHandling} from 'src/shared/decorators/errors' import {ErrorHandling} from 'src/shared/decorators/errors'
// Types
import {LogsTableColumn} from 'src/types/logs' import {LogsTableColumn} from 'src/types/logs'
// Constants
const columnType = 'column' const columnType = 'column'
interface Props { interface Props {
@ -123,7 +132,6 @@ export default class DraggableColumn extends Component<Props> {
displayName, displayName,
connectDragPreview, connectDragPreview,
connectDropTarget, connectDropTarget,
visible,
} = this.props } = this.props
return connectDragPreview( return connectDragPreview(
@ -134,21 +142,29 @@ export default class DraggableColumn extends Component<Props> {
{this.visibilityToggle} {this.visibilityToggle}
<div className="customizable-field--name">{internalName}</div> <div className="customizable-field--name">{internalName}</div>
</div> </div>
<input <Input
className="form-control input-sm customizable-field--input" customClass="customizable-field--input"
type="text"
spellCheck={false}
id="internalName" id="internalName"
value={displayName} value={displayName}
onChange={this.handleColumnRename} onChange={this.handleColumnRename}
placeholder={`Rename ${internalName}`} placeholder={`Rename ${internalName}`}
disabled={!visible} status={this.inputStatus}
/> />
</div> </div>
) )
) )
} }
private get inputStatus(): ComponentStatus {
const {visible} = this.props
if (visible) {
return ComponentStatus.Default
}
return ComponentStatus.Disabled
}
private get dragHandle(): JSX.Element { private get dragHandle(): JSX.Element {
const {connectDragSource} = this.props const {connectDragSource} = this.props

View File

@ -6,6 +6,7 @@ import _ from 'lodash'
import {ErrorHandling} from 'src/shared/decorators/errors' import {ErrorHandling} from 'src/shared/decorators/errors'
import FancyScrollbar from 'src/shared/components/fancy_scrollbar/FancyScrollbar' import FancyScrollbar from 'src/shared/components/fancy_scrollbar/FancyScrollbar'
import TableSidebarItem from 'src/shared/components/tables/TableSidebarItem' import TableSidebarItem from 'src/shared/components/tables/TableSidebarItem'
import {Input, IconFont} from 'src/clockface'
// Types // Types
import {FluxTable} from 'src/types' import {FluxTable} from 'src/types'
@ -34,12 +35,12 @@ export default class TableSidebar extends PureComponent<Props, State> {
<div className="time-machine-sidebar"> <div className="time-machine-sidebar">
{!this.isDataEmpty && ( {!this.isDataEmpty && (
<div className="time-machine-sidebar--heading"> <div className="time-machine-sidebar--heading">
<input <Input
type="text" icon={IconFont.Search}
className="form-control input-xs time-machine-sidebar--filter"
onChange={this.handleSearch} onChange={this.handleSearch}
placeholder="Filter tables" placeholder="Filter tables..."
value={searchTerm} value={searchTerm}
customClass="time-machine-sidebar--filter"
/> />
</div> </div>
)} )}

View File

@ -78,6 +78,8 @@ export class TableOptions extends Component<Props, {}> {
<> <>
<Grid.Column widthSM={Columns.Four}> <Grid.Column widthSM={Columns.Four}>
<h4 className="view-options--header">Table Formatting</h4> <h4 className="view-options--header">Table Formatting</h4>
<Grid>
<Grid.Row>
{!!fieldOptions.length && ( {!!fieldOptions.length && (
<SortBy <SortBy
selected={sortBy} selected={sortBy}
@ -96,9 +98,13 @@ export class TableOptions extends Component<Props, {}> {
onDecimalPlacesChange={onSetDecimalPlaces} onDecimalPlacesChange={onSetDecimalPlaces}
/> />
)} )}
</Grid.Row>
</Grid>
</Grid.Column> </Grid.Column>
<Grid.Column widthSM={Columns.Four}> <Grid.Column widthSM={Columns.Four}>
<h4 className="view-options--header">Column Settings</h4> <h4 className="view-options--header">Column Settings</h4>
<Grid>
<Grid.Row>
<TimeAxis <TimeAxis
verticalTimeAxis={verticalTimeAxis} verticalTimeAxis={verticalTimeAxis}
onToggleVerticalTimeAxis={this.handleToggleVerticalTimeAxis} onToggleVerticalTimeAxis={this.handleToggleVerticalTimeAxis}
@ -112,6 +118,8 @@ export class TableOptions extends Component<Props, {}> {
onMoveColumn={this.handleMoveColumn} onMoveColumn={this.handleMoveColumn}
onUpdateColumn={this.handleUpdateColumn} onUpdateColumn={this.handleUpdateColumn}
/> />
</Grid.Row>
</Grid>
</Grid.Column> </Grid.Column>
<Grid.Column widthSM={Columns.Four}> <Grid.Column widthSM={Columns.Four}>
<h4 className="view-options--header">Colorized Thresholds</h4> <h4 className="view-options--header">Colorized Thresholds</h4>

View File

@ -2,7 +2,7 @@ import _ from 'lodash'
import React from 'react' import React from 'react'
// Types // Types
import {Dropdown, Form, DropdownMode} from 'src/clockface' import {Grid, Dropdown, Form, DropdownMode} from 'src/clockface'
import {FieldOption} from 'src/types/v2/dashboards' import {FieldOption} from 'src/types/v2/dashboards'
interface Props { interface Props {
@ -13,6 +13,7 @@ interface Props {
const SortBy = ({fieldOptions, onChange, selected}: Props) => { const SortBy = ({fieldOptions, onChange, selected}: Props) => {
return ( return (
<Grid.Column>
<Form.Element label="Default Sort Field"> <Form.Element label="Default Sort Field">
<Dropdown <Dropdown
selectedID={_.get(selected, 'internalName', null)} selectedID={_.get(selected, 'internalName', null)}
@ -32,6 +33,7 @@ const SortBy = ({fieldOptions, onChange, selected}: Props) => {
))} ))}
</Dropdown> </Dropdown>
</Form.Element> </Form.Element>
</Grid.Column>
) )
} }

View File

@ -8,6 +8,7 @@ import {
InputType, InputType,
ComponentStatus, ComponentStatus,
ButtonType, ButtonType,
ComponentSize,
} from 'src/clockface' } from 'src/clockface'
import ColorDropdown from 'src/shared/components/ColorDropdown' import ColorDropdown from 'src/shared/components/ColorDropdown'
@ -62,6 +63,7 @@ class Threshold extends PureComponent<Props, State> {
{isDeletable && {isDeletable &&
!isBase && ( !isBase && (
<Button <Button
size={ComponentSize.ExtraSmall}
shape={ButtonShape.Square} shape={ButtonShape.Square}
onClick={this.handleDelete} onClick={this.handleDelete}
icon={IconFont.Remove} icon={IconFont.Remove}

View File

@ -28,22 +28,22 @@
} }
.threshold-item--label { .threshold-item--label {
flex: 0 0 120px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
height: 30px; height: 30px;
font-weight: 600; font-weight: 600;
font-size: 13px; font-size: 13px;
padding-left: 11px; padding-left: $ix-marg-b;
padding-right: $ix-marg-a;
border-radius: 4px; border-radius: 4px;
@include no-user-select(); @include no-user-select();
width: 120px;
background-color: $g4-onyx; background-color: $g4-onyx;
color: $g11-sidewalk; color: $g9-mountain;
&.threshold-item--label__editable { &.threshold-item--label__editable {
color: $g16-pearl; color: $g13-mist;
background-color: initial;
} }
} }

View File

@ -2,7 +2,7 @@
import React, {SFC} from 'react' import React, {SFC} from 'react'
// Components // Components
import {Radio, ButtonShape, Form} from 'src/clockface' import {Grid, Radio, ButtonShape, Form} from 'src/clockface'
interface Props { interface Props {
verticalTimeAxis: boolean verticalTimeAxis: boolean
@ -10,6 +10,7 @@ interface Props {
} }
const TimeAxis: SFC<Props> = ({verticalTimeAxis, onToggleVerticalTimeAxis}) => ( const TimeAxis: SFC<Props> = ({verticalTimeAxis, onToggleVerticalTimeAxis}) => (
<Grid.Column>
<Form.Element label="Time Axis"> <Form.Element label="Time Axis">
<Radio shape={ButtonShape.StretchToFit}> <Radio shape={ButtonShape.StretchToFit}>
<Radio.Button <Radio.Button
@ -32,6 +33,7 @@ const TimeAxis: SFC<Props> = ({verticalTimeAxis, onToggleVerticalTimeAxis}) => (
</Radio.Button> </Radio.Button>
</Radio> </Radio>
</Form.Element> </Form.Element>
</Grid.Column>
) )
export default TimeAxis export default TimeAxis

View File

@ -0,0 +1,12 @@
/*
Time Format Styles
------------------------------------------------------------------------------
*/
@import 'src/style/modules';
.time-format--helper {
color: $g11-sidewalk;
margin: 0;
font-size: 13px;
}

View File

@ -1,8 +1,17 @@
import React, {PureComponent} from 'react' import React, {PureComponent} from 'react'
// Components // Components
import {Form, Grid, Input, InputType, Dropdown, Columns} from 'src/clockface' import {
import QuestionMarkTooltip from 'src/shared/components/QuestionMarkTooltip' ComponentSpacer,
Stack,
Alignment,
Form,
Grid,
Input,
InputType,
Dropdown,
Columns,
} from 'src/clockface'
// Constants // Constants
import {DEFAULT_TIME_FORMAT} from 'src/shared/constants' import {DEFAULT_TIME_FORMAT} from 'src/shared/constants'
@ -12,6 +21,9 @@ import {
TIME_FORMAT_TOOLTIP_LINK, TIME_FORMAT_TOOLTIP_LINK,
} from 'src/dashboards/constants' } from 'src/dashboards/constants'
// Styles
import 'src/shared/components/view_options/options/TimeFormat.scss'
// Decorators // Decorators
import {ErrorHandling} from 'src/shared/decorators/errors' import {ErrorHandling} from 'src/shared/decorators/errors'
@ -36,9 +48,9 @@ class TimeFormat extends PureComponent<Props, State> {
const {format} = this.state const {format} = this.state
return ( return (
<Grid.Column widthXS={Columns.Twelve}> <Grid.Column widthSM={Columns.Six}>
<Form.Element label="Time Format" labelAddOn={this.timeFormatTooltip}> <Form.Element label="Time Format">
<> <ComponentSpacer stackChildren={Stack.Rows} align={Alignment.Left}>
<Dropdown <Dropdown
selectedID={this.showCustom ? TIME_FORMAT_CUSTOM : format} selectedID={this.showCustom ? TIME_FORMAT_CUSTOM : format}
onChange={this.handleChooseFormat} onChange={this.handleChooseFormat}
@ -50,18 +62,9 @@ class TimeFormat extends PureComponent<Props, State> {
</Dropdown.Item> </Dropdown.Item>
))} ))}
</Dropdown> </Dropdown>
{this.showCustom && ( {this.customTimeInput}
<Input {this.helpBox}
type={InputType.Text} </ComponentSpacer>
spellCheck={false}
placeholder="Enter custom format..."
value={format}
data-test="custom-time-format"
customClass="custom-time-format"
onChange={this.handleChangeFormat}
/>
)}
</>
</Form.Element> </Form.Element>
</Grid.Column> </Grid.Column>
) )
@ -74,21 +77,6 @@ class TimeFormat extends PureComponent<Props, State> {
return !formatOption || customFormat return !formatOption || customFormat
} }
private timeFormatTooltip = (): JSX.Element => {
const tipContent = `For information on formatting, see <br/><a href="#">${TIME_FORMAT_TOOLTIP_LINK}</a>`
if (this.showCustom) {
return (
<a href={TIME_FORMAT_TOOLTIP_LINK} target="_blank">
<QuestionMarkTooltip
tipID="Time Axis Format"
tipContent={tipContent}
/>
</a>
)
}
}
private get onTimeFormatChange() { private get onTimeFormatChange() {
return this.props.onTimeFormatChange return this.props.onTimeFormatChange
} }
@ -107,6 +95,39 @@ class TimeFormat extends PureComponent<Props, State> {
this.setState({format, customFormat: false}) this.setState({format, customFormat: false})
} }
} }
private get customTimeInput(): JSX.Element {
const {format} = this.state
if (this.showCustom) {
return (
<Input
type={InputType.Text}
spellCheck={false}
placeholder="Enter custom format..."
value={format}
data-test="custom-time-format"
customClass="custom-time-format"
onChange={this.handleChangeFormat}
/>
)
}
}
private get helpBox(): JSX.Element {
if (this.showCustom) {
return (
<Form.Box>
<p className="time-format--helper">
For help with formatting time, see{' '}
<a href={TIME_FORMAT_TOOLTIP_LINK} target="_blank">
MomentJS Docs
</a>
</p>
</Form.Box>
)
}
}
} }
export default TimeFormat export default TimeFormat