¨4.0.1¨
This commit is contained in:
@@ -26,6 +26,7 @@ class CreateCategoriesTable extends Migration
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
|
||||
@@ -24,6 +24,7 @@ class CreateCategoryTranslationsTable extends Migration
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
|
||||
@@ -60,30 +60,12 @@ class Category extends Model
|
||||
*/
|
||||
protected $slugAttribute = 'name';
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
static::addActiveGlobalScope();
|
||||
}
|
||||
|
||||
public static function findBySlug($slug)
|
||||
{
|
||||
return static::with('files')->where('slug', $slug)->firstOrNew([]);
|
||||
}
|
||||
|
||||
public function isRoot()
|
||||
{
|
||||
return $this->exists && is_null($this->parent_id);
|
||||
}
|
||||
|
||||
public function url()
|
||||
{
|
||||
return route('categories.products.index', ['category' => $this->slug]);
|
||||
}
|
||||
|
||||
public static function tree()
|
||||
{
|
||||
@@ -96,6 +78,7 @@ class Category extends Model
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static function treeList()
|
||||
{
|
||||
return Cache::tags('categories')->rememberForever(md5('categories.tree_list:' . locale()), function () {
|
||||
@@ -107,6 +90,7 @@ class Category extends Model
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static function searchable()
|
||||
{
|
||||
return Cache::tags('categories')
|
||||
@@ -122,21 +106,48 @@ class Category extends Model
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
static::addActiveGlobalScope();
|
||||
}
|
||||
|
||||
|
||||
public function isRoot()
|
||||
{
|
||||
return $this->exists && is_null($this->parent_id);
|
||||
}
|
||||
|
||||
|
||||
public function url()
|
||||
{
|
||||
return route('categories.products.index', ['category' => $this->slug]);
|
||||
}
|
||||
|
||||
|
||||
public function products()
|
||||
{
|
||||
return $this->belongsToMany(Product::class, 'product_categories');
|
||||
}
|
||||
|
||||
|
||||
public function getLogoAttribute()
|
||||
{
|
||||
return $this->files->where('pivot.zone', 'logo')->first() ?: new File;
|
||||
}
|
||||
|
||||
|
||||
public function getBannerAttribute()
|
||||
{
|
||||
return $this->files->where('pivot.zone', 'banner')->first() ?: new File;
|
||||
}
|
||||
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
$attributes = parent::toArray();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Modules\Category\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
use Modules\Category\Entities\Category;
|
||||
use Modules\Admin\Traits\HasCrudActions;
|
||||
use Modules\Category\Http\Requests\SaveCategoryRequest;
|
||||
@@ -38,27 +39,31 @@ class CategoryController
|
||||
*/
|
||||
protected $validation = SaveCategoryRequest::class;
|
||||
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
return Category::with('files')->withoutGlobalScope('active')->find($id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy resources by given ids.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param string $ids
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy(string $ids)
|
||||
{
|
||||
Category::withoutGlobalScope('active')
|
||||
->findOrFail($id)
|
||||
->findOrFail($ids)
|
||||
->delete();
|
||||
|
||||
return back()->withSuccess(trans('admin::messages.resource_deleted', ['resource' => $this->getLabel()]));
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Modules\Category\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
use Modules\Category\Entities\Category;
|
||||
use Modules\Category\Services\CategoryTreeUpdater;
|
||||
use Modules\Category\Http\Responses\CategoryTreeResponse;
|
||||
@@ -11,7 +12,7 @@ class CategoryTreeController
|
||||
/**
|
||||
* Display category tree in json.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
@@ -22,15 +23,16 @@ class CategoryTreeController
|
||||
return new CategoryTreeResponse($categories);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update category tree in storage.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return Response
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
CategoryTreeUpdater::update(request('category_tree'));
|
||||
|
||||
return trans('category::messages.category_order_saved');
|
||||
return trans('category::messages.category_order_updated');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Modules\Category\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
use Modules\Category\Entities\Category;
|
||||
|
||||
class CategoryController
|
||||
@@ -9,7 +10,7 @@ class CategoryController
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Modules\Category\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
use Modules\Product\Entities\Product;
|
||||
use Modules\Category\Entities\Category;
|
||||
use Modules\Product\Filters\ProductFilter;
|
||||
@@ -15,9 +16,10 @@ class CategoryProductController
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param string $slug
|
||||
* @param \Modules\Product\Entities\Product $model
|
||||
* @param \Modules\Product\Filters\ProductFilter $productFilter
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param Product $model
|
||||
* @param ProductFilter $productFilter
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index($slug, Product $model, ProductFilter $productFilter)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ class SaveCategoryRequest extends Request
|
||||
*/
|
||||
protected $availableAttributes = 'category::attributes';
|
||||
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
@@ -26,10 +27,10 @@ class SaveCategoryRequest extends Request
|
||||
'name' => 'required',
|
||||
'slug' => $this->getSlugRules(),
|
||||
'is_active' => 'required|boolean',
|
||||
'is_active' => 'required|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
private function getSlugRules()
|
||||
{
|
||||
$rules = $this->route()->getName() === 'admin.categories.update'
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace Modules\Category\Http\Responses;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Contracts\Support\Responsable;
|
||||
|
||||
class CategoryTreeResponse implements Responsable
|
||||
@@ -13,6 +16,7 @@ class CategoryTreeResponse implements Responsable
|
||||
*/
|
||||
private $categories;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
@@ -23,21 +27,24 @@ class CategoryTreeResponse implements Responsable
|
||||
$this->categories = $categories;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create an HTTP response that represents the object.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function toResponse($request)
|
||||
{
|
||||
return response()->json($this->transform());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transform the categories.
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
* @return Collection
|
||||
*/
|
||||
private function transform()
|
||||
{
|
||||
|
||||
@@ -2,13 +2,10 @@
|
||||
|
||||
namespace Modules\Category\Providers;
|
||||
|
||||
use Modules\Support\Traits\AddsAsset;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class CategoryServiceProvider extends ServiceProvider
|
||||
{
|
||||
use AddsAsset;
|
||||
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*
|
||||
@@ -16,9 +13,5 @@ class CategoryServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->addAdminAssets('admin.categories.index', [
|
||||
'admin.category.css', 'admin.jstree.js', 'admin.category.js',
|
||||
'admin.media.css', 'admin.media.js',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,15 @@ export default class {
|
||||
this.fetchCategoryTree();
|
||||
|
||||
// On selecting a category.
|
||||
selector.on('select_node.jstree', (e, node) => categoryForm.fetchCategory(node.selected[0]));
|
||||
selector.on("select_node.jstree", (e, node) =>
|
||||
categoryForm.fetchCategory(node.selected[0])
|
||||
);
|
||||
|
||||
// Expand categories when jstree is loaded.
|
||||
selector.on('loaded.jstree', () => selector.jstree('open_all'));
|
||||
selector.on("loaded.jstree", () => selector.jstree("open_all"));
|
||||
|
||||
// On updating category tree.
|
||||
this.selector.on('move_node.jstree', (e, data) => {
|
||||
this.selector.on("move_node.jstree", (e, data) => {
|
||||
this.updateCategoryTree(data);
|
||||
});
|
||||
}
|
||||
@@ -22,10 +24,10 @@ export default class {
|
||||
fetchCategoryTree() {
|
||||
this.selector.jstree({
|
||||
core: {
|
||||
data: { url: route('admin.categories.tree') },
|
||||
data: { url: route("admin.categories.tree") },
|
||||
check_callback: true,
|
||||
},
|
||||
plugins: ['dnd'],
|
||||
plugins: ["dnd"],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -33,8 +35,8 @@ export default class {
|
||||
this.loading(data.node, true);
|
||||
|
||||
$.ajax({
|
||||
type: 'PUT',
|
||||
url: route('admin.categories.tree.update'),
|
||||
type: "PUT",
|
||||
url: route("admin.categories.tree.update"),
|
||||
data: { category_tree: this.getCategoryTree() },
|
||||
success: (message) => {
|
||||
success(message);
|
||||
@@ -50,12 +52,14 @@ export default class {
|
||||
}
|
||||
|
||||
getCategoryTree() {
|
||||
let categories = this.selector.jstree(true).get_json('#', { flat: true });
|
||||
let categories = this.selector
|
||||
.jstree(true)
|
||||
.get_json("#", { flat: true });
|
||||
|
||||
return categories.reduce((formatted, category) => {
|
||||
return formatted.concat({
|
||||
id: category.id,
|
||||
parent_id: (category.parent === '#') ? null : category.parent,
|
||||
parent_id: category.parent === "#" ? null : category.parent,
|
||||
position: category.data.position,
|
||||
});
|
||||
}, []);
|
||||
@@ -65,9 +69,9 @@ export default class {
|
||||
let nodeElement = this.selector.jstree().get_node(node, true);
|
||||
|
||||
if (state) {
|
||||
$(nodeElement).addClass('jstree-loading');
|
||||
$(nodeElement).addClass("jstree-loading");
|
||||
} else {
|
||||
$(nodeElement).removeClass('jstree-loading');
|
||||
$(nodeElement).removeClass("jstree-loading");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import CategoryForm from './CategoryForm';
|
||||
import CategoryForm from "./CategoryForm";
|
||||
|
||||
new CategoryForm();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
@import '~jstree/dist/themes/default/style';
|
||||
/*rtl:begin:ignore*/
|
||||
@import "jstree/dist/themes/default/style";
|
||||
/*rtl:end:ignore*/
|
||||
|
||||
.category-tree {
|
||||
margin-left: -10px;
|
||||
@@ -13,14 +15,6 @@
|
||||
margin: 5px 0 10px;
|
||||
}
|
||||
|
||||
.rtl {
|
||||
.jstree-default {
|
||||
&.jstree-rtl .jstree-node {
|
||||
background-position: 0% 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#category-form .loading-spinner {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'category_order_saved' => 'Category order has been saved.',
|
||||
'category_order_updated' => 'Category order updated',
|
||||
];
|
||||
|
||||
@@ -105,3 +105,14 @@
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('globals')
|
||||
<script type="module" src="{{ v(asset('build/assets/jstree.min.js')) }}"></script>
|
||||
|
||||
@vite([
|
||||
'Modules/Category/Resources/assets/admin/sass/main.scss',
|
||||
'Modules/Category/Resources/assets/admin/js/main.js',
|
||||
'Modules/Media/Resources/assets/admin/sass/main.scss',
|
||||
'Modules/Media/Resources/assets/admin/js/main.js',
|
||||
])
|
||||
@endpush
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace Modules\Category\Services;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Modules\Category\Entities\Category;
|
||||
|
||||
class CategoryTreeUpdater
|
||||
{
|
||||
@@ -13,11 +12,12 @@ class CategoryTreeUpdater
|
||||
* Update category tree order.
|
||||
*
|
||||
* @param array $tree
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function update(array $tree)
|
||||
{
|
||||
list($ids, $parentIdCases, $positionCases, $params) = static::getDataForQuery($tree);
|
||||
[$ids, $parentIdCases, $positionCases, $params] = static::getDataForQuery($tree);
|
||||
|
||||
$sql = "UPDATE `categories` SET
|
||||
`parent_id` = CASE `id` {$parentIdCases} END,
|
||||
@@ -30,10 +30,12 @@ class CategoryTreeUpdater
|
||||
Cache::tags('categories')->flush();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get data for update query.
|
||||
*
|
||||
* @param array $tree
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function getDataForQuery(array $tree)
|
||||
@@ -53,10 +55,12 @@ class CategoryTreeUpdater
|
||||
return static::prepareData($ids, $cases, $params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get attributes list from given tree.
|
||||
*
|
||||
* @param array $tree
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function getAttributesList(array $tree)
|
||||
@@ -73,12 +77,14 @@ class CategoryTreeUpdater
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepare data for update query.
|
||||
*
|
||||
* @param array $ids
|
||||
* @param array $cases
|
||||
* @param array $params
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function prepareData(array $ids, array $cases, array $params)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "category-module",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"jstree": "^3.3.9"
|
||||
"devDependencies": {},
|
||||
"dependencies": {
|
||||
"jstree": "^3.3.16"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user