diff options
Diffstat (limited to 'testapi/opnfv_testapi/ui/components/results')
4 files changed, 315 insertions, 251 deletions
diff --git a/testapi/opnfv_testapi/ui/components/results/result/result.html b/testapi/opnfv_testapi/ui/components/results/result/result.html new file mode 100644 index 0000000..b435dce --- /dev/null +++ b/testapi/opnfv_testapi/ui/components/results/result/result.html @@ -0,0 +1,115 @@ +<legend>Result</legend> +<div style="padding-right:0px"> + <div class="table-responsive"> + <table class="table" ng-data="ctrl.data.pods"> + <tbody> + <tr style="padding:9px"> + <td class="podsTableTd">Id :</td> + <td class="podsTableLeftTd">{{ctrl.data._id}}</td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Pod Name:</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data.pod_name}}</td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Project Name:</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data.project_name}}</td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Case Name :</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data.case_name}}</td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Installer :</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data.installer}}</td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Version :</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data.version}}</td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Scenario :</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data.scenario}}</td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Build tag :</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data['build_tag']}}</td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Criteria :</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data.criteria}}</td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Start Date:</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data.start_date}}</td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Stop Date :</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data.stop_date}}</td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Trust Indicator :</td> + <td width="90%" class="podsTableLeftTd"> + <a ng-click="ctrl.showTrustIndicator()"> + <p ng-if="ctrl.trust_indicator">Hide</p> + <p ng-if="!ctrl.trust_indicator">Show</p> + </a> + <table class="table" ng-class="{'hidden' : !ctrl.trust_indicator}" style="margin:10px"> + <tbody> + <tr style="padding:9px"></tr> + <tr style="padding:9px" > + <td class="podsTableTd">Current :</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data.trust_indicator.current}}</td> + </tr> + <tr style="padding:9px" > + <td class="podsTableTd">Histories :</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data.trust_indicator.histories}}</td> + </tr> + </tbody> + </table> + </td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Details :</td> + <td width="90%" class="podsTableLeftTd"> + <a ng-click="ctrl.showDetails()"> + <p ng-if="ctrl.details">Hide</p> + <p ng-if="!ctrl.details">Show</p> + </a> + <table class="table" ng-class="{'hidden' : !ctrl.details}" style="margin:10px"> + <tbody> + <tr style="padding:9px"></tr> + <tr style="padding:9px"> + <td class="podsTableTd">Failures :</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data.details.failures}}</td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Details :</td> + <td width="90%" class="podsTableLeftTd">{{ctrl.data.details.errors}}</td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">Stream :</td> + <td width="90%" class="podsTableLeftTd"><p>{{ctrl.data.details.stream}}</p></td> + </tr> + <tr style="padding:9px"> + <td class="podsTableTd">TestsRun :</td> + <td width="90%" class="podsTableLeftTd"><p>{{ctrl.data.details.testsRun}}</p></td> + </tr> + </tbody> + </table> + </td> + </tr> + </tbody> + </table> + </div> +</div> +<div class="col-md-12"> + <div ng-show="ctrl.showError" class="col-md-12 alert alert-danger" role="alert"> + <span class="pull-right"> {{ctrl.error}}</span> + <span class="glyphicon glyphicon-exclamation-sign pull-right" aria-hidden="true" >Error:</span> + </div> + <div ng-show="ctrl.showSuccess" class="col-md-12 alert alert-success" role="alert"> + <span class="pull-right"> {{ctrl.success}}</span> + <span class="glyphicon glyphicon-ok pull-right" aria-hidden="true"></span> + </div> + </div>
\ No newline at end of file diff --git a/testapi/opnfv_testapi/ui/components/results/result/resultController.js b/testapi/opnfv_testapi/ui/components/results/result/resultController.js new file mode 100644 index 0000000..028e5d8 --- /dev/null +++ b/testapi/opnfv_testapi/ui/components/results/result/resultController.js @@ -0,0 +1,74 @@ +/* + * 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('ResultController', ResultController); + + ResultController.$inject = [ + '$scope', '$http', '$filter', '$state', '$window', '$uibModal', 'testapiApiUrl','raiseAlert', + 'confirmModal' + ]; + + /** + * TestAPI ResultController + * This controller is for the '/result/:_id' page where a user can browse + * through result declared in TestAPI. + */ + function ResultController($scope, $http, $filter, $state, $window, $uibModal, testapiApiUrl, + raiseAlert, confirmModal) { + var ctrl = this; + ctrl.url = testapiApiUrl + '/results'; + ctrl._id = $state.params['_id']; + ctrl.loadDetails = loadDetails + ctrl.showTrustIndicator = showTrustIndicator + ctrl.showDetails = showDetails + + /** + *Contact the testapi and retrevie the result details + */ + function loadDetails(){ + var resultUrl = ctrl.url + '/' + ctrl._id; + ctrl.showError = false; + ctrl.podsRequest = + $http.get(resultUrl).success(function (data) { + ctrl.data = data; + }).catch(function (error) { + ctrl.data = null; + ctrl.showError = true; + ctrl.error = error.statusText; + }); + } + + function showTrustIndicator(){ + if(ctrl.trust_indicator){ + ctrl.trust_indicator = false + }else{ + ctrl.trust_indicator = true + } + } + + function showDetails(){ + if(ctrl.details){ + ctrl.details = false + }else{ + ctrl.details = true + } + } + ctrl.loadDetails(); + } +})();
\ No newline at end of file diff --git a/testapi/opnfv_testapi/ui/components/results/results.html b/testapi/opnfv_testapi/ui/components/results/results.html index 2ae5339..b0c05ba 100644 --- a/testapi/opnfv_testapi/ui/components/results/results.html +++ b/testapi/opnfv_testapi/ui/components/results/results.html @@ -18,15 +18,28 @@ </div> </form> <div class="row" style="margin-bottom:24px;"></div> -<div class="result-filters"> - <h4>Filters</h4> - <div class="row"> - <div class="col-md-3"> - <label for="cpid">Start Date</label> - <p class="input-group"> +<div class="result-filters" style="border-top: none;"> + <div class="row podTable" style="vertical-align:middle"> + <div class="col-sm-1 pull-right"> + <button type="button" class="btn btn-danger" ng-click="ctrl.clearFilters()"> + <i class="fa fa-search"></i> Clear + </button> + </div> + <div class="col-sm-1 pull-right"> + <button type="button" class="btn btn-success" ng-click="ctrl.filterList()"> + <i class="fa fa-search"></i> Filter</button> + </div> + <div class="col-sm-2 pull-right" ng-class="{'hidden': ctrl.filter=='start_date' || ctrl.filter=='end_date'}"> + <span style="margin-top:6px">Search: </span> + <input type="text" class="form-control search" style="display:inline;width:105px;padding-left:6px;" + ng-Model="ctrl.filterText" placeholder="Search String"> + </div> + <div class="col-sm-3 pull-right" style="width:20%" ng-class="{'hidden': ctrl.filter!='start_date'}"> + <span style="margin-top:6px">Start Date: </span> + <p class="input-group" style="width:48%;display:inline-flex;"> <input type="text" class="form-control" uib-datepicker-popup="{{ctrl.format}}" - ng-model="ctrl.startDate" is-open="ctrl.startOpen" + ng-model="ctrl.filterText" is-open="ctrl.startOpen" close-text="Close" /> <span class="input-group-btn"> <button type="button" class="btn btn-default" ng-click="ctrl.open($event, 'startOpen')"> @@ -35,12 +48,12 @@ </span> </p> </div> - <div class="col-md-3"> - <label for="cpid">End Date</label> - <p class="input-group"> + <div class="col-sm-3 pull-right" style="width:20%" ng-class="{'hidden': ctrl.filter!='end_date'}"> + <span style="margin-top:6px">End Date: </span> + <p class="input-group" style="width:48%;display:inline-flex;"> <input type="text" class="form-control" uib-datepicker-popup="{{ctrl.format}}" - ng-model="ctrl.endDate" is-open="ctrl.endOpen" + ng-model="ctrl.filterText" is-open="ctrl.endOpen" close-text="Close" /> <span class="input-group-btn"> <button type="button" class="btn btn-default" ng-click="ctrl.open($event, 'endOpen')"> @@ -49,9 +62,29 @@ </span> </p> </div> - <div class="col-md-3" style="margin-top:24px;"> - <button type="submit" class="btn btn-primary" ng-click="ctrl.update()">Filter</button> - <button type="submit" class="btn btn-primary btn-danger" ng-click="ctrl.clearFilters()">Clear</button> + <div class="col-md-2 row pull-right" style="width: 20%;"> + <span style="margin-top:6px">Filter: </span> + <select ng-model="ctrl.filter" class="form-control" style="display:inline; width:150px;"> + <option value="pod" ng-disabled="ctrl.testFilter('pod')" >Pod Name</option> + <option value="project" ng-disabled="ctrl.testFilter('project')" >Project Name</option> + <option value="case" ng-disabled="ctrl.testFilter('case')">Case Name</option> + <option value="installer" ng-disabled="ctrl.testFilter('installer')">Installer</option> + <option value="version" ng-disabled="ctrl.testFilter('version')">Version</option> + <option value="scenario" ng-disabled="ctrl.testFilter('scenario')">Scenario</option> + <option value="build_tag" ng-disabled="ctrl.testFilter('build_tag')">Build Tag</option> + <option value="criteria" ng-disabled="ctrl.testFilter('criteria')">Criteria</option> + <option value="start_date" ng-disabled="ctrl.testFilter('start_date')">Start Date</option> + <option value="end_date" ng-disabled="ctrl.testFilter('end_date')">End Date</option> + </select> + </div> + + <div class='filter-box'> + <div class='filter-tag' ng-repeat="(key, tag) in ctrl.tagArray"> + {{key}} : {{tag}} + <div class='delete-tag' ng-click='ctrl.deleteTag(key)'> + × + </div> + </div> </div> </div> </div> @@ -70,14 +103,13 @@ <th>Version</th> <th>Scenario</th> <th>Criteria</th> - <th>Start Date</th> - <th>Stop Date</th> + <th>Build tag</th> </tr> </thead> <tbody> <tr ng-repeat-start="(index, result) in ctrl.data.results"> - <td>{{ result._id }}</td> + <td><a ng-click="ctrl.viewResult(result._id)">{{ result._id.substr(-8) }}</a></td> <td>{{ result.pod_name }}</td> <td>{{ result.project_name }}</td> <td>{{ result.case_name }}</td> @@ -85,8 +117,7 @@ <td>{{ result.version }}</td> <td>{{ result.scenario }}</td> <td>{{ result.criteria }}</td> - <td>{{ result.start_date }}</td> - <td>{{ result.stop_date }}</td> + <td>{{ result["build_tag"]}}</td> </tr> <tr ng-repeat-end=> </tr> @@ -103,7 +134,7 @@ boundary-links="true" rotate="false" num-pages="ctrl.numPages" - ng-change="ctrl.update()"> + ng-change="ctrl.filterList()"> </uib-pagination> </div> </div> diff --git a/testapi/opnfv_testapi/ui/components/results/resultsController.js b/testapi/opnfv_testapi/ui/components/results/resultsController.js index cc6cc0b..73f3c15 100644 --- a/testapi/opnfv_testapi/ui/components/results/resultsController.js +++ b/testapi/opnfv_testapi/ui/components/results/resultsController.js @@ -50,16 +50,14 @@ raiseAlert) { 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.deleteTag = deleteTag; + ctrl.filterList= filterList; + ctrl.testFilter = testFilter + ctrl.viewResult = viewResult; + + ctrl.tagArray = {} /** Mappings of Interop WG components to marketing program names. */ ctrl.targetMappings = { @@ -97,99 +95,98 @@ /** 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.isUserResults = $state.current.name === 'userResults'; - // Should only be on user-results-page if authenticated. - if (ctrl.isUserResults && !$scope.auth.isAuthenticated) { - $state.go('home'); - } + // // 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.pageHeader = "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 = ''; + // ctrl.uploadState = ''; ctrl.isPublic = false; - if (ctrl.isUserResults) { - ctrl.authRequest = $scope.auth.doSignCheck() - .then(ctrl.update); - // ctrl.getUserProducts(); - } else { - ctrl.update(); - } - - - function uploadFileToUrl(file, uploadUrl){ - var fd = new FormData(); - fd.append('file', file); - fd.append('public', ctrl.isPublic) - - $http.post(uploadUrl, fd, { - transformRequest: angular.identity, - headers: {'Content-Type': undefined} - }) - - .success(function(data){ - var id = data.href.substr(data.href.lastIndexOf('/')+1); - ctrl.uploadState = "Upload succeed. Result id is " + id; - ctrl.update(); - }) + // if (ctrl.isUserResults) { + // ctrl.authRequest = $scope.auth.doSignCheck() + // .then(ctrl.filterList); + // // ctrl.getUserProducts(); + // } else { + // ctrl.filterList(); + // } - .error(function(data, status){ - ctrl.uploadState = "Upload failed. Error code is " + status; - }); + function viewResult(_id){ + $state.go('result', {'_id':_id}, {reload: true}); } - function uploadFile(){ - var file = $scope.resultFile; - console.log('file is ' ); - console.dir(file); + function deleteTag(index){ + delete ctrl.tagArray[index]; + ctrl.filterList(); + } - var uploadUrl = testapiApiUrl + "/results/upload"; - uploadFileToUrl(file, uploadUrl); - }; + function testFilter(text){ + for (var filter in ctrl.tagArray){ + if(text==filter){ + return true; + } + } + return false; + } /** * This will contact the TestAPI API to get a listing of test run * results. */ - function update() { + function filterList(){ + if(ctrl.filter && ctrl.filterText!=""){ + ctrl.tagArray[ctrl.filter] = ctrl.filterText; + } ctrl.showError = false; - // Construct the API URL based on user-specified filters. var content_url = testapiApiUrl + '/results' + '?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'; + for(var key in ctrl.tagArray){ + if(key=="start_date"){ + var start = $filter('date')(ctrl.tagArray[key], 'yyyy-MM-dd'); + if (start) { + content_url = + content_url + '&from=' + start + ' 00:00:00'; + } + } + else if(key=="end_date"){ + var end = $filter('date')(ctrl.tagArray[key], 'yyyy-MM-dd'); + if (end) { + content_url = content_url + '&to=' + end + ' 23:59:59'; + } + } + else{ + content_url = content_url + "&" + key + "=" + ctrl.tagArray[key] + } + if (ctrl.isUserResults) { + content_url = content_url + '&signed'; + } } 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; - }).error(function (error) { - ctrl.data = null; - ctrl.totalItems = 0; - ctrl.showError = true; - ctrl.error = - 'Error retrieving results listing from server: ' + - angular.toJson(error); - }); + $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; + }).error(function (error) { + ctrl.data = null; + ctrl.totalItems = 0; + ctrl.showError = true; + ctrl.error = + 'Error retrieving results listing from server: ' + + angular.toJson(error); + }); + ctrl.filterText = '' } + ctrl.filterList(); /** * This is called when the date filter calendar is opened. It @@ -209,162 +206,9 @@ * 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); - } - }); - } + ctrl.tagArray = {} + ctrl.filter = undefined + ctrl.filterList(); } - - /** - * 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); - } - } })(); |