diff --git a/Database/Seeders/RoleSeeder.php b/Database/Seeders/RoleSeeder.php index 5aad582..b7d95e4 100644 --- a/Database/Seeders/RoleSeeder.php +++ b/Database/Seeders/RoleSeeder.php @@ -4,7 +4,7 @@ use Illuminate\Database\Seeder; use Illuminate\Database\Eloquent\Model; -use Modules\Admin\Models\Authorization\Role; +use Modules\Admin\Models\Rbac\Role; class RoleSeeder extends Seeder { diff --git a/Http/Controllers/Rbac/RoleController.php b/Http/Controllers/Rbac/RoleController.php index e5a6fec..897570e 100644 --- a/Http/Controllers/Rbac/RoleController.php +++ b/Http/Controllers/Rbac/RoleController.php @@ -1,19 +1,18 @@ roleService = $roleService; - $this->permissionService = $permissionService; $this->authenticatedSessionService = $authenticatedSessionService; } @@ -59,7 +51,7 @@ public function index(Request $request) $filters = $request->except('_token'); $roles = $this->roleService->rolePaginate($filters); - return view('backend::role.index', [ + return view('admin::rbac.role.index', [ 'roles' => $roles ]); } @@ -71,11 +63,8 @@ public function index(Request $request) */ public function create() { - $permissions = $this->permissionService->getAllPermissions(); - return view('backend::role.create', [ - 'permissions' => $permissions - ]); + return view('admin::rbac.role.create'); } /** @@ -87,14 +76,14 @@ public function create() */ public function store(RoleRequest $request): RedirectResponse { - $inputs = $request->except('_token'); + $confirm = $this->roleService->storeRole($request->except('_token')); - if ($this->roleService->storeRole($inputs)) { - toastr('New Role Created', 'success', 'Notification'); - return redirect()->route('roles.index'); + if ($confirm['status'] == true) { + notify($confirm['message'], $confirm['level'], $confirm['title']); + return redirect()->route('admin.roles.index'); } - toastr('Role Creation Failed', 'error', 'Alert'); + notify($confirm['message'], $confirm['level'], $confirm['title']); return redirect()->back()->withInput(); } @@ -109,12 +98,12 @@ public function show(int $id) { $withTrashed = false; - if (\request()->has('with') && \request()->get('with') == \Constant::PURGE_MODEL_QSA) { + if (request()->has('with') && request()->get('with') == Constant::PURGE_MODEL_QSA) { $withTrashed = true; } if ($role = $this->roleService->getRoleById($id, $withTrashed)) { - return view('backend::role.show', [ + return view('admin::rbac.role.show', [ 'role' => $role ]); } @@ -131,16 +120,15 @@ public function show(int $id) */ public function edit($id) { - if ($role = $this->roleService->getRoleById($id)) { + $withTrashed = false; - $permissions = $this->permissionService->getAllPermissions(); - $role_permissions = $role->permissions()->pluck('id')->toArray() ?? []; + if (request()->has('with') && request()->get('with') == Constant::PURGE_MODEL_QSA) { + $withTrashed = true; + } - return view('backend::role.edit', [ - 'role' => $role, - 'permissions' => $permissions, - 'role_permissions' => $role_permissions - ]); + if ($role = $this->roleService->getRoleById($id, $withTrashed)) { + + return view('admin::rbac.role.edit', ['role' => $role]); } abort(404); @@ -156,14 +144,14 @@ public function edit($id) */ public function update(RoleRequest $request, $id): RedirectResponse { - $inputs = $request->except('_token', 'submit', '_method'); + $confirm = $this->roleService->updateRole($request->except('_token', 'submit', '_method'), $id); - if ($this->roleService->updateRole($inputs, $id)) { - toastr('Role Information Updated', 'success', 'Notification'); - return redirect()->route('roles.index'); + if ($confirm['status'] == true) { + notify($confirm['message'], $confirm['level'], $confirm['title']); + return redirect()->route('admin.roles.index'); } - toastr('Role Information Update Failed', 'error', 'Alert'); + notify($confirm['message'], $confirm['level'], $confirm['title']); return redirect()->back()->withInput(); } @@ -175,18 +163,17 @@ public function update(RoleRequest $request, $id): RedirectResponse * @return RedirectResponse * @throws Throwable */ - public function destroy($id, Request $request): RedirectResponse + public function destroy($id, Request $request) { if ($this->authenticatedSessionService->verifyUser($request)) { - - if ($this->roleService->destroyRole($id)) { - toastr('Role Deleted', 'success', 'Notification'); + $confirm = $this->roleService->destroyRole($id); + if ($confirm['status'] == true) { + notify($confirm['message'], $confirm['level'], $confirm['title']); } else { - toastr('Role Removal Failed', 'error', 'Alert'); + notify($confirm['message'], $confirm['level'], $confirm['title']); } - return redirect()->route('roles.index'); + return redirect()->route('admin.roles.index'); } - abort(403, 'Wrong user credentials'); } } diff --git a/Http/Requests/Rbac/RoleRequest.php b/Http/Requests/Rbac/RoleRequest.php index b795ad0..093c260 100644 --- a/Http/Requests/Rbac/RoleRequest.php +++ b/Http/Requests/Rbac/RoleRequest.php @@ -14,8 +14,9 @@ class RoleRequest extends FormRequest */ public function authorize(): bool { - return request()->user()->can('roles.store') || - request()->user()->can('roles.update'); + /*return request()->user()->can('roles.store') || + request()->user()->can('roles.update');*/ + return true; } /** diff --git a/Models/Rbac/Role.php b/Models/Rbac/Role.php index e139a8a..6e1fba8 100644 --- a/Models/Rbac/Role.php +++ b/Models/Rbac/Role.php @@ -2,12 +2,12 @@ namespace Modules\Admin\Models\Rbac; -use Modules\Backend\Models\Authentication\User; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Notifications\Notifiable; use Kyslik\ColumnSortable\Sortable; +use Modules\Core\Models\User; use OwenIt\Auditing\Auditable as AuditableTrait; use OwenIt\Auditing\Contracts\Auditable; use Spatie\Permission\Models\Role as SpatieRole; @@ -96,11 +96,17 @@ public function deletedBy(): BelongsTo */ public function getTotalPermissionsAttribute(): int { - return $this->belongsToMany( - config('permission.models.permission'), - config('permission.table_names.role_has_permissions'), - 'role_id', - 'permission_id' - )->count(); + return $this->permissions->count(); } + + /** + * Count Total User Assigned to this role + * + * @return int + */ + public function getTotalUsersAttribute(): int + { + return $this->users->count(); + } + } diff --git a/Providers/HtmlServiceProvider.php b/Providers/HtmlServiceProvider.php index 1d9cd80..80a1d43 100644 --- a/Providers/HtmlServiceProvider.php +++ b/Providers/HtmlServiceProvider.php @@ -50,5 +50,8 @@ public function boot() //Dropdown Html::component('actionDropdown', 'admin::htmls.action-dropdowns', ['resourceRouteName', 'id', 'options' => []]); + + //Selection + Html::component('selection', 'admin::htmls.selection', ['target']); } } diff --git a/Repositories/Eloquent/Rbac/RoleRepository.php b/Repositories/Eloquent/Rbac/RoleRepository.php index bea5f38..c5a22b9 100644 --- a/Repositories/Eloquent/Rbac/RoleRepository.php +++ b/Repositories/Eloquent/Rbac/RoleRepository.php @@ -1,15 +1,15 @@ + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [Installation](#installation) + - [CDN](#cdn) + - [Download](#download) + - [NPM](#npm) + - [Yarn](#yarn) +- [Usage](#usage) + - [Initialize With HTML](#initialize-with-html) + - [Initialize With Code](#initialize-with-code) +- [API](#api) + - [Options](#options) + - [Methods](#methods) +- [Events](#events) + - [Event Propagation](#event-propagation) + - [API vs Input](#api-vs-input) + + + +************************************************************************************************** + +# Installation + +## CDN +```html + + +``` + +## Download +[Latest GitHub Release](https://github.com/gitbrent/bootstrap4-toggle/releases/latest) + +## NPM +```ksh +npm install bootstrap4-toggle +``` + +## Yarn +```ksh +yarn add bootstrap4-toggle +``` + +# Usage + +## Initialize With HTML +Simply add `data-toggle="toggle"` to automatically convert a plain checkbox into a bootstrap 4 toggle. + +```html + +``` + +## Initialize With Code +Toggles can also be initialized via JavaScript code. + +EX: Initialize id `chkToggle` with a single line of JavaScript. +```html + + +``` + +# API + +## Options +* Options can be passed via data attributes or JavaScript +* For data attributes, append the option name to `data-` (ex: `data-on="Enabled"`) + +```html + + + +``` + +Name |Type |Default |Description | +----------|-----------|----------|----------------------------| +`on` |string/html|"On" |Text of the on toggle +`off` |string/html|"Off" |Text of the off toggle +`size` |string |"normal" |Size of the toggle. Possible values are: `large`, `normal`, `small`, `mini`. +`onstyle` |string |"primary" |Style of the on toggle. Possible values are: `primary`,`secondary`,`success`,`danger`,`warning`,`info`,`light`,`dark` +`offstyle`|string |"light" |Style of the off toggle. Possible values are: `primary`,`secondary`,`success`,`danger`,`warning`,`info`,`light`,`dark` +`style` |string | |Appends the value to the class attribute of the toggle. This can be used to apply custom styles. Refer to Custom Styles for reference. +`width` |integer |*null* |Sets the width of the toggle. if set to *null*, width will be auto-calculated. +`height` |integer |*null* |Sets the height of the toggle. if set to *null*, height will be auto-calculated. + +## Methods +Methods can be used to control toggles directly. + +```html + +``` + +Method |Example |Description +-----------|------------------------------------------------|------------------------------------------ +initialize | `$('#toggle-demo').bootstrapToggle()` |Initializes the toggle plugin with options +destroy | `$('#toggle-demo').bootstrapToggle('destroy')` |Destroys the toggle +on | `$('#toggle-demo').bootstrapToggle('on')` |Sets the toggle to 'On' state +off | `$('#toggle-demo').bootstrapToggle('off')` |Sets the toggle to 'Off' state +toggle | `$('#toggle-demo').bootstrapToggle('toggle')` |Toggles the state of the toggle on/off +enable | `$('#toggle-demo').bootstrapToggle('enable')` |Enables the toggle +disable | `$('#toggle-demo').bootstrapToggle('disable')` |Disables the toggle + +# Events + +## Event Propagation +Note All events are propagated to and from input element to the toggle. + +You should listen to events from the `` directly rather than look for custom events. + +```html + +
+ +``` + +## API vs Input +This also means that using the API or Input to trigger events will work both ways. + +```html + + + + + + +``` diff --git a/Resources/plugins/bootstrap4-toggle/css/bootstrap4-toggle.min.css b/Resources/plugins/bootstrap4-toggle/css/bootstrap4-toggle.min.css new file mode 100644 index 0000000..42b1ec7 --- /dev/null +++ b/Resources/plugins/bootstrap4-toggle/css/bootstrap4-toggle.min.css @@ -0,0 +1,10 @@ +/*\ +|*| ======================================================================== +|*| Bootstrap Toggle: bootstrap4-toggle.css v3.6.1 +|*| https://gitbrent.github.io/bootstrap4-toggle/ +|*| ======================================================================== +|*| Copyright 2018-2019 Brent Ely +|*| Licensed under MIT +|*| ======================================================================== +\*/ +.btn-group-xs>.btn,.btn-xs{padding:.35rem .4rem .25rem .4rem;font-size:.875rem;line-height:.5;border-radius:.2rem}.checkbox label .toggle,.checkbox-inline .toggle{margin-left:-1.25rem;margin-right:.35rem}.toggle{position:relative;overflow:hidden}.toggle.btn.btn-light,.toggle.btn.btn-outline-light{border-color:rgba(0,0,0,.15)}.toggle input[type=checkbox]{display:none}.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none}.toggle-group label,.toggle-group span{cursor:pointer}.toggle.off .toggle-group{left:-100%}.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0;box-shadow:none}.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px;background-color:#fff}.toggle.btn-outline-primary .toggle-handle{background-color:var(--primary);border-color:var(--primary)}.toggle.btn-outline-secondary .toggle-handle{background-color:var(--secondary);border-color:var(--secondary)}.toggle.btn-outline-success .toggle-handle{background-color:var(--success);border-color:var(--success)}.toggle.btn-outline-danger .toggle-handle{background-color:var(--danger);border-color:var(--danger)}.toggle.btn-outline-warning .toggle-handle{background-color:var(--warning);border-color:var(--warning)}.toggle.btn-outline-info .toggle-handle{background-color:var(--info);border-color:var(--info)}.toggle.btn-outline-light .toggle-handle{background-color:var(--light);border-color:var(--light)}.toggle.btn-outline-dark .toggle-handle{background-color:var(--dark);border-color:var(--dark)}.toggle[class*=btn-outline]:hover .toggle-handle{background-color:var(--light);opacity:.5}.toggle.btn{min-width:3.7rem;min-height:2.15rem}.toggle-on.btn{padding-right:1.5rem}.toggle-off.btn{padding-left:1.5rem}.toggle.btn-lg{min-width:5rem;min-height:2.815rem}.toggle-on.btn-lg{padding-right:2rem}.toggle-off.btn-lg{padding-left:2rem}.toggle-handle.btn-lg{width:2.5rem}.toggle.btn-sm{min-width:3.125rem;min-height:1.938rem}.toggle-on.btn-sm{padding-right:1rem}.toggle-off.btn-sm{padding-left:1rem}.toggle.btn-xs{min-width:2.19rem;min-height:1.375rem}.toggle-on.btn-xs{padding-right:.8rem}.toggle-off.btn-xs{padding-left:.8rem} diff --git a/Resources/plugins/bootstrap4-toggle/js/bootstrap4-toggle.min.js b/Resources/plugins/bootstrap4-toggle/js/bootstrap4-toggle.min.js new file mode 100644 index 0000000..3839319 --- /dev/null +++ b/Resources/plugins/bootstrap4-toggle/js/bootstrap4-toggle.min.js @@ -0,0 +1,11 @@ +/*\ +|*| ======================================================================== +|*| Bootstrap Toggle: bootstrap4-toggle.js v3.6.1 +|*| https://gitbrent.github.io/bootstrap4-toggle/ +|*| ======================================================================== +|*| Copyright 2018-2019 Brent Ely +|*| Licensed under MIT +|*| ======================================================================== +\*/ +!function(a){"use strict";function l(t,e){this.$element=a(t),this.options=a.extend({},this.defaults(),e),this.render()}l.VERSION="3.6.0",l.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"light",size:"normal",style:"",width:null,height:null},l.prototype.defaults=function(){return{on:this.$element.attr("data-on")||l.DEFAULTS.on,off:this.$element.attr("data-off")||l.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||l.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||l.DEFAULTS.offstyle,size:this.$element.attr("data-size")||l.DEFAULTS.size,style:this.$element.attr("data-style")||l.DEFAULTS.style,width:this.$element.attr("data-width")||l.DEFAULTS.width,height:this.$element.attr("data-height")||l.DEFAULTS.height}},l.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var t="large"===this.options.size||"lg"===this.options.size?"btn-lg":"small"===this.options.size||"sm"===this.options.size?"btn-sm":"mini"===this.options.size||"xs"===this.options.size?"btn-xs":"",e=a('