Skip to content

Commit

Permalink
[IMP] web_chatter_position: improve function compile
Browse files Browse the repository at this point in the history
  • Loading branch information
trisdoan committed Jul 20, 2024
1 parent 8412027 commit 3e7e6f8
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 135 deletions.
1 change: 1 addition & 0 deletions web_chatter_position/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Contributors
- `Camptocamp <https://www.camptocamp.com>`__

- Iván Todorovich <ivan.todorovich@camptocamp.com>
- Tris Doan <tridm@trobz.com>

- `Alitec Pte Ltd <http://www.alitec.sg>`__

Expand Down
1 change: 1 addition & 0 deletions web_chatter_position/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
- Juan Miguel Sánchez Arce \<<juan.sanchez@camptocamp.com>\>
- [Camptocamp](https://www.camptocamp.com)
- Iván Todorovich \<<ivan.todorovich@camptocamp.com>\>
- Tris Doan \<<tridm@trobz.com>\>
- [Alitec Pte Ltd](http://www.alitec.sg)
- Jay Patel \<<jay@alitec.sg>\>
1 change: 1 addition & 0 deletions web_chatter_position/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ <h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<li>Juan Miguel Sánchez Arce &lt;<a class="reference external" href="mailto:juan.sanchez&#64;camptocamp.com">juan.sanchez&#64;camptocamp.com</a>&gt;</li>
<li><a class="reference external" href="https://www.camptocamp.com">Camptocamp</a><ul>
<li>Iván Todorovich &lt;<a class="reference external" href="mailto:ivan.todorovich&#64;camptocamp.com">ivan.todorovich&#64;camptocamp.com</a>&gt;</li>
<li>Tris Doan &lt;<a class="reference external" href="mailto:tridm&#64;trobz.com">tridm&#64;trobz.com</a>&gt;</li>
</ul>
</li>
<li><a class="reference external" href="http://www.alitec.sg">Alitec Pte Ltd</a><ul>
Expand Down
184 changes: 49 additions & 135 deletions web_chatter_position/static/src/js/web_chatter_position.esm.js
Original file line number Diff line number Diff line change
@@ -1,124 +1,43 @@
/** @odoo-module **/
/*
Copyright 2023 Camptocamp SA (https://www.camptocamp.com).
Copyright 2024 Alitec Pte Ltd (https://www.alitec.sg).
License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
*/

import {FormCompiler} from "@web/views/form/form_compiler";
import {FormController} from "@web/views/form/form_controller";
import {patch} from "@web/core/utils/patch";
import {append, setAttributes} from "@web/core/utils/xml";
import {SIZES} from "@web/core/ui/ui_service";
import {hasTouch} from "@web/core/browser/feature_detection";
import {append, createElement, getTag, setAttributes} from "@web/core/utils/xml";

patch(FormCompiler.prototype, {
/**
* Patch the css classes of the `Form`, to include an extra `h-100` class.
* Without it, the form sheet will not be full height in some situations,
* looking a bit weird.
*
* @override
*/
compileForm(el, params) {
const sheetNode = el.querySelector("sheet");
const displayClasses = sheetNode
? `d-flex {{ ((__comp__.uiService.size < ${SIZES.XXL} && ${
odoo.web_chatter_position != "sided"
}) || ${
odoo.web_chatter_position === "bottom"
}) ? "flex-column" : "flex-nowrap h-100" }}`
: "d-block";
const stateClasses =
"{{ __comp__.props.record.dirty ? 'o_form_dirty' : !__comp__.props.record.isNew ? 'o_form_saved' : '' }}";
const form = createElement("div", {
class: "o_form_renderer",
"t-att-class": "__comp__.props.class",
"t-attf-class": `{{__comp__.props.record.isInEdition ? 'o_form_editable' : 'o_form_readonly'}} ${displayClasses} ${stateClasses}`,
});
if (!sheetNode) {
for (const child of el.childNodes) {
// ButtonBox are already compiled for the control panel and should not
// be recompiled for the renderer of the view
if (child.attributes?.name?.value !== "button_box") {
append(form, this.compileNode(child, params));
}
}
form.classList.add("o_form_nosheet");
} else {
let compiledList = [];
for (const child of el.childNodes) {
const compiled = this.compileNode(child, params);
if (getTag(child, true) === "sheet") {
append(form, compiled);
compiled.prepend(...compiledList);
compiledList = [];
} else if (compiled) {
compiledList.push(compiled);
}
}
append(form, compiledList);
}
return form;
},
compile(node, params) {
// TODO no chatter if in dialog?
const res = super.compile(node, params);
const chatterContainerHookXml = res.querySelector(".o-mail-Form-chatter");
const webClientViewAttachmentViewHookXml = res.querySelector(
".o_attachment_preview"
);
const chatterContainerHookXml = res.querySelector(
".o-mail-Form-chatter:not(.o-isInFormSheetBg)"
);
if (!chatterContainerHookXml) {
return res; // No chatter, keep the result as it is
}
const chatterContainerXml = chatterContainerHookXml.querySelector(
"t[t-component='__comp__.mailComponents.Chatter']"
);
setAttributes(chatterContainerXml, {
isChatterAside: "false",
isInFormSheetBg: "false",
saveRecord: "__comp__.props.saveRecord",
});
if (chatterContainerHookXml.parentNode.classList.contains("o_form_sheet")) {
return res; // If chatter is inside sheet, keep it there
}
const formSheetBgXml = res.querySelector(".o_form_sheet_bg");
const parentXml = formSheetBgXml && formSheetBgXml.parentNode;
if (!parentXml) {
return res; // Miss-config: a sheet-bg is required for the rest
}

const webClientViewAttachmentViewHookXml = res.querySelector(
".o_attachment_preview"
);
if (webClientViewAttachmentViewHookXml) {
// In sheet bg (attachment viewer present)
setAttributes(webClientViewAttachmentViewHookXml, {
"t-if": `__comp__.hasFileViewer() and __comp__.uiService.size >= ${SIZES.XXL}`,
});
const sheetBgChatterContainerHookXml =
chatterContainerHookXml.cloneNode(true);
sheetBgChatterContainerHookXml.classList.add("o-isInFormSheetBg", "w-auto");
setAttributes(sheetBgChatterContainerHookXml, {
"t-if": `__comp__.hasFileViewer() and __comp__.uiService.size >= ${SIZES.XXL}`,
});
append(formSheetBgXml, sheetBgChatterContainerHookXml);
const sheetBgChatterContainerXml =
sheetBgChatterContainerHookXml.querySelector(
"t[t-component='__comp__.mailComponents.Chatter']"
);
setAttributes(sheetBgChatterContainerXml, {
isInFormSheetBg: "true",
isChatterAside: "false",
});
}
// After sheet bg (standard position, either aside or below)
if (webClientViewAttachmentViewHookXml) {
setAttributes(chatterContainerHookXml, {
"t-if": `!(__comp__.hasFileViewer() and __comp__.uiService.size >= ${SIZES.XXL})`,
"t-attf-class": `{{ __comp__.uiService.size >= ${SIZES.XXL} and !(__comp__.hasFileViewer() and __comp__.uiService.size >= ${SIZES.XXL}) ? "o-aside" : "" }}`,
});
setAttributes(chatterContainerXml, {
isInFormSheetBg: "__comp__.hasFileViewer()",
isChatterAside: `__comp__.uiService.size >= ${SIZES.XXL} and !(__comp__.hasFileViewer() and __comp__.uiService.size >= ${SIZES.XXL})`,
});
// Don't patch anything if the setting is "auto": this is the core behaviour
if (odoo.web_chatter_position === "auto") {
return res;
// For "sided", we have to remote the bottom chatter
// (except if there is an attachment viewer, as we have to force bottom)
} else if (odoo.web_chatter_position === "sided") {
setAttributes(chatterContainerXml, {
isInFormSheetBg: "false",
Expand All @@ -127,49 +46,44 @@ patch(FormCompiler.prototype, {
setAttributes(chatterContainerHookXml, {
"t-attf-class": "o-aside",
});
} else {
setAttributes(chatterContainerXml, {
isInFormSheetBg: "false",
isChatterAside: `__comp__.uiService.size >= ${SIZES.XXL}`,
});
setAttributes(chatterContainerHookXml, {
"t-attf-class": `{{ (__comp__.uiService.size >= ${SIZES.XXL} && ${
odoo.web_chatter_position != "bottom"
}) ? "o-aside" : "mt-4 mt-md-0" }}`,
});
}
append(parentXml, chatterContainerHookXml);
return res;
},
});
// For "bottom", we keep the chatter in the form sheet
// (the one used for the attachment viewer case)
// If it's not there, we create it.
} else if (odoo.web_chatter_position === "bottom") {
if (webClientViewAttachmentViewHookXml) {
const sheetBgChatterContainerHookXml = res.querySelector(
".o-mail-Form-chatter.o-isInFormSheetBg"
);
setAttributes(sheetBgChatterContainerHookXml, {
"t-if": "true",
});
setAttributes(chatterContainerHookXml, {
"t-if": "false",
});
} else {
const sheetBgChatterContainerHookXml =
chatterContainerHookXml.cloneNode(true);
sheetBgChatterContainerHookXml.classList.add("o-isInFormSheetBg");
setAttributes(sheetBgChatterContainerHookXml, {
"t-if": "true",
"t-attf-class": `{{ (__comp__.uiService.size >= ${SIZES.XXL} && ${
odoo.web_chatter_position != "bottom"
}) ? "o-aside" : "mt-4 mt-md-0" }}`,
});
append(formSheetBgXml, sheetBgChatterContainerHookXml);
const sheetBgChatterContainerXml =
sheetBgChatterContainerHookXml.querySelector(
"t[t-component='__comp__.mailComponents.Chatter']"
);

patch(FormController.prototype, {
/**
* Patch the css classes of the form container, to include an extra `flex-row` class.
* Without it, it'd go for flex columns direction and it won't look good.
*
* @override
*/
get className() {
const result = {};
const {size} = this.ui;
if (size <= SIZES.XS) {
result.o_xxs_form_view = true;
} else if (
(!this.env.inDialog &&
size === SIZES.XXL &&
odoo.web_chatter_position != "bottom") ||
odoo.web_chatter_position === "sided"
) {
result["o_xxl_form_view h-100"] = true;
}
if (this.props.className) {
result[this.props.className] = true;
}
result.o_field_highlight = size < SIZES.SM || hasTouch();
if (odoo.web_chatter_position === "sided") {
result["flex-row"] = true;
setAttributes(sheetBgChatterContainerXml, {
isInFormSheetBg: "true",
});
setAttributes(chatterContainerHookXml, {
"t-if": "false",
});
}
}
return result;
return res;
},
});

0 comments on commit 3e7e6f8

Please sign in to comment.