257 lines
13 KiB
HTML
257 lines
13 KiB
HTML
<div ng-controller="MemberDetailsController as ctrl"
|
|
ng-if="model.context.create_pool || model.context.id">
|
|
<p translate>Add members to the load balancer pool.</p>
|
|
<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="expander"></th>
|
|
|
|
<th class="rsp-p1">
|
|
<translate>IP Address</translate>
|
|
<span class="hz-icon-required fa fa-asterisk" ng-show="ctrl.tableData.displayedAllocated.length > 0">
|
|
</th>
|
|
<th class="rsp-p1">
|
|
<translate>Subnet</translate>
|
|
<span class="hz-icon-required fa fa-asterisk" ng-show="ctrl.tableData.displayedAllocated.length > 0">
|
|
</th>
|
|
<th class="rsp-p1">
|
|
<translate>Port</translate>
|
|
<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-start="row in ctrl.tableData.displayedAllocated track by row.id">
|
|
<td class="expander">
|
|
<span class="fa fa-chevron-right"
|
|
hz-expand-detail
|
|
duration="200">
|
|
</span>
|
|
</td>
|
|
<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="row.allocatedMember"
|
|
popover-placement="top" popover-append-to-body="true"
|
|
popover-trigger="focus"
|
|
uib-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||subnet.id) for subnet in model.subnets"
|
|
ng-model="row.subnet_id" ng-required="true"
|
|
ng-disabled="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.protocol_port" ng-pattern="/^\d+$/" min="1" max="65535"
|
|
ng-required="true" ng-disabled="row.allocatedMember"
|
|
popover-placement="top" popover-append-to-body="true"
|
|
popover-trigger="focus"
|
|
uib-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="0" max="256"
|
|
ng-disabled="row.allocatedMember"
|
|
popover-placement="top" popover-append-to-body="true"
|
|
popover-trigger="focus"
|
|
uib-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 ng-repeat-end class="detail-row">
|
|
<!--
|
|
Detail-row:
|
|
Contains detailed information on this item.
|
|
Can be toggled using the chevron button.
|
|
Ensure colspan is greater or equal to number of column-headers.
|
|
-->
|
|
<td class="detail" colspan="10">
|
|
|
|
<div class="row">
|
|
<dl class="col-lg-5 col-md-5 col-sm-5">
|
|
<dt translate>Monitor Address</dt>
|
|
<dd
|
|
class="form-group member-monitor-address"
|
|
ng-class="{ 'has-error': memberDetailsForm['{$ ::row.id $}-monitor-address'].$invalid && memberDetailsForm['{$ ::row.id $}-monitor-address'].$dirty }">
|
|
<input name="{$ ::row.id $}-monitor-address" type="text" class="form-control"
|
|
ng-model="row.monitor_address" ng-pattern="::ctrl.ipPattern"
|
|
ng-disabled="row.allocatedMember"
|
|
popover-placement="top" popover-append-to-body="true"
|
|
popover-trigger="focus"
|
|
uib-popover="{$ memberDetailsForm[row.id + '-monitor-address'].$invalid && memberDetailsForm[row.id + '-monitor-address'].$dirty ? ctrl.ipError : '' $}">
|
|
</dd>
|
|
</dl>
|
|
<dl class="col-lg-5 col-md-5 col-sm-5">
|
|
<dt translate>Monitor Port</dt>
|
|
<dd class="form-group member-monitor-port"
|
|
ng-class="{ 'has-error': memberDetailsForm['{$ ::row.id $}-monitor-port'].$invalid && memberDetailsForm['{$ ::row.id $}-monitor-port'].$dirty }">
|
|
<input name="{$ ::row.id $}-monitor-port" type="number" class="form-control"
|
|
ng-model="row.monitor_port" ng-pattern="/^\d+$/" min="1" max="65535"
|
|
ng-disabled="row.allocatedMember"
|
|
popover-placement="top" popover-append-to-body="true"
|
|
popover-trigger="focus"
|
|
uib-popover="{$ memberDetailsForm[row.id + '-monitor-port'].$invalid && memberDetailsForm[row.id + '-monitor-port'].$dirty ? ctrl.portError : '' $}">
|
|
</dd>
|
|
</dl>
|
|
<dl class="col-lg-5 col-md-5 col-sm-5">
|
|
<dt class="control-label required" translate>Admin State Up</dt>
|
|
<dd class="form-group">
|
|
<div class="form-field">
|
|
<div class="btn-group">
|
|
<label class="btn btn-default"
|
|
ng-repeat="option in model.yesNoOptions"
|
|
ng-model="row.admin_state_up"
|
|
ng-disabled="row.allocatedMember"
|
|
uib-btn-radio="option.value">{$ ::option.label $}</label>
|
|
</div>
|
|
</div>
|
|
</dd>
|
|
</dl>
|
|
<dl class="col-lg-5 col-md-5 col-sm-5">
|
|
<dt class="control-label required" translate>Backup</dt>
|
|
<dd class="form-group">
|
|
<div class="form-field">
|
|
<div class="btn-group">
|
|
<label class="btn btn-default"
|
|
ng-repeat="option in model.yesNoOptions"
|
|
ng-model="row.backup"
|
|
ng-disabled="row.allocatedMember"
|
|
uib-btn-radio="option.value">{$ ::option.label $}</label>
|
|
</div>
|
|
</div>
|
|
</dd>
|
|
</dl>
|
|
<dl class="col-lg-5 col-md-5 col-sm-5">
|
|
<dt class="control-label required" translate>Name</dt>
|
|
<dd class="form-group">
|
|
<div class="form-field">
|
|
<input type="text"
|
|
id="name"
|
|
ng-model="row.name"
|
|
ng-disabled="row.allocatedMember"
|
|
>
|
|
</div>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
<tr table-status table="table" column-count="10"></tr>
|
|
|
|
<tr>
|
|
<td colspan="6">
|
|
<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 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>
|