feat: Enhance Google Ads API integration and add column visibility control in product view
- Updated GoogleAdsApi class to include new GAQL queries for Performance Max campaigns and fallback mechanisms. - Refactored data collection logic to handle ad groups and asset groups more effectively. - Modified get_campaigns_30_days and get_campaigns_all_time methods to accept an optional date parameter for improved date filtering. - Introduced a new UI feature in the products main view to allow users to toggle column visibility, enhancing user experience. - Implemented local storage functionality to remember user preferences for column visibility across sessions.
This commit is contained in:
@@ -30,6 +30,13 @@
|
||||
<label for="bestseller_min_roas"><i class="fa-solid fa-star"></i> Bestseller min ROAS</label>
|
||||
<input type="text" id="bestseller_min_roas" name="bestseller_min_roas" class="form-control" placeholder="np. 500" value="" />
|
||||
</div>
|
||||
<div class="filter-group filter-group-columns">
|
||||
<label><i class="fa-solid fa-table-columns"></i> Kolumny</label>
|
||||
<details class="products-columns-control">
|
||||
<summary>Widocznosc kolumn</summary>
|
||||
<div class="products-columns-list" id="products_columns_list"></div>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Akcje bulk -->
|
||||
@@ -76,9 +83,63 @@
|
||||
$openai_enabled = \services\GoogleAdsApi::get_setting( 'openai_enabled' ) !== '0';
|
||||
$claude_enabled = \services\GoogleAdsApi::get_setting( 'claude_enabled' ) !== '0';
|
||||
?>
|
||||
<style>
|
||||
.products-page .products-filters .filter-group.filter-group-columns {
|
||||
min-width: 240px;
|
||||
}
|
||||
.products-columns-control {
|
||||
border: 1px solid #E2E8F0;
|
||||
border-radius: 6px;
|
||||
background: #FFFFFF;
|
||||
overflow: hidden;
|
||||
}
|
||||
.products-columns-control summary {
|
||||
cursor: pointer;
|
||||
padding: 8px 10px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #334155;
|
||||
list-style: none;
|
||||
}
|
||||
.products-columns-control summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
.products-columns-control summary::after {
|
||||
content: '\25BC';
|
||||
float: right;
|
||||
font-size: 10px;
|
||||
color: #64748B;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.products-columns-control[open] summary::after {
|
||||
content: '\25B2';
|
||||
}
|
||||
.products-columns-list {
|
||||
border-top: 1px solid #EEF2F7;
|
||||
padding: 8px 10px;
|
||||
max-height: 220px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.products-columns-list .products-col-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
color: #334155;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.products-columns-list .products-col-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.products-columns-list .products-col-item input[type=checkbox] {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
var AI_OPENAI_ENABLED = <?= $openai_enabled ? 'true' : 'false'; ?>;
|
||||
var AI_CLAUDE_ENABLED = <?= $claude_enabled ? 'true' : 'false'; ?>;
|
||||
var PRODUCTS_COLUMNS_STORAGE_KEY = 'products.columns.visibility';
|
||||
var PRODUCTS_LOCKED_COLUMNS = [ 0, 19 ];
|
||||
|
||||
function show_toast( message, type )
|
||||
{
|
||||
@@ -123,6 +184,151 @@ function loadGoogleCategories( callback )
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function products_storage_set( key, value )
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( value === null || typeof value === 'undefined' )
|
||||
{
|
||||
localStorage.removeItem( key );
|
||||
}
|
||||
else
|
||||
{
|
||||
localStorage.setItem( key, String( value ) );
|
||||
}
|
||||
}
|
||||
catch ( e ) {}
|
||||
}
|
||||
|
||||
function products_storage_get( key )
|
||||
{
|
||||
try
|
||||
{
|
||||
return localStorage.getItem( key ) || '';
|
||||
}
|
||||
catch ( e )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function products_is_locked_column( idx )
|
||||
{
|
||||
return PRODUCTS_LOCKED_COLUMNS.indexOf( Number( idx ) ) !== -1;
|
||||
}
|
||||
|
||||
function products_get_saved_columns_visibility( columns_count )
|
||||
{
|
||||
var raw = products_storage_get( PRODUCTS_COLUMNS_STORAGE_KEY );
|
||||
if ( !raw )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var saved = JSON.parse( raw );
|
||||
if ( !Array.isArray( saved ) || saved.length !== columns_count )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return saved;
|
||||
}
|
||||
catch ( e )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function products_save_columns_visibility( table_instance )
|
||||
{
|
||||
if ( !table_instance || !table_instance.columns )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var columns_count = table_instance.columns().count();
|
||||
var visible_map = [];
|
||||
var i;
|
||||
|
||||
for ( i = 0; i < columns_count; i++ )
|
||||
{
|
||||
visible_map.push( table_instance.column( i ).visible() );
|
||||
}
|
||||
|
||||
products_storage_set( PRODUCTS_COLUMNS_STORAGE_KEY, JSON.stringify( visible_map ) );
|
||||
}
|
||||
|
||||
function products_apply_saved_columns_visibility( table_instance )
|
||||
{
|
||||
if ( !table_instance || !table_instance.columns )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var columns_count = table_instance.columns().count();
|
||||
var saved_visibility = products_get_saved_columns_visibility( columns_count );
|
||||
var i;
|
||||
|
||||
if ( !saved_visibility )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for ( i = 0; i < columns_count; i++ )
|
||||
{
|
||||
if ( products_is_locked_column( i ) )
|
||||
{
|
||||
table_instance.column( i ).visible( true, false );
|
||||
continue;
|
||||
}
|
||||
|
||||
table_instance.column( i ).visible( !!saved_visibility[i], false );
|
||||
}
|
||||
|
||||
table_instance.columns.adjust().draw( false );
|
||||
}
|
||||
|
||||
function products_render_columns_picker( table_instance )
|
||||
{
|
||||
var $list = $( '#products_columns_list' );
|
||||
var columns_count = ( table_instance && table_instance.columns ) ? table_instance.columns().count() : 0;
|
||||
var i;
|
||||
|
||||
if ( !$list.length )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$list.empty();
|
||||
|
||||
if ( !columns_count )
|
||||
{
|
||||
$list.append( '<div class="products-col-item">Brak kolumn.</div>' );
|
||||
return;
|
||||
}
|
||||
|
||||
for ( i = 0; i < columns_count; i++ )
|
||||
{
|
||||
if ( products_is_locked_column( i ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var id = 'products-col-toggle-' + i;
|
||||
var th = $( '#products thead th' ).eq( i );
|
||||
var title = $.trim( th.find( '.dt-column-title' ).first().text() || th.text() ) || ( 'Kolumna ' + i );
|
||||
var checked = table_instance.column( i ).visible() ? ' checked' : '';
|
||||
|
||||
$list.append(
|
||||
'<label class="products-col-item" for="' + id + '">' +
|
||||
'<input type="checkbox" class="products-col-toggle" id="' + id + '" data-col-index="' + i + '"' + checked + '>' +
|
||||
'<span>' + title + '</span>' +
|
||||
'</label>'
|
||||
);
|
||||
}
|
||||
}
|
||||
$( function()
|
||||
{
|
||||
var products_table = new DataTable( '#products', {
|
||||
@@ -181,6 +387,9 @@ $( function()
|
||||
}
|
||||
});
|
||||
|
||||
products_apply_saved_columns_visibility( products_table );
|
||||
products_render_columns_picker( products_table );
|
||||
|
||||
function reload_products_table()
|
||||
{
|
||||
products_table.ajax.reload( null, false );
|
||||
@@ -648,6 +857,22 @@ $( function()
|
||||
updateSelectedCount();
|
||||
});
|
||||
|
||||
$( 'body' ).on( 'change', '.products-col-toggle', function()
|
||||
{
|
||||
var col_index = Number( $( this ).data( 'col-index' ) );
|
||||
var is_visible = $( this ).is( ':checked' );
|
||||
|
||||
if ( !products_table || Number.isNaN( col_index ) || products_is_locked_column( col_index ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
products_table.column( col_index ).visible( is_visible, false );
|
||||
products_table.columns.adjust().draw( false );
|
||||
products_save_columns_visibility( products_table );
|
||||
products_render_columns_picker( products_table );
|
||||
});
|
||||
|
||||
// Usuwanie zaznaczonych produktów
|
||||
$( 'body' ).on( 'click', '#delete-selected-products', function()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user