Let's assume the following scenario: in a kanban view with a
domain, remove that domain and quickly click on a record to open it
in form view. On a slow network, it may happen that the reload of
the kanban view (triggered by the domain change) returns after the
load of the form view.
Before this rev., when this happened, the form view was correctly
displayed but the control panel contained the buttons, searchview,
pager... of the kanban view.
Note that this fix is quite ugly, but it won't be necessary anymore
as soon as the control panel won't be shared between actions and
controllers, i.e. as soon as each controller will have its own
control panel.
With this commit, we introduce a better screen to manipulate the search
view in a mobile device.
Note: most of this work was initially done by suh-odoo, then was adapted
and moved to community by myself.
task 31464
... in session_storage.
The current action is stored in the session_storage (stringified),
so that it can always be restored on F5 (useful for dynamic
actions). Before this rev., it was stored with it's 'raw' context,
i.e. before its evaluation. However, when this context is an
instance of a CompoundContext, it is meaningless once restored.
So this rev. ensures that the action is stored with its evaluated
context.
In some situations, it could happen that the action manager had a
rejected deferred representing the creation of a view, and was blocked
from doing any other interaction with that view.
For example, imagine that a read operation crashes for record 1 on the
model res.partner. If the user is on the kanban view and click on
record 1, there will be an error dialog informing him of the error.
However, if the user clicks then on another record, nothing will happen
because the action manager is blocked (only the form view in this case).
With this commit, whenever the view creation process failed, we also
remove the rejected deferred so the action manager will be allowed to
try again.
this.call('web.Notification', 'notify', params)
Display a notification at the appropriate location, and returns the
reference id to the same widget. Note that this method does not wait
for the appendTo method to complete.
@param {Object} params
@param {string} params.title notification title
@param {string} params.message notification main message
@param {string} params.type 'notification' or 'warning'
@param {boolean} [params.sticky=false] if true, the notification will stay
visible until the user clicks on it.
@param {string} [params.className] className to add on the dom
@param {function} [params.onClose] callback when the user click on the x
or when the notification is auto close (no sticky)
@param {Array<Object>} params.buttons
@param {function} params.buttons[0].click callback on click
@param {Boolean} [params.buttons[0].primary] display the button as primary
@param {string} [params.buttons[0].text] button label
@param {string} [params.buttons[0].icon] font-awsome className or image src
@returns {Number} notification id
this.call('web.Notification', 'close', notificationId)
Reproduce the issue:
- open the manual reconciliation (it is a client action)
- add a reconciliation (using the + sign)
- expand it (using the > sign)
- put the focus on the first field and hit TAB
--> you would expect that the focus moves to the second field
--> what happens is: the focus stays on the first field
Before this fix, when in a client action (or any place that contains
fields) that contains fields, the keyboard navigation did not occur
correctly because the default behavior of the TAB key was prevented.
After this fix, if the navigation_move event was not stopped, we allow
the default behavior of the TAB key.
Revision on https://github.com/odoo/odoo/commit/32b8cec5361174c92c45a4975d4e02f1fb448aa2
Before this commit, when we switch channels in the Discuss app, the breadcrumb
was visually not updated: it keeps the name of the first opened channel.
With this commit, the breadcrumb is updated on each change of channel, so that
it displays the name of the currently opened channel.
Technical details:
This is due to a change of logic of updating the GUI of the breadcrumb:
before the refactoring above, discuss had to pass the content of the
breadcrumb to the control panel, in order to update the breadcrumb visually.
After the refactoring, the action manager should warn the control panel to
update the breadcrumb on any change of the title. This is already the case
for `ir.actions.act_window`, but not for all types of client actions.
Here is the issue that initiated this work: the bank reconciliation tour
sometimes failed in community. The reason was that the discuss client
action seemed to be loaded after the tour started, and interfered with
the second step of the tour.
What happened exactly was the following:
- web client is loaded
- initial action is starting (but not complete) (this is discuss)
- tour manager is loaded and starts the reconciliation tour
- the reconciliation tour changes the url to trigger an hash change
- the web client calls loadState on the action manager
- the action manager perform a doAction with the tour url
- the discuss client action is now ready, and replace the reconciliation
action
- the tour is broken.
The underlying cause is really a generic problem: the action manager
does not add the client action starting process in its 'dropprevious'
concurrency primitive. This is probably not really an issue for the
act_window actions, since they have custom loading code that make sure
the loading process is put in the drop previous, but it is definitely a
problem for all client actions.
The solution is quite simple, and should also protect the act window
renderers: put the action controller in the drop previous
Here is the issue that initiated this work: the bank reconciliation tour
sometimes failed in community. The reason was that the discuss client
action seemed to be loaded after the tour started, and interfered with
the second step of the tour.
What happened exactly was the following:
- web client is loaded
- initial action is starting (but not complete) (this is discuss)
- tour manager is loaded and starts the reconciliation tour
- the reconciliation tour changes the url to trigger an hash change
- the web client calls loadState on the action manager
- the action manager perform a doAction with the tour url
- the discuss client action is now ready, and replace the reconciliation
action
- the tour is broken.
The underlying cause is really a generic problem: the action manager
does not add the client action starting process in its 'dropprevious'
concurrency primitive. This is probably not really an issue for the
act_window actions, since they have custom loading code that make sure
the loading process is put in the drop previous, but it is definitely a
problem for all client actions.
The solution is quite simple, and should also protect the act window
renderers: put the action controller in the drop previous
This rev. introduces an option to doAction (keepSearchView). If set
to true, the searchView of the current action will be kept and used
by the new action (this only works if there is already an action
with a searchView, and if the new action is stacked over that one).
This is necessary for the new dashboard view.
A better solution would have been to export the state of the
existing searchView, and import it to the new one, but the current
implementation of the searchView doesn't allow to do that easily.
This will be done as soon as the searchView will be rewrote.
Actions can be loaded from the state of the url (e.g. when pressing
F5). For window actions, it was working properly if the action id
or a record id (i.e. for form views) was given. In other words,
states like 'model=res.partner&view_type=kanban' couldn't be
loaded.
This can be explained by the fact that without an action id, the
context and domain of the action couldn't be obtained.
This rev. solves this problem by storing the current action into
the sessionStorage, so that important information like context,
domain and name can be retrieved if this action has to be restored
(i.e. if the user refreshes the page).
Before this rev., the search menus (Filters, Group By, Favorites)
were lost when the user came back to an action with the
breadcrumbs (e.g. go to My pipeline, open a lead, click on the
Meetings stat button, go back to My pipeline).
This was because the two searchviews shared the same jQuery element
containing their dropdowns. This behavior is there for a long time,
but the bug has been revealed by 7b6056a0, which changes the way
the action manager and controllers interact with the control panel.
Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com>
This rev. strengthens the handling of concurrent actions of type
'ir.actions.act_window' in the ActionManager. In particular, the
two following cases are now handled:
- execute an action A, its 'load_views' RPC takes a while, during
that time, execute an action B: A can be dropped, meaning that
it doesn't need to fetch its data, and thus it should not be
appended to the DOM (nor appear in the breadcrumbs) ;
- execute an action A, its 'read' or 'search_read' RPC takes a
while, during that time, execute an action B: A can be dropped
and should not be appended to the DOM (nor appear in the
breadcrumbs).
Loaded actions (i.e. executed from url state, e.g. after an F5)
should not push their state back to the url. This was working fine
of act_window actions, but not for client actions, and this was
causing an issue in Studio as the same mechanism is used to prevent
the main Studio client action from pushing its state into the url
(to keep the state of the edited action in the url instead).
This rev. improves the way the scroll position is restored when
coming back to a view (e.g. open a kanban view, scroll, click on a
record to open it in a form view, go back to kanban using the
breadcrumbs):
- generalize the scroll position handling from web_enterprise to
web to make it available in the community webclient as well
- also restore left scroll position, not only top (especially
useful for grouped Kanban views with a lot of columns)
- handle the case where the scrolling area is a sub element of
the view (e.g. the grouped Kanban view in mobile).
Task 34037
Co-authored-by: Mohammed Shekha <msh@openerp.com>
Co-authored-by: Ankit Sathvara <asa@odoo.com>
Actions loaded from the url are flagged with 'pushState: false', to
prevent them from pushing their state back to the url, thus
producing an infinite loop. However, if the state of a loaded
action changes in the future (e.g. load an action in kanban view,
then switch to a form view), this state should be pushed to update
the url. Before this rev., this wasn't the case.
Before this commit, a client action was simply a subclass of Widget.
This is quite simple, but not really enough for the ActionManager. The
ActionManager needs to handle client actions in a different way that
view actions. Sometimes, it needs to check if a method exists before
calling it.
With this commit, we introduce a new abstraction: the AbstractAction
class, which defines a common API for all actions managed by the web
client.
Note that the API proposed in this commit is just the beginning. We will
introduce other methods in the future, to manage the focus, or the
scroll position, for example.
This rev. fixes two issues with the loading (e.g. after an F5) of
form views in mobile.
First, the form view being not a mobile-friendly view, it opened
the kanban view instead (if there were one defined in the action),
whether it should have kept the form view as they don't diplay the
same things (one is multiRecord, the other isn't).
Second, after fixing the first issue, the main (multiRecord) view
which was lazyloaded when loading a form view wasn't
mobile-friendly so if the user clicked on the breadcrumbs to go
back, he landed on a list view (if the list view was the first view
of the action), whether he should be on a kanban view, which is
mobile-friendly.
This is a manual forwardport of rev. b466b3bc60.
Consider the following scenario: open in edit mode a form view
containing a many2many field displayed with widget many2many_tags,
on the many2many field dropdown, click on 'Search More' (it opens
a dialog), and in the dialog, try to save the current search in
the searchview's favorite menu.
Before this rev., it crashed because it tried to retrieve the
action's context (to add to the saved filter), whereas there is no
action in this case.
Actually, the action's context should never been used in this case.
What must be used is the controller's context (this mainly makes
sense for Pivot and Graph views).
Fixes#23293
Before this commit, doAction returns a deferred that is
resolved when the action is performed (the exact moment
depends of the type of the action).
However, the deferred was not resolved with the action.
This is misleading, hence a traceback in the web_client
when clicking on 'Run JS Tests' in debug mode (enterprise):
after doAction, the web_client should hide the home_menu
depending on the type of the action.
With this commit, any doAction returns a deferred that is
resolved with the performed action.
When executing an act_window action, the ActionManager has to
determine whether or not the first view of the action is a form
view (typically, when this happens, this is also the only view of
the action, and most of the time, it is displayed in a dialog, i.e.
the action's target is 'new'). This ensures that the control panel
is correctly shown/hidden, that form buttons are correctly rendered
and displayed at the right place, and so on.
Before this rev., it uses the view_mode to do that, but there is no
guarantee that the view_mode is even defined (for instance, actions
returned from python methods don't have to define it), so from now
on, we use the 'views' attribute instead, which must always be set.
Server actions return an action to execute, or false. When they
return false, an 'ir.actions.act_window_close' must be executed,
such that the current dialog closes (if any) and mostly, the
'on_close' handler is executed, which ensures for example that the
current view is reloaded.
The case where server actions return false has been broken by rev.
32b8cec53. It produced tracebacks in several models, when clicking
on some actions in the 'Action' dropdown. For instance, in lunch,
go to Configuration > Products, open one in a form view, and click
on 'Lunch: Archive/Restore products' in the Action dropdown.
In the tests environment, we listen to the 'DOMNodeInserted' event
to remove the src attribute of img and iframe nodes as soon as they
are inserted into the DOM, so that they don't perform RPCs.
However, this listener was bound in the create(Async)View, and
createActionManager helpers only. This rev. moves it to the
addMockEnvironment helper which is more global, and basically used
by all tests.
Moreover, we now listen to the 'DOMNodeInserted' event on the body,
instead of on the widget, as it may happen that some content is
inserted into the DOM outside the widget itself (e.g. dialogs are
appended to the body).
A traceback occurred on the Intrastat list view (Accounting >
Reporting > Management > Intrastat), when the user clicked on a row
of the list. This action only specifies 2 view modes: list and
kanban. When a record is clicked, the ActionManager tries to open
that record in a form view. As the view isn't in the action, this
request should be ignored. Before this rev., this case wasn't
correctly supported.
This commit improves the JS code of the mail module,
which comes maily from the new coding guidelines
and the addition of "JS services".
JS services are important objects that do not fit
well in the component tree, such as chat_manager
or ajax.
The benefits of JS services are improved readability
of the code, reduced coupling, and more testable
modules. In particular, discuss was hard to
Summary of the changes:
- ClientAction has been renamed into Discuss
- Clear instantiation of chatManager
- New coding guidelines in most mail modules
- JS Services can interact with each other
- Chat Manager and Window Manager are services
- Window Manager renamed to Chat Window Manager
- bus.bus is now encapsulated in Bus Service (a service)
- The test infrastructure has been tweaked with JS Services
- Chat Mixin has been removed
A future improvement would be to translate some 'trigger' into 'trigger_up'.
Before this rev., the group_by specified in the action context was
completely overridden by the group_by specified in the search view,
even if it was []. In other words, it was completely ignored.
Moreover, it was only took into account (before being overridden)
at the first load of a view, not at reload.
Before this rev., an error occurred when the user changed a param
of the url when being in a client action. For instance, open
Discuss, go to 'Starred', then click on the 'Back' arrow of the
browser.
The error occurred because the code made the assumption that the
current action was an ir.actions.act_window.
This rev. is the first part (out of 3) of the refactoring of the
ActionManager and ViewManager layer of the webclient.
The main changes are:
- there is no ViewManager anymore, its work is now handled by the
ActionManager itself, but isolated in a specific file ; this
eases a lot of things, as the breadcrumbs handling for example.
- the ActionManager code is converted to the new coding principles
and guidelines ; mainly, children widgets communicate with it by
triggering events up, and not by function calls anymore.
- the ActionManager layer is now testable, and a lot of tests have
already been written.
- the code in other addons has been adapted consequently.
What's coming next:
- introduce the 'AbstractAction' Widget, and make client actions
and view controllers inherit from it ; this widget will
implement a common API that could be used uniformly by the
ActionManager (e.g. restore(), canBeLeft(), renderButtons(),
getTitle()...).
- move the ControlPanel handling from the ActionManager to the
AbstractAction.