Update styles to match latest horizon

This makes many small changes to the wizard, tables, form fields
and detail pages to match changes in base horizon.

Partially-Implements: blueprint horizon-lbaas-v2-ui
Change-Id: Id24ed0c6726d13756c5aefebb4b43c27613322c2
This commit is contained in:
Justin Pomeroy 2016-03-03 20:03:13 -06:00
parent d3f799b711
commit 73f1e37304
23 changed files with 689 additions and 837 deletions

View File

@ -1,5 +1,5 @@
<div class="content" ng-controller="HealthMonitorDetailController as ctrl">
<div class='page-header'>
<div ng-controller="HealthMonitorDetailController as ctrl">
<div class="page-header">
<ol class="breadcrumb">
<li><a href="project/ngloadbalancersv2/"><translate>Load Balancers</translate></a></li>
<li><a href="project/ngloadbalancersv2/{$ ::ctrl.loadbalancer.id $}">{$ ::(ctrl.loadbalancer.name || ctrl.loadbalancer.id) $}</a></li>
@ -8,48 +8,30 @@
<li class="active">{$ ::(ctrl.healthmonitor.name || ctrl.healthmonitor.id) $}</li>
</ol>
</div>
<div class="detail-page">
<dl class="dl-horizontal">
<div>
<dt translate>Monitor ID</dt>
<dd>{$ ::ctrl.healthmonitor.id $}</dd>
</div>
<div>
<dt translate>Tenant ID</dt>
<dd>{$ ::ctrl.healthmonitor.tenant_id $}</dd>
</div>
<div>
<div class="row">
<div class="col-md-6 detail">
<dl class="dl-horizontal">
<dt translate>Type</dt>
<dd>{$ ::ctrl.healthmonitor.type $}</dd>
</div>
<div>
<dt translate>HTTP Method</dt>
<dd>{$ ::ctrl.healthmonitor.http_method $}</dd>
</div>
<div>
<dt translate>Admin State Up</dt>
<dd>{$ ::ctrl.healthmonitor.admin_state | yesno $}</dd>
</div>
<div>
<dt translate>Expected Codes</dt>
<dd>{$ ::ctrl.healthmonitor.expected_codes $}</dd>
</div>
<div>
<dt translate>Max Retries</dt>
<dd>{$ ::ctrl.healthmonitor.max_retries $}</dd>
</div>
<div>
<dt translate>Timeout</dt>
<dd>{$ ::ctrl.healthmonitor.timeout $}</dd>
</div>
<div>
<dt translate>Delay</dt>
<dd>{$ ::ctrl.healthmonitor.delay $}</dd>
</div>
<div>
<dt translate>URL Path</dt>
<dd>{$ ::ctrl.healthmonitor.url_path $}</dd>
</div>
</dl>
<dt translate>Max Retries</dt>
<dd>{$ ::ctrl.healthmonitor.max_retries $}</dd>
<dt translate>Timeout</dt>
<dd>{$ ::ctrl.healthmonitor.timeout $}</dd>
<dt translate ng-if="::ctrl.healthmonitor.http_method">HTTP Method</dt>
<dd ng-if="::ctrl.healthmonitor.http_method">{$ ::ctrl.healthmonitor.http_method $}</dd>
<dt translate ng-if="::ctrl.healthmonitor.expected_codes">Expected Codes</dt>
<dd ng-if="::ctrl.healthmonitor.expected_codes">{$ ::ctrl.healthmonitor.expected_codes $}</dd>
<dt translate ng-if="::ctrl.healthmonitor.url_path">URL Path</dt>
<dd ng-if="::ctrl.healthmonitor.url_path">{$ ::ctrl.healthmonitor.url_path $}</dd>
<dt translate>Admin State Up</dt>
<dd>{$ ctrl.healthmonitor.admin_state_up | yesno $}</dd>
<dt translate>Monitor ID</dt>
<dd>{$ ::ctrl.healthmonitor.id $}</dd>
<dt translate>Tenant ID</dt>
<dd>{$ ::ctrl.healthmonitor.tenant_id $}</dd>
</dl>
</div>
</div>
</div>

View File

@ -14,61 +14,22 @@
* limitations under the License.
*/
@import "/app/app";
/*
* TODO(jpomero): This detail page styling should become common with the following patch:
* https://review.openstack.org/158881
*/
.detail-page {
position: relative;
p {
margin-top: 6px;
}
.detail-statuses {
margin-top: 8px;
margin-bottom: 12px;
div {
display: inline;
margin-right: 20px;
> b {
margin-right: 4px;
}
}
}
div.tab-pane > dl {
margin-top: 12px;
}
actions + dl {
clear: both;
}
}
/* Load Balancer Wizard */
.lbaas-wizard {
/* Field widths for editable inputs in the members table */
table {
.member-weight,
.member-port {
width: 6em;
}
.member-address {
width: 20em;
}
div.form-field {
display: inline-block;
}
span.invalid {
vertical-align: top;
margin: 8px 0px 0px 5px;
width: 18em;
}
}
/* The IP addresses list displayed when hovering over the IP address in the
available instances table. */
.addresses-popover + .popover {
ul {
list-style-type: disc;
@ -76,10 +37,11 @@
}
}
/* Listeners tab */
[ng-form="listenerDetailsForm"] {
div.listener-protocol > span.fa-exclamation-triangle {
color: #aaaaaa;
/* Popover help icons for fields in the wizard */
.form-group {
span.fa-exclamation-triangle,
span.fa-question-circle {
color: $gray-light;
}
}
@ -97,6 +59,12 @@
.table-rsp.table-detail.table-striped tbody tr:last-child > td {
background: none;
}
td {
/* So the input fields fit better in the table row */
.form-group {
margin-bottom: 0px;
}
}
}
.transfer-section:last-child {
/* Hide the badge on the bottom table with the instance count. */
@ -106,12 +74,3 @@
}
}
}
/*
TODO(jpomero): The float property is being set to "none" in _debt.scss apparently
to work around a known bootstrap bug, but this appears to break the actions menu
only in angular tables. Setting back to the original value ("left") here for now.
*/
td .btn-group.ng-scope > .btn {
float: left;
}

View File

@ -1,50 +1,39 @@
<div class="content" ng-controller="ListenerDetailController as ctrl">
<div class='page-header'>
<div ng-controller="ListenerDetailController as ctrl">
<div class="page-header">
<ol class="breadcrumb">
<li><a href="project/ngloadbalancersv2/"><translate>Load Balancers</translate></a></li>
<li><a href="project/ngloadbalancersv2/{$ ::ctrl.loadbalancer.id $}">{$ ::(ctrl.loadbalancer.name || ctrl.loadbalancer.id) $}</a></li>
<li class="active">{$ ::(ctrl.listener.name || ctrl.listener.id) $}</li>
<actions allowed="ctrl.actions" type="row" item="ctrl.listener" ng-if="ctrl.listener"
class="actions_column pull-right"></actions>
</ol>
<p ng-if="::ctrl.listener.description">{$ ::ctrl.listener.description $}</p>
</div>
<div class="detail-page">
<actions allowed="ctrl.actions" type="row" item="ctrl.listener" ng-if="ctrl.listener" class="pull-right"></actions>
<dl class="dl-horizontal">
<div>
<dt translate>Listener ID</dt>
<dd>{$ ::ctrl.listener.id $}</dd>
</div>
<div>
<dt translate>Tenant ID</dt>
<dd>{$ ::ctrl.listener.tenant_id $}</dd>
</div>
<div>
<div class="row">
<div class="col-md-6 detail">
<dl class="dl-horizontal">
<dt translate>Protocol</dt>
<dd>{$ ::ctrl.listener.protocol $}</dd>
</div>
<div>
<dt translate>Protocol Port</dt>
<dd>{$ ::ctrl.listener.protocol_port $}</dd>
</div>
<div>
<dt translate>Connection Limit</dt>
<dd>{$ ::ctrl.listener.connection_limit | limit $}</dd>
</div>
<div>
<dd>{$ ctrl.listener.connection_limit | limit $}</dd>
<dt translate>Admin State Up</dt>
<dd>{$ ::ctrl.listener.admin_state_up | yesno $}</dd>
</div>
<div>
<dd>{$ ctrl.listener.admin_state_up | yesno $}</dd>
<dt translate>Default Pool ID</dt>
<dd>
<div ng-if="ctrl.listener.default_pool_id">
<a ng-href="project/ngloadbalancersv2/{$ ::ctrl.loadbalancer.id $}/listeners/{$ ::ctrl.listener.id $}/pools/{$ ::ctrl.listener.default_pool_id $}">{$ ::ctrl.listener.default_pool_id $}</a>
</div>
<div ng-if="!ctrl.listener.default_pool_id">
<a ng-href="project/ngloadbalancersv2/{$ ::ctrl.loadbalancer.id $}/listeners/{$ ::ctrl.listener.id $}/pools/{$ ::ctrl.listener.default_pool_id $}" ng-if="ctrl.listener.default_pool_id">
{$ ::ctrl.listener.default_pool_id $}
</a>
<span ng-if="!ctrl.listener.default_pool_id">
{$ 'None' | translate $}
</div>
</span>
</dd>
</div>
</dl>
<dt translate>Listener ID</dt>
<dd>{$ ::ctrl.listener.id $}</dd>
<dt translate>Tenant ID</dt>
<dd>{$ ::ctrl.listener.tenant_id $}</dd>
</dl>
</div>
</div>
</div>

