summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorVincent Schippefilt <vsc@odoo.com>2019-11-05 14:28:19 +0000
committerVincent Schippefilt <vsc@odoo.com>2019-12-09 11:09:10 +0000
commitd06e67e748ca9c5c538d5e1a1efc4ae798fee707 (patch)
tree551b153833d7a6ba72d99798983ac475d200e3ce /addons
parent2cfa68b57158f6f4ac49549e79a5eb7f90cefb5f (diff)
[IMP] web: add Odoo view compatibility for OWL
Add a base class for a complete OWL renderer Add a compatibility layer for a Odoo controller that uses a OWL renderer. Co-authored-by: Pierre Rousseau <pro@odoo.com>
Diffstat (limited to 'addons')
-rw-r--r--addons/web/static/src/js/views/abstract_controller.js14
-rw-r--r--addons/web/static/src/js/views/abstract_renderer_owl.js8
-rw-r--r--addons/web/static/src/js/views/controller_adapter.js42
-rw-r--r--addons/web/static/src/js/views/renderer_wrapper.js57
-rw-r--r--addons/web/views/webclient_templates.xml3
5 files changed, 123 insertions, 1 deletions
diff --git a/addons/web/static/src/js/views/abstract_controller.js b/addons/web/static/src/js/views/abstract_controller.js
index 780b0bcf1b6..70cec99aa86 100644
--- a/addons/web/static/src/js/views/abstract_controller.js
+++ b/addons/web/static/src/js/views/abstract_controller.js
@@ -287,7 +287,7 @@ var AbstractController = mvc.Controller.extend(ActionMixin, {
self.handle = handle || self.handle; // update handle if we reloaded
var state = self.model.get(self.handle);
var localState = self.renderer.getLocalState();
- return self.dp.add(self.renderer.updateState(state, params)).then(function () {
+ return self.dp.add(self.updateRendererState(state, params)).then(function () {
if (self._controlPanel && cpUpdateIndex !== self._controlPanel.updateIndex) {
return;
}
@@ -297,6 +297,18 @@ var AbstractController = mvc.Controller.extend(ActionMixin, {
});
},
+ /**
+ * Update the state of the renderer.
+ * This method is required to be overridden in OWL components through the controller
+ * adapter
+ *
+ * @param {Object} state the model state
+ * @param {Object} params will be given to the model and to the renderer
+ */
+ updateRendererState: function(state, params) {
+ return this.renderer.updateState(state, params);
+ },
+
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
diff --git a/addons/web/static/src/js/views/abstract_renderer_owl.js b/addons/web/static/src/js/views/abstract_renderer_owl.js
new file mode 100644
index 00000000000..6071d410d4a
--- /dev/null
+++ b/addons/web/static/src/js/views/abstract_renderer_owl.js
@@ -0,0 +1,8 @@
+odoo.define('web.AbstractRendererOwl', function (require) {
+ "use strict";
+
+ class AbstractRenderer extends owl.Component { }
+
+ return AbstractRenderer;
+
+});
diff --git a/addons/web/static/src/js/views/controller_adapter.js b/addons/web/static/src/js/views/controller_adapter.js
new file mode 100644
index 00000000000..17973cd3b54
--- /dev/null
+++ b/addons/web/static/src/js/views/controller_adapter.js
@@ -0,0 +1,42 @@
+odoo.define('web.ControllerAdapter', function (require) {
+"use strict";
+
+var AbstractController = require('web.AbstractController');
+
+var ControllerAdapter = AbstractController.extend({
+ on_attach_callback: function () {
+ this.renderer.__callMounted();
+ },
+ on_detach_callback: function () {
+ this.renderer.__callWillUnmount();
+ },
+
+ /**
+ * @override
+ * */
+ updateRendererState: async function (props) {
+ let prom;
+ this.renderer.updateProps(props);
+ if (this.renderer.__owl__.isMounted) {
+ prom = this.renderer.render();
+ } else {
+ prom = this.renderer.mount(this.$('.o_content')[0], true);
+ }
+ return prom;
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+ /**
+ * @override
+ * @private
+ */
+ _startRenderer: async function () {
+ return this.renderer.mount(this.$('.o_content')[0]);
+ },
+});
+
+return ControllerAdapter;
+
+});
diff --git a/addons/web/static/src/js/views/renderer_wrapper.js b/addons/web/static/src/js/views/renderer_wrapper.js
new file mode 100644
index 00000000000..7c1c5d6b273
--- /dev/null
+++ b/addons/web/static/src/js/views/renderer_wrapper.js
@@ -0,0 +1,57 @@
+odoo.define('web.RendererWrapper', function (require) {
+ "use strict";
+
+ const { xml } = owl.tags;
+ const AbstractRenderer = require('web.AbstractRendererOwl');
+
+ class RendererWrapper extends owl.Component {
+ /**
+ *
+ * @param {Object} parent
+ * @param {Object} props
+ * @param {Class} concreteRenderer
+ */
+ constructor(parent, props, concreteRenderer) {
+ super(...arguments);
+ this.concreteRenderer = concreteRenderer;
+ this.data = props;
+ }
+
+ /**
+ * Update the props of the renderer before a re-render
+ * called on the initial render as well as when the renderer is re-mounted (view switched)
+ *
+ * @param {Object} props new props
+ */
+ updateProps(props) {
+ this.data = Object.assign(this.data || {}, props);
+ }
+
+ mounted() {
+ for (let x in this.__owl__.children) {
+ this.__owl__.children[x].__callMounted();
+ }
+ }
+
+ willUnmount() {
+ for (let x in this.__owl__.children) {
+ this.__owl__.children[x].__callWillUnmount();
+ }
+ }
+
+ setParent() { }
+
+ getLocalState() { }
+
+ setLocalState() { }
+
+ giveFocus() { }
+ };
+
+ RendererWrapper.template = xml`<t t-component="concreteRenderer" t-props="data"/>`;
+
+ RendererWrapper.components = { AbstractRenderer };
+
+ return RendererWrapper;
+
+});
diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml
index 8050d18341a..a9f05f97891 100644
--- a/addons/web/views/webclient_templates.xml
+++ b/addons/web/views/webclient_templates.xml
@@ -298,8 +298,11 @@
<script type="text/javascript" src="/web/static/src/js/views/abstract_view.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/abstract_renderer.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/views/abstract_renderer_owl.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/abstract_model.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/abstract_controller.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/views/controller_adapter.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/views/renderer_wrapper.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/basic/basic_model.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/basic/basic_view.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/basic/basic_controller.js"></script>