[FIX] web: domain selector dialog: validate domain on confirm
With ab4f45b, the domain validation done on confirmation in the domain selector dialog was removed. Now that we have a new route /web/domain/validate (see previous commit) that allows us to quickly check the validity of a domain, we can reintroduce the validation. closes odoo/odoo#128913 X-original-commit: fa7788fac3c48e95dcbe78abb66ac5c284d27c56 Related: odoo/enterprise#44291 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com> Signed-off-by: Mathieu Duckerts-Antoine (dam) <dam@odoo.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import { useService } from "../utils/hooks";
|
||||
export class DomainSelectorDialog extends Component {
|
||||
setup() {
|
||||
this.notification = useService("notification");
|
||||
this.rpc = useService("rpc");
|
||||
this.orm = useService("orm");
|
||||
this.user = useService("user");
|
||||
this.state = useState({ domain: this.props.domain });
|
||||
@@ -50,13 +51,23 @@ export class DomainSelectorDialog extends Component {
|
||||
};
|
||||
}
|
||||
|
||||
onConfirm() {
|
||||
async onConfirm() {
|
||||
this.confirmButtonRef.el.disabled = true;
|
||||
const evalContext = { ...this.user.context, ...this.props.context };
|
||||
let domain;
|
||||
let isValid;
|
||||
try {
|
||||
const domain = new Domain(this.state.domain);
|
||||
domain.toList(evalContext);
|
||||
const evalContext = { ...this.user.context, ...this.props.context };
|
||||
domain = new Domain(this.state.domain).toList(evalContext);
|
||||
} catch {
|
||||
isValid = false;
|
||||
}
|
||||
if (isValid === undefined) {
|
||||
isValid = await this.rpc("/web/domain/validate", {
|
||||
model: this.props.resModel,
|
||||
domain,
|
||||
});
|
||||
}
|
||||
if (!isValid) {
|
||||
if (this.confirmButtonRef.el) {
|
||||
this.confirmButtonRef.el.disabled = false;
|
||||
}
|
||||
|
||||
@@ -109,15 +109,16 @@ QUnit.module("Components", (hooks) => {
|
||||
assert.strictEqual(domain, "[('foo', '=', uid)]");
|
||||
assert.step("confirmed");
|
||||
},
|
||||
mockRPC(_, args) {
|
||||
if (args.method === "search_count") {
|
||||
assert.step("rpc validation");
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
assert.step("validation");
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
const confirmButton = fixture.querySelector(".o_dialog footer button");
|
||||
await click(confirmButton);
|
||||
assert.verifySteps(["confirmed"]);
|
||||
assert.verifySteps(["validation", "confirmed"]);
|
||||
});
|
||||
|
||||
QUnit.test("can extend eval context", async (assert) => {
|
||||
@@ -129,15 +130,16 @@ QUnit.module("Components", (hooks) => {
|
||||
assert.step("confirmed");
|
||||
},
|
||||
|
||||
mockRPC(_, args) {
|
||||
if (args.method === "search_count") {
|
||||
assert.step("rpc validation");
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
assert.step("validation");
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
const confirmButton = fixture.querySelector(".o_dialog footer button");
|
||||
await click(confirmButton);
|
||||
assert.verifySteps(["confirmed"]);
|
||||
assert.verifySteps(["validation", "confirmed"]);
|
||||
});
|
||||
|
||||
QUnit.test("a domain with an unknown expression is not valid", async (assert) => {
|
||||
@@ -146,9 +148,9 @@ QUnit.module("Components", (hooks) => {
|
||||
onConfirm() {
|
||||
assert.step("confirmed");
|
||||
},
|
||||
mockRPC(_, args) {
|
||||
if (args.method === "search_count") {
|
||||
assert.step("rpc validation");
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
assert.step("validation");
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1612,6 +1612,11 @@ QUnit.module("Search", (hooks) => {
|
||||
context: {
|
||||
search_default_filter: true,
|
||||
},
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.deepEqual(getFacetTexts(target), ["Filter"]);
|
||||
assert.deepEqual(getDomain(controlPanel), [["foo", "=", "abc"]]);
|
||||
@@ -1669,6 +1674,11 @@ QUnit.module("Search", (hooks) => {
|
||||
searchMenuTypes: ["filter"],
|
||||
searchViewId: false,
|
||||
searchViewArch: `<search />`,
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.deepEqual(getFacetTexts(target), []);
|
||||
assert.deepEqual(getDomain(controlPanel), []);
|
||||
@@ -1694,6 +1704,11 @@ QUnit.module("Search", (hooks) => {
|
||||
searchMenuTypes: ["filter"],
|
||||
searchViewId: false,
|
||||
searchViewArch: `<search />`,
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.deepEqual(getFacetTexts(target), []);
|
||||
assert.deepEqual(getDomain(controlPanel), []);
|
||||
@@ -1717,6 +1732,11 @@ QUnit.module("Search", (hooks) => {
|
||||
searchMenuTypes: ["filter"],
|
||||
searchViewId: false,
|
||||
searchViewArch: `<search />`,
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
await toggleSearchBarMenu(target);
|
||||
await openAddCustomFilterDialog(target);
|
||||
@@ -1747,6 +1767,11 @@ QUnit.module("Search", (hooks) => {
|
||||
resModel: "foo",
|
||||
Component: SearchBar,
|
||||
searchMenuTypes: ["filter"],
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.deepEqual(getFacetTexts(target), []);
|
||||
assert.deepEqual(getDomain(controlPanel), []);
|
||||
@@ -1796,6 +1821,42 @@ QUnit.module("Search", (hooks) => {
|
||||
assert.deepEqual(getDomain(controlPanel), [["boolean", "!=", true]]);
|
||||
});
|
||||
|
||||
QUnit.test("Add a custom filter: notification on invalid domain", async function (assert) {
|
||||
assert.expect(3);
|
||||
patchWithCleanup(odoo, { debug: true });
|
||||
registry.category("services").add(
|
||||
"notification",
|
||||
{
|
||||
start() {
|
||||
return {
|
||||
add(message, options) {
|
||||
assert.strictEqual(message, "Domain is invalid. Please correct it");
|
||||
assert.deepEqual(options, { type: "danger" });
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{ force: true }
|
||||
);
|
||||
await makeWithSearch({
|
||||
serverData,
|
||||
resModel: "foo",
|
||||
Component: SearchBar,
|
||||
searchMenuTypes: ["filter"],
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
await toggleSearchBarMenu(target);
|
||||
await openAddCustomFilterDialog(target);
|
||||
await editInput(target, ".o_domain_debug_input", "[(uid, uid, uid)]");
|
||||
await click(target.querySelector(".modal footer button"));
|
||||
assert.containsOnce(target, ".modal .o_domain_selector");
|
||||
});
|
||||
|
||||
QUnit.test("display names in facets", async function (assert) {
|
||||
patchWithCleanup(odoo, { debug: true });
|
||||
serverData.models.partner = {
|
||||
@@ -1813,6 +1874,11 @@ QUnit.module("Search", (hooks) => {
|
||||
searchMenuTypes: ["filter"],
|
||||
searchViewId: false,
|
||||
searchViewArch: `<search />`,
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
await toggleSearchBarMenu(target);
|
||||
await openAddCustomFilterDialog(target);
|
||||
|
||||
@@ -1440,6 +1440,11 @@ QUnit.module("Search", (hooks) => {
|
||||
search_default_filter: true,
|
||||
search_default_bool: true,
|
||||
},
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.deepEqual(getFacetTexts(target), ["Filter", "Bool"]);
|
||||
assert.containsN(target, ".o_searchview_facet .o_searchview_facet_label", 2);
|
||||
@@ -1497,6 +1502,11 @@ QUnit.module("Search", (hooks) => {
|
||||
context: {
|
||||
search_default_filter: true,
|
||||
},
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.deepEqual(getFacetTexts(target), ["Filter"]);
|
||||
assert.deepEqual(getContext(controlPanel).specialKey, "abc");
|
||||
@@ -1533,6 +1543,11 @@ QUnit.module("Search", (hooks) => {
|
||||
</search>
|
||||
`,
|
||||
irFilters,
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.deepEqual(getFacetTexts(target), ["My favorite"]);
|
||||
assert.containsOnce(
|
||||
@@ -1578,6 +1593,11 @@ QUnit.module("Search", (hooks) => {
|
||||
context: {
|
||||
search_default_birthday: true,
|
||||
},
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.deepEqual(getFacetTexts(target), ["Birthday: April 2023"]);
|
||||
assert.containsOnce(
|
||||
@@ -1633,6 +1653,11 @@ QUnit.module("Search", (hooks) => {
|
||||
context: {
|
||||
search_default_foo: "abc",
|
||||
},
|
||||
mockRPC(route) {
|
||||
if (route === "/web/domain/validate") {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.deepEqual(getFacetTexts(target), ["Foo\nabc"]);
|
||||
assert.containsOnce(
|
||||
|
||||
@@ -914,6 +914,11 @@ QUnit.module("Fields", (hooks) => {
|
||||
<form>
|
||||
<field name="display_name" widget="domain" options="{'model': 'partner', 'in_dialog': True}"/>
|
||||
</form>`,
|
||||
mockRPC: (route) => {
|
||||
if (route === "/web/domain/validate") {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.containsNone(target, ".o_domain_leaf");
|
||||
assert.containsNone(target, ".modal");
|
||||
|
||||
Reference in New Issue
Block a user