View File

@ -4,7 +4,7 @@
st-safe-src="table.src"
default-sort="name"
default-sort-reverse="false"
class="table-striped table-rsp table-detail modern">
class="table table-striped table-rsp table-detail">
<!--
TODO(jpomero): This table pattern does not allow for extensibility and should be revisited
once horizon implements a better one.
@ -16,9 +16,8 @@
Table-batch-actions:
This is where batch actions like searching, creating, and deleting.
-->
<th colspan="100" class="search-header">
<hz-search-bar group-classes="input-group-sm" icon-classes="fa-search">
</hz-search-bar>
<th colspan="7" class="search-header">
<hz-search-bar icon-classes="fa-search"></hz-search-bar>
</th>
</tr>
@ -30,7 +29,7 @@
Include expander if you want to inline details.
Include action-col if you want to perform actions.
-->
<th class="select-col">
<th class="multi_select_column">
<input type="checkbox" hz-select-all="table.items">
</th>
@ -40,6 +39,7 @@
<th class="rsp-p1" st-sort="description" translate>Description</th>
<th class="rsp-p1" st-sort="protocol" translate>Protocol</th>
<th class="rsp-p1" st-sort="port" translate>Port</th>
<th class="actions_column" translate>Actions</th>
</tr>
</thead>
@ -55,7 +55,7 @@
<tr ng-repeat-start="item in table.items track by item.id"
ng-class="{'st-selected': checked[item.id]}">
<td class="select-col">
<td class="multi_select_column">
<input type="checkbox"
ng-model="tCtrl.selections[item.id].checked"
hz-select="item">
@ -70,7 +70,7 @@
<td class="rsp-p1">{$ ::item.description | noValue $}</td>
<td class="rsp-p1">{$ ::item.protocol$}</td>
<td class="rsp-p1">{$ ::item.protocol_port$}</td>
<td class="action-col">
<td class="actions_column">
<!--
Table-row-action-column:
Actions taken here apply to a single item/row.
@ -86,7 +86,7 @@
Can be toggled using the chevron button.
Ensure colspan is greater or equal to number of column-headers.
-->
<td class="detail" colspan="100">
<td class="detail" colspan="7">
<div class="row">
<dl class="col-sm-2">

View File

@ -6,11 +6,14 @@
<div class="modal-body">
<p translate>Select a floating IP address to associate with the load balancer or a floating IP pool in which to allocate a new floating IP address.</p>
<div ng-form="form">
<div class="row form-group">
<div class="row">
<div class="col-sm-12 col-md-6">
<div class="form-field required">
<label translate class="on-top" for="floating-ip">Floating IP address or pool</label>
<select class="form-control input-sm" name="floating-ip" id="floating-ip"
<div class="form-group required">
<label translate class="control-label" for="floating-ip">
Floating IP address or pool
<span class="hz-icon-required fa fa-asterisk"></span>
</label>
<select class="form-control" name="floating-ip" id="floating-ip"
ng-options="item.name group by item.group for item in modal.options"
ng-model="modal.selected" ng-required="true">
</select>

View File

@ -1,64 +1,54 @@
<div class="content" ng-controller="LoadBalancerDetailController as ctrl">
<div class='page-header'>
<div ng-controller="LoadBalancerDetailController as ctrl">
<div class="page-header">
<ol class="breadcrumb">
<li><a href="project/ngloadbalancersv2/"><translate>Load Balancers</translate></a></li>
<li class="active">{$ (ctrl.loadbalancer.name || ctrl.loadbalancer.id) $}</li>
<actions allowed="ctrl.actions" type="row" item="ctrl.loadbalancer"
ng-if="ctrl.loadbalancer" class="actions_column pull-right"></actions>
</ol>
<p ng-if="::ctrl.loadbalancer.description">{$ ::ctrl.loadbalancer.description $}</p>
</div>
<div class="detail-page">
<actions allowed="ctrl.actions" type="row" item="ctrl.loadbalancer"
ng-if="ctrl.loadbalancer" class="pull-right"></actions>
<div class="detail-statuses">
<div>
<ul class="list-inline">
<li>
<strong translate>IP Address</strong>
{$ ::ctrl.loadbalancer.vip_address $}
</div>
<div>
</li>
<li ng-if="ctrl.image.properties.filename">
<strong translate>Operating Status</strong>
{$ ::ctrl.loadbalancer.operating_status | decode:ctrl.operatingStatus $}
</div>
<div>
</li>
<li>
<strong translate>Provisioning Status</strong>
{$ ::ctrl.loadbalancer.provisioning_status | decode:ctrl.provisioningStatus $}
</div>
</div>
<tabset>
<tab heading="{$ 'Overview' | translate $}">
<dl class="dl-horizontal">
<div>
</li>
</ul>
</div>
<tabset>
<tab heading="{$ 'Overview' | translate $}">
<div class="row">
<div class="col-md-6 detail">
<dl class="dl-horizontal">
<dt translate>Provider</dt>
<dd>{$ ::ctrl.loadbalancer.provider $}</dd>
</div>
<div>
<dt translate>Admin State Up</dt>
<dd>{$ ctrl.loadbalancer.admin_state_up | yesno $}</dd>
</div>
<div ng-if="ctrl.loadbalancer.floating_ip !== undefined">
<dt translate>Floating IP Address</dt>
<dd>{$ ctrl.loadbalancer.floating_ip.ip || 'None' | translate $}</dd>
</div>
<div>
<dt translate ng-if="ctrl.loadbalancer.floating_ip !== undefined">Floating IP Address</dt>
<dd ng-if="ctrl.loadbalancer.floating_ip !== undefined">{$ ctrl.loadbalancer.floating_ip.ip || 'None' | translate $}</dd>
<dt translate>Load Balancer ID</dt>
<dd>{$ ::ctrl.loadbalancer.id $}</dd>
</div>
<div>
<dt translate>Subnet ID</dt>
<dd>
<a target="_self" ng-href="project/networks/subnets/{$ ::ctrl.loadbalancer.vip_subnet_id $}/detail">{$ ::ctrl.loadbalancer.vip_subnet_id $}</a>
</dd>
</div>
<div>
<dt translate>Port ID</dt>
<dd>
<a target="_self" ng-href="project/networks/ports/{$ ::ctrl.loadbalancer.vip_port_id $}/detail">{$ ::ctrl.loadbalancer.vip_port_id $}</a>
</dd>
</div>
</dl>
</tab>
<tab heading="{$ 'Listeners' | translate $}">
<ng-include src="'static/dashboard/project/lbaasv2/listeners/table.html'"></ng-include>
</tab>
</tabset>
</div>
</dl>
</div>
</div>
</tab>
<tab heading="{$ 'Listeners' | translate $}">
<ng-include src="'static/dashboard/project/lbaasv2/listeners/table.html'"></ng-include>
</tab>
</tabset>
</div>

View File

