[REF] *: Adapt all modules to new control panel
Adaptation of the code throughout all modules to properly instantiate the newly refactored control panel and update it accordingly. Part of task 2196029 Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com>
This commit is contained in:
co-authored by
Mathieu Duckerts-Antoine
parent
18e5416636
commit
e68d3bb09d
@@ -88,60 +88,69 @@ FormController.include({
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_barcodePagerFirst: function () {
|
||||
var self = this;
|
||||
return this.mutex.exec(function () {}).then(function () {
|
||||
if (!self.pager) {
|
||||
self.do_warn(_t('Error: Pager not available'));
|
||||
return;
|
||||
}
|
||||
self.pager.updateState({
|
||||
current_min: 1,
|
||||
}, {notifyChange: true});
|
||||
});
|
||||
_barcodePagerFirst: async function () {
|
||||
return this._updatePage(() => 1);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_barcodePagerLast: function () {
|
||||
var self = this;
|
||||
return this.mutex.exec(function () {}).then(function () {
|
||||
if (!self.pager) {
|
||||
self.do_warn(_t('Error: Pager not available'));
|
||||
return;
|
||||
}
|
||||
var state = self.model.get(self.handle, {raw: true});
|
||||
self.pager.updateState({
|
||||
current_min: state.count,
|
||||
}, {notifyChange: true});
|
||||
});
|
||||
_barcodePagerLast: async function () {
|
||||
return this._updatePage((min, state) => state.count);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_barcodePagerNext: function () {
|
||||
var self = this;
|
||||
return this.mutex.exec(function () {}).then(function () {
|
||||
if (!self.pager) {
|
||||
self.do_warn(_t('Error: Pager not available'));
|
||||
return;
|
||||
return this._updatePage((min, state) => {
|
||||
min += 1;
|
||||
if (min > state.count) {
|
||||
min = 1;
|
||||
}
|
||||
self.pager.next();
|
||||
return min;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_barcodePagerPrevious: function () {
|
||||
var self = this;
|
||||
return this.mutex.exec(function () {}).then(function () {
|
||||
if (!self.pager) {
|
||||
self.do_warn(_t('Error: Pager not available'));
|
||||
return;
|
||||
return this._updatePage((min, state) => {
|
||||
min -= 1;
|
||||
if (min < 1) {
|
||||
min = state.count;
|
||||
}
|
||||
self.pager.previous();
|
||||
return min;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Change the current minimum value of the pager using provided function.
|
||||
* This function will be given the current minimum and state and must return
|
||||
* the updated value.
|
||||
*
|
||||
* @private
|
||||
* @param {Function(currentMin: Number, state: Object)} updater
|
||||
*/
|
||||
_updatePage: async function (updater) {
|
||||
await this.mutex.exec(() => {});
|
||||
const state = this.model.get(this.handle, { raw: true });
|
||||
const pagingInfo = this._getPagingInfo(state);
|
||||
if (!pagingInfo) {
|
||||
return this.do_warn(_t('Error: Pager not available'));
|
||||
}
|
||||
const currentMinimum = updater(pagingInfo.currentMinimum, state);
|
||||
const limit = pagingInfo.limit;
|
||||
const reloadParams = state.groupedBy && state.groupedBy.length ? {
|
||||
groupsLimit: limit,
|
||||
groupsOffset: currentMinimum - 1,
|
||||
} : {
|
||||
limit,
|
||||
offset: currentMinimum - 1,
|
||||
};
|
||||
await this.reload(reloadParams);
|
||||
// reset the scroll position to the top on page changed only
|
||||
if (state.limit === limit) {
|
||||
this.trigger_up('scrollTo', { top: 0 });
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Returns true iff the given barcode matches the given record (candidate).
|
||||
*
|
||||
|
||||
@@ -21,8 +21,8 @@ ActionManager.include({
|
||||
if (action.res_model === 'board.board' && action.view_mode === 'form') {
|
||||
action.target = 'inline';
|
||||
_.extend(action.flags, {
|
||||
hasActionMenus: false,
|
||||
hasSearchView: false,
|
||||
hasSidebar: false,
|
||||
headless: true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,211 +1,154 @@
|
||||
odoo.define('board.AddToBoardMenu', function (require) {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
var ActionManager = require('web.ActionManager');
|
||||
var Context = require('web.Context');
|
||||
var core = require('web.core');
|
||||
var Domain = require('web.Domain');
|
||||
var favorites_submenus_registry = require('web.favorites_submenus_registry');
|
||||
var pyUtils = require('web.py_utils');
|
||||
var Widget = require('web.Widget');
|
||||
const Context = require('web.Context');
|
||||
const Domain = require('web.Domain');
|
||||
const DropdownMenuItem = require('web.DropdownMenuItem');
|
||||
const FavoriteMenu = require('web.FavoriteMenu');
|
||||
const pyUtils = require('web.py_utils');
|
||||
const { sprintf } = require('web.utils');
|
||||
const { useAutofocus } = require('web.custom_hooks');
|
||||
|
||||
var _t = core._t;
|
||||
var QWeb = core.qweb;
|
||||
|
||||
var AddToBoardMenu = Widget.extend({
|
||||
events: _.extend({}, Widget.prototype.events, {
|
||||
'click .o_add_to_board.o_menu_header': '_onMenuHeaderClick',
|
||||
'click .o_add_to_board_confirm_button': '_onAddToBoardConfirmButtonClick',
|
||||
'click .o_add_to_board_input': '_onAddToBoardInputClick',
|
||||
'keyup .o_add_to_board_input': '_onKeyUp',
|
||||
}),
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} params
|
||||
* @param {Object} params.action an ir.actions description
|
||||
*/
|
||||
init: function (parent, params) {
|
||||
this._super(parent);
|
||||
this.action = params.action;
|
||||
this.isOpen = false;
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
if (this.action.id && this.action.type === 'ir.actions.act_window') {
|
||||
this._render();
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
const { useState } = owl.hooks;
|
||||
|
||||
/**
|
||||
* Closes the menu and render it.
|
||||
* 'Add to board' menu
|
||||
*
|
||||
* Component consisiting of a toggle button, a text input and an 'Add' button.
|
||||
* The first button is simply used to toggle the component and will determine
|
||||
* whether the other elements should be rendered.
|
||||
* The input will be given the name (or title) of the view that will be added.
|
||||
* Finally, the last button will send the name as well as some of the action
|
||||
* properties to the server to add the current view (and its context) to the
|
||||
* user's dashboard.
|
||||
* This component is only available in actions of type 'ir.actions.act_window'.
|
||||
* @extends DropdownMenuItem
|
||||
*/
|
||||
closeMenu: function () {
|
||||
this.isOpen = false;
|
||||
this._render();
|
||||
},
|
||||
class AddToBoardMenu extends DropdownMenuItem {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
this.interactive = true;
|
||||
this.state = useState({
|
||||
name: this.env.action.name || "",
|
||||
open: false,
|
||||
});
|
||||
|
||||
/**
|
||||
* This is the main function for actually saving the dashboard. This method
|
||||
* is supposed to call the route /board/add_to_dashboard with proper
|
||||
* information.
|
||||
*
|
||||
* @private
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_addToBoard: function () {
|
||||
var self = this;
|
||||
var searchQuery;
|
||||
// TO DO: for now the domains in query are evaluated.
|
||||
// This should be changed I think.
|
||||
this.trigger_up('get_search_query', {
|
||||
callback: function (query) {
|
||||
searchQuery = query;
|
||||
}
|
||||
});
|
||||
// TO DO: replace direct reference to action manager, controller, and currentAction in code below
|
||||
|
||||
// AAB: trigger_up an event that will be intercepted by the controller,
|
||||
// as soon as the controller is the parent of the control panel
|
||||
var actionManager = this.findAncestor(function (ancestor) {
|
||||
return ancestor instanceof ActionManager;
|
||||
});
|
||||
var controller = actionManager.getCurrentController();
|
||||
|
||||
var context = new Context(this.action.context);
|
||||
context.add(searchQuery.context);
|
||||
context.add({
|
||||
group_by: searchQuery.groupBy,
|
||||
orderedBy: searchQuery.orderedBy,
|
||||
});
|
||||
|
||||
this.trigger_up('get_controller_query_params', {
|
||||
callback: function (controllerQueryParams) {
|
||||
var queryContext = controllerQueryParams.context;
|
||||
var allContext = _.extend(
|
||||
_.omit(controllerQueryParams, ['context']),
|
||||
queryContext
|
||||
);
|
||||
context.add(allContext);
|
||||
}
|
||||
});
|
||||
|
||||
var domain = new Domain(this.action.domain || []);
|
||||
domain = Domain.prototype.normalizeArray(domain.toArray().concat(searchQuery.domain));
|
||||
|
||||
var evalutatedContext = pyUtils.eval('context', context);
|
||||
for (var key in evalutatedContext) {
|
||||
if (evalutatedContext.hasOwnProperty(key) && /^search_default_/.test(key)) {
|
||||
delete evalutatedContext[key];
|
||||
}
|
||||
useAutofocus();
|
||||
}
|
||||
evalutatedContext.dashboard_merge_domains_contexts = false;
|
||||
|
||||
var name = this.$input.val();
|
||||
//---------------------------------------------------------------------
|
||||
// Private
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
this.closeMenu();
|
||||
/**
|
||||
* This is the main function for actually saving the dashboard. This method
|
||||
* is supposed to call the route /board/add_to_dashboard with proper
|
||||
* information.
|
||||
* @private
|
||||
*/
|
||||
async _addToBoard() {
|
||||
const searchQuery = this.env.controlPanelModel.getQuery();
|
||||
const context = new Context(this.env.action.context);
|
||||
context.add(searchQuery.context);
|
||||
context.add({
|
||||
group_by: searchQuery.groupBy,
|
||||
orderedBy: searchQuery.orderedBy,
|
||||
});
|
||||
if (searchQuery.timeRanges && searchQuery.timeRanges.hasOwnProperty('fieldName')) {
|
||||
const { fieldName: field, range, comparisonRange } = searchQuery.timeRanges;
|
||||
context.add({
|
||||
time_ranges : { field, range, comparisonRange },
|
||||
});
|
||||
}
|
||||
let controllerQueryParams;
|
||||
this.env.controlPanelModel.trigger('get-controller-query-params', params => {
|
||||
controllerQueryParams = params || {};
|
||||
});
|
||||
controllerQueryParams.context = controllerQueryParams.context || {};
|
||||
const queryContext = controllerQueryParams.context;
|
||||
delete controllerQueryParams.context;
|
||||
context.add(Object.assign(controllerQueryParams, queryContext));
|
||||
|
||||
return self._rpc({
|
||||
const domainArray = new Domain(this.env.action.domain || []);
|
||||
const domain = Domain.prototype.normalizeArray(domainArray.toArray().concat(searchQuery.domain));
|
||||
|
||||
const evalutatedContext = context.eval();
|
||||
for (const key in evalutatedContext) {
|
||||
if (evalutatedContext.hasOwnProperty(key) && /^search_default_/.test(key)) {
|
||||
delete evalutatedContext[key];
|
||||
}
|
||||
}
|
||||
evalutatedContext.dashboard_merge_domains_contexts = false;
|
||||
|
||||
Object.assign(this.state, {
|
||||
name: this.env.action.name || "",
|
||||
open: false,
|
||||
});
|
||||
|
||||
const result = await this.rpc({
|
||||
route: '/board/add_to_dashboard',
|
||||
params: {
|
||||
action_id: self.action.id || false,
|
||||
action_id: this.env.action.id || false,
|
||||
context_to_save: evalutatedContext,
|
||||
domain: domain,
|
||||
view_mode: controller.viewType,
|
||||
name: name,
|
||||
view_mode: this.env.view.type,
|
||||
name: this.state.name,
|
||||
},
|
||||
})
|
||||
.then(function (r) {
|
||||
if (r) {
|
||||
self.do_notify(
|
||||
_.str.sprintf(_t("'%s' added to dashboard"), name),
|
||||
_t('Please refresh your browser for the changes to take effect.')
|
||||
);
|
||||
} else {
|
||||
self.do_warn(_t("Could not add filter to dashboard"));
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Renders and focuses the unique input if it is visible.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_render: function () {
|
||||
var $el = QWeb.render('AddToBoardMenu', {widget: this});
|
||||
this._replaceElement($el);
|
||||
if (this.isOpen) {
|
||||
this.$input = this.$('.o_add_to_board_input');
|
||||
this.$input.val(this.action.name);
|
||||
this.$input.focus();
|
||||
if (result) {
|
||||
this.env.services.notification.notify({
|
||||
title: sprintf(this.env._t("'%s' added to dashboard"), this.state.name),
|
||||
message: this.env._t("Please refresh your browser for the changes to take effect."),
|
||||
type: 'warning',
|
||||
});
|
||||
} else {
|
||||
this.env.services.notification.notify({
|
||||
message: this.env._t("Could not add filter to dashboard"),
|
||||
type: 'danger',
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Hides and displays the submenu which allows adding custom filters.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_toggleMenu: function () {
|
||||
this.isOpen = !this.isOpen;
|
||||
this._render();
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------
|
||||
// Handlers
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {jQueryEvent} event
|
||||
*/
|
||||
_onAddToBoardInputClick: function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.$input.focus();
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @param {jQueryEvent} event
|
||||
*/
|
||||
_onAddToBoardConfirmButtonClick: function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this._addToBoard();
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @param {jQueryEvent} event
|
||||
*/
|
||||
_onKeyUp: function (event) {
|
||||
if (event.which === $.ui.keyCode.ENTER) {
|
||||
this._addToBoard();
|
||||
/**
|
||||
* @private
|
||||
* @param {KeyboardEvent} ev
|
||||
*/
|
||||
_onInputKeydown(ev) {
|
||||
switch (ev.key) {
|
||||
case 'Enter':
|
||||
ev.preventDefault();
|
||||
this._addToBoard();
|
||||
break;
|
||||
case 'Escape':
|
||||
// Gives the focus back to the component.
|
||||
ev.preventDefault();
|
||||
ev.target.blur();
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @param {jQueryEvent} event
|
||||
*/
|
||||
_onMenuHeaderClick: function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this._toggleMenu();
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
favorites_submenus_registry.add('add_to_board_menu', AddToBoardMenu, 10);
|
||||
|
||||
return AddToBoardMenu;
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Static
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @param {Object} env
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static shouldBeDisplayed(env) {
|
||||
return env.action.type === 'ir.actions.act_window';
|
||||
}
|
||||
}
|
||||
|
||||
AddToBoardMenu.props = {};
|
||||
AddToBoardMenu.template = 'AddToBoardMenu';
|
||||
|
||||
FavoriteMenu.registry.add('add-to-board-menu', AddToBoardMenu, 10);
|
||||
|
||||
return AddToBoardMenu;
|
||||
});
|
||||
|
||||
@@ -42,10 +42,7 @@ var BoardController = FormController.extend({
|
||||
* @override
|
||||
*/
|
||||
getTitle: function () {
|
||||
if (this.inDashboard) {
|
||||
return _t("My Dashboard");
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
return _t("My Dashboard");
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -93,12 +90,6 @@ var BoardController = FormController.extend({
|
||||
});
|
||||
dialog.open();
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onEnableDashboard: function () {
|
||||
this.inDashboard = true;
|
||||
},
|
||||
/**
|
||||
* We need to intercept switch_view event coming from sub views, because we
|
||||
* don't actually want to switch view in dashboard, we want to do a
|
||||
@@ -255,6 +246,7 @@ var BoardRenderer = FormRenderer.extend({
|
||||
var rawContext = new Context(action.context, evalContext, {lang: session.user_context.lang});
|
||||
var context = pyUtils.eval('context', rawContext, evalContext);
|
||||
var domain = params.domain || pyUtils.eval('domain', action.domain || '[]', action.context);
|
||||
|
||||
action.context = context;
|
||||
action.domain = domain;
|
||||
var viewType = params.viewType || action.views[0][1];
|
||||
@@ -265,17 +257,32 @@ var BoardRenderer = FormRenderer.extend({
|
||||
.then(function (viewsInfo) {
|
||||
var viewInfo = viewsInfo[viewType];
|
||||
var View = viewRegistry.get(viewType);
|
||||
|
||||
const searchQuery = {
|
||||
context: context,
|
||||
domain: domain,
|
||||
groupBy: typeof context.group_by === 'string' && context.group_by ?
|
||||
[context.group_by] :
|
||||
context.group_by || [],
|
||||
orderedBy: context.orderedBy || [],
|
||||
};
|
||||
|
||||
if (['pivot', 'dashboard', 'graph', 'cohort'].includes(viewType)) {
|
||||
if (context.time_ranges) {
|
||||
const { field: fieldName, range, comparisonRange } = context.time_ranges;
|
||||
searchQuery.timeRanges = { fieldName, range, comparisonRange };
|
||||
} else {
|
||||
searchQuery.timeRanges = {};
|
||||
}
|
||||
}
|
||||
|
||||
var view = new View(viewInfo, {
|
||||
action: action,
|
||||
hasSelectors: false,
|
||||
modelName: action.res_model,
|
||||
searchQuery: {
|
||||
context: context,
|
||||
domain: domain,
|
||||
groupBy: typeof context.group_by === 'string' && context.group_by ? [context.group_by] : context.group_by || [],
|
||||
orderedBy: context.orderedBy || [],
|
||||
},
|
||||
searchQuery,
|
||||
withControlPanel: false,
|
||||
withSearchPanel: false,
|
||||
});
|
||||
return view.getController(self).then(function (controller) {
|
||||
self._boardFormViewIDs[controller.handle] = _.first(
|
||||
@@ -300,7 +307,6 @@ var BoardRenderer = FormRenderer.extend({
|
||||
// this function has a side effect. This is ok because we assume that
|
||||
// once we have a '<board>' tag, we are in a special dashboard mode.
|
||||
this.$el.addClass('o_dashboard');
|
||||
this.trigger_up('enable_dashboard');
|
||||
|
||||
var hasAction = _.detect(node.children, function (column) {
|
||||
return _.detect(column.children,function (element){
|
||||
|
||||
@@ -151,7 +151,8 @@
|
||||
// Favorites menu in control panel
|
||||
.o_add_to_dashboard {
|
||||
display: none; // hidden by default
|
||||
@include o-search-options-dropdown-custom-item;
|
||||
max-width: 250px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
|
||||
@@ -80,15 +80,27 @@
|
||||
<iframe width="100%" frameborder="0" t-att-src="url"/>
|
||||
</t>
|
||||
|
||||
<div t-name="AddToBoardMenu">
|
||||
<button type="button" class="dropdown-item o_add_to_board o_menu_header">Add to my Dashboard</button>
|
||||
<div t-if="widget.isOpen" class="dropdown-item-text o_add_to_board">
|
||||
<input class="o_input o_add_to_board_input" type="text"/>
|
||||
</div>
|
||||
<div t-if="widget.isOpen" class="dropdown-item-text o_add_to_board">
|
||||
<button type="button" class="btn btn-primary o_add_to_board_confirm_button">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
<t t-name="AddToBoardMenu" owl="1">
|
||||
<li class="o_menu_item o_add_to_board" role="menuitem">
|
||||
<button type="button" class="dropdown-item"
|
||||
t-ref="fallback-focus"
|
||||
t-on-click="state.open = !state.open"
|
||||
>
|
||||
<t>Add to my Dashboard</t>
|
||||
</button>
|
||||
<t t-if="state.open">
|
||||
<div class="dropdown-item-text">
|
||||
<input type="text" class="o_input" autofocus=""
|
||||
t-model.trim="state.name"
|
||||
t-on-keydown="_onInputKeydown"
|
||||
/>
|
||||
</div>
|
||||
<div class="dropdown-item-text">
|
||||
<button type="button" class="btn btn-primary" t-on-click="_addToBoard">Add</button>
|
||||
</div>
|
||||
</t>
|
||||
</li>
|
||||
</t>
|
||||
|
||||
<t t-name="SearchView.addtodashboard">
|
||||
<a href="#" class="dropdown-item o_add_to_dashboard_link o_closed_menu">Add to my Dashboard</a>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
'views/google_drive_templates.xml',
|
||||
'views/res_config_settings_views.xml',
|
||||
],
|
||||
'qweb': ['static/src/xml/*.xml'],
|
||||
'demo': [
|
||||
'data/google_drive_demo.xml'
|
||||
],
|
||||
|
||||
@@ -1,110 +1,90 @@
|
||||
odoo.define('google_drive.sidebar', function (require) {
|
||||
"use strict";
|
||||
odoo.define('google_drive.ActionMenus', function (require) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* The purpose of this file is to include the Sidebar widget to add Google
|
||||
* Drive related items.
|
||||
*/
|
||||
|
||||
var Sidebar = require('web.Sidebar');
|
||||
|
||||
|
||||
Sidebar.include({
|
||||
// TO DO: clean me in master
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
var def;
|
||||
if (this.options.viewType === "form") {
|
||||
def = this._addGoogleDocItems(this.env.model, this.env.activeIds[0]);
|
||||
}
|
||||
return Promise.resolve(def).then(this._super.bind(this));
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
const ActionMenus = require('web.ActionMenus');
|
||||
const DropdownMenuItem = require('web.DropdownMenuItem');
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {string} model
|
||||
* @param {integer} resID
|
||||
* @returns {Promise}
|
||||
* Google drive menu
|
||||
*
|
||||
* This component is actually a set of list items used to enrich the ActionMenus's
|
||||
* "Action" dropdown list (@see ActionMenus). It will fetch
|
||||
* the current user's google drive configuration and set the result as its
|
||||
* items if any.
|
||||
* @extends DropdownMenuItem
|
||||
*/
|
||||
_addGoogleDocItems: function (model, resID) {
|
||||
var self = this;
|
||||
if (!resID) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
var gdoc_item = _.indexOf(_.pluck(self.items.other, 'classname'), 'oe_share_gdoc');
|
||||
if (gdoc_item !== -1) {
|
||||
self.items.other.splice(gdoc_item, 1);
|
||||
}
|
||||
return this._rpc({
|
||||
args: [this.env.model, resID],
|
||||
context: this.env.context,
|
||||
method: 'get_google_drive_config',
|
||||
model: 'google.drive.config',
|
||||
}).then(function (r) {
|
||||
if (!_.isEmpty(r)) {
|
||||
_.each(r, function (res) {
|
||||
var already_there = false;
|
||||
for (var i = 0; i < self.items.other.length; i++) {
|
||||
var item = self.items.other[i];
|
||||
if (item.classname === 'oe_share_gdoc' && item.label.indexOf(res.name) > -1) {
|
||||
already_there = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!already_there) {
|
||||
self._addItems('other', [{
|
||||
callback: self._onGoogleDocItemClicked.bind(self, res.id),
|
||||
classname: 'oe_share_gdoc',
|
||||
config_id: res.id,
|
||||
label: res.name,
|
||||
res_id: resID,
|
||||
res_model: model,
|
||||
}]);
|
||||
}
|
||||
});
|
||||
class GoogleDriveMenu extends DropdownMenuItem {
|
||||
|
||||
async willStart() {
|
||||
if (this.env.view.type === "form" && this.props.activeIds[0]) {
|
||||
this.gdriveItems = await this._getGoogleDocItems();
|
||||
} else {
|
||||
this.gdriveItems = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------
|
||||
// Private
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {integer} configID
|
||||
* @param {integer} resID
|
||||
*/
|
||||
_onGoogleDocItemClicked: function (configID) {
|
||||
var self = this;
|
||||
var resID = this.env.activeIds[0];
|
||||
var domain = [['id', '=', configID]];
|
||||
var fields = ['google_drive_resource_id', 'google_drive_client_id'];
|
||||
this._rpc({
|
||||
args: [domain, fields],
|
||||
method: 'search_read',
|
||||
model: 'google.drive.config',
|
||||
}).then(function (configs) {
|
||||
self._rpc({
|
||||
args: [configID, resID, configs[0].google_drive_resource_id],
|
||||
context: self.env.context,
|
||||
/**
|
||||
* @private
|
||||
* @returns {Promise<Object[]>}
|
||||
*/
|
||||
async _getGoogleDocItems() {
|
||||
const items = await this.rpc({
|
||||
args: [this.env.action.res_model, this.props.activeIds[0]],
|
||||
context: this.props.context,
|
||||
method: 'get_google_drive_config',
|
||||
model: 'google.drive.config',
|
||||
});
|
||||
return items;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Handlers
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {number} itemId
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async _onGoogleDocItemClick(itemId) {
|
||||
const resID = this.props.activeIds[0];
|
||||
const domain = [['id', '=', itemId]];
|
||||
const fields = ['google_drive_resource_id', 'google_drive_client_id'];
|
||||
const configs = await this.rpc({
|
||||
args: [domain, fields],
|
||||
method: 'search_read',
|
||||
model: 'google.drive.config',
|
||||
});
|
||||
const url = await this.rpc({
|
||||
args: [itemId, resID, configs[0].google_drive_resource_id],
|
||||
context: this.props.context,
|
||||
method: 'get_google_drive_url',
|
||||
model: 'google.drive.config',
|
||||
}).then(function (url) {
|
||||
if (url){
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
if (url) {
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
}
|
||||
}
|
||||
GoogleDriveMenu.props = {
|
||||
activeIds: Array,
|
||||
context: Object,
|
||||
};
|
||||
GoogleDriveMenu.template = 'GoogleDriveMenu';
|
||||
|
||||
});
|
||||
ActionMenus.registry.add('google-drive-menu', {
|
||||
Component: GoogleDriveMenu,
|
||||
getProps(parentProps) {
|
||||
return {
|
||||
activeIds: parentProps.activeIds,
|
||||
context: parentProps.context,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
return Sidebar;
|
||||
return GoogleDriveMenu;
|
||||
});
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<templates>
|
||||
<t t-name="GoogleDriveMenu" owl="1">
|
||||
<li>
|
||||
<ul class="o_embed_menu">
|
||||
<li t-foreach="gdriveItems" t-as="gdriveItem" t-key="gdriveItem.id"
|
||||
role="menuitem"
|
||||
class="o_menu_item oe_share_gdoc_item dropdown-item"
|
||||
>
|
||||
<a href="#" t-esc="gdriveItem.name" t-on-click.prevent="_onGoogleDocItemClick(gdriveItem.id)"/>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -1,102 +1,63 @@
|
||||
odoo.define('board.AddToGoogleSpreadsheetMenu', function (require) {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
var ActionManager = require('web.ActionManager');
|
||||
var core = require('web.core');
|
||||
var data = require('web.data');
|
||||
var Domain = require('web.Domain');
|
||||
var favorites_submenus_registry = require('web.favorites_submenus_registry');
|
||||
var pyUtils = require('web.py_utils');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
var QWeb = core.qweb;
|
||||
|
||||
var AddToGoogleSpreadsheetMenu = Widget.extend({
|
||||
events: _.extend({}, Widget.prototype.events, {
|
||||
'click .add_to_spreadsheet': '_onAddToSpreadsheetClick',
|
||||
}),
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} params
|
||||
* @param {Object} params.action an ir.actions description
|
||||
*/
|
||||
init: function (parent, params) {
|
||||
this._super(parent);
|
||||
this.action = params.action;
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
if (this.action.type === 'ir.actions.act_window') {
|
||||
this._render();
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
const Domain = require('web.Domain');
|
||||
const DropdownMenuItem = require('web.DropdownMenuItem');
|
||||
const FavoriteMenu = require('web.FavoriteMenu');
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_addToSpreadsheet: function () {
|
||||
// AAB: trigger_up an event that will be intercepted by the controller,
|
||||
// as soon as the controller is the parent of the control panel
|
||||
var actionManager = this.findAncestor(function (ancestor) {
|
||||
return ancestor instanceof ActionManager;
|
||||
});
|
||||
var controller = actionManager.getCurrentController();
|
||||
var searchQuery;
|
||||
// TO DO: for now the domains in query are evaluated.
|
||||
// This should be changed I think.
|
||||
this.trigger_up('get_search_query', {
|
||||
callback: function (query) {
|
||||
searchQuery = query;
|
||||
}
|
||||
});
|
||||
var modelName = this.action.res_model;
|
||||
var list_view = _.findWhere(controller.widget.actionViews, {type: 'list'});
|
||||
var list_view_id = list_view ? list_view.viewID : false;
|
||||
var domain = searchQuery.domain;
|
||||
var groupBys = pyUtils.eval('groupbys', searchQuery.groupBys).join(" ");
|
||||
var ds = new data.DataSet(this, 'google.drive.config');
|
||||
|
||||
ds.call('set_spreadsheet', [modelName, Domain.prototype.arrayToString(domain), groupBys, list_view_id])
|
||||
.then(function (res) {
|
||||
if (res.url){
|
||||
window.open(res.url, '_blank');
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Renders the `SearchView.addtogooglespreadsheet` template.
|
||||
* 'Add to Google spreadsheet' menu
|
||||
*
|
||||
* @private
|
||||
* Component consisting only of a button calling the server to add the current
|
||||
* view to the user's spreadsheet configuration.
|
||||
* This component is only available in actions of type 'ir.actions.act_window'.
|
||||
* @extends DropdownMenuItem
|
||||
*/
|
||||
_render: function () {
|
||||
var $el = QWeb.render('SearchView.addtogooglespreadsheet', {widget: this});
|
||||
this._replaceElement($el);
|
||||
},
|
||||
class AddToGoogleSpreadsheetMenu extends DropdownMenuItem {
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {jQueryEvent} event
|
||||
*/
|
||||
_onAddToSpreadsheetClick: function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this._addToSpreadsheet();
|
||||
},
|
||||
});
|
||||
|
||||
favorites_submenus_registry.add('add_to_google_spreadsheet_menu', AddToGoogleSpreadsheetMenu, 20);
|
||||
|
||||
return AddToGoogleSpreadsheetMenu;
|
||||
//---------------------------------------------------------------------
|
||||
// Handlers
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
async _onAddToSpreadsheet() {
|
||||
const searchQuery = this.env.controlPanelModel.getQuery();
|
||||
const listView = this.env.action.views.find(view => view.type === 'list');
|
||||
const modelName = this.env.action.res_model;
|
||||
const domain = Domain.prototype.arrayToString(searchQuery.domain);
|
||||
const groupBys = searchQuery.groupBy.join(" ");
|
||||
const listViewId = listView ? listView.viewID : false;
|
||||
const result = await this.rpc({
|
||||
model: 'google.drive.config',
|
||||
method: 'set_spreadsheet',
|
||||
args: [modelName, domain, groupBys, listViewId],
|
||||
});
|
||||
if (result.url) {
|
||||
// According to MDN doc, one should not use _blank as title.
|
||||
// todo: find a good name for the new window
|
||||
window.open(result.url, '_blank');
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Static
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @param {Object} env
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static shouldBeDisplayed(env) {
|
||||
return env.action.type === 'ir.actions.act_window';
|
||||
}
|
||||
}
|
||||
|
||||
AddToGoogleSpreadsheetMenu.props = {};
|
||||
AddToGoogleSpreadsheetMenu.template = 'AddToGoogleSpreadsheetMenu';
|
||||
|
||||
FavoriteMenu.registry.add('add-to-google-spreadsheet-menu', AddToGoogleSpreadsheetMenu, 20);
|
||||
|
||||
return AddToGoogleSpreadsheetMenu;
|
||||
});
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<template>
|
||||
<div t-name="SearchView.addtogooglespreadsheet">
|
||||
<a class="add_to_spreadsheet dropdown-item">Add to Google Spreadsheet</a>
|
||||
</div>
|
||||
<t t-name="AddToGoogleSpreadsheetMenu" owl="1">
|
||||
<li class="o_menu_item o_add_to_spreadsheet" role="menuitem">
|
||||
<a class="dropdown-item" href="#" t-on-click.prevent="_onAddToSpreadsheet">Add to Google Spreadsheet</a>
|
||||
</li>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
odoo.define('mail.CustomFilterItem', function (require) {
|
||||
"use strict";
|
||||
|
||||
const CustomFilterItem = require('web.CustomFilterItem');
|
||||
const utils = require('web.utils');
|
||||
|
||||
utils.patch(CustomFilterItem, 'mail.CustomFilterItem', {
|
||||
|
||||
/**
|
||||
* With the `mail` module installed, we want to filter out some of the
|
||||
* available fields in 'Add custom filter' menu (@see CustomFilterItem).
|
||||
* @override
|
||||
*/
|
||||
_validateField(field) {
|
||||
return this._super(...arguments) &&
|
||||
field.relation !== 'mail.message' &&
|
||||
field.name !== 'message_ids';
|
||||
},
|
||||
});
|
||||
|
||||
return CustomFilterItem;
|
||||
});
|
||||
@@ -243,7 +243,6 @@ var Discuss = AbstractAction.extend({
|
||||
custom_events: _.extend({}, AbstractAction.prototype.custom_events, {
|
||||
discard_extended_composer: '_onDiscardExtendedComposer',
|
||||
message_moderation: '_onMessageModeration',
|
||||
search: '_onSearch',
|
||||
update_moderation_buttons: '_onUpdateModerationButtons',
|
||||
}),
|
||||
events: {
|
||||
@@ -292,7 +291,7 @@ var Discuss = AbstractAction.extend({
|
||||
this._throttledUpdateThreads = _.throttle(
|
||||
this._updateThreads.bind(this), 100, { leading: false });
|
||||
|
||||
this.controlPanelParams.modelName = 'mail.message';
|
||||
this.controlPanelModelConfig.modelName = 'mail.message';
|
||||
this.call('mail_service', 'getMailBus').on('messaging_ready', this, this._onMessagingReady);
|
||||
},
|
||||
/**
|
||||
@@ -313,7 +312,7 @@ var Discuss = AbstractAction.extend({
|
||||
*/
|
||||
do_show: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this._updateControlPanel();
|
||||
this.updateControlPanel();
|
||||
this.action_manager.do_push_state({
|
||||
action: this.action.id,
|
||||
active_id: this._thread.getID(),
|
||||
@@ -332,6 +331,7 @@ var Discuss = AbstractAction.extend({
|
||||
* @override
|
||||
*/
|
||||
on_attach_callback: function () {
|
||||
this._super();
|
||||
this.call('mail_service', 'getMailBus').trigger('discuss_open', true);
|
||||
if (this._thread) {
|
||||
this._threadWidget.scrollToPosition(this._threadsScrolltop[this._thread.getID()]);
|
||||
@@ -342,6 +342,7 @@ var Discuss = AbstractAction.extend({
|
||||
* @override
|
||||
*/
|
||||
on_detach_callback: function () {
|
||||
this._super();
|
||||
this.call('mail_service', 'getMailBus').trigger('discuss_open', false);
|
||||
this._threadsScrolltop[this._thread.getID()] = this._threadWidget.getScrolltop();
|
||||
},
|
||||
@@ -937,9 +938,7 @@ var Discuss = AbstractAction.extend({
|
||||
* @param {integer} threadID a thread with such ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_setThread: function (threadID) {
|
||||
var self = this;
|
||||
|
||||
_setThread: async function (threadID) {
|
||||
this.$('.o_out_of_office').remove();
|
||||
// Store scroll position and composer state of the previous thread
|
||||
this._storeThreadState();
|
||||
@@ -960,36 +959,39 @@ var Discuss = AbstractAction.extend({
|
||||
this._basicComposer.setThread(this._thread);
|
||||
this._extendedComposer.setThread(this._thread);
|
||||
|
||||
return this._fetchAndRenderThread().then(function () {
|
||||
// Mark thread's messages as read and clear needactions
|
||||
if (self._thread.getType() !== 'mailbox') {
|
||||
self._thread.markAsRead();
|
||||
}
|
||||
// Restore scroll position and composer of the new current thread
|
||||
self._restoreThreadState();
|
||||
await this._fetchAndRenderThread();
|
||||
// Mark thread's messages as read and clear needactions
|
||||
if (this._thread.getType() !== 'mailbox') {
|
||||
this._thread.markAsRead();
|
||||
}
|
||||
// Restore scroll position and composer of the new current thread
|
||||
this._restoreThreadState();
|
||||
|
||||
// Update control panel before focusing the composer, otherwise
|
||||
// focus is on the searchview
|
||||
self._setTitle('#' + self._thread.getName());
|
||||
self._updateControlPanel();
|
||||
self._updateControlPanelButtons(self._thread);
|
||||
// Update control panel before focusing the composer, otherwise
|
||||
// focus is on the searchview
|
||||
await this.updateControlPanel({
|
||||
title: '#' + this._thread.getName(),
|
||||
cp_content: {
|
||||
$buttons: this.$buttons,
|
||||
},
|
||||
});
|
||||
this._updateControlPanelButtons(this._thread);
|
||||
|
||||
// Display and focus the adequate composer, and unselect possibly
|
||||
// selected message to prevent sending messages as reply to that
|
||||
// message
|
||||
self._unselectMessage();
|
||||
// Display and focus the adequate composer, and unselect possibly
|
||||
// selected message to prevent sending messages as reply to that
|
||||
// message
|
||||
this._unselectMessage();
|
||||
|
||||
if (self._thread.hasOutOfOffice()) {
|
||||
const $outOfOffice = $(QWeb.render('mail.thread.OutOfOffice', {
|
||||
thread: self._thread
|
||||
}));
|
||||
$outOfOffice.prependTo(self.$('.o_mail_discuss_content'));
|
||||
}
|
||||
if (this._thread.hasOutOfOffice()) {
|
||||
const $outOfOffice = $(QWeb.render('mail.thread.OutOfOffice', {
|
||||
thread: this._thread
|
||||
}));
|
||||
$outOfOffice.prependTo(this.$('.o_mail_discuss_content'));
|
||||
}
|
||||
|
||||
self.action_manager.do_push_state({
|
||||
action: self.action.id,
|
||||
active_id: self._thread.getID(),
|
||||
});
|
||||
this.action_manager.do_push_state({
|
||||
action: this.action.id,
|
||||
active_id: this._thread.getID(),
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -1097,16 +1099,6 @@ var Discuss = AbstractAction.extend({
|
||||
this._updateModerationButtons();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_updateControlPanel: function () {
|
||||
this.updateControlPanel({
|
||||
cp_content: {
|
||||
$buttons: this.$buttons,
|
||||
},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Updates the control panel buttons visibility based on thread type
|
||||
*
|
||||
@@ -1530,11 +1522,10 @@ var Discuss = AbstractAction.extend({
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @param {OdooEvent} ev
|
||||
* @param {Object} searchQuery
|
||||
*/
|
||||
_onSearch: function (ev) {
|
||||
ev.stopPropagation();
|
||||
this.domain = ev.data.domain;
|
||||
_onSearch: function (searchQuery) {
|
||||
this.domain = searchQuery.domain;
|
||||
if (this._thread) {
|
||||
// initially (when _onSearch is called manually), there is no
|
||||
// thread set yet, so don't try to fetch and render the thread as
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
odoo.define('mail.FilterMenu', function (require) {
|
||||
"use strict";
|
||||
|
||||
var FilterMenu = require('web.FilterMenu');
|
||||
|
||||
FilterMenu.include({
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
//remove messages from custom filters
|
||||
this.fields = _.pick(this.fields, function (field, name) {
|
||||
return field.relation !== 'mail.message' && name !== 'message_ids';
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
});
|
||||
@@ -33,13 +33,18 @@ var ActivityController = BasicController.extend({
|
||||
this._super.apply(this, arguments);
|
||||
this.title = params.title;
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Overridden to remove the pager as it makes no sense in this view.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
renderPager: function () {
|
||||
return Promise.resolve();
|
||||
_getPagingInfo: function () {
|
||||
return null;
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
<!-- tools -->
|
||||
<script type="text/javascript" src="/mail/static/src/js/tools/debug_manager.js"></script>
|
||||
<!-- filter menu -->
|
||||
<script type="text/javascript" src="/mail/static/src/js/filter_menu.js"></script>
|
||||
<script type="text/javascript" src="/mail/static/src/js/custom_filter_item.js"></script>
|
||||
<!-- utils -->
|
||||
<script type="text/javascript" src="/mail/static/src/js/utils.js"></script>
|
||||
<script type="text/javascript" src="/mail/static/src/js/activity.js"></script>
|
||||
|
||||
@@ -101,7 +101,7 @@ var MrpBomReport = stock_report_generic.extend({
|
||||
var status = {
|
||||
cp_content: {
|
||||
$buttons: this.$buttonPrint,
|
||||
$searchview_buttons: this.$searchView
|
||||
$searchview: this.$searchView
|
||||
},
|
||||
};
|
||||
return this.updateControlPanel(status);
|
||||
@@ -132,7 +132,7 @@ var MrpBomReport = stock_report_generic.extend({
|
||||
var action = {
|
||||
'type': 'ir.actions.report',
|
||||
'report_type': 'qweb-pdf',
|
||||
'report_name': reportname,
|
||||
'report_name': reportname,
|
||||
'report_file': 'mrp.report_bom_structure',
|
||||
};
|
||||
return this.do_action(action).then(function (){
|
||||
|
||||
@@ -30,7 +30,7 @@ var QtyTagWidget = Widget.extend({
|
||||
|
||||
/**
|
||||
* Add a quantity when add(+) button clicked.
|
||||
*
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_onClickAddQty: function () {
|
||||
@@ -143,9 +143,8 @@ var GeneratePriceList = AbstractAction.extend(StandaloneFieldManagerMixin, {
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
this.controlPanelProps.cp_content = this._renderComponent();
|
||||
return this._super.apply(this, arguments).then(() => {
|
||||
this._renderComponent();
|
||||
this.update_cp();
|
||||
this.$('.o_content').html(this.reportHtml);
|
||||
});
|
||||
},
|
||||
@@ -163,22 +162,6 @@ var GeneratePriceList = AbstractAction.extend(StandaloneFieldManagerMixin, {
|
||||
return _t('Pricelist Report');
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
update_cp: function () {
|
||||
this.updateControlPanel({
|
||||
cp_content: {
|
||||
$buttons: this.$buttonPrint,
|
||||
$searchview_buttons: this.$searchView,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -215,16 +198,17 @@ var GeneratePriceList = AbstractAction.extend(StandaloneFieldManagerMixin, {
|
||||
* @private
|
||||
*/
|
||||
_renderComponent: function () {
|
||||
this.$buttonPrint = $('<button>', {
|
||||
const $buttons = $('<button>', {
|
||||
class: 'btn btn-primary',
|
||||
text: _t("Print"),
|
||||
}).on('click', this._onClickPrint.bind(this));
|
||||
|
||||
this.$searchView = $(QWeb.render('product.report_pricelist_search'));
|
||||
this.many2one.appendTo(this.$searchView.find('.o_pricelist'));
|
||||
const $searchview = $(QWeb.render('product.report_pricelist_search'));
|
||||
this.many2one.appendTo($searchview.find('.o_pricelist'));
|
||||
|
||||
this.qtyTagWidget = new QtyTagWidget(this, this.context.quantities);
|
||||
this.qtyTagWidget.replace(this.$searchView.find('.o_product_qty'));
|
||||
this.qtyTagWidget.replace($searchview.find('.o_product_qty'));
|
||||
return { $buttons, $searchview };
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -28,8 +28,7 @@ var InventoryReportListController = ListController.extend({
|
||||
}
|
||||
var $buttonToDate = $(qweb.render('InventoryReport.Buttons'));
|
||||
$buttonToDate.on('click', this._onOpenWizard.bind(this));
|
||||
|
||||
$buttonToDate.prependTo($node.find('.o_list_buttons'));
|
||||
this.$buttons.prepend($buttonToDate);
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@@ -24,13 +24,24 @@ var ThemePreviewController = FormController.extend({
|
||||
// -------------------------------------------------------------------------
|
||||
// Public
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
renderButtons: function ($node) {
|
||||
var $previewButton = $(qweb.render('website.ThemePreview.Buttons'));
|
||||
$node.html($previewButton);
|
||||
this.$buttons = $(qweb.render('website.ThemePreview.Buttons'));
|
||||
if ($node) {
|
||||
$node.html(this.$buttons);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Overriden to prevent the controller from hiding the buttons
|
||||
* @see FormController
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
updateButtons: function () { },
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -39,16 +50,11 @@ var ThemePreviewController = FormController.extend({
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_updatePager: function () {
|
||||
this._super(...arguments);
|
||||
|
||||
const $buttonSwitch = $(qweb.render('website.ThemePreview.SwitchModeButton'));
|
||||
if (!this.$switcherButton) {
|
||||
$buttonSwitch.appendTo(this.pager.$el);
|
||||
} else {
|
||||
this.$switcherButton.replaceWith($buttonSwitch);
|
||||
}
|
||||
this.$switcherButton = $buttonSwitch;
|
||||
_updateControlPanelProps: async function () {
|
||||
const props = this._super(...arguments);
|
||||
const $switchModeButton = $(qweb.render('website.ThemePreview.SwitchModeButton'));
|
||||
this.controlPanelProps.cp_content.$pager = $switchModeButton;
|
||||
return props;
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@@ -9,9 +9,15 @@ var ThemePreviewKanbanController = KanbanController.extend({
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
this.$el.addClass('o_view_kanban_theme_preview_controller');
|
||||
return this._super.apply(this, arguments);
|
||||
start: async function () {
|
||||
await this._super(...arguments);
|
||||
this.el.classList.add('o_view_kanban_theme_preview_controller');
|
||||
const websiteLink = Object.assign(document.createElement('a'), {
|
||||
className: 'btn btn-secondary ml-3',
|
||||
href: '/',
|
||||
innerHTML: '<i class="fa fa-close"></i>',
|
||||
});
|
||||
this._controlPanelWrapper.el.querySelector('.o_cp_top').appendChild(websiteLink);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -21,21 +27,6 @@ var ThemePreviewKanbanView = KanbanView.extend({
|
||||
config: _.extend({}, KanbanView.prototype.config, {
|
||||
Controller: ThemePreviewKanbanController,
|
||||
}),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private
|
||||
// -------------------------------------------------------------------------
|
||||
/**
|
||||
* @override
|
||||
*
|
||||
*/
|
||||
_createControlPanel: function (parent) {
|
||||
return this._super.apply(this, arguments).then(controlPanel => {
|
||||
var websiteLink = '<a class="btn btn-secondary ml-3" href="/"><i class="fa fa-close"></i></a>';
|
||||
controlPanel.$('div.o_cp_searchview').after(websiteLink);
|
||||
return controlPanel;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
ViewRegistry.add('theme_preview_kanban', ThemePreviewKanbanView);
|
||||
|
||||
Reference in New Issue
Block a user