Import Redactions work in progress / fix for missing dossier templates, annotation debug
This commit is contained in:
parent
6565c2da20
commit
c1a342e6ee
@ -37,7 +37,7 @@ export class DossierDetailsStatsComponent implements OnInit {
|
||||
switchMap(() => this._filesService.getDeletedFilesFor(this.dossier.id)),
|
||||
map(files => files.length),
|
||||
);
|
||||
this.dossierTemplateName = this._dossierTemplatesService.find(this.dossier.dossierTemplateId).name;
|
||||
this.dossierTemplateName = this._dossierTemplatesService.find(this.dossier.dossierTemplateId)?.name || '-';
|
||||
}
|
||||
|
||||
openEditDossierDialog(section: string): void {
|
||||
|
||||
@ -36,6 +36,6 @@ export class DossiersListingDossierNameComponent {
|
||||
}
|
||||
|
||||
getDossierTemplateNameFor(dossierTemplateId: string): string {
|
||||
return this._dossierTemplatesService.find(dossierTemplateId).name;
|
||||
return this._dossierTemplatesService.find(dossierTemplateId)?.name || '-';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
<ng-container *ngIf="dossier.dossierStatusId">
|
||||
<ng-container *ngIf="dossier.dossierStatusId && currentState">
|
||||
<div class="flex-align-items-center dossier-status-container">
|
||||
<div class="dossier-status-text">{{ currentState.name }}</div>
|
||||
<redaction-small-chip [color]="currentState.color"></redaction-small-chip>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="!dossier.dossierStatusId">
|
||||
<ng-container *ngIf="!dossier.dossierStatusId || !currentState">
|
||||
<div class="flex-align-items-center dossier-status-container">
|
||||
<div class="dossier-status-text">{{ 'edit-dossier-dialog.general-info.form.dossier-status.placeholder' | translate }}</div>
|
||||
<redaction-small-chip [color]="'#E2E4E9'"></redaction-small-chip>
|
||||
|
||||
@ -143,7 +143,7 @@ export class ConfigService {
|
||||
id =>
|
||||
new NestedFilter({
|
||||
id: id,
|
||||
label: this._dossierTemplatesService.find(id).name,
|
||||
label: this._dossierTemplatesService.find(id)?.name || '-',
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ import { MultiSelectService } from '../../services/multi-select.service';
|
||||
import { AnnotationReferencesService } from '../../services/annotation-references.service';
|
||||
import { ViewModeService } from '../../services/view-mode.service';
|
||||
import { FilePreviewStateService } from '../../services/file-preview-state.service';
|
||||
import { UserPreferenceService } from '../../../../../../services/user-preference.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-annotations-list',
|
||||
@ -28,6 +29,7 @@ export class AnnotationsListComponent implements OnChanges {
|
||||
readonly annotationReferencesService: AnnotationReferencesService,
|
||||
private readonly _filterService: FilterService,
|
||||
private readonly _state: FilePreviewStateService,
|
||||
private readonly _userPreferenceService: UserPreferenceService,
|
||||
) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
@ -37,6 +39,10 @@ export class AnnotationsListComponent implements OnChanges {
|
||||
}
|
||||
|
||||
annotationClicked(annotation: AnnotationWrapper, $event: MouseEvent): void {
|
||||
if (this._userPreferenceService.areDevFeaturesEnabled) {
|
||||
console.log('Selected Annotation:', annotation);
|
||||
}
|
||||
|
||||
if (($event?.target as IqserEventTarget)?.localName === 'input') {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div #viewer [id]="(stateService.file$ | async).fileId" class="viewer"></div>
|
||||
</div>
|
||||
|
||||
<input #compareFileInput (change)="uploadFile($event.target['files'])" class="file-upload-input" type="file" />
|
||||
<input #compareFileInput (change)="uploadFile($event.target['files'])" class="file-upload-input" type="file" accept="application/pdf" />
|
||||
|
||||
<div *ngIf="utils?.totalPages && utils?.currentPage" class="pagination noselect">
|
||||
<div (click)="utils.previousPage()">
|
||||
|
||||
@ -4,6 +4,14 @@
|
||||
<iqser-status-bar *ngIf="showStatusBar" [configs]="[{ color: file.workflowStatus, length: 1 }]"></iqser-status-bar>
|
||||
</div>
|
||||
|
||||
<input
|
||||
#importRedactionsInput
|
||||
(change)="importRedactions($event.target['files'])"
|
||||
class="file-upload-input"
|
||||
type="file"
|
||||
accept="application/pdf"
|
||||
/>
|
||||
|
||||
<ng-container *ngIf="isFilePreview || isDossierOverviewWorkflow">
|
||||
<ng-container *ngTemplateOutlet="actions"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
@ -10,6 +10,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.file-upload-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.reviewer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@ -2,6 +2,7 @@ import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
HostBinding,
|
||||
Input,
|
||||
OnChanges,
|
||||
@ -37,6 +38,9 @@ import { tap } from 'rxjs/operators';
|
||||
import { DocumentInfoService } from '../../../screens/file-preview-screen/services/document-info.service';
|
||||
import { ExpandableFileActionsComponent } from '@shared/components/expandable-file-actions/expandable-file-actions.component';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { environment } from '../../../../../../environments/environment';
|
||||
import { loadCompareDocumentWrapper } from '../../../utils/compare-mode.utils';
|
||||
import { RedactionImportService } from '../../services/redaction-import.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-actions [file] [type]',
|
||||
@ -52,12 +56,15 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
@Input() type: 'file-preview' | 'dossier-overview-list' | 'dossier-overview-workflow';
|
||||
@Input() maxWidth: number;
|
||||
|
||||
@ViewChild('importRedactionsInput', { static: true }) importRedactionsInput: ElementRef;
|
||||
|
||||
toggleTooltip?: string;
|
||||
assignTooltip?: string;
|
||||
buttonType?: CircleButtonType;
|
||||
|
||||
showUndoApproval = false;
|
||||
showAssignToSelf = false;
|
||||
showImportRedactions = false;
|
||||
showAssign = false;
|
||||
showDelete = false;
|
||||
showOCR = false;
|
||||
@ -99,6 +106,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
private readonly _reanalysisService: ReanalysisService,
|
||||
private readonly _router: Router,
|
||||
private readonly _changeRef: ChangeDetectorRef,
|
||||
private readonly _redactionImportService: RedactionImportService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@ -139,6 +147,13 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
icon: 'red:assign-me',
|
||||
show: this.showAssignToSelf,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this._triggerImportRedactions($event),
|
||||
tooltip: _('dossier-overview.import-redactions'),
|
||||
icon: 'iqser:upload',
|
||||
show: this.showImportRedactions,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.downloadBtn,
|
||||
show: true,
|
||||
@ -271,6 +286,25 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
);
|
||||
}
|
||||
|
||||
private _triggerImportRedactions($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
this.importRedactionsInput.nativeElement.click();
|
||||
}
|
||||
|
||||
async importRedactions(files: FileList) {
|
||||
const fileToImport = files[0];
|
||||
|
||||
if (!fileToImport) {
|
||||
console.error('No file to compare!');
|
||||
return;
|
||||
}
|
||||
|
||||
await firstValueFrom(this._redactionImportService.importRedactions(this.file.dossierId, this.file.fileId, fileToImport)).catch(
|
||||
exception => {},
|
||||
);
|
||||
// reload file
|
||||
}
|
||||
|
||||
forceReanalysisAction($event: LongPressEvent) {
|
||||
this.analysisForced = !$event.touchEnd && this._userPreferenceService.areDevFeaturesEnabled;
|
||||
this._setup();
|
||||
@ -380,6 +414,8 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
(this._permissionsService.canAssignUser(this.file) || this._permissionsService.canUnassignUser(this.file)) &&
|
||||
this.isDossierOverview;
|
||||
|
||||
this.showImportRedactions = this._permissionsService.canImportRedactions(this.file);
|
||||
|
||||
this.showReanalyseFilePreview = this.canReanalyse && this.isFilePreview && (this.analysisForced || this.canEnableAutoAnalysis);
|
||||
this.showReanalyseDossierOverview =
|
||||
this.canReanalyse && this.isDossierOverview && (this.analysisForced || this.canEnableAutoAnalysis);
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { GenericService, HeadersConfiguration, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
|
||||
@Injectable()
|
||||
export class RedactionImportService extends GenericService<void> {
|
||||
constructor(protected readonly _injector: Injector) {
|
||||
super(_injector, 'import-redactions');
|
||||
}
|
||||
|
||||
@Validate()
|
||||
importRedactions(@RequiredParam() dossierId: string, @RequiredParam() fileId: string, file?: Blob) {
|
||||
const formParams = new FormData();
|
||||
|
||||
if (file !== undefined) {
|
||||
formParams.append('file', file);
|
||||
}
|
||||
|
||||
const headers = HeadersConfiguration.getHeaders({ contentType: false }).append('ngsw-bypass', 'true');
|
||||
|
||||
return this._http.post<void>(`/${this._defaultModelPath}/${dossierId}/${fileId}`, formParams, {
|
||||
headers,
|
||||
observe: 'response',
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -4,13 +4,14 @@ import { FileAssignService } from './services/file-assign.service';
|
||||
import { FileActionsComponent } from './components/file-actions/file-actions.component';
|
||||
import { IqserIconsModule } from '@iqser/common-ui';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { RedactionImportService } from './services/redaction-import.service';
|
||||
|
||||
const components = [FileActionsComponent];
|
||||
|
||||
@NgModule({
|
||||
declarations: [...components],
|
||||
exports: [...components],
|
||||
providers: [FileAssignService],
|
||||
providers: [FileAssignService, RedactionImportService],
|
||||
imports: [CommonModule, IqserIconsModule, SharedModule],
|
||||
})
|
||||
export class SharedDossiersModule {}
|
||||
|
||||
@ -15,6 +15,6 @@ export class DictionariesMapService extends EntitiesMapService<Dictionary, IDict
|
||||
}
|
||||
|
||||
getDictionaryColor(type: string, dossierTemplateId: string) {
|
||||
return !this.get(dossierTemplateId) ? '#cccccc' : this.getDictionary(type, dossierTemplateId).hexColor;
|
||||
return !this.get(dossierTemplateId) ? '#cccccc' : this.getDictionary(type, dossierTemplateId)?.hexColor || '#cccccc';
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import { EntitiesService, mapEach, RequiredParam, Validate } from '@iqser/common
|
||||
import { DossierState, IDossierState } from '@red/domain';
|
||||
import { forkJoin, Observable, switchMap } from 'rxjs';
|
||||
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { defaultIfEmpty, map, tap } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@ -27,7 +27,7 @@ export class DossierStateService extends EntitiesService<DossierState, IDossierS
|
||||
return this._dossierTemplatesService.all$.pipe(
|
||||
mapEach(template => template.dossierTemplateId),
|
||||
mapEach(id => this.loadAllForTemplate(id)),
|
||||
switchMap(all => forkJoin(all)),
|
||||
switchMap(all => forkJoin(all).pipe(defaultIfEmpty([]))),
|
||||
map(value => value.flatMap(item => item)),
|
||||
tap(value => this.setEntities(value)),
|
||||
);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { EntitiesService, List, mapEach, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
|
||||
import { DossierTemplate, IDossierTemplate } from '@red/domain';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { forkJoin, Observable, throwError } from 'rxjs';
|
||||
import { forkJoin, map, Observable, of, throwError } from 'rxjs';
|
||||
import { FileAttributesService } from './file-attributes.service';
|
||||
import { catchError, mapTo, switchMap, tap } from 'rxjs/operators';
|
||||
import { DossierTemplateStatsService } from '@services/entity-services/dossier-template-stats.service';
|
||||
@ -34,13 +34,17 @@ export class DossierTemplatesService extends EntitiesService<DossierTemplate, ID
|
||||
return this.getAll().pipe(
|
||||
mapEach(entity => new DossierTemplate(entity)),
|
||||
/* Load stats before updating entities */
|
||||
switchMap(templates =>
|
||||
forkJoin([
|
||||
this._dossierTemplateStatsService.getFor(dossierTemplateIds(templates)),
|
||||
...getAttributes(templates),
|
||||
this._dictionaryService.loadDictionaryData(dossierTemplateIds(templates)),
|
||||
]).pipe(mapTo(templates)),
|
||||
),
|
||||
switchMap(templates => {
|
||||
if (templates.length) {
|
||||
return forkJoin([
|
||||
this._dossierTemplateStatsService.getFor(dossierTemplateIds(templates)),
|
||||
...getAttributes(templates),
|
||||
this._dictionaryService.loadDictionaryData(dossierTemplateIds(templates)),
|
||||
]).pipe(mapTo(templates));
|
||||
} else {
|
||||
return of(templates);
|
||||
}
|
||||
}),
|
||||
tap(templates => this.setEntities(templates)),
|
||||
);
|
||||
}
|
||||
|
||||
@ -154,6 +154,10 @@ export class PermissionsService {
|
||||
return (comment.user === this._userService.currentUser.id || this.isApprover(dossier)) && !file.isApproved;
|
||||
}
|
||||
|
||||
canImportRedactions(file: File) {
|
||||
return (this.isFileAssignee(file) || this.isApprover(this._getDossier(file))) && !file.isApproved;
|
||||
}
|
||||
|
||||
private _canToggleAnalysis(file: File): boolean {
|
||||
return this.isFileAssignee(file) && (file.isNew || file.isUnderReview || file.isUnderApproval);
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"ADMIN_CONTACT_NAME": null,
|
||||
"ADMIN_CONTACT_URL": null,
|
||||
"API_URL": "https://dev-04.iqser.cloud/redaction-gateway-v1",
|
||||
"API_URL": "https://rosa1.iqser.cloud/redaction-gateway-v1",
|
||||
"APP_NAME": "RedactManager",
|
||||
"AUTO_READ_TIME": 3,
|
||||
"BACKEND_APP_VERSION": "4.4.40",
|
||||
@ -17,7 +17,7 @@
|
||||
"MAX_RETRIES_ON_SERVER_ERROR": 3,
|
||||
"OAUTH_CLIENT_ID": "redaction",
|
||||
"OAUTH_IDP_HINT": null,
|
||||
"OAUTH_URL": "https://dev-04.iqser.cloud/auth/realms/redaction",
|
||||
"OAUTH_URL": "https://rosa1.iqser.cloud/auth/realms/redaction",
|
||||
"RECENT_PERIOD_IN_HOURS": 24,
|
||||
"SELECTION_MODE": "structural",
|
||||
"MANUAL_BASE_URL": "https://docs.redactmanager.com/3.0"
|
||||
|
||||
@ -733,6 +733,7 @@
|
||||
"assign-approver": "Assign Approver",
|
||||
"assign-me": "Assign To Me",
|
||||
"assign-reviewer": "Assign User",
|
||||
"import-redactions": "Import redactions from other file",
|
||||
"bulk": {
|
||||
"delete": "Delete Documents",
|
||||
"reanalyse": "Analyze Documents"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user