Refactor user listing
This commit is contained in:
parent
271e8b6501
commit
f3dca378e2
@ -15,7 +15,7 @@
|
||||
<div class="content-container">
|
||||
<div class="header-item">
|
||||
<span class="all-caps-label">
|
||||
{{ 'default-colors-screen.table-header.title' | translate: { length: colors.length } }}
|
||||
{{ 'default-colors-screen.table-header.title' | translate: { length: allEntities.length } }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||
<!-- Table lines -->
|
||||
<div class="table-item" *cdkVirtualFor="let color of colors | sortBy: sortingOption.order:sortingOption.column">
|
||||
<div class="table-item" *cdkVirtualFor="let color of allEntities | sortBy: sortingOption.order:sortingOption.column">
|
||||
<div>
|
||||
<div class="table-item-title heading" [translate]="'default-colors-screen.types.' + color.key"></div>
|
||||
</div>
|
||||
|
||||
@ -11,12 +11,11 @@ import { BaseListingComponent } from '../../../shared/base/base-listing.componen
|
||||
templateUrl: './default-colors-screen.component.html',
|
||||
styleUrls: ['./default-colors-screen.component.scss']
|
||||
})
|
||||
export class DefaultColorsScreenComponent extends BaseListingComponent {
|
||||
export class DefaultColorsScreenComponent extends BaseListingComponent<{ key: string; value: string }> {
|
||||
protected readonly _sortKey = 'default-colors';
|
||||
|
||||
public viewReady = false;
|
||||
private _colorsObj: Colors;
|
||||
public colors: { key: string; value: string }[] = [];
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
@ -41,7 +40,7 @@ export class DefaultColorsScreenComponent extends BaseListingComponent {
|
||||
.toPromise()
|
||||
.then((data) => {
|
||||
this._colorsObj = data;
|
||||
this.colors = Object.keys(data).map((key) => ({
|
||||
this.allEntities = Object.keys(data).map((key) => ({
|
||||
key,
|
||||
value: data[key]
|
||||
}));
|
||||
|
||||
@ -14,15 +14,13 @@ import { BaseListingComponent } from '../../../shared/base/base-listing.componen
|
||||
templateUrl: './dictionary-listing-screen.component.html',
|
||||
styleUrls: ['./dictionary-listing-screen.component.scss']
|
||||
})
|
||||
export class DictionaryListingScreenComponent extends BaseListingComponent implements OnInit {
|
||||
export class DictionaryListingScreenComponent extends BaseListingComponent<TypeValue> implements OnInit {
|
||||
protected readonly _searchKey = 'label';
|
||||
protected readonly _selectionKey = 'type';
|
||||
protected readonly _sortKey = 'dictionary-listing';
|
||||
|
||||
public viewReady = false;
|
||||
public chartData: DoughnutChartConfig[] = [];
|
||||
public allEntities: TypeValue[];
|
||||
public displayedEntities: TypeValue[];
|
||||
|
||||
constructor(
|
||||
private readonly _dialogService: AdminDialogService,
|
||||
|
||||
@ -16,7 +16,6 @@ export class FileAttributesListingScreenComponent extends BaseListingComponent<F
|
||||
protected readonly _selectionKey = 'id';
|
||||
protected readonly _sortKey = 'file-attributes-listing';
|
||||
|
||||
public allEntities: FileAttributeConfig[] = [];
|
||||
public viewReady = false;
|
||||
public loading = false;
|
||||
|
||||
|
||||
@ -4,13 +4,14 @@ import { PermissionsService } from '../../../../services/permissions.service';
|
||||
import { UserPreferenceService } from '../../../../services/user-preference.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { BaseListingComponent } from '../../../shared/base/base-listing.component';
|
||||
import { RuleSetModel } from '@redaction/red-ui-http';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-rule-sets-listing-screen',
|
||||
templateUrl: './rule-sets-listing-screen.component.html',
|
||||
styleUrls: ['./rule-sets-listing-screen.component.scss']
|
||||
})
|
||||
export class RuleSetsListingScreenComponent extends BaseListingComponent implements OnInit {
|
||||
export class RuleSetsListingScreenComponent extends BaseListingComponent<RuleSetModel> implements OnInit {
|
||||
protected readonly _searchKey = 'name';
|
||||
protected readonly _selectionKey = 'ruleSetId';
|
||||
protected readonly _sortKey = 'rule-sets-listing';
|
||||
|
||||
@ -28,23 +28,23 @@
|
||||
<div class="select-all-container">
|
||||
<div
|
||||
(click)="toggleSelectAll()"
|
||||
[class.active]="areAllUsersSelected"
|
||||
[class.active]="areAllEntitiesSelected"
|
||||
class="select-oval always-visible"
|
||||
*ngIf="!areAllUsersSelected && !areSomeUsersSelected"
|
||||
*ngIf="!areAllEntitiesSelected && !areSomeEntitiesSelected"
|
||||
></div>
|
||||
<mat-icon *ngIf="areAllUsersSelected" (click)="toggleSelectAll()" class="selection-icon active" svgIcon="red:radio-selected"></mat-icon>
|
||||
<mat-icon *ngIf="areAllEntitiesSelected" (click)="toggleSelectAll()" class="selection-icon active" svgIcon="red:radio-selected"></mat-icon>
|
||||
<mat-icon
|
||||
*ngIf="areSomeUsersSelected && !areAllUsersSelected"
|
||||
*ngIf="areSomeEntitiesSelected && !areAllEntitiesSelected"
|
||||
(click)="toggleSelectAll()"
|
||||
class="selection-icon"
|
||||
svgIcon="red:radio-indeterminate"
|
||||
></mat-icon>
|
||||
</div>
|
||||
<span class="all-caps-label">
|
||||
{{ 'user-listing.table-header.title' | translate: { length: displayedUsers.length } }}
|
||||
{{ 'user-listing.table-header.title' | translate: { length: displayedEntities.length } }}
|
||||
</span>
|
||||
|
||||
<ng-container *ngIf="areSomeUsersSelected && !loading">
|
||||
<ng-container *ngIf="areSomeEntitiesSelected && !loading">
|
||||
<redaction-circle-button
|
||||
(action)="bulkDelete()"
|
||||
[disabled]="!canDeleteSelected"
|
||||
@ -73,14 +73,14 @@
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<redaction-empty-state *ngIf="!displayedUsers.length" screen="user-listing" type="no-match"></redaction-empty-state>
|
||||
<redaction-empty-state *ngIf="!displayedEntities.length" screen="user-listing" type="no-match"></redaction-empty-state>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||
<!-- Table lines -->
|
||||
<div class="table-item" *cdkVirtualFor="let user of displayedUsers">
|
||||
<div class="pr-0" (click)="toggleUserSelected($event, user)">
|
||||
<div *ngIf="!isUserSelected(user)" class="select-oval"></div>
|
||||
<mat-icon class="selection-icon active" *ngIf="isUserSelected(user)" svgIcon="red:radio-selected"></mat-icon>
|
||||
<div class="table-item" *cdkVirtualFor="let user of displayedEntities">
|
||||
<div class="pr-0" (click)="toggleEntitySelected($event, user)">
|
||||
<div *ngIf="!isEntitySelected(user)" class="select-oval"></div>
|
||||
<mat-icon class="selection-icon active" *ngIf="isEntitySelected(user)" svgIcon="red:radio-selected"></mat-icon>
|
||||
</div>
|
||||
<div>
|
||||
<redaction-initials-avatar [user]="user" [withName]="true" [showYou]="true"></redaction-initials-avatar>
|
||||
|
||||
@ -1,53 +1,44 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, Injector, OnInit } from '@angular/core';
|
||||
import { PermissionsService } from '../../../../services/permissions.service';
|
||||
import { UserService } from '../../../../services/user.service';
|
||||
import { User, UserControllerService } from '@redaction/red-ui-http';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { debounce } from '../../../../utils/debounce';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DoughnutChartConfig } from '../../../shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
|
||||
import { TranslateChartService } from '../../../../services/translate-chart.service';
|
||||
import { BaseListingComponent } from '../../../shared/base/base-listing.component';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-user-listing-screen',
|
||||
templateUrl: './user-listing-screen.component.html',
|
||||
styleUrls: ['./user-listing-screen.component.scss']
|
||||
})
|
||||
export class UserListingScreenComponent implements OnInit {
|
||||
export class UserListingScreenComponent extends BaseListingComponent<User> implements OnInit {
|
||||
protected readonly _selectionKey = 'userId';
|
||||
|
||||
public viewReady = false;
|
||||
public loading = false;
|
||||
public collapsedDetails = false;
|
||||
public chartData: DoughnutChartConfig[] = [];
|
||||
public users: User[];
|
||||
public displayedUsers: User[] = [];
|
||||
public searchForm: FormGroup;
|
||||
public selectedUsersIds: string[] = [];
|
||||
|
||||
constructor(
|
||||
public readonly permissionsService: PermissionsService,
|
||||
public readonly userService: UserService,
|
||||
private readonly _formBuilder: FormBuilder,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _adminDialogService: AdminDialogService,
|
||||
private readonly _userControllerService: UserControllerService,
|
||||
private readonly _translateChartService: TranslateChartService
|
||||
private readonly _translateChartService: TranslateChartService,
|
||||
protected readonly _injector: Injector
|
||||
) {
|
||||
this.searchForm = this._formBuilder.group({
|
||||
query: ['']
|
||||
});
|
||||
|
||||
this.searchForm.valueChanges.subscribe(() => this._executeSearch());
|
||||
super(_injector);
|
||||
}
|
||||
|
||||
public async ngOnInit() {
|
||||
await this._loadData();
|
||||
}
|
||||
|
||||
@debounce(200)
|
||||
private _executeSearch() {
|
||||
const value = this.searchForm.get('query').value;
|
||||
this.displayedUsers = this.users.filter((user) => this.userService.getName(user).toLowerCase().includes(value.toLowerCase()));
|
||||
protected _searchField(user: any): string {
|
||||
return this.userService.getName(user);
|
||||
}
|
||||
|
||||
public openAddEditUserDialog($event: MouseEvent, user?: User) {
|
||||
@ -77,7 +68,7 @@ export class UserListingScreenComponent implements OnInit {
|
||||
}
|
||||
|
||||
private async _loadData() {
|
||||
this.users = (await this._userControllerService.getAllUsers({ requestId: new Date().toISOString() }).toPromise()).users;
|
||||
this.allEntities = (await this._userControllerService.getAllUsers({ requestId: new Date().toISOString() }).toPromise()).users;
|
||||
this._executeSearch();
|
||||
this._computeStats();
|
||||
this.viewReady = true;
|
||||
@ -88,32 +79,32 @@ export class UserListingScreenComponent implements OnInit {
|
||||
this.chartData = this._translateChartService.translateRoles(
|
||||
[
|
||||
{
|
||||
value: this.users.filter((user) => !this.userService.isActive(user)).length,
|
||||
value: this.allEntities.filter((user) => !this.userService.isActive(user)).length,
|
||||
color: 'INACTIVE',
|
||||
label: 'INACTIVE'
|
||||
},
|
||||
{
|
||||
value: this.users.filter((user) => user.roles.length === 1 && user.roles[0] === 'RED_USER').length,
|
||||
value: this.allEntities.filter((user) => user.roles.length === 1 && user.roles[0] === 'RED_USER').length,
|
||||
color: 'REGULAR',
|
||||
label: 'REGULAR'
|
||||
},
|
||||
{
|
||||
value: this.users.filter((user) => this.userService.isManager(user) && !this.userService.isAdmin(user)).length,
|
||||
value: this.allEntities.filter((user) => this.userService.isManager(user) && !this.userService.isAdmin(user)).length,
|
||||
color: 'MANAGER',
|
||||
label: 'RED_MANAGER'
|
||||
},
|
||||
{
|
||||
value: this.users.filter((user) => this.userService.isManager(user) && this.userService.isAdmin(user)).length,
|
||||
value: this.allEntities.filter((user) => this.userService.isManager(user) && this.userService.isAdmin(user)).length,
|
||||
color: 'MANAGER_ADMIN',
|
||||
label: 'MANAGER_ADMIN'
|
||||
},
|
||||
{
|
||||
value: this.users.filter((user) => this.userService.isUserAdmin(user) && !this.userService.isAdmin(user)).length,
|
||||
value: this.allEntities.filter((user) => this.userService.isUserAdmin(user) && !this.userService.isAdmin(user)).length,
|
||||
color: 'USER_ADMIN',
|
||||
label: 'RED_USER_ADMIN'
|
||||
},
|
||||
{
|
||||
value: this.users.filter((user) => this.userService.isAdmin(user) && !this.userService.isManager(user)).length,
|
||||
value: this.allEntities.filter((user) => this.userService.isAdmin(user) && !this.userService.isManager(user)).length,
|
||||
color: 'ADMIN',
|
||||
label: 'RED_ADMIN'
|
||||
}
|
||||
@ -136,41 +127,11 @@ export class UserListingScreenComponent implements OnInit {
|
||||
this.collapsedDetails = !this.collapsedDetails;
|
||||
}
|
||||
|
||||
toggleUserSelected($event: MouseEvent, user: User) {
|
||||
$event.stopPropagation();
|
||||
const idx = this.selectedUsersIds.indexOf(user.userId);
|
||||
if (idx === -1) {
|
||||
this.selectedUsersIds.push(user.userId);
|
||||
} else {
|
||||
this.selectedUsersIds.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public toggleSelectAll() {
|
||||
if (this.areSomeUsersSelected) {
|
||||
this.selectedUsersIds = [];
|
||||
} else {
|
||||
this.selectedUsersIds = this.displayedUsers.map((user) => user.userId);
|
||||
}
|
||||
}
|
||||
|
||||
public get areAllUsersSelected() {
|
||||
return this.displayedUsers.length !== 0 && this.selectedUsersIds.length === this.displayedUsers.length;
|
||||
}
|
||||
|
||||
public get areSomeUsersSelected() {
|
||||
return this.selectedUsersIds.length > 0;
|
||||
}
|
||||
|
||||
public isUserSelected(user: User) {
|
||||
return this.selectedUsersIds.indexOf(user.userId) !== -1;
|
||||
}
|
||||
|
||||
public async bulkDelete() {
|
||||
this.openDeleteUserDialog(this.users.filter((u) => this.isUserSelected(u)));
|
||||
this.openDeleteUserDialog(this.allEntities.filter((u) => this.isEntitySelected(u)));
|
||||
}
|
||||
|
||||
public get canDeleteSelected(): boolean {
|
||||
return this.selectedUsersIds.indexOf(this.userService.userId) === -1;
|
||||
return this.selectedEntitiesIds.indexOf(this.userService.userId) === -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,6 +39,10 @@ export class BaseListingComponent<T = any> {
|
||||
protected get filterComponents(): FilterComponent[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
protected _searchField(entity: T): string {
|
||||
return entity[this.searchKey];
|
||||
}
|
||||
// ----
|
||||
|
||||
constructor(protected readonly _injector: Injector) {
|
||||
@ -82,9 +86,11 @@ export class BaseListingComponent<T = any> {
|
||||
@debounce(200)
|
||||
protected _executeSearch() {
|
||||
this.displayedEntities = (this.filters.length ? this.filteredEntities : this.allEntities).filter((entity) =>
|
||||
entity[this.searchKey].toLowerCase().includes(this.searchForm.get('query').value.toLowerCase())
|
||||
this._searchField(entity).toLowerCase().includes(this.searchForm.get('query').value.toLowerCase())
|
||||
);
|
||||
this.selectedEntitiesIds = this.displayedEntities.map((entity) => entity[this.selectionKey]).filter((id) => this.selectedEntitiesIds.includes(id));
|
||||
if (this._selectionKey) {
|
||||
this.selectedEntitiesIds = this.displayedEntities.map((entity) => entity[this.selectionKey]).filter((id) => this.selectedEntitiesIds.includes(id));
|
||||
}
|
||||
}
|
||||
|
||||
// Filter
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user