Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Add Ajax support to Quick button 馃槑 #5512

Merged
merged 12 commits into from
May 30, 2024
Merged

Conversation

karandatwani92
Copy link
Contributor

@karandatwani92 karandatwani92 commented Apr 26, 2024

WHY

The quick button is good for us(lazy devs), but Ajax support was missing.

Creating an Ajax button manually takes time. What if one project needs multiple Ajax buttons?
Everyone loves seamless UI(but with less effort).

AFTER

Now, We can create buttons quickly that support Ajax calling. Just add one attribute to have it.

  • On success: it shows a notification.
  • On Failure: it shows an alert.
Screen.Recording.2024-04-26.at.7.35.16.PM.mov

Is it a breaking change?

NO

How can we test the before & after?

It picks the URL from the same old href attribute, which was either user-provided or autogenerated.

Example:
I created an operation and used the following button to send invoices.

CRUD::button('send')->stack('line')->view('crud::buttons.quick')->meta([
            'access' => true,
            'label' => 'Send Invoice',
            'icon' => 'la la-envelope',
            'ajax' => true,
        ]);

OR

CRUD::button('send')->stack('line')->view('crud::buttons.quick')->meta([
            'access' => true,
            'label' => 'Send Invoice',
            'icon' => 'la la-envelope',
            'wrapper' => [
                'href' => url(('admin/dashboard')), // to change URL(nothing new)
            ],
            'ajax' => [
               // optional attributes
                'method' => 'GET',
                'refreshCrudTable' => true, // to refresh table on success
                'success_title' => "asas\'sds\"",
                'success_message' => 'The payment reminder has been sent successfully.',
                'error_title' => 'Error',
                'error_message' => 'There was an error sending the payment reminder. Please try again.',
            ],
        ]);

karandatwani92 and others added 2 commits April 26, 2024 19:59
@tabacitu
Copy link
Member

tabacitu commented May 16, 2024

@pxpm will you please give this a review / polish? I think it's a small, quick, cool thing we can launch by the end of the month.

One note I see right away is that the notification text&type should probably NOT be defined in the blade file. But in the PHP that returns the response. That way, you could return different notifications depending on success/error. You might see other stuff, personally I only saw that one as pretty important and worth changing.

Wait no. I also saw that you have different notification types on success/error. On success you have bubble notification, on error sweetalert. No bueno - let's make them both regular bubble alerts - it's much simpler and good enough.

Anything else?

@tabacitu tabacitu removed their assignment May 16, 2024
@karandatwani92
Copy link
Contributor Author

karandatwani92 commented May 17, 2024

Hey @tabacitu @pxpm

I have my opinion here. Why I chose:

  • sweetalert on error.
  • bubble notification on success.

Imagine I'm the admin and want to send payment reminders to users with the due amount. I filtered the users on CRUD.
Now I simply want to click click click on all rows. If everything is going smoothly, success bubble notifications rain without interrupting me.

If some row click in the middle has a problem causing an error, the sweet alert will interrupt and stop my finger click reflex action to click the next row & I'll be able to remember what I clicked last, identifying which row had the problem.

But if we implement bubble notification on error, it will not stop my finger click reflex action and the error will be mixed in the raining notification, and it would be hard for me to identify the row with the error. Bubble notification also dismisses itself, so I might now be able to read the info in the short visible timespan.

But with the error on sweet alert, I can patiently read the error and proceed further.

Copy link
Contributor

@pxpm pxpm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @karandatwani92, good job 馃檹

I haven't tested this yet in actual scenarios, lets first clarify some points and then we move on.

I've left some inline comments, and I still have some questions/concerns.

I agree with Cristian in regard to alert for sucess/swal for error. I think you are trying to push a UX that's not very good. The example you gave is a perfect example of when you should use bulk actions, not click on every row. Just filter what you want, select all and "Do something" only once.

There are also two questions that I think they will come up when we use this in a variety of scenarios, eg:

1) How can I reload the datatable after the ajax response ? Should I be able to ? I think yes right ? It's what happens for example in the Trash button. https://github.com/Laravel-Backpack/PRO/blob/edf0f8670eeb8f9dbd102937bcff380af197e747/resources/views/buttons/trash.blade.php#L47

2) Can I have custom messages for my users or can I just return success/error status code from the endpoint?

Let me know what you think.

Cheers

src/resources/views/crud/buttons/quick.blade.php Outdated Show resolved Hide resolved
src/resources/views/crud/buttons/quick.blade.php Outdated Show resolved Hide resolved
src/resources/views/crud/buttons/quick.blade.php Outdated Show resolved Hide resolved
src/resources/views/crud/buttons/quick.blade.php Outdated Show resolved Hide resolved
src/resources/views/crud/buttons/quick.blade.php Outdated Show resolved Hide resolved
@pxpm pxpm assigned karandatwani92 and unassigned pxpm May 22, 2024
@karandatwani92
Copy link
Contributor Author

