[REF] web, * : simplify concrete fields API - remove update prop

This commit, is part of a series of commits that aim to simplifie
the concrete fields API.

In this commit we will remove update prop from concrete fields. Now each
field will directly use this.props.record.update to make changes, and
handle the save in fields that need to (e.g. priority). As a consequence
of this, the record props need to be mandatory.

task-id 3179751

Part-of: odoo/odoo#112792
This commit is contained in:
Jorge Pinna Puissant
2023-02-22 13:46:19 +01:00
parent bc15040c8e
commit 8cde3e84bb
47 changed files with 194 additions and 137 deletions
@@ -415,7 +415,7 @@ export class AnalyticDistribution extends Component {
async save() {
const currentDistribution = this.listForJson;
const dataToSave = currentDistribution;
await this.props.update(dataToSave);
await this.props.record.update({ [this.props.name]: dataToSave });
}
onSaveNew() {
@@ -33,22 +33,26 @@ export function useAssignUserCommand() {
const add = async (record) => {
if (component.props.type === "many2one") {
component.props.update(record);
component.props.record.update({ [component.props.name]: record });
} else if (component.props.type === "many2many") {
component.props.update({
operation: "REPLACE_WITH",
resIds: [...getCurrentIds(), record[0]],
component.props.record.update({
[component.props.name]: {
operation: "REPLACE_WITH",
resIds: [...getCurrentIds(), record[0]],
},
});
}
};
const remove = async (record) => {
if (component.props.type === "many2one") {
component.props.update([]);
component.props.record.update({ [component.props.name]: [] });
} else if (component.props.type === "many2many") {
component.props.update({
operation: "REPLACE_WITH",
resIds: getCurrentIds().filter((id) => id !== record[0]),
component.props.record.update({
[component.props.name]: {
operation: "REPLACE_WITH",
resIds: getCurrentIds().filter((id) => id !== record[0]),
},
});
}
};
+1 -1
View File
@@ -8,7 +8,7 @@ import { standardFieldProps } from "@web/views/fields/standard_field_props";
const { Component, useState, onWillUpdateProps, onWillStart, onWillDestroy } = owl;
function formatMinutes(value) {
export function formatMinutes(value) {
if (value === false) {
return "";
}
@@ -4,8 +4,7 @@ import { useService } from '@web/core/utils/hooks';
import { TextField } from '@web/views/fields/text/text_field';
import { PortalAttachDocument } from '../portal_attach_document/portal_attach_document';
import { ChatterAttachmentsViewer } from './chatter_attachments_viewer';
const { Component, useState, onWillUpdateProps } = owl;
import { Component, useState, onWillUpdateProps, useRef } from "@odoo/owl";
export class ChatterComposer extends Component {
setup() {
@@ -16,6 +15,7 @@ export class ChatterComposer extends Component {
message: '',
loading: false,
});
this.inputRef = useRef("textarea");
onWillUpdateProps(this.onWillUpdateProps);
}
@@ -23,6 +23,7 @@ export class ChatterComposer extends Component {
onWillUpdateProps(nextProps) {
this.clearErrors();
this.state.message = '';
this.inputRef.el.value = "";
this.state.attachments = nextProps.attachments.map(file => file.state === 'done');
}
@@ -30,9 +31,9 @@ export class ChatterComposer extends Component {
return `${window.location.href.split('#')[0]}#discussion`;
}
update(change) {
update() {
this.clearErrors();
this.state.message = change;
this.state.message = this.inputRef.el.value;
}
prepareMessageData() {
@@ -20,11 +20,13 @@
<div class="flex-grow-1">
<div class="o_portal_chatter_composer_input">
<div class="o_portal_chatter_composer_body mb32">
<TextField
rowCount="4"
placeholder="'Write a message...'"
<textarea
class="o_input"
placeholder="Write a message..."
rows="4"
value="state.message"
update.bind="update"
t-on-input="update"
t-ref="textarea"
/>
<ChatterAttachmentsViewer
attachments="state.attachments"
@@ -113,7 +113,7 @@ export class AceField extends Component {
if (!this.props.readonly) {
const value = this.aceSession.getValue();
if (this.props.value !== value) {
return this.props.update(value);
return this.props.record.update({ [this.props.name]: value });
}
}
}
@@ -54,13 +54,15 @@ export class BadgeSelectionField extends Component {
switch (this.props.type) {
case "many2one":
if (value === false) {
this.props.update(false);
this.props.record.update({ [this.props.name]: false });
} else {
this.props.update(this.options.find((option) => option[0] === value));
this.props.record.update({
[this.props.name]: this.options.find((option) => option[0] === value),
});
}
break;
case "selection":
this.props.update(value);
this.props.record.update({ [this.props.name]: value });
break;
}
}
@@ -22,7 +22,7 @@ export class BooleanField extends Component {
* @param {boolean} newValue
*/
onChange(newValue) {
this.props.update(newValue);
this.props.record.update({ [this.props.name]: newValue });
}
}
@@ -16,6 +16,10 @@ export class BooleanFavoriteField extends Component {
static defaultProps = {
noLabel: false,
};
update() {
this.props.record.update({ [this.props.name]: !this.props.value });
}
}
export const booleanFavoriteField = {
@@ -2,7 +2,7 @@
<templates xml:space="preserve">
<t t-name="web.BooleanFavoriteField" owl="1">
<div class="o_favorite" t-on-click.prevent.stop="() => props.update(!props.value)">
<div class="o_favorite" t-on-click.prevent.stop="update">
<a href="#">
<i
class="fa"
@@ -18,6 +18,10 @@ export class BooleanIconField extends Component {
get label() {
return this.props.record.activeFields[this.props.name].string;
}
update() {
this.props.record.update({ [this.props.name]: !this.props.value });
}
}
export const booleanIconField = {
@@ -2,7 +2,7 @@
<templates xml:space="preserve">
<t t-name="web.BooleanIconField" owl="1">
<button t-attf-class="btn btn-sm btn-{{props.value ? 'primary' : 'outline-secondary'}} mx-2 py-1 fa {{props.icon}}" t-att-data-tooltip="label" t-on-click.prevent.stop="() => props.update(!props.value)" />
<button t-attf-class="btn btn-sm btn-{{props.value ? 'primary' : 'outline-secondary'}} mx-2 py-1 fa {{props.icon}}" t-att-data-tooltip="label" t-on-click.prevent.stop="update" />
</t>
</templates>
@@ -10,6 +10,18 @@ export class BooleanToggleField extends BooleanField {
get isReadonly() {
return this.props.record.isReadonly(this.props.name);
}
async onChange(newValue) {
await this.props.record.update({ [this.props.name]: newValue });
const rootRecord =
this.props.record.model.root instanceof this.props.record.constructor &&
this.props.record.model.root;
const isInEdition = rootRecord ? rootRecord.isInEdition : this.props.record.isInEdition;
// We save only if we're on view mode readonly and no readonly field modifier
if (!isInEdition) {
return this.props.record.save();
}
}
}
export const booleanToggleField = {
@@ -8,7 +8,7 @@ export class ListBooleanToggleField extends BooleanToggleField {
onClick() {
if (!this.props.readonly) {
this.props.update(!this.props.value);
this.props.record.update({ [this.props.name]: !this.props.value });
}
}
}
@@ -66,9 +66,10 @@ export class CharField extends Component {
let dynamicPlaceholder = "{{object." + chain.join(".");
dynamicPlaceholder +=
defaultValue && defaultValue !== "" ? ` or '''${defaultValue}'''}}` : "}}";
this.props.update(
this.input.el.value.replace(triggerKeyReplaceRegex, "") + dynamicPlaceholder
);
this.props.record.update({
[this.props.name]:
this.input.el.value.replace(triggerKeyReplaceRegex, "") + dynamicPlaceholder,
});
}
}
onDynamicPlaceholderClose() {
@@ -3,7 +3,7 @@
<t t-name="web.ColorField" owl="1">
<div class="o_field_color d-flex" t-att-class="{ 'o_field_cursor_disabled': isReadonly }" t-attf-style="background: #{state.color or 'url(/web/static/img/transparent.png)'}">
<input t-on-click.stop="" class="w-100 h-100 opacity-0" type="color" t-att-value="state.color" t-att-disabled="isReadonly" t-on-input="(ev) => this.state.color = ev.target.value" t-on-change="(ev) => this.props.update(ev.target.value)" />
<input t-on-click.stop="" class="w-100 h-100 opacity-0" type="color" t-att-value="state.color" t-att-disabled="isReadonly" t-on-input="(ev) => this.state.color = ev.target.value" t-on-change="(ev) => this.props.record.update({ [this.props.name]: ev.target.value })" />
</div>
</t>
@@ -26,7 +26,7 @@ export class ColorPickerField extends Component {
}
switchColor(colorIndex) {
this.props.update(colorIndex);
this.props.record.update({ [this.props.name]: colorIndex });
}
}
@@ -46,7 +46,7 @@ export class DateField extends Component {
onDateTimeChanged(date) {
if (!areDateEquals(this.date || "", date)) {
this.props.update(date);
this.props.record.update({ [this.props.name]: date });
}
}
onDatePickerInput(ev) {
@@ -114,7 +114,7 @@ export class DateRangeField extends Component {
this.props.record.setInvalidField(this.props.name);
return;
}
this.props.update(value);
this.props.record.update({ [this.props.name]: value });
}
onWindowScroll(ev) {
@@ -36,7 +36,7 @@ export class DateTimeField extends Component {
onDateTimeChanged(date) {
if (!areDateEquals(this.props.value || "", date)) {
this.props.update(date);
this.props.record.update({ [this.props.name]: date });
}
}
onDatePickerInput(ev) {
@@ -125,7 +125,7 @@ export class DomainField extends Component {
update(domain, isDebugEdited) {
this.isDebugEdited = isDebugEdited;
return this.props.update(domain);
this.props.record.update({ [this.props.name]: domain });
}
onEditDialogBtnClick() {
@@ -134,7 +134,7 @@ export class DomainField extends Component {
initialValue: this.props.value || "[]",
readonly: this.props.readonly,
isDebugMode: !!this.env.debug,
onSelected: this.props.update,
onSelected: (value) => this.props.record.update({ [this.props.name]: value }),
});
}
}
@@ -160,20 +160,6 @@ export class Field extends Component {
return {
...fieldInfo.props,
update: async (value) => {
await record.update({ [this.props.name]: value });
if (record.selected && record.model.multiEdit) {
return;
}
const rootRecord =
record.model.root instanceof record.constructor && record.model.root;
const isInEdition = rootRecord ? rootRecord.isInEdition : record.isInEdition;
// We save only if we're on view mode readonly and no readonly field modifier
if (!isInEdition && !readonlyFromModifiers) {
// TODO: maybe move this in the model
return record.save();
}
},
value: this.props.record.data[this.props.name],
decorations: decorationMap,
readonly: !record.isInEdition || readonlyFromModifiers || false,
@@ -37,10 +37,14 @@ export class FloatField extends Component {
}
get formattedValue() {
if (this.props.inputType === "number" && !this.props.readonly && this.props.value) {
return this.props.value;
if (this.props.inputType === "number" && !this.props.readonly && this.value) {
return this.value;
}
return formatFloat(this.props.value, { digits: this.props.digits });
return formatFloat(this.value, { digits: this.props.digits });
}
get value() {
return this.props.value;
}
}
@@ -2,11 +2,8 @@
import { registry } from "@web/core/registry";
import { floatField, FloatField } from "../float/float_field";
import { Component } from "@odoo/owl";
export class FloatFactorField extends Component {
static template = "web.FloatFactorField";
static components = { FloatField };
export class FloatFactorField extends FloatField {
static props = {
...FloatField.props,
factor: { type: Number, optional: true },
@@ -16,18 +13,16 @@ export class FloatFactorField extends Component {
factor: 1,
};
get factor() {
return this.props.factor;
parse(value) {
let factorValue = value / this.props.factor;
if (this.props.inputType !== "number") {
factorValue = factorValue.toString();
}
return super.parse(factorValue);
}
get floatFieldProps() {
const result = {
...this.props,
value: this.props.value * this.factor,
update: (value) => this.props.update(value / this.factor),
};
delete result.factor;
return result;
get value() {
return this.props.value * this.props.factor;
}
}
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="web.FloatFactorField" owl="1">
<FloatField t-props="floatFieldProps" />
</t>
</templates>
@@ -29,7 +29,9 @@ export class FloatToggleField extends Component {
if (currentIndex > this.props.range.length - 1) {
currentIndex = 0;
}
this.props.update(this.props.range[currentIndex] / this.factor);
this.props.record.update({
[this.props.name]: this.props.range[currentIndex] / this.factor,
});
}
// This property has been created in order to allow overrides in other modules.
@@ -35,7 +35,7 @@ export class FontSelectionField extends Component {
*/
onChange(ev) {
const value = JSON.parse(ev.target.value);
this.props.update(value);
this.props.record.update({ [this.props.name]: value });
}
}
@@ -112,13 +112,13 @@ export class ImageField extends Component {
}
onFileRemove() {
this.state.isValid = true;
this.props.update(false);
this.props.record.update({ [this.props.name]: false });
}
onFileUploaded(info) {
this.state.isValid = true;
// Invalidate the `rawCacheKey`.
this.rawCacheKey = null;
this.props.update(info.data);
this.props.record.update({ [this.props.name]: info.data });
}
onLoadFailed() {
this.state.isValid = false;
@@ -64,16 +64,16 @@ export function useInputField(params) {
try {
val = params.parse(val);
} catch {
if (component.props.record) {
component.props.record.setInvalidField(component.props.name);
}
component.props.record.setInvalidField(component.props.name);
isInvalid = true;
}
}
if (!isInvalid) {
pendingUpdate = true;
Promise.resolve(component.props.update(val)).then(() => {
Promise.resolve(
component.props.record.update({ [component.props.name]: val })
).then(() => {
pendingUpdate = false;
});
lastSetValue = ev.target.value;
@@ -114,10 +114,7 @@ export function useInputField(params) {
* If it is not such a case, we update the field with the new value.
*/
useEffect(() => {
const isInvalid = component.props.record
? component.props.record.isInvalid(component.props.name)
: false;
if (inputRef.el && !isDirty && !isInvalid) {
if (inputRef.el && !isDirty && !component.props.record.isInvalid(component.props.name)) {
inputRef.el.value = params.getValue();
lastSetValue = inputRef.el.value;
}
@@ -148,7 +145,7 @@ export function useInputField(params) {
isInvalid = true;
if (urgent) {
return;
} else if (component.props.record) {
} else {
component.props.record.setInvalidField(component.props.name);
}
}
@@ -159,7 +156,7 @@ export function useInputField(params) {
}
if ((val || false) !== (component.props.value || false)) {
await component.props.update(val);
await component.props.record.update({ [component.props.name]: val });
lastSetValue = inputRef.el.value;
if (component.props.setDirty) {
component.props.setDirty(isDirty);
@@ -57,6 +57,7 @@ export class Many2OneField extends Component {
relation: { type: String, optional: true },
string: { type: String, optional: true },
canScanBarcode: { type: Boolean, optional: true },
update: { type: Function, optional: true },
openTarget: {
type: String,
validate: (v) => ["current", "new"].includes(v),
@@ -101,7 +102,7 @@ export class Many2OneField extends Component {
isToMany: false,
onRecordSaved: async (record) => {
await this.props.record.load();
await this.props.update(m2oTupleFromData(record.data));
await this.updateRecord(m2oTupleFromData(record.data));
if (this.props.record.model.root.id !== this.props.record.id) {
this.props.record.switchMode("readonly");
}
@@ -115,7 +116,7 @@ export class Many2OneField extends Component {
value = m2oTupleFromData(value[0]);
}
this.state.isFloating = false;
return this.props.update(value);
return this.updateRecord(value);
};
if (this.props.canQuickCreate) {
@@ -123,7 +124,7 @@ export class Many2OneField extends Component {
if (params.triggeredOnBlur) {
return this.openConfirmationDialog(name);
}
return this.props.update([false, name]);
return this.updateRecord([false, name]);
};
}
@@ -137,6 +138,14 @@ export class Many2OneField extends Component {
});
}
updateRecord(value) {
const changes = { [this.props.name]: value };
if (this.props.update) {
return this.props.update(changes);
}
return this.props.record.update(changes);
}
get relation() {
return this.props.relation || this.props.record.fields[this.props.name].relation;
}
@@ -299,7 +308,6 @@ export const many2OneField = {
nameCreateField: attrs.options.create_name_field,
canScanBarcode: !!attrs.options.can_scan_barcode,
openTarget: attrs.open_target,
relation: field.relation,
string: attrs.string || field.string,
};
@@ -31,7 +31,7 @@ export class PriorityField extends Component {
this.options.map((value) => ({
name: value[1],
action: () => {
this.props.update(value[0]);
this.updateRecord(value[0]);
},
})),
},
@@ -66,9 +66,21 @@ export class PriorityField extends Component {
onStarClicked(value) {
if (this.props.value === value) {
this.state.index = -1;
this.props.update(this.options[0][0]);
this.updateRecord(this.options[0][0]);
} else {
this.props.update(value);
this.updateRecord(value);
}
}
async updateRecord(value) {
await this.props.record.update({ [this.props.name]: value });
const rootRecord =
this.props.record.model.root instanceof this.props.record.constructor &&
this.props.record.model.root;
const isInEdition = rootRecord ? rootRecord.isInEdition : this.props.record.isInEdition;
// We save only if we're on view mode readonly and no readonly field modifier
if (!isInEdition) {
return this.props.record.save();
}
}
}
@@ -193,7 +193,7 @@ export class PropertiesField extends Component {
propertiesValues[targetIndex] = propertiesValues[propertyIndex];
propertiesValues[propertyIndex] = prop;
propertiesValues[propertyIndex].definition_changed = true;
this.props.update(propertiesValues).then(() => {
this.props.record.update({ [this.props.name]: propertiesValues }).then(() => {
// move the popover once the DOM is updated
this.shouldUpdatePopoverPosition = true;
});
@@ -209,7 +209,7 @@ export class PropertiesField extends Component {
onPropertyValueChange(propertyName, propertyValue) {
const propertiesValues = this.propertiesList;
propertiesValues.find((property) => property.name === propertyName).value = propertyValue;
this.props.update(propertiesValues);
this.props.record.update({ [this.props.name]: propertiesValues });
}
/**
@@ -247,7 +247,7 @@ export class PropertiesField extends Component {
this._regeneratePropertyName(propertyDefinition);
propertiesValues[propertyIndex] = propertyDefinition;
this.props.update(propertiesValues);
this.props.record.update({ [this.props.name]: propertiesValues });
}
/**
@@ -275,7 +275,7 @@ export class PropertiesField extends Component {
propertiesDefinitions.find(
(property) => property.name === propertyName
).definition_deleted = true;
this.props.update(propertiesDefinitions);
this.props.record.update({ [this.props.name]: propertiesDefinitions });
},
cancel: () => {},
};
@@ -307,7 +307,7 @@ export class PropertiesField extends Component {
definition_changed: true,
});
this.openLastPropertyDefinition = true;
this.props.update(propertiesDefinitions);
this.props.record.update({ [this.props.name]: propertiesDefinitions });
}
/**
@@ -58,10 +58,10 @@ export class RadioField extends Component {
onChange(value) {
switch (this.props.type) {
case "selection":
this.props.update(value[0]);
this.props.record.update({ [this.props.name]: value[0] });
break;
case "many2one":
this.props.update(value);
this.props.record.update({ [this.props.name]: value });
break;
}
}
@@ -34,7 +34,7 @@ export class ReferenceField extends Component {
this.state.resModel &&
this.getRelation(nextProps) !== this.state.resModel
) {
nextProps.update(false);
nextProps.record.update({ [this.props.name]: false });
}
});
}
@@ -102,20 +102,21 @@ export class ReferenceField extends Component {
updateModel(value) {
this.state.resModel = value;
this.props.update(false);
this.props.record.update({ [this.props.name]: false });
}
updateM2O(value) {
updateM2O(data) {
const value = data[this.props.name];
if (!this.state.resModel) {
this.state.resModel = this.relation;
}
this.props.update(
value && {
this.props.record.update({
[this.props.name]: value && {
resModel: this.state.resModel,
resId: value[0],
displayName: value[1],
}
);
},
});
}
}
@@ -39,10 +39,10 @@ export class RemainingDaysField extends Component {
onDateTimeChanged(datetime) {
if (datetime) {
this.props.update(datetime);
this.props.record.update({ [this.props.name]: datetime });
} else if (typeof datetime === "string") {
// when the date is cleared
this.props.update(false);
this.props.record.update({ [this.props.name]: false });
}
}
}
@@ -57,13 +57,15 @@ export class SelectionField extends Component {
switch (this.props.type) {
case "many2one":
if (value === false) {
this.props.update(false);
this.props.record.update({ [this.props.name]: false });
} else {
this.props.update(this.options.find((option) => option[0] === value));
this.props.record.update({
[this.props.name]: this.options.find((option) => option[0] === value),
});
}
break;
case "selection":
this.props.update(value);
this.props.record.update({ [this.props.name]: value });
break;
}
}
@@ -130,7 +130,7 @@ export class SignatureField extends Component {
* @private
*/
uploadSignature({ signatureImage }) {
return this.props.update(signatureImage[1] || false);
return this.props.record.update({ [this.props.name]: signatureImage[1] || false });
}
}
@@ -4,9 +4,8 @@ export const standardFieldProps = {
id: { type: String, optional: true },
name: { type: String, optional: true },
readonly: { type: Boolean, optional: true },
record: { type: Object, optional: true },
record: { type: Object },
type: { type: String, optional: true },
update: { type: Function, optional: true },
value: true,
decorations: { type: Object, optional: true },
setDirty: { type: Function, optional: true },
@@ -37,7 +37,7 @@ export class StateSelectionField extends Component {
for (const [index, [value, label]] of this.options.entries()) {
useCommand(
sprintf(this.env._t("Set kanban state as %s"), label),
() => this.props.update(value),
() => this.updateRecord(value),
{
category: "smart_action",
hotkey: "alt+" + hotkeys[index],
@@ -76,6 +76,18 @@ export class StateSelectionField extends Component {
statusColor(value) {
return this.colors[value] ? this.colorPrefix + this.colors[value] : "";
}
async updateRecord(value) {
await this.props.record.update({ [this.props.name]: value });
const rootRecord =
this.props.record.model.root instanceof this.props.record.constructor &&
this.props.record.model.root;
const isInEdition = rootRecord ? rootRecord.isInEdition : this.props.record.isInEdition;
// We save only if we're on view mode readonly and no readonly field modifier
if (!isInEdition) {
return this.props.record.save();
}
}
}
export const stateSelectionField = {
@@ -17,7 +17,7 @@
</div>
</t>
<t t-foreach="availableOptions" t-as="option" t-key="option[0]">
<DropdownItem onSelected="() => props.update(option[0])">
<DropdownItem onSelected="() => this.updateRecord(option[0])">
<div class="d-flex align-items-center">
<span t-attf-class="o_status {{ statusColor(option[0]) }} "/>
<span class="ms-2" t-esc="option[1]"/>
@@ -192,12 +192,24 @@ export class StatusBarField extends Component {
}
selectItem(item) {
const rootRecord =
this.props.record.model.root instanceof this.props.record.constructor &&
this.props.record.model.root;
const isInEdition = rootRecord ? rootRecord.isInEdition : this.props.record.isInEdition;
switch (this.props.type) {
case "many2one":
this.props.update([item.id, item.name]);
this.props.record.update({ [this.props.name]: [item.id, item.name] });
// We save only if we're on view mode readonly and no readonly field modifier
if (!isInEdition) {
return this.props.record.save();
}
break;
case "selection":
this.props.update(item.id);
this.props.record.update({ [this.props.name]: item.id });
// We save only if we're on view mode readonly and no readonly field modifier
if (!isInEdition) {
return this.props.record.save();
}
break;
}
}
@@ -73,9 +73,11 @@ export class TextField extends Component {
let dynamicPlaceholder = "{{object." + chain.join(".");
dynamicPlaceholder +=
defaultValue && defaultValue !== "" ? ` or '''${defaultValue}'''}}` : "}}";
this.props.update(
this.textareaRef.el.value.replace(triggerKeyReplaceRegex, "") + dynamicPlaceholder
);
this.props.record.update({
[this.props.name]:
this.textareaRef.el.value.replace(triggerKeyReplaceRegex, "") +
dynamicPlaceholder,
});
}
}
onDynamicPlaceholderClose() {
@@ -1669,10 +1669,13 @@ class DynamicList extends DataPoint {
fieldNodes: this.model.fieldNodes,
};
this.model.trigger("list-confirmation-dialog-will-open");
await this.model.dialogService.add(ListConfirmationDialog, dialogProps, {
onClose: () => {
this.model.trigger("list-confirmation-dialog-closed");
},
await new Promise((resolve) => {
this.model.dialogService.add(ListConfirmationDialog, dialogProps, {
onClose: () => {
this.model.trigger("list-confirmation-dialog-closed");
resolve();
},
});
});
} else {
await record._save();
@@ -24,7 +24,7 @@ export class UpgradeBooleanField extends BooleanField {
{},
{
onClose: () => {
this.props.update(false);
this.props.record.update({ [this.props.name]: false });
},
}
);
@@ -11811,7 +11811,7 @@ QUnit.module("Views", (hooks) => {
);
// Close the confirmation dialog
await click(target.querySelector(".modal .btn-primary"));
await click(target.querySelectorAll(".modal")[1], ".btn-primary");
assert.strictEqual(
target.querySelector(".o_data_cell").innerText,
@@ -277,7 +277,7 @@ QUnit.module("Record Component", (hooks) => {
Parent.components = { Record, Many2OneField };
Parent.template = xml`
<Record resModel="'partner'" fieldNames="['foo']" fields="fields" values="values" t-slot-scope="data" onRecordChanged.bind="onRecordChanged">
<Many2OneField name="'foo'" record="data.record" relation="'bar'" value="data.record.data.foo" update="(value) => data.record.update({ foo: value })"/>
<Many2OneField name="'foo'" record="data.record" relation="'bar'" value="data.record.data.foo"/>
</Record>
`;
@@ -284,7 +284,7 @@ export class HtmlField extends Component {
if (value !== null && !(!lastValue && stripHistoryIds(value) === "<p><br></p>") && value !== lastValue) {
this.props.setDirty(false);
this.currentEditingValue = value;
await this.props.update(value);
await this.props.record.update({ [this.props.name]: value });
}
}
async startWysiwyg(wysiwyg) {
@@ -320,12 +320,12 @@ export class HtmlField extends Component {
if (this.state.showCodeView) {
this.wysiwyg.odooEditor.toolbarHide();
const value = this.wysiwyg.getValue();
this.props.update(value);
this.props.record.update({ [this.props.name]: value });
} else {
this.wysiwyg.odooEditor.observerActive('toggleCodeView');
const $codeview = $(this.codeViewRef.el);
const value = $codeview.val();
this.props.update(value);
this.props.record.update({ [this.props.name]: value });
}
}
@@ -562,7 +562,7 @@ export class HtmlField extends Component {
checked: !checked,
});
if (value) {
this.props.update(value);
this.props.record.update({ [this.props.name]: value });
}
}
async _onReadonlyClickStar(ev) {
@@ -590,7 +590,7 @@ export class HtmlField extends Component {
rating,
});
if (value) {
this.props.update(value);
this.props.record.update({ [this.props.name]: value });
}
}
}