Pull request #43: Refactor buttons
Merge in RED/ui from buttons to master * commit '794716c3172cbee3755bf8e0e1ae6dcf767decc4': Refactor buttons
This commit is contained in:
commit
4eaf13c164
@ -79,6 +79,10 @@ import { DictionaryAnnotationIconComponent } from './components/dictionary-annot
|
||||
import { BulkActionsComponent } from './screens/project-overview-screen/bulk-actions/bulk-actions.component';
|
||||
import { HttpCacheInterceptor } from '@redaction/red-cache';
|
||||
import { HiddenActionComponent } from './common/hidden-action/hidden-action.component';
|
||||
import { IconButtonComponent } from './components/buttons/icon-button/icon-button.component';
|
||||
import { UserButtonComponent } from './components/buttons/user-button/user-button.component';
|
||||
import { CircleButtonComponent } from './components/buttons/circle-button/circle-button.component';
|
||||
import { ChevronButtonComponent } from './components/buttons/chevron-button/chevron-button.component';
|
||||
|
||||
export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
|
||||
@ -125,7 +129,11 @@ export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
DictionaryAnnotationIconComponent,
|
||||
BulkActionsComponent,
|
||||
FileActionsComponent,
|
||||
HiddenActionComponent
|
||||
HiddenActionComponent,
|
||||
IconButtonComponent,
|
||||
UserButtonComponent,
|
||||
CircleButtonComponent,
|
||||
ChevronButtonComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
||||
@ -1,107 +1,102 @@
|
||||
<div class="file-actions">
|
||||
<button
|
||||
(click)="reanalyseFile($event, fileStatus)"
|
||||
<redaction-circle-button
|
||||
(action)="reanalyseFile($event, fileStatus)"
|
||||
*ngIf="permissionsService.canReanalyseFile(fileStatus) && screen === 'file-preview'"
|
||||
[matTooltip]="'file-preview.reanalyse-notification' | translate"
|
||||
class="warn"
|
||||
mat-icon-button
|
||||
matTooltipClass="warn small"
|
||||
tooltip="file-preview.reanalyse-notification"
|
||||
type="warn"
|
||||
tooltipClass="warn small"
|
||||
icon="red:refresh"
|
||||
>
|
||||
<mat-icon svgIcon="red:refresh"></mat-icon>
|
||||
</button>
|
||||
</redaction-circle-button>
|
||||
|
||||
<button
|
||||
(click)="reanalyseFile($event, fileStatus)"
|
||||
*ngIf="permissionsService.canReanalyseFile(fileStatus) && screen !== 'file-preview'"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
[matTooltip]="'project-overview.reanalyse.action' | translate"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
<redaction-circle-button
|
||||
(action)="reanalyseFile($event, fileStatus)"
|
||||
*ngIf="permissionsService.canReanalyseFile(fileStatus) && screen === 'project-overview'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
tooltip="project-overview.reanalyse.action"
|
||||
icon="red:refresh"
|
||||
type="dark-bg"
|
||||
>
|
||||
<mat-icon svgIcon="red:refresh"></mat-icon>
|
||||
</button>
|
||||
</redaction-circle-button>
|
||||
|
||||
<button
|
||||
(click)="assignReviewer($event, fileStatus)"
|
||||
*ngIf="permissionsService.canAssignReviewer(fileStatus) && screen !== 'file-preview'"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
[matTooltip]="'project-overview.assign.action' | translate"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
>
|
||||
<mat-icon svgIcon="red:assign" *ngIf="permissionsService.isManagerAndOwner()"></mat-icon>
|
||||
<mat-icon svgIcon="red:assign-me" *ngIf="!permissionsService.isManagerAndOwner()"></mat-icon>
|
||||
</button>
|
||||
|
||||
<button
|
||||
(click)="openDeleteFileDialog($event, fileStatus)"
|
||||
<redaction-circle-button
|
||||
(action)="openDeleteFileDialog($event, fileStatus)"
|
||||
*ngIf="permissionsService.canDeleteFile(fileStatus)"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
[matTooltip]="'project-overview.delete.action' | translate"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
tooltip="project-overview.delete.action"
|
||||
icon="red:trash"
|
||||
[type]="buttonType"
|
||||
>
|
||||
<mat-icon svgIcon="red:trash"></mat-icon>
|
||||
</button>
|
||||
<div
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="downloadFileRedactionReport($event, fileStatus)"
|
||||
*ngIf="permissionsService.canShowRedactionReportDownloadBtn(fileStatus)"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
[matTooltip]="(fileStatus.isApproved ? 'report.action' : 'report.unavailable-single') | translate"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="fileStatus.isApproved ? 'report.action' : 'report.unavailable-single'"
|
||||
[disabled]="!fileStatus.isApproved"
|
||||
icon="red:report"
|
||||
[type]="buttonType"
|
||||
>
|
||||
<button (click)="downloadFileRedactionReport($event, fileStatus)" [disabled]="!fileStatus.isApproved" color="accent" mat-icon-button>
|
||||
<mat-icon svgIcon="red:report"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</redaction-circle-button>
|
||||
|
||||
<button
|
||||
(click)="downloadFile($event, fileStatus)"
|
||||
<redaction-circle-button
|
||||
(action)="assignReviewer($event, fileStatus)"
|
||||
*ngIf="permissionsService.canAssignReviewer(fileStatus)"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
tooltip="project-overview.assign.action"
|
||||
[icon]="permissionsService.isManagerAndOwner() ? 'red:assign' : 'red-assign-me'"
|
||||
[type]="buttonType"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="downloadFile($event, fileStatus)"
|
||||
*ngIf="permissionsService.canDownloadRedactedFile(fileStatus)"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
[matTooltip]="'project-overview.download-redacted-file' | translate"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
tooltip="project-overview.download-redacted-file"
|
||||
icon="red:download"
|
||||
[type]="buttonType"
|
||||
>
|
||||
<mat-icon svgIcon="red:download"></mat-icon>
|
||||
</button>
|
||||
</redaction-circle-button>
|
||||
|
||||
<button
|
||||
(click)="setFileApproved($event, fileStatus)"
|
||||
<redaction-circle-button
|
||||
(action)="setFileApproved($event, fileStatus)"
|
||||
*ngIf="permissionsService.canApprove(fileStatus)"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
[matTooltip]="'project-overview.approve' | translate"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
tooltip="project-overview.approve"
|
||||
icon="red:check-alt"
|
||||
[type]="buttonType"
|
||||
>
|
||||
<mat-icon svgIcon="red:check-alt"></mat-icon>
|
||||
</button>
|
||||
<button
|
||||
(click)="setFileUnderApproval($event, fileStatus)"
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="setFileUnderApproval($event, fileStatus)"
|
||||
*ngIf="permissionsService.canSetUnderApproval(fileStatus)"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
[matTooltip]="'project-overview.under-approval' | translate"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
tooltip="project-overview.under-approval"
|
||||
icon="red:check-alt"
|
||||
[type]="buttonType"
|
||||
>
|
||||
<mat-icon svgIcon="red:check-alt"></mat-icon>
|
||||
</button>
|
||||
<button
|
||||
(click)="setFileUnderApproval($event, fileStatus)"
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="setFileUnderApproval($event, fileStatus)"
|
||||
*ngIf="permissionsService.canUndoApproval(fileStatus)"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
[matTooltip]="'project-overview.under-approval' | translate"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
tooltip="project-overview.under-approval"
|
||||
icon="red:undo"
|
||||
[type]="buttonType"
|
||||
>
|
||||
<mat-icon svgIcon="red:undo"></mat-icon>
|
||||
</button>
|
||||
<button
|
||||
(click)="setFileUnderReview($event, fileStatus)"
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="setFileUnderReview($event, fileStatus)"
|
||||
*ngIf="permissionsService.canUndoUnderApproval(fileStatus)"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
[matTooltip]="'project-overview.under-review' | translate"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
tooltip="project-overview.under-review"
|
||||
icon="red:undo"
|
||||
[type]="buttonType"
|
||||
>
|
||||
<mat-icon svgIcon="red:undo"></mat-icon>
|
||||
</button>
|
||||
</redaction-circle-button>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
.file-actions {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.reviewer {
|
||||
|
||||
@ -44,6 +44,10 @@ export class FileActionsComponent implements OnInit {
|
||||
return this.screen === 'file-preview' ? 'below' : 'above';
|
||||
}
|
||||
|
||||
public get buttonType() {
|
||||
return this.screen === 'file-preview' ? 'default' : 'dark-bg';
|
||||
}
|
||||
|
||||
openDeleteFileDialog($event: MouseEvent, fileStatusWrapper: FileStatusWrapper) {
|
||||
this._dialogService.openDeleteFilesDialog($event, fileStatusWrapper.projectId, [fileStatusWrapper.fileId], () => {
|
||||
this.actionPerformed.emit('delete');
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
<div class="filter-root">
|
||||
<button color="accent" mat-button [class.arrow-button]="hasArrow" [matMenuTriggerFor]="filterMenu" [ngClass]="{ overlay: hasActiveFilters }">
|
||||
<mat-icon [svgIcon]="icon" *ngIf="icon"></mat-icon>
|
||||
<span [translate]="filterLabel"></span>
|
||||
<mat-icon svgIcon="red:arrow-down" *ngIf="hasArrow"></mat-icon>
|
||||
</button>
|
||||
<div class="dot" *ngIf="hasActiveFilters"></div>
|
||||
<redaction-icon-button
|
||||
*ngIf="!chevron"
|
||||
[text]="filterLabel"
|
||||
[icon]="icon"
|
||||
[matMenuTriggerFor]="filterMenu"
|
||||
[showDot]="hasActiveFilters"
|
||||
></redaction-icon-button>
|
||||
<redaction-chevron-button *ngIf="chevron" [text]="filterLabel" [matMenuTriggerFor]="filterMenu" [showDot]="hasActiveFilters"></redaction-chevron-button>
|
||||
<mat-menu #filterMenu="matMenu" xPosition="before" (closed)="applyFilters()">
|
||||
<div (mouseleave)="filterMouseLeave()" (mouseenter)="filterMouseEnter()">
|
||||
<div class="filter-menu-header">
|
||||
|
||||
@ -1,19 +1,5 @@
|
||||
@import '../../../assets/styles/red-variables';
|
||||
|
||||
.filter-root {
|
||||
position: relative;
|
||||
|
||||
.dot {
|
||||
background: $primary;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-menu-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, EventEmitter, Input, Output, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { AppStateService } from '../../state/app-state.service';
|
||||
import { FilterModel } from './model/filter.model';
|
||||
import { handleCheckedValue } from './utils/filter-utils';
|
||||
import { MatMenu, MatMenuTrigger } from '@angular/material/menu';
|
||||
import { MatMenuTrigger } from '@angular/material/menu';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-filter',
|
||||
@ -10,12 +10,12 @@ import { MatMenu, MatMenuTrigger } from '@angular/material/menu';
|
||||
styleUrls: ['./filter.component.scss']
|
||||
})
|
||||
export class FilterComponent {
|
||||
@Input() filterTemplate: TemplateRef<any>;
|
||||
@Output() filtersChanged = new EventEmitter<FilterModel[]>();
|
||||
@Input() filterTemplate: TemplateRef<any>;
|
||||
@Input() filters: FilterModel[] = [];
|
||||
@Input() filterLabel = 'filter-menu.label';
|
||||
@Input() hasArrow = true;
|
||||
@Input() icon: string;
|
||||
@Input() chevron = false;
|
||||
|
||||
@ViewChild(MatMenuTrigger) trigger: MatMenuTrigger;
|
||||
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
<div class="flex-row">
|
||||
<div
|
||||
[className]="colorClass + ' oval ' + size"
|
||||
[matTooltipPosition]="'above'"
|
||||
[matTooltip]="username"
|
||||
>
|
||||
<div class="wrapper">
|
||||
<div [className]="colorClass + ' oval ' + size" [matTooltipPosition]="'above'" [matTooltip]="username">
|
||||
{{ initials }}
|
||||
</div>
|
||||
<div *ngIf="withName" class="clamp-2">
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
@import '../../../assets/styles/red-variables';
|
||||
|
||||
.flex-row {
|
||||
.wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: fit-content;
|
||||
gap: 12px;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
<button mat-button [class.overlay]="showDot" [class.primary]="primary">
|
||||
<span [translate]="text"></span>
|
||||
<mat-icon svgIcon="red:arrow-down" class="chevron-icon"></mat-icon>
|
||||
</button>
|
||||
<div class="dot" *ngIf="showDot"></div>
|
||||
@ -0,0 +1,8 @@
|
||||
button {
|
||||
padding: 0 10px 0 14px;
|
||||
|
||||
mat-icon {
|
||||
width: 7px;
|
||||
margin: 0 3.5px;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-chevron-button',
|
||||
templateUrl: './chevron-button.component.html',
|
||||
styleUrls: ['./chevron-button.component.scss']
|
||||
})
|
||||
export class ChevronButtonComponent implements OnInit {
|
||||
@Input() text: string;
|
||||
@Input() showDot = false;
|
||||
@Input() primary = false;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
<div [matTooltipClass]="tooltipClass" [matTooltipPosition]="tooltipPosition" [matTooltip]="tooltip | translate">
|
||||
<button
|
||||
(click)="action.emit($event)"
|
||||
[class.dark-bg]="type === 'dark-bg'"
|
||||
[class.primary]="type === 'primary'"
|
||||
[class.warn]="type === 'warn'"
|
||||
[disabled]="disabled"
|
||||
mat-icon-button
|
||||
>
|
||||
<mat-icon [svgIcon]="icon"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
@ -0,0 +1,25 @@
|
||||
@import '../../../../assets/styles/red-variables';
|
||||
|
||||
button {
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
line-height: 34px;
|
||||
|
||||
mat-icon {
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
&.primary {
|
||||
&.mat-button-disabled {
|
||||
background-color: $grey-6;
|
||||
color: $white !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.warn {
|
||||
background-color: $yellow-2;
|
||||
&:hover {
|
||||
background-color: $yellow-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-circle-button',
|
||||
templateUrl: './circle-button.component.html',
|
||||
styleUrls: ['./circle-button.component.scss']
|
||||
})
|
||||
export class CircleButtonComponent implements OnInit {
|
||||
@Input() icon: string;
|
||||
@Input() tooltip: string;
|
||||
@Input() tooltipPosition: 'above' | 'below' | 'before' | 'after' = 'above';
|
||||
@Input() tooltipClass: string;
|
||||
@Input() disabled = false;
|
||||
@Input() type: 'default' | 'primary' | 'warn' | 'dark-bg' = 'default';
|
||||
@Output() action = new EventEmitter<any>();
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
<button mat-button [class.overlay]="showDot" [class.primary]="primary" (click)="action.emit($event)">
|
||||
<mat-icon [svgIcon]="icon" *ngIf="icon"></mat-icon>
|
||||
<span [translate]="text"></span>
|
||||
</button>
|
||||
<div class="dot" *ngIf="showDot"></div>
|
||||
@ -0,0 +1,7 @@
|
||||
button {
|
||||
padding: 0 14px 0 10px;
|
||||
|
||||
mat-icon {
|
||||
width: 14px;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-icon-button',
|
||||
templateUrl: './icon-button.component.html',
|
||||
styleUrls: ['./icon-button.component.scss']
|
||||
})
|
||||
export class IconButtonComponent implements OnInit {
|
||||
@Input() icon: string;
|
||||
@Input() text: string;
|
||||
@Input() showDot = false;
|
||||
@Input() primary = false;
|
||||
@Output() action = new EventEmitter<any>();
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
<button mat-button>
|
||||
<redaction-initials-avatar color="red-white" size="small" [userId]="user?.id" [withName]="true"></redaction-initials-avatar>
|
||||
<mat-icon svgIcon="red:arrow-down"></mat-icon>
|
||||
</button>
|
||||
@ -0,0 +1,23 @@
|
||||
@import '../../../../assets/styles/red-variables';
|
||||
|
||||
:host {
|
||||
button {
|
||||
padding: 0 10px 0 5px;
|
||||
font-weight: 400 !important;
|
||||
|
||||
&:hover {
|
||||
background-color: $grey-6;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
width: 7px;
|
||||
margin: 0 3.5px;
|
||||
}
|
||||
}
|
||||
|
||||
&[aria-expanded='true'] {
|
||||
button {
|
||||
background: rgba($primary, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { UserWrapper } from '../../../user/user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-user-button',
|
||||
templateUrl: './user-button.component.html',
|
||||
styleUrls: ['./user-button.component.scss']
|
||||
})
|
||||
export class UserButtonComponent implements OnInit {
|
||||
@Input() user: UserWrapper;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
}
|
||||
@ -1,10 +1,10 @@
|
||||
<div class="wrapper">
|
||||
<ng-container *ngIf="expanded">
|
||||
<div *ngFor="let comment of annotation.comments; let idx = index" class="comment">
|
||||
<div class="comment-icon" [class.red]="isCommentOwner(comment)" [class.comment-owner]="isCommentOwner(comment)">
|
||||
<div [class.comment-owner]="isCommentOwner(comment)" [class.red]="isCommentOwner(comment)" class="comment-icon">
|
||||
<mat-icon [svgIcon]="isCommentOwner(comment) ? 'red:comment-fill' : 'red:comment'"></mat-icon>
|
||||
</div>
|
||||
<div class="trash-icon red" (click)="deleteComment(comment)" [class.comment-owner]="isCommentOwner(comment)">
|
||||
<div (click)="deleteComment(comment)" [class.comment-owner]="isCommentOwner(comment)" class="trash-icon red">
|
||||
<mat-icon svgIcon="red:trash"></mat-icon>
|
||||
</div>
|
||||
|
||||
@ -25,19 +25,17 @@
|
||||
})
|
||||
}}
|
||||
</div>
|
||||
<div *ngIf="!addingComment" (click)="toggleAddingComment($event)" translate="comments.add-comment"></div>
|
||||
<div (click)="toggleAddingComment($event)" *ngIf="!addingComment" translate="comments.add-comment"></div>
|
||||
</div>
|
||||
|
||||
<form *ngIf="addingComment" [formGroup]="commentForm" (submit)="addComment()">
|
||||
<form (submit)="addComment()" *ngIf="addingComment" [formGroup]="commentForm">
|
||||
<div class="red-input-group">
|
||||
<input formControlName="comment" name="comment" type="text" [placeholder]="translateService.instant('comments.add-comment')" />
|
||||
<input [placeholder]="translateService.instant('comments.add-comment')" formControlName="comment" name="comment" type="text" />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div *ngIf="addingComment" class="comment-actions-container">
|
||||
<button (click)="addComment()" mat-icon-button class="primary" [disabled]="!commentForm.value.comment">
|
||||
<mat-icon svgIcon="red:check-alt"></mat-icon>
|
||||
</button>
|
||||
<redaction-circle-button (action)="addComment()" [disabled]="!commentForm.value.comment" icon="red:check-alt" type="primary"></redaction-circle-button>
|
||||
<div (click)="toggleAddingComment($event)" class="all-caps-label" translate="comments.cancel"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -42,6 +42,9 @@ export class CommentsComponent {
|
||||
public toggleAddingComment($event?: MouseEvent): void {
|
||||
$event?.stopPropagation();
|
||||
this.addingComment = !this.addingComment;
|
||||
if (this.addingComment) {
|
||||
this.expanded = true;
|
||||
}
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
@ -54,7 +57,6 @@ export class CommentsComponent {
|
||||
id: commentResponse.commentId,
|
||||
user: this._userService.userId
|
||||
});
|
||||
this.expanded = true;
|
||||
});
|
||||
this.commentForm.reset();
|
||||
this.toggleAddingComment();
|
||||
|
||||
@ -5,26 +5,13 @@
|
||||
<mat-icon svgIcon="red:menu"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuNav="matMenu">
|
||||
<button
|
||||
mat-menu-item
|
||||
routerLink="/ui/projects"
|
||||
translate="top-bar.navigation-items.projects"
|
||||
></button>
|
||||
<button
|
||||
*ngIf="appStateService.activeProject"
|
||||
[routerLink]="'/ui/projects/' + appStateService.activeProjectId"
|
||||
mat-menu-item
|
||||
>
|
||||
<button mat-menu-item routerLink="/ui/projects" translate="top-bar.navigation-items.projects"></button>
|
||||
<button *ngIf="appStateService.activeProject" [routerLink]="'/ui/projects/' + appStateService.activeProjectId" mat-menu-item>
|
||||
{{ appStateService.activeProject.project.projectName }}
|
||||
</button>
|
||||
<button
|
||||
*ngIf="appStateService.activeFile"
|
||||
[routerLink]="
|
||||
'/ui/projects/' +
|
||||
appStateService.activeProjectId +
|
||||
'/file/' +
|
||||
appStateService.activeFile.fileId
|
||||
"
|
||||
[routerLink]="'/ui/projects/' + appStateService.activeProjectId + '/file/' + appStateService.activeFile.fileId"
|
||||
mat-menu-item
|
||||
>
|
||||
{{ appStateService.activeFile.filename }}
|
||||
@ -32,19 +19,11 @@
|
||||
</mat-menu>
|
||||
</div>
|
||||
<div class="menu flex-2 visible-lg breadcrumbs-container">
|
||||
<a
|
||||
class="breadcrumb"
|
||||
routerLink="/ui/projects"
|
||||
translate="top-bar.navigation-items.projects"
|
||||
></a>
|
||||
<a class="breadcrumb" routerLink="/ui/projects" translate="top-bar.navigation-items.projects"></a>
|
||||
<div *ngIf="appStateService.activeProject" class="breadcrumb">
|
||||
<mat-icon svgIcon="red:arrow-right"></mat-icon>
|
||||
</div>
|
||||
<a
|
||||
*ngIf="appStateService.activeProject"
|
||||
class="breadcrumb"
|
||||
[routerLink]="'/ui/projects/' + appStateService.activeProjectId"
|
||||
>
|
||||
<a *ngIf="appStateService.activeProject" class="breadcrumb" [routerLink]="'/ui/projects/' + appStateService.activeProjectId">
|
||||
{{ appStateService.activeProject.project.projectName }}
|
||||
</a>
|
||||
<div *ngIf="appStateService.activeFile" class="breadcrumb">
|
||||
@ -53,12 +32,7 @@
|
||||
<a
|
||||
*ngIf="appStateService.activeFile"
|
||||
class="breadcrumb"
|
||||
[routerLink]="
|
||||
'/ui/projects/' +
|
||||
appStateService.activeProjectId +
|
||||
'/file/' +
|
||||
appStateService.activeFile.fileId
|
||||
"
|
||||
[routerLink]="'/ui/projects/' + appStateService.activeProjectId + '/file/' + appStateService.activeFile.fileId"
|
||||
>
|
||||
{{ appStateService.activeFile.filename }}
|
||||
</a>
|
||||
@ -68,32 +42,12 @@
|
||||
<div class="app-name" translate="app-name"></div>
|
||||
</div>
|
||||
<div class="menu right flex-2">
|
||||
<button [matMenuTriggerFor]="menu" mat-button class="arrow-button">
|
||||
<redaction-initials-avatar
|
||||
color="red-white"
|
||||
size="small"
|
||||
[userId]="user?.id"
|
||||
[withName]="true"
|
||||
></redaction-initials-avatar>
|
||||
<mat-icon svgIcon="red:arrow-down"></mat-icon>
|
||||
</button>
|
||||
<redaction-user-button [user]="user" [matMenuTriggerFor]="menu"></redaction-user-button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button
|
||||
[matMenuTriggerFor]="language"
|
||||
mat-menu-item
|
||||
translate="top-bar.navigation-items.my-account.children.language.label"
|
||||
></button>
|
||||
<button [matMenuTriggerFor]="language" mat-menu-item translate="top-bar.navigation-items.my-account.children.language.label"></button>
|
||||
<mat-menu #language="matMenu">
|
||||
<button
|
||||
(click)="changeLanguage('en')"
|
||||
mat-menu-item
|
||||
translate="top-bar.navigation-items.my-account.children.language.english"
|
||||
></button>
|
||||
<button
|
||||
(click)="changeLanguage('de')"
|
||||
mat-menu-item
|
||||
translate="top-bar.navigation-items.my-account.children.language.german"
|
||||
></button>
|
||||
<button (click)="changeLanguage('en')" mat-menu-item translate="top-bar.navigation-items.my-account.children.language.english"></button>
|
||||
<button (click)="changeLanguage('de')" mat-menu-item translate="top-bar.navigation-items.my-account.children.language.german"></button>
|
||||
</mat-menu>
|
||||
<button (click)="logout()" mat-menu-item>
|
||||
<mat-icon svgIcon="red:logout"> </mat-icon>
|
||||
|
||||
@ -1,46 +1,51 @@
|
||||
<div [class.visible]="menuOpen" *ngIf="canPerformAnnotationActions" class="annotation-actions">
|
||||
<button
|
||||
(click)="acceptSuggestion($event, annotation)"
|
||||
mat-icon-button
|
||||
<redaction-circle-button
|
||||
(action)="acceptSuggestion($event, annotation)"
|
||||
type="dark-bg"
|
||||
*ngIf="canAcceptSuggestion"
|
||||
[matTooltip]="'annotation-actions.accept-suggestion.label' | translate"
|
||||
tooltip="annotation-actions.accept-suggestion.label"
|
||||
icon="red:check-alt"
|
||||
>
|
||||
<mat-icon svgIcon="red:check-alt"></mat-icon>
|
||||
</button>
|
||||
</redaction-circle-button>
|
||||
|
||||
<button (click)="undoDirectAction($event, annotation)" *ngIf="canUndoAnnotation" mat-icon-button>
|
||||
<mat-icon svgIcon="red:undo" [matTooltip]="'annotation-actions.undo' | translate"></mat-icon>
|
||||
</button>
|
||||
<redaction-circle-button
|
||||
(action)="undoDirectAction($event, annotation)"
|
||||
*ngIf="canUndoAnnotation"
|
||||
type="dark-bg"
|
||||
icon="red:undo"
|
||||
tooltip="annotation-actions.undo"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<button
|
||||
(click)="rejectSuggestion($event, annotation)"
|
||||
mat-icon-button
|
||||
<redaction-circle-button
|
||||
(action)="rejectSuggestion($event, annotation)"
|
||||
type="dark-bg"
|
||||
icon="red:close"
|
||||
*ngIf="canRejectSuggestion"
|
||||
[matTooltip]="'annotation-actions.reject-suggestion' | translate"
|
||||
tooltip="annotation-actions.reject-suggestion"
|
||||
>
|
||||
<mat-icon svgIcon="red:close"></mat-icon>
|
||||
</button>
|
||||
</redaction-circle-button>
|
||||
|
||||
<button
|
||||
(click)="suggestRemoveAnnotation($event, annotation, true)"
|
||||
mat-icon-button
|
||||
<redaction-circle-button
|
||||
(action)="suggestRemoveAnnotation($event, annotation, true)"
|
||||
type="dark-bg"
|
||||
icon="red:trash"
|
||||
*ngIf="canDirectlySuggestToRemoveAnnotation"
|
||||
[matTooltip]="'annotation-actions.suggest-remove-annotation' | translate"
|
||||
tooltip="annotation-actions.suggest-remove-annotation"
|
||||
>
|
||||
<mat-icon svgIcon="red:trash"></mat-icon>
|
||||
</button>
|
||||
</redaction-circle-button>
|
||||
|
||||
<button
|
||||
(click)="openMenu($event)"
|
||||
<redaction-circle-button
|
||||
*ngIf="requiresSuggestionRemoveMenu"
|
||||
(action)="openMenu($event)"
|
||||
[class.active]="menuOpen"
|
||||
[matMenuTriggerFor]="menu"
|
||||
[matTooltip]="'annotation-actions.suggest-remove-annotation' | translate"
|
||||
class="confirm"
|
||||
mat-icon-button
|
||||
*ngIf="requiresSuggestionRemoveMenu"
|
||||
tooltip="annotation-actions.suggest-remove-annotation"
|
||||
type="dark-bg"
|
||||
icon="red:trash"
|
||||
>
|
||||
<mat-icon svgIcon="red:trash"></mat-icon>
|
||||
</button>
|
||||
</redaction-circle-button>
|
||||
|
||||
<mat-menu #menu="matMenu" (closed)="onMenuClosed()" xPosition="before">
|
||||
<div (click)="suggestRemoveAnnotation($event, annotation, true)" mat-menu-item>
|
||||
<redaction-annotation-icon [type]="'rhombus'" [label]="'S'" [color]="dictionaryColor"></redaction-annotation-icon>
|
||||
|
||||
@ -106,8 +106,4 @@ export class AnnotationActionsComponent implements OnInit {
|
||||
get dictionaryColor() {
|
||||
return this.appStateService.getDictionaryColor('suggestion-add-dictionary');
|
||||
}
|
||||
|
||||
get suggestRemoveLabel() {
|
||||
return 'suggestRemoveLabel';
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,10 +26,10 @@
|
||||
]"
|
||||
>
|
||||
</redaction-status-bar>
|
||||
<div class="all-caps-label mr-8">{{ appStateService.activeFile.status.toLowerCase().replace('_', '-') | translate }}</div>
|
||||
<div class="all-caps-label mr-16 ml-8">{{ appStateService.activeFile.status.toLowerCase().replace('_', '-') | translate }}</div>
|
||||
<redaction-initials-avatar
|
||||
[userId]="appStateService.activeFile.currentReviewer"
|
||||
[withName]="appStateService.activeFile.currentReviewer"
|
||||
[withName]="!!appStateService.activeFile.currentReviewer"
|
||||
></redaction-initials-avatar>
|
||||
<div
|
||||
*ngIf="!appStateService.activeFile.currentReviewer && permissionsService.canAssignReviewer(appStateService.activeFile)"
|
||||
@ -37,29 +37,37 @@
|
||||
translate="file-preview.assign-reviewer"
|
||||
(click)="assignReviewer()"
|
||||
></div>
|
||||
<button
|
||||
mat-icon-button
|
||||
matTooltipPosition="below"
|
||||
[matTooltip]="'project-overview.assign.action' | translate"
|
||||
*ngIf="permissionsService.canAssignReviewer(appStateService.activeFile) && appStateService.activeFile.currentReviewer"
|
||||
(click)="assignReviewer()"
|
||||
>
|
||||
<mat-icon svgIcon="red:edit"></mat-icon>
|
||||
</button>
|
||||
<button
|
||||
mat-icon-button
|
||||
matTooltipPosition="below"
|
||||
[matTooltip]="'file-preview.assign-me' | translate"
|
||||
*ngIf="permissionsService.canAssignReviewer(appStateService.activeFile) && !permissionsService.isFileReviewer()"
|
||||
(click)="assignToMe()"
|
||||
>
|
||||
<mat-icon svgIcon="red:assign-me"></mat-icon>
|
||||
</button>
|
||||
|
||||
<div class="assign-actions-wrapper" *ngIf="permissionsService.canAssignReviewer(appStateService.activeFile)">
|
||||
<redaction-circle-button
|
||||
tooltipPosition="below"
|
||||
tooltip="project-overview.assign.action"
|
||||
*ngIf="permissionsService.canAssignReviewer(appStateService.activeFile) && appStateService.activeFile.currentReviewer"
|
||||
(action)="assignReviewer()"
|
||||
icon="red:edit"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
tooltipPosition="below"
|
||||
tooltip="file-preview.assign-me"
|
||||
*ngIf="permissionsService.canAssignReviewer(appStateService.activeFile) && !permissionsService.isFileReviewer()"
|
||||
(action)="assignToMe()"
|
||||
icon="red:assign-me"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
</div>
|
||||
|
||||
<div class="vertical-line"></div>
|
||||
|
||||
<redaction-file-actions (actionPerformed)="fileActionPerformed($event)" *ngIf="viewReady"></redaction-file-actions>
|
||||
<button [routerLink]="['/ui/projects/' + appStateService.activeProjectId]" mat-icon-button [matTooltip]="'common.close' | translate">
|
||||
<mat-icon svgIcon="red:close"></mat-icon>
|
||||
</button>
|
||||
<redaction-circle-button
|
||||
class="ml-8"
|
||||
[routerLink]="['/ui/projects/' + appStateService.activeProjectId]"
|
||||
tooltip="common.close"
|
||||
tooltipPosition="below"
|
||||
icon="red:close"
|
||||
></redaction-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -87,6 +95,7 @@
|
||||
(filtersChanged)="filtersChanged($event)"
|
||||
[filterTemplate]="annotationFilterTemplate"
|
||||
[filters]="annotationFilters"
|
||||
[chevron]="true"
|
||||
></redaction-filter>
|
||||
</div>
|
||||
</redaction-hidden-action>
|
||||
|
||||
@ -13,14 +13,11 @@ redaction-pdf-viewer {
|
||||
width: 1px;
|
||||
height: 30px;
|
||||
background-color: $grey-4;
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
.mr-8 {
|
||||
margin-right: 8px;
|
||||
margin: 0 16px;
|
||||
}
|
||||
|
||||
.assign-reviewer {
|
||||
margin-left: 6px;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@ -28,7 +25,6 @@ redaction-pdf-viewer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.right-fixed-container {
|
||||
@ -128,3 +124,21 @@ redaction-pdf-viewer {
|
||||
padding: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.assign-actions-wrapper {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.mr-8 {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.mr-16 {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.ml-8 {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
@ -1,18 +1,16 @@
|
||||
<section *ngIf="appStateService.hasProjects">
|
||||
<div class="page-header">
|
||||
<div class="filters flex-row">
|
||||
<div class="filters">
|
||||
<div translate="filters.filter-by"></div>
|
||||
<redaction-filter
|
||||
[filters]="statusFilters"
|
||||
[filterLabel]="'filters.status'"
|
||||
[hasArrow]="false"
|
||||
[icon]="'red:status'"
|
||||
(filtersChanged)="filtersChanged()"
|
||||
></redaction-filter>
|
||||
<redaction-filter
|
||||
[filters]="peopleFilters"
|
||||
[filterLabel]="'filters.people'"
|
||||
[hasArrow]="false"
|
||||
[icon]="'red:user'"
|
||||
(filtersChanged)="filtersChanged()"
|
||||
></redaction-filter>
|
||||
@ -21,14 +19,16 @@
|
||||
[filterLabel]="'filters.needs-work'"
|
||||
[filterTemplate]="needsWorkTemplate"
|
||||
[filters]="needsWorkFilters"
|
||||
[hasArrow]="false"
|
||||
[icon]="'red:needs-work'"
|
||||
></redaction-filter>
|
||||
</div>
|
||||
<button (click)="openAddProjectDialog()" *ngIf="userService.isManager(user)" class="add-project-btn" color="primary" mat-flat-button>
|
||||
<mat-icon svgIcon="red:plus"></mat-icon>
|
||||
<span translate="project-listing.add-new"></span>
|
||||
</button>
|
||||
<redaction-icon-button
|
||||
*ngIf="userService.isManager(user)"
|
||||
icon="red:plus"
|
||||
(action)="openAddProjectDialog()"
|
||||
text="project-listing.add-new"
|
||||
[primary]="true"
|
||||
></redaction-icon-button>
|
||||
</div>
|
||||
|
||||
<div class="flex red-content-inner">
|
||||
@ -99,54 +99,48 @@
|
||||
<redaction-status-bar [config]="getProjectStatusConfig(pw)"></redaction-status-bar>
|
||||
|
||||
<div class="action-buttons" *ngIf="permissionsService.isManager()">
|
||||
<button
|
||||
(click)="openDeleteProjectDialog($event, pw.project)"
|
||||
[matTooltip]="'project-listing.delete.action' | translate"
|
||||
matTooltipPosition="above"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
<redaction-circle-button
|
||||
(action)="openDeleteProjectDialog($event, pw.project)"
|
||||
tooltip="project-listing.delete.action"
|
||||
type="dark-bg"
|
||||
icon="red:trash"
|
||||
>
|
||||
<mat-icon svgIcon="red:trash"></mat-icon>
|
||||
</button>
|
||||
</redaction-circle-button>
|
||||
|
||||
<button
|
||||
(click)="openEditProjectDialog($event, pw.project)"
|
||||
[matTooltip]="'project-listing.edit.action' | translate"
|
||||
matTooltipPosition="above"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
<redaction-circle-button
|
||||
(action)="openEditProjectDialog($event, pw.project)"
|
||||
tooltip="project-listing.edit.action"
|
||||
type="dark-bg"
|
||||
icon="red:edit"
|
||||
>
|
||||
<mat-icon svgIcon="red:edit"></mat-icon>
|
||||
</button>
|
||||
</redaction-circle-button>
|
||||
|
||||
<div
|
||||
[matTooltip]="(pw.allFilesApproved ? 'report.action' : 'report.unavailable') | translate"
|
||||
matTooltipPosition="above"
|
||||
<redaction-circle-button
|
||||
*ngIf="permissionsService.isManagerAndOwner(pw.project) && pw.hasFiles"
|
||||
(action)="downloadRedactionReport($event, pw.project)"
|
||||
[tooltip]="pw.allFilesApproved ? 'report.action' : 'report.unavailable'"
|
||||
[disabled]="!pw.allFilesApproved"
|
||||
type="dark-bg"
|
||||
icon="red:report"
|
||||
>
|
||||
<button mat-icon-button (click)="downloadRedactionReport($event, pw.project)" [disabled]="!pw.allFilesApproved" color="accent">
|
||||
<mat-icon svgIcon="red:report"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
(click)="openAssignProjectOwnerDialog($event, pw.project)"
|
||||
[matTooltip]="'project-listing.assign.action' | translate"
|
||||
matTooltipPosition="above"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="openAssignProjectOwnerDialog($event, pw.project)"
|
||||
tooltip="project-listing.assign.action"
|
||||
type="dark-bg"
|
||||
icon="red:assign"
|
||||
>
|
||||
<mat-icon svgIcon="red:assign"></mat-icon>
|
||||
</button>
|
||||
<button
|
||||
color="accent"
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
*ngIf="permissionsService.isManagerAndOwner(pw.project) && pw.hasFiles"
|
||||
(click)="reanalyseProject($event, pw.project)"
|
||||
mat-icon-button
|
||||
[matTooltip]="'project-listing.reanalyse.action' | translate"
|
||||
matTooltipPosition="above"
|
||||
(action)="reanalyseProject($event, pw.project)"
|
||||
tooltip="project-listing.reanalyse.action"
|
||||
type="dark-bg"
|
||||
icon="red:refresh"
|
||||
>
|
||||
<mat-icon svgIcon="red:refresh"></mat-icon>
|
||||
</button>
|
||||
</redaction-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,12 +1,5 @@
|
||||
@import '../../../assets/styles/red-mixins';
|
||||
|
||||
.add-project-btn {
|
||||
.mat-icon {
|
||||
width: 14px;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.left-container {
|
||||
width: calc(100vw - #{$right-container-width} - 90px);
|
||||
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
<ng-container *ngIf="areSomeFilesSelected">
|
||||
<button
|
||||
(click)="delete()"
|
||||
<redaction-circle-button
|
||||
(action)="delete()"
|
||||
*ngIf="canDelete"
|
||||
[matTooltip]="'project-overview.bulk.delete' | translate"
|
||||
class="dark"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
matTooltipPosition="above"
|
||||
>
|
||||
<mat-icon svgIcon="red:trash"></mat-icon>
|
||||
</button>
|
||||
tooltip="project-overview.bulk.delete"
|
||||
type="dark-bg"
|
||||
icon="red:trash"
|
||||
></redaction-circle-button>
|
||||
|
||||
<button
|
||||
(click)="assign()"
|
||||
<redaction-circle-button
|
||||
(action)="assign()"
|
||||
*ngIf="canAssign"
|
||||
[matTooltip]="'project-overview.bulk.assign' | translate"
|
||||
class="dark"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
matTooltipPosition="above"
|
||||
>
|
||||
<mat-icon svgIcon="red:assign"></mat-icon>
|
||||
</button>
|
||||
tooltip="project-overview.bulk.assign"
|
||||
type="dark-bg"
|
||||
icon="red:assign"
|
||||
></redaction-circle-button>
|
||||
|
||||
<!-- <div [matTooltip]="reanalyseTooltip | translate" matTooltipPosition="above">-->
|
||||
<!-- <button (click)="reanalyse()" [disabled]="reanalyseDisabled" class="dark" color="accent" mat-icon-button>-->
|
||||
@ -29,39 +21,23 @@
|
||||
<!-- </button>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<button
|
||||
(click)="approveDocuments()"
|
||||
<redaction-circle-button
|
||||
(action)="approveDocuments()"
|
||||
*ngIf="canApprove"
|
||||
[matTooltip]="'project-overview.approve' | translate"
|
||||
class="dark"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
matTooltipPosition="above"
|
||||
>
|
||||
<mat-icon svgIcon="red:check-alt"></mat-icon>
|
||||
</button>
|
||||
tooltip="project-overview.approve"
|
||||
type="dark-bg"
|
||||
icon="red:check-alt"
|
||||
></redaction-circle-button>
|
||||
|
||||
<button
|
||||
(click)="setToUnderApproval()"
|
||||
<redaction-circle-button
|
||||
(action)="setToUnderApproval()"
|
||||
*ngIf="canSetToUnderApproval"
|
||||
[matTooltip]="'project-overview.under-approval' | translate"
|
||||
class="dark"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
matTooltipPosition="above"
|
||||
tooltip="project-overview.under-approval"
|
||||
type="dark-bg"
|
||||
icon="red:check-alt"
|
||||
>
|
||||
<mat-icon svgIcon="red:check-alt"></mat-icon>
|
||||
</button>
|
||||
</redaction-circle-button>
|
||||
|
||||
<button
|
||||
(click)="setToUnderReview()"
|
||||
*ngIf="canSetToUnderReview"
|
||||
[matTooltip]="'project-overview.under-review' | translate"
|
||||
class="dark"
|
||||
color="accent"
|
||||
mat-icon-button
|
||||
matTooltipPosition="above"
|
||||
>
|
||||
<mat-icon svgIcon="red:refresh"></mat-icon>
|
||||
</button>
|
||||
<redaction-circle-button (action)="setToUnderReview()" *ngIf="canSetToUnderReview" tooltip="project-overview.under-review" type="dark-bg" icon="red:refres">
|
||||
</redaction-circle-button>
|
||||
</ng-container>
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
:host {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
@ -1,22 +1,4 @@
|
||||
<div *ngIf="permissionsService.isManager()" class="actions-row">
|
||||
<button (click)="openDeleteProjectDialog($event)" [matTooltip]="'project-details.delete' | translate" mat-icon-button matTooltipPosition="above">
|
||||
<mat-icon svgIcon="red:trash"></mat-icon>
|
||||
</button>
|
||||
<button (click)="openEditProjectDialog($event)" [matTooltip]="'project-details.edit' | translate" mat-icon-button matTooltipPosition="above">
|
||||
<mat-icon svgIcon="red:edit"></mat-icon>
|
||||
</button>
|
||||
<div
|
||||
*ngIf="permissionsService.isManagerAndOwner()"
|
||||
[matTooltip]="(appStateService.activeProject.allFilesApproved ? 'report.action' : 'report.unavailable') | translate"
|
||||
matTooltipPosition="above"
|
||||
>
|
||||
<button (click)="downloadRedactionReport($event)" [disabled]="!appStateService.activeProject.allFilesApproved" mat-icon-button>
|
||||
<mat-icon svgIcon="red:report"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="heading-xl mt-16">
|
||||
<div class="heading-xl mt-8">
|
||||
{{ appStateService.activeProject.project.projectName }}
|
||||
</div>
|
||||
|
||||
@ -36,7 +18,7 @@
|
||||
<div *ngIf="overflowCount" class="member">
|
||||
<div class="oval large white-dark">+{{ overflowCount }}</div>
|
||||
</div>
|
||||
<div (click)="openAssignProjectMembersDialog()" *ngIf="permissionsService.isManager()" class="member pointer">
|
||||
<div (click)="openAssignProjectMembersDialog.emit()" *ngIf="permissionsService.isManager()" class="member pointer">
|
||||
<div class="oval red-white large">+</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, OnInit, Output, EventEmitter, Input, ChangeDetectorRef } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { AppStateService } from '../../../state/app-state.service';
|
||||
import { groupBy } from '../../../utils/functions';
|
||||
import { DoughnutChartConfig } from '../../../components/simple-doughnut-chart/simple-doughnut-chart.component';
|
||||
@ -17,8 +17,8 @@ import { StatusSorter } from '../../../common/sorters/status-sorter';
|
||||
export class ProjectDetailsComponent implements OnInit {
|
||||
public documentsChartData: DoughnutChartConfig[] = [];
|
||||
@Input() public filters: { needsWorkFilters: FilterModel[]; statusFilters: FilterModel[] };
|
||||
@Output() public reloadProjects = new EventEmitter();
|
||||
@Output() public filtersChanged = new EventEmitter();
|
||||
@Output() public openAssignProjectMembersDialog = new EventEmitter();
|
||||
|
||||
constructor(
|
||||
public readonly appStateService: AppStateService,
|
||||
@ -44,28 +44,6 @@ export class ProjectDetailsComponent implements OnInit {
|
||||
return this.appStateService.activeProject.project.memberIds.length > 6 ? this.appStateService.activeProject.project.memberIds.length - 6 : 0;
|
||||
}
|
||||
|
||||
public openEditProjectDialog($event: MouseEvent) {
|
||||
this._dialogService.openEditProjectDialog($event, this.appStateService.activeProject.project);
|
||||
}
|
||||
|
||||
public openDeleteProjectDialog($event: MouseEvent) {
|
||||
this._dialogService.openDeleteProjectDialog($event, this.appStateService.activeProject.project, () => {
|
||||
this._router.navigate(['/ui/projects']);
|
||||
});
|
||||
}
|
||||
|
||||
public openAssignProjectMembersDialog(): void {
|
||||
this._dialogService.openAssignProjectMembersAndOwnerDialog(null, this.appStateService.activeProject.project, () => {
|
||||
this.reloadProjects.emit();
|
||||
this._changeDetectorRef.detectChanges();
|
||||
});
|
||||
}
|
||||
|
||||
public downloadRedactionReport($event: MouseEvent): void {
|
||||
$event.stopPropagation();
|
||||
this.appStateService.downloadRedactionReport();
|
||||
}
|
||||
|
||||
public calculateChartConfig(): void {
|
||||
if (this.appStateService.activeProject) {
|
||||
const groups = groupBy(this.appStateService.activeProject?.files, 'status');
|
||||
|
||||
@ -1,20 +1,18 @@
|
||||
<redaction-project-overview-empty (uploadFiles)="uploadFiles($event)" *ngIf="!appStateService.activeProject?.hasFiles"></redaction-project-overview-empty>
|
||||
<section *ngIf="appStateService.activeProject?.hasFiles">
|
||||
<div *ngIf="appStateService.activeProject" class="page-header">
|
||||
<div class="filters flex-row">
|
||||
<div class="filters">
|
||||
<div translate="filters.filter-by"></div>
|
||||
<redaction-filter
|
||||
(filtersChanged)="filtersChanged()"
|
||||
[filterLabel]="'filters.status'"
|
||||
[filters]="statusFilters"
|
||||
[hasArrow]="false"
|
||||
[icon]="'red:status'"
|
||||
></redaction-filter>
|
||||
<redaction-filter
|
||||
(filtersChanged)="filtersChanged()"
|
||||
[filterLabel]="'filters.assigned-people'"
|
||||
[filters]="peopleFilters"
|
||||
[hasArrow]="false"
|
||||
[icon]="'red:user'"
|
||||
></redaction-filter>
|
||||
<redaction-filter
|
||||
@ -22,24 +20,52 @@
|
||||
[filterLabel]="'filters.needs-work'"
|
||||
[filterTemplate]="needsWorkTemplate"
|
||||
[filters]="needsWorkFilters"
|
||||
[hasArrow]="false"
|
||||
[icon]="'red:needs-work'"
|
||||
></redaction-filter>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button
|
||||
(click)="fileInput.click()"
|
||||
class="primary"
|
||||
mat-icon-button
|
||||
[matTooltip]="'project-overview.upload-document' | translate"
|
||||
matTooltipPosition="before"
|
||||
>
|
||||
<mat-icon svgIcon="red:upload"></mat-icon>
|
||||
</button>
|
||||
<button [routerLink]="['/ui/projects/']" mat-icon-button [matTooltip]="'common.close' | translate">
|
||||
<mat-icon svgIcon="red:close"></mat-icon>
|
||||
</button>
|
||||
<div class="actions">
|
||||
<redaction-circle-button
|
||||
(action)="openEditProjectDialog($event)"
|
||||
tooltip="project-overview.header-actions.edit"
|
||||
tooltipPosition="below"
|
||||
icon="red:edit"
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button
|
||||
(action)="openDeleteProjectDialog($event)"
|
||||
tooltip="project-overview.header-actions.delete"
|
||||
tooltipPosition="below"
|
||||
icon="red:trash"
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button
|
||||
*ngIf="permissionsService.isManagerAndOwner()"
|
||||
(action)="downloadRedactionReport($event)"
|
||||
[tooltip]="appStateService.activeProject.allFilesApproved ? 'report.action' : 'report.unavailable'"
|
||||
[disabled]="!appStateService.activeProject.allFilesApproved"
|
||||
tooltipPosition="below"
|
||||
icon="red:report"
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button
|
||||
(action)="openAssignProjectMembersDialog()"
|
||||
tooltip="project-overview.header-actions.assign"
|
||||
tooltipPosition="below"
|
||||
icon="red:assign"
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button
|
||||
class="ml-14"
|
||||
(action)="fileInput.click()"
|
||||
tooltip="project-overview.header-actions.upload-document"
|
||||
tooltipPosition="below"
|
||||
icon="red:upload"
|
||||
type="primary"
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button
|
||||
class="ml-6"
|
||||
[routerLink]="['/ui/projects/']"
|
||||
tooltip="common.close"
|
||||
tooltipPosition="below"
|
||||
icon="red:close"
|
||||
></redaction-circle-button>
|
||||
|
||||
<input #fileInput (change)="uploadFiles($event.target['files'])" class="file-upload-input" multiple="true" type="file" />
|
||||
</div>
|
||||
@ -184,6 +210,7 @@
|
||||
[fileStatus]="fileStatus"
|
||||
(actionPerformed)="calculateData()"
|
||||
*ngIf="!fileStatus.isProcessing"
|
||||
class="mr-4"
|
||||
></redaction-file-actions>
|
||||
<redaction-status-bar
|
||||
class="mr-8"
|
||||
@ -204,7 +231,7 @@
|
||||
<div class="right-fixed-container">
|
||||
<redaction-project-details
|
||||
#projectDetailsComponent
|
||||
(reloadProjects)="calculateData()"
|
||||
(openAssignProjectMembersDialog)="openAssignProjectMembersDialog()"
|
||||
[filters]="detailsContainerFilters"
|
||||
(filtersChanged)="filtersChanged($event)"
|
||||
></redaction-project-details>
|
||||
|
||||
@ -65,3 +65,15 @@
|
||||
color: lighten($accent, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.ml-6 {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.ml-14 {
|
||||
margin-left: 14px;
|
||||
}
|
||||
|
||||
.mr-4 {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
@ -286,4 +286,25 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
this.selectedFileIds = [];
|
||||
this.reloadProjects();
|
||||
}
|
||||
|
||||
public openEditProjectDialog($event: MouseEvent) {
|
||||
this._dialogService.openEditProjectDialog($event, this.appStateService.activeProject.project);
|
||||
}
|
||||
|
||||
public openDeleteProjectDialog($event: MouseEvent) {
|
||||
this._dialogService.openDeleteProjectDialog($event, this.appStateService.activeProject.project, () => {
|
||||
this._router.navigate(['/ui/projects']);
|
||||
});
|
||||
}
|
||||
|
||||
public downloadRedactionReport($event: MouseEvent): void {
|
||||
$event.stopPropagation();
|
||||
this.appStateService.downloadRedactionReport();
|
||||
}
|
||||
|
||||
public openAssignProjectMembersDialog(): void {
|
||||
this._dialogService.openAssignProjectMembersAndOwnerDialog(null, this.appStateService.activeProject.project, () => {
|
||||
this.reloadProjects();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,13 +62,13 @@
|
||||
"needs-work": "Analyzed"
|
||||
},
|
||||
"report": {
|
||||
"unavailable": "Redaction Report is only available once all files have been approved.",
|
||||
"unavailable-single": "Redaction Report is only available once this file has been approved.",
|
||||
"unavailable": "Redaction report is only available once all files have been approved.",
|
||||
"unavailable-single": "Redaction report is only available once this file has been approved.",
|
||||
"action": "Download Redaction Report"
|
||||
},
|
||||
"project-listing": {
|
||||
"reanalyse": {
|
||||
"action": "Reanalyse entire Project"
|
||||
"action": "Reanalyse entire project"
|
||||
},
|
||||
"assign": {
|
||||
"action": "Assign Owner & Members"
|
||||
@ -126,8 +126,6 @@
|
||||
}
|
||||
},
|
||||
"project-details": {
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"dialog": {
|
||||
"title": "Project Details",
|
||||
"info": {
|
||||
@ -142,6 +140,12 @@
|
||||
"members": "Members"
|
||||
},
|
||||
"project-overview": {
|
||||
"header-actions": {
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"assign": "Assign Owner & Members",
|
||||
"upload-document": "Upload Document"
|
||||
},
|
||||
"download-redacted-file": "Download Redacted File",
|
||||
"under-approval": "For Approval",
|
||||
"approve": "Approve",
|
||||
@ -162,7 +166,7 @@
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"action": "Download Redaction Report"
|
||||
"action": "Download redaction report"
|
||||
},
|
||||
"assign": {
|
||||
"action": "Assign Reviewer"
|
||||
@ -214,13 +218,11 @@
|
||||
"description": "Description"
|
||||
},
|
||||
"header": "Project Overview",
|
||||
"upload-document": "Upload Document",
|
||||
"no-project": "Requested project: {{projectId}} does not exist! <a href='/ui/projects'>Back to Project Listing. <a/>",
|
||||
"bulk": {
|
||||
"delete": "Delete documents",
|
||||
"assign": "Assign reviewer",
|
||||
"change-state": "Change state",
|
||||
"reanalyse": "Reanalyse documents",
|
||||
"delete": "Delete Documents",
|
||||
"assign": "Assign Reviewer",
|
||||
"reanalyse": "Reanalyse Documents",
|
||||
"reanalyse-error-outdated": "Not all selected documents can be reanalysed, some may not be assigned to you or may not be outdated."
|
||||
}
|
||||
},
|
||||
|
||||
@ -1,3 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 426.67" width="640" height="426.67"><defs><path d="M640 0L0 0L320 426.67L640 0Z" id="c419bDOtl"></path></defs><g><g><g><use xlink:href="#c419bDOtl" opacity="1" fill-opacity="1"></use><g><use xlink:href="#c419bDOtl" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g></g></g></svg>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>9A0E7FCD-AD02-40D9-BEF9-48F61351C288</title>
|
||||
<g id="Styleguide" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Styleguide-Buttons" transform="translate(-469.000000, -757.000000)">
|
||||
<rect x="0" y="0" width="904" height="906"></rect>
|
||||
<rect id="Rectangle" x="359" y="747" width="134" height="34" rx="17"></rect>
|
||||
<g id="right" transform="translate(469.000000, 757.000000)" fill="currentColor">
|
||||
<polygon id="Fill-1" points="7 9 10 5 4 5"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 630 B After Width: | Height: | Size: 772 B |
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="100px" height="100px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg width="100px" height="90px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>upload</title>
|
||||
<g id="upload" stroke="none" stroke-width="1" fill="currentColor" fill-rule="evenodd">
|
||||
<path d="M35,35 L35,45 L15,45 L15,90 L85,90 L85,45 L65,45 L65,35 L95,35 L95,100 L5,100 L5,35 L35,35 Z M50,0 L70,20 L63,27 L55,19 L55,70 L45,70 L45,19 L37,27 L30,20 L50,0 Z" id="Combined-Shape" fill-rule="nonzero"></path>
|
||||
|
||||
|
Before Width: | Height: | Size: 551 B After Width: | Height: | Size: 550 B |
@ -9,14 +9,6 @@
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
|
||||
&.mat-primary {
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
&:not(.mat-primary) {
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
.mat-button-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -24,50 +16,62 @@
|
||||
}
|
||||
}
|
||||
|
||||
.mat-button[aria-expanded='true'],
|
||||
.mat-button.overlay {
|
||||
background: rgba($primary, 0.1);
|
||||
}
|
||||
redaction-icon-button,
|
||||
redaction-chevron-button,
|
||||
redaction-circle-button {
|
||||
position: relative;
|
||||
transition: background-color 0.2s;
|
||||
|
||||
.mat-button,
|
||||
.mat-flat-button,
|
||||
.mat-icon-button {
|
||||
gap: 6px;
|
||||
button {
|
||||
font-weight: 400 !important;
|
||||
|
||||
mat-icon {
|
||||
width: 14px;
|
||||
}
|
||||
}
|
||||
&.overlay {
|
||||
background: rgba($primary, 0.1);
|
||||
}
|
||||
|
||||
.arrow-button mat-icon {
|
||||
width: 9px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
&:not(.overlay):hover {
|
||||
background-color: $grey-6;
|
||||
}
|
||||
|
||||
.mat-icon-button {
|
||||
transition: background-color 0.25s ease-in-out;
|
||||
width: 34px !important;
|
||||
height: 34px !important;
|
||||
line-height: 34px !important;
|
||||
&.primary {
|
||||
font-weight: 500 !important;
|
||||
background-color: $primary;
|
||||
color: $white;
|
||||
|
||||
&.warn {
|
||||
background-color: $yellow-2;
|
||||
}
|
||||
&:hover {
|
||||
background-color: $red-2;
|
||||
}
|
||||
}
|
||||
|
||||
&.primary {
|
||||
background-color: $primary;
|
||||
color: $white !important;
|
||||
|
||||
&.mat-button-disabled {
|
||||
background-color: rgba($primary, 0.7);
|
||||
&.dark-bg:hover {
|
||||
background-color: $grey-4;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover:not(.warn):not(.primary) {
|
||||
background-color: $grey-2;
|
||||
}
|
||||
|
||||
&.dark:hover {
|
||||
background-color: $grey-4;
|
||||
.dot {
|
||||
background: $primary;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
redaction-chevron-button,
|
||||
redaction-icon-button {
|
||||
&[aria-expanded='true'] {
|
||||
button {
|
||||
background: rgba($primary, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
redaction-circle-button {
|
||||
&[aria-expanded='true'] {
|
||||
button {
|
||||
background: $grey-4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,21 @@ body {
|
||||
box-sizing: border-box;
|
||||
background-color: $white;
|
||||
z-index: 3;
|
||||
|
||||
.filters {
|
||||
gap: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> div:first-child {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.red-content-inner {
|
||||
@ -33,33 +48,12 @@ body {
|
||||
.right-fixed-container {
|
||||
border-left: 1px solid $grey-4;
|
||||
background: $white;
|
||||
height: calc(100vh - 110px - 2 * #{$right-container-padding});
|
||||
height: calc(100vh - 110px - 2 * #{$right-container-vertical-padding});
|
||||
width: $right-container-inside-width;
|
||||
padding: $right-container-padding;
|
||||
padding: $right-container-vertical-padding $right-container-horizontal-padding;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
z-index: 2;
|
||||
|
||||
.actions-row {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
}
|
||||
|
||||
.filters {
|
||||
div {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
button {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex {
|
||||
|
||||
@ -14,6 +14,7 @@ $blue-2: #48c9f7;
|
||||
$blue-3: #5b97db;
|
||||
$blue-4: #374c81;
|
||||
$red-1: #dd4d50;
|
||||
$red-2: #f16164;
|
||||
$yellow-1: #ffb83b;
|
||||
$yellow-2: #fdbd00;
|
||||
$green-1: #00ff00;
|
||||
@ -28,7 +29,6 @@ $dark: $black;
|
||||
$separator: rgba(226, 228, 233, 0.9);
|
||||
|
||||
$right-container-inside-width: 340px;
|
||||
$right-container-padding: 24px;
|
||||
$right-container-width: calc(
|
||||
#{$right-container-inside-width} + 2 *#{$right-container-padding} + 1px
|
||||
);
|
||||
$right-container-horizontal-padding: 24px;
|
||||
$right-container-vertical-padding: 16px;
|
||||
$right-container-width: calc(#{$right-container-inside-width} + 2 *#{$right-container-horizontal-padding} + 1px);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user