As `_renderInnerGroupRow` is returning the row, appended to the
previous result, and not only the row, it was not possible to
override the method to add, for example, another row.
This commit doesn't change the behaviour, only the return of
private functions.
As `create_view` is asynchronous, it is possible that there is an
active view without any associated controller.
We thus test here if there is a controller before calling its method.
In a recent commit, the fields object describing all fields of a
model is (deeply) frozen by the data_manager. As a consequence, if
a field has a domain (represented by an Array), this domain is
frozen as well.
Moreover, when the function getDomain is called on a dataPoint,
the returned domain is the one in fields, not a copy.
Problem is that the Many2One field updates this domain to add the
blacklisted ids, which produces an error if the domain is frozen.
Before this commit, every field changes were sent upstream and triggered
a notifyChange, potentially causing multiple (onchanges) RPCS in rapid
succession.
It is useful to have a feedback of the new values of the fields even
without needing to lose the focus, but it should not be done for each
keystroke.
With this commit, we debounce the onInput handler, so the method
setValue is in practice debounced as well. We need to add a handler on
the focusout event to make sure that if the user changes input, the
setValue is immediately called.
Note that we had to add support for that in the test utils environment
(and not only in the createView method: field widgets can be
instantiated in other environment, such as the reconciliation widget)
With the new `field_utils` parsing functions, many field types were
not able to be used with the domain selector anymore.
* a m2o value is now parsed to an object with an `id` key and a
`display_name` key. This object cannot be placed in the `<input/>`
holding a `DomainLeaf` value in the domain selector widget (right
now, it is showing [Object object] because of this parsing). If
the value is an object, display its `id` key or nothing if this
key does not exist.
* a date(time) value is now parsed to a moment object. Adaptation had
to be made so that it is correctly displayed for the user and
properly converted to its server format when building the char
domain.
* an array of char is formatted to an empty string... obviously the
selector implementation is wrong here and should format array
values individually. However, as the widget only support arrays
for char values, the formatting is useless so it can simply be
disabled in that case while waiting for better implementation.
Note: the parsing and formatting code in domain selector should be
improved to be more accurate and understandable. This will be done
in a future update.
A big problem is that the read_group method has a variable API: it
sometimes returns values in a __count key, sometimes in a
[somefield]__count key.
Before this commit, the graph view was not using the correct value in
some cases.
With the new views, we totally broke the dashboard. This commit
rewrites all the code to comply with our new coding guidelines, and make
sure it works, with some tests.
Note that a big change is that we don't instantiate an action manager
and a view manager, we directly instantiate the views.
Also, this is not the best way to organize the dashboard. I think that
it should be a client action, not a form view, so we don't have to
overload all the form view classes and we don't depend on form view
behaviour/view caches/...
In some cases, the view manager do_load_state method can receive an
empty string as id. This was the case when we refresh the dashboard for
example.
This is not a perfect fix (the do_load_state and the url mechanisms
should be improved), but it makes things more robust.
One2Many fields edition (creation of new related records or
edition of existing ones) needs a specific handling, because the
related records aren't saved when the user clicks on 'Save' in
the dialog, but when he clicks on 'Save' in the main form view.
To make this work, the model (instance of BasicModel) and the
representation of the edited record in the model must be given to
the form in the dialog.
Problem is that the fields to display in the kanban or list view
and the form view in the dialog may be different, so when opening
the dialog, the list of fields in the record is updated, and this
list must be reset to its original value when the user closes the
dialog. This last part wasn't done correctly before this commit,
which causes tracebacks when the kanban/list view contained fields
that weren't in the form view.
When the view is saved (either directly or via a widget in readonly
mode), the flag isDirty was not reset to false.
also, use the $ function on widgets insted of $el.find and remove some
unused imports
Before this commit, we did not check if the changes can be discarded
when opening the app switcher. This is now done. Note that this check
was formerly done in the form view, and we moved this to the view
manager. This now means that all views have the power to decide if they
can be discarded.
Before this rev. parts of the processing of the fields_views and
fields returned by the server done in data_manager were
duplicated in the MockServer and test_utils, and other parts
were missing, so the test environment didn't reproduce well
the tested one.
This rev. refactors the code s.t. it can call the method of the
data_manager that postprocesses the result of a loadViews(). It
also moves the logic to the fieldsViewGet() method so that this
works in every test scenario, not only when a view is created
(e.g. Studio).
The fields are represented as an Object whose keys are the field
names and values their description. By adding the name inside the
description, this commit makes it fully self-contained.
This commit also moves the processing of fields_views s.t. they
are stored processed in the cache, instead of processing them each
time they were requested.
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.
There were several issues with the resequence method.
First the lookup in the model's fields to determine if there is a
'sequence' field (to know whether or not an RPC should be done)
was incorrect when resequencing columns as the lookup was done for
the wrong model. Actually, we don't have the list of fields of the
related model, so this lookup shouldn't exist at all, and the RPC
should be done in all cases (the controller correctly handles the
absence of 'sequence' field).
Second, the JS sort of the data didn't work either as we didn't
manipulate the dataPoints but only their ids (the internal
representation of the dataPoints is flat, so the data of elements
of type 'list' only contains the id of its dataPoints).
Returning a rejected deferred isn't the correct way to notify the
MockServer that something went wrong, throwing an error is. This
error is then catched, and the RPC deferred is rejected with two
arguments: an object describing the error and a JQuery event.
When the user quick creates a record in a grouped kanban view, a
name_create RPC is done. This RPC may fail, and there were
several issues with the fail handler.
First, those fail handlers take 2 params: an object describing
the error, and a JQuery event. The event was the first argument
in the handler, so it crashes on event.preventDefault().
Second, when the name_create fails, a FormViewDialog in edit
should be open. Former code opened a SelectCreateDialog.
This commit also ensures that the default values are correctly
given to the form in the dialog, through the context.
When reloading a grouped Kanban view (e.g. after specifying a new
domain), the internal state of the (sub-)groups is kept so that
it can be restored (like which are the open groups and the limit
and offset inside the groups).
However, for models and fields whose read_group returns empty
groups (e.g. project.task grouped by stade_id) this was wrong if
the specified domain filtered out all records of an open group,
because as its data wasn't reloaded (because there is no record),
the old data were still in place, so the filtered out records still
appeared in the Kanban.
The `FieldDomain` was sending string domains instead of array domains
to the server (by its associated `BasicModel._fetchSpecialDomain`
function). The server does not do the conversion string -> array for
domains, so the RPC broke everytime.
This commit also modifies the `MockServer` so that tests also break
when sending string domains.
It also improves the way failed rpc are handled. Indeed when an rpc
fails, its deferred is rejected with two arguments: the error object,
and a JQuery event (that will display the error if not
preventDefaulted). The mockRPC didn't pass the second one and thus
there was a crash when reaching code that e.g. calls preventDefault
on that event. Note: this also removes the stringify/parse of the
error object as it is not a correct simulation of a server error
object anyway.
* 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.
This rev. allows to specify some kwargs of read_group directly in
an Object given to kwargs(), instead of explicitly specify them
using the corresponding method (e.g. to specify the context in the
kwargs instead of by calling .withContext().
When calling a route using the new RPC query builder (e.g. by
doing "this._rpc('/a/route').params({a: 'a'}).exec()"), if one of
the route kwargs was 'model', 'method', 'args' or 'kwargs', the
given value was overriden by undefined.
The session can me mocked in the test environment (if a session
is given in the params). However, when it is not, it crashed
if one of the instantiated widgets requests the session with
getSession().
This rev. adds a fallback so that when this happens, the real
session (web.session) is given.