summaryrefslogtreecommitdiffstats
path: root/vnfmarket/app/modules
diff options
context:
space:
mode:
authorseshukm <seshu.kumar.m@huawei.com>2017-03-06 10:22:11 +0530
committerseshukm <seshu.kumar.m@huawei.com>2017-03-06 10:22:11 +0530
commit194d6e19da729265130123b6638e0f57589c9367 (patch)
treee691276ec48cf36ce1c01d09aea59553296f3170 /vnfmarket/app/modules
parentae3ed32af0fb30e2f4caa3a24cd6f278f4be9796 (diff)
Code for the VNF Market place
Issue-Id : CLIENT-4 Change-Id: I138f9ee72853ab12e0dd5197cc72db169b6f65ef Signed-off-by: seshukm <seshu.kumar.m@huawei.com>
Diffstat (limited to 'vnfmarket/app/modules')
-rw-r--r--vnfmarket/app/modules/home/home-test.js164
-rw-r--r--vnfmarket/app/modules/home/home.html52
-rw-r--r--vnfmarket/app/modules/home/homeCtrl.js135
-rw-r--r--vnfmarket/app/modules/home/homeModule.js28
-rw-r--r--vnfmarket/app/modules/home/homeRoute.js51
-rw-r--r--vnfmarket/app/modules/home/homeService.js76
-rw-r--r--vnfmarket/app/modules/home/marketplace.html228
-rw-r--r--vnfmarket/app/modules/home/serviceDelete/serviceDelete-test.js103
-rw-r--r--vnfmarket/app/modules/home/serviceDelete/serviceDelete.html48
-rw-r--r--vnfmarket/app/modules/home/serviceDelete/serviceDeleteCtrl.js65
-rw-r--r--vnfmarket/app/modules/home/serviceDelete/serviceDeleteService.js52
-rw-r--r--vnfmarket/app/modules/home/serviceDetails/serviceDetails-test.js89
-rw-r--r--vnfmarket/app/modules/home/serviceDetails/serviceDetails.html101
-rw-r--r--vnfmarket/app/modules/home/serviceDetails/serviceDetailsCtrl.js63
-rw-r--r--vnfmarket/app/modules/home/serviceDetails/serviceDetailsService.js54
-rw-r--r--vnfmarket/app/modules/home/serviceUpload/serviceUpload.html97
-rw-r--r--vnfmarket/app/modules/home/serviceUpload/serviceUploadCtrl.js93
-rw-r--r--vnfmarket/app/modules/home/serviceUpload/serviceUploadService.js53
-rw-r--r--vnfmarket/app/modules/layouts/main-page/main-page.html76
-rw-r--r--vnfmarket/app/modules/layouts/main-page/mainPageCtrl.js113
-rw-r--r--vnfmarket/app/modules/layouts/side-nav/sidenav.html46
-rw-r--r--vnfmarket/app/modules/layouts/side-nav/sidenavCtrl.js68
22 files changed, 1855 insertions, 0 deletions
diff --git a/vnfmarket/app/modules/home/home-test.js b/vnfmarket/app/modules/home/home-test.js
new file mode 100644
index 00000000..a182a9b3
--- /dev/null
+++ b/vnfmarket/app/modules/home/home-test.js
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.test:homeTest
+ * @description
+ * # homeTest
+ * Test of the app
+ */
+
+ describe('Home - Marketplace', function() {
+ var controller = null,
+ $scope = null,
+ $location, service, httpBackend, config, state;
+
+ beforeEach(function() {
+ module('vnfmarket');
+ });
+ beforeEach(module('ui.router'));
+ beforeEach(module('md.data.table'));
+ beforeEach(module('pascalprecht.translate'));
+
+ beforeEach(inject(function($controller, $rootScope, _$location_, homeService, $httpBackend, vnfConfig, $state) {
+ $scope = $rootScope.$new();
+ $location = _$location_;
+ service = homeService;
+ httpBackend = $httpBackend;
+ config = vnfConfig;
+ state = $state;
+ controller = $controller('HomeCtrl', {
+ $scope: $scope
+ });
+ }));
+
+ it('Should HomeCtrl must be defined', function() {
+ expect(controller).toBeDefined();
+ });
+
+ it('Service List response should be of type array', function() {
+ var data = [{
+ "csarId": "26b4d6c4-a157-43c0-8ebc-9d6af1d6c40c",
+ "name": "clearwater_vnf",
+ "downloadUri": "null/files/catalog-http/NFAR/Canonical/clearwater_vnf/v1.0/clearwater_vnf.csar",
+ "report": "/Demo/reports/b3232e0c-3843-4df8-88e7-734cf2d7a97c/report.html",
+ "size": "1.8 MB",
+ "version": "v1.0",
+ "provider": "Canonical",
+ "type": "NFAR",
+ "format": "yaml",
+ "deletionPending": false,
+ "createTime": "2017-02-22 08:59:06",
+ "modifyTime": "2017-02-22 08:59:06",
+ "shortDesc": "",
+ "details": "",
+ "remarks": ""
+ }];
+ httpBackend.whenGET(config.common.baseUrl + config.api.home.getFeaturesList.url).respond(200, data);
+
+ var returnData = {};
+ httpBackend.expectGET(config.common.baseUrl + config.api.home.getFeaturesList.url).respond(returnData);
+
+ service.getFeaturesList().then(function(response) {
+ expect(response.data).toBeDefined();
+ expect(Array.isArray(response.data)).toBeTruthy();
+ });
+ httpBackend.flush();
+ });
+
+ it('Service List response is not of array type', function() {
+ var data = {};
+ httpBackend.whenGET(config.common.baseUrl + config.api.home.getFeaturesList.url).respond(200, data);
+
+ var returnData = {};
+ httpBackend.expectGET(config.common.baseUrl + config.api.home.getFeaturesList.url).respond(returnData);
+
+ service.getFeaturesList().then(function(response) {
+ expect(response.data).toBeDefined();
+ expect(Array.isArray(response.data)).toBeFalsy();
+ });
+ httpBackend.flush();
+ });
+
+ it('Service List response should contain service details', function() {
+ var returnData = {};
+ var data = [{
+ "csarId": "26b4d6c4-a157-43c0-8ebc-9d6af1d6c40c",
+ "name": "clearwater_vnf",
+ "downloadUri": "null/files/catalog-http/NFAR/Canonical/clearwater_vnf/v1.0/clearwater_vnf.csar",
+ "report": "/Demo/reports/b3232e0c-3843-4df8-88e7-734cf2d7a97c/report.html",
+ "size": "1.8 MB",
+ "version": "v1.0",
+ "provider": "Canonical",
+ "type": "NFAR",
+ "format": "yaml",
+ "deletionPending": false,
+ "createTime": "2017-02-22 08:59:06",
+ "modifyTime": "2017-02-22 08:59:06",
+ "shortDesc": "",
+ "details": "",
+ "remarks": ""
+ }];
+ httpBackend.whenGET(config.common.baseUrl + config.api.home.getFeaturesList.url).respond(200, data);
+
+ httpBackend.expectGET(config.common.baseUrl + config.api.home.getFeaturesList.url).respond(returnData);
+ service.getFeaturesList().then(function(response) {
+ expect(response.data).toBeDefined();
+ var serviceDetails = response.data[0];
+ expect(serviceDetails.csarId).toBeDefined();
+ expect(serviceDetails.name).toBeDefined();
+ expect(serviceDetails.downloadUri).toBeDefined();
+ expect(serviceDetails.report).toBeDefined();
+ expect(serviceDetails.size).toBeDefined();
+ expect(serviceDetails.version).toBeDefined();
+ expect(serviceDetails.provider).toBeDefined();
+ expect(serviceDetails.type).toBeDefined();
+ expect(serviceDetails.format).toBeDefined();
+ expect(serviceDetails.deletionPending).toBeDefined();
+ expect(serviceDetails.createTime).toBeDefined();
+ expect(serviceDetails.modifyTime).toBeDefined();
+ expect(serviceDetails.shortDesc).toBeDefined();
+ expect(serviceDetails.details).toBeDefined();
+ expect(serviceDetails.remarks).toBeDefined();
+ });
+ httpBackend.flush();
+ });
+
+ it('Should match the path Module name', function() {
+ $location.path('/marketplace');
+ expect($location.path()).toBe('/marketplace');
+ });
+
+ it('Path to the state home has to be defined', function() {
+ expect(state.href("home")).toBe('#!');
+ });
+
+ it('Path to the state home.marketplace has to be defined', function() {
+ expect(state.href("home.marketplace")).toBe('#!/marketplace');
+ });
+
+ it('Path to the state home.serviceDetails has to be defined', function() {
+ expect(state.href("home.serviceDetails")).toBe('#!/serviceDetails');
+ });
+
+ it('When a state is invalid', function() {
+ expect(state.href("blah")).toBeNull('/marketplace');
+ });
+ });
+})(); \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/home.html b/vnfmarket/app/modules/home/home.html
new file mode 100644
index 00000000..4dc16960
--- /dev/null
+++ b/vnfmarket/app/modules/home/home.html
@@ -0,0 +1,52 @@
+<!--
+ Copyright 2017 Huawei Technologies Co., Ltd.
+
+ 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.
+-->
+<md-sidenav layout="column" class="md-sidenav-left md-whiteframe-z2" md-component-id="left" md-is-locked-open="$mdMedia('gt-md')" id="sideNav">
+ <div ng-controller="SidenavCtrl as vm" ng-cloak>
+ <md-toolbar class="md-tall md-hue-2">
+ <div layout="column" class="md-toolbar-tools-bottom inset">
+ </div>
+ </md-toolbar>
+ <md-list>
+ <md-list-item ui-sref="home.marketplace">
+ <div class="inset">
+ <ng-md-icon icon="apps"></ng-md-icon>
+ </div>
+ <p> {{ 'module.marketplace.sideNav.marketplaceNav' | translate}} </p>
+ </md-list-item>
+ <md-list-item ng-repeat="item in vm.menu" ng-click="vm.navigateTo('home.' + item.link)">
+ <div class="inset" ng-show="item.icon">
+ <ng-md-icon icon="{{item.icon}}"></ng-md-icon>
+ </div>
+ <p> {{ item.name }}</p>
+ </md-list-item>
+ <md-divider></md-divider>
+ </md-list>
+ </div>
+</md-sidenav>
+
+<div layout="column" class="relative" layout-fill role="main" ng-controller="LayoutCtrl as layout" ng-cloak>
+ <md-toolbar class="md-hue-2 md-whiteframe-z2">
+ <div class="md-toolbar-tools">
+ <md-button ng-click="layout.toggleSidenav('left')" hide-gt-md aria-label="Menu">
+ <ng-md-icon icon="menu"></ng-md-icon>
+ </md-button>
+ <h3>{{ 'module.marketplace.main.headerTitle' | translate}}</h3>
+ </div>
+ </md-toolbar>
+ <md-content layout="column" flex md-scroll-y style="background-color:#DCDCDC">
+ <div ui-view></div>
+ </md-content>
+</div> \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/homeCtrl.js b/vnfmarket/app/modules/home/homeCtrl.js
new file mode 100644
index 00000000..a48e05e4
--- /dev/null
+++ b/vnfmarket/app/modules/home/homeCtrl.js
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.controller:HomeCtrl
+ * @description
+ * # HomeCtrl
+ * Controller of the app
+ */
+
+ angular
+ .module('vnfmarket')
+ .controller('HomeCtrl', Home);
+
+ Home.$inject = ['$mdDialog', 'homeService', 'vnfConfig', '$state'];
+
+ /*
+ * recommend
+ * Using function declarations
+ * and bindable members up top.
+ */
+
+ function Home($mdDialog, homeService, vnfConfig, $state) {
+ /*jshint validthis: true */
+ var vm = this;
+ vm.showSearch = true;
+ vm.hasGridView = localStorage.getItem("viewType") === "list" ? false : true;
+ if (!localStorage.getItem("viewType")) {
+ localStorage.setItem("viewType", "grid");
+ }
+ vm.SpinClass = "";
+
+ vm.filter = {
+ "search": '',
+ "name": 'TableList'
+ };
+
+ vm.listViewActions = {
+ "search": ""
+ }
+
+ vm.pagination = [5, 10, 15, {
+ label: 'All',
+ value: function() {
+ return vm.services.length ? vm.services.length : 0;
+ }
+ }];
+
+ vm.paginationQuery = {
+ order: "name",
+ limit: 10,
+ page: 1
+ };
+
+ vm.paginationOptions = {
+ rowSelect: false,
+ multiSelect: false,
+ autoSelect: false,
+ autoSelect: false,
+ decapitate: false,
+ largeEditDialog: false,
+ boundaryLink: true,
+ limitSelect: true,
+ pageSelect: true
+ };
+
+ vm.getFeatureList = function() {
+ vm.SpinClass = "fa-spin"
+ homeService.getFeaturesList().then(function(response) {
+ for (var i = 0; i < response.data.length; i++) {
+ response.data[i].createTime = new Date(response.data[i].createTime);
+ response.data[i].modifyTime = new Date(response.data[i].modifyTime);
+ }
+ vm.services = response.data;
+ vm.SpinClass = ""
+ });
+ }
+
+ vm.downloadService = function(csarId) {
+ homeService.downloadServiceFile(csarId);
+ }
+
+ vm.changeView = function(viewType) {
+ vm.hasGridView = !vm.hasGridView;
+ localStorage.setItem('viewType', viewType);
+ }
+
+ vm.showDetails = function(serviceDetails) {
+ $state.go('home.serviceDetails', {
+ serviceDetails: serviceDetails
+ });
+ }
+
+ vm.serviceUpload = function() {
+ $mdDialog.show({
+ controller: 'serviceUploadCtrl',
+ templateUrl: vnfConfig.modulePath.home + '/serviceUpload/serviceUpload.html',
+ controllerAs: 'vm'
+ })
+ .then(function(answer) {
+ vm.getFeatureList();
+ // vm.status = 'You said the information was "' + answer + '".';
+ }, function() {
+ // vm.status = 'You cancelled the dialog.';
+ });
+ };
+
+ vm.onDeleteCompletion = function() {
+ vm.getFeatureList();
+ }
+
+ vm.serviceDelete = function(serviceDetails) {
+ homeService.openDeleteDialog(serviceDetails, vm.onDeleteCompletion);
+ };
+
+ vm.getFeatureList();
+ }
+
+})(); \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/homeModule.js b/vnfmarket/app/modules/home/homeModule.js
new file mode 100644
index 00000000..acf0516c
--- /dev/null
+++ b/vnfmarket/app/modules/home/homeModule.js
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.module:homeModule
+ * @description
+ * # homeModule
+ * Module of the app
+ */
+
+ angular.module('home', []);
+})(); \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/homeRoute.js b/vnfmarket/app/modules/home/homeRoute.js
new file mode 100644
index 00000000..68bcef7d
--- /dev/null
+++ b/vnfmarket/app/modules/home/homeRoute.js
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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.
+ */
+'use strict';
+
+/**
+ * @ngdoc function
+ * @name app.route:HomeRoute
+ * @description
+ * # HomeRoute
+ * Route of the app
+ */
+
+angular.module('vnfmarket')
+ .config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider, vnfConfig) {
+
+ var homePath = 'vnfmarket/app/modules/home';
+ $stateProvider
+ .state('home', {
+ url: '',
+ abstract: true,
+ templateUrl: homePath + '/home.html',
+ controller: 'HomeCtrl',
+ controllerAs: 'vm'
+ })
+ .state('home.marketplace', {
+ url: '/marketplace',
+ templateUrl: homePath + '/marketplace.html'
+ })
+ .state('home.serviceDetails', {
+ url: '/serviceDetails',
+ templateUrl: homePath + '/serviceDetails/serviceDetails.html',
+ params: {
+ serviceDetails: undefined
+ },
+ controller: 'serviceDetailsCtrl',
+ controllerAs: 'vm'
+ });
+ }]); \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/homeService.js b/vnfmarket/app/modules/home/homeService.js
new file mode 100644
index 00000000..dde31564
--- /dev/null
+++ b/vnfmarket/app/modules/home/homeService.js
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.service:homeService
+ * @description
+ * # homeService
+ * Service of the app
+ */
+
+ angular.module('vnfmarket')
+ .factory('homeService', homeService);
+
+ homeService.$inject = ['$q', 'vnfConfig', 'httpService', '$mdDialog'];
+
+ function homeService($q, vnfConfig, httpService, $mdDialog) {
+ return {
+ getFeaturesList: getFeaturesList,
+ downloadServiceFile: downloadServiceFile,
+ openDeleteDialog: openDeleteDialog
+ };
+
+ function getFeaturesList() {
+ var url = vnfConfig.common.baseUrl + vnfConfig.api.home.getFeaturesList.url,
+ method = vnfConfig.api.home.getFeaturesList.method;
+
+ var defer = $q.defer()
+ httpService.apiRequest(url, method)
+ .then(function(response) {
+ defer.resolve(response);
+ }, function(error) {
+ defer.reject(error);
+ });
+ return defer.promise;
+ }
+
+ function downloadServiceFile(csarId) {
+ var url = vnfConfig.common.baseUrl + vnfConfig.api.home.downloadServiceFile.url;
+ url = url.replace(":csarId", csarId)
+ window.location.href = url;
+ }
+
+ function openDeleteDialog(serviceDetails, callbackFunction) {
+ $mdDialog.show({
+ controller: 'serviceDeleteCtrl',
+ templateUrl: vnfConfig.modulePath.home + '/serviceDelete/serviceDelete.html',
+ serviceDetails: serviceDetails,
+ controllerAs: 'vm'
+ })
+ .then(function(answer) {
+ //vm.status = 'You said the information was "' + answer + '".';
+ callbackFunction();
+ }, function() {
+ //vm.status = 'You cancelled the dialog.';
+ });
+ }
+
+ }
+
+})(); \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/marketplace.html b/vnfmarket/app/modules/home/marketplace.html
new file mode 100644
index 00000000..5e2916ac
--- /dev/null
+++ b/vnfmarket/app/modules/home/marketplace.html
@@ -0,0 +1,228 @@
+<!--
+ Copyright 2017 Huawei Technologies Co., Ltd.
+
+ 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.
+-->
+<div class="md-padding" flex layout-sm="column">
+ <md-card>
+ <md-card-content>
+ <p> </p>
+ <h4>{{'module.marketplace.main.description' | translate }}</h4>
+ <ul id="description">
+ <li>{{'module.marketplace.main.pointOne' | translate }}</li>
+ <li>{{'module.marketplace.main.pointTwo' | translate }}</li>
+ </ul>
+ </md-card-content>
+ </md-card>
+ <!-- Start About Page -->
+ <md-card>
+ <md-toolbar id="homeToolbar" class="md-hue-2">
+ <div class="md-toolbar-tools">
+ <md-select ng-model="sortBy" placeholder="{{'module.marketplace.main.sortBy.title'| translate}}" class="md-no-underline noMargin iconMargin fontSize" id="sortByLabel">
+ <md-option class="fontSize" value="">{{'module.marketplace.main.sortBy.title' | translate}}</md-option>
+ <md-option class="fontSize" value="{{'module.marketplace.main.sortBy.options.name.value' | translate}}">{{'module.marketplace.main.sortBy.options.name.key' | translate}}</md-option>
+ <md-option class="fontSize" value="{{'module.marketplace.main.sortBy.options.dateModified.value' | translate}}">{{'module.marketplace.main.sortBy.options.dateModified.key' | translate}}</md-option>
+ <md-option class="fontSize" value="{{'module.marketplace.main.sortBy.options.downloads.value' | translate}}">{{'module.marketplace.main.sortBy.options.downloads.key' | translate}}</md-option>
+ </md-select>
+
+ <md-icon class="md-icon iconAlignment defaultColor" aria-label="{{'module.marketplace.main.search.label' | translate}}" ng-if="!vm.showSearch">
+ <i class="fa fa-search" aria-hidden="true"></i>
+ </md-icon>
+ <form flex name="vm.filter.name">
+ <md-input-container md-no-float class="md-block" id="searchFieldContainer" ng-if="!vm.showSearch">
+ <input class="fontSize" ng-model="vm.filter.search" type="text" id="searchField" placeholder="{{'module.marketplace.main.search.placeholder' | translate}}" autofocus>
+ </md-input-container>
+ </form>
+
+ <md-icon class="md-icon iconAlignment defaultColor" aria-label="{{'common.actions.close' | translate}}" ng-click="vm.showSearch = !vm.showSearch; vm.filter.search = '';" ng-if="!vm.showSearch">
+ <md-tooltip md-direction="top">{{'common.actions.close' | translate}}</md-tooltip>
+ <i class="fa fa-close" aria-hidden="true"></i>
+ </md-icon>
+ <md-icon class="md-icon iconMargin iconAlignment defaultColor" aria-label="{{'common.actions.search' | translate}}" ng-if="vm.showSearch" ng-click="vm.showSearch = !vm.showSearch;">
+
+ <md-tooltip md-direction="top">{{'common.actions.search' | translate}}</md-tooltip>
+ <i class="fa fa-search" aria-hidden="true"></i>
+ </md-icon>
+
+ <button id="serviceUpload" type="button" class="btn btnDefault iconMargin" ng-click="vm.serviceUpload()">{{'module.marketplace.main.upload.label' | translate}}</button>
+
+ <span ng-if="vm.services.length > 0" class="iconMargin">
+ <md-icon class="md-icon iconAlignment defaultColor" aria-label="{{'module.marketplace.main.gridView.label' | translate}}" ng-if="!vm.hasGridView" ng-click="vm.changeView('grid')">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.gridView.label' | translate}}</md-tooltip>
+ <i class="fa fa-th" aria-hidden="true"></i>
+ </md-icon>
+ <md-icon class="md-icon iconAlignment defaultColor" aria-label="{{'module.marketplace.main.listView.label' | translate}}" ng-if="vm.hasGridView" ng-click="vm.changeView('list')">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.listView.label' | translate}}</md-tooltip>
+ <i class="fa fa-list" aria-hidden="true"></i>
+ </md-icon>
+ </span>
+ <md-icon class="md-icon iconAlignment defaultColor" aria-label="{{'module.marketplace.main.refresh.label' | translate}}" ng-click="vm.getFeatureList()">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.refresh.label' | translate}}</md-tooltip>
+ <i class="fa fa-refresh" ng-class="vm.SpinClass" aria-hidden="true"></i>
+ </md-icon>
+
+ </div>
+ </md-toolbar>
+ </md-card>
+ <div class="md-padding" layout-xs="column" layout="row" layout-wrap ng-if="vm.hasGridView && vm.services.length > 0" id="gridView">
+ <md-card class="gridViewMargin md-padding" flex-xs="50" flex-gt-xs="30" ng-repeat="service in vm.services | filter: vm.filter.search| orderBy:sortBy" layout-wrap>
+ <md-card-header>
+ <md-card-header-text>
+ <span class="md-headline"><a class="pointerClick" ng-click="vm.showDetails(service)">{{service.name}}</a></span>
+ </md-card-header-text>
+ <span class="mdl-layout-spacer"></span>
+ <span id="service-type-name" class="mdl-chip mdl-chip--contact service-detail-tags" data-toggle="tooltip">
+
+ <md-tooltip md-direction="top">{{'module.marketplace.main.gridView.serviceType.label' | translate}}</md-tooltip>
+ <span class="mdl-chip__contact mdl-color--teal mdl-color-text--white"><i class="material-icons service-details-icon">{{'module.marketplace.main.gridView.serviceType.value' | translate}}</i></span>
+ <span class="mdl-chip__text">{{service.type}}</span>
+ </span>
+ <span id="service-downloads-count" class="mdl-chip mdl-chip--contact service-detail-tags" data-toggle="tooltip">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.gridView.downloads.label' | translate}}</md-tooltip>
+ <span class="mdl-chip__contact mdl-color--teal mdl-color-text--white"><i class="material-icons service-details-icon">{{'module.marketplace.main.gridView.downloads.value' | translate}}</i></span>
+ <span class="mdl-chip__text">{{service.downloads ?service.downloads : 0 }}</span>
+ </span>
+ </md-card-header>
+ <div class="mdl-card__supporting-text service-desc">
+ {{service.shortDesc}}
+ </div>
+ <md-card-actions layout="row" layout-align="start center" class="mdl-card__actions service-actions">
+ <div class="col-sm-12 no-padding">
+ <div class="col-md-8 no-padding">
+ <div class="pull-left">
+ <div class="btn-group btn-group-xs" role="group">
+ <button class="show-deploy btn btn-default btnDefault" data-toggle="modal" data-target="#service-update-history-modal" data-tooltip="tooltip">
+
+ <md-tooltip md-direction="top">{{'module.marketplace.main.gridView.upload.tooltip' | translate}}</md-tooltip>
+ <i class="fa fa-history" aria-hidden="true"></i>
+ {{'module.marketplace.main.gridView.upload.buttonLabel' | translate}}
+ </button>
+ <button id="delete-service-button" class="show-deploy btn btn-default btnDefault" data-toggle="modal" data-target="#service-download-history-modal" data-tooltip="tooltip">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.gridView.downloads.tooltip' | translate}}</md-tooltip>
+ <i class="fa fa-history fa-flip-horizontal"></i>
+ {{'module.marketplace.main.gridView.downloads.buttonLabel' | translate}}
+ </button>
+ </div>
+ </div>
+ </div>
+ <div class="col-md-4 no-padding">
+ <div class="pull-right">
+ <div class="btn-group btn-group-xs" role="group">
+ <button class="show-deploy btn btn-default btnDefault actionBtnHeight">
+ <md-tooltip md-direction="top">{{'common.actions.update' | translate}}</md-tooltip>
+ <i class="material-icons materialIconAdjustment">{{'common.actions.fileUpload' | translate}}</i>
+ </button>
+ <button class="show-deploy btn btn-default btnDefault actionBtnHeight" ng-click="vm.downloadService(service.csarId)">
+ <md-tooltip md-direction="top">{{'common.actions.download' | translate}}</md-tooltip>
+ <i class="material-icons materialIconAdjustment">{{'common.actions.getApp' | translate}}</i>
+ </button>
+ <button id="delete-service-button" class="show-deploy btn btn-default btnDefault" ng-click="vm.serviceDelete(service)">
+ <md-tooltip md-direction="top">{{'common.actions.delete' | translate}}</md-tooltip>
+ <i class="fa fa-times icon-red fa-lg"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </md-card-actions>
+ </md-card>
+ </div>
+ <md-card flex="100" ng-if="!vm.hasGridView && vm.services.length > 0" id="listView">
+ <md-table-container>
+ <table md-table>
+ <thead md-head md-order="sortBy">
+ <tr md-row>
+ <th md-column class="text-center fontSize">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.listView.headers.name' | translate}}</md-tooltip>{{'module.marketplace.main.listView.headers.name' | translate}}
+ </th>
+ <th md-column class="text-center fontSize">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.listView.headers.provider' | translate}}</md-tooltip>{{'module.marketplace.main.listView.headers.provider' | translate}}</th>
+ <th md-column class="text-center fontSize">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.listView.headers.description' | translate}}</md-tooltip>{{'module.marketplace.main.listView.headers.description' | translate}}</th>
+ <th md-column class="text-center fontSize">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.listView.headers.type' | translate}}</md-tooltip>{{'module.marketplace.main.listView.headers.type' | translate}}</th>
+ <th md-column class="text-center fontSize">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.listView.headers.size' | translate}}</md-tooltip>{{'module.marketplace.main.listView.headers.size' | translate}}</th>
+ <th md-column class="text-center fontSize">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.listView.headers.createdAt' | translate}}</md-tooltip>{{'module.marketplace.main.listView.headers.createdAt' | translate}}</th>
+ <th md-column class="text-center fontSize">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.listView.headers.lastModified' | translate}}</md-tooltip>{{'module.marketplace.main.listView.headers.lastModified' | translate}}</th>
+ <th md-column md-numeric class="text-center fontSize">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.listView.headers.donwloads' | translate}}</md-tooltip>{{'module.marketplace.main.listView.headers.donwloads' | translate}}</th>
+ <th md-column md-numeric class="text-center fontSize">
+ <md-tooltip md-direction="top">{{'module.marketplace.main.listView.headers.actions' | translate}}</md-tooltip>{{'module.marketplace.main.listView.headers.actions' | translate}}</th>
+ </tr>
+ </thead>
+ <tbody md-body>
+ <tr md-row md-select="dessert" md-select-id="name" md-auto-select ng-repeat="service in vm.services | filter: vm.filter.search | orderBy:sortBy | limitTo: vm.paginationQuery.limit: (vm.paginationQuery.page - 1) * vm.paginationQuery.limit">
+ <td md-cell class="text-center">
+ <md-tooltip md-direction="top">{{service.name}}</md-tooltip>
+ <a class="pointerClick" ng-click="vm.showDetails(service)">{{service.name}}</a></td>
+ <td md-cell class="text-center">
+ <md-tooltip md-direction="top">{{service.provider}}</md-tooltip>
+ {{service.provider}}</td>
+ <td md-cell class="text-center">
+ <md-tooltip md-direction="top">{{service.shortDesc}}</md-tooltip>
+ {{service.shortDesc | limitTo:50 }}<span ng-if="service.shortDesc.length > 50">...<span></td>
+ <td md-cell class="text-center">
+ <md-tooltip md-direction="top">{{service.type}}</md-tooltip>
+ {{service.type}}</td>
+ <td md-cell class="text-center">
+ <md-tooltip md-direction="top">{{service.size}}</md-tooltip>
+ {{service.size}}</td>
+ <td md-cell class="text-center">
+ <md-tooltip md-direction="top">{{service.createTime | date:'yyyy-MM-dd h:mm a'}}</md-tooltip>
+ {{service.createTime | date:'yyyy-MM-dd h:mm a'}}</td>
+ <td md-cell class="text-center">
+ <md-tooltip md-direction="top">{{service.modifyTime | date:'yyyy-MM-dd h:mm a'}}</md-tooltip>
+ {{service.modifyTime | date:'yyyy-MM-dd h:mm a'}}</td>
+ <td md-cell class="text-center">
+ <md-tooltip md-direction="top">{{service.downloads ?service.downloads : 0 }}</md-tooltip>
+ {{service.downloads ?service.downloads : 0 }}</td>
+ <td md-cell>
+ <span class="pull-right">
+ <md-icon class="md-icon" aria-label="{{'common.actions.update' | translate}}">
+ <md-tooltip md-direction="top">{{'common.actions.update' | translate}}</md-tooltip>
+ <i class="material-icons materialIconAdjustment" aria-hidden="true">{{'common.actions.fileUpload' | translate}}</i>
+ </md-icon>
+ <md-icon class="md-icon" aria-label="{{'common.actions.download' | translate}}" ng-click="vm.downloadService(service.csarId)">
+ <md-tooltip md-direction="top">{{'common.actions.download' | translate}}</md-tooltip>
+ <i class="material-icons materialIconAdjustment" aria-hidden="true">{{'common.actions.getApp' | translate}}</i>
+ </md-icon>
+ <md-icon class="md-icon" aria-label="{{'common.actions.delete' | translate}}" ng-click="vm.serviceDelete(service)">
+ <md-tooltip md-direction="top">{{'common.actions.delete' | translate}}</md-tooltip>
+ <i class="fa fa-times icon-red fa-sm" aria-hidden="true"></i>
+ </md-icon>
+ <md-icon class="md-icon" aria-label="Delete service" >
+ </span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </md-table-container>
+ <md-table-pagination class="pagination-class" md-limit="vm.paginationQuery.limit" md-limit-options="vm.pagination" md-page="vm.paginationQuery.page" md-total="{{vm.services.length}}" md-page-select="vm.paginationOptions.pageSelect" md-boundary-links="vm.paginationOptions.boundaryLink" md-label="{ page : 'Page', RowPerPage:'row per page', of:'of'}"></md-table-pagination>
+ </md-card>
+
+ <md-card ng-if=" vm.services.length == 0">
+ <div flex layout="row">
+ <div flex="25" layout="column">
+ </div>
+ <div flex="50" layout="column" id="emptyList">
+ <h4 class="text-center">{{'module.marketplace.main.emptyList.label' | translate}} <a ng-click="vm.serviceUpload()">{{'module.marketplace.main.emptyList.anchor' | translate}}</a> {{'module.marketplace.main.emptyList.labelContinued' | translate}} </h4>
+ </div>
+ <div flex="25" layout="column">
+ </div>
+ </div>
+ </md-card>
+</div>
+</div> \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/serviceDelete/serviceDelete-test.js b/vnfmarket/app/modules/home/serviceDelete/serviceDelete-test.js
new file mode 100644
index 00000000..2fb828a1
--- /dev/null
+++ b/vnfmarket/app/modules/home/serviceDelete/serviceDelete-test.js
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.test:homeTest
+ * @description
+ * # homeTest
+ * Test of the app
+ */
+ angular
+ .module('vnfmarket')
+ .constant("serviceDetails", {
+ "csarId": "26b4d6c4-a157-43c0-8ebc-9d6af1d6c40c",
+ "name": "clearwater_vnf",
+ "downloadUri": "null/files/catalog-http/NFAR/Canonical/clearwater_vnf/v1.0/clearwater_vnf.csar",
+ "report": "/Demo/reports/b3232e0c-3843-4df8-88e7-734cf2d7a97c/report.html",
+ "size": "1.8 MB",
+ "version": "v1.0",
+ "provider": "Canonical",
+ "type": "NFAR",
+ "format": "yaml",
+ "deletionPending": false,
+ "createTime": "2017-02-22 08:59:06",
+ "modifyTime": "2017-02-22 08:59:06",
+ "shortDesc": "",
+ "details": "",
+ "remarks": ""
+ })
+
+ describe('Home - serviceDeleteCtrl', function() {
+ var controller = null,
+ $scope = null,
+ $location, service, httpBackend, config, state, blah;
+
+ beforeEach(function() {
+ module('vnfmarket');
+ });
+ beforeEach(module('ui.router'));
+ beforeEach(module('md.data.table'));
+ beforeEach(module('pascalprecht.translate'));
+
+ beforeEach(inject(function($controller, $rootScope, serviceDeleteService, $httpBackend, vnfConfig, serviceDetails) {
+ $scope = $rootScope.$new();
+ service = serviceDeleteService;
+ httpBackend = $httpBackend;
+ config = vnfConfig;
+ blah = serviceDetails;
+ controller = $controller('serviceDeleteCtrl', {
+ $scope: $scope
+ });
+ }));
+
+ it('Should serviceDeleteCtrl must be defined', function() {
+ expect(controller).toBeDefined();
+ });
+
+ it('Delete service for a valid scenario', function() {
+ var csarId = "26b4d6c4-a157-43c0-8ebc-9d6af1d6c40c", url = config.common.baseUrl + config.api.home.serviceDelete.url;
+ url = url.replace(":csarId", csarId);
+ httpBackend.whenDELETE(url).respond(200, {});
+
+ var returnData = {};
+ httpBackend.expectDELETE(url).respond(returnData);
+
+ service.serviceDelete(csarId).then(function(response) {
+ expect(response.status).toBeDefined();
+ expect(response.status).toBe(200);
+ });
+ httpBackend.flush();
+ });
+
+ // it('Delete service for a valid scenario', function() {
+ // var csarId = "Test-26b4d6c4-a157-43c0-8ebc-9d6af1d6c40c-test", url = config.common.baseUrl + config.api.home.serviceDelete.url;
+ // url = url.replace(":csarId", csarId);
+ // httpBackend.whenDELETE(url).respond(500, { "errorText" : "Invalid"});
+
+ // var returnData = {}, code;
+ // httpBackend.expectDELETE(url).respond(returnData);
+
+ // service.serviceDelete(csarId).then(function(response) {
+ // expect(response.data).toBeDefined();
+ // expect(response.data).toBe("Invalid");
+ // });
+ // httpBackend.flush();
+ // });
+ });
+})(); \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/serviceDelete/serviceDelete.html b/vnfmarket/app/modules/home/serviceDelete/serviceDelete.html
new file mode 100644
index 00000000..05ca674e
--- /dev/null
+++ b/vnfmarket/app/modules/home/serviceDelete/serviceDelete.html
@@ -0,0 +1,48 @@
+<!--
+ Copyright 2017 Huawei Technologies Co., Ltd.
+
+ 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.
+-->
+<md-dialog aria-label="Delete Service dialog" flex="30" class="md-red-theme">
+ <form ng-cloak>
+ <md-toolbar class="md-hue-2 dialogHeader">
+ <div class="md-toolbar-tools">
+ <h2>{{'module.marketplace.serviceDelete.title' | translate}}</h2>
+ <span flex></span>
+ <button class="btnTransparency" ng-click="vm.cancel()">
+ <i class="fa fa-close fa-sm" aria-hidden="true"></i>
+ </button>
+ </div>
+ </md-toolbar>
+
+ <md-dialog-content>
+ <div class="md-dialog-content">
+ <div class="fullWidth center">
+ <div class="row">
+ <div class="col-xs-2 col-sm-2 col-md-1 col-lg-1 deleteIconSize glyphicon glyphicon-warning-sign icon_warning"></div>
+ <div class="msg col-xs-10 col-sm-10 col-md-11 col-lg-11" style="text-align:left;vertical-align: middle;">{{'module.marketplace.serviceDelete.confirmationMesaage' | translate}} "{{ vm.serviceDetails.name }}"?</div>
+ </div>
+ </div>
+ </md-dialog-content>
+
+ <md-dialog-actions layout="row" class="row deleteAction">
+
+ <button ng-click="vm.answer('Deleted')" class="btn btnDefault btnSpacing deleteBtn">
+ {{'common.actions.yes' | translate}}
+ </button>
+ <button ng-click="vm.cancel()" class="btn btnDefault deleteBtn">
+ {{'common.actions.no' | translate}}
+ </button>
+ </md-dialog-actions>
+ </form>
+</md-dialog> \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/serviceDelete/serviceDeleteCtrl.js b/vnfmarket/app/modules/home/serviceDelete/serviceDeleteCtrl.js
new file mode 100644
index 00000000..5eafe9e8
--- /dev/null
+++ b/vnfmarket/app/modules/home/serviceDelete/serviceDeleteCtrl.js
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.controller:HomeCtrl
+ * @description
+ * # HomeCtrl
+ * Controller of the app
+ */
+
+ angular
+ .module('vnfmarket')
+ .controller('serviceDeleteCtrl', ServiceDelete);
+
+ ServiceDelete.$inject = ['serviceDeleteService', '$mdDialog', '$mdToast', 'serviceDetails'];
+
+ /*
+ * recommend
+ * Using function declarations
+ * and bindable members up top.
+ */
+
+ function ServiceDelete(serviceDeleteService, $mdDialog, $mdToast, serviceDetails) {
+ var vm = this;
+ vm.serviceDetails = serviceDetails;
+
+ vm.hide = function() {
+ $mdDialog.hide();
+ };
+
+ vm.cancel = function() {
+ $mdDialog.cancel();
+ };
+
+ vm.answer = function(answer) {
+ serviceDeleteService.serviceDelete(vm.serviceDetails.csarId)
+ .then(function(response) {
+ $mdDialog.hide(response);
+ $mdToast.show(
+ $mdToast.simple()
+ .textContent('Service deleted successfully')
+ .position("bottom right")
+ .action('Ok')
+ .theme('success-toast')
+ );
+ });
+ };
+ }
+})(); \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/serviceDelete/serviceDeleteService.js b/vnfmarket/app/modules/home/serviceDelete/serviceDeleteService.js
new file mode 100644
index 00000000..9664b97f
--- /dev/null
+++ b/vnfmarket/app/modules/home/serviceDelete/serviceDeleteService.js
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.service:homeService
+ * @description
+ * # homeService
+ * Service of the app
+ */
+
+ angular.module('vnfmarket')
+ .factory('serviceDeleteService', serviceDelete);
+
+ serviceDelete.$inject = ['$q', 'vnfConfig', 'httpService'];
+
+ function serviceDelete($q, vnfConfig, httpService) {
+ return {
+ serviceDelete: serviceDelete
+ };
+
+ function serviceDelete(csarId) {
+ var url = vnfConfig.common.baseUrl + vnfConfig.api.home.serviceDelete.url,
+ method = vnfConfig.api.home.serviceDelete.method;
+ url = url.replace(":csarId", csarId)
+ var defer = $q.defer()
+ httpService.apiRequest(url, method)
+ .then(function(response) {
+ defer.resolve(response);
+ }, function(error) {
+ defer.reject(error);
+ });
+ return defer.promise;
+ }
+ }
+
+})(); \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/serviceDetails/serviceDetails-test.js b/vnfmarket/app/modules/home/serviceDetails/serviceDetails-test.js
new file mode 100644
index 00000000..0c6edc27
--- /dev/null
+++ b/vnfmarket/app/modules/home/serviceDetails/serviceDetails-test.js
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.test:homeTest
+ * @description
+ * # homeTest
+ * Test of the app
+ */
+
+ describe('Home - serviceDetailsCtrl', function() {
+ var controller = null,
+ $scope = null,
+ $location, stateParams, httpBackend, config, state, blah;
+ var data = {
+ "csarId": "26b4d6c4-a157-43c0-8ebc-9d6af1d6c40c",
+ "name": "clearwater_vnf",
+ "downloadUri": "null/files/catalog-http/NFAR/Canonical/clearwater_vnf/v1.0/clearwater_vnf.csar",
+ "report": "/Demo/reports/b3232e0c-3843-4df8-88e7-734cf2d7a97c/report.html",
+ "size": "1.8 MB",
+ "version": "v1.0",
+ "provider": "Canonical",
+ "type": "NFAR",
+ "format": "yaml",
+ "deletionPending": false,
+ "createTime": "2017-02-22 08:59:06",
+ "modifyTime": "2017-02-22 08:59:06",
+ "shortDesc": "",
+ "details": "",
+ "remarks": ""
+ };
+
+ beforeEach(function() {
+ module('vnfmarket');
+ });
+ beforeEach(module('ui.router'));
+ beforeEach(module('md.data.table'));
+ beforeEach(module('pascalprecht.translate'));
+
+ beforeEach(inject(function($controller, $rootScope, $stateParams, $httpBackend, vnfConfig) {
+ $scope = $rootScope.$new();
+ stateParams = $stateParams;
+ httpBackend = $httpBackend;
+ config = vnfConfig;
+ stateParams.serviceDetails = data;
+ controller = $controller('serviceDetailsCtrl', {
+ $scope: $scope
+ });
+ }));
+
+ it('Should serviceDetailsCtrl must be defined', function() {
+ expect(controller).toBeDefined();
+ });
+
+ it('Receving state param service details', function() {
+ expect(stateParams.serviceDetails.csarId).toBeDefined();
+ expect(stateParams.serviceDetails.name).toBeDefined();
+ expect(stateParams.serviceDetails.downloadUri).toBeDefined();
+ expect(stateParams.serviceDetails.report).toBeDefined();
+ expect(stateParams.serviceDetails.size).toBeDefined();
+ expect(stateParams.serviceDetails.version).toBeDefined();
+ expect(stateParams.serviceDetails.provider).toBeDefined();
+ expect(stateParams.serviceDetails.type).toBeDefined();
+ expect(stateParams.serviceDetails.format).toBeDefined();
+ expect(stateParams.serviceDetails.deletionPending).toBeDefined();
+ expect(stateParams.serviceDetails.createTime).toBeDefined();
+ expect(stateParams.serviceDetails.modifyTime).toBeDefined();
+ expect(stateParams.serviceDetails.shortDesc).toBeDefined();
+ expect(stateParams.serviceDetails.details).toBeDefined();
+ expect(stateParams.serviceDetails.remarks).toBeDefined();
+ });
+ });
+})(); \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/serviceDetails/serviceDetails.html b/vnfmarket/app/modules/home/serviceDetails/serviceDetails.html
new file mode 100644
index 00000000..446a5cd5
--- /dev/null
+++ b/vnfmarket/app/modules/home/serviceDetails/serviceDetails.html
@@ -0,0 +1,101 @@
+<!--
+ Copyright 2017 Huawei Technologies Co., Ltd.
+
+ 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.
+-->
+
+<md-card>
+ <main class="mdl-layout__content service-details-page">
+ <div class="mdl-grid">
+ <!-- Start Top Description -->
+ <div class="mdl-card mdl-cell mdl-cell--12-col page-header-container">
+ <div class="mdl-card__title">
+ <h1 class="mdl-card__title-text">
+ {{'module.marketplace.serviceDetails.title' | translate}} {{vm.service.name}}
+ </h1>
+ <div class="mdl-layout-spacer"></div>
+ <!-- <a href="testFile.txt" download="testFile" class="show-install mdl-button mdl-js-button mdl-button--primary"><i class="material-icons">get_app</i>Download</a> -->
+ <button class="show-deploy mdl-button mdl-js-button mdl-button--primary" data-toggle="modal" data-target="#upload-service" data-uplsubmitbtn="update" ng-click="vm.downloadService(vm.service.csarId)">
+ <md-tooltip md-direction="top">{{'common.actions.download' | translate}} </md-tooltip>
+ <i class="material-icons">{{'common.actions.getApp' | translate}}</i>{{'common.actions.download' | translate}}</button>
+ <button class="show-deploy mdl-button mdl-js-button mdl-button--primary" data-toggle="modal" data-target="#upload-service" data-uplsubmitbtn="update">
+ <md-tooltip md-direction="top">{{'common.actions.update' | translate}}</md-tooltip>
+ <i class="material-icons">{{'common.actions.fileUpload' | translate}}</i>{{'common.actions.update' | translate}}</button>
+ <button id="delete-service-button" class="show-deploy mdl-button mdl-js-button mdl-button--primary" data-toggle="modal" data-target="#delete-service-modal" ng-click="vm.serviceDelete(vm.service)">
+ <md-tooltip md-direction="top">{{'common.actions.delete' | translate}}</md-tooltip>
+ <i class="fa fa-times serviceDelete"></i>{{'common.actions.delete' | translate}}</button>
+ </div>
+ <div class="mdl-card__supporting-text service-details-page-header-text">
+ <div class="row service-actions">
+ <div class="col-md-6">
+ <div class="panel panel-default">
+ <div class="panel-heading">{{'module.marketplace.serviceDetails.info.details' | translate}}</div>
+ <div class="panel-body ng-binding">{{vm.service.details}}</div>
+ </div>
+ <div class="panel panel-default">
+ <div class="panel-heading">{{'module.marketplace.serviceDetails.info.remarks' | translate}}</div>
+ <div class="panel-body ng-binding">{{vm.service.remarks}}</div>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <div class="row">
+ <div class="col-md-6">
+ <div class="panel panel-default">
+ <div class="panel-heading ng-binding">{{'module.marketplace.serviceDetails.info.provider' | translate}}</div>
+ <div class="panel-body">{{vm.service.provider}}</div>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <div class="panel panel-default">
+ <div class="panel-heading ng-binding">{{'module.marketplace.serviceDetails.info.serviceType' | translate}}</div>
+ <div class="panel-body">{{vm.service.type}}</div>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <div class="panel panel-default">
+ <div class="panel-heading ng-binding">{{'module.marketplace.serviceDetails.info.csarId' | translate}}</div>
+ <div class="panel-body">{{vm.service.csarId}}</div>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <div class="panel panel-default">
+ <div class="panel-heading ng-binding">{{'module.marketplace.serviceDetails.info.fileSize' | translate}}</div>
+ <div class="panel-body">{{vm.service.size}}</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="row service-actions">
+ <div class="col-md-6">
+ <div class="panel panel-default">
+ <div class="panel-heading">{{'module.marketplace.serviceDetails.info.funcTestReport' | translate}}</div>
+ <div class="panel-body ng-binding">
+ <a href="{{vm.service.funcTestReportUrl}}" target="_blank">{{'common.actions.clickHere' | translate}}</a>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- End top Description -->
+ <div class="mdl-layout__tab-panel is-active" id="overview">
+
+ </div>
+
+ </main>
+ <!-- main ends -->
+</md-card> \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/serviceDetails/serviceDetailsCtrl.js b/vnfmarket/app/modules/home/serviceDetails/serviceDetailsCtrl.js
new file mode 100644
index 00000000..3ec6b58a
--- /dev/null
+++ b/vnfmarket/app/modules/home/serviceDetails/serviceDetailsCtrl.js
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.controller:HomeCtrl
+ * @description
+ * # HomeCtrl
+ * Controller of the app
+ */
+
+ angular
+ .module('vnfmarket')
+ .controller('serviceDetailsCtrl', ServiceDetail);
+
+ ServiceDetail.$inject = ['serviceDetailsService', '$state', '$stateParams', 'vnfConfig', 'homeService'];
+
+ /*
+ * recommend
+ * Using function declarations
+ * and bindable members up top.
+ */
+
+ function ServiceDetail(serviceDetailsService, $state, $stateParams, vnfConfig, homeService) {
+ var vm = this;
+ if (!$stateParams.serviceDetails) {
+ $state.go('home.marketplace');
+ return;
+ }
+
+ vm.service = $stateParams.serviceDetails;
+ vm.service.funcTestReportUrl = vnfConfig.common.baseUrl + vm.service.report;
+
+ vm.downloadService = function(csarId) {
+ homeService.downloadServiceFile(csarId);
+ }
+
+ vm.onDeleteCompletion = function() {
+ $state.go('home.marketplace', {}, {
+ reload: true
+ });
+ }
+
+ vm.serviceDelete = function(serviceDetails) {
+ homeService.openDeleteDialog(serviceDetails, vm.onDeleteCompletion);
+ };
+ }
+})(); \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/serviceDetails/serviceDetailsService.js b/vnfmarket/app/modules/home/serviceDetails/serviceDetailsService.js
new file mode 100644
index 00000000..843d3eb6
--- /dev/null
+++ b/vnfmarket/app/modules/home/serviceDetails/serviceDetailsService.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.service:homeService
+ * @description
+ * # homeService
+ * Service of the app
+ */
+
+ angular.module('vnfmarket')
+ .factory('serviceDetailsService', ServiceDetails);
+
+ ServiceDetails.$inject = ['$q', 'vnfConfig', 'httpService'];
+
+ function ServiceDetails($q, vnfConfig, httpService) {
+ return {
+ serviceDetails: serviceDetails
+ };
+
+ function serviceDetails(csarId) {
+ var url = vnfConfig.common.baseUrl + vnfConfig.api.home.serviceDetails.url,
+ method = vnfConfig.api.home.serviceDetails.method;
+
+ url = url.replace(":csarId", csarId)
+
+ var defer = $q.defer()
+ httpService.apiRequest(url, method)
+ .then(function(response) {
+ defer.resolve(response);
+ }, function(error) {
+ defer.reject(error);
+ });
+ return defer.promise;
+ }
+ }
+
+})(); \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/serviceUpload/serviceUpload.html b/vnfmarket/app/modules/home/serviceUpload/serviceUpload.html
new file mode 100644
index 00000000..c9323c82
--- /dev/null
+++ b/vnfmarket/app/modules/home/serviceUpload/serviceUpload.html
@@ -0,0 +1,97 @@
+<!--
+ Copyright 2017 Huawei Technologies Co., Ltd.
+
+ 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.
+-->
+<md-dialog aria-label="Upload Service dialog" flex="40">
+
+ <md-toolbar class="md-hue-2 dialogHeader">
+ <div class="md-toolbar-tools">
+ <h2>{{'module.marketplace.serviceUpload.title' | translate}}</h2>
+ <span flex></span>
+ <button class="btnTransparency" ng-click="vm.cancel()" ng-hide="vm.status == 'progress'">
+ <i class="fa fa-close fa-sm" aria-hidden="true"></i>
+ </button>
+ </div>
+ </md-toolbar>
+<form ng-cloak name="service">
+ <md-dialog-content ng-show="vm.status == 'Idle'">
+ <div class="md-dialog-content">
+ <div layout="column">
+ <label>{{'module.marketplace.serviceUpload.fields.fileUpload.label' | translate}}</label>
+ <input type="file" file-upload="vm.service.file" md-asterisk accept=".csar">
+ </div>
+ <div layout="column">
+ <md-input-container md-no-float class="md-block">
+ <input ng-model="vm.service.shortDesc" placeholder="{{'module.marketplace.serviceUpload.fields.shortDescription.placeholder' | translate}}">
+ </md-input-container>
+ </div>
+ <div layout="column">
+ <md-input-container md-no-float class="md-block">
+ <textarea ng-model="vm.service.details" md-maxlength="150" rows="3" md-select-on-focus placeholder="{{'module.marketplace.serviceUpload.fields.details.placeholder' | translate}}"></textarea>
+ </md-input-container>
+ </div>
+ <div layout="column">
+ <md-input-container md-no-float class="md-block">
+ <input ng-model="vm.service.remarks" placeholder="{{'module.marketplace.serviceUpload.fields.remarks.placeholder' | translate}}">
+ </md-input-container>
+ </div>
+ </div>
+ </md-dialog-content>
+
+ </form>
+
+ <md-dialog-content ng-show="(vm.status == 'progress') || (vm.status == 'success')">
+ <div class="md-dialog-content" layout="column" layout-sm="column">
+ <div flex layout="row">
+ <div flex="25" layout="column">
+ </div>
+ <div flex="50" layout="column">
+ <h4 class="text-center" ng-if="vm.status != 'success'"> {{'module.marketplace.serviceUpload.messages.onUploading' | translate}} </h4>
+ <!-- <h4 class="text-center" ng-if="vm.status == 'success'"> {{'module.marketplace.serviceUpload.messages.onSuccessful' | translate}} </h4> -->
+ <div class="fullWidth center" ng-if="vm.status == 'success'">
+ <div class="row">
+ <div class="col-xs-2 col-sm-2 col-md-1 col-lg-1 deleteIconSize glyphicon glyphicon-info-sign icon_info con_confirm"></div>
+ <div class="msg col-xs-10 col-sm-10 col-md-11 col-lg-11" style="text-align:left;vertical-align: middle;">{{'module.marketplace.serviceUpload.messages.onSuccessful' | translate}}</div>
+ </div>
+ </div>
+ <md-progress-linear md-mode="determinate" value="{{vm.apiInfo}}"></md-progress-linear>
+ <h4 class="text-center"> {{vm.apiInfo}} % </h4>
+ </div>
+ <div flex="25" layout="column">
+ </div>
+ </div>
+ <div flex layout="row" ng-if="vm.status == 'success'">
+ <h4>{{'module.marketplace.serviceUpload.fields.funcTestReport.label' | translate}} <a href="{{funcTestReportUrl}}" target="_blank">{{'common.actions.clickHere' | translate}}</a></h4>
+ </div>
+ </div>
+ </md-dialog-content>
+
+
+
+ <md-dialog-actions layout="row" ng-show="vm.status == 'Idle'">
+ <span flex></span>
+ <button ng-click="vm.cancel()" class="btn btnDefault btnSpacing">
+ {{'common.actions.close' | translate}}
+ </button>
+ <button ng-click="vm.answer('Uploaded')" class="btn btnDefault" ng-disabled="!vm.service.file || service.$invalid" ng-hide="vm.status == 'success'">
+ {{'common.actions.upload' | translate}}
+ </button>
+ </md-dialog-actions>
+ <md-dialog-actions layout="row" ng-show="vm.status == 'success'">
+ <md-button class="btn btn-primary" ng-click="vm.hide('Uploaded')">
+ {{'common.actions.ok' | translate}}
+ </md-button>
+ </md-dialog-actions>
+
+</md-dialog> \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/serviceUpload/serviceUploadCtrl.js b/vnfmarket/app/modules/home/serviceUpload/serviceUploadCtrl.js
new file mode 100644
index 00000000..50b1d845
--- /dev/null
+++ b/vnfmarket/app/modules/home/serviceUpload/serviceUploadCtrl.js
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.controller:HomeCtrl
+ * @description
+ * # HomeCtrl
+ * Controller of the app
+ */
+
+ angular
+ .module('vnfmarket')
+ .controller('serviceUploadCtrl', ServiceUpload);
+
+ ServiceUpload.$inject = ['serviceUploadService', '$scope', 'vnfConfig', '$mdDialog', '$mdToast', '$rootScope', '$interval'];
+
+ /*
+ * recommend
+ * Using function declarations
+ * and bindable members up top.
+ */
+
+ function ServiceUpload(serviceUploadService, $scope, vnfConfig, $mdDialog, $mdToast, $rootScope, $interval) {
+ var vm = this;
+ vm.apiInfo = 0;
+ vm.status = "Idle";
+ vm.promise = null;
+ vm.service = {};
+
+ vm.hide = function(answer) {
+ $mdDialog.hide(answer);
+ };
+
+ vm.cancel = function() {
+ $mdDialog.cancel();
+ };
+
+ vm.answer = function(answer) {
+ vm.status = "progress";
+ var dataObj = vm.service,
+ file = vm.service.file,
+ fd = new FormData(),
+ params = {
+ "details": vm.service.details ? vm.service.details : "",
+ "shortDesc": vm.service.shortDesc ? vm.service.shortDesc : "",
+ "remarks": vm.service.remarks ? vm.service.remarks : ""
+ };
+ fd.append("file", file);
+ fd.append("params", JSON.stringify(params));
+
+ var headers = {
+ "Content-Type": undefined
+ }
+
+ vm.promise = $interval(function() {
+ if ($rootScope.progressBar >= 80 && vm.status !== "success") {
+ vm.apiInfo = 80;
+ } else {
+ vm.apiInfo = parseInt($rootScope.progressBar, 10);
+ }
+ }, 500);
+
+ serviceUploadService.postServiceUpload(fd, headers)
+ .then(function(response) {
+ vm.status = "success";
+ vm.apiInfo = 100;
+ vm.funcTestReportUrl = vnfConfig.common.baseUrl + response.data.functestReport;
+ });
+ };
+
+ $scope.$on("$destroy", function() {
+ if (vm.promise) {
+ $interval.cancel(vm.promise);
+ }
+ })
+ }
+})(); \ No newline at end of file
diff --git a/vnfmarket/app/modules/home/serviceUpload/serviceUploadService.js b/vnfmarket/app/modules/home/serviceUpload/serviceUploadService.js
new file mode 100644
index 00000000..2606143a
--- /dev/null
+++ b/vnfmarket/app/modules/home/serviceUpload/serviceUploadService.js
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.service:homeService
+ * @description
+ * # homeService
+ * Service of the app
+ */
+
+ angular.module('vnfmarket')
+ .factory('serviceUploadService', serviceUpload);
+
+ serviceUpload.$inject = ['$q', 'vnfConfig', 'httpService'];
+
+ function serviceUpload($q, vnfConfig, httpService) {
+ return {
+ postServiceUpload: postServiceUpload
+ };
+
+ function postServiceUpload(data, headers) {
+ var url = vnfConfig.common.baseUrl + vnfConfig.api.home.postServiceUpload.url,
+ method = vnfConfig.api.home.postServiceUpload.method,
+ apiData = data;
+
+ var defer = $q.defer()
+ httpService.apiRequestWithProgress(url, method, apiData, headers)
+ .then(function(response) {
+ defer.resolve(response);
+ }, function(error) {
+ defer.reject(error);
+ });
+ return defer.promise;
+ }
+ }
+
+})(); \ No newline at end of file
diff --git a/vnfmarket/app/modules/layouts/main-page/main-page.html b/vnfmarket/app/modules/layouts/main-page/main-page.html
new file mode 100644
index 00000000..57920a10
--- /dev/null
+++ b/vnfmarket/app/modules/layouts/main-page/main-page.html
@@ -0,0 +1,76 @@
+<!--
+ Copyright 2017 Huawei Technologies Co., Ltd.
+
+ 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.
+-->
+ <md-toolbar ng-show="!showSearch">
+ <div class="md-toolbar-tools">
+ <md-button ng-click="layout.toggleSidenav('left')" hide-gt-md aria-label="Menu">
+ <ng-md-icon icon="menu"></ng-md-icon>
+ </md-button>
+ <h3>
+ <a href="/">vnfmarket</a>
+ </h3>
+ <span flex></span>
+ <md-button aria-label="Search" ng-click="showSearch = !showSearch">
+ <ng-md-icon icon="search"></ng-md-icon>
+ </md-button>
+ <md-menu>
+ <md-button aria-label="Open Settings" ng-click="layout.openMenu($mdOpenMenu, $event)">
+ <md-icon> more_vert </md-icon>
+ </md-button>
+ <md-menu-content width="4">
+ <md-menu-item>
+ <md-button ng-click="layout.changeProfile($event)">
+ <md-icon>face</md-icon>
+ Profile
+ </md-button>
+ </md-menu-item>
+ <md-menu-item>
+ <md-button ng-click="layout.changePassword()">
+ <md-icon>lock</md-icon>
+ Password
+ </md-button>
+ </md-menu-item>
+ <md-menu-divider></md-menu-divider>
+ <md-menu-item>
+ <md-button ng-click="layout.logOut()">
+ <md-icon>power_settings_new</md-icon>
+ Logout
+ </md-button>
+ </md-menu-item>
+ </md-menu-content>
+ </md-menu>
+ </div>
+ </md-toolbar>
+ <md-toolbar class="md-hue-1" ng-show="showSearch">
+ <div class="md-toolbar-tools">
+ <md-button ng-click="showSearch = !showSearch" aria-label="Back">
+ <ng-md-icon icon="arrow_back"></ng-md-icon>
+ </md-button>
+ <h3 flex="10">
+ Back
+ </h3>
+ <md-input-container md-theme="input" flex>
+ <label>&nbsp;</label>
+ <input ng-model="search.who" placeholder="Search ...">
+ </md-input-container>
+
+ </div>
+ </md-toolbar>
+ <md-content class="md-blue-grey-theme" flex md-scroll-y>
+ <ui-view layout="column" layout-fill layout-padding>
+
+
+ </ui-view>
+ </md-content>
diff --git a/vnfmarket/app/modules/layouts/main-page/mainPageCtrl.js b/vnfmarket/app/modules/layouts/main-page/mainPageCtrl.js
new file mode 100644
index 00000000..c1430ffb
--- /dev/null
+++ b/vnfmarket/app/modules/layouts/main-page/mainPageCtrl.js
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.controller:LayoutCtrl
+ * @description
+ * # LayoutCtrl
+ * Controller of the app
+ */
+
+ angular
+ .module('vnfmarket')
+ .controller('LayoutCtrl', Layout);
+
+ Layout.$inject = ['$mdSidenav', '$cookies', '$state', '$mdToast', '$mdDialog'];
+
+ /*
+ * recommend
+ * Using function declarations
+ * and bindable members up top.
+ */
+
+ function Layout($mdSidenav, $cookies, $state, $mdToast, $mdDialog ) {
+ /*jshint validthis: true */
+ var vm = this;
+
+ vm.toggleSidenav = function (menuId) {
+ $mdSidenav(menuId).toggle();
+ };
+
+ // vm.changePassword = function () {
+ // $mdToast.show(
+ // $mdToast.simple()
+ // .content('Password clicked!')
+ // .position('top right')
+ // .hideDelay(2000)
+ // );
+ // };
+
+ // vm.changeProfile = function (ev) {
+ // $mdDialog.show({
+ // controller: DialogController,
+ // templateUrl: 'tabDialog.tmpl.html',
+ // parent: angular.element(document.body),
+ // targetEvent: ev,
+ // clickOutsideToClose:true
+ // })
+ // .then(function(answer) {
+ // $mdToast.show(
+ // $mdToast.simple()
+ // .content('You said the information was "' + answer + '".')
+ // .position('top right')
+ // .hideDelay(2000)
+ // );
+
+ // }, function() {
+ // $mdToast.show(
+ // $mdToast.simple()
+ // .content('You cancelled the dialog.')
+ // .position('top right')
+ // .hideDelay(2000)
+ // );
+ // });
+
+ // function DialogController($scope, $mdDialog) {
+ // $scope.hide = function() {
+ // $mdDialog.hide();
+ // };
+
+ // $scope.cancel = function() {
+ // $mdDialog.cancel();
+ // };
+
+ // $scope.answer = function(answer) {
+ // $mdDialog.hide(answer);
+ // };
+ // }
+ // };
+
+
+ // vm.logOut = function () {
+
+ // alert('Implement your Function Here');
+ // // $cookies.put('dev_appserver_login', ' ');
+ // //$state.go('out', {}, {reload: true});
+
+ // };
+
+ // var originatorEv;
+ // vm.openMenu = function ($mdOpenMenu, ev) {
+ // originatorEv = ev;
+ // $mdOpenMenu(ev);
+ // };
+
+ }
+
+})();
diff --git a/vnfmarket/app/modules/layouts/side-nav/sidenav.html b/vnfmarket/app/modules/layouts/side-nav/sidenav.html
new file mode 100644
index 00000000..36aebb6e
--- /dev/null
+++ b/vnfmarket/app/modules/layouts/side-nav/sidenav.html
@@ -0,0 +1,46 @@
+<!--
+ Copyright 2017 Huawei Technologies Co., Ltd.
+
+ 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.
+-->
+ <md-toolbar class="md-tall md-hue-2">
+ <div layout="column" class="md-toolbar-tools-bottom inset">
+ <div layout="row">
+ <div flex="20">
+ <img style="width: 36px; height: 36px; border-radius: 50%"
+ actual-src="data:image/jpeg;base64,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"
+ showloader="" loader-class="preload" loader-src="app/assets/images/loader.gif"
+ src="data:image/jpeg;base64,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">
+ </div>
+ <div flex="80" style="margin-top: 10px;font-size: 1em;">
+ <div></div>
+ </div>
+ </div>
+ </div>
+ </md-toolbar>
+ <md-list>
+ <md-list-item ng-repeat="item in vm.menu" ng-click="vm.navigateTo(item.link)" >
+ <div class="inset" ng-show="item.icon">
+ <ng-md-icon icon="{{item.icon}}"></ng-md-icon>
+ </div>
+ <p> {{ item.name }}</p>
+ </md-list-item>
+ <md-divider></md-divider>
+ <md-subheader></md-subheader>
+ <md-list-item ng-repeat="item in vm.admin" ng-click="vm.showSettingsBottom($event)" >
+ <div class="inset">
+ <ng-md-icon icon="{{item.icon}}"></ng-md-icon>
+ </div>
+ <p> {{ item.title }}</p>
+ </md-list-item>
+ </md-list>
diff --git a/vnfmarket/app/modules/layouts/side-nav/sidenavCtrl.js b/vnfmarket/app/modules/layouts/side-nav/sidenavCtrl.js
new file mode 100644
index 00000000..59bd9fae
--- /dev/null
+++ b/vnfmarket/app/modules/layouts/side-nav/sidenavCtrl.js
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *
+ * 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';
+
+ /**
+ * @ngdoc function
+ * @name app.controller:SidenavCtrl
+ * @description
+ * # SidenavCtrl
+ * Controller of the app
+ */
+ angular
+ .module('vnfmarket')
+ .controller('SidenavCtrl', SidenavCtrl)
+ // .controller('SettingsCtrl', SettingsCtrl);
+
+ // Injecting Denpendencies
+
+ SidenavCtrl.$inject = ['$mdSidenav', '$state', '$mdBottomSheet', '$mdToast', '$scope'];
+ // SettingsCtrl.$inject = ['$mdBottomSheet'];
+
+ /*
+ * recommend
+ * Using function declarations
+ * and bindable members up top.
+ */
+
+ function SidenavCtrl($mdSidenav, $state, $mdBottomSheet, $mdToast, $scope) {
+ /*jshint validthis: true */
+ var vm = this;
+
+ vm.toggleSidenav = function (menuId) {
+ $mdSidenav(menuId).toggle();
+ };
+
+ vm.closeSidenav = function() {
+ $mdSidenav('left').close();
+ };
+
+ // Close menu on small screen after click on menu item.
+ // Only use $scope in controllerAs when necessary; for example, publishing and subscribing events using $emit, $broadcast, $on or $watch.
+ $scope.$on('$stateChangeSuccess', vm.closeSidenav);
+
+ vm.navigateTo = function (target) {
+
+ var page = target;
+
+ $state.go(page);
+
+ };
+
+ }
+
+})();