@ -6,7 +6,7 @@
st-safe-src="table.src"
default-sort="name"
default-sort-reverse="false"
class="table-striped table-rsp table-detail modern">
class="table table-striped table-rsp table-detail">
<!--
TODO(jpomero): This table pattern does not allow for extensibility and should be revisited
once horizon implements a better one.
@ -18,8 +18,8 @@
Table-batch-actions:
This is where batch actions like searching, creating, and deleting.
-->
<th colspan="100" class="search-header">
<hz-search-bar group-classes="input-group-sm" icon-classes="fa-search">
<th colspan="9" class="search-header">
<hz-search-bar icon-classes="fa-search">
<actions allowed="table.batchActions.actions" type="batch"></actions>
</hz-search-bar>
</th>
@ -33,7 +33,7 @@
Include expander if you want to inline details.
Include action-col if you want to perform actions.
-->
<th class="select-col">
<th class="multi_select_column">
<input type="checkbox" hz-select-all="table.items">
</th>
@ -45,6 +45,7 @@
<th class="rsp-p1" st-sort="provisioning_status" translate>Provisioning Status</th>
<th class="rsp-p2" st-sort="vip_address" translate>IP Address</th>
<th class="rsp-p2" st-sort="listeners.length" translate>Listeners</th>
<th class="actions_column" translate>Actions</th>
</tr>
</thead>
@ -60,7 +61,7 @@
<tr ng-repeat-start="item in table.items track by item.id"
ng-class="{'st-selected': checked[item.id]}">
<td class="select-col">
<td class="multi_select_column">
<input type="checkbox"
ng-model="tCtrl.selections[item.id].checked"
hz-select="item">
@ -77,7 +78,7 @@
<td class="rsp-p1">{$ ::item.provisioning_status | decode:table.provisioningStatus $}</td>
<td class="rsp-p2">{$ ::item.vip_address $}</td>
<td class="rsp-p2">{$ item.listeners.length $}</td>
<td class="action-col">
<td class="actions_column">
<!--
Table-row-action-column:
Actions taken here apply to a single item/row.
@ -93,7 +94,7 @@
Can be toggled using the chevron button.
Ensure colspan is greater or equal to number of column-headers.
-->
<td class="detail" colspan="100">
<td class="detail" colspan="9">
<!--
The responsive columns that disappear typically should reappear here
with the same responsive priority that they disappear.

View File

@ -1,5 +1,5 @@
<div class="content" ng-controller="MemberDetailController as ctrl">
<div class='page-header'>
<div ng-controller="MemberDetailController as ctrl">
<div class="page-header">
<ol class="breadcrumb">
<li><a href="project/ngloadbalancersv2/"><translate>Load Balancers</translate></a></li>
<li><a href="project/ngloadbalancersv2/{$ ::ctrl.loadbalancer.id $}">{$ ::(ctrl.loadbalancer.name || ctrl.loadbalancer.id) $}</a></li>
@ -8,32 +8,22 @@
<li class="active">{$ ::(ctrl.member.name || ctrl.member.id) $}</li>
</ol>
</div>
<div class="detail-page">
<dl class="dl-horizontal">
<div>
<dt translate>Member ID</dt>
<dd>{$ ::ctrl.member.id $}</dd>
</div>
<div>
<dt translate>Tenant ID</dt>
<dd>{$ ::ctrl.member.tenant_id $}</dd>
</div>
<div>
<div class="row">
<div class="col-md-6 detail">
<dl class="dl-horizontal">
<dt translate>Protocol Port</dt>
<dd>{$ ::ctrl.member.protocol_port $}</dd>
</div>
<div>
<dt translate>Admin State Up</dt>
<dd>{$ ::ctrl.member.admin_state_up | yesno $}</dd>
</div>
<div>
<dt translate>Address</dt>
<dd>{$ ::ctrl.member.address $}</dd>
</div>
<div>
<dt translate>Weight</dt>
<dd>{$ ::ctrl.member.weight $}</dd>
</div>
</dl>
<dt translate>Admin State Up</dt>
<dd>{$ ctrl.member.admin_state_up | yesno $}</dd>
<dt translate>Member ID</dt>
<dd>{$ ::ctrl.member.id $}</dd>
<dt translate>Tenant ID</dt>
<dd>{$ ::ctrl.member.tenant_id $}</dd>
</dl>
</div>
</div>
</div>

View File

@ -4,7 +4,7 @@
st-safe-src="table.src"
default-sort="id"
default-sort-reverse="false"
class="table-striped table-rsp table-detail modern">
class="table table-striped table-rsp table-detail">
<!--
TODO(jpomero): This table pattern does not allow for extensibility and should be revisited
once horizon implements a better one.
@ -16,9 +16,8 @@
Table-batch-actions:
This is where batch actions like searching, creating, and deleting.
-->
<th colspan="100" class="search-header">
<hz-search-bar group-classes="input-group-sm" icon-classes="fa-search">
</hz-search-bar>
<th colspan="5" class="search-header">
<hz-search-bar icon-classes="fa-search"></hz-search-bar>
</th>
</tr>
@ -30,7 +29,7 @@
Include expander if you want to inline details.
Include action-col if you want to perform actions.
-->
<th class="select-col">
<th class="multi_select_column">
<input type="checkbox" hz-select-all="table.items">
</th>
@ -53,7 +52,7 @@
<tr ng-repeat="item in table.items track by item.id"
ng-class="{'st-selected': checked[item.id]}">
<td class="select-col">
<td class="multi_select_column">
<input type="checkbox"
ng-model="tCtrl.selections[item.id].checked"
hz-select="item">

View File

@ -1,5 +1,5 @@
<div class="content" ng-controller="PoolDetailController as ctrl">
<div class='page-header'>
<div ng-controller="PoolDetailController as ctrl">
<div class="page-header">
<ol class="breadcrumb">
<li><a href="project/ngloadbalancersv2/"><translate>Load Balancers</translate></a></li>
<li><a href="project/ngloadbalancersv2/{$ ::ctrl.loadbalancer.id $}">{$ ::(ctrl.loadbalancer.name || ctrl.loadbalancer.id) $}</a></li>
@ -8,57 +8,38 @@
</ol>
<p ng-if="::ctrl.pool.description">{$ ::ctrl.pool.description $}</p>
</div>
<div class="detail-page">
<tabset>
<tab heading="{$ 'Overview' | translate $}">
<dl class="dl-horizontal">
<div>
<dt translate>Pool ID</dt>
<dd>{$ ::ctrl.pool.id $}</dd>
</div>
<div>
<dt translate>Admin State Up</dt>
<dd>{$ ::ctrl.pool.admin_state_up | yesno $}</dd>
</div>
<div>
<dt translate>Tenant ID</dt>
<dd>{$ ::ctrl.pool.tenant_id $}</dd>
</div>
<div>
<tabset>
<tab heading="{$ 'Overview' | translate $}">
<div class="row">
<div class="col-md-6 detail">
<dl class="dl-horizontal">
<dt translate>Protocol</dt>
<dd>{$ ::ctrl.pool.protocol $}</dd>
</div>
<div>
<dt translate>Load Balancer Algorithm</dt>
<dd>{$ ctrl.pool.lb_algorithm | decode:ctrl.loadBalancerAlgorithm $}</dd>
</div>
<div>
<dt translate>Session Persistence</dt>
<dd>
<div ng-if="ctrl.pool.session_persistence">
{$ ::ctrl.pool.session_persistence $}
</div>
<div ng-if="!ctrl.pool.session_persistence">
{$ 'None' | translate $}
</div>
</dd>
</div>
<div>
<dd>{$ ctrl.pool.session_persistence | noValue:('None' | translate) $}</dd>
<dt translate>Admin State Up</dt>
<dd>{$ ctrl.pool.admin_state_up | yesno $}</dd>
<dt translate>Health Monitor ID</dt>
<dd>
<div ng-if="ctrl.pool.healthmonitor_id">
<a ng-href="project/ngloadbalancersv2/{$ ::ctrl.loadbalancer.id $}/listeners/{$ ::ctrl.listener.id $}/pools/{$ ::ctrl.pool.id $}/healthmonitors/{$ ::ctrl.pool.healthmonitor_id $}">{$ ::ctrl.pool.healthmonitor_id $}</a>
</div>
<div ng-if="!ctrl.pool.healthmonitor_id">
<a ng-href="project/ngloadbalancersv2/{$ ::ctrl.loadbalancer.id $}/listeners/{$ ::ctrl.listener.id $}/pools/{$ ::ctrl.pool.id $}/healthmonitors/{$ ::ctrl.pool.healthmonitor_id $}" ng-if="ctrl.pool.healthmonitor_id">
{$ ::ctrl.pool.healthmonitor_id $}
</a>
<span ng-if="!ctrl.pool.healthmonitor_id">
{$ 'None' | translate $}
</div>
</span>
</dd>
</div>
</dl>
</tab>
<tab heading="{$ 'Members' | translate $}">
<ng-include src="'static/dashboard/project/lbaasv2/members/table.html'"></ng-include>
</tab>
</tabset>
</div>
<dt translate>Pool ID</dt>
<dd>{$ ::ctrl.pool.id $}</dd>
<dt translate>Tenant ID</dt>
<dd>{$ ::ctrl.pool.tenant_id $}</dd>
</dl>
</div>
</div>
</tab>
<tab heading="{$ 'Members' | translate $}">
<ng-include src="'static/dashboard/project/lbaasv2/members/table.html'"></ng-include>
</tab>
</tabset>
</div>

