Skip to content

Commit 3d95de8

Browse files
HejdaJakubxflord
authored andcommitted
feat(admin): disable member invitation
* Invite button will be disabled if 'isInvitationEnabled' returns false. * Invitation is enabled if invitation notification exists, application form exists and application can be sumbited - submin/auto-submit button exists in the form.
1 parent 729d9ed commit 3d95de8

File tree

6 files changed

+160
-20
lines changed

6 files changed

+160
-20
lines changed

apps/admin-gui/src/app/vos/pages/group-detail-page/group-members/group-members.component.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ <h1 class="page-subtitle">{{'GROUP_DETAIL.MEMBERS.TITLE' | translate}}</h1>
2020
</button>
2121
</span>
2222
<span
23-
[matTooltipDisabled]="!(group | groupMembersActionButtonDisabled)"
23+
[matTooltipDisabled]="!((group | groupMembersActionButtonDisabled) || inviteDisabled)"
2424
[matTooltipPosition]="'above'"
25-
matTooltip="{{group | groupMembersActionButtonDisabledTooltip | translate}}">
25+
matTooltip="{{inviteDisabled ? ('GROUP_DETAIL.MEMBERS.INVITE_DISABLED' | translate) : (group | groupMembersActionButtonDisabledTooltip | translate)}}">
2626
<button
2727
*ngIf="inviteAuth"
28-
[disabled]="(group | groupMembersActionButtonDisabled)"
28+
[disabled]="(group | groupMembersActionButtonDisabled) || inviteDisabled"
2929
[matMenuTriggerFor]="menu"
3030
class="me-2 dropdown-toggle"
3131
color="accent"

