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
← All changes | includes/page-availability-general/_src/availability_general_page.js +534 -5 11.0 → 11.9 View file →
@@ -1,4 +1,4 @@
1 1 /**
2 2 * General Availability UI.
3 3 */
4 4 ( function ( $, w ) {
@@ -36,8 +36,105 @@
36 36 $button.attr( 'aria-expanded', is_open ? 'false' : 'true' );
37 37 $fields.prop( 'hidden', is_open ).attr( 'aria-hidden', is_open ? 'true' : 'false' );
38 38 }
39 39
40 + function close_group( $group ) {
41 + var $button = $group.find( '> .group__header' );
42 + var $fields = $group.find( '> .group__fields' );
43 +
44 + $group.removeClass( 'is-open' );
45 + $button.attr( 'aria-expanded', 'false' );
46 + $fields.prop( 'hidden', true ).attr( 'aria-hidden', 'true' );
47 + }
48 +
49 + function open_group( group_name, is_exclusive ) {
50 + var $group = $( '.wpbc_ui__collapsible_group[data-group="' + group_name + '"]' );
51 + var $button = $group.find( '> .group__header' );
52 + var $fields = $group.find( '> .group__fields' );
53 +
54 + if ( ! $group.length ) {
55 + return;
56 + }
57 +
58 + if ( is_exclusive ) {
59 + $group.siblings( '.wpbc_ui__collapsible_group' ).each( function () {
60 + close_group( $( this ) );
61 + } );
62 + }
63 +
64 + $group.addClass( 'is-open' );
65 + $button.attr( 'aria-expanded', 'true' );
66 + $fields.prop( 'hidden', false ).attr( 'aria-hidden', 'false' );
67 + }
68 +
69 + function scroll_to_group( group_name ) {
70 + var $group = $( '.wpbc_ui__collapsible_group[data-group="' + group_name + '"]' );
71 + var $scroll_parent = $();
72 + var scroll_parent_el;
73 + var group_el;
74 + var scroll_top;
75 + var parent_rect;
76 + var group_rect;
77 +
78 + if ( ! $group.length ) {
79 + return;
80 + }
81 +
82 + $group.parents().each( function () {
83 + var $candidate = $( this );
84 + var overflow_y = $candidate.css( 'overflow-y' );
85 +
86 + if (
87 + $candidate.hasClass( 'simplebar-content-wrapper' )
88 + || (
89 + /(auto|scroll)/.test( overflow_y )
90 + && this.scrollHeight > this.clientHeight
91 + )
92 + ) {
93 + $scroll_parent = $candidate;
94 + return false;
95 + }
96 + } );
97 +
98 + if ( ! $scroll_parent.length ) {
99 + $scroll_parent = $group.closest( '.wpbc_ui_el__vert_right_bar__content' ).find( '.simplebar-content-wrapper' ).first();
100 + }
101 +
102 + if ( ! $scroll_parent.length ) {
103 + $group.get( 0 ).scrollIntoView( { block: 'nearest' } );
104 + return;
105 + }
106 +
107 + scroll_parent_el = $scroll_parent.get( 0 );
108 + group_el = $group.get( 0 );
109 + parent_rect = scroll_parent_el.getBoundingClientRect();
110 + group_rect = group_el.getBoundingClientRect();
111 + scroll_top = $scroll_parent.scrollTop() + group_rect.top - parent_rect.top - 10;
112 +
113 + $scroll_parent.stop().animate( { scrollTop: Math.max( 0, scroll_top ) }, 180 );
114 + }
115 +
116 + function apply_open_section_from_url() {
117 + var section_groups = {
118 + weekdays: 'general-availability-weekdays',
119 + from_today: 'general-availability-from-today',
120 + buffer: 'general-availability-buffer',
121 + working_time: 'general-availability-working-time'
122 + };
123 + var group_name = section_groups[ cfg.open_section ] || '';
124 +
125 + if ( '' === group_name ) {
126 + return;
127 + }
128 +
129 + open_group( group_name, true );
130 + $.each( [ 120, 650 ], function ( index, delay ) {
131 + setTimeout( function () {
132 + scroll_to_group( group_name );
133 + }, delay );
134 + } );
135 + }
136 +
40 137 function refresh_buffer_fields() {
41 138 var value = $( 'input[name="booking_unavailable_extra_in_out"]:checked' ).val() || '';
42 139
43 140 $( '.wpbc_ag_buffer_fields' ).each( function () {
@@ -132,9 +229,10 @@
132 229 booking_unavailable_extra_in_out: $form.find( '[name="booking_unavailable_extra_in_out"]:checked' ).val() || '',
133 230 booking_unavailable_extra_minutes_in: $form.find( '[name="booking_unavailable_extra_minutes_in"]' ).val() || '',
134 231 booking_unavailable_extra_minutes_out: $form.find( '[name="booking_unavailable_extra_minutes_out"]' ).val() || '',
135 232 booking_unavailable_extra_days_in: $form.find( '[name="booking_unavailable_extra_days_in"]' ).val() || '',
136 - booking_unavailable_extra_days_out: $form.find( '[name="booking_unavailable_extra_days_out"]' ).val() || ''
233 + booking_unavailable_extra_days_out: $form.find( '[name="booking_unavailable_extra_days_out"]' ).val() || '',
234 + working_time: get_working_time_settings_from_form()
137 235 };
138 236 }
139 237
140 238 function set_select_value( name, value ) {
@@ -171,8 +269,9 @@
171 269 set_select_value( 'booking_unavailable_extra_days_out', settings.booking_unavailable_extra_days_out || '' );
172 270
173 271 $form.find( 'input[name="booking_unavailable_extra_in_out"]' ).prop( 'checked', false );
174 272 $form.find( 'input[name="booking_unavailable_extra_in_out"][value="' + ( settings.booking_unavailable_extra_in_out || '' ) + '"]' ).prop( 'checked', true );
273 + apply_working_time_settings_to_form( settings.working_time || {}, $( '#wpbc_ag_resource_id' ).val() );
175 274
176 275 refresh_buffer_fields();
177 276 sync_all_ranges();
178 277 schedule_preview_refresh();
@@ -272,8 +371,396 @@
272 371 }
273 372 return parseInt( value, 10 ) || 0;
274 373 }
275 374
375 + function time_to_seconds( time ) {
376 + var parts = String( time || '' ).split( ':' );
377 + var hours;
378 + var mins;
379 +
380 + if ( parts.length < 2 ) {
381 + return 0;
382 + }
383 +
384 + hours = Math.max( 0, Math.min( 24, parseInt( parts[0], 10 ) || 0 ) );
385 + mins = hours === 24 ? 0 : Math.max( 0, Math.min( 59, parseInt( parts[1], 10 ) || 0 ) );
386 +
387 + return Math.min( 86400, ( hours * 3600 ) + ( mins * 60 ) );
388 + }
389 +
390 + function seconds_to_time( seconds ) {
391 + var hours;
392 + var mins;
393 +
394 + seconds = Math.max( 0, Math.min( 86400, parseInt( seconds, 10 ) || 0 ) );
395 + hours = Math.floor( seconds / 3600 );
396 + mins = Math.floor( ( seconds % 3600 ) / 60 );
397 +
398 + return ( hours < 10 ? '0' : '' ) + hours + ':' + ( mins < 10 ? '0' : '' ) + mins;
399 + }
400 +
401 + /**
402 + * Return the bounded interval limit for one Working Time editor.
403 + *
404 + * @param {jQuery} $weekdays Working Time weekday wrapper.
405 + * @return {number} Maximum intervals per weekday.
406 + */
407 + function get_max_working_time_intervals( $weekdays ) {
408 + var configured_limit = parseInt( $weekdays.attr( 'data-max-intervals' ), 10 );
409 + var localized_limit = parseInt( cfg.max_working_time_intervals, 10 );
410 +
411 + return Math.max( 1, Math.min( 48, configured_limit || localized_limit || 8 ) );
412 + }
413 +
414 + /**
415 + * Read all visible interval controls for one weekday.
416 + *
417 + * @param {jQuery} $day_row Weekday row.
418 + * @return {Object[]} Canonical interval records.
419 + */
420 + function collect_working_time_day_intervals( $day_row ) {
421 + var intervals = [];
422 +
423 + $day_row.find( '[data-wpbc-working-time-interval="1"]' ).each( function () {
424 + var $interval = $( this );
425 +
426 + intervals.push( {
427 + start_second: time_to_seconds( $interval.find( '.wpbc_ag_working_time_start' ).val() ),
428 + end_second: time_to_seconds( $interval.find( '.wpbc_ag_working_time_end' ).val() )
429 + } );
430 + } );
431 +
432 + return intervals;
433 + }
434 +
435 + /**
436 + * Rebuild dynamic names, IDs, and label associations after a row mutation.
437 + *
438 + * @param {jQuery} $day_row Weekday row.
439 + * @return {void}
440 + */
441 + function reindex_working_time_day( $day_row ) {
442 + var $weekdays = $day_row.closest( '[data-wpbc-working-time-weekdays]' );
443 + var prefix = String( $weekdays.attr( 'data-wpbc-working-time-weekdays' ) || '' );
444 + var day = parseInt( $day_row.attr( 'data-wpbc-working-time-day' ), 10 );
445 +
446 + $day_row.find( '[data-wpbc-working-time-interval="1"]' ).each( function ( interval_index ) {
447 + var $interval = $( this );
448 + var start_id = prefix + '_start_' + day + '_' + interval_index;
449 + var end_id = prefix + '_end_' + day + '_' + interval_index;
450 + var $labels = $interval.find( 'label' );
451 +
452 + $interval.attr( 'data-interval-index', interval_index );
453 + $interval.find( '.wpbc_ag_working_time_start' )
454 + .attr( 'id', start_id )
455 + .attr( 'name', prefix + '_start[' + day + '][]' );
456 + $interval.find( '.wpbc_ag_working_time_end' )
457 + .attr( 'id', end_id )
458 + .attr( 'name', prefix + '_end[' + day + '][]' );
459 + $labels.eq( 0 ).attr( 'for', start_id );
460 + $labels.eq( 1 ).attr( 'for', end_id );
461 + } );
462 + }
463 +
464 + /**
465 + * Refresh one weekday's enabled controls and interval-limit state.
466 + *
467 + * @param {jQuery} $day_row Weekday row.
468 + * @return {void}
469 + */
470 + function refresh_working_time_day( $day_row ) {
471 + var $weekdays = $day_row.closest( '[data-wpbc-working-time-weekdays]' );
472 + var $toggle = $day_row.find( '[data-wpbc-working-time-day-toggle="1"]' ).first();
473 + var $resource_custom = $day_row.closest( '[data-wpbc-working-time-resource-custom="1"]' );
474 + var is_block_disabled = $day_row.closest( '.wpbc_ag_working_time_block' ).hasClass( 'is-disabled' )
475 + || ( $resource_custom.length && ! $resource_custom.hasClass( 'is-visible' ) );
476 + var is_day_enabled = ! is_block_disabled && $toggle.prop( 'checked' );
477 + var interval_count = $day_row.find( '[data-wpbc-working-time-interval="1"]' ).length;
478 + var max_intervals = get_max_working_time_intervals( $weekdays );
479 +
480 + $day_row.toggleClass( 'is-enabled', $toggle.prop( 'checked' ) );
481 + $toggle.prop( 'disabled', is_block_disabled );
482 + $day_row.find( '.wpbc_ag_working_time_start, .wpbc_ag_working_time_end, [data-wpbc-remove-working-time-interval]' ).prop( 'disabled', ! is_day_enabled );
483 + $day_row.find( '[data-wpbc-add-working-time-interval]' ).prop( 'disabled', ! is_day_enabled || interval_count >= max_intervals );
484 + }
485 +
486 + /**
487 + * Find a non-overlapping one-hour interval proposal.
488 + *
489 + * @param {Object[]} intervals Current weekday intervals.
490 + * @return {Object|null} Proposed interval, or null when the day has no gap.
491 + */
492 + function find_working_time_interval_proposal( intervals ) {
493 + var sorted_intervals = intervals.slice().sort( function ( first_interval, second_interval ) {
494 + return first_interval.start_second - second_interval.start_second;
495 + } );
496 + var preferred_start = sorted_intervals.length ? sorted_intervals[ sorted_intervals.length - 1 ].end_second : 9 * 3600;
497 + var candidates = [];
498 + var candidate_start;
499 +
500 + for ( candidate_start = 0; candidate_start <= 23 * 3600; candidate_start += 1800 ) {
501 + if ( candidate_start >= preferred_start ) {
502 + candidates.push( candidate_start );
503 + }
504 + }
505 + for ( candidate_start = 0; candidate_start < preferred_start && candidate_start <= 23 * 3600; candidate_start += 1800 ) {
506 + candidates.push( candidate_start );
507 + }
508 +
509 + candidate_start = null;
510 + candidates.some( function ( proposed_start ) {
511 + var proposed_end = proposed_start + 3600;
512 + var overlaps = sorted_intervals.some( function ( interval ) {
513 + return proposed_start < interval.end_second && proposed_end > interval.start_second;
514 + } );
515 +
516 + if ( proposed_end <= 86400 && ! overlaps ) {
517 + candidate_start = proposed_start;
518 + return true;
519 + }
520 + return false;
521 + } );
522 +
523 + return null === candidate_start ? null : {
524 + start_second: candidate_start,
525 + end_second: candidate_start + 3600
526 + };
527 + }
528 +
529 + /**
530 + * Append an interval by cloning the server-rendered allow-listed controls.
531 + *
532 + * @param {jQuery} $day_row Weekday row.
533 + * @param {Object} interval Canonical interval record.
534 + * @return {jQuery} Appended interval node.
535 + */
536 + function append_working_time_interval( $day_row, interval ) {
537 + var $container = $day_row.find( '[data-wpbc-working-time-intervals="1"]' ).first();
538 + var $prototype = $container.find( '[data-wpbc-working-time-interval="1"]' ).first();
539 + var $interval = $prototype.clone( false, false );
540 +
541 + $interval.find( '.wpbc_ag_working_time_start' ).val( seconds_to_time( interval.start_second ) );
542 + $interval.find( '.wpbc_ag_working_time_end' ).val( seconds_to_time( interval.end_second ) );
543 + $container.append( $interval );
544 + reindex_working_time_day( $day_row );
545 +
546 + return $interval;
547 + }
548 +
549 + /**
550 + * Add the next available one-hour interval to a weekday.
551 + *
552 + * @param {HTMLElement} button Add-interval button.
553 + * @return {void}
554 + */
555 + function add_working_time_interval( button ) {
556 + var $day_row = $( button ).closest( '[data-wpbc-working-time-day]' );
557 + var $weekdays = $day_row.closest( '[data-wpbc-working-time-weekdays]' );
558 + var intervals = collect_working_time_day_intervals( $day_row );
559 + var max_intervals = get_max_working_time_intervals( $weekdays );
560 + var proposal;
561 + var $interval;
562 +
563 + if ( intervals.length >= max_intervals ) {
564 + show_message( ( cfg.i18n && cfg.i18n.interval_limit ) || 'No additional one-hour interval is available for this weekday.', 'error', 6000 );
565 + return;
566 + }
567 +
568 + proposal = find_working_time_interval_proposal( intervals );
569 + if ( ! proposal ) {
570 + show_message( ( cfg.i18n && cfg.i18n.interval_limit ) || 'No additional one-hour interval is available for this weekday.', 'error', 6000 );
571 + return;
572 + }
573 +
574 + $interval = append_working_time_interval( $day_row, proposal );
575 + $day_row.find( '[data-wpbc-working-time-day-toggle="1"]' ).prop( 'checked', true );
576 + refresh_working_time_day( $day_row );
577 + $interval.find( '.wpbc_ag_working_time_start' ).trigger( 'focus' );
578 + schedule_preview_refresh();
579 + }
580 +
581 + /**
582 + * Remove one weekday interval, closing the weekday when it is the last one.
583 + *
584 + * Keeping one disabled interval in the DOM preserves an allow-listed control
585 + * prototype for reopening the day or adding a later interval.
586 + *
587 + * @param {HTMLElement} button Remove-interval button.
588 + * @return {void}
589 + */
590 + function remove_working_time_interval( button ) {
591 + var $button = $( button );
592 + var $day_row = $button.closest( '[data-wpbc-working-time-day]' );
593 + var $intervals = $day_row.find( '[data-wpbc-working-time-interval="1"]' );
594 + var $focus_target;
595 +
596 + if ( $intervals.length > 1 ) {
597 + $button.closest( '[data-wpbc-working-time-interval="1"]' ).remove();
598 + $focus_target = $day_row.find( '[data-wpbc-add-working-time-interval="1"]' ).first();
599 + } else {
600 + $day_row.find( '[data-wpbc-working-time-day-toggle="1"]' ).prop( 'checked', false );
601 + $focus_target = $day_row.find( '[data-wpbc-working-time-day-toggle="1"]' ).first();
602 + }
603 +
604 + reindex_working_time_day( $day_row );
605 + refresh_working_time_day( $day_row );
606 + $focus_target.trigger( 'focus' );
607 + schedule_preview_refresh();
608 + }
609 +
610 + function collect_working_time_weekdays( prefix ) {
611 + var $form = get_form();
612 + var weekdays = {};
613 +
614 + $form.find( '[data-wpbc-working-time-weekdays="' + prefix + '"] .wpbc_ag_working_time_row' ).each( function () {
615 + var $row = $( this );
616 + var day = parseInt( $row.attr( 'data-wpbc-working-time-day' ), 10 );
617 +
618 + weekdays[ day ] = [];
619 + if ( ! $row.find( '[data-wpbc-working-time-day-toggle="1"]' ).prop( 'checked' ) ) {
620 + return;
621 + }
622 +
623 + weekdays[ day ] = collect_working_time_day_intervals( $row );
624 + } );
625 +
626 + return weekdays;
627 + }
628 +
629 + function set_working_time_weekdays( prefix, weekdays ) {
630 + var $wrap = get_form().find( '[data-wpbc-working-time-weekdays="' + prefix + '"]' );
631 +
632 + $wrap.find( '.wpbc_ag_working_time_row' ).each( function () {
633 + var $row = $( this );
634 + var day = parseInt( $row.attr( 'data-wpbc-working-time-day' ), 10 );
635 + var intervals = weekdays && $.isArray( weekdays[ day ] ) ? weekdays[ day ] : [];
636 + var display_intervals = intervals.length ? intervals : [ { start_second: 32400, end_second: 64800 } ];
637 + var $container = $row.find( '[data-wpbc-working-time-intervals="1"]' ).first();
638 + var $prototype = $container.find( '[data-wpbc-working-time-interval="1"]' ).first().clone( false, false );
639 +
640 + $container.empty().append( $prototype );
641 + $prototype.find( '.wpbc_ag_working_time_start' ).val( seconds_to_time( display_intervals[0].start_second ) );
642 + $prototype.find( '.wpbc_ag_working_time_end' ).val( seconds_to_time( display_intervals[0].end_second ) );
643 + display_intervals.slice( 1 ).forEach( function ( interval ) {
644 + append_working_time_interval( $row, interval );
645 + } );
646 + $row.find( '[data-wpbc-working-time-day-toggle="1"]' ).prop( 'checked', intervals.length > 0 );
647 + reindex_working_time_day( $row );
648 + } );
649 + }
650 +
651 + function refresh_working_time_panels() {
652 + var is_enabled = get_form().find( 'input[name="booking_working_time_enabled"]' ).prop( 'checked' );
653 + var mode = get_form().find( 'input[name="booking_working_time_resource_mode"]:checked' ).val() || 'inherit';
654 + var $resource_custom = get_form().find( '[data-wpbc-working-time-resource-custom]' );
655 +
656 + $resource_custom.toggleClass( 'is-visible', mode === 'custom' );
657 +
658 + get_form()
659 + .find( '.wpbc_ag_working_time_block' )
660 + .toggleClass( 'is-disabled', ! is_enabled );
661 +
662 + get_form().find( '.wpbc_ag_working_time_block' ).each( function () {
663 + $( this ).find( 'input, select, button' ).prop( 'disabled', ! is_enabled );
664 + } );
665 + get_form().find( '[data-wpbc-working-time-day]' ).each( function () {
666 + refresh_working_time_day( $( this ) );
667 + } );
668 + }
669 +
670 + function get_working_time_settings_from_form() {
671 + var $form = get_form();
672 + var resourceId = parseInt( $form.find( '[data-wpbc-working-time-resource-id]' ).val(), 10 ) || parseInt( $( '#wpbc_ag_resource_id' ).val(), 10 ) || 0;
673 + var workingTime = $.extend( true, {}, cfg.settings && cfg.settings.working_time ? cfg.settings.working_time : ( cfg.default_settings && cfg.default_settings.working_time ? cfg.default_settings.working_time : {} ) );
674 +
675 + if ( ! workingTime.default ) {
676 + workingTime.default = {};
677 + }
678 + if ( ! workingTime.resources ) {
679 + workingTime.resources = {};
680 + }
681 +
682 + workingTime.enabled = $form.find( 'input[name="booking_working_time_enabled"]' ).prop( 'checked' ) ? 'On' : 'Off';
683 + workingTime.default.weekdays = collect_working_time_weekdays( 'booking_working_time_default' );
684 +
685 + if ( resourceId > 0 ) {
686 + workingTime.resources[ resourceId ] = {
687 + mode: $form.find( 'input[name="booking_working_time_resource_mode"]:checked' ).val() || 'inherit',
688 + weekdays: collect_working_time_weekdays( 'booking_working_time_resource' )
689 + };
690 + }
691 +
692 + return workingTime;
693 + }
694 +
695 + function apply_working_time_settings_to_form( workingTime, resourceId ) {
696 + var resourceSettings;
697 +
698 + workingTime = workingTime || {};
699 + resourceId = parseInt( resourceId, 10 ) || parseInt( $( '#wpbc_ag_resource_id' ).val(), 10 ) || 0;
700 + resourceSettings = workingTime.resources && workingTime.resources[ resourceId ] ? workingTime.resources[ resourceId ] : {
701 + mode: 'inherit',
702 + weekdays: workingTime.default && workingTime.default.weekdays ? workingTime.default.weekdays : {}
703 + };
704 +
705 + get_form().find( 'input[name="booking_working_time_enabled"]' ).prop( 'checked', workingTime.enabled === 'On' );
706 + get_form().find( '[data-wpbc-working-time-resource-id]' ).val( resourceId );
707 + set_working_time_weekdays( 'booking_working_time_default', workingTime.default && workingTime.default.weekdays ? workingTime.default.weekdays : {} );
708 + get_form().find( 'input[name="booking_working_time_resource_mode"][value="' + ( resourceSettings.mode || 'inherit' ) + '"]' ).prop( 'checked', true );
709 + set_working_time_weekdays( 'booking_working_time_resource', resourceSettings.weekdays || ( workingTime.default ? workingTime.default.weekdays : {} ) );
710 + refresh_working_time_panels();
711 + }
712 +
713 + function append_working_time_payload( payload ) {
714 + var $form = get_form();
715 + var defaultDays = [];
716 + var resourceDays = [];
717 + var defaultStart = {};
718 + var defaultEnd = {};
719 + var resourceStart = {};
720 + var resourceEnd = {};
721 +
722 + $form.find( '[data-wpbc-working-time-weekdays="booking_working_time_default"] .wpbc_ag_working_time_row' ).each( function () {
723 + var $row = $( this );
724 + var day = parseInt( $row.attr( 'data-wpbc-working-time-day' ), 10 );
725 +
726 + defaultStart[ day ] = [];
727 + defaultEnd[ day ] = [];
728 + $row.find( '[data-wpbc-working-time-interval="1"]' ).each( function () {
729 + defaultStart[ day ].push( $( this ).find( '.wpbc_ag_working_time_start' ).val() || '09:00' );
730 + defaultEnd[ day ].push( $( this ).find( '.wpbc_ag_working_time_end' ).val() || '18:00' );
731 + } );
732 + if ( $row.find( '[data-wpbc-working-time-day-toggle="1"]' ).prop( 'checked' ) ) {
733 + defaultDays.push( day );
734 + }
735 + } );
736 +
737 + $form.find( '[data-wpbc-working-time-weekdays="booking_working_time_resource"] .wpbc_ag_working_time_row' ).each( function () {
738 + var $row = $( this );
739 + var day = parseInt( $row.attr( 'data-wpbc-working-time-day' ), 10 );
740 +
741 + resourceStart[ day ] = [];
742 + resourceEnd[ day ] = [];
743 + $row.find( '[data-wpbc-working-time-interval="1"]' ).each( function () {
744 + resourceStart[ day ].push( $( this ).find( '.wpbc_ag_working_time_start' ).val() || '09:00' );
745 + resourceEnd[ day ].push( $( this ).find( '.wpbc_ag_working_time_end' ).val() || '18:00' );
746 + } );
747 + if ( $row.find( '[data-wpbc-working-time-day-toggle="1"]' ).prop( 'checked' ) ) {
748 + resourceDays.push( day );
749 + }
750 + } );
751 +
752 + payload.booking_working_time_enabled = $form.find( 'input[name="booking_working_time_enabled"]' ).prop( 'checked' ) ? 'On' : '';
753 + payload.booking_working_time_resource_id = $form.find( '[data-wpbc-working-time-resource-id]' ).val() || $( '#wpbc_ag_resource_id' ).val() || '';
754 + payload.booking_working_time_resource_mode = $form.find( 'input[name="booking_working_time_resource_mode"]:checked' ).val() || 'inherit';
755 + payload.booking_working_time_default_days = defaultDays;
756 + payload.booking_working_time_default_start = defaultStart;
757 + payload.booking_working_time_default_end = defaultEnd;
758 + payload.booking_working_time_resource_days = resourceDays;
759 + payload.booking_working_time_resource_start = resourceStart;
760 + payload.booking_working_time_resource_end = resourceEnd;
761 + }
762 +
276 763 function update_wpbc_preview_params( settings ) {
277 764 if ( ! w._wpbc || typeof w._wpbc.set_other_param !== 'function' ) {
278 765 return;
279 766 }
@@ -670,8 +1157,10 @@
670 1157 nonce: cfg.nonce || '',
671 1158 booking_unavailable_days: settings.weekdays
672 1159 } );
673 1160
1161 + append_working_time_payload( payload );
1162 +
674 1163 if ( ! cfg.ajax_url ) {
675 1164 show_message( ( cfg.i18n && cfg.i18n.save_failed ) || 'Unable to save general availability settings.', 'error', 10000 );
676 1165 return;
677 1166 }
@@ -691,14 +1180,29 @@
691 1180
692 1181 if ( response.data && response.data.settings && response.data.settings.hints ) {
693 1182 update_hints( response.data.settings.hints );
694 1183 }
1184 + if ( response.data && response.data.settings ) {
1185 + cfg.settings = response.data.settings;
1186 + if ( response.data.settings.working_time ) {
1187 + apply_working_time_settings_to_form( response.data.settings.working_time, $( '#wpbc_ag_resource_id' ).val() );
1188 + }
1189 + }
695 1190
696 1191 load_calendar_preview();
1192 + document.dispatchEvent( new CustomEvent( 'wpbc:availability-general:settings-saved', {
1193 + detail: {
1194 + settings: response.data && response.data.settings ? response.data.settings : {}
1195 + }
1196 + } ) );
697 1197 show_message( ( response.data && response.data.message ) || ( cfg.i18n && cfg.i18n.saved ) || 'General availability settings updated.', 'success', 2000 );
698 - } ).fail( function () {
699 - show_message( ( cfg.i18n && cfg.i18n.save_failed ) || 'Unable to save general availability settings.', 'error', 10000 );
700 - } ).always( function () {
1198 + } ).fail( function ( jq_xhr ) {
1199 + var response_message = jq_xhr && jq_xhr.responseJSON && jq_xhr.responseJSON.data && jq_xhr.responseJSON.data.message
1200 + ? jq_xhr.responseJSON.data.message
1201 + : '';
1202 +
1203 + show_message( response_message || ( cfg.i18n && cfg.i18n.save_failed ) || 'Unable to save general availability settings.', 'error', 10000 );
1204 + } ).always( function () {
701 1205 set_busy( $button, false );
702 1206 } );
703 1207 }
704 1208
@@ -711,9 +1215,10 @@
711 1215 booking_unavailable_extra_in_out: '',
712 1216 booking_unavailable_extra_minutes_in: '',
713 1217 booking_unavailable_extra_minutes_out: '',
714 1218 booking_unavailable_extra_days_in: '',
715 - booking_unavailable_extra_days_out: ''
1219 + booking_unavailable_extra_days_out: '',
1220 + working_time: {}
716 1221 };
717 1222
718 1223 if ( ! w.confirm( confirm_message ) ) {
719 1224 return;
@@ -756,8 +1261,14 @@
756 1261 } );
757 1262
758 1263 $( document ).on( 'change', '#wpbc_ag_resource_id, #wpbc_ag_months_count', load_calendar_preview );
759 1264
1265 + $( document ).on( 'change', '#wpbc_ag_resource_id', function () {
1266 + cfg.settings = cfg.settings || {};
1267 + cfg.settings.working_time = get_working_time_settings_from_form();
1268 + apply_working_time_settings_to_form( cfg.settings.working_time, $( this ).val() );
1269 + } );
1270 +
760 1271 $( document ).on( 'input change', '[data-wpbc-ag-range-for]', function () {
761 1272 sync_select_from_range( this );
762 1273 schedule_preview_refresh();
763 1274 } );
@@ -774,8 +1285,24 @@
774 1285 refresh_buffer_fields();
775 1286 schedule_preview_refresh();
776 1287 } );
777 1288
1289 + $( document ).on( 'change', 'input[name="booking_working_time_enabled"]', refresh_working_time_panels );
1290 +
1291 + $( document ).on( 'change', 'input[name="booking_working_time_resource_mode"]', refresh_working_time_panels );
1292 +
1293 + $( document ).on( 'change', '[data-wpbc-working-time-day-toggle="1"]', function () {
1294 + refresh_working_time_day( $( this ).closest( '[data-wpbc-working-time-day]' ) );
1295 + } );
1296 +
1297 + $( document ).on( 'click', '[data-wpbc-add-working-time-interval="1"]', function () {
1298 + add_working_time_interval( this );
1299 + } );
1300 +
1301 + $( document ).on( 'click', '[data-wpbc-remove-working-time-interval="1"]', function () {
1302 + remove_working_time_interval( this );
1303 + } );
1304 +
778 1305 $( document ).on( 'change', '[data-wpbc-ag-settings-form="1"] input, [data-wpbc-ag-settings-form="1"] select', schedule_preview_refresh );
779 1306
780 1307 $( document ).on( 'submit', '[data-wpbc-ag-settings-form="1"]', function ( event ) {
781 1308 event.preventDefault();
@@ -790,8 +1317,10 @@
790 1317 reset_settings( this );
791 1318 } );
792 1319
793 1320 $( document ).ready( function () {
1321 + apply_working_time_settings_to_form( ( cfg.settings && cfg.settings.working_time ) || ( cfg.default_settings && cfg.default_settings.working_time ) || {}, $( '#wpbc_ag_resource_id' ).val() );
1322 + apply_open_section_from_url();
794 1323 refresh_buffer_fields();
795 1324 sync_all_ranges();
796 1325 observe_calendar_changes();
797 1326 schedule_preview_refresh();