View File

@ -1,3 +1,5 @@
<h1 translate>SSL Certificates Help</h1>
<p translate>If the listener uses the TERMINATED_HTTPS protocol, then one or more SSL certificates must be selected. The first certificate will be the default. Use the key-manager service to create any certificate containers before creating the listener.</p>
<p translate>
If the listener uses the TERMINATED_HTTPS protocol, then one or more SSL certificates must
be selected. The first certificate will be the default. Use the key-manager service to create
any certificate containers before creating the listener.
</p>

View File

@ -1,94 +1,88 @@
<div ng-controller="CertificatesController as ctrl">
<h1 translate>SSL Certificates</h1>
<p translate>Select one or more SSL certificates for the listener.</p>
<!--content-->
<div class="content">
<div translate class="subtitle">Select one or more SSL certificates for the listener.</div>
<transfer-table tr-model="ctrl.tableData"
limits="::ctrl.tableLimits"
help-text="::ctrl.tableHelp">
<transfer-table tr-model="ctrl.tableData"
limits="::ctrl.tableLimits"
help-text="::ctrl.tableHelp">
<!-- Allocated-->
<allocated validate-number-min="1" ng-model="ctrl.tableData.allocated.length">
<table st-table="ctrl.tableData.displayedAllocated"
st-safe-src="ctrl.tableData.allocated" hz-table
class="table table-striped table-rsp table-detail">
<thead>
<tr>
<th class="rsp-p1" translate>Certificate Name</th>
<th class="rsp-p1" translate>Expiration Date</th>
<th class="actions_column"></th>
</tr>
</thead>
<tbody>
<tr ng-if="ctrl.tableData.allocated.length === 0">
<td colspan="3">
<div class="no-rows-help">
{$ ::trCtrl.helpText.noneAllocText $}
</div>
</td>
</tr>
<tr ng-repeat="row in ctrl.tableData.displayedAllocated track by row.id">
<td class="rsp-p1">{$ ::row.name $}</td>
<td class="rsp-p1">{$ row.expiration | date | noValue $}</td>
<td class="actions_column">
<action-list>
<action action-classes="'btn btn-sm btn-default'"
callback="trCtrl.deallocate" item="row">
<span class="fa fa-minus"></span>
</action>
</action-list>
</td>
</tr>
</tbody>
</table>
</allocated>
<!-- Allocated-->
<allocated validate-number-min="1" ng-model="ctrl.tableData.allocated.length">
<table st-table="ctrl.tableData.displayedAllocated"
st-safe-src="ctrl.tableData.allocated" hz-table
class="table-striped table-rsp table-detail modern form-group">
<thead>
<tr>
<th class="rsp-p1" translate>Certificate Name</th>
<th class="rsp-p1" translate>Expiration Date</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-if="ctrl.tableData.allocated.length === 0">
<td colspan="100">
<div class="no-rows-help">
{$ ::trCtrl.helpText.noneAllocText $}
</div>
</td>
</tr>
<tr ng-repeat="row in ctrl.tableData.displayedAllocated track by row.id">
<td class="rsp-p1">{$ ::row.name $}</td>
<td class="rsp-p1">{$ ::row.expiration | date | noValue $}</td>
<td class="action-col">
<action-list>
<action action-classes="'btn btn-sm btn-default'"
callback="trCtrl.deallocate" item="row">
<span class="fa fa-minus"></span>
</action>
</action-list>
</td>
</tr>
</tbody>
</table>
</allocated>
<!-- Available -->
<available>
<table st-table="ctrl.tableData.displayedAvailable"
st-safe-src="ctrl.tableData.available"
hz-table class="table table-striped table-rsp table-detail">
<thead>
<tr>
<th class="search-header" colspan="3">
<hz-search-bar icon-classes="fa-search"></hz-search-bar>
</th>
</tr>
<tr>
<th st-sort="name" st-sort-default class="rsp-p1" translate>Certificate Name</th>
<th class="rsp-p1" translate>Expiration Date</th>
<th class="actions_column"></th>
</tr>
</thead>
<tbody>
<tr ng-if="trCtrl.numAvailable() === 0">
<td colspan="3">
<div class="no-rows-help">
{$ ::trCtrl.helpText.noneAvailText $}
</div>
</td>
</tr>
<tr ng-repeat="row in ctrl.tableData.displayedAvailable track by row.id"
ng-if="!trCtrl.allocatedIds[row.id]">
<td class="rsp-p1">{$ ::row.name $}</td>
<td class="rsp-p1">{$ row.expiration | date | noValue $}</td>
<td class="actions_column">
<action-list>
<action action-classes="'btn btn-sm btn-default'"
callback="trCtrl.allocate" item="row">
<span class="fa fa-plus"></span>
</action>
</action-list>
</td>
</tr>
</tbody>
</table>
</available>
<!-- Available -->
<available>
<table st-table="ctrl.tableData.displayedAvailable"
st-safe-src="ctrl.tableData.available"
hz-table class="table-striped table-rsp table-detail modern">
<thead>
<tr>
<th class="search-header" colspan="100">
<hz-search-bar group-classes="input-group-sm" icon-classes="fa-search">
</hz-search-bar>
</th>
</tr>
<tr>
<th st-sort="name" st-sort-default class="rsp-p1" translate>Certificate Name</th>
<th class="rsp-p1" translate>Expiration Date</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-if="trCtrl.numAvailable() === 0">
<td colspan="100">
<div class="no-rows-help">
{$ ::trCtrl.helpText.noneAvailText $}
</div>
</td>
</tr>
<tr ng-repeat="row in ctrl.tableData.displayedAvailable track by row.id"
ng-if="!trCtrl.allocatedIds[row.id]">
<td class="rsp-p1">{$ ::row.name $}</td>
<td class="rsp-p1">{$ ::row.expiration | date | noValue $}</td>
<td class="action-col">
<action-list>
<action action-classes="'btn btn-sm btn-default'"
callback="trCtrl.allocate" item="row">
<span class="fa fa-plus"></span>
</action>
</action-list>
</td>
</tr>
</tbody>
</table>
</available>
</transfer-table>
</transfer-table> <!-- End Transfer Table -->
</div> <!-- end content -->
</div>

View File

@ -1,4 +1,8 @@
<h1 translate>Listener Details Help</h1>
<p translate>A listener represents a listening endpoint for a load balancer. A single load balancer can have multiple listeners.</p>
<p translate><strong>NOTE:</strong> The TERMINATED_HTTPS protocol is only available if the key-manager service is enabled and you have authority to list certificate containers and secrets.</p>
<p translate>
A listener represents a listening endpoint for a load balancer. A single load balancer can
have multiple listeners.
</p>
<p translate>
<strong>NOTE:</strong> The TERMINATED_HTTPS protocol is only available if the key-manager
service is enabled and you have authority to list certificate containers and secrets.
</p>

View File

