RED-2544: User management filters
This commit is contained in:
parent
fa3125302f
commit
b95410f6fd
@ -25,6 +25,7 @@
|
||||
[strokeWidth]="15"
|
||||
[subtitle]="'user-stats.chart.users' | translate"
|
||||
direction="row"
|
||||
filterKey="roleFilters"
|
||||
totalType="sum"
|
||||
></redaction-simple-doughnut-chart>
|
||||
</div>
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
IconButtonTypes,
|
||||
ListingComponent,
|
||||
LoadingService,
|
||||
NestedFilter,
|
||||
TableColumnConfig,
|
||||
} from '@iqser/common-ui';
|
||||
import { Observable } from 'rxjs';
|
||||
@ -18,6 +19,7 @@ import { map } from 'rxjs/operators';
|
||||
import { rolesTranslations } from '../../../../translations/roles-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { User } from '@red/domain';
|
||||
import { userTypeChecker, userTypeFilters, UserTypes } from '../../../../utils';
|
||||
|
||||
@Component({
|
||||
templateUrl: './user-listing-screen.component.html',
|
||||
@ -110,38 +112,30 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
|
||||
|
||||
private _computeStats() {
|
||||
this.chartData = this._translateChartService.translateRoles(
|
||||
[
|
||||
{
|
||||
value: this.allEntities.filter(user => !user.isActive).length,
|
||||
color: 'INACTIVE',
|
||||
label: 'INACTIVE',
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(user => user.roles.length === 1 && user.roles[0] === 'RED_USER').length,
|
||||
color: 'REGULAR',
|
||||
label: 'REGULAR',
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(user => user.isManager && !user.isAdmin).length,
|
||||
color: 'MANAGER',
|
||||
label: 'RED_MANAGER',
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(user => user.isManager && user.isAdmin).length,
|
||||
color: 'MANAGER_ADMIN',
|
||||
label: 'MANAGER_ADMIN',
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(user => user.isUserAdmin && !user.isAdmin).length,
|
||||
color: 'USER_ADMIN',
|
||||
label: 'RED_USER_ADMIN',
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(user => user.isAdmin && !user.isManager).length,
|
||||
color: 'ADMIN',
|
||||
label: 'RED_ADMIN',
|
||||
},
|
||||
].filter(type => type.value > 0),
|
||||
UserTypes.map(type => ({
|
||||
value: this.allEntities.filter(userTypeFilters[type]).length,
|
||||
color: type.replace('RED_', ''),
|
||||
label: type,
|
||||
key: type,
|
||||
})).filter(type => type.value > 0),
|
||||
);
|
||||
|
||||
this._computeAllFilters();
|
||||
}
|
||||
|
||||
private _computeAllFilters() {
|
||||
const roleFilters = this.chartData.map(
|
||||
config =>
|
||||
new NestedFilter({
|
||||
id: config.key,
|
||||
label: config.label,
|
||||
}),
|
||||
);
|
||||
|
||||
this.filterService.addFilterGroup({
|
||||
slug: 'roleFilters',
|
||||
filters: roleFilters,
|
||||
checker: userTypeChecker,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Component, Input, OnChanges } from '@angular/core';
|
||||
import { Component, Input, OnChanges, OnInit } from '@angular/core';
|
||||
import { Color } from '@utils/types';
|
||||
import { FilterService } from '@iqser/common-ui';
|
||||
import { FilterService, INestedFilter } from '@iqser/common-ui';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@ -12,14 +12,12 @@ export interface DoughnutChartConfig {
|
||||
active?: boolean;
|
||||
}
|
||||
|
||||
const FILTER_KEY = 'statusFilters';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-simple-doughnut-chart',
|
||||
templateUrl: './simple-doughnut-chart.component.html',
|
||||
styleUrls: ['./simple-doughnut-chart.component.scss'],
|
||||
})
|
||||
export class SimpleDoughnutChartComponent implements OnChanges {
|
||||
export class SimpleDoughnutChartComponent implements OnChanges, OnInit {
|
||||
@Input() subtitle: string;
|
||||
@Input() config: DoughnutChartConfig[] = [];
|
||||
@Input() radius = 85;
|
||||
@ -27,7 +25,8 @@ export class SimpleDoughnutChartComponent implements OnChanges {
|
||||
@Input() direction: 'row' | 'column' = 'column';
|
||||
@Input() totalType: 'sum' | 'count' = 'sum';
|
||||
@Input() counterText: string;
|
||||
readonly filtersEnabled: boolean;
|
||||
@Input() filterKey = 'statusFilters';
|
||||
filtersEnabled: boolean;
|
||||
|
||||
chartData: any[] = [];
|
||||
perimeter: number;
|
||||
@ -35,10 +34,12 @@ export class SimpleDoughnutChartComponent implements OnChanges {
|
||||
cy = 0;
|
||||
size = 0;
|
||||
|
||||
readonly statusFilters$ = this.filterService.getFilterModels$(FILTER_KEY) ?? of([]);
|
||||
filters$: Observable<INestedFilter[]>;
|
||||
|
||||
constructor(readonly filterService: FilterService) {
|
||||
this.filtersEnabled = !!this.filterService.filterGroups.find(g => g.slug === FILTER_KEY);
|
||||
this.filterService.filterGroups$.subscribe(() => {
|
||||
this.filtersEnabled = !!this.filterService.filterGroups.find(g => g.slug === this.filterKey);
|
||||
});
|
||||
}
|
||||
|
||||
get circumference(): number {
|
||||
@ -53,6 +54,10 @@ export class SimpleDoughnutChartComponent implements OnChanges {
|
||||
return this.totalType === 'sum' ? this.dataTotal : this.config.length;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.filters$ = this.filterService.getFilterModels$(this.filterKey) ?? of([]);
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
this.calculateChartData();
|
||||
this.cx = this.radius + this.strokeWidth / 2;
|
||||
@ -61,7 +66,7 @@ export class SimpleDoughnutChartComponent implements OnChanges {
|
||||
}
|
||||
|
||||
filterChecked$(key: string): Observable<boolean> {
|
||||
return this.statusFilters$.pipe(map(all => all?.find(e => e.id === key)?.checked));
|
||||
return this.filters$.pipe(map(all => all?.find(e => e.id === key)?.checked));
|
||||
}
|
||||
|
||||
calculateChartData() {
|
||||
@ -96,7 +101,7 @@ export class SimpleDoughnutChartComponent implements OnChanges {
|
||||
|
||||
selectValue(key: string): void {
|
||||
if (this.filtersEnabled) {
|
||||
this.filterService.toggleFilter(FILTER_KEY, key);
|
||||
this.filterService.toggleFilter(this.filterKey, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { File } from '@models/file/file';
|
||||
import { Dossier } from '@red/domain';
|
||||
import { Dossier, User } from '@red/domain';
|
||||
import { handleCheckedValue, INestedFilter } from '@iqser/common-ui';
|
||||
|
||||
export function handleFilterDelta(oldFilters: INestedFilter[], newFilters: INestedFilter[], allFilters: INestedFilter[]) {
|
||||
@ -85,3 +85,17 @@ export const dossierMemberChecker = (dw: Dossier, filter: INestedFilter) => dw.h
|
||||
export const dossierTemplateChecker = (dw: Dossier, filter: INestedFilter) => dw.dossierTemplateId === filter.id;
|
||||
|
||||
export const dossierApproverChecker = (dw: Dossier, filter: INestedFilter) => dw.approverIds.includes(filter.id);
|
||||
|
||||
export const UserTypes = ['INACTIVE', 'REGULAR', 'RED_MANAGER', 'MANAGER_ADMIN', 'RED_USER_ADMIN', 'RED_ADMIN'] as const;
|
||||
export type UserType = typeof UserTypes[number];
|
||||
|
||||
export const userTypeFilters: { [key in UserType]: (user: User) => boolean } = {
|
||||
INACTIVE: (user: User) => !user.isActive,
|
||||
REGULAR: (user: User) => user.roles.length === 1 && user.roles[0] === 'RED_USER',
|
||||
RED_MANAGER: (user: User) => user.isManager && !user.isAdmin,
|
||||
MANAGER_ADMIN: (user: User) => user.isManager && user.isAdmin,
|
||||
RED_USER_ADMIN: (user: User) => user.isUserAdmin && !user.isAdmin,
|
||||
RED_ADMIN: (user: User) => user.isAdmin && !user.isManager,
|
||||
};
|
||||
|
||||
export const userTypeChecker = (user: User, filter: INestedFilter) => userTypeFilters[filter.id](user);
|
||||
|
||||
@ -23,7 +23,7 @@ export class User implements IUser, IListable {
|
||||
this.firstName = user.firstName;
|
||||
this.lastName = user.lastName;
|
||||
this.name = this.firstName && this.lastName ? `${this.firstName} ${this.lastName}` : this.username;
|
||||
this.searchKey = `${this.name}${this.username}${this.email}`;
|
||||
this.searchKey = `${this.name || '-'}${this.username || '-'}${this.email || ''}`;
|
||||
}
|
||||
|
||||
hasRole(role: string): boolean {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user