-
Notifications
You must be signed in to change notification settings - Fork 916
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature proposal] Fluent syntax for CRUD #394
Comments
I'll keep this one short and sweet :D
|
|
I had a similar idea wrapping all field and column types in classes to even provide exact code completion for supported attributes depending on field/column type. This would be very helpful when starting to use backpack. And syntax would also be more Laravely. $date = DateCRUDField::name('date')->label('date')->type('date')->value(date('Y-m-d'))->showOnCreate();
$select2 = new Select2CRUDField('category_id')->type('select2')->label('Category')->entity('category')->attribute('name')->model('App\Models\Category');
$this->crud->addField($date);
$this->crud->addField($select2); or even $this->crud->addFields([$date, $select2]); When we want to stick to an Laravel $date = CRUDField::date('date')->label('date')->value(date('Y-m-d'));
$select2 = CRUDField::select2('category_id')->label('Category')->entity('category')->attribute('name')->model('App\Models\Category'); And instead of real classes just return some contract to get intelligent code completion depending on field/column type. What do you think? |
Hi @OliverZiegler , I think One problem I see, though, is the name convention. I really don't like prefixing or suffixing all classes with CRUD, looks bad and it is confusing (in case we split it up, some methods will not be for all actions - CREATE, READ, UPDATE, DELETE, but just for a few of them. Yet you type CRUD for each of them). Maybe we find a solution together. Say: // general
Panel::setModel("App\Models\Example");
Panel::setRoute("admin/example");
Panel::setRouteName("admin.example");
Panel::setEntityNameStrings("example", "examples");
Fields::setFromDb(); // automatically set fields and columns from your database columns
Columns::setFromDb();
// ------ FIELDS
Fields::add($field_definition_array)->forAction('update/create/both');
Fields::add($array_of_fields_definition_arrays)->forAction('update/create/both');
Fields::remove('name')->forAction('update/create/both');
Fields::remove($array_of_names->forAction('update/create/both');
// ------ COLUMNS
Columns::add(); // add a single column, at the end of the stack
Columns::add([]); // add multiple columns, at the end of the stack
Columns::remove('column_name'); // remove a column from the stack
Columns::remove(['column_name_1', 'column_name_2']); // remove an array of columns from the stack
Columns::setDetails('column_name', ['attribute' => 'value']);
Columns::setDetails(['column_1', 'column_2'], ['attribute' => 'value']);
Columns::set(); // set the columns you want in the table view, either as array of column names, or multidimensional array with all columns detailed with their types
// ------ REORDER FIELDS
Fields::add()->before('name'); // will show this before the given field
Fields::add()->after('name'); // will show this after the given field
// ------ REORDER COLUMNS
Columns::add()->before('name'); // will show this before the given column
Columns::add()->after('name'); // will show this after the given column
// ------ CRUD BUTTONS
// possible positions: 'beginning' and 'end'; defaults to 'beginning' for the 'line' stack, 'end' for the others;
Buttons::add($stack, $name, $type, $content, $position); // add a button; possible types are: view, model_function
Buttons::addFromModelFunction($stack, $name, $model_function_name, $position); // add a button whose HTML is returned by a method in the CRUD model
Buttons::addFromView($stack, $name, $view, $position); // add a button whose HTML is in a view placed at resources\views\vendor\backpack\crud\buttons
Buttons::remove($name);
Buttons::removeFromStack($name, $stack);
// ------ ACCESS
Panel::allowAccess('list');
Panel::allowAccess(['list', 'create', 'delete']);
Panel::denyAccess('list');
Panel::denyAccess(['list', 'create', 'delete']);
Panel::hasAccess('add'); // returns true/false
Panel::hasAccessOrFail('add'); // throws 403 error
Panel::hasAccessToAll(['create', 'update']); // returns true/false
Panel::hasAccessToAny(['create', 'update']); // returns true/false
// ------ REORDER
Reorder::enable('label_name', MAX_TREE_LEVEL);
// NOTE: you also need to do allow access to the right users: $this->crud->allowAccess('reorder');
Reorder::disable();
Reorder::isEnabled(); // return true/false
// ------ DETAILS ROW
Panel::enableDetailsRow();
// NOTE: you also need to do allow access to the right users: $this->crud->allowAccess('details_row');
// NOTE: you also need to do overwrite the showDetailsRow($id) method in your EntityCrudController to show whatever you'd like in the details row OR overwrite the views/backpack/crud/details_row.blade.php
Panel::disableDetailsRow();
// ------ REVISIONS
// You also need to use \Venturecraft\Revisionable\RevisionableTrait;
// Please check out: https://laravel-backpack.readme.io/docs/crud#revisions
Panel::allowAccess('revisions');
// ------ AJAX TABLE VIEW
// Please note the drawbacks of this though:
// - 1-n and n-n relationship columns won't be searched anymore;
// - date and datetime columns won't be sortable anymore;
Panel::enableAjaxTable();
// ------ DATATABLE EXPORT BUTTONS
// Show export to PDF, CSV, XLS and Print buttons on the table view.
// Does not work well with AJAX datatables.
Panel::enableExportButtons();
// ------ ADVANCED QUERIES
Panel::addClause('active');
Panel::addClause('type', 'car');
Panel::addClause('where', 'name', '=', 'car');
Panel::addClause('whereName', 'car');
Panel::addClause('whereHas', 'posts', function($query) {
$query->activePosts();
});
Panel::orderBy();
Panel::groupBy();
Panel::limit(); Etc. Do you see any problems to this? Think it would conflict with other class names? |
If you were worried about naming conflicts, you could keep the classes all CRUDPanel:setModel But when you import the class alias it? use Backpack\CrudPanel as Panel; |
@OwenMelbz so true. That's a simple solution :-) |
Is there any progress on this? I'm currently wondering how to achieve this as a standalone package as I can't remember all the fields and columns and hate always looking them up in the docs. How could this My suggestion (for a first standalone package) would be:
$date = CRUDField::date('date')->label('date')->value(date('Y-m-d'));
$select2 = CRUDField::select2('category_id')->label('Category')->entity('category')->attribute('name')->model('App\Models\Category');
For Backpack updates we could just use the What do you think? |
@OliverZiegler I was thinking we could use Facades for that. Similar to how you can do |
@tabacitu Sounds good. Will have a closer look on how facades work and start working on it in a fork. Any more input on this I should know? |
Not really, no. Ideally all these Facades should point to the same object - |
Ok. Will tell you when there is code to review |
👿 Devil's Advocate WARNING What would this improve over other PRs (such as merging in all the fixes to data tables etc)? |
@lloy0076 not sure what you mean. I think this would help new users get started easier and speed up your own process as you don't need to remember everything or look it up in the docs 😉 |
@lloy0076 - apples and oranges. I expect ALL existing PRs to be merged or closed in the next 1-2 weeks, as we prepare for the next breaking change. Bold plan, I know :-) |
Started implementing this here. Currently available Facades:
What do you think? Should I proceed like this for the fields? |
Hi @OliverZiegler - I've bundled it into a PR so it's easier to see the difference - https://github.com/Laravel-Backpack/CRUD/pull/826/files - but won't merge it until it's ready (of course). Thanks for the short feedback loop. I'll take a look at it ASAP and come back to you - lots to think about and ponder about this... |
My two cents here: For every new concept introduced, there's a cost in learning. My opinion is: keep it simple, and then, make it simpler. This would be good:
How to make it simpler?
How to make it simpler? look at this beauty:
|
@eduardoarandah thats basically what it does now xD $this->crud->addColumns([
['name' => 'name'],
['name' => 'email'],
['name' => 'phone'],
]); |
really? then it's perfect does it accept a single string like this? haven't checked
|
I think this currently won't work. The intention behind this feature was, that your IDE can help you remember different column/field types by providing the options via code completion... |
Yes, but I don't use an IDE and there are at 80+ open issues and the AJAX functionality is still, at best, wobbly... |
@tabacitu @OliverZiegler @eduardoarandah - this is a good idea but until "someone" has the time to implement it, it's cluttering up the issue boards. |
Started implementing this in #826 but waiting for some feedback for a while now. |
I'm going to close this in favour of discussion in #826. |
I think I just had an epiphany, because all these changes seem excellent to me AND I think they're backwards-compatible:
(1) What if we use a Facade for the CRUD, and use
CRUD::addField()
instead of$this->crud->addField()
? Shorter is better, right?(2) What if we also create a fluent syntax for defining fields, columns, etc, like Laravel 5.4 does with its routes (
Route::name('users.index')->middleware('auth');
)?We could then use both this:
AND this:
I'm super-excited about this, because
but I don't exactly have strong technical reasons... Thoughts?
The text was updated successfully, but these errors were encountered: