-
+
{{'MEMBER.NEW_MEMBER' | translate }}
{{'MEMBER.DELETE' | translate}}
{{'MEMBER.PROJECT_ADMIN' | translate}}
diff --git a/src/ui_ng/src/app/project/member/member.component.ts b/src/ui_ng/src/app/project/member/member.component.ts
index 33a7539a5..cbcca9728 100644
--- a/src/ui_ng/src/app/project/member/member.component.ts
+++ b/src/ui_ng/src/app/project/member/member.component.ts
@@ -60,7 +60,10 @@ export class MemberComponent implements OnInit, OnDestroy {
hasProjectAdminRole: boolean;
searchMember: string;
- selectedRow: Member[] = [];
+ selectedRow: Member[] = []
+ roleNum: number;
+ isDelete: boolean =false;
+ isChangeRole: boolean =false;
batchDelectionInfos: BatchInfo[] = [];
constructor(
@@ -69,15 +72,20 @@ export class MemberComponent implements OnInit, OnDestroy {
private memberService: MemberService,
private translate: TranslateService,
private messageHandlerService: MessageHandlerService,
- private deletionDialogService: ConfirmationDialogService,
+ private OperateDialogService: ConfirmationDialogService,
private session: SessionService,
private ref: ChangeDetectorRef) {
- this.delSub = deletionDialogService.confirmationConfirm$.subscribe(message => {
+ this.delSub = OperateDialogService.confirmationConfirm$.subscribe(message => {
if (message &&
message.state === ConfirmationState.CONFIRMED &&
message.source === ConfirmationTargets.PROJECT_MEMBER) {
- this.deleteMem(message.data);
+ if (this.isDelete) {
+ this.deleteMem(message.data);
+ }
+ if (this.isChangeRole) {
+ this.changeOpe(message.data);
+ }
}
});
let hnd = setInterval(()=>ref.markForCheck(), 100);
@@ -127,27 +135,75 @@ export class MemberComponent implements OnInit, OnDestroy {
}
changeRole(m: Member[], roleId: number) {
- if (m) {
- let promiseList: any[] = [];
+ if (m && m.length) {
+ this.isDelete = false;
+ this.isChangeRole = true;
+ this.roleNum = roleId;
+ let nameArr: string[] = [];
+ this.batchDelectionInfos = [];
m.forEach(data => {
- if (!(data.user_id === this.currentUser.user_id || !this.hasProjectAdminRole)) {
- promiseList.push(this.memberService.changeMemberRole(this.projectId, data.user_id, roleId));
- }
- })
- Promise.all(promiseList).then(num => {
- if (num.length === promiseList.length) {
- this.messageHandlerService.showSuccess('MEMBER.SWITCHED_SUCCESS');
- this.retrieve(this.projectId, '');
- }
- },
- error => {
- this.messageHandlerService.handleError(error);
- }
+ nameArr.push(data.username);
+ let initBatchMessage = new BatchInfo();
+ initBatchMessage.name = data.username;
+ this.batchDelectionInfos.push(initBatchMessage);
+ });
+ this.OperateDialogService.addBatchInfoList(this.batchDelectionInfos);
+
+ let switchMessage = new ConfirmationMessage(
+ 'MEMBER.SWITCH_TITLE',
+ 'MEMBER.SWITCH_SUMMARY',
+ nameArr.join(','),
+ m,
+ ConfirmationTargets.PROJECT_MEMBER,
+ ConfirmationButtons.DELETE_CANCEL
);
- }
+ this.OperateDialogService.openComfirmDialog(switchMessage);
+ }
+ }
+
+ changeOpe(members: Member[]) {
+ if (members && members.length) {
+ let promiseList: any[] = [];
+ members.forEach(member => {
+ if (member.user_id === this.currentUser.user_id || member.role_id >= this.roleNum) {
+ let findedList = this.batchDelectionInfos.find(data => data.name === member.username);
+ this.translate.get('BATCH.SWITCH_FAILURE').subscribe(res => {
+ findedList = BathInfoChanges(findedList, res, false, true);
+ });
+ }else {
+ promiseList.push(this.changeOperate(this.projectId, member.user_id, this.roleNum, member.username));
+ }
+
+ });
+
+ Promise.all(promiseList).then(num => {
+ this.retrieve(this.projectId, '');
+ },
+ );
+ }
+ }
+
+ changeOperate(projectId: number, memberId: number, roleId: number, username: string) {
+ let findedList = this.batchDelectionInfos.find(data => data.name === username);
+ return this.memberService
+ .changeMemberRole(projectId, memberId, roleId)
+ .then(
+ response => {
+ this.translate.get('BATCH.SWITCH_SUCCESS').subscribe(res => {
+ findedList = BathInfoChanges(findedList, res);
+ });
+ },
+ error => {
+ this.translate.get('BATCH.SWITCH_FAILURE').subscribe(res => {
+ findedList = BathInfoChanges(findedList, res, false, true);
+ });
+ }
+ );
}
deleteMembers(m: Member[]) {
+ this.isDelete = true;
+ this.isChangeRole = false;
let nameArr: string[] = [];
this.batchDelectionInfos = [];
if (m && m.length) {
@@ -157,17 +213,17 @@ export class MemberComponent implements OnInit, OnDestroy {
initBatchMessage.name = data.username;
this.batchDelectionInfos.push(initBatchMessage);
});
- this.deletionDialogService.addBatchInfoList(this.batchDelectionInfos);
+ this.OperateDialogService.addBatchInfoList(this.batchDelectionInfos);
let deletionMessage = new ConfirmationMessage(
- 'PROJECT.DELETION_TITLE',
- 'PROJECT.DELETION_SUMMARY',
+ 'MEMBER.DELETION_TITLE',
+ 'MEMBER.DELETION_SUMMARY',
nameArr.join(','),
m,
ConfirmationTargets.PROJECT_MEMBER,
ConfirmationButtons.DELETE_CANCEL
);
- this.deletionDialogService.openComfirmDialog(deletionMessage);
+ this.OperateDialogService.openComfirmDialog(deletionMessage);
}
}
diff --git a/src/ui_ng/src/app/project/project.component.css b/src/ui_ng/src/app/project/project.component.css
index 98973f4d1..e83772ed7 100644
--- a/src/ui_ng/src/app/project/project.component.css
+++ b/src/ui_ng/src/app/project/project.component.css
@@ -18,5 +18,5 @@
color: #007CBB;
}
.rightPos {
- position: absolute; right: 20px; margin-top: 16px; height:32px;
+ position: absolute; right: 20px; margin-top: 5px; height:32px; z-index: 100;
}
\ No newline at end of file
diff --git a/src/ui_ng/src/app/shared/confirmation-dialog/confirmation-dialog.component.css b/src/ui_ng/src/app/shared/confirmation-dialog/confirmation-dialog.component.css
index 73e3372f9..349f53e74 100644
--- a/src/ui_ng/src/app/shared/confirmation-dialog/confirmation-dialog.component.css
+++ b/src/ui_ng/src/app/shared/confirmation-dialog/confirmation-dialog.component.css
@@ -21,7 +21,8 @@
padding: 20px; list-style-type: none;
}
.batchInfoUl li {line-height: 24px;border-bottom: 1px solid #e8e8e8;}
-.batchInfoUl li span:first-child {padding-right: 20px; width: 210px; display: inline-block; color:#666;}
-.batchInfoUl li span:last-child {width: 260px; display: inline-block; color:#666;}
+.batchInfoUl li span:first-child {padding-right: 20px; width: 240px; display: inline-block; color:#666;
+ text-overflow: ellipsis; overflow: hidden; vertical-align: middle;}
+.batchInfoUl li span:last-child {width: 230px; display: inline-block; color:#666;}
.batchInfoUl li span i {display: inline-block; line-height: 1.2em; font-size: 0.8em; color: #999;}
.batchInfoUl li span a{cursor: pointer; text-decoration: underline;}
diff --git a/src/ui_ng/src/i18n/lang/en-us-lang.json b/src/ui_ng/src/i18n/lang/en-us-lang.json
index a3a4de2b4..ff23d35a0 100644
--- a/src/ui_ng/src/i18n/lang/en-us-lang.json
+++ b/src/ui_ng/src/i18n/lang/en-us-lang.json
@@ -37,7 +37,9 @@
},
"BATCH": {
"DELETED_SUCCESS": "Deleted successfully",
- "DELETED_FAILURE": "Deleted failed"
+ "DELETED_FAILURE": "Deleted failed",
+ "SWITCH_SUCCESS": "Switch successfully",
+ "SWITCH_FAILURE": "Switch failed"
},
"TOOLTIP": {
"EMAIL": "Email should be a valid email address like name@example.com.",
@@ -201,12 +203,15 @@
"USERNAME_ALREADY_EXISTS": "Username already exists.",
"UNKNOWN_ERROR": "Unknown error occurred while adding member.",
"FILTER_PLACEHOLDER": "Filter Members",
- "DELETION_TITLE": "Confirm project member deletion",
- "DELETION_SUMMARY": "Do you want to delete project member {{param}}?",
+ "DELETION_TITLE": "Confirm project members deletion",
+ "DELETION_SUMMARY": "Do you want to delete project members {{param}}?",
"ADDED_SUCCESS": "Added member successfully.",
- "DELETED_SUCCESS": "Deleted members successfully.",
- "SWITCHED_SUCCESS": "Switched members role successfully.",
- "OF": "of"
+ "DELETED_SUCCESS": "Deleted member successfully.",
+ "SWITCHED_SUCCESS": "Switched member role successfully.",
+ "OF": "of",
+ "SWITCH_TITLE": "Confirm project members switch",
+ "SWITCH_SUMMARY": "Do you want to switch project members {{param}}?"
+
},
"AUDIT_LOG": {
"USERNAME": "Username",
diff --git a/src/ui_ng/src/i18n/lang/es-es-lang.json b/src/ui_ng/src/i18n/lang/es-es-lang.json
index d74968509..74de7209a 100644
--- a/src/ui_ng/src/i18n/lang/es-es-lang.json
+++ b/src/ui_ng/src/i18n/lang/es-es-lang.json
@@ -35,6 +35,12 @@
"COPY": "COPY",
"EDIT": "EDITAR"
},
+ "BATCH": {
+ "DELETED_SUCCESS": "Deleted successfully",
+ "DELETED_FAILURE": "Deleted failed",
+ "SWITCH_SUCCESS": "Switch successfully",
+ "SWITCH_FAILURE": "Switch failed"
+ },
"TOOLTIP": {
"EMAIL": "El email debe ser una dirección válida como nombre@ejemplo.com.",
"USER_NAME": "Debe tener una longitud máxima de 20 caracteres y no puede contener caracteres especiales.",
@@ -202,7 +208,9 @@
"ADDED_SUCCESS": "Miembro añadido satisfactoriamente.",
"DELETED_SUCCESS": "Miembro eliminado satisfactoriamente",
"SWITCHED_SUCCESS": "Rol del miembro cambiado satisfactoriamente.",
- "OF": "of"
+ "OF": "of",
+ "SWITCH_TITLE": "Confirm project members switch",
+ "SWITCH_SUMMARY": "Do you want to switch project members {{param}}?"
},
"AUDIT_LOG": {
"USERNAME": "Nombre de usuario",
diff --git a/src/ui_ng/src/i18n/lang/zh-cn-lang.json b/src/ui_ng/src/i18n/lang/zh-cn-lang.json
index 483d94e75..07970081f 100644
--- a/src/ui_ng/src/i18n/lang/zh-cn-lang.json
+++ b/src/ui_ng/src/i18n/lang/zh-cn-lang.json
@@ -35,6 +35,12 @@
"COPY": "拷贝",
"EDIT": "编辑"
},
+ "BATCH": {
+ "DELETED_SUCCESS": "删除成功",
+ "DELETED_FAILURE": "删除失败",
+ "SWITCH_SUCCESS": "切换成功",
+ "SWITCH_FAILURE": "切换失败"
+ },
"TOOLTIP": {
"EMAIL": "请使用正确的邮箱地址,比如name@example.com。",
"USER_NAME": "不能包含特殊字符且长度不能超过20。",
@@ -202,7 +208,9 @@
"DELETION_SUMMARY": "你确认删除项目成员 {{param}}?",
"ADDED_SUCCESS": "成功新增成员。",
"DELETED_SUCCESS": "成功删除成员。",
- "SWITCHED_SUCCESS": "切换角色成功。"
+ "SWITCHED_SUCCESS": "切换角色成功。",
+ "SWITCH_TITLE": "切换项目成员确认",
+ "SWITCH_SUMMARY": "你确认切换项目成员 {{param}}??"
},
"AUDIT_LOG": {
"USERNAME": "用户名",
diff --git a/tests/resources/Harbor-Pages/Project-Members.robot b/tests/resources/Harbor-Pages/Project-Members.robot
index 419861ee8..2125086dd 100644
--- a/tests/resources/Harbor-Pages/Project-Members.robot
+++ b/tests/resources/Harbor-Pages/Project-Members.robot
@@ -69,7 +69,11 @@ Change Project Member Role
#change role
Click Element //button[@class='btn dropdown-toggle']
Click Element //button[contains(.,'${role}')]
- #Click Element xpath=//project-detail//clr-dg-action-overflow//button[contains(.,"${role}")]
+ sleep 1
+ Click Element xpath=//clr-modal//button[contains(.,'SWITCH')];
+ sleep 1
+ Click Element xpath=//clr-modal//button[contains(.,'CLOSE')];
+
Sleep 2
Wait Until Page Contains ${role}