Hey @pxpm

Thanks for the feedback; I have left a few comments and resolved a few as directed. Now, coming to major questions:

  1. How can I reload the data table after the Ajax response?
    -- Nice idea, but I wouldn't say I like the whole data table reload. A single-element reload would look nice. What do you think about it & how would you implement it?

  2. Can I have custom messages for my users or return the success/error status code from the endpoint?
    -- I just pushed a few commits for this. If abort() or some exception, it will display an error message from the server. If the success message is passed, it will display the server response message; if unavailable - it will display the default message. If one uses some external API and can't change the response, he can set success/error messages via the field attribute.

@pxpm
Copy link
Contributor

pxpm commented May 24, 2024

How can I reload the data table after the Ajax response?
-- Nice idea, but I wouldn't say I like the whole data table reload. A single-element reload would look nice. What do you think about it & how would you implement it?

I think single element is not something achievable in datatables. What we do as I've showed in trash, is that we check if there is only one item in the current table, if we have only one we will move to the previous page, and after that we call the datatable redraw. But that only works in trash and delete, that we are sure the entry is deleted/removed from the dataset.

In this case, most likely the entry will not be deleted, so I think we shouldn't move to the previous page and only call the redraw. If needed in the future we can add that option like removesEntryFromTable => true/false

I think an "easy-way" to add the reload option without much bell and whistles is to add an option like:
refreshCrudTable - true/false, in case true we run our reload table script, it can be false by default.

@pxpm
Copy link
Contributor

pxpm commented May 24, 2024

Another thing that may come handy and may be requested, is a way to "wait for request completion", something like a loading state, instead of allowing the user to send multiple requests at once.

This can be worked out later if needed, I just wanted to let this written here. 馃憤

@pxpm pxpm assigned karandatwani92 and unassigned pxpm May 24, 2024
@karandatwani92
Copy link
Contributor Author

removesEntryFromTable

Optional attribute added:
removesEntryFromTable => true/false

Copy link
Contributor

@pxpm pxpm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just suggested two small changes and I think in terms of semantics/features we are done here.
Would you mind writing the docs for it ?

Cheers

src/resources/views/crud/buttons/quick.blade.php Outdated Show resolved Hide resolved
src/resources/views/crud/buttons/quick.blade.php Outdated Show resolved Hide resolved
@karandatwani92
Copy link
Contributor Author

Docs PR: Laravel-Backpack/docs#581

karandatwani92 and others added 2 commits May 28, 2024 19:36
default message closure

Co-authored-by: Pedro Martins <pxpm88@gmail.com>
Co-authored-by: Pedro Martins <pxpm88@gmail.com>
Co-authored-by: Pedro Martins <pxpm88@gmail.com>
@pxpm
Copy link
Contributor

pxpm commented May 29, 2024

@pxpm will you please give this a review / polish? I think it's a small, quick, cool thing we can launch by the end of the month.

One note I see right away is that the notification text&type should probably NOT be defined in the blade file. But in the PHP that returns the response. That way, you could return different notifications depending on success/error. You might see other stuff, personally I only saw that one as pretty important and worth changing.

Wait no. I also saw that you have different notification types on success/error. On success you have bubble notification, on error sweetalert. No bueno - let's make them both regular bubble alerts - it's much simpler and good enough.

Anything else?

@karandatwani92 I think this is the only thing (apart from my comments) that needs to be addressed.

I've also already comment on it on a previous iteration:

I agree with Cristian in regard to alert for success/swal for error. I think you are trying to push a UX that's not very good. The example you gave is a perfect example of when you should use bulk actions, not click on every row. Just filter what you want, select all and "Do something" only once.

I've read your thoughts on why you disagree with me and Cristian, but if that example is the only argument I don't think that will be enough to convince us to change our mind.

If you can find a better use case for using both, let me know so that we can evaluate.
As a counter to your argument, I would probably return a link to the entry on the notification, so that If I saw one red, I could just click the link on the notification and go to that entry for example.

Let's finish this. 馃挭

karandatwani92 and others added 3 commits May 29, 2024 17:15
Co-authored-by: Pedro Martins <pxpm88@gmail.com>
@pxpm
Copy link
Contributor

pxpm commented May 30, 2024

It's done!
Thank you @karandatwani92 for all the effort here, I am really happy with how it ended and how it works. 馃檹

I just did a little cleanup here e1db6e3

I think this completely drops my concern about separating the file into multiple files as this is now short and easy to reason about.

Good job 馃コ

@pxpm pxpm merged commit 9181d89 into main May 30, 2024
8 checks passed
@pxpm pxpm deleted the quick-button-ajax branch May 30, 2024 07:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

None yet

4 participants