force redaction phase 1
This commit is contained in:
parent
992ac2b3ed
commit
0f0a331c56
@ -35,6 +35,21 @@ export class AnnotationActionsService {
|
||||
});
|
||||
}
|
||||
|
||||
public forceRedaction($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
||||
$event?.stopPropagation();
|
||||
annotations.forEach((annotation) => {
|
||||
this._processObsAndEmit(
|
||||
this._manualAnnotationService.forceRedaction({
|
||||
annotationId: annotation.id,
|
||||
comment: 'Test',
|
||||
legalBasis: 'Test'
|
||||
}),
|
||||
annotation,
|
||||
annotationsChanged
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public suggestRemoveAnnotation(
|
||||
$event: MouseEvent,
|
||||
annotations: AnnotationWrapper[],
|
||||
@ -98,6 +113,20 @@ export class AnnotationActionsService {
|
||||
return { annotation: a, permissions: AnnotationPermissions.forUser(this._permissionsService.currentUser, a) };
|
||||
});
|
||||
|
||||
const canForceRedaction = annotationPermissions.reduce((acc, next) => acc && next.permissions.canForceRedaction, true);
|
||||
if (canForceRedaction) {
|
||||
availableActions.push({
|
||||
type: 'actionButton',
|
||||
img: '/assets/icons/general/thumb-up.svg',
|
||||
title: this._translateService.instant('annotation-actions.force-redaction.label'),
|
||||
onClick: () => {
|
||||
this._ngZone.run(() => {
|
||||
this.forceRedaction(null, annotations, annotationsChanged);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const canAcceptRecommendation = annotationPermissions.reduce((acc, next) => acc && next.permissions.canAcceptRecommendation, true);
|
||||
if (canAcceptRecommendation) {
|
||||
availableActions.push({
|
||||
|
||||
@ -65,6 +65,7 @@ export class IconsModule {
|
||||
'status-collapse',
|
||||
'template',
|
||||
'thumb-down',
|
||||
'thumb-up',
|
||||
'trash',
|
||||
'under-construction',
|
||||
'undo',
|
||||
|
||||
@ -1,5 +1,15 @@
|
||||
<redaction-hidden-action (action)="logAnnotation(annotation)">
|
||||
<div [class.visible]="menuOpen" *ngIf="canPerformAnnotationActions" class="annotation-actions">
|
||||
<redaction-circle-button
|
||||
(action)="annotationActionsService.forceRedaction($event, [annotation], annotationsChanged)"
|
||||
type="dark-bg"
|
||||
*ngIf="annotationPermissions.canForceRedaction"
|
||||
tooltipPosition="before"
|
||||
tooltip="annotation-actions.force-redaction.label"
|
||||
icon="red:thumb-up"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="annotationActionsService.convertRecommendationToAnnotation($event, [annotation], annotationsChanged)"
|
||||
type="dark-bg"
|
||||
|
||||
@ -14,10 +14,13 @@ export class AnnotationPermissions {
|
||||
canAcceptSuggestion: boolean;
|
||||
canRejectSuggestion: boolean;
|
||||
|
||||
canForceRedaction: boolean;
|
||||
|
||||
public static forUser(user: UserWrapper, annotation: AnnotationWrapper) {
|
||||
const permissions: AnnotationPermissions = new AnnotationPermissions();
|
||||
|
||||
permissions.canUndo = annotation.userId === user.id && annotation.isUndoableSuperType;
|
||||
permissions.canForceRedaction = annotation.isSkipped && !permissions.canUndo;
|
||||
|
||||
permissions.canAcceptRecommendation = annotation.isRecommendation;
|
||||
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AppStateService } from '../../../state/app-state.service';
|
||||
import { AddRedactionRequest, DictionaryControllerService, ManualRedactionControllerService, ManualRedactionEntry } from '@redaction/red-ui-http';
|
||||
import {
|
||||
AddRedactionRequest,
|
||||
DictionaryControllerService,
|
||||
ForceRedactionRequest,
|
||||
ManualRedactionControllerService,
|
||||
ManualRedactionEntry
|
||||
} from '@redaction/red-ui-http';
|
||||
import { AnnotationWrapper } from '../model/annotation.wrapper';
|
||||
import { NotificationService, NotificationType } from '../../../notification/notification.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
@ -65,6 +71,17 @@ export class ManualAnnotationService {
|
||||
}
|
||||
}
|
||||
|
||||
// this wraps
|
||||
// /manualRedaction/redaction/force
|
||||
// /manualRedaction/request/force
|
||||
public forceRedaction(request: ForceRedactionRequest) {
|
||||
if (this._permissionsService.isManagerAndOwner()) {
|
||||
return this._makeForceRedaction(request);
|
||||
} else {
|
||||
return this._makeForceRedactionRequest(request);
|
||||
}
|
||||
}
|
||||
|
||||
// this wraps
|
||||
// /manualRedaction/approve
|
||||
public approveRequest(annotationId: string, addToDictionary: boolean = false) {
|
||||
@ -173,6 +190,28 @@ export class ManualAnnotationService {
|
||||
}
|
||||
}
|
||||
|
||||
private _makeForceRedactionRequest(forceRedactionRequest: ForceRedactionRequest) {
|
||||
return this._manualRedactionControllerService
|
||||
.requestForceRedaction(forceRedactionRequest, this._appStateService.activeProject.project.projectId, this._appStateService.activeFile.fileId)
|
||||
.pipe(
|
||||
tap(
|
||||
() => this._notify(this._getMessage('suggest', false)),
|
||||
(error) => this._notify(this._getMessage('suggest', false, true), NotificationType.ERROR, error)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private _makeForceRedaction(forceRedactionRequest: ForceRedactionRequest) {
|
||||
return this._manualRedactionControllerService
|
||||
.forceRedaction(forceRedactionRequest, this._appStateService.activeProject.project.projectId, this._appStateService.activeFile.fileId)
|
||||
.pipe(
|
||||
tap(
|
||||
() => this._notify(this._getMessage('add', false)),
|
||||
(error) => this._notify(this._getMessage('add', false, true), NotificationType.ERROR, error)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private _makeRedactionRequest(manualRedactionEntry: AddRedactionRequest) {
|
||||
return this._manualRedactionControllerService
|
||||
.requestAddRedaction(manualRedactionEntry, this._appStateService.activeProject.project.projectId, this._appStateService.activeFile.fileId)
|
||||
|
||||
@ -371,6 +371,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"force-redaction": {
|
||||
"label": "Force Redaction"
|
||||
},
|
||||
"accept-suggestion": {
|
||||
"label": "Accept Suggestion",
|
||||
"add-to-dict": "Approve and add to dictionary",
|
||||
|
||||
9
apps/red-ui/src/assets/icons/general/thumb-up.svg
Normal file
9
apps/red-ui/src/assets/icons/general/thumb-up.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -256 1792 1792" id="svg3888" version="1.1"
|
||||
width="100%" height="100%">
|
||||
<defs id="defs3896"/>
|
||||
<g transform="matrix(1,0,0,-1,129.08475,1346.1695)" id="g3890">
|
||||
<path
|
||||
d="m 256,192 q 0,26 -19,45 -19,19 -45,19 -26,0 -45,-19 -19,-19 -19,-45 0,-26 19,-45 19,-19 45,-19 26,0 45,19 19,19 19,45 z m 1152,576 q 0,51 -39,89.5 -39,38.5 -89,38.5 H 928 q 0,58 48,159.5 48,101.5 48,160.5 0,98 -32,145 -32,47 -128,47 -26,-26 -38,-85 -12,-59 -30.5,-125.5 Q 777,1131 736,1088 714,1065 659,997 655,992 636,967 617,942 604.5,926 592,910 570,883.5 548,857 530,839.5 512,822 491.5,804 471,786 451.5,777 432,768 416,768 H 384 V 128 h 32 q 13,0 31.5,-3 18.5,-3 33,-6.5 14.5,-3.5 38,-11 Q 542,100 553.5,96 565,92 589,83.5 613,75 618,73 829,0 960,0 h 121 q 192,0 192,167 0,26 -5,56 30,16 47.5,52.5 17.5,36.5 17.5,73.5 0,37 -18,69 53,50 53,119 0,25 -10,55.5 -10,30.5 -25,47.5 32,1 53.5,47 21.5,46 21.5,81 z m 128,1 q 0,-89 -49,-163 9,-33 9,-69 0,-77 -38,-144 3,-21 3,-43 0,-101 -60,-178 1,-139 -85,-219.5 -86,-80.5 -227,-80.5 h -36 -93 q -96,0 -189.5,22.5 Q 677,-83 554,-40 438,0 416,0 H 128 Q 75,0 37.5,37.5 0,75 0,128 V 768 Q 0,821 37.5,858.5 75,896 128,896 h 274 q 36,24 137,155 58,75 107,128 24,25 35.5,85.5 11.5,60.5 30.5,126.5 19,66 62,108 39,37 90,37 84,0 151,-32.5 67,-32.5 102,-101.5 35,-69 35,-186 0,-93 -48,-192 h 176 q 104,0 180,-76 76,-76 76,-179 z"
|
||||
id="path3892" style="fill:currentColor"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@ -25,6 +25,7 @@ import { RemoveRedactionRequest } from '../model/removeRedactionRequest';
|
||||
|
||||
import { BASE_PATH } from '../variables';
|
||||
import { Configuration } from '../configuration';
|
||||
import { ForceRedactionRequest } from '..';
|
||||
|
||||
@Injectable()
|
||||
export class ManualRedactionControllerService {
|
||||
@ -140,6 +141,174 @@ export class ManualRedactionControllerService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces a redaction
|
||||
* None
|
||||
* @param body forceRedactionRequest
|
||||
* @param projectId projectId
|
||||
* @param fileId fileId
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public forceRedaction(
|
||||
body: ForceRedactionRequest,
|
||||
projectId: string,
|
||||
fileId: string,
|
||||
observe?: 'body',
|
||||
reportProgress?: boolean
|
||||
): Observable<ManualAddResponse>;
|
||||
public forceRedaction(
|
||||
body: ForceRedactionRequest,
|
||||
projectId: string,
|
||||
fileId: string,
|
||||
observe?: 'response',
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpResponse<ManualAddResponse>>;
|
||||
public forceRedaction(
|
||||
body: ForceRedactionRequest,
|
||||
projectId: string,
|
||||
fileId: string,
|
||||
observe?: 'events',
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpEvent<ManualAddResponse>>;
|
||||
public forceRedaction(
|
||||
body: ForceRedactionRequest,
|
||||
projectId: string,
|
||||
fileId: string,
|
||||
observe: any = 'body',
|
||||
reportProgress: boolean = false
|
||||
): Observable<any> {
|
||||
if (body === null || body === undefined) {
|
||||
throw new Error('Required parameter body was null or undefined when calling forceRedaction.');
|
||||
}
|
||||
|
||||
if (projectId === null || projectId === undefined) {
|
||||
throw new Error('Required parameter projectId was null or undefined when calling forceRedaction.');
|
||||
}
|
||||
|
||||
if (fileId === null || fileId === undefined) {
|
||||
throw new Error('Required parameter fileId was null or undefined when calling forceRedaction.');
|
||||
}
|
||||
|
||||
let headers = this.defaultHeaders;
|
||||
|
||||
// authentication (RED-OAUTH) required
|
||||
if (this.configuration.accessToken) {
|
||||
const accessToken = typeof this.configuration.accessToken === 'function' ? this.configuration.accessToken() : this.configuration.accessToken;
|
||||
headers = headers.set('Authorization', 'Bearer ' + accessToken);
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
const httpHeaderAccepts: string[] = ['application/json'];
|
||||
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
if (httpHeaderAcceptSelected !== undefined) {
|
||||
headers = headers.set('Accept', httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
// to determine the Content-Type header
|
||||
const consumes: string[] = ['application/json'];
|
||||
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
|
||||
if (httpContentTypeSelected !== undefined) {
|
||||
headers = headers.set('Content-Type', httpContentTypeSelected);
|
||||
}
|
||||
|
||||
return this.httpClient.request<ManualAddResponse>(
|
||||
'post',
|
||||
`${this.basePath}/manualRedaction/redaction/force/${encodeURIComponent(String(projectId))}/${encodeURIComponent(String(fileId))}`,
|
||||
{
|
||||
body: body,
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
observe: observe,
|
||||
reportProgress: reportProgress
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a request to force a redaction.
|
||||
* None
|
||||
* @param body forceRedactionRequest
|
||||
* @param projectId projectId
|
||||
* @param fileId fileId
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public requestForceRedaction(
|
||||
body: ForceRedactionRequest,
|
||||
projectId: string,
|
||||
fileId: string,
|
||||
observe?: 'body',
|
||||
reportProgress?: boolean
|
||||
): Observable<ManualAddResponse>;
|
||||
public requestForceRedaction(
|
||||
body: ForceRedactionRequest,
|
||||
projectId: string,
|
||||
fileId: string,
|
||||
observe?: 'response',
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpResponse<ManualAddResponse>>;
|
||||
public requestForceRedaction(
|
||||
body: ForceRedactionRequest,
|
||||
projectId: string,
|
||||
fileId: string,
|
||||
observe?: 'events',
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpEvent<ManualAddResponse>>;
|
||||
public requestForceRedaction(
|
||||
body: ForceRedactionRequest,
|
||||
projectId: string,
|
||||
fileId: string,
|
||||
observe: any = 'body',
|
||||
reportProgress: boolean = false
|
||||
): Observable<any> {
|
||||
if (body === null || body === undefined) {
|
||||
throw new Error('Required parameter body was null or undefined when calling requestForceRedaction.');
|
||||
}
|
||||
|
||||
if (projectId === null || projectId === undefined) {
|
||||
throw new Error('Required parameter projectId was null or undefined when calling requestForceRedaction.');
|
||||
}
|
||||
|
||||
if (fileId === null || fileId === undefined) {
|
||||
throw new Error('Required parameter fileId was null or undefined when calling requestForceRedaction.');
|
||||
}
|
||||
|
||||
let headers = this.defaultHeaders;
|
||||
|
||||
// authentication (RED-OAUTH) required
|
||||
if (this.configuration.accessToken) {
|
||||
const accessToken = typeof this.configuration.accessToken === 'function' ? this.configuration.accessToken() : this.configuration.accessToken;
|
||||
headers = headers.set('Authorization', 'Bearer ' + accessToken);
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
let httpHeaderAccepts: string[] = ['application/json'];
|
||||
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
if (httpHeaderAcceptSelected !== undefined) {
|
||||
headers = headers.set('Accept', httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
// to determine the Content-Type header
|
||||
const consumes: string[] = ['application/json'];
|
||||
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
|
||||
if (httpContentTypeSelected !== undefined) {
|
||||
headers = headers.set('Content-Type', httpContentTypeSelected);
|
||||
}
|
||||
|
||||
return this.httpClient.request<ManualAddResponse>(
|
||||
'post',
|
||||
`${this.basePath}/manualRedaction/request/force/${encodeURIComponent(String(projectId))}/${encodeURIComponent(String(fileId))}`,
|
||||
{
|
||||
body: body,
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
observe: observe,
|
||||
reportProgress: reportProgress
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a manual redaction
|
||||
* None
|
||||
|
||||
17
libs/red-ui-http/src/lib/model/forceRedactionRequest.ts
Normal file
17
libs/red-ui-http/src/lib/model/forceRedactionRequest.ts
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* API Documentation for Redaction Gateway
|
||||
* Description for redaction
|
||||
*
|
||||
* OpenAPI spec version: 1.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
export interface ForceRedactionRequest {
|
||||
annotationId?: string;
|
||||
comment?: string;
|
||||
legalBasis?: string;
|
||||
}
|
||||
28
libs/red-ui-http/src/lib/model/manualForceRedaction.ts
Normal file
28
libs/red-ui-http/src/lib/model/manualForceRedaction.ts
Normal file
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* API Documentation for Redaction Gateway
|
||||
* Description for redaction
|
||||
*
|
||||
* OpenAPI spec version: 1.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
export interface ManualForceRedaction {
|
||||
id?: string;
|
||||
legalBasis?: string;
|
||||
processedDate?: string;
|
||||
requestDate?: string;
|
||||
status?: ManualForceRedaction.StatusEnum;
|
||||
user?: string;
|
||||
}
|
||||
export namespace ManualForceRedaction {
|
||||
export type StatusEnum = 'REQUESTED' | 'APPROVED' | 'DECLINED';
|
||||
export const StatusEnum = {
|
||||
REQUESTED: 'REQUESTED' as StatusEnum,
|
||||
APPROVED: 'APPROVED' as StatusEnum,
|
||||
DECLINED: 'DECLINED' as StatusEnum
|
||||
};
|
||||
}
|
||||
@ -12,9 +12,11 @@
|
||||
import { Comment } from './comment';
|
||||
import { IdRemoval } from './idRemoval';
|
||||
import { ManualRedactionEntry } from './manualRedactionEntry';
|
||||
import { ManualForceRedaction } from './manualForceRedaction';
|
||||
|
||||
export interface ManualRedactions {
|
||||
comments?: { [key: string]: Array<Comment> };
|
||||
entriesToAdd?: Array<ManualRedactionEntry>;
|
||||
forceRedactions?: Array<ManualForceRedaction>;
|
||||
idsToRemove?: Array<IdRemoval>;
|
||||
}
|
||||
|
||||
@ -52,3 +52,5 @@ export * from './digitalSignature';
|
||||
export * from './digitalSignatureViewModel';
|
||||
export * from './redactionChangeLog';
|
||||
export * from './redactionChangeLogEntry';
|
||||
export * from './forceRedactionRequest';
|
||||
export * from './manualForceRedaction';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user