Plugin Directory

Changeset 3469054


Ignore:
Timestamp:
02/25/2026 05:30:42 AM (5 weeks ago)
Author:
fernandopimenta
Message:

Release v2.0.2 - Preset UX improvements, settings save fix

Location:
pap-afiliados-pro/trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • pap-afiliados-pro/trunk/assets/css/papafpro-template-builder.css

    r3468187 r3469054  
    229229}
    230230
     231/* =============================================
     232   Preset List Table
     233   ============================================= */
     234
    231235.papafpro-preset-list {
    232     list-style: none;
    233     padding: 0;
    234     margin: 0;
    235 }
    236 
    237 .papafpro-preset-item {
    238     display: flex;
    239     justify-content: space-between;
    240     align-items: center;
     236    border-collapse: collapse;
     237    width: 100%;
     238    margin-top: 8px;
     239}
     240
     241/* ----- Header ----- */
     242
     243.papafpro-preset-list thead th {
     244    background-color: #f1f1f1;
     245    border-bottom: 2px solid #ddd;
     246    font-weight: 600;
     247    font-size: 12px;
     248    color: #555;
     249    text-transform: uppercase;
     250    letter-spacing: 0.5px;
     251    padding: 8px 12px;
     252    text-align: left;
     253}
     254
     255.papafpro-preset-list thead th.papafpro-col-check {
     256    width: 30px;
     257    padding: 8px;
     258    text-align: center;
     259}
     260
     261.papafpro-preset-list thead th.papafpro-col-id {
     262    width: 60px;
     263    text-align: center;
     264}
     265
     266.papafpro-preset-list thead th.papafpro-col-actions {
     267    width: 220px;
     268    text-align: center;
     269}
     270
     271/* ----- Body rows ----- */
     272
     273.papafpro-preset-list tbody td {
    241274    padding: 8px 12px;
    242275    border-bottom: 1px solid #eee;
    243 }
    244 
    245 .papafpro-preset-item:hover {
    246     background: #f5f5f5;
    247 }
    248 
    249 .papafpro-preset-item label {
    250     display: flex;
    251     align-items: center;
    252     gap: 8px;
    253     cursor: pointer;
    254 }
     276    vertical-align: middle;
     277}
     278
     279.papafpro-preset-list tbody td.papafpro-col-check {
     280    width: 30px;
     281    padding: 8px;
     282    text-align: center;
     283}
     284
     285.papafpro-preset-list tbody td.papafpro-col-id {
     286    text-align: center;
     287}
     288
     289.papafpro-preset-list tbody td.papafpro-col-actions {
     290    text-align: center;
     291}
     292
     293/* ----- Zebra striping ----- */
     294
     295.papafpro-preset-list tbody tr:nth-child(even) {
     296    background-color: #f9f9f9;
     297}
     298
     299/* ----- Hover ----- */
     300
     301.papafpro-preset-list tbody tr:hover {
     302    background-color: #e8f4fd;
     303}
     304
     305/* ----- Name column ----- */
     306
     307.papafpro-preset-list td.papafpro-col-name label {
     308    display: block;
     309    cursor: default;
     310    overflow: hidden;
     311    text-overflow: ellipsis;
     312    white-space: nowrap;
     313    max-width: 400px;
     314}
     315
     316/* ----- ID badge ----- */
     317
     318.papafpro-preset-id {
     319    display: inline-block;
     320    font-size: 11px;
     321    color: #888;
     322    background: #f0f0f0;
     323    padding: 2px 6px;
     324    border-radius: 3px;
     325    font-family: monospace;
     326    white-space: nowrap;
     327    cursor: default;
     328}
     329
     330/* ----- Action buttons ----- */
    255331
    256332.papafpro-preset-actions {
    257333    display: flex;
    258     gap: 8px;
     334    gap: 6px;
     335    justify-content: center;
    259336}
    260337
  • pap-afiliados-pro/trunk/assets/js/papafpro-settings.js

    r3468187 r3469054  
    3535                    action: 'papafpro_save_settings',
    3636                    nonce: papafproTemplateBuilder.nonce,
    37                     keep_data_on_uninstall: $keepData.is( ':checked' ) ? 1 : 0
     37                    settings: {
     38                        keep_data_on_uninstall: $keepData.is( ':checked' ) ? 1 : 0
     39                    }
    3840                },
    3941                success: function( response ) {
  • pap-afiliados-pro/trunk/assets/js/papafpro-template-builder.js

    r3468187 r3469054  
    475475     */
    476476    function renderPresetList( presets ) {
    477         var $list = $( '.papafpro-preset-list' );
    478         $list.empty();
    479 
     477        var $table = $( '.papafpro-preset-list' );
     478        var $thead = $table.find( 'thead' );
     479        var $tbody = $table.find( 'tbody' );
     480
     481        $thead.empty();
     482        $tbody.empty();
     483
     484        // Empty state.
    480485        if ( ! presets.length ) {
    481             $list.append( '<li class="papafpro-preset-item"><em>Nenhum preset salvo.</em></li>' );
     486            $thead.append(
     487                '<tr><th colspan="4"><em>Nenhum preset salvo.</em></th></tr>'
     488            );
    482489            return;
    483490        }
    484491
     492        // Header row.
     493        var headerHtml = '<tr class="papafpro-preset-header">' +
     494            '<th class="papafpro-col-check">&nbsp;</th>' +
     495            '<th class="papafpro-col-name">Name</th>' +
     496            '<th class="papafpro-col-id">ID</th>' +
     497            '<th class="papafpro-col-actions">Actions</th>' +
     498            '</tr>';
     499        $thead.append( headerHtml );
     500
     501        // Data rows.
    485502        $.each( presets, function( i, preset ) {
    486             var $item = $( '<li>' ).addClass( 'papafpro-preset-item' );
    487             var $label = $( '<label>' )
    488                 .append( $( '<input>' ).attr({ type: 'checkbox', value: preset.id }).addClass( 'papafpro-preset-checkbox' ) )
     503            var $row = $( '<tr>' ).addClass( 'papafpro-preset-item' );
     504
     505            // Column 1: Checkbox.
     506            var $cellCheck = $( '<td>' ).addClass( 'papafpro-col-check' );
     507            var $checkbox = $( '<input>' )
     508                .attr({ type: 'checkbox', value: preset.id })
     509                .addClass( 'papafpro-preset-checkbox' );
     510            $cellCheck.append( $checkbox );
     511
     512            // Column 2: Name.
     513            var $cellName = $( '<td>' ).addClass( 'papafpro-col-name' );
     514            var $nameLabel = $( '<label>' )
    489515                .append( document.createTextNode( preset.name ) );
    490 
     516            $cellName.append( $nameLabel );
     517
     518            // Column 3: ID badge.
     519            var $cellId = $( '<td>' ).addClass( 'papafpro-col-id' );
     520            var $idBadge = $( '<span>' )
     521                .addClass( 'papafpro-preset-id' )
     522                .attr( 'title', 'preset_id="' + preset.id + '"' )
     523                .text( '#' + preset.id );
     524            $cellId.append( $idBadge );
     525
     526            // Column 4: Actions.
     527            var $cellActions = $( '<td>' ).addClass( 'papafpro-col-actions' );
    491528            var $actions = $( '<div>' ).addClass( 'papafpro-preset-actions' )
    492529                .append(
    493                     $( '<button>' )
    494                         .addClass( 'button papafpro-preset-load' )
    495                         .attr( 'data-id', preset.id )
    496                         .text( 'Carregar' )
     530                    $( '<button>' ).addClass( 'button papafpro-preset-load' )
     531                        .attr( 'data-id', preset.id ).text( 'Carregar' )
    497532                )
    498533                .append(
    499                     $( '<button>' )
    500                         .addClass( 'button papafpro-preset-preview' )
    501                         .attr( 'data-id', preset.id )
    502                         .text( 'Preview' )
     534                    $( '<button>' ).addClass( 'button papafpro-preset-preview' )
     535                        .attr( 'data-id', preset.id ).text( 'Preview' )
    503536                )
    504537                .append(
    505                     $( '<button>' )
    506                         .addClass( 'button papafpro-preset-delete' )
    507                         .attr( 'data-id', preset.id )
    508                         .text( 'Excluir' )
     538                    $( '<button>' ).addClass( 'button papafpro-preset-delete' )
     539                        .attr( 'data-id', preset.id ).text( 'Excluir' )
    509540                );
    510 
    511             $item.append( $label ).append( $actions );
    512             $list.append( $item );
     541            $cellActions.append( $actions );
     542
     543            $row.append( $cellCheck ).append( $cellName )
     544                .append( $cellId ).append( $cellActions );
     545            $tbody.append( $row );
    513546        });
    514547    }
  • pap-afiliados-pro/trunk/includes/class-papafpro-help-page.php

    r3468187 r3469054  
    188188                        'type'        => 'preset',
    189189                        'required'    => false,
    190                         'description' => __( 'Appearance preset ID', 'pap-afiliados-pro' ),
     190                        'description' => __( 'Preset ID or name', 'pap-afiliados-pro' ),
    191191                    ),
    192192                ),
     
    214214                        'type'        => 'preset',
    215215                        'required'    => false,
    216                         'description' => __( 'Preset ID', 'pap-afiliados-pro' ),
     216                        'description' => __( 'Preset ID or name', 'pap-afiliados-pro' ),
    217217                    ),
    218218                ),
     
    246246                        'type'        => 'preset',
    247247                        'required'    => false,
    248                         'description' => __( 'Preset ID', 'pap-afiliados-pro' ),
     248                        'description' => __( 'Preset ID or name', 'pap-afiliados-pro' ),
    249249                    ),
    250250                ),
     
    272272                        'type'        => 'preset',
    273273                        'required'    => false,
    274                         'description' => __( 'Preset ID', 'pap-afiliados-pro' ),
     274                        'description' => __( 'Preset ID or name', 'pap-afiliados-pro' ),
    275275                    ),
    276276                ),
     
    286286                        'type'        => 'preset',
    287287                        'required'    => true,
    288                         'description' => __( 'Preset ID', 'pap-afiliados-pro' ),
     288                        'description' => __( 'Preset ID or name', 'pap-afiliados-pro' ),
    289289                    ),
    290290                    array(
  • pap-afiliados-pro/trunk/includes/class-papafpro-shortcodes.php

    r3468187 r3469054  
    159159
    160160    /**
    161      * Load preset settings by ID, falling back to global settings.
     161     * Load preset settings by ID or name, falling back to global settings.
    162162     *
    163163     * @since  2.0.0
    164164     * @access private
    165      * @param  int $preset_id Preset ID (0 = global settings).
     165     * @param  mixed $preset_id Preset ID or name (0 = global settings).
    166166     * @return array Settings array merged with defaults.
    167167     */
    168168    private function get_preset_settings( $preset_id ) {
    169         $preset_id = absint( $preset_id );
     169        $preset_id = $this->resolve_preset_id( $preset_id );
    170170        $defaults  = get_option( 'papafpro_settings', array() );
    171171
     
    209209
    210210    /**
     211     * Resolve preset identifier to numeric ID.
     212     *
     213     * Accepts a numeric ID (passthrough) or a preset name (database lookup).
     214     * Used by get_preset_settings() to support both preset_id="3" and
     215     * preset_id="Tema Azul" in shortcodes.
     216     *
     217     * @since  2.0.2
     218     * @access private
     219     * @param  mixed $preset_id Numeric ID or preset name string.
     220     * @return int Resolved preset ID. Returns 0 if not found or invalid.
     221     */
     222    private function resolve_preset_id( $preset_id ) {
     223        // Numeric ID — passthrough.
     224        if ( is_numeric( $preset_id ) ) {
     225            return absint( $preset_id );
     226        }
     227
     228        // Empty or non-string — return 0 (global settings).
     229        if ( empty( $preset_id ) || ! is_string( $preset_id ) ) {
     230            return 0;
     231        }
     232
     233        // Name lookup with cache.
     234        $sanitized_name = sanitize_text_field( $preset_id );
     235        $cache_key      = 'papafpro_preset_name_' . md5( $sanitized_name );
     236        $cached         = wp_cache_get( $cache_key, 'papafpro' );
     237
     238        if ( false !== $cached ) {
     239            return absint( $cached );
     240        }
     241
     242        global $wpdb;
     243        $table_name = $wpdb->prefix . 'papafpro_presets';
     244
     245        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Custom table, no WP API available.
     246        $result = $wpdb->get_var(
     247            $wpdb->prepare(
     248                'SELECT id FROM %i WHERE name = %s LIMIT 1',
     249                $table_name,
     250                $sanitized_name
     251            )
     252        );
     253
     254        $resolved_id = $result ? absint( $result ) : 0;
     255        wp_cache_set( $cache_key, $resolved_id, 'papafpro' );
     256
     257        return $resolved_id;
     258    }
     259
     260    /**
    211261     * Render single product shortcode.
    212262     *
     
    227277        );
    228278
    229         $id        = absint( $atts['id'] );
    230         $preset_id = absint( $atts['preset_id'] );
     279        $id = absint( $atts['id'] );
    231280
    232281        if ( 0 === $id ) {
     
    239288        }
    240289
    241         $settings = $this->get_preset_settings( $preset_id );
     290        $settings = $this->get_preset_settings( $atts['preset_id'] );
    242291
    243292        $this->enqueue_frontend_assets();
     
    283332        $limite       = min( max( absint( $atts['limite'] ), 1 ), 100 );
    284333        $colunas      = absint( $atts['colunas'] );
    285         $preset_id    = absint( $atts['preset_id'] );
    286334
    287335        // Whitelist tag_relation.
     
    290338        }
    291339
    292         $settings = $this->get_preset_settings( $preset_id );
     340        $settings = $this->get_preset_settings( $atts['preset_id'] );
    293341
    294342        // Resolve columns: shortcode attr > global setting > fallback 3.
     
    375423        $ordem        = strtoupper( sanitize_text_field( wp_unslash( $atts['ordem'] ) ) );
    376424        $colunas      = absint( $atts['colunas'] );
    377         $preset_id    = absint( $atts['preset_id'] );
    378425
    379426        // Categoria is required.
     
    395442        }
    396443
    397         $settings = $this->get_preset_settings( $preset_id );
     444        $settings = $this->get_preset_settings( $atts['preset_id'] );
    398445
    399446        // Resolve columns: shortcode attr > global setting > fallback 3.
     
    461508        $limite       = min( max( absint( $atts['limite'] ), 1 ), 100 );
    462509        $colunas      = absint( $atts['colunas'] );
    463         $preset_id    = absint( $atts['preset_id'] );
    464510
    465511        // Whitelist tag_relation.
     
    468514        }
    469515
    470         $settings = $this->get_preset_settings( $preset_id );
     516        $settings = $this->get_preset_settings( $atts['preset_id'] );
    471517
    472518        // Resolve columns: shortcode attr > global setting > fallback 3.
     
    535581
    536582        // Sanitize.
    537         $preset_id    = absint( $atts['id'] );
     583        $preset_id    = $this->resolve_preset_id( $atts['id'] );
    538584        $ids_raw      = sanitize_text_field( wp_unslash( $atts['ids'] ) );
    539585        $tag          = sanitize_text_field( wp_unslash( $atts['tag'] ) );
  • pap-afiliados-pro/trunk/languages/pap-afiliados-pro-pt_BR.po

    r3468187 r3469054  
    814814
    815815#: includes/class-papafpro-help-pagephp:190
    816 msgid "Appearance preset ID"
    817 msgstr "ID do preset de aparência"
    818 
    819 #: includes/class-papafpro-help-pagephp:197
    820 msgid "Multiple Products"
    821 msgstr "Múltiplos Produtos"
    822 
    823 #: includes/class-papafpro-help-pagephp:198
    824 msgid "Displays multiple product cards in a grid."
    825 msgstr "Exibe múltiplos cards de produto em grid."
    826 
    827 #: includes/class-papafpro-help-pagephp:204
    828 msgid "Comma-separated IDs"
    829 msgstr "IDs separados por vírgula"
    830 
    831 #: includes/class-papafpro-help-pagephp:210
    832 msgid "Number of columns (1-6)"
    833 msgstr "Número de colunas (1-6)"
    834 
    835816#: includes/class-papafpro-help-pagephp:216
    836817#: includes/class-papafpro-help-pagephp:248
    837818#: includes/class-papafpro-help-pagephp:274
    838819#: includes/class-papafpro-help-pagephp:288
    839 msgid "Preset ID"
    840 msgstr "ID do preset"
     820msgid "Preset ID or name"
     821msgstr "ID ou nome do preset"
     822
     823#: includes/class-papafpro-help-pagephp:197
     824msgid "Multiple Products"
     825msgstr "Múltiplos Produtos"
     826
     827#: includes/class-papafpro-help-pagephp:198
     828msgid "Displays multiple product cards in a grid."
     829msgstr "Exibe múltiplos cards de produto em grid."
     830
     831#: includes/class-papafpro-help-pagephp:204
     832msgid "Comma-separated IDs"
     833msgstr "IDs separados por vírgula"
     834
     835#: includes/class-papafpro-help-pagephp:210
     836msgid "Number of columns (1-6)"
     837msgstr "Número de colunas (1-6)"
    841838
    842839#: includes/class-papafpro-help-pagephp:223
  • pap-afiliados-pro/trunk/languages/pap-afiliados-pro.pot

    r3468187 r3469054  
    810810
    811811#: includes/class-papafpro-help-pagephp:190
    812 msgid "Appearance preset ID"
    813 msgstr ""
    814 
    815 #: includes/class-papafpro-help-pagephp:197
    816 msgid "Multiple Products"
    817 msgstr ""
    818 
    819 #: includes/class-papafpro-help-pagephp:198
    820 msgid "Displays multiple product cards in a grid."
    821 msgstr ""
    822 
    823 #: includes/class-papafpro-help-pagephp:204
    824 msgid "Comma-separated IDs"
    825 msgstr ""
    826 
    827 #: includes/class-papafpro-help-pagephp:210
    828 msgid "Number of columns (1-6)"
    829 msgstr ""
    830 
    831812#: includes/class-papafpro-help-pagephp:216
    832813#: includes/class-papafpro-help-pagephp:248
    833814#: includes/class-papafpro-help-pagephp:274
    834815#: includes/class-papafpro-help-pagephp:288
    835 msgid "Preset ID"
     816msgid "Preset ID or name"
     817msgstr ""
     818
     819#: includes/class-papafpro-help-pagephp:197
     820msgid "Multiple Products"
     821msgstr ""
     822
     823#: includes/class-papafpro-help-pagephp:198
     824msgid "Displays multiple product cards in a grid."
     825msgstr ""
     826
     827#: includes/class-papafpro-help-pagephp:204
     828msgid "Comma-separated IDs"
     829msgstr ""
     830
     831#: includes/class-papafpro-help-pagephp:210
     832msgid "Number of columns (1-6)"
    836833msgstr ""
    837834
  • pap-afiliados-pro/trunk/pap-afiliados-pro.php

    r3468187 r3469054  
    44 * Plugin URI:        https://pap-afiliados-pro.com.br
    55 * Description:       Professional affiliate link management for Brazilian marketplaces (Amazon, Mercado Livre, Shopee, AliExpress, and others).
    6  * Version:           2.0.1
     6 * Version:           2.0.2
    77 * Requires at least: 6.2
    88 * Requires PHP:      7.4
     
    2424 * Constantes do plugin.
    2525 */
    26 define( 'PAPAFPRO_VERSION', '2.0.1' );
     26define( 'PAPAFPRO_VERSION', '2.0.2' );
    2727define( 'PAPAFPRO_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
    2828define( 'PAPAFPRO_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
  • pap-afiliados-pro/trunk/readme.txt

    r3468187 r3469054  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 2.0.1
     7Stable tag: 2.0.2
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    131131== Changelog ==
    132132
     133= 2.0.2 =
     134* Added: Preset ID column in Template Builder preset list
     135* Added: Shortcodes now accept preset name in addition to numeric ID (e.g., preset_id="My Theme")
     136* Improved: Preset list migrated to native table layout for better alignment
     137* Improved: Zebra striping in preset list for better readability
     138* Fixed: Settings page save not working correctly
     139
    133140= 2.0.1 =
    134141* Fixed: Preset system now correctly applies individual visual configurations per shortcode
     
    164171== Upgrade Notice ==
    165172
     173= 2.0.2 =
     174Preset UX improvements: ID column, name-based lookup in shortcodes, native table layout.
     175
    166176= 2.0.1 =
    167177Bug fixes for preset system, shortcode generator, and click tracking. Block API updated for WordPress 7.0 compatibility.
  • pap-afiliados-pro/trunk/views/papafpro-template-builder.php

    r3468187 r3469054  
    368368                </div>
    369369                <h3><?php esc_html_e( 'Saved Presets', 'pap-afiliados-pro' ); ?></h3>
    370                 <ul class="papafpro-preset-list">
    371                     <!-- Carregado via JS -->
    372                 </ul>
     370                <table class="papafpro-preset-list widefat">
     371                    <thead></thead>
     372                    <tbody></tbody>
     373                </table>
    373374                <div class="papafpro-builder-actions" style="margin-top: 12px;">
    374375                    <button class="button" id="papafpro-bulk-duplicate-presets">
Note: See TracChangeset for help on using the changeset viewer.