new widget structure

This commit is contained in:
denisdulici
2019-12-31 02:20:10 +03:00
parent 8c6ca5e5fb
commit 71c5caf264
44 changed files with 333 additions and 502 deletions

View File

@@ -2,31 +2,31 @@
namespace App\Abstracts;
use Arrilot\Widgets\AbstractWidget;
use App\Models\Income\Invoice;
use App\Traits\Charts;
use Date;
abstract class Widget extends AbstractWidget
abstract class Widget
{
use Charts;
/**
* The configuration array.
*
* @var array
*/
protected $config = [
'width' => 'col-md-4',
];
public $model;
/**
* Treat this method as a controller action.
* Return view() or other content to display.
*/
public function run()
public function __construct($model = null)
{
return $this->show();
$this->model = $model;
}
public function getDefaultSettings()
{
return [
'width' => 'col-md-4',
];
}
public function view($name, $data = [])
{
return view($name, array_merge(['model' => $this->model], (array) $data));
}
public function applyFilters($model, $args = ['date_field' => 'paid_at'])
@@ -38,7 +38,7 @@ abstract class Widget extends AbstractWidget
$start_date = request()->get('start_date') . ' 00:00:00';
$end_date = request()->get('end_date') . ' 23:59:59';
return $model->whereBetween($args['date_field'], [$start_date, $end_date]);
return $model->whereBetween($args['date_field'], [$start_date, $end_date]);
}
public function calculateDocumentTotals($model)

View File

@@ -10,6 +10,6 @@
"files": [],
"requires": [],
"reports": [],
"settings": [],
"widgets": []
"widgets": [],
"settings": []
}

View File

