added needs work for project overview, extracted component
This commit is contained in:
parent
a3bc58c269
commit
6241ef254a
@ -70,6 +70,7 @@ import { SortingComponent } from './components/sorting/sorting.component';
|
||||
import { TableColNameComponent } from './components/table-col-name/table-col-name.component';
|
||||
import { ProjectDetailsComponent } from './screens/project-overview-screen/project-details/project-details.component';
|
||||
import { PageIndicatorComponent } from './screens/file/page-indicator/page-indicator.component';
|
||||
import { NeedsWorkBadgeComponent } from './screens/common/needs-work-badge/needs-work-badge.component';
|
||||
|
||||
export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
|
||||
@ -105,7 +106,8 @@ export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
SortingComponent,
|
||||
TableColNameComponent,
|
||||
ProjectDetailsComponent,
|
||||
PageIndicatorComponent
|
||||
PageIndicatorComponent,
|
||||
NeedsWorkBadgeComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
<div *ngIf="displayed" class="needs-work">
|
||||
<redaction-annotation-icon
|
||||
*ngIf="needsWorkInput.hasRedactions"
|
||||
[typeValue]="appStateService.getDictionaryTypeValue('redaction')"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="needsWorkInput.hasHints"
|
||||
[typeValue]="appStateService.getDictionaryTypeValue('hint')"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="needsWorkInput.hasRequests"
|
||||
[typeValue]="appStateService.getDictionaryTypeValue('request')"
|
||||
></redaction-annotation-icon>
|
||||
</div>
|
||||
@ -0,0 +1,7 @@
|
||||
.needs-work {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 4px;
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { AppStateService } from '../../../state/app-state.service';
|
||||
|
||||
export interface NeedsWorkInput {
|
||||
hasHints?: boolean;
|
||||
hasRedactions?: boolean;
|
||||
hasRequests?: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-needs-work-badge',
|
||||
templateUrl: './needs-work-badge.component.html',
|
||||
styleUrls: ['./needs-work-badge.component.scss']
|
||||
})
|
||||
export class NeedsWorkBadgeComponent implements OnInit {
|
||||
@Input() displayed: boolean;
|
||||
@Input() needsWorkInput: NeedsWorkInput;
|
||||
|
||||
constructor(public appStateService: AppStateService) {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
}
|
||||
@ -22,20 +22,13 @@
|
||||
[icon]="'red:lightning'"
|
||||
(filtersChanged)="filtersChanged()"
|
||||
></redaction-filter>
|
||||
<!-- <redaction-filter-->
|
||||
<!-- [filters]="addedDateFilters"-->
|
||||
<!-- [filterLabel]="'filters.created-on'"-->
|
||||
<!-- [hasArrow]="false"-->
|
||||
<!-- [icon]="'red:calendar'"-->
|
||||
<!-- (filtersChanged)="filtersChanged()"-->
|
||||
<!-- ></redaction-filter>-->
|
||||
|
||||
<!-- <button mat-button translate="filters.project">-->
|
||||
<!-- <mat-icon svgIcon="red:folder"></mat-icon>-->
|
||||
<!-- </button>-->
|
||||
<!-- <button mat-button translate="filters.document">-->
|
||||
<!-- <mat-icon svgIcon="red:document"></mat-icon>-->
|
||||
<!-- </button>-->
|
||||
<redaction-filter
|
||||
(filtersChanged)="filtersChanged()"
|
||||
[filterLabel]="'filters.needs-work'"
|
||||
[filters]="needsWorkFilters"
|
||||
[hasArrow]="false"
|
||||
[icon]="'red:needs-work'"
|
||||
></redaction-filter>
|
||||
</div>
|
||||
<button
|
||||
(click)="openAddProjectDialog()"
|
||||
@ -94,6 +87,10 @@
|
||||
(toggleSort)="sortingComponent.toggleSort($event)"
|
||||
></redaction-table-col-name>
|
||||
|
||||
<redaction-table-col-name
|
||||
label="project-listing.table-col-names.needs-work"
|
||||
></redaction-table-col-name>
|
||||
|
||||
<redaction-table-col-name
|
||||
label="project-listing.table-col-names.owner"
|
||||
></redaction-table-col-name>
|
||||
@ -152,6 +149,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<redaction-needs-work-badge
|
||||
[needsWorkInput]="pw"
|
||||
[displayed]="true"
|
||||
></redaction-needs-work-badge>
|
||||
</div>
|
||||
<div>
|
||||
<redaction-initials-avatar
|
||||
[userId]="pw.project.ownerId"
|
||||
|
||||
@ -11,10 +11,10 @@
|
||||
width: calc(100vw - #{$right-container-width} - 90px);
|
||||
|
||||
.grid-container {
|
||||
grid-template-columns: 2fr 1fr auto;
|
||||
grid-template-columns: 2fr 1fr 1fr auto;
|
||||
|
||||
&.bulk-select {
|
||||
grid-template-columns: auto 2fr 1fr auto;
|
||||
grid-template-columns: auto 2fr 1fr 1fr auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,11 +10,13 @@ import * as moment from 'moment';
|
||||
import { SortingComponent, SortingOption } from '../../components/sorting/sorting.component';
|
||||
import {
|
||||
addedDateChecker,
|
||||
annotationFilterChecker,
|
||||
dueDateChecker,
|
||||
getFilteredEntities,
|
||||
projectMemberChecker,
|
||||
projectStatusChecker
|
||||
} from '../../common/filter/utils/filter-utils';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-project-listing-screen',
|
||||
@ -32,8 +34,7 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
public statusFilters: FilterModel[];
|
||||
public dueDateFilters: FilterModel[];
|
||||
public peopleFilters: FilterModel[];
|
||||
public addedDateFilters: FilterModel[];
|
||||
|
||||
public needsWorkFilters: FilterModel[];
|
||||
public displayedProjects: ProjectWrapper[] = [];
|
||||
|
||||
@ViewChild('sortingComponent', { static: true }) public sortingComponent: SortingComponent;
|
||||
@ -43,7 +44,8 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
public readonly appStateService: AppStateService,
|
||||
public readonly userService: UserService,
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||
private readonly _dialogService: DialogService
|
||||
private readonly _dialogService: DialogService,
|
||||
private readonly _translateService: TranslateService
|
||||
) {}
|
||||
|
||||
public ngOnInit(): void {
|
||||
@ -158,7 +160,7 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
const allDistinctFileStatus = new Set<string>();
|
||||
const allDistinctPeople = new Set<string>();
|
||||
const allDistinctDueDates = new Set<string>();
|
||||
const allDistinctAddedDates = new Set<string>();
|
||||
const allDistinctNeedsWork = new Set<string>();
|
||||
this.appStateService.allProjects.forEach((entry) => {
|
||||
// all people
|
||||
entry.project.memberIds.forEach((memberId) => allDistinctPeople.add(memberId));
|
||||
@ -166,12 +168,17 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
if (entry.dueDate) {
|
||||
allDistinctDueDates.add(moment(entry.dueDate).format('DD/MM/YYYY'));
|
||||
}
|
||||
// added date
|
||||
allDistinctAddedDates.add(moment(entry.projectDate).format('DD/MM/YYYY'));
|
||||
// file statuses
|
||||
entry.files.forEach((file) => {
|
||||
allDistinctFileStatus.add(file.status);
|
||||
});
|
||||
|
||||
// Needs work
|
||||
entry.files.forEach((file) => {
|
||||
if (file.hasHints) allDistinctNeedsWork.add('hints');
|
||||
if (file.hasRedactions) allDistinctNeedsWork.add('redactions');
|
||||
if (file.hasRequests) allDistinctNeedsWork.add('requests');
|
||||
});
|
||||
});
|
||||
|
||||
this.statusFilters = [];
|
||||
@ -198,11 +205,11 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
});
|
||||
});
|
||||
|
||||
this.addedDateFilters = [];
|
||||
allDistinctAddedDates.forEach((date) => {
|
||||
this.addedDateFilters.push({
|
||||
key: date,
|
||||
label: date
|
||||
this.needsWorkFilters = [];
|
||||
allDistinctNeedsWork.forEach((type) => {
|
||||
this.needsWorkFilters.push({
|
||||
key: type,
|
||||
label: this._translateService.instant('filter.' + type)
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -216,7 +223,7 @@ export class ProjectListingScreenComponent implements OnInit {
|
||||
{ values: this.statusFilters, checker: projectStatusChecker },
|
||||
{ values: this.peopleFilters, checker: projectMemberChecker },
|
||||
{ values: this.dueDateFilters, checker: dueDateChecker },
|
||||
{ values: this.addedDateFilters, checker: addedDateChecker }
|
||||
{ values: this.needsWorkFilters, checker: annotationFilterChecker, matchAll: true }
|
||||
];
|
||||
|
||||
this.displayedProjects = getFilteredEntities(this.appStateService.allProjects, filters);
|
||||
|
||||
@ -27,16 +27,6 @@
|
||||
[hasArrow]="false"
|
||||
[icon]="'red:user'"
|
||||
></redaction-filter>
|
||||
<!-- <button mat-button translate="filters.due-date">-->
|
||||
<!-- <mat-icon svgIcon="red:lightning"></mat-icon>-->
|
||||
<!-- </button>-->
|
||||
<redaction-filter
|
||||
(filtersChanged)="filtersChanged()"
|
||||
[filterLabel]="'filters.created-on'"
|
||||
[filters]="addedDateFilters"
|
||||
[hasArrow]="false"
|
||||
[icon]="'red:calendar'"
|
||||
></redaction-filter>
|
||||
<redaction-filter
|
||||
(filtersChanged)="filtersChanged()"
|
||||
[filterLabel]="'filters.needs-work'"
|
||||
@ -44,12 +34,6 @@
|
||||
[hasArrow]="false"
|
||||
[icon]="'red:needs-work'"
|
||||
></redaction-filter>
|
||||
<!-- <button mat-button translate="filters.project">-->
|
||||
<!-- <mat-icon svgIcon="red:folder"></mat-icon>-->
|
||||
<!-- </button>-->
|
||||
<!-- <button mat-button translate="filters.document">-->
|
||||
<!-- <mat-icon svgIcon="red:document"></mat-icon>-->
|
||||
<!-- </button>-->
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@ -210,21 +194,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!isError(fileStatus)" class="needs-work">
|
||||
<redaction-annotation-icon
|
||||
*ngIf="fileStatus.hasRedactions"
|
||||
[typeValue]="appStateService.getDictionaryTypeValue('redaction')"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="fileStatus.hasHints"
|
||||
[typeValue]="appStateService.getDictionaryTypeValue('hint')"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="fileStatus.hasRequests"
|
||||
[typeValue]="appStateService.getDictionaryTypeValue('request')"
|
||||
></redaction-annotation-icon>
|
||||
<div>
|
||||
<redaction-needs-work-badge
|
||||
[needsWorkInput]="fileStatus"
|
||||
[displayed]="!isError(fileStatus)"
|
||||
></redaction-needs-work-badge>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!isError(fileStatus)" class="assigned-to">
|
||||
<redaction-initials-avatar
|
||||
[userId]="fileStatus.currentReviewer"
|
||||
|
||||
@ -37,14 +37,6 @@
|
||||
max-width: 25vw;
|
||||
}
|
||||
|
||||
.needs-work {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.pages {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
@ -40,7 +40,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
|
||||
public statusFilters: FilterModel[];
|
||||
public peopleFilters: FilterModel[];
|
||||
public addedDateFilters: FilterModel[];
|
||||
// public addedDateFilters: FilterModel[];
|
||||
public needsWorkFilters: FilterModel[];
|
||||
|
||||
public displayedFiles: FileStatusWrapper[] = [];
|
||||
@ -305,14 +305,6 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
});
|
||||
|
||||
this.addedDateFilters = [];
|
||||
allDistinctAddedDates.forEach((date) => {
|
||||
this.addedDateFilters.push({
|
||||
key: date,
|
||||
label: date
|
||||
});
|
||||
});
|
||||
|
||||
this.needsWorkFilters = [];
|
||||
allDistinctNeedsWork.forEach((type) => {
|
||||
this.needsWorkFilters.push({
|
||||
@ -330,7 +322,6 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
const filters = [
|
||||
{ values: this.statusFilters, checker: keyChecker('status') },
|
||||
{ values: this.peopleFilters, checker: keyChecker('currentReviewer') },
|
||||
{ values: this.addedDateFilters, checker: fileAddedFilterChecker },
|
||||
{ values: this.needsWorkFilters, checker: annotationFilterChecker, matchAll: true }
|
||||
];
|
||||
this.displayedFiles = getFilteredEntities(
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { EventEmitter, Injectable } from '@angular/core';
|
||||
import {
|
||||
DictionaryControllerService,
|
||||
FileStatus,
|
||||
FileUploadControllerService,
|
||||
Project,
|
||||
ProjectControllerService,
|
||||
@ -9,7 +8,6 @@ import {
|
||||
StatusControllerService,
|
||||
TypeValue,
|
||||
VersionsControllerService,
|
||||
ViewedPages,
|
||||
ViewedPagesControllerService
|
||||
} from '@redaction/red-ui-http';
|
||||
import { NotificationService, NotificationType } from '../notification/notification.service';
|
||||
@ -38,11 +36,24 @@ export interface AppState {
|
||||
export class ProjectWrapper {
|
||||
totalNumberOfPages?: number;
|
||||
|
||||
hasStatus(status: string) {
|
||||
return this.files.find((f) => f.status === status);
|
||||
hasHints?: boolean;
|
||||
hasRedactions?: boolean;
|
||||
hasRequests?: boolean;
|
||||
private _files: FileStatusWrapper[];
|
||||
|
||||
constructor(public project: Project, files: FileStatusWrapper[]) {
|
||||
this._files = files ? files : [];
|
||||
this._recomputeFileStatus();
|
||||
}
|
||||
|
||||
constructor(public project: Project, public files: FileStatusWrapper[]) {}
|
||||
set files(files: FileStatusWrapper[]) {
|
||||
this._files = files ? files : [];
|
||||
this._recomputeFileStatus();
|
||||
}
|
||||
|
||||
get files() {
|
||||
return this._files;
|
||||
}
|
||||
|
||||
get projectDate() {
|
||||
return this.project.date;
|
||||
@ -52,6 +63,14 @@ export class ProjectWrapper {
|
||||
return this.project.dueDate;
|
||||
}
|
||||
|
||||
get hasFiles() {
|
||||
return this._files.length > 0;
|
||||
}
|
||||
|
||||
hasStatus(status: string) {
|
||||
return this._files.find((f) => f.status === status);
|
||||
}
|
||||
|
||||
hasMember(key: string) {
|
||||
return this.project.memberIds.indexOf(key) >= 0;
|
||||
}
|
||||
@ -64,8 +83,15 @@ export class ProjectWrapper {
|
||||
return moment(this.projectDate).format('DD/MM/YYYY') === key;
|
||||
}
|
||||
|
||||
get hasFiles() {
|
||||
return this.files?.length > 0;
|
||||
private _recomputeFileStatus() {
|
||||
this.hasHints = false;
|
||||
this.hasRedactions = false;
|
||||
this.hasRequests = false;
|
||||
this._files.forEach((f) => {
|
||||
this.hasHints = this.hasHints || f.hasHints;
|
||||
this.hasRedactions = this.hasRedactions || f.hasRedactions;
|
||||
this.hasRequests = this.hasRequests || f.hasRequests;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -90,7 +90,7 @@
|
||||
"created-on": "Created On",
|
||||
"project": "Project",
|
||||
"document": "Document",
|
||||
"needs-work": "Needs Work"
|
||||
"needs-work": "Analysed"
|
||||
},
|
||||
"project-listing": {
|
||||
"report": {
|
||||
@ -109,6 +109,7 @@
|
||||
},
|
||||
"table-col-names": {
|
||||
"name": "Document",
|
||||
"needs-work": "Analysed",
|
||||
"owner": "Owner",
|
||||
"status": "Status"
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user