Files
horizon/openstack_dashboard/static/dashboard/launch-instance/source/source.js

300 lines
8.9 KiB
JavaScript

(function () {
'use strict';
var module = angular.module('hz.dashboard.launch-instance');
module.controller('LaunchInstanceSourceCtrl', [
'$scope',
'bytesFilter',
LaunchInstanceSourceCtrl
]);
module.controller('LaunchInstanceSourceHelpCtrl', [
'$scope',
LaunchInstanceSourceHelpCtrl
]);
function LaunchInstanceSourceCtrl($scope, bytesFilter) {
$scope.label = {
title: gettext('Instance Details'),
subtitle: gettext(''),
instanceName: gettext('Instance Name'),
availabilityZone: gettext('Availability Zone'),
instance_count: gettext('Count'),
instanceSourceTitle: gettext('Instance Source'),
instanceSourceSubTitle: gettext(''),
bootSource: gettext('Select Boot Source'),
deviceSize: gettext('Device Size (GB)'),
volumeSize: gettext('Volume Size (GB)'),
volumeCreate: gettext('Create New Volume'),
deleteVolumeOnTerminate: gettext('Delete Volume on Terminate'),
id: gettext('ID')
};
//
// Boot Sources
//
$scope.bootSourcesOptions = [
{ type: 'image', label: gettext('Image') },
{ type: 'snapshot', label: gettext('Instance Snapshot') },
{ type: 'volume', label: gettext('Volume') },
{ type: 'volume_snapshot', label: gettext('Volume Snapshot') }
];
$scope.updateBootSourceSelection = function (selectedSource) {
$scope.currentBootSource = selectedSource.type;
$scope.model.newInstanceSpec.vol_create = false;
$scope.model.newInstanceSpec.vol_delete_on_terminate = false;
changeBootSource(selectedSource.type);
};
//
// Transfer table
//
$scope.tableHeadCells = [];
$scope.tableBodyCells= [];
$scope.tableData = {};
$scope.helpText = {};
var selection = $scope.model.newInstanceSpec.source;
var bootSources = {
image: {
available: $scope.model.images,
allocated: selection,
displayedAvailable: $scope.model.images,
displayedAllocated: selection
},
volume: {
available: $scope.model.volumes,
allocated: selection,
displayedAvailable: [],
displayedAllocated: selection
},
snapshot: {
available: $scope.model.imageSnapshots,
allocated: selection,
displayedAvailable: [],
displayedAllocated: selection
},
volume_snapshot: {
available: $scope.model.volumeSnapshots,
allocated: selection,
displayedAvailable: [],
displayedAllocated: selection
}
};
var tableHeadCellsMap = {
image: [
{ text: gettext('Name'), style: { width: '25%' }, sortable: true, sortDefault: true },
{ text: gettext('Updated'), style: { width: '20%' }, sortable: true },
{ text: gettext('Size'), style: { width: '15%' }, classList: ['number'], sortable: true },
{ text: gettext('Type'), sortable: true }
],
volume: [
{ text: gettext('Name'), style: { width: '25%' }, sortable: true, sortDefault: true },
{ text: gettext('Type'), style: { width: '20%' } },
{ text: gettext('Size'), classList: ['number'], sortable: true }
],
snapshot: [
{ text: gettext('Name'), style: { width: '25%' }, sortable: true, sortDefault: true },
{ text: gettext('Type'), style: { width: '20%' } },
{ text: gettext('Size'), classList: ['number'], sortable: true }
],
volume_snapshot: [
{ text: gettext('Name'), style: { width: '25%' }, sortable: true, sortDefault: true },
{ text: gettext('Type'), style: { width: '20%' } },
{ text: gettext('Size'), classList: ['number'], sortable: true }
]
};
var tableBodyCellsMap = {
image: [
{ key: 'name', classList: ['hi-light'] },
{ key: 'updated_at' },
{ key: 'size', filter: bytesFilter, classList: ['number'] },
{ key: 'disk_format', style: { 'text-transform': 'uppercase' } }
],
volume: [
{ key: 'name', classList: ['hi-light'] },
{ key: 'disk_format', style: { 'text-transform': 'uppercase' } },
{ key: 'size', filter: bytesFilter, classList: ['number'] }
],
snapshot: [
{ key: 'name', classList: ['hi-light'] },
{ key: 'disk_format', style: { 'text-transform': 'uppercase' } },
{ key: 'size', filter: bytesFilter, classList: ['number'] }
],
volume_snapshot: [
{ key: 'name', classList: ['hi-light'] },
{ key: 'disk_format', style: { 'text-transform': 'uppercase' } },
{ key: 'size', filter: bytesFilter, classList: ['number'] }
]
};
function changeBootSource(key) {
updateDataSource(key);
updateHelpText(key);
updateTableHeadCells(key);
updateTableBodyCells(key);
updateChart();
}
function updateDataSource(key) {
angular.extend($scope.tableData, bootSources[key]);
selection.length = 0;
}
function updateHelpText(key) {
angular.extend($scope.helpText, {
noneAllocText: gettext('Select a source from those listed below.'),
availHelpText: gettext('Select one')
});
}
function updateTableHeadCells(key) {
refillArray($scope.tableHeadCells, tableHeadCellsMap[key]);
}
function updateTableBodyCells(key) {
refillArray($scope.tableBodyCells, tableBodyCellsMap[key]);
}
function refillArray(arrayToRefill, contentArray) {
arrayToRefill.length = 0;
Array.prototype.push.apply(arrayToRefill, contentArray);
}
//
// Donut chart
//
var maxTotalInstances = 1, // Must has default value > 0
totalInstancesUsed = 0,
remaining = 0;
if ($scope.model.novaLimits && $scope.model.novaLimits.maxTotalInstances) {
maxTotalInstances = $scope.model.novaLimits.maxTotalInstances;
}
if ($scope.model.novaLimits && $scope.model.novaLimits.totalInstancesUsed) {
totalInstancesUsed = $scope.model.novaLimits.totalInstancesUsed;
}
$scope.donutSettings = {
innerRadius: 24,
outerRadius: 30,
label: {
'font-size': '16px',
'fill': '#1f83c6'
},
title: {
'font-size': '10px'
}
};
$scope.instanceStats = {
title: gettext('Total Instances'),
label: '100%',
data: [
{ label: gettext('Current Usage'), value: 1, color: '#1f83c6' },
{ label: gettext('Added'), value: 1, color: '#81c1e7' },
{ label: gettext('Remaining'), value: 1, color: '#d1d3d4' }
]
};
$scope.$watch(
function () {
return $scope.model.newInstanceSpec.instance_count;
},
function (newValue, oldValue) {
if (newValue !== oldValue) {
updateChart();
}
}
);
$scope.$watch(
function () {
return $scope.model.novaLimits.maxTotalInstances;
},
function (newValue, oldValue) {
if (newValue !== oldValue) {
maxTotalInstances = Math.max(1, newValue);
updateChart();
}
}
);
$scope.$watch(
function () {
return $scope.model.novaLimits.totalInstancesUsed;
},
function (newValue, oldValue) {
if (newValue !== oldValue) {
totalInstancesUsed = newValue;
updateChart();
}
}
);
$scope.$watch(
function () {
return $scope.tableData.allocated.length;
},
function (newValue, oldValue) {
if (newValue !== oldValue) {
updateChart();
}
}
);
function updateChart() {
// initialize instance_count to 1
if ($scope.model.newInstanceSpec.instance_count <= 0) {
$scope.model.newInstanceSpec.instance_count = 1;
}
var instance_count = $scope.model.newInstanceSpec.instance_count || 1;
var data = $scope.instanceStats.data;
var remaining = Math.max(0, maxTotalInstances - totalInstancesUsed - selection.length * instance_count);
// If a user has entered a count that will result in them exceeding their
// quota, automatically decrease the count so that it stays within quota
if (instance_count + totalInstancesUsed > maxTotalInstances) {
$scope.model.newInstanceSpec.instance_count = maxTotalInstances - totalInstancesUsed;
}
data[0].value = totalInstancesUsed;
data[1].value = selection.length * instance_count;
data[2].value = remaining;
$scope.instanceStats.label =
(maxTotalInstances - remaining) * 100 / maxTotalInstances + '%';
$scope.instanceStats = angular.extend({}, $scope.instanceStats);
}
//
// initialize
//
changeBootSource($scope.bootSourcesOptions[0].type);
if (!$scope.model.newInstanceSpec.source_type) {
$scope.model.newInstanceSpec.source_type = $scope.bootSourcesOptions[0];
$scope.currentBootSource = $scope.bootSourcesOptions[0].type;
}
}
function LaunchInstanceSourceHelpCtrl($scope) {
$scope.title = gettext('Instance Details Help');
$scope.content = gettext('This is the help text.');
}
})();