Merge pull request #4153 from jaseelbavu/issue-4082

Added bulk category delete functionality
This commit is contained in:
Glenn Hermans 2020-11-02 17:16:33 +01:00 committed by GitHub
commit a0970f590d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 191 additions and 68 deletions

View File

@ -99,6 +99,14 @@ class CategoryDataGrid extends DataGrid
'route' => 'admin.catalog.categories.delete',
'confirm_text' => trans('ui::app.datagrid.massaction.delete', ['resource' => 'product']),
'icon' => 'icon trash-icon',
'function' => 'deleteFunction($event, "delete")'
]);
$this->addMassAction([
'type' => 'delete',
'label' => trans('admin::app.datagrid.delete'),
'action' => route('admin.catalog.categories.massdelete'),
'method' => 'DELETE',
]);
}
}

View File

@ -335,6 +335,13 @@ Route::group(['middleware' => ['web']], function () {
Route::post('/categories/delete/{id}', 'Webkul\Category\Http\Controllers\CategoryController@destroy')->name('admin.catalog.categories.delete');
//category massdelete
Route::post('categories/massdelete', 'Webkul\Category\Http\Controllers\CategoryController@massDestroy')->defaults('_config', [
'redirect' => 'admin.catalog.categories.index',
])->name('admin.catalog.categories.massdelete');
Route::post('/categories/product/count', 'Webkul\Category\Http\Controllers\CategoryController@categoryProductCount')->name('admin.catalog.categories.product.count');
// Catalog Attribute Routes
Route::get('/attributes', 'Webkul\Attribute\Http\Controllers\AttributeController@index')->defaults('_config', [

View File

@ -26,4 +26,58 @@
{!! view_render_event('bagisto.admin.catalog.categories.list.after') !!}
</div>
@stop
@stop
@push('scripts')
<script>
$(document).ready(function(){
$("input[type='checkbox']").change(deleteFunction);
});
var deleteFunction = function(e,type) {
if (type == 'delete') {
var indexes = $(e.target).parent().attr('id');
} else {
$("input[type='checkbox']").attr('disabled', true);
var formData = {};
$.each($('form').serializeArray(), function(i, field) {
formData[field.name] = field.value;
});
var indexes = formData.indexes;
}
if (indexes) {
$.ajax({
type : 'POST',
url : '{{route("admin.catalog.categories.product.count")}}',
data : {
_token: '{{csrf_token()}}',
indexes: indexes
},
success:function(data) {
$("input[type='checkbox']").attr('disabled', false);
if (data.product_count > 0) {
var message = "{{trans('ui::app.datagrid.massaction.delete-category-product')}}";
if (type == 'delete') {
doAction(e, message);
} else {
$('form').attr('onsubmit', 'return confirm("'+message+'")');
}
} else {
var message = "{{ __('ui::app.datagrid.click_on_action') }}";
if (type == 'delete') {
doAction(e, message);
} else {
$('form').attr('onsubmit', 'return confirm("'+message+'")');
}
}
}
});
} else {
$("input[type='checkbox']").attr('disabled', false);
}
}
</script>
@endpush

View File

@ -153,7 +153,10 @@ class CategoryController extends Controller
try {
Event::dispatch('catalog.category.delete.before', $id);
$this->categoryRepository->delete($id);
if($category->products->count() > 0) {
$category->products()->delete();
}
$category->delete();
Event::dispatch('catalog.category.delete.after', $id);
@ -175,36 +178,52 @@ class CategoryController extends Controller
*/
public function massDestroy()
{
$suppressFlash = false;
$suppressFlash = true;
$categoryIds = explode(',', request()->input('indexes'));
if (request()->isMethod('delete') || request()->isMethod('post')) {
$indexes = explode(',', request()->input('indexes'));
foreach ($categoryIds as $categoryId) {
$category = $this->categoryRepository->find($categoryId);
foreach ($indexes as $key => $value) {
try {
Event::dispatch('catalog.category.delete.before', $value);
if (isset($category)) {
if(strtolower($category->name) == "root") {
$suppressFlash = false;
session()->flash('warning', trans('admin::app.response.delete-category-root', ['name' => 'Category']));
} else {
try {
$suppressFlash = true;
Event::dispatch('catalog.category.delete.before', $categoryId);
$this->categoryRepository->delete($value);
if($category->products->count() > 0) {
$category->products()->delete();
}
$category->delete();
Event::dispatch('catalog.category.delete.after', $value);
} catch(\Exception $e) {
$suppressFlash = true;
continue;
Event::dispatch('catalog.category.delete.after', $categoryId);
} catch(\Exception $e) {
session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Category']));
}
}
}
if (! $suppressFlash) {
session()->flash('success', trans('admin::app.datagrid.mass-ops.delete-success'));
} else {
session()->flash('info', trans('admin::app.datagrid.mass-ops.partial-action', ['resource' => 'Attribute Family']));
}
return redirect()->back();
} else {
session()->flash('error', trans('admin::app.datagrid.mass-ops.method-error'));
return redirect()->back();
}
if (count($categoryIds) != 1 || $suppressFlash == true) {
session()->flash('success', trans('admin::app.datagrid.mass-ops.delete-success', ['resource' => 'Category']));
}
return redirect()->route($this->_config['redirect']);
}
public function categoryProductCount() {
$indexes = explode(",", request()->input('indexes'));
$product_count = 0;
foreach($indexes as $index) {
$category = $this->categoryRepository->find($index);
$product_count += $category->products->count();
}
return response()->json(['product_count' => $product_count], 200);
}
}

View File

@ -9,6 +9,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Webkul\Category\Contracts\Category as CategoryContract;
use Webkul\Attribute\Models\AttributeProxy;
use Webkul\Category\Repositories\CategoryRepository;
use Webkul\Product\Models\ProductProxy;
/**
* Class Category
@ -129,4 +130,12 @@ class Category extends TranslatableModel implements CategoryContract
return $this->findInTree($category->children);
}
/**
* The products that belong to the category.
*/
public function products()
{
return $this->belongsToMany(ProductProxy::modelClass(), 'product_categories');
}
}

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'هل تريد حقا تحديث الحالة من منتقى :resource?',
'delete' => 'هل تريد حقا حذف هذا :resource?',
'edit' => 'هل تريد حقا تحرير هذا :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'يمكن أن تحتوي أعمدة الفهرس على قيم أكبر من الصفر فقط',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Möchten Sie den Status der ausgewählten :resource wirklich aktualisieren?',
'delete' => 'Möchten Sie diese Aktion wirklich ausführen?',
'edit' => 'Möchten Sie :resource wirklich bearbeiten?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Indexspalten können nur Werte größer als Null haben',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Do you really want to update status of these selected :resource?',
'delete' => 'Do you really want to perform this action?',
'edit' => 'Do you really want to edit this :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Index columns can have values greater than zero only',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'آیا واقعاً می خواهید وضعیت انتخاب شده را به روز کنید :resource?',
'delete' => 'آیا واقعاً می خواهید این عمل را انجام دهید؟',
'edit' => 'آیا واقعاً می خواهید این را ویرایش کنید :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'ستون های فهرست می توانند مقادیری بیشتر از صفر داشته باشند',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Vuoi aggiornare davvero lo stato dei :resource selezionati?',
'delete' => 'Vuoi davvero effettuare questa azione?',
'edit' => 'Vuoi davvero modificare questo :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Le colonnne indice possono avere solo valori maggiori di zero',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Do you really want to update status of these selected :resource?',
'delete' => 'Wilt u deze actie echt uitvoeren?',
'edit' => 'Wil je dit echt bewerken :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Index columns can have values greater than zero only',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Czy naprawdę chcesz zaktualizować status tych wybranych :resource?',
'delete' => 'Czy naprawdę chcesz wykonać tę akcję?',
'edit' => 'Czy naprawdę chcesz edytować :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Kolumny indeksu mogą mieć wartości większe niż tylko zero',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Você realmente deseja atualizar o status desses itens selecionados :resource?',
'delete' => 'Você realmente deseja excluir este :resource?',
'edit' => 'Você realmente quer editar este :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Colunas do índice podem ter valores maiores que zero apenas',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Seçili :resource kayıtlarının durumunu güncellemek istediğinizden emin misiniz?',
'delete' => 'Bu işlemi gerçekleştirmek istediğinizden emin misiniz?',
'edit' => ':resource kaydını düzenlemek istediğinizden emin misiniz?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Index sütunları sadece sıfırdan büyük değere sahip olmalı',

View File

@ -48,25 +48,32 @@
@if ($toDisplay)
<a
@if ($action['method'] == 'GET')
href="{{ route($action['route'], $record->{$action['index'] ?? $index}) }}"
@endif
id="{{ $record->{$action['index'] ?? $index} }}"
@if ($action['method'] != 'GET')
v-on:click="doAction($event)"
@endif
@if ($action['method'] == 'GET')
href="{{ route($action['route'], $record->{$action['index'] ?? $index}) }}"
@endif
data-method="{{ $action['method'] }}"
data-action="{{ route($action['route'], $record->{$index}) }}"
data-token="{{ csrf_token() }}"
@if ($action['method'] != 'GET')
@if (isset($action['function']))
v-on:click="{{$action['function']}}"
@else
v-on:click="doAction($event)"
@endif
@endif
@if (isset($action['target']))
target="{{ $action['target'] }}"
@endif
data-method="{{ $action['method'] }}"
data-action="{{ route($action['route'], $record->{$index}) }}"
data-token="{{ csrf_token() }}"
@if (isset($action['title']))
title="{{ $action['title'] }}"
@endif>
@if (isset($action['target']))
target="{{ $action['target'] }}"
@endif
@if (isset($action['title']))
title="{{ $action['title'] }}"
@endif
>
<span class="{{ $action['icon'] }}"></span>
</a>
@endif

View File

@ -8,7 +8,7 @@
<span class="icon checkbox-dash-icon"></span>
</span>
<form method="POST" id="mass-action-form" style="display: inline-flex;" action="" onsubmit="return confirm('{{ __('ui::app.datagrid.click_on_action') }}')">
<form method="POST" id="mass-action-form" style="display: inline-flex;" action="" :onsubmit="`return confirm('${massActionConfirmText}')`">
@csrf()
<input type="hidden" id="indexes" name="indexes" v-model="dataIds">

View File

@ -272,6 +272,7 @@
massActions: @json($results['massactions']),
massActionsToggle: false,
massActionTarget: null,
massActionConfirmText: '{{ __('ui::app.datagrid.click_on_action') }}',
massActionType: null,
massActionValues: [],
massActionTargets: [],
@ -457,7 +458,8 @@
for (let id in this.massActions) {
targetObj = {
'type': this.massActions[id].type,
'action': this.massActions[id].action
'action': this.massActions[id].action,
'confirm_text': this.massActions[id].confirm_text
};
this.massActionTargets.push(targetObj);
@ -483,6 +485,7 @@
for (let i in this.massActionTargets) {
if (this.massActionTargets[i].type === 'delete') {
this.massActionTarget = this.massActionTargets[i].action;
this.massActionConfirmText = this.massActionTargets[i].confirm_text ? this.massActionTargets[i].confirm_text : this.massActionConfirmText;
break;
}
@ -493,6 +496,7 @@
for (let i in this.massActionTargets) {
if (this.massActionTargets[i].type === 'update') {
this.massActionTarget = this.massActionTargets[i].action;
this.massActionConfirmText = this.massActionTargets[i].confirm_text ? this.massActionTargets[i].confirm_text : this.massActionConfirmText;
break;
}
@ -816,31 +820,6 @@
}
},
doAction: function (e) {
var element = e.currentTarget;
if (confirm('{{__('ui::app.datagrid.massaction.delete') }}')) {
axios.post(element.getAttribute('data-action'), {
_token: element.getAttribute('data-token'),
_method: element.getAttribute('data-method')
}).then(function (response) {
this.result = response;
if (response.data.redirect) {
window.location.href = response.data.redirect;
} else {
location.reload();
}
}).catch(function (error) {
location.reload();
});
e.preventDefault();
} else {
e.preventDefault();
}
},
captureColumn: function (id) {
element = document.getElementById(id);
@ -869,6 +848,37 @@
}
}
});
function doAction(e, message, type) {
var element = e.currentTarget;
if (message) {
element = e.target.parentElement;
}
message = message || '{{__('ui::app.datagrid.massaction.delete') }}';
if (confirm(message)) {
axios.post(element.getAttribute('data-action'), {
_token: element.getAttribute('data-token'),
_method: element.getAttribute('data-method')
}).then(function (response) {
this.result = response;
if (response.data.redirect) {
window.location.href = response.data.redirect;
} else {
location.reload();
}
}).catch(function (error) {
location.reload();
});
e.preventDefault();
} else {
e.preventDefault();
}
}
</script>
@endpush
</div>