@@ -3,10 +3,9 @@
namespace App\Http\Controllers\Common;
use App\Abstracts\Http\Controller;
use App\Models\Common\Dashboard as Model;
use App\Models\Common\DashboardWidget;
use App\Http\Requests\Common\Dashboard as Request;
use App\Models\Common\Dashboard as Model;
use App\Models\Common\Widget;
use App\Traits\DateTime;
class Dashboard extends Controller
@@ -40,14 +39,12 @@ class Dashboard extends Controller
// Dashboard
$dashboard = Model::find($dashboard_id);
// Dashboard Widgets
$widgets = DashboardWidget::where('dashboard_id', $dashboard->id)
->where('user_id', $user_id)
->orderBy('sort', 'asc')->get();
// Widgets
$widgets = Widget::where('dashboard_id', $dashboard->id)->orderBy('sort', 'asc')->get();
$financial_start = $this->getFinancialStart()->format('Y-m-d');
return view('common.dashboard.index', compact('dashboards','dashboard', 'widgets', 'financial_start'));
return view('common.dashboard.index', compact('dashboards', 'dashboard', 'widgets', 'financial_start'));
}
/**

View File

@@ -3,10 +3,9 @@
namespace App\Http\Controllers\Common;
use App\Abstracts\Http\Controller;
use App\Models\Common\DashboardWidget as Model;
use App\Models\Common\Widget;
use App\Http\Requests\Common\Widget as Request;
use App\Models\Common\Widget;
use App\Utilities\Widgets as Utility;
class Widgets extends Controller
{
@@ -17,7 +16,7 @@ class Widgets extends Controller
*/
public function index()
{
$widgets = Widget::enabled()->get();
$widgets = Utility::getClasses();
return response()->json($widgets);
}
@@ -30,13 +29,11 @@ class Widgets extends Controller
*/
public function store(Request $request)
{
$request['user_id'] = user()->id;
$request['settings'] = [
'width' => $request->get('width'),
];
$widget = Model::create($request->input());
$widget = Widget::create($request->input());
$settings = $widget->settings;
unset($settings['widget']);
@@ -59,17 +56,17 @@ class Widgets extends Controller
/**
* Show the form for editing the specified resource.
*
* @param Model $dashboard
* @param Widget $widget
*
* @return Response
*/
public function edit(Model $widget)
public function edit(Widget $widget)
{
$settings = $widget->settings;
unset($settings['widget']);
return response()->json([
'widget_id' => $widget->widget_id,
'class' => $widget->class,
'name' => $widget->name,
'settings' => $settings,
'sort' => $widget->sort,
@@ -79,14 +76,12 @@ class Widgets extends Controller
/**
* Update the specified resource in storage.
*
* @param Model $dashboard
* @param Widget $widget
* @param $request
* @return Response
*/
public function update(Model $widget, Request $request)
public function update(Widget $widget, Request $request)
{
$request['user_id'] = user()->id;
$request['settings'] = [
'width' => $request->get('width'),
];
@@ -102,7 +97,7 @@ class Widgets extends Controller
'error' => false,
'message' => trans('messages.success.added', ['type' => $widget->name]),
'data' => [
'widget_id' => $widget->widget_id,
'class' => $widget->class,
'name' => $widget->name,
'settings' => $settings,
'sort' => $widget->sort,
@@ -114,11 +109,11 @@ class Widgets extends Controller
/**
* Remove the specified resource from storage.
*
* @param Model $dashboard
* @param Widget $widget
*
* @return Response
*/
public function destroy(Model $widget)
public function destroy(Widget $widget)
{
$message = trans('messages.success.deleted', ['type' => $widget->name]);

View File

@@ -28,7 +28,7 @@ class DeleteUser extends Job
{
$this->authorize();
$this->deleteRelationships($this->user, ['dashboards', 'dashboard_widgets']);
$this->deleteRelationships($this->user, ['widgets', 'dashboards']);
$this->user->delete();

View File

@@ -33,9 +33,9 @@ class DeleteCompany extends Job
$this->deleteRelationships($this->company, [
'accounts', 'bills', 'bill_histories', 'bill_items', 'bill_item_taxes', 'bill_statuses', 'bill_totals', 'categories',
'contacts', 'currencies', 'dashboards', 'dashboard_widgets', 'email_templates', 'invoices', 'invoice_histories',
'invoice_items', 'invoice_item_taxes', 'invoice_statuses', 'invoice_totals', 'items', 'modules', 'module_histories',
'reconciliations', 'recurring', 'reports', 'settings', 'taxes', 'transactions', 'transfers', 'widgets',
'contacts', 'currencies', 'dashboards', 'email_templates', 'invoices', 'invoice_histories', 'invoice_items',
'invoice_item_taxes', 'invoice_statuses', 'invoice_totals', 'items', 'modules', 'module_histories', 'reconciliations',
'recurring', 'reports', 'settings', 'taxes', 'transactions', 'transfers', 'widgets',
]);
$this->company->delete();

View File

@@ -62,9 +62,9 @@ class User extends Authenticatable
return $this->hasMany('App\Models\Common\Dashboard');
}
public function dashboard_widgets()
public function widgets()
{
return $this->hasMany('App\Models\Common\DashboardWidget');
return $this->hasManyThrough('App\Models\Common\Widget', 'App\Models\Common\Dashboard');
}
/**

View File

@@ -98,11 +98,6 @@ class Company extends Eloquent
return $this->hasMany('App\Models\Common\Dashboard');
}
public function dashboard_widgets()
{
return $this->hasMany('App\Models\Common\DashboardWidget');
}
public function email_templates()
{
return $this->hasMany('App\Models\Common\EmailTemplate');

View File

@@ -27,7 +27,7 @@ class Dashboard extends Model
public function widgets()
{
return $this->hasMany('App\Models\Common\DashboardWidget')->orderBy('sort', 'asc');
return $this->hasMany('App\Models\Common\Widget')->orderBy('sort', 'asc');
}
public function user()

View File

@@ -1,65 +0,0 @@
<?php
namespace App\Models\Common;
use App\Abstracts\Model;
class DashboardWidget extends Model
{
protected $table = 'dashboard_widgets';
/**
* Attributes that should be mass-assignable.
*
* @var array
*/
protected $fillable = ['company_id', 'user_id', 'dashboard_id', 'widget_id', 'name', 'settings', 'sort'];
/**
* The attributes that should be casted to native types.
*
* @var array
*/
protected $casts = [
'settings' => 'array',
];
public function user()
{
return $this->belongsTo('App\Models\Auth\User', 'user_id', 'id');
}
public function dashboard()
{
return $this->belongsTo('App\Models\Common\Dashboard');
}
public function widget()
{
return $this->belongsTo('App\Models\Common\Widget');
}
public function getNameAttribute($value)
{
if ($value) {
return $value;
}
return $this->widget->name;
}
public function getSettingsAttribute($value)
{
if (!empty($value)) {
$value = json_decode($value, true);
$value['widget'] = $this;
} else {
$value = [
'widget' => $this,
];
}
return $value;
}
}

View File

@@ -16,14 +16,7 @@ class Widget extends Model
*
* @var array
*/
protected $fillable = ['company_id', 'name', 'alias', 'settings', 'enabled'];
/**
* Sortable columns.
*
* @var array
*/
public $sortable = ['name', 'alias', 'enabled'];
protected $fillable = ['company_id', 'dashboard_id', 'class', 'name', 'settings', 'sort'];
/**
* The attributes that should be casted to native types.
@@ -31,16 +24,11 @@ class Widget extends Model
* @var array
*/
protected $casts = [
'settings' => 'array',
'settings' => 'object',
];
public function dashboard_widgets()
public function dashboard()
{
return $this->hasMany('App\Models\Common\DashboardWidget');
}
public function dashboard_widget()
{
return $this->belongsTo('App\Models\Common\DashboardWidget', 'id', 'widget_id')->where('dashboard_id', 1);
return $this->belongsTo('App\Models\Common\Dashboard');
}
}

View File

@@ -20,6 +20,10 @@ class Blade extends ServiceProvider
Facade::directive('date', function ($expression) {
return "<?php echo company_date($expression); ?>";
});
Facade::directive('widget', function ($expression) {
return "<?php echo show_widget($expression); ?>";
});
}
/**

67
app/Utilities/Widgets.php Normal file
View File

@@ -0,0 +1,67 @@
<?php
namespace App\Utilities;
use App\Models\Module\Module;
class Widgets
{
public static function getClasses()
{
$classes = [];
$core_classes = [
'App\Widgets\TotalIncome',
'App\Widgets\TotalExpenses',
'App\Widgets\TotalProfit',
'App\Widgets\CashFlow',
'App\Widgets\IncomeByCategory',
'App\Widgets\ExpensesByCategory',
'App\Widgets\AccountBalance',
'App\Widgets\LatestIncome',
'App\Widgets\LatestExpenses',
];
static::parseClasses($classes, $core_classes);
$modules = Module::enabled()->get();
foreach ($modules as $module) {
$m = module($module->alias);
// Check if the module exists and has widgets
if (!$m || empty($m->get('widgets'))) {
continue;
}
static::parseClasses($classes, $m->get('widgets'));
}
return $classes;
}
protected static function parseClasses(&$classes, $list)
{
foreach ($list as $class) {
if (!class_exists($class)) {
continue;
}
$name = (new $class())->getDefaultName();
$classes[$class] = $name;
}
}
public static function getInstance($model)
{
$class = $model->class;
return new $class($model);
}
public static function show($model)
{
return static::getInstance($model)->show();
}
}

View File

@@ -1,6 +1,7 @@
<?php
use App\Traits\DateTime;
use App\Utilities\Widgets;
use Jenssegers\Date\Date;
if (!function_exists('user')) {
@@ -37,3 +38,15 @@ if (!function_exists('company_date')) {
return Date::parse($date)->format($date_time->getCompanyDateFormat());
}
}
if (!function_exists('show_widget')) {
/**
* Format the given date based on company settings.
*
* @return string
*/
function show_widget($model)
{
return Widgets::show($model);
}
}

View File

@@ -11,9 +11,13 @@ class AccountBalance extends Widget
{
$accounts = Account::enabled()->take(5)->get();
return view('widgets.account_balance', [
'config' => (object) $this->config,
return $this->view('widgets.account_balance', [
'accounts' => $accounts,
]);
}
public function getDefaultName()
{
return trans('widgets.account_balance');
}
}

View File

@@ -13,10 +13,6 @@ class CashFlow extends Widget
{
use Currencies, DateTime;
protected $config = [
'width' => 'col-md-12',
];
public function show()
{
$financial_start = $this->getFinancialStart()->format('Y-m-d');
@@ -96,8 +92,7 @@ class CashFlow extends Widget
])
->fill(false);
return view('widgets.cash_flow', [
'config' => (object) $this->config,
return $this->view('widgets.cash_flow', [
'chart' => $chart,
]);
}
@@ -175,4 +170,16 @@ class CashFlow extends Widget
return $profit;
}
public function getDefaultName()
{
return trans('widgets.cash_flow');
}
public function getDefaultSettings()
{
return [
'width' => 'col-md-12',
];
}
}

View File

@@ -7,10 +7,6 @@ use App\Models\Setting\Category;
class ExpensesByCategory extends Widget
{
protected $config = [
'width' => 'col-md-6',
];
public function show()
{
Category::with('expense_transactions')->type('expense')->enabled()->each(function ($category) {
@@ -27,9 +23,20 @@ class ExpensesByCategory extends Widget
$chart = $this->getDonutChart(trans_choice('general.expenses', 2), 0, 160, 6);
return view('widgets.expenses_by_category', [
'config' => (object) $this->config,
return $this->view('widgets.expenses_by_category', [
'chart' => $chart,
]);
}
public function getDefaultName()
{
return trans('widgets.expenses_by_category');
}
public function getDefaultSettings()
{
return [
'width' => 'col-md-6',
];
}
}

View File

@@ -7,10 +7,6 @@ use App\Models\Setting\Category;
class IncomeByCategory extends Widget
{
protected $config = [
'width' => 'col-md-6',
];
public function show()
{
Category::with('income_transacions')->type('income')->enabled()->each(function ($category) {
@@ -27,9 +23,20 @@ class IncomeByCategory extends Widget
$chart = $this->getDonutChart(trans_choice('general.incomes', 1), 0, 160, 6);
return view('widgets.income_by_category', [
'config' => (object) $this->config,
return $this->view('widgets.income_by_category', [
'chart' => $chart,
]);
}
public function getDefaultName()
{
return trans('widgets.income_by_category');
}
public function getDefaultSettings()
{
return [
'width' => 'col-md-6',
];
}
}

View File

@@ -11,9 +11,13 @@ class LatestExpenses extends Widget
{
$transactions = $this->applyFilters(Transaction::with('category')->type('expense')->orderBy('paid_at', 'desc')->isNotTransfer()->take(5))->get();
return view('widgets.latest_expenses', [
'config' => (object) $this->config,
return $this->view('widgets.latest_expenses', [
'transactions' => $transactions,
]);
}
public function getDefaultName()
{
return trans('widgets.latest_expenses');
}
}

View File

@@ -11,9 +11,13 @@ class LatestIncome extends Widget
{
$transactions = $this->applyFilters(Transaction::with('category')->type('income')->orderBy('paid_at', 'desc')->isNotTransfer()->take(5))->get();
return view('widgets.latest_income', [
'config' => (object) $this->config,
return $this->view('widgets.latest_income', [
'transactions' => $transactions,
]);
}
public function getDefaultName()
{
return trans('widgets.latest_income');
}
}

View File

@@ -36,9 +36,13 @@ class TotalExpenses extends Widget
'progress' => $progress,
];
return view('widgets.total_expenses', [
'config' => (object) $this->config,
return $this->view('widgets.total_expenses', [
'totals' => $totals,
]);
}
public function getDefaultName()
{
return trans('widgets.total_expenses');
}
}

View File

@@ -30,15 +30,19 @@ class TotalIncome extends Widget
}
$totals = [
'current' => $current,
'open' => money($open, setting('default.currency'), true),
'overdue' => money($overdue, setting('default.currency'), true),
'progress' => $progress,
'current' => $current,
'open' => money($open, setting('default.currency'), true),
'overdue' => money($overdue, setting('default.currency'), true),
'progress' => $progress,
];
return view('widgets.total_income', [
'config' => (object) $this->config,
return $this->view('widgets.total_income', [
'totals' => $totals,
]);
}
public function getDefaultName()
{
return trans('widgets.total_income');
}
}

View File

@@ -55,9 +55,13 @@ class TotalProfit extends Widget
'progress' => $progress,
];
return view('widgets.total_profit', [
'config' => (object) $this->config,
return $this->view('widgets.total_profit', [
'totals' => $totals,
]);
}
public function getDefaultName()
{
return trans('widgets.total_profit');
}
}