[IMP] web_hierarchy: clean up UX org chart

closes odoo/odoo#140238

Signed-off-by: Fabien Pinckaers (fp) <fp@odoo.com>
This commit is contained in:
Fabien Pinckaers
2023-10-29 17:29:11 +00:00
parent 6739c317d1
commit 142f38e263
5 changed files with 18 additions and 48 deletions
@@ -11,10 +11,6 @@
width: 250px;
min-height: 130px;
.o_hierarchy_node_button_container {
height: 30px;
}
&.o_hierarchy_dragged {
.o_hierarchy_node {
background-color: $hierarchy_element_dragged-background;
@@ -50,8 +46,6 @@
}
.o_hierarchy_node_body {
height: 65px;
.o_employee_availability {
position: absolute;
top: 4px;
@@ -59,24 +53,10 @@
}
}
.o_hierarchy_node_footer {
height: 30px;
}
.o_hierarchy_node_color_0 {
background-color: $gray-200;
}
@include o-hierarchy-node-color;
}
.o_hierarchy_node_button {
display: grid;
grid-template-columns: 50px 1fr 50px;
border-radius: 0;
.o_hierarchy_icon {
vertical-align: text-top;
}
}
}
@@ -2,8 +2,8 @@
<templates>
<t t-name="web_hierarchy.HierarchyCard">
<div class="o_hierarchy_node_container mb-4 d-flex flex-column" t-att-class="classNames" t-att-data-node-id="props.node.id">
<div class="o_hierarchy_node_button_container w-100 d-flex justify-content-end">
<div class="o_hierarchy_node_container d-flex flex-column" t-att-class="classNames" t-att-data-node-id="props.node.id">
<div class="o_hierarchy_node_button_container w-100 d-flex justify-content-center">
<button t-if="props.node.parentResId !== false and !props.node.parentNode"
name="hierarchy_search_parent_node"
class="btn p-0"
@@ -12,7 +12,7 @@
<i class="fa fa-chevron-up"/>
</button>
</div>
<div class="o_hierarchy_node w-100 h-100 d-flex flex-column justify-content-between border"
<div class="o_hierarchy_node w-100 h-100 d-flex flex-column justify-content-between border mt-4"
t-att-class="{
'border-bottom-0': props.node.nodes.length or props.node.canShowChildNodes,
}"
@@ -33,26 +33,18 @@
<button t-if="props.node.nodes.length or props.node.canShowChildNodes"
name="hierarchy_search_subsidiaries"
t-att-class="{
'o_hierarchy_node_button w-100 btn pt-1': true,
'o_hierarchy_node_button btn': true,
'btn-primary': !props.node.nodes.length,
'btn-secondary': props.node.nodes.length > 0,
}"
t-on-click.synthetic="onClickArrowDown"
>
<t t-if="!props.node.nodes.length">
<span style="grid-column: 2;">
Unfold
</span>
<span class="text-end" style="grid-column: 3;">
<t t-out="props.node.childResIds.length"/>
<i class="fa ps-1" t-att-class="props.archInfo.icon"/>
</span>
</t>
<t t-else="">
<span style="grid-column: 2;">
Fold
</span>
<i class="fa fa-fw fa-caret-right"/>
</t><t t-else="">
<i class="fa fa-fw fa-caret-down"/>
</t>
<t t-out="props.node.childResIds.length"/> people
</button>
</div>
</div>
@@ -18,8 +18,6 @@ $o-chart-line-color: #ababb1;
.o_hierarchy_separator {
position: relative;
margin-top: 10px;
margin-bottom: 10px;
width: 100%;
.o_hierarchy_line_left {
@@ -3,7 +3,7 @@
<t t-name="web_hierarchy.HierarchyRenderer" owl="1">
<div class="o_hierarchy_renderer w-100 d-flex justify-content-center" t-ref="renderer">
<div class="o_hierarchy_container d-flex flex-column w-100 w-lg-75 h-100 pt-5 px-2">
<div class="o_hierarchy_container d-flex flex-column px-3 pt-4 mw-xl-75">
<t t-foreach="rows" t-as="row" t-key="row_index">
<t t-set="previousRow" t-value="!row_first ? rows[row_index - 1] : null"/>
<t t-if="!row_first">
@@ -12,12 +12,12 @@
>
<span t-esc="row.parentNode.data.name" />
</div>
<div class="o_hierarchy_separator d-flex pb-4">
<div class="o_hierarchy_separator d-flex">
<div class="o_hierarchy_line_part o_hierarchy_line_left"></div>
<div class="o_hierarchy_line_part o_hierarchy_line_right"></div>
</div>
</t>
<div class="o_hierarchy_row row justify-content-center flex-wrap row-cols-2 row-cols-lg-5 g-2 g-lg-3 pt-3"
<div class="o_hierarchy_row row justify-content-center flex-wrap row-cols-2 row-cols-lg-5 g-2 g-lg-3"
t-att-data-parent-node-id="row.parentNode?.id" t-att-data-row-id="row_index"
>
<t t-foreach="row.nodes" t-as="node" t-key="node.id">
@@ -91,13 +91,13 @@ QUnit.module("Views", (hooks) => {
assert.containsN(target, ".o_hierarchy_node", 3);
assert.containsN(target, ".o_hierarchy_node_button", 2);
assert.containsOnce(target, ".o_hierarchy_node_button.btn-primary");
assert.strictEqual(target.querySelector(".o_hierarchy_node_button.btn-primary").textContent.trim(), "Unfold 1");
assert.strictEqual(target.querySelector(".o_hierarchy_node_button.btn-primary").textContent.trim(), "1 people");
// check nodes in each row
const row = target.querySelector(".o_hierarchy_row");
assert.containsOnce(row, ".o_hierarchy_node");
assert.strictEqual(row.querySelector(".o_hierarchy_node_content").textContent, "Albert");
assert.containsOnce(target, ".o_hierarchy_node_button.btn-secondary");
assert.strictEqual(target.querySelector(".o_hierarchy_node_button.btn-secondary").textContent.trim(), "Fold");
assert.strictEqual(target.querySelector(".o_hierarchy_node_button.btn-secondary").textContent.trim(), "2 people");
});
QUnit.test("display child nodes", async function (assert) {
@@ -129,7 +129,7 @@ QUnit.module("Views", (hooks) => {
assert.containsN(target, ".o_hierarchy_node_button", 2);
assert.containsNone(target, ".o_hierarchy_node_button.btn-primary");
assert.containsN(target, ".o_hierarchy_node_button.btn-secondary", 2);
assert.strictEqual(target.querySelector(".o_hierarchy_node_button.btn-secondary").textContent.trim(), "Fold");
assert.strictEqual(target.querySelector(".o_hierarchy_node_button.btn-secondary").textContent.trim(), "2 people");
// check nodes in each row
const rows = target.querySelectorAll(".o_hierarchy_row");
let row = rows[0];
@@ -635,10 +635,10 @@ QUnit.module("Views", (hooks) => {
});
assert.containsOnce(target, ".o_hierarchy_node button[name=hierarchy_search_subsidiaries].btn-primary");
assert.strictEqual(target.querySelector(".o_hierarchy_node button[name=hierarchy_search_subsidiaries].btn-primary").textContent.trim(), "Unfold 1");
assert.strictEqual(target.querySelector(".o_hierarchy_node button[name=hierarchy_search_subsidiaries].btn-primary").textContent.trim(), "1 people");
assert.containsOnce(
target,
".o_hierarchy_node button[name=hierarchy_search_subsidiaries] i.fa-share-alt.o_hierarchy_icon",
".o_hierarchy_node button[name=hierarchy_search_subsidiaries] i.fa-caret-right",
"The default icon of the hierarchy view should be displayed inside the button to unfold the node."
);
});
@@ -652,10 +652,10 @@ QUnit.module("Views", (hooks) => {
});
assert.containsOnce(target, ".o_hierarchy_node button[name=hierarchy_search_subsidiaries].btn-primary");
assert.strictEqual(target.querySelector(".o_hierarchy_node button[name=hierarchy_search_subsidiaries].btn-primary").textContent.trim(), "Unfold 1");
assert.strictEqual(target.querySelector(".o_hierarchy_node button[name=hierarchy_search_subsidiaries].btn-primary").textContent.trim(), "1 people");
assert.containsOnce(
target,
".o_hierarchy_node button[name=hierarchy_search_subsidiaries] i.fa-users",
".o_hierarchy_node button[name=hierarchy_search_subsidiaries] i.fa-caret-down",
"The icon defined in the attribute icon in hierarchy tag should be displayed inside the button to unfold the node instead of the default one."
);
});