Privacy: Give progress indication for export and erasure.

This adds a progress indicator for "Download Personal Data" and "Erase Personal Data" row actions, which can take a while with a lot of data.

Props garrett-eclipse, allendav, dominic_ks, xkon, karmatosed, birgire.
Fixes #44264.
Built from https://develop.svn.wordpress.org/trunk@47246


git-svn-id: http://core.svn.wordpress.org/trunk@47046 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Sergey Biryukov 2020-02-10 20:19:05 +00:00
parent 3342aafe5e
commit 5ddf97e142
5 changed files with 25 additions and 7 deletions

View File

@ -57,7 +57,7 @@ class WP_Privacy_Data_Export_Requests_List_Table extends WP_Privacy_Requests_Tab
'">'; '">';
$download_data_markup .= '<span class="export-personal-data-idle"><button type="button" class="button-link export-personal-data-handle">' . __( 'Download Personal Data' ) . '</button></span>' . $download_data_markup .= '<span class="export-personal-data-idle"><button type="button" class="button-link export-personal-data-handle">' . __( 'Download Personal Data' ) . '</button></span>' .
'<span class="export-personal-data-processing hidden">' . __( 'Downloading Data...' ) . '</span>' . '<span class="export-personal-data-processing hidden">' . __( 'Downloading Data...' ) . ' <span class="export-progress"></span></span>' .
'<span class="export-personal-data-success hidden"><button type="button" class="button-link export-personal-data-handle">' . __( 'Download Personal Data Again' ) . '</button></span>' . '<span class="export-personal-data-success hidden"><button type="button" class="button-link export-personal-data-handle">' . __( 'Download Personal Data Again' ) . '</button></span>' .
'<span class="export-personal-data-failed hidden">' . __( 'Download failed.' ) . ' <button type="button" class="button-link">' . __( 'Retry' ) . '</button></span>'; '<span class="export-personal-data-failed hidden">' . __( 'Download failed.' ) . ' <button type="button" class="button-link">' . __( 'Retry' ) . '</button></span>';
@ -100,7 +100,7 @@ class WP_Privacy_Data_Export_Requests_List_Table extends WP_Privacy_Requests_Tab
?> ?>
<span class="export-personal-data-idle"><button type="button" class="button export-personal-data-handle"><?php _e( 'Send Export Link' ); ?></button></span> <span class="export-personal-data-idle"><button type="button" class="button export-personal-data-handle"><?php _e( 'Send Export Link' ); ?></button></span>
<span class="export-personal-data-processing button updating-message hidden"><?php _e( 'Sending Email...' ); ?></span> <span class="export-personal-data-processing button updating-message hidden"><?php _e( 'Sending Email...' ); ?> <span class="export-progress"></span></span>
<span class="export-personal-data-success success-message hidden"><?php _e( 'Email sent.' ); ?></span> <span class="export-personal-data-success success-message hidden"><?php _e( 'Email sent.' ); ?></span>
<span class="export-personal-data-failed hidden"><?php _e( 'Email could not be sent.' ); ?> <button type="button" class="button export-personal-data-handle"><?php _e( 'Retry' ); ?></button></span> <span class="export-personal-data-failed hidden"><?php _e( 'Email could not be sent.' ); ?> <button type="button" class="button export-personal-data-handle"><?php _e( 'Retry' ); ?></button></span>
<?php <?php

View File

