Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sections to settings #849

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 54 additions & 2 deletions assets/css/settings-styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -383,8 +383,8 @@ body.woocommerce_page_wpo_wcpdf_options_page {
padding-bottom: 0.6em;
}

#wpo-wcpdf-preview-wrapper .sidebar .form-table > tr > td,
#wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr > td {
#wpo-wcpdf-preview-wrapper .sidebar .form-table > tr:not(:last-child) > td,
#wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr:not(:last-child) > td {
padding-bottom: 2.4em;
}

Expand Down Expand Up @@ -454,6 +454,58 @@ body.woocommerce_page_wpo_wcpdf_options_page {
width: 300px !important;
}


#wpo-wcpdf-preview-wrapper .sidebar .settings_category {
margin-bottom: 1em;
}

#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2 {
border: 1px solid #ddd;
font-weight: normal;
color: #222;
font-family: serif;
font-size: 18px;
cursor: pointer;
background-color: #fafafa;
padding: 0.75em;
margin: 0;
border-radius: 3px;
position: relative;
transition: transform 0.3s;
}

#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2.active {
border-radius: 3px 3px 0 0;
}

#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2:hover {
background-color: #f3f3f3;
}

#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2 ~ .form-table {
padding: 1em !important;
border: 1px solid #dcdcdc;
margin-top: -2px;
border-radius: 0 0 3px 3px;
}

#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2::after {
content: '\f347';
font-family: 'dashicons';
font-size: 19px;
color: #82878c;
position: absolute;
right: 16px;
top: 50%;
transform: translateY(-50%);
transition: transform 0.3s;
}

#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2.active::after {
transform: translateY(-50%) rotate(180deg);
}


/* WPML */

#wpo-wcpdf-settings .form-table .ui-tabs-nav {
Expand Down
2 changes: 1 addition & 1 deletion assets/css/settings-styles.min.css

Large diffs are not rendered by default.

