fixed doughnut charts
This commit is contained in:
parent
2b3638a97d
commit
860cc91abc
@ -22,7 +22,6 @@ import { DICTIONARY_TYPE, DOSSIER_TEMPLATE_ID } from '@utils/constants';
|
||||
import { DossierTemplateExistsGuard } from '../../guards/dossier-template-exists.guard';
|
||||
import { DictionaryExistsGuard } from '../../guards/dictionary-exists.guard';
|
||||
import { DossierStatesListingScreenComponent } from './screens/dossier-states-listing/dossier-states-listing-screen.component';
|
||||
import { DossiersGuard } from '../../guards/dossiers.guard';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', redirectTo: 'dossier-templates', pathMatch: 'full' },
|
||||
@ -121,7 +120,7 @@ const routes: Routes = [
|
||||
component: DossierStatesListingScreenComponent,
|
||||
canActivate: [CompositeRouteGuard],
|
||||
data: {
|
||||
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard, DossiersGuard],
|
||||
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button (click)="dialogRef.close(replaceDossierStatusId)" [disabled]="!replaceDossierStatusId" mat-flat-button>
|
||||
<button (click)="dialogRef.close(replaceDossierStatusId)" color="primary" [disabled]="!replaceDossierStatusId" mat-flat-button>
|
||||
{{ 'confirm-delete-dossier-state.delete-replace' | translate }}
|
||||
</button>
|
||||
<div (click)="dialogRef.close()" [translate]="'confirm-delete-dossier-state.cancel'" class="all-caps-label cancel"></div>
|
||||
|
||||
@ -1,94 +1,98 @@
|
||||
<section>
|
||||
<div class="page-header">
|
||||
<redaction-dossier-template-breadcrumbs class="flex-1"></redaction-dossier-template-breadcrumbs>
|
||||
<ng-container *ngIf="dossierStateService.all">
|
||||
<section>
|
||||
<div class="page-header">
|
||||
<redaction-dossier-template-breadcrumbs class="flex-1"></redaction-dossier-template-breadcrumbs>
|
||||
|
||||
<div class="actions flex-1">
|
||||
<redaction-dossier-template-actions></redaction-dossier-template-actions>
|
||||
<div class="actions flex-1">
|
||||
<redaction-dossier-template-actions></redaction-dossier-template-actions>
|
||||
|
||||
<iqser-circle-button
|
||||
[routerLink]="['../..']"
|
||||
[tooltip]="'common.close' | translate"
|
||||
icon="iqser:close"
|
||||
tooltipPosition="below"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-inner">
|
||||
<div class="overlay-shadow"></div>
|
||||
|
||||
<redaction-admin-side-nav type="dossierTemplates"></redaction-admin-side-nav>
|
||||
|
||||
<div class="content-container">
|
||||
<iqser-table
|
||||
[headerTemplate]="headerTemplate"
|
||||
[itemSize]="80"
|
||||
[noDataText]="'dossier-states-listing.no-data.title' | translate"
|
||||
[noMatchText]="'dossier-states-listing.no-match.title' | translate"
|
||||
[selectionEnabled]="true"
|
||||
[tableColumnConfigs]="tableColumnConfigs"
|
||||
emptyColumnWidth="1fr"
|
||||
noDataIcon="red:attribute"
|
||||
></iqser-table>
|
||||
</div>
|
||||
|
||||
<div class="right-container">
|
||||
<redaction-simple-doughnut-chart
|
||||
[config]="chartData"
|
||||
[radius]="80"
|
||||
[strokeWidth]="15"
|
||||
[subtitle]="'dossier-states-listing.chart.dossier-states' | translate"
|
||||
[totalType]="'simpleLabel'"
|
||||
></redaction-simple-doughnut-chart>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ng-template #headerTemplate>
|
||||
<div class="table-header-actions">
|
||||
<iqser-input-with-action
|
||||
[(value)]="searchService.searchValue"
|
||||
[placeholder]="'dossier-states-listing.search' | translate"
|
||||
></iqser-input-with-action>
|
||||
|
||||
<iqser-icon-button
|
||||
(action)="openAddEditStateDialog($event)"
|
||||
*ngIf="currentUser.isAdmin"
|
||||
[label]="'dossier-states-listing.add-new' | translate"
|
||||
[type]="iconButtonTypes.primary"
|
||||
icon="iqser:plus"
|
||||
></iqser-icon-button>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #tableItemTemplate let-entity="entity">
|
||||
<div *ngIf="cast(entity) as state">
|
||||
<div class="cell">
|
||||
<div class="flex-align-items-center">
|
||||
<div [style.background-color]="state.description" class="dossier-state-square"></div>
|
||||
<div class="state-name">{{ state.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cell small-label">
|
||||
<span>{{ state.dossierCount }}</span>
|
||||
</div>
|
||||
|
||||
<div class="cell">
|
||||
<div *ngIf="currentUser.isAdmin" class="action-buttons">
|
||||
<iqser-circle-button
|
||||
(action)="openAddEditStateDialog($event, state)"
|
||||
[tooltip]="'dossier-states-listing.action.edit' | translate"
|
||||
[type]="circleButtonTypes.dark"
|
||||
icon="iqser:edit"
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="openConfirmDeleteStateDialog($event, state)"
|
||||
[tooltip]="'dossier-states-listing.action.delete' | translate"
|
||||
[type]="circleButtonTypes.dark"
|
||||
icon="iqser:trash"
|
||||
[routerLink]="['../..']"
|
||||
[tooltip]="'common.close' | translate"
|
||||
icon="iqser:close"
|
||||
tooltipPosition="below"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<div class="content-inner">
|
||||
<div class="overlay-shadow"></div>
|
||||
|
||||
<redaction-admin-side-nav type="dossierTemplates"></redaction-admin-side-nav>
|
||||
|
||||
<div class="content-container">
|
||||
<iqser-table
|
||||
[headerTemplate]="headerTemplate"
|
||||
[itemSize]="80"
|
||||
[noDataText]="'dossier-states-listing.no-data.title' | translate"
|
||||
[noMatchText]="'dossier-states-listing.no-match.title' | translate"
|
||||
[selectionEnabled]="true"
|
||||
[tableColumnConfigs]="tableColumnConfigs"
|
||||
emptyColumnWidth="1fr"
|
||||
noDataIcon="red:attribute"
|
||||
></iqser-table>
|
||||
</div>
|
||||
|
||||
<div class="right-container">
|
||||
<ng-container *ngIf="chartData">
|
||||
<redaction-simple-doughnut-chart
|
||||
[config]="chartData"
|
||||
[radius]="80"
|
||||
[strokeWidth]="15"
|
||||
[subtitle]="'dossier-states-listing.chart.dossier-states' | translate"
|
||||
[totalType]="'simpleLabel'"
|
||||
></redaction-simple-doughnut-chart>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ng-template #headerTemplate>
|
||||
<div class="table-header-actions">
|
||||
<iqser-input-with-action
|
||||
[(value)]="searchService.searchValue"
|
||||
[placeholder]="'dossier-states-listing.search' | translate"
|
||||
></iqser-input-with-action>
|
||||
|
||||
<iqser-icon-button
|
||||
(action)="openAddEditStateDialog($event)"
|
||||
*ngIf="currentUser.isAdmin"
|
||||
[label]="'dossier-states-listing.add-new' | translate"
|
||||
[type]="iconButtonTypes.primary"
|
||||
icon="iqser:plus"
|
||||
></iqser-icon-button>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #tableItemTemplate let-entity="entity">
|
||||
<div *ngIf="cast(entity) as state">
|
||||
<div class="cell">
|
||||
<div class="flex-align-items-center">
|
||||
<div [style.background-color]="state.description" class="dossier-state-square"></div>
|
||||
<div class="state-name">{{ state.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cell small-label">
|
||||
<span>{{ state.dossierCount }}</span>
|
||||
</div>
|
||||
|
||||
<div class="cell">
|
||||
<div *ngIf="currentUser.isAdmin" class="action-buttons">
|
||||
<iqser-circle-button
|
||||
(action)="openAddEditStateDialog($event, state)"
|
||||
[tooltip]="'dossier-states-listing.action.edit' | translate"
|
||||
[type]="circleButtonTypes.dark"
|
||||
icon="iqser:edit"
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="openConfirmDeleteStateDialog($event, state)"
|
||||
[tooltip]="'dossier-states-listing.action.delete' | translate"
|
||||
[type]="circleButtonTypes.dark"
|
||||
icon="iqser:trash"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
|
||||
@ -44,7 +44,7 @@ export class DossierStatesListingScreenComponent extends ListingComponent<Dossie
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
private readonly _dossierStateService: DossierStateService,
|
||||
readonly dossierStateService: DossierStateService,
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
private readonly _dialogService: AdminDialogService,
|
||||
private readonly _userService: UserService,
|
||||
@ -77,38 +77,34 @@ export class DossierStatesListingScreenComponent extends ListingComponent<Dossie
|
||||
};
|
||||
this._dialogService.openDialog('deleteDossierState', $event, data, async (value: string) => {
|
||||
if (value) {
|
||||
await firstValueFrom(this._dossierStateService.deleteAndReplace(dossierState.dossierStatusId, value));
|
||||
await firstValueFrom(this.dossierStateService.deleteAndReplace(dossierState.dossierStatusId, value));
|
||||
}
|
||||
|
||||
await firstValueFrom(this._dossierStateService.loadAllForAllTemplates());
|
||||
await this._appStateService.refreshDossierTemplate(templateId);
|
||||
await this._loadData();
|
||||
});
|
||||
}
|
||||
|
||||
private async _createNewDossierStateAndRefreshView(newValue: IDossierState): Promise<void> {
|
||||
await firstValueFrom(this._dossierStateService.setDossierState(newValue)).catch(error => {
|
||||
await firstValueFrom(this.dossierStateService.setDossierState(newValue)).catch(error => {
|
||||
if (error.status === HttpStatusCode.Conflict) {
|
||||
this._toaster.error(_('dossier-states-listing.error.conflict'));
|
||||
} else {
|
||||
this._toaster.error(_('dossier-states-listing.error.generic'));
|
||||
}
|
||||
});
|
||||
await firstValueFrom(this._dossierStateService.loadAllForAllTemplates());
|
||||
await this._appStateService.refreshDossierTemplate(this._dossierTemplatesService.activeDossierTemplateId);
|
||||
await this._loadData();
|
||||
}
|
||||
|
||||
private async _loadData() {
|
||||
private async _loadData(): Promise<void> {
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(this._dossiersService.loadAll());
|
||||
|
||||
try {
|
||||
const templateId = this._dossierTemplatesService.activeDossierTemplateId;
|
||||
const dossierStates = this._dossierStateService.all.filter(d => d.dossierTemplateId === templateId);
|
||||
const dossiers = this._dossiersService.all;
|
||||
this._dossierStateService.all.forEach(
|
||||
state => (state.dossierCount = dossiers.filter(dossier => dossier.dossierStatusId === state.dossierStatusId).length),
|
||||
);
|
||||
const dossierStates = this.dossierStateService.all.filter(d => d.dossierTemplateId === templateId);
|
||||
this._setStatesCount();
|
||||
this.chartData = this._loadChartData();
|
||||
this.entitiesService.setEntities(dossierStates || []);
|
||||
} catch (e) {}
|
||||
@ -117,10 +113,16 @@ export class DossierStatesListingScreenComponent extends ListingComponent<Dossie
|
||||
|
||||
private _loadChartData(): DoughnutChartConfig[] {
|
||||
const config: DoughnutChartConfig[] = [];
|
||||
this._dossierStateService.all.forEach(state => {
|
||||
this.dossierStateService.all.forEach(state => {
|
||||
config.push({ value: state.dossierCount, label: state.name, key: state.name, color: state.description });
|
||||
});
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
private _setStatesCount(): void {
|
||||
this.dossierStateService.all.forEach(
|
||||
state => (state.dossierCount = this._dossiersService.getCountWithState(state.dossierStatusId)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,7 +57,9 @@
|
||||
<label translate="edit-dossier-dialog.general-info.form.dossier-status.label"></label>
|
||||
<mat-select
|
||||
[placeholder]="
|
||||
currentStatus ? currentStatus.name : ('edit-dossier-dialog.general-info.form.dossier-status.label' | translate)
|
||||
currentStatus
|
||||
? currentStatus.name
|
||||
: ('edit-dossier-dialog.general-info.form.dossier-status.placeholder' | translate)
|
||||
"
|
||||
formControlName="dossierStatusId"
|
||||
>
|
||||
|
||||
@ -7,8 +7,9 @@ import { Dossier, DossierStats, FileCountPerWorkflowStatus, StatusSorter } from
|
||||
import { workflowFileStatusTranslations } from '../../../../translations/file-status-translations';
|
||||
import { TranslateChartService } from '@services/translate-chart.service';
|
||||
import { filter, map, switchMap } from 'rxjs/operators';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { DossierStatsService } from '@services/entity-services/dossier-stats.service';
|
||||
import { DossierStateService } from '../../../../../../services/entity-services/dossier-state.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dossiers-listing-details',
|
||||
@ -25,6 +26,8 @@ export class DossiersListingDetailsComponent {
|
||||
readonly dossiersService: DossiersService,
|
||||
private readonly _dossierStatsMap: DossierStatsService,
|
||||
private readonly _translateChartService: TranslateChartService,
|
||||
private readonly _dossierStateService: DossierStateService,
|
||||
private readonly _translateService: TranslateService,
|
||||
) {
|
||||
this.documentsChartData$ = this.dossiersService.all$.pipe(
|
||||
mapEach(dossier => _dossierStatsMap.watch$(dossier.dossierId)),
|
||||
@ -37,12 +40,19 @@ export class DossiersListingDetailsComponent {
|
||||
}
|
||||
|
||||
private async _toDossierChartData(dossiers: Dossier[]): Promise<DoughnutChartConfig[]> {
|
||||
const config: DoughnutChartConfig[] = [];
|
||||
this._dossierStateService.all.forEach(state => {
|
||||
state.dossierCount = this.dossiersService.getCountWithState(state.dossierStatusId);
|
||||
config.push({ value: state.dossierCount, label: state.name, color: state.description });
|
||||
});
|
||||
const notAssignedLength = this.dossiersService.all.length - config.map(v => v.value).reduce((acc, val) => acc + val, 0);
|
||||
config.push({
|
||||
value: notAssignedLength,
|
||||
label: this._translateService.instant('edit-dossier-dialog.general-info.form.dossier-status.placeholder'),
|
||||
color: '#D8DAE0',
|
||||
});
|
||||
// TODO: deleted dossiers count should come with stats
|
||||
// const deletedDossiers = await this.dossiersService.getDeleted();
|
||||
return [
|
||||
{ value: dossiers.length, color: 'ACTIVE', label: _('active') },
|
||||
// { value: deletedDossiers.length, color: 'DELETED', label: _('archived') },
|
||||
];
|
||||
return config;
|
||||
}
|
||||
|
||||
private _toChartData(stats: DossierStats[]) {
|
||||
|
||||
@ -51,7 +51,7 @@ export class SimpleDoughnutChartComponent implements OnChanges, OnInit {
|
||||
}
|
||||
|
||||
get displayedDataTotal() {
|
||||
return this.totalType === 'count' ? this.config.length : this.dataTotal;
|
||||
return this.totalType === 'sum' ? this.dataTotal : this.config.length;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
@ -62,7 +62,17 @@ export class DossiersService extends EntitiesService<Dossier, IDossier> {
|
||||
}
|
||||
|
||||
loadAllIfChanged(): Observable<ChangesDetails> {
|
||||
return this.hasChangesDetails$().pipe(switchMap(changes => this.loadAll().pipe(mapTo(changes))));
|
||||
return this.hasChangesDetails$().pipe(
|
||||
catchError(err => {
|
||||
console.log('aaa', err);
|
||||
return of(err);
|
||||
}),
|
||||
switchMap(changes => this.loadAll().pipe(mapTo(changes))),
|
||||
catchError(err => {
|
||||
console.log('bbb', err);
|
||||
return of(err);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
hasChangesDetails$(): Observable<ChangesDetails> {
|
||||
@ -111,6 +121,10 @@ export class DossiersService extends EntitiesService<Dossier, IDossier> {
|
||||
return firstValueFrom(super.delete(body, 'deleted-dossiers/hard-delete', body));
|
||||
}
|
||||
|
||||
getCountWithState(dossierStatusId: string): number {
|
||||
return this.all.filter(dossier => dossier.dossierStatusId === dossierStatusId).length;
|
||||
}
|
||||
|
||||
private _emitFileChanges(changes: ChangesDetails): void {
|
||||
changes.dossierChanges.filter(change => change.fileChanges).forEach(change => this.dossierFileChanges$.next(change.dossierId));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user