diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/mail/static/src/components/discuss_sidebar/discuss_sidebar.js | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/mail/static/src/components/discuss_sidebar/discuss_sidebar.js')
| -rw-r--r-- | addons/mail/static/src/components/discuss_sidebar/discuss_sidebar.js | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/addons/mail/static/src/components/discuss_sidebar/discuss_sidebar.js b/addons/mail/static/src/components/discuss_sidebar/discuss_sidebar.js new file mode 100644 index 00000000..d12d0353 --- /dev/null +++ b/addons/mail/static/src/components/discuss_sidebar/discuss_sidebar.js @@ -0,0 +1,308 @@ +odoo.define('mail/static/src/components/discuss_sidebar/discuss_sidebar.js', function (require) { +'use strict'; + +const components = { + AutocompleteInput: require('mail/static/src/components/autocomplete_input/autocomplete_input.js'), + DiscussSidebarItem: require('mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.js'), +}; +const useShouldUpdateBasedOnProps = require('mail/static/src/component_hooks/use_should_update_based_on_props/use_should_update_based_on_props.js'); +const useStore = require('mail/static/src/component_hooks/use_store/use_store.js'); +const useUpdate = require('mail/static/src/component_hooks/use_update/use_update.js'); + +const { Component } = owl; +const { useRef } = owl.hooks; + +class DiscussSidebar extends Component { + + /** + * @override + */ + constructor(...args) { + super(...args); + useShouldUpdateBasedOnProps(); + useStore( + (...args) => this._useStoreSelector(...args), + { compareDepth: this._useStoreCompareDepth() } + ); + useUpdate({ func: () => this._update() }); + /** + * Reference of the quick search input. Useful to filter channels and + * chats based on this input content. + */ + this._quickSearchInputRef = useRef('quickSearchInput'); + + // bind since passed as props + this._onAddChannelAutocompleteSelect = this._onAddChannelAutocompleteSelect.bind(this); + this._onAddChannelAutocompleteSource = this._onAddChannelAutocompleteSource.bind(this); + this._onAddChatAutocompleteSelect = this._onAddChatAutocompleteSelect.bind(this); + this._onAddChatAutocompleteSource = this._onAddChatAutocompleteSource.bind(this); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * @returns {mail.discuss} + */ + get discuss() { + return this.env.messaging && this.env.messaging.discuss; + } + + /** + * @returns {string} + */ + get FIND_OR_CREATE_CHANNEL() { + return this.env._t("Find or create a channel..."); + } + + /** + * @returns {mail.thread[]} + */ + get orderedMailboxes() { + return this.env.models['mail.thread'] + .all(thread => thread.isPinned && thread.model === 'mail.box') + .sort((mailbox1, mailbox2) => { + if (mailbox1 === this.env.messaging.inbox) { + return -1; + } + if (mailbox2 === this.env.messaging.inbox) { + return 1; + } + if (mailbox1 === this.env.messaging.starred) { + return -1; + } + if (mailbox2 === this.env.messaging.starred) { + return 1; + } + const mailbox1Name = mailbox1.displayName; + const mailbox2Name = mailbox2.displayName; + mailbox1Name < mailbox2Name ? -1 : 1; + }); + } + + /** + * Return the list of chats that match the quick search value input. + * + * @returns {mail.thread[]} + */ + get quickSearchPinnedAndOrderedChats() { + const allOrderedAndPinnedChats = this.env.models['mail.thread'] + .all(thread => + thread.channel_type === 'chat' && + thread.isPinned && + thread.model === 'mail.channel' + ) + .sort((c1, c2) => c1.displayName < c2.displayName ? -1 : 1); + if (!this.discuss.sidebarQuickSearchValue) { + return allOrderedAndPinnedChats; + } + const qsVal = this.discuss.sidebarQuickSearchValue.toLowerCase(); + return allOrderedAndPinnedChats.filter(chat => { + const nameVal = chat.displayName.toLowerCase(); + return nameVal.includes(qsVal); + }); + } + + /** + * Return the list of channels that match the quick search value input. + * + * @returns {mail.thread[]} + */ + get quickSearchOrderedAndPinnedMultiUserChannels() { + const allOrderedAndPinnedMultiUserChannels = this.env.models['mail.thread'] + .all(thread => + thread.channel_type === 'channel' && + thread.isPinned && + thread.model === 'mail.channel' + ) + .sort((c1, c2) => { + if (c1.displayName && !c2.displayName) { + return -1; + } else if (!c1.displayName && c2.displayName) { + return 1; + } else if (c1.displayName && c2.displayName && c1.displayName !== c2.displayName) { + return c1.displayName.toLowerCase() < c2.displayName.toLowerCase() ? -1 : 1; + } else { + return c1.id - c2.id; + } + }); + if (!this.discuss.sidebarQuickSearchValue) { + return allOrderedAndPinnedMultiUserChannels; + } + const qsVal = this.discuss.sidebarQuickSearchValue.toLowerCase(); + return allOrderedAndPinnedMultiUserChannels.filter(channel => { + const nameVal = channel.displayName.toLowerCase(); + return nameVal.includes(qsVal); + }); + } + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + */ + _update() { + if (!this.discuss) { + return; + } + if (this._quickSearchInputRef.el) { + this._quickSearchInputRef.el.value = this.discuss.sidebarQuickSearchValue; + } + } + + /** + * @private + * @returns {Object} + */ + _useStoreCompareDepth() { + return { + allOrderedAndPinnedChats: 1, + allOrderedAndPinnedMailboxes: 1, + allOrderedAndPinnedMultiUserChannels: 1, + }; + } + + /** + * @private + * @param {Object} props + * @returns {Object} + */ + _useStoreSelector(props) { + const discuss = this.env.messaging.discuss; + return { + allOrderedAndPinnedChats: this.quickSearchPinnedAndOrderedChats, + allOrderedAndPinnedMailboxes: this.orderedMailboxes, + allOrderedAndPinnedMultiUserChannels: this.quickSearchOrderedAndPinnedMultiUserChannels, + allPinnedChannelAmount: + this.env.models['mail.thread'] + .all(thread => + thread.isPinned && + thread.model === 'mail.channel' + ).length, + discussIsAddingChannel: discuss && discuss.isAddingChannel, + discussIsAddingChat: discuss && discuss.isAddingChat, + discussSidebarQuickSearchValue: discuss && discuss.sidebarQuickSearchValue, + }; + } + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + * @param {Event} ev + * @param {Object} ui + * @param {Object} ui.item + * @param {integer} ui.item.id + */ + _onAddChannelAutocompleteSelect(ev, ui) { + this.discuss.handleAddChannelAutocompleteSelect(ev, ui); + } + + /** + * @private + * @param {Object} req + * @param {string} req.term + * @param {function} res + */ + _onAddChannelAutocompleteSource(req, res) { + this.discuss.handleAddChannelAutocompleteSource(req, res); + } + + /** + * @private + * @param {Event} ev + * @param {Object} ui + * @param {Object} ui.item + * @param {integer} ui.item.id + */ + _onAddChatAutocompleteSelect(ev, ui) { + this.discuss.handleAddChatAutocompleteSelect(ev, ui); + } + + /** + * @private + * @param {Object} req + * @param {string} req.term + * @param {function} res + */ + _onAddChatAutocompleteSource(req, res) { + this.discuss.handleAddChatAutocompleteSource(req, res); + } + + /** + * Called when clicking on add channel icon. + * + * @private + * @param {MouseEvent} ev + */ + _onClickChannelAdd(ev) { + ev.stopPropagation(); + this.discuss.update({ isAddingChannel: true }); + } + + /** + * Called when clicking on channel title. + * + * @private + * @param {MouseEvent} ev + */ + _onClickChannelTitle(ev) { + ev.stopPropagation(); + return this.env.bus.trigger('do-action', { + action: { + name: this.env._t("Public Channels"), + type: 'ir.actions.act_window', + res_model: 'mail.channel', + views: [[false, 'kanban'], [false, 'form']], + domain: [['public', '!=', 'private']] + }, + }); + } + + /** + * Called when clicking on add chat icon. + * + * @private + * @param {MouseEvent} ev + */ + _onClickChatAdd(ev) { + ev.stopPropagation(); + this.discuss.update({ isAddingChat: true }); + } + + /** + * @private + * @param {CustomEvent} ev + */ + _onHideAddingItem(ev) { + ev.stopPropagation(); + this.discuss.clearIsAddingItem(); + } + + /** + * @private + * @param {KeyboardEvent} ev + */ + _onInputQuickSearch(ev) { + ev.stopPropagation(); + this.discuss.update({ + sidebarQuickSearchValue: this._quickSearchInputRef.el.value, + }); + } + +} + +Object.assign(DiscussSidebar, { + components, + props: {}, + template: 'mail.DiscussSidebar', +}); + +return DiscussSidebar; + +}); |
