-
Notifications
You must be signed in to change notification settings - Fork 2
Upload data loading indicator #211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ee7ffdd
f07af90
805229a
51d82f0
fde86e8
c1af647
0f6ffb0
81f3ae4
c3ea4e0
cfd08e8
6ac9cef
d6a8f46
d6cf71a
5e3c158
2c7fca4
8464fc4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -96,3 +96,6 @@ ENV/ | |
|
|
||
| # Rope project settings | ||
| .ropeproject | ||
|
|
||
| #vscode settings | ||
| .vscode/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,108 +1,210 @@ | ||
| $(function() { | ||
| $('button#import-button').click(function(e) { | ||
| e.preventDefault(); | ||
| if ( | ||
| window.confirm( | ||
| "This process will remove all data and files from your current " + | ||
| "database and replace it with data from the provided zip file. " + | ||
| "\n\n" + | ||
| "This process CANNOT be undone. \n\n" + | ||
| "It is recommended that you use the button above to export " + | ||
| "your current database status so that you may restore to your " + | ||
| "present state, AND that you COORDINATE WITH IT professionals " + | ||
| "prior to attempting this. \n\n" + | ||
| "You will need to log in again using administrator credentials " + | ||
| "as defined by the new data: your current account will cease to " + | ||
| "exist.\n\n" + | ||
| "Are you sure you understand and are prepared to take this risk?" | ||
| ) | ||
| ) { | ||
| form = $('#import-database-form'); | ||
| $.ajax({ | ||
| url: '/import_database/', | ||
| data: new FormData(form[0]), | ||
| type: "POST", | ||
| processData: false, | ||
| contentType: false, | ||
| success: function(data, status) { | ||
| if (data.hasOwnProperty('status_code') && data.hasOwnProperty('status_message')) { | ||
| if (data.status_code == 200) { | ||
| window.alert(data.status_message + "\n\nYou may now be logged out."); | ||
| window.location.reload(); | ||
| } else { | ||
| window.alert("Error Code: " + data.status_code + "\n\n" + data.status_message); | ||
| } | ||
| } else { | ||
| window.alert("Unexpected error occurred: " + status); | ||
| } | ||
| }, | ||
| error: function(xhr, desc, err) { | ||
| window.alert("Unexpected error occurred: " + err); | ||
| } | ||
| }) | ||
| } | ||
| const importText = ` | ||
| This process will remove all data and files from your current | ||
| database and replace it with data from the provided zip file. | ||
| </br><br> | ||
| This process CANNOT be undone. </br><br> | ||
| It is recommended that you use the 'Export to .zip' button above to export | ||
| your current database status so that you may restore to your | ||
| present state, AND that you COORDINATE WITH IT professionals | ||
| prior to attempting this. </br><br> | ||
| You will need to log in again using administrator credentials | ||
| as defined by the new data: your current account will cease to | ||
| exist.</br><br> | ||
| Are you sure you understand and are prepared to take this risk? | ||
| `; | ||
|
|
||
| const importInfoText = `The Import Database Tool is designed to support restoring your Traditional Knowledge Database back to a prior state. This is best used in conjunction with the 'Export Database' tool above. </br><br> | ||
| To use the Import Database tool is simple: select a properly formatted zip file to upload and then click 'Import'. All of your data will be reverted back to the state it was when that zipfile was created. </br><br> | ||
| This is VERY DANGEROUS! For this to work, all of the data currently | ||
| in your database, including your users, your records, and your page | ||
| contents will be removed, and then replaced. Also, any files | ||
| associated with your media records (images, audio, video, PDFs, | ||
| etc...) will be overwritten by any files of the same name included | ||
| in the zipped up backup file that you import.</br><br> | ||
| If you wish to use this, it is recommended that you work with IT | ||
| professionals prior to undertaking this task. While IT cannot create | ||
| one of these import files for a prior state, they can help you | ||
| securely preserve any new zipped export files, and should be able | ||
| to create a system backup of your database to restore in the event | ||
| of complications while using this tool. </br><br> | ||
| Note that a zipped backup file is easily created for your current | ||
| state with the 'Export to .zip' button above, but cannot be | ||
| created by hand. If you have not created any of these files, you | ||
| should not use this tool.`; | ||
|
|
||
| const exportInfoText = `The Export Database Tool is designed to support saving the current | ||
| state of your Traditional Knowledge Database. This is best | ||
| used in conjunction with the 'Import Database' tool below. </br><br> | ||
| To use the Export Database tool is simple: just press 'Export to | ||
| .zip' button and all of your data and media files will be collected | ||
| into a single zipfile and downloaded to your current computer.</br></br> | ||
| This is VERY DANGEROUS! While keeping regular backups | ||
| of your database is crucial to preventing data loss from future | ||
| incidents, the exported file will contain ALL of your data in an | ||
| unencrypted format. These exported files | ||
| must be kept in a secure place and only shared via secure channels: | ||
| NOT BY EMAIL.</br></br> | ||
| Please work with IT professionals to design | ||
| a safe and secure practice for regular backups, which may or may | ||
| not involve this tool.`; | ||
|
|
||
| $(function () { | ||
| const unexpectedError = (statusCode, statusMessage = "") => { | ||
| return `<p class='text-danger'>Unexpected error occurred: ${statusCode}</p><p>${statusMessage}</p>`; | ||
| }; | ||
|
|
||
| const showNextStepsSection = () => { | ||
| $("#modalNextSteps").removeClass("hidden"); | ||
| }; | ||
|
|
||
| const showModalFooter = () => { | ||
| $(".modal-footer").show(); | ||
| }; | ||
|
|
||
| const hideModalFooter = () => { | ||
| $(".modal-footer").hide(); | ||
| }; | ||
|
|
||
| const resetModal = () => { | ||
| $("#continueImport").html("Close"); | ||
| $("#closeModalButton").prop("disabled", false); | ||
| $("#continueImport").click(function () { | ||
| $("#exportImportModal").modal("hide"); | ||
| }); | ||
| }; | ||
|
|
||
| $('button#export-info').click(function(e) { | ||
| window.alert( | ||
| "Export Database Tool:\n\n" + | ||
|
|
||
| "The Export Database Tool is designed to support saving the current " + | ||
| "state of your Traditional Knowledge Database. This is best " + | ||
| "used in conjunction with the 'Import Database' tool below. \n\n" + | ||
|
|
||
| "To use the Export Database tool is simple: just press 'Export to " + | ||
| ".zip' button and all of your data and media files will be collected " + | ||
| "into a single zipfile and downloaded to your current computer." + | ||
| "\n\n" + | ||
|
|
||
| "This is VERY DANGEROUS! While keeping regular backups " + | ||
| "of your database is crucial to preventing data loss from future " + | ||
| "incidents, the exported file will contain ALL of your data in an " + | ||
| "unencrypted format. These exported files " + | ||
| "must be kept in a secure place and only shared via secure channels: " + | ||
| "NOT BY EMAIL.\n\n" + | ||
|
|
||
| "Please work with IT professionals to design " + | ||
| "a safe and secure practice for regular backups, which may or may " + | ||
| "not involve this tool." | ||
| ); | ||
| }) | ||
|
|
||
| $('button#import-info').click(function(e) { | ||
| window.alert( | ||
| "Import Database Tool:\n\n" + | ||
|
|
||
| "The Import Database Tool is designed to support restoring your " + | ||
| "Traditional Knowledge Database back to a prior state. This is best " + | ||
| "used in conjunction with the 'Export Database' tool above. \n\n" + | ||
|
|
||
| "To use the Import Database tool is simple: select a properly formatted " + | ||
| "zip file to upload and then click 'Import'. All of your data will " + | ||
| "be reverted back to the state it was when that zipfile was created." + | ||
| "\n\n" + | ||
|
|
||
| "This is VERY DANGEROUS! For this to work, all of the data currently " + | ||
| "in your database, including your users, your records, and your page " + | ||
| "contents will be removed, and then replaced. Also, any files " + | ||
| "associated with your media records (images, audio, video, PDFs, " + | ||
| "etc...) will be overwritten by any files of the same name included " + | ||
| "in the zipped up backup file that you import.\n\n" + | ||
|
|
||
| "If you wish to use this, it is recommended that you work with IT " + | ||
| "professionals prior to undertaking this task. While IT cannot create " + | ||
| "one of these import files for a prior state, they can help you " + | ||
| "securely preserve any new zipped export files, and should be able " + | ||
| "to create a system backup of your database to restore in the event " + | ||
| "of complications while using this tool. \n\n" + | ||
|
|
||
| "Note that a zipped backup file is easily created for your current " + | ||
| "state with the 'Export to .zip' button above, but cannot be " + | ||
| "created by hand. If you have not created any of these files, you " + | ||
| "should not use this tool." | ||
| const resetExportButton = (iframe, clearInterval) => { | ||
| $("#export-button").prop("disabled", false); | ||
| $("#export-button").html("Export to .zip"); | ||
| iframe.remove(); | ||
| clearInterval(); | ||
| }; | ||
|
|
||
| $("button#import-button").click(function (e) { | ||
| e.preventDefault(); | ||
| showModalFooter(); | ||
|
|
||
| $("#modalTitle").text("Import Database"); | ||
| $("#modalBody").html(importText); | ||
|
|
||
| $("#continueImport").click(function () { | ||
| // prevent closing the modal after verifying import | ||
| $("#exportImportModal").modal({ | ||
| backdrop: "static", | ||
| keyboard: false, | ||
| }); | ||
|
|
||
| // add spinner to the button | ||
| // change button text to "Importing..." | ||
| $("#continueImport").html( | ||
| `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Importing...` | ||
| ); | ||
| }) | ||
| $("#continueImport").prop("disabled", true); | ||
| $("#closeModalButton").prop("disabled", true); | ||
|
|
||
| const form = $("#import-database-form"); | ||
| $.ajax({ | ||
| url: "/import_database/", | ||
| data: new FormData(form[0]), | ||
| type: "POST", | ||
| processData: false, | ||
| contentType: false, | ||
| success: function (data, status) { | ||
| if ( | ||
| data.hasOwnProperty("status_code") && | ||
| data.hasOwnProperty("status_message") | ||
| ) { | ||
| showNextStepsSection(); | ||
| $("#continueImport").prop("disabled", false); | ||
|
|
||
| if (data.status_code == 200) { | ||
| $("#modalNextSteps").html( | ||
| `<p class='text-success'>Import successful. You may now be logged out.</p>` | ||
| ); | ||
| $("#continueImport").html("Log out"); | ||
| $("#continueImport").click(function () { | ||
| location.reload(true); | ||
| }); | ||
| } else { | ||
| $("#modalNextSteps").html( | ||
| `<p class='text-danger'>Import failed with error code ${data.status_code}.</p><p class='text-danger'>${data.status_message}</p>` | ||
| ); | ||
| resetModal(); | ||
| } | ||
| } else { | ||
| $("#modalNextSteps").html(unexpectedError(status)); | ||
| resetModal(); | ||
| } | ||
| }, | ||
| error: function (xhr) { | ||
| $("#modalNextSteps").html( | ||
| unexpectedError(xhr.status, xhr.statusText) | ||
| ); | ||
| resetModal(); | ||
| }, | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| $("button#import-info").click(function (e) { | ||
| hideModalFooter(); | ||
| $("#modalTitle").text("Import Database Tool"); | ||
| $("#modalBody").html(importInfoText); | ||
| }); | ||
|
|
||
| $("button#export-info").click(function (e) { | ||
| hideModalFooter(); | ||
| $("#modalTitle").text("Export Database Tool"); | ||
| $("#modalBody").html(exportInfoText); | ||
| }); | ||
|
|
||
| $("button#export-button").click(function (e) { | ||
| e.preventDefault(); | ||
|
|
||
| // remove error message if present | ||
| $("#exportStatus").addClass("hidden"); | ||
|
|
||
| // disable button and show spinner | ||
| $("#export-button").prop("disabled", true); | ||
| $("#export-button").html( | ||
| `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Exporting...` | ||
| ); | ||
|
|
||
| // set cookie to pending | ||
| document.cookie = "export_status=pending"; | ||
|
|
||
| // create hidden iframe to trigger download | ||
| const iframe = $("<iframe/>") | ||
| .hide() | ||
| .attr("src", "/export_database/") | ||
| .appendTo("body"); | ||
|
|
||
| // poll cookie for export_status | ||
| const checkStatus = setInterval(function () { | ||
| const cookies = document.cookie.split(";").map((c) => c.trim()); | ||
| const exportStatus = cookies.filter((c) => | ||
| c.startsWith("export_status=") | ||
| ); | ||
|
|
||
| if (exportStatus && exportStatus.includes("export_status=done")) { | ||
| resetExportButton(iframe, clearInterval(checkStatus)); | ||
| } else if (exportStatus && exportStatus.includes("export_status=error")) { | ||
| $("#exportStatus").removeClass("hidden"); | ||
| resetExportButton(iframe, clearInterval(checkStatus)); | ||
| } | ||
| }, 1000); | ||
| }); | ||
|
|
||
| // Clear modal content on close; reset to default state | ||
| $("#exportImportModal").on("hidden.bs.modal", function () { | ||
| $("#modalTitle").text(""); | ||
| $("#modalBody").html(""); | ||
| $("#modalNextSteps").html(""); | ||
| $("#modalNextSteps").addClass("hidden"); | ||
| $("#continueImport").html("Continue"); | ||
| $("#continueImport").off("click"); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,20 +25,21 @@ | |
|
|
||
| {% if user.is_superuser %} | ||
| <div class="module" id="export-module"> | ||
| <h2>{% translate 'Export database' %}<button class='btn btn-info' id='export-info'>Info</button></h2> | ||
| <a href="/export_database/" id='export-button' class="btn btn-primary"> | ||
| <h2>{% translate 'Export database' %}<button class='btn btn-info' id='export-info' data-bs-toggle="modal" data-bs-target="#exportImportModal">Info</button></h2> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I love Bootstrap modals, and we already installed Bootstrap to the admin view, so this solution is perfect. I expect my love of Bootstrap is dated (Twitter built it long before their name change, which is already old news -- I assume newer frameworks are en vogue ATM). But replacing Bootstrap with a modern framework here should be informed by and performed in conjunction with an often-suggested rebuild of the front-end. |
||
| <button id='export-button' class="mx-3 btn btn-primary"> | ||
| Export to .zip | ||
| </a> | ||
| </button> | ||
| <div id="exportStatus" class="text-danger m-3 hidden">There was an error during export. Please try again.</div> | ||
| </div> | ||
|
|
||
| <hr /> | ||
|
|
||
| <div class="module" id="import-module"> | ||
| <h2>{% translate 'Import database' %}<button class='btn btn-info' id='import-info'>Info</button></h2> | ||
| <h2>{% translate 'Import database' %}<button class='btn btn-info' id='import-info' data-bs-toggle="modal" data-bs-target="#exportImportModal">Info</button></h2> | ||
| <form method="post" enctype="multipart/form-data" id='import-database-form'> | ||
| {% csrf_token %} | ||
| <input type="file" name="import_file" id='import_database_file_field'> | ||
| <button type="submit" id='import-button' class='btn btn-success'>Import</button> | ||
| <input type="file" name="import_file" id='import_database_file_field' class="mx-3"> | ||
| <button data-bs-toggle="modal" data-bs-target="#exportImportModal" type="submit" id='import-button' class='m-3 btn btn-success'>Import</button> | ||
| </form> | ||
| </div> | ||
|
|
||
|
|
@@ -74,5 +75,22 @@ <h3>{% translate 'My actions' %}</h3> | |
| </ul> | ||
| {% endif %} | ||
| </div> | ||
|
|
||
| <div class="modal fade" id="exportImportModal" tabindex="-1" aria-labelledby="modalTitle" aria-hidden="true" role="dialog" data-bs-backdrop="static" data-bs-keyboard="false"> | ||
| <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable"> | ||
| <div class="modal-content"> | ||
| <div class="modal-header"> | ||
| <h1 class="modal-title fs-5 text-dark" id="modalTitle"></h1> | ||
| <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" id="closeModalButton"></button> | ||
| </div> | ||
| <div id="modalBody" class="modal-body"> | ||
| </div> | ||
| <div id="modalNextSteps" class="pt-3 m-3 border rounded hidden"></div> | ||
| <div class="modal-footer"> | ||
| <button type="button" id="continueImport" class="btn btn-primary">Continue</button> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| {% endblock %} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So much cleaner!