@ -1,70 +1,64 @@
<div ng-controller="ListenerDetailsController as ctrl">
<h1 translate>Listener Details</h1>
<p translate>Provide the details for the listener.</p>
<!--content-->
<div class="content">
<div translate class="subtitle">Provide the details for the listener.</div>
<div class="row">
<div class="row form-group">
<div class="col-xs-12 col-sm-8 col-md-6">
<div class="form-group">
<label translate class="control-label" for="name">Name</label>
<input name="name" id="name" type="text" class="form-control"
ng-model="model.spec.listener.name">
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-field listener-name">
<label translate class="on-top" for="listener-name">Name</label>
<input name="listener-name" id="listener-name"
type="text" class="form-control input-sm"
ng-model="model.spec.listener.name">
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-field listener-description">
<label translate class="on-top" for="listener-description">Description</label>
<input name="listener-description" id="listener-description"
type="text" class="form-control input-sm"
ng-model="model.spec.listener.description">
</div>
</div>
</div>
<div class="row form-group">
<div class="col-sm-6 col-md-3">
<div class="form-field required listener-protocol">
<label translate class="on-top" for="listener-protocol">Protocol</label>
<span class="fa fa-exclamation-triangle invalid"
ng-show="model.certificatesError"
popover="{$ ::ctrl.certificatesError $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<select class="form-control input-sm" name="listener-protocol" id="listener-protocol"
ng-model="model.spec.listener.protocol" ng-required="true"
ng-change="ctrl.protocolChange(model.spec.listener.protocol)"
ng-disabled="model.context.id">
<option ng-repeat="protocol in model.listenerProtocols" value="{$ protocol $}"
ng-disabled="protocol==='TERMINATED_HTTPS' && model.certificatesError">{$ protocol $}</option>
</select>
</div>
</div>
<div class="col-sm-6 col-md-3">
<div class="form-field required listener-port"
ng-class="{ 'has-error': listenerDetailForm['listener-port'].$invalid && listenerDetailForm['listener-port'].$dirty }">
<label translate class="on-top" for="listener-port">Port</label>
<span class="fa fa-exclamation-triangle invalid"
ng-show="listenerDetailForm['listener-port'].$invalid && listenerDetailForm.$dirty"
popover="{$ ::ctrl.portError $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<input name="listener-port" id="listener-port"
type="number" class="form-control input-sm"
ng-model="model.spec.listener.port" ng-pattern="/^\d+$/" min="1" max="65535"
ng-required="true" ng-disabled="model.context.id">
</div>
</div>
</div>
<div class="col-xs-12 col-sm-8 col-md-6">
<div class="form-group">
<label translate class="control-label" for="description">Description</label>
<input name="description" id="description" type="text" class="form-control"
ng-model="model.spec.listener.description">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-8 col-md-6">
<div class="form-group required">
<label translate class="control-label" for="protocol">
Protocol
<span class="hz-icon-required fa fa-asterisk"></span>
</label>
<span class="fa fa-exclamation-triangle invalid"
ng-show="model.certificatesError"
popover="{$ ::ctrl.certificatesError $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<select class="form-control" name="protocol" id="protocol"
ng-model="model.spec.listener.protocol" ng-required="true"
ng-change="ctrl.protocolChange(model.spec.listener.protocol)"
ng-disabled="model.context.id">
<option ng-repeat="protocol in model.listenerProtocols" value="{$ protocol $}"
ng-disabled="protocol==='TERMINATED_HTTPS' && model.certificatesError">{$ protocol $}</option>
</select>
</div>
</div>
<div class="col-xs-12 col-sm-8 col-md-6">
<div class="form-group required"
ng-class="{ 'has-error': listenerDetailsForm.port.$invalid && listenerDetailsForm.port.$dirty }">
<label translate class="control-label" for="port">
Port
<span class="hz-icon-required fa fa-asterisk"></span>
</label>
<input name="port" id="port" type="number" class="form-control"
ng-model="model.spec.listener.port" ng-pattern="/^\d+$/" min="1" max="65535"
ng-required="true" ng-disabled="model.context.id">
<span class="help-block" ng-show="listenerDetailsForm.port.$invalid && listenerDetailsForm.port.$dirty">
{$ ::ctrl.portError $}
</span>
</div>
</div>
</div>
<!-- end content -->
</div>

View File

@ -1,3 +1,5 @@
<h1 translate>Load Balancer Details Help</h1>
<p translate>The subnet is the network on which to allocate the load balancer's IP address. If an IP address is provided it must be a well-formed IPv4 or IPv6 address. The system will attempt to assign the provided IP address to the load balancer.</p>
<p translate>
The subnet is the network on which to allocate the load balancer's IP address. If an IP
address is provided it must be a well-formed IPv4 or IPv6 address. The system will attempt
to assign the provided IP address to the load balancer.
</p>

View File

@ -1,63 +1,54 @@
<div ng-controller="LoadBalancerDetailsController as ctrl">
<h1 translate>Load Balancer Details</h1>
<p translate>Provide the details for the load balancer.</p>
<!--content-->
<div class="content">
<div translate class="subtitle">Provide the details for the load balancer.</div>
<div class="row">
<div class="row form-group">
<div class="col-sm-12 col-md-6">
<div class="form-field loadbalancer-name"
ng-class="{ 'has-error': loadBalancerDetailsForm['loadbalancer-name'].$invalid && loadBalancerDetailsForm['loadbalancer-name'].$dirty }">
<label translate class="on-top" for="loadbalancer-name">Name</label>
<input name="loadbalancer-name" id="loadbalancer-name"
type="text" class="form-control input-sm"
ng-model="model.spec.loadbalancer.name">
</div>
</div>
<div class="col-xs-12 col-sm-8 col-md-6">
<div class="form-group">
<label translate class="control-label" for="name">Name</label>
<input name="name" id="name" type="text" class="form-control"
ng-model="model.spec.loadbalancer.name">
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-field loadbalancer-description">
<label translate class="on-top" for="loadbalancer-description">Description</label>
<input name="loadbalancer-description" id="loadbalancer-description"
type="text" class="form-control input-sm"
ng-model="model.spec.loadbalancer.description">
</div>
</div>
</div>
<div class="row form-group">
<div class="col-sm-6 col-md-3">
<div class="form-field loadbalancer-ip"
ng-class="{ 'has-error': loadBalancerDetailsForm['loadbalancer-ip'].$invalid && loadBalancerDetailsForm['loadbalancer-ip'].$dirty }">
<label translate class="on-top" for="loadbalancer-ip">IP Address</label>
<span class="fa fa-exclamation-triangle invalid"
ng-show="loadBalancerDetailsForm['loadbalancer-ip'].$invalid && loadBalancerDetailsForm.$dirty"
popover="{$ ::ctrl.ipError $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<input name="loadbalancer-ip" id="loadbalancer-ip"
type="text" class="form-control input-sm"
ng-model="model.spec.loadbalancer.ip" ng-pattern="::ctrl.ipPattern"
ng-disabled="model.context.id">
</div>
</div>
<div class="col-sm-6 col-md-3">
<div class="form-field required loadbalancer-subnet">
<label translate class="on-top" for="loadbalancer-subnet">Subnet</label>
<select class="form-control input-sm" name="loadbalancer-subnet"
id="loadbalancer-subnet"
ng-options="subnet.name for subnet in model.subnets"
ng-model="model.spec.loadbalancer.subnet" ng-required="true"
ng-disabled="model.context.id">
</select>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-8 col-md-6">
<div class="form-group">
<label translate class="control-label" for="description">Description</label>
<input name="description" id="description" type="text" class="form-control"
ng-model="model.spec.loadbalancer.description">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-8 col-md-6">
<div class="form-group"
ng-class="{ 'has-error': loadBalancerDetailsForm.ip.$invalid && loadBalancerDetailsForm.ip.$dirty }">
<label translate class="control-label" for="ip">IP Address</label>
<input name="ip" id="ip" type="text" class="form-control"
ng-model="model.spec.loadbalancer.ip" ng-pattern="::ctrl.ipPattern"
ng-disabled="model.context.id">
<span class="help-block" ng-show="loadBalancerDetailsForm.ip.$invalid && loadBalancerDetailsForm.ip.$dirty">
{$ ::ctrl.ipError $}
</span>
</div>
</div>
<div class="col-xs-12 col-sm-8 col-md-6">
<div class="form-group required">
<label translate class="control-label" for="subnet">
Subnet
<span class="hz-icon-required fa fa-asterisk"></span>
</label>
<select class="form-control" name="subnet" id="subnet"
ng-options="subnet.name for subnet in model.subnets"
ng-model="model.spec.loadbalancer.subnet" ng-required="true"
ng-disabled="model.context.id">
</select>
</div>
</div>
</div>
<!-- end content -->
</div>

View File

@ -1,4 +1,8 @@
<h1 translate>Pool Members Help</h1>
<p translate>The Available Instances table contains existing instances that can be added as members of the pool. Use the "Add external member" button to add a member not found in the Available Instances table.</p>
<p translate>Each member must have a unique combination of IP address and port.</p>
<p translate>
The Available Instances table contains existing instances that can be added as members of
the pool. Use the "Add external member" button to add a member not found in the Available
Instances table.
</p>
<p translate>
Each member must have a unique combination of IP address and port.
</p>

View File