apps/admin-gui/src/app/vos/pages/group-detail-page/group-members/group-members.component.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
AttributesManagerService,
1515
GroupsManagerService,
1616
MemberGroupStatus,
17+
RegistrarManagerService,
1718
RichGroup,
1819
RichMember,
1920
VoMemberStatuses,
@@ -57,6 +58,7 @@ export class GroupMembersComponent implements OnInit {
5758
addAuth: boolean;
5859
removeAuth: boolean;
5960
inviteAuth: boolean;
61+
inviteDisabled = true;
6062
copyAuth: boolean;
6163
copyDisabled = false;
6264
blockManualMemberAdding: boolean;
@@ -89,6 +91,7 @@ export class GroupMembersComponent implements OnInit {
8991

9092
constructor(
9193
private groupService: GroupsManagerService,
94+
private registrarService: RegistrarManagerService,
9295
private dialog: MatDialog,
9396
private guiAuthResolver: GuiAuthResolver,
9497
private storeService: StoreService,
@@ -107,6 +110,13 @@ export class GroupMembersComponent implements OnInit {
107110
this.memberAttrNames = this.memberAttrNames.concat(this.storeService.getLoginAttributeNames());
108111
this.group = this.entityStorageService.getEntity();
109112
this.setAuthRights();
113+
if (this.inviteAuth) {
114+
this.registrarService
115+
.isInvitationEnabled(this.group.voId, this.group.id)
116+
.subscribe((enabled) => {
117+
this.inviteDisabled = !enabled;
118+
});
119+
}
110120
void this.isManualAddingBlocked(this.group.voId).then(() => this.loadPage(this.group.id));
111121
this.isCopyMembersDisabled();
112122
}

apps/admin-gui/src/app/vos/pages/vo-detail-page/vo-members/vo-members.component.html

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,28 @@ <h1 class="page-subtitle">{{'VO_DETAIL.MEMBERS.TITLE' | translate}}</h1>
1616
{{'VO_DETAIL.MEMBERS.ADD_MEMBER' | translate}}
1717
</button>
1818
</div>
19-
<button
20-
*ngIf="inviteAuth"
21-
[disabled]="blockManualMemberAdding"
22-
[matMenuTriggerFor]="menu"
23-
class="me-2 dropdown-toggle"
24-
color="accent"
25-
mat-flat-button>
26-
{{'VO_DETAIL.MEMBERS.INVITE' | translate}}
27-
</button>
28-
<mat-menu #menu="matMenu">
29-
<button *ngIf="inviteAuth" (click)="onInviteMember()" class="action-button" mat-menu-item>
30-
{{'VO_DETAIL.MEMBERS.INVITE_ONE' | translate}}
31-
</button>
32-
<button *ngIf="inviteAuth" (click)="onBulkInvite()" class="action-button" mat-menu-item>
33-
{{'VO_DETAIL.MEMBERS.INVITE_BULK' | translate}}
19+
<span
20+
[matTooltipDisabled]="!inviteDisabled"
21+
[matTooltipPosition]="'above'"
22+
matTooltip="{{'VO_DETAIL.MEMBERS.INVITE_DISABLED' | translate}}">
23+
<button
24+
*ngIf="inviteAuth"
25+
[disabled]="blockManualMemberAdding || inviteDisabled"
26+
[matMenuTriggerFor]="menu"
27+
class="me-2 dropdown-toggle"
28+
color="accent"
29+
mat-flat-button>
30+
{{'VO_DETAIL.MEMBERS.INVITE' | translate}}
3431
</button>
35-
</mat-menu>
32+
<mat-menu #menu="matMenu">
33+
<button *ngIf="inviteAuth" (click)="onInviteMember()" class="action-button" mat-menu-item>
34+
{{'VO_DETAIL.MEMBERS.INVITE_ONE' | translate}}
35+
</button>
36+
<button *ngIf="inviteAuth" (click)="onBulkInvite()" class="action-button" mat-menu-item>
37+
{{'VO_DETAIL.MEMBERS.INVITE_BULK' | translate}}
38+
</button>
39+
</mat-menu>
40+
</span>
3641
<button
3742
*ngIf="removeAuth"
3843
(click)="onRemoveMembers()"

apps/admin-gui/src/app/vos/pages/vo-detail-page/vo-members/vo-members.component.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { MatDialog } from '@angular/material/dialog';
1111
import { RemoveMembersDialogComponent } from '../../../../shared/components/dialogs/remove-members-dialog/remove-members-dialog.component';
1212
import {
1313
AttributesManagerService,
14+
RegistrarManagerService,
1415
RichMember,
1516
Vo,
1617
VoMemberStatuses,
@@ -56,10 +57,12 @@ export class VoMembersComponent implements OnInit {
5657
addAuth: boolean;
5758
removeAuth: boolean;
5859
inviteAuth: boolean;
60+
inviteDisabled = true;
5961
routeAuth: boolean;
6062
blockManualMemberAdding: boolean;
6163

6264
constructor(
65+
private registrarService: RegistrarManagerService,
6366
private notificator: NotificatorService,
6467
private dialog: MatDialog,
6568
private authzService: GuiAuthResolver,
@@ -77,6 +80,11 @@ export class VoMembersComponent implements OnInit {
7780

7881
this.vo = this.entityStorageService.getEntity();
7982
this.setAuthRights();
83+
if (this.inviteAuth) {
84+
this.registrarService.isInvitationEnabled(this.vo.id, null).subscribe((enabled) => {
85+
this.inviteDisabled = !enabled;
86+
});
87+
}
8088

8189
void this.isManualAddingBlocked(this.vo.id);
8290
}

apps/admin-gui/src/assets/i18n/en.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,8 @@
365365
"FILTER_STATUS": "Filter by Status",
366366
"INVITE": "Invite",
367367
"INVITE_ONE": "Invite member",
368-
"INVITE_BULK": "Invite multiple members"
368+
"INVITE_BULK": "Invite multiple members",
369+
"INVITE_DISABLED": "Application form is not setup correctly or invitation notification does not exist."
369370
},
370371
"OVERVIEW": {
371372
"INVITE_MEMBER": "Invite member",
@@ -690,6 +691,7 @@
690691
"INVITE": "Invite",
691692
"INVITE_ONE": "Invite member",
692693
"INVITE_BULK": "Invite multiple members",
694+
"INVITE_DISABLED": "Application form is not setup correctly or invitation notification does not exist.",
693695
"SYNCHRONIZED": "Action is disabled on this group, group is filled with members from external source.",
694696
"FILTER_STATUS": "Filter by organizations status",
695697
"FILTER_GROUP_STATUS": "Filter by group status",

libs/perun/openapi/src/lib/api/registrarManager.service.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5417,6 +5417,121 @@ export class RegistrarManagerService {
54175417
});
54185418
}
54195419

5420+
/**
5421+
* Checks if invitation is enabled (invitation notification exists, application form exists and application form can be submitted).
5422+
* @param vo id of Vo
5423+
* @param group id of Group
5424+
* @param useNon if set to true sends the request to the backend server as 'non' instead of the usual (oauth, krb...).
5425+
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
5426+
* @param reportProgress flag to report request and response progress.
5427+
*/
5428+
public isInvitationEnabled(
5429+
vo: number,
5430+
group?: number,
5431+
useNon?: boolean,
5432+
observe?: 'body',
5433+
reportProgress?: boolean,
5434+
options?: { httpHeaderAccept?: 'application/json'; context?: HttpContext }
5435+
): Observable<boolean>;
5436+
public isInvitationEnabled(
5437+
vo: number,
5438+
group?: number,
5439+
useNon?: boolean,
5440+
observe?: 'response',
5441+
reportProgress?: boolean,
5442+
options?: { httpHeaderAccept?: 'application/json'; context?: HttpContext }
5443+
): Observable<HttpResponse<boolean>>;
5444+
public isInvitationEnabled(
5445+
vo: number,
5446+
group?: number,
5447+
useNon?: boolean,
5448+
observe?: 'events',
5449+
reportProgress?: boolean,
5450+
options?: { httpHeaderAccept?: 'application/json'; context?: HttpContext }
5451+
): Observable<HttpEvent<boolean>>;
5452+
public isInvitationEnabled(
5453+
vo: number,
5454+
group?: number,
5455+
useNon: boolean = false,
5456+
observe: any = 'body',
5457+
reportProgress: boolean = false,
5458+
options?: { httpHeaderAccept?: 'application/json'; context?: HttpContext }
5459+
): Observable<any> {
5460+
if (vo === null || vo === undefined) {
5461+
throw new Error(
5462+
'Required parameter vo was null or undefined when calling isInvitationEnabled.'
5463+
);
5464+
}
5465+
5466+
let localVarQueryParameters = new HttpParams({ encoder: this.encoder });
5467+
if (vo !== undefined && vo !== null) {
5468+
localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, <any>vo, 'vo');
5469+
}
5470+
if (group !== undefined && group !== null) {
5471+
localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, <any>group, 'group');
5472+
}
5473+
5474+
let localVarHeaders = this.defaultHeaders;
5475+
5476+
let localVarCredential: string | undefined;
5477+
// authentication (BasicAuth) required
5478+
localVarCredential = this.configuration.lookupCredential('BasicAuth');
5479+
if (localVarCredential) {
5480+
localVarHeaders = localVarHeaders.set('Authorization', 'Basic ' + localVarCredential);
5481+
}
5482+
5483+
// authentication (BearerAuth) required
5484+
localVarCredential = this.configuration.lookupCredential('BearerAuth');
5485+
if (localVarCredential) {
5486+
localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential);
5487+
}
5488+
5489+
let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
5490+
if (localVarHttpHeaderAcceptSelected === undefined) {
5491+
// to determine the Accept header
5492+
const httpHeaderAccepts: string[] = ['application/json'];
5493+
localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
5494+
}
5495+
if (localVarHttpHeaderAcceptSelected !== undefined) {
5496+
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
5497+
}
5498+
5499+
let localVarHttpContext: HttpContext | undefined = options && options.context;
5500+
if (localVarHttpContext === undefined) {
5501+
localVarHttpContext = new HttpContext();
5502+
}
5503+
5504+
let responseType_: 'text' | 'json' | 'blob' = 'json';
5505+
if (localVarHttpHeaderAcceptSelected) {
5506+
if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
5507+
responseType_ = 'text';
5508+
} else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
5509+
responseType_ = 'json';
5510+
} else {
5511+
responseType_ = 'blob';
5512+
}
5513+
}
5514+
5515+
let requestUrl = `${this.configuration.basePath}/json/registrarManager/isInvitationEnabled`;
5516+
if (useNon) {
5517+
// replace the authentication part of url with 'non' authentication
5518+
let helperUrl = new URL(requestUrl);
5519+
let path = helperUrl.pathname.split('/');
5520+
path[1] = 'non';
5521+
helperUrl.pathname = path.join('/');
5522+
requestUrl = helperUrl.toString();
5523+
}
5524+
return this.httpClient.get<boolean>(requestUrl, {
5525+
context: localVarHttpContext,
5526+
params: localVarQueryParameters,
5527+
responseType: <any>responseType_,
5528+
withCredentials: this.configuration.withCredentials,
5529+
headers: localVarHeaders,
5530+
observe: observe,
5531+
reportProgress: reportProgress,
5532+
});
5533+
}
5534+
54205535
/**
54215536
* Manually rejects an application.
54225537
* Expected to be called as a result of direct VO administrator action in the web UI.

0 commit comments

Comments
 (0)