Pull request #88: RED-910: Show a dialog if a file already exists
Merge in RED/ui from RED-910 to master * commit '32f29c946f8f664e46151abde3f43274f4a9f18f': fixed lint err Show a dialog if a file already exists Fixed sync width directive
This commit is contained in:
commit
c738fafec7
@ -104,6 +104,7 @@ import { RuleSetActionsComponent } from './components/rule-set-actions/rule-set-
|
||||
import { RuleSetViewSwitchComponent } from './components/rule-set-view-switch/rule-set-view-switch.component';
|
||||
import { MatSliderModule } from '@angular/material/slider';
|
||||
import { PendingChangesGuard } from './utils/can-deactivate.guard';
|
||||
import { OverwriteFilesDialogComponent } from './dialogs/overwrite-files-dialog/overwrite-files-dialog.component';
|
||||
|
||||
export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
|
||||
@ -276,6 +277,7 @@ const matImports = [
|
||||
ProjectOverviewScreenComponent,
|
||||
AddEditProjectDialogComponent,
|
||||
ConfirmationDialogComponent,
|
||||
OverwriteFilesDialogComponent,
|
||||
FilePreviewScreenComponent,
|
||||
PdfViewerComponent,
|
||||
AssignOwnerDialogComponent,
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
:host {
|
||||
display: flex;
|
||||
height: 30px;
|
||||
flex: 1;
|
||||
|
||||
> div {
|
||||
align-items: center;
|
||||
|
||||
@ -22,6 +22,7 @@ import { ManualAnnotationService } from '../screens/file/service/manual-annotati
|
||||
import { ProjectWrapper } from '../state/model/project.wrapper';
|
||||
import { AddEditDictionaryDialogComponent } from '../screens/admin/dictionary-listing-screen/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component';
|
||||
import { AddEditRuleSetDialogComponent } from '../screens/admin/rule-sets-listing-screen/add-edit-rule-set-dialog/add-edit-rule-set-dialog.component';
|
||||
import { OverwriteFilesDialogComponent } from './overwrite-files-dialog/overwrite-files-dialog.component';
|
||||
|
||||
const dialogConfig = {
|
||||
width: '662px',
|
||||
@ -331,4 +332,18 @@ export class DialogService {
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
openOverwriteFileDialog(filename: string): Promise<{ option?: 'overwrite' | 'no-overwrite'; remember?: boolean; cancel?: boolean }> {
|
||||
const ref = this._dialog.open(OverwriteFilesDialogComponent, {
|
||||
...dialogConfig,
|
||||
data: filename
|
||||
});
|
||||
|
||||
return ref
|
||||
.afterClosed()
|
||||
.toPromise()
|
||||
.then((res) => {
|
||||
return res || { cancel: true };
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
<section class="dialog">
|
||||
<div class="dialog-header heading-l" translate="overwrite-files-dialog.title"></div>
|
||||
|
||||
<div class="dialog-content">
|
||||
<p [innerHTML]="'overwrite-files-dialog.question' | translate: { filename: filename }"></p>
|
||||
|
||||
<mat-checkbox [checked]="remember" (change)="remember = !remember" color="primary">
|
||||
{{ 'overwrite-files-dialog.options.remember' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<div class="all-caps-label primary pointer" (click)="selectOption('overwrite')" translate="overwrite-files-dialog.options.overwrite"></div>
|
||||
<div class="all-caps-label primary pointer" (click)="selectOption('no-overwrite')" translate="overwrite-files-dialog.options.no-overwrite"></div>
|
||||
<div class="all-caps-label cancel" (click)="cancel()" translate="overwrite-files-dialog.options.cancel"></div>
|
||||
</div>
|
||||
</section>
|
||||
@ -0,0 +1,7 @@
|
||||
mat-checkbox {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.dialog-actions > div:not(:last-child) {
|
||||
margin-right: 32px;
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-overwrite-files-dialog',
|
||||
templateUrl: './overwrite-files-dialog.component.html',
|
||||
styleUrls: ['./overwrite-files-dialog.component.scss']
|
||||
})
|
||||
export class OverwriteFilesDialogComponent implements OnInit {
|
||||
public remember = false;
|
||||
|
||||
constructor(
|
||||
private readonly _translateService: TranslateService,
|
||||
public dialogRef: MatDialogRef<OverwriteFilesDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public filename: string
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
cancel() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
selectOption(option: 'overwrite' | 'no-overwrite') {
|
||||
this.dialogRef.close({ option, remember: this.remember });
|
||||
}
|
||||
}
|
||||
@ -212,13 +212,15 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
uploadFiles(files: File[] | FileList) {
|
||||
this._uploadFiles(convertFiles(files, this.appStateService.activeProjectId));
|
||||
async uploadFiles(files: File[] | FileList) {
|
||||
await this._uploadFiles(convertFiles(files, this.appStateService.activeProjectId));
|
||||
}
|
||||
|
||||
private _uploadFiles(files: FileUploadModel[]) {
|
||||
this._fileUploadService.uploadFiles(files);
|
||||
this._uploadStatusOverlayService.openStatusOverlay();
|
||||
private async _uploadFiles(files: FileUploadModel[]) {
|
||||
const fileCount = await this._fileUploadService.uploadFiles(files);
|
||||
if (fileCount) {
|
||||
this._uploadStatusOverlayService.openStatusOverlay();
|
||||
}
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
|
||||
@ -44,9 +44,11 @@ export class FileDropComponent implements OnInit {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
uploadFiles(files: FileUploadModel[]) {
|
||||
this._fileUploadService.uploadFiles(files);
|
||||
this._uploadStatusOverlayService.openStatusOverlay();
|
||||
async uploadFiles(files: FileUploadModel[]) {
|
||||
const fileCount = await this._fileUploadService.uploadFiles(files);
|
||||
if (fileCount) {
|
||||
this._uploadStatusOverlayService.openStatusOverlay();
|
||||
}
|
||||
this._dialogRef.detach();
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import { FileManagementControllerService } from '@redaction/red-ui-http';
|
||||
import { interval, Subscription } from 'rxjs';
|
||||
import { AppConfigKey, AppConfigService } from '../app-config/app-config.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DialogService } from '../dialogs/dialog.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@ -23,7 +24,8 @@ export class FileUploadService {
|
||||
private readonly _applicationRef: ApplicationRef,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _appConfigService: AppConfigService,
|
||||
private readonly _fileManagementControllerService: FileManagementControllerService
|
||||
private readonly _fileManagementControllerService: FileManagementControllerService,
|
||||
private readonly _dialogService: DialogService
|
||||
) {
|
||||
interval(2500).subscribe((val) => {
|
||||
this._handleUploads();
|
||||
@ -39,20 +41,41 @@ export class FileUploadService {
|
||||
}
|
||||
}
|
||||
|
||||
uploadFiles(files: FileUploadModel[]) {
|
||||
async uploadFiles(files: FileUploadModel[]): Promise<number> {
|
||||
const maxSizeMB = this._appConfigService.getConfig(AppConfigKey.MAX_FILE_SIZE_MB, 50);
|
||||
const maxSizeBytes = maxSizeMB * 1024 * 1024;
|
||||
files.forEach((file) => {
|
||||
const projectFiles = this._appStateService.activeProject.files;
|
||||
let option: 'overwrite' | 'no-overwrite' | undefined;
|
||||
for (let idx = 0; idx < files.length; ++idx) {
|
||||
const file = files[idx];
|
||||
let currentOption = option;
|
||||
if (!!projectFiles.find((pf) => pf.filename === file.file.name)) {
|
||||
if (!option) {
|
||||
const res = await this._dialogService.openOverwriteFileDialog(file.file.name);
|
||||
if (res.cancel) {
|
||||
return;
|
||||
}
|
||||
currentOption = res.option;
|
||||
option = res.remember ? currentOption : undefined;
|
||||
}
|
||||
|
||||
if (currentOption === 'no-overwrite') {
|
||||
files.splice(idx, 1);
|
||||
--idx;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (file.size > maxSizeBytes) {
|
||||
file.completed = true;
|
||||
file.error = { message: this._translateService.instant('upload-status.error.file-size', { size: maxSizeMB }) };
|
||||
file.sizeError = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
this.files.push(...files);
|
||||
files.forEach((newFile) => {
|
||||
this.scheduleUpload(newFile);
|
||||
});
|
||||
return files.length;
|
||||
}
|
||||
|
||||
stopAllUploads() {
|
||||
|
||||
@ -15,6 +15,22 @@ export class SyncWidthDirective implements AfterViewChecked {
|
||||
this.matchWidth();
|
||||
}
|
||||
|
||||
private get _sampleRow(): { tableRow: Element; length: number } {
|
||||
const tableRows = document.getElementsByClassName(this.redactionSyncWidth);
|
||||
let length = 0;
|
||||
let tableRow: Element;
|
||||
|
||||
for (let idx = 0; idx < tableRows.length; ++idx) {
|
||||
const row = tableRows.item(idx);
|
||||
if (row.children.length > length) {
|
||||
length = row.children.length;
|
||||
tableRow = row;
|
||||
}
|
||||
}
|
||||
|
||||
return { tableRow, length };
|
||||
}
|
||||
|
||||
@debounce(0)
|
||||
matchWidth() {
|
||||
const headerItems = this.el.nativeElement.children;
|
||||
@ -22,13 +38,18 @@ export class SyncWidthDirective implements AfterViewChecked {
|
||||
|
||||
if (!tableRows || !tableRows.length) return;
|
||||
|
||||
const tableRow = tableRows[0];
|
||||
if (tableRow.children.length !== headerItems.length) return;
|
||||
const { tableRow, length } = this._sampleRow;
|
||||
|
||||
for (let idx = 0; idx < headerItems.length - 1; ++idx) {
|
||||
const hasExtraColumns = headerItems.length !== length ? 1 : 0;
|
||||
|
||||
for (let idx = 0; idx < length - hasExtraColumns - 1; ++idx) {
|
||||
headerItems[idx].style.width = `${tableRow.children[idx].getBoundingClientRect().width}px`;
|
||||
headerItems[idx].style.minWidth = `${tableRow.children[idx].getBoundingClientRect().width}px`;
|
||||
}
|
||||
|
||||
for (let idx = length - hasExtraColumns - 1; idx < headerItems.length; ++idx) {
|
||||
headerItems[idx].style.minWidth = `0`;
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('window:resize')
|
||||
|
||||
@ -695,5 +695,15 @@
|
||||
"rule-editor": "Rule Editor",
|
||||
"watermark": "Watermark",
|
||||
"pending-changes-guard": "WARNING: You have unsaved changes. Press Cancel to go back and save these changes, or OK to lose these changes.",
|
||||
"reset-filters": "Reset Filters"
|
||||
"reset-filters": "Reset Filters",
|
||||
"overwrite-files-dialog": {
|
||||
"title": "File already exists!",
|
||||
"question": "<b>{{filename}}</b> already exists. What do you want to do?",
|
||||
"options": {
|
||||
"overwrite": "Overwrite",
|
||||
"no-overwrite": "Keep old file",
|
||||
"cancel": "Cancel all uploads",
|
||||
"remember": "Remember option"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user