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 React, {Component, KeyboardEvent} from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
|
import './RenameDashboard.scss'
|
||||||
import {
|
import {
|
||||||
DASHBOARD_NAME_MAX_LENGTH,
|
DASHBOARD_NAME_MAX_LENGTH,
|
||||||
NEW_DASHBOARD,
|
DEFAULT_DASHBOARD_NAME,
|
||||||
} from 'src/dashboards/constants/index'
|
} 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
|
@ErrorHandling
|
||||||
class DashboardEditHeader extends Component {
|
class DashboardEditHeader extends Component<Props, State> {
|
||||||
constructor(props) {
|
private inputRef: HTMLInputElement
|
||||||
|
|
||||||
|
constructor(props: Props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
|
isEditing: false,
|
||||||
reset: false,
|
reset: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleInputBlur = e => {
|
public render() {
|
||||||
const {onSave, onCancel} = this.props
|
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
|
const {reset} = this.state
|
||||||
|
|
||||||
if (reset) {
|
if (reset) {
|
||||||
onCancel()
|
this.setState({isEditing: false})
|
||||||
} else {
|
} else {
|
||||||
const newName = e.target.value || NEW_DASHBOARD.name
|
const newName = e.target.value || DEFAULT_DASHBOARD_NAME
|
||||||
onSave(newName)
|
onRename(newName)
|
||||||
}
|
}
|
||||||
this.setState({reset: false})
|
this.setState({isEditing: false, reset: false})
|
||||||
}
|
}
|
||||||
|
|
||||||
handleKeyDown = e => {
|
private handleKeyDown = (e: KeyboardEvent<HTMLInputElement>): void => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
this.inputRef.blur()
|
this.inputRef.blur()
|
||||||
}
|
}
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
this.inputRef.value = this.props.activeDashboard
|
this.inputRef.value = this.props.name
|
||||||
this.setState({reset: true}, () => this.inputRef.blur())
|
this.setState({reset: true}, () => this.inputRef.blur())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleFocus = e => {
|
private handleFocus = (e): void => {
|
||||||
e.target.select()
|
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
|
export default DashboardEditHeader
|
||||||
|
|
|
@ -398,75 +398,6 @@ $tick-script-overlay-margin: 30px;
|
||||||
white-space: nowrap;
|
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
|
/* Add borders between items in .nav-tablist
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
TODO: Add these styles into the theme
|
TODO: Add these styles into the theme
|
||||||
|
@ -510,3 +441,8 @@ div.dropdown.dropdown-stretch > button.dropdown-toggle {
|
||||||
.custom-time-format {
|
.custom-time-format {
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.annotation-selector {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
Loading…
Reference in New Issue