From f1dec8db9f3aeee0d46fca5dbf1ddb7201d5684a Mon Sep 17 00:00:00 2001 From: A1Gard Date: Fri, 19 Jul 2024 02:26:42 +0330 Subject: [PATCH] added menu controller [WIP: sort] added menu item input vue component added v-model(s) & name support to MorphSelector --- app/Http/Controllers/Admin/MenuController.php | 147 ++++++++++++++++ app/Http/Requests/MenuSaveRequest.php | 28 +++ app/Models/Menu.php | 2 + resources/js/app.js | 3 + resources/js/components/MenuItemInput.vue | 164 ++++++++++++++++++ resources/js/components/MorphSelector.vue | 61 +++++-- .../views/admin/menus/menu-form.blade.php | 80 +++++++++ .../views/admin/menus/menu-list.blade.php | 15 ++ .../components/panel-side-navbar.blade.php | 2 +- .../views/website/inc/website-foot.blade.php | 10 +- routes/web.php | 13 ++ 11 files changed, 506 insertions(+), 19 deletions(-) create mode 100644 app/Http/Controllers/Admin/MenuController.php create mode 100644 app/Http/Requests/MenuSaveRequest.php create mode 100644 resources/js/components/MenuItemInput.vue create mode 100644 resources/views/admin/menus/menu-form.blade.php create mode 100644 resources/views/admin/menus/menu-list.blade.php diff --git a/app/Http/Controllers/Admin/MenuController.php b/app/Http/Controllers/Admin/MenuController.php new file mode 100644 index 0000000..1ee1048 --- /dev/null +++ b/app/Http/Controllers/Admin/MenuController.php @@ -0,0 +1,147 @@ + + ['title' => "Edit", 'class' => 'btn-outline-primary', 'icon' => 'ri-edit-2-line'], +// 'show' => +// ['title' => "Detail", 'class' => 'btn-outline-light', 'icon' => 'ri-eye-line'], + 'destroy' => + ['title' => "Remove", 'class' => 'btn-outline-danger delete-confirm', 'icon' => 'ri-close-line'], + ]; + + + public function __construct() + { + parent::__construct(Menu::class, MenuSaveRequest::class); + } + + /** + * @param $menu Menu + * @param $request MenuSaveRequest + * @return Menu + */ + public function save($menu, $request) + { + + $menu->name = $request->input('name'); + if ($menu->user_id == null){ + $menu->user_id = auth()->user()->id; + } + $menu->save(); + + $items = json_decode($request->input('items','[]')); + foreach ($items as $item) { + if ($item->id == null){ + $i = new Item(); + }else{ + $i = Item::whereId($item->id)->first(); + } + $i->user_id = auth()->user()->id; + $i->menu_id = $menu->id; + $i->meta = $item->meta??null; + $i->sort = $item->sort; + $i->parent = $item->parent; + $i->kind = $item->kind; + $i->title = $item->title; + $i->menuable_id = $item->menuable_id??null; + $i->menuable_type = $item->menuable_type??null; + $i->save(); + } + + Item::whereIn('id',json_decode($request->input('removed','[]')))->delete(); + + return $menu; + + } + + + /** + * Show the form for creating a new resource. + */ + public function create() + { + // + return view($this->formView); + } + + /** + * Show the form for editing the specified resource. + */ + public function edit(Menu $item) + { + // + return view($this->formView, compact('item')); + } + + public function bulk(Request $request) + { + +// dd($request->all()); + $data = explode('.', $request->input('action')); + $action = $data[0]; + $ids = $request->input('id'); + switch ($action) { + case 'delete': + $msg = __(':COUNT items deleted successfully', ['COUNT' => count($ids)]); + $this->_MODEL_::destroy($ids); + break; + /**restore*/ + case 'restore': + $msg = __(':COUNT items restored successfully', ['COUNT' => count($ids)]); + foreach ($ids as $id) { + $this->_MODEL_::withTrashed()->find($id)->restore(); + } + break; + /*restore**/ + default: + $msg = __('Unknown bulk action : :ACTION', ["ACTION" => $action]); + } + + return $this->do_bulk($msg, $action, $ids); + } + + public function destroy(Menu $item) + { + return parent::delete($item); + } + + + public function update(Request $request, Menu $item) + { + return $this->bringUp($request, $item); + } + + /**restore*/ + public function restore($item) + { + return parent::restoreing(Menu::withTrashed()->where('id', $item)->first()); + } + /*restore**/ +} diff --git a/app/Http/Requests/MenuSaveRequest.php b/app/Http/Requests/MenuSaveRequest.php new file mode 100644 index 0000000..e0cf808 --- /dev/null +++ b/app/Http/Requests/MenuSaveRequest.php @@ -0,0 +1,28 @@ +check(); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'name' => ['required','string','max:255','min:2'], + ]; + } +} diff --git a/app/Models/Menu.php b/app/Models/Menu.php index 996743d..d062c2a 100644 --- a/app/Models/Menu.php +++ b/app/Models/Menu.php @@ -10,6 +10,8 @@ class Menu extends Model { use HasFactory,SoftDeletes; + public static $mrohps = [Product::class,Post::class,Group::class, + Category::class,Clip::class,Gallery::class]; public function items() { return $this->hasMany(Item::class); diff --git a/resources/js/app.js b/resources/js/app.js index 3f82a57..09a119a 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -113,6 +113,9 @@ app.component('area-designer', AreaDesginer); import Latlng from "./components/latlng.vue"; app.component('lat-lng', Latlng); +import MenuItemInput from "./components/MenuItemInput.vue"; +app.component('menu-item-input', MenuItemInput); + /** * The following block of code may be used to automatically register your * Vue components. It will recursively scan this directory for the Vue diff --git a/resources/js/components/MenuItemInput.vue b/resources/js/components/MenuItemInput.vue new file mode 100644 index 0000000..a8b5b11 --- /dev/null +++ b/resources/js/components/MenuItemInput.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/resources/js/components/MorphSelector.vue b/resources/js/components/MorphSelector.vue index c8e7861..7271d0d 100644 --- a/resources/js/components/MorphSelector.vue +++ b/resources/js/components/MorphSelector.vue @@ -1,16 +1,17 @@ @@ -54,10 +55,24 @@ export default { q: '', all: [], id: null, - } }, props: { + emits: ['update:modelType', 'update:modelId'], + modelType: { + default: 'noting', + type: String, + }, + modelId: { + default: 'noting', + type: String, + }, + xnameType: { + default: 'attachable_type' + }, + xnameId: { + default: 'attachable_id' + }, morphs: { default: [], }, @@ -75,11 +90,17 @@ export default { } }, mounted() { - if (this.xmorph != null && this.xmorph != 'null' && this.xmorph != '') { - this.morph = this.xmorph; - } - if (this.xid != null && this.xid != 'null' && this.xid != '') { - this.id = parseInt(this.xid); + if (this.modelType == 'noting' || this.modelType == 'noting') { + + if (this.xmorph != null && this.xmorph != 'null' && this.xmorph != '') { + this.morph = this.xmorph; + } + if (this.xid != null && this.xid != 'null' && this.xid != '') { + this.id = parseInt(this.xid); + } + } else { + this.morph = this.modelType; + this.id = this.modelId; } }, computed: {}, @@ -103,13 +124,27 @@ export default { humanReadableMorph(morph) { const tmp = morph.split('\\'); return tmp[tmp.length - 1]; - } + }, + + + }, + watch: { + morph(newValue) { + if (this.modelType != 'noting') { + this.$emit('update:modelType', newValue); + } + }, + id(newValue) { + if (this.modelId != 'noting' && newValue != null) { + this.$emit('update:modelId', newValue.toString()); + } + }, } }