refatrar / dynamic-dashboard-design
Reusable dynamic dashboard design package for Laravel with Inertia and Vue.
Package info
github.com/refatrar/dynamic-dashboard-design
Language:Vue
pkg:composer/refatrar/dynamic-dashboard-design
Requires
- php: ^8.3
- inertiajs/inertia-laravel: ^3.0
- laravel/framework: ^13.0
Requires (Dev)
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
README
Reusable Laravel package for building configurable dynamic dashboards with Inertia.js, Vue 3, and Chart.js.
Packagist: refatrar/dynamic-dashboard-design
Source: github.com/refatrar/dynamic-dashboard-design
1. Introduction
refatrar/dynamic-dashboard-design extracts the Dynamic Dashboard Design module into a standalone Laravel package. It includes:
- Backend controllers, services, models, migrations, and routes
- Vue dashboard designer and live dashboard pages
- Chart widgets (bar, line, pie, summary, table, and more)
- Whitelist-based database security
- Configurable routes, middleware, and allowed tables/columns
The host application keeps authentication, layouts, and shared UI components.
2. Features
- Drag-and-drop dashboard designer
- Grid layouts (1–5 columns)
- 21 chart/widget types
- Secure query builder (no arbitrary SQL by default)
- Configurable route prefix and middleware
- Publishable Vue assets
- Package-owned migrations for layouts, chart types, and saved designs
3. Requirements
- PHP 8.3+
- Laravel 13+
- Inertia.js Laravel 3+
- Vue 3+
- Node.js 20+ and npm
- MySQL, PostgreSQL, or SQLite
Host application frontend dependencies
The published Vue assets expect these host dependencies:
@inertiajs/vue3chart.jsvue-chartjs@iconify/vue(optional, used for icons)- Host UI components under
@/components/ui/*(Button, Input, Select, Sheet, Checkbox, Label, Spinner)
4. Laravel Compatibility
| Package version | Laravel |
|---|---|
| 1.0.x | 13.x |
5. Installation
Step 1 — Require from Packagist
Install via Composer (Packagist):
composer require refatrar/dynamic-dashboard-design
Or add it to your application composer.json:
{
"require": {
"refatrar/dynamic-dashboard-design": "^1.0"
}
}
Then run:
composer update refatrar/dynamic-dashboard-design
Expected result:
- Package installed under
vendor/refatrar/dynamic-dashboard-design - Service provider auto-discovered by Laravel
Optional — local path repository (package development only)
{
"repositories": [
{
"type": "path",
"url": "packages/dynamic-dashboard-design",
"options": {
"versions": {
"refatrar/dynamic-dashboard-design": "1.0.1"
}
}
}
],
"require": {
"refatrar/dynamic-dashboard-design": "^1.0"
}
}
Step 2 — Publish Configuration
php artisan vendor:publish --tag=dynamic-dashboard-design-config
Expected result: config/dynamic-dashboard-design.php is created.
Step 3 — Run Migrations
Migrations are auto-loaded by the package. You do not need to publish them unless you want to customize the files.
php artisan migrate
Expected result: grids, types, and dashboard_designs tables exist.
Optional (only if you want copies in your app):
php artisan vendor:publish --tag=dynamic-dashboard-design-migrations
Avoid publishing migrations and relying on auto-loaded package migrations on a fresh database if you do not want duplicate migration file paths. Prefer the auto-loaded package migrations for most apps.
Step 4 — Seed Layouts and Chart Types
Recommended:
php artisan dynamic-dashboard-design:seed
Or seed each class directly:
php artisan db:seed --class="Vendor\\DynamicDashboardDesign\\Database\\Seeders\\TypeSeeder" php artisan db:seed --class="Vendor\\DynamicDashboardDesign\\Database\\Seeders\\GridSeeder"
If you get Target class [...] does not exist, rebuild Composer’s autoloader first:
composer dump-autoload
Then run the seed command again.
You can also call the seeders from database/seeders/DatabaseSeeder.php:
use Vendor\DynamicDashboardDesign\Database\Seeders\GridSeeder; use Vendor\DynamicDashboardDesign\Database\Seeders\TypeSeeder; public function run(): void { $this->call([ TypeSeeder::class, GridSeeder::class, ]); }
Note for Packagist 1.0.1: Seeders were only under
database/seedersand were not autoloaded. Upgrade to 1.0.2+ (seeders live undersrc/Database/Seeders), or runcomposer dump-autoloadafter ensuring the classes exist undervendor/refatrar/dynamic-dashboard-design/src/Database/Seeders/.
Step 5 — Configure Database Tables
Edit config/dynamic-dashboard-design.php:
'database' => [ 'tables' => [ 'users' => [ 'columns' => ['id', 'name', 'email', 'created_at'], 'aggregates' => ['count', 'sum', 'avg', 'min', 'max'], 'group_by' => ['id', 'name', 'email', 'created_at'], 'filters' => ['id', 'name', 'email', 'created_at'], 'sort' => ['id', 'name', 'email', 'created_at'], ], ], ],
Step 6 — Configure Routes (optional)
'route' => [ 'prefix' => 'dynamic-dashboard', 'middleware' => ['web', 'auth'], 'name_prefix' => 'dynamic-dashboard-design.', ],
Expected URLs:
- Dashboard:
/dynamic-dashboard - Designer:
/dynamic-dashboard/design
Step 7 — Install Frontend Dependencies
npm install chart.js vue-chartjs @iconify/vue
Step 8 — Publish Frontend Assets
php artisan vendor:publish --tag=dynamic-dashboard-design-assets --force
Expected result:
resources/js/pages/Dashboard.vueresources/js/pages/Dashboard/Design/Create.vueresources/js/components/Dashboard/**resources/js/lib/dashboard/chart-js.tsresources/js/lib/dashboard/chart-colors.tsresources/js/lib/dashboard/chart-data.tsresources/js/lib/dashboard/chart-options.tsresources/js/composables/useDashboardRoutes.tsresources/js/types/dashboard.ts
Chart components import
@/lib/dashboard/chart-js(and related helpers). After publishing, those files must live directly underresources/js/lib/dashboard/, not under a nesteddashboard/dashboard/folder.
Step 9 — Build Frontend
npm run build
For development:
npm run dev
Step 10 — Open Dynamic Dashboard
- Register or log in.
- Visit
/dynamic-dashboard - Open the designer at
/dynamic-dashboard/design
6. Configuration
Full config file: config/dynamic-dashboard-design.php
| Key | Purpose |
|---|---|
route.prefix |
URL prefix for all package routes |
route.middleware |
Middleware applied to package routes |
route.name_prefix |
Route name prefix for route() helpers |
database.connection |
DB connection for widget queries |
database.tables |
Whitelist of allowed tables/columns |
database.default_limit |
Max rows returned per query |
auth.guard |
Auth guard for ownership checks |
auth.users_table |
Users table for foreign keys |
features.custom_query |
Enable/disable custom SQL (default: false) |
inertia.dashboard_page |
Inertia page name for dashboard |
inertia.design_page |
Inertia page name for designer |
7. Database Table Configuration
Only tables listed in database.tables are exposed to the designer.
'users' => [ 'columns' => ['id', 'name', 'email', 'created_at'], 'aggregates' => ['count', 'sum', 'avg', 'min', 'max'], 'group_by' => ['id', 'name', 'email', 'created_at'], 'filters' => ['id', 'name', 'email', 'created_at'], 'sort' => ['id', 'name', 'email', 'created_at'], ],
8. Route Configuration
php artisan route:list --path=dynamic-dashboard
Default route names:
dynamic-dashboard-design.dashboarddynamic-dashboard-design.design.indexdynamic-dashboard-design.design.storedynamic-dashboard-design.design.chart-data.tablesdynamic-dashboard-design.design.chart-data.columnsdynamic-dashboard-design.design.chart-data.preview
9. Frontend Configuration
Published Vue files read package URLs from Inertia shared props via:
import { useDashboardRoutes } from '@/composables/useDashboardRoutes'; const { dashboard, designIndex } = useDashboardRoutes();
Add navigation links in your host layout:
import { useDashboardRoutes } from '@/composables/useDashboardRoutes'; const { dashboard } = useDashboardRoutes(); const mainNavItems = [ { title: 'Dashboard', href: dashboard(), }, ];
Do not import @/routes/dynamic-dashboard-design. Those Wayfinder files are host-generated and are not part of the package.
10. Using the Dashboard
- Log in.
- Visit the dashboard URL.
- Saved widgets render with live data from configured tables.
11. Creating Dashboard Widgets
- Visit
/dynamic-dashboard/design. - Drag a grid layout into the dropzone.
- Configure a chart widget.
- Select allowed table/column values.
- Save the design.
12. Security
- Whitelist-only tables and columns
- No arbitrary SQL execution by default
- Structured preview endpoint instead of raw query execution
- Identifier validation for table/column names
- Allowed operator and aggregate validation
- SELECT-only query builder
- Query limits enforced server-side
13. Testing
Host application
php artisan test --compact tests/Feature/DashboardTest.php tests/Feature/ChartDataTest.php
Package (Testbench)
cd packages/dynamic-dashboard-design composer install composer test
14. Troubleshooting
Route Not Found
php artisan route:list --path=dynamic-dashboard php artisan config:clear
Vite Manifest Not Found
npm install npm run build
Configuration Not Found
php artisan vendor:publish --tag=dynamic-dashboard-design-config php artisan config:clear
Seeder Class Not Found (1.0.1)
composer dump-autoload php artisan dynamic-dashboard-design:seed
Or:
php artisan db:seed --class="Vendor\\DynamicDashboardDesign\\Database\\Seeders\\TypeSeeder" php artisan db:seed --class="Vendor\\DynamicDashboardDesign\\Database\\Seeders\\GridSeeder"
Upgrade to 1.0.2+ for a permanent Packagist fix (seeders under src/Database/Seeders + dynamic-dashboard-design:seed command).
Vue Component Not Found / Chart Import Build Errors
If Vite fails with Could not load @/lib/dashboard/chart-js (or chart-colors, chart-data, chart-options), republish assets and confirm the helpers are flat:
php artisan vendor:publish --tag=dynamic-dashboard-design-assets --force
ls resources/js/lib/dashboard/
# expect: chart-js.ts chart-colors.ts chart-data.ts chart-options.ts types.ts
npm run build
If you still see resources/js/lib/dashboard/dashboard/chart-*.ts, move those files up one directory (or upgrade to package 1.0.2+ and republish).
No Tables in Designer
Add tables to config/dynamic-dashboard-design.php under database.tables.
15. Production Deployment
composer install --no-dev --optimize-autoloader php artisan config:cache php artisan route:cache php artisan migrate --force npm ci npm run build
16. Updating the Package
composer update refatrar/dynamic-dashboard-design php artisan vendor:publish --tag=dynamic-dashboard-design-config php artisan vendor:publish --tag=dynamic-dashboard-design-assets --force php artisan migrate npm run build
Review CHANGELOG.md for breaking changes.
17. Uninstallation
- Remove
refatrar/dynamic-dashboard-designfromcomposer.json - Run
composer update - Delete published assets/config if desired
- Roll back migrations if needed
18. FAQ
Does the package include authentication?
No. Use Laravel Fortify, Breeze, or your existing auth.
Can I use /dashboard instead of /dynamic-dashboard?
Yes. Set route.prefix to dashboard in config.
Does it support custom SQL?
Not by default. Set features.custom_query to true only if you accept the security risk.
Does it require PrimeVue or Pinia?
No. The module uses Inertia Vue 3 and host UI components.