Filters in project overview
This commit is contained in:
parent
b03607dd1f
commit
b60b5154fc
@ -9,24 +9,36 @@
|
||||
<div *ngIf="appStateService.activeProject" class="page-header">
|
||||
<div class="filters flex-row">
|
||||
<div translate="filters.filter-by.label"></div>
|
||||
<button mat-button translate="filters.status.label">
|
||||
<mat-icon svgIcon="red:status"></mat-icon>
|
||||
</button>
|
||||
<button mat-button translate="filters.people.label">
|
||||
<mat-icon svgIcon="red:user"></mat-icon>
|
||||
</button>
|
||||
<button mat-button translate="filters.due-date.label">
|
||||
<mat-icon svgIcon="red:lightning"></mat-icon>
|
||||
</button>
|
||||
<button mat-button translate="filters.created-on.label">
|
||||
<mat-icon svgIcon="red:calendar"></mat-icon>
|
||||
</button>
|
||||
<button mat-button translate="filters.project.label">
|
||||
<mat-icon svgIcon="red:folder"></mat-icon>
|
||||
</button>
|
||||
<button mat-button translate="filters.document.label">
|
||||
<mat-icon svgIcon="red:document"></mat-icon>
|
||||
</button>
|
||||
<redaction-filter
|
||||
[filters]="statusFilters"
|
||||
[filterLabel]="'filters.status.label'"
|
||||
[hasArrow]="false"
|
||||
[icon]="'red:status'"
|
||||
(filtersChanged)="filtersChanged()"
|
||||
></redaction-filter>
|
||||
<redaction-filter
|
||||
[filters]="peopleFilters"
|
||||
[filterLabel]="'filters.people.label'"
|
||||
[hasArrow]="false"
|
||||
[icon]="'red:user'"
|
||||
(filtersChanged)="filtersChanged()"
|
||||
></redaction-filter>
|
||||
<!-- <button mat-button translate="filters.due-date.label">-->
|
||||
<!-- <mat-icon svgIcon="red:lightning"></mat-icon>-->
|
||||
<!-- </button>-->
|
||||
<redaction-filter
|
||||
[filters]="addedDateFilters"
|
||||
[filterLabel]="'filters.created-on.label'"
|
||||
[hasArrow]="false"
|
||||
[icon]="'red:calendar'"
|
||||
(filtersChanged)="filtersChanged()"
|
||||
></redaction-filter>
|
||||
<!-- <button mat-button translate="filters.project.label">-->
|
||||
<!-- <mat-icon svgIcon="red:folder"></mat-icon>-->
|
||||
<!-- </button>-->
|
||||
<!-- <button mat-button translate="filters.document.label">-->
|
||||
<!-- <mat-icon svgIcon="red:document"></mat-icon>-->
|
||||
<!-- </button>-->
|
||||
</div>
|
||||
<button
|
||||
(click)="fileInput.click()"
|
||||
@ -127,11 +139,17 @@
|
||||
></span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
*ngIf="displayedFiles?.length === 0"
|
||||
class="no-data"
|
||||
translate="project-overview.no-files.label"
|
||||
></div>
|
||||
|
||||
<div
|
||||
class="table-item"
|
||||
[class.pointer]="canOpenFile(fileStatus)"
|
||||
*ngFor="
|
||||
let fileStatus of appStateService.activeProject.files
|
||||
let fileStatus of displayedFiles
|
||||
| sortBy: sortingOption.order:sortingOption.column;
|
||||
trackBy: fileId
|
||||
"
|
||||
|
||||
@ -15,10 +15,12 @@ import { UploadStatusOverlayService } from '../../upload/upload-status-dialog/se
|
||||
import { UserService } from '../../user/user.service';
|
||||
import { SortingOption } from '../../utils/types';
|
||||
import { DoughnutChartConfig } from '../../components/simple-doughnut-chart/simple-doughnut-chart.component';
|
||||
import { groupBy } from '../../utils/functions';
|
||||
import { groupBy, humanize } from '../../utils/functions';
|
||||
import { DialogService } from '../../dialogs/dialog.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { FileActionService } from '../file/service/file-action.service';
|
||||
import { FilterModel } from '../../common/filter/model/filter.model';
|
||||
import * as moment from 'moment';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-project-overview-screen',
|
||||
@ -51,6 +53,12 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
public documentsChartData: DoughnutChartConfig[] = [];
|
||||
public bulkSelectActive = false;
|
||||
|
||||
public statusFilters: FilterModel[];
|
||||
public peopleFilters: FilterModel[];
|
||||
public addedDateFilters: FilterModel[];
|
||||
|
||||
public displayedFiles: FileStatus[] = [];
|
||||
|
||||
constructor(
|
||||
public readonly appStateService: AppStateService,
|
||||
public readonly userService: UserService,
|
||||
@ -72,13 +80,13 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
|
||||
this.appStateService.fileStatusChanged.subscribe(() => {
|
||||
this._calculateChartConfig();
|
||||
this._calculateData();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this._fileDropOverlayService.initFileDropHandling();
|
||||
this._calculateChartConfig();
|
||||
this._calculateData();
|
||||
this._displayNewRuleToast();
|
||||
}
|
||||
|
||||
@ -162,10 +170,16 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
|
||||
private _reloadProjects() {
|
||||
this.appStateService.loadAllProjects().then(() => {
|
||||
this._calculateChartConfig();
|
||||
this._calculateData();
|
||||
});
|
||||
}
|
||||
|
||||
private _calculateData(): void {
|
||||
this._computeAllFilters();
|
||||
this._filterFiles();
|
||||
this._calculateChartConfig();
|
||||
}
|
||||
|
||||
private _calculateChartConfig() {
|
||||
if (this.appStateService.activeProject) {
|
||||
const groups = groupBy(this.appStateService.activeProject?.files, 'status');
|
||||
@ -213,7 +227,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
fileStatus.projectId,
|
||||
fileStatus.fileId,
|
||||
() => {
|
||||
this._calculateChartConfig();
|
||||
this._calculateData();
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -284,6 +298,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
this._fileUploadService.uploadFiles(uploadFiles);
|
||||
this._uploadStatusOverlayService.openStatusOverlay();
|
||||
}
|
||||
|
||||
public canOpenFile(fileStatus: FileStatus): boolean {
|
||||
// TODO check correct condition for this
|
||||
return !this.isError(fileStatus) && !this.isProcessing(fileStatus);
|
||||
@ -293,4 +308,99 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
const sortedByRecent: boolean = this.sortingOption === this.sortingOptions[0];
|
||||
this.sortingOption = sortedByRecent ? this.sortingOptions[1] : this.sortingOptions[0];
|
||||
}
|
||||
|
||||
private _computeAllFilters() {
|
||||
const allDistinctFileStatus = new Set<string>();
|
||||
const allDistinctPeople = new Set<string>();
|
||||
const allDistinctAddedDates = new Set<string>();
|
||||
|
||||
// All people
|
||||
this.appStateService.activeProject.project.memberIds.forEach((memberId) =>
|
||||
allDistinctPeople.add(memberId)
|
||||
);
|
||||
|
||||
// File statuses
|
||||
this.appStateService.activeProject.files.forEach((file) =>
|
||||
allDistinctFileStatus.add(file.status)
|
||||
);
|
||||
|
||||
// Added dates
|
||||
this.appStateService.activeProject.files.forEach((file) =>
|
||||
allDistinctAddedDates.add(moment(file.added).format('DD/MM/YYYY'))
|
||||
);
|
||||
|
||||
this.statusFilters = [];
|
||||
allDistinctFileStatus.forEach((status) => {
|
||||
this.statusFilters.push({
|
||||
key: status,
|
||||
label: humanize(status)
|
||||
});
|
||||
});
|
||||
|
||||
this.peopleFilters = [];
|
||||
allDistinctPeople.forEach((userId) => {
|
||||
this.peopleFilters.push({
|
||||
key: userId,
|
||||
label: this.userService.getNameForId(userId)
|
||||
});
|
||||
});
|
||||
|
||||
this.addedDateFilters = [];
|
||||
allDistinctAddedDates.forEach((date) => {
|
||||
this.addedDateFilters.push({
|
||||
key: date,
|
||||
label: date
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
filtersChanged() {
|
||||
this._filterFiles();
|
||||
}
|
||||
|
||||
private _filterFiles() {
|
||||
const filteredFiles = [];
|
||||
|
||||
for (const file of this.appStateService.activeProject.files) {
|
||||
const statusFilterMatched = this._checkFilter(
|
||||
file,
|
||||
this.statusFilters,
|
||||
(file: FileStatus, filter: FilterModel) => file.status === filter.key
|
||||
);
|
||||
|
||||
const peopleFilterMatched = this._checkFilter(
|
||||
file,
|
||||
this.peopleFilters,
|
||||
(file: FileStatus, filter: FilterModel) => file.currentReviewer === filter.key
|
||||
);
|
||||
|
||||
const addedFilterMatched = this._checkFilter(
|
||||
file,
|
||||
this.peopleFilters,
|
||||
(file: FileStatus, filter: FilterModel) =>
|
||||
moment(file.added).format('DD/MM/YYYY') === filter.key
|
||||
);
|
||||
|
||||
if (statusFilterMatched && peopleFilterMatched && addedFilterMatched) {
|
||||
filteredFiles.push(file);
|
||||
}
|
||||
}
|
||||
|
||||
this.displayedFiles = filteredFiles;
|
||||
}
|
||||
|
||||
private _checkFilter(file: FileStatus, filters: FilterModel[], validate: Function) {
|
||||
const hasChecked = filters.find((f) => f.checked);
|
||||
if (!hasChecked) {
|
||||
return true;
|
||||
}
|
||||
let filterMatched = false;
|
||||
for (const filter of filters) {
|
||||
if (filter.checked && validate(file, filter)) {
|
||||
filterMatched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return filterMatched;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user