1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-24 12:06:15 +01:00

filtering

This commit is contained in:
Kyle Spearrin 2018-10-18 12:15:13 -04:00
parent 7ab132bbf6
commit 323e54b4bd
3 changed files with 106 additions and 50 deletions

View File

@ -10,57 +10,80 @@
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" *ngIf="loading">
<div class="modal-body" *ngIf="loading || !users">
<i class="fa fa-spinner fa-spin text-muted" title="{{'loading' | i18n}}"></i>
</div>
<div class="modal-body" *ngIf="!loading">
<ng-container *ngIf="!users || !users.length">
<div class="modal-body" *ngIf="!loading && users && (users | search:searchText:'name':'email':'id') as searchedUsers">
<div class="d-flex">
<div class="mr-3">
<label class="sr-only" for="search">{{'search' | i18n}}</label>
<input type="search" class="form-control form-control-sm" id="search" placeholder="{{'search' | i18n}}"
name="SearchText" [(ngModel)]="searchText">
</div>
<div class="btn-group btn-group-sm" role="group">
<button type="button" class="btn btn-outline-secondary" [ngClass]="{active: !showSelected}"
(click)="filterSelected(false)">
{{'all' | i18n}}
</button>
<button type="button" class="btn btn-outline-secondary" [ngClass]="{active: showSelected}"
(click)="filterSelected(true)">
{{'selected' | i18n}}
<span class="badge badge-pill badge-info" *ngIf="selectedCount">{{selectedCount}}</span>
</button>
</div>
</div>
<ng-container *ngIf="!searchedUsers.length">
<hr>
{{'noUsersInList' | i18n}}
</ng-container>
<table class="table table-hover table-list mb-0" *ngIf="users && users.length">
<thead>
<tr>
<th>&nbsp;</th>
<th>&nbsp;</th>
<th>{{'name' | i18n}}</th>
<th *ngIf="entity === 'collection'">&nbsp;</th>
<th>{{'userType' | i18n}}</th>
<th width="100" class="text-center" *ngIf="entity === 'collection'">{{'readOnly' | i18n}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let u of users; let i = index">
<td class="table-list-checkbox" (click)="check(u)">
<input type="checkbox" [(ngModel)]="u.checked" name="Users[{{i}}].Checked" [disabled]="u.accessAll"
appStopProp>
</td>
<td width="30" (click)="check(u)">
<app-avatar [data]="u.name || u.email" [email]="u.email" size="25" [circle]="true"
[fontSize]="14"></app-avatar>
</td>
<td>
{{u.email}}
<span class="badge badge-secondary" *ngIf="u.status === organizationUserStatusType.Invited">{{'invited'
| i18n}}</span>
<span class="badge badge-warning" *ngIf="u.status === organizationUserStatusType.Accepted">{{'accepted'
| i18n}}</span>
<small class="text-muted d-block" *ngIf="u.name">{{u.name}}</small>
</td>
<td *ngIf="entity === 'collection'">
<i class="fa fa-th" *ngIf="u.accessAll" title="{{'userAccessAllItems' | i18n}}"></i>
</td>
<td>
<span *ngIf="u.type === organizationUserType.Owner">{{'owner' | i18n}}</span>
<span *ngIf="u.type === organizationUserType.Admin">{{'admin' | i18n}}</span>
<span *ngIf="u.type === organizationUserType.Manager">{{'manager' | i18n}}</span>
<span *ngIf="u.type === organizationUserType.User">{{'user' | i18n}}</span>
</td>
<td class="text-center" *ngIf="entity === 'collection'">
<input type="checkbox" [(ngModel)]="u.readOnly" name="Users[{{i}}].ReadOnly" [disabled]="u.accessAll || !u.checked">
</td>
</tr>
</tbody>
</table>
<ng-container *ngIf="searchedUsers.length">
<table class="table table-hover table-list mb-0">
<thead>
<tr>
<th>&nbsp;</th>
<th>&nbsp;</th>
<th>{{'name' | i18n}}</th>
<th *ngIf="entity === 'collection'">&nbsp;</th>
<th>{{'userType' | i18n}}</th>
<th width="100" class="text-center" *ngIf="entity === 'collection'">{{'readOnly' |
i18n}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let u of searchedUsers">
<td class="table-list-checkbox" (click)="check(u)">
<input type="checkbox" [(ngModel)]="u.checked" name="{{u.id.substr(0,8)}}_Checked"
[disabled]="u.accessAll" (change)="selectedChanged(u)" appStopProp>
</td>
<td width="30" (click)="check(u)">
<app-avatar [data]="u.name || u.email" [email]="u.email" size="25" [circle]="true"
[fontSize]="14"></app-avatar>
</td>
<td>
{{u.email}}
<span class="badge badge-secondary" *ngIf="u.status === organizationUserStatusType.Invited">{{'invited'
| i18n}}</span>
<span class="badge badge-warning" *ngIf="u.status === organizationUserStatusType.Accepted">{{'accepted'
| i18n}}</span>
<small class="text-muted d-block" *ngIf="u.name">{{u.name}}</small>
</td>
<td *ngIf="entity === 'collection'">
<i class="fa fa-th" *ngIf="u.accessAll" title="{{'userAccessAllItems' | i18n}}"></i>
</td>
<td>
<span *ngIf="u.type === organizationUserType.Owner">{{'owner' | i18n}}</span>
<span *ngIf="u.type === organizationUserType.Admin">{{'admin' | i18n}}</span>
<span *ngIf="u.type === organizationUserType.Manager">{{'manager' | i18n}}</span>
<span *ngIf="u.type === organizationUserType.User">{{'user' | i18n}}</span>
</td>
<td class="text-center" *ngIf="entity === 'collection'">
<input type="checkbox" [(ngModel)]="u.readOnly" name="{{u.id.substr(0,8)}}_ReadOnly"
[disabled]="u.accessAll || !u.checked">
</td>
</tr>
</tbody>
</table>
</ng-container>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary btn-submit" [disabled]="form.loading">

View File

@ -33,9 +33,12 @@ export class EntityUsersComponent implements OnInit {
organizationUserType = OrganizationUserType;
organizationUserStatusType = OrganizationUserStatusType;
showSelected = false;
loading = true;
users: OrganizationUserUserDetailsResponse[] = [];
formPromise: Promise<any>;
selectedCount = 0;
private allUsers: OrganizationUserUserDetailsResponse[] = [];
constructor(private apiService: ApiService, private i18nService: I18nService,
private analytics: Angulartics2, private toasterService: ToasterService) { }
@ -45,9 +48,17 @@ export class EntityUsersComponent implements OnInit {
this.loading = false;
}
get users() {
if (this.showSelected) {
return this.allUsers.filter((u) => (u as any).checked);
} else {
return this.allUsers;
}
}
async loadUsers() {
const users = await this.apiService.getOrganizationUsers(this.organizationId);
this.users = users.data.map((r) => r).sort(Utils.getSortFunction(this.i18nService, 'email'));
this.allUsers = users.data.map((r) => r).sort(Utils.getSortFunction(this.i18nService, 'email'));
if (this.entity === 'group') {
const response = await this.apiService.getGroupUsers(this.organizationId, this.entityId);
if (response != null && users.data.length > 0) {
@ -71,10 +82,13 @@ export class EntityUsersComponent implements OnInit {
}
}
this.users.forEach((u) => {
this.allUsers.forEach((u) => {
if (u.accessAll) {
(u as any).checked = true;
}
if ((u as any).checked) {
this.selectedCount++;
}
});
}
@ -83,6 +97,22 @@ export class EntityUsersComponent implements OnInit {
return;
}
(u as any).checked = !(u as any).checked;
this.selectedChanged(u);
}
selectedChanged(u: OrganizationUserUserDetailsResponse) {
if ((u as any).checked) {
this.selectedCount++;
} else {
if (this.entity === 'collection') {
(u as any).readOnly = false;
}
this.selectedCount--;
}
}
filterSelected(showSelected: boolean) {
this.showSelected = showSelected;
}
async submit() {

View File

@ -2495,5 +2495,8 @@
},
"updatedUsers": {
"message": "Updated users"
},
"selected": {
"message": "Selected"
}
}