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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,9 +3,9 @@ import EndpointInput from 'src/kapacitor/components/EndpointInput'
const VictoropsConfig = ({selectedEndpoint, handleModifyEndpoint}) => { const VictoropsConfig = ({selectedEndpoint, handleModifyEndpoint}) => {
return ( return (
<div className="rule-section--row rule-section--border-bottom"> <div className="endpoint-tab-contents">
<p>Alert Parameters:</p> <div className="endpoint-tab--parameters">
<div className="optional-alert-parameters"> <h4>Optional Parameters</h4>
<EndpointInput <EndpointInput
selectedEndpoint={selectedEndpoint} selectedEndpoint={selectedEndpoint}
handleModifyEndpoint={handleModifyEndpoint} 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 { .rule-message--add-endpoint {
margin-left: 4px; margin-left: 4px;
} }
/* .endpoint-tabs {
Deletable tabs in .nav-tablist width: 260px;
----------------------------------------------------------------------------- background-color: $rule-builder--section-border;
TODO: Add this into the theme styles border-bottom-left-radius: $rule-builder--radius-lg;
*/ display: flex;
.nav-tab--delete { flex-direction: column;
display: inline-block; margin: 0;
width: 16px; padding: 0;
height: 16px; overflow: hidden;
margin-right: -6px; }
margin-left: 6px;
border-radius: 3px; .endpoint-tab {
position: relative; display: block;
transition: background-color 0.25s ease; 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, &:before,
&:after { &:after {
content: ''; content: '';
position: absolute; position: absolute;
top: 50%; top: 50%;
left: 50%; left: 50%;
background-color: $g7-graphite; background-color: $g8-storm;
width: 10px;
height: 2px;
border-radius: 1px; border-radius: 1px;
transform: translate(-50%,-50%) rotate(45deg);
transition: background-color 0.25s ease; transition: background-color 0.25s ease;
} }
&:before {transform: translate(-50%,-50%) rotate(45deg);} &:before {
&:after {transform: translate(-50%,-50%) rotate(-45deg);} width: 12px;
} height: 2px;
.nav-tablist li:hover .nav-tab--delete, }
.nav-tablist li.active .nav-tab--delete { &:after {
&:before, &:after { width: 2px;
background-color: $g11-sidewalk; height: 12px;
} }
&:hover { &:hover {
background-color: $g5-pepper;
cursor: pointer; cursor: pointer;
&:before,
&:after {background-color: $g20-white;}
}
&:hover:active {
background-color: $c-curacao; 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;
}