mirror of
https://github.com/goharbor/harbor.git
synced 2025-02-22 14:52:17 +01:00
update for validation on project and member.
This commit is contained in:
parent
4caf2becb4
commit
2911f09b34
@ -1,33 +1,29 @@
|
||||
<div class="well panel-group">
|
||||
<div class="row">
|
||||
<div class="col-xs-10 col-md-10">
|
||||
<form name="form" novalidate ng-submit="form.$valid">
|
||||
<form name="form" class="css-form" novalidate>
|
||||
<div class="col-xs-10 col-md-10">
|
||||
<div class="form-group col-md-6">
|
||||
<input type="text" class="form-control" id="addUsername" placeholder="// 'username' | tr //" ng-model="pm.username" name="uUsername" ng-model-options="{ debounce: 250 }" ng-change="vm.reset()" required>
|
||||
<div class="error-message">
|
||||
<div ng-messages="form.$dirty && form.uUsername.$error">
|
||||
<div ng-messages="form.$submitted && form.uUsername.$error">
|
||||
<span ng-message="required">// 'username_is_required' | tr //</span>
|
||||
</div>
|
||||
<span ng-show="vm.hasError">// vm.errorMessage | tr //</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form class="form-inline clearfix">
|
||||
<div class="form-group">
|
||||
<label for="roleIdList">// 'role' | tr //:</label>
|
||||
<span ng-repeat="role in vm.roles">
|
||||
<input type="radio" name="role" ng-model="vm.optRole" value="//role.id//"> //role.name//
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-xs-2 col-md-2">
|
||||
<form>
|
||||
</div>
|
||||
<div class="col-xs-2 col-md-2">
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn btn-primary" id="btnSave" ng-disabled="form.$invalid" ng-click="vm.save(pm)">// 'save' | tr //</button>
|
||||
<button type="submit" class="btn btn-primary" id="btnSave" ng-click="vm.save(pm)">// 'save' | tr //</button>
|
||||
<button type="button" class="btn btn-default" id="btnCancel" ng-click="vm.cancel(form)">// 'cancel' | tr //</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -7,5 +7,5 @@
|
||||
<a ng-show="vm.userId != vm.currentUserId" href="javascript:void(0);" ng-click="vm.cancelUpdate()" title="Cancel">
|
||||
<span ng-if="vm.editMode" class="glyphicon glyphicon-repeat"></span>
|
||||
</a>
|
||||
<a ng-show="vm.userId != vm.currentUserId && !vm.editMode" href="javascript:void(0);" data-toggle="modal" data-target="#myModal" ng-click="vm.deleteProjectMember()" title="Delete"><span class="glyphicon glyphicon-trash"></span></a>
|
||||
<a ng-show="vm.userId != vm.currentUserId && !vm.editMode" href="javascript:void(0);" ng-click="vm.deleteProjectMember()" title="Delete"><span class="glyphicon glyphicon-trash"></span></a>
|
||||
</td>
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -12,14 +12,14 @@
|
||||
</div>
|
||||
<div class="pane">
|
||||
<add-project-member ng-show="vm.isOpen" is-open="vm.isOpen" project-id="//vm.projectId//" reload='vm.search({projectId: vm.projectId, username: vm.username})'></add-project-member>
|
||||
<modal-dialog modal-title="// 'confirm_to_delete_member_title' | tr //" modal-message="// 'confirm_to_delete_member' | tr //" action="vm.deleteProjectMember()"></modal-dialog>
|
||||
<modal-dialog modal-title="// vm.modalTitle //" modal-message="// vm.modalMessage //" confirm-only="true"></modal-dialog>
|
||||
<div class="sub-pane">
|
||||
<table class="table table-pane" >
|
||||
<thead>
|
||||
<th width="30%">// 'username' | tr //</th><th width="40%">// 'role' | tr //</th><th width="30%">// 'operation' | tr //</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="pr in vm.projectMembers" edit-project-member username="pr.username" project-id="vm.projectId" user-id="pr.user_id" delete="vm.deleteMember({projectId: vm.projectId, userId: pr.user_id})" current-user-id="vm.user.user_id" role-name="pr.role_name" reload='vm.search({projectId: vm.projectId, username: vm.username})'></tr>
|
||||
<tr ng-repeat="pr in vm.projectMembers" edit-project-member username="pr.username" project-id="vm.projectId" user-id="pr.user_id" delete="vm.deleteProjectMember({projectId: vm.projectId, userId: pr.user_id})" current-user-id="vm.user.user_id" role-name="pr.role_name" reload='vm.search({projectId: vm.projectId, username: vm.username})'></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
<div class="well panel-group">
|
||||
<div class="row">
|
||||
<div class="col-xs-10 col-md-10">
|
||||
<form name="form" ng-submit="form.$valid">
|
||||
<div class="form-group col-md-6">
|
||||
<input type="text" class="form-control" placeholder="// 'project_name' | tr //" ng-model="p.projectName" name="uProjectName" ng-model-options="{ debounce: 250 }" ng-change="vm.reset()" required>
|
||||
<form name="form" class="css-form" novalidate>
|
||||
<div class="row">
|
||||
<div class="col-xs-10 col-md-10">
|
||||
<div class="form-group col-md-7">
|
||||
<input type="text" class="form-control" placeholder="// 'project_name' | tr //" ng-model="p.projectName" name="uProjectName" ng-change="vm.reset()" ng-model-options="{ debounce: 250 }" project-name required>
|
||||
<div class="error-message">
|
||||
<div ng-messages="form.$dirty && form.uProjectName.$error" ng-if="form.uProjectName.$touched">
|
||||
<div ng-messages="form.$submitted && form.uProjectName.$error">
|
||||
<span ng-message="required">// 'project_name_is_required' | tr //</span>
|
||||
<span ng-message="projectName">// 'project_name_is_invalid' | tr //</span>
|
||||
</div>
|
||||
<span ng-show="vm.hasError">// vm.errorMessage | tr //</span>
|
||||
</div>
|
||||
@ -14,15 +15,13 @@
|
||||
<div class="form-group">
|
||||
<input type="checkbox" ng-model="vm.isPublic"> // 'public' | tr //
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-xs-2 col-md-2">
|
||||
<form>
|
||||
</div>
|
||||
<div class="col-xs-2 col-md-2">
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn btn-primary" ng-disabled="form.$invalid" ng-click="vm.addProject(p)">// 'save' | tr //</button>
|
||||
<button type="submit" class="btn btn-primary" ng-click="vm.addProject(p)">// 'save' | tr //</button>
|
||||
<button type="button" class="btn btn-default" ng-click="vm.cancel(form)">// 'cancel' | tr //</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -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])*)*$/);
|
||||
})();
|
@ -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.',
|
||||
|
@ -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': '删除目标',
|
||||
|
@ -175,6 +175,7 @@
|
||||
<script src="/static/resources/js/components/validator/confirm-password.validator.js"></script>
|
||||
<script src="/static/resources/js/components/validator/user-exist.validator.js"></script>
|
||||
<script src="/static/resources/js/components/validator/invalid-chars.validator.js"></script>
|
||||
<script src="/static/resources/js/components/validator/project-name.validator.js"></script>
|
||||
|
||||
<script src="/static/resources/js/components/search/search.module.js"></script>
|
||||
<script src="/static/resources/js/components/search/search.directive.js"></script>
|
||||
|
Loading…
Reference in New Issue
Block a user