[FIX] web: kanban: attributes of card dropdowns
Some attributes of the elements determining the "ellipsis" dropdown menu
of a kanban card were invalidly reported on the main Dropdown node
created during the compilation. This could cause crashes (during the
props validation) or broke the CSS.
In this commit:
- we fix the above mentioned problem
- we put the class o_drowdown_kanban on all "ellipsis" dropdowns
generated by the kanban compiler in order to get the appropriate CSS
- we make sure that those dropdowns are visible in kanban dashboards
by default
Part-of: odoo/odoo#92475
This commit is contained in:
committed by
Aaron Bohy
parent
5d0a28d0f5
commit
a5bfa26692
@@ -30,12 +30,21 @@ export class KanbanCompiler extends ViewCompiler {
|
||||
this.compilers.push(
|
||||
{ selector: `[t-name='${KANBAN_BOX_ATTRIBUTE}']`, fn: this.compileCard },
|
||||
{ selector: ".oe_kanban_colorpicker", fn: this.compileColorPicker },
|
||||
{ selector: ".dropdown,.o_kanban_manage_button_section", fn: this.compileDropdown },
|
||||
{
|
||||
selector: ".dropdown,.o_kanban_manage_button_section",
|
||||
fn: this.compileDropdown,
|
||||
doNotCopyAttributes: true,
|
||||
},
|
||||
{
|
||||
selector: ".dropdown-toggle,.o_kanban_manage_toggle_button",
|
||||
fn: this.compileDropdownButton,
|
||||
doNotCopyAttributes: true,
|
||||
},
|
||||
{
|
||||
selector: ".dropdown-menu",
|
||||
fn: this.compileDropdownMenu,
|
||||
doNotCopyAttributes: true,
|
||||
},
|
||||
{ selector: ".dropdown-menu", fn: this.compileDropdownMenu },
|
||||
{ selector: "t[t-call]", fn: this.compileTCall }
|
||||
);
|
||||
this.dropdown = null;
|
||||
@@ -55,6 +64,7 @@ export class KanbanCompiler extends ViewCompiler {
|
||||
this.dropdown = createElement("Dropdown", {
|
||||
position: toStringExpression("bottom-end"),
|
||||
});
|
||||
this.dropdown.setAttribute("class", "'o_dropdown_kanban'");
|
||||
return this.dropdown;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
// ------- Dropdown toggle & menu -------
|
||||
$o-kanban-manage-toggle-height: 35px;
|
||||
|
||||
.o_dropdown_kanban {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.o_kanban_manage_toggle_button {
|
||||
@include o-kanban-dropdown($o-kanban-dashboard-hpadding);
|
||||
@include o-position-absolute(0, 0);
|
||||
|
||||
@@ -97,10 +97,6 @@ export function assignOwlDirectives(target, ...sources) {
|
||||
* @param {Element} compiled
|
||||
*/
|
||||
export function copyAttributes(el, compiled) {
|
||||
if (getTag(el, true) === "button") {
|
||||
return;
|
||||
}
|
||||
|
||||
const isComponent = isComponentNode(compiled);
|
||||
const classes = el.className;
|
||||
if (classes) {
|
||||
@@ -215,7 +211,8 @@ export class ViewCompiler {
|
||||
this.id = 1;
|
||||
/** @type {Compiler[]} */
|
||||
this.compilers = [
|
||||
{ selector: "a[type],a[data-type],button", fn: this.compileButton },
|
||||
{ selector: "a[type],a[data-type]", fn: this.compileButton },
|
||||
{ selector: "button", fn: this.compileButton, doNotCopyAttributes: true },
|
||||
{ selector: "field", fn: this.compileField },
|
||||
{ selector: "widget", fn: this.compileWidget },
|
||||
];
|
||||
@@ -287,7 +284,7 @@ export class ViewCompiler {
|
||||
let compiledNode;
|
||||
if (compiler) {
|
||||
compiledNode = compiler.fn.call(this, node, params);
|
||||
if (compiledNode) {
|
||||
if (!compiler.doNotCopyAttributes && compiledNode) {
|
||||
copyAttributes(node, compiledNode);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -9874,4 +9874,97 @@ QUnit.module("Views", (hooks) => {
|
||||
assert.containsNone(target, ".o_kanban_quick_create");
|
||||
assert.containsN(target, ".o_kanban_group:nth-child(2) .o_kanban_record", 3);
|
||||
});
|
||||
|
||||
QUnit.test("classes on dropdown menu do not end on dropdown main div", async (assert) => {
|
||||
serverData.models.partner.records.splice(1, 3); // keep one record only
|
||||
await makeView({
|
||||
type: "kanban",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `
|
||||
<kanban>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div>
|
||||
<field name="foo"/>
|
||||
<ul class="o_kanban_card_manage_pane dropdown-menu" role="menu">
|
||||
<li>Hello</li>
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
`,
|
||||
});
|
||||
|
||||
const dropdown = target.querySelector(".o_kanban_record .o-dropdown");
|
||||
assert.isVisible(dropdown);
|
||||
assert.hasClass(dropdown, "o_dropdown_kanban");
|
||||
assert.doesNotHaveClass(dropdown, "dropdown-menu");
|
||||
assert.doesNotHaveClass(dropdown, "o_kanban_card_manage_pane");
|
||||
await click(dropdown, "button.dropdown-toggle");
|
||||
assert.containsOnce(dropdown, ".o_kanban_card_manage_pane.dropdown-menu");
|
||||
});
|
||||
|
||||
QUnit.test("classes on toggler do not end on dropdown main div", async (assert) => {
|
||||
serverData.models.partner.records.splice(1, 3); // keep one record only
|
||||
await makeView({
|
||||
type: "kanban",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `
|
||||
<kanban>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div>
|
||||
<field name="foo"/>
|
||||
<a class="o_kanban_manage_toggle_button o_left" href="#">
|
||||
<i class="fa fa-ellipsis-v" role="img" aria-label="Manage" title="Manage"/>
|
||||
</a>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
`,
|
||||
});
|
||||
|
||||
const dropdown = target.querySelector(".o_kanban_record .o-dropdown");
|
||||
assert.isVisible(dropdown);
|
||||
assert.hasClass(dropdown, "o_dropdown_kanban");
|
||||
assert.doesNotHaveClass(dropdown, "o_kanban_manage_toggle_button");
|
||||
assert.doesNotHaveClass(dropdown, "o_left");
|
||||
assert.containsOnce(dropdown, ".o_kanban_manage_toggle_button.o_left");
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"classes on dropdown are on dropdown main div but not the other attributes",
|
||||
async (assert) => {
|
||||
serverData.models.partner.records.splice(1, 3); // keep one record only
|
||||
await makeView({
|
||||
type: "kanban",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `
|
||||
<kanban>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div>
|
||||
<field name="foo"/>
|
||||
<div class="o_kanban_manage_button_section my_class" placeholder="Bouh"/>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
`,
|
||||
});
|
||||
|
||||
const dropdown = target.querySelector(".o_kanban_record .o-dropdown");
|
||||
assert.isVisible(dropdown);
|
||||
assert.strictEqual(
|
||||
dropdown.className,
|
||||
"o-dropdown dropdown o_dropdown_kanban o_kanban_manage_button_section my_class o-dropdown--no-caret"
|
||||
);
|
||||
assert.notOk(dropdown.hasAttribute("placeholder"));
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user