@ -1,182 +1,165 @@
<div ng-controller="MemberDetailsController as ctrl">
<h1 translate>Pool Members</h1>
<p translate>Add members to the load balancer pool.</p>
<transfer-table tr-model="ctrl.tableData"
limits="::ctrl.tableLimits"
help-text="::ctrl.tableHelp">
<!--content-->
<div class="content">
<div translate class="subtitle">Add members to the load balancer pool.</div>
<transfer-table tr-model="ctrl.tableData"
limits="::ctrl.tableLimits"
help-text="::ctrl.tableHelp">
<!-- Allocated-->
<allocated>
<table st-table="ctrl.tableData.displayedAllocated"
st-safe-src="ctrl.tableData.allocated" hz-table
class="table table-striped table-rsp table-detail">
<thead>
<tr>
<th class="rsp-p1" translate>
IP Address
<span class="hz-icon-required fa fa-asterisk" ng-show="ctrl.tableData.displayedAllocated.length > 0">
</th>
<th class="rsp-p1" translate>
Subnet
<span class="hz-icon-required fa fa-asterisk" ng-show="ctrl.tableData.displayedAllocated.length > 0">
</th>
<th class="rsp-p1">
Port
<span class="hz-icon-required fa fa-asterisk" ng-show="ctrl.tableData.displayedAllocated.length > 0">
</th>
<th class="rsp-p1" translate>Weight</th>
<th class="actions_column"></th>
</tr>
</thead>
<tbody>
<tr ng-if="ctrl.tableData.allocated.length === 0">
<td colspan="5">
<div class="no-rows-help">
{$ ::trCtrl.helpText.noneAllocText $}
</div>
</td>
</tr>
<tr ng-repeat="row in ctrl.tableData.displayedAllocated track by row.id">
<td class="rsp-p1">
<div ng-if="!row.addresses"
class="form-group required member-address"
ng-class="{ 'has-error': memberDetailsForm['{$ ::row.id $}-address'].$invalid && memberDetailsForm['{$ ::row.id $}-address'].$dirty }">
<input name="{$ ::row.id $}-address" type="text" class="form-control"
ng-model="row.address" ng-pattern="::ctrl.ipPattern"
ng-required="true" ng-disabled="model.context.id && row.allocatedMember"
popover-placement="top" popover-append-to-body="true"
popover-trigger="focus"
ng-attr-popover="{$ memberDetailsForm[row.id + '-address'].$invalid && memberDetailsForm[row.id + '-address'].$dirty ? ctrl.ipError : '' $}">
</div>
<span ng-if="row.addresses.length === 1">{$ row.address.ip $}</span>
<div ng-if="row.addresses.length > 1"
class="form-group required member-address">
<select class="form-control input-sm"
ng-options="addr.ip for addr in row.addresses"
ng-model="row.address" ng-required="true" ng-if="row.addresses">
</select>
</div>
</td>
<td class="rsp-p1">
<div ng-if="!row.addresses" class="form-group required">
<select name="{$ ::row.id $}-subnet" class="form-control"
ng-options="subnet.name for subnet in model.subnets"
ng-model="row.subnet" ng-required="true"
ng-disabled="model.context.id && row.allocatedMember">
</select>
</div>
<span ng-if="row.addresses">{$ ctrl.getSubnetName(row) $}</span>
</td>
<td class="rsp-p1">
<div class="form-group required member-port"
ng-class="{ 'has-error': memberDetailsForm['{$ ::row.id $}-port'].$invalid && memberDetailsForm['{$ ::row.id $}-port'].$dirty }">
<input name="{$ ::row.id $}-port" type="number" class="form-control"
ng-model="row.port" ng-pattern="/^\d+$/" min="1" max="65535"
ng-required="true" ng-disabled="model.context.id && row.allocatedMember"
popover-placement="top" popover-append-to-body="true"
popover-trigger="focus"
ng-attr-popover="{$ memberDetailsForm[row.id + '-port'].$invalid && memberDetailsForm[row.id + '-port'].$dirty ? ctrl.portError : '' $}">
</div>
</td>
<td class="rsp-p1">
<div class="form-group member-weight"
ng-class="{ 'has-error': memberDetailsForm['{$ ::row.id $}-weight'].$invalid && memberDetailsForm['{$ ::row.id $}-weight'].$dirty }">
<input name="{$ ::row.id $}-weight" type="number" class="form-control"
ng-model="row.weight" ng-pattern="/^\d+$/" min="1" max="256"
ng-disabled="model.context.id && row.allocatedMember"
popover-placement="top" popover-append-to-body="true"
popover-trigger="focus"
ng-attr-popover="{$ memberDetailsForm[row.id + '-weight'].$invalid && memberDetailsForm[row.id + '-weight'].$dirty ? ctrl.weightError : '' $}">
</div>
</td>
<td class="actions_column">
<action-list>
<action action-classes="'btn btn-sm btn-default'"
callback="ctrl.deallocateMember" item="row">
<span translate>Remove</span>
</action>
</action-list>
</td>
</tr>
<tr>
<td colspan="5">
<action-list class="pull-right">
<action action-classes="'btn btn-sm btn-default'"
callback="ctrl.allocateExternalMember">
<span translate>Add external member</span>
</action>
</action-list>
</td>
</tr>
</tbody>
</table>
</allocated>
<!-- Allocated-->
<allocated>
<table st-table="ctrl.tableData.displayedAllocated"
st-safe-src="ctrl.tableData.allocated" hz-table
class="table-striped table-rsp table-detail modern form-group">
<thead>
<tr>
<th class="rsp-p1"
ng-class="{ 'required': ctrl.tableData.displayedAllocated.length > 0 }">
<label translate>IP Address</label>
</th>
<th class="rsp-p1"
ng-class="{ 'required': ctrl.tableData.displayedAllocated.length > 0 }">
<label translate>Subnet</label>
</th>
<th class="rsp-p1"
ng-class="{ 'required': ctrl.tableData.displayedAllocated.length > 0 }">
<label translate>Port</label>
</th>
<th class="rsp-p1" translate>Weight</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-if="ctrl.tableData.allocated.length === 0">
<td colspan="100">
<div class="no-rows-help">
{$ ::trCtrl.helpText.noneAllocText $}
</div>
</td>
</tr>
<tr ng-repeat="row in ctrl.tableData.displayedAllocated track by row.id">
<td class="rsp-p1">
<div ng-if="!row.addresses"
class="form-field member-address"
ng-class="{ 'has-error': memberDetailsForm['{$ ::row.id $}-address'].$invalid && memberDetailsForm['{$ ::row.id $}-address'].$dirty }">
<input name="{$ ::row.id $}-address" type="text" class="form-control input-sm"
ng-model="row.address" ng-pattern="::ctrl.ipPattern"
ng-required="true"
ng-disabled="model.context.id && row.allocatedMember">
</div>
<span ng-if="!row.addresses"
class="fa fa-exclamation-triangle invalid"
ng-show="memberDetailsForm['{$ ::row.id $}-address'].$invalid && memberDetailsForm.$dirty"
popover="{$ ::ctrl.ipError $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<span ng-if="row.addresses.length === 1">{$ row.address.ip $}</span>
<div ng-if="row.addresses.length > 1"
class="form-field member-address">
<select class="form-control input-sm"
ng-options="addr.ip for addr in row.addresses"
ng-model="row.address" ng-required="true"
ng-if="row.addresses">
</select>
</div>
</td>
<td class="rsp-p1">
<div ng-if="!row.addresses"
class="form-field">
<select name="{$ ::row.id $}-subnet" class="form-control input-sm"
ng-options="subnet.name for subnet in model.subnets"
ng-model="row.subnet" ng-required="true"
ng-disabled="model.context.id && row.allocatedMember">
</select>
</div>
<span ng-if="row.addresses">{$ ctrl.getSubnetName(row) $}</span>
</td>
<td class="rsp-p1">
<div class="form-field member-port"
ng-class="{ 'has-error': memberDetailsForm['{$ ::row.id $}-port'].$invalid && memberDetailsForm['{$ ::row.id $}-port'].$dirty }">
<input name="{$ ::row.id $}-port" type="number" class="form-control input-sm"
ng-model="row.port" ng-pattern="/^\d+$/" min="1" max="65535"
ng-required="true"
ng-disabled="model.context.id && row.allocatedMember">
</div>
<span class="fa fa-exclamation-triangle invalid"
ng-show="memberDetailsForm['{$ ::row.id $}-port'].$invalid && memberDetailsForm.$dirty"
popover="{$ ::ctrl.portError $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
</td>
<td class="rsp-p1">
<div class="form-field member-weight"
ng-class="{ 'has-error': memberDetailsForm['{$ ::row.id $}-weight'].$invalid && memberDetailsForm['{$ ::row.id $}-weight'].$dirty }">
<input name="{$ ::row.id $}-weight" type="number" class="form-control input-sm"
ng-model="row.weight" ng-pattern="/^\d+$/" min="1" max="256"
ng-disabled="model.context.id && row.allocatedMember">
</div>
<span class="fa fa-exclamation-triangle invalid"
ng-show="memberDetailsForm['{$ ::row.id $}-weight'].$invalid && memberDetailsForm.$dirty"
popover="{$ ::ctrl.weightError $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
</td>
<td class="action-col">
<action-list>
<action action-classes="'btn btn-sm btn-default'"
callback="ctrl.deallocateMember" item="row">
<span translate>Remove</span>
</action>
</action-list>
</td>
</tr>
<tr>
<td colspan="100">
<action-list class="pull-right">
<action action-classes="'btn btn-sm btn-default'"
callback="ctrl.allocateExternalMember">
<span translate>Add external member</span>
</action>
</action-list>
</td>
</tr>
</tbody>
</table>
</allocated>
<!-- Available -->
<available>
<table st-table="ctrl.tableData.displayedAvailable"
st-safe-src="ctrl.tableData.available"
hz-table class="table-striped table-rsp table-detail modern">
<thead>
<tr>
<th class="search-header" colspan="100">
<hz-search-bar group-classes="input-group-sm" icon-classes="fa-search">
</hz-search-bar>
</th>
</tr>
<tr>
<th st-sort="name" st-sort-default class="rsp-p1" translate>Name</th>
<th class="rsp-p1" translate>IP Address</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-if="ctrl.tableData.available.length === 0">
<td colspan="100">
<div class="no-rows-help">
{$ ::trCtrl.helpText.noneAvailText $}
</div>
</td>
</tr>
<tr ng-repeat="row in ctrl.tableData.displayedAvailable track by row.id"
ng-if="!trCtrl.allocatedIds[row.id]">
<td class="rsp-p1">{$ ::row.name $}</td>
<td class="rsp-p1">
<span ng-if="row.addresses.length === 1">{$ row.address.ip $}</span>
<!-- The current version of the popover directive doesn't seem to allow HTML content (0.11.0) -->
<span ng-if="row.addresses.length > 1"
class="addresses-popover"
ng-mouseover="ctrl.showAddressPopover($event, row)"
ng-mouseleave="ctrl.hideAddressPopover($event)">
{$ ctrl.addressPopoverTarget(row) $}
</span>
</td>
<td class="action-col">
<action-list>
<action action-classes="'btn btn-sm btn-default'"
callback="ctrl.allocateMember" item="row">
<span translate>Add</span>
</action>
</action-list>
</td>
</tr>
</tbody>
</table>
</available>
</transfer-table> <!-- End Transfer Table -->
</div> <!-- end content -->
<!-- Available -->
<available>
<table st-table="ctrl.tableData.displayedAvailable"
st-safe-src="ctrl.tableData.available"
hz-table class="table table-striped table-rsp table-detail">
<thead>
<tr>
<th class="search-header" colspan="5">
<hz-search-bar icon-classes="fa-search"></hz-search-bar>
</th>
</tr>
<tr>
<th st-sort="name" st-sort-default class="rsp-p1" translate>Name</th>
<th class="rsp-p1" translate>IP Address</th>
<th class="actions_column"></th>
</tr>
</thead>
<tbody>
<tr ng-if="ctrl.tableData.available.length === 0">
<td colspan="5">
<div class="no-rows-help">
{$ ::trCtrl.helpText.noneAvailText $}
</div>
</td>
</tr>
<tr ng-repeat="row in ctrl.tableData.displayedAvailable track by row.id"
ng-if="!trCtrl.allocatedIds[row.id]">
<td class="rsp-p1">{$ ::row.name $}</td>
<td class="rsp-p1">
<span ng-if="row.addresses.length === 1">{$ row.address.ip $}</span>
<!-- The current version of the popover directive doesn't seem to allow HTML content (0.11.0) -->
<span ng-if="row.addresses.length > 1"
class="addresses-popover"
ng-mouseover="ctrl.showAddressPopover($event, row)"
ng-mouseleave="ctrl.hideAddressPopover($event)">
{$ ctrl.addressPopoverTarget(row) $}
</span>
</td>
<td class="actions_column">
<action-list>
<action action-classes="'btn btn-sm btn-default'"
callback="ctrl.allocateMember" item="row">
<span translate>Add</span>
</action>
</action-list>
</td>
</tr>
</tbody>
</table>
</available>
</transfer-table>
</div>

