/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function () { 'use strict'; angular .module('refstackApp') .controller('CapabilitiesController', CapabilitiesController); CapabilitiesController.$inject = ['$http', '$uibModal', 'refstackApiUrl']; /** * RefStack Capabilities Controller * This controller is for the '/capabilities' page where a user can browse * through tests belonging to DefCore-defined capabilities. */ function CapabilitiesController($http, $uibModal, refstackApiUrl) { var ctrl = this; ctrl.getVersionList = getVersionList; ctrl.update = update; ctrl.updateTargetCapabilities = updateTargetCapabilities; ctrl.filterStatus = filterStatus; ctrl.getObjectLength = getObjectLength; ctrl.getTestList = getTestList; ctrl.openTestListModal = openTestListModal; /** The target OpenStack marketing program to show capabilities for. */ ctrl.target = 'platform'; /** The various possible capability statuses. */ ctrl.status = { required: true, advisory: false, deprecated: false, removed: false }; /** * The template to load for displaying capability details. */ ctrl.detailsTemplate = 'components/capabilities/partials/' + 'capabilityDetails.html'; /** * Retrieve an array of available capability files from the Refstack * API server, sort this array reverse-alphabetically, and store it in * a scoped variable. The scope's selected version is initialized to * the latest (i.e. first) version here as well. After a successful API * call, the function to update the capabilities is called. * Sample API return array: ["2015.03.json", "2015.04.json"] */ function getVersionList() { var content_url = refstackApiUrl + '/capabilities'; ctrl.versionsRequest = $http.get(content_url).success(function (data) { ctrl.versionList = data.sort().reverse(); ctrl.version = ctrl.versionList[0]; ctrl.update(); }).error(function (error) { ctrl.showError = true; ctrl.error = 'Error retrieving version list: ' + angular.toJson(error); }); } /** * This will contact the Refstack API server to retrieve the JSON * content of the capability file corresponding to the selected * version. */ function update() { var content_url = refstackApiUrl + '/capabilities/' + ctrl.version; ctrl.capsRequest = $http.get(content_url).success(function (data) { ctrl.capabilities = data; ctrl.updateTargetCapabilities(); }).error(function (error) { ctrl.showError = true; ctrl.capabilities = null; ctrl.error = 'Error retrieving capabilities: ' + angular.toJson(error); }); } /** * This will update the scope's 'targetCapabilities' object with * capabilities belonging to the selected OpenStack marketing program * (programs typically correspond to 'components' in the DefCore * schema). Each capability will have its status mapped to it. */ function updateTargetCapabilities() { ctrl.targetCapabilities = {}; var components = ctrl.capabilities.components; var targetCaps = ctrl.targetCapabilities; // The 'platform' target is comprised of multiple components, so // we need to get the capabilities belonging to each of its // components. if (ctrl.target === 'platform') { var platform_components = ctrl.capabilities.platform.required; // This will contain status priority values, where lower // values mean higher priorities. var statusMap = { required: 1, advisory: 2, deprecated: 3, removed: 4 }; // For each component required for the platform program. angular.forEach(platform_components, function (component) { // Get each capability list belonging to each status. angular.forEach(components[component], function (caps, status) { // For each capability. angular.forEach(caps, function(cap) { // If the capability has already been added. if (cap in targetCaps) { // If the status priority value is less // than the saved priority value, update // the value. if (statusMap[status] < statusMap[targetCaps[cap]]) { targetCaps[cap] = status; } } else { targetCaps[cap] = status; } }); }); }); } else { angular.forEach(components[ctrl.target], function (caps, status) { angular.forEach(caps, function(cap) { targetCaps[cap] = status; }); }); } } /** * This filter will check if a capability's status corresponds * to a status that is checked/selected in the UI. This filter * is meant to be used with the ng-repeat directive. * @param {Object} capability * @returns {Boolean} True if capability's status is selected */ function filterStatus(capability) { var caps = ctrl.targetCapabilities; return (ctrl.status.required && caps[capability.id] === 'required') || (ctrl.status.advisory && caps[capability.id] === 'advisory') || (ctrl.status.deprecated && caps[capability.id] === 'deprecated') || (ctrl.status.removed && caps[capability.id] === 'removed'); } /** * This function will get the length of an Object/dict based on * the number of keys it has. * @param {Object} object * @returns {Number} length of object */ function getObjectLength(object) { return Object.keys(object).length; } /** * This will give a list of tests belonging to capabilities with * the selected status(es). */ function getTestList() { var caps = ctrl.capabilities.capabilities; var tests = []; angular.forEach(ctrl.targetCapabilities, function (status, cap) { if (ctrl.status[status]) { if (ctrl.capabilities.schema === '1.2') { tests.push.apply(tests, caps[cap].tests); } else { angular.forEach(caps[cap].tests, function(info, test) { tests.push(test); }); } } }); return tests; } /** * This will open the modal that will show a list of all tests * belonging to capabilities with the selected status(es). */ function openTestListModal() { $uibModal.open({ templateUrl: '/components/capabilities/partials' + '/testListModal.html', backdrop: true, windowClass: 'modal', animation: true, controller: 'TestListModalController as modal', size: 'lg', resolve: { tests: function () { return ctrl.getTestList(); }, version: function () { return ctrl.version.slice(0, -5); }, status: function () { return ctrl.status; } } }); } ctrl.getVersionList(); } angular .module('refstackApp') .controller('TestListModalController', TestListModalController); TestListModalController.$inject = [ '$uibModalInstance', '$window', 'tests', 'version', 'status' ]; /** * Test List Modal Controller * This controller is for the modal that appears if a user wants to see the * ftest list corresponding to DefCore capabilities with the selected * statuses. */ function TestListModalController($uibModalInstance, $window, tests, version, status) { var ctrl = this; ctrl.tests = tests; ctrl.version = version; ctrl.status = status; ctrl.close = close; ctrl.getTestListString = getTestListString; ctrl.downloadTestList = downloadTestList; /** * This function will close/dismiss the modal. */ function close() { $uibModalInstance.dismiss('exit'); } /** * This function will return a string representing the sorted * tests list separated by newlines. */ function getTestListString() { return ctrl.tests.sort().join('\n'); } /** * Serve the test list as a downloadable file. */ function downloadTestList() { var blob = new Blob([ctrl.getTestListString()], {type: 'text/csv'}); var filename = ctrl.version + '-test-list.txt'; if ($window.navigator.msSaveOrOpenBlob) { $window.navigator.msSaveBlob(blob, filename); } else { var a = $window.document.createElement('a'); a.href = $window.URL.createObjectURL(blob); a.download = filename; $window.document.body.appendChild(a); a.click(); $window.document.body.removeChild(a); } } } })();