diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 17:14:58 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 17:14:58 +0700 |
| commit | 1ca3b3df3421961caec3b747a364071c80f5c7da (patch) | |
| tree | 6778a1f0f3f9b4c6e26d6d87ccde16e24da6c9d6 /muk_web_theme/static/src/js | |
| parent | b57188be371d36d96caac4b8d65a40745c0e972c (diff) | |
initial commit
Diffstat (limited to 'muk_web_theme/static/src/js')
| -rw-r--r-- | muk_web_theme/static/src/js/chrome/actions.js | 39 | ||||
| -rw-r--r-- | muk_web_theme/static/src/js/chrome/apps.js | 96 | ||||
| -rw-r--r-- | muk_web_theme/static/src/js/chrome/appsbar.js | 69 | ||||
| -rw-r--r-- | muk_web_theme/static/src/js/chrome/menu.js | 101 | ||||
| -rw-r--r-- | muk_web_theme/static/src/js/core/search.js | 134 | ||||
| -rw-r--r-- | muk_web_theme/static/src/js/fields/relational.js | 64 | ||||
| -rw-r--r-- | muk_web_theme/static/src/js/libs/scrollbar.js | 27 | ||||
| -rw-r--r-- | muk_web_theme/static/src/js/views/form_renderer.js | 50 | ||||
| -rw-r--r-- | muk_web_theme/static/src/js/views/form_view.js | 49 | ||||
| -rw-r--r-- | muk_web_theme/static/src/js/views/kanban_column.js | 42 | ||||
| -rw-r--r-- | muk_web_theme/static/src/js/views/kanban_quick_create.js | 44 | ||||
| -rw-r--r-- | muk_web_theme/static/src/js/views/kanban_renderer.js | 271 |
12 files changed, 986 insertions, 0 deletions
diff --git a/muk_web_theme/static/src/js/chrome/actions.js b/muk_web_theme/static/src/js/chrome/actions.js new file mode 100644 index 0000000..37b3c45 --- /dev/null +++ b/muk_web_theme/static/src/js/chrome/actions.js @@ -0,0 +1,39 @@ +/********************************************************************************** +* +* Copyright (c) 2017-today MuK IT GmbH. +* +* This file is part of MuK Grid Snippets +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +**********************************************************************************/ + +odoo.define('muk_web_theme.ActionManager', function (require) { +"use strict"; + +const ActionManager = require('web.ActionManager'); + +ActionManager.include({ + _handleAction(action) { + return this._super(...arguments).then($.proxy(this, '_hideMenusByAction', action)); + }, + _hideMenusByAction(action) { + const unique_selection = '[data-action-id=' + action.id + ']'; + $(_.str.sprintf('.o_menu_apps .dropdown:has(.dropdown-menu.show:has(%s)) > a', unique_selection)).dropdown('toggle'); + $(_.str.sprintf('.o_menu_sections.show:has(%s)', unique_selection)).collapse('hide'); + }, +}); + +}); diff --git a/muk_web_theme/static/src/js/chrome/apps.js b/muk_web_theme/static/src/js/chrome/apps.js new file mode 100644 index 0000000..8423aa9 --- /dev/null +++ b/muk_web_theme/static/src/js/chrome/apps.js @@ -0,0 +1,96 @@ +/********************************************************************************** +* +* Copyright (c) 2017-today MuK IT GmbH. +* +* This file is part of MuK Grid Snippets +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +**********************************************************************************/ + +odoo.define('muk_web_theme.AppsMenu', function (require) { +"use strict"; + +const core = require('web.core'); +const session = require("web.session"); + +const AppsMenu = require("web.AppsMenu"); +const MenuSearchMixin = require("muk_web_theme.MenuSearchMixin"); + +AppsMenu.include(_.extend({}, MenuSearchMixin, { + events: _.extend({}, AppsMenu.prototype.events, { + "keydown .mk_search_input input": "_onSearchResultsNavigate", + "click .mk_menu_search_result": "_onSearchResultChosen", + "shown.bs.dropdown": "_onMenuShown", + "hidden.bs.dropdown": "_onMenuHidden", + "hide.bs.dropdown": "_onMenuHide", + }), + init(parent, menuData) { + this._super(...arguments); + for (let n in this._apps) { + this._apps[n].web_icon_data = menuData.children[n].web_icon_data; + } + this._searchableMenus = _.reduce( + menuData.children, this._findNames.bind(this), {} + ); + this._search_def = $.Deferred(); + }, + start() { + this._setBackgroundImage(); + this.$search_container = this.$(".mk_search_container"); + this.$search_input = this.$(".mk_search_input input"); + this.$search_results = this.$(".mk_search_results"); + return this._super(...arguments); + }, + _onSearchResultChosen(event) { + event.preventDefault(); + const $result = $(event.currentTarget), + text = $result.text().trim(), + data = $result.data(), + suffix = ~text.indexOf("/") ? "/" : ""; + this.trigger_up("menu_clicked", { + action_id: data.actionId, + id: data.menuId, + previous_menu_id: data.parentId, + }); + const app = _.find(this._apps, (_app) => text.indexOf(_app.name + suffix) === 0); + core.bus.trigger("change_menu_section", app.menuID); + }, + _onAppsMenuItemClicked(event) { + this._super(...arguments); + event.preventDefault(); + }, + _setBackgroundImage() { + const url = session.url('/web/image', { + model: 'res.company', + id: session.company_id, + field: 'background_image', + }); + this.$('.dropdown-menu').css({ + "background-size": "cover", + "background-image": "url(" + url + ")" + }); + if (session.muk_web_theme_background_blend_mode) { + this.$('.o-app-name').css({ + "mix-blend-mode": session.muk_web_theme_background_blend_mode, + }); + } + }, + _onMenuHide(event) { + return $('.oe_wait').length === 0 && !this.$('input').is(':focus'); + }, +})); + +});
\ No newline at end of file diff --git a/muk_web_theme/static/src/js/chrome/appsbar.js b/muk_web_theme/static/src/js/chrome/appsbar.js new file mode 100644 index 0000000..eaa91d3 --- /dev/null +++ b/muk_web_theme/static/src/js/chrome/appsbar.js @@ -0,0 +1,69 @@ +/********************************************************************************** +* +* Copyright (c) 2017-today MuK IT GmbH. +* +* This file is part of MuK Grid Snippets +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +**********************************************************************************/ + +odoo.define('muk_web_theme.AppsBar', function (require) { +"use strict"; + +const Widget = require('web.Widget'); + +const AppsBar = Widget.extend({ + events: _.extend({}, Widget.prototype.events, { + 'click .nav-link': '_onAppsMenuItemClicked', + }), + template: "muk_web_theme.AppsBarMenu", + init(parent, menu) { + this._super(...arguments); + this._apps = _.map(menu.children, (app) => ({ + actionID: parseInt(app.action.split(',')[1]), + web_icon_data: app.web_icon_data, + menuID: app.id, + name: app.name, + xmlID: app.xmlid, + }) + ); + }, + getApps() { + return this._apps; + }, + _openApp(app) { + this.trigger_up('app_clicked', { + action_id: app.actionID, + menu_id: app.menuID, + }); + }, + _onAppsMenuItemClicked(ev) { + const $target = $(ev.currentTarget); + const actionID = $target.data('action-id'); + const menuID = $target.data('menu-id'); + const app = _.findWhere(this._apps, { + actionID: actionID, + menuID: menuID + }); + this._openApp(app); + ev.preventDefault(); + $target.blur(); + }, +}); + +return AppsBar; + +});
\ No newline at end of file diff --git a/muk_web_theme/static/src/js/chrome/menu.js b/muk_web_theme/static/src/js/chrome/menu.js new file mode 100644 index 0000000..c1e522f --- /dev/null +++ b/muk_web_theme/static/src/js/chrome/menu.js @@ -0,0 +1,101 @@ +/********************************************************************************** +* +* Copyright (c) 2017-today MuK IT GmbH. +* +* This file is part of MuK Grid Snippets +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +**********************************************************************************/ + +odoo.define('muk_web_theme.Menu', function (require) { +"use strict"; + +const config = require("web.config"); + +const Menu = require("web.Menu"); +const AppsBar = require("muk_web_theme.AppsBar"); + +Menu.include({ + events: _.extend({}, Menu.prototype.events, { + "click .o_menu_apps a[data-toggle=dropdown]": "_onAppsMenuClick", + "click .mk_menu_mobile_section": "_onMobileSectionClick", + "click .o_menu_sections [role=menuitem]": "_hideMobileSubmenus", + "show.bs.dropdown .o_menu_systray, .o_menu_apps": "_hideMobileSubmenus", + }), + menusTemplate: config.device.isMobile ? + 'muk_web_theme.MobileMenu.sections' : Menu.prototype.menusTemplate, + start() { + const res = this._super(...arguments); + this.$menu_toggle = this.$(".mk_menu_sections_toggle"); + this.$menu_apps_sidebar = this.$('.mk_apps_sidebar_panel'); + this._appsBar = new AppsBar(this, this.menu_data); + const appsBarProm = this._appsBar.appendTo(this.$menu_apps_sidebar); + appsBarProm.then(() => { + this.$menu_apps_sidebar.renderScrollBar(); + }); + if (config.device.isMobile) { + const menu_ids = _.keys(this.$menu_sections); + for (let i = 0; i < menu_ids.length; i++) { + const $section = this.$menu_sections[menu_ids[i]]; + $section.on('click', 'a[data-menu]', this, (ev) => { + ev.stopPropagation(); + }); + } + } + return Promise.all([ + res, appsBarProm + ]); + }, + _hideMobileSubmenus() { + if (this.$menu_toggle.is(":visible") && $('.oe_wait').length === 0 && + this.$section_placeholder.is(":visible")) { + this.$section_placeholder.collapse("hide"); + } + }, + _updateMenuBrand() { + return !config.device.isMobile ? this._super(...arguments) : null; + }, + _onAppsMenuClick(event, checkedCanBeRemoved) { + const action_manager = this.getParent().action_manager; + const controller = action_manager.getCurrentController(); + if (controller && !checkedCanBeRemoved) { + controller.widget.canBeRemoved().then(() => { + $(event.currentTarget).trigger('click', [true]); + $(event.currentTarget).off('.bs.dropdown'); + }); + event.stopPropagation(); + event.preventDefault(); + } + }, + _onMobileSectionClick(event) { + event.preventDefault(); + event.stopPropagation(); + const $section = $(event.currentTarget); + if ($section.hasClass('show')) { + $section.removeClass('show'); + $section.find('.show').removeClass('show'); + $section.find('.fa-chevron-down').hide(); + $section.find('.fa-chevron-right').show(); + } else { + $section.addClass('show'); + $section.find('ul:first').addClass('show'); + $section.find('.fa-chevron-down:first').show(); + $section.find('.fa-chevron-right:first').hide(); + } + }, +}); + +});
\ No newline at end of file diff --git a/muk_web_theme/static/src/js/core/search.js b/muk_web_theme/static/src/js/core/search.js new file mode 100644 index 0000000..0bf5996 --- /dev/null +++ b/muk_web_theme/static/src/js/core/search.js @@ -0,0 +1,134 @@ +/********************************************************************************** +* +* Copyright (c) 2017-today MuK IT GmbH. +* +* This file is part of MuK Grid Snippets +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +**********************************************************************************/ + +odoo.define('muk_web_theme.MenuSearchMixin', function (require) { +"use strict"; + +const core = require('web.core'); +const config = require("web.config"); + +const QWeb = core.qweb; + +const MenuSearchMixin = { + _findNames(memo, menu) { + if (menu.action) { + const key = menu.parent_id ? menu.parent_id[1] + "/" : ""; + memo[key + menu.name] = menu; + } + if (menu.children.length) { + _.reduce(menu.children, this._findNames.bind(this), memo); + } + return memo; + }, + _menuInfo(key) { + const original = this._searchableMenus[key]; + return _.extend({ + action_id: parseInt(original.action.split(',')[1], 10), + }, original); + }, + _searchFocus() { + if (!config.device.isMobile) { + this.$search_input.focus(); + } else { + this.$search_input.blur(); + } + }, + _searchReset() { + this.$search_container.removeClass("has-results"); + this.$search_results.empty(); + this.$search_input.val(""); + }, + _searchMenusSchedule() { + this._search_def.reject(); + this._search_def = $.Deferred(); + setTimeout(this._search_def.resolve.bind(this._search_def), 50); + this._search_def.then(this._searchMenus.bind(this)); + }, + _searchMenus() { + const query = this.$search_input.val(); + if (query === "") { + this.$search_container.removeClass("has-results"); + this.$search_results.empty(); + return; + } + const results = fuzzy.filter(query, _.keys(this._searchableMenus), { + pre: "<b>", + post: "</b>", + }); + this.$search_container.toggleClass("has-results", Boolean(results.length)); + this.$search_results.html(QWeb.render("muk_web_theme.MenuSearchResults", { + results: results, + widget: this, + })); + }, + _onSearchResultsNavigate(event) { + if (this.$search_results.html().trim() === "") { + this._searchMenusSchedule(); + return; + } + const all = this.$search_results.find(".mk_menu_search_result"); + const key = event.key || String.fromCharCode(event.which); + const pre_focused = all.filter(".active") || $(all[0]); + const offset = all.index(pre_focused); + if (key === "Tab") { + event.preventDefault(); + key = event.shiftKey ? "ArrowUp" : "ArrowDown"; + } + switch (key) { + case "Enter": + pre_focused.click(); + break; + case "ArrowUp": + offset--; + break; + case "ArrowDown": + offset++; + break; + default: + this._searchMenusSchedule(); + return; + } + if (offset < 0) { + offset = all.length + offset; + } else if (offset >= all.length) { + offset -= all.length; + } + const new_focused = $(all[offset]); + pre_focused.removeClass("active"); + new_focused.addClass("active"); + this.$search_results.scrollTo(new_focused, { + offset: { + top: this.$search_results.height() * -0.5, + }, + }); + }, + _onMenuShown(event) { + this._searchFocus(); + }, + _onMenuHidden(event) { + this._searchReset(); + }, +}; + +return MenuSearchMixin; + +});
\ No newline at end of file diff --git a/muk_web_theme/static/src/js/fields/relational.js b/muk_web_theme/static/src/js/fields/relational.js new file mode 100644 index 0000000..71133ce --- /dev/null +++ b/muk_web_theme/static/src/js/fields/relational.js @@ -0,0 +1,64 @@ +/********************************************************************************** +* +* Copyright (c) 2017-today MuK IT GmbH. +* +* This file is part of MuK Grid Snippets +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +**********************************************************************************/ + +odoo.define('muk_web_theme.relational_fields', function (require) { +"use strict"; + +const config = require("web.config"); +const fields = require('web.relational_fields'); + +fields.FieldStatus.include({ + _setState() { + this._super(...arguments); + if (config.device.isMobile) { + _.map(this.status_information, (value) => { + value.fold = true; + }); + } + }, +}); + +fields.FieldOne2Many.include({ + _renderButtons() { + const result = this._super(...arguments); + if (config.device.isMobile && this.$buttons) { + const $buttons = this.$buttons.find('.btn-secondary'); + $buttons.addClass('btn-primary mk_mobile_add'); + $buttons.removeClass('btn-secondary'); + } + return result; + } +}); + +fields.FieldMany2Many.include({ + _renderButtons() { + const result = this._super(...arguments); + if (config.device.isMobile && this.$buttons) { + const $buttons = this.$buttons.find('.btn-secondary'); + $buttons.addClass('btn-primary mk_mobile_add'); + $buttons.removeClass('btn-secondary'); + } + return result; + } +}); + +});
\ No newline at end of file diff --git a/muk_web_theme/static/src/js/libs/scrollbar.js b/muk_web_theme/static/src/js/libs/scrollbar.js new file mode 100644 index 0000000..3842f53 --- /dev/null +++ b/muk_web_theme/static/src/js/libs/scrollbar.js @@ -0,0 +1,27 @@ +/********************************************************************************** +* +* Copyright (c) 2017-today MuK IT GmbH. +* +* This file is part of MuK Grid Snippets +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +**********************************************************************************/ + +$.fn.renderScrollBar = function() { + this.each(function() { + new SimpleBar(this); + }); +}; diff --git a/muk_web_theme/static/src/js/views/form_renderer.js b/muk_web_theme/static/src/js/views/form_renderer.js new file mode 100644 index 0000000..87a202d --- /dev/null +++ b/muk_web_theme/static/src/js/views/form_renderer.js @@ -0,0 +1,50 @@ +/********************************************************************************** +* +* Copyright (c) 2017-today MuK IT GmbH. +* +* This file is part of MuK Grid Snippets +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +**********************************************************************************/ + +odoo.define('muk_web_theme.FormRenderer', function (require) { +"use strict"; + +const core = require('web.core'); +const config = require("web.config"); + +const FormRenderer = require('web.FormRenderer'); + +FormRenderer.include({ + _renderHeaderButtons() { + const $buttons = this._super(...arguments); + if ( + !config.device.isMobile || + !$buttons.is(":has(>:not(.o_invisible_modifier))") + ) { + return $buttons; + } + + $buttons.addClass("dropdown-menu"); + const $dropdown = $( + core.qweb.render("muk_web_theme.MenuStatusbarButtons") + ); + $buttons.addClass("dropdown-menu").appendTo($dropdown); + return $dropdown; + }, +}); + +});
\ No newline at end of file diff --git a/muk_web_theme/static/src/js/views/form_view.js b/muk_web_theme/static/src/js/views/form_view.js new file mode 100644 index 0000000..3bd2610 --- /dev/null +++ b/muk_web_theme/static/src/js/views/form_view.js @@ -0,0 +1,49 @@ +/********************************************************************************** +* +* Copyright (c) 2017-today MuK IT GmbH. +* +* This file is part of MuK Grid Snippets +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +**********************************************************************************/ + +odoo.define('muk_web_theme.FormView', function (require) { +"use strict"; + +const config = require("web.config"); + +const FormView = require('web.FormView'); +const QuickCreateFormView = require('web.QuickCreateFormView'); + +FormView.include({ + init() { + this._super(...arguments); + if (config.device.isMobile) { + this.controllerParams.disableAutofocus = true; + } + }, +}); + +QuickCreateFormView.include({ + init() { + this._super(...arguments); + if (config.device.isMobile) { + this.controllerParams.disableAutofocus = true; + } + }, +}); + +}); diff --git a/muk_web_theme/static/src/js/views/kanban_column.js b/muk_web_theme/static/src/js/views/kanban_column.js new file mode 100644 index 0000000..0cdc8dd --- /dev/null +++ b/muk_web_theme/static/src/js/views/kanban_column.js @@ -0,0 +1,42 @@ +/********************************************************************************** +* +* Copyright (c) 2017-today MuK IT GmbH. +* +* This file is part of MuK Grid Snippets +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +**********************************************************************************/ + +odoo.define('muk_web_theme.KanbanColumn', function (require) { +"use strict"; + +const config = require('web.config'); + +const KanbanColumn = require('web.KanbanColumn'); + +if (!config.device.isMobile) { + return; +} + +KanbanColumn.include({ + init() { + this._super(...arguments); + this.recordsDraggable = false; + this.canBeFolded = false; + }, +}); + +}); diff --git a/muk_web_theme/static/src/js/views/kanban_quick_create.js b/muk_web_theme/static/src/js/views/kanban_quick_create.js new file mode 100644 index 0000000..b86ed52 --- /dev/null +++ b/muk_web_theme/static/src/js/views/kanban_quick_create.js @@ -0,0 +1,44 @@ +/**********************************************************************************
+*
+* Copyright (c) 2017-today MuK IT GmbH.
+*
+* This file is part of MuK Grid Snippets
+* (see https://mukit.at).
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+**********************************************************************************/
+
+odoo.define('muk_web_theme.kanban_column_quick_create', function (require) {
+"use strict";
+
+const config = require('web.config');
+
+const KanbanRenderer = require('web.kanban_column_quick_create');
+
+KanbanRenderer.include({
+ init() {
+ this._super(...arguments);
+ this.isMobile = config.device.isMobile;
+ },
+ _cancel() {
+ if (!config.device.isMobile) {
+ this._super(...arguments);
+ } else if (!this.folded) {
+ this.$input.val('');
+ }
+ },
+});
+
+});
diff --git a/muk_web_theme/static/src/js/views/kanban_renderer.js b/muk_web_theme/static/src/js/views/kanban_renderer.js new file mode 100644 index 0000000..2cdd94d --- /dev/null +++ b/muk_web_theme/static/src/js/views/kanban_renderer.js @@ -0,0 +1,271 @@ +/********************************************************************************** +* +* Copyright (c) 2017-today MuK IT GmbH. +* +* This file is part of MuK Grid Snippets +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +**********************************************************************************/ + +odoo.define('muk_web_theme.KanbanRenderer', function (require) { +"use strict"; + +const config = require('web.config'); +const core = require('web.core'); + +const KanbanRenderer = require('web.KanbanRenderer'); + +const _t = core._t; +const qweb = core.qweb; + +if (!config.device.isMobile) { + return; +} + +KanbanRenderer.include({ + custom_events: _.extend({}, KanbanRenderer.prototype.custom_events || {}, { + quick_create_column_created: '_onColumnAdded', + }), + events: _.extend({}, KanbanRenderer.prototype.events, { + 'click .o_kanban_mobile_tab': '_onMobileTabClicked', + 'click .o_kanban_mobile_add_column': '_onMobileQuickCreateClicked', + }), + ANIMATE: true, + init() { + this._super.apply(this, arguments); + this.activeColumnIndex = 0; + this._scrollPosition = null; + }, + on_attach_callback() { + if (this._scrollPosition && this.state.groupedBy.length && this.widgets.length) { + var $column = this.widgets[this.activeColumnIndex].$el; + $column.scrollLeft(this._scrollPosition.left); + $column.scrollTop(this._scrollPosition.top); + } + this._computeTabPosition(); + this._super.apply(this, arguments); + }, + on_detach_callback() { + if (this.state.groupedBy.length && this.widgets.length) { + var $column = this.widgets[this.activeColumnIndex].$el; + this._scrollPosition = { + left: $column.scrollLeft(), + top: $column.scrollTop(), + }; + } else { + this._scrollPosition = null; + } + this._super.apply(this, arguments); + }, + addQuickCreate() { + if(this._canCreateColumn() && !this.quickCreate.folded) { + this._onMobileQuickCreateClicked(); + } + return this.widgets[this.activeColumnIndex].addQuickCreate(); + }, + updateColumn(localID) { + var index = _.findIndex(this.widgets, {db_id: localID}); + var $column = this.widgets[index].$el; + var scrollTop = $column.scrollTop(); + return this._super.apply(this, arguments) + .then(() => this._layoutUpdate(false)) + .then(() => $column.scrollTop(scrollTop)); + }, + _canCreateColumn: function() { + return this.quickCreateEnabled && this.quickCreate && this.widgets.length; + }, + _computeColumnPosition(animate) { + if (this.widgets.length) { + const rtl = _t.database.parameters.direction === 'rtl'; + this.$('.o_kanban_group').show(); + const $columnAfter = this._toNode(this.widgets.filter((widget, index) => index > this.activeColumnIndex)); + const promiseAfter = this._updateColumnCss($columnAfter, rtl ? {right: '100%'} : {left: '100%'}, animate); + const $columnBefore = this._toNode(this.widgets.filter((widget, index) => index < this.activeColumnIndex)); + const promiseBefore = this._updateColumnCss($columnBefore, rtl ? {right: '-100%'} : {left: '-100%'}, animate); + const $columnCurrent = this._toNode(this.widgets.filter((widget, index) => index === this.activeColumnIndex)); + const promiseCurrent = this._updateColumnCss($columnCurrent, rtl ? {right: '0%'} : {left: '0%'}, animate); + promiseAfter + .then(promiseBefore) + .then(promiseCurrent) + .then(() => { + $columnAfter.hide(); + $columnBefore.hide(); + }); + } + }, + _computeCurrentColumn() { + if (this.widgets.length) { + var column = this.widgets[this.activeColumnIndex]; + if (!column) { + return; + } + var columnID = column.id || column.db_id; + this.$('.o_kanban_mobile_tab.o_current, .o_kanban_group.o_current') + .removeClass('o_current'); + this.$('.o_kanban_group[data-id="' + columnID + '"], ' + + '.o_kanban_mobile_tab[data-id="' + columnID + '"]') + .addClass('o_current'); + } + }, + _computeTabPosition() { + this._computeTabJustification(); + this._computeTabScrollPosition(); + }, + _computeTabScrollPosition() { + if (this.widgets.length) { + var lastItemIndex = this.widgets.length - 1; + var moveToIndex = this.activeColumnIndex; + var scrollToLeft = 0; + for (var i = 0; i < moveToIndex; i++) { + var columnWidth = this._getTabWidth(this.widgets[i]); + if (moveToIndex !== lastItemIndex && i === moveToIndex - 1) { + var partialWidth = 0.75; + scrollToLeft += columnWidth * partialWidth; + } else { + scrollToLeft += columnWidth; + } + } + this.$('.o_kanban_mobile_tabs').scrollLeft(scrollToLeft); + } + }, + _computeTabJustification() { + if (this.widgets.length) { + var self = this; + var widthChilds = this.widgets.reduce(function (total, column) { + return total + self._getTabWidth(column); + }, 0); + var $tabs = this.$('.o_kanban_mobile_tabs'); + $tabs.toggleClass('justify-content-between', $tabs.outerWidth() >= widthChilds); + } + }, + _enableSwipe() { + var self = this; + var step = _t.database.parameters.direction === 'rtl' ? -1 : 1; + this.$el.swipe({ + excludedElements: ".o_kanban_mobile_tabs", + swipeLeft() { + var moveToIndex = self.activeColumnIndex + step; + if (moveToIndex < self.widgets.length) { + self._moveToGroup(moveToIndex, self.ANIMATE); + } + }, + swipeRight() { + var moveToIndex = self.activeColumnIndex - step; + if (moveToIndex > -1) { + self._moveToGroup(moveToIndex, self.ANIMATE); + } + } + }); + }, + _getTabWidth (column) { + var columnID = column.id || column.db_id; + return this.$('.o_kanban_mobile_tab[data-id="' + columnID + '"]').outerWidth(); + }, + _layoutUpdate (animate) { + this._computeCurrentColumn(); + this._computeTabPosition(); + this._computeColumnPosition(animate); + }, + _moveToGroup(moveToIndex, animate) { + if (moveToIndex < 0 || moveToIndex >= this.widgets.length) { + this._layoutUpdate(animate); + return Promise.resolve(); + } + this.activeColumnIndex = moveToIndex; + var column = this.widgets[this.activeColumnIndex]; + if (column.data.isOpen) { + this._layoutUpdate(animate); + } else { + this.trigger_up('column_toggle_fold', { + db_id: column.db_id, + onSuccess: () => this._layoutUpdate(animate) + }); + } + this._enableSwipe(); + return Promise.resolve(); + }, + _renderGrouped(fragment) { + var self = this; + var newFragment = document.createDocumentFragment(); + this._super.apply(this, [newFragment]); + this.defs.push(Promise.all(this.defs).then(function () { + var data = []; + _.each(self.state.data, function (group) { + if (!group.value) { + group = _.extend({}, group, {value: _t('Undefined')}); + data.unshift(group); + } else { + data.push(group); + } + }); + + var kanbanColumnContainer = document.createElement('div'); + kanbanColumnContainer.classList.add('o_kanban_columns_content'); + kanbanColumnContainer.appendChild(newFragment); + fragment.appendChild(kanbanColumnContainer); + $(qweb.render('KanbanView.MobileTabs', { + data: data, + quickCreateEnabled: self._canCreateColumn() + })).prependTo(fragment); + })); + }, + _renderView() { + var self = this; + return this._super.apply(this, arguments).then(function () { + if (self.state.groupedBy.length) { + return self._moveToGroup(0); + } else { + if(self._canCreateColumn()) { + self._onMobileQuickCreateClicked(); + } + return Promise.resolve(); + } + }); + }, + _toNode(widgets) { + const selectorCss = widgets + .map(widget => '.o_kanban_group[data-id="' + (widget.id || widget.db_id) + '"]') + .join(', '); + return this.$(selectorCss); + }, + _updateColumnCss($column, cssProperties, animate) { + if (animate) { + return new Promise(resolve => $column.animate(cssProperties, 'fast', resolve)); + } else { + $column.css(cssProperties); + return Promise.resolve(); + } + }, + _onColumnAdded() { + this._computeTabPosition(); + if(this._canCreateColumn() && !this.quickCreate.folded) { + this.quickCreate.toggleFold(); + } + }, + _onMobileQuickCreateClicked: function() { + this.$('.o_kanban_group').toggle(); + this.quickCreate.toggleFold(); + }, + _onMobileTabClicked(event) { + if(this._canCreateColumn() && !this.quickCreate.folded) { + this.quickCreate.toggleFold(); + } + this._moveToGroup($(event.currentTarget).index(), true); + }, + _renderExampleBackground() {}, +}); + +});
\ No newline at end of file |