34 changes: 32 additions & 2 deletions assets/js/admin-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ jQuery( function( $ ) {
$( "[name='wpo_wcpdf_documents_settings_invoice[display_number]']" ).on( 'change', function( event ) {
if ( $( this ).val() == 'order_number' ) {
$( this ).closest( 'td' ).find( '.description' ).slideDown();
$( this ).closest( 'tr' ).next( 'tr' ).hide();
$( this ).closest( 'tr' ).nextAll( 'tr' ).has( 'input#next_invoice_number' ).first().hide();
} else {
$( this ).closest( 'td' ).find( '.description' ).hide();
$( this ).closest( 'tr' ).next( 'tr' ).show();
$( this ).closest( 'tr' ).nextAll( 'tr' ).has( 'input#next_invoice_number' ).first().show();
}
} ).trigger( 'change' );

Expand Down Expand Up @@ -585,4 +585,34 @@ jQuery( function( $ ) {

//----------> /Preview <----------//

function settingsAccordion() {
// Hide all the content initially except the "init"
$( '.settings_category' ).not( '#init' ).find( '.form-table' ).hide();
MohamadNateqi marked this conversation as resolved.
Show resolved Hide resolved

let state_exists = false;
// Retrieve the state from localStorage
$( '.settings_category h2' ).each( function( index ) {
const state = localStorage.getItem( 'wcpdf_accordion_state' + index );
if ( 'true' === state ) {
state_exists = true;
$( this ).addClass( 'active' ).next( '.form-table' ).show();
}
} );

// Show the first accordion by default if there's no state saved
if ( ! state_exists ) {
$( '.settings_category h2:first' ).addClass( 'active' ).next( '.form-table' ).show();
}
MohamadNateqi marked this conversation as resolved.
Show resolved Hide resolved

$('.settings_category h2' ).click( function() {
const index = $( '.settings_category h2' ).index( $( this ) );

$( this ).toggleClass( 'active' ).next( '.form-table' ).slideToggle( 'fast', function() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not work for screens sizes under 960px. At the moment we use display: block !important here:

So the section is never hidden when clicking on the section title. Also the slide animation is not working when the .form-table element is set to display: table;. Which we do when viewing the settings full screen.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Terminator-Barbapapa For the full-screen mode, where the display: table;, I think there is no easy way to fix it.

One way would be to make the display property block, then make the transition, and then revert it to table, which has other side effects and issues, such as the bad display of elements during the transition.

Another option would be to switch to height transition instead of toggling the display.

Another option would be wrapping the form-table around a DIV element and working with that, but this is not a good way as it requires many modifications.

I tried to fix it using the first option, but several issues appeared that made me think this was not a good approach.

If we're going to fix this issue for full-screen mode, then switching to height transition might be the better option here.

Would you happen to have any suggestions or opinions?

localStorage.setItem( 'wcpdf_accordion_state' + index, $( this ).is( ':visible' ) );
} );
} );
}

settingsAccordion();

} );
2 changes: 1 addition & 1 deletion assets/js/admin-script.min.js

Large diffs are not rendered by default.

182 changes: 181 additions & 1 deletion includes/class-wcpdf-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ public function __construct() {

// schedule yearly reset numbers
add_action( 'wpo_wcpdf_schedule_yearly_reset_numbers', array( $this, 'yearly_reset_numbers' ) );

// Apply settings sections.
add_action( 'wpo_wcpdf_init_documents', array( $this, 'update_documents_settings' ), 999 );
}

public function menu() {
Expand Down Expand Up @@ -476,7 +479,8 @@ public function add_settings_fields( $settings_fields, $page, $option_group, $op
$settings_field['id'],
$settings_field['title'],
$callback,
$page
$page,
$settings_field['args'] ?? array()
);
} else {
add_settings_field(
Expand Down Expand Up @@ -1005,6 +1009,182 @@ public function move_setting_after_id( $settings, $insert_settings, $after_setti
return $new_settings;
}

public function update_documents_settings(): void {
$documents = WPO_WCPDF()->documents->get_documents( 'all' );

foreach ( $documents as $document ) {
$document = str_replace( '-', '_', $document->get_type() );
add_filter( 'wpo_wcpdf_settings_fields_documents_' . $document, array( $this, 'apply_settings_categories' ), 999, 4 );
}
}

/**
* Apply settings categories to the settings fields.
*
* @param array $settings_fields
* @param string $page
* @param string $option_group
* @param string $option_name
*
* @return array
*/
public function apply_settings_categories( array $settings_fields, string $page, string $option_group, string $option_name ): array {
$document_type = explode( '_', $option_group );
$document_type = end( $document_type );
$document = wcpdf_get_document( $document_type, null );

if ( ! $document ) {
return $settings_fields;
}

$settings_categories = is_callable( array( $document, 'get_settings_categories' ) ) ? $document->get_settings_categories() : array();

// Return if no category found!
if ( empty( $settings_categories ) ) {
return $settings_fields;
}

// Remove all sections first.
foreach ( $settings_fields as $key => $field ) {
if ( 'section' === $field['type'] ) {
unset( $settings_fields[ $key ] );
}
}

$modified_settings_fields = array();
$settings_lookup = array();
$processed_keys = array();

// Create a lookup array for settings fields by id.
// This allows for quick access to settings fields by their id, reducing the time complexity
// of finding a settings field from O(n*m) to O(n+m), where n is the number of category members
// and m is the number of settings fields.
foreach ( $settings_fields as $key => $settings_field ) {
$settings_lookup[ $settings_field['id'] ] = $key;
}

// Update settings fields.
foreach ( $settings_categories as $category_name => $category_details ) {
// Add section for each category.
$modified_settings_fields[] = array(
'type' => 'section',
'id' => $category_name,
'title' => $category_details['title'],
'callback' => 'section',
'args' => array(
'before_section' => '<div class="settings_category" id="' . $category_name . '">',
'after_section' => '</div>',
),
);

// Add settings fields based on the order in the members array.
foreach ( $category_details['members'] as $member ) {
if ( isset( $settings_lookup[ $member ] ) ) {
$key = $settings_lookup[ $member ];

// Skip if the key has already been processed.
if ( in_array( $key, $processed_keys, true ) ) {
continue;
}

$settings_field = $settings_fields[ $key ];
$settings_field['section'] = $category_name;
$modified_settings_fields[] = $settings_field;
$processed_keys[] = $key;
}
}
}

// Check for any unprocessed settings fields.
$unprocessed_settings_fields = array_diff_key( $settings_fields, array_flip( $processed_keys ) );

// Create a "More" section for uncategorized settings fields.
if ( ! empty( $unprocessed_settings_fields ) ) {
$category_name = 'more';
$modified_settings_fields[] = array(
'type' => 'section',
'id' => $category_name,
'title' => __( 'More', 'woocommerce-pdf-invoices-packing-slips' ),
MohamadNateqi marked this conversation as resolved.
Show resolved Hide resolved
'callback' => 'section',
'args' => array(
'before_section' => '<div class="settings_category" id="' . $category_name . '">',
'after_section' => '</div>',
),
);

// Add rest of settings to the $modified_settings_fields array under "More" category
foreach ( $unprocessed_settings_fields as $settings_field ) {
$settings_field['section'] = $category_name;
$modified_settings_fields[] = $settings_field;
}
}

return $modified_settings_fields;
}

/**
* Helper method to add a setting field to a category.
*
* @param array $settings_categories
* @param string|array $new_setting_id
* @param string $category_name
* @param string|int|null $position
*
* @return array
*/
public function add_setting_field_to_category( array $settings_categories, $new_setting_id, string $category_name, $position = null ): array {
if ( ! isset( $settings_categories[ $category_name ] ) ) {
return $settings_categories;
}

$new_setting_ids = (array) $new_setting_id;
$members = &$settings_categories[ $category_name ]['members'];

if ( is_null( $position ) ) {
$members = array_merge( $members, $new_setting_ids );
} else {
// If it's a member name
if ( is_string( $position ) ) {
$key = array_search( $position, $members, true );

if ( false !== $key ) {
array_splice( $members, $key + 1, 0, $new_setting_id );
} else {
$members = array_merge( $members, $new_setting_ids );
}
} elseif ( is_int( $position ) ) {
// If it's a member index
array_splice( $members, $position, 0, $new_setting_id );
}
}

return $settings_categories;
}

/**
* Helper method to add a setting category.
*
* @param array $settings_categories
* @param string $category_name
* @param string $title
* @param array $members
*
* @return array
*/
public function add_settings_category( array $settings_categories, string $category_name, string $title, array $members ): array {
// Do not override if the category already exist.
if ( isset( $settings_categories[ $category_name ] ) ) {
return $settings_categories;
}

$settings_categories[ $category_name ] = array(
'title' => $title,
'members' => $members,
);

return $settings_categories;
}

}

endif; // class_exists
57 changes: 57 additions & 0 deletions includes/documents/class-wcpdf-invoice.php
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,63 @@ public function get_ubl_settings_fields( $option_name ) {
return apply_filters( "wpo_wcpdf_{$this->type}_ubl_settings_fields", $settings_fields, $option_name, $this );
}

public function get_settings_categories(): array {
$settings_categories = array(
'init' => array(
'title' => '',
'members' => array( 'enabled' ),
),
MohamadNateqi marked this conversation as resolved.
Show resolved Hide resolved
'general' => array(
'title' => __( 'General', 'woocommerce-pdf-invoices-packing-slips' ),
'members' => array(
'attach_to_email_ids',
'disable_for_statuses',
'number_format',
'my_account_buttons',
),
),
'document_display' => array(
'title' => __( 'Document display options', 'woocommerce-pdf-invoices-packing-slips' ),
'members' => array(
'display_email',
'display_phone',
'display_customer_notes',
'display_shipping_address',
'display_date',
'display_number',
'next_invoice_number' // this should follow 'display_number'
)
),
'due_date' => array(
'title' => __( 'Due date', 'woocommerce-pdf-invoices-packing-slips' ),
'members' => array(
'due_date',
)
MohamadNateqi marked this conversation as resolved.
Show resolved Hide resolved
),
'admin_display' => array(
'title' => __( 'Admin display options', 'woocommerce-pdf-invoices-packing-slips' ),
MohamadNateqi marked this conversation as resolved.
Show resolved Hide resolved
'members' => array(
'invoice_number_column',
'invoice_date_column',
'invoice_number_search',
),
),
'advanced' => array(
'title' => __( 'Advanced', 'woocommerce-pdf-invoices-packing-slips' ),
'members' => array(
'next_invoice_number',
'reset_number_yearly',
'mark_printed',
'unmark_printed',
'disable_free',
'use_latest_settings',
)
)
);

return apply_filters( "wpo_wcpdf_{$this->type}_settings_categories", $settings_categories, $this );
}

/**
* Document number title
*/
Expand Down
Loading
Loading