feat: Add XML file management functionality
- Created XmlFiles control class for handling XML file views and regeneration. - Implemented method to retrieve clients with XML feeds in the factory class. - Added database migration to include google_merchant_account_id in clients table. - Created migrations for products_keyword_planner_terms and products_merchant_sync_log tables. - Added campaign_keywords table migration for managing campaign keyword data. - Developed main view template for displaying XML files and their statuses. - Introduced a debug script for analyzing product URLs and their statuses.
This commit is contained in:
@@ -56,6 +56,7 @@
|
||||
<th>Id oferty</th>
|
||||
<th>Kampania</th>
|
||||
<th>Grupa reklam</th>
|
||||
<th>URL</th>
|
||||
<th>Nazwa produktu</th>
|
||||
<th>Wyśw.</th>
|
||||
<th>Wyśw. (30d)</th>
|
||||
@@ -83,63 +84,11 @@
|
||||
$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 ];
|
||||
var PRODUCTS_LOCKED_COLUMNS = [ 0, 20 ];
|
||||
|
||||
function show_toast( message, type )
|
||||
{
|
||||
@@ -160,6 +109,11 @@ function show_toast( message, type )
|
||||
}, 3000 );
|
||||
}
|
||||
|
||||
function escape_html( value )
|
||||
{
|
||||
return $( '<div>' ).text( value == null ? '' : String( value ) ).html();
|
||||
}
|
||||
|
||||
var GOOGLE_TAXONOMY_ENDPOINT = '/tools/google-taxonomy.php';
|
||||
var googleCategories = [];
|
||||
|
||||
@@ -317,7 +271,8 @@ function products_render_columns_picker( table_instance )
|
||||
}
|
||||
|
||||
var id = 'products-col-toggle-' + i;
|
||||
var th = $( '#products thead th' ).eq( i );
|
||||
var header_node = table_instance.column( i ).header();
|
||||
var th = header_node ? $( header_node ) : $();
|
||||
var title = $.trim( th.find( '.dt-column-title' ).first().text() || th.text() ) || ( 'Kolumna ' + i );
|
||||
var checked = table_instance.column( i ).visible() ? ' checked' : '';
|
||||
|
||||
@@ -356,6 +311,7 @@ $( function()
|
||||
{ width: '80px', name: 'offer_id' },
|
||||
{ width: '200px', name: 'campaign_name' },
|
||||
{ width: '200px', name: 'ad_group_name' },
|
||||
{ width: '120px', orderable: false, searchable: false },
|
||||
{ name: 'name' },
|
||||
{ width: '50px', name: 'impressions' },
|
||||
{ width: '80px', name: 'impressions_30' },
|
||||
@@ -370,12 +326,12 @@ $( function()
|
||||
{ width: '70px', name: 'min_roas' },
|
||||
{ width: '50px', name: 'cl3', orderable: false },
|
||||
{ width: '120px', orderable: false },
|
||||
{ width: '50px', orderable: false, className: 'dt-center' }
|
||||
{ width: '190px', orderable: false, className: 'dt-center' }
|
||||
],
|
||||
order: [ [ 8, 'desc' ] ],
|
||||
order: [ [ 9, 'desc' ] ],
|
||||
language: {
|
||||
processing: '£adowanie...',
|
||||
emptyTable: 'Brak produktów do wyœwietlenia',
|
||||
processing: 'Ładowanie...',
|
||||
emptyTable: 'Brak produktów do wyświetlenia',
|
||||
info: 'Produkty _START_ - _END_ z _TOTAL_',
|
||||
infoEmpty: '',
|
||||
paginate: {
|
||||
@@ -466,6 +422,308 @@ $( function()
|
||||
} );
|
||||
}
|
||||
|
||||
$( 'body' ).on( 'click', '.assign-product-scope', function( e )
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var product_id = $( this ).attr( 'product_id' );
|
||||
var client_id = $( '#client_id' ).val() || '';
|
||||
|
||||
if ( !client_id )
|
||||
{
|
||||
$.alert({ title: 'Brak klienta', content: 'Najpierw wybierz klienta, aby przypisać produkt do kampanii i grupy reklam.', type: 'orange' });
|
||||
return;
|
||||
}
|
||||
|
||||
$.confirm({
|
||||
title: 'Dodaj produkt do kampanii/grupy',
|
||||
content: '' +
|
||||
'<form class="assign-product-form">' +
|
||||
'<div class="assign-step assign-step-1">' +
|
||||
'<h4 style="margin-top:0">Krok 1 z 2: Kampania</h4>' +
|
||||
'<div class="form-group">' +
|
||||
'<label style="display:block"><input type="radio" name="campaign_mode" value="existing" checked> Istniejąca kampania</label>' +
|
||||
'<select class="form-control assign-campaign-id" style="margin-top:8px"><option value="">— wybierz kampanię —</option></select>' +
|
||||
'</div>' +
|
||||
'<div class="form-group">' +
|
||||
'<label style="display:block"><input type="radio" name="campaign_mode" value="new"> Nowa kampania</label>' +
|
||||
'<input type="text" class="form-control assign-campaign-name" placeholder="Nazwa nowej kampanii" style="margin-top:8px;display:none">' +
|
||||
'<div class="assign-new-campaign-options" style="display:none;margin-top:8px">' +
|
||||
'<div style="display:flex;gap:8px">' +
|
||||
'<input type="number" min="1" step="0.01" class="form-control assign-campaign-budget" value="50.00" placeholder="Budżet dzienny (np. 50.00 PLN)">' +
|
||||
'<input type="number" min="0.1" step="0.01" class="form-control assign-default-cpc" value="1.00" placeholder="Domyślne CPC (np. 1.00 PLN)">' +
|
||||
'</div>' +
|
||||
'<small class="text-muted">Dotyczy tylko tworzenia nowej kampanii Standard Shopping.</small>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="assign-step assign-step-2" style="display:none">' +
|
||||
'<h4 style="margin-top:0">Krok 2 z 2: Grupa reklam</h4>' +
|
||||
'<div class="form-group">' +
|
||||
'<label style="display:block"><input type="radio" name="ad_group_mode" value="existing" checked> Istniejąca grupa reklam</label>' +
|
||||
'<select class="form-control assign-ad-group-id" style="margin-top:8px"><option value="">— wybierz grupę reklam —</option></select>' +
|
||||
'</div>' +
|
||||
'<div class="form-group">' +
|
||||
'<label style="display:block"><input type="radio" name="ad_group_mode" value="new"> Nowa grupa reklam</label>' +
|
||||
'<input type="text" class="form-control assign-ad-group-name" placeholder="Nazwa nowej grupy reklam" style="margin-top:8px;display:none">' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</form>',
|
||||
useBootstrap: false,
|
||||
boxWidth: '720px',
|
||||
theme: 'modern',
|
||||
buttons: {
|
||||
back: {
|
||||
text: 'Wstecz',
|
||||
isHidden: true,
|
||||
action: function() {
|
||||
this.$content.find( '.assign-step-1' ).show();
|
||||
this.$content.find( '.assign-step-2' ).hide();
|
||||
this.$$back.hide();
|
||||
this.$$next.show();
|
||||
this.$$save.hide();
|
||||
return false;
|
||||
}
|
||||
},
|
||||
next: {
|
||||
text: 'Dalej',
|
||||
btnClass: 'btn-blue',
|
||||
action: function() {
|
||||
var $content = this.$content;
|
||||
var campaign_mode = $content.find( 'input[name="campaign_mode"]:checked' ).val();
|
||||
var campaign_id = $content.find( '.assign-campaign-id' ).val();
|
||||
var campaign_name = $.trim( $content.find( '.assign-campaign-name' ).val() );
|
||||
var campaign_daily_budget = parseFloat( $content.find( '.assign-campaign-budget' ).val() || '0' );
|
||||
var default_cpc = parseFloat( $content.find( '.assign-default-cpc' ).val() || '0' );
|
||||
|
||||
if ( campaign_mode === 'existing' && !campaign_id )
|
||||
{
|
||||
$.alert( 'Wybierz kampanię.' );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( campaign_mode === 'new' && !campaign_name )
|
||||
{
|
||||
$.alert( 'Podaj nazwę nowej kampanii.' );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( campaign_mode === 'new' && ( isNaN( campaign_daily_budget ) || campaign_daily_budget <= 0 ) )
|
||||
{
|
||||
$.alert( 'Podaj poprawny budżet dzienny (większy od 0).' );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( campaign_mode === 'new' && ( isNaN( default_cpc ) || default_cpc <= 0 ) )
|
||||
{
|
||||
$.alert( 'Podaj poprawne domyślne CPC (większe od 0).' );
|
||||
return false;
|
||||
}
|
||||
|
||||
this.$content.find( '.assign-step-1' ).hide();
|
||||
this.$content.find( '.assign-step-2' ).show();
|
||||
this.$$back.show();
|
||||
this.$$next.hide();
|
||||
this.$$save.show();
|
||||
return false;
|
||||
}
|
||||
},
|
||||
save: {
|
||||
text: 'Zapisz',
|
||||
btnClass: 'btn-green',
|
||||
isHidden: true,
|
||||
action: function() {
|
||||
var jc = this;
|
||||
var $content = jc.$content;
|
||||
|
||||
var campaign_mode = $content.find( 'input[name="campaign_mode"]:checked' ).val();
|
||||
var campaign_id = $content.find( '.assign-campaign-id' ).val() || '';
|
||||
var campaign_name = $.trim( $content.find( '.assign-campaign-name' ).val() );
|
||||
var campaign_daily_budget = parseFloat( $content.find( '.assign-campaign-budget' ).val() || '0' );
|
||||
var default_cpc = parseFloat( $content.find( '.assign-default-cpc' ).val() || '0' );
|
||||
|
||||
var ad_group_mode = $content.find( 'input[name="ad_group_mode"]:checked' ).val();
|
||||
var ad_group_id = $content.find( '.assign-ad-group-id' ).val() || '';
|
||||
var ad_group_name = $.trim( $content.find( '.assign-ad-group-name' ).val() );
|
||||
|
||||
if ( campaign_mode === 'existing' && !campaign_id )
|
||||
{
|
||||
$.alert( 'Wybierz kampanię.' );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( campaign_mode === 'new' && !campaign_name )
|
||||
{
|
||||
$.alert( 'Podaj nazwę nowej kampanii.' );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( campaign_mode === 'new' && ( isNaN( campaign_daily_budget ) || campaign_daily_budget <= 0 ) )
|
||||
{
|
||||
$.alert( 'Podaj poprawny budżet dzienny (większy od 0).' );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( campaign_mode === 'new' && ( isNaN( default_cpc ) || default_cpc <= 0 ) )
|
||||
{
|
||||
$.alert( 'Podaj poprawne domyślne CPC (większe od 0).' );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ad_group_mode === 'existing' && !ad_group_id )
|
||||
{
|
||||
$.alert( 'Wybierz grupę reklam.' );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ad_group_mode === 'new' && !ad_group_name )
|
||||
{
|
||||
$.alert( 'Podaj nazwę nowej grupy reklam.' );
|
||||
return false;
|
||||
}
|
||||
|
||||
jc.showLoading( true );
|
||||
|
||||
$.ajax({
|
||||
url: '/products/assign_product_scope/',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
product_id: product_id,
|
||||
campaign_mode: campaign_mode,
|
||||
campaign_id: campaign_id,
|
||||
campaign_name: campaign_name,
|
||||
campaign_daily_budget: campaign_daily_budget,
|
||||
default_cpc: default_cpc,
|
||||
ad_group_mode: ad_group_mode,
|
||||
ad_group_id: ad_group_id,
|
||||
ad_group_name: ad_group_name
|
||||
},
|
||||
success: function( res ) {
|
||||
jc.hideLoading();
|
||||
|
||||
if ( res && res.status === 'ok' )
|
||||
{
|
||||
jc.close();
|
||||
reload_products_table();
|
||||
show_toast( 'Produkt został przypisany do kampanii i grupy reklam.', 'success' );
|
||||
}
|
||||
else
|
||||
{
|
||||
show_toast( ( res && res.message ) ? res.message : 'Nie udało się zapisać przypisania.', 'error' );
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
jc.hideLoading();
|
||||
show_toast( 'Błąd połączenia podczas przypisywania produktu.', 'error' );
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
cancel: {
|
||||
text: 'Anuluj'
|
||||
}
|
||||
},
|
||||
onContentReady: function() {
|
||||
var jc = this;
|
||||
var $content = jc.$content;
|
||||
var $campaignModeInputs = $content.find( 'input[name="campaign_mode"]' );
|
||||
var $campaignSelect = $content.find( '.assign-campaign-id' );
|
||||
var $campaignName = $content.find( '.assign-campaign-name' );
|
||||
var $newCampaignOptions = $content.find( '.assign-new-campaign-options' );
|
||||
|
||||
var $adGroupModeInputs = $content.find( 'input[name="ad_group_mode"]' );
|
||||
var $adGroupSelect = $content.find( '.assign-ad-group-id' );
|
||||
var $adGroupName = $content.find( '.assign-ad-group-name' );
|
||||
|
||||
function loadCampaignsForStep()
|
||||
{
|
||||
$campaignSelect.empty().append( '<option value="">— wybierz kampanię —</option>' );
|
||||
|
||||
return $.ajax({
|
||||
url: '/products/get_campaigns_list/client_id=' + client_id,
|
||||
type: 'GET',
|
||||
dataType: 'json'
|
||||
}).done( function( res ) {
|
||||
( res.campaigns || [] ).forEach( function( row ) {
|
||||
$campaignSelect.append( '<option value="' + row.id + '">' + escape_html( row.campaign_name || '' ) + '</option>' );
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
function loadAdGroupsForStep( campaign_id )
|
||||
{
|
||||
$adGroupSelect.empty().append( '<option value="">— wybierz grupę reklam —</option>' );
|
||||
|
||||
if ( !campaign_id )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '/products/get_campaign_ad_groups/campaign_id=' + campaign_id,
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
success: function( res ) {
|
||||
( res.ad_groups || [] ).forEach( function( row ) {
|
||||
$adGroupSelect.append( '<option value="' + row.id + '">' + escape_html( row.ad_group_name || '' ) + '</option>' );
|
||||
} );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function toggleCampaignMode()
|
||||
{
|
||||
var mode = $campaignModeInputs.filter( ':checked' ).val();
|
||||
var isExisting = mode === 'existing';
|
||||
|
||||
$campaignSelect.toggle( isExisting );
|
||||
$campaignName.toggle( !isExisting );
|
||||
$newCampaignOptions.toggle( !isExisting );
|
||||
|
||||
if ( isExisting )
|
||||
{
|
||||
$adGroupModeInputs.filter( '[value="existing"]' ).prop( 'disabled', false );
|
||||
loadAdGroupsForStep( $campaignSelect.val() || '' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$adGroupModeInputs.filter( '[value="existing"]' ).prop( 'disabled', true );
|
||||
$adGroupModeInputs.filter( '[value="new"]' ).prop( 'checked', true );
|
||||
$adGroupSelect.empty().append( '<option value="">— wybierz grupę reklam —</option>' );
|
||||
}
|
||||
|
||||
toggleAdGroupMode();
|
||||
}
|
||||
|
||||
function toggleAdGroupMode()
|
||||
{
|
||||
var mode = $adGroupModeInputs.filter( ':checked' ).val();
|
||||
var isExisting = mode === 'existing';
|
||||
|
||||
$adGroupSelect.toggle( isExisting );
|
||||
$adGroupName.toggle( !isExisting );
|
||||
}
|
||||
|
||||
$campaignModeInputs.on( 'change', toggleCampaignMode );
|
||||
$adGroupModeInputs.on( 'change', toggleAdGroupMode );
|
||||
|
||||
$campaignSelect.on( 'change', function() {
|
||||
if ( $campaignModeInputs.filter( ':checked' ).val() === 'existing' )
|
||||
{
|
||||
loadAdGroupsForStep( $( this ).val() || '' );
|
||||
}
|
||||
} );
|
||||
|
||||
loadCampaignsForStep().always( function() {
|
||||
toggleCampaignMode();
|
||||
} );
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$( 'body' ).on( 'change', '#client_id', function()
|
||||
{
|
||||
var client_id = $( this ).val() || '';
|
||||
@@ -516,6 +774,102 @@ $( function()
|
||||
} );
|
||||
});
|
||||
|
||||
$( 'body' ).on( 'click', '.view-merchant-logs', function( e )
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var product_id = $( this ).attr( 'product_id' );
|
||||
|
||||
$.confirm({
|
||||
title: 'Logi synchronizacji Merchant (produkt #' + product_id + ')',
|
||||
content: '<div class="merchant-logs-wrap" style="max-height:460px;overflow:auto">Ładowanie logów...</div>',
|
||||
useBootstrap: false,
|
||||
boxWidth: '1100px',
|
||||
theme: 'modern',
|
||||
buttons: {
|
||||
close: {
|
||||
text: 'Zamknij',
|
||||
btnClass: 'btn-blue'
|
||||
}
|
||||
},
|
||||
onContentReady: function()
|
||||
{
|
||||
var jc = this;
|
||||
var $wrap = jc.$content.find( '.merchant-logs-wrap' );
|
||||
|
||||
$.ajax({
|
||||
url: '/products/get_product_merchant_sync_logs/',
|
||||
type: 'POST',
|
||||
data: { product_id: product_id, limit: 100 },
|
||||
success: function( response )
|
||||
{
|
||||
var data;
|
||||
|
||||
try
|
||||
{
|
||||
data = JSON.parse( response );
|
||||
}
|
||||
catch ( err )
|
||||
{
|
||||
$wrap.html( '<div class="text-danger">Nie udało się odczytać odpowiedzi serwera.</div>' );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( data.status !== 'ok' )
|
||||
{
|
||||
$wrap.html( '<div class="text-danger">' + escape_html( data.message || 'Błąd pobierania logów.' ) + '</div>' );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !data.logs || !data.logs.length )
|
||||
{
|
||||
$wrap.html( '<div class="text-muted">Brak logów synchronizacji dla tego produktu.</div>' );
|
||||
return;
|
||||
}
|
||||
|
||||
var rows_html = '';
|
||||
$.each( data.logs, function( _, log ) {
|
||||
var status_class = log.sync_status === 'success'
|
||||
? 'text-success'
|
||||
: ( log.sync_status === 'error' ? 'text-danger' : 'text-muted' );
|
||||
|
||||
rows_html += '<tr>' +
|
||||
'<td>' + escape_html( log.date_add || '' ) + '</td>' +
|
||||
'<td>' + escape_html( log.field_name || '' ) + '</td>' +
|
||||
'<td class="' + status_class + '"><b>' + escape_html( log.sync_status || '' ) + '</b></td>' +
|
||||
'<td>' + escape_html( log.sync_source || '' ) + '</td>' +
|
||||
'<td>' + escape_html( log.old_value || '' ) + '</td>' +
|
||||
'<td>' + escape_html( log.new_value || '' ) + '</td>' +
|
||||
'<td>' + escape_html( log.error_message || '' ) + '</td>' +
|
||||
'</tr>';
|
||||
} );
|
||||
|
||||
$wrap.html(
|
||||
'<table class="table table-sm table-bordered table-striped" style="font-size:12px;">' +
|
||||
'<thead>' +
|
||||
'<tr>' +
|
||||
'<th style="min-width:140px;">Data</th>' +
|
||||
'<th style="min-width:120px;">Pole</th>' +
|
||||
'<th style="min-width:90px;">Status</th>' +
|
||||
'<th style="min-width:110px;">Źródło</th>' +
|
||||
'<th style="min-width:180px;">Stara wartość</th>' +
|
||||
'<th style="min-width:180px;">Nowa wartość</th>' +
|
||||
'<th style="min-width:220px;">Błąd</th>' +
|
||||
'</tr>' +
|
||||
'</thead>' +
|
||||
'<tbody>' + rows_html + '</tbody>' +
|
||||
'</table>'
|
||||
);
|
||||
},
|
||||
error: function()
|
||||
{
|
||||
$wrap.html( '<div class="text-danger">Nie udało się pobrać logów synchronizacji.</div>' );
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Usuwanie produktu
|
||||
$( 'body' ).on( 'click', '.delete-product', function( e )
|
||||
{
|
||||
@@ -584,7 +938,34 @@ $( function()
|
||||
$.ajax({
|
||||
url: '/products/save_custom_label_4/',
|
||||
type: 'POST',
|
||||
data: { product_id: product_id, custom_label_4: custom_label_4 }
|
||||
data: { product_id: product_id, custom_label_4: custom_label_4 },
|
||||
success: function( response )
|
||||
{
|
||||
var data;
|
||||
|
||||
try
|
||||
{
|
||||
data = JSON.parse( response );
|
||||
}
|
||||
catch ( e )
|
||||
{
|
||||
show_toast( 'Custom Label 4: nieprawidłowa odpowiedź serwera.', 'error' );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( data.status === 'ok' )
|
||||
{
|
||||
show_toast( 'Custom Label 4 zapisany.', 'success' );
|
||||
}
|
||||
else
|
||||
{
|
||||
show_toast( 'Custom Label 4: zapis nie powiódł się.', 'error' );
|
||||
}
|
||||
},
|
||||
error: function()
|
||||
{
|
||||
show_toast( 'Custom Label 4: błąd połączenia podczas zapisu.', 'error' );
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -673,6 +1054,7 @@ $( function()
|
||||
jc.hideLoading();
|
||||
if ( data.status == 'ok' ) {
|
||||
jc.close();
|
||||
reload_products_table();
|
||||
show_toast( 'Dane produktu zostały zapisane.', 'success' );
|
||||
} else {
|
||||
show_toast( 'Błąd: ' + response, 'error' );
|
||||
@@ -789,10 +1171,18 @@ $( function()
|
||||
}
|
||||
if ( data.warning ) {
|
||||
show_toast( providerLabel + ': ' + data.warning, 'error' );
|
||||
} else if ( data.page_fetched ) {
|
||||
show_toast( providerLabel + ': Sugestia wygenerowana z treścią strony produktu', 'success' );
|
||||
} else {
|
||||
show_toast( providerLabel + ': Sugestia wygenerowana', 'success' );
|
||||
var successMessage = data.page_fetched
|
||||
? providerLabel + ': Sugestia wygenerowana z treścią strony produktu'
|
||||
: providerLabel + ': Sugestia wygenerowana';
|
||||
|
||||
if ( ( field == 'title' || field == 'description' ) && data.keyword_planner_terms_used ) {
|
||||
var kwCount = parseInt( data.keyword_planner_terms_count || 0, 10 );
|
||||
var kwLabel = kwCount > 0 ? ' (' + kwCount + ' fraz)' : '';
|
||||
successMessage += '; użyto fraz z Keyword Planner' + kwLabel;
|
||||
}
|
||||
|
||||
show_toast( successMessage, 'success' );
|
||||
}
|
||||
} else {
|
||||
show_toast( providerLabel + ': ' + ( data.message || 'Wystąpił błąd AI.' ), 'error' );
|
||||
|
||||
Reference in New Issue
Block a user