mirror of
https://github.com/bitwarden/browser.git
synced 2025-02-02 23:11:40 +01:00
manage user groups
This commit is contained in:
parent
b428660f92
commit
57e13c25b5
@ -43,6 +43,7 @@ import { GroupsComponent as OrgGroupsComponent } from './organizations/manage/gr
|
|||||||
import { ManageComponent as OrgManageComponent } from './organizations/manage/manage.component';
|
import { ManageComponent as OrgManageComponent } from './organizations/manage/manage.component';
|
||||||
import { PeopleComponent as OrgPeopleComponent } from './organizations/manage/people.component';
|
import { PeopleComponent as OrgPeopleComponent } from './organizations/manage/people.component';
|
||||||
import { UserAddEditComponent as OrgUserAddEditComponent } from './organizations/manage/user-add-edit.component';
|
import { UserAddEditComponent as OrgUserAddEditComponent } from './organizations/manage/user-add-edit.component';
|
||||||
|
import { UserGroupsComponent as OrgUserGroupsComponent } from './organizations/manage/user-groups.component';
|
||||||
|
|
||||||
import { ExportComponent as OrgExportComponent } from './organizations/tools/export.component';
|
import { ExportComponent as OrgExportComponent } from './organizations/tools/export.component';
|
||||||
import { ImportComponent as OrgImportComponent } from './organizations/tools/import.component';
|
import { ImportComponent as OrgImportComponent } from './organizations/tools/import.component';
|
||||||
@ -189,6 +190,7 @@ import { SearchPipe } from 'jslib/angular/pipes/search.pipe';
|
|||||||
OrgPeopleComponent,
|
OrgPeopleComponent,
|
||||||
OrgToolsComponent,
|
OrgToolsComponent,
|
||||||
OrgUserAddEditComponent,
|
OrgUserAddEditComponent,
|
||||||
|
OrgUserGroupsComponent,
|
||||||
OrganizationsComponent,
|
OrganizationsComponent,
|
||||||
OrganizationLayoutComponent,
|
OrganizationLayoutComponent,
|
||||||
OrgVaultComponent,
|
OrgVaultComponent,
|
||||||
@ -240,6 +242,7 @@ import { SearchPipe } from 'jslib/angular/pipes/search.pipe';
|
|||||||
OrgEntityUsersComponent,
|
OrgEntityUsersComponent,
|
||||||
OrgGroupAddEditComponent,
|
OrgGroupAddEditComponent,
|
||||||
OrgUserAddEditComponent,
|
OrgUserAddEditComponent,
|
||||||
|
OrgUserGroupsComponent,
|
||||||
PasswordGeneratorHistoryComponent,
|
PasswordGeneratorHistoryComponent,
|
||||||
PurgeVaultComponent,
|
PurgeVaultComponent,
|
||||||
ShareComponent,
|
ShareComponent,
|
||||||
|
@ -23,6 +23,7 @@ import { Utils } from 'jslib/misc/utils';
|
|||||||
|
|
||||||
import { ModalComponent } from '../../modal.component';
|
import { ModalComponent } from '../../modal.component';
|
||||||
import { UserAddEditComponent } from './user-add-edit.component';
|
import { UserAddEditComponent } from './user-add-edit.component';
|
||||||
|
import { UserGroupsComponent } from './user-groups.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-org-people',
|
selector: 'app-org-people',
|
||||||
@ -92,6 +93,28 @@ export class PeopleComponent implements OnInit {
|
|||||||
this.edit(null);
|
this.edit(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
groups(user: OrganizationUserUserDetailsResponse) {
|
||||||
|
if (this.modal != null) {
|
||||||
|
this.modal.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
||||||
|
this.modal = this.groupsModalRef.createComponent(factory).instance;
|
||||||
|
const childComponent = this.modal.show<UserGroupsComponent>(
|
||||||
|
UserGroupsComponent, this.groupsModalRef);
|
||||||
|
|
||||||
|
childComponent.name = user != null ? user.name || user.email : null;
|
||||||
|
childComponent.organizationId = this.organizationId;
|
||||||
|
childComponent.organizationUserId = user != null ? user.id : null;
|
||||||
|
childComponent.onSavedUser.subscribe(() => {
|
||||||
|
this.modal.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.modal.onClosed.subscribe(() => {
|
||||||
|
this.modal = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async remove(user: OrganizationUserUserDetailsResponse) {
|
async remove(user: OrganizationUserUserDetailsResponse) {
|
||||||
const confirmed = await this.platformUtilsService.showDialog(
|
const confirmed = await this.platformUtilsService.showDialog(
|
||||||
this.i18nService.t('removeUserConfirmation'), user.name || user.email,
|
this.i18nService.t('removeUserConfirmation'), user.name || user.email,
|
||||||
|
49
src/app/organizations/manage/user-groups.component.html
Normal file
49
src/app/organizations/manage/user-groups.component.html
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<div class="modal fade">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<form class="modal-content" #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h2 class="modal-title">
|
||||||
|
{{'groupAccess' | i18n}}
|
||||||
|
<small class="text-muted" *ngIf="name">{{name}}</small>
|
||||||
|
</h2>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" attr.aria-label="{{'close' | i18n}}">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body" *ngIf="loading">
|
||||||
|
<i class="fa fa-spinner fa-spin text-muted"></i>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body" *ngIf="!loading">
|
||||||
|
<p>{{'groupAccessUserDesc' | i18n}}</p>
|
||||||
|
<div *ngIf="!groups || !groups.length">
|
||||||
|
{{'noGroupsInList' | i18n}}
|
||||||
|
</div>
|
||||||
|
<table class="table table-hover table-list mb-0" *ngIf="groups && groups.length">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th> </th>
|
||||||
|
<th>{{'name' | i18n}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr *ngFor="let g of groups; let i = index">
|
||||||
|
<td class="table-list-checkbox" (click)="check(g)">
|
||||||
|
<input type="checkbox" [(ngModel)]="g.checked" name="Groups[{{i}}].Checked">
|
||||||
|
</td>
|
||||||
|
<td (click)="check(g)">
|
||||||
|
<span appStopProp>{{g.name}}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button appBlurClick type="submit" class="btn btn-primary btn-submit" [disabled]="form.loading">
|
||||||
|
<i class="fa fa-spinner fa-spin"></i>
|
||||||
|
<span>{{'save' | i18n}}</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">{{'cancel' | i18n}}</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
79
src/app/organizations/manage/user-groups.component.ts
Normal file
79
src/app/organizations/manage/user-groups.component.ts
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import {
|
||||||
|
Component,
|
||||||
|
EventEmitter,
|
||||||
|
Input,
|
||||||
|
OnInit,
|
||||||
|
Output,
|
||||||
|
} from '@angular/core';
|
||||||
|
|
||||||
|
import { ToasterService } from 'angular2-toaster';
|
||||||
|
import { Angulartics2 } from 'angulartics2';
|
||||||
|
|
||||||
|
import { ApiService } from 'jslib/abstractions/api.service';
|
||||||
|
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||||
|
|
||||||
|
import { OrganizationUserUpdateGroupsRequest } from 'jslib/models/request/organizationUserUpdateGroupsRequest';
|
||||||
|
import { GroupResponse } from 'jslib/models/response/groupResponse';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-user-groups',
|
||||||
|
templateUrl: 'user-groups.component.html',
|
||||||
|
})
|
||||||
|
export class UserGroupsComponent implements OnInit {
|
||||||
|
@Input() name: string;
|
||||||
|
@Input() organizationUserId: string;
|
||||||
|
@Input() organizationId: string;
|
||||||
|
@Output() onSavedUser = new EventEmitter();
|
||||||
|
|
||||||
|
loading = true;
|
||||||
|
groups: GroupResponse[] = [];
|
||||||
|
formPromise: Promise<any>;
|
||||||
|
|
||||||
|
constructor(private apiService: ApiService, private i18nService: I18nService,
|
||||||
|
private analytics: Angulartics2, private toasterService: ToasterService) { }
|
||||||
|
|
||||||
|
async ngOnInit() {
|
||||||
|
const groupsResponse = await this.apiService.getGroups(this.organizationId);
|
||||||
|
this.groups = groupsResponse.data.map((r) => r);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const userGroups = await this.apiService.getOrganizationUserGroups(
|
||||||
|
this.organizationId, this.organizationUserId);
|
||||||
|
if (userGroups != null && this.groups != null) {
|
||||||
|
userGroups.forEach((ug) => {
|
||||||
|
const group = this.groups.filter((g) => g.id === ug);
|
||||||
|
if (group != null && group.length > 0) {
|
||||||
|
(group[0] as any).checked = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch { }
|
||||||
|
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
check(g: GroupResponse, select?: boolean) {
|
||||||
|
(g as any).checked = select == null ? !(g as any).checked : select;
|
||||||
|
if (!(g as any).checked) {
|
||||||
|
(g as any).readOnly = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectAll(select: boolean) {
|
||||||
|
this.groups.forEach((g) => this.check(g, select));
|
||||||
|
}
|
||||||
|
|
||||||
|
async submit() {
|
||||||
|
const request = new OrganizationUserUpdateGroupsRequest();
|
||||||
|
request.groupIds = this.groups.filter((g) => (g as any).checked).map((g) => g.id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.formPromise = this.apiService.putOrganizationUserGroups(this.organizationId, this.organizationUserId,
|
||||||
|
request);
|
||||||
|
await this.formPromise;
|
||||||
|
this.analytics.eventTrack.next({ action: 'Edited User Groups' });
|
||||||
|
this.toasterService.popAsync('success', null, this.i18nService.t('editedGroupsForUser', this.name));
|
||||||
|
this.onSavedUser.emit();
|
||||||
|
} catch { }
|
||||||
|
}
|
||||||
|
}
|
@ -2048,6 +2048,9 @@
|
|||||||
"groupAccess": {
|
"groupAccess": {
|
||||||
"message": "Group Access"
|
"message": "Group Access"
|
||||||
},
|
},
|
||||||
|
"groupAccessUserDesc": {
|
||||||
|
"message": "Edit the groups that this user belongs to."
|
||||||
|
},
|
||||||
"invitedUsers": {
|
"invitedUsers": {
|
||||||
"message": "Invited user(s)."
|
"message": "Invited user(s)."
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user