diff --git a/addons/web/static/src/views/fields/progress_bar/kanban_progress_bar_field.js b/addons/web/static/src/views/fields/progress_bar/kanban_progress_bar_field.js
index 97c39bf4aa1..470d8bf67ff 100644
--- a/addons/web/static/src/views/fields/progress_bar/kanban_progress_bar_field.js
+++ b/addons/web/static/src/views/fields/progress_bar/kanban_progress_bar_field.js
@@ -5,7 +5,7 @@ import { ProgressBarField } from "./progress_bar_field";
export class KanbanProgressBarField extends ProgressBarField {
onClick() {
- if (this.props.isEditable && !this.props.record.isReadonly(this.props.name)) {
+ if (this.props.isEditable) {
this.state.isEditing = true;
}
}
diff --git a/addons/web/static/src/views/fields/progress_bar/progress_bar_field.js b/addons/web/static/src/views/fields/progress_bar/progress_bar_field.js
index 58d001165d2..287061489f0 100644
--- a/addons/web/static/src/views/fields/progress_bar/progress_bar_field.js
+++ b/addons/web/static/src/views/fields/progress_bar/progress_bar_field.js
@@ -1,10 +1,11 @@
/** @odoo-module **/
-import { registry } from "@web/core/registry";
import { _lt } from "@web/core/l10n/translation";
+import { registry } from "@web/core/registry";
+import { useAutofocus } from "@web/core/utils/hooks";
+import { useNumpadDecimal } from "../numpad_decimal_hook";
import { parseFloat } from "../parsers";
import { standardFieldProps } from "../standard_field_props";
-import { useNumpadDecimal } from "../numpad_decimal_hook";
const { Component, onWillUpdateProps, useState } = owl;
const formatters = registry.category("formatters");
@@ -13,6 +14,8 @@ const parsers = registry.category("parsers");
export class ProgressBarField extends Component {
setup() {
useNumpadDecimal();
+ useAutofocus({ refName: "max-value", selectAll: true });
+ useAutofocus({ refName: "current-value", selectAll: true });
this.state = useState({
currentValue: this.getCurrentValue(this.props),
maxValue: this.getMaxValue(this.props),
@@ -62,10 +65,10 @@ export class ProgressBarField extends Component {
return formatter(this.state.maxValue, { humanReadable });
}
- onCurrentValueChange(value) {
+ onCurrentValueChange(ev) {
let parsedValue;
try {
- parsedValue = parseFloat(value);
+ parsedValue = parseFloat(ev.target.value);
} catch {
this.props.record.setInvalidField(this.props.name);
return;
@@ -81,10 +84,10 @@ export class ProgressBarField extends Component {
this.props.record.save();
}
}
- onMaxValueChange(value) {
+ onMaxValueChange(ev) {
let parsedValue;
try {
- parsedValue = parseFloat(value);
+ parsedValue = parseFloat(ev.target.value);
} catch {
this.props.record.setInvalidField(this.props.name);
return;
@@ -151,7 +154,7 @@ ProgressBarField.extractProps = ({ attrs }) => {
maxValueField: attrs.options.max_value,
currentValueField: attrs.options.current_value,
isPercentage: !attrs.options.max_value,
- isEditable: attrs.options.editable,
+ isEditable: !attrs.options.readonly && attrs.options.editable,
isEditableInReadonly: attrs.options.editable_readonly,
isCurrentValueEditable:
attrs.options.editable &&
diff --git a/addons/web/static/src/views/fields/progress_bar/progress_bar_field.xml b/addons/web/static/src/views/fields/progress_bar/progress_bar_field.xml
index 20b0134418a..351fa5235fe 100644
--- a/addons/web/static/src/views/fields/progress_bar/progress_bar_field.xml
+++ b/addons/web/static/src/views/fields/progress_bar/progress_bar_field.xml
@@ -30,8 +30,8 @@
inputmode="numeric"
t-att-value="formatCurrentValue() or ''"
t-att-required="props.required"
- t-on-change="(ev) => this.onCurrentValueChange(ev.target.value)"
- t-on-input="(ev) => this.onCurrentValueInput(ev)"
+ t-on-change="onCurrentValueChange"
+ t-on-input="onCurrentValueInput"
t-on-blur="onBlur"
/>
%
@@ -40,23 +40,25 @@
@@ -65,4 +67,3 @@
-
diff --git a/addons/web/static/src/views/kanban/kanban_arch_parser.js b/addons/web/static/src/views/kanban/kanban_arch_parser.js
index ebf7ca3bc7a..5bf4b4a1ceb 100644
--- a/addons/web/static/src/views/kanban/kanban_arch_parser.js
+++ b/addons/web/static/src/views/kanban/kanban_arch_parser.js
@@ -72,6 +72,11 @@ export class KanbanArchParser extends XMLParser {
node.setAttribute("widget", "many2many_tags");
}
const fieldInfo = Field.parseFieldNode(node, models, modelName, "kanban", jsClass);
+ if (!node.hasAttribute("force_save")) {
+ // Force save is true by default on kanban views:
+ // this allows to write on any field regardless of its modifiers.
+ fieldInfo.forceSave = true;
+ }
const name = fieldInfo.name;
fieldNodes[name] = fieldInfo;
node.setAttribute("field_id", name);
diff --git a/addons/web/static/tests/views/fields/progress_bar_field_tests.js b/addons/web/static/tests/views/fields/progress_bar_field_tests.js
index 0eeee07cece..9eb8d205239 100644
--- a/addons/web/static/tests/views/fields/progress_bar_field_tests.js
+++ b/addons/web/static/tests/views/fields/progress_bar_field_tests.js
@@ -364,6 +364,8 @@ QUnit.module("Fields", (hooks) => {
QUnit.test("ProgressBarField: field is editable in kanban", async function (assert) {
assert.expect(7);
+
+ serverData.models.partner.fields.int_field.readonly = true;
serverData.models.partner.records[0].int_field = 99;
await makeView({
@@ -412,6 +414,7 @@ QUnit.module("Fields", (hooks) => {
);
await editInput(target, ".o_progressbar_value.o_input", "69");
+
assert.strictEqual(
target.querySelector(".o_progressbar_value").textContent,
"69 / 100",
@@ -423,6 +426,42 @@ QUnit.module("Fields", (hooks) => {
);
});
+ QUnit.test("force readonly in kanban", async (assert) => {
+ assert.expect(3);
+
+ serverData.models.partner.records[0].int_field = 99;
+
+ await makeView({
+ serverData,
+ type: "kanban",
+ resModel: "partner",
+ arch: /* xml */ `
+
+
+
+
+
+
+
+
+ `,
+ resId: 1,
+ mockRPC(route, { method, args }) {
+ if (method === "write") {
+ throw new Error("Not supposed to write");
+ }
+ },
+ });
+
+ assert.strictEqual(target.querySelector(".o_progressbar_value").textContent, "99 / 100");
+
+ // Clicking on the progress bar should not change the value
+ await click(target.querySelector(".o_progress"));
+
+ assert.strictEqual(target.querySelector(".o_progressbar_value").textContent, "99 / 100");
+ assert.containsNone(target, ".o_progressbar_value.o_input");
+ });
+
QUnit.test(
"ProgressBarField: readonly and editable attrs/options in kanban",
async function (assert) {