diff --git a/ui/button_actions.md b/ui/button_actions.md index f1817469..f119da9e 100644 --- a/ui/button_actions.md +++ b/ui/button_actions.md @@ -1,6 +1,14 @@ ### Button Actions -When a toolbar button is pressed current controller's `button` or `x_button` method is called. This is tru with the exception of some client-side only actions. +Toolbar button actions can be server-side or client-side. + +Currently most buttons are server-side but the preferred way of writing new +code is calling the API from client-side button actions. + +#### Server-side Button Actions + +When a toolbar button is pressed current controller's `button` or `x_button` +method is called. The identifier of the button that was pressed is passed in `params[:pressed]`. @@ -12,6 +20,14 @@ The `x_button` or `button` handlers should follow this pattern: end ``` -Meaning that just a lookup in the list of valid actions for the controller is done and the action is called if found. Nothing else. +Meaning that just a lookup in the list of valid actions for the controller is +done and the action is called if found. Nothing else. + +Cleaning up the handlers to this form will allow us to do furter refactorings +and make the button actions plugable. + +#### Client-side Button Actions +In [Toolbars and Buttons](toolbars.md#javascript-only-buttons) you can see how to define javascript-only buttons. -Cleaning up the handlers to this form will allow us to do furter refactorings and make the button actions plugable. +Such button can perform changes in the UI or it can call the ManageIQ REST API +to get work done. See [Calling the API](calling_api.md). diff --git a/ui/patterns.md b/ui/patterns.md index ef746f00..aafcc954 100644 --- a/ui/patterns.md +++ b/ui/patterns.md @@ -3,19 +3,22 @@ This guide aims to provide information that allows a quick start for new contributors for the UI. -* [Menus](menus.md) -* [RBAC Features](rbac_features.md) -* [Toolbar and Buttons](toolbars.md) -* [Button Actions](button_actions.md) -* [Page Layout](page_layout.md) -* [Trees, Nodes, Accordions](trees.md) -* [Textual Summaries](textual_summary.md) +* [Page Layout](page_layout.md) -- basic page structure and elements. +* [Menus](menus.md) -- menu sections, subsections, menu items. +* [RBAC](rbac_features.md) -- permission system, verifying acces to features and items. +* [Toolbar and Buttons](toolbars.md) -- how to define toolbars and toolbar buttons. +* [Button Actions](button_actions.md) -- how to react on button presses. +* [Textual Summaries](textual_summary.md) -- entities' details, relations, properties. * [Listnavs](listnav.md) +* [Trees, Nodes, Accordions](trees.md) * [GTL -- Grid, Table, List](gtl.md) -* [Calling the API](calling_api.md) * [Running through the Queue and Busy Waiting](queue_wait.md) * [Quadicons](quadicons.md) * [Reports and Charts](reports_charts.md) * [Topology](topology.md) * [Remote Consoles](remote_consoles.md) * [Angular Components](angular_components.md) +* [Calling the API](calling_api.md) -- how to call the API from the client-side. + +To write new Javascript components for ManageIQ e.g. in Typescript and Angular, please, read +* [UI Components Readme](https://github.com/ManageIQ/ui-components/blob/master/README.md) diff --git a/ui/rbac_features.md b/ui/rbac_features.md index 00f2c2f8..d15f8094 100644 --- a/ui/rbac_features.md +++ b/ui/rbac_features.md @@ -10,4 +10,16 @@ RBAC checking is done for every action and every button in `check_privileges` in `ApplicationController`. Therefore each button, each menu item and each screen needs to have its RBAC feature. -More detailed RBAC checking is done in individual actions both in the UI and the API. +### Checking permissions on individual items + +More detailed RBAC checking is done in individual actions both in the UI and +the API. In `CheckedIdMixin` you can find methods that fetch and verify access +to items selected in the UI. + +Example below fetches cloud volumes whose IDs are either passed in as checked +items from a GTL view or in `params[:id]`. + + +``` + volumes = find_records_with_rbac(CloudVolume, checked_or_params) +``` diff --git a/ui/toolbars.md b/ui/toolbars.md index 0c6ea14f..c8467bae 100644 --- a/ui/toolbars.md +++ b/ui/toolbars.md @@ -40,7 +40,7 @@ class ApplicationHelper::Toolbar::VmCloudsCenter < ApplicationHelper::Toolbar::B ### Buttons -Toolbars consist of button groups and button groups consist of buttons. +Toolbars consist of button groups and button groups consist of buttons. There are 3 types of buttons: @@ -64,7 +64,7 @@ In toolbar definitions text and hover text need to be marked for translation wit instance variables are present and can be used to determine the values of the texts. -Furher values have to be passed in as hash. In the example above it is +Further values have to be passed in as hash. In the example above it is * `:url\_parms`, * `:confirm`, * `:enabled`, @@ -72,7 +72,7 @@ Furher values have to be passed in as hash. In the example above it is Very important key is * :`klass`. - + Toolbars are rendered into JSON by the ManageIQ and then processed by toolbar component from the [ui-components repository](https://github.com/ManageIQ/ui-components) #### Button details @@ -91,16 +91,47 @@ etc. has particular **feature**. Example usage: ```ruby -button( - :vm_collect_running_processes, - 'fa fa-eyedropper fa-lg', - N_('Extract Running Processes for this VM'), - N_('Extract Running Processes'), - :confirm => N_("Extract Running Processes for this VM?"), - :klass => ApplicationHelper::Button::GenericFeatureButtonWithDisable, - :options => {:feature => :collect_running_processes}), +button( + :vm_collect_running_processes, + 'fa fa-eyedropper fa-lg', + N_('Extract Running Processes for this VM'), + N_('Extract Running Processes'), + :confirm => N_("Extract Running Processes for this VM?"), + :klass => ApplicationHelper::Button::GenericFeatureButtonWithDisable, + :options => {:feature => :collect_running_processes}), ``` The feature to be tested is passed in the :options hash as :feature. All content of the :options is passed to the Button classes and can be used to parametrize generic button classes. + +### Javascript-only buttons + +You can create buttons that don't need a client--server roundtrip when pressed. Such buttons instead call some javascript function, talk to Angular components or send RxJS messages to perform their action. + +Example of such button definition: +``` + button_group('middleware_server_operations', [ + select( + :middleware_server_power_choice, + 'fa fa-power-off fa-lg', + t = N_('Power'), + t, + :items => [ + button( + :middleware_server_shutdown, + nil, + N_('Gracefully shut this server down'), + N_('Gracefully shutdown Server'), + :image => 'guest_shutdown', + :data => {'toggle' => 'modal', + 'target' => '#modal_param_div', + 'function' => 'sendDataWithRx', + 'function-data' => '{"type": "mwServerOps", "operation": "shutdown", "timeout": 0}'}, + :klass => ApplicationHelper::Button::MiddlewareStandaloneServerAction), +... +``` + +Under `:data` you need to set 2 important keys: + * `:function`, defines javascript function to be called when the button is pressed, + * `:function-data`, defines arguments to be passed to the function.