Pull request #32: Filters
Merge in RED/ui from filters to master * commit '5fa011822c2cf0b18e3390fce3ff29f7e12c3534': Fixed styling Link filters on project listing Project listing details component Doughnut chart filters Fixed filter linking Minor UI improvements Filename tooltip position Link needs work filters with project details
This commit is contained in:
commit
8cf51e6014
@ -73,6 +73,7 @@ import { PageIndicatorComponent } from './screens/file/page-indicator/page-indic
|
||||
import { NeedsWorkBadgeComponent } from './screens/common/needs-work-badge/needs-work-badge.component';
|
||||
import { ProjectOverviewEmptyComponent } from './screens/empty-states/project-overview-empty/project-overview-empty.component';
|
||||
import { ProjectListingEmptyComponent } from './screens/empty-states/project-listing-empty/project-listing-empty.component';
|
||||
import { ProjectListingDetailsComponent } from './screens/project-listing-screen/project-listing-details/project-listing-details.component';
|
||||
|
||||
export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
|
||||
@ -111,7 +112,8 @@ export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
PageIndicatorComponent,
|
||||
NeedsWorkBadgeComponent,
|
||||
ProjectOverviewEmptyComponent,
|
||||
ProjectListingEmptyComponent
|
||||
ProjectListingEmptyComponent,
|
||||
ProjectListingDetailsComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { FilterModel } from '../model/filter.model';
|
||||
import { FileStatusWrapper } from '../../../screens/file/model/file-status.wrapper';
|
||||
import * as moment from 'moment';
|
||||
import { ProjectWrapper } from '../../../state/app-state.service';
|
||||
|
||||
export const RedactionFilterSorter = {
|
||||
@ -57,9 +56,6 @@ export const annotationFilterChecker = (f: FileStatusWrapper, filter: FilterMode
|
||||
return f[getter];
|
||||
};
|
||||
|
||||
export const fileAddedFilterChecker = (f: FileStatusWrapper, filter: FilterModel) =>
|
||||
moment(f.added).format('DD/MM/YYYY') === filter.key;
|
||||
|
||||
export const projectStatusChecker = (pw: ProjectWrapper, filter: FilterModel) =>
|
||||
pw.hasStatus(filter.key);
|
||||
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
<div [matTooltipPosition]="'above'" [matTooltip]="username" class="flex-row">
|
||||
<div [className]="colorClass + ' oval ' + size">{{ initials }}</div>
|
||||
<div class="flex-row">
|
||||
<div
|
||||
[className]="colorClass + ' oval ' + size"
|
||||
[matTooltipPosition]="'above'"
|
||||
[matTooltip]="username"
|
||||
>
|
||||
{{ initials }}
|
||||
</div>
|
||||
<div *ngIf="withName" class="clamp-2">
|
||||
{{ username || ('initials-avatar.unassigned' | translate) }}
|
||||
</div>
|
||||
|
||||
@ -30,7 +30,12 @@
|
||||
|
||||
<div class="breakdown-container">
|
||||
<div>
|
||||
<div *ngFor="let val of parsedConfig">
|
||||
<div
|
||||
*ngFor="let val of parsedConfig"
|
||||
[class.active]="val.checked"
|
||||
[class.filter-disabled]="!filter"
|
||||
(click)="toggleFilter.emit(val.label)"
|
||||
>
|
||||
<redaction-status-bar
|
||||
[small]="true"
|
||||
[config]="[
|
||||
|
||||
@ -30,11 +30,29 @@
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-left: -8px;
|
||||
|
||||
div {
|
||||
> div {
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
|
||||
> div {
|
||||
border-radius: 4px;
|
||||
padding: 3px 8px;
|
||||
|
||||
&:not(.filter-disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover:not(.active):not(.filter-disabled) {
|
||||
background-color: $grey-6;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: rgba($primary, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||
import { Color } from '../../utils/types';
|
||||
import { FilterModel } from '../../common/filter/model/filter.model';
|
||||
|
||||
export class DoughnutChartConfig {
|
||||
value: number;
|
||||
color: Color;
|
||||
label: string;
|
||||
active?: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
@ -18,6 +20,8 @@ export class SimpleDoughnutChartComponent implements OnChanges {
|
||||
@Input() radius = 85;
|
||||
@Input() strokeWidth = 20;
|
||||
@Input() direction: 'row' | 'column' = 'column';
|
||||
@Input() filter: FilterModel[];
|
||||
@Output() public toggleFilter = new EventEmitter<string>();
|
||||
|
||||
public chartData: any[] = [];
|
||||
public perimeter: number;
|
||||
@ -70,6 +74,11 @@ export class SimpleDoughnutChartComponent implements OnChanges {
|
||||
|
||||
// Eliminate items with value = 0
|
||||
public get parsedConfig() {
|
||||
return this.config.filter((el) => el.value);
|
||||
return this.config
|
||||
.filter((el) => el.value)
|
||||
.map((el) => ({
|
||||
...el,
|
||||
checked: this.filter?.find((f) => f.key === el.label)?.checked
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
<div>
|
||||
<redaction-simple-doughnut-chart
|
||||
[config]="projectsChartData"
|
||||
[strokeWidth]="15"
|
||||
[subtitle]="'project-listing.stats.charts.projects'"
|
||||
></redaction-simple-doughnut-chart>
|
||||
|
||||
<div class="project-stats-container">
|
||||
<div class="project-stats-item">
|
||||
<mat-icon svgIcon="red:document"></mat-icon>
|
||||
<div>
|
||||
<div class="heading">{{ totalPages }}</div>
|
||||
<div translate="project-listing.stats.analyzed-pages"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="project-stats-item">
|
||||
<mat-icon svgIcon="red:user"></mat-icon>
|
||||
<div>
|
||||
<div class="heading">{{ totalPeople }}</div>
|
||||
<div translate="project-listing.stats.total-people"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<redaction-simple-doughnut-chart
|
||||
[config]="documentsChartData"
|
||||
[strokeWidth]="15"
|
||||
[subtitle]="'project-listing.stats.charts.total-documents'"
|
||||
[filter]="filters.statusFilters"
|
||||
(toggleFilter)="toggleFilter('statusFilters', $event)"
|
||||
></redaction-simple-doughnut-chart>
|
||||
</div>
|
||||
@ -0,0 +1,32 @@
|
||||
:host {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.project-stats-container {
|
||||
width: fit-content;
|
||||
|
||||
.project-stats-item {
|
||||
display: flex;
|
||||
width: fit-content;
|
||||
gap: 5px;
|
||||
margin-top: 25px;
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
height: 16px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { DoughnutChartConfig } from '../../../components/simple-doughnut-chart/simple-doughnut-chart.component';
|
||||
import { AppStateService } from '../../../state/app-state.service';
|
||||
import { FilterModel } from '../../../common/filter/model/filter.model';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-project-listing-details',
|
||||
templateUrl: './project-listing-details.component.html',
|
||||
styleUrls: ['./project-listing-details.component.scss']
|
||||
})
|
||||
export class ProjectListingDetailsComponent implements OnInit {
|
||||
@Input() public projectsChartData: DoughnutChartConfig[];
|
||||
@Input() public documentsChartData: DoughnutChartConfig[];
|
||||
@Input() public filters: { statusFilters: FilterModel[] };
|
||||
@Output() public filtersChanged = new EventEmitter();
|
||||
|
||||
constructor(private readonly _appStateService: AppStateService) {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
public get totalPages() {
|
||||
return this._appStateService.totalAnalysedPages;
|
||||
}
|
||||
|
||||
public get totalPeople() {
|
||||
return this._appStateService.totalPeople;
|
||||
}
|
||||
|
||||
public toggleFilter(filterType: 'needsWorkFilters' | 'statusFilters', key: string): void {
|
||||
const filter = this.filters[filterType].find((f) => f.key === key);
|
||||
filter.checked = !filter.checked;
|
||||
this.filtersChanged.emit(this.filters);
|
||||
}
|
||||
}
|
||||
@ -162,7 +162,7 @@
|
||||
[config]="getProjectStatusConfig(pw)"
|
||||
></redaction-status-bar>
|
||||
|
||||
<div class="action-buttons">
|
||||
<div class="action-buttons" *ngIf="userService.isManager(user)">
|
||||
<button
|
||||
(click)="openDeleteProjectDialog($event, pw.project)"
|
||||
[matTooltip]="'project-listing.delete.action' | translate"
|
||||
@ -229,38 +229,12 @@
|
||||
</div>
|
||||
|
||||
<div class="right-fixed-container">
|
||||
<div>
|
||||
<redaction-simple-doughnut-chart
|
||||
[config]="projectsChartData"
|
||||
[strokeWidth]="15"
|
||||
[subtitle]="'project-listing.stats.charts.projects'"
|
||||
></redaction-simple-doughnut-chart>
|
||||
|
||||
<div class="project-stats-container">
|
||||
<div class="project-stats-item">
|
||||
<mat-icon svgIcon="red:document"></mat-icon>
|
||||
<div>
|
||||
<div class="heading">{{ totalPages }}</div>
|
||||
<div translate="project-listing.stats.analyzed-pages"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="project-stats-item">
|
||||
<mat-icon svgIcon="red:user"></mat-icon>
|
||||
<div>
|
||||
<div class="heading">{{ totalPeople }}</div>
|
||||
<div translate="project-listing.stats.total-people"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<redaction-simple-doughnut-chart
|
||||
[config]="documentsChartData"
|
||||
[strokeWidth]="15"
|
||||
[subtitle]="'project-listing.stats.charts.total-documents'"
|
||||
></redaction-simple-doughnut-chart>
|
||||
</div>
|
||||
<redaction-project-listing-details
|
||||
[projectsChartData]="projectsChartData"
|
||||
[documentsChartData]="documentsChartData"
|
||||
[filters]="detailsContainerFilters"
|
||||
(filtersChanged)="filtersChanged($event)"
|
||||
></redaction-project-listing-details>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -38,31 +38,4 @@
|
||||
display: flex;
|
||||
width: 430px;
|
||||
padding-top: 50px;
|
||||
|
||||
> div {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.project-stats-container {
|
||||
width: fit-content;
|
||||
|
||||
.project-stats-item {
|
||||
display: flex;
|
||||
width: fit-content;
|
||||
gap: 5px;
|
||||
margin-top: 25px;
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
height: 16px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,8 +34,12 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
public dueDateFilters: FilterModel[];
|
||||
public peopleFilters: FilterModel[];
|
||||
public needsWorkFilters: FilterModel[];
|
||||
public displayedProjects: ProjectWrapper[] = [];
|
||||
|
||||
public detailsContainerFilters: {
|
||||
statusFilters: FilterModel[];
|
||||
};
|
||||
|
||||
public displayedProjects: ProjectWrapper[] = [];
|
||||
public sortingOption: SortingOption = { column: 'projectDate', order: 'desc' };
|
||||
|
||||
constructor(
|
||||
@ -72,14 +76,6 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
return this.userService.user;
|
||||
}
|
||||
|
||||
public get totalPages() {
|
||||
return this.appStateService.totalAnalysedPages;
|
||||
}
|
||||
|
||||
public get totalPeople() {
|
||||
return this.appStateService.totalPeople;
|
||||
}
|
||||
|
||||
public get activeProjects() {
|
||||
return this.appStateService.allProjects.reduce(
|
||||
(i, p) => i + (p.project.status === Project.StatusEnum.ACTIVE ? 1 : 0),
|
||||
@ -216,7 +212,14 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
this.needsWorkFilters = needsWorkFilters;
|
||||
}
|
||||
|
||||
public filtersChanged() {
|
||||
filtersChanged(filters?: { [key: string]: FilterModel[] }): void {
|
||||
if (filters) {
|
||||
for (const key of Object.keys(filters)) {
|
||||
for (let idx = 0; idx < this[key].length; ++idx) {
|
||||
this[key][idx] = filters[key][idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
this._filterProjects();
|
||||
}
|
||||
|
||||
@ -227,7 +230,9 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
{ values: this.dueDateFilters, checker: dueDateChecker },
|
||||
{ values: this.needsWorkFilters, checker: annotationFilterChecker, matchAll: true }
|
||||
];
|
||||
|
||||
this.detailsContainerFilters = {
|
||||
statusFilters: this.statusFilters.map((f) => ({ ...f }))
|
||||
};
|
||||
this.displayedProjects = getFilteredEntities(this.appStateService.allProjects, filters);
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
@ -64,29 +64,23 @@
|
||||
[config]="documentsChartData"
|
||||
[radius]="70"
|
||||
[strokeWidth]="15"
|
||||
[subtitle]="'project-overview.project-details.charts.total-documents'"
|
||||
[subtitle]="'project-overview.project-details.charts.documents-in-project'"
|
||||
direction="row"
|
||||
[filter]="filters.statusFilters"
|
||||
(toggleFilter)="toggleFilter('statusFilters', $event)"
|
||||
></redaction-simple-doughnut-chart>
|
||||
</div>
|
||||
|
||||
<div class="mt-24 legend" *ngIf="hasFiles">
|
||||
<div>
|
||||
<div
|
||||
*ngFor="let filter of filters.needsWorkFilters"
|
||||
[class.active]="filter.checked"
|
||||
(click)="toggleFilter('needsWorkFilters', filter.key)"
|
||||
>
|
||||
<redaction-annotation-icon
|
||||
[typeValue]="appStateService.getDictionaryTypeValue('hint')"
|
||||
[typeValue]="appStateService.getDictionaryTypeValue(filter.key.slice(0, -1))"
|
||||
></redaction-annotation-icon>
|
||||
{{ 'project-overview.legend.contains-hints' | translate }}
|
||||
</div>
|
||||
<div>
|
||||
<redaction-annotation-icon
|
||||
[typeValue]="appStateService.getDictionaryTypeValue('redaction')"
|
||||
></redaction-annotation-icon>
|
||||
{{ 'project-overview.legend.contains-redactions' | translate }}
|
||||
</div>
|
||||
<div>
|
||||
<redaction-annotation-icon
|
||||
[typeValue]="appStateService.getDictionaryTypeValue('suggestion')"
|
||||
></redaction-annotation-icon>
|
||||
{{ 'project-overview.legend.contains-suggestions' | translate }}
|
||||
{{ 'project-overview.legend.' + filter.key | translate }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
@import '../../../../assets/styles/red-variables';
|
||||
|
||||
.members-container {
|
||||
gap: 5px;
|
||||
}
|
||||
@ -5,12 +7,24 @@
|
||||
.legend {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
gap: 4px;
|
||||
margin-left: -8px;
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
padding: 3px 8px;
|
||||
|
||||
&:hover {
|
||||
background-color: $grey-6;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: rgba($primary, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { Component, OnInit, Output, EventEmitter, ChangeDetectorRef } from '@angular/core';
|
||||
import { Component, OnInit, Output, EventEmitter, Input, ChangeDetectorRef } from '@angular/core';
|
||||
import { AppStateService } from '../../../state/app-state.service';
|
||||
import { UserService } from '../../../user/user.service';
|
||||
import { groupBy } from '../../../utils/functions';
|
||||
import { DoughnutChartConfig } from '../../../components/simple-doughnut-chart/simple-doughnut-chart.component';
|
||||
import { DialogService } from '../../../dialogs/dialog.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { FilterModel } from '../../../common/filter/model/filter.model';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-project-details',
|
||||
@ -13,7 +14,9 @@ import { Router } from '@angular/router';
|
||||
})
|
||||
export class ProjectDetailsComponent implements OnInit {
|
||||
public documentsChartData: DoughnutChartConfig[] = [];
|
||||
@Output() public reloadProjects = new EventEmitter<void>();
|
||||
@Input() public filters: { needsWorkFilters: FilterModel[]; statusFilters: FilterModel[] };
|
||||
@Output() public reloadProjects = new EventEmitter();
|
||||
@Output() public filtersChanged = new EventEmitter();
|
||||
|
||||
constructor(
|
||||
public readonly appStateService: AppStateService,
|
||||
@ -61,7 +64,7 @@ export class ProjectDetailsComponent implements OnInit {
|
||||
);
|
||||
}
|
||||
|
||||
public openAssignProjectMembersDialog() {
|
||||
public openAssignProjectMembersDialog(): void {
|
||||
this._dialogService.openAssignProjectMembersAndOwnerDialog(
|
||||
null,
|
||||
this.appStateService.activeProject.project,
|
||||
@ -71,12 +74,12 @@ export class ProjectDetailsComponent implements OnInit {
|
||||
);
|
||||
}
|
||||
|
||||
public downloadRedactionReport($event: MouseEvent) {
|
||||
public downloadRedactionReport($event: MouseEvent): void {
|
||||
$event.stopPropagation();
|
||||
this.appStateService.downloadRedactionReport();
|
||||
}
|
||||
|
||||
public calculateChartConfig() {
|
||||
public calculateChartConfig(): void {
|
||||
if (this.appStateService.activeProject) {
|
||||
const groups = groupBy(this.appStateService.activeProject?.files, 'status');
|
||||
this.documentsChartData = [];
|
||||
@ -87,7 +90,13 @@ export class ProjectDetailsComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
get hasFiles() {
|
||||
get hasFiles(): boolean {
|
||||
return this.appStateService.activeProject.hasFiles;
|
||||
}
|
||||
|
||||
public toggleFilter(filterType: 'needsWorkFilters' | 'statusFilters', key: string): void {
|
||||
const filter = this.filters[filterType].find((f) => f.key === key);
|
||||
filter.checked = !filter.checked;
|
||||
this.filtersChanged.emit(this.filters);
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,24 +159,21 @@
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
[matTooltipPosition]="'above'"
|
||||
[matTooltip]="'[' + fileStatus.status + '] ' + fileStatus.filename"
|
||||
>
|
||||
<div class="filename-wrapper">
|
||||
<div
|
||||
[class.disabled]="isPending(fileStatus) || isProcessing(fileStatus)"
|
||||
[class.error]="isError(fileStatus)"
|
||||
class="table-item-title"
|
||||
>
|
||||
{{ fileStatus.filename }}
|
||||
</div>
|
||||
<span
|
||||
*ngIf="appStateService.fileNotUpToDateWithDictionary(fileStatus)"
|
||||
class="pill"
|
||||
translate="project-overview.new-rule.label"
|
||||
></span>
|
||||
<div>
|
||||
<div
|
||||
[class.disabled]="isPending(fileStatus) || isProcessing(fileStatus)"
|
||||
[class.error]="isError(fileStatus)"
|
||||
class="table-item-title"
|
||||
[matTooltipPosition]="'above'"
|
||||
[matTooltip]="'[' + fileStatus.status + '] ' + fileStatus.filename"
|
||||
>
|
||||
{{ fileStatus.filename }}
|
||||
</div>
|
||||
<span
|
||||
*ngIf="appStateService.fileNotUpToDateWithDictionary(fileStatus)"
|
||||
class="pill"
|
||||
translate="project-overview.new-rule.label"
|
||||
></span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@ -355,6 +352,8 @@
|
||||
<redaction-project-details
|
||||
#projectDetailsComponent
|
||||
(reloadProjects)="reloadProjects()"
|
||||
[filters]="detailsContainerFilters"
|
||||
(filtersChanged)="filtersChanged($event)"
|
||||
></redaction-project-details>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -57,13 +57,6 @@
|
||||
.status-container {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.filename-wrapper {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -43,6 +43,11 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
|
||||
public displayedFiles: FileStatusWrapper[] = [];
|
||||
|
||||
public detailsContainerFilters: {
|
||||
needsWorkFilters: FilterModel[];
|
||||
statusFilters: FilterModel[];
|
||||
};
|
||||
|
||||
@ViewChild('projectDetailsComponent', { static: false })
|
||||
private _projectDetailsComponent: ProjectDetailsComponent;
|
||||
|
||||
@ -313,7 +318,14 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
this.needsWorkFilters = needsWorkFilters;
|
||||
}
|
||||
|
||||
filtersChanged() {
|
||||
filtersChanged(filters?: { [key: string]: FilterModel[] }): void {
|
||||
if (filters) {
|
||||
for (const key of Object.keys(filters)) {
|
||||
for (let idx = 0; idx < this[key].length; ++idx) {
|
||||
this[key][idx] = filters[key][idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
this._filterFiles();
|
||||
}
|
||||
|
||||
@ -327,6 +339,10 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
this.appStateService.activeProject.files,
|
||||
filters
|
||||
);
|
||||
this.detailsContainerFilters = {
|
||||
needsWorkFilters: this.needsWorkFilters.map((f) => ({ ...f })),
|
||||
statusFilters: this.statusFilters.map((f) => ({ ...f }))
|
||||
};
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
|
||||
@ -226,7 +226,7 @@
|
||||
},
|
||||
"project-details": {
|
||||
"charts": {
|
||||
"total-documents": "Total Documents"
|
||||
"documents-in-project": "Documents in Project"
|
||||
},
|
||||
"stats": {
|
||||
"documents": "{{count}} documents",
|
||||
@ -241,9 +241,9 @@
|
||||
"upload-document": "Upload Document",
|
||||
"no-project": "Requested project: {{projectId}} does not exist! <a href='/ui/projects'>Back to Project Listing. <a/>",
|
||||
"legend": {
|
||||
"contains-hints": "Hints only ",
|
||||
"contains-redactions": "Redacted ",
|
||||
"contains-suggestions": "Suggested Redaction "
|
||||
"hints": "Hints only",
|
||||
"redactions": "Redacted",
|
||||
"requests": "Redaction requests"
|
||||
}
|
||||
},
|
||||
"file-preview": {
|
||||
|
||||
186
package.json
186
package.json
@ -1,96 +1,96 @@
|
||||
{
|
||||
"name": "redaction",
|
||||
"version": "0.0.123",
|
||||
"license": "MIT",
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "pretty-quick --staged && ng lint --project=red-ui-http && ng lint --project=red-ui --fix"
|
||||
"name": "redaction",
|
||||
"version": "0.0.123",
|
||||
"license": "MIT",
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "pretty-quick --staged && ng lint --project=red-ui-http && ng lint --project=red-ui --fix"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build-lint-all": "ng lint --project=red-ui-http --fix && ng build --project=red-ui-http && ng lint --project=red-ui --fix && ng build --project=red-ui --prod",
|
||||
"nx": "nx",
|
||||
"start": "nx serve",
|
||||
"build": "nx build",
|
||||
"test": "nx test",
|
||||
"lint": "nx workspace-lint && nx lint",
|
||||
"e2e": "nx e2e",
|
||||
"affected:apps": "nx affected:apps",
|
||||
"affected:libs": "nx affected:libs",
|
||||
"affected:build": "nx affected:build",
|
||||
"affected:e2e": "nx affected:e2e",
|
||||
"affected:test": "nx affected:test",
|
||||
"affected:lint": "nx affected:lint",
|
||||
"affected:dep-graph": "nx affected:dep-graph",
|
||||
"affected": "nx affected",
|
||||
"format": "nx format:write",
|
||||
"format:write": "nx format:write",
|
||||
"format:check": "nx format:check",
|
||||
"update": "nx migrate latest",
|
||||
"workspace-schematic": "nx workspace-schematic",
|
||||
"dep-graph": "nx dep-graph",
|
||||
"help": "nx help",
|
||||
"postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^10.0.0",
|
||||
"@angular/cdk": "^10.2.3",
|
||||
"@angular/common": "^10.0.0",
|
||||
"@angular/core": "^10.0.0",
|
||||
"@angular/forms": "^10.0.0",
|
||||
"@angular/material": "^10.2.1",
|
||||
"@angular/platform-browser": "^10.0.0",
|
||||
"@angular/platform-browser-dynamic": "^10.0.0",
|
||||
"@angular/router": "^10.0.0",
|
||||
"@angular/service-worker": "^10.0.0",
|
||||
"@ngx-translate/core": "^13.0.0",
|
||||
"@ngx-translate/http-loader": "^6.0.0",
|
||||
"@nrwl/angular": "^10.2.0",
|
||||
"@pdftron/webviewer": "^7.0.1",
|
||||
"file-saver": "^2.0.2",
|
||||
"jwt-decode": "^3.0.0",
|
||||
"keycloak-angular": "^8.0.1",
|
||||
"keycloak-js": "10.0.2",
|
||||
"lint-staged": "^10.5.0",
|
||||
"ng2-file-upload": "^1.4.0",
|
||||
"ngp-sort-pipe": "^0.0.4",
|
||||
"ngx-dropzone": "^2.2.2",
|
||||
"ngx-toastr": "^13.0.0",
|
||||
"rxjs": "~6.5.5",
|
||||
"scroll-into-view-if-needed": "^2.2.26",
|
||||
"zone.js": "^0.10.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.1000.0",
|
||||
"@angular-devkit/build-ng-packagr": "^0.1001.3",
|
||||
"@angular/cli": "^10.1.2",
|
||||
"@angular/compiler": "^10.0.0",
|
||||
"@angular/compiler-cli": "^10.0.0",
|
||||
"@angular/language-service": "^10.0.0",
|
||||
"@nrwl/cypress": "10.2.0",
|
||||
"@nrwl/jest": "10.2.0",
|
||||
"@nrwl/workspace": "10.2.0",
|
||||
"@types/jest": "26.0.8",
|
||||
"@types/node": "~8.9.4",
|
||||
"codelyzer": "~5.0.1",
|
||||
"cypress": "^4.1.0",
|
||||
"dotenv": "6.2.0",
|
||||
"eslint": "6.8.0",
|
||||
"google-translate-api-browser": "^1.1.71",
|
||||
"husky": "^4.3.0",
|
||||
"jest": "26.2.2",
|
||||
"jest-preset-angular": "8.2.1",
|
||||
"lodash": "^4.17.20",
|
||||
"moment": "^2.29.1",
|
||||
"ng-packagr": "^10.1.2",
|
||||
"prettier": "2.0.4",
|
||||
"pretty-quick": "^3.1.0",
|
||||
"superagent": "^6.1.0",
|
||||
"superagent-promise": "^1.1.0",
|
||||
"ts-jest": "26.1.4",
|
||||
"ts-node": "~7.0.0",
|
||||
"tslint": "~6.0.0",
|
||||
"typescript": "~3.9.3"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build-lint-all": "ng lint --project=red-ui-http --fix && ng build --project=red-ui-http && ng lint --project=red-ui --fix && ng build --project=red-ui --prod",
|
||||
"nx": "nx",
|
||||
"start": "nx serve",
|
||||
"build": "nx build",
|
||||
"test": "nx test",
|
||||
"lint": "nx workspace-lint && nx lint",
|
||||
"e2e": "nx e2e",
|
||||
"affected:apps": "nx affected:apps",
|
||||
"affected:libs": "nx affected:libs",
|
||||
"affected:build": "nx affected:build",
|
||||
"affected:e2e": "nx affected:e2e",
|
||||
"affected:test": "nx affected:test",
|
||||
"affected:lint": "nx affected:lint",
|
||||
"affected:dep-graph": "nx affected:dep-graph",
|
||||
"affected": "nx affected",
|
||||
"format": "nx format:write",
|
||||
"format:write": "nx format:write",
|
||||
"format:check": "nx format:check",
|
||||
"update": "nx migrate latest",
|
||||
"workspace-schematic": "nx workspace-schematic",
|
||||
"dep-graph": "nx dep-graph",
|
||||
"help": "nx help",
|
||||
"postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^10.0.0",
|
||||
"@angular/cdk": "^10.2.3",
|
||||
"@angular/common": "^10.0.0",
|
||||
"@angular/core": "^10.0.0",
|
||||
"@angular/forms": "^10.0.0",
|
||||
"@angular/material": "^10.2.1",
|
||||
"@angular/platform-browser": "^10.0.0",
|
||||
"@angular/platform-browser-dynamic": "^10.0.0",
|
||||
"@angular/router": "^10.0.0",
|
||||
"@angular/service-worker": "^10.0.0",
|
||||
"@ngx-translate/core": "^13.0.0",
|
||||
"@ngx-translate/http-loader": "^6.0.0",
|
||||
"@nrwl/angular": "^10.2.0",
|
||||
"@pdftron/webviewer": "^7.0.1",
|
||||
"file-saver": "^2.0.2",
|
||||
"jwt-decode": "^3.0.0",
|
||||
"keycloak-angular": "^8.0.1",
|
||||
"keycloak-js": "10.0.2",
|
||||
"lint-staged": "^10.5.0",
|
||||
"ng2-file-upload": "^1.4.0",
|
||||
"ngp-sort-pipe": "^0.0.4",
|
||||
"ngx-dropzone": "^2.2.2",
|
||||
"ngx-toastr": "^13.0.0",
|
||||
"rxjs": "~6.5.5",
|
||||
"scroll-into-view-if-needed": "^2.2.26",
|
||||
"zone.js": "^0.10.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.1000.0",
|
||||
"@angular-devkit/build-ng-packagr": "^0.1001.3",
|
||||
"@angular/cli": "^10.1.2",
|
||||
"@angular/compiler": "^10.0.0",
|
||||
"@angular/compiler-cli": "^10.0.0",
|
||||
"@angular/language-service": "^10.0.0",
|
||||
"@nrwl/cypress": "10.2.0",
|
||||
"@nrwl/jest": "10.2.0",
|
||||
"@nrwl/workspace": "10.2.0",
|
||||
"@types/jest": "26.0.8",
|
||||
"@types/node": "~8.9.4",
|
||||
"codelyzer": "~5.0.1",
|
||||
"cypress": "^4.1.0",
|
||||
"dotenv": "6.2.0",
|
||||
"eslint": "6.8.0",
|
||||
"google-translate-api-browser": "^1.1.71",
|
||||
"husky": "^4.3.0",
|
||||
"jest": "26.2.2",
|
||||
"jest-preset-angular": "8.2.1",
|
||||
"lodash": "^4.17.20",
|
||||
"moment": "^2.29.1",
|
||||
"ng-packagr": "^10.1.2",
|
||||
"prettier": "2.0.4",
|
||||
"pretty-quick": "^3.1.0",
|
||||
"superagent": "^6.1.0",
|
||||
"superagent-promise": "^1.1.0",
|
||||
"ts-jest": "26.1.4",
|
||||
"ts-node": "~7.0.0",
|
||||
"tslint": "~6.0.0",
|
||||
"typescript": "~3.9.3"
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user