From c95e0e402d35abe88dfb51e5381d7901e877ab8c Mon Sep 17 00:00:00 2001 From: Ludovic DANIEL <ludovic.daniel@smile.fr> Date: Wed, 9 Aug 2023 16:18:23 +0200 Subject: [PATCH 1/3] Adding internationalization capabilities + initialized with English and French --- src/dvwebloader.html | 8 +++--- src/js/fileupload2.js | 57 ++++++++++++++++++++++++++----------------- src/js/lang.js | 45 ++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 26 deletions(-) create mode 100644 src/js/lang.js diff --git a/src/dvwebloader.html b/src/dvwebloader.html index fa2cee3..bfded93 100644 --- a/src/dvwebloader.html +++ b/src/dvwebloader.html @@ -5,15 +5,15 @@ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/core.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/md5.js"></script> - <script src="js/fileupload2.js"></script> + <script type="module" src="js/fileupload2.js"></script> </head> <body> - <div id='help'><a href='https://github.com/gdcc/dvwebloader/wiki' target='_blank'>Help/Tutorial</a></div> - <div id="top"><label for='files' class='button'>Select a Directory<input type="file" id="files" name="files[]" multiple webkitdirectory style="display:none"/></label> + <div id='help'><a href='https://github.com/gdcc/dvwebloader/wiki' target='_blank'><span id="help-tutorial-text">Help/Tutorial</span></a></div> + <div id="top"><label for='files' class='button'><span id="select-dir-text">Select a Directory</span><input type="file" id="files" name="files[]" multiple webkitdirectory style="display:none"/></label> <div id='messages'></div> </div> <div id="filelist"></div> - <div id="credit"><a href='https://github.com/gdcc/dvwebloader' target='_blank'>DVWebloader v0.2</a>, development sponsored by UiT/DataverseNO</div> + <div id="credit"><a href='https://github.com/gdcc/dvwebloader' target='_blank'>DVWebloader v0.2</a><span id="sponsor-text">, development sponsored by UiT/DataverseNO</span></div> <script> var input = document.getElementById('files'); diff --git a/src/js/fileupload2.js b/src/js/fileupload2.js index 63cb9ee..22b07dc 100644 --- a/src/js/fileupload2.js +++ b/src/js/fileupload2.js @@ -1,3 +1,5 @@ +import getLocalizedString from './lang.js'; + var fileList = []; var rawFileMap = {}; var toRegisterFileList = []; @@ -42,6 +44,7 @@ var apiKey; var existingFiles; var convertedFileNameMap; var queryParams; +var dvLocale; $(document).ready(function () { queryParams = new URLSearchParams(window.location.search.substring(1)); @@ -51,8 +54,11 @@ $(document).ready(function () { console.log('PID: ' + datasetPid); apiKey = queryParams.get("key"); console.log(apiKey); + dvLocale = queryParams.get("dvLocale"); + console.log('locale: ' + dvLocale); directUploadEnabled = true; - addMessage('info', 'Getting Dataset Information...'); + initTranslation(); + addMessage('info', 'msgGettingDatasetInfo'); retrieveDatasetInfo(); var input = document.getElementById('files'); input.onchange = function (e) { @@ -69,24 +75,31 @@ $(document).ready(function () { console.log('exists: ' + numExists); console.log('rawFileMap len: ' + totalFiles); if (totalFiles === numExists) { - addMessage('info', 'All files already exist in dataset. There\'s nothing to upload.'); + addMessage('info', 'msgFilesAlreadyExist'); } else if (numExists !== 0 && totalFiles > numExists) { - addMessage('info', 'Some files already exist in dataset. Only checked files will be uploaded.'); + addMessage('info', 'msgUploadOnlyCheckedFiles'); } $('label.button').hide(); }; }); -function addMessage(type, text) { - $('#messages').html('').append($('<div/>').addClass(type).text(text)); +function initTranslation() { + initSpanTxt('select-dir-text', 'selectDir'); + initSpanTxt('help-tutorial-text', 'helpTutorial'); + initSpanTxt('sponsor-text', 'sponsor'); +} +function initSpanTxt(htmlId, key) { + $('#'+htmlId).text(getLocalizedString(dvLocale, key)); +} +function addMessage(type, key) { + $('#messages').html('').append($('<div/>').addClass(type).text(getLocalizedString(dvLocale, key))); } async function populatePageMetadata(data) { var mdFields = data.metadataBlocks.citation.fields; var title = ""; var authors = ""; - datasetUrl = data.storageIdentifier; - datasetUrl = siteUrl + '/dataset.xhtml?persistentId=' + datasetPid; - version = queryParams.get("datasetversion"); + var datasetUrl = siteUrl + '/dataset.xhtml?persistentId=' + datasetPid; + var version = queryParams.get("datasetversion"); if (version === ":draft") { version = "DRAFT"; } @@ -106,7 +119,7 @@ async function populatePageMetadata(data) { } } } - let mdDiv = $('<div/>').append($('<h1/>').text("Uploading to ").append($('<a/>').prop("href", datasetUrl).prop('target', '_blank').text(title))); + let mdDiv = $('<div/>').append($('<h1/>').text(getLocalizedString(dvLocale, 'uploadingTo')).append($('<a/>').prop("href", datasetUrl).prop('target', '_blank').text(title))); $('#top').prepend(mdDiv); } @@ -149,7 +162,7 @@ async function retrieveDatasetInfo() { } } $('#files').prop('disabled', false); - addMessage('info', 'Ready. Click Select a Directory. Review the selected files. Start Uploads. (Note - selection dialog will not show files, but they will be shown afterwards on the page.) '); + addMessage('info', 'msgReadyToStart'); }, error: function (jqXHR, textStatus, errorThrown) { console.log('Failure: ' + jqXHR.status); @@ -576,7 +589,7 @@ function queueFileForDirectUpload(file) { //startUploads(); if (send) { if ($('#upload').length === 0) { - $('<button/>').prop('id', 'upload').text('Start Uploads').addClass('button').click(startUploads).appendTo($('#top')); + $('<button/>').prop('id', 'upload').text(getLocalizedString(dvLocale, 'startUpload')).addClass('button').click(startUploads).appendTo($('#top')); } } let fileBlock = $('#filelist>.ui-fileupload-files'); @@ -602,12 +615,12 @@ function toggleUpload() { if ($('.ui-fileupload-row').children('input:checked').length !== 0) { console.log('yes'); if ($('#upload').length === 0) { - $('<button/>').prop('id', 'upload').text('Start Uploads').addClass('button').click(startUploads).insertBefore($('#messages')); - addMessage('info', 'Checked files will be uploaded.'); + $('<button/>').prop('id', 'upload').text(getLocalizedString(dvLocale, 'startUpload')).addClass('button').click(startUploads).insertBefore($('#messages')); + addMessage('info', 'msgStartUpload'); } } else { $('#upload').remove(); - addMessage('info', 'No files to upload. Check some files, or refresh to start over.'); + addMessage('info', 'msgNoFile'); } } @@ -634,7 +647,7 @@ async function uploadFileDirectly(urls, storageId, filesize) { if (directUploadEnabled) { var upload = null; //As long as we have the right file size, we're OK - for (i = 0; i < fileList.length; i++) { + for (let i = 0; i < fileList.length; i++) { if (fileList[i].file.size === filesize) { upload = fileList.splice(i, 1)[0]; break; @@ -654,7 +667,7 @@ async function uploadFileDirectly(urls, storageId, filesize) { function removeErrors() { var errors = document.getElementsByClassName("ui-fileupload-error"); - for (i = errors.length - 1; i >= 0; i--) { + for (let i = errors.length - 1; i >= 0; i--) { errors[i].parentNode.removeChild(errors[i]); } } @@ -668,7 +681,7 @@ function uploadStarted() { //Find the upload table body var files = $('.ui-fileupload-files .ui-fileupload-row'); //Add an id attribute to each entry so we can later match errors with the right entry - for (i = 0; i < files.length; i++) { + for (let i = 0; i < files.length; i++) { files[i].setAttribute('upid', curId); curId = curId + 1; } @@ -677,7 +690,7 @@ function uploadStarted() { var callback = function (mutations) { //Add an id attribute to all new entries mutations.forEach(function (mutation) { - for (i = 0; i < mutation.addedNodes.length; i++) { + for (let i = 0; i < mutation.addedNodes.length; i++) { mutation.addedNodes[i].setAttribute('upid', curId); curId = curId + 1; } @@ -716,7 +729,7 @@ async function directUploadFinished() { if (total === numDone) { // $('button[id$="AllUploadsFinished"]').trigger('click'); console.log("All files in S3"); - addMessage('info', 'Uploads to S3 complete. Now registering all files with the dataset. This may take some time for large numbers of files.'); + addMessage('info', 'msgUploadCompleteRegistering'); let body = []; for (let i = 0; i < toRegisterFileList.length; i++) { let fup = toRegisterFileList[i]; @@ -754,7 +767,7 @@ async function directUploadFinished() { processData: false, success: function (body, statusText, jqXHR) { console.log("All files sent to " + siteUrl + '/dataset.xhtml?persistentId=doi:' + datasetPid + '&version=DRAFT'); - addMessage('success', 'Upload complete, all files in dataset. Close this window and refresh your dataset page to see the uploaded files.'); + addMessage('success', 'msgUploadComplete'); }, error: function (jqXHR, textStatus, errorThrown) { console.log('Failure: ' + jqXHR.status); @@ -771,7 +784,7 @@ async function directUploadFinished() { } else { if ((inProgress < 4) && (inProgress < inList)) { filesInProgress = filesInProgress + 1; - for (i = 0; i < fileList.length; i++) { + for (let i = 0; i < fileList.length; i++) { if (fileList[i].state === UploadState.QUEUED) { fileList[i].startRequestForDirectUploadUrl(); break; @@ -844,7 +857,7 @@ async function uploadFailure(jqXHR, upid, filename) { var textnode = document.createTextNode("Upload unsuccessful (" + status + ": " + statusText + ")."); node.appendChild(textnode); //Add the error message to the correct row - for (i = 0; i < rows.length; i++) { + for (let i = 0; i < rows.length; i++) { if (rows[i].getAttribute('upid') === id) { //Remove any existing error message/only show last error (have seen two error 0 from one network disconnect) var err = rows[i].getElementsByClassName('ui-fileupload-error'); diff --git a/src/js/lang.js b/src/js/lang.js new file mode 100644 index 0000000..1cc6c1f --- /dev/null +++ b/src/js/lang.js @@ -0,0 +1,45 @@ +const defaultLocale = 'en'; +const translations = { + en: { + selectDir: "Select a Directory", + helpTutorial: "Help/Tutorial", + sponsor: ", development sponsored by UiT/DataverseNO", + startUpload: "Start Uploads", + uploadingTo: "Uploading to ", + msgGettingDatasetInfo: "Getting Dataset Information...", + msgFilesAlreadyExist: "All files already exist in dataset. There's nothing to upload.", + msgUploadOnlyCheckedFiles: "Some files already exist in dataset. Only checked files will be uploaded.", + msgReadyToStart: "Ready. Click Select a Directory. Review the selected files. Start Uploads. (Note - selection dialog will not show files, but they will be shown afterwards on the page.) ", + msgStartUpload: "Checked files will be uploaded.", + msgNoFile: "No files to upload. Check some files, or refresh to start over.", + msgUploadCompleteRegistering: "Uploads to S3 complete. Now registering all files with the dataset. This may take some time for large numbers of files.", + msgUploadComplete: "Upload complete, all files in dataset. Close this window and refresh your dataset page to see the uploaded files.", + }, + fr: { + selectDir: "Sélectionner un répertoire", + helpTutorial: "Aide/Tutoriel", + sponsor: ", développement sponsorisé par UiT/DataverseNO", + startUpload: "Démarrer les envois", + uploadingTo: "Envoi vers ", + msgGettingDatasetInfo: "Récupération des informations du jeu de données...", + msgFilesAlreadyExist: "Tous les fichiers existent déjà dans le jeu de données. Il n'y a rien à envoyer.", + msgUploadOnlyCheckedFiles: "Certains fichiers existent déjà dans le jeu de données. Seuls les fichiers cochés seront envoyés.", + msgReadyToStart: "Prêt. Cliquez sur Sélectionner un répertoire. Passez en revue les fichiers sélectionnés. Démarrez les envois. (Remarque : la boîte de dialogue de sélection ne montrera pas les fichiers, mais ils seront affichés ensuite sur la page.) ", + msgStartUpload: "Les fichiers cochés seront envoyés.", + msgNoFile: "Aucun fichier à envoyer. Cochez certains fichiers ou rafraîchissez la page pour recommencer.", + msgUploadCompleteRegistering: "Envois vers S3 terminés. Enregistrement de tous les fichiers en cours dans le jeu de données. Cela peut prendre du temps pour un grand nombre de fichiers.", + msgUploadComplete: "Envoi terminé, tous les fichiers sont dans le jeu de données. Fermez cette fenêtre et rafraîchissez la page de votre jeu de données pour voir les fichiers envoyés.", + }, +}; + +export default function getLocalizedString(locale, key) { + if(!locale || !translations[locale]) { + locale = defaultLocale; + console.log('getLocalizedString - locale empty or unknown, using defaultLocale: '+defaultLocale) + } + if (translations[locale] && translations[locale][key]) { + return translations[locale][key]; + } + console.log('getLocalizedString - transalation not found with locale: '+locale+' and key:'+key); + return key; +} \ No newline at end of file From ca1cee633cf5b13fd0d296bfb6ce241169b4bb22 Mon Sep 17 00:00:00 2001 From: Ludovic DANIEL <ludovic.daniel@smile.fr> Date: Wed, 9 Aug 2023 17:17:26 +0200 Subject: [PATCH 2/3] Fixed issues after merge --- src/dvwebloader.html | 2 +- src/js/fileupload2.js | 9 ++++++--- src/js/lang.js | 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/dvwebloader.html b/src/dvwebloader.html index dff3c50..21e7169 100644 --- a/src/dvwebloader.html +++ b/src/dvwebloader.html @@ -11,7 +11,7 @@ <main> <div> <img id='logo' alt='Site Logo'> - <h1>Folder Upload</h1> + <h1><span id="title-text">Folder Upload</span></h1> <div id='help'> <a href='https://github.com/gdcc/dvwebloader/wiki' target='_blank'><span id="help-tutorial-text">Help/Tutorial</span></a> </div> diff --git a/src/js/fileupload2.js b/src/js/fileupload2.js index cc1723d..f984da2 100644 --- a/src/js/fileupload2.js +++ b/src/js/fileupload2.js @@ -1,3 +1,5 @@ +import getLocalizedString from './lang.js'; + var fileList = []; var rawFileMap = {}; var toRegisterFileList = []; @@ -174,6 +176,7 @@ function addIconAndLogo(siteUrl) { } function initTranslation() { + initSpanTxt('title-text', 'title'); initSpanTxt('select-dir-text', 'selectDir'); initSpanTxt('help-tutorial-text', 'helpTutorial'); initSpanTxt('sponsor-text', 'sponsor'); @@ -289,7 +292,7 @@ function setupDirectUpload(enabled) { var config = { childList: true }; var callback = function(mutations) { mutations.forEach(function(mutation) { - for (i = 0; i < mutation.addedNodes.length; i++) { + for (let i = 0; i < mutation.addedNodes.length; i++) { //Add a listener on any replacement file 'select' widget if (mutation.addedNodes[i].id === 'datasetForm:fileUpload_input') { fileInput = mutation.addedNodes[i]; @@ -851,7 +854,7 @@ async function directUploadFinished() { processData: false, success: function(body, statusText, jqXHR) { console.log("All files sent to " + siteUrl + '/dataset.xhtml?persistentId=doi:' + datasetPid + '&version=DRAFT'); - addMessage('success', 'Upload complete, all files in dataset. Close this window and refresh your dataset page to see the uploaded files.'); + addMessage('success', 'msgUploadComplete'); }, error: function(jqXHR, textStatus, errorThrown) { console.log('Failure: ' + jqXHR.status); @@ -868,7 +871,7 @@ async function directUploadFinished() { } else { if ((inProgress < 4) && (inProgress < inList)) { filesInProgress = filesInProgress + 1; - for (i = 0; i < fileList.length; i++) { + for (let i = 0; i < fileList.length; i++) { if (fileList[i].state === UploadState.QUEUED) { fileList[i].startRequestForDirectUploadUrl(); break; diff --git a/src/js/lang.js b/src/js/lang.js index 1cc6c1f..39a3d9b 100644 --- a/src/js/lang.js +++ b/src/js/lang.js @@ -1,6 +1,7 @@ const defaultLocale = 'en'; const translations = { en: { + title: "Folder Upload", selectDir: "Select a Directory", helpTutorial: "Help/Tutorial", sponsor: ", development sponsored by UiT/DataverseNO", @@ -16,6 +17,7 @@ const translations = { msgUploadComplete: "Upload complete, all files in dataset. Close this window and refresh your dataset page to see the uploaded files.", }, fr: { + title: "Envoi d'un dossier", selectDir: "Sélectionner un répertoire", helpTutorial: "Aide/Tutoriel", sponsor: ", développement sponsorisé par UiT/DataverseNO", From 01ad117c5c31c1339e6381320c9f447f9b58b11f Mon Sep 17 00:00:00 2001 From: Ludovic DANIEL <ludovic.daniel@smile.fr> Date: Wed, 9 Aug 2023 17:21:52 +0200 Subject: [PATCH 3/3] Fixed a space in texts --- src/dvwebloader.html | 2 +- src/js/lang.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dvwebloader.html b/src/dvwebloader.html index 21e7169..3dfe7b0 100644 --- a/src/dvwebloader.html +++ b/src/dvwebloader.html @@ -19,7 +19,7 @@ <h1><span id="title-text">Folder Upload</span></h1> <hr class='solid'> <div id="top"> - <label for='files' class='button'><span id="select-dir-text">Select a Directory</span><input type="file" id="files" name="files[]" multiple webkitdirectory style="display: none" /></label> + <label for='files' class='button'><span id="select-dir-text">Select a Directory</span><input type="file" id="files" name="files[]" multiple webkitdirectory style="display: none" /></label> <div id='messages'></div> </div> <div id="filelist"></div> diff --git a/src/js/lang.js b/src/js/lang.js index 39a3d9b..c6ea7ba 100644 --- a/src/js/lang.js +++ b/src/js/lang.js @@ -2,7 +2,7 @@ const defaultLocale = 'en'; const translations = { en: { title: "Folder Upload", - selectDir: "Select a Directory", + selectDir: "Select a Directory", helpTutorial: "Help/Tutorial", sponsor: ", development sponsored by UiT/DataverseNO", startUpload: "Start Uploads",