Style Template Variable Manager and customize markup

Adjusts to different screen sizes nicely
pull/10616/head
Alex P 2017-04-27 18:03:53 -07:00
parent 56f1ceca61
commit 4ce17e842c
5 changed files with 290 additions and 95 deletions

View File

@ -15,13 +15,13 @@ const TemplateQueryBuilder = ({
}) => { }) => {
switch (selectedType) { switch (selectedType) {
case 'csv': case 'csv':
return <div>n/a</div> return <div className="tvm-csv-instructions">Enter values below</div>
case 'databases': case 'databases':
return <div>SHOW DATABASES</div> return <div className="tvm-query-builder--text">SHOW DATABASES</div>
case 'measurements': case 'measurements':
return ( return (
<div> <div className="tvm-query-builder">
<span>SHOW MEASUREMENTS ON</span> <span className="tvm-query-builder--text">SHOW MEASUREMENTS ON</span>
<DatabaseDropdown <DatabaseDropdown
onSelectDatabase={onSelectDatabase} onSelectDatabase={onSelectDatabase}
database={selectedDatabase} database={selectedDatabase}
@ -32,14 +32,16 @@ const TemplateQueryBuilder = ({
case 'fieldKeys': case 'fieldKeys':
case 'tagKeys': case 'tagKeys':
return ( return (
<div> <div className="tvm-query-builder">
SHOW {selectedType === 'fieldKeys' ? 'FIELD' : 'TAG'} KEYS ON <span className="tvm-query-builder--text">
SHOW {selectedType === 'fieldKeys' ? 'FIELD' : 'TAG'} KEYS ON
</span>
<DatabaseDropdown <DatabaseDropdown
onSelectDatabase={onSelectDatabase} onSelectDatabase={onSelectDatabase}
database={selectedDatabase} database={selectedDatabase}
onStartEdit={onStartEdit} onStartEdit={onStartEdit}
/> />
FROM <span className="tvm-query-builder--text">FROM</span>
{selectedDatabase {selectedDatabase
? <MeasurementDropdown ? <MeasurementDropdown
database={selectedDatabase} database={selectedDatabase}
@ -52,14 +54,14 @@ const TemplateQueryBuilder = ({
) )
case 'tagValues': case 'tagValues':
return ( return (
<div> <div className="tvm-query-builder">
SHOW TAG VALUES ON <span className="tvm-query-builder--text">SHOW TAG VALUES ON</span>
<DatabaseDropdown <DatabaseDropdown
onSelectDatabase={onSelectDatabase} onSelectDatabase={onSelectDatabase}
database={selectedDatabase} database={selectedDatabase}
onStartEdit={onStartEdit} onStartEdit={onStartEdit}
/> />
FROM <span className="tvm-query-builder--text">FROM</span>
{selectedDatabase {selectedDatabase
? <MeasurementDropdown ? <MeasurementDropdown
database={selectedDatabase} database={selectedDatabase}
@ -68,7 +70,7 @@ const TemplateQueryBuilder = ({
onStartEdit={onStartEdit} onStartEdit={onStartEdit}
/> />
: 'Pick a DB'} : 'Pick a DB'}
WITH KEY = <span className="tvm-query-builder--text">WITH KEY =</span>
{selectedMeasurement {selectedMeasurement
? <TagKeyDropdown ? <TagKeyDropdown
database={selectedDatabase} database={selectedDatabase}
@ -81,7 +83,7 @@ const TemplateQueryBuilder = ({
</div> </div>
) )
default: default:
return <div>n/a</div> return <div><span className="tvm-query-builder--text">n/a</span></div>
} }
} }

View File

@ -3,6 +3,7 @@ import {connect} from 'react-redux'
import {bindActionCreators} from 'redux' import {bindActionCreators} from 'redux'
import OnClickOutside from 'react-onclickoutside' import OnClickOutside from 'react-onclickoutside'
import classNames from 'classnames'
import Dropdown from 'shared/components/Dropdown' import Dropdown from 'shared/components/Dropdown'
import DeleteConfirmButtons from 'shared/components/DeleteConfirmButtons' import DeleteConfirmButtons from 'shared/components/DeleteConfirmButtons'
@ -42,10 +43,8 @@ const RowValues = ({
) )
} }
return ( return (
<div className="td"> <div className={values.length ? 'tvm-values' : 'tvm-values-empty'}>
{values.length {values.length ? _values : 'No values to display'}
? <span>{_values}</span>
: <span>(No values to display)</span>}
</div> </div>
) )
} }
@ -60,24 +59,25 @@ const RowButtons = ({
}) => { }) => {
if (isEditing) { if (isEditing) {
return ( return (
<div> <div className="tvm-actions">
<button className="btn btn-sm btn-success" type="submit">
{selectedType === 'csv' ? 'Save Values' : 'Get Values'}
</button>
<button <button
className="btn btn-sm btn-primary" className="btn btn-sm btn-info"
type="button" type="button"
onClick={onCancelEdit} onClick={onCancelEdit}
> >
Cancel Cancel
</button> </button>
<button className="btn btn-sm btn-success" type="submit">
{selectedType === 'csv' ? 'Save Values' : 'Get Values'}
</button>
</div> </div>
) )
} }
return ( return (
<div> <div className="tvm-actions">
<DeleteConfirmButtons onDelete={() => onDelete(id)} />
<button <button
className="btn btn-sm btn-info" className="btn btn-sm btn-info btn-edit"
type="button" type="button"
onClick={e => { onClick={e => {
// prevent subsequent 'onSubmit' that is caused by an unknown source, // prevent subsequent 'onSubmit' that is caused by an unknown source,
@ -87,9 +87,8 @@ const RowButtons = ({
onStartEdit('tempVar') onStartEdit('tempVar')
}} }}
> >
Edit <span className="icon pencil" />
</button> </button>
<DeleteConfirmButtons onDelete={() => onDelete(id)} />
</div> </div>
) )
} }
@ -112,7 +111,7 @@ const TemplateVariableRow = ({
onDelete, onDelete,
}) => ( }) => (
<form <form
className="tr" className={classNames('template-variable-manager--table-row', {editing: isEditing})}
onSubmit={onSubmit({ onSubmit={onSubmit({
selectedType, selectedType,
selectedDatabase, selectedDatabase,
@ -120,23 +119,25 @@ const TemplateVariableRow = ({
selectedTagKey, selectedTagKey,
})} })}
> >
<TableInput <div className="tvm--col-1">
name="tempVar" <TableInput
defaultValue={tempVar} name="tempVar"
isEditing={isEditing} defaultValue={tempVar}
onStartEdit={onStartEdit} isEditing={isEditing}
autoFocusTarget={autoFocusTarget} onStartEdit={onStartEdit}
/> autoFocusTarget={autoFocusTarget}
<div className="td"> />
</div>
<div className="tvm--col-2">
<Dropdown <Dropdown
items={TEMPLATE_TYPES} items={TEMPLATE_TYPES}
onChoose={onSelectType} onChoose={onSelectType}
onClick={() => onStartEdit(null)} onClick={() => onStartEdit(null)}
selected={TEMPLATE_TYPES.find(t => t.type === selectedType).text} selected={TEMPLATE_TYPES.find(t => t.type === selectedType).text}
className={'template-variable--dropdown'} className="dropdown-140"
/> />
</div> </div>
<div className="td"> <div className="tvm--col-3">
<TemplateQueryBuilder <TemplateQueryBuilder
onSelectDatabase={onSelectDatabase} onSelectDatabase={onSelectDatabase}
selectedType={selectedType} selectedType={selectedType}
@ -147,15 +148,15 @@ const TemplateVariableRow = ({
onSelectTagKey={onSelectTagKey} onSelectTagKey={onSelectTagKey}
onStartEdit={onStartEdit} onStartEdit={onStartEdit}
/> />
<RowValues
selectedType={selectedType}
values={values}
isEditing={isEditing}
onStartEdit={onStartEdit}
autoFocusTarget={autoFocusTarget}
/>
</div> </div>
<RowValues <div className="tvm--col-4">
selectedType={selectedType}
values={values}
isEditing={isEditing}
onStartEdit={onStartEdit}
autoFocusTarget={autoFocusTarget}
/>
<div className="td" style={{display: 'flex'}}>
<RowButtons <RowButtons
onStartEdit={onStartEdit} onStartEdit={onStartEdit}
isEditing={isEditing} isEditing={isEditing}
@ -176,12 +177,12 @@ const TableInput = ({
autoFocusTarget, autoFocusTarget,
}) => { }) => {
return isEditing return isEditing
? <div name={name} className="td"> ? <div name={name} style={{width: '100%'}}>
<input <input
required={true} required={true}
name={name} name={name}
autoFocus={name === autoFocusTarget} autoFocus={name === autoFocusTarget}
className="input" className="form-control input-sm tvm-input-edit"
type="text" type="text"
defaultValue={ defaultValue={
name === 'tempVar' name === 'tempVar'
@ -190,7 +191,9 @@ const TableInput = ({
} }
/> />
</div> </div>
: <div className="td" onClick={() => onStartEdit(name)}>{defaultValue}</div> : <div style={{width: '100%'}} onClick={() => onStartEdit(name)}>
<div className="tvm-input">{defaultValue}</div>
</div>
} }
class RowWrapper extends Component { class RowWrapper extends Component {

View File

@ -11,19 +11,16 @@ const TemplateVariableTable = ({
onDelete, onDelete,
tempVarAlreadyExists, tempVarAlreadyExists,
}) => ( }) => (
<div className="table-custom"> <div className="template-variable-manager--table">
{templates.length {templates.length
? <div> ? <div className="template-variable-manager--table-container">
<div className="thead"> <div className="template-variable-manager--table-heading">
<div className="tr"> <div className="tvm--col-1">Variable</div>
<div className="th">Variable</div> <div className="tvm--col-2">Type</div>
<div className="th">Type</div> <div className="tvm--col-3">Definition / Values</div>
<div className="th">Queries</div> <div className="tvm--col-4" />
<div className="th">Values</div>
<div className="th" />
</div>
</div> </div>
<div className="tbody"> <div className="template-variable-manager--table-rows">
{templates.map(t => ( {templates.map(t => (
<TemplateVariableRow <TemplateVariableRow
key={t.id} key={t.id}

View File

@ -4,27 +4,220 @@
Accessed via Dashboards Accessed via Dashboards
*/ */
$tvmp-panel-max-width: 1300px;
$tvmp-gutter: 30px;
$tvmp-min-height: 150px;
$tvmp-max-height: calc(100% - 90px);
$tvmp-table-gutter: 8px;
.template-variable-manager { .template-variable-manager {
width: 80%; max-width: $tvmp-panel-max-width;
margin: auto; margin: 0 $tvmp-gutter;
}
.template-variable-manager--header {
height: $chronograf-page-header-height;
background: $g0-obsidian;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 $tvmp-gutter;
.template-variable-manager--header { .page-header__dismiss {
height: 60px; margin-left: 10px;
background: $g0-obsidian; margin-right: -20px;
display: flex; }
justify-content: space-between; }
align-items: center; .template-variable-manager--body {
padding: 0 20px; padding: 18px ($tvmp-gutter - $tvmp-table-gutter) $tvmp-gutter ($tvmp-gutter - $tvmp-table-gutter);
font-size: 18px; border-radius: 0 0 $radius $radius;
min-height: $tvmp-min-height;
max-height: $tvmp-max-height;
@include gradient-v($g2-kevlar,$g0-obsidian);
@include custom-scrollbar-round($g0-obsidian,$g3-castle);
overflow: auto;
}
.template-variable-manager--table,
.template-variable-manager--table-container {
width: 100%;
}
/* Column Widths */
.tvm--col-1 {flex: 0 0 140px;}
.tvm--col-2 {flex: 0 0 140px;}
.tvm--col-3 {flex: 1 0 500px;}
.tvm--col-4 {flex: 0 0 160px;}
/* Table Column Labels */
.template-variable-manager--table-heading {
padding: 0 $tvmp-table-gutter;
height: 18px;
display: flex;
align-items: center;
flex-wrap: nowrap;
font-weight: 600;
font-size: 12px;
color: $g11-sidewalk;
> * {
@include no-user-select();
padding-left: 6px;
margin-right: $tvmp-table-gutter;
&:last-child {margin-right: 0;}
}
}
/* Table Body */
.template-variable-manager--table-rows {
display: flex;
flex-direction: column;
align-items: stretch;
}
.template-variable-manager--table-row {
border-radius: 4px;
display: flex;
align-items: flex-start;
padding: $tvmp-table-gutter;
transition: background-color 0.25s ease;
&.editing {
background-color: $g3-castle;
} }
.template-variable-manager--body { > * {
border-radius: 0 0 $radius $radius; margin-right: $tvmp-table-gutter;
min-height: 150px; &:last-child {margin-right: 0;}
@include gradient-v($g2-kevlar,$g0-obsidian); }
}
.tvm-input,
.form-control.tvm-input-edit {
font-weight: 600 !important;
width: 100% !important;
padding: 0 6px !important;
font-family: $code-font;
color: $c-comet !important;
height: 30px !important;
&:focus,
&:focus:hover {
color: $c-comet !important;
}
}
.tvm-input {
font-size: 12px;
line-height: 26px;
padding: 0 8px;
border-radius: $radius;
border: 2px solid $g5-pepper;
background-color: $g2-kevlar;
transition:
border-color 0.25s ease;
&:hover {
cursor: text;
border-color: $g6-smoke;
}
}
.tvm-values,
.tvm-values-empty {
width: 100%;
white-space: pre-wrap;
overflow: auto;
font-size: 12px;
font-weight: 600;
font-family: $code-font;
color: $c-pool;
padding: 0 $tvmp-table-gutter;
min-height: 30px;
max-height: 90px;
line-height: 30px;
border-radius: $radius;
background-color: $g5-pepper;
margin-top: 2px;
@include custom-scrollbar-round($g5-pepper, $g7-graphite);
}
.tvm-values-empty {
color: $g9-mountain;
font-style: italic;
}
.tvm-csv-instructions {
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 12px;
font-weight: 600;
font-family: $code-font;
padding: 0 $tvmp-table-gutter;
height: 30px;
line-height: 30px;
border-radius: $radius;
background-color: $g5-pepper;
margin-bottom: 2px;
color: $g9-mountain;
font-style: italic;
}
.tvm-query-builder {
display: flex;
align-items: center;
height: 30px;
> * {margin-right: 2px;}
> *:last-child {margin-right: 0;}
.dropdown {
flex: 1 0 0;
& > .dropdown-toggle {width: 100%;}
}
}
.tvm-query-builder--text {
@include no-user-select();
background-color: $g5-pepper;
border-radius: $radius-small;
padding: 0 $tvmp-table-gutter;
white-space: nowrap;
height: 30px;
line-height: 30px;
color: $c-pool;
font-size: 12px;
font-weight: 600;
font-family: $code-font;
}
.tvm-actions {
display: flex;
align-items: center;
justify-content: flex-end;
.btn-edit {
order: 1;
width: 30px;
text-align: center;
padding-left: 0 !important;
padding-right: 0 !important;
> span.icon {margin: 0 !important;}
} }
.dropdown-toggle { > .btn {margin-left: $tvmp-table-gutter;}
width: 150px;
/* Override confirm buttons styles */
/* Janky, but doing this quick & dirty for now */
.btn-danger {
order: 2;
height: 30px !important;
line-height: 30px !important;
padding: 0 9px !important;
font-size: 13px;
}
.confirm-buttons > .btn {
height: 30px !important;
width: 30px !important;
margin-left: $tvmp-table-gutter !important;
font-size: 13px;
padding: 0 !important;
}
/* Hide the edit button when confirming a delete */
.confirm-buttons + .btn-edit {
display: none;
} }
} }

View File

@ -64,29 +64,29 @@ $overlay-z: 100;
text-transform: uppercase; text-transform: uppercase;
@include no-user-select; @include no-user-select;
} }
.confirm-buttons { }
margin-left: 32px; .overlay-controls .confirm-buttons {
} margin-left: 32px;
.confirm-buttons .btn { }
height: 30px; .overlay-controls .confirm-buttons .btn {
line-height: 30px; height: 30px;
padding: 0 9px; line-height: 30px;
padding: 0 9px;
& > span.icon { & > span.icon {
font-size: 16px; font-size: 16px;
}
}
.overlay-controls .toggle {
.toggle-btn {
background-color: $overlay-controls-bg;
&:hover {
background-color: $g4-onyx;
} }
} &.active {
.overlay-controls .toggle { background-color: $g5-pepper;
.toggle-btn {
background-color: $overlay-controls-bg;
&:hover {
background-color: $g4-onyx;
}
&.active {
background-color: $g5-pepper;
}
} }
} }
} }