feat: Dodaj funkcjonalność usuwania zaznaczonych produktów w interfejsie użytkownika
This commit is contained in:
20
.vscode/ftp-kr.sync.cache.json
vendored
20
.vscode/ftp-kr.sync.cache.json
vendored
@@ -41,8 +41,8 @@
|
||||
},
|
||||
"class.Products.php": {
|
||||
"type": "-",
|
||||
"size": 12516,
|
||||
"lmtime": 1763678563804,
|
||||
"size": 13723,
|
||||
"lmtime": 1769467026122,
|
||||
"modified": false
|
||||
},
|
||||
"class.Site.php": {
|
||||
@@ -61,9 +61,9 @@
|
||||
"factory": {
|
||||
"class.Campaigns.php": {
|
||||
"type": "-",
|
||||
"size": 1089,
|
||||
"size": 1245,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
"modified": true
|
||||
},
|
||||
"class.Cron.php": {
|
||||
"type": "-",
|
||||
@@ -73,8 +73,8 @@
|
||||
},
|
||||
"class.Products.php": {
|
||||
"type": "-",
|
||||
"size": 6067,
|
||||
"lmtime": 1760996968673,
|
||||
"size": 6644,
|
||||
"lmtime": 1769467013018,
|
||||
"modified": false
|
||||
},
|
||||
"class.Users.php": {
|
||||
@@ -161,14 +161,14 @@
|
||||
"products": {
|
||||
"main_view.php": {
|
||||
"type": "-",
|
||||
"size": 13363,
|
||||
"size": 15258,
|
||||
"lmtime": 1763678650806,
|
||||
"modified": false
|
||||
"modified": true
|
||||
},
|
||||
"product_history.php": {
|
||||
"type": "-",
|
||||
"size": 10103,
|
||||
"lmtime": 1764629661097,
|
||||
"size": 12423,
|
||||
"lmtime": 1769467103988,
|
||||
"modified": false
|
||||
}
|
||||
},
|
||||
|
||||
@@ -167,6 +167,7 @@ class Products
|
||||
$roasCellHtml = '<div class="roas-cell">'.$roasNumeric.$roasPerfBar.'</div>';
|
||||
|
||||
$data['data'][] = [
|
||||
'', // checkbox column
|
||||
$row['product_id'],
|
||||
$row['offer_id'],
|
||||
'<div class="table-product-title" product_id="' . $row['product_id'] . '">
|
||||
@@ -208,6 +209,21 @@ class Products
|
||||
exit;
|
||||
}
|
||||
|
||||
static public function delete_products() {
|
||||
$product_ids = \S::get( 'product_ids' );
|
||||
|
||||
if ( !is_array( $product_ids ) || empty( $product_ids ) ) {
|
||||
echo json_encode( [ 'status' => 'error', 'message' => 'Brak produktów do usunięcia' ] );
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( \factory\Products::delete_products( $product_ids ) )
|
||||
echo json_encode( [ 'status' => 'ok' ] );
|
||||
else
|
||||
echo json_encode( [ 'status' => 'error', 'message' => 'Błąd podczas usuwania produktów' ] );
|
||||
exit;
|
||||
}
|
||||
|
||||
static public function save_min_roas()
|
||||
{
|
||||
$product_id = \S::get( 'product_id' );
|
||||
|
||||
@@ -8,6 +8,17 @@ class Products
|
||||
return true;
|
||||
}
|
||||
|
||||
static public function delete_products( $product_ids ) {
|
||||
global $mdb;
|
||||
if ( empty( $product_ids ) || !is_array( $product_ids ) ) {
|
||||
return false;
|
||||
}
|
||||
foreach ( $product_ids as $product_id ) {
|
||||
$mdb -> delete( 'products', [ 'id' => $product_id ] );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static public function get_product_comments( $product_id )
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
@@ -27,9 +27,15 @@
|
||||
<div class="admin-form theme-primary">
|
||||
<div class="panel heading-border panel-primary">
|
||||
<div class="panel-body">
|
||||
<div class="mb-3">
|
||||
<button type="button" class="btn btn-danger" id="delete-selected-products" disabled>
|
||||
<i class="fa fa-trash"></i> Usuń zaznaczone (<span id="selected-count">0</span>)
|
||||
</button>
|
||||
</div>
|
||||
<table class="table table-sm table-hover" id="products">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"><input type="checkbox" id="select-all-products" title="Zaznacz wszystkie" /></th>
|
||||
<th scope="col">Id</th>
|
||||
<th scope="col">Id oferty</th>
|
||||
<th scope="col">Nazwa produktu</th>
|
||||
@@ -128,24 +134,29 @@
|
||||
},
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
autoWidth: false,
|
||||
columns: [
|
||||
{ width: '30px', orderable: false, className: 'select-checkbox', render: function(data, type, row) {
|
||||
return '<input type="checkbox" class="product-checkbox" value="' + row[1] + '" />';
|
||||
}
|
||||
},
|
||||
{ width: '50px', orderable: false },
|
||||
{ width: '80px', name: 'offer_id' },
|
||||
{ name: 'name' },
|
||||
{ width: '50px', name: 'impressions' },
|
||||
{ width: '150px', name: 'impressions_30' },
|
||||
{ width: '50px', name: 'clicks' },
|
||||
{ width: '150px', name: 'clicks_30' },
|
||||
{ width: '50px', name: 'ctr' },
|
||||
{ width: '100px', name: 'cost', className: "dt-type-numeric" },
|
||||
{ width: '50px', name: 'cpc', className: "dt-type-numeric" },
|
||||
{ width: '50px', name: 'conversions' },
|
||||
{ width: '125px', name: 'conversions_value', className: "dt-type-numeric" },
|
||||
{ width: '70px', name: 'roas' },
|
||||
{ width: '70px', name: 'min_roas' },
|
||||
{ width: '50px', name: 'cl3', orderable: false },
|
||||
{ width: '100px', orderable: false },
|
||||
{ width: '100px', name: 'offer_id' },
|
||||
{ width: 'auto', name: 'name' },
|
||||
{ width: 'auto', name: 'impressions' },
|
||||
{ width: 'auto', name: 'impressions_30' },
|
||||
{ width: 'auto', name: 'clicks' },
|
||||
{ width: 'auto', name: 'clicks_30' },
|
||||
{ width: 'auto', name: 'ctr' },
|
||||
{ width: 'auto', name: 'cost', className: "dt-type-numeric" },
|
||||
{ width: 'auto', name: 'cpc', className: "dt-type-numeric" },
|
||||
{ width: 'auto', name: 'conversions' },
|
||||
{ width: 'auto', name: 'conversions_value', className: "dt-type-numeric" },
|
||||
{ width: 'auto', name: 'roas' },
|
||||
{ width: '100px', name: 'min_roas' },
|
||||
{ width: 'auto', name: 'cl3', orderable: false },
|
||||
{ width: '200px', orderable: false },
|
||||
{ width: '100px', orderable: false }],
|
||||
{ width: '50px', orderable: false }],
|
||||
order: [ [ 5, 'desc' ] ]
|
||||
});
|
||||
});
|
||||
@@ -184,9 +195,9 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
// usuń wiersz z tabeli
|
||||
// usuń wiersz z tabeli (zachowaj bieżącą stronę)
|
||||
var table = $('#products').DataTable();
|
||||
table.row(row).remove().draw();
|
||||
table.row(row).remove().draw(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -439,5 +450,91 @@
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Funkcja aktualizująca licznik i stan przycisku
|
||||
function updateSelectedCount() {
|
||||
var count = $('.product-checkbox:checked').length;
|
||||
$('#selected-count').text(count);
|
||||
$('#delete-selected-products').prop('disabled', count === 0);
|
||||
}
|
||||
|
||||
// Zaznacz/odznacz wszystkie produkty na bieżącej stronie
|
||||
$('body').on('change', '#select-all-products', function() {
|
||||
var isChecked = $(this).is(':checked');
|
||||
$('.product-checkbox').prop('checked', isChecked);
|
||||
updateSelectedCount();
|
||||
});
|
||||
|
||||
// Obsługa pojedynczych checkboxów
|
||||
$('body').on('change', '.product-checkbox', function() {
|
||||
updateSelectedCount();
|
||||
// Aktualizuj stan checkboxa "zaznacz wszystkie"
|
||||
var allChecked = $('.product-checkbox').length === $('.product-checkbox:checked').length;
|
||||
$('#select-all-products').prop('checked', allChecked);
|
||||
});
|
||||
|
||||
// Reset checkboxa "zaznacz wszystkie" przy zmianie strony/sortowaniu
|
||||
$('#products').on('draw.dt', function() {
|
||||
$('#select-all-products').prop('checked', false);
|
||||
updateSelectedCount();
|
||||
});
|
||||
|
||||
// Usuwanie zaznaczonych produktów
|
||||
$('body').on('click', '#delete-selected-products', function() {
|
||||
var selectedIds = [];
|
||||
$('.product-checkbox:checked').each(function() {
|
||||
selectedIds.push($(this).val());
|
||||
});
|
||||
|
||||
if (selectedIds.length === 0) {
|
||||
$.alert('Nie zaznaczono żadnych produktów.');
|
||||
return;
|
||||
}
|
||||
|
||||
$.confirm({
|
||||
title: 'Potwierdzenie',
|
||||
content: 'Czy na pewno chcesz usunąć ' + selectedIds.length + ' zaznaczonych produktów?',
|
||||
buttons: {
|
||||
confirm: {
|
||||
text: 'Usuń',
|
||||
keys: ['enter'],
|
||||
action: function() {
|
||||
$.ajax({
|
||||
url: '/products/delete_products/',
|
||||
type: 'POST',
|
||||
data: {
|
||||
product_ids: selectedIds
|
||||
},
|
||||
success: function(response) {
|
||||
var data = JSON.parse(response);
|
||||
if (data.status == 'ok') {
|
||||
$.alert({
|
||||
title: 'Sukces',
|
||||
content: 'Usunięto ' + selectedIds.length + ' produktów.',
|
||||
autoClose: 'ok|2000',
|
||||
buttons: {
|
||||
ok: function() {}
|
||||
}
|
||||
});
|
||||
// Odśwież tabelę zachowując bieżącą stronę
|
||||
var table = $('#products').DataTable();
|
||||
table.ajax.reload(null, false);
|
||||
} else {
|
||||
$.alert('Błąd: ' + data.message);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
$.alert('Wystąpił błąd podczas usuwania produktów. Spróbuj ponownie.');
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
cancel: {
|
||||
text: 'Anuluj',
|
||||
action: function() {}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user