From 2436898f048cc6b69e2ca600afa9123d47353242 Mon Sep 17 00:00:00 2001 From: denisdulici Date: Tue, 7 Jan 2020 17:15:00 +0300 Subject: [PATCH] shared dashboards --- app/Abstracts/Http/Controller.php | 2 +- app/BulkActions/Common/Dashboards.php | 70 +++++ app/Http/Controllers/Common/Dashboard.php | 117 --------- app/Http/Controllers/Common/Dashboards.php | 244 ++++++++++++++++++ app/Jobs/Auth/CreateUser.php | 14 +- app/Jobs/Auth/DeleteUser.php | 2 - app/Jobs/Common/CreateDashboard.php | 52 ++++ app/Jobs/Common/DeleteDashboard.php | 64 +++++ app/Jobs/Common/UpdateDashboard.php | 70 +++++ app/Listeners/Menu/AddAdminItems.php | 3 +- app/Listeners/Update/V20/Version200.php | 6 +- app/Models/Auth/User.php | 7 +- app/Models/Common/Dashboard.php | 11 +- app/Traits/Users.php | 26 +- config/search-string.php | 7 + ...9_11_14_000000_create_dashboards_table.php | 12 +- database/seeds/Dashboards.php | 10 +- database/seeds/Roles.php | 4 +- .../js/components/AkauntingDashboard.vue | 212 --------------- .../common/{dashboard.js => dashboards.js} | 49 +--- resources/lang/en-GB/companies.php | 4 +- resources/lang/en-GB/dashboards.php | 10 + resources/lang/en-GB/general.php | 4 +- .../views/common/dashboards/create.blade.php | 41 +++ .../views/common/dashboards/edit.blade.php | 44 ++++ .../views/common/dashboards/index.blade.php | 92 +++++++ .../show.blade.php} | 60 ++--- resources/views/partials/admin/menu.blade.php | 2 +- .../widgets/standard_header.blade.php | 6 + .../partials/widgets/stats_header.blade.php | 8 +- routes/admin.php | 6 +- routes/common.php | 2 +- webpack.mix.js | 2 +- 33 files changed, 806 insertions(+), 457 deletions(-) create mode 100644 app/BulkActions/Common/Dashboards.php delete mode 100644 app/Http/Controllers/Common/Dashboard.php create mode 100644 app/Http/Controllers/Common/Dashboards.php create mode 100644 app/Jobs/Common/CreateDashboard.php create mode 100644 app/Jobs/Common/DeleteDashboard.php create mode 100644 app/Jobs/Common/UpdateDashboard.php delete mode 100644 resources/assets/js/components/AkauntingDashboard.vue rename resources/assets/js/views/common/{dashboard.js => dashboards.js} (68%) create mode 100644 resources/lang/en-GB/dashboards.php create mode 100644 resources/views/common/dashboards/create.blade.php create mode 100644 resources/views/common/dashboards/edit.blade.php create mode 100644 resources/views/common/dashboards/index.blade.php rename resources/views/common/{dashboard/index.blade.php => dashboards/show.blade.php} (73%) diff --git a/app/Abstracts/Http/Controller.php b/app/Abstracts/Http/Controller.php index 78fa45f3b..779868b1b 100644 --- a/app/Abstracts/Http/Controller.php +++ b/app/Abstracts/Http/Controller.php @@ -58,7 +58,7 @@ abstract class Controller extends BaseController $controller .= Str::kebab($arr[0]); // Skip ACL - $skip = ['common-dashboard', 'portal-dashboard']; + $skip = ['portal-dashboard']; if (in_array($controller, $skip)) { return; } diff --git a/app/BulkActions/Common/Dashboards.php b/app/BulkActions/Common/Dashboards.php new file mode 100644 index 000000000..472ba7f79 --- /dev/null +++ b/app/BulkActions/Common/Dashboards.php @@ -0,0 +1,70 @@ + [ + 'name' => 'general.enable', + 'message' => 'bulk_actions.message.enable', + 'permission' => 'update-common-dashboards', + ], + 'disable' => [ + 'name' => 'general.disable', + 'message' => 'bulk_actions.message.disable', + 'permission' => 'update-common-dashboards', + ], + 'delete' => [ + 'name' => 'general.delete', + 'message' => 'bulk_actions.message.delete', + 'permission' => 'delete-common-dashboards', + ], + ]; + + public function enable($request) + { + $dashboards = $this->getSelectedRecords($request); + + foreach ($dashboards as $dashboard) { + try { + $this->dispatch(new UpdateDashboard($dashboard, $request->merge(['enabled' => 1]))); + } catch (\Exception $e) { + flash($e->getMessage())->error(); + } + } + } + + public function disable($request) + { + $dashboards = $this->getSelectedRecords($request); + + foreach ($dashboards as $dashboard) { + try { + $this->dispatch(new UpdateDashboard($dashboard, $request->merge(['enabled' => 0]))); + } catch (\Exception $e) { + flash($e->getMessage())->error(); + } + } + } + + public function destroy($request) + { + $dashboards = $this->getSelectedRecords($request); + + foreach ($dashboards as $dashboard) { + try { + $this->dispatch(new DeleteDashboard($dashboard)); + } catch (\Exception $e) { + flash($e->getMessage())->error(); + } + } + } +} diff --git a/app/Http/Controllers/Common/Dashboard.php b/app/Http/Controllers/Common/Dashboard.php deleted file mode 100644 index bdf00ac3d..000000000 --- a/app/Http/Controllers/Common/Dashboard.php +++ /dev/null @@ -1,117 +0,0 @@ -get('dashboard_id', 0)) { - $dashboard_id = request()->get('dashboard_id'); - - session(['dashboard_id' => $dashboard_id]); - } - - $dashboards = Model::where('user_id', user()->id)->enabled()->get(); - - if (!$dashboard_id) { - $dashboard_id = $dashboards->pluck('id')->first(); - } - - // Dashboard - $dashboard = Model::find($dashboard_id); - - // Widgets - $widgets = Widget::where('dashboard_id', $dashboard->id)->orderBy('sort', 'asc')->get()->filter(function ($widget) { - return WidgetUtility::canRead($widget->class); - }); - - $financial_start = $this->getFinancialStart()->format('Y-m-d'); - - return view('common.dashboard.index', compact('dashboards', 'dashboard', 'widgets', 'financial_start')); - } - - /** - * Store a newly created resource in storage. - * - * @param $request - * @return Response - */ - public function store(Request $request) - { - $request['enabled'] = 1; - $request['user_id'] = user()->id; - - $dashboard = Model::create($request->input()); - - $response['data'] = $dashboard; - $response['redirect'] = route('dashboard'); - - return response()->json($response); - } - - /** - * Show the form for editing the specified resource. - * - * @param Model $dashboard - * - * @return Response - */ - public function edit(Model $dashboard) - { - return response()->json($dashboard); - } - - /** - * Update the specified resource in storage. - * - * @param Model $dashboard - * @param $request - * @return Response - */ - public function update(Model $dashboard, Request $request) - { - $request['enabled'] = 1; - $dashboard->update($request->input()); - - $response['data'] = $dashboard; - $response['redirect'] = route('dashboard'); - - return response()->json($response); - } - - /** - * Remove the specified resource from storage. - * - * @param Model $dashboard - * - * @return Response - */ - public function destroy(Model $dashboard) - { - $dashboard->delete(); - - session(['dashboard_id' => user()->dashboards()->pluck('id')->first()]); - - $response['redirect'] = route('dashboard'); - - return response()->json($response); - } -} diff --git a/app/Http/Controllers/Common/Dashboards.php b/app/Http/Controllers/Common/Dashboards.php new file mode 100644 index 000000000..56c38ea3c --- /dev/null +++ b/app/Http/Controllers/Common/Dashboards.php @@ -0,0 +1,244 @@ +middleware('permission:create-common-dashboards')->only(['create', 'store', 'duplicate', 'import']); + $this->middleware('permission:read-common-dashboards')->only(['index', 'edit', 'export']); + $this->middleware('permission:update-common-dashboards')->only(['update', 'enable', 'disable', 'share']); + $this->middleware('permission:delete-common-dashboards')->only('destroy'); + } + + /** + * Display a listing of the resource. + * + * @return Response + */ + public function index() + { + $dashboards = user()->dashboards()->collect(); + + return view('common.dashboards.index', compact('dashboards')); + } + + /** + * Show the form for viewing the specified resource. + * + * @return Response + */ + public function show() + { + $dashboard_id = session('dashboard_id', 0); + + // Change Dashboard + if (request()->get('dashboard_id', 0)) { + $dashboard_id = request()->get('dashboard_id'); + + session(['dashboard_id' => $dashboard_id]); + } + + $dashboards = user()->dashboards()->enabled()->get(); + + if (!$dashboard_id) { + $dashboard_id = $dashboards->pluck('id')->first(); + } + + // Dashboard + $dashboard = Dashboard::find($dashboard_id); + + // Widgets + $widgets = Widget::where('dashboard_id', $dashboard->id)->orderBy('sort', 'asc')->get()->filter(function ($widget) { + return Widgets::canRead($widget->class); + }); + + $financial_start = $this->getFinancialStart()->format('Y-m-d'); + + return view('common.dashboards.show', compact('dashboards', 'dashboard', 'widgets', 'financial_start')); + } + + /** + * Show the form for creating a new resource. + * + * @return Response + */ + public function create() + { + $users = Company::find(session('company_id'))->users()->get()->sortBy('name'); + + return view('common.dashboards.create', compact('users')); + } + + /** + * Store a newly created resource in storage. + * + * @param $request + * @return Response + */ + public function store(Request $request) + { + $response = $this->ajaxDispatch(new CreateDashboard($request)); + + if ($response['success']) { + $response['redirect'] = route('dashboard'); + + $message = trans('messages.success.added', ['type' => trans_choice('general.dashboards', 1)]); + + flash($message)->success(); + } else { + $response['redirect'] = route('dashboard'); + + $message = $response['message']; + + flash($message)->error(); + } + + return response()->json($response); + } + + /** + * Show the form for editing the specified resource. + * + * @param Dashboard $dashboard + * + * @return Response + */ + public function edit(Dashboard $dashboard) + { + if (!$this->isUserDashboard($dashboard->id)) { + return redirect()->route('dashboards.index'); + } + + $users = Company::find(session('company_id'))->users()->get()->sortBy('name'); + + return view('common.dashboards.edit', compact('dashboard', 'users')); + } + + /** + * Update the specified resource in storage. + * + * @param Dashboard $dashboard + * @param $request + * @return Response + */ + public function update(Dashboard $dashboard, Request $request) + { + $response = $this->ajaxDispatch(new UpdateDashboard($dashboard, $request)); + + if ($response['success']) { + $response['redirect'] = route('dashboards.index'); + + $message = trans('messages.success.updated', ['type' => trans_choice('general.dashboards', 1)]); + + flash($message)->success(); + } else { + $response['redirect'] = route('dashboards.edit', $dashboard->id); + + $message = $response['message']; + + flash($message)->error(); + } + + return response()->json($response); + } + + /** + * Enable the specified resource. + * + * @param Dashboard $dashboard + * + * @return Response + */ + public function enable(Dashboard $dashboard) + { + $response = $this->ajaxDispatch(new UpdateDashboard($dashboard, request()->merge(['enabled' => 1]))); + + if ($response['success']) { + $response['message'] = trans('messages.success.enabled', ['type' => trans_choice('general.dashboards', 1)]); + } + + return response()->json($response); + } + + /** + * Disable the specified resource. + * + * @param Dashboard $dashboard + * + * @return Response + */ + public function disable(Dashboard $dashboard) + { + $response = $this->ajaxDispatch(new UpdateDashboard($dashboard, request()->merge(['enabled' => 0]))); + + if ($response['success']) { + $response['message'] = trans('messages.success.disabled', ['type' => trans_choice('general.dashboards', 1)]); + } + + return response()->json($response); + } + + /** + * Remove the specified resource from storage. + * + * @param Dashboard $dashboard + * + * @return Response + */ + public function destroy(Dashboard $dashboard) + { + $response = $this->ajaxDispatch(new DeleteDashboard($dashboard)); + + $response['redirect'] = route('dashboard'); + + if ($response['success']) { + $message = trans('messages.success.deleted', ['type' => $dashboard->name]); + + flash($message)->success(); + + session(['dashboard_id' => user()->dashboards()->pluck('id')->first()]); + } else { + $message = $response['message']; + + flash($message)->error(); + } + + return response()->json($response); + } + + /** + * Change the active dashboard. + * + * @param Dashboard $dashboard + * + * @return Response + */ + public function switch(Dashboard $dashboard) + { + if ($this->isUserDashboard($dashboard->id)) { + session(['dashboard_id' => $dashboard->id]); + } + + return redirect()->route('dashboard'); + } +} diff --git a/app/Jobs/Auth/CreateUser.php b/app/Jobs/Auth/CreateUser.php index 551d1de9e..239d0a8f2 100644 --- a/app/Jobs/Auth/CreateUser.php +++ b/app/Jobs/Auth/CreateUser.php @@ -29,10 +29,6 @@ class CreateUser extends Job { $user = User::create($this->request->input()); - if ($this->request->has('permissions')) { - $user->permissions()->attach($this->request->get('permissions')); - } - // Upload picture if ($this->request->file('picture')) { $media = $this->getMedia($this->request->file('picture'), 'users'); @@ -40,10 +36,16 @@ class CreateUser extends Job $user->attachMedia($media, 'picture'); } - // Attach roles + if ($this->request->has('dashboards')) { + $user->dashboards()->attach($this->request->get('dashboards')); + } + + if ($this->request->has('permissions')) { + $user->permissions()->attach($this->request->get('permissions')); + } + $user->roles()->attach($this->request->get('roles')); - // Attach companies $user->companies()->attach($this->request->get('companies')); Artisan::call('cache:clear'); diff --git a/app/Jobs/Auth/DeleteUser.php b/app/Jobs/Auth/DeleteUser.php index de0ef9ea5..e060ed585 100644 --- a/app/Jobs/Auth/DeleteUser.php +++ b/app/Jobs/Auth/DeleteUser.php @@ -28,8 +28,6 @@ class DeleteUser extends Job { $this->authorize(); - $this->deleteRelationships($this->user, ['widgets', 'dashboards']); - $this->user->delete(); Artisan::call('cache:clear'); diff --git a/app/Jobs/Common/CreateDashboard.php b/app/Jobs/Common/CreateDashboard.php new file mode 100644 index 000000000..dd6b9eb01 --- /dev/null +++ b/app/Jobs/Common/CreateDashboard.php @@ -0,0 +1,52 @@ +request = $this->getRequestInstance($request); + } + + /** + * Execute the job. + * + * @return Item + */ + public function handle() + { + $this->request['enabled'] = $this->request['enabled'] ?? 1; + + $this->dashboard = Dashboard::create($this->request->all()); + + $this->attachToUser(); + + return $this->dashboard; + } + + protected function attachToUser() + { + if ($this->request->has('users')) { + $user = $this->request->get('users'); + } else { + $user = user(); + } + + if (empty($user)) { + return; + } + + $this->dashboard->users()->attach($user); + } +} diff --git a/app/Jobs/Common/DeleteDashboard.php b/app/Jobs/Common/DeleteDashboard.php new file mode 100644 index 000000000..9b1d82bbb --- /dev/null +++ b/app/Jobs/Common/DeleteDashboard.php @@ -0,0 +1,64 @@ +dashboard = $dashboard; + } + + /** + * Execute the job. + * + * @return boolean + */ + public function handle() + { + $this->authorize(); + + $this->deleteRelationships($this->dashboard, ['widgets']); + + $this->dashboard->delete(); + + Artisan::call('cache:clear'); + + return true; + } + + /** + * Determine if this action is applicable. + * + * @return void + */ + public function authorize() + { + // Can't delete your last dashboard + if (user()->dashboards()->enabled()->count() == 1) { + $message = trans('dashboards.error.delete_last'); + + throw new \Exception($message); + } + + // Check if user can access dashboard + if (!$this->isUserDashboard($this->dashboard->id)) { + $message = trans('dashboards.error.not_user_dashboard'); + + throw new \Exception($message); + } + } +} diff --git a/app/Jobs/Common/UpdateDashboard.php b/app/Jobs/Common/UpdateDashboard.php new file mode 100644 index 000000000..83e0c08b4 --- /dev/null +++ b/app/Jobs/Common/UpdateDashboard.php @@ -0,0 +1,70 @@ +dashboard = $dashboard; + $this->request = $this->getRequestInstance($request); + } + + /** + * Execute the job. + * + * @return Dashboard + */ + public function handle() + { + $this->authorize(); + + $this->dashboard->update($this->request->all()); + + if ($this->request->has('users')) { + $this->dashboard->users()->sync($this->request->get('users')); + } + + return $this->dashboard; + } + + /** + * Determine if this action is applicable. + * + * @return void + */ + public function authorize() + { + $user = user(); + + // Can't delete your last dashboard + if ($this->request->has('users') && !in_array($user->id, (array) $this->request->get('users')) && ($user->dashboards()->enabled()->count() == 1)) { + $message = trans('dashboards.error.delete_last'); + + throw new \Exception($message); + } + + // Check if user can access dashboard + if (!$this->isUserDashboard($this->dashboard->id)) { + $message = trans('dashboards.error.not_user_dashboard'); + + throw new \Exception($message); + } + } +} diff --git a/app/Listeners/Menu/AddAdminItems.php b/app/Listeners/Menu/AddAdminItems.php index 624c1fb16..c8be23cd5 100644 --- a/app/Listeners/Menu/AddAdminItems.php +++ b/app/Listeners/Menu/AddAdminItems.php @@ -3,7 +3,6 @@ namespace App\Listeners\Menu; use App\Events\Menu\AdminCreated as Event; -use App\Models\Common\Dashboard; class AddAdminItems { @@ -21,7 +20,7 @@ class AddAdminItems $attr = ['icon' => '']; // Dashboard - $dashboards = Dashboard::ofUser($user->id)->get(); + $dashboards = user()->dashboards()->enabled()->get(); if ($dashboards->count() > 1) { $menu->dropdown(trim(trans_choice('general.dashboards', 2)), function ($sub) use ($user, $attr, $dashboards) { diff --git a/app/Listeners/Update/V20/Version200.php b/app/Listeners/Update/V20/Version200.php index d7272b4bf..66f08542e 100644 --- a/app/Listeners/Update/V20/Version200.php +++ b/app/Listeners/Update/V20/Version200.php @@ -695,6 +695,7 @@ class Version200 extends Listener { $this->attachPermissions([ 'admin' => [ + 'common-dashboards' => 'c,r,u,d', 'common-reports' => 'c,r,u,d', 'common-search' => 'r', 'common-widgets' => 'c,r,u,d', @@ -720,9 +721,10 @@ class Version200 extends Listener 'widgets-total-profit' => 'r', ], 'manager' => [ + 'common-dashboards' => 'c,r,u,d', 'common-reports' => 'c,r,u,d', 'common-search' => 'r', - 'common-widgets' => 'r', + 'common-widgets' => 'c,r,u,d', 'offline-payments-settings' => 'r,u,d', 'paypal-standard-settings' => 'r,u', 'settings-company' => 'r', @@ -885,6 +887,7 @@ class Version200 extends Listener 'app/Http/Controllers/Api/Incomes/Revenues.php', 'app/Http/Controllers/ApiController.php', 'app/Http/Controllers/Controller.php', + 'app/Http/Controllers/Common/Dashboard.php', 'app/Http/Controllers/Modals/BillPayments.php', 'app/Http/Controllers/Modals/InvoicePayments.php', 'app/Http/Controllers/modules/Token.php', @@ -1021,6 +1024,7 @@ class Version200 extends Listener 'public/js/highchart', 'public/js/lightbox', 'public/js/moment', + 'resources/views/common/dashboard', 'resources/views/customers', 'resources/views/expenses', 'resources/views/incomes', diff --git a/app/Models/Auth/User.php b/app/Models/Auth/User.php index 9f4b7b2f0..cce08165c 100644 --- a/app/Models/Auth/User.php +++ b/app/Models/Auth/User.php @@ -59,12 +59,7 @@ class User extends Authenticatable public function dashboards() { - return $this->hasMany('App\Models\Common\Dashboard'); - } - - public function widgets() - { - return $this->hasManyThrough('App\Models\Common\Widget', 'App\Models\Common\Dashboard'); + return $this->morphToMany('App\Models\Common\Dashboard', 'user', 'user_dashboards', 'user_id', 'dashboard_id'); } /** diff --git a/app/Models/Common/Dashboard.php b/app/Models/Common/Dashboard.php index 71be1fd7e..0b9342158 100644 --- a/app/Models/Common/Dashboard.php +++ b/app/Models/Common/Dashboard.php @@ -16,7 +16,7 @@ class Dashboard extends Model * * @var array */ - protected $fillable = ['company_id', 'user_id', 'name', 'enabled']; + protected $fillable = ['company_id', 'name', 'enabled']; /** * Sortable columns. @@ -25,18 +25,13 @@ class Dashboard extends Model */ public $sortable = ['name', 'enabled']; - public function user() + public function users() { - return $this->belongsTo('App\Models\Auth\User', 'user_id', 'id'); + return $this->morphedByMany('App\Models\Auth\User', 'user', 'user_dashboards', 'dashboard_id', 'user_id'); } public function widgets() { return $this->hasMany('App\Models\Common\Widget')->orderBy('sort', 'asc'); } - - public function scopeOfUser($query, $user_id) - { - return $query->where('user_id', $user_id); - } } diff --git a/app/Traits/Users.php b/app/Traits/Users.php index 55d483996..cecd425f4 100644 --- a/app/Traits/Users.php +++ b/app/Traits/Users.php @@ -2,8 +2,6 @@ namespace App\Traits; -use App\Models\Auth\User; - trait Users { /** @@ -39,4 +37,28 @@ trait Users return false; } + + /** + * Check user dashboard assignment + * + * @param $id + * + * @return boolean + */ + public function isUserDashboard($id) + { + $user = user(); + + if (empty($user)) { + return false; + } + + $dashboards = $user->dashboards()->pluck('id')->toArray(); + + if (in_array($id, $dashboards)) { + return true; + } + + return false; + } } diff --git a/config/search-string.php b/config/search-string.php index 7c4873253..1f49d1f94 100644 --- a/config/search-string.php +++ b/config/search-string.php @@ -108,6 +108,13 @@ return [ ], ], + App\Models\Common\Dashboard::class => [ + 'columns' => [ + 'name' => ['searchable' => true], + 'enabled' => ['boolean' => true], + ], + ], + App\Models\Common\Item::class => [ 'columns' => [ 'name' => ['searchable' => true], diff --git a/database/migrations/2019_11_14_000000_create_dashboards_table.php b/database/migrations/2019_11_14_000000_create_dashboards_table.php index 961701826..9b996ab1c 100644 --- a/database/migrations/2019_11_14_000000_create_dashboards_table.php +++ b/database/migrations/2019_11_14_000000_create_dashboards_table.php @@ -16,7 +16,6 @@ class CreateDashboardsTable extends Migration Schema::create('dashboards', function (Blueprint $table) { $table->increments('id'); $table->integer('company_id'); - $table->integer('user_id'); $table->string('name'); $table->boolean('enabled')->default(1); $table->timestamps(); @@ -25,6 +24,14 @@ class CreateDashboardsTable extends Migration $table->index(['company_id']); }); + Schema::create('user_dashboards', function (Blueprint $table) { + $table->integer('user_id')->unsigned(); + $table->integer('dashboard_id')->unsigned(); + $table->string('user_type', 20); + + $table->primary(['user_id', 'dashboard_id', 'user_type']); + }); + Schema::create('widgets', function (Blueprint $table) { $table->increments('id'); $table->integer('company_id'); @@ -36,7 +43,7 @@ class CreateDashboardsTable extends Migration $table->timestamps(); $table->softDeletes(); - $table->index(['company_id']); + $table->index(['company_id', 'dashboard_id']); }); } @@ -48,6 +55,7 @@ class CreateDashboardsTable extends Migration public function down() { Schema::drop('dashboards'); + Schema::drop('user_dashboards'); Schema::drop('widgets'); } } diff --git a/database/seeds/Dashboards.php b/database/seeds/Dashboards.php index e083857ea..29e78a490 100644 --- a/database/seeds/Dashboards.php +++ b/database/seeds/Dashboards.php @@ -3,9 +3,10 @@ namespace Database\Seeds; use App\Abstracts\Model; +use App\Models\Auth\User; use App\Models\Common\Widget; use App\Models\Common\Dashboard; -use App\Utilities\Widgets as WidgetUtility; +use App\Utilities\Widgets; use Illuminate\Database\Seeder; class Dashboards extends Seeder @@ -31,12 +32,11 @@ class Dashboards extends Seeder $dashboard = Dashboard::create([ 'company_id' => $company_id, - 'user_id' => $user_id, - 'name' => trans('general.dashboard'), + 'name' => trans_choice('general.dashboards', 1), 'enabled' => 1, ]); - $widgets = WidgetUtility::getClasses(false); + $widgets = Widgets::getClasses(false); $sort = 1; @@ -52,5 +52,7 @@ class Dashboards extends Seeder $sort++; } + + User::find($user_id)->dashboards()->attach($dashboard->id); } } diff --git a/database/seeds/Roles.php b/database/seeds/Roles.php index cd42fa2bf..14054392f 100644 --- a/database/seeds/Roles.php +++ b/database/seeds/Roles.php @@ -38,6 +38,7 @@ class Roles extends Seeder 'banking-transactions' => 'c,r,u,d', 'banking-transfers' => 'c,r,u,d', 'common-companies' => 'c,r,u,d', + 'common-dashboards' => 'c,r,u,d', 'common-import' => 'c', 'common-items' => 'c,r,u,d', 'common-notifications' => 'c,r,u,d', @@ -98,13 +99,14 @@ class Roles extends Seeder 'banking-transactions' => 'c,r,u,d', 'banking-transfers' => 'c,r,u,d', 'common-companies' => 'c,r,u,d', + 'common-dashboards' => 'c,r,u,d', 'common-import' => 'c', 'common-items' => 'c,r,u,d', 'common-notifications' => 'c,r,u,d', 'common-reports' => 'c,r,u,d', 'common-search' => 'r', 'common-uploads' => 'r', - 'common-widgets' => 'r', + 'common-widgets' => 'c,r,u,d', 'purchases-bills' => 'c,r,u,d', 'purchases-payments' => 'c,r,u,d', 'purchases-vendors' => 'c,r,u,d', diff --git a/resources/assets/js/components/AkauntingDashboard.vue b/resources/assets/js/components/AkauntingDashboard.vue deleted file mode 100644 index 634aa8c64..000000000 --- a/resources/assets/js/components/AkauntingDashboard.vue +++ /dev/null @@ -1,212 +0,0 @@ - - - - - diff --git a/resources/assets/js/views/common/dashboard.js b/resources/assets/js/views/common/dashboards.js similarity index 68% rename from resources/assets/js/views/common/dashboard.js rename to resources/assets/js/views/common/dashboards.js index 41b1338d7..204f474fe 100644 --- a/resources/assets/js/views/common/dashboard.js +++ b/resources/assets/js/views/common/dashboards.js @@ -11,9 +11,11 @@ import Vue from 'vue'; import DashboardPlugin from './../../plugins/dashboard-plugin'; import Global from './../../mixins/global'; + +import Form from './../../plugins/form'; +import BulkAction from './../../plugins/bulk-action'; import {getQueryVariable} from './../../plugins/functions'; -import AkauntingDashboard from './../../components/AkauntingDashboard'; import AkauntingWidget from './../../components/AkauntingWidget'; import {DatePicker, Tooltip} from 'element-ui'; @@ -29,7 +31,6 @@ const dashboard = new Vue({ components: { [DatePicker.name]: DatePicker, [Tooltip.name]: Tooltip, - AkauntingDashboard, AkauntingWidget }, @@ -39,13 +40,6 @@ const dashboard = new Vue({ data: function () { return { - dashboard_modal: false, - dashboard: { - name: '', - enabled: 1, - type: 'create', - dashboard_id: 0 - }, widget_modal: false, widgets: {}, widget: { @@ -57,7 +51,8 @@ const dashboard = new Vue({ sort: 0, }, filter_date: [], - + form: new Form('dashboard'), + bulk_action: new BulkAction('dashboards') }; }, @@ -75,33 +70,6 @@ const dashboard = new Vue({ }, methods:{ - // Create Dashboard form open - onCreateDashboard() { - this.dashboard_modal = true; - this.dashboard.name = ''; - this.dashboard.enabled = 1; - this.dashboard.type = 'create'; - this.dashboard.dashboard_id = 0; - }, - - // Edit Dashboard information - onEditDashboard(dashboard_id) { - var self = this; - - axios.get(url + '/common/dashboards/' + dashboard_id + '/edit') - .then(function (response) { - self.dashboard.name = response.data.name; - self.dashboard.enabled = response.data.enabled; - self.dashboard.type = 'edit'; - self.dashboard.dashboard_id = dashboard_id; - - self.dashboard_modal = true; - }) - .catch(function (error) { - self.dashboard_modal = false; - }); - }, - // Get All Widgets getWidgets() { var self = this; @@ -140,13 +108,6 @@ const dashboard = new Vue({ }, onCancel() { - this.dashboard_modal = false; - - this.dashboard.name = ''; - this.dashboard.enabled = 1; - this.dashboard.type = 'create'; - this.dashboard.dashboard_id = 0; - this.widget_modal = false; this.widget.id = 0; diff --git a/resources/lang/en-GB/companies.php b/resources/lang/en-GB/companies.php index af64dc5cb..8415b2f8b 100644 --- a/resources/lang/en-GB/companies.php +++ b/resources/lang/en-GB/companies.php @@ -4,12 +4,10 @@ return [ 'domain' => 'Domain', 'logo' => 'Logo', - 'manage' => 'Manage Companies', - 'all' => 'All Companies', 'error' => [ 'not_user_company' => 'Error: You are not allowed to change this company!', - 'delete_active' => 'Error: Can not delete active company, please, change it first!', + 'delete_active' => 'Error: Can not delete the active company. Please, switch to another first!', ], ]; diff --git a/resources/lang/en-GB/dashboards.php b/resources/lang/en-GB/dashboards.php new file mode 100644 index 000000000..fae098c4c --- /dev/null +++ b/resources/lang/en-GB/dashboards.php @@ -0,0 +1,10 @@ + [ + 'not_user_dashboard' => 'Error: You are not allowed to change this dashboard!', + 'delete_last' => 'Error: Can not delete the last dashboard. Please, create a new one first!', + ], + +]; diff --git a/resources/lang/en-GB/general.php b/resources/lang/en-GB/general.php index 39061fa0f..933e72c50 100644 --- a/resources/lang/en-GB/general.php +++ b/resources/lang/en-GB/general.php @@ -52,7 +52,6 @@ return [ 'sales' => 'Sale|Sales', 'purchases' => 'Purchases|Purchases', - 'dashboard' => 'Dashboard', 'welcome' => 'Welcome', 'banking' => 'Banking', 'general' => 'General', @@ -142,6 +141,8 @@ return [ 'cash' => 'Cash', 'group_by' => 'Group By', 'accounting' => 'Accounting', + 'sort' => 'Sort', + 'width' => 'Width', 'month' => 'Month', 'year' => 'Year', @@ -161,6 +162,7 @@ return [ 'send' => 'Send :type', 'get' => 'Get :type', 'add' => 'Add :type', + 'manage' => 'Manage :type', ], 'form' => [ diff --git a/resources/views/common/dashboards/create.blade.php b/resources/views/common/dashboards/create.blade.php new file mode 100644 index 000000000..3a4fe48e9 --- /dev/null +++ b/resources/views/common/dashboards/create.blade.php @@ -0,0 +1,41 @@ +@extends('layouts.admin') + +@section('title', trans('general.title.new', ['type' => trans_choice('general.dashboards', 1)])) + +@section('content') +
+ {!! Form::open([ + 'id' => 'dashboard', + 'route' => 'dashboards.store', + '@submit.prevent' => 'onSubmit', + '@keydown' => 'form.errors.clear($event.target.name)', + 'files' => true, + 'role' => 'form', + 'class' => 'form-loading-button', + 'novalidate' => true, + ]) !!} + +
+
+ {{ Form::textGroup('name', trans('general.name'), 'font') }} + + @permission('read-auth-users') + {{ Form::checkboxGroup('users', trans_choice('general.users', 2), $users, 'name') }} + @endpermission + + {{ Form::radioGroup('enabled', trans('general.enabled'), true) }} +
+
+ + + {!! Form::close() !!} +
+@endsection + +@push('scripts_start') + +@endpush diff --git a/resources/views/common/dashboards/edit.blade.php b/resources/views/common/dashboards/edit.blade.php new file mode 100644 index 000000000..d45c1bc34 --- /dev/null +++ b/resources/views/common/dashboards/edit.blade.php @@ -0,0 +1,44 @@ +@extends('layouts.admin') + +@section('title', trans('general.title.edit', ['type' => trans_choice('general.dashboards', 1)])) + +@section('content') +
+ {!! Form::model($dashboard, [ + 'id' => 'dashboard', + 'method' => 'PATCH', + 'route' => ['dashboards.update', $dashboard->id], + '@submit.prevent' => 'onSubmit', + '@keydown' => 'form.errors.clear($event.target.name)', + 'files' => true, + 'role' => 'form', + 'class' => 'form-loading-button', + 'novalidate' => true, + ]) !!} + +
+
+ {{ Form::textGroup('name', trans('general.name'), 'font') }} + + @permission('read-auth-users') + {{ Form::checkboxGroup('users', trans_choice('general.users', 2), $users, 'name') }} + @endpermission + + {{ Form::radioGroup('enabled', trans('general.enabled'), $dashboard->enabled) }} +
+
+ + @permission('update-common-dashboards') + + @endpermission + {!! Form::close() !!} +
+@endsection + +@push('scripts_start') + +@endpush diff --git a/resources/views/common/dashboards/index.blade.php b/resources/views/common/dashboards/index.blade.php new file mode 100644 index 000000000..bd9ccd05e --- /dev/null +++ b/resources/views/common/dashboards/index.blade.php @@ -0,0 +1,92 @@ +@extends('layouts.admin') + +@section('title', trans_choice('general.dashboards', 2)) + +@permission('create-common-dashboards') + @section('new_button') +  {{ trans('general.add_new') }} + @endsection +@endpermission + +@section('content') +
+
+ {!! Form::open([ + 'route' => 'dashboards.index', + 'role' => 'form', + 'method' => 'GET', + 'class' => 'mb-0' + ]) !!} +
+
+ {{ trans('general.search') }}: + +
+
+ + {{ Form::bulkActionRowGroup('general.dashboards', $bulk_actions, 'common/dashboards') }} + {!! Form::close() !!} +
+ +
+ + + + + + + + + + + + @foreach($dashboards as $item) + + + + + + + @endforeach + +
{{ Form::bulkActionAllGroup() }}@sortablelink('name', trans('general.name'))@sortablelink('enabled', trans('general.enabled')){{ trans('general.actions') }}
{{ Form::bulkActionGroup($item->id, $item->name) }}{{ $item->name }} + @if (user()->can('update-common-dashboards')) + {{ Form::enabledGroup($item->id, $item->name, $item->enabled) }} + @else + @if ($item->enabled) + {{ trans('general.enabled') }} + @else + {{ trans('general.disabled') }} + @endif + @endif + + +
+
+ + +
+@endsection + +@push('scripts_start') + +@endpush diff --git a/resources/views/common/dashboard/index.blade.php b/resources/views/common/dashboards/show.blade.php similarity index 73% rename from resources/views/common/dashboard/index.blade.php rename to resources/views/common/dashboards/show.blade.php index a68bf7421..1157934a6 100644 --- a/resources/views/common/dashboard/index.blade.php +++ b/resources/views/common/dashboards/show.blade.php @@ -3,6 +3,7 @@ @section('title', $dashboard->name) @section('dashboard_action') + @permission(['create-common-widgets', 'read-common-dashboards']) + @endpermission @php $text = json_encode([ 'name' => trans('general.name'), - 'type' => 'Type', - 'width' => 'Width', - 'sort' => 'Sort', + 'type' => trans_choice('general.types', 1), + 'width' => trans('general.width'), + 'sort' => trans('general.sort'), 'enabled' => trans('general.enabled'), 'yes' => trans('general.yes'), 'no' => trans('general.no'), @@ -54,24 +46,12 @@ $placeholder = json_encode([ 'name' => trans('general.form.enter', ['field' => trans('general.name')]), - 'type' => trans('general.form.enter', ['field' => 'Type']), - 'width' => trans('general.form.enter', ['field' => 'Width']), - 'sort' => trans('general.form.enter', ['field' => 'Sort']) + 'type' => trans('general.form.enter', ['field' => trans_choice('general.types', 1)]), + 'width' => trans('general.form.enter', ['field' => trans('general.width')]), + 'sort' => trans('general.form.enter', ['field' => trans('general.sprt')]) ]); @endphp - - - + @endpush diff --git a/resources/views/partials/admin/menu.blade.php b/resources/views/partials/admin/menu.blade.php index 61447caff..5bf7caae6 100644 --- a/resources/views/partials/admin/menu.blade.php +++ b/resources/views/partials/admin/menu.blade.php @@ -23,7 +23,7 @@ - {{ trans('companies.manage') }} + {{ trans('general.title.manage', ['type' => trans_choice('general.companies', 2)]) }} @endpermission diff --git a/resources/views/partials/widgets/standard_header.blade.php b/resources/views/partials/widgets/standard_header.blade.php index 107c8709e..26af63eea 100644 --- a/resources/views/partials/widgets/standard_header.blade.php +++ b/resources/views/partials/widgets/standard_header.blade.php @@ -1,3 +1,4 @@ +@permission(['update-common-widgets', 'delete-common-widgets'])
@@ -13,17 +14,22 @@
+@endpermission diff --git a/resources/views/partials/widgets/stats_header.blade.php b/resources/views/partials/widgets/stats_header.blade.php index 5d59de50f..546035ea5 100644 --- a/resources/views/partials/widgets/stats_header.blade.php +++ b/resources/views/partials/widgets/stats_header.blade.php @@ -1,3 +1,4 @@ +@permission(['update-common-widgets', 'delete-common-widgets']) - \ No newline at end of file + +@endpermission diff --git a/routes/admin.php b/routes/admin.php index c4e246c97..059874a6b 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -10,7 +10,11 @@ Route::group(['prefix' => 'common'], function () { Route::get('companies/{company}/disable', 'Common\Companies@disable')->name('companies.disable'); Route::resource('companies', 'Common\Companies'); - Route::resource('dashboards', 'Common\Dashboard'); + Route::get('dashboards/{dashboard}/switch', 'Common\Dashboards@switch')->name('dashboards.switch'); + Route::get('dashboards/{dashboard}/enable', 'Common\Dashboards@enable')->name('dashboards.enable'); + Route::get('dashboards/{dashboard}/disable', 'Common\Dashboards@disable')->name('dashboards.disable'); + Route::resource('dashboards', 'Common\Dashboards'); + Route::post('widgets/getData', 'Common\Widgets@getData')->name('widgets.getData'); Route::resource('widgets', 'Common\Widgets'); diff --git a/routes/common.php b/routes/common.php index 40b7bb1ea..1a7923edb 100644 --- a/routes/common.php +++ b/routes/common.php @@ -9,7 +9,7 @@ Route::group(['middleware' => 'auth'], function () { Route::group(['middleware' => ['permission:read-admin-panel']], function () { Route::group(['middleware' => ['menu.admin']], function () { - Route::get('/', 'Common\Dashboard@index')->name('dashboard'); + Route::get('/', 'Common\Dashboards@show')->name('dashboard'); }); Route::get('wizard', 'Wizard\Companies@edit')->name('wizard.edit'); diff --git a/webpack.mix.js b/webpack.mix.js index abf88d8c1..c887f858d 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -31,7 +31,7 @@ mix // Common .js('resources/assets/js/views/common/items.js', 'public/js/common') .js('resources/assets/js/views/common/companies.js', 'public/js/common') - .js('resources/assets/js/views/common/dashboard.js', 'public/js/common') + .js('resources/assets/js/views/common/dashboards.js', 'public/js/common') .js('resources/assets/js/views/common/reports.js', 'public/js/common') .js('resources/assets/js/views/common/search.js', 'public/js/common')