View File

@ -81,9 +81,10 @@
function open(item) {
var spec = {
size: 'lg',
backdrop: 'static',
controller: 'ModalContainerController',
template: '<wizard class="lbaas-wizard" ng-controller="' +
template: '<wizard class="wizard lbaas-wizard" ng-controller="' +
args.controller + '"></wizard>',
windowClass: 'modal-dialog-wizard',
resolve: {

View File

@ -1,3 +1,5 @@
<h1 translate>Monitor Help</h1>
<p translate>The health monitor is used to determine the health of your pool members. Health checks routinely run against each member within the pool and the result of the health check is used to determine if the member receives new connections.</p>
<p translate>
The health monitor is used to determine the health of your pool members. Health checks
routinely run against each member within the pool and the result of the health check is used
to determine if the member receives new connections.
</p>

View File

@ -1,137 +1,124 @@
<div ng-controller="MonitorDetailsController as ctrl">
<h1 translate>Monitor</h1>
<p translate>Provide the details for the health monitor.</p>
<!--content-->
<div class="content">
<div translate class="subtitle">Provide the details for the health monitor.</div>
<div class="row">
<div class="row form-group">
<div class="col-sm-6 col-md-3">
<div class="form-field required monitor-type">
<label translate class="on-top" for="monitor-type">Monitor type</label>
<select class="form-control input-sm" name="monitor-type"
id="monitor-type"
ng-options="type for type in model.monitorTypes"
ng-model="model.spec.monitor.type"
ng-disabled="model.context.id" ng-required="true">
</select>
</div>
</div>
</div>
<div class="row form-group">
<div class="col-sm-6 col-md-3">
<div class="form-field required monitor-interval"
ng-class="{ 'has-error': monitorDetailsForm['monitor-interval'].$invalid && monitorDetailsForm['monitor-interval'].$dirty }">
<label translate class="on-top" for="monitor-interval">Health check interval (sec)</label>
<span class="fa fa-exclamation-triangle invalid"
ng-show="monitorDetailsForm['monitor-interval'].$invalid && monitorDetailsForm.$dirty"
popover="{$ ::ctrl.intervalError $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<span class="fa fa-question-circle pull-right"
popover="{$ ::ctrl.intervalHelp $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<input name="monitor-interval" id="monitor-interval"
type="number" class="form-control input-sm"
ng-model="model.spec.monitor.interval" ng-pattern="/^\d+$/"
ng-min="model.spec.monitor.timeout"
ng-required="true">
</div>
</div>
<div class="col-sm-6 col-md-3">
<div class="form-field required monitor-retry"
ng-class="{ 'has-error': monitorDetailsForm['monitor-retry'].$invalid && monitorDetailsForm['monitor-retry'].$dirty }">
<label translate class="on-top" for="monitor-retry">Retry count before markdown</label>
<span class="fa fa-exclamation-triangle invalid"
ng-show="monitorDetailsForm['monitor-retry'].$invalid && monitorDetailsForm.$dirty"
popover="{$ ::ctrl.retryError $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<span class="fa fa-question-circle pull-right"
popover="{$ ::ctrl.retryHelp $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<input name="monitor-retry" id="monitor-retry"
type="number" class="form-control input-sm"
ng-model="model.spec.monitor.retry" ng-pattern="/^\d+$/" min="1" max="10"
ng-required="true">
</div>
</div>
<div class="col-sm-6 col-md-3">
<div class="form-field required monitor-timeout"
ng-class="{ 'has-error': monitorDetailsForm['monitor-timeout'].$invalid && monitorDetailsForm['monitor-timeout'].$dirty }">
<label translate class="on-top" for="monitor-timeout">Timeout (sec)</label>
<span class="fa fa-exclamation-triangle invalid"
ng-show="monitorDetailsForm['monitor-timeout'].$invalid && monitorDetailsForm.$dirty"
popover="{$ ::ctrl.timeoutError $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<input name="monitor-timeout" id="monitor-timeout"
type="number" class="form-control input-sm"
ng-model="model.spec.monitor.timeout" ng-pattern="/^\d+$/" min="0"
ng-required="true">
</div>
</div>
</div>
<div class="row form-group" ng-if="model.spec.monitor.type === 'HTTP'">
<div class="col-sm-6 col-md-3">
<div class="form-field monitor-method">
<label translate class="on-top" for="monitor-method">HTTP method</label>
<select class="form-control input-sm" name="monitor-method"
id="monitor-method"
ng-options="method for method in model.monitorMethods"
ng-model="model.spec.monitor.method">
</select>
</div>
</div>
<div class="col-sm-6 col-md-3">
<div class="form-field monitor-status"
ng-class="{ 'has-error': monitorDetailsForm['monitor-status'].$invalid && monitorDetailsForm['monitor-status'].$dirty }">
<label translate class="on-top" for="monitor-status">Expected HTTP status code</label>
<span class="fa fa-exclamation-triangle invalid"
ng-show="monitorDetailsForm['monitor-status'].$invalid && monitorDetailsForm.$dirty"
popover="{$ ::ctrl.statusError $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<span class="fa fa-question-circle pull-right"
popover="{$ ::ctrl.statusHelp $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<input name="monitor-status" id="monitor-status"
type="text" class="form-control input-sm"
ng-model="model.spec.monitor.status" ng-pattern="::ctrl.statusPattern"
ng-disabled="model.context.id">
</div>
</div>
<div class="col-sm-6 col-md-3">
<div class="form-field monitor-path"
ng-class="{ 'has-error': monitorDetailsForm['monitor-path'].$invalid && monitorDetailsForm['monitor-path'].$dirty }">
<label translate class="on-top" for="monitor-path">URL path</label>
<span class="fa fa-exclamation-triangle invalid"
ng-show="monitorDetailsForm['monitor-path'].$invalid && monitorDetailsForm.$dirty"
popover="{$ ::ctrl.pathError $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<input name="monitor-path" id="monitor-path"
type="text" class="form-control input-sm"
ng-model="model.spec.monitor.path" ng-pattern="::ctrl.urlPathPattern">
</div>
</div>
</div>
<div class="col-xs-12 col-sm-8 col-md-6 col-lg-4">
<div class="form-group required">
<label translate class="control-label" for="type">
Monitor type
<span class="hz-icon-required fa fa-asterisk"></span>
</label>
<select class="form-control" name="type" id="type"
ng-options="type for type in model.monitorTypes"
ng-model="model.spec.monitor.type"
ng-disabled="model.context.id" ng-required="true">
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-8 col-md-6 col-lg-4">
<div class="form-group required"
ng-class="{ 'has-error': monitorDetailsForm.interval.$invalid && monitorDetailsForm.interval.$dirty }">
<label translate class="control-label" for="interval">
Health check interval (sec)
<span class="hz-icon-required fa fa-asterisk"></span>
</label>
<span class="fa fa-question-circle pull-right"
popover="{$ ::ctrl.intervalHelp $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<input name="interval" id="interval" type="number" class="form-control"
ng-model="model.spec.monitor.interval" ng-pattern="/^\d+$/"
ng-min="model.spec.monitor.timeout" ng-required="true">
<span class="help-block" ng-show="monitorDetailsForm.interval.$invalid && monitorDetailsForm.interval.$dirty">
{$ ::ctrl.intervalError $}
</span>
</div>
</div>
<div class="col-xs-12 col-sm-8 col-md-6 col-lg-4">
<div class="form-group required"
ng-class="{ 'has-error': monitorDetailsForm.retry.$invalid && monitorDetailsForm.retry.$dirty }">
<label translate class="control-label" for="retry">
Retry count before markdown
<span class="hz-icon-required fa fa-asterisk"></span>
</label>
<span class="fa fa-question-circle pull-right"
popover="{$ ::ctrl.retryHelp $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<input name="retry" id="retry" type="number" class="form-control"
ng-model="model.spec.monitor.retry" ng-pattern="/^\d+$/" min="1" max="10"
ng-required="true">
<span class="help-block" ng-show="monitorDetailsForm.retry.$invalid && monitorDetailsForm.retry.$dirty">
{$ ::ctrl.retryError $}
</span>
</div>
</div>
<div class="col-xs-12 col-sm-8 col-md-6 col-lg-4">
<div class="form-group required"
ng-class="{ 'has-error': monitorDetailsForm.timeout.$invalid && monitorDetailsForm.timeout.$dirty }">
<label translate class="control-label" for="timeout">
Timeout (sec)
<span class="hz-icon-required fa fa-asterisk"></span>
</label>
<input name="timeout" id="timeout" type="number" class="form-control"
ng-model="model.spec.monitor.timeout" ng-pattern="/^\d+$/" min="0"
ng-required="true">
<span class="help-block" ng-show="monitorDetailsForm.timeout.$invalid && monitorDetailsForm.timeout.$dirty">
{$ ::ctrl.timeoutError $}
</span>
</div>
</div>
</div>
<div class="row" ng-if="model.spec.monitor.type === 'HTTP'">
<div class="col-xs-12 col-sm-8 col-md-6 col-lg-4">
<div class="form-group">
<label translate class="control-label" for="method">HTTP method</label>
<select class="form-control" name="method" id="method"
ng-options="method for method in model.monitorMethods"
ng-model="model.spec.monitor.method">
</select>
</div>
</div>
<div class="col-xs-12 col-sm-8 col-md-6 col-lg-4">
<div class="form-group"
ng-class="{ 'has-error': monitorDetailsForm.status.$invalid && monitorDetailsForm.status.$dirty }">
<label translate class="control-label" for="status">Expected HTTP status code</label>
<span class="fa fa-question-circle pull-right"
popover="{$ ::ctrl.statusHelp $}"
popover-placement="top" popover-append-to-body="true"
popover-trigger="hover"></span>
<input name="status" id="status" type="text" class="form-control"
ng-model="model.spec.monitor.status" ng-pattern="::ctrl.statusPattern"
ng-disabled="model.context.id">
<span class="help-block" ng-show="monitorDetailsForm.status.$invalid && monitorDetailsForm.status.$dirty">
{$ ::ctrl.statusError $}
</span>
</div>
</div>
<div class="col-xs-12 col-sm-8 col-md-6 col-lg-4">
<div class="form-group"
ng-class="{ 'has-error': monitorDetailsForm.path.$invalid && monitorDetailsForm.path.$dirty }">
<label translate class="control-label" for="path">URL path</label>
<input name="path" id="path" type="text" class="form-control"
ng-model="model.spec.monitor.path" ng-pattern="::ctrl.urlPathPattern">
<span class="help-block" ng-show="monitorDetailsForm.path.$invalid && monitorDetailsForm.path.$dirty">
{$ ::ctrl.pathError $}
</span>
</div>
</div>
</div>
<!-- end content -->
</div>

View File

@ -1,3 +1,3 @@
<h1 translate>Pool Details Help</h1>
<p translate>A pool represents a group of members over which the load balancing will be applied.</p>
<p translate>
A pool represents a group of members over which the load balancing will be applied.
</p>

View File

@ -1,47 +1,41 @@
<div>
<h1 translate>Pool Details</h1>
<p translate>Provide the details for the pool.</p>
<!--content-->
<div class="content">
<div translate class="subtitle">Provide the details for the pool.</div>
<div class="row">
<div class="row form-group">
<div class="col-xs-12 col-sm-8 col-md-6">
<div class="form-group">
<label translate class="control-label" for="name">Name</label>
<input name="name" id="name" type="text" class="form-control"
ng-model="model.spec.pool.name">
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-field pool-name">
<label translate class="on-top" for="pool-name">Name</label>
<input name="pool-name" id="pool-name"
type="text" class="form-control input-sm"
ng-model="model.spec.pool.name">
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="form-field pool-description">
<label translate class="on-top" for="pool-description">Description</label>
<input name="pool-description" id="pool-description"
type="text" class="form-control input-sm"
ng-model="model.spec.pool.description">
</div>
</div>
</div>
<div class="row form-group">
<div class="col-sm-6 col-md-3">
<div class="form-field required pool-method">
<label translate class="on-top" for="pool-method">Method</label>
<select class="form-control input-sm" name="pool-method" id="pool-method"
ng-options="method for method in model.methods"
ng-model="model.spec.pool.method"
ng-disabled="model.context.id" ng-required="true">
</select>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-8 col-md-6">
<div class="form-group">
<label translate class="control-label" for="description">Description</label>
<input name="description" id="description" type="text" class="form-control"
ng-model="model.spec.pool.description">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-8 col-md-6">
<div class="form-group required">
<label translate class="control-label" for="method">
Method
<span class="hz-icon-required fa fa-asterisk"></span>
</label>
<select class="form-control" name="method" id="method"
ng-options="method for method in model.methods"
ng-model="model.spec.pool.method"
ng-disabled="model.context.id" ng-required="true">
</select>
</div>
</div>
</div>
<!-- end content -->
</div>