collection and group listing from org admin

This commit is contained in:
Kyle Spearrin 2018-07-06 12:49:06 -04:00
parent d830499c76
commit 93582da044
8 changed files with 168 additions and 17 deletions

2
jslib

@ -1 +1 @@
Subproject commit a600c4a5398f8893d4cfea298fcfb66f90c3d975
Subproject commit 2a526940fd4eefd2758ea654b0c7994e0ee12c4e

View File

@ -109,6 +109,7 @@ import { TrueFalseValueDirective } from 'jslib/angular/directives/true-false-val
import { I18nPipe } from 'jslib/angular/pipes/i18n.pipe';
import { SearchCiphersPipe } from 'jslib/angular/pipes/search-ciphers.pipe';
import { SearchPipe } from 'jslib/angular/pipes/search.pipe';
@NgModule({
imports: [
@ -189,6 +190,7 @@ import { SearchCiphersPipe } from 'jslib/angular/pipes/search-ciphers.pipe';
PurgeVaultComponent,
RegisterComponent,
SearchCiphersPipe,
SearchPipe,
SettingsComponent,
ShareComponent,
StopClickDirective,

View File

@ -1,3 +1,43 @@
<div class="page-header">
<div class="page-header d-flex">
<h1>{{'collections' | i18n}}</h1>
<div class="ml-auto d-flex">
<div class="form-inline">
<label class="sr-only" for="search">{{'search' | i18n}}</label>
<input type="search" class="form-control form-control-sm" id="search" placeholder="{{'search' | i18n}}" [(ngModel)]="searchText">
</div>
<button type="button" class="btn btn-sm btn-outline-primary ml-3" (click)="add()">
<i class="fa fa-plus fa-fw"></i>
{{'newCollection' | i18n}}
</button>
</div>
</div>
<i class="fa fa-spinner fa-spin text-muted" *ngIf="loading"></i>
<ng-container *ngIf="!loading && (collections | search:searchText:'name') as searchedCollections">
<p *ngIf="!searchedCollections.length">{{'noItemsInList' | i18n}}</p>
<table class="table table-hover table-list" *ngIf="searchedCollections.length">
<tbody>
<tr *ngFor="let c of searchedCollections">
<td class="normal-lh">
<a href="#" appStopClick (click)="edit(c)">{{c.name}}</a>
</td>
<td class="table-list-options">
<div class="dropdown" appListDropdown>
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-cog fa-lg"></i>
</button>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" href="#" appStopClick (click)="users(c)">
<i class="fa fa-fw fa-users"></i>
{{'users' | i18n}}
</a>
<a class="dropdown-item text-danger" href="#" appStopClick (click)="delete(c)">
<i class="fa fa-fw fa-trash-o"></i>
{{'delete' | i18n}}
</a>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</ng-container>

View File

@ -1,7 +1,40 @@
import { Component } from '@angular/core';
import {
Component,
OnInit,
} from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ApiService } from 'jslib/abstractions/api.service';
import { CollectionService } from 'jslib/abstractions/collection.service';
import { CollectionData } from 'jslib/models/data/collectionData';
import { Collection } from 'jslib/models/domain/collection';
import { CollectionView } from 'jslib/models/view/collectionView';
@Component({
selector: 'app-org-manage-collections',
templateUrl: 'collections.component.html',
})
export class CollectionsComponent { }
export class CollectionsComponent implements OnInit {
loading = true;
organizationId: string;
collections: CollectionView[];
searchText: string;
constructor(private apiService: ApiService, private route: ActivatedRoute,
private collectionService: CollectionService) { }
async ngOnInit() {
this.route.parent.parent.params.subscribe(async (params) => {
this.organizationId = params.organizationId;
});
await this.load();
}
async load() {
const response = await this.apiService.getCollections(this.organizationId);
const collections = response.data.map((r) => new Collection(new CollectionData(r)));
this.collections = await this.collectionService.decryptMany(collections);
this.loading = false;
}
}

View File

@ -1,3 +1,43 @@
<div class="page-header">
<div class="page-header d-flex">
<h1>{{'groups' | i18n}}</h1>
<div class="ml-auto d-flex">
<div class="form-inline">
<label class="sr-only" for="search">{{'search' | i18n}}</label>
<input type="search" class="form-control form-control-sm" id="search" placeholder="{{'search' | i18n}}" [(ngModel)]="searchText">
</div>
<button type="button" class="btn btn-sm btn-outline-primary ml-3" (click)="add()">
<i class="fa fa-plus fa-fw"></i>
{{'newGroup' | i18n}}
</button>
</div>
</div>
<i class="fa fa-spinner fa-spin text-muted" *ngIf="loading"></i>
<ng-container *ngIf="!loading && (groups | search:searchText:'name') as searchedGroups">
<p *ngIf="!searchedGroups.length">{{'noItemsInList' | i18n}}</p>
<table class="table table-hover table-list" *ngIf="searchedGroups.length">
<tbody>
<tr *ngFor="let g of searchedGroups">
<td class="normal-lh">
<a href="#" appStopClick (click)="edit(g)">{{g.name}}</a>
</td>
<td class="table-list-options">
<div class="dropdown" appListDropdown>
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-cog fa-lg"></i>
</button>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" href="#" appStopClick (click)="users(g)">
<i class="fa fa-fw fa-users"></i>
{{'users' | i18n}}
</a>
<a class="dropdown-item text-danger" href="#" appStopClick (click)="delete(g)">
<i class="fa fa-fw fa-trash-o"></i>
{{'delete' | i18n}}
</a>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</ng-container>

View File

@ -1,7 +1,39 @@
import { Component } from '@angular/core';
import {
Component,
OnInit,
} from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ApiService } from 'jslib/abstractions/api.service';
import { GroupResponse } from 'jslib/models/response/groupUserResponse';
@Component({
selector: 'app-org-groups',
templateUrl: 'groups.component.html',
})
export class GroupsComponent { }
export class GroupsComponent implements OnInit {
loading = true;
organizationId: string;
groups: GroupResponse[];
searchText: string;
constructor(private apiService: ApiService, private route: ActivatedRoute) { }
async ngOnInit() {
this.route.parent.parent.params.subscribe(async (params) => {
this.organizationId = params.organizationId;
});
await this.load();
}
async load() {
const response = await this.apiService.getGroups(this.organizationId);
if (response.data != null && response.data.length > 0) {
this.groups = response.data;
} else {
this.groups = [];
}
this.loading = false;
}
}

View File

@ -31,16 +31,8 @@ export class GroupingsComponent extends BaseGroupingsComponent {
}
const collections = await this.apiService.getCollections(this.organization.id);
if (collections != null && collections.data != null && collections.data.length) {
const decCollections: CollectionView[] = [];
const promises: any[] = [];
collections.data.forEach((r) => {
const data = new CollectionData(r);
const collection = new Collection(data);
promises.push(collection.decrypt().then((c) => decCollections.push(c)));
});
await Promise.all(promises);
decCollections.sort(this.collectionService.getLocaleSortingFunction());
this.collections = decCollections;
const collectionDomains = collections.data.map((r) => new Collection(new CollectionData(r)));
this.collections = await this.collectionService.decryptMany(collectionDomains);
} else {
this.collections = [];
}

View File

@ -1699,5 +1699,17 @@
},
"groups": {
"message": "Groups"
},
"newGroup": {
"message": "New Group"
},
"newCollection": {
"message": "New Collection"
},
"inviteUser": {
"message": "Invite User"
},
"search": {
"message": "Search"
}
}