Refactor RenameDashboard component & styles
parent
5cb7fbc8dd
commit
78d3b2b4be
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Rename Dashboard Component Styles
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@import 'src/style/modules/influx-colors';
|
||||
@import 'src/style/modules/variables';
|
||||
@import 'src/style/modules/mixins';
|
||||
@import 'src/style/layout/page-header';
|
||||
|
||||
$rename-dash-title-padding: 7px;
|
||||
|
||||
.rename-dashboard {
|
||||
height: $chronograf-page-header-height;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1 0 0;
|
||||
}
|
||||
|
||||
.rename-dashboard--title {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
padding: 0 $rename-dash-title-padding;
|
||||
border: $ix-border solid $g0-obsidian;
|
||||
height: $form-sm-height;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border-radius: $radius;
|
||||
@include no-user-select();
|
||||
color: $g17-whisper;
|
||||
transition:
|
||||
color 0.25s ease,
|
||||
background-color 0.25s ease,
|
||||
border-color 0.25s ease;
|
||||
|
||||
h1 {
|
||||
text-transform: none;
|
||||
letter-spacing: 0;
|
||||
line-height: $form-sm-height - $ix-border;
|
||||
margin: 0;
|
||||
font-size: $page-header-size;
|
||||
font-weight: $page-header-weight;
|
||||
}
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
font-size: 15px;
|
||||
top: 50%;
|
||||
right: $rename-dash-title-padding;
|
||||
transform: translateY(-50%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.25s ease;
|
||||
color: $g11-sidewalk;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: text;
|
||||
color: $g20-white;
|
||||
background-color: $g3-castle;
|
||||
border-color: $g3-castle;
|
||||
}
|
||||
|
||||
&:hover .icon {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
input.form-control.input-sm.rename-dashboard--input {
|
||||
padding: 0 $rename-dash-title-padding;
|
||||
font-size: $page-header-size;
|
||||
font-weight: $page-header-weight;
|
||||
}
|
|
@ -1,84 +1,102 @@
|
|||
import React, {Component} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import React, {Component, KeyboardEvent} from 'react'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
import './RenameDashboard.scss'
|
||||
import {
|
||||
DASHBOARD_NAME_MAX_LENGTH,
|
||||
NEW_DASHBOARD,
|
||||
DEFAULT_DASHBOARD_NAME,
|
||||
} from 'src/dashboards/constants/index'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
interface Props {
|
||||
onRename: (name: string) => void
|
||||
name: string
|
||||
}
|
||||
|
||||
interface State {
|
||||
isEditing: boolean
|
||||
reset: boolean
|
||||
}
|
||||
@ErrorHandling
|
||||
class DashboardEditHeader extends Component {
|
||||
constructor(props) {
|
||||
class DashboardEditHeader extends Component<Props, State> {
|
||||
private inputRef: HTMLInputElement
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
isEditing: false,
|
||||
reset: false,
|
||||
}
|
||||
}
|
||||
|
||||
handleInputBlur = e => {
|
||||
const {onSave, onCancel} = this.props
|
||||
public render() {
|
||||
const {isEditing} = this.state
|
||||
const {name} = this.props
|
||||
|
||||
if (isEditing) {
|
||||
return <div className="rename-dashboard">{this.input}</div>
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rename-dashboard">
|
||||
<div className="rename-dashboard--title">
|
||||
<h1 onClick={this.handleStartEditing}>{name}</h1>
|
||||
<span className="icon pencil" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private get input(): JSX.Element {
|
||||
const {name} = this.props
|
||||
|
||||
return (
|
||||
<input
|
||||
maxLength={DASHBOARD_NAME_MAX_LENGTH}
|
||||
type="text"
|
||||
className="rename-dashboard--input form-control input-sm"
|
||||
defaultValue={name}
|
||||
autoComplete="off"
|
||||
autoFocus={true}
|
||||
spellCheck={false}
|
||||
onBlur={this.handleInputBlur}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
onFocus={this.handleFocus}
|
||||
placeholder="Name this Dashboard"
|
||||
ref={r => (this.inputRef = r)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
private handleStartEditing = (): void => {
|
||||
this.setState({isEditing: true})
|
||||
}
|
||||
|
||||
private handleInputBlur = e => {
|
||||
const {onRename} = this.props
|
||||
const {reset} = this.state
|
||||
|
||||
if (reset) {
|
||||
onCancel()
|
||||
this.setState({isEditing: false})
|
||||
} else {
|
||||
const newName = e.target.value || NEW_DASHBOARD.name
|
||||
onSave(newName)
|
||||
const newName = e.target.value || DEFAULT_DASHBOARD_NAME
|
||||
onRename(newName)
|
||||
}
|
||||
this.setState({reset: false})
|
||||
this.setState({isEditing: false, reset: false})
|
||||
}
|
||||
|
||||
handleKeyDown = e => {
|
||||
private handleKeyDown = (e: KeyboardEvent<HTMLInputElement>): void => {
|
||||
if (e.key === 'Enter') {
|
||||
this.inputRef.blur()
|
||||
}
|
||||
if (e.key === 'Escape') {
|
||||
this.inputRef.value = this.props.activeDashboard
|
||||
this.inputRef.value = this.props.name
|
||||
this.setState({reset: true}, () => this.inputRef.blur())
|
||||
}
|
||||
}
|
||||
|
||||
handleFocus = e => {
|
||||
private handleFocus = (e): void => {
|
||||
e.target.select()
|
||||
}
|
||||
|
||||
render() {
|
||||
const {onEditDashboard, isEditMode, activeDashboard} = this.props
|
||||
|
||||
return (
|
||||
<div className="dashboard-title">
|
||||
{isEditMode ? (
|
||||
<input
|
||||
maxLength={DASHBOARD_NAME_MAX_LENGTH}
|
||||
type="text"
|
||||
className="dashboard-title--input form-control input-sm"
|
||||
defaultValue={activeDashboard}
|
||||
autoComplete="off"
|
||||
autoFocus={true}
|
||||
spellCheck={false}
|
||||
onBlur={this.handleInputBlur}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
onFocus={this.handleFocus}
|
||||
placeholder="Name this Dashboard"
|
||||
ref={r => (this.inputRef = r)}
|
||||
/>
|
||||
) : (
|
||||
<h1 onClick={onEditDashboard}>{activeDashboard}</h1>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const {bool, func, string} = PropTypes
|
||||
|
||||
DashboardEditHeader.propTypes = {
|
||||
activeDashboard: string.isRequired,
|
||||
onSave: func.isRequired,
|
||||
onCancel: func.isRequired,
|
||||
isEditMode: bool,
|
||||
onEditDashboard: func.isRequired,
|
||||
}
|
||||
|
||||
export default DashboardEditHeader
|
||||
|
|
|
@ -398,75 +398,6 @@ $tick-script-overlay-margin: 30px;
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/*
|
||||
Dashboard Name Editing
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
$dash-editable-header-padding: 7px;
|
||||
|
||||
.page-header--left.page-header__dash-editable,
|
||||
.dashboard-title,
|
||||
.dashboard-title input[type='text'].form-control.dashboard-title--input,
|
||||
.dashboard-title h1 {
|
||||
flex: 1 0 0;
|
||||
}
|
||||
.dashboard-title {
|
||||
display: flex;
|
||||
|
||||
input[type='text'].form-control.dashboard-title--input,
|
||||
input[type='text'].form-control.dashboard-title--input:focus,
|
||||
h1 {
|
||||
font-size: $page-header-size;
|
||||
font-weight: $page-header-weight;
|
||||
padding: 0 $dash-editable-header-padding;
|
||||
}
|
||||
|
||||
input[type='text'].form-control.dashboard-title--input,
|
||||
input[type='text'].form-control.dashboard-title--input:focus {
|
||||
font-size: $page-header-size;
|
||||
font-weight: $page-header-weight;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@include no-user-select();
|
||||
position: relative;
|
||||
border: 2px solid $g0-obsidian;
|
||||
color: $g17-whisper;
|
||||
height: 30px;
|
||||
line-height: 28px;
|
||||
border-radius: 4px;
|
||||
margin: 0;
|
||||
letter-spacing: 0;
|
||||
text-transform: none;
|
||||
transition: color 0.25s ease, background-color 0.25s ease,
|
||||
border-color 0.25s ease;
|
||||
|
||||
&:after {
|
||||
content: '\f058';
|
||||
font-family: 'icomoon';
|
||||
position: absolute;
|
||||
font-size: 15px;
|
||||
top: 50%;
|
||||
right: $dash-editable-header-padding;
|
||||
transform: translateY(-50%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.25s ease;
|
||||
color: $g11-sidewalk;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: text;
|
||||
color: $g20-white;
|
||||
background-color: $g3-castle;
|
||||
border-color: $g3-castle;
|
||||
|
||||
&:after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add borders between items in .nav-tablist
|
||||
-----------------------------------------------------------------------------
|
||||
TODO: Add these styles into the theme
|
||||
|
@ -510,3 +441,8 @@ div.dropdown.dropdown-stretch > button.dropdown-toggle {
|
|||
.custom-time-format {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
|
||||
.annotation-selector {
|
||||
margin-left: 4px;
|
||||
}
|
Loading…
Reference in New Issue