Skip to content

Commit

Permalink
Folder names invalid characters check and code improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
vilarodr committed Jan 25, 2024
1 parent 2401669 commit 7fb2f1c
Show file tree
Hide file tree
Showing 11 changed files with 477 additions and 130 deletions.
1 change: 1 addition & 0 deletions assets/images/logos/_org-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
263 changes: 262 additions & 1 deletion assets/images/logos/org-logo.svg
100755 → 100644
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
84 changes: 35 additions & 49 deletions src/index-renderer/components/data-file-list.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { JsonData } from './../../model/json-data';
import { ipcRenderer, shell } from 'electron';

import Cmp from './base-component.js';
Expand All @@ -9,59 +10,40 @@ export class DataFileList extends Cmp<HTMLDivElement, HTMLDivElement> {
fileListElement: HTMLUListElement;
openDatasetElement: HTMLLinkElement;

modalElement: HTMLElement;
modalButtonElement: HTMLButtonElement;
backdropElement: HTMLElement;

selectedFiles: FileInfo[];

constructor() {
super("data-file-list", "app-file-list", true, "file2upload-list");
this.fileListElement = this.element.querySelector(
"#research-files-list"
) as HTMLUListElement;

this.modalElement = document.getElementById('alertModal') as HTMLElement;
this.modalButtonElement = document.getElementById(
'modalClose'
) as HTMLButtonElement;

this.backdropElement = document.getElementById('backdrop') as HTMLElement;

this.selectedFiles = [];

this.configure();
}

configure(): void {
this.modalButtonElement.addEventListener('click', this.closeModal.bind(this));

this.backdropElement.style.display = "none";
this.backdropElement.style.visibility = "hidden";

const regexp = /[:;#<>"\*\?\/\|]/ ;

ipcRenderer.setMaxListeners(0);

dataFiles.updateListener((file: FileInfo) => {
if (!regexp.test(file.name)) {
this.selectedFiles.push(file);
this.renderItem(this.selectedFiles[this.selectedFiles.length - 1]);
} else {
dataFiles.removeDataFile(file);
this.openModal(`<strong>${file.name}</strong> excluded from your selection! <hr>File Name cannot contain any of the following characters: <br/><strong> / : * ? \" < > | ; #</strong>`);
}
this.selectedFiles.push(file);
this.renderItem(this.selectedFiles[this.selectedFiles.length - 1]);
});

ipcRenderer.on("DO_FILE_CLEAR", (event: Event, file: FileInfo) => {
dataFiles.removeDataFile(file);
this.selectedFiles.splice(file.id, 1);
const element = document.getElementById(file.id.toString());
element.remove();
if (!dataFiles.length()) {
(document.getElementById("clear") as HTMLButtonElement).disabled = true;
(document.getElementById("upload") as HTMLButtonElement).disabled = true;
(document.getElementById("cancel") as HTMLButtonElement).disabled = true;
if (dataFiles.length() === 0) {
(document.querySelector(
'#clear'
) as HTMLButtonElement).disabled = true;
(document.querySelector(
'#upload'
) as HTMLButtonElement).disabled = true;
ipcRenderer.send('DO_CLEAR_SELECTED');
}
});

Expand All @@ -71,20 +53,20 @@ export class DataFileList extends Cmp<HTMLDivElement, HTMLDivElement> {

this.element.querySelector(
"ul"
)!.innerHTML = `<div id="upload-done">
<h5>${result.numFiles2Upload}<i> files to upload, </i>${(result.numFiles2Upload as number) - (result.numFilesUploaded as number)} fails</h5>
<h5>${result.numFilesUploaded}<i> files uploaded to </i>${result.destination}</h5>
<br>
<a id="open-dataset" href="${repository}/dataset.xhtml?persistentId=${result.destination}&version=DRAFT" target="_blank"><button class="btn btn-secondary"><i class="bi bi-card-checklist"></i> Open Dataset</button></a>
</div>`;
)!.innerHTML = this.successReport(result, repository);
this.openDatasetElement = document.getElementById(
'open-dataset'
) as HTMLLinkElement;
this.openDatasetElement.addEventListener('click', this.openDatasetHandler.bind(this));
});

(document.getElementById("cancel") as HTMLButtonElement).disabled = true;
(document.getElementById("files") as HTMLButtonElement).disabled = false;
(document.getElementById("folder") as HTMLButtonElement).disabled = false;
ipcRenderer.on("UPLOAD_FAILED", (event: Event, result: Record<string, unknown>, repository: string) => {
this.selectedFiles = [];
dataFiles.clear();

this.element.querySelector(
"ul"
)!.innerHTML = this.failReport(result);
});

ipcRenderer.on("abort", (event: Event, result: Record<string, unknown>) => {
Expand Down Expand Up @@ -118,19 +100,23 @@ export class DataFileList extends Cmp<HTMLDivElement, HTMLDivElement> {
shell.openExternal(this.openDatasetElement.href);
}

private openModal(message:string) {
this.backdropElement.style.display = "block"
this.backdropElement.style.visibility = "visible"
this.modalElement.style.display = "block"
this.modalElement.classList.add("show");
this.modalElement.children[0].children[0].children[1].innerHTML = message;
private successReport(result: any, repository: any): string {

return `<div id="upload-done">
<h5>Upload report</h5>
<h5>${result.numFiles2Upload}<i> files to upload, </i>${(result.numFiles2Upload as number) - (result.numFilesUploaded as number)} fails</h5>
<h5>${result.numFilesUploaded}<i> files uploaded to </i>${result.destination}</h5>
<br>
<a id="open-dataset" href="${repository}/dataset.xhtml?persistentId=${result.destination}&version=DRAFT" target="_blank"><button class="btn btn-secondary"><i class="bi bi-card-checklist"></i> Open your dataset page on browser </button></a>
</div>`;
}

private closeModal() {
this.backdropElement.style.display = "none"
this.backdropElement.style.visibility = "hidden"
this.modalElement.style.display = "none"
this.modalElement.classList.remove("show");
private failReport(result: any): string {

return `<div id="upload-failed">
<h5>Upload failed!</h5>
<p>${result}</p>
</div>`;
}

}
140 changes: 103 additions & 37 deletions src/index-renderer/components/data-files-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export class DataFilesInput extends Cmp<HTMLDivElement, HTMLFormElement> {
submitButtonElement: HTMLButtonElement;
cancelButtonElement: HTMLButtonElement;

modalElement: HTMLElement;
modalButtonElement: HTMLButtonElement;
backdropElement: HTMLElement;

MAXFILES: number;
remainingFiles: number;
enteredFiles: FileInfo[]
Expand All @@ -34,11 +38,20 @@ export class DataFilesInput extends Cmp<HTMLDivElement, HTMLFormElement> {
'#cancel'
) as HTMLButtonElement;

this.modalElement = document.getElementById('alertModal') as HTMLElement;
this.modalButtonElement = document.getElementById(
'modalClose'
) as HTMLButtonElement;

this.backdropElement = document.getElementById('backdrop') as HTMLElement;

this.configure();
}

configure():void {
this.MAXFILES = 2000;
const regexp = /[:;#<>"\*\?\/\|]/ ;
const regexp2 = /[^A-Za-z0-9_ .\/\-]+/ ;

this.element.addEventListener('change', this.changeHandler.bind(this));
this.filesButtonElement.addEventListener('click', this.filesHandler.bind(this));
Expand All @@ -47,9 +60,13 @@ export class DataFilesInput extends Cmp<HTMLDivElement, HTMLFormElement> {
this.submitButtonElement.addEventListener('click', this.submitHandler.bind(this));
this.cancelButtonElement.addEventListener('click', this.cancelHandler.bind(this));

this.modalButtonElement.addEventListener('click', this.closeModal.bind(this));

this.backdropElement.style.display = "none";
this.backdropElement.style.visibility = "hidden";

ipcRenderer.on('DO_FILE_SELECT', (event: Event, folder: string, filesCount: number) => {
const dsSelected = document.getElementById("dataset") as HTMLInputElement;
if (dsSelected.value.length > 0 && dsSelected.value[0].length > 0) {
if (this.isDSSelected) {
this.filesButtonElement.disabled = false;
} else {
this.filesButtonElement.disabled = true;
Expand All @@ -59,26 +76,27 @@ export class DataFilesInput extends Cmp<HTMLDivElement, HTMLFormElement> {
})

ipcRenderer.on('FILE_SELECT_DONE', (event: Event, enteredFiles: FileInfo[]) => {
const doneElement = document.getElementById('upload-done');
if (doneElement) {
doneElement.innerHTML = '';
}
this.clearView();
if (enteredFiles.length) {
const files = Array.from(enteredFiles);
enteredFiles.forEach((file) => {
dataFiles.addFile(file);
if (!regexp.test(file.name)) {
dataFiles.addFile(file);
} else {
this.openModal(`<strong>${file.name}</strong> excluded from your selection! <hr>File Name cannot contain any of the following characters: <br/><strong> / : * ? \" < > | ; #</strong>`);
}
});
const dsSelected = document.getElementById("dataset") as HTMLInputElement;
if (dsSelected.value.length > 0 && dsSelected.value[0].length > 0) {
this.submitButtonElement.disabled = false;
if (dataFiles.length()) {
if (this.isDSSelected) {
this.submitButtonElement.disabled = false;
}
this.resetButtonElement.disabled = false;
}
this.resetButtonElement.disabled = false;
}
})

ipcRenderer.on('DO_FOLDER_SELECT', (event: Event, folder: string, filesCount: number) => {
const dsSelected = document.getElementById("dataset") as HTMLInputElement;
if (dsSelected.value.length > 0 && dsSelected.value[0].length > 0) {
if (this.isDSSelected) {
this.folderButtonElement.disabled = false;
} else {
this.folderButtonElement.disabled = true;
Expand All @@ -87,29 +105,43 @@ export class DataFilesInput extends Cmp<HTMLDivElement, HTMLFormElement> {
})

ipcRenderer.on('FOLDER_SELECT_DONE', (event: Event, enteredFiles: FileInfo[]) => {
const doneElement = document.getElementById('upload-done');
if (doneElement) {
doneElement.innerHTML = '';
}
this.clearView();
if (enteredFiles.length) {
let lastPath = '';
const files = Array.from(enteredFiles);
enteredFiles.forEach((file) => {
dataFiles.addFile(file);
if (!regexp2.test(file.relativePath)) {
if (!regexp.test(file.name)) {
dataFiles.addFile(file);
} else {
this.openModal(`<strong>${file.name}</strong> excluded from your selection! <hr>File Name cannot contain any of the following characters: <br/><strong> / : * ? \" < > | ; #</strong>`);
}
} else {
if (file.relativePath !== lastPath) {
this.openModal(`Directory <strong>${file.relativePath}</strong> name cannot contain invalid characters! <hr>Valid characters are: <br/><strong> a-Z 0-9 _ - . \\ / </strong>and ' ' (white space).`);
lastPath = file.relativePath;
}
}
});
const dsSelected = document.getElementById("dataset") as HTMLInputElement;
if (dsSelected.value.length > 0 && dsSelected.value[0].length > 0) {
this.submitButtonElement.disabled = false;
if (dataFiles.length()) {
if (this.isDSSelected) {
this.submitButtonElement.disabled = false;
}
this.resetButtonElement.disabled = false;
}
this.resetButtonElement.disabled = false;
} else {
alert(`The selected folder is empty, please select a folder that contains files`);
}
})

ipcRenderer.on('UPLOAD_DONE', (event: Event, result: Record<string, unknown>) => {
this.remainingFiles = this.remainingFiles - Number(result.numFilesUploaded);
this.actionButtons({cancel: true, files: false, folder: false});
this.nextUpload();
})

ipcRenderer.on('UPLOAD_FAILED', (event: Event, dummy: string) => {
this.actionButtons({cancel: true, files: false, folder: false});
this.nextUpload();
})

Expand Down Expand Up @@ -142,11 +174,7 @@ export class DataFilesInput extends Cmp<HTMLDivElement, HTMLFormElement> {
private submitHandler(event: Event) {
event.preventDefault();
if (dataFiles.length()) {
this.filesButtonElement.disabled = true;
this.folderButtonElement.disabled = true;
this.resetButtonElement.disabled = true;
this.submitButtonElement.disabled = true;
this.cancelButtonElement.disabled = false;
this.actionButtons({files: true, folder: true, clear: true, upload: true, cancel: false});
ipcRenderer.send('DO_UPLOAD', dataFiles.getAll());
}
}
Expand All @@ -168,30 +196,68 @@ export class DataFilesInput extends Cmp<HTMLDivElement, HTMLFormElement> {
for (const file of enteredFiles) {
dataFiles.addFile(file);
};
this.submitButtonElement.disabled = false;
this.resetButtonElement.disabled = false;
this.actionButtons({files: true, folder: true, clear: true, upload: true, cancel: false});
} else {
this.actionButtons({files: false, folder: false, clear: true, upload: true, cancel: true});
}
}

private resetHandler(event: Event) {
event.preventDefault();
dataFiles.clear();
this.submitButtonElement.disabled = true;
this.resetButtonElement.disabled = true;

this.actionButtons({files: false, folder: false, clear: true, upload: true, cancel: true});
ipcRenderer.send('DO_CLEAR_SELECTED');
}

private cancelHandler(event: Event) {
event.preventDefault();
dataFiles.clear();
this.submitButtonElement.innerHTML = ' <i class="bi bi-upload d-none d-xxl-inline"></i> Upload ';
this.resetButtonElement.disabled = true;
this.submitButtonElement.disabled = true;
this.cancelButtonElement.disabled = true;
this.filesButtonElement.disabled = false;
this.folderButtonElement.disabled = false;
this.actionButtons({files: false, folder: false, clear: true, upload: true, cancel: true});
ipcRenderer.send('DO_ABORT');
}

private clearView() {
const doneElement = document.getElementById('upload-done');
if (doneElement) {
doneElement.innerHTML = '';
}
const failedElement = document.getElementById('upload-failed');
if (failedElement) {
failedElement.innerHTML = '';
}
}

private isDSSelected(): boolean {
const dsSelected = document.getElementById("dataset") as HTMLInputElement;
if (dsSelected.value.length > 0 && dsSelected.value[0].length > 0) {
return true;
} else {
return false;
}
}

private actionButtons(enabled: {files?: boolean, folder?: boolean , clear?: boolean, upload?: boolean, cancel?: boolean}):void {
if (typeof enabled.files !== 'undefined') this.filesButtonElement.disabled = enabled.files;
if (typeof enabled.folder !== 'undefined') this.folderButtonElement.disabled = enabled.folder;
if (typeof enabled.clear !== 'undefined') this.resetButtonElement.disabled = enabled.clear;
if (typeof enabled.upload !== 'undefined') this.submitButtonElement.disabled = enabled.upload;
if (typeof enabled.cancel !== 'undefined') this.cancelButtonElement.disabled = enabled.cancel;
}

private openModal(message:string) {
this.backdropElement.style.display = "block"
this.backdropElement.style.visibility = "visible"
this.modalElement.style.display = "block"
this.modalElement.classList.add("show");
this.modalElement.children[0].children[0].children[1].innerHTML = message;
}

private closeModal() {
this.backdropElement.style.display = "none"
this.backdropElement.style.visibility = "hidden"
this.modalElement.style.display = "none"
this.modalElement.classList.remove("show");
}

}
1 change: 1 addition & 0 deletions src/index-renderer/components/user-dataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export class UserDataset extends Cmp<HTMLDivElement, HTMLDivElement> {
) {
(document.getElementById("upload") as HTMLButtonElement).disabled = true;
(document.getElementById("cancel") as HTMLButtonElement).disabled = true;
this.lastSelected = '';
alert('Please, select a Dataset');
return;
} else {
Expand Down
Loading

0 comments on commit 7fb2f1c

Please sign in to comment.