summaryrefslogtreecommitdiff
path: root/addons/website/static/src/snippets/s_dynamic_snippet/000.js
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/website/static/src/snippets/s_dynamic_snippet/000.js
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/website/static/src/snippets/s_dynamic_snippet/000.js')
-rw-r--r--addons/website/static/src/snippets/s_dynamic_snippet/000.js244
1 files changed, 244 insertions, 0 deletions
diff --git a/addons/website/static/src/snippets/s_dynamic_snippet/000.js b/addons/website/static/src/snippets/s_dynamic_snippet/000.js
new file mode 100644
index 00000000..d6a3e0ff
--- /dev/null
+++ b/addons/website/static/src/snippets/s_dynamic_snippet/000.js
@@ -0,0 +1,244 @@
+odoo.define('website.s_dynamic_snippet', function (require) {
+'use strict';
+
+const core = require('web.core');
+const config = require('web.config');
+const publicWidget = require('web.public.widget');
+
+const DynamicSnippet = publicWidget.Widget.extend({
+ selector: '.s_dynamic_snippet',
+ xmlDependencies: ['/website/static/src/snippets/s_dynamic_snippet/000.xml'],
+ read_events: {
+ 'click [data-url]': '_onCallToAction',
+ },
+ disabledInEditableMode: false,
+
+ /**
+ *
+ * @override
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+ /**
+ * The dynamic filter data source data formatted with the chosen template.
+ * Can be accessed when overriding the _render_content() function in order to generate
+ * a new renderedContent from the original data.
+ *
+ * @type {*|jQuery.fn.init|jQuery|HTMLElement}
+ */
+ this.data = [];
+ this.renderedContent = '';
+ this.isDesplayedAsMobile = config.device.isMobile;
+ this.uniqueId = _.uniqueId('s_dynamic_snippet_');
+ this.template_key = 'website.s_dynamic_snippet.grid';
+ },
+ /**
+ *
+ * @override
+ */
+ willStart: function () {
+ return this._super.apply(this, arguments).then(
+ () => Promise.all([
+ this._fetchData(),
+ this._manageWarningMessageVisibility()
+ ])
+ );
+ },
+ /**
+ *
+ * @override
+ */
+ start: function () {
+ return this._super.apply(this, arguments)
+ .then(() => {
+ this._setupSizeChangedManagement(true);
+ this._render();
+ this._toggleVisibility(true);
+ });
+ },
+ /**
+ *
+ * @override
+ */
+ destroy: function () {
+ this._toggleVisibility(false);
+ this._setupSizeChangedManagement(false);
+ this._clearContent();
+ this._super.apply(this, arguments);
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ *
+ * @private
+ */
+ _clearContent: function () {
+ const $dynamicSnippetTemplate = this.$el.find('.dynamic_snippet_template');
+ if ($dynamicSnippetTemplate) {
+ $dynamicSnippetTemplate.html('');
+ }
+ },
+ /**
+ * Method to be overridden in child components if additional configuration elements
+ * are required in order to fetch data.
+ * @private
+ */
+ _isConfigComplete: function () {
+ return this.$el.get(0).dataset.filterId !== undefined && this.$el.get(0).dataset.templateKey !== undefined;
+ },
+ /**
+ * Method to be overridden in child components in order to provide a search
+ * domain if needed.
+ * @private
+ */
+ _getSearchDomain: function () {
+ return [];
+ },
+ /**
+ * Fetches the data.
+ * @private
+ */
+ _fetchData: function () {
+ if (this._isConfigComplete()) {
+ return this._rpc(
+ {
+ 'route': '/website/snippet/filters',
+ 'params': {
+ 'filter_id': parseInt(this.$el.get(0).dataset.filterId),
+ 'template_key': this.$el.get(0).dataset.templateKey,
+ 'limit': parseInt(this.$el.get(0).dataset.numberOfRecords),
+ 'search_domain': this._getSearchDomain()
+ },
+ })
+ .then(
+ (data) => {
+ this.data = data;
+ }
+ );
+ } else {
+ return new Promise((resolve) => {
+ this.data = [];
+ resolve();
+ });
+ }
+ },
+ /**
+ *
+ * @private
+ */
+ _mustMessageWarningBeHidden: function() {
+ return this._isConfigComplete() || !this.editableMode;
+ },
+ /**
+ *
+ * @private
+ */
+ _manageWarningMessageVisibility: async function () {
+ this.$el.find('.missing_option_warning').toggleClass(
+ 'd-none',
+ this._mustMessageWarningBeHidden()
+ );
+ },
+ /**
+ * Method to be overridden in child components in order to prepare content
+ * before rendering.
+ * @private
+ */
+ _prepareContent: function () {
+ if (this.$target[0].dataset.numberOfElements && this.$target[0].dataset.numberOfElementsSmallDevices) {
+ this.renderedContent = core.qweb.render(
+ this.template_key,
+ this._getQWebRenderOptions());
+ } else {
+ this.renderedContent = '';
+ }
+ },
+ /**
+ * Method to be overridden in child components in order to prepare QWeb
+ * options.
+ * @private
+ */
+ _getQWebRenderOptions: function () {
+ return {
+ chunkSize: parseInt(
+ config.device.isMobile
+ ? this.$target[0].dataset.numberOfElementsSmallDevices
+ : this.$target[0].dataset.numberOfElements
+ ),
+ data: this.data,
+ uniqueId: this.uniqueId
+ };
+ },
+ /**
+ *
+ * @private
+ */
+ _render: function () {
+ if (this.data.length) {
+ this._prepareContent();
+ } else {
+ this.renderedContent = '';
+ }
+ this._renderContent();
+ },
+ /**
+ *
+ * @private
+ */
+ _renderContent: function () {
+ this.$el.find('.dynamic_snippet_template').html(this.renderedContent);
+ },
+ /**
+ *
+ * @param {Boolean} enable
+ * @private
+ */
+ _setupSizeChangedManagement: function (enable) {
+ if (enable === true) {
+ config.device.bus.on('size_changed', this, this._onSizeChanged);
+ } else {
+ config.device.bus.off('size_changed', this, this._onSizeChanged);
+ }
+ },
+ /**
+ *
+ * @param visible
+ * @private
+ */
+ _toggleVisibility: function (visible) {
+ this.$el.toggleClass('d-none', !visible);
+ },
+
+ //------------------------------------- -------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * Navigates to the call to action url.
+ * @private
+ */
+ _onCallToAction: function (ev) {
+ window.location = $(ev.currentTarget).attr('data-url');
+ },
+ /**
+ * Called when the size has reached a new bootstrap breakpoint.
+ *
+ * @private
+ * @param {number} size as Integer @see web.config.device.SIZES
+ */
+ _onSizeChanged: function (size) {
+ if (this.isDesplayedAsMobile !== config.device.isMobile) {
+ this.isDesplayedAsMobile = config.device.isMobile;
+ this._render();
+ }
+ },
+});
+
+publicWidget.registry.dynamic_snippet = DynamicSnippet;
+
+return DynamicSnippet;
+
+});