From 2911f09b349d47f2cad26395cc0c9d7d85e71521 Mon Sep 17 00:00:00 2001 From: kunw Date: Sat, 25 Jun 2016 16:15:50 +0800 Subject: [PATCH] update for validation on project and member. --- .../add-project-member.directive.html | 20 ++++----- .../add-project-member.directive.js | 43 +++++++++++++------ .../edit-project-member.directive.html | 2 +- .../edit-project-member.directive.js | 5 ++- .../list-project-member.directive.html | 4 +- .../list-project-member.directive.js | 23 ++++------ .../project/add-project.directive.html | 25 ++++++----- .../project/add-project.directive.js | 42 +++++++++++------- .../validator/project-name.validator.js | 27 ++++++++++++ .../components/validator/validator.config.js | 4 +- .../js/services/i18n/locale_messages_en-US.js | 10 +++-- .../js/services/i18n/locale_messages_zh-CN.js | 8 +++- views/sections/header-include.htm | 1 + 13 files changed, 133 insertions(+), 81 deletions(-) create mode 100644 static/resources/js/components/validator/project-name.validator.js diff --git a/static/resources/js/components/project-member/add-project-member.directive.html b/static/resources/js/components/project-member/add-project-member.directive.html index 55a226a17..7be8b7d0f 100644 --- a/static/resources/js/components/project-member/add-project-member.directive.html +++ b/static/resources/js/components/project-member/add-project-member.directive.html @@ -1,33 +1,29 @@
-
-
+ +
-
+
// 'username_is_required' | tr //
// vm.errorMessage | tr //
- -
    //role.name//  
