diff options
Diffstat (limited to 'vnfmarket/app')
24 files changed, 2000 insertions, 0 deletions
diff --git a/vnfmarket/app/app.config.js b/vnfmarket/app/app.config.js new file mode 100644 index 00000000..ea8c4c5e --- /dev/null +++ b/vnfmarket/app/app.config.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 configuration file + * @name app.config:config + * @description + * # Config and run block + * Configutation of the app + */ + + + angular + .module('vnfmarket') + .config(configure) + .run(runBlock); + + configure.$inject = ['$stateProvider', '$urlRouterProvider', '$locationProvider', '$httpProvider', '$mdThemingProvider', '$translateProvider']; + //red, pink, purple, deep-purple, indigo, blue, light-blue, cyan, teal, green, light-green, lime, yellow, amber, orange, deep-orange, brown, grey, blue-grey + function configure($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider, $mdThemingProvider, $translateProvider) { + // This is required for Browser Sync to work poperly + //$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; + + // The above lines is commented for CORS + // For CORS + $httpProvider.defaults.useXDomain = true; + delete $httpProvider.defaults.headers.common['X-Requested-With']; + // END of CORS + + + // Angualr material + // $mdThemingProvider.theme('default') + // .primaryPalette('light-blue') + // .accentPalette('light-blue', { + // 'hue-1': 'A100' // use shade 200 for default, and keep all other shades the same + // }); + + $mdThemingProvider.definePalette('amazingPaletteName', { + '50': 'ff8a80', + '100': 'eaeaea', + '200': 'ef9a9a', + '300': '#37474f', + '400': '#37474f', + '500': 'f44336', + '600': 'e53935', + '700': 'd32f2f', + '800': 'c62828', + '900': 'b71c1c', + 'A100': 'ff8a80', + 'A200': '#78909c', + 'A400': '#90a4ae', + 'A700': '#428bca' + }); + + $mdThemingProvider.theme('default') + .primaryPalette('amazingPaletteName',{ + 'default' : 'A700', + 'hue-1' : "A700", + 'hue-2' : "100", + 'hue-3' : "A200" + }).accentPalette('amazingPaletteName', { + 'hue-1' : 'A400' + }) + + $locationProvider.hashPrefix('!'); + + // Default Routing + $urlRouterProvider + .otherwise('/marketplace'); + + $translateProvider.useSanitizeValueStrategy(null); + $translateProvider.useStaticFilesLoader({ + prefix: "vnfmarket/common/locale/locale-", + suffix: ".json" + }); + $translateProvider.preferredLanguage('en') + } + + runBlock.$inject = ['$rootScope']; + + function runBlock($rootScope) { + 'use strict'; + + console.log('AngularJS run() function...'); + } + + +})();
\ No newline at end of file diff --git a/vnfmarket/app/app.js b/vnfmarket/app/app.js new file mode 100644 index 00000000..b582b622 --- /dev/null +++ b/vnfmarket/app/app.js @@ -0,0 +1,42 @@ +/* + * 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 index + * @name app + * @description + * # app + * + * Main modules of the application. + */ + + angular.module('vnfmarket', [ + 'ngResource', + 'ngAria', + 'ngMaterial', + 'ngMdIcons', + 'ngCookies', + 'ngAnimate', + 'ngSanitize', + 'ui.router', + 'md.data.table', + 'home', + 'pascalprecht.translate', + ]); + +})();
\ No newline at end of file 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> </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,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAUDBAsMBgkICQcJCQgGCQcGBgYFBgcHBQkGBgUHCQcGBgcHChwXBwgaCQcHGCEMGhERHxMfBxciGCIeGBAeHxIBBQUFBwcFDAgIBxIIBQgSHhISEhISHhISEhISHh4SEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEv/AABEIAGAAYAMBIgACEQEDEQH/xAAcAAACAwEBAQEAAAAAAAAAAAAHCAMFBgQCAQD/xAA6EAABAgQDBQYFAQgDAQAAAAACAQMABBESBQYiByExMkETQlFSYWIIcXKBoSMzgpGSorLR8BQk4RX/xAAWAQEBAQAAAAAAAAAAAAAAAAAAAQL/xAAWEQEBAQAAAAAAAAAAAAAAAAAAARH/2gAMAwEAAhEDEQA/AG0WPx9I+RDOPIIqS+F0BVZyx5uUknZpw0RGBU9XTTCJbRs6zGI4icw66pNiRCwBUsFoVXSm7wpBF+JraOr75yDRr2LSkLpCVBMx7q06ekAFmbVCUV7yRETg4pP7y3B+YmfcRw7b6J3fNp7sRYPhrkxMCy2JEpeX/wAg97NdkjQEL02KHuG0D6FAAl3CnFqQtOKgr3RVRX3cIv8AD2Udl1lyAxcG20iFUG4e7SGvYy/Ltgggw2iD3bEivm8uS6uoX/GBFrdcI01faGGFJk5pyVnbhJW3GjuElGhad/VIcfYRtHHEJImjokzLgHaj5htp2iRgtoORWJlg9CA4IkQmA6rresCfY9i7mHZqbaKqC6RSrgFzEJlQa19YqnmU/GPKxzST1wpTjQf7Y6C9YCzJeMYra1mQJbCXSUqOECi343EOn7RsDPSvyhZfivxYhsADWggREIlu1ad6QC05mxHtZpwlJVUjMi+ojVbv49Ipe0W/0H+7uxYtYM8Uq5OtgJtMLa5aVXUu3dpZ4V6xYbOsrnPT7cu3dqISdMR5Wh5oygnfDlhaFMG6o8qW3W8ChjmJe2lOb3cvhGXy3l+Xw+TS3TYn6h8CX3LHO9tPkBPsldVLVISIh4xpWyqq+u/+rhHG/dduHqo/LzRVS2epAhEhnARfKW4rvWJix1shV1sk7MSAbxLStxaoD5ijaoBcV3W28Kwv+0PCSbxmUm03K66PL5rq7oOuPTwqFwEhXd4SSkYvMWFJMnJEttrU2yThdLL0ur9oA/5ecXsGitVFNpkv5mki2UvvEEkgoAiNEQUtbt5bB3D+I9ksBNiszawZr3RUrvaIwnXxD48B313uvl5tKNCX43Q1OfcQskHNNVMCBsB4qRpuhBNoc45/9F4Xq1E1HV0tKgjv9IlSrfIcyIybulVQQUCpyqJFXekEz4ZZFtDmnUFaitt3tMuVIHGxdgXH3mnBq2QFp9x7hgy7DcFclX5wTGjbpj2Hrq6xBqc/TAixruVvvCnFRgF5rxiVSYQBkyRT5SMKcxUhn5uSA+Iou7lIajGAzhk9tzWjQK4K/p6E3fKNKCOHygEe9qlpfLveEEzHHf8Aj5cuCo3qkWGXtnVrvbPnRSW+xOVfcsaTPuBg5hJs7lQQ/Tt8w8v3gFmHM0wswgBMm2hLaQ7zC2CfkybdZk0ecnEdR9wBbAh0jaSKVPWkU2GZaQXUvY1abdPH5+Mdue3OxGQZaoBOvkTg920RgybPBZhClWj43NgX8wJHSZxnsjTF2Fy5cbmw+1ookXarBoP9suYBZJv2XH7VtHm+dYS3PM528469uW8iK63vEVYZTbNid8/MNIKIjTdokZUERMKq4pQrOJLrIbkVLi1D1tKJUqyyDmY5KcR8BQ0pY60Y1EvLT1rDIbN8xI+0L279XVaPdK7lhTz3cPqgqbHMdtBWriuArvndEDRMTKrQkJNSR01HmXup1jL5exds2EqSItLSr0KPmP460AWm+gXppJev5jSu6YxVFNRbbv1W3CXDV0+0RYmikwfRaEP+pAj2g577AbZGZGpJc4Vur6fSKpdtF0kouCqviNpEnKXS6njAELD3hW8TFO0aXmLzf4gRbV8YQceYBa2sANxeBOrzfyxHge0G6a/UFRR1dX1d2MjnvEhexYzTeg2BcXtTV+YjJwdguPo9IKyW8pMrCIeoENwF86UglkaQuXwszSoUySVVugCJeJcF+0MK06hcOEVosnxOOqxihWFaM02gueojTTC9Tn7UqcCXTBo+JTGgfxFRQhPsG7bhKooRU4QF3G06kteYYlSvDqcBi0ydPk3ODQqXrq+mKevjXT4xNhy/9gfaoxEHbCMwUESQ046vWB/tEzI4/iPZNkqgCCIjdpQuscU2+4GneiElzZf4jKuvEjpFdRdRe6Au3cKdLTeirTmujyOX6ftHwH96Kg8UctQUdX/fGIXZkl5iUl90BMqiD9wlWxeaPMsqk7duVSLVd5iWORVrx/ej2waoS0410l4QDX/D480MujQigqQCJW0/aiWr8QYmpi3h4wpuw/GibnGxUuYv4kWlfxDQsPIo7+9qt8NMVSLYtMKRKJEpGXMRFUlisdqhJHTxNYgfSkBG+VY7cCbq+g9SSK5FjswmYQHQNa0FRut8sRBZl8IF2SQTAtCaTQe9GOxrKhXKo/1cywfNm5y78gBt0PSIkBeYh61SJsx4G0WgmkAi73h8oBYHsuOjxIaU/eirfbUVtXu96C/mvBVC4LPpXxGBfjrFrtsBV1j2A6V90fEj2qwF5lDGFYmAO7cC3W/T4QwmW9q0sQiJnYVBu7XoXpCwSyav93RMZrdcm5fNAf/Z"> + </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); + + }; + + } + +})(); |