diff --git a/domain-server/resources/web/content/js/content.js b/domain-server/resources/web/content/js/content.js index 0fd5f37a94..4e2c27bf54 100644 --- a/domain-server/resources/web/content/js/content.js +++ b/domain-server/resources/web/content/js/content.js @@ -7,17 +7,67 @@ $(document).ready(function(){ // construct the HTML needed for the settings backup panel var html = "
"; - html += "Upload a Content Backup to replace the content of this domain"; - html += "
Note: Your domain's content will be replaced by the content you upload, but the existing backup files of your domain's content will not immediately be changed.
"; + html += "Upload a Content Archive (.zip) or entity file (.json, .json.gz) to replace the content of this domain."; + html += "
Note: Your domain content will be replaced by the content you upload, but the existing backup files of your domain's content will not immediately be changed.
"; html += ""; - html += ""; + html += ""; html += "
"; $('#' + Settings.UPLOAD_CONTENT_BACKUP_PANEL_ID + ' .panel-body').html(html); } + // handle content archive or entity file upload + + // when the selected file is changed, enable the button if there's a selected file + $('body').on('change', '#' + RESTORE_SETTINGS_FILE_ID, function() { + if ($(this).val()) { + $('#' + RESTORE_SETTINGS_UPLOAD_ID).attr('disabled', false); + } + }); + + // when the upload button is clicked, send the file to the DS + // and reload the page if restore was successful or + // show an error if not + $('body').on('click', '#' + RESTORE_SETTINGS_UPLOAD_ID, function(e){ + e.preventDefault(); + + swal({ + title: "Are you sure?", + text: "Your domain content will be replaced by the uploaded Content Archive or entity file", + type: "warning", + showCancelButton: true, + closeOnConfirm: false + }, + function () { + var files = $('#' + RESTORE_SETTINGS_FILE_ID).prop('files'); + + var fileFormData = new FormData(); + fileFormData.append('restore-file', files[0]); + + showSpinnerAlert("Restoring Content"); + + $.ajax({ + url: '/content/upload', + type: 'POST', + cache: false, + processData: false, + contentType: false, + data: fileFormData + }).done(function(data, textStatus, jqXHR) { + swal.close(); + showRestartModal(); + }).fail(function(jqXHR, textStatus, errorThrown) { + showErrorMessage( + "Error", + "There was a problem restoring domain content.\n" + + "Please ensure that the content archive or entity file is valid and try again." + ); + }); + }); + }); + var GENERATE_ARCHIVE_BUTTON_ID = 'generate-archive-button'; var AUTOMATIC_ARCHIVES_TABLE_ID = 'automatic-archives-table'; var AUTOMATIC_ARCHIVES_TBODY_ID = 'automatic-archives-tbody'; @@ -136,7 +186,7 @@ $(document).ready(function(){ text: "You have pending changes to content settings that have not been saved. They will be lost if you leave the page to manage automatic content archive intervals.", type: "warning", showCancelButton: true, - confirmButtonText: "Leave and Lose Pending Changes", + confirmButtonText: "Proceed without Saving", closeOnConfirm: true }, function () { diff --git a/domain-server/resources/web/js/domain-server.js b/domain-server/resources/web/js/domain-server.js index 6b2d4e1316..d3b20d40bb 100644 --- a/domain-server/resources/web/js/domain-server.js +++ b/domain-server/resources/web/js/domain-server.js @@ -79,7 +79,7 @@ $(document).ready(function(){ Settings.extraDomainGroupsAtEnd = [ { html_id: 'settings_backup', - label: 'Settings Backup' + label: 'Settings Backup / Restore' } ] diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index 1c6510298f..b73337ef2d 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -1033,31 +1033,40 @@ $(document).ready(function(){ $('body').on('click', '#' + RESTORE_SETTINGS_UPLOAD_ID, function(e){ e.preventDefault(); - var files = $('#' + RESTORE_SETTINGS_FILE_ID).prop('files'); + swal({ + title: "Are you sure?", + text: "Your domain settings will be replaced by the uploaded settings", + type: "warning", + showCancelButton: true, + closeOnConfirm: false + }, + function() { + var files = $('#' + RESTORE_SETTINGS_FILE_ID).prop('files'); - var fileFormData = new FormData(); - fileFormData.append('restore-file', files[0]); + var fileFormData = new FormData(); + fileFormData.append('restore-file', files[0]); - showSpinnerAlert("Restoring Settings"); + showSpinnerAlert("Restoring Settings"); - $.ajax({ - url: '/settings/restore', - type: 'POST', - processData: false, - contentType: false, - dataType: 'json', - data: fileFormData - }).done(function(data, textStatus, jqXHR) { - swal.close(); - showRestartModal(); - }).fail(function(jqXHR, textStatus, errorThrown) { - showErrorMessage( - "Error", - "There was a problem restoring domain settings.\n" - + "Please ensure that your current domain settings are valid and try again." - ); + $.ajax({ + url: '/settings/restore', + type: 'POST', + processData: false, + contentType: false, + dataType: 'json', + data: fileFormData + }).done(function(data, textStatus, jqXHR) { + swal.close(); + showRestartModal(); + }).fail(function(jqXHR, textStatus, errorThrown) { + showErrorMessage( + "Error", + "There was a problem restoring domain settings.\n" + + "Please ensure that your current domain settings are valid and try again." + ); - reloadSettings(); + reloadSettings(); + }); }); }); @@ -1079,7 +1088,7 @@ $(document).ready(function(){ html += "
"; html += ""; html += "Upload a settings configuration to quickly configure this domain"; - html += "
Note: Your domain's settings will be replaced by the settings you upload
"; + html += "
Note: Your domain settings will be replaced by the settings you upload"; html += ""; html += ""; diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 8247e12de5..f3765f6868 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -2256,12 +2256,32 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url QList formData = connection->parseFormData(); if (formData.size() > 0 && formData[0].second.size() > 0) { - // invoke our method to hand the new octree file off to the octree server - QMetaObject::invokeMethod(this, "handleOctreeFileReplacement", - Qt::QueuedConnection, Q_ARG(QByteArray, formData[0].second)); + auto& firstFormData = formData[0]; + + // check the file extension to see what kind of file this is + // to match sure we handle this filetype for a content restore + auto dispositionValue = QString(firstFormData.first.value("Content-Disposition")); + auto formDataFilenameRegex = QRegExp("filename=\"(\\S+)\""); + auto matchIndex = formDataFilenameRegex.indexIn(dispositionValue); + + QString uploadedFilename = ""; + if (matchIndex != -1) { + uploadedFilename = formDataFilenameRegex.cap(1); + } + + if (uploadedFilename.endsWith(".json", Qt::CaseInsensitive) + || uploadedFilename.endsWith(".json.gz", Qt::CaseInsensitive)) { + // invoke our method to hand the new octree file off to the octree server + QMetaObject::invokeMethod(this, "handleOctreeFileReplacement", + Qt::QueuedConnection, Q_ARG(QByteArray, formData[0].second)); + + // respond with a 200 for success + connection->respond(HTTPConnection::StatusCode200); + } else { + // we don't have handling for this filetype, send back a 400 for failure + connection->respond(HTTPConnection::StatusCode400); + } - // respond with a 200 for success - connection->respond(HTTPConnection::StatusCode200); } else { // respond with a 400 for failure connection->respond(HTTPConnection::StatusCode400);