-
-
-
-
+
+
- +
- +
-
+
\ No newline at end of file diff --git a/static/resources/js/components/project-member/add-project-member.directive.js b/static/resources/js/components/project-member/add-project-member.directive.js index 3c1343c3b..0936b6a76 100644 --- a/static/resources/js/components/project-member/add-project-member.directive.js +++ b/static/resources/js/components/project-member/add-project-member.directive.js @@ -10,37 +10,41 @@ function AddProjectMemberController($scope, roles, AddProjectMemberService) { var vm = this; - vm.username = ''; + + $scope.pm = {}; + + var pm = $scope.pm; + vm.roles = roles(); vm.optRole = 1; - - vm.reset = reset; + vm.save = save; vm.cancel = cancel; + vm.reset = reset; + vm.hasError = false; vm.errorMessage = ''; - function reset() { - vm.hasError = false; - vm.errorMessage = ''; - } - function save(pm) { if(pm && angular.isDefined(pm.username)) { AddProjectMemberService(vm.projectId, vm.optRole, pm.username) .success(addProjectMemberComplete) - .error(addProjectMemberFailed); + .error(addProjectMemberFailed); } } function cancel(form) { - if(form) { - form.$setPristine(); - } + + form.$setPristine(); + form.$setUntouched(); + vm.isOpen = false; - vm.username = ''; + pm.username = ''; vm.optRole = 1; + + vm.hasError = false; + vm.errorMessage = ''; } function addProjectMemberComplete(data, status, header) { @@ -49,7 +53,7 @@ } function addProjectMemberFailed(data, status, headers) { - if(status === 409) { + if(status === 409 && pm.username != '') { vm.hasError = true; vm.errorMessage = 'username_already_exist'; } @@ -60,6 +64,11 @@ console.log('addProjectMemberFailed: status:' + status + ', data:' + data); } + function reset() { + vm.hasError = false; + vm.errorMessage = ''; + } + } function addProjectMember() { @@ -71,12 +80,18 @@ 'isOpen': '=', 'reload': '&' }, + 'link': link, 'controller': AddProjectMemberController, 'controllerAs': 'vm', 'bindToController': true }; return directive; + + function link(scope, element, attrs, ctrl) { + scope.form.$setPristine(); + scope.form.$setUntouched(); + } } })(); \ No newline at end of file diff --git a/static/resources/js/components/project-member/edit-project-member.directive.html b/static/resources/js/components/project-member/edit-project-member.directive.html index 867c90b84..830278346 100644 --- a/static/resources/js/components/project-member/edit-project-member.directive.html +++ b/static/resources/js/components/project-member/edit-project-member.directive.html @@ -7,5 +7,5 @@ - + \ No newline at end of file diff --git a/static/resources/js/components/project-member/edit-project-member.directive.js b/static/resources/js/components/project-member/edit-project-member.directive.js index 6e15afb47..3d69e42ad 100644 --- a/static/resources/js/components/project-member/edit-project-member.directive.js +++ b/static/resources/js/components/project-member/edit-project-member.directive.js @@ -6,9 +6,9 @@ .module('harbor.project.member') .directive('editProjectMember', editProjectMember); - EditProjectMemberController.$inject = ['$scope', 'roles', 'getRole','EditProjectMemberService']; + EditProjectMemberController.$inject = ['$scope', 'roles', 'getRole','EditProjectMemberService', '$filter', 'trFilter']; - function EditProjectMemberController($scope, roles, getRole, EditProjectMemberService) { + function EditProjectMemberController($scope, roles, getRole, EditProjectMemberService, $filter, trFilter) { var vm = this; vm.roles = roles(); @@ -49,6 +49,7 @@ } function editProjectMemberFailed(e) { + alert($filter('tr')('failed_to_change_member')); console.log('Failed to edit project member:' + e); } diff --git a/static/resources/js/components/project-member/list-project-member.directive.html b/static/resources/js/components/project-member/list-project-member.directive.html index e55530df3..3f917f3ef 100644 --- a/static/resources/js/components/project-member/list-project-member.directive.html +++ b/static/resources/js/components/project-member/list-project-member.directive.html @@ -12,14 +12,14 @@
- +
- +
// 'username' | tr //// 'role' | tr //// 'operation' | tr //
diff --git a/static/resources/js/components/project-member/list-project-member.directive.js b/static/resources/js/components/project-member/list-project-member.directive.js index caa47a36d..73d523c87 100644 --- a/static/resources/js/components/project-member/list-project-member.directive.js +++ b/static/resources/js/components/project-member/list-project-member.directive.js @@ -6,16 +6,15 @@ .module('harbor.project.member') .directive('listProjectMember', listProjectMember); - ListProjectMemberController.$inject = ['$scope', 'ListProjectMemberService', 'DeleteProjectMemberService', 'getParameterByName', '$location', 'currentUser']; + ListProjectMemberController.$inject = ['$scope', 'ListProjectMemberService', 'DeleteProjectMemberService', 'getParameterByName', '$location', 'currentUser', '$filter', 'trFilter']; - function ListProjectMemberController($scope, ListProjectMemberService, DeleteProjectMemberService, getParameterByName, $location, currentUser) { + function ListProjectMemberController($scope, ListProjectMemberService, DeleteProjectMemberService, getParameterByName, $location, currentUser, $filter, trFilter) { var vm = this; vm.isOpen = false; vm.search = search; vm.addProjectMember = addProjectMember; vm.deleteProjectMember = deleteProjectMember; - vm.deleteMember = deleteMember vm.retrieve = retrieve; vm.username = ''; @@ -41,27 +40,21 @@ } } - function deleteProjectMember() { - DeleteProjectMemberService(vm.selectedProjectId, vm.selectedUserId) + function deleteProjectMember(e) { + DeleteProjectMemberService(e.projectId, e.userId) .success(deleteProjectMemberSuccess) .error(deleteProjectMemberFailed); } - - function deleteMember(e) { - vm.selectedProjectId = e.projectId; - vm.selectedUserId = e.userId; - - vm.modalTitle = 'Delete project member'; - vm.modalMessage = 'Are you sure to delete the current member?'; - - } - + function deleteProjectMemberSuccess(data, status) { console.log('Successful delete project member complete.'); vm.retrieve(); } function deleteProjectMemberFailed(e) { + vm.modalTitle = $filter('tr')('confirm_to_delete_member_title'); + vm.modalMessage = $filter('tr')('failed_to_delete_member'); + $scope.$broadcast('showDialog', true); console.log('Failed to edit project member:' + e); } diff --git a/static/resources/js/components/project/add-project.directive.html b/static/resources/js/components/project/add-project.directive.html index 7202199f4..d3c279354 100644 --- a/static/resources/js/components/project/add-project.directive.html +++ b/static/resources/js/components/project/add-project.directive.html @@ -1,12 +1,13 @@
-
-
-
-
- + +
+
+
+
-
+
// 'project_name_is_required' | tr // + // 'project_name_is_invalid' | tr //
// vm.errorMessage | tr //
@@ -14,15 +15,13 @@
 // 'public' | tr //
- -
-
-
+
+
- +
- +
-
+
\ No newline at end of file diff --git a/static/resources/js/components/project/add-project.directive.js b/static/resources/js/components/project/add-project.directive.js index 5aca66cca..c242dfb01 100644 --- a/static/resources/js/components/project/add-project.directive.js +++ b/static/resources/js/components/project/add-project.directive.js @@ -10,21 +10,20 @@ function AddProjectController(AddProjectService, $scope) { var vm = this; - vm.projectName = ""; + + $scope.p = {}; + var vm0 = $scope.p; + vm0.projectName = ''; vm.isPublic = false; - vm.reset = reset; vm.addProject = addProject; vm.cancel = cancel; + vm.reset = reset; + vm.hasError = false; vm.errorMessage = ''; - - function reset() { - vm.hasError = false; - vm.errorMessage = ''; - } - + function addProject(p) { if(p && angular.isDefined(p.projectName)) { AddProjectService(p.projectName, vm.isPublic) @@ -34,17 +33,20 @@ } function addProjectSuccess(data, status) { - vm.projectName = ""; - vm.isPublic = false; $scope.$emit('addedSuccess', true); + vm.hasError = false; + vm.errorMessage = ''; } function addProjectFailed(data, status) { vm.hasError = true; - if(status == 400) { - vm.errorMessage = 'project_name_is_invalid'; + if(status === 400 && vm0.projectName!= '' && vm0.projectName.length < 4) { + vm.errorMessage = 'project_name_is_too_short'; } - if(status === 409) { + if(status === 400 && vm0.projectName.length > 30) { + vm.errorMessage = 'project_name_is_too_long'; + } + if(status === 409 && vm0.projectName != '') { vm.errorMessage = 'project_already_exist'; } console.log('Failed to add project:' + status); @@ -53,10 +55,19 @@ function cancel(form){ if(form) { form.$setPristine(); + form.$setUntouched(); } vm.isOpen = false; - vm.projectName = ''; + vm0.projectName = ''; vm.isPublic = false; + + vm.hasError = false; + vm.errorMessage = ''; + } + + function reset() { + vm.hasError = false; + vm.errorMessage = ''; } } @@ -75,7 +86,8 @@ return directive; function link(scope, element, attrs, ctrl) { - + scope.form.$setPristine(); + scope.form.$setUntouched(); } } diff --git a/static/resources/js/components/validator/project-name.validator.js b/static/resources/js/components/validator/project-name.validator.js new file mode 100644 index 000000000..b3e9e6abd --- /dev/null +++ b/static/resources/js/components/validator/project-name.validator.js @@ -0,0 +1,27 @@ +(function() { + + 'use strict'; + + angular + .module('harbor.validator') + .directive('projectName', projectName); + + projectName.$inject = ['PROJECT_REGEXP'] + + function projectName(PROJECT_REGEXP) { + var directive = { + 'require': 'ngModel', + 'link': link + }; + return directive; + + function link(scope, element, attrs, ctrl) { + ctrl.$validators.projectName = validator; + + function validator(modelValue, viewValue) { + return PROJECT_REGEXP.test(modelValue); + } + } + } + +})(); \ No newline at end of file diff --git a/static/resources/js/components/validator/validator.config.js b/static/resources/js/components/validator/validator.config.js index 6cf368cca..65dc8ac31 100644 --- a/static/resources/js/components/validator/validator.config.js +++ b/static/resources/js/components/validator/validator.config.js @@ -5,6 +5,6 @@ angular .module('harbor.validator') .constant('INVALID_CHARS', [",","~","#", "$", "%"]) - .constant('PASSWORD_REGEXP', /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{7,20}$/); - + .constant('PASSWORD_REGEXP', /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{7,20}$/) + .constant('PROJECT_REGEXP', /^[a-z0-9](?:-*[a-z0-9])*(?:[._][a-z0-9](?:-*[a-z0-9])*)*$/); })(); \ No newline at end of file diff --git a/static/resources/js/services/i18n/locale_messages_en-US.js b/static/resources/js/services/i18n/locale_messages_en-US.js index b6c6a6bb6..2ef58b354 100644 --- a/static/resources/js/services/i18n/locale_messages_en-US.js +++ b/static/resources/js/services/i18n/locale_messages_en-US.js @@ -108,7 +108,9 @@ var locale_messages = { 'username_email': 'Username/Email', 'project_name_is_required': 'Project name is required', 'project_already_exist': 'Project already exist', - 'project_name_is_invalid': 'Project name is invalid', + 'project_name_is_invalid': 'Project name is invalid, it should be all lowercase and with no space.', + 'project_name_is_too_short': 'Project name is too short, it should be greater than 4 characters.', + 'project_name_is_too_long': 'Project name is too long, it should be less than 30 characters.', 'projects_or_repositories': 'Projects or repositories', 'tag': 'Tag', 'image_details': 'Image Details', @@ -130,7 +132,9 @@ var locale_messages = { 'no_projects_add_new_project': 'No projects, add new project now.', 'no_repositories': 'No repositories found, please use "docker push" to upload images.', 'confirm_to_delete_member_title': 'Delete project member', - 'confirm_to_delete_member': 'Are you sure to delete the current project member?', + 'failed_to_change_member': 'Project member can not be changed, insuffient permissions.', + 'failed_to_delete_member': 'Project member can not be deleted, insuffient permissions.', + 'confirm_to_change_member_title': 'Change project member', 'confirm_to_delete_user_title': 'Delete user', 'confirm_to_delete_user': 'Are you sure to delete the current user?', 'confirm_to_delete_destination_title': 'Delete destination', @@ -180,7 +184,7 @@ var locale_messages = { 'copyright': 'Copyright', 'all_rights_reserved': 'All Rights Reserved.', 'successful_ping_target': 'Successful Ping target.', - 'failed_ping_target': 'Failed Ping target:', + 'failed_ping_target': 'Failed to Ping target:', 'policy_already_exists': 'Policy alreay exists.', 'failed_update_policy': 'Failed update policy:', 'destination_already_exists': 'Destination already exists.', diff --git a/static/resources/js/services/i18n/locale_messages_zh-CN.js b/static/resources/js/services/i18n/locale_messages_zh-CN.js index c2d21b813..d96c5d1bb 100644 --- a/static/resources/js/services/i18n/locale_messages_zh-CN.js +++ b/static/resources/js/services/i18n/locale_messages_zh-CN.js @@ -108,7 +108,9 @@ var locale_messages = { 'username_email': '用户名/邮箱', 'project_name_is_required': '项目名称为必填项。', 'project_already_exist': '项目已存在。', - 'project_name_is_invalid': '项目名称无效。', + 'project_name_is_invalid': '项目名称无效。全部为小写字母,且不能包含空格。', + 'project_name_is_too_short': '项目名称长度过短,至少多于4个字符。', + 'projecT_name_is_too_long': '项目名称长度超出限制,最长30个字符。', 'projects_or_repositories': '项目和镜像资源', 'tag': '标签', 'image_details': '镜像明细', @@ -128,7 +130,9 @@ var locale_messages = { 'no_projects_add_new_project': '当前没有项目,请新增项目。', 'no_repositories': '未发现镜像,请用"docker push"命令上传镜像。', 'confirm_to_delete_member_title': '删除项目成员', - 'confirm_to_delete_member': '确认删除当前项目成员吗?', + 'failed_to_change_member': '无法修改项目成员,权限不足。', + 'failed_to_delete_member': '无法删除项目成员,权限不足。', + 'confirm_to_change_member_title': '修改项目成员', 'confirm_to_delete_user_title': '删除用户', 'confirm_to_delete_user': '确认删除当前用户吗?', 'confirm_to_delete_destination_title': '删除目标', diff --git a/views/sections/header-include.htm b/views/sections/header-include.htm index e17315c32..d0230f0ff 100644 --- a/views/sections/header-include.htm +++ b/views/sections/header-include.htm @@ -175,6 +175,7 @@ +