From 6bc76458680dca05b310bafa7705481009dda02b Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Fri, 31 Jul 2020 13:28:24 +0200 Subject: [PATCH] MDL-69381 core_backup: make progressbar selector more specific --- backup/util/ui/amd/build/async_backup.min.js | 2 +- backup/util/ui/amd/build/async_backup.min.js.map | 2 +- backup/util/ui/amd/src/async_backup.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backup/util/ui/amd/build/async_backup.min.js b/backup/util/ui/amd/build/async_backup.min.js index 15d852a7e99..1511c10a96d 100644 --- a/backup/util/ui/amd/build/async_backup.min.js +++ b/backup/util/ui/amd/build/async_backup.min.js @@ -1,2 +1,2 @@ -define ("core_backup/async_backup",["jquery","core/ajax","core/str","core/notification","core/templates"],function(a,b,c,d,e){var q=900,r=1e3,s={},t=15e3,u=15e3,v=1.5,w,x,y,z,A,B,C,D=2e3;function f(a,b,c){var d=Math.round(c)+"%",e=document.querySelectorAll("[data-"+b+"id="+CSS.escape(a)+"]")[0],f=c.toFixed(2)+"%";e.setAttribute("aria-valuenow",d);e.style.width=d;e.innerHTML=f}function g(a,b,c){clearInterval(a);return setInterval(b,c)}function h(c){var f=a("#"+c+"_bar").parent().parent(),g=f.parent(),h=f.siblings(),i=h[1],j=a(i).text(),k=h[0],l=a(k).text();b.call([{methodname:"core_backup_get_async_backup_links_backup",args:{filename:l,contextid:x}}])[0].done(function(a){var b={filename:l,time:j,size:a.filesize,fileurl:a.fileurl,restoreurl:a.restoreurl};e.render("core/async_backup_progress_row",b).then(function(a,b){e.replaceNodeContents(g,a,b)}).fail(function(){d.exception(new Error("Failed to load table row"))})})}function i(c){var f=a("#"+c+"_bar").parent().parent(),g=f.parent(),h=f.siblings(),i=h[0],j=h[1],k=a(j).text();b.call([{methodname:"core_backup_get_async_backup_links_restore",args:{backupid:c,contextid:x}}])[0].done(function(b){var c=a(i).text(),f={resourcename:c,restoreurl:b.restoreurl,time:k};e.render("core/async_restore_progress_row",f).then(function(a,b){e.replaceNodeContents(g,a,b)}).fail(function(){d.exception(new Error("Failed to load table row"))})})}function j(a){var f=document.querySelectorAll("[data-restoreid="+CSS.escape(a)+"]")[0],g=f.closest("tr").children[1],h=g.innerHTML,i=document.createElement("a"),j=f.closest("td"),k=j.previousElementSibling;c.get_string("complete").then(function(a){k.innerHTML=a}).catch(function(){d.exception(new Error("Failed to load string: complete"))});e.render("core/async_copy_complete_cell",{}).then(function(a,b){e.replaceNodeContents(j,a,b)}).fail(function(){d.exception(new Error("Failed to load table cell"))});b.call([{methodname:"core_backup_get_async_backup_links_restore",args:{backupid:a,contextid:0}}])[0].done(function(a){i.setAttribute("href",a.restoreurl);i.innerHTML=h;g.innerHTML=null;g.appendChild(i)}).fail(function(){d.exception(new Error("Failed to update table row"))})}function k(e){var g=100*e.progress,h="backup",i=document.querySelectorAll("[data-"+h+"id="+CSS.escape(w)+"]")[0],j=a("#"+w+"_status"),k=a("#"+w+"_detail"),l=a("#"+w+"_button"),m;if(e.status==800){i.classList.add("bg-success");f(w,h,g);var n="async"+z+"processing";c.get_string(n,"backup").then(function(a){j.text(a)}).catch(function(){d.exception(new Error("Failed to load string: backup "+n))})}else if(e.status==q){i.classList.add("bg-danger");i.classList.remove("bg-success");f(w,h,100);var o="async"+z+"error",p="async"+z+"errordetail";m=[{key:o,component:"backup"},{key:p,component:"backup"}];c.get_strings(m).then(function(a){j.text(a[0]);k.text(a[1])}).catch(function(){d.exception(new Error("Failed to load string"))});a(".backup_progress").children("span").removeClass("backup_stage_current");a(".backup_progress").children("span").last().addClass("backup_stage_current");clearInterval(A)}else if(e.status==r){i.classList.add("bg-success");f(w,h,100);var s="async"+z+"complete";c.get_string(s,"backup").then(function(a){j.text(a)}).catch(function(){d.exception(new Error("Failed to load string: backup "+s))});if("restore"==z){b.call([{methodname:"core_backup_get_async_backup_links_restore",args:{backupid:w,contextid:x}}])[0].done(function(a){var b="async"+z+"completedetail",e="async"+z+"completebutton",f=[{key:b,component:"backup",param:a.restoreurl},{key:e,component:"backup"}];c.get_strings(f).then(function(b){k.html(b[0]);l.text(b[1]);l.attr("href",a.restoreurl)}).catch(function(){d.exception(new Error("Failed to load string"))})})}else{var t="async"+z+"completedetail",u="async"+z+"completebutton";m=[{key:t,component:"backup",param:y},{key:u,component:"backup"}];c.get_strings(m).then(function(a){k.html(a[0]);l.text(a[1]);l.attr("href",y)}).catch(function(){d.exception(new Error("Failed to load string"))})}a(".backup_progress").children("span").removeClass("backup_stage_current");a(".backup_progress").children("span").last().addClass("backup_stage_current");clearInterval(A)}}function l(a){a.forEach(function(a){var b=100*a.progress,c=a.backupid,d=a.operation,e=document.querySelectorAll("[data-"+d+"id="+CSS.escape(c)+"]")[0];if(a.status==800){e.classList.add("bg-success");f(c,d,b)}else if(a.status==q){e.classList.add("bg-danger");e.classList.add("complete");e.classList.remove("bg-success");f(c,d,100)}else if(a.status==r){e.classList.add("bg-success");e.classList.add("complete");f(c,d,100);if("backup"==d){h(c)}else{i(c)}}})}function m(a){a.forEach(function(a){var b=100*a.progress,e=a.backupid,g=a.operation,h=document.querySelectorAll("[data-"+g+"id="+CSS.escape(e)+"]")[0];if("restore"==g){var i=h.closest("tr").children[3];c.get_string("restore").then(function(a){i.innerHTML=a}).catch(function(){d.exception(new Error("Failed to load string: restore"))})}if(a.status==800){h.classList.add("bg-success");f(e,g,b)}else if(a.status==q){h.classList.add("bg-danger");h.classList.add("complete");h.classList.remove("bg-success");f(e,g,100)}else if(a.status==r&&"restore"==g){h.classList.add("bg-success");h.classList.add("complete");f(e,g,100);j(e)}})}function n(){b.call([{methodname:"core_backup_get_async_backup_progress",args:{backupids:[w],contextid:x}}],!0,!0,!1,D)[0].done(function(a){k(a[0]);u=t;A=g(A,n,t)}).fail(function(){u=u*v;A=g(A,n,u)})}function o(){var c=[],d=a(".progress").find(".progress-bar").not(".complete");d.each(function(){c.push(this.id.substring(0,32))});if(0.\n\n/**\n * This module updates the UI during an asynchronous\n * backup or restore process.\n *\n * @module backup/util/async_backup\n * @package core\n * @copyright 2018 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.7\n */\ndefine(['jquery', 'core/ajax', 'core/str', 'core/notification', 'core/templates'],\n function($, ajax, Str, notification, Templates) {\n\n /**\n * Module level constants.\n *\n * Using var instead of const as ES6 isn't fully supported yet.\n */\n var STATUS_EXECUTING = 800;\n var STATUS_FINISHED_ERR = 900;\n var STATUS_FINISHED_OK = 1000;\n\n /**\n * Module level variables.\n */\n var Asyncbackup = {};\n var checkdelayoriginal = 15000; // This is the default time to use.\n var checkdelay = 15000; // How often we should check for progress updates.\n var checkdelaymultipler = 1.5; // If a request fails this multiplier will be used to increase the checkdelay value\n var backupid; // The backup id to get the progress for.\n var contextid; // The course this backup progress is for.\n var restoreurl; // The URL to view course restores.\n var typeid; // The type of operation backup or restore.\n var backupintervalid; // The id of the setInterval function.\n var allbackupintervalid; // The id of the setInterval function.\n var allcopyintervalid; // The id of the setInterval function.\n var timeout = 2000; // Timeout for ajax requests.\n\n /**\n * Helper function to update UI components.\n *\n * @param {string} backupid The id to match elements on.\n * @param {string} type The type of operation, backup or restore.\n * @param {number} percentage The completion percentage to apply.\n */\n function updateElement(backupid, type, percentage) {\n var percentagewidth = Math.round(percentage) + '%';\n var elementbar = document.querySelectorAll(\"[data-\" + type + \"id=\" + CSS.escape(backupid) + \"]\")[0];\n var percentagetext = percentage.toFixed(2) + '%';\n\n // Set progress bar percentage indicators\n elementbar.setAttribute('aria-valuenow', percentagewidth);\n elementbar.style.width = percentagewidth;\n elementbar.innerHTML = percentagetext;\n }\n\n /**\n * Updates the interval we use to check for backup progress.\n *\n * @param {Number} intervalid The id of the interval\n * @param {Function} callback The function to use in setInterval\n * @param {Number} value The specified interval (in milliseconds)\n * @returns {Number}\n */\n function updateInterval(intervalid, callback, value) {\n clearInterval(intervalid);\n return setInterval(callback, value);\n }\n\n /**\n * Update backup table row when an async backup completes.\n *\n * @param {string} backupid The id to match elements on.\n */\n function updateBackupTableRow(backupid) {\n var statuscell = $('#' + backupid + '_bar').parent().parent();\n var tablerow = statuscell.parent();\n var cellsiblings = statuscell.siblings();\n var timecell = cellsiblings[1];\n var timevalue = $(timecell).text();\n var filenamecell = cellsiblings[0];\n var filename = $(filenamecell).text();\n\n ajax.call([{\n // Get the table data via webservice.\n methodname: 'core_backup_get_async_backup_links_backup',\n args: {\n 'filename': filename,\n 'contextid': contextid\n },\n }])[0].done(function(response) {\n // We have the data now update the UI.\n var context = {\n filename: filename,\n time: timevalue,\n size: response.filesize,\n fileurl: response.fileurl,\n restoreurl: response.restoreurl\n };\n\n Templates.render('core/async_backup_progress_row', context).then(function(html, js) {\n Templates.replaceNodeContents(tablerow, html, js);\n return;\n }).fail(function() {\n notification.exception(new Error('Failed to load table row'));\n return;\n });\n });\n }\n\n /**\n * Update restore table row when an async restore completes.\n *\n * @param {string} backupid The id to match elements on.\n */\n function updateRestoreTableRow(backupid) {\n var statuscell = $('#' + backupid + '_bar').parent().parent();\n var tablerow = statuscell.parent();\n var cellsiblings = statuscell.siblings();\n var coursecell = cellsiblings[0];\n var timecell = cellsiblings[1];\n var timevalue = $(timecell).text();\n\n ajax.call([{\n // Get the table data via webservice.\n methodname: 'core_backup_get_async_backup_links_restore',\n args: {\n 'backupid': backupid,\n 'contextid': contextid\n },\n }])[0].done(function(response) {\n // We have the data now update the UI.\n var resourcename = $(coursecell).text();\n var context = {\n resourcename: resourcename,\n restoreurl: response.restoreurl,\n time: timevalue\n };\n\n Templates.render('core/async_restore_progress_row', context).then(function(html, js) {\n Templates.replaceNodeContents(tablerow, html, js);\n return;\n }).fail(function() {\n notification.exception(new Error('Failed to load table row'));\n return;\n });\n });\n }\n\n /**\n * Update copy table row when an course copy completes.\n *\n * @param {string} backupid The id to match elements on.\n */\n function updateCopyTableRow(backupid) {\n var elementbar = document.querySelectorAll(\"[data-restoreid=\" + CSS.escape(backupid) + \"]\")[0];\n var restorecourse = elementbar.closest('tr').children[1];\n var coursename = restorecourse.innerHTML;\n var courselink = document.createElement('a');\n var elementbarparent = elementbar.closest('td');\n var operation = elementbarparent.previousElementSibling;\n\n // Replace the prgress bar.\n Str.get_string('complete').then(function(content) {\n operation.innerHTML = content;\n return;\n }).catch(function() {\n notification.exception(new Error('Failed to load string: complete'));\n return;\n });\n\n Templates.render('core/async_copy_complete_cell', {}).then(function(html, js) {\n Templates.replaceNodeContents(elementbarparent, html, js);\n return;\n }).fail(function() {\n notification.exception(new Error('Failed to load table cell'));\n return;\n });\n\n // Update the destination course name to a link to that course.\n ajax.call([{\n methodname: 'core_backup_get_async_backup_links_restore',\n args: {\n 'backupid': backupid,\n 'contextid': 0\n },\n }])[0].done(function(response) {\n courselink.setAttribute('href', response.restoreurl);\n courselink.innerHTML = coursename;\n restorecourse.innerHTML = null;\n restorecourse.appendChild(courselink);\n\n return;\n }).fail(function() {\n notification.exception(new Error('Failed to update table row'));\n return;\n });\n }\n\n /**\n * Update the Moodle user interface with the progress of\n * the backup process.\n *\n * @param {object} progress The progress and status of the process.\n */\n function updateProgress(progress) {\n var percentage = progress.progress * 100;\n var type = 'backup';\n var elementbar = document.querySelectorAll(\"[data-\" + type + \"id=\" + CSS.escape(backupid) + \"]\")[0];\n var elementstatus = $('#' + backupid + '_status');\n var elementdetail = $('#' + backupid + '_detail');\n var elementbutton = $('#' + backupid + '_button');\n var stringRequests;\n\n if (progress.status == STATUS_EXECUTING) {\n // Process is in progress.\n // Add in progress class color to bar.\n elementbar.classList.add('bg-success');\n\n updateElement(backupid, type, percentage);\n\n // Change heading.\n var strProcessing = 'async' + typeid + 'processing';\n Str.get_string(strProcessing, 'backup').then(function(title) {\n elementstatus.text(title);\n return;\n }).catch(function() {\n notification.exception(new Error('Failed to load string: backup ' + strProcessing));\n });\n\n } else if (progress.status == STATUS_FINISHED_ERR) {\n // Process completed with error.\n\n // Add in fail class color to bar.\n elementbar.classList.add('bg-danger');\n\n // Remove in progress class color to bar.\n elementbar.classList.remove('bg-success');\n\n updateElement(backupid, type, 100);\n\n // Change heading and text.\n var strStatus = 'async' + typeid + 'error';\n var strStatusDetail = 'async' + typeid + 'errordetail';\n stringRequests = [\n {key: strStatus, component: 'backup'},\n {key: strStatusDetail, component: 'backup'}\n ];\n Str.get_strings(stringRequests).then(function(strings) {\n elementstatus.text(strings[0]);\n elementdetail.text(strings[1]);\n\n return;\n })\n .catch(function() {\n notification.exception(new Error('Failed to load string'));\n return;\n });\n\n $('.backup_progress').children('span').removeClass('backup_stage_current');\n $('.backup_progress').children('span').last().addClass('backup_stage_current');\n\n // Stop checking when we either have an error or a completion.\n clearInterval(backupintervalid);\n\n } else if (progress.status == STATUS_FINISHED_OK) {\n // Process completed successfully.\n\n // Add in progress class color to bar\n elementbar.classList.add('bg-success');\n\n updateElement(backupid, type, 100);\n\n // Change heading and text\n var strComplete = 'async' + typeid + 'complete';\n Str.get_string(strComplete, 'backup').then(function(title) {\n elementstatus.text(title);\n return;\n }).catch(function() {\n notification.exception(new Error('Failed to load string: backup ' + strComplete));\n });\n\n if (typeid == 'restore') {\n ajax.call([{\n // Get the table data via webservice.\n methodname: 'core_backup_get_async_backup_links_restore',\n args: {\n 'backupid': backupid,\n 'contextid': contextid\n },\n }])[0].done(function(response) {\n var strDetail = 'async' + typeid + 'completedetail';\n var strButton = 'async' + typeid + 'completebutton';\n var stringRequests = [\n {key: strDetail, component: 'backup', param: response.restoreurl},\n {key: strButton, component: 'backup'}\n ];\n Str.get_strings(stringRequests).then(function(strings) {\n elementdetail.html(strings[0]);\n elementbutton.text(strings[1]);\n elementbutton.attr('href', response.restoreurl);\n\n return;\n })\n .catch(function() {\n notification.exception(new Error('Failed to load string'));\n return;\n });\n\n });\n } else {\n var strDetail = 'async' + typeid + 'completedetail';\n var strButton = 'async' + typeid + 'completebutton';\n stringRequests = [\n {key: strDetail, component: 'backup', param: restoreurl},\n {key: strButton, component: 'backup'}\n ];\n Str.get_strings(stringRequests).then(function(strings) {\n elementdetail.html(strings[0]);\n elementbutton.text(strings[1]);\n elementbutton.attr('href', restoreurl);\n\n return;\n })\n .catch(function() {\n notification.exception(new Error('Failed to load string'));\n return;\n });\n\n }\n\n $('.backup_progress').children('span').removeClass('backup_stage_current');\n $('.backup_progress').children('span').last().addClass('backup_stage_current');\n\n // Stop checking when we either have an error or a completion.\n clearInterval(backupintervalid);\n }\n }\n\n /**\n * Update the Moodle user interface with the progress of\n * all the pending processes for backup and restore operations.\n *\n * @param {object} progress The progress and status of the process.\n */\n function updateProgressAll(progress) {\n progress.forEach(function(element) {\n var percentage = element.progress * 100;\n var backupid = element.backupid;\n var type = element.operation;\n var elementbar = document.querySelectorAll(\"[data-\" + type + \"id=\" + CSS.escape(backupid) + \"]\")[0];\n\n if (element.status == STATUS_EXECUTING) {\n // Process is in element.\n\n // Add in element class color to bar\n elementbar.classList.add('bg-success');\n\n updateElement(backupid, type, percentage);\n\n } else if (element.status == STATUS_FINISHED_ERR) {\n // Process completed with error.\n\n // Add in fail class color to bar\n elementbar.classList.add('bg-danger');\n elementbar.classList.add('complete');\n\n // Remove in element class color to bar\n elementbar.classList.remove('bg-success');\n\n updateElement(backupid, type, 100);\n\n } else if (element.status == STATUS_FINISHED_OK) {\n // Process completed successfully.\n\n // Add in element class color to bar\n elementbar.classList.add('bg-success');\n elementbar.classList.add('complete');\n\n updateElement(backupid, type, 100);\n\n // We have a successful backup. Update the UI with download and file details.\n if (type == 'backup') {\n updateBackupTableRow(backupid);\n } else {\n updateRestoreTableRow(backupid);\n }\n\n }\n\n });\n }\n\n /**\n * Update the Moodle user interface with the progress of\n * all the pending processes for copy operations.\n *\n * @param {object} progress The progress and status of the process.\n */\n function updateProgressCopy(progress) {\n progress.forEach(function(element) {\n var percentage = element.progress * 100;\n var backupid = element.backupid;\n var type = element.operation;\n var elementbar = document.querySelectorAll(\"[data-\" + type + \"id=\" + CSS.escape(backupid) + \"]\")[0];\n\n if (type == 'restore') {\n let restorecell = elementbar.closest('tr').children[3];\n Str.get_string('restore').then(function(content) {\n restorecell.innerHTML = content;\n return;\n }).catch(function() {\n notification.exception(new Error('Failed to load string: restore'));\n });\n }\n\n if (element.status == STATUS_EXECUTING) {\n // Process is in element.\n\n // Add in element class color to bar\n elementbar.classList.add('bg-success');\n\n updateElement(backupid, type, percentage);\n\n } else if (element.status == STATUS_FINISHED_ERR) {\n // Process completed with error.\n\n // Add in fail class color to bar\n elementbar.classList.add('bg-danger');\n elementbar.classList.add('complete');\n\n // Remove in element class color to bar\n elementbar.classList.remove('bg-success');\n\n updateElement(backupid, type, 100);\n\n } else if ((element.status == STATUS_FINISHED_OK) && (type == 'restore')) {\n // Process completed successfully.\n\n // Add in element class color to bar\n elementbar.classList.add('bg-success');\n elementbar.classList.add('complete');\n\n updateElement(backupid, type, 100);\n\n // We have a successful copy. Update the UI link to copied course.\n updateCopyTableRow(backupid);\n }\n\n });\n }\n\n /**\n * Get the progress of the backup process via ajax.\n */\n function getBackupProgress() {\n ajax.call([{\n // Get the backup progress via webservice.\n methodname: 'core_backup_get_async_backup_progress',\n args: {\n 'backupids': [backupid],\n 'contextid': contextid\n },\n }], true, true, false, timeout)[0].done(function(response) {\n // We have the progress now update the UI.\n updateProgress(response[0]);\n checkdelay = checkdelayoriginal;\n backupintervalid = updateInterval(backupintervalid, getBackupProgress, checkdelayoriginal);\n }).fail(function() {\n checkdelay = checkdelay * checkdelaymultipler;\n backupintervalid = updateInterval(backupintervalid, getBackupProgress, checkdelay);\n });\n }\n\n /**\n * Get the progress of all backup processes via ajax.\n */\n function getAllBackupProgress() {\n var backupids = [];\n var progressbars = $('.progress').find('.progress-bar').not('.complete');\n\n progressbars.each(function() {\n backupids.push((this.id).substring(0, 32));\n });\n\n if (backupids.length > 0) {\n ajax.call([{\n // Get the backup progress via webservice.\n methodname: 'core_backup_get_async_backup_progress',\n args: {\n 'backupids': backupids,\n 'contextid': contextid\n },\n }], true, true, false, timeout)[0].done(function(response) {\n updateProgressAll(response);\n checkdelay = checkdelayoriginal;\n allbackupintervalid = updateInterval(allbackupintervalid, getAllBackupProgress, checkdelayoriginal);\n }).fail(function() {\n checkdelay = checkdelay * checkdelaymultipler;\n allbackupintervalid = updateInterval(allbackupintervalid, getAllBackupProgress, checkdelay);\n });\n } else {\n clearInterval(allbackupintervalid); // No more progress bars to update, stop checking.\n }\n }\n\n /**\n * Get the progress of all copy processes via ajax.\n */\n function getAllCopyProgress() {\n var copyids = [];\n var progressbars = $('.progress').find('.progress-bar').not('.complete');\n\n progressbars.each(function() {\n let progressvars = {\n 'backupid': this.dataset.backupid,\n 'restoreid': this.dataset.restoreid,\n 'operation': this.dataset.operation,\n };\n copyids.push(progressvars);\n });\n\n if (copyids.length > 0) {\n ajax.call([{\n // Get the copy progress via webservice.\n methodname: 'core_backup_get_copy_progress',\n args: {\n 'copies': copyids\n },\n }], true, true, false, timeout)[0].done(function(response) {\n updateProgressCopy(response);\n checkdelay = checkdelayoriginal;\n allcopyintervalid = updateInterval(allcopyintervalid, getAllCopyProgress, checkdelayoriginal);\n }).fail(function() {\n checkdelay = checkdelay * checkdelaymultipler;\n allcopyintervalid = updateInterval(allcopyintervalid, getAllCopyProgress, checkdelay);\n });\n } else {\n clearInterval(allcopyintervalid); // No more progress bars to update, stop checking.\n }\n }\n\n /**\n * Get status updates for all backups.\n *\n * @public\n * @param {number} context The context id.\n */\n Asyncbackup.asyncBackupAllStatus = function(context) {\n contextid = context;\n allbackupintervalid = setInterval(getAllBackupProgress, checkdelay);\n };\n\n /**\n * Get status updates for all course copies.\n *\n * @public\n */\n Asyncbackup.asyncCopyAllStatus = function() {\n allcopyintervalid = setInterval(getAllCopyProgress, checkdelay);\n };\n\n /**\n * Get status updates for backup.\n *\n * @public\n * @param {string} backup The backup record id.\n * @param {number} context The context id.\n * @param {string} restore The restore link.\n * @param {string} type The operation type (backup or restore).\n */\n Asyncbackup.asyncBackupStatus = function(backup, context, restore, type) {\n backupid = backup;\n contextid = context;\n restoreurl = restore;\n\n if (type == 'backup') {\n typeid = 'backup';\n } else {\n typeid = 'restore';\n }\n\n // Remove the links from the progress bar, no going back now.\n $('.backup_progress').children('a').removeAttr('href');\n\n // Periodically check for progress updates and update the UI as required.\n backupintervalid = setInterval(getBackupProgress, checkdelay);\n\n };\n\n return Asyncbackup;\n});\n"],"file":"async_backup.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/async_backup.js"],"names":["define","$","ajax","Str","notification","Templates","STATUS_FINISHED_ERR","STATUS_FINISHED_OK","Asyncbackup","checkdelayoriginal","checkdelay","checkdelaymultipler","backupid","contextid","restoreurl","typeid","backupintervalid","allbackupintervalid","allcopyintervalid","timeout","updateElement","type","percentage","percentagewidth","Math","round","elementbar","document","querySelectorAll","CSS","escape","percentagetext","toFixed","setAttribute","style","width","innerHTML","updateInterval","intervalid","callback","value","clearInterval","setInterval","updateBackupTableRow","statuscell","parent","tablerow","cellsiblings","siblings","timecell","timevalue","text","filenamecell","filename","call","methodname","args","done","response","context","time","size","filesize","fileurl","render","then","html","js","replaceNodeContents","fail","exception","Error","updateRestoreTableRow","coursecell","resourcename","updateCopyTableRow","restorecourse","closest","children","coursename","courselink","createElement","elementbarparent","operation","previousElementSibling","get_string","content","catch","appendChild","updateProgress","progress","elementstatus","elementdetail","elementbutton","stringRequests","status","classList","add","strProcessing","title","remove","strStatus","strStatusDetail","key","component","get_strings","strings","removeClass","last","addClass","strComplete","strDetail","strButton","param","attr","updateProgressAll","forEach","element","updateProgressCopy","restorecell","getBackupProgress","getAllBackupProgress","backupids","progressbars","find","not","each","push","id","substring","length","getAllCopyProgress","copyids","progressvars","dataset","restoreid","asyncBackupAllStatus","asyncCopyAllStatus","asyncBackupStatus","backup","restore","removeAttr"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * This module updates the UI during an asynchronous\n * backup or restore process.\n *\n * @module backup/util/async_backup\n * @package core\n * @copyright 2018 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.7\n */\ndefine(['jquery', 'core/ajax', 'core/str', 'core/notification', 'core/templates'],\n function($, ajax, Str, notification, Templates) {\n\n /**\n * Module level constants.\n *\n * Using var instead of const as ES6 isn't fully supported yet.\n */\n var STATUS_EXECUTING = 800;\n var STATUS_FINISHED_ERR = 900;\n var STATUS_FINISHED_OK = 1000;\n\n /**\n * Module level variables.\n */\n var Asyncbackup = {};\n var checkdelayoriginal = 15000; // This is the default time to use.\n var checkdelay = 15000; // How often we should check for progress updates.\n var checkdelaymultipler = 1.5; // If a request fails this multiplier will be used to increase the checkdelay value\n var backupid; // The backup id to get the progress for.\n var contextid; // The course this backup progress is for.\n var restoreurl; // The URL to view course restores.\n var typeid; // The type of operation backup or restore.\n var backupintervalid; // The id of the setInterval function.\n var allbackupintervalid; // The id of the setInterval function.\n var allcopyintervalid; // The id of the setInterval function.\n var timeout = 2000; // Timeout for ajax requests.\n\n /**\n * Helper function to update UI components.\n *\n * @param {string} backupid The id to match elements on.\n * @param {string} type The type of operation, backup or restore.\n * @param {number} percentage The completion percentage to apply.\n */\n function updateElement(backupid, type, percentage) {\n var percentagewidth = Math.round(percentage) + '%';\n var elementbar = document.querySelectorAll(\"[data-\" + type + \"id=\" + CSS.escape(backupid) + \"]\")[0];\n var percentagetext = percentage.toFixed(2) + '%';\n\n // Set progress bar percentage indicators\n elementbar.setAttribute('aria-valuenow', percentagewidth);\n elementbar.style.width = percentagewidth;\n elementbar.innerHTML = percentagetext;\n }\n\n /**\n * Updates the interval we use to check for backup progress.\n *\n * @param {Number} intervalid The id of the interval\n * @param {Function} callback The function to use in setInterval\n * @param {Number} value The specified interval (in milliseconds)\n * @returns {Number}\n */\n function updateInterval(intervalid, callback, value) {\n clearInterval(intervalid);\n return setInterval(callback, value);\n }\n\n /**\n * Update backup table row when an async backup completes.\n *\n * @param {string} backupid The id to match elements on.\n */\n function updateBackupTableRow(backupid) {\n var statuscell = $('#' + backupid + '_bar').parent().parent();\n var tablerow = statuscell.parent();\n var cellsiblings = statuscell.siblings();\n var timecell = cellsiblings[1];\n var timevalue = $(timecell).text();\n var filenamecell = cellsiblings[0];\n var filename = $(filenamecell).text();\n\n ajax.call([{\n // Get the table data via webservice.\n methodname: 'core_backup_get_async_backup_links_backup',\n args: {\n 'filename': filename,\n 'contextid': contextid\n },\n }])[0].done(function(response) {\n // We have the data now update the UI.\n var context = {\n filename: filename,\n time: timevalue,\n size: response.filesize,\n fileurl: response.fileurl,\n restoreurl: response.restoreurl\n };\n\n Templates.render('core/async_backup_progress_row', context).then(function(html, js) {\n Templates.replaceNodeContents(tablerow, html, js);\n return;\n }).fail(function() {\n notification.exception(new Error('Failed to load table row'));\n return;\n });\n });\n }\n\n /**\n * Update restore table row when an async restore completes.\n *\n * @param {string} backupid The id to match elements on.\n */\n function updateRestoreTableRow(backupid) {\n var statuscell = $('#' + backupid + '_bar').parent().parent();\n var tablerow = statuscell.parent();\n var cellsiblings = statuscell.siblings();\n var coursecell = cellsiblings[0];\n var timecell = cellsiblings[1];\n var timevalue = $(timecell).text();\n\n ajax.call([{\n // Get the table data via webservice.\n methodname: 'core_backup_get_async_backup_links_restore',\n args: {\n 'backupid': backupid,\n 'contextid': contextid\n },\n }])[0].done(function(response) {\n // We have the data now update the UI.\n var resourcename = $(coursecell).text();\n var context = {\n resourcename: resourcename,\n restoreurl: response.restoreurl,\n time: timevalue\n };\n\n Templates.render('core/async_restore_progress_row', context).then(function(html, js) {\n Templates.replaceNodeContents(tablerow, html, js);\n return;\n }).fail(function() {\n notification.exception(new Error('Failed to load table row'));\n return;\n });\n });\n }\n\n /**\n * Update copy table row when an course copy completes.\n *\n * @param {string} backupid The id to match elements on.\n */\n function updateCopyTableRow(backupid) {\n var elementbar = document.querySelectorAll(\"[data-restoreid=\" + CSS.escape(backupid) + \"]\")[0];\n var restorecourse = elementbar.closest('tr').children[1];\n var coursename = restorecourse.innerHTML;\n var courselink = document.createElement('a');\n var elementbarparent = elementbar.closest('td');\n var operation = elementbarparent.previousElementSibling;\n\n // Replace the prgress bar.\n Str.get_string('complete').then(function(content) {\n operation.innerHTML = content;\n return;\n }).catch(function() {\n notification.exception(new Error('Failed to load string: complete'));\n return;\n });\n\n Templates.render('core/async_copy_complete_cell', {}).then(function(html, js) {\n Templates.replaceNodeContents(elementbarparent, html, js);\n return;\n }).fail(function() {\n notification.exception(new Error('Failed to load table cell'));\n return;\n });\n\n // Update the destination course name to a link to that course.\n ajax.call([{\n methodname: 'core_backup_get_async_backup_links_restore',\n args: {\n 'backupid': backupid,\n 'contextid': 0\n },\n }])[0].done(function(response) {\n courselink.setAttribute('href', response.restoreurl);\n courselink.innerHTML = coursename;\n restorecourse.innerHTML = null;\n restorecourse.appendChild(courselink);\n\n return;\n }).fail(function() {\n notification.exception(new Error('Failed to update table row'));\n return;\n });\n }\n\n /**\n * Update the Moodle user interface with the progress of\n * the backup process.\n *\n * @param {object} progress The progress and status of the process.\n */\n function updateProgress(progress) {\n var percentage = progress.progress * 100;\n var type = 'backup';\n var elementbar = document.querySelectorAll(\"[data-\" + type + \"id=\" + CSS.escape(backupid) + \"]\")[0];\n var elementstatus = $('#' + backupid + '_status');\n var elementdetail = $('#' + backupid + '_detail');\n var elementbutton = $('#' + backupid + '_button');\n var stringRequests;\n\n if (progress.status == STATUS_EXECUTING) {\n // Process is in progress.\n // Add in progress class color to bar.\n elementbar.classList.add('bg-success');\n\n updateElement(backupid, type, percentage);\n\n // Change heading.\n var strProcessing = 'async' + typeid + 'processing';\n Str.get_string(strProcessing, 'backup').then(function(title) {\n elementstatus.text(title);\n return;\n }).catch(function() {\n notification.exception(new Error('Failed to load string: backup ' + strProcessing));\n });\n\n } else if (progress.status == STATUS_FINISHED_ERR) {\n // Process completed with error.\n\n // Add in fail class color to bar.\n elementbar.classList.add('bg-danger');\n\n // Remove in progress class color to bar.\n elementbar.classList.remove('bg-success');\n\n updateElement(backupid, type, 100);\n\n // Change heading and text.\n var strStatus = 'async' + typeid + 'error';\n var strStatusDetail = 'async' + typeid + 'errordetail';\n stringRequests = [\n {key: strStatus, component: 'backup'},\n {key: strStatusDetail, component: 'backup'}\n ];\n Str.get_strings(stringRequests).then(function(strings) {\n elementstatus.text(strings[0]);\n elementdetail.text(strings[1]);\n\n return;\n })\n .catch(function() {\n notification.exception(new Error('Failed to load string'));\n return;\n });\n\n $('.backup_progress').children('span').removeClass('backup_stage_current');\n $('.backup_progress').children('span').last().addClass('backup_stage_current');\n\n // Stop checking when we either have an error or a completion.\n clearInterval(backupintervalid);\n\n } else if (progress.status == STATUS_FINISHED_OK) {\n // Process completed successfully.\n\n // Add in progress class color to bar\n elementbar.classList.add('bg-success');\n\n updateElement(backupid, type, 100);\n\n // Change heading and text\n var strComplete = 'async' + typeid + 'complete';\n Str.get_string(strComplete, 'backup').then(function(title) {\n elementstatus.text(title);\n return;\n }).catch(function() {\n notification.exception(new Error('Failed to load string: backup ' + strComplete));\n });\n\n if (typeid == 'restore') {\n ajax.call([{\n // Get the table data via webservice.\n methodname: 'core_backup_get_async_backup_links_restore',\n args: {\n 'backupid': backupid,\n 'contextid': contextid\n },\n }])[0].done(function(response) {\n var strDetail = 'async' + typeid + 'completedetail';\n var strButton = 'async' + typeid + 'completebutton';\n var stringRequests = [\n {key: strDetail, component: 'backup', param: response.restoreurl},\n {key: strButton, component: 'backup'}\n ];\n Str.get_strings(stringRequests).then(function(strings) {\n elementdetail.html(strings[0]);\n elementbutton.text(strings[1]);\n elementbutton.attr('href', response.restoreurl);\n\n return;\n })\n .catch(function() {\n notification.exception(new Error('Failed to load string'));\n return;\n });\n\n });\n } else {\n var strDetail = 'async' + typeid + 'completedetail';\n var strButton = 'async' + typeid + 'completebutton';\n stringRequests = [\n {key: strDetail, component: 'backup', param: restoreurl},\n {key: strButton, component: 'backup'}\n ];\n Str.get_strings(stringRequests).then(function(strings) {\n elementdetail.html(strings[0]);\n elementbutton.text(strings[1]);\n elementbutton.attr('href', restoreurl);\n\n return;\n })\n .catch(function() {\n notification.exception(new Error('Failed to load string'));\n return;\n });\n\n }\n\n $('.backup_progress').children('span').removeClass('backup_stage_current');\n $('.backup_progress').children('span').last().addClass('backup_stage_current');\n\n // Stop checking when we either have an error or a completion.\n clearInterval(backupintervalid);\n }\n }\n\n /**\n * Update the Moodle user interface with the progress of\n * all the pending processes for backup and restore operations.\n *\n * @param {object} progress The progress and status of the process.\n */\n function updateProgressAll(progress) {\n progress.forEach(function(element) {\n var percentage = element.progress * 100;\n var backupid = element.backupid;\n var type = element.operation;\n var elementbar = document.querySelectorAll(\"[data-\" + type + \"id=\" + CSS.escape(backupid) + \"]\")[0];\n\n if (element.status == STATUS_EXECUTING) {\n // Process is in element.\n\n // Add in element class color to bar\n elementbar.classList.add('bg-success');\n\n updateElement(backupid, type, percentage);\n\n } else if (element.status == STATUS_FINISHED_ERR) {\n // Process completed with error.\n\n // Add in fail class color to bar\n elementbar.classList.add('bg-danger');\n elementbar.classList.add('complete');\n\n // Remove in element class color to bar\n elementbar.classList.remove('bg-success');\n\n updateElement(backupid, type, 100);\n\n } else if (element.status == STATUS_FINISHED_OK) {\n // Process completed successfully.\n\n // Add in element class color to bar\n elementbar.classList.add('bg-success');\n elementbar.classList.add('complete');\n\n updateElement(backupid, type, 100);\n\n // We have a successful backup. Update the UI with download and file details.\n if (type == 'backup') {\n updateBackupTableRow(backupid);\n } else {\n updateRestoreTableRow(backupid);\n }\n\n }\n\n });\n }\n\n /**\n * Update the Moodle user interface with the progress of\n * all the pending processes for copy operations.\n *\n * @param {object} progress The progress and status of the process.\n */\n function updateProgressCopy(progress) {\n progress.forEach(function(element) {\n var percentage = element.progress * 100;\n var backupid = element.backupid;\n var type = element.operation;\n var elementbar = document.querySelectorAll(\"[data-\" + type + \"id=\" + CSS.escape(backupid) + \"]\")[0];\n\n if (type == 'restore') {\n let restorecell = elementbar.closest('tr').children[3];\n Str.get_string('restore').then(function(content) {\n restorecell.innerHTML = content;\n return;\n }).catch(function() {\n notification.exception(new Error('Failed to load string: restore'));\n });\n }\n\n if (element.status == STATUS_EXECUTING) {\n // Process is in element.\n\n // Add in element class color to bar\n elementbar.classList.add('bg-success');\n\n updateElement(backupid, type, percentage);\n\n } else if (element.status == STATUS_FINISHED_ERR) {\n // Process completed with error.\n\n // Add in fail class color to bar\n elementbar.classList.add('bg-danger');\n elementbar.classList.add('complete');\n\n // Remove in element class color to bar\n elementbar.classList.remove('bg-success');\n\n updateElement(backupid, type, 100);\n\n } else if ((element.status == STATUS_FINISHED_OK) && (type == 'restore')) {\n // Process completed successfully.\n\n // Add in element class color to bar\n elementbar.classList.add('bg-success');\n elementbar.classList.add('complete');\n\n updateElement(backupid, type, 100);\n\n // We have a successful copy. Update the UI link to copied course.\n updateCopyTableRow(backupid);\n }\n\n });\n }\n\n /**\n * Get the progress of the backup process via ajax.\n */\n function getBackupProgress() {\n ajax.call([{\n // Get the backup progress via webservice.\n methodname: 'core_backup_get_async_backup_progress',\n args: {\n 'backupids': [backupid],\n 'contextid': contextid\n },\n }], true, true, false, timeout)[0].done(function(response) {\n // We have the progress now update the UI.\n updateProgress(response[0]);\n checkdelay = checkdelayoriginal;\n backupintervalid = updateInterval(backupintervalid, getBackupProgress, checkdelayoriginal);\n }).fail(function() {\n checkdelay = checkdelay * checkdelaymultipler;\n backupintervalid = updateInterval(backupintervalid, getBackupProgress, checkdelay);\n });\n }\n\n /**\n * Get the progress of all backup processes via ajax.\n */\n function getAllBackupProgress() {\n var backupids = [];\n var progressbars = $('.progress').find('.progress-bar').not('.complete');\n\n progressbars.each(function() {\n backupids.push((this.id).substring(0, 32));\n });\n\n if (backupids.length > 0) {\n ajax.call([{\n // Get the backup progress via webservice.\n methodname: 'core_backup_get_async_backup_progress',\n args: {\n 'backupids': backupids,\n 'contextid': contextid\n },\n }], true, true, false, timeout)[0].done(function(response) {\n updateProgressAll(response);\n checkdelay = checkdelayoriginal;\n allbackupintervalid = updateInterval(allbackupintervalid, getAllBackupProgress, checkdelayoriginal);\n }).fail(function() {\n checkdelay = checkdelay * checkdelaymultipler;\n allbackupintervalid = updateInterval(allbackupintervalid, getAllBackupProgress, checkdelay);\n });\n } else {\n clearInterval(allbackupintervalid); // No more progress bars to update, stop checking.\n }\n }\n\n /**\n * Get the progress of all copy processes via ajax.\n */\n function getAllCopyProgress() {\n var copyids = [];\n var progressbars = $('.progress').find('.progress-bar[data-operation][data-backupid][data-restoreid]').not('.complete');\n\n progressbars.each(function() {\n let progressvars = {\n 'backupid': this.dataset.backupid,\n 'restoreid': this.dataset.restoreid,\n 'operation': this.dataset.operation,\n };\n copyids.push(progressvars);\n });\n\n if (copyids.length > 0) {\n ajax.call([{\n // Get the copy progress via webservice.\n methodname: 'core_backup_get_copy_progress',\n args: {\n 'copies': copyids\n },\n }], true, true, false, timeout)[0].done(function(response) {\n updateProgressCopy(response);\n checkdelay = checkdelayoriginal;\n allcopyintervalid = updateInterval(allcopyintervalid, getAllCopyProgress, checkdelayoriginal);\n }).fail(function() {\n checkdelay = checkdelay * checkdelaymultipler;\n allcopyintervalid = updateInterval(allcopyintervalid, getAllCopyProgress, checkdelay);\n });\n } else {\n clearInterval(allcopyintervalid); // No more progress bars to update, stop checking.\n }\n }\n\n /**\n * Get status updates for all backups.\n *\n * @public\n * @param {number} context The context id.\n */\n Asyncbackup.asyncBackupAllStatus = function(context) {\n contextid = context;\n allbackupintervalid = setInterval(getAllBackupProgress, checkdelay);\n };\n\n /**\n * Get status updates for all course copies.\n *\n * @public\n */\n Asyncbackup.asyncCopyAllStatus = function() {\n allcopyintervalid = setInterval(getAllCopyProgress, checkdelay);\n };\n\n /**\n * Get status updates for backup.\n *\n * @public\n * @param {string} backup The backup record id.\n * @param {number} context The context id.\n * @param {string} restore The restore link.\n * @param {string} type The operation type (backup or restore).\n */\n Asyncbackup.asyncBackupStatus = function(backup, context, restore, type) {\n backupid = backup;\n contextid = context;\n restoreurl = restore;\n\n if (type == 'backup') {\n typeid = 'backup';\n } else {\n typeid = 'restore';\n }\n\n // Remove the links from the progress bar, no going back now.\n $('.backup_progress').children('a').removeAttr('href');\n\n // Periodically check for progress updates and update the UI as required.\n backupintervalid = setInterval(getBackupProgress, checkdelay);\n\n };\n\n return Asyncbackup;\n});\n"],"file":"async_backup.min.js"} \ No newline at end of file diff --git a/backup/util/ui/amd/src/async_backup.js b/backup/util/ui/amd/src/async_backup.js index 59a4bc997ed..4854dedc34b 100644 --- a/backup/util/ui/amd/src/async_backup.js +++ b/backup/util/ui/amd/src/async_backup.js @@ -524,7 +524,7 @@ define(['jquery', 'core/ajax', 'core/str', 'core/notification', 'core/templates' */ function getAllCopyProgress() { var copyids = []; - var progressbars = $('.progress').find('.progress-bar').not('.complete'); + var progressbars = $('.progress').find('.progress-bar[data-operation][data-backupid][data-restoreid]').not('.complete'); progressbars.each(function() { let progressvars = {