PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
tablepress / admin / js / common / ajax-request.js

ajax-request.js in TablePress – Tables in WordPress made easy 3.4, at admin/js/common/ajax-request.js

173 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * JavaScript code for AJAX requests with Notices functionality on admin screens.
3 *
4 * @package TablePress
5 * @subpackage Views JavaScript
6 * @author Tobias Bäthge
7 * @since 3.1.0
8 */
9
10 /**
11 * WordPress dependencies.
12 */
13 import {
14 Icon,
15 } from '@wordpress/components';
16 import { RawHTML } from '@wordpress/element';
17 import { __, sprintf } from '@wordpress/i18n';
18 import { buildQueryString } from '@wordpress/url';
19
20 /**
21 * Internal dependencies.
22 */
23 import { TablePressIconSimple } from '../../img/tablepress-icon';
24
25 /**
26 * Default callback for handling specifics of a successful request.
27 *
28 * @param {Object} data
29 */
30 const onSuccessfulRequestDefault = ( data ) => {
31 const actionMessages = {
32 success_save: __( 'The changes were saved successfully.', 'tablepress' ),
33 };
34
35 const notice = {
36 status: ( data.message.includes( 'error' ) ) ? 'error' : 'success',
37 content: actionMessages[ data.message ],
38 type: ( data.message.includes( 'error' ) ) ? 'notice' : 'snackbar',
39 };
40
41 return { notice };
42 };
43
44 /**
45 * Processes an AJAX request with Notices functionality.
46 *
47 * @param {Object} props Function parameters.
48 * @param {Object} props.requestData Request data.
49 * @param {Function} props.onSuccessfulRequest Callback for handling a successful save.
50 * @param {Function} props.setBusyState Callback for setting the busy state.
51 * @param {Function} props.noticeOperations Callbacks for working with notices.
52 * @param {Function} props.noticesStoreDispatch Dispatch function for notices store. (Optional, only for "success" Snackbar notices.)
53 */
54 const processAjaxRequest = ( { requestData, onSuccessfulRequest = onSuccessfulRequestDefault, setBusyState, noticeOperations, noticesStoreDispatch } ) => {
55 /**
56 * Shows a notice to the user.
57 *
58 * @param {Object} notice Notice data.
59 * @param {string} notice.status Status of the notice (error, success, warning, info).
60 * @param {string} notice.content Content of the notice.
61 */
62 const showNotice = ( { status, content } ) => {
63 const id = `notice-${ Date.now() }`;
64 content = <>
65 { /* Notices don't have a DOM ID, so add a custom span which has one, for the fade-out and removal. */ }
66 <span id={ id }></span>
67 <RawHTML>{ content }</RawHTML>
68 </>;
69 noticeOperations.createNotice( { id, status, content, isDismissible: ( 'error' === status ) } );
70
71 if ( 'error' !== status ) {
72 // Fade out non-error notices after 5 seconds and then remove them.
73 setTimeout( () => {
74 const notice = document.getElementById( id ).closest( '.components-notice' );
75 notice.addEventListener( 'transitionend', () => noticeOperations.removeNotice( id ) );
76 notice.style.opacity = 0;
77 }, 5000 );
78 } else {
79 // Scroll error notices into view.
80 setTimeout( () => {
81 const notice = document.getElementById( id ).closest( '.components-notice' );
82 if ( notice.getBoundingClientRect().bottom > ( window.innerHeight || document.documentElement.clientHeight ) ) {
83 notice.scrollIntoView( { behavior: 'smooth', block: 'end', inline: 'nearest' } );
84 }
85 }, 1 );
86 }
87 };
88
89 // Put the screen into "is busy" mode.
90 setBusyState( true );
91 document.body.classList.add( 'wait' );
92
93 // Save the table data to the server via an AJAX request.
94 fetch( ajaxurl, {
95 method: 'POST',
96 headers: {
97 'Content-Type': 'application/x-www-form-urlencoded',
98 Accept: 'application/json',
99 },
100 body: buildQueryString( requestData ),
101 } )
102 // Check for HTTP connection problems.
103 .then( ( response ) => {
104 if ( ! response.ok ) {
105 throw new Error( sprintf( __( 'There was a problem with the server, HTTP response code %1$d (%2$s).', 'tablepress' ), response.status, response.statusText ) );
106 }
107 return response.json();
108 } )
109 // Check for problems with the transmitted data.
110 .then( ( data ) => {
111 if ( 'undefined' === typeof data || null === data || '-1' === data || 'undefined' === typeof data.success ) {
112 throw new Error( __( 'The JSON data returned from the server is unclear or incomplete.', 'tablepress' ) );
113 }
114
115 if ( true !== data.success ) {
116 const debugHtml = data.error_details ? `<p>${ __( 'These errors were encountered:', 'tablepress' ) }</p><pre>${ data.error_details }</pre>` : '';
117 throw new Error( `<p>${ __( 'There was a problem with the request.', 'tablepress' ) }</p>${ debugHtml }` );
118 }
119
120 handleRequestSuccess( data );
121 } )
122 // Handle errors.
123 .catch( ( error ) => {
124 handleRequestError( error.message );
125 } )
126 // Clean up.
127 .finally( () => {
128 // Reset the screen from "is busy" mode.
129 setBusyState( false );
130 document.body.classList.remove( 'wait' );
131 } );
132
133 /**
134 * Handles a successful AJAX request.
135 *
136 * @param {Object} data Request response data.
137 */
138 const handleRequestSuccess = ( data ) => {
139 const { notice } = onSuccessfulRequest( data );
140 if ( notice ) {
141 if ( 'snackbar' === notice.type && 'undefined' !== typeof noticesStoreDispatch ) {
142 // Dispatch a Snackbar notice.
143 noticesStoreDispatch.createSuccessNotice(
144 notice.content,
145 {
146 type: 'snackbar',
147 icon: <Icon icon={ TablePressIconSimple } />,
148 }
149 );
150 } else {
151 // Show a normal notice.
152 showNotice( notice );
153 }
154 }
155 };
156
157 /**
158 * Handles an error during the AJAX request.
159 *
160 * @param {string} message Error message.
161 */
162 const handleRequestError = ( message ) => {
163 message = __( 'Attention: Unfortunately, an error occurred.', 'tablepress' ) + ' ' + message + '<br>' + sprintf( __( 'Please see the <a href="%s" target="_blank">TablePress FAQ page</a> for suggestions.', 'tablepress' ), 'https://tablepress.org/faq/common-errors/' );
164 const notice = {
165 status: 'error',
166 content: message,
167 };
168 showNotice( notice );
169 };
170 };
171
172 export default processAjaxRequest;
173