When a user edit a record, then click on a stat button, the web client was a
little too aggressive in avoiding to reload data. It was assuming that
even if the server overrides the create method, the web client did not
need to know anything about the record before executing the action from
the stat button.
However, that assumption is incorrect: the display_name property is
needed to correctly display the breadcrumbs. For example, here is a scenario
that was not correct: open a res.partner in a form view, edit its name, then
click on one of the stat button. You will see that the breadcrumb is not
properly updated.
To fix this issue, we have to reload the record, and to properly update
the title property. In this commit, we also add a getName method in the
model.
Before this revision, pressing ENTER when inside a many2one field
triggers a 'focus out' event. In particular, if one creates a many2one
record and uses the ENTER key to click "Create and Edit", two dialog
windows appear: one to actually create the associated record, and a
second to alert the user that they are creating an associated record.
The latter appears every time the many2one field loses focus.
This commit changes the 'key up' event for many2one fields to ensure
that the ENTER key does not trigger a 'focus out' event.
The commit 5854bb7d12 introduces a new option
to drag element without dropping them.
But it's not allowed to start a new drag and drop until the first one is
completely done.
So when the element is removed from the dom (the test is finished), we complete
the drag and drop in order to let next tests perform drag and drop.
This commit introduces the 'rainbowification' feature to the web client
(and to some affected addons). This feature is essentially a way to
display a nice friendly message when some business event happens. For
example, a encouraging message is displayed when the user clear her/his
inbox, or when a salesman closes a deal.
The mechanism currently only displays a 'rainbowman', but could be
extended later to add other kind of animation.
There are a few different ways to display a 'rainbowman':
- any JS code can simply trigger_up an event ('show_effect') with some
options: for example
this.trigger_up('show_effect', {
type: 'rainbow_man',
fadeout: 'no',
message: $done,
click_close: false,
});
- an action returned by the server can have an 'effect' key, with some
options
- the do_execute_action method accepts a 'effect' option. This is
useful when one wants to specify a rainbow on an action button in a
form view
Joint work with: dbh <dbh@odoo.com>, ged <ged@odoo.com>
Before this commit, all x2many fields values were sent to the server in the
onchange call. If a x2many field was not present in the view, then it
was sent as an empty list [], which is totally wrong.
Purpose
=======
Currently, it's not possible to activate a boolean on a non-editable list view without adding 2 buttons linked to a python method. These buttons aren't aligned and the result is not pretty.
This commit adds a new widget that allows to toggle a boolean record by record by clicking on the slider.
Before this fix, the field 'color' was hardcoded in the m2m_tags widget,
which means that:
- one couldn't specify another field (problem for custom models, with x_...)
- if the related model didn't have the field 'color', a warning was raised
by the server
Now, the color attribute needs to be specified on the widget options if one
wants to display colored tags.
If the color is not specified, the tags will be displayed in grey.
When an invisible x2many field is modified by an onchange, we had a
crash because the reset function did not return a deferred in that case.
This happens because the signature of _render in AbstractField allow for
an undefined return value, but the reset method should return a
deferred.
This was an issue for example in stock: editing the
pack_operation_product_ids one2many field in a stock.picking could
trigger an onchange on another invisible one2many (with no inline views).
In some situations, it would be desirable to be able to attempt a drag
and drop, without actually triggering the dropping action. As an
example, we would like to see whether dragging a new field in studio
ensures that a class 'o_web_studio_nearest_hook' be assigned. This can
only be tested *before* the new field is dropped.
This commit adds an optional argument 'disableDrop' to the
dragAndDrop method, and sets it by default to false. The dropping action
will then only be triggered if the aforementioned parameter is set to
false.
In some cases (onchange in a purchase order), the onchange can return a
domain for a field that is not in view. It should not be the case, but
it is really simple to protect the web client anyway.
Before this commit, the web client read the readonly in the modifiers,
and if no readonly was in the modifiers, it fell back to the field
property. But the field property was already taken into account in the
modifiers, so this was useless. And worse, in some case, it could cause
an issue. For example, a field with readonly=true, and readonly="0" in
the arch was considered readonly.
Previously, enabling some filters created a domain of which events
to display, but disabling all filters resulted in a domain of []
which, instead of showing no events at all, actually showed all events.
In saas-15, when an event had more than 3 attendees, it used to
show a '+' at the left of the avatars. This behavior was lost in
saas-16 where it became 'display 5 avatars max and that's it'.
This commit brings back the behavior of saas-15 and improves it
such that the '+' sign displays the number of additional attendees
whose avatars are not shown and displays it on the right.
Example for 7 attendees, '[]' representing an avatar:
saas-15: +[][][]
saas-16 before: [][][][][]
saas-16 now: [][][]+4
Before this commit, when whe loglevel was set to 2 in the mock server,
we simply logged the parameters in the console, then give the same
object to the _performRpc route. Most of the time, it is not an issue,
but nothing prevents the _performRpc route to modify the args object.
And this happens with the /create route, which is very confusing: when
we have a breakpoint/debugger in the mock rpc function in a test, we see
the correct arguments passed to the function. However, if we look at
the arguments in the console, after the end of the test, we see other
values (for all fields) in the args.args[0] object.
The solution is to simply deep copying everything, so any modification
in the mockserver will not affect the logged object.
In field_utils, the parse monetary method was remapped to parsefloat. In this commit, we add a specific parseMonetary method to handle currency specific formatting.
Onchange RPCs return an object that may contain a 'domain' key.
When it does, its value is an object whose keys are field names and
values are the new domain for the corresponding field.
Before this rev., the 'domain' key was totally ignored by the
BasicModel. This feature is used for example in the account.payment
form view (go to an open invoice, click on 'Register payment'): the
domain of field payment_method_id is updated by the onchanges (e.g.
when changing the journal_id). As the domain was ignored, it always
displayed all possible payment methods.
... when reading and writing on a record (especially inside lists).
Before this rev., the context sent when reading a record, and when
writing records inside lists (editable list views) wasn't correct.
This caused an issue in Sales > Products (variant activated) >
open a product with variants > click on variant prices > edit the
prices of a variant: the value wasn't saved correctly (because the
inverse function requires 'active_id' to be in the context and it
wasn't the case).
Fixes two issues in the test environment:
- for unset fields, the mockRead is supposed to return 0 (numerical
fields), empty array (x2many fields) or false (otherwise). Except
for the first case, it was returning undefined, and this might
cause crashes when evaluating contexts or domains.
- the mock environment allows overriding some global properties
like the session, for the test case only. Once the widget is
destroyed, those global properties are reset to their original
value. This wasn't working for models tests, because the destroy
function of the parent widget was never called. This could make
tests fail as they could have been impacted by other tests.
The test changed in this commit had a big issue: it did not properly
destroy the second form view that it created. Because of that, it was
still alive and could interact with other tests, such as the barcode
tests.
This is what happened:
1. var form was assigned to a form view
2. form was destroyed
3. in a try catch, form was reassigned to the result of createView, but
the evaluation of createView crashed (after creating a form view), so the
assignation was not done, and the var form was still pointing to the first
form view
4. form.destroy is called, which did nothing for the second form view.
There is no easy way to get the reference to the form view created by
createView without changing some other code, so we simply remove the
second part of the test, which was not particularly important.
The reference fields haven't been correctly implemented with the new views.
This commit restores their behaviour.
Note that an small improvement has been introduced in this commit.
Before saas-16, a `name_get` was done for each record (so 80 if the field
was displayed in a full list view), which is not optimal. The calls are now
batched by model (so one `name_get` by model appearing in the field values).
In the editable list, when pressing enter, the cursor goes to the next line and
the current row is saved.
This should not be the case for a textarea (i.e. in the FieldText widget). In
this particular case, we just want to continue editing the textarea.
Before this commit, the discard confirm dialog was directly shown
without waiting for the write RPC. For instance, it the user clicked on 'Save'
after editing a record, and then directly clicked on another menu or on the
breadcrumb before the write RPC returned, the record was still considered
as dirty and thus the confirm dialog was displayed. We now wait for the RPC
to return before checking if the record is dirty, so that the confirm dialog
is only displayed when the record is actually dirty.
When the value of a many2one field with widget selection was unset,
it's value wasn't actually set to false in the BasicModel. It was
set to a virtual id like 'virtual_294' instead. This caused a
traceback when this value was sent to the server, obviously.
This was for example the case of the Register Payment form view
(accessible from a customer invoice), when the user selected a
payment journal, and then unselected it (the virtual id was then
sent to the onchange RPC).
The MonetaryField can be rendered with or without a currency. The
currency can change during the lifecyle of the widget (e.g.
currency field in the view, whose value is set by an onchange).
More precisely, the widget can be instantiated without currency,
then a change on another field can trigger an onchange which sets
the currency, and our monetary widget is re-rendered with a
currency.
Before this rev., this wasn't supported in edit mode because the
$el's root node was different if there were a currency or not
(it was an input if there were no currency, and a div containing
an input and a span otherwise). This root node being rendered only
once (at the creation of the widget), the widget wasn't re-rendered
correctly if the currency was suddenly set or unset.
This fix makes the widget behave uniformly whether or not there is
a currency, so now it is always a div containing an input (and
optionally a span if there is a currency).
When x2many fields have to be evaluated in domains (e.g. ['id',
'in', some_x2many_field]), they must be evaluated as the list of
ids in the relation (whereas in contexts, they are evaluated as a
list of commands). Before this rev., they were always evaluated as
a list of commands.
Note that this didn't work neither before the new views.
Datapoints of the BasicModel store the data fetched from the
server and changes done (not saved yet) by the user. For x2many
fields, datapoints are of type 'list' and have a 'res_ids' key
containing the ids of all records in the relation. They also have a
'data' key containing datapoints of type 'record', representing the
records in the relation that have been fetched (with a limit set to
40 or 80 depending on the subview used). So basically, the length
of res_ids may be different than the length of data.
Before this rev., the changes in x2manys were saved under the key
'_changes' as a duplication of the content of 'data', i.e. same
list of datapoints of type 'record', modulo the changes done (it
contained the new records added and didn't contained the removed
records, whereas the 'data' remained unchanged). This didn't worked
at all when there were more records than the limit in the relation.
Indeed, when this happened, the commands to send to the server
couldn't be generated correctly.
This rev. modifies the way changes are stored in those datapoints.
Now, each change is stored as an operation. An operation could be
of type 'ADD', 'REMOVE', 'REMOVE_ALL' or 'UPDATE'. As before,
'data' remains unchanged and always keeps the datapoints of records
that have been fetched (the ones that are currently displayed in
the list or kanban subview). This way, commands can now be properly
computed.
This had a nice side-effect of fixing two other bugs linked to
x2manys.
First, when used in a context (e.g. {some_key: some_x2many_field}),
the value of some_x2many_field (i.e. a list of commands) was always
[] if the field was invisible="1" in the view, because it's
subrecords weren't fetched, and the generated commands were based
on them. Now, they are generated from the list of res_ids in the
relation, so it works fine.
Second, the x2many records are supposed to be sorted client-side,
after being read, and after each edition. This was working in the
first case, but not in the second. Now it's working even after
a record edition.
This rev. also correctly sets the 'parentID' and 'static' keys in
datapoints.
Finally, we also fixed the pager in x2manys as it was badly
displayed (small less tweaks).
The previous code loading the tooltip data was sending a null value
to read as id, which resulted in an access error. This behavior was
not observable in the tests because of b8c1571 which was meant to
allow giving inexistant ids to mockRead but also ended up accepting
falsy values, which was not true to the actual server.
In addition, the title of the column was wrong for unset m2o, it
displayed false, the value of the field when unset, rather than
the default "Undefined" title.
When I introduced this line in 374295b, I was working on the form
view and didn't realize I would be breaking the editable list view.
The _setMode function only updates the buttons when given the id of
a record. Since I was working on a form view at the time, I didn't
need to give a recordID to make it work since the default ID of a
form view is the id of the record itself. However, in editable list
view, the id of the view is a list of ids, so the buttons would not
be updated in this case.
When the show_address option is enabled, the display_name of a
partner becomes a newline concatenated version of his name and his
address, so the internal value of the widget is this conglomerate.
However, if one uses a keypress that does not change the value of
the input in edit mode, say ESC for example, the keyup handler of
this widget will compare the value in the input with its internal
value. If the internal value is still the conglomerate, which is
the case if the user hasn't changed the input content since
switching in edit mode, we need to trim it to compare it to the
actual input value, which is the "standard" display_name, ignoring
the magic show_address feature which is only used in readonly.
When creating a new record, the numeric field default value should be 0 in order
to avoid manually setting mandatory fields to 0.
This behaviour has been removed with the new views but one wants to restore it.
The `mockRead` function has also been adapted in this commit because the server
returns 0 for unset numeric fields.
Before this fix, a traceback occured when we clicked on the translate icon
in a form dialog.
The `translate` event wasn't stopped and was thus handled by the dialog's form
controller and by the main controller.
Before this fix, multiple records were created if you clicked
on the quick create of a many2one in a modal.
The 'mutexify' event wasn't stopped and was thus handled by
the dialog's form controller and by the main form controller.
The module `crm.voip` alters the focusable behaviour of the phone
widget by overriding the `canCall` method.
We thus disable this test if the module is installed.
Rev. https://github.com/odoo/odoo/commit/c5f8f35747b4ca9633c664d6be74614c5ce22fcd
introduced a regression: the input of widgets 'email' and 'url' was not correctly
focused anymore with tab navigation.
The method `getFocusableElement` on their common parent (`InputField`) has not been
correctly overriden because `_super``was not called in edit mode.
The tab navigation was only working in edit mode. Entering a readonly form
view with input fields was causing a traceback.
As the default browser behaviour has been overriden with custom navigation,
we need to specify which widget can be focused (e.g.: url, many2one, etc.).
In an empty kanban view, when moving a freshly created record from
the second column to the first one, then moving it back again in to
the first one, the record was mysteriously duplicated.
When moving the record, it should be removed from the old column.
In this case, the second column was not found (and thus the record
not removed) because the iteration was on `parent.count` (which is
the count of records in this datapoint (1 in our case)) and not
parent.data.length (the number of columns).