I am trying to create a dashboard where a user can choose which widgets they want to see on their dashboard. Those widgets must be within what his role can do.
Step 1: Create migrations.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateDashboardTilesTable extends Migration
{
public function up()
{
Schema::create('dashboard_tiles', function (Blueprint $table) {
$table->id();
$table->string('widget_type')->nullable();
$table->string('crud_model')->nullable();
$table->string('groupbycolumn')->nullable();
$table->string('title')->nullable();
$table->string('ranges')->nullable();
$table->integer('position')->nullable();
$table->integer('width')->nullable();
$table->integer('height')->nullable();
$table->timestamps();
$table->softDeletes();
});
}
}
Step2 : Create Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class DashboardTile extends Model
{
-----
----
---
--
}
Step3: Livewire Component:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use Illuminate\Support\Facades\Auth;
use App\Models\DashboardTile;
use App\Traits\DashboardTraits;
class DashboardComponent extends Component
{
use DashboardTraits;
public $updatemode=false;
protected $listeners = ['widgetAdded'];
public $modalFormVisible = false;
public $modalWidth = '7xl';
public $aggregate_function,$crud_model,$widget_type,$groupbycolumn,$title,$ranges,$position,$width,$height;
public $groupingcolumns=[];
public function getDashboardWidgetsProperty(){
return $this->widgetAdded();
}
protected $rules = [
'widget_type' => 'required',
'crud_model' => 'required',
'groupbycolumn' => 'required',
'title' => 'required',
'width' => 'required',
'height' => 'required'
];
public function create(){
$this->validate();
DashboardTile::create([
'widget_type' => $this->widget_type,
'crud_model' => $this->crud_model,
'groupbycolumn' => $this->groupbycolumn,
'title' => $this->title,
'ranges' => $this->ranges,
'position'=>$this->position,
'width'=>$this->width,
'height'=>$this->height
]);
$this->refreshPages();
}
public function refreshpages(){
$this->reset();
$this->emitTo('DashboardComponent', 'widgetAdded');
}
public function widgetAdded(){
return DashboardTile::where('created_by','=',Auth::user()->id)->orderBy('position', 'ASC')->get();
}
public function render()
{
return view('dashboard');
}
public function createShowModal()
{
$this->modalFormVisible = true;
}
public function closeCreateModal(){
$this->modalFormVisible = false;
$this->reset();
}
}
Step 4: Create DashboardTraits.
<?php
namespace App\Traits;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Eloquent\Model;
use App\Models\DashboardTile;
trait DashboardTraits
{
public $modelId;
public $modalConfirmDeleteVisible = false;
public function displaymodels(): array
{
$composer = json_decode(file_get_contents(base_path('composer.json')), true);
$models = [];
foreach ((array)data_get($composer, 'autoload.psr-4') as $namespace => $path) {
$models = array_merge(collect(File::allFiles(base_path($path)))
->map(function ($item) use ($namespace) {
$path = $item->getRelativePathName();
return sprintf('\%s%s',
$namespace,
strtr(substr($path, 0, strrpos($path, '.')), '/', '\\'));
})
->filter(function ($class) {
$valid = false;
if (class_exists($class)) {
$reflection = new \ReflectionClass($class);
$valid = $reflection->isSubclassOf(Model::class) &&
!$reflection->isAbstract();
}
return $valid;
})
->values()
->toArray(), $models);
}
return $models;
}
public function displaycolumns($modelname){
$table= $modelname::getModel()->getTable();
$primaryKey = App::make($modelname)->getKeyName();
$cols= Schema::getColumnListing($table);
$colsWithFields = [];
foreach ($cols as $key => $column) {
$columntype= Schema::getColumnType($table,$column);
if(!in_array($column, array($primaryKey,'deleted_by','deleted_at','restored_by'))){
$columnlabel = ucfirst(str_replace('_', ' ', $column));
if( $columntype== 'datetime'){
$colsWithFields[$column.'|DAY'] = 'DAY('.$columnlabel.')';
$colsWithFields[$column.'|DATE'] = 'DATE('.$columnlabel.')';
$colsWithFields[$column.'|MONTH'] = 'MONTH('.$columnlabel.')';
$colsWithFields[$column.'|YEAR'] = 'YEAR('.$columnlabel.')';
}else if( $columntype== 'text') {}
else{
$colsWithFields[$column] = $columnlabel;
}
}
}
return $colsWithFields;
}
public function addDateRangeFilter($query){
switch($this->AvailableRanges){
case 'TODAY':
$query->whereDate('created_at', Carbon::today());
break;
case 'WEEK':
$query->whereBetween('created_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()]);
break;
case 'MONTH':
$query->whereMonth('created_at', date('m'))
->whereYear('created_at', date('Y'));
break;
case 'YEAR':
$query->whereYear('created_at', date('Y'));
break;
}
return $query;
}
public function addSelectFilters($query){
$groupbycolumn= $this->groupbycolumn;
$groupbycolumnArr = explode("|",$groupbycolumn);
if(count($groupbycolumnArr)>1){
switch($groupbycolumnArr[1]){
case 'DAY':
$query->selectRaw('(COUNT(*)) as count, DAYNAME('.$groupbycolumnArr[0].') as label');
break;
case 'DATE':
$query->selectRaw('(COUNT(*)) as count, DATE_FORMAT('.$groupbycolumnArr[0].',"%d/%m/%Y") as label');
break;
case 'YEAR':
$query->selectRaw('(COUNT(*)) as count, YEAR('.$groupbycolumnArr[0].') as label');
break;
case 'MONTH':
$query->selectRaw('(COUNT(*)) as count, MONTHNAME('.$groupbycolumnArr[0].') as label');
break;
default:
$query->selectRaw('(COUNT(*)) as count, ('.$groupbycolumnArr[0].') as label');
break;
}
}
else{
$query->selectRaw('(COUNT(*)) as count, '.$groupbycolumn.' as label');
}
return $query;
}
/**
* Get the ranges available.
*
* @return array
*/
public function getAvailableRangesProperty()
{
return $this->allRanges()[$this->ranges ?? 'all'];
}
public function allRanges(){
return $ranges = [
'Today' => 'TODAY',
'This Week' => 'WEEK',
'This Month' => 'MONTH',
'This Year' => 'YEAR',
'all' => ''
];
}
}
Examples:
I created a package for dashboard widget creating in laravel livewire. You can refer that for more details.