@ -62,7 +62,7 @@ class WP_Privacy_Data_Removal_Requests_List_Table extends WP_Privacy_Requests_Ta
'">'; '">';
$remove_data_markup .= '<span class="remove-personal-data-idle"><button type="button" class="button-link remove-personal-data-handle">' . __( 'Force Erase Personal Data' ) . '</button></span>' . $remove_data_markup .= '<span class="remove-personal-data-idle"><button type="button" class="button-link remove-personal-data-handle">' . __( 'Force Erase Personal Data' ) . '</button></span>' .
'<span class="remove-personal-data-processing hidden">' . __( 'Erasing Data...' ) . '</span>' . '<span class="remove-personal-data-processing hidden">' . __( 'Erasing Data...' ) . ' <span class="erasure-progress"></span></span>' .
'<span class="remove-personal-data-success hidden">' . __( 'Erasure completed.' ) . '</span>' . '<span class="remove-personal-data-success hidden">' . __( 'Erasure completed.' ) . '</span>' .
'<span class="remove-personal-data-failed hidden">' . __( 'Force Erasure has failed.' ) . ' <button type="button" class="button-link remove-personal-data-handle">' . __( 'Retry' ) . '</button></span>'; '<span class="remove-personal-data-failed hidden">' . __( 'Force Erasure has failed.' ) . ' <button type="button" class="button-link remove-personal-data-handle">' . __( 'Retry' ) . '</button></span>';
@ -106,7 +106,7 @@ class WP_Privacy_Data_Removal_Requests_List_Table extends WP_Privacy_Requests_Ta
?> ?>
<span class="remove-personal-data-idle"><button type="button" class="button remove-personal-data-handle"><?php _e( 'Erase Personal Data' ); ?></button></span> <span class="remove-personal-data-idle"><button type="button" class="button remove-personal-data-handle"><?php _e( 'Erase Personal Data' ); ?></button></span>
<span class="remove-personal-data-processing button updating-message hidden"><?php _e( 'Erasing Data...' ); ?></span> <span class="remove-personal-data-processing button updating-message hidden"><?php _e( 'Erasing Data...' ); ?> <span class="erasure-progress"></span></span>
<span class="remove-personal-data-success success-message hidden" ><?php _e( 'Erasure completed.' ); ?></span> <span class="remove-personal-data-success success-message hidden" ><?php _e( 'Erasure completed.' ); ?></span>
<span class="remove-personal-data-failed hidden"><?php _e( 'Data Erasure has failed.' ); ?> <button type="button" class="button remove-personal-data-handle"><?php _e( 'Retry' ); ?></button></span> <span class="remove-personal-data-failed hidden"><?php _e( 'Data Erasure has failed.' ); ?> <button type="button" class="button remove-personal-data-handle"><?php _e( 'Retry' ); ?></button></span>
<?php <?php

View File

