summaryrefslogtreecommitdiff
path: root/addons/website_blog/static/src/js/website_blog.editor.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_blog/static/src/js/website_blog.editor.js
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/website_blog/static/src/js/website_blog.editor.js')
-rw-r--r--addons/website_blog/static/src/js/website_blog.editor.js380
1 files changed, 380 insertions, 0 deletions
diff --git a/addons/website_blog/static/src/js/website_blog.editor.js b/addons/website_blog/static/src/js/website_blog.editor.js
new file mode 100644
index 00000000..95daa0fb
--- /dev/null
+++ b/addons/website_blog/static/src/js/website_blog.editor.js
@@ -0,0 +1,380 @@
+odoo.define('website_blog.new_blog_post', function (require) {
+'use strict';
+
+var core = require('web.core');
+var wUtils = require('website.utils');
+var WebsiteNewMenu = require('website.newMenu');
+
+var _t = core._t;
+
+WebsiteNewMenu.include({
+ actions: _.extend({}, WebsiteNewMenu.prototype.actions || {}, {
+ new_blog_post: '_createNewBlogPost',
+ }),
+
+ //--------------------------------------------------------------------------
+ // Actions
+ //--------------------------------------------------------------------------
+
+ /**
+ * Asks the user information about a new blog post to create, then creates
+ * it and redirects the user to this new post.
+ *
+ * @private
+ * @returns {Promise} Unresolved if there is a redirection
+ */
+ _createNewBlogPost: function () {
+ return this._rpc({
+ model: 'blog.blog',
+ method: 'search_read',
+ args: [wUtils.websiteDomain(this), ['name']],
+ }).then(function (blogs) {
+ if (blogs.length === 1) {
+ document.location = '/blog/' + blogs[0]['id'] + '/post/new';
+ return new Promise(function () {});
+ } else if (blogs.length > 1) {
+ return wUtils.prompt({
+ id: 'editor_new_blog',
+ window_title: _t("New Blog Post"),
+ select: _t("Select Blog"),
+ init: function (field) {
+ return _.map(blogs, function (blog) {
+ return [blog['id'], blog['name']];
+ });
+ },
+ }).then(function (result) {
+ var blog_id = result.val;
+ if (!blog_id) {
+ return;
+ }
+ document.location = '/blog/' + blog_id + '/post/new';
+ return new Promise(function () {});
+ });
+ }
+ });
+ },
+});
+});
+
+//==============================================================================
+
+odoo.define('website_blog.editor', function (require) {
+'use strict';
+
+require('web.dom_ready');
+const {qweb, _t} = require('web.core');
+const options = require('web_editor.snippets.options');
+var WysiwygMultizone = require('web_editor.wysiwyg.multizone');
+
+if (!$('.website_blog').length) {
+ return Promise.reject("DOM doesn't contain '.website_blog'");
+}
+
+const NEW_TAG_PREFIX = 'new-blog-tag-';
+
+WysiwygMultizone.include({
+ custom_events: Object.assign({}, WysiwygMultizone.prototype.custom_events, {
+ 'set_blog_post_updated_tags': '_onSetBlogPostUpdatedTags',
+ }),
+
+ /**
+ * @override
+ */
+ init() {
+ this._super(...arguments);
+ this.blogTagsPerBlogPost = {};
+ },
+ /**
+ * @override
+ */
+ async start() {
+ await this._super(...arguments);
+ $('.js_tweet, .js_comment').off('mouseup').trigger('mousedown');
+ },
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ async save() {
+ const ret = await this._super(...arguments);
+ await this._saveBlogTags(); // Note: important to be called after save otherwise cleanForSave is not called before
+ return ret;
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * Saves the blog tags in the database.
+ *
+ * @private
+ */
+ async _saveBlogTags() {
+ for (const [key, tags] of Object.entries(this.blogTagsPerBlogPost)) {
+ const proms = tags.filter(tag => typeof tag.id === 'string').map(tag => {
+ return this._rpc({
+ model: 'blog.tag',
+ method: 'create',
+ args: [{
+ 'name': tag.name,
+ }],
+ });
+ });
+ const createdIDs = await Promise.all(proms);
+
+ await this._rpc({
+ model: 'blog.post',
+ method: 'write',
+ args: [parseInt(key), {
+ 'tag_ids': [[6, 0, tags.filter(tag => typeof tag.id === 'number').map(tag => tag.id).concat(createdIDs)]],
+ }],
+ });
+ }
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {OdooEvent} ev
+ */
+ _onSetBlogPostUpdatedTags: function (ev) {
+ this.blogTagsPerBlogPost[ev.data.blogPostID] = ev.data.tags;
+ },
+});
+
+options.registry.many2one.include({
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ _selectRecord: function ($opt) {
+ var self = this;
+ this._super.apply(this, arguments);
+ if (this.$target.data('oe-field') === 'author_id') {
+ var $nodes = $('[data-oe-model="blog.post"][data-oe-id="'+this.$target.data('oe-id')+'"][data-oe-field="author_avatar"]');
+ $nodes.each(function () {
+ var $img = $(this).find('img');
+ var css = window.getComputedStyle($img[0]);
+ $img.css({ width: css.width, height: css.height });
+ $img.attr('src', '/web/image/res.partner/'+self.ID+'/image_1024');
+ });
+ setTimeout(function () { $nodes.removeClass('o_dirty'); },0);
+ }
+ }
+});
+
+options.registry.CoverProperties.include({
+ /**
+ * @override
+ */
+ updateUI: async function () {
+ await this._super(...arguments);
+ var isRegularCover = this.$target.is('.o_wblog_post_page_cover_regular');
+ var $coverFull = this.$el.find('[data-select-class*="o_full_screen_height"]');
+ var $coverMid = this.$el.find('[data-select-class*="o_half_screen_height"]');
+ var $coverAuto = this.$el.find('[data-select-class*="cover_auto"]');
+ this._coverFullOriginalLabel = this._coverFullOriginalLabel || $coverFull.text();
+ this._coverMidOriginalLabel = this._coverMidOriginalLabel || $coverMid.text();
+ this._coverAutoOriginalLabel = this._coverAutoOriginalLabel || $coverAuto.text();
+ $coverFull.children('div').text(isRegularCover ? _t("Large") : this._coverFullOriginalLabel);
+ $coverMid.children('div').text(isRegularCover ? _t("Medium") : this._coverMidOriginalLabel);
+ $coverAuto.children('div').text(isRegularCover ? _t("Tiny") : this._coverAutoOriginalLabel);
+ },
+});
+
+options.registry.BlogPostTagSelection = options.Class.extend({
+ xmlDependencies: (options.Class.prototype.xmlDependencies || [])
+ .concat(['/website_blog/static/src/xml/website_blog_tag.xml']),
+
+ /**
+ * @override
+ */
+ async willStart() {
+ const _super = this._super.bind(this);
+
+ this.blogPostID = parseInt(this.$target[0].dataset.blogId);
+ this.isEditingTags = false;
+ const tags = await this._rpc({
+ model: 'blog.tag',
+ method: 'search_read',
+ args: [[], ['id', 'name', 'post_ids']],
+ });
+ this.allTagsByID = {};
+ this.tagIDs = [];
+ for (const tag of tags) {
+ this.allTagsByID[tag.id] = tag;
+ if (tag['post_ids'].includes(this.blogPostID)) {
+ this.tagIDs.push(tag.id);
+ }
+ }
+
+ return _super(...arguments);
+ },
+ /**
+ * @override
+ */
+ cleanForSave() {
+ if (this.isEditingTags) {
+ this._notifyUpdatedTags();
+ }
+ },
+
+ //--------------------------------------------------------------------------
+ // Options
+ //--------------------------------------------------------------------------
+
+ /**
+ * @see this.selectClass for params
+ */
+ editTagList(previewMode, widgetValue, params) {
+ this.isEditingTags = true;
+ this.rerender = true;
+ },
+ /**
+ * Send changes that will be saved in the database.
+ *
+ * @see this.selectClass for params
+ */
+ saveTagList(previewMode, widgetValue, params) {
+ this.isEditingTags = false;
+ this.rerender = true;
+ this._notifyUpdatedTags();
+ },
+ /**
+ * @see this.selectClass for params
+ */
+ setNewTagName(previewMode, widgetValue, params) {
+ this.newTagName = widgetValue;
+ },
+ /**
+ * @see this.selectClass for params
+ */
+ confirmNew(previewMode, widgetValue, params) {
+ if (!this.newTagName) {
+ return;
+ }
+ const existing = Object.values(this.allTagsByID).some(tag => tag.name.toLowerCase() === this.newTagName.toLowerCase());
+ if (existing) {
+ return this.displayNotification({
+ type: 'warning',
+ message: _t("This tag already exists"),
+ });
+ }
+ const newTagID = _.uniqueId(NEW_TAG_PREFIX);
+ this.allTagsByID[newTagID] = {
+ 'id': newTagID,
+ 'name': this.newTagName,
+ };
+ this.tagIDs.push(newTagID);
+ this.newTagName = '';
+ this.rerender = true;
+ },
+ /**
+ * @see this.selectClass for params
+ */
+ addTag(previewMode, widgetValue, params) {
+ const tagID = parseInt(widgetValue);
+ this.tagIDs.push(tagID);
+ this.rerender = true;
+ },
+ /**
+ * @see this.selectClass for params
+ */
+ removeTag(previewMode, widgetValue, params) {
+ this.tagIDs = this.tagIDs.filter(tagID => (`${tagID}` !== widgetValue));
+ if (widgetValue.startsWith(NEW_TAG_PREFIX)) {
+ delete this.allTagsByID[widgetValue];
+ }
+ this.rerender = true;
+ },
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ async updateUI() {
+ if (this.rerender) {
+ this.rerender = false;
+ await this._rerenderXML();
+ return;
+ }
+ return this._super(...arguments);
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ async _computeWidgetVisibility(widgetName, params) {
+ if (['blog_existing_tag_opt', 'new_tag_input_opt', 'new_tag_button_opt', 'save_tags_opt'].includes(widgetName)) {
+ return this.isEditingTags;
+ }
+ if (widgetName === 'edit_tags_opt') {
+ return !this.isEditingTags;
+ }
+ if (params.optionsPossibleValues['removeTag']) {
+ return this.isEditingTags;
+ }
+ return this._super(...arguments);
+ },
+ /**
+ * @override
+ */
+ async _computeWidgetState(methodName, params) {
+ if (methodName === 'addTag') {
+ // The related widget allows to select a value but then resets its state to a non-selected value
+ return '';
+ }
+ return this._super(...arguments);
+ },
+ /**
+ * @private
+ */
+ _notifyUpdatedTags() {
+ this.trigger_up('set_blog_post_updated_tags', {
+ blogPostID: this.blogPostID,
+ tags: this.tagIDs.map(tagID => this.allTagsByID[tagID]),
+ });
+ },
+ /**
+ * @override
+ */
+ async _renderCustomXML(uiFragment) {
+ const $tagList = $(uiFragment.querySelector('.o_wblog_tag_list'));
+ for (const tagID of this.tagIDs) {
+ const tag = this.allTagsByID[tagID];
+ $tagList.append(qweb.render('website_blog.TagListItem', {
+ tag: tag,
+ }));
+ }
+ const $select = $(uiFragment.querySelector('we-select[data-name="blog_existing_tag_opt"]'));
+ for (const [key, tag] of Object.entries(this.allTagsByID)) {
+ if (this.tagIDs.includes(parseInt(key)) || this.tagIDs.includes(key)) {
+ // saved tag keys are numbers, new tag keys are strings
+ continue;
+ }
+ $select.prepend(qweb.render('website_blog.TagSelectItem', {
+ tag: tag,
+ }));
+ }
+ },
+});
+});