Merge "Add pagination to Source table in Launch Instance wizard"
This commit is contained in:
commit
c0a7a43d3f
@ -1,34 +1,30 @@
|
||||
<td colspan="{$ ::ctrl.tableHeadCells.length +2 $}" class="detail">
|
||||
<div class="item">
|
||||
<dl class="col-xs-4">
|
||||
<dt translate>Min Disk (GB)</dt>
|
||||
<dd>
|
||||
{$ (item.properties ? item.min_disk : item.volume_image_metadata.min_disk) || '--' $}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="col-xs-4">
|
||||
<dt translate>Min RAM (MB)</dt>
|
||||
<dd>
|
||||
{$ (item.properties ? item.min_ram : item.volume_image_metadata.min_ram) || '--' $}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<dl class="col-xs-4">
|
||||
<dt translate>Min Disk (GB)</dt>
|
||||
<dd>
|
||||
{$ (row.properties ? row.min_disk : row.volume_image_metadata.min_disk) || '--' $}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="col-xs-4">
|
||||
<dt translate>Min RAM (MB)</dt>
|
||||
<dd>
|
||||
{$ (row.properties ? row.min_ram : row.volume_image_metadata.min_ram) || '--' $}
|
||||
</dd>
|
||||
</dl>
|
||||
<div ng-if="model.metadataDefs.image || model.metadataDefs.volume">
|
||||
<div ng-if="item.properties && model.metadataDefs.image">
|
||||
<metadata-display
|
||||
available="::model.metadataDefs.image"
|
||||
existing="::item.properties">
|
||||
</metadata-display>
|
||||
</div>
|
||||
|
||||
<div ng-if="model.metadataDefs.image || model.metadataDefs.volume">
|
||||
<div ng-if="row.properties && model.metadataDefs.image">
|
||||
<metadata-display
|
||||
available="::model.metadataDefs.image"
|
||||
existing="::row.properties">
|
||||
</metadata-display>
|
||||
</div>
|
||||
|
||||
<div ng-if="row.volume_image_metadata && model.metadataDefs.volume">
|
||||
<metadata-display
|
||||
available="::model.metadataDefs.volume"
|
||||
existing="::row.volume_image_metadata">
|
||||
</metadata-display>
|
||||
</div>
|
||||
<div ng-if="item.volume_image_metadata && model.metadataDefs.volume">
|
||||
<metadata-display
|
||||
available="::model.metadataDefs.volume"
|
||||
existing="::item.volume_image_metadata">
|
||||
</metadata-display>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</div>
|
||||
|
@ -33,11 +33,6 @@
|
||||
LaunchInstanceSourceController.$inject = [
|
||||
'$scope',
|
||||
'horizon.dashboard.project.workflow.launch-instance.boot-source-types',
|
||||
'bytesFilter',
|
||||
'dateFilter',
|
||||
'decodeFilter',
|
||||
'diskFormatFilter',
|
||||
'gbFilter',
|
||||
'horizon.dashboard.project.workflow.launch-instance.basePath',
|
||||
'horizon.framework.widgets.transfer-table.events',
|
||||
'horizon.framework.widgets.magic-search.events'
|
||||
@ -45,11 +40,6 @@
|
||||
|
||||
function LaunchInstanceSourceController($scope,
|
||||
bootSourceTypes,
|
||||
bytesFilter,
|
||||
dateFilter,
|
||||
decodeFilter,
|
||||
diskFormatFilter,
|
||||
gbFilter,
|
||||
basePath,
|
||||
events,
|
||||
magicSearchEvents
|
||||
@ -78,8 +68,6 @@
|
||||
/*
|
||||
* Transfer table
|
||||
*/
|
||||
ctrl.tableHeadCells = [];
|
||||
ctrl.tableBodyCells = [];
|
||||
ctrl.tableData = {
|
||||
available: [],
|
||||
allocated: selection,
|
||||
@ -87,7 +75,21 @@
|
||||
displayedAllocated: []
|
||||
};
|
||||
ctrl.helpText = {};
|
||||
ctrl.sourceDetails = basePath + 'source/source-details.html';
|
||||
|
||||
ctrl.availableTableConfig = {
|
||||
selectAll: false,
|
||||
trackId: 'id',
|
||||
detailsTemplateUrl: basePath + 'source/source-details.html',
|
||||
columns: []
|
||||
};
|
||||
|
||||
ctrl.allocatedTableConfig = angular.copy(ctrl.availableTableConfig);
|
||||
ctrl.allocatedTableConfig.noItemsMessage = gettext(
|
||||
'Select an item from Available items below');
|
||||
|
||||
ctrl.tableLimits = {
|
||||
maxAllocation: 1
|
||||
};
|
||||
|
||||
var bootSources = {
|
||||
image: {
|
||||
@ -130,35 +132,66 @@
|
||||
{ label: gettext('VMDK'), key: 'vmdk' }
|
||||
];
|
||||
|
||||
// Mapping for dynamic table headers
|
||||
var tableHeadCellsMap = {
|
||||
var diskFormatsObj = diskFormats.reduce(function (acc, cur) {
|
||||
acc[cur.key] = cur.label;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
function getImageDiskFormat(key) {
|
||||
return diskFormatsObj[key];
|
||||
}
|
||||
|
||||
function getVolumeDiskFormat(data) {
|
||||
return diskFormatsObj[data.disk_format];
|
||||
}
|
||||
|
||||
var statuses = [
|
||||
{ label: gettext('Available'), key: 'available' },
|
||||
{ label: gettext('Creating'), key: 'creating' },
|
||||
{ label: gettext('Deleting'), key: 'deleting' },
|
||||
{ label: gettext('Error'), key: 'error' },
|
||||
{ label: gettext('Error Deleting'), key: 'error_deleting' }
|
||||
];
|
||||
|
||||
var statusesObj = statuses.reduce(function (acc, cur) {
|
||||
acc[cur.key] = cur.label;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
function getStatus(status) {
|
||||
return statusesObj[status];
|
||||
}
|
||||
|
||||
// Mapping for dynamic table columns
|
||||
var tableColumnsMap = {
|
||||
image: [
|
||||
{ text: gettext('Name') },
|
||||
{ text: gettext('Updated') },
|
||||
{ text: gettext('Size') },
|
||||
{ text: gettext('Type') },
|
||||
{ text: gettext('Visibility') }
|
||||
{ id: 'name', title: gettext('Name'), priority: 1 },
|
||||
{ id: 'updated_at', title: gettext('Updated'), filters: ['simpleDate'], priority: 2 },
|
||||
{ id: 'size', title: gettext('Size'), filters: ['bytes'], priority: 2 },
|
||||
{ id: 'disk_format', title: gettext('Type'), filters: [getImageDiskFormat], priority: 2 },
|
||||
{ id: 'visibility', title: gettext('Visibility'), filters: [getVisibility], priority: 2 }
|
||||
],
|
||||
snapshot: [
|
||||
{ text: gettext('Name') },
|
||||
{ text: gettext('Updated') },
|
||||
{ text: gettext('Size') },
|
||||
{ text: gettext('Type') },
|
||||
{ text: gettext('Visibility') }
|
||||
{ id: 'name', title: gettext('Name'), priority: 1 },
|
||||
{ id: 'updated_at', title: gettext('Updated'), filters: ['simpleDate'], priority: 2 },
|
||||
{ id: 'size', title: gettext('Size'), filters: ['bytes'], priority: 2 },
|
||||
{ id: 'disk_format', title: gettext('Type'), filters: [getImageDiskFormat], priority: 2 },
|
||||
{ id: 'visibility', title: gettext('Visibility'), filters: [getVisibility], priority: 2 }
|
||||
],
|
||||
volume: [
|
||||
{ text: gettext('Name') },
|
||||
{ text: gettext('Description') },
|
||||
{ text: gettext('Size') },
|
||||
{ text: gettext('Type') },
|
||||
{ text: gettext('Availability Zone') }
|
||||
{ id: 'name', title: gettext('Name'), priority: 1 },
|
||||
{ id: 'description', title: gettext('Description'), filters: ['noValue'], priority: 2 },
|
||||
{ id: 'size', title: gettext('Size'), filters: ['gb'], priority: 2 },
|
||||
{ id: 'volume_image_metadata', title: gettext('Type'),
|
||||
filters: [getVolumeDiskFormat], priority: 2 },
|
||||
{ id: 'availability_zone', title: gettext('Availability Zone'), priority: 2 }
|
||||
],
|
||||
volume_snapshot: [
|
||||
{ text: gettext('Name') },
|
||||
{ text: gettext('Description') },
|
||||
{ text: gettext('Size') },
|
||||
{ text: gettext('Created') },
|
||||
{ text: gettext('Status') }
|
||||
{ id: 'name', title: gettext('Name'), priority: 1 },
|
||||
{ id: 'description', title: gettext('Description'), filters: ['noValue'], priority: 2 },
|
||||
{ id: 'size', title: gettext('Size'), filters: ['gb'], priority: 2 },
|
||||
{ id: 'created_at', title: gettext('Created'), filters: ['simpleDate'], priority: 2 },
|
||||
{ id: 'status', title: gettext('Status'), filters: [getStatus], priority: 2 }
|
||||
]
|
||||
};
|
||||
|
||||
@ -169,37 +202,9 @@
|
||||
'community': gettext('Community')
|
||||
};
|
||||
|
||||
// Mapping for dynamic table data
|
||||
var tableBodyCellsMap = {
|
||||
image: [
|
||||
{ key: 'name', classList: ['hi-light', 'word-break'] },
|
||||
{ key: 'updated_at', filter: dateFilter, filterArg: 'short' },
|
||||
{ key: 'size', filter: bytesFilter, classList: ['number'] },
|
||||
{ key: 'disk_format', filter: diskFormatFilter, filterRawData: true },
|
||||
{ key: 'visibility', filter: decodeFilter, filterArg: _visibilitymap }
|
||||
],
|
||||
snapshot: [
|
||||
{ key: 'name', classList: ['hi-light', 'word-break'] },
|
||||
{ key: 'updated_at', filter: dateFilter, filterArg: 'short' },
|
||||
{ key: 'size', filter: bytesFilter, classList: ['number'] },
|
||||
{ key: 'disk_format', filter: diskFormatFilter, filterRawData: true },
|
||||
{ key: 'visibility', filter: decodeFilter, filterArg: _visibilitymap }
|
||||
],
|
||||
volume: [
|
||||
{ key: 'name', classList: ['hi-light', 'word-break'] },
|
||||
{ key: 'description' },
|
||||
{ key: 'size', filter: gbFilter, classList: ['number'] },
|
||||
{ key: 'volume_image_metadata', filter: diskFormatFilter },
|
||||
{ key: 'availability_zone' }
|
||||
],
|
||||
volume_snapshot: [
|
||||
{ key: 'name', classList: ['hi-light', 'word-break'] },
|
||||
{ key: 'description' },
|
||||
{ key: 'size', filter: gbFilter, classList: ['number'] },
|
||||
{ key: 'created_at', filter: dateFilter, filterArg: 'short' },
|
||||
{ key: 'status' }
|
||||
]
|
||||
};
|
||||
function getVisibility(visibility) {
|
||||
return _visibilitymap[visibility];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a map of functions that sort by the key at a given index for
|
||||
@ -208,8 +213,8 @@
|
||||
ctrl.sortByField = [];
|
||||
|
||||
var sortFunction = function(columnIndex, comparedObject) {
|
||||
var cell = tableBodyCellsMap[ctrl.currentBootSource];
|
||||
var key = cell[columnIndex].key;
|
||||
var cell = tableColumnsMap[ctrl.currentBootSource];
|
||||
var key = cell[columnIndex].id;
|
||||
return comparedObject[key];
|
||||
};
|
||||
|
||||
@ -257,13 +262,7 @@
|
||||
label: gettext('Status'),
|
||||
name: 'status',
|
||||
singleton: true,
|
||||
options: [
|
||||
{ label: gettext('Available'), key: 'available' },
|
||||
{ label: gettext('Creating'), key: 'creating' },
|
||||
{ label: gettext('Deleting'), key: 'deleting' },
|
||||
{ label: gettext('Error'), key: 'error' },
|
||||
{ label: gettext('Error Deleting'), key: 'error_deleting' }
|
||||
]
|
||||
options: statuses
|
||||
},
|
||||
type: {
|
||||
label: gettext('Type'),
|
||||
@ -479,8 +478,7 @@
|
||||
function changeBootSource(key, preSelection) {
|
||||
updateDataSource(key, preSelection);
|
||||
updateHelpText(key);
|
||||
updateTableHeadCells(key);
|
||||
updateTableBodyCells(key);
|
||||
updateTableColumns(key);
|
||||
updateFacets(key);
|
||||
}
|
||||
|
||||
@ -502,12 +500,9 @@
|
||||
});
|
||||
}
|
||||
|
||||
function updateTableHeadCells(key) {
|
||||
refillArray(ctrl.tableHeadCells, tableHeadCellsMap[key]);
|
||||
}
|
||||
|
||||
function updateTableBodyCells(key) {
|
||||
refillArray(ctrl.tableBodyCells, tableBodyCellsMap[key]);
|
||||
function updateTableColumns(key) {
|
||||
refillArray(ctrl.availableTableConfig.columns, tableColumnsMap[key]);
|
||||
refillArray(ctrl.allocatedTableConfig.columns, tableColumnsMap[key]);
|
||||
}
|
||||
|
||||
function updateFacets(key) {
|
||||
|
@ -82,10 +82,10 @@
|
||||
it('initializes transfer table variables', function() {
|
||||
// NOTE: these are set by the default, not the initial values.
|
||||
// Arguably we shouldn't even set the original values.
|
||||
expect(ctrl.tableHeadCells).toBeDefined();
|
||||
expect(ctrl.tableHeadCells.length).toEqual(5);
|
||||
expect(ctrl.tableBodyCells).toBeDefined();
|
||||
expect(ctrl.tableBodyCells.length).toEqual(5);
|
||||
expect(ctrl.availableTableConfig.columns).toBeDefined();
|
||||
expect(ctrl.availableTableConfig.columns.length).toEqual(5);
|
||||
expect(ctrl.allocatedTableConfig.columns).toBeDefined();
|
||||
expect(ctrl.allocatedTableConfig.columns.length).toEqual(5);
|
||||
expect(ctrl.tableData).toBeDefined();
|
||||
expect(Object.keys(ctrl.tableData).length).toEqual(4);
|
||||
expect(ctrl.helpText).toBeDefined();
|
||||
@ -291,8 +291,8 @@
|
||||
// check table data
|
||||
expect(ctrl.tableData).toBeDefined();
|
||||
expect(Object.keys(ctrl.tableData)).toEqual(tableKeys);
|
||||
expect(ctrl.tableHeadCells.length).toBeGreaterThan(0);
|
||||
expect(ctrl.tableBodyCells.length).toBeGreaterThan(0);
|
||||
expect(ctrl.availableTableConfig.columns.length).toBeGreaterThan(0);
|
||||
expect(ctrl.allocatedTableConfig.columns.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('updates the scope appropriately, with Cinder available', function() {
|
||||
|
@ -101,184 +101,16 @@
|
||||
type="text">
|
||||
</div>
|
||||
|
||||
<transfer-table help-text="ctrl.helpText"
|
||||
tr-model="ctrl.tableData">
|
||||
<allocated validate-number-min="1"
|
||||
ng-model="ctrl.tableData.allocated.length">
|
||||
<table class="table table-striped table-rsp table-detail modern"
|
||||
hz-table
|
||||
st-safe-src="ctrl.tableData.allocated"
|
||||
st-table="ctrl.tableData.displayAllocated">
|
||||
<!-- transfer table, allocated table head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="expander"></th>
|
||||
<th ng-class="ctrl.tableHeadCells[0].classList">
|
||||
{$ ctrl.tableHeadCells[0].text $}
|
||||
</th>
|
||||
<th ng-class="ctrl.tableHeadCells[1].classList">
|
||||
{$ ctrl.tableHeadCells[1].text $}
|
||||
</th>
|
||||
<th ng-class="ctrl.tableHeadCells[2].classList">
|
||||
{$ ctrl.tableHeadCells[2].text $}
|
||||
</th>
|
||||
<th ng-class="ctrl.tableHeadCells[3].classList">
|
||||
{$ ctrl.tableHeadCells[3].text $}
|
||||
</th>
|
||||
<th ng-class="ctrl.tableHeadCells[4].classList">
|
||||
{$ ctrl.tableHeadCells[4].text $}
|
||||
</th>
|
||||
<th class="action"></th>
|
||||
</tr>
|
||||
</thead><!-- /transfer table, allocated table head -->
|
||||
|
||||
<!-- transfer table, allocated table body -->
|
||||
<tbody>
|
||||
|
||||
<tr ng-if="ctrl.tableData.allocated.length === 0">
|
||||
<td colspan="{$ ctrl.tableHeadCells.length + 2 $}">
|
||||
<div class="no-rows-help">
|
||||
{$ ::trCtrl.helpText.noneAllocText $}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr ng-repeat-start="row in ctrl.selection">
|
||||
<td class="expander">
|
||||
<span class="fa fa-chevron-right"
|
||||
hz-expand-detail
|
||||
title="{$ ::trCtrl.helpText.expandDetailsText $}"></span>
|
||||
</td>
|
||||
<td ng-class="ctrl.tableBodyCells[0].classList">
|
||||
{$ ctrl.tableBodyCells[0].filter ? ctrl.tableBodyCells[0].filter(row[ctrl.tableBodyCells[0].key], ctrl.tableBodyCells[0].filterArg) : row[ctrl.tableBodyCells[0].key] $}
|
||||
</td>
|
||||
<td ng-class="ctrl.tableBodyCells[1].classList">
|
||||
{$ ctrl.tableBodyCells[1].filter ? ctrl.tableBodyCells[1].filter(row[ctrl.tableBodyCells[1].key], ctrl.tableBodyCells[1].filterArg) : row[ctrl.tableBodyCells[1].key] $}
|
||||
</td>
|
||||
<td ng-class="ctrl.tableBodyCells[2].classList">
|
||||
{$ ctrl.tableBodyCells[2].filter ? ctrl.tableBodyCells[2].filter(row[ctrl.tableBodyCells[2].key], ctrl.tableBodyCells[2].filterArg) : row[ctrl.tableBodyCells[2].key] $}
|
||||
</td>
|
||||
<td ng-class="ctrl.tableBodyCells[3].classList">
|
||||
{$ ctrl.tableBodyCells[3].filter ? ctrl.tableBodyCells[3].filter(ctrl.tableBodyCells[3].filterRawData ? row : row[ctrl.tableBodyCells[3].key], ctrl.tableBodyCells[3].filterArg) : row[ctrl.tableBodyCells[3].key] $}
|
||||
</td>
|
||||
<td ng-class="ctrl.tableBodyCells[4].classList">
|
||||
<span ng-if="model.newInstanceSpec.source_type.type === 'volume' && row.availability_zone !== model.newInstanceSpec.availability_zone"
|
||||
class="invalid fa fa-exclamation-triangle"
|
||||
uib-popover="{$ ::trCtrl.helpText.volumeAZHelpText $}"
|
||||
popover-trigger="'mouseenter'"
|
||||
popover-append-to-body="true"
|
||||
popover-placement="top"></span>
|
||||
{$ ctrl.tableBodyCells[4].filter ? ctrl.tableBodyCells[4].filter(row[ctrl.tableBodyCells[4].key], ctrl.tableBodyCells[4].filterArg) : row[ctrl.tableBodyCells[4].key] $}
|
||||
</td>
|
||||
<td class="actions_column">
|
||||
<action-list>
|
||||
<action action-classes="'btn btn-default'"
|
||||
callback="trCtrl.deallocate"
|
||||
item="row">
|
||||
<span class="fa fa-arrow-down"></span>
|
||||
</action>
|
||||
</action-list>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="detail-row"
|
||||
ng-repeat-end
|
||||
ng-include="ctrl.sourceDetails">
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</allocated>
|
||||
|
||||
<available>
|
||||
<hz-magic-search-context filter-facets="ctrl.sourceFacets">
|
||||
<hz-magic-search-bar>
|
||||
</hz-magic-search-bar>
|
||||
<table st-table="ctrl.tableData.displayedAvailable"
|
||||
st-safe-src="ctrl.tableData.available"
|
||||
hz-table
|
||||
st-magic-search
|
||||
class="table table-striped table-rsp table-detail modern">
|
||||
|
||||
<!-- transfer table, available table head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="expander"></th>
|
||||
<th st-sort="ctrl.sortByField[0]">
|
||||
{$ ctrl.tableHeadCells[0].text $}
|
||||
</th>
|
||||
<th st-sort="ctrl.sortByField[1]">
|
||||
{$ ctrl.tableHeadCells[1].text $}
|
||||
</th>
|
||||
<th st-sort="ctrl.sortByField[2]">
|
||||
{$ ctrl.tableHeadCells[2].text $}
|
||||
</th>
|
||||
<th st-sort="ctrl.sortByField[3]">
|
||||
{$ ctrl.tableHeadCells[3].text $}
|
||||
</th>
|
||||
<th st-sort="ctrl.sortByField[4]">
|
||||
{$ ctrl.tableHeadCells[4].text $}
|
||||
</th>
|
||||
<th class="action"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr ng-if="trCtrl.numAvailable() === 0">
|
||||
<td colspan="{$ ctrl.tableHeadCells.length + 2 $}">
|
||||
<div class="no-rows-help">
|
||||
{$ ::trCtrl.helpText.noneAvailText $}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr ng-repeat-start="row in ctrl.tableData.displayedAvailable track by row.id"
|
||||
ng-if="!trCtrl.allocatedIds[row.id]">
|
||||
<td class="expander">
|
||||
<span class="fa fa-chevron-right"
|
||||
hz-expand-detail
|
||||
title="{$ ::trCtrl.helpText.expandDetailsText $}">
|
||||
</span>
|
||||
</td>
|
||||
<td ng-class="ctrl.tableBodyCells[0].classList">
|
||||
{$ ctrl.tableBodyCells[0].filter ? ctrl.tableBodyCells[0].filter(row[ctrl.tableBodyCells[0].key], ctrl.tableBodyCells[0].filterArg) : row[ctrl.tableBodyCells[0].key] $}
|
||||
</td>
|
||||
<td ng-class="ctrl.tableBodyCells[1].classList">
|
||||
{$ ctrl.tableBodyCells[1].filter ? ctrl.tableBodyCells[1].filter(row[ctrl.tableBodyCells[1].key], ctrl.tableBodyCells[1].filterArg) : row[ctrl.tableBodyCells[1].key] $}
|
||||
</td>
|
||||
<td ng-class="ctrl.tableBodyCells[2].classList">
|
||||
{$ ctrl.tableBodyCells[2].filter ? ctrl.tableBodyCells[2].filter(row[ctrl.tableBodyCells[2].key], ctrl.tableBodyCells[2].filterArg) : row[ctrl.tableBodyCells[2].key] $}
|
||||
</td>
|
||||
<td ng-class="ctrl.tableBodyCells[3].classList">
|
||||
{$ ctrl.tableBodyCells[3].filter ? ctrl.tableBodyCells[3].filter(ctrl.tableBodyCells[3].filterRawData ? row : row[ctrl.tableBodyCells[3].key], ctrl.tableBodyCells[3].filterArg) : row[ctrl.tableBodyCells[3].key] $}
|
||||
</td>
|
||||
<td ng-class="ctrl.tableBodyCells[4].classList">
|
||||
<span ng-if="model.newInstanceSpec.source_type.type === 'volume' && row.availability_zone !== model.newInstanceSpec.availability_zone"
|
||||
class="invalid fa fa-exclamation-triangle"
|
||||
uib-popover="{$ ::trCtrl.helpText.volumeAZHelpText $}"
|
||||
popover-trigger="'mouseenter'"
|
||||
popover-append-to-body="true"
|
||||
popover-placement="top"></span>
|
||||
{$ ctrl.tableBodyCells[4].filter ? ctrl.tableBodyCells[4].filter(row[ctrl.tableBodyCells[4].key], ctrl.tableBodyCells[4].filterArg) : row[ctrl.tableBodyCells[4].key] $}
|
||||
</td>
|
||||
<td class="actions_column">
|
||||
<action-list>
|
||||
<action action-classes="'btn btn-default'"
|
||||
callback="trCtrl.allocate"
|
||||
item="row">
|
||||
<span class="fa fa-arrow-up"></span>
|
||||
</action>
|
||||
</action-list>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="detail-row"
|
||||
ng-repeat-end
|
||||
ng-include="ctrl.sourceDetails"
|
||||
ng-if="!trCtrl.allocatedIds[row.id]">
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</hz-magic-search-context>
|
||||
</available>
|
||||
<transfer-table help-text="ctrl.helpText" tr-model="ctrl.tableData" limits="ctrl.tableLimits" clone-content>
|
||||
<hz-dynamic-table
|
||||
config="$isAvailableTable ? ctrl.availableTableConfig : ctrl.allocatedTableConfig"
|
||||
items="$isAvailableTable ? (ctrl.tableData.available | filterAvailable:trCtrl.allocatedIds) : $sourceItems"
|
||||
item-actions="trCtrl.itemActions"
|
||||
filter-facets="$isAvailableTable && ctrl.sourceFacets"
|
||||
table="ctrl">
|
||||
</hz-dynamic-table>
|
||||
</transfer-table>
|
||||
|
||||
</div>
|
||||
<div ng-if="model.allowedBootSources.length === 0">
|
||||
<div translate class="subtitle text-danger">There are no allowed boot
|
||||
|
Loading…
Reference in New Issue
Block a user