[IMP] web: add disabled props to CopyButton and CopyClipboard field

The CopyClipboardButton Component acts as a button. As such it is
interesting to add the possibility to make it disabled when needed.
This commit adds the possibility to add the attribute `disabled="1"`
to the xml code and let it function as one should expect.

See task 2672713 for a practical use.

closes odoo/odoo#111724

Signed-off-by: Luca Vitali <luvi@odoo.com>
This commit is contained in:
hote
2023-02-07 12:36:45 +01:00
committed by Horacio Tellez
parent ba5eb671af
commit c1f8c4abda
5 changed files with 74 additions and 7 deletions
@@ -42,6 +42,7 @@ CopyButton.template = "web.CopyButton";
CopyButton.props = {
className: { type: String, optional: true },
copyText: { type: String, optional: true },
disabled: { type: Boolean, optional: true },
successText: { type: String, optional: true },
content: { type: [String, Object], optional: true },
};
@@ -5,6 +5,7 @@
<button
class="text-nowrap"
t-ref="button"
t-att-disabled="props.disabled"
t-attf-class="btn btn-primary o_clipboard_button {{ props.className || '' }}"
t-on-click.stop="onClick"
>
@@ -1,7 +1,10 @@
/** @odoo-module **/
import { _lt } from "@web/core/l10n/translation";
import { evaluateExpr } from "@web/core/py_js/py";
import { evalDomain } from "@web/views/utils";
import { registry } from "@web/core/registry";
import { omit } from "@web/core/utils/objects";
import { CopyButton } from "./copy_button";
import { UrlField } from "../url/url_field";
@@ -20,19 +23,27 @@ class CopyClipboardField extends Component {
return `o_btn_${this.props.type}_copy btn-sm`;
}
get fieldProps() {
const fieldProps = {...this.props};
delete fieldProps.string;
return fieldProps;
return omit(this.props, "string", "disabledExpr");
}
get disabled() {
const context = this.props.record.evalContext;
const evaluated = this.props.disabledExpr ? evaluateExpr(this.props.disabledExpr) : false;
if (evaluated instanceof Array) {
return evalDomain(evaluated, context);
}
return Boolean(evaluated);
}
}
CopyClipboardField.template = "web.CopyClipboardField";
CopyClipboardField.props = {
...standardFieldProps,
string: { type: String, optional: true },
disabledExpr: { type: String, optional: true },
};
CopyClipboardField.extractProps = ({ attrs }) => {
return {
string: attrs.string,
disabledExpr: attrs.disabled,
};
};
@@ -9,7 +9,7 @@
</t>
<t t-name="web.CopyClipboardButtonField" owl="1">
<CopyButton t-if="props.value" className="copyButtonClassName" content="props.value" copyText="copyText" successText="successText"/>
<CopyButton t-if="props.value" className="copyButtonClassName" content="props.value" copyText="copyText" disabled="disabled" successText="successText"/>
</t>
</templates>
@@ -2,7 +2,13 @@
import { browser } from "@web/core/browser/browser";
import { registry } from "@web/core/registry";
import { click, getFixture, nextTick, patchWithCleanup } from "@web/../tests/helpers/utils";
import {
click,
getFixture,
editInput,
nextTick,
patchWithCleanup,
} from "@web/../tests/helpers/utils";
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
const serviceRegistry = registry.category("services");
@@ -222,9 +228,9 @@ QUnit.module("Fields", (hooks) => {
);
});
QUnit.module("CopyToClipboardButtonField");
QUnit.module("CopyClipboardButtonField");
QUnit.test("CopyToClipboardButtonField in form view", async function (assert) {
QUnit.test("CopyClipboardButtonField in form view", async function (assert) {
patchWithCleanup(browser, {
navigator: {
clipboard: {
@@ -266,4 +272,52 @@ Ho-ho-hoooo Merry Christmas`,
"yop",
]);
});
QUnit.test("CopyClipboardButtonField can be disabled", async function (assert) {
patchWithCleanup(browser, {
navigator: {
clipboard: {
writeText: (text) => {
assert.step(text);
return Promise.resolve();
},
},
},
});
await makeView({
serverData,
type: "form",
resModel: "partner",
arch: `
<form>
<sheet>
<div>
<field name="text_field" disabled="1" widget="CopyClipboardButton"/>
<field name="char_field" disabled="[('char_field', '=', 'yop')]" widget="CopyClipboardButton"/>
<field name="char_field" widget="char"/>
</div>
</sheet>
</form>`,
resId: 1,
});
assert.containsOnce(
target,
".o_clipboard_button.o_btn_text_copy[disabled]",
"The inner button should be disabled."
);
assert.containsOnce(
target,
".o_clipboard_button.o_btn_char_copy[disabled]",
"The inner button should be disabled."
);
await editInput(target, ".o_input", "yip");
assert.containsNone(
target,
".o_clipboard_button.o_btn_char_copy[disabled]",
"The inner button should not be disabled."
);
});
});