PluginProbe
Booking Calendar / 11.9
Booking Calendar v11.9
11.9 11.8.4 11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 All 205 releases
booking / includes / page-setup-wizard / step-date-time-formats / _src / step-date-time-formats.js

step-date-time-formats.js in Booking Calendar 11.9, at includes/page-setup-wizard/step-date-time-formats/_src/step-date-time-formats.js

352 lines 12.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Coordinate the explicit Local translation action on Setup Wizard Step 3.
3 *
4 * Draft date/time controls remain owned by the shared shell. This adapter only
5 * runs after an explicit button click and sends no locale or package URL; the
6 * server derives the current site language and owns the installation target.
7 *
8 * @package Booking Calendar
9 */
10 ( function ( $, window, document ) {
11 'use strict';
12
13 var module_config = window.wpbc_setup_wizard_date_time_formats || { i18n: {} };
14 var request_sequence = 0;
15
16 /**
17 * Extract a safe message from a failed WordPress AJAX response.
18 *
19 * @param {Object} xhr jQuery request object.
20 * @param {Object} adapter_config Module configuration.
21 * @return {string} Human-readable error message.
22 */
23 function get_error_message( xhr, adapter_config ) {
24 if ( xhr && xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message ) {
25 return String( xhr.responseJSON.data.message );
26 }
27
28 return adapter_config.i18n.error || '';
29 }
30
31 /**
32 * Extract authorized operation-console records from an AJAX payload.
33 *
34 * @param {Object} payload WordPress AJAX response data.
35 * @return {Array} Safe console records.
36 */
37 function get_operation_logs( payload ) {
38 if ( ! payload || ! Array.isArray( payload.logs ) ) {
39 return [];
40 }
41
42 return payload.logs.filter( function ( log_entry ) {
43 return log_entry && 'string' === typeof log_entry.message;
44 } );
45 }
46
47 /**
48 * Append one operation record using text-only DOM output.
49 *
50 * @param {HTMLElement} log_container Console list element.
51 * @param {string} level Authorized severity.
52 * @param {string} message Human-readable operation message.
53 * @return {void}
54 */
55 function append_operation_log( log_container, level, message ) {
56 var allowed_levels = [ 'info', 'success', 'warning', 'error' ];
57 var log_entry;
58
59 if ( ! log_container || ! message ) {
60 return;
61 }
62
63 level = -1 !== allowed_levels.indexOf( level ) ? level : 'info';
64 log_entry = document.createElement( 'li' );
65 log_entry.className = 'wpbc_setup_wizard__translation-console-entry is-' + level;
66 log_entry.textContent = String( message );
67 log_container.appendChild( log_entry );
68 }
69
70 /**
71 * Replace the console list with server-authorized operation records.
72 *
73 * @param {HTMLElement} log_container Console list element.
74 * @param {Array} operation_logs Authorized console records.
75 * @return {void}
76 */
77 function render_operation_logs( log_container, operation_logs ) {
78 if ( ! log_container ) {
79 return;
80 }
81
82 log_container.textContent = '';
83 operation_logs.forEach( function ( log_entry ) {
84 append_operation_log( log_container, String( log_entry.level || 'info' ), String( log_entry.message || '' ) );
85 } );
86 }
87
88 /**
89 * Refresh the server-authoritative language and translation-source display.
90 *
91 * @param {HTMLElement} editor Step editor root.
92 * @param {Object} language_context Authorized language response.
93 * @return {void}
94 */
95 function update_language_context( editor, language_context ) {
96 var allowed_statuses = [ 'active', 'available', 'builtin', 'unavailable' ];
97 var action_label = editor.querySelector( '[data-wpbc-install-local-translation-label]' );
98 var action_button = editor.querySelector( '[data-wpbc-install-local-translation]' );
99 var help = editor.querySelector( '[data-wpbc-local-translation-help]' );
100 var local_source_recommendation = editor.querySelector( '[data-wpbc-local-source-recommendation]' );
101 var source = editor.querySelector( '[data-wpbc-local-translation-source]' );
102 var source_label = editor.querySelector( '[data-wpbc-local-translation-source-label]' );
103 var status = editor.querySelector( '[data-wpbc-local-translation-status]' );
104 var updated = editor.querySelector( '[data-wpbc-local-translation-updated]' );
105 var recommendation = editor.querySelector( '[data-wpbc-local-translation-recommendation]' );
106 var status_key;
107
108 if ( ! language_context ) {
109 return;
110 }
111
112 status_key = -1 !== allowed_statuses.indexOf( language_context.status ) ? language_context.status : 'unavailable';
113 if ( status ) {
114 status.className = 'wpbc_setup_wizard__language-status wpbc_setup_wizard__language-status--' + status_key;
115 status.textContent = String( language_context.status_label || '' );
116 }
117 if ( help ) {
118 help.textContent = String( language_context.help || '' );
119 }
120 if ( source ) {
121 source.setAttribute( 'data-wpbc-local-translation-source', String( language_context.translation_source || '' ) );
122 }
123 if ( source_label ) {
124 source_label.textContent = String( language_context.translation_source_label || '' );
125 }
126 if ( action_label ) {
127 action_label.textContent = String( language_context.action_label || action_label.textContent );
128 }
129 if ( action_button ) {
130 action_button.classList.toggle( 'wpbc_setup_wizard__translation-action--recommended', Boolean( language_context.is_local_source_recommended ) );
131 }
132 if ( local_source_recommendation ) {
133 local_source_recommendation.textContent = String( language_context.local_source_recommendation || '' );
134 local_source_recommendation.hidden = ! language_context.is_local_source_recommended || ! language_context.local_source_recommendation;
135 }
136 if ( updated ) {
137 updated.textContent = String( language_context.updated_label || '' );
138 updated.hidden = ! language_context.updated_label;
139 }
140 if ( recommendation ) {
141 recommendation.textContent = String( language_context.update_recommendation || '' );
142 recommendation.hidden = ! language_context.is_update_recommended || ! language_context.update_recommendation;
143 }
144 }
145
146 /**
147 * Create the shell adapter for the Step 3 explicit action.
148 *
149 * @param {Object} adapter_config Localized module configuration.
150 * @return {Object} Shared shell adapter.
151 */
152 function create_date_time_formats_adapter( adapter_config ) {
153 var services = null;
154 var root = null;
155 var editor = null;
156 adapter_config = adapter_config || { i18n: {} };
157 adapter_config.i18n = adapter_config.i18n || {};
158
159 return {
160 /**
161 * Bind the Local translation action when it is authorized and rendered.
162 *
163 * @param {Object} shell_services Domain-neutral shell services.
164 * @return {void}
165 */
166 initialize: function ( shell_services ) {
167 services = shell_services;
168 root = shell_services.root;
169 editor = root.querySelector( '[data-wpbc-date-time-formats-editor]' );
170
171 if ( ! editor ) {
172 return;
173 }
174
175 editor.addEventListener( 'click', function ( event ) {
176 var install_button = event.target.closest( '[data-wpbc-install-local-translation]' );
177 var feedback;
178 var operation_console;
179 var console_log;
180 var console_state;
181 var source;
182 var source_label;
183 var previous_source;
184 var previous_source_label;
185 var reload_pending = false;
186 var sequence;
187 var request_id;
188 var request;
189
190 if ( ! install_button ) {
191 return;
192 }
193
194 event.preventDefault();
195 feedback = editor.querySelector( '[data-wpbc-local-translation-feedback]' );
196 operation_console = editor.querySelector( '[data-wpbc-local-translation-console]' );
197 console_log = editor.querySelector( '[data-wpbc-local-translation-console-log]' );
198 console_state = editor.querySelector( '[data-wpbc-local-translation-console-state]' );
199 source = editor.querySelector( '[data-wpbc-local-translation-source]' );
200 source_label = editor.querySelector( '[data-wpbc-local-translation-source-label]' );
201 previous_source = source ? source.getAttribute( 'data-wpbc-local-translation-source' ) : '';
202 previous_source_label = source_label ? source_label.textContent : '';
203 request_sequence += 1;
204 sequence = request_sequence;
205 request_id = 'translation_' + Date.now() + '_' + sequence;
206
207 if ( feedback ) {
208 feedback.classList.remove( 'is-error', 'is-success' );
209 feedback.textContent = '';
210 }
211 if ( operation_console ) {
212 operation_console.hidden = false;
213 operation_console.setAttribute( 'aria-busy', 'true' );
214 if ( 'function' === typeof operation_console.scrollIntoView ) {
215 operation_console.scrollIntoView( { block: 'nearest' } );
216 }
217 }
218 if ( console_state ) {
219 console_state.textContent = adapter_config.i18n.working || '';
220 }
221 if ( console_log ) {
222 console_log.textContent = '';
223 append_operation_log( console_log, 'info', adapter_config.i18n.connecting || adapter_config.i18n.working || '' );
224 append_operation_log( console_log, 'info', adapter_config.i18n.working || '' );
225 }
226 if ( source ) {
227 source.setAttribute( 'data-wpbc-local-translation-source', 'wpbc' );
228 }
229 if ( source_label ) {
230 source_label.textContent = adapter_config.i18n.local_source_label || previous_source_label;
231 }
232
233 install_button.disabled = true;
234 services.set_status( adapter_config.i18n.working || '' );
235 request = $.ajax( {
236 url: adapter_config.ajax_url,
237 method: 'POST',
238 dataType: 'json',
239 data: {
240 action: adapter_config.action,
241 nonce: adapter_config.nonce,
242 request_id: request_id
243 }
244 } );
245
246 request.done( function ( response ) {
247 var operation_logs;
248
249 if ( sequence !== request_sequence || ! response || ! response.success || ! response.data || response.data.request_id !== request_id ) {
250 return;
251 }
252
253 operation_logs = get_operation_logs( response.data );
254 render_operation_logs( console_log, operation_logs );
255 if ( console_state ) {
256 console_state.textContent = adapter_config.i18n.complete || '';
257 }
258
259 if ( feedback ) {
260 feedback.classList.add( 'is-success' );
261 feedback.textContent = String( response.data.message || '' );
262 }
263
264 update_language_context( editor, response.data.language );
265
266 services.set_status( String( response.data.message || '' ) );
267 if ( true === response.data.reload_page ) {
268 reload_pending = true;
269 if ( console_state ) {
270 console_state.textContent = adapter_config.i18n.reloading || adapter_config.i18n.complete || '';
271 }
272 window.setTimeout( function () {
273 window.location.reload();
274 }, 250 );
275 }
276 } );
277
278 request.fail( function ( xhr ) {
279 var message;
280 var response_data;
281 var operation_logs;
282
283 if ( sequence !== request_sequence ) {
284 return;
285 }
286
287 message = get_error_message( xhr, adapter_config );
288 response_data = xhr && xhr.responseJSON ? xhr.responseJSON.data : null;
289 operation_logs = get_operation_logs( response_data );
290 if ( response_data && response_data.language ) {
291 update_language_context( editor, response_data.language );
292 } else {
293 if ( source ) {
294 source.setAttribute( 'data-wpbc-local-translation-source', previous_source || '' );
295 }
296 if ( source_label ) {
297 source_label.textContent = previous_source_label || '';
298 }
299 }
300 render_operation_logs( console_log, operation_logs );
301 if ( 0 === operation_logs.length ) {
302 append_operation_log( console_log, 'error', message );
303 }
304 if ( console_state ) {
305 console_state.textContent = adapter_config.i18n.failed || '';
306 }
307 if ( feedback ) {
308 feedback.classList.add( 'is-error' );
309 feedback.textContent = message;
310 }
311 services.set_status( message );
312 } );
313
314 request.always( function () {
315 if ( sequence === request_sequence && ! reload_pending ) {
316 install_button.disabled = false;
317 if ( operation_console ) {
318 operation_console.setAttribute( 'aria-busy', 'false' );
319 }
320 }
321 } );
322 } );
323 },
324
325 /**
326 * Step 3 native controls need no draft synchronization.
327 *
328 * @return {void}
329 */
330 sync: function () {},
331
332 /**
333 * Server and native required-select validation remain authoritative.
334 *
335 * @return {null} No module-specific invalid control.
336 */
337 validate: function () {
338 return null;
339 }
340 };
341 }
342
343 window.wpbc_setup_editor_modules = window.wpbc_setup_editor_modules || {};
344 window.wpbc_setup_editor_modules.date_time_formats = {
345 create: create_date_time_formats_adapter
346 };
347
348 if ( window.wpbc_setup_wizard_api && 'function' === typeof window.wpbc_setup_wizard_api.register_step_adapter ) {
349 window.wpbc_setup_wizard_api.register_step_adapter( create_date_time_formats_adapter( module_config ) );
350 }
351 }( jQuery, window, document ) );
352