min word length fixed to 2

This commit is contained in:
Timo 2020-12-02 19:22:16 +02:00
parent e0c26c14ba
commit 962b1d39af
10 changed files with 158 additions and 58 deletions

View File

@ -17,6 +17,8 @@ declare var ace;
styleUrls: ['./dictionary-overview-screen.component.scss']
})
export class DictionaryOverviewScreenComponent {
static readonly MIN_WORD_LENGTH: number = 2;
@ViewChild('editorComponent')
editorComponent: AceEditorComponent;
@ -136,12 +138,12 @@ export class DictionaryOverviewScreenComponent {
const Range = ace.acequire('ace/range').Range;
for (const i of this.changedLines) {
let entry = this.currentDictionaryEntries[i];
const entry = this.currentDictionaryEntries[i];
if (entry?.trim().length > 0) {
// only mark non-empty lines
this.activeEditMarkers.push(this.editorComponent.getEditor().getSession().addMarker(new Range(i, 0, i, 1), 'changed-row-marker', 'fullLine'));
}
if (entry?.trim().length > 0 && entry.trim().length < 3) {
if (entry?.trim().length > 0 && entry.trim().length < DictionaryOverviewScreenComponent.MIN_WORD_LENGTH) {
// show lines that are to short
this.activeEditMarkers.push(this.editorComponent.getEditor().getSession().addMarker(new Range(i, 0, i, 1), 'to-short-marker', 'fullLine'));
}
@ -167,15 +169,21 @@ export class DictionaryOverviewScreenComponent {
});
// remove empty lines
entriesToAdd = entriesToAdd.filter((e) => e && e.trim().length > 0);
entriesToAdd = entriesToAdd.filter((e) => e && e.trim().length > 0).map((e) => e.trim());
if (entriesToAdd.length > 0) {
await this._dictionaryControllerService.addEntry(entriesToAdd, this.dictionary.type).toPromise();
const invalidRowsExist = entriesToAdd.filter((e) => e.length < DictionaryOverviewScreenComponent.MIN_WORD_LENGTH);
if (invalidRowsExist.length === 0) {
if (entriesToAdd.length > 0) {
await this._dictionaryControllerService.addEntry(entriesToAdd, this.dictionary.type).toPromise();
}
if (entriesToDelete.length > 0) {
await this._dictionaryControllerService.deleteEntries(entriesToDelete, this.dictionary.type).toPromise();
}
this._initialize();
} else {
console.log('Invalid ROW', invalidRowsExist);
}
if (entriesToDelete.length > 0) {
await this._dictionaryControllerService.deleteEntries(entriesToDelete, this.dictionary.type).toPromise();
}
this._initialize();
// .ace_marker-layer .search-marker
}

View File

@ -1,4 +1,4 @@
import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ChangeDetectorRef, Component, HostListener, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { NotificationService, NotificationType } from '../../notification/notification.service';
import { AppStateService } from '../../state/app-state.service';
@ -38,6 +38,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
public needsWorkFilters: FilterModel[];
public collapsedDetails = false;
public searchForm: FormGroup;
showFileDrop: boolean;
displayedFiles: FileStatusWrapper[] = [];
@ -188,12 +189,14 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
file: file,
progress: 0,
completed: false,
error: null
error: null,
retryCount: 0
});
}
this._fileUploadService.uploadFiles(uploadFiles);
this._uploadStatusOverlayService.openStatusOverlay();
this._changeDetectorRef.detectChanges();
}
private _computeAllFilters() {

View File

@ -1,4 +1,4 @@
<section>
<section (mouseout)="close()">
<ngx-dropzone (change)="handleFileInput($event.addedFiles)" class="file-drop-zone">
<ngx-dropzone-label>{{ 'project-overview.upload-files' | translate }}</ngx-dropzone-label>
</ngx-dropzone>

View File

@ -1,4 +1,4 @@
import { Component, HostListener, OnInit } from '@angular/core';
import { ChangeDetectorRef, Component, HostListener, OnInit } from '@angular/core';
import { FileUploadService } from '../file-upload.service';
import { FileUploadModel } from '../model/file-upload.model';
import { OverlayRef } from '@angular/cdk/overlay';
@ -13,7 +13,8 @@ export class FileDropComponent implements OnInit {
constructor(
private readonly _dialogRef: OverlayRef,
private readonly _fileUploadService: FileUploadService,
private _uploadStatusOverlayService: UploadStatusOverlayService
private readonly _changeDetectorRef: ChangeDetectorRef,
private readonly _uploadStatusOverlayService: UploadStatusOverlayService
) {}
ngOnInit() {}
@ -35,12 +36,14 @@ export class FileDropComponent implements OnInit {
file: file,
progress: 0,
completed: false,
error: null
error: null,
retryCount: 0
});
}
this._fileUploadService.uploadFiles(uploadFiles);
this._uploadStatusOverlayService.openStatusOverlay();
this._dialogRef.detach();
this._changeDetectorRef.detectChanges();
}
}