@ -59,6 +59,7 @@ jQuery( document ).ready( function( $ ) {
var $this = $( this ), var $this = $( this ),
$action = $this.parents( '.export-personal-data' ), $action = $this.parents( '.export-personal-data' ),
$requestRow = $this.parents( 'tr' ), $requestRow = $this.parents( 'tr' ),
$progress = $requestRow.find( '.export-progress' );
requestID = $action.data( 'request-id' ), requestID = $action.data( 'request-id' ),
nonce = $action.data( 'nonce' ), nonce = $action.data( 'nonce' ),
exportersCount = $action.data( 'exporters-count' ), exportersCount = $action.data( 'exporters-count' ),
@ -69,6 +70,7 @@ jQuery( document ).ready( function( $ ) {
$action.blur(); $action.blur();
clearResultsAfterRow( $requestRow ); clearResultsAfterRow( $requestRow );
setExportProgress( 0 );
function onExportDoneSuccess( zipUrl ) { function onExportDoneSuccess( zipUrl ) {
var summaryMessage = strings.emailSent; var summaryMessage = strings.emailSent;
@ -77,7 +79,7 @@ jQuery( document ).ready( function( $ ) {
appendResultsAfterRow( $requestRow, 'notice-success', summaryMessage, [] ); appendResultsAfterRow( $requestRow, 'notice-success', summaryMessage, [] );
$this.hide(); $this.hide();
if ( 'undefined' !== typeof zipUrl ) { if ( 'undefined' !== typeof zipUrl ) {
window.location = zipUrl; window.location = zipUrl;
} else if ( ! sendAsEmail ) { } else if ( ! sendAsEmail ) {
@ -92,6 +94,12 @@ jQuery( document ).ready( function( $ ) {
} }
} }
function setExportProgress( exporterIndex ) {
var progress = ( exportersCount > 0 ? exporterIndex / exportersCount : 0 );
var progressString = Math.round( progress * 100 ).toString() + '%';
$progress.html( progressString );
}
function doNextExport( exporterIndex, pageIndex ) { function doNextExport( exporterIndex, pageIndex ) {
$.ajax( $.ajax(
{ {
@ -120,6 +128,7 @@ jQuery( document ).ready( function( $ ) {
setTimeout( doNextExport( exporterIndex, pageIndex + 1 ) ); setTimeout( doNextExport( exporterIndex, pageIndex + 1 ) );
} else { } else {
if ( exporterIndex < exportersCount ) { if ( exporterIndex < exportersCount ) {
setExportProgress( exporterIndex );
setTimeout( doNextExport( exporterIndex + 1, 1 ) ); setTimeout( doNextExport( exporterIndex + 1, 1 ) );
} else { } else {
onExportDoneSuccess( responseData.url ); onExportDoneSuccess( responseData.url );
@ -141,6 +150,7 @@ jQuery( document ).ready( function( $ ) {
var $this = $( this ), var $this = $( this ),
$action = $this.parents( '.remove-personal-data' ), $action = $this.parents( '.remove-personal-data' ),
$requestRow = $this.parents( 'tr' ), $requestRow = $this.parents( 'tr' ),
$progress = $requestRow.find( '.erasure-progress' );
requestID = $action.data( 'request-id' ), requestID = $action.data( 'request-id' ),
nonce = $action.data( 'nonce' ), nonce = $action.data( 'nonce' ),
erasersCount = $action.data( 'erasers-count' ), erasersCount = $action.data( 'erasers-count' ),
@ -152,6 +162,7 @@ jQuery( document ).ready( function( $ ) {
$action.blur(); $action.blur();
clearResultsAfterRow( $requestRow ); clearResultsAfterRow( $requestRow );
setErasureProgress( 0 );
function onErasureDoneSuccess() { function onErasureDoneSuccess() {
var summaryMessage = strings.noDataFound; var summaryMessage = strings.noDataFound;
@ -183,6 +194,12 @@ jQuery( document ).ready( function( $ ) {
appendResultsAfterRow( $requestRow, 'notice-error', strings.removalError, [] ); appendResultsAfterRow( $requestRow, 'notice-error', strings.removalError, [] );
} }
function setErasureProgress( eraserIndex ) {
var progress = ( erasersCount > 0 ? eraserIndex / erasersCount : 0 );
var progressString = Math.round( progress * 100 ).toString() + '%';
$progress.html( progressString );
}
function doNextErasure( eraserIndex, pageIndex ) { function doNextErasure( eraserIndex, pageIndex ) {
$.ajax({ $.ajax({
url: window.ajaxurl, url: window.ajaxurl,
@ -214,6 +231,7 @@ jQuery( document ).ready( function( $ ) {
setTimeout( doNextErasure( eraserIndex, pageIndex + 1 ) ); setTimeout( doNextErasure( eraserIndex, pageIndex + 1 ) );
} else { } else {
if ( eraserIndex < erasersCount ) { if ( eraserIndex < erasersCount ) {
setErasureProgress( eraserIndex );
setTimeout( doNextErasure( eraserIndex + 1, 1 ) ); setTimeout( doNextErasure( eraserIndex + 1, 1 ) );
} else { } else {
onErasureDoneSuccess(); onErasureDoneSuccess();

View File

@ -1,2 +1,2 @@
/*! This file is auto-generated */ /*! This file is auto-generated */
jQuery(document).ready(function(v){var f=window.privacyToolsL10n||{};function h(e,t){e.children().addClass("hidden"),e.children("."+t).removeClass("hidden")}function g(e){e.removeClass("has-request-results"),e.next().hasClass("request-results")&&e.next().remove()}function x(e,t,a,n){var o="",s="request-results";g(e),n.length&&(v.each(n,function(e,t){o=o+"<li>"+t+"</li>"}),o="<ul>"+o+"</ul>"),e.addClass("has-request-results"),e.hasClass("status-request-confirmed")&&(s+=" status-request-confirmed"),e.hasClass("status-request-failed")&&(s+=" status-request-failed"),e.after(function(){return'<tr class="'+s+'"><th colspan="5"><div class="notice inline notice-alt '+t+'"><p>'+a+"</p>"+o+"</div></td></tr>"})}v(".export-personal-data-handle").click(function(e){var s=v(this),r=s.parents(".export-personal-data"),i=s.parents("tr"),t=r.data("request-id"),d=r.data("nonce"),c=r.data("exporters-count"),l=!!r.data("send-as-email");function u(e){h(r,"export-personal-data-failed"),e&&x(i,"notice-error",f.exportError,[e])}e.preventDefault(),e.stopPropagation(),r.blur(),g(i),h(r,"export-personal-data-processing"),function a(n,o){v.ajax({url:window.ajaxurl,data:{action:"wp-privacy-export-personal-data",exporter:n,id:t,page:o,security:d,sendAsEmail:l},method:"post"}).done(function(e){var t=e.data;e.success?t.done?n<c?setTimeout(a(n+1,1)):function(e){var t=f.emailSent;h(r,"export-personal-data-success"),x(i,"notice-success",t,[]),s.hide(),void 0!==e?window.location=e:l||u(f.noExportFile)}(t.url):setTimeout(a(n,o+1)):u(e.data)}).fail(function(e,t,a){u(a)})}(1,1)}),v(".remove-personal-data-handle").click(function(e){var s=v(this),r=s.parents(".remove-personal-data"),i=s.parents("tr"),t=r.data("request-id"),d=r.data("nonce"),c=r.data("erasers-count"),l=!1,u=!1,p=[];function m(){h(r,"remove-personal-data-failed"),x(i,"notice-error",f.removalError,[])}e.stopPropagation(),r.blur(),g(i),h(r,"remove-personal-data-processing"),function a(n,o){v.ajax({url:window.ajaxurl,data:{action:"wp-privacy-erase-personal-data",eraser:n,id:t,page:o,security:d},method:"post"}).done(function(e){var t=e.data;e.success?(t.items_removed&&(l=l||t.items_removed),t.items_retained&&(u=u||t.items_retained),t.messages&&(p=p.concat(t.messages)),t.done?n<c?setTimeout(a(n+1,1)):function(){var e=f.noDataFound,t="notice-success";h(r,"remove-personal-data-success"),!1===l?!1===u?e=f.noDataFound:(e=f.noneRemoved,t="notice-warning"):!1===u?e=f.foundAndRemoved:(e=f.someNotRemoved,t="notice-warning"),x(i,t,e,p),s.hide()}():setTimeout(a(n,o+1))):m()}).fail(function(){m()})}(1,1)}),v(document).on("click",function(e){var t,a,n,o=v(e.target);if(o.is("button.privacy-text-copy")&&((a=(t=o.parent().parent()).find("div.wp-suggested-text")).length||(a=t.find("div.policy-text")),a.length))try{window.getSelection().removeAllRanges(),n=document.createRange(),a.addClass("hide-privacy-policy-tutorial"),n.selectNodeContents(a[0]),window.getSelection().addRange(n),document.execCommand("copy"),a.removeClass("hide-privacy-policy-tutorial"),window.getSelection().removeAllRanges()}catch(e){}})}); jQuery(document).ready(function(u){var l=window.privacyToolsL10n||{};function p(e,t){e.children().addClass("hidden"),e.children("."+t).removeClass("hidden")}function m(e){e.removeClass("has-request-results"),e.next().hasClass("request-results")&&e.next().remove()}function v(e,t,a,s){var n="",o="request-results";m(e),s.length&&(u.each(s,function(e,t){n=n+"<li>"+t+"</li>"}),n="<ul>"+n+"</ul>"),e.addClass("has-request-results"),e.hasClass("status-request-confirmed")&&(o+=" status-request-confirmed"),e.hasClass("status-request-failed")&&(o+=" status-request-failed"),e.after(function(){return'<tr class="'+o+'"><th colspan="5"><div class="notice inline notice-alt '+t+'"><p>'+a+"</p>"+n+"</div></td></tr>"})}u(".export-personal-data-handle").click(function(e){var o=u(this),r=o.parents(".export-personal-data"),i=o.parents("tr"),s=i.find(".export-progress");function d(e){p(r,"export-personal-data-failed"),e&&v(i,"notice-error",l.exportError,[e])}function c(e){var t=0<exportersCount?e/exportersCount:0,a=Math.round(100*t).toString()+"%";s.html(a)}requestID=r.data("request-id"),nonce=r.data("nonce"),exportersCount=r.data("exporters-count"),sendAsEmail=!!r.data("send-as-email"),e.preventDefault(),e.stopPropagation(),r.blur(),m(i),c(0),p(r,"export-personal-data-processing"),function a(s,n){u.ajax({url:window.ajaxurl,data:{action:"wp-privacy-export-personal-data",exporter:s,id:requestID,page:n,security:nonce,sendAsEmail:sendAsEmail},method:"post"}).done(function(e){var t=e.data;e.success?t.done?s<exportersCount?(c(s),setTimeout(a(s+1,1))):function(e){var t=l.emailSent;p(r,"export-personal-data-success"),v(i,"notice-success",t,[]),o.hide(),void 0!==e?window.location=e:sendAsEmail||d(l.noExportFile)}(t.url):setTimeout(a(s,n+1)):d(e.data)}).fail(function(e,t,a){d(a)})}(1,1)}),u(".remove-personal-data-handle").click(function(e){var o=u(this),r=o.parents(".remove-personal-data"),i=o.parents("tr"),s=i.find(".erasure-progress");function d(){p(r,"remove-personal-data-failed"),v(i,"notice-error",l.removalError,[])}function c(e){var t=0<erasersCount?e/erasersCount:0,a=Math.round(100*t).toString()+"%";s.html(a)}requestID=r.data("request-id"),nonce=r.data("nonce"),erasersCount=r.data("erasers-count"),hasRemoved=!1,hasRetained=!1,messages=[],e.stopPropagation(),r.blur(),m(i),c(0),p(r,"remove-personal-data-processing"),function a(s,n){u.ajax({url:window.ajaxurl,data:{action:"wp-privacy-erase-personal-data",eraser:s,id:requestID,page:n,security:nonce},method:"post"}).done(function(e){var t=e.data;e.success?(t.items_removed&&(hasRemoved=hasRemoved||t.items_removed),t.items_retained&&(hasRetained=hasRetained||t.items_retained),t.messages&&(messages=messages.concat(t.messages)),t.done?s<erasersCount?(c(s),setTimeout(a(s+1,1))):function(){var e=l.noDataFound,t="notice-success";p(r,"remove-personal-data-success"),!1===hasRemoved?!1===hasRetained?e=l.noDataFound:(e=l.noneRemoved,t="notice-warning"):!1===hasRetained?e=l.foundAndRemoved:(e=l.someNotRemoved,t="notice-warning"),v(i,t,e,messages),o.hide()}():setTimeout(a(s,n+1))):d()}).fail(function(){d()})}(1,1)}),u(document).on("click",function(e){var t,a,s,n=u(e.target);if(n.is("button.privacy-text-copy")&&((a=(t=n.parent().parent()).find("div.wp-suggested-text")).length||(a=t.find("div.policy-text")),a.length))try{window.getSelection().removeAllRanges(),s=document.createRange(),a.addClass("hide-privacy-policy-tutorial"),s.selectNodeContents(a[0]),window.getSelection().addRange(s),document.execCommand("copy"),a.removeClass("hide-privacy-policy-tutorial"),window.getSelection().removeAllRanges()}catch(e){}})});

View File

@ -13,7 +13,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '5.4-alpha-47245'; $wp_version = '5.4-alpha-47246';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.