reworked analysis required
This commit is contained in:
parent
5f16c2988e
commit
1f2acf201e
@ -1,8 +1,10 @@
|
||||
import { FilterModel } from '../model/filter.model';
|
||||
import { FileStatusWrapper } from '../../../screens/file/model/file-status.wrapper';
|
||||
import { ProjectWrapper } from '../../../state/model/project.wrapper';
|
||||
import { PermissionsService } from '../../service/permissions.service';
|
||||
|
||||
export const RedactionFilterSorter = {
|
||||
analysis: 0,
|
||||
hint: 1,
|
||||
redaction: 2,
|
||||
suggestion: 3,
|
||||
@ -22,9 +24,16 @@ export function handleCheckedValue(filter: FilterModel) {
|
||||
}
|
||||
}
|
||||
|
||||
export function checkFilter(entity: any, filters: FilterModel[], validate: Function, matchAll: boolean = false) {
|
||||
export function checkFilter(entity: any, filters: FilterModel[], validate: Function, validateArgs: any = [], matchAll: boolean = false) {
|
||||
const hasChecked = filters.find((f) => f.checked);
|
||||
|
||||
if (validateArgs) {
|
||||
if (!Array.isArray(validateArgs)) {
|
||||
validateArgs = [validateArgs];
|
||||
}
|
||||
} else {
|
||||
validateArgs = [];
|
||||
}
|
||||
if (!hasChecked) {
|
||||
return true;
|
||||
}
|
||||
@ -33,9 +42,9 @@ export function checkFilter(entity: any, filters: FilterModel[], validate: Funct
|
||||
for (const filter of filters) {
|
||||
if (filter.checked) {
|
||||
if (matchAll) {
|
||||
filterMatched = filterMatched && validate(entity, filter);
|
||||
filterMatched = filterMatched && validate(entity, filter, ...validateArgs);
|
||||
} else {
|
||||
filterMatched = filterMatched || validate(entity, filter);
|
||||
filterMatched = filterMatched || validate(entity, filter, ...validateArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -45,19 +54,26 @@ export function checkFilter(entity: any, filters: FilterModel[], validate: Funct
|
||||
|
||||
export const keyChecker = (key: string) => (entity: any, filter: FilterModel) => entity[key] === filter.key;
|
||||
|
||||
export const annotationFilterChecker = (f: FileStatusWrapper, filter: FilterModel) => {
|
||||
export const annotationFilterChecker = (input: FileStatusWrapper | ProjectWrapper, filter: FilterModel, permissionsService: PermissionsService) => {
|
||||
switch (filter.key) {
|
||||
case 'analysis': {
|
||||
if (input instanceof ProjectWrapper) {
|
||||
return permissionsService.projectReanalysisRequired(input);
|
||||
} else {
|
||||
return permissionsService.fileRequiresReanalysis(input);
|
||||
}
|
||||
}
|
||||
case 'suggestion': {
|
||||
return f.hasRequests;
|
||||
return input.hasRequests;
|
||||
}
|
||||
case 'redaction': {
|
||||
return f.hasRedactions;
|
||||
return input.hasRedactions;
|
||||
}
|
||||
case 'hint': {
|
||||
return f.hintsOnly;
|
||||
return input.hintsOnly;
|
||||
}
|
||||
case 'none': {
|
||||
return f.hasNone;
|
||||
return input.hasNone;
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -72,12 +88,12 @@ export const dueDateChecker = (pw: ProjectWrapper, filter: FilterModel) => pw.du
|
||||
|
||||
export const addedDateChecker = (pw: ProjectWrapper, filter: FilterModel) => pw.addedDateMatches(filter.key);
|
||||
|
||||
export function getFilteredEntities(entities: any[], filters: { values: FilterModel[]; checker: Function; matchAll?: boolean }[]) {
|
||||
export function getFilteredEntities(entities: any[], filters: { values: FilterModel[]; checker: Function; matchAll?: boolean; checkerArgs?: any }[]) {
|
||||
const filteredEntities = [];
|
||||
for (const entity of entities) {
|
||||
let add = true;
|
||||
for (const filter of filters) {
|
||||
add = add && checkFilter(entity, filter.values, filter.checker, filter.matchAll);
|
||||
add = add && checkFilter(entity, filter.values, filter.checker, filter.checkerArgs, filter.matchAll);
|
||||
}
|
||||
if (add) {
|
||||
filteredEntities.push(entity);
|
||||
|
||||
@ -3,6 +3,7 @@ import { AppStateService } from '../../state/app-state.service';
|
||||
import { UserService, UserWrapper } from '../../user/user.service';
|
||||
import { FileStatusWrapper } from '../../screens/file/model/file-status.wrapper';
|
||||
import { Project, User } from '@redaction/red-ui-http';
|
||||
import { ProjectWrapper } from '../../state/model/project.wrapper';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@ -22,6 +23,15 @@ export class PermissionsService {
|
||||
return this.isFileReviewer(fileStatus) || this.isManagerAndOwner();
|
||||
}
|
||||
|
||||
projectReanalysisRequired(project?: ProjectWrapper) {
|
||||
for (let file of project.files) {
|
||||
const fileReanalysisRequired = this.fileRequiresReanalysis(file);
|
||||
if (fileReanalysisRequired) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileRequiresReanalysis(fileStatus?: FileStatusWrapper) {
|
||||
if (!fileStatus) {
|
||||
fileStatus = this._appStateService.activeFile;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<div class="needs-work">
|
||||
<redaction-annotation-icon *ngIf="reanalysisRequired()" [typeValue]="appStateService.getDictionaryTypeValue('analysis')"></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="needsWorkInput.hasRedactions"
|
||||
[typeValue]="appStateService.getDictionaryTypeValue('redaction')"
|
||||
|
||||
@ -1,11 +1,8 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { AppStateService } from '../../../state/app-state.service';
|
||||
|
||||
export interface NeedsWorkInput {
|
||||
hintsOnly?: boolean;
|
||||
hasRedactions?: boolean;
|
||||
hasRequests?: boolean;
|
||||
}
|
||||
import { PermissionsService } from '../../../common/service/permissions.service';
|
||||
import { FileStatusWrapper } from '../../file/model/file-status.wrapper';
|
||||
import { ProjectWrapper } from '../../../state/model/project.wrapper';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-needs-work-badge',
|
||||
@ -13,9 +10,17 @@ export interface NeedsWorkInput {
|
||||
styleUrls: ['./needs-work-badge.component.scss']
|
||||
})
|
||||
export class NeedsWorkBadgeComponent implements OnInit {
|
||||
@Input() needsWorkInput: NeedsWorkInput;
|
||||
@Input() needsWorkInput: FileStatusWrapper | ProjectWrapper;
|
||||
|
||||
constructor(public appStateService: AppStateService) {}
|
||||
constructor(public appStateService: AppStateService, public permissionsService: PermissionsService) {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
reanalysisRequired() {
|
||||
if (this.needsWorkInput instanceof ProjectWrapper) {
|
||||
return this.permissionsService.projectReanalysisRequired(this.needsWorkInput);
|
||||
} else {
|
||||
return this.permissionsService.fileRequiresReanalysis(this.needsWorkInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
</div>
|
||||
|
||||
<div class="flex-1 filename page-title">
|
||||
<span *ngIf="permissionsService.fileRequiresReanalysis()" class="pill" translate="project-overview.new-rule.label"></span>
|
||||
<!-- <span *ngIf="permissionsService.fileRequiresReanalysis()" class="pill" translate="project-overview.new-rule.label"></span>-->
|
||||
<span *ngIf="!permissionsService.canPerformAnnotationActions()" class="pill" translate="readonly-pill"></span> <span>{{
|
||||
appStateService.activeFile.filename
|
||||
}}</span>
|
||||
|
||||
@ -167,10 +167,11 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
|
||||
// Needs work
|
||||
entry.files.forEach((file) => {
|
||||
if (file.hintsOnly) allDistinctNeedsWork.add('hint');
|
||||
if (file.hasRedactions) allDistinctNeedsWork.add('redaction');
|
||||
if (file.hasRequests) allDistinctNeedsWork.add('suggestion');
|
||||
if (file.hasNone) allDistinctNeedsWork.add('none');
|
||||
if (this.permissionsService.fileRequiresReanalysis(file)) allDistinctNeedsWork.add('analysis');
|
||||
if (entry.hintsOnly) allDistinctNeedsWork.add('hint');
|
||||
if (entry.hasRedactions) allDistinctNeedsWork.add('redaction');
|
||||
if (entry.hasRequests) allDistinctNeedsWork.add('suggestion');
|
||||
if (entry.hasNone) allDistinctNeedsWork.add('none');
|
||||
});
|
||||
});
|
||||
|
||||
@ -226,7 +227,7 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
{ values: this.statusFilters, checker: projectStatusChecker },
|
||||
{ values: this.peopleFilters, checker: projectMemberChecker },
|
||||
{ values: this.dueDateFilters, checker: dueDateChecker },
|
||||
{ values: this.needsWorkFilters, checker: annotationFilterChecker, matchAll: true }
|
||||
{ values: this.needsWorkFilters, checker: annotationFilterChecker, matchAll: true, checkerArgs: this.permissionsService }
|
||||
];
|
||||
this.detailsContainerFilters = {
|
||||
statusFilters: this.statusFilters.map((f) => ({ ...f }))
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
<div class="mt-24 legend" *ngIf="hasFiles">
|
||||
<div *ngFor="let filter of filters.needsWorkFilters" [class.active]="filter.checked" (click)="toggleFilter('needsWorkFilters', filter.key)">
|
||||
<redaction-annotation-icon *ngIf="filter.key !== 'none'" [typeValue]="appStateService.getDictionaryTypeValue(filter.key)"></redaction-annotation-icon>
|
||||
{{ 'project-overview.legend.' + filter.key | translate }}
|
||||
{{ 'filter.' + filter.key | translate }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -122,7 +122,7 @@
|
||||
<div [class.disabled]="fileStatus.isPending || fileStatus.isProcessing" [class.error]="fileStatus.isError" class="table-item-title">
|
||||
{{ fileStatus.filename }}
|
||||
</div>
|
||||
<span *ngIf="permissionsService.fileRequiresReanalysis(fileStatus)" class="pill" translate="project-overview.new-rule.label"></span>
|
||||
<!-- <span *ngIf="permissionsService.fileRequiresReanalysis(fileStatus)" class="pill" translate="project-overview.new-rule.label"></span>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -191,6 +191,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
|
||||
// Needs work
|
||||
this.appStateService.activeProject.files.forEach((file) => {
|
||||
if (this.permissionsService.fileRequiresReanalysis(file)) allDistinctNeedsWork.add('analysis');
|
||||
if (file.hintsOnly) allDistinctNeedsWork.add('hint');
|
||||
if (file.hasRedactions) allDistinctNeedsWork.add('redaction');
|
||||
if (file.hasRequests) allDistinctNeedsWork.add('suggestion');
|
||||
@ -250,7 +251,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
const filters = [
|
||||
{ values: this.statusFilters, checker: keyChecker('status') },
|
||||
{ values: this.peopleFilters, checker: keyChecker('currentReviewer') },
|
||||
{ values: this.needsWorkFilters, checker: annotationFilterChecker, matchAll: true }
|
||||
{ values: this.needsWorkFilters, checker: annotationFilterChecker, matchAll: true, checkerArgs: this.permissionsService }
|
||||
];
|
||||
this.displayedFiles = getFilteredEntities(this.appStateService.activeProject.files, filters);
|
||||
this.detailsContainerFilters = {
|
||||
|
||||
@ -390,6 +390,11 @@ export class AppStateService {
|
||||
type: 'add',
|
||||
virtual: true
|
||||
};
|
||||
this._dictionaryData['analysis'] = {
|
||||
hexColor: '#dd4d50',
|
||||
type: 'analysis',
|
||||
virtual: true
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ export class ProjectWrapper {
|
||||
hintsOnly?: boolean;
|
||||
hasRedactions?: boolean;
|
||||
hasRequests?: boolean;
|
||||
hasNone?: boolean;
|
||||
|
||||
allFilesApproved?: boolean;
|
||||
|
||||
@ -63,6 +64,7 @@ export class ProjectWrapper {
|
||||
this.hintsOnly = false;
|
||||
this.hasRedactions = false;
|
||||
this.hasRequests = false;
|
||||
this.hasNone = false;
|
||||
this.allFilesApproved = true;
|
||||
this._files.forEach((f) => {
|
||||
this.hintsOnly = this.hintsOnly || f.hintsOnly;
|
||||
@ -70,5 +72,6 @@ export class ProjectWrapper {
|
||||
this.hasRequests = this.hasRequests || f.hasRequests;
|
||||
this.allFilesApproved = this.allFilesApproved && f.isApproved;
|
||||
});
|
||||
this.hasNone = !this.hasRequests && !this.hasRedactions && !this.hintsOnly;
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,13 +239,7 @@
|
||||
},
|
||||
"header": "Project Overview",
|
||||
"upload-document": "Upload Document",
|
||||
"no-project": "Requested project: {{projectId}} does not exist! <a href='/ui/projects'>Back to Project Listing. <a/>",
|
||||
"legend": {
|
||||
"hint": "Hints only",
|
||||
"redaction": "Redacted",
|
||||
"suggestion": "Suggested Redaction",
|
||||
"none": "No Annotations"
|
||||
}
|
||||
"no-project": "Requested project: {{projectId}} does not exist! <a href='/ui/projects'>Back to Project Listing. <a/>"
|
||||
},
|
||||
"file-preview": {
|
||||
"show-redacted-view": "Show Redacted Preview",
|
||||
@ -317,6 +311,7 @@
|
||||
"hint": "Hints only",
|
||||
"redaction": "Redacted",
|
||||
"suggestion": "Suggested Redaction",
|
||||
"analysis": "Re-analysis required",
|
||||
"none": "No Annotations"
|
||||
},
|
||||
"annotation-filter": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user