Redesign endpoints to use vertical tabs

pull/2447/head
Alex P 2017-11-17 12:56:16 -08:00
parent 7b52a09fd0
commit 2809f5273c
17 changed files with 170 additions and 86 deletions

View File

@ -9,18 +9,18 @@ const EndpointTabs = ({
handleRemoveEndpoint,
}) => {
return endpointsOnThisAlert.length
? <ul className="nav nav-tablist nav-tablist-sm nav-tablist-malachite">
? <ul className="endpoint-tabs">
{endpointsOnThisAlert.map(ep =>
<li
key={uuid.v4()}
className={classnames({
className={classnames('endpoint-tab', {
active: ep.alias === (selectedEndpoint && selectedEndpoint.alias),
})}
onClick={handleChooseAlert(ep)}
>
{ep.alias}
<div
className="nav-tab--delete"
<button
className="endpoint-tab--delete"
onClick={handleRemoveEndpoint(ep)}
/>
</li>

View File

@ -137,28 +137,37 @@ class RuleEndpoints extends Component {
const alerts = _.map([...DEFAULT_ALERTS, ...enabledAlerts], a => {
return {...a, text: a.type}
})
const dropdownLabel = endpointsOnThisAlert.length
? 'Add another Endpoint'
: 'Add an Endpoint'
const ruleSectionClassName = endpointsOnThisAlert.length
? 'rule-section--row rule-section--row-first rule-section--border-bottom'
: 'rule-section--row rule-section--row-first rule-section--row-last'
return (
<div className="rule-section">
<h3 className="rule-section--heading">Endpoints</h3>
<div className="rule-section--body">
<div className="rule-section--row rule-section--row-first rule-section--border-bottom">
<div className={ruleSectionClassName}>
<p>Send this Alert to:</p>
<EndpointTabs
endpointsOnThisAlert={endpointsOnThisAlert}
selectedEndpoint={selectedEndpoint}
handleChooseAlert={this.handleChooseAlert}
handleRemoveEndpoint={this.handleRemoveEndpoint}
/>
<Dropdown
items={alerts}
menuClass="dropdown-malachite"
selected="Add an Endpoint"
selected={dropdownLabel}
onChoose={this.handleAddEndpoint}
className="dropdown-140 rule-message--add-endpoint"
className="dropdown-200 rule-message--add-endpoint"
/>
</div>
{endpointsOnThisAlert.length
? <div>
? <div className="rule-message--endpoints">
<EndpointTabs
endpointsOnThisAlert={endpointsOnThisAlert}
selectedEndpoint={selectedEndpoint}
handleChooseAlert={this.handleChooseAlert}
handleRemoveEndpoint={this.handleRemoveEndpoint}
/>
<EndpointOptions
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={this.handleModifyEndpoint}

View File

@ -3,9 +3,12 @@ import EndpointInput from 'src/kapacitor/components/EndpointInput'
const AlertaConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Configured Parameters</h4>
</div>
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -3,9 +3,9 @@ import EndpointInput from 'src/kapacitor/components/EndpointInput'
const ExecConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -3,9 +3,9 @@ import EndpointInput from 'src/kapacitor/components/EndpointInput'
const HipchatConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -3,9 +3,9 @@ import EndpointInput from 'src/kapacitor/components/EndpointInput'
const LogConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -3,9 +3,9 @@ import EndpointInput from 'src/kapacitor/components/EndpointInput'
const OpsgenieConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -3,9 +3,9 @@ import EndpointInput from 'src/kapacitor/components/EndpointInput'
const PagerdutyConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -4,9 +4,9 @@ import EndpointCheckbox from 'src/kapacitor/components/EndpointCheckbox'
const HttpConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -3,9 +3,9 @@ import EndpointInput from 'src/kapacitor/components/EndpointInput'
const PushoverConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -3,9 +3,9 @@ import EndpointInput from 'src/kapacitor/components/EndpointInput'
const SmtpConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -3,9 +3,9 @@ import EndpointInput from 'src/kapacitor/components/EndpointInput'
const SensuConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -3,9 +3,9 @@ import EndpointInput from 'src/kapacitor/components/EndpointInput'
const SlackConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Optional Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -3,9 +3,9 @@ import EndpointInput from 'src/kapacitor/components/EndpointInput'
const TcpConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -4,9 +4,9 @@ import EndpointCheckbox from 'src/kapacitor/components/EndpointCheckbox'
const TelegramConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -3,9 +3,9 @@ import EndpointInput from 'src/kapacitor/components/EndpointInput'
const VictoropsConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return (
<div className="rule-section--row rule-section--border-bottom">
<p>Alert Parameters:</p>
<div className="optional-alert-parameters">
<div className="endpoint-tab-contents">
<div className="endpoint-tab--parameters">
<h4>Optional Parameters</h4>
<EndpointInput
selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint}

View File

@ -408,56 +408,128 @@ $rule-builder--radius-lg: 5px;
}
/*
Styles for Rule Message dropdown
Styles for Endpoints section
-----------------------------------------------------------------------------
*/
.rule-message--endpoints {
display: flex;
align-items: stretch;
flex-wrap: nowrap;
}
.rule-message--add-endpoint {
margin-left: 4px;
}
/*
Deletable tabs in .nav-tablist
-----------------------------------------------------------------------------
TODO: Add this into the theme styles
*/
.nav-tab--delete {
display: inline-block;
width: 16px;
height: 16px;
margin-right: -6px;
margin-left: 6px;
border-radius: 3px;
position: relative;
transition: background-color 0.25s ease;
.endpoint-tabs {
width: 260px;
background-color: $rule-builder--section-border;
border-bottom-left-radius: $rule-builder--radius-lg;
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
overflow: hidden;
}
.endpoint-tab {
display: block;
list-style: none;
@include no-user-select();
position: relative;
height: 40px;
line-height: 40px;
padding: 0 $rule-builder--padding-lg;
margin: 0 0 2px 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: $g9-mountain;
font-size: 14.5px;
font-weight: 600;
border-right: 2px solid $rule-builder--section-border;
transition:
color 0.25s ease,
background-color 0.25s ease,
border-color 0.25s ease;
&:last-child {
margin-bottom: 0px;
}
&:hover {
cursor: pointer;
background-color: $rule-builder--section-bg;
color: $g15-platinum;
}
&.active {
color: $c-rainforest;
background-color: $rule-builder--section-bg;
border-color: $rule-builder--section-bg;
}
}
.endpoint-tab--delete {
position: absolute;
top: 50%;
right: 10px;
transform: translateY(-50%);
width: 20px;
height: 20px;
border-radius: 3px;
transition: background-color 0.25s ease;
outline: none;
background-color: transparent;
border: none;
// Psuedo elements used to form the X
&:before,
&:after {
content: '';
position: absolute;
top: 50%;
left: 50%;
background-color: $g7-graphite;
width: 10px;
height: 2px;
background-color: $g8-storm;
border-radius: 1px;
transform: translate(-50%,-50%) rotate(45deg);
transition: background-color 0.25s ease;
}
&:before {transform: translate(-50%,-50%) rotate(45deg);}
&:after {transform: translate(-50%,-50%) rotate(-45deg);}
}
.nav-tablist li:hover .nav-tab--delete,
.nav-tablist li.active .nav-tab--delete {
&:before, &:after {
background-color: $g11-sidewalk;
&:before {
width: 12px;
height: 2px;
}
&:after {
width: 2px;
height: 12px;
}
&:hover {
background-color: $g5-pepper;
cursor: pointer;
&:before,
&:after {background-color: $g20-white;}
}
&:hover:active {
background-color: $c-curacao;
&:before, &:after {
background-color: $g20-white;
}
}
}
.endpoint-tab-contents {
flex: 1 0 0;
background-color: $rule-builder--section-bg;
border-bottom-right-radius: $rule-builder--radius-lg;
display: flex;
flex-direction: column;
align-items: stretch;
h4 {
width: 100%;
margin: 0;
margin-bottom: 8px;
@include no-user-select();
font-size: 14.5px;
font-weight: 600;
color: $g15-platinum;
}
}
.endpoint-tab--parameters {
padding: $rule-builder--padding-lg;
}