summaryrefslogtreecommitdiffstats
path: root/cvp
diff options
context:
space:
mode:
authorEddie Arrage <eddie.arrage@huawei.com>2018-05-31 23:59:31 +0000
committerGeorg Kunz <georg.kunz@ericsson.com>2018-06-07 09:25:12 +0000
commit772983d58e28848f3945eccd278adf8cbb01a262 (patch)
treea07102184166227ae71c1e9272e331ee27c36acd /cvp
parentb37fe7b72a6b6b2ba63eb4f8761c91975344a14e (diff)
Add improvements to OVP directory and logo upload
- Formatting changes to directory on home page based on OPNFV marketing - Updated branding guide link - Added test_id field to mongo applications collection to associate to approved results for directory - Set Test ID from user accounts with administrator role in Applications view - Provide file upload function for administrator to post company logos for OVP directory - Company logos are stored and served through tornado from cvp-cvpapi container rather than cvp-web JIRA: DOVETAIL-663 JIRA: DOVETAIL-664 Change-Id: I1226b42883afa2ea2eb5551e3836211abbb94b20 Signed-off-by: Eddie Arrage <eddie.arrage@huawei.com>
Diffstat (limited to 'cvp')
-rw-r--r--cvp/3rd_party/static/testapi-ui/assets/css/home/home.css14
-rw-r--r--cvp/3rd_party/static/testapi-ui/components/application/application.html23
-rw-r--r--cvp/3rd_party/static/testapi-ui/components/application/applicationController.js21
-rw-r--r--cvp/3rd_party/static/testapi-ui/components/directory/directory.html2
-rw-r--r--cvp/3rd_party/static/testapi-ui/components/home/home.html9
-rw-r--r--cvp/opnfv_testapi/resources/application_handlers.py43
-rw-r--r--cvp/opnfv_testapi/router/url_mappings.py4
7 files changed, 110 insertions, 6 deletions
diff --git a/cvp/3rd_party/static/testapi-ui/assets/css/home/home.css b/cvp/3rd_party/static/testapi-ui/assets/css/home/home.css
index ce8c88e2..f6f9a2ee 100644
--- a/cvp/3rd_party/static/testapi-ui/assets/css/home/home.css
+++ b/cvp/3rd_party/static/testapi-ui/assets/css/home/home.css
@@ -55,9 +55,21 @@
#directory_inner > thead > tr > th {
border-bottom: 2px solid #ddd;
- padding: 8px;
+ padding-bottom: 8px;
}
#directory_inner > tbody > tr > td {
border-bottom: 1px solid #ddd;
}
+
+.company_logo {
+ padding-right: 30px;
+ padding-left: 20px;
+ padding-top: 20px;
+ padding-bottom: 20px;
+}
+
+.company_row:hover {
+ cursor: pointer;
+ text-decoration: underline;
+}
diff --git a/cvp/3rd_party/static/testapi-ui/components/application/application.html b/cvp/3rd_party/static/testapi-ui/components/application/application.html
index dc27585d..17b17c68 100644
--- a/cvp/3rd_party/static/testapi-ui/components/application/application.html
+++ b/cvp/3rd_party/static/testapi-ui/components/application/application.html
@@ -180,6 +180,13 @@ urpose. Once we understand more about your product or service, we can determine
</div>
</div>
<div class="field text col-md-4">
+ <label class="left">Test ID</label>
+ <i uib-tooltip="Test ID - enter approved test_id" class="glyphicon glyphicon-question-sign opnfv-blue"></i>
+ <div class="middleColumn">
+ <input type="text" class="text form-control" ng-model="ctrl.test_id" />
+ </div>
+ </div>
+ <div class="field text col-md-4">
<label class="left">Location</label>
<i uib-tooltip="Location" class="glyphicon glyphicon-question-sign opnfv-blue"></i>
<div class="middleColumn">
@@ -243,6 +250,7 @@ urpose. Once we understand more about your product or service, we can determine
<th>Company logo</th>
<th>Approve date</th>
<th>Approved</th>
+ <th>Test ID</th>
<th>Location</th>
<th>Operation</th>
</tr>
@@ -302,6 +310,7 @@ urpose. Once we understand more about your product or service, we can determine
<td>{{ app.company_logo }}</td>
<td>{{ app.approve_date }}</td>
<td>{{ app.approved }}</td>
+ <td>{{ app.test_id }}</td>
<td><span popover-enable="app.lab_location != 'internal'" uib-popover-template="ctrl.lab_tpl" popover-title="Lab Info" popover-placement="top" popover-trigger="mouseenter">{{ app.lab_location | labLocation}}</span><i ng-if="app.lab_location != 'internal'" class="glyphicon glyphicon-info-sign opnfv-blue"></i></td>
<td><a ng-click="ctrl.deleteApp(app._id)" class="badge badge-info"><i class="glyphicon glyphicon-remove" ></i></a></td>
</tr>
@@ -322,4 +331,18 @@ urpose. Once we understand more about your product or service, we can determine
</uib-pagination>
</div>
</div>
+
+<div>
+ <br>
+ <h3>Company Logo Upload for Directory</h3>
+ <form enctype="multipart/form-data" method="post">
+ <div class="form-group col-m-3">
+ <input class="form-contrl btn btn-success cvp-btn medium accent-color regular-button" file-model="logoFile" type="file">
+ </div>
+ <div class="form-group col-m-3">
+ <a class="btn btn-success cvp-btn medium accent-color regular-button" ng-click="ctrl.uploadLogo()"><span>Upload Logo</span></a>
+ </div>
+ </form>
+</div>
+
</div>
diff --git a/cvp/3rd_party/static/testapi-ui/components/application/applicationController.js b/cvp/3rd_party/static/testapi-ui/components/application/applicationController.js
index 32f1053e..5666ff23 100644
--- a/cvp/3rd_party/static/testapi-ui/components/application/applicationController.js
+++ b/cvp/3rd_party/static/testapi-ui/components/application/applicationController.js
@@ -30,6 +30,7 @@
$uibModal, testapiApiUrl, raiseAlert, ngDialog, $scope) {
var ctrl = this;
+ ctrl.uploadLogo=uploadLogo;
function init(){
ctrl.organization_name = null;
@@ -52,6 +53,7 @@
ctrl.company_logo = null;
ctrl.approve_date = null;
ctrl.approved = "false";
+ ctrl.test_id = null;
ctrl.lab_location="internal";
ctrl.lab_name = null;
ctrl.lab_email=null;
@@ -94,6 +96,7 @@
"company_logo": ctrl.company_logo,
"approve_date": ctrl.approve_date,
"approved": ctrl.approved,
+ "test_id": ctrl.test_id,
"lab_location": ctrl.lab_location,
"lab_email": ctrl.lab_email,
"lab_address": ctrl.lab_address,
@@ -141,6 +144,24 @@
});
}
+ function uploadLogo(){
+ var file = $scope.logoFile;
+ var fd = new FormData();
+ fd.append('file', file);
+
+ $http.post(testapiApiUrl + "/cvp/applications/uploadlogo", fd, {
+ transformRequest: angular.identity,
+ headers: {'Content-Type': undefined}
+ }).then(function(resp){
+ if(resp.data.code && resp.data.code != 0) {
+ alert(resp.data.msg);
+ return;
+ }
+ }, function(error){
+ });
+
+ };
+
function getApplication(){
$http.get(testapiApiUrl + "/cvp/applications?page="+ctrl.currentPage+"&signed&per_page="+ctrl.itemsPerPage).then(function(response){
ctrl.applications = response.data.applications;
diff --git a/cvp/3rd_party/static/testapi-ui/components/directory/directory.html b/cvp/3rd_party/static/testapi-ui/components/directory/directory.html
index d1383138..1174752c 100644
--- a/cvp/3rd_party/static/testapi-ui/components/directory/directory.html
+++ b/cvp/3rd_party/static/testapi-ui/components/directory/directory.html
@@ -3,7 +3,7 @@
<div>
<h4>Compliance Marks Granted to {{ctrl.companyID}}</h4>
- <img class="" src="testapi-ui/assets/img/{{ctrl.company_logo}}" />
+ <img class="" src="api/v1/cvp/applications/getlogo/{{ctrl.company_logo}}" />
<table class="table table-striped table-hover">
<thead>
<tr class="">
diff --git a/cvp/3rd_party/static/testapi-ui/components/home/home.html b/cvp/3rd_party/static/testapi-ui/components/home/home.html
index f7d61cda..184980b3 100644
--- a/cvp/3rd_party/static/testapi-ui/components/home/home.html
+++ b/cvp/3rd_party/static/testapi-ui/components/home/home.html
@@ -61,7 +61,7 @@
" target="_blank">2018.01 Reviewer Guide&nbsp<span class="glyphicon glyphicon-new-window" aria-hidden="true"></span></a></div>
<div><a href="http://docs.opnfv.org/en/stable-danube/submodules/dovetail/docs/testing/user/ovpaddendum/index.html
" target="_blank">2018.01 Guidelines Addendum&nbsp<span class="glyphicon glyphicon-new-window" aria-hidden="true"></span></a></div>
- <div><a href="https://www.opnfv.org/wp-content/uploads/sites/12/2018/02/OPNFV_Verified_BrandGuide_021618.pdf
+ <div><a href="https://www.opnfv.org/wp-content/uploads/sites/12/2018/05/OPNFV_Verified_BrandGuide_021618.pdf
" target="_blank">OPNFV Verified Brand Guidelines&nbsp<span class="glyphicon glyphicon-new-window" aria-hidden="true"></span></a></div>
<!--
<div><a target="_blank">FAQ</a></div>
@@ -113,9 +113,10 @@
</div>
<div class="home-content-title">
<h1>OPNFV Verified Products Directory</h1>
+ Click on rows for more product verification details per company.
</div>
<div class="directory_main">
- <table id="directory_inner" class="table-striped table-hover">
+ <table id="directory_inner" class="">
<thead>
<tr>
<th>Company</th>
@@ -125,8 +126,8 @@
</tr>
</thead>
<tbody style="overflow: hidden; text-overflow: ellipsis;">
- <tr ng-click="ctrl.getCompany(app)" ng-repeat="app in ctrl.applications | filter:{approved:true} | orderBy : 'approve_date'">
- <td width="450"><img src="testapi-ui/assets/img/{{app.company_logo}}" />&ensp;{{ app.organization_name}}</td>
+ <tr class="company_row" ng-click="ctrl.getCompany(app)" ng-repeat="app in ctrl.applications | filter:{approved:true} | orderBy : 'approve_date'">
+ <td width="400"><img class="company_logo" src="api/v1/cvp/applications/getlogo/{{app.company_logo}}" />{{ app.organization_name}}</td>
<td width="300">{{ app.product_name}}</td>
<td width="150">{{ app.ovp_category}}</td>
<td width="150">{{ app.ovp_version}}</td>
diff --git a/cvp/opnfv_testapi/resources/application_handlers.py b/cvp/opnfv_testapi/resources/application_handlers.py
index 144b2241..258c1aa2 100644
--- a/cvp/opnfv_testapi/resources/application_handlers.py
+++ b/cvp/opnfv_testapi/resources/application_handlers.py
@@ -30,6 +30,49 @@ class GenericApplicationHandler(handlers.GenericApiHandler):
self.table_cls = application_models.Application
+class ApplicationsLogoHandler(GenericApplicationHandler):
+ @web.asynchronous
+ @gen.coroutine
+ def post(self):
+ role = self.get_secure_cookie(auth_const.ROLE)
+ if role.find('administrator') == -1:
+ msg = 'Only administrator is allowed to upload logos'
+ self.finish_request({'code': '-1', 'msg': msg})
+ return
+
+ fileinfo = self.request.files['file'][0]
+ fname = fileinfo['filename']
+ location = '3rd_party/static/testapi-ui/assets/img/'
+ fh = open(location + fname, 'w')
+ fh.write(fileinfo['body'])
+ msg = 'Successfully uploaded logo: ' + fname
+ resp = {'code': '1', 'msg': msg}
+ self.finish_request(resp)
+
+
+class ApplicationsGetLogoHandler(GenericApplicationHandler):
+ def get(self, filename):
+ location = '3rd_party/static/testapi-ui/assets/img/' + filename
+ self.set_header('Content-Type', 'application/force-download')
+ self.set_header('Content-Disposition',
+ 'attachment; filename=%s' % filename)
+ try:
+ with open(location, "rb") as f:
+ try:
+ while True:
+ _buffer = f.read(4096)
+ if _buffer:
+ self.write(_buffer)
+ else:
+ f.close()
+ self.finish()
+ return
+ except Exception:
+ raise web.HTTPError(404)
+ except Exception:
+ raise web.HTTPError(500)
+
+
class ApplicationsCLHandler(GenericApplicationHandler):
@swagger.operation(nickname="queryApplications")
@web.asynchronous
diff --git a/cvp/opnfv_testapi/router/url_mappings.py b/cvp/opnfv_testapi/router/url_mappings.py
index 83190ee4..e1d4c181 100644
--- a/cvp/opnfv_testapi/router/url_mappings.py
+++ b/cvp/opnfv_testapi/router/url_mappings.py
@@ -24,6 +24,10 @@ mappings = [
(r"/api/v1/tests", test_handlers.TestsCLHandler),
(r"/api/v1/tests/([^/]+)", test_handlers.TestsGURHandler),
+ (r"/api/v1/cvp/applications/getlogo/([^/]+)",
+ application_handlers.ApplicationsGetLogoHandler),
+ (r"/api/v1/cvp/applications/uploadlogo",
+ application_handlers.ApplicationsLogoHandler),
(r"/api/v1/cvp/applications", application_handlers.ApplicationsCLHandler),
(r"/api/v1/cvp/applications/([^/]+)",
application_handlers.ApplicationsGURHandler),