The RPC system was not completely satisfactory, we decided to prepare
the future and do it properly. This commit introduces the new rpc
system, which replace the previous new one. We now simply have a
method, this._rpc, which takes a dictionary of parameters. The idea is
that depending on the parameters, it is able to add correct default
value when necessary.
For situations where we don't have the this._rpc method, we can use the
rpc.query method, which takes the same arguments, but directly calls
ajax.rpc instead of triggering up some events.
* Data manager load_view returns a viewInfo object
* ViewInfo contains: the arch, fields and fieldsInfo objects, and some extra informations
* The fields come from the server and are frozen, without any view attributes (depend of the model).
* The fieldsInfo contains every view attributes and informations.
With the new JS test framework, we had experimented with an autodestroy
feature, meaning that all views/widgets are automatically destroyed
after a while. By default, it was 50ms, because we could not hook some
code to run after the end of the current test.
For various reasons, this was not a good idea: some side effects, such
as modifications of the session or of the DOM (with modals) could
interfere with other tests. This commit disable the feature.
From now on, we will have to destroy each widgets created in a test.
This commit introduce a full redesign of all JS views. We started
basically from scratch. The goal was to unify all the various views
under a common framework, to make them testable, to make then usable in
different conditions (in studio, or in the frontend), and to make our
lives easier.
Some important points are:
- we introduced new coding guidelines (camelCase, 80 chars width, ...)
- we have a brand new testing framework (still QUnit based)
- kanban view moved to the web addon
- calendar view (formerly web_calender) moved to web as well
- the tree view was removed
- all new code should be documented
We hope that this code is the start of a new era for the Odoo web
client, we want to have a high quality codebase, well documented, well
tested, well designed.
Work done by the framework team: mostly aab, ged, chm, dmo, qsm
Since rev. 002660a, form views are instantiated with their fields_view.
This has an impact in FormViewDialog as the inner form view
instantiation is now asynchronous. The diagram view instantiates several
FormViewDialogs but doesn't wait for the form view to be instantiated
before accessing it, which produces a traceback.
Closes#13775
Load the fields_view of all views of the action together. If a searchview is
required, also load its fields_view and its filters.
Use lazy-loading for fields as they are required for the Pivot and Graph
views only, and may be used by Filters and GroupBy menus of the Search view
if the users clicks on 'Add a custom Filter/Group'.
The fields are thus also loaded directly if the first view of the action is
Pivot or Graph, and otherwise, they are lazy-loaded when/if the user opens
a Pivot or Graph view, or if he wants to add a custom Filter/Group.
Some refactoring of views API as well:
- Views must now be instantiated with their fields_view
- Move code requiring fields_view from start() to init(), or willStart() for
heavy processing.
- Remove view_type attribute from views as it was used to call
fields_view_get.
- Remove view_id parameter to views' init as it is no longer used.
- Move duplicate code from various views' init to the View widget.
- Remove view_loading() function from views as they now follow the classical
lifecycle of widgets (init -> willStart -> start -> destroy).
- Searchview now extends View like all other views.
- Remove useless function guard_active() as it was used for the form_view's
action buttons to wrap handlers to ensure that they are executed only if
the form_view is the current active view. This is not useful anymore as
from v9, views and their control panel are appended in the DOM
simultaneously, so one can't click on a button of a view which is not the
current active view.
Commit 516b1a6c72 fixes a bug with action buttons not being displayed when they
should in dialogs. However, it makes the assumption that either $node or
this.options.$buttons exist, which is not always the case (e.g. dashboard).
This rev. moves that logic out of the views to the view_manager, and protects
the call of empty() on this.options.$buttons.
- Ensure compatibility with both editions of web
- Use the Pager widget instead of re-implementing it
- Fix the use of Dialogs which was broken (wrong type of Dialog was used)
- Convert css into less
- Some js linting
The 'New node' button is inserted in the ControlPanel. Breadcrumbs
are now handled as well.
The 'multi_record' flag has been added to the views to distinguish views
displaying several records, like the List view, from views displaying
a single record like the Form view and the Diagram view. This flag is
used by the ViewManager to manage its view stack. Fixes the breadcrumb
bug when switching between Form view and Diagram view (the last element
of the view stack is now replaced by the new one in that case).
Change the logic of rendering and displaying/hidding the control
elements (buttons, sidebar and pager) of all views. The views do no
more render automatically their elements as this is rather done
through the render_[element] function called by the ViewManager.
This function only appends the element to the $node given as argument.
If no argument is given, then it may appends it to the DOM directly,
within the adequate div of its template.
This allows the ViewManager to attach/detach all elements of the
ControlPanel in an atomic may, to prevent the ControlPanel from
flickering.
Also detach the contents of the ControlPanel in headless mode. Headless
means that the ControlPanel exists, but is hidden. Detaching its
contents permits to have a cleaner DOM.
Also remove the oe_form_dirty class on the buttons in the FormView, as
this class is only used on the view itself.
Side changes:
* base_import: import.js:
Extend render_buttons function to be compliant with the new buttons
rendering logic
* board: dashboard.js:
Set flag search_view to True as the searchview is needed for the
Views displayed in the Dashboard to retrieve the records to display.
Necessary since we do no more construct the searchview when this
is set to false
* google_drive: drive.js,
share: share.js:
Module extending the Sidebar widget often add their own buttons
by extending the start(), which is called each time the Widget
is appended to the DOM. With our new design, this could be done
in start() anymore as it should be done only one. It is now done
in init() instead.
The ControlPanel is still instantiated by the ViewManager.
Changes details:
* web: views.js:
Code related to views header is extracted from the ViewManager
to a new Widget named ControlPanel.
Also uses the headless flag to tell the inner view not to put
its buttons (use case: kanban) or pager (use case: list) in the
header as it is hidden.
* web: view_form.js, base.xml:
Uses the headless flag at initialization of the One2ManyViewManager
widget instead of extending the ViewManager template (which doesn't
handle the header anymore).
* web: view_list.js:
Test on this.options.$pager instead of this.options.$buttons
when dealing with pager.
Note: the behavior for list view is unchanged and has a bug.
If there are more then 80 records to display, only the 80th
first are display, and as there is no pager, there is no way
to see the remaining ones. A fix for this would be to use a
light ControlPanel in One2Many views as well. With this,
there won't be duplicated .oe-'view'-buttons/sidebar/pager
anymore.
* web: view_graph.js, view_pivot.js:
Only render buttons in non-headless mode
* web_dashboard: dashboard.js:
Fix some references that were broken with ControlPanel extraction
* web_view_editor: web_view_editor.js:
Extend ControlPanel instead of ViewManager
* Changes in selector of ControlPanel elements in several addons:
* base_import
* mail
* web
The module system needs to know the dependencies of a given module
before executing the function. This is why the dependencies were
defined once in an array, and then were described one more times in the
call to require.
But a trick can simplify this: the boot function can parse the string
representation of the module and extract the calls to require from it.
It is more work for the processor, but it leads to simpler module
definitions.
* ir_actions_common should return a deferred : some widgets
do not return a deferred in start, so it could be undefined.
it now is always a deferred.
* add icon for diagram view + breadcrumb support. diagram view
is so rare that it wasn't tested in the client refactoring.
This patch adds an icon for diagram view, and better support for
breadcrumbs
* add warning in debug mode print workflow: when no record is
selected, display a warning instead of failing silently