From b3e40f026d655501bfa581452c447784604ecb05 Mon Sep 17 00:00:00 2001 From: xudan Date: Fri, 6 Jul 2018 05:16:40 -0400 Subject: Move all web portal code to the new repo dovetail-webportal This is only the first step to simply copy the file here. There still need some more work to make sure all work well. All the changes will be submitted with other patches to make it easily to review. JIRA: DOVETAIL-671 Change-Id: I64d32a9df562184166b6199e2719f298687d1a0a Signed-off-by: xudan --- .../components/results/resultsController.js | 515 +++++++++++++++++++++ 1 file changed, 515 insertions(+) create mode 100644 3rd_party/static/testapi-ui/components/results/resultsController.js (limited to '3rd_party/static/testapi-ui/components/results/resultsController.js') diff --git a/3rd_party/static/testapi-ui/components/results/resultsController.js b/3rd_party/static/testapi-ui/components/results/resultsController.js new file mode 100644 index 0000000..aa593dc --- /dev/null +++ b/3rd_party/static/testapi-ui/components/results/resultsController.js @@ -0,0 +1,515 @@ +/* + * 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('testapiApp') + .controller('ResultsController', ResultsController); + + angular + .module('testapiApp') + .directive('fileModel', ['$parse', function ($parse) { + return { + restrict: 'A', + link: function(scope, element, attrs) { + var model = $parse(attrs.fileModel); + var modelSetter = model.assign; + + element.bind('change', function(){ + scope.$apply(function(){ + modelSetter(scope, element[0].files[0]); + }); + }); + } + }; + }]); + + ResultsController.$inject = [ + '$scope', '$http', '$filter', '$state', 'testapiApiUrl','raiseAlert', 'ngDialog', '$resource' + ]; + + /** + * TestAPI Results Controller + * This controller is for the '/results' page where a user can browse + * a listing of community uploaded results. + */ + function ResultsController($scope, $http, $filter, $state, testapiApiUrl, raiseAlert, ngDialog, $resource) { + var ctrl = this; + + ctrl.uploadFile=uploadFile; + ctrl.update = update; + ctrl.open = open; + ctrl.clearFilters = clearFilters; + ctrl.associateMeta = associateMeta; + ctrl.getVersionList = getVersionList; + ctrl.getUserProducts = getUserProducts; + ctrl.associateProductVersion = associateProductVersion; + ctrl.getProductVersions = getProductVersions; + ctrl.prepVersionEdit = prepVersionEdit; + ctrl.gotoSUT = gotoSUT; + ctrl.gotoResultDetail = gotoResultDetail; + ctrl.toggleCheck = toggleCheck; + ctrl.changeLabel = changeLabel; + ctrl.toReview = toReview; + ctrl.toPrivate = toPrivate; + ctrl.removeSharedUser = removeSharedUser; + ctrl.addSharedUser = addSharedUser; + ctrl.openSharedModal = openSharedModal; + ctrl.downloadLogs = downloadLogs; + ctrl.deleteTest = deleteTest; + + /** Mappings of Interop WG components to marketing program names. */ + ctrl.targetMappings = { + 'platform': 'Openstack Powered Platform', + 'compute': 'OpenStack Powered Compute', + 'object': 'OpenStack Powered Object Storage' + }; + + /** Initial page to be on. */ + ctrl.currentPage = 1; + + /** + * How many results should display on each page. Since pagination + * is server-side implemented, this value should match the + * 'results_per_page' configuration of the TestAPI server which + * defaults to 20. + */ + ctrl.itemsPerPage = 20; + + /** + * How many page buttons should be displayed at max before adding + * the '...' button. + */ + ctrl.maxSize = 5; + + /** The upload date lower limit to be used in filtering results. */ + ctrl.startDate = ''; + + /** The upload date upper limit to be used in filtering results. */ + ctrl.endDate = ''; + + /** The date format for the date picker. */ + ctrl.format = 'yyyy-MM-dd'; + + ctrl.userName = null; + + /** Check to see if this page should display user-specific results. */ + // ctrl.isUserResults = $state.current.name === 'userResults'; + // need auth to browse + ctrl.isUserResults = $state.current.name === 'userResults'; + + ctrl.currentUser = $scope.auth.name; + console.log($scope.auth); + + // Should only be on user-results-page if authenticated. + if (ctrl.isUserResults && !$scope.auth.isAuthenticated) { + $state.go('home'); + } + + ctrl.pageHeader = ctrl.isUserResults ? + 'Private test results' : 'Community test results'; + + ctrl.pageParagraph = ctrl.isUserResults ? + 'Your most recently uploaded test results are listed here.' : + 'The most recently uploaded community test results are listed ' + + 'here.'; + + ctrl.uploadState = ''; + + if (ctrl.isUserResults) { + ctrl.authRequest = $scope.auth.doSignCheck() + .then(ctrl.update); + // ctrl.getUserProducts(); + } else { + ctrl.update(); + } + + function downloadLogs(id) { + // var logsUrl = testapiApiUrl + "/logs/log_" + id+".tar.gz"; + var logsUrl = "/logs/" + id+"/results/"; + window.location.href = logsUrl; + // $http.get(logsUrl); + } + + function deleteTest(inner_id) { + var resp = confirm('Are you sure to delete this test?'); + if (!resp) + return; + + var delUrl = testapiApiUrl + "/tests/" + inner_id; + $http.get(delUrl) + .then( function(resp) { + var results = resp.data.results; + $http.delete(delUrl) + .then( function(ret) { + if(ret.data.code && ret.data.code != 0) { + alert(ret.data.msg); + return; + } + ctrl.update(); + angular.forEach(results, function(ele) { + delUrl = testapiApiUrl + "/results/" + ele; + $http.delete(delUrl); + }); + }); + }); + } + + function toggleCheck(result, item, newValue) { + var id = result._id; + var updateUrl = testapiApiUrl + "/tests/"+ id; + + var data = {}; + data['item'] = item; + data[item] = newValue; + + $http.put(updateUrl, JSON.stringify(data), { + transformRequest: angular.identity, + headers: {'Content-Type': 'application/json'}}).then(function(ret){ + if(ret.data.code && ret.data.code != 0) { + alert(ret.data.msg); + } + else { + result[item] = newValue; + console.log('update success'); + } + }, function(error){ + alert("Error when update data"); + }); + } + + function changeLabel(result, key, data){ + toggleCheck(result, key, data); + } + + function toReview(result, value){ + var resp = confirm('Once you submit a test result for review, it will become readable to all OVP reviewers. Do you want to proceed?'); + if(resp){ + toggleCheck(result, 'status', value); + } + } + + function toPrivate(result, value){ + var resp = confirm('Do you want to proceed?'); + if(resp){ + toggleCheck(result, 'status', value); + } + } + + function openSharedModal(result){ + ctrl.tempResult = result; + ngDialog.open({ + preCloseCallback: function(value) { + }, + template: 'testapi-ui/components/results/modal/sharedModal.html', + scope: $scope, + className: 'ngdialog-theme-default', + width: 950, + showClose: true, + closeByDocument: true + }); + } + + function addSharedUser(result, userId){ + var tempList = copy(result.shared); + tempList.push(userId); + toggleCheck(result, 'shared', tempList); + ngDialog.close(); + } + + function removeSharedUser(result, userId){ + var tempList = copy(result.shared); + var idx = tempList.indexOf(userId); + if(idx != -1){ + tempList.splice(idx, 1); + toggleCheck(result, 'shared', tempList); + } + } + + function copy(arrList){ + var tempList = []; + angular.forEach(arrList, function(ele){ + tempList.push(ele); + }); + return tempList; + } + + function uploadFileToUrl(file, uploadUrl){ + var fd = new FormData(); + fd.append('file', file); + + $http.post(uploadUrl, fd, { + transformRequest: angular.identity, + headers: {'Content-Type': undefined} + }).then(function(data){ + + if(data.data.code && data.data.code != 0){ + alert(data.data.msg); + return; + } + + ctrl.uploadState = ""; + data.data.filename = file.name; + var createTestUrl = testapiApiUrl + "/tests" + + $http.post(createTestUrl, data.data).then(function(data){ + if (data.data.code && data.data.code != 0) { + alert(data.data.msg); + } else { + ctrl.update(); + } + }, function(error){ + }); + + }, function(error){ + ctrl.uploadState = "Upload failed. Error code is " + error.status; + }); + } + + function uploadFile(){ + var file = $scope.resultFile; + console.log('file is ' ); + console.dir(file); + + var uploadUrl = testapiApiUrl + "/results/upload"; + uploadFileToUrl(file, uploadUrl); + }; + + /** + * This will contact the TestAPI API to get a listing of test run + * results. + */ + function update() { + ctrl.showError = false; + // Construct the API URL based on user-specified filters. + var content_url = testapiApiUrl + '/tests' + + '?page=' + ctrl.currentPage; + var start = $filter('date')(ctrl.startDate, 'yyyy-MM-dd'); + if (start) { + content_url = + content_url + '&from=' + start + ' 00:00:00'; + } + var end = $filter('date')(ctrl.endDate, 'yyyy-MM-dd'); + if (end) { + content_url = content_url + '&to=' + end + ' 23:59:59'; + } + if (ctrl.isUserResults) { + content_url = content_url + '&signed'+'&per_page='+ ctrl.itemsPerPage; + } + ctrl.resultsRequest = + $http.get(content_url).success(function (data) { + ctrl.data = data; + ctrl.totalItems = ctrl.data.pagination.total_pages * ctrl.itemsPerPage; + ctrl.currentPage = ctrl.data.pagination.current_page; + ctrl.numPages = ctrl.data.pagination.total_pages; + console.log(ctrl.data); + }).error(function (error) { + ctrl.data = null; + ctrl.totalItems = 0; + ctrl.showError = true; + ctrl.error = + 'Error retrieving results listing from server: ' + + angular.toJson(error); + }); + } + + /** + * This is called when the date filter calendar is opened. It + * does some event handling, and sets a scope variable so the UI + * knows which calendar was opened. + * @param {Object} $event - The Event object + * @param {String} openVar - Tells which calendar was opened + */ + function open($event, openVar) { + $event.preventDefault(); + $event.stopPropagation(); + ctrl[openVar] = true; + } + + /** + * This function will clear all filters and update the results + * listing. + */ + function clearFilters() { + ctrl.startDate = null; + ctrl.endDate = null; + ctrl.update(); + } + + /** + * This will send an API request in order to associate a metadata + * key-value pair with the given testId + * @param {Number} index - index of the test object in the results list + * @param {String} key - metadata key + * @param {String} value - metadata value + */ + function associateMeta(index, key, value) { + var testId = ctrl.data.results[index].id; + var metaUrl = [ + testapiApiUrl, '/results/', testId, '/meta/', key + ].join(''); + + var editFlag = key + 'Edit'; + if (value) { + ctrl.associateRequest = $http.post(metaUrl, value) + .success(function () { + ctrl.data.results[index][editFlag] = false; + }).error(function (error) { + raiseAlert('danger', error.title, error.detail); + }); + } + else { + ctrl.unassociateRequest = $http.delete(metaUrl) + .success(function () { + ctrl.data.results[index][editFlag] = false; + }).error(function (error) { + if (error.code == 404) { + // Key doesn't exist, so count it as a success, + // and don't raise an alert. + ctrl.data.results[index][editFlag] = false; + } + else { + raiseAlert('danger', error.title, error.detail); + } + }); + } + } + + /** + * Retrieve an array of available capability files from the TestAPI + * API server, sort this array reverse-alphabetically, and store it in + * a scoped variable. + * Sample API return array: ["2015.03.json", "2015.04.json"] + */ + function getVersionList() { + if (ctrl.versionList) { + return; + } + var content_url = testapiApiUrl + '/guidelines'; + ctrl.versionsRequest = + $http.get(content_url).success(function (data) { + ctrl.versionList = data.sort().reverse(); + }).error(function (error) { + raiseAlert('danger', error.title, + 'Unable to retrieve version list'); + }); + } + + /** + * Get products user has management rights to or all products depending + * on the passed in parameter value. + */ + function getUserProducts() { + if (ctrl.products) { + return; + } + var contentUrl = testapiApiUrl + '/products'; + ctrl.productsRequest = + $http.get(contentUrl).success(function (data) { + ctrl.products = {}; + angular.forEach(data.products, function(prod) { + if (prod.can_manage) { + ctrl.products[prod.id] = prod; + } + }); + }).error(function (error) { + ctrl.products = null; + ctrl.showError = true; + ctrl.error = + 'Error retrieving Products listing from server: ' + + angular.toJson(error); + }); + } + + /** + * Send a PUT request to the API server to associate a product with + * a test result. + */ + function associateProductVersion(result) { + var verId = (result.selectedVersion ? + result.selectedVersion.id : null); + var testId = result.id; + var url = testapiApiUrl + '/results/' + testId; + ctrl.associateRequest = $http.put(url, {'product_version_id': + verId}) + .success(function (data) { + result.product_version = result.selectedVersion; + if (result.selectedVersion) { + result.product_version.product_info = + result.selectedProduct; + } + result.productEdit = false; + }).error(function (error) { + raiseAlert('danger', error.title, error.detail); + }); + } + + /** + * Get all versions for a product. + */ + function getProductVersions(result) { + if (!result.selectedProduct) { + result.productVersions = []; + result.selectedVersion = null; + return; + } + + var url = testapiApiUrl + '/products/' + + result.selectedProduct.id + '/versions'; + ctrl.getVersionsRequest = $http.get(url) + .success(function (data) { + result.productVersions = data; + + // If the test result isn't already associated to a + // version, default it to the null version. + if (!result.product_version) { + angular.forEach(data, function(ver) { + if (!ver.version) { + result.selectedVersion = ver; + } + }); + } + }).error(function (error) { + raiseAlert('danger', error.title, error.detail); + }); + } + + /** + * Instantiate variables needed for editing product/version + * associations. + */ + function prepVersionEdit(result) { + result.productEdit = true; + if (result.product_version) { + result.selectedProduct = + ctrl.products[result.product_version.product_info.id]; + } + result.selectedVersion = result.product_version; + ctrl.getProductVersions(result); + } + + + + function gotoResultDetail(testId, innerID) { + $state.go('resultsDetail', {'testID': testId, 'innerID': innerID}); + } + + function gotoSUT(testId) { + $state.go('sut', {'testID': testId}); + } + + } +})(); -- cgit 1.2.3-korg