diff --git a/controllers/ng/accountsetting.go b/controllers/ng/accountsetting.go index f98ff56c9..5bb240d9c 100644 --- a/controllers/ng/accountsetting.go +++ b/controllers/ng/accountsetting.go @@ -1,9 +1,11 @@ package ng +// AccountSettingController handles request to /ng/account_setting type AccountSettingController struct { BaseController } +// Get renders the account settings page func (asc *AccountSettingController) Get() { asc.Forward("Account Settings", "account-settings.htm") } diff --git a/controllers/ng/adminoption.go b/controllers/ng/adminoption.go index c0a56bb2d..1fc366296 100644 --- a/controllers/ng/adminoption.go +++ b/controllers/ng/adminoption.go @@ -1,9 +1,11 @@ package ng +// AdminOptionController handles requests to /ng/admin_option type AdminOptionController struct { BaseController } +// Get renders the admin options page func (aoc *AdminOptionController) Get() { aoc.Forward("Admin Options", "admin-options.htm") } diff --git a/controllers/ng/base.go b/controllers/ng/base.go index 3b0b94fc6..4171894e1 100644 --- a/controllers/ng/base.go +++ b/controllers/ng/base.go @@ -11,6 +11,7 @@ import ( "github.com/vmware/harbor/utils/log" ) +// BaseController wraps common methods such as i18n support, forward, which can be leveraged by other UI render controllers. type BaseController struct { beego.Controller i18n.Locale @@ -84,32 +85,37 @@ func (b *BaseController) Prepare() { } -func (bc *BaseController) Forward(title, templateName string) { - bc.Layout = filepath.Join(prefixNg, "layout.htm") - bc.TplName = filepath.Join(prefixNg, templateName) - bc.Data["Title"] = title - bc.LayoutSections = make(map[string]string) - bc.LayoutSections["HeaderInclude"] = filepath.Join(prefixNg, viewPath, "header-include.htm") - bc.LayoutSections["FooterInclude"] = filepath.Join(prefixNg, viewPath, "footer-include.htm") - bc.LayoutSections["HeaderContent"] = filepath.Join(prefixNg, viewPath, "header-content.htm") - bc.LayoutSections["FooterContent"] = filepath.Join(prefixNg, viewPath, "footer-content.htm") +// Forward to setup layout and template for content for a page. +func (b *BaseController) Forward(title, templateName string) { + b.Layout = filepath.Join(prefixNg, "layout.htm") + b.TplName = filepath.Join(prefixNg, templateName) + b.Data["Title"] = title + b.LayoutSections = make(map[string]string) + b.LayoutSections["HeaderInclude"] = filepath.Join(prefixNg, viewPath, "header-include.htm") + b.LayoutSections["FooterInclude"] = filepath.Join(prefixNg, viewPath, "footer-include.htm") + b.LayoutSections["HeaderContent"] = filepath.Join(prefixNg, viewPath, "header-content.htm") + b.LayoutSections["FooterContent"] = filepath.Join(prefixNg, viewPath, "footer-content.htm") } var langTypes []*langType +// CommonController handles request from UI that doesn't expect a page, such as /SwitchLanguage /logout ... type CommonController struct { BaseController } +// Render returns nil. func (cc *CommonController) Render() error { return nil } +// LogOut Habor UI func (cc *CommonController) LogOut() { cc.DestroySession() } +// SwitchLanguage User can swith to prefered language func (cc *CommonController) SwitchLanguage() { lang := cc.GetString("lang") if _, exist := supportLanguages[lang]; exist { diff --git a/controllers/ng/dashboard.go b/controllers/ng/dashboard.go index ca9ddc95c..9fa0a6448 100644 --- a/controllers/ng/dashboard.go +++ b/controllers/ng/dashboard.go @@ -1,9 +1,11 @@ package ng +// DashboardController handles requests to /ng/dashboard type DashboardController struct { BaseController } +// Get renders the dashboard page func (dc *DashboardController) Get() { dc.Forward("Dashboard", "dashboard.htm") } diff --git a/controllers/ng/index.go b/controllers/ng/index.go index 0c34fe58b..69020cbad 100644 --- a/controllers/ng/index.go +++ b/controllers/ng/index.go @@ -1,9 +1,11 @@ package ng +// IndexController handles request to /ng type IndexController struct { BaseController } +// Get renders the index page func (ic *IndexController) Get() { ic.Forward("Index", "index.htm") } diff --git a/controllers/ng/navigationheader.go b/controllers/ng/navigationheader.go index 69276bbb9..2f88723f9 100644 --- a/controllers/ng/navigationheader.go +++ b/controllers/ng/navigationheader.go @@ -8,10 +8,12 @@ import ( "github.com/vmware/harbor/utils/log" ) +// NavigationHeaderController handles requests to /ng/navigation_header type NavigationHeaderController struct { BaseController } +// Get renders user's navigation header func (nhc *NavigationHeaderController) Get() { sessionUserID := nhc.GetSession("userId") var hasLoggedIn bool diff --git a/controllers/ng/optionalmenu.go b/controllers/ng/optionalmenu.go index 6945681dc..7afac21e6 100644 --- a/controllers/ng/optionalmenu.go +++ b/controllers/ng/optionalmenu.go @@ -8,10 +8,12 @@ import ( "github.com/vmware/harbor/utils/log" ) +// OptionalMenuController handles request to /ng/optional_menu type OptionalMenuController struct { BaseController } +// Get renders optional menu, Admin user has "Add User" menu func (omc *OptionalMenuController) Get() { sessionUserID := omc.GetSession("userId") diff --git a/controllers/ng/password.go b/controllers/ng/password.go index f6f169c4a..4a655ff95 100644 --- a/controllers/ng/password.go +++ b/controllers/ng/password.go @@ -95,10 +95,12 @@ func (cc *CommonController) SendEmail() { } +// ForgotPasswordController handles requests to /ng/forgot_password type ForgotPasswordController struct { BaseController } +// Get renders forgot password page func (fpc *ForgotPasswordController) Get() { fpc.Forward("Forgot Password", "forgot-password.htm") } diff --git a/controllers/ng/project.go b/controllers/ng/project.go index 79a02185f..af5dcd7a9 100644 --- a/controllers/ng/project.go +++ b/controllers/ng/project.go @@ -1,9 +1,11 @@ package ng +// ProjectController handles requests to /ng/projec type ProjectController struct { BaseController } +// Get renders project page func (pc *ProjectController) Get() { pc.Forward("My Projects", "project.htm") } diff --git a/controllers/ng/repository.go b/controllers/ng/repository.go index 696def246..e9173f15e 100644 --- a/controllers/ng/repository.go +++ b/controllers/ng/repository.go @@ -2,10 +2,12 @@ package ng import "os" +// RepositoryController handles request to /ng/repository type RepositoryController struct { BaseController } +// Get renders repository page func (rc *RepositoryController) Get() { rc.Data["HarborRegUrl"] = os.Getenv("HARBOR_REG_URL") rc.Forward("Repository", "repository.htm") diff --git a/controllers/ng/search.go b/controllers/ng/search.go index 341c864a0..0d6f3321e 100644 --- a/controllers/ng/search.go +++ b/controllers/ng/search.go @@ -1,9 +1,11 @@ package ng +// SearchController handles request to ng/search type SearchController struct { BaseController } +// Get rendlers search bar func (sc *SearchController) Get() { sc.Forward("Search", "search.htm") } diff --git a/controllers/ng/signup.go b/controllers/ng/signup.go index e2883f4a9..28d77761a 100644 --- a/controllers/ng/signup.go +++ b/controllers/ng/signup.go @@ -1,9 +1,11 @@ package ng +// SignUpController handles requests to /ng/sign_up type SignUpController struct { BaseController } +// Get renders sign up page func (suc *SignUpController) Get() { suc.Forward("Sign Up", "sign-up.htm") } diff --git a/static/ng/Gruntfile.js b/static/ng/Gruntfile.js new file mode 100644 index 000000000..567dd3850 --- /dev/null +++ b/static/ng/Gruntfile.js @@ -0,0 +1,59 @@ +/*global module:false*/ +module.exports = function(grunt) { + + 'use strict'; + // Project configuration. + grunt.initConfig({ + // Task configuration. + jshint: { + options: { + browser: true, + curly: true, + freeze: true, + bitwise: true, + eqeqeq: true, + strict: true, + immed: true, + latedef: false, + newcap: false, + smarttabs: true, + noarg: true, + devel: true, + sub: true, + undef: true, + unused: false, + boss: true, + eqnull: true, + globals: { + jQuery: true, + angular: true, + $: true, + } + }, + gruntfile: { + src: 'Gruntfile.js' + }, + scripts: { + src: ['resources/**/**/*.js'] + } + }, + watch: { + gruntfile: { + files: '<%= jshint.gruntfile.src %>', + tasks: ['jshint:gruntfile'] + }, + scripts: { + files: '<%= jshint.scripts.src %>', + tasks: ['jshint:scripts'] + } + } + }); + + // These plugins provide necessary tasks. + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-watch'); + + // Default task. + grunt.registerTask('default', ['jshint']); + +}; diff --git a/static/ng/package.json b/static/ng/package.json new file mode 100644 index 000000000..763d881ec --- /dev/null +++ b/static/ng/package.json @@ -0,0 +1,10 @@ +{ + "engines": { + "node": ">= 0.10.0" + }, + "devDependencies": { + "grunt": "~0.4.5", + "grunt-contrib-jshint": "~0.10.0", + "grunt-contrib-watch": "~0.6.1" + } +} diff --git a/static/ng/resources/js/components/details/retrieve-projects.directive.js b/static/ng/resources/js/components/details/retrieve-projects.directive.js index 6d437b4a5..3f9dedf32 100644 --- a/static/ng/resources/js/components/details/retrieve-projects.directive.js +++ b/static/ng/resources/js/components/details/retrieve-projects.directive.js @@ -58,7 +58,7 @@ if($routeParams.project_id){ angular.forEach(vm.projects, function(value, index) { - if(value['ProjectId'] == $routeParams.project_id) { + if(value['ProjectId'] === $routeParams.project_id) { vm.selectedProject = value; } }); @@ -117,7 +117,7 @@ controller: RetrieveProjectsController, bindToController: true, controllerAs: 'vm' - } + }; return directive; diff --git a/static/ng/resources/js/components/details/switch-pane-projects.directive.js b/static/ng/resources/js/components/details/switch-pane-projects.directive.js index 1a10dd70e..7c1ba33f6 100644 --- a/static/ng/resources/js/components/details/switch-pane-projects.directive.js +++ b/static/ng/resources/js/components/details/switch-pane-projects.directive.js @@ -42,7 +42,7 @@ controller: SwitchPaneProjectsController, controllerAs: 'vm', bindToController: true - } + }; return directive; diff --git a/static/ng/resources/js/components/log/advanced-search.directive.js b/static/ng/resources/js/components/log/advanced-search.directive.js index a8d4dc0d5..facb0649b 100644 --- a/static/ng/resources/js/components/log/advanced-search.directive.js +++ b/static/ng/resources/js/components/log/advanced-search.directive.js @@ -24,7 +24,7 @@ vm.op = []; vm.op.push('all'); function checkOperation(e) { - if(e.checked == 'all') { + if(e.checked === 'all') { vm.opCreate = vm.opAll; vm.opPull = vm.opAll; vm.opPush = vm.opAll; @@ -48,7 +48,7 @@ if(vm.opDelete) { vm.op.push('delete'); } - if(vm.opOthers && vm.others != "") { + if(vm.opOthers && vm.others !== "") { vm.op.push(vm.others); } } diff --git a/static/ng/resources/js/components/log/list-log.directive.js b/static/ng/resources/js/components/log/list-log.directive.js index c92ddc11c..ad7f4e323 100644 --- a/static/ng/resources/js/components/log/list-log.directive.js +++ b/static/ng/resources/js/components/log/list-log.directive.js @@ -33,7 +33,7 @@ retrieve(vm.queryParams); function search(e) { - if(e.op[0] == 'all') { + if(e.op[0] === 'all') { vm.queryParams.keywords = ''; }else { vm.queryParams.keywords = e.op.join('/') ; @@ -68,7 +68,7 @@ } function toUTCSeconds(date, hour, min, sec) { - if(date == "") { + if(date === "") { return 0; } @@ -96,7 +96,7 @@ controller: ListLogController, controllerAs: 'vm', bindToController: true - } + }; return directive; } diff --git a/static/ng/resources/js/components/project-member/add-project-member.directive.js b/static/ng/resources/js/components/project-member/add-project-member.directive.js index 6aeaa9f13..9e4446110 100644 --- a/static/ng/resources/js/components/project-member/add-project-member.directive.js +++ b/static/ng/resources/js/components/project-member/add-project-member.directive.js @@ -55,7 +55,7 @@ vm.hasError = true; vm.errorMessage = 'username_already_exist'; } - if(status == 404) { + if(status === 404) { vm.hasError = true; vm.errorMessage = 'username_does_not_exist'; } @@ -76,7 +76,8 @@ 'controller': AddProjectMemberController, 'controllerAs': 'vm', 'bindToController': true - } + }; + return directive; } diff --git a/static/ng/resources/js/components/project-member/list-project-member.directive.js b/static/ng/resources/js/components/project-member/list-project-member.directive.js index c07c666c1..1e16d5ba0 100644 --- a/static/ng/resources/js/components/project-member/list-project-member.directive.js +++ b/static/ng/resources/js/components/project-member/list-project-member.directive.js @@ -60,7 +60,8 @@ controller: ListProjectMemberController, controllerAs: 'vm', bindToController: true - } + }; + return directive; } diff --git a/static/ng/resources/js/components/project-member/project-member.config.js b/static/ng/resources/js/components/project-member/project-member.config.js index f9d705be1..937dbccb7 100644 --- a/static/ng/resources/js/components/project-member/project-member.config.js +++ b/static/ng/resources/js/components/project-member/project-member.config.js @@ -24,8 +24,8 @@ for(var i = 0; i < r.length; i++) { var role = r[i]; - if(query.key == 'roleName' && role.roleName == query.value - || query.key == 'roleId' && role.id == query.value) { + if(query.key === 'roleName' && role.roleName === query.value + || query.key === 'roleId' && role.id === query.value) { return role; } } diff --git a/static/ng/resources/js/components/project/add-project.directive.js b/static/ng/resources/js/components/project/add-project.directive.js index bbc2bab1e..eb51e0730 100644 --- a/static/ng/resources/js/components/project/add-project.directive.js +++ b/static/ng/resources/js/components/project/add-project.directive.js @@ -44,7 +44,7 @@ vm.hasError = true; vm.errorMessage = 'project_already_exist'; } - if(status == 500) { + if(status === 500) { vm.hasError = true; vm.errorMessage = 'project_name_is_invalid'; } diff --git a/static/ng/resources/js/components/project/publicity-button.directive.js b/static/ng/resources/js/components/project/publicity-button.directive.js index 31132ceeb..dfd94c034 100644 --- a/static/ng/resources/js/components/project/publicity-button.directive.js +++ b/static/ng/resources/js/components/project/publicity-button.directive.js @@ -12,7 +12,7 @@ var vm = this; vm.toggle = toggle; - if(vm.isPublic == 1) { + if(vm.isPublic === 1) { vm.isPublic = true; }else{ vm.isPublic = false; diff --git a/static/ng/resources/js/components/repository/list-repository.directive.js b/static/ng/resources/js/components/repository/list-repository.directive.js index e3362117c..a8416c57f 100644 --- a/static/ng/resources/js/components/repository/list-repository.directive.js +++ b/static/ng/resources/js/components/repository/list-repository.directive.js @@ -98,7 +98,7 @@ controller: ListRepositoryController, controllerAs: 'vm', bindToController: true - } + }; return directive; diff --git a/static/ng/resources/js/components/repository/list-tag.directive.js b/static/ng/resources/js/components/repository/list-tag.directive.js index 63f9b759d..b683364a5 100644 --- a/static/ng/resources/js/components/repository/list-tag.directive.js +++ b/static/ng/resources/js/components/repository/list-tag.directive.js @@ -40,7 +40,7 @@ $scope.$emit('modalTitle', $filter('tr')('alert_delete_tag_title', [e.tag])); var message; - if(vm.tags.length == 1) { + if(vm.tags.length === 1) { message = $filter('tr')('alert_delete_last_tag', [e.tag]); }else { message = $filter('tr')('alert_delete_tag', [e.tag]); diff --git a/static/ng/resources/js/components/repository/popup-details.directive.js b/static/ng/resources/js/components/repository/popup-details.directive.js index 6878b9338..56804f8ed 100644 --- a/static/ng/resources/js/components/repository/popup-details.directive.js +++ b/static/ng/resources/js/components/repository/popup-details.directive.js @@ -81,15 +81,15 @@ '
' + ctrl.manifest['Created'] + '
' + (ctrl.manifest['Duration Days'] == '' ? 'N/A' : ctrl.manifest['Duration Days']) + ' days
' + (ctrl.manifest['Duration Days'] === '' ? 'N/A' : ctrl.manifest['Duration Days']) + ' days
' + (ctrl.manifest['Author'] == '' ? 'N/A' : ctrl.manifest['Author']) + '
' + (ctrl.manifest['Author'] === '' ? 'N/A' : ctrl.manifest['Author']) + '
' + (ctrl.manifest['Architecture'] == '' ? 'N/A' : ctrl.manifest['Architecture']) + '
' + (ctrl.manifest['Architecture'] === '' ? 'N/A' : ctrl.manifest['Architecture']) + '
' + (ctrl.manifest['Docker Version'] == '' ? 'N/A' : ctrl.manifest['Docker Version']) + '
' + (ctrl.manifest['Docker Version'] === '' ? 'N/A' : ctrl.manifest['Docker Version']) + '
' + (ctrl.manifest['OS'] == '' ? 'N/A' : ctrl.manifest['OS']) + '
' + (ctrl.manifest['OS'] === '' ? 'N/A' : ctrl.manifest['OS']) + '