View File

@ -1,13 +1,13 @@
import { Injectable, Injector } from '@angular/core';
import { Overlay } from '@angular/cdk/overlay';
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
import { FileDropComponent } from '../file-drop.component';
import { ComponentPortal } from '@angular/cdk/portal';
import { OverlayRef } from '@angular/cdk/overlay';
@Injectable({
providedIn: 'root'
})
export class FileDropOverlayService {
private _mouseIn: boolean = false;
private readonly _dropOverlayRef: OverlayRef;
constructor(private overlay: Overlay, private readonly _injector: Injector) {
@ -17,29 +17,40 @@ export class FileDropOverlayService {
});
}
dragListener = () => {
this.openFileDropOverlay();
dragListener = (e) => {
e.preventDefault();
e.stopPropagation();
if (this._mouseIn) {
this.openFileDropOverlay();
}
return false;
};
mouseIn = (e) => {
e.preventDefault();
e.stopPropagation();
this._mouseIn = true;
return false;
};
mouseOut = (e) => {
e.preventDefault();
e.stopPropagation();
if (e.toElement == null && e.relatedTarget == null) {
this._mouseIn = false;
this.closeFileDropOverlay();
}
return false;
};
initFileDropHandling() {
document
.getElementsByTagName('body')[0]
.addEventListener('dragenter', this.dragListener, false);
document.getElementsByTagName('body')[0].addEventListener('dragenter', this.dragListener, false);
document.getElementsByTagName('body')[0].addEventListener('mouseenter', this.mouseIn, false);
document.getElementsByTagName('body')[0].addEventListener('mouseout', this.mouseOut, false);
}
cleanupFileDropHandling() {
document
.getElementsByTagName('body')[0]
.removeEventListener('dragenter', this.dragListener, false);
document
.getElementsByTagName('body')[0]
.removeEventListener('mouseout', this.mouseOut, false);
document.getElementsByTagName('body')[0].removeEventListener('dragenter', this.dragListener, false);
document.getElementsByTagName('body')[0].removeEventListener('mouseenter', this.mouseIn, false);
document.getElementsByTagName('body')[0].removeEventListener('mouseout', this.mouseOut, false);
}
private _createInjector() {

View File

@ -3,43 +3,108 @@ import { FileUploadModel } from './model/file-upload.model';
import { AppStateService } from '../state/app-state.service';
import { HttpEventType } from '@angular/common/http';
import { FileManagementControllerService } from '@redaction/red-ui-http';
import { interval, Subscription } from 'rxjs';
export interface UploadFile {
fileUploadModel: FileUploadModel;
}
@Injectable({
providedIn: 'root'
})
export class FileUploadService {
static readonly MAX_PARALLEL_UPLOADS = 5;
files: FileUploadModel[] = [];
constructor(private readonly _appStateService: AppStateService, private readonly _fileManagementControllerService: FileManagementControllerService) {}
activeUploads: number = 0;
private _pendingUploads: UploadFile[] = [];
private _activeUploads: Subscription[] = [];
constructor(private readonly _appStateService: AppStateService, private readonly _fileManagementControllerService: FileManagementControllerService) {
interval(2500).subscribe((val) => {
this._handleUploads();
});
}
scheduleUpload(item: FileUploadModel) {
this._pendingUploads.push({
fileUploadModel: item
});
}
uploadFiles(files: FileUploadModel[]) {
this.files.push(...files);
files.forEach((newFile) => {
this._fileManagementControllerService.uploadFileForm(newFile.file, this._appStateService.activeProject.project.projectId, 'events', true).subscribe(
async (event) => {
if (event.type === HttpEventType.UploadProgress) {
newFile.progress = Math.round((event.loaded / (event.total || event.loaded)) * 100);
}
if (event.type === HttpEventType.Response) {
if (event.status < 300) {
newFile.progress = 100;
newFile.completed = true;
} else {
newFile.completed = true;
newFile.error = event.body;
}
await this._appStateService.reloadActiveProjectFiles();
}
},
(error) => {
newFile.completed = true;
newFile.error = error;
}
);
this.scheduleUpload(newFile);
});
}
stopAllUploads() {
this.files = [];
}
private _handleUploads() {
if (this._activeUploads.length < FileUploadService.MAX_PARALLEL_UPLOADS && this._pendingUploads.length > 0) {
let cnt = FileUploadService.MAX_PARALLEL_UPLOADS - this._activeUploads.length;
while (cnt > 0) {
cnt--;
const popped = this._pendingUploads.pop();
if (popped) {
const sub = this._createSubscription(popped);
this._activeUploads.push(sub);
} else {
return;
}
}
}
}
private _createSubscription(uploadFile: UploadFile) {
this.activeUploads++;
const obs = this._fileManagementControllerService.uploadFileForm(
uploadFile.fileUploadModel.file,
this._appStateService.activeProject.project.projectId,
'events',
true
);
const subscription = obs.subscribe(
async (event) => {
if (event.type === HttpEventType.UploadProgress) {
uploadFile.fileUploadModel.progress = Math.round((event.loaded / (event.total || event.loaded)) * 100);
}
if (event.type === HttpEventType.Response) {
if (event.status < 300) {
uploadFile.fileUploadModel.progress = 100;
uploadFile.fileUploadModel.completed = true;
} else {
uploadFile.fileUploadModel.completed = true;
uploadFile.fileUploadModel.error = event.body;
}
this._removeUpload(subscription);
await this._appStateService.reloadActiveProjectFiles();
}
},
(error) => {
uploadFile.fileUploadModel.completed = true;
uploadFile.fileUploadModel.error = error;
this._removeUpload(subscription);
}
);
return subscription;
}
private _removeUpload(subscription: Subscription) {
const index = this._activeUploads.indexOf(subscription);
if (index > -1) {
this._activeUploads.splice(index, 1);
this.activeUploads--;
}
}
removeFile(item: FileUploadModel) {
const index = this.files.indexOf(item);
if (index > -1) {
this.files.splice(index, 1);
}
}
}

View File

@ -3,4 +3,5 @@ export interface FileUploadModel {
progress: number;
completed: boolean;
error: any;
retryCount: number;
}

View File

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { FileUploadModel } from '../model/file-upload.model';
import { FileUploadService } from '../file-upload.service';
import { OverlayRef } from '@angular/cdk/overlay';
@ -13,7 +13,11 @@ export class UploadStatusOverlay implements OnInit {
uploadStatusInterval: number;
constructor(public readonly uploadService: FileUploadService, private readonly _overlayRef: OverlayRef) {}
constructor(
public readonly uploadService: FileUploadService,
private readonly _overlayRef: OverlayRef,
private readonly _changeDetectorRef: ChangeDetectorRef
) {}
ngOnInit() {
this.uploadStatusInterval = setInterval(() => {
@ -27,11 +31,16 @@ export class UploadStatusOverlay implements OnInit {
}, 2500);
}
cancelItem(item: FileUploadModel) {}
cancelItem(item: FileUploadModel) {
this.uploadService.removeFile(item);
}
uploadItem(item: FileUploadModel) {
item.progress = 0;
item.completed = false;
item.error = null;
this._changeDetectorRef.detectChanges();
this.uploadService.scheduleUpload(item);
}
closeDialog() {

View File

@ -1,5 +1,5 @@
{
"OAUTH_URL": "https://redkc-staging.iqser.cloud/auth/realms/redaction",
"OAUTH_CLIENT_ID": "redaction",
"API_URL": "https://timo-redaction-dev.iqser.cloud"
"API_URL": "https://redapi-staging.iqser.cloud"
}

View File

@ -8476,10 +8476,10 @@ ngx-color-picker@^10.1.0:
dependencies:
tslib "^2.0.0"
ngx-dropzone@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/ngx-dropzone/-/ngx-dropzone-2.2.2.tgz#450609031efb909461181c6b693d7c5f793a278d"
integrity sha512-REuBcPNTY33OtcZD6dw8Fq/jFqwviiYydYaCn74yig8TvDDYhtJ/BPjtvbw7uEgF4BJr/UEHbKMvkdZIyCgsww==
ngx-dropzone@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/ngx-dropzone/-/ngx-dropzone-2.3.0.tgz#fb34bceb0d8ad3c00c314b957d095018d15c5fe9"
integrity sha512-Mhsu6MW1yJRxLPRPbwal7y18trokU9josTD8GDb8wFRmaCd/N+dJeMDXn0XsxtDhlZ7vWqbpEr9k0ej4Na3v8Q==
dependencies:
tslib "^1.9.0"