[IMP] *: remove legacy rpc
This commit removes the files ajax.js and rpc.js then adapts all the
places where their exports were used. For most of the changes, it's a
replace of `this._rpc({...})` by a new `useService("rpc|orm")` like
pattern in the widgets.
closes odoo/odoo#136271
Task: 3439226
Related: odoo/enterprise#47775
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import ajax from "@web/legacy/js/core/ajax";
|
||||
import { jsonrpc } from "@web/core/network/rpc_service";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { stepUtils } from "@web_tour/tour_service/tour_utils";
|
||||
|
||||
@@ -98,7 +98,7 @@ registry.category("web_tour.tours").add('totp_tour_setup', {
|
||||
const $secret = this.$anchor.closest('div').find('[name=secret] span:first-child');
|
||||
const $copyBtn = $secret.find('button');
|
||||
$copyBtn.remove();
|
||||
const token = await ajax.jsonRpc('/totphook', 'call', {
|
||||
const token = await jsonrpc('/totphook', {
|
||||
secret: $secret.text()
|
||||
});
|
||||
helpers.text(token, '[name=code] input');
|
||||
@@ -148,7 +148,7 @@ registry.category("web_tour.tours").add('totp_login_enabled', {
|
||||
// content of the HTML element, not the JS value property. We
|
||||
// could set a class but that's really no better than
|
||||
// procedurally clicking the button after we've set the input.
|
||||
const token = await ajax.jsonRpc('/totphook', 'call', {});
|
||||
const token = await jsonrpc('/totphook');
|
||||
helpers.text(token);
|
||||
helpers.click('button:contains("Log in")');
|
||||
}
|
||||
@@ -185,7 +185,7 @@ registry.category("web_tour.tours").add('totp_login_device', {
|
||||
content: "input code",
|
||||
trigger: 'input[name=totp_token]',
|
||||
async run(helpers) {
|
||||
const token = await ajax.jsonRpc('/totphook', 'call', {})
|
||||
const token = await jsonrpc('/totphook')
|
||||
helpers.text(token);
|
||||
helpers.click('button:contains("Log in")');
|
||||
}
|
||||
|
||||
@@ -139,14 +139,20 @@ publicWidget.registry.TOTPButton = publicWidget.Widget.extend({
|
||||
click: '_onClick',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
this.dialog = this.bindService("dialog");
|
||||
},
|
||||
|
||||
async _onClick(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const w = await handleCheckIdentity(this.proxy('_rpc'), this._rpc({
|
||||
model: 'res.users',
|
||||
method: 'action_totp_enable_wizard',
|
||||
args: [session.user_id]
|
||||
}), (...args) => this.call("dialog", "add", ...args));
|
||||
const w = await handleCheckIdentity(
|
||||
this.orm.call("res.users", "action_totp_enable_wizard", [session.user_id]),
|
||||
this.orm,
|
||||
this.dialog
|
||||
);
|
||||
|
||||
if (!w) {
|
||||
// TOTP probably already enabled, just reload page
|
||||
@@ -156,9 +162,7 @@ publicWidget.registry.TOTPButton = publicWidget.Widget.extend({
|
||||
|
||||
const {res_model: model, res_id: wizard_id} = w;
|
||||
|
||||
const record = await this._rpc({
|
||||
model, method: 'read', args: [wizard_id, []]
|
||||
}).then(ar => ar[0]);
|
||||
const record = await this.orm.read(model, [wizard_id], []).then(ar => ar[0]);
|
||||
|
||||
const doc = new DOMParser().parseFromString(
|
||||
document.getElementById('totp_wizard_view').textContent,
|
||||
@@ -181,15 +185,11 @@ publicWidget.registry.TOTPButton = publicWidget.Widget.extend({
|
||||
}
|
||||
|
||||
try {
|
||||
await this._rpc({
|
||||
model,
|
||||
method: "write",
|
||||
args: [record.id, { code: inputEl.value }],
|
||||
});
|
||||
await this.orm.write(model, [record.id], { code: inputEl.value });
|
||||
await handleCheckIdentity(
|
||||
this.proxy("_rpc"),
|
||||
this._rpc({ model, method: "enable", args: [record.id] }),
|
||||
(...args) => this.call("dialog", "add", ...args)
|
||||
this.orm.call(model, "enable", [record.id]),
|
||||
this.orm,
|
||||
this.dialog
|
||||
);
|
||||
} catch (e) {
|
||||
const errorMessage = (
|
||||
@@ -216,12 +216,18 @@ publicWidget.registry.DisableTOTPButton = publicWidget.Widget.extend({
|
||||
click: '_onClick'
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
this.dialog = this.bindService("dialog");
|
||||
},
|
||||
|
||||
async _onClick(e) {
|
||||
e.preventDefault();
|
||||
await handleCheckIdentity(
|
||||
this.proxy('_rpc'),
|
||||
this._rpc({model: 'res.users', method: 'action_totp_disable', args: [session.user_id]}),
|
||||
(...args) => this.call("dialog", "add", ...args)
|
||||
this.orm.call("res.users", "action_totp_disable", [session.user_id]),
|
||||
this.orm,
|
||||
this.dialog
|
||||
)
|
||||
window.location = window.location;
|
||||
}
|
||||
@@ -235,13 +241,9 @@ publicWidget.registry.RevokeTrustedDeviceButton = publicWidget.Widget.extend({
|
||||
async _onClick(e){
|
||||
e.preventDefault();
|
||||
await handleCheckIdentity(
|
||||
this.proxy('_rpc'),
|
||||
this._rpc({
|
||||
model: 'auth_totp.device',
|
||||
method: 'remove',
|
||||
args: [parseInt(this.el.id)]
|
||||
}),
|
||||
(...args) => this.call("dialog", "add", ...args)
|
||||
this.orm.call("auth_totp.device", "remove", [parseInt(this.el.id)]),
|
||||
this.orm,
|
||||
this.dialog
|
||||
);
|
||||
window.location = window.location;
|
||||
}
|
||||
@@ -252,16 +254,18 @@ publicWidget.registry.RevokeAllTrustedDevicesButton = publicWidget.Widget.extend
|
||||
click: '_onClick'
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
this.dialog = this.bindService("dialog");
|
||||
},
|
||||
|
||||
async _onClick(e){
|
||||
e.preventDefault();
|
||||
await handleCheckIdentity(
|
||||
this.proxy('_rpc'),
|
||||
this._rpc({
|
||||
model: 'res.users',
|
||||
method: 'revoke_all_devices',
|
||||
args: [session.user_id]
|
||||
}),
|
||||
(...args) => this.call("dialog", "add", ...args)
|
||||
this.orm.call("res.users", "revoke_all_devices", [session.user_id]),
|
||||
this.orm,
|
||||
this.dialog
|
||||
);
|
||||
window.location = window.location;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import ajax from "@web/legacy/js/core/ajax";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { jsonrpc } from "@web/core/network/rpc_service";
|
||||
|
||||
registry.category("web_tour.tours").add('totportal_tour_setup', {
|
||||
test: true,
|
||||
@@ -29,7 +29,7 @@ registry.category("web_tour.tours").add('totportal_tour_setup', {
|
||||
trigger: 'a:contains("Cannot scan it?")',
|
||||
run: async function(helpers) {
|
||||
const secret = this.$anchor.closest('div').find('span[name="secret"]').text();
|
||||
const token = await ajax.jsonRpc('/totphook', 'call', {
|
||||
const token = await jsonrpc('/totphook', {
|
||||
secret
|
||||
});
|
||||
helpers._text(helpers._get_action_values('input[name=code]'), token);
|
||||
@@ -65,7 +65,7 @@ registry.category("web_tour.tours").add('totportal_login_enabled', {
|
||||
content: "input code",
|
||||
trigger: 'input[name=totp_token]',
|
||||
run: async function (helpers) {
|
||||
const token = await ajax.jsonRpc('/totphook', 'call', {});
|
||||
const token = await jsonrpc('/totphook');
|
||||
helpers._text(helpers._get_action_values(), token);
|
||||
// FIXME: is there a way to put the button as its own step trigger without
|
||||
// the tour straight blowing through and not waiting for this?
|
||||
|
||||
+2
-3
@@ -30,12 +30,11 @@ import { session } from "@web/session";
|
||||
{
|
||||
async: true,
|
||||
start(env) {
|
||||
let rpcId = 0;
|
||||
return function rpc(route, params = {}, settings) {
|
||||
return function rpc(route, params = {}, settings = {}) {
|
||||
if (!route.match(/^(?:https?:)?\/\//)) {
|
||||
route = session.origin + route;
|
||||
}
|
||||
return jsonrpc(env, rpcId++, route, params, settings);
|
||||
return jsonrpc(route, params, { bus: env.bus, ...settings });
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
@@ -9,6 +9,11 @@ publicWidget.registry.MailGroup = publicWidget.Widget.extend({
|
||||
'click .o_mg_subscribe_btn': '_onSubscribeBtnClick',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -42,13 +47,10 @@ publicWidget.registry.MailGroup = publicWidget.Widget.extend({
|
||||
|
||||
const action = (this.isMember || this.forceUnsubscribe) ? 'unsubscribe' : 'subscribe';
|
||||
|
||||
const response = await this._rpc({
|
||||
route: '/group/' + action,
|
||||
params: {
|
||||
'group_id': this.mailgroupId,
|
||||
'email': email,
|
||||
'token': this.token,
|
||||
},
|
||||
const response = await this.rpc('/group/' + action, {
|
||||
'group_id': this.mailgroupId,
|
||||
'email': email,
|
||||
'token': this.token,
|
||||
});
|
||||
|
||||
this.$el.find('.o_mg_alert').remove();
|
||||
|
||||
@@ -10,6 +10,11 @@ publicWidget.registry.MailGroupMessage = publicWidget.Widget.extend({
|
||||
'click button.o_mg_read_more': '_onReadMoreClick',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -63,11 +68,8 @@ publicWidget.registry.MailGroupMessage = publicWidget.Widget.extend({
|
||||
*/
|
||||
_onReadMoreClick: function (ev) {
|
||||
const $link = $(ev.target);
|
||||
this._rpc({
|
||||
route: $link.data('href'),
|
||||
params: {
|
||||
last_displayed_id: $link.data('last-displayed-id'),
|
||||
},
|
||||
this.rpc($link.data('href'), {
|
||||
last_displayed_id: $link.data('last-displayed-id'),
|
||||
}).then(function (data) {
|
||||
if (!data) {
|
||||
return;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import ajax from "@web/legacy/js/core/ajax";
|
||||
import { escape } from "@web/core/utils/strings";
|
||||
import { whenReady } from "@odoo/owl";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { jsonrpc } from "@web/core/network/rpc_service";
|
||||
|
||||
whenReady(() => {
|
||||
var email = $("input[name='email']").val();
|
||||
@@ -13,7 +13,7 @@ whenReady(() => {
|
||||
|
||||
if ($('.o_unsubscribe_form').length) {
|
||||
if (email != '' && email != undefined){
|
||||
ajax.jsonRpc('/mailing/blacklist/check', 'call', {'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'token': token})
|
||||
jsonrpc('/mailing/blacklist/check', {'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'token': token})
|
||||
.then(function (result) {
|
||||
if (result == 'unauthorized'){
|
||||
$('#button_add_blacklist').hide();
|
||||
@@ -67,7 +67,7 @@ whenReady(() => {
|
||||
unchecked_ids[i] = parseInt($(this).val());
|
||||
});
|
||||
|
||||
ajax.jsonRpc('/mailing/list/update', 'call', {'opt_in_ids': checked_ids, 'opt_out_ids': unchecked_ids, 'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'token': token})
|
||||
jsonrpc('/mailing/list/update', {'opt_in_ids': checked_ids, 'opt_out_ids': unchecked_ids, 'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'token': token})
|
||||
.then(function (result) {
|
||||
if (result == 'unauthorized'){
|
||||
$('#subscription_info').text(_t('You are not authorized to do this!'));
|
||||
@@ -94,7 +94,7 @@ whenReady(() => {
|
||||
$('#button_add_blacklist').click(function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
ajax.jsonRpc('/mailing/blacklist/add', 'call', {'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'token': token})
|
||||
jsonrpc('/mailing/blacklist/add', {'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'token': token})
|
||||
.then(function (result) {
|
||||
if (result == 'unauthorized'){
|
||||
$('#subscription_info').text(_t('You are not authorized to do this!'));
|
||||
@@ -126,7 +126,7 @@ whenReady(() => {
|
||||
$('#button_remove_blacklist').click(function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
ajax.jsonRpc('/mailing/blacklist/remove', 'call', {'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'token': token})
|
||||
jsonrpc('/mailing/blacklist/remove', {'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'token': token})
|
||||
.then(function (result) {
|
||||
if (result == 'unauthorized'){
|
||||
$('#subscription_info').text(_t('You are not authorized to do this!'));
|
||||
@@ -161,7 +161,7 @@ whenReady(() => {
|
||||
$('#button_feedback').click(function (e) {
|
||||
var feedback = $("textarea[name='opt_out_feedback']").val();
|
||||
e.preventDefault();
|
||||
ajax.jsonRpc('/mailing/feedback', 'call', {'mailing_id': mailing_id, 'res_id': res_id, 'email': email, 'feedback': feedback, 'token': token})
|
||||
jsonrpc('/mailing/feedback', {'mailing_id': mailing_id, 'res_id': res_id, 'email': email, 'feedback': feedback, 'token': token})
|
||||
.then(function (result) {
|
||||
if (result == 'unauthorized'){
|
||||
$('#subscription_info').text(_t('You are not authorized to do this!'));
|
||||
|
||||
@@ -9,7 +9,6 @@ import { toInline, getCSSRules } from "@web_editor/js/backend/convert_inline";
|
||||
import { loadBundle } from "@web/core/assets";
|
||||
import { renderToElement } from "@web/core/utils/render";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { buildQuery } from "@web/legacy/js/core/rpc";
|
||||
import { HtmlField, htmlField } from "@web_editor/js/backend/html_field";
|
||||
import { MassMailingMobilePreviewDialog } from "./mass_mailing_mobile_preview";
|
||||
import { getRangePosition } from '@web_editor/js/editor/odoo-editor/src/utils/utils';
|
||||
@@ -39,6 +38,7 @@ export class MassMailingHtmlField extends HtmlField {
|
||||
});
|
||||
this.action = useService('action');
|
||||
this.rpc = useService('rpc');
|
||||
this.orm = useService('orm');
|
||||
this.dialog = useService('dialog');
|
||||
|
||||
useRecordObserver((record) => {
|
||||
@@ -217,13 +217,8 @@ export class MassMailingHtmlField extends HtmlField {
|
||||
? [[['mailing_model_id', '=', this.props.record.data.mailing_model_id[0]]]]
|
||||
: [];
|
||||
|
||||
const rpcQuery = buildQuery({
|
||||
model: 'mailing.mailing',
|
||||
method: 'action_fetch_favorites',
|
||||
args: args,
|
||||
})
|
||||
// Templates taken from old mailings
|
||||
const result = await this.rpc(rpcQuery.route, rpcQuery.params);
|
||||
const result = await this.orm.call('mailing.mailing', 'action_fetch_favorites', args);
|
||||
if (status(this) === 'destroyed') return;
|
||||
const templatesParams = result.map(values => {
|
||||
return {
|
||||
@@ -416,13 +411,7 @@ export class MassMailingHtmlField extends HtmlField {
|
||||
const $target = $(ev.currentTarget);
|
||||
const mailingId = $target.data('id');
|
||||
|
||||
const rpcQuery = buildQuery({
|
||||
model: 'mailing.mailing',
|
||||
method: 'action_remove_favorite',
|
||||
args: [mailingId],
|
||||
})
|
||||
const action = await this.rpc(rpcQuery.route, rpcQuery.params);
|
||||
|
||||
const action = await this.orm.call('mailing.mailing', 'action_remove_favorite', [mailingId]);
|
||||
this.action.doAction(action);
|
||||
|
||||
$target.parents('.o_mail_template_preview').remove();
|
||||
|
||||
@@ -96,14 +96,12 @@
|
||||
'web/static/src/legacy/js/libs/bootstrap.js',
|
||||
'web/static/src/legacy/js/libs/jquery.js',
|
||||
'web/static/src/legacy/js/libs/jSignatureCustom.js',
|
||||
'web/static/src/legacy/js/core/ajax.js',
|
||||
'web/static/src/legacy/js/core/bus.js',
|
||||
'web/static/src/legacy/js/core/class.js',
|
||||
'web/static/src/legacy/js/core/dialog.js',
|
||||
'web/static/src/legacy/xml/dialog.xml',
|
||||
'web/static/src/legacy/js/core/dom.js',
|
||||
'web/static/src/legacy/js/core/mixins.js',
|
||||
'web/static/src/legacy/js/core/rpc.js',
|
||||
'web/static/src/legacy/js/core/service_mixins.js',
|
||||
'web/static/src/legacy/js/core/time.js',
|
||||
'web/static/src/legacy/js/core/widget.js',
|
||||
|
||||
@@ -17,6 +17,15 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
|
||||
|
||||
// #=== WIDGET LIFECYCLE ===#
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -76,11 +85,11 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
|
||||
|
||||
const linkedRadio = document.getElementById(ev.currentTarget.dataset['linkedRadio']);
|
||||
const tokenId = this._getPaymentOptionId(linkedRadio);
|
||||
this._rpc({
|
||||
model: 'payment.token',
|
||||
method: 'get_linked_records_info',
|
||||
args: [tokenId],
|
||||
}).then(linkedRecordsInfo => {
|
||||
this.orm.call(
|
||||
'payment.token',
|
||||
'get_linked_records_info',
|
||||
[tokenId],
|
||||
).then(linkedRecordsInfo => {
|
||||
this._challengeTokenDeletion(tokenId, linkedRecordsInfo);
|
||||
}).guardedCatch(error => {
|
||||
error.event.preventDefault();
|
||||
@@ -342,12 +351,9 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
|
||||
* @return {void}
|
||||
*/
|
||||
async _assignToken(tokenId) {
|
||||
this._rpc({
|
||||
route: this.paymentContext['assignTokenRoute'],
|
||||
params: {
|
||||
'token_id': tokenId,
|
||||
'access_token': this.paymentContext['accessToken'],
|
||||
}
|
||||
this.rpc(this.paymentContext['assignTokenRoute'], {
|
||||
'token_id': tokenId,
|
||||
'access_token': this.paymentContext['accessToken'],
|
||||
}).then(() => {
|
||||
window.location = this.paymentContext['landingRoute'];
|
||||
}).guardedCatch(error => {
|
||||
@@ -376,10 +382,10 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
|
||||
*/
|
||||
async _initiatePaymentFlow(providerCode, paymentOptionId, paymentMethodCode, flow) {
|
||||
// Create a transaction and retrieve its processing values.
|
||||
this._rpc({
|
||||
route: this.paymentContext['transactionRoute'],
|
||||
params: this._prepareTransactionRouteParams(),
|
||||
}).then(processingValues => {
|
||||
this.rpc(
|
||||
this.paymentContext['transactionRoute'],
|
||||
this._prepareTransactionRouteParams(),
|
||||
).then(processingValues => {
|
||||
if (flow === 'redirect') {
|
||||
this._processRedirectFlow(
|
||||
providerCode, paymentOptionId, paymentMethodCode, processingValues
|
||||
@@ -490,11 +496,8 @@ publicWidget.registry.PaymentForm = publicWidget.Widget.extend({
|
||||
* @return {void}
|
||||
*/
|
||||
_archiveToken(tokenId) {
|
||||
this._rpc({
|
||||
route: '/payment/archive_token',
|
||||
params: {
|
||||
'token_id': tokenId,
|
||||
},
|
||||
this.rpc('/payment/archive_token', {
|
||||
'token_id': tokenId,
|
||||
}).then(() => {
|
||||
browser.location.reload();
|
||||
}).guardedCatch(error => {
|
||||
|
||||
@@ -11,6 +11,11 @@ publicWidget.registry.PaymentPostProcessing = publicWidget.Widget.extend({
|
||||
timeout: 0,
|
||||
pollCount: 0,
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
async start() {
|
||||
this.call('ui', 'block', {
|
||||
'message': _t("We are processing your payment. Please wait."),
|
||||
@@ -24,11 +29,8 @@ publicWidget.registry.PaymentPostProcessing = publicWidget.Widget.extend({
|
||||
setTimeout(() => {
|
||||
// Fetch the post-processing values from the server.
|
||||
const self = this;
|
||||
this._rpc({
|
||||
route: '/payment/status/poll',
|
||||
params: {
|
||||
'csrf_token': odoo.csrf_token,
|
||||
}
|
||||
this.rpc('/payment/status/poll', {
|
||||
'csrf_token': odoo.csrf_token,
|
||||
}).then(postProcessingValues => {
|
||||
let { state, display_message, landing_route } = postProcessingValues;
|
||||
|
||||
|
||||
@@ -50,18 +50,15 @@ paymentForm.include({
|
||||
|
||||
// Create the checkout object if not already done for another payment method.
|
||||
if (!this.adyenCheckout) {
|
||||
await this._rpc({ // Await the RPC to let it create AdyenCheckout before using it.
|
||||
route: '/payment/adyen/payment_methods',
|
||||
params: {
|
||||
'provider_id': providerId,
|
||||
'partner_id': parseInt(this.paymentContext['partnerId']),
|
||||
'amount': this.paymentContext['amount']
|
||||
? parseFloat(this.paymentContext['amount'])
|
||||
: undefined,
|
||||
'currency_id': this.paymentContext['currencyId']
|
||||
? parseInt(this.paymentContext['currencyId'])
|
||||
: undefined,
|
||||
},
|
||||
await this.rpc('/payment/adyen/payment_methods', { // Await the RPC to let it create AdyenCheckout before using it.
|
||||
'provider_id': providerId,
|
||||
'partner_id': parseInt(this.paymentContext['partnerId']),
|
||||
'amount': this.paymentContext['amount']
|
||||
? parseFloat(this.paymentContext['amount'])
|
||||
: undefined,
|
||||
'currency_id': this.paymentContext['currencyId']
|
||||
? parseInt(this.paymentContext['currencyId'])
|
||||
: undefined,
|
||||
}).then(async response => {
|
||||
// Create the Adyen Checkout SDK.
|
||||
const providerState = this._getProviderState(radio);
|
||||
@@ -161,24 +158,21 @@ paymentForm.include({
|
||||
*/
|
||||
_adyenOnSubmit(state, component) {
|
||||
// Create the transaction and retrieve the processing values.
|
||||
this._rpc({
|
||||
route: this.paymentContext['transactionRoute'],
|
||||
params: this._prepareTransactionRouteParams(),
|
||||
}).then(processingValues => {
|
||||
this.rpc(
|
||||
this.paymentContext['transactionRoute'],
|
||||
this._prepareTransactionRouteParams(),
|
||||
).then(processingValues => {
|
||||
component.reference = processingValues.reference; // Store final reference.
|
||||
// Initiate the payment.
|
||||
return this._rpc({
|
||||
route: '/payment/adyen/payments',
|
||||
params: {
|
||||
'provider_id': processingValues.provider_id,
|
||||
'reference': processingValues.reference,
|
||||
'converted_amount': processingValues.converted_amount,
|
||||
'currency_id': processingValues.currency_id,
|
||||
'partner_id': processingValues.partner_id,
|
||||
'payment_method': state.data.paymentMethod,
|
||||
'access_token': processingValues.access_token,
|
||||
'browser_info': state.data.browserInfo,
|
||||
},
|
||||
return this.rpc('/payment/adyen/payments', {
|
||||
'provider_id': processingValues.provider_id,
|
||||
'reference': processingValues.reference,
|
||||
'converted_amount': processingValues.converted_amount,
|
||||
'currency_id': processingValues.currency_id,
|
||||
'partner_id': processingValues.partner_id,
|
||||
'payment_method': state.data.paymentMethod,
|
||||
'access_token': processingValues.access_token,
|
||||
'browser_info': state.data.browserInfo,
|
||||
});
|
||||
}).then(paymentResponse => {
|
||||
if (paymentResponse.action) { // An additional action is required from the shopper.
|
||||
@@ -204,13 +198,10 @@ paymentForm.include({
|
||||
* @return {void}
|
||||
*/
|
||||
_adyenOnSubmitAdditionalDetails(state, component) {
|
||||
this._rpc({
|
||||
route: '/payment/adyen/payments/details',
|
||||
params: {
|
||||
'provider_id': this.paymentContext['providerId'],
|
||||
'reference': component.reference,
|
||||
'payment_details': state.data,
|
||||
},
|
||||
this.rpc('/payment/adyen/payments/details', {
|
||||
'provider_id': this.paymentContext['providerId'],
|
||||
'reference': component.reference,
|
||||
'payment_details': state.data,
|
||||
}).then(paymentDetails => {
|
||||
if (paymentDetails.action) { // Additional action required from the shopper.
|
||||
component.handleAction(paymentDetails.action);
|
||||
|
||||
@@ -138,14 +138,11 @@ paymentForm.include({
|
||||
}
|
||||
|
||||
// Initiate the payment
|
||||
this._rpc({
|
||||
route: '/payment/authorize/payment',
|
||||
params: {
|
||||
'reference': processingValues.reference,
|
||||
'partner_id': processingValues.partner_id,
|
||||
'opaque_data': response.opaqueData,
|
||||
'access_token': processingValues.access_token,
|
||||
}
|
||||
this.rpc('/payment/authorize/payment', {
|
||||
'reference': processingValues.reference,
|
||||
'partner_id': processingValues.partner_id,
|
||||
'opaque_data': response.opaqueData,
|
||||
'access_token': processingValues.access_token,
|
||||
}).then(() => {
|
||||
window.location = '/payment/status';
|
||||
}).guardedCatch((error) => {
|
||||
|
||||
@@ -51,13 +51,10 @@ paymentForm.include({
|
||||
|
||||
const customerInput = document.getElementById('customer_input').value;
|
||||
const simulatedPaymentState = document.getElementById('simulated_payment_state').value;
|
||||
this._rpc({
|
||||
route: '/payment/demo/simulate_payment',
|
||||
params: {
|
||||
'reference': processingValues.reference,
|
||||
'payment_details': customerInput,
|
||||
'simulated_state': simulatedPaymentState,
|
||||
},
|
||||
this.rpc('/payment/demo/simulate_payment', {
|
||||
'reference': processingValues.reference,
|
||||
'payment_details': customerInput,
|
||||
'simulated_state': simulatedPaymentState,
|
||||
}).then(() => {
|
||||
window.location = '/payment/status';
|
||||
}).guardedCatch(error => {
|
||||
|
||||
@@ -6,6 +6,10 @@ import { paymentExpressCheckoutForm } from '@payment/js/express_checkout_form';
|
||||
import { StripeOptions } from '@payment_stripe/js/stripe_options';
|
||||
|
||||
paymentExpressCheckoutForm.include({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the order details to display on the payment form.
|
||||
@@ -123,14 +127,15 @@ paymentExpressCheckoutForm.include({
|
||||
addresses.shipping_option = ev.shippingOption;
|
||||
}
|
||||
// Update the customer addresses on the related document.
|
||||
this.paymentContext.partnerId = parseInt(await this._rpc({
|
||||
route: this.paymentContext['expressCheckoutRoute'], params: addresses,
|
||||
}));
|
||||
this.paymentContext.partnerId = parseInt(await this.rpc(
|
||||
this.paymentContext['expressCheckoutRoute'],
|
||||
addresses,
|
||||
));
|
||||
// Call the transaction route to create the transaction and retrieve the client secret.
|
||||
const { client_secret } = await this._rpc({
|
||||
route: this.paymentContext['transactionRoute'],
|
||||
params: this._prepareTransactionRouteParams(providerData.providerId),
|
||||
});
|
||||
const { client_secret } = await this.rpc(
|
||||
this.paymentContext['transactionRoute'],
|
||||
this._prepareTransactionRouteParams(providerData.providerId),
|
||||
);
|
||||
// Confirm the PaymentIntent without handling eventual next actions (e.g. 3DS).
|
||||
const { paymentIntent, error: confirmError } = await stripeJS.confirmCardPayment(
|
||||
client_secret, {payment_method: ev.paymentMethod.id}, {handleActions: false}
|
||||
@@ -157,9 +162,9 @@ paymentExpressCheckoutForm.include({
|
||||
// shipping address, the shipping options need to be fetched again.
|
||||
paymentRequest.on('shippingaddresschange', async (ev) => {
|
||||
// Call the shipping address update route to fetch the shipping options.
|
||||
const availableCarriers = await this._rpc({
|
||||
route: this.paymentContext['shippingAddressUpdateRoute'],
|
||||
params: {
|
||||
const availableCarriers = await this.rpc(
|
||||
this.paymentContext['shippingAddressUpdateRoute'],
|
||||
{
|
||||
partial_shipping_address: {
|
||||
zip: ev.shippingAddress.postalCode,
|
||||
city: ev.shippingAddress.city,
|
||||
@@ -167,7 +172,7 @@ paymentExpressCheckoutForm.include({
|
||||
state: ev.shippingAddress.region,
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
if (availableCarriers.length === 0) {
|
||||
ev.updateWith({status: 'invalid_shipping_address'});
|
||||
} else {
|
||||
|
||||
@@ -1602,13 +1602,8 @@ export class PosStore extends Reactive {
|
||||
}
|
||||
const payload = ev.data;
|
||||
if (ev.name === "call_service") {
|
||||
let args = payload.args || [];
|
||||
if (payload.service === "ajax" && payload.method === "rpc") {
|
||||
// ajax service uses an extra 'target' argument for rpc
|
||||
args = args.concat(ev.target);
|
||||
}
|
||||
const service = this.env.services[payload.service];
|
||||
const result = service[payload.method].apply(service, args);
|
||||
const result = service[payload.method].apply(service, ev.data.args || []);
|
||||
payload.callback(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,11 @@ publicWidget.registry.portalDetails = publicWidget.Widget.extend({
|
||||
export const PortalHomeCounters = publicWidget.Widget.extend({
|
||||
selector: '.o_portal_my_home',
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -86,11 +91,8 @@ export const PortalHomeCounters = publicWidget.Widget.extend({
|
||||
const countersAlwaysDisplayed = this._getCountersAlwaysDisplayed();
|
||||
|
||||
const proms = [...Array(Math.min(numberRpc, needed.length)).keys()].map(async i => {
|
||||
const documentsCountersData = await this._rpc({
|
||||
route: "/my/counters",
|
||||
params: {
|
||||
counters: needed.slice(i * counterByRpc, (i + 1) * counterByRpc)
|
||||
},
|
||||
const documentsCountersData = await this.rpc("/my/counters", {
|
||||
counters: needed.slice(i * counterByRpc, (i + 1) * counterByRpc)
|
||||
});
|
||||
Object.keys(documentsCountersData).forEach(counterName => {
|
||||
const documentsCounterEl = this.el.querySelector(`[data-placeholder_count='${counterName}']`);
|
||||
|
||||
@@ -37,6 +37,8 @@ var PortalChatter = publicWidget.Widget.extend({
|
||||
this.set('pager', {});
|
||||
this.set('domain', this.options['domain']);
|
||||
this._currentPage = this.options['pager_start'];
|
||||
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -83,10 +85,7 @@ var PortalChatter = publicWidget.Widget.extend({
|
||||
*/
|
||||
messageFetch: function (domain) {
|
||||
var self = this;
|
||||
return this._rpc({
|
||||
route: '/mail/chatter_fetch',
|
||||
params: self._messageFetchPrepareParams(),
|
||||
}).then(function (result) {
|
||||
return this.rpc('/mail/chatter_fetch', self._messageFetchPrepareParams()).then(function (result) {
|
||||
self.set('messages', self.preprocessMessages(result['messages']));
|
||||
self.set('message_count', result['message_count']);
|
||||
return result;
|
||||
@@ -177,10 +176,7 @@ var PortalChatter = publicWidget.Widget.extend({
|
||||
*/
|
||||
_chatterInit: function () {
|
||||
var self = this;
|
||||
return this._rpc({
|
||||
route: '/mail/chatter_init',
|
||||
params: this._messageFetchPrepareParams()
|
||||
}).then(function (result) {
|
||||
return this.rpc('/mail/chatter_init', this._messageFetchPrepareParams()).then(function (result) {
|
||||
self.result = result;
|
||||
self.options = Object.assign(self.options, self.result['options'] || {});
|
||||
return result;
|
||||
@@ -300,12 +296,9 @@ var PortalChatter = publicWidget.Widget.extend({
|
||||
ev.preventDefault();
|
||||
|
||||
var $elem = $(ev.currentTarget);
|
||||
return this._rpc({
|
||||
route: '/mail/update_is_internal',
|
||||
params: {
|
||||
message_id: $elem.data('message-id'),
|
||||
is_internal: ! $elem.data('is-internal'),
|
||||
},
|
||||
return this.rpc('/mail/update_is_internal', {
|
||||
message_id: $elem.data('message-id'),
|
||||
is_internal: ! $elem.data('is-internal'),
|
||||
}).then(function (result) {
|
||||
$elem.data('is-internal', result);
|
||||
if (result === true) {
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { escape } from "@web/core/utils/strings";
|
||||
import ajax from "@web/legacy/js/core/ajax";
|
||||
import core from "@web/legacy/js/services/core";
|
||||
import { renderToElement } from "@web/core/utils/render";
|
||||
import publicWidget from "@web/legacy/js/public/public_widget";
|
||||
import { post } from "@web/core/network/http_service";
|
||||
|
||||
/**
|
||||
* Widget PortalComposer
|
||||
@@ -36,6 +36,7 @@ var PortalComposer = publicWidget.Widget.extend({
|
||||
'res_id': false,
|
||||
}, options || {});
|
||||
this.attachments = [];
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -84,12 +85,9 @@ var PortalComposer = publicWidget.Widget.extend({
|
||||
|
||||
this.$sendButton.prop('disabled', true);
|
||||
|
||||
return this._rpc({
|
||||
route: '/portal/attachment/remove',
|
||||
params: {
|
||||
'attachment_id': attachmentId,
|
||||
'access_token': accessToken,
|
||||
},
|
||||
return this.rpc('/portal/attachment/remove', {
|
||||
'attachment_id': attachmentId,
|
||||
'access_token': accessToken,
|
||||
}).then(function () {
|
||||
self.attachments = self.attachments.filter(attachment => attachment.id !== attachmentId);
|
||||
self._updateAttachments();
|
||||
@@ -117,7 +115,10 @@ var PortalComposer = publicWidget.Widget.extend({
|
||||
return Promise.all([...this.$fileInput[0].files].map((file) => {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var data = self._prepareAttachmentData(file);
|
||||
ajax.post('/portal/attachment/add', data).then(function (attachment) {
|
||||
if (odoo.csrf_token) {
|
||||
data.csrf_token = odoo.csrf_token;
|
||||
}
|
||||
post('/portal/attachment/add', data).then(function (attachment) {
|
||||
attachment.state = 'pending';
|
||||
self.attachments.push(attachment);
|
||||
self._updateAttachments();
|
||||
@@ -195,10 +196,7 @@ var PortalComposer = publicWidget.Widget.extend({
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_chatterPostMessage: async function (route) {
|
||||
const result = await this._rpc({
|
||||
route: route,
|
||||
params: this._prepareMessageData(),
|
||||
});
|
||||
const result = await this.rpc(route, this._prepareMessageData());
|
||||
core.bus.trigger('reload_chatter_content', result);
|
||||
return result;
|
||||
},
|
||||
|
||||
@@ -13,6 +13,12 @@ publicWidget.registry.NewAPIKeyButton = publicWidget.Widget.extend({
|
||||
click: '_onClick'
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
this.dialog = this.bindService("dialog");
|
||||
},
|
||||
|
||||
async _onClick(e){
|
||||
e.preventDefault();
|
||||
// This call is done just so it asks for the password confirmation before starting displaying the
|
||||
@@ -20,11 +26,11 @@ publicWidget.registry.NewAPIKeyButton = publicWidget.Widget.extend({
|
||||
// displaying the wizard.
|
||||
// The result of the call is unused. But it's required to call a method with the decorator `@check_identity`
|
||||
// in order to use `handleCheckIdentity`.
|
||||
await handleCheckIdentity(this.proxy('_rpc'), this._rpc({
|
||||
model: 'res.users',
|
||||
method: 'api_key_wizard',
|
||||
args: [session.user_id],
|
||||
}), (...args) => this.call("dialog", "add", ...args));
|
||||
await handleCheckIdentity(
|
||||
this.orm.call("res.users", "api_key_wizard", [session.user_id]),
|
||||
this.orm,
|
||||
this.dialog
|
||||
);
|
||||
|
||||
this.call("dialog", "add", InputConfirmationDialog, {
|
||||
title: _t("New API Key"),
|
||||
@@ -32,19 +38,11 @@ publicWidget.registry.NewAPIKeyButton = publicWidget.Widget.extend({
|
||||
confirmLabel: _t("Confirm"),
|
||||
confirm: async ({ inputEl }) => {
|
||||
const description = inputEl.value;
|
||||
const wizard_id = await this._rpc({
|
||||
model: "res.users.apikeys.description",
|
||||
method: "create",
|
||||
args: [{ name: description }],
|
||||
});
|
||||
const wizard_id = await this.orm.create("res.users.apikeys.description", [{ name: description }]);
|
||||
const res = await handleCheckIdentity(
|
||||
this.proxy('_rpc'),
|
||||
this._rpc({
|
||||
model: 'res.users.apikeys.description',
|
||||
method: 'make_key',
|
||||
args: [wizard_id],
|
||||
}),
|
||||
(...args) => this.call("dialog", "add", ...args)
|
||||
this.orm.call("res.users.apikeys.description", "make_key", [wizard_id]),
|
||||
this.orm,
|
||||
this.dialog
|
||||
);
|
||||
|
||||
this.call("dialog", "add", ConfirmationDialog, {
|
||||
@@ -67,16 +65,18 @@ publicWidget.registry.RemoveAPIKeyButton = publicWidget.Widget.extend({
|
||||
click: '_onClick'
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
this.dialog = this.bindService("dialog");
|
||||
},
|
||||
|
||||
async _onClick(e){
|
||||
e.preventDefault();
|
||||
await handleCheckIdentity(
|
||||
this.proxy('_rpc'),
|
||||
this._rpc({
|
||||
model: 'res.users.apikeys',
|
||||
method: 'remove',
|
||||
args: [parseInt(this.el.id)]
|
||||
}),
|
||||
(...args) => this.call("dialog", "add", ...args)
|
||||
this.orm.call("res.users.apikeys", "remove", [parseInt(this.el.id)]),
|
||||
this.orm,
|
||||
this.dialog
|
||||
);
|
||||
window.location = window.location;
|
||||
}
|
||||
@@ -116,12 +116,15 @@ publicWidget.registry.RevokeSessionsButton = publicWidget.Widget.extend({
|
||||
click: '_onClick',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
async _onClick() {
|
||||
const { res_id: checkId } = await this._rpc({
|
||||
model: 'res.users',
|
||||
method: 'api_key_wizard',
|
||||
args: [session.user_id],
|
||||
});
|
||||
const { res_id: checkId } = await this.orm.call("res.users", "api_key_wizard", [
|
||||
session.user_id,
|
||||
]);
|
||||
this.call("dialog", "add", InputConfirmationDialog, {
|
||||
title: _t("Log out from all devices?"),
|
||||
body: renderToMarkup("portal.revoke_all_devices_popup_template"),
|
||||
@@ -132,17 +135,13 @@ publicWidget.registry.RevokeSessionsButton = publicWidget.Widget.extend({
|
||||
return false;
|
||||
}
|
||||
|
||||
await this._rpc({
|
||||
model: "res.users.identitycheck",
|
||||
method: "write",
|
||||
args: [checkId, { password: inputEl.value }],
|
||||
});
|
||||
await this.orm.write("res.users.identitycheck", [checkId], { password: inputEl.value });
|
||||
try {
|
||||
await this._rpc({
|
||||
model: "res.users.identitycheck",
|
||||
method: "revoke_all_devices",
|
||||
args: [checkId],
|
||||
});
|
||||
await this.orm.call(
|
||||
"res.users.identitycheck",
|
||||
"revoke_all_devices",
|
||||
[checkId]
|
||||
);
|
||||
} catch {
|
||||
inputEl.classList.add("is-invalid");
|
||||
inputEl.setCustomValidity(_t("Check failed"));
|
||||
@@ -171,19 +170,19 @@ publicWidget.registry.RevokeSessionsButton = publicWidget.Widget.extend({
|
||||
* Warning: does not in and of itself trigger an identity check, a promise which
|
||||
* never triggers and identity check internally will do nothing of use.
|
||||
*
|
||||
* @param {Function} rpc Widget#_rpc bound do the widget
|
||||
* @param {Promise} wrapped promise to check for an identity check request
|
||||
* @param {Function} addDialog add a dialog to the dialog service
|
||||
* @param {Function} ormService bound do the widget
|
||||
* @param {Function} dialogService dialog service
|
||||
* @returns {Promise} result of the original call
|
||||
*/
|
||||
export async function handleCheckIdentity(rpc, wrapped, addDialog) {
|
||||
export async function handleCheckIdentity(wrapped, ormService, dialogService) {
|
||||
return wrapped.then((r) => {
|
||||
if (!(r.type === "ir.actions.act_window" && r.res_model === "res.users.identitycheck")) {
|
||||
return r;
|
||||
}
|
||||
const checkId = r.res_id;
|
||||
return new Promise((resolve) => {
|
||||
addDialog(InputConfirmationDialog, {
|
||||
dialogService.add(InputConfirmationDialog, {
|
||||
title: _t("Security Control"),
|
||||
body: renderToMarkup("portal.identitycheck"),
|
||||
confirmLabel: _t("Confirm Password"),
|
||||
@@ -193,17 +192,9 @@ export async function handleCheckIdentity(rpc, wrapped, addDialog) {
|
||||
return false;
|
||||
}
|
||||
let result;
|
||||
await rpc({
|
||||
model: "res.users.identitycheck",
|
||||
method: "write",
|
||||
args: [checkId, { password: inputEl.value }],
|
||||
});
|
||||
await ormService.write("res.users.identitycheck", [checkId], { password: inputEl.value });
|
||||
try {
|
||||
result = await rpc({
|
||||
model: "res.users.identitycheck",
|
||||
method: "run_check",
|
||||
args: [checkId],
|
||||
});
|
||||
result = await ormService.call("res.users.identitycheck", "run_check", [checkId]);
|
||||
} catch {
|
||||
inputEl.classList.add("is-invalid");
|
||||
inputEl.setCustomValidity(_t("Check failed"));
|
||||
|
||||
@@ -43,6 +43,8 @@ var SignatureForm = publicWidget.Widget.extend({
|
||||
|
||||
this.nameAndSignature = new NameAndSignature(this,
|
||||
options.nameAndSignatureOptions || {});
|
||||
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
/**
|
||||
* Overridden to get the DOM elements
|
||||
@@ -107,13 +109,13 @@ var SignatureForm = publicWidget.Widget.extend({
|
||||
var name = this.nameAndSignature.getName();
|
||||
var signature = this.nameAndSignature.getSignatureImage()[1];
|
||||
|
||||
return this._rpc({
|
||||
route: this.callUrl,
|
||||
params: Object.assign(this.rpcParams, {
|
||||
return this.rpc(
|
||||
this.callUrl,
|
||||
Object.assign(this.rpcParams, {
|
||||
'name': name,
|
||||
'signature': signature,
|
||||
}),
|
||||
}).then(function (data) {
|
||||
})
|
||||
).then(function (data) {
|
||||
if (data.error) {
|
||||
self.$('.o_portal_sign_error_msg').remove();
|
||||
self.$controls.prepend(renderToElement('portal.portal_signature_error', {widget: data}));
|
||||
|
||||
@@ -293,12 +293,9 @@ PortalChatter.include({
|
||||
var messageIndex = $source.data("mes_index");
|
||||
var ratingId = this.messages[messageIndex].rating.id;
|
||||
|
||||
this._rpc({
|
||||
route: '/website/rating/comment',
|
||||
params: {
|
||||
"rating_id": ratingId,
|
||||
"publisher_comment": '' // Empty publisher comment means no comment
|
||||
}
|
||||
this.rpc('/website/rating/comment', {
|
||||
"rating_id": ratingId,
|
||||
"publisher_comment": '' // Empty publisher comment means no comment
|
||||
}).then(function (res) {
|
||||
self.messages[messageIndex].rating = self._preprocessCommentData(res, messageIndex);
|
||||
self._getCommentButton($source).removeClass("d-none");
|
||||
@@ -318,12 +315,9 @@ PortalChatter.include({
|
||||
var comment = this._getCommentTextarea($source).val();
|
||||
var ratingId = this.messages[messageIndex].rating.id;
|
||||
|
||||
this._rpc({
|
||||
route: '/website/rating/comment',
|
||||
params: {
|
||||
"rating_id": ratingId,
|
||||
"publisher_comment": comment
|
||||
}
|
||||
this.rpc('/website/rating/comment', {
|
||||
"rating_id": ratingId,
|
||||
"publisher_comment": comment
|
||||
}).then(function (res) {
|
||||
|
||||
// Modify the related message
|
||||
|
||||
@@ -146,14 +146,12 @@
|
||||
'web/static/src/legacy/js/libs/bootstrap.js',
|
||||
'web/static/src/legacy/js/libs/jquery.js',
|
||||
'web/static/src/legacy/js/libs/jSignatureCustom.js',
|
||||
'web/static/src/legacy/js/core/ajax.js',
|
||||
'web/static/src/legacy/js/core/bus.js',
|
||||
'web/static/src/legacy/js/core/class.js',
|
||||
'web/static/src/legacy/js/core/dialog.js',
|
||||
'web/static/src/legacy/xml/dialog.xml',
|
||||
'web/static/src/legacy/js/core/dom.js',
|
||||
'web/static/src/legacy/js/core/mixins.js',
|
||||
'web/static/src/legacy/js/core/rpc.js',
|
||||
'web/static/src/legacy/js/core/service_mixins.js',
|
||||
'web/static/src/legacy/js/core/time.js',
|
||||
'web/static/src/legacy/js/core/widget.js',
|
||||
|
||||
@@ -3,16 +3,17 @@ import PublicWidget from "@web/legacy/js/public/public_widget";
|
||||
|
||||
export const PurchaseDatePicker = PublicWidget.Widget.extend({
|
||||
selector: ".o-purchase-datetimepicker",
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
start() {
|
||||
this.call("datetime_picker", "create", {
|
||||
target: this.el,
|
||||
onChange: (newDate) => {
|
||||
const { accessToken, orderId, lineId } = this.el.dataset;
|
||||
this._rpc({
|
||||
route: `/my/purchase/${orderId}/update?access_token=${accessToken}`,
|
||||
params: {
|
||||
[lineId]: newDate.toISODate(),
|
||||
},
|
||||
this.rpc(`/my/purchase/${orderId}/update?access_token=${accessToken}`, {
|
||||
[lineId]: newDate.toISODate(),
|
||||
});
|
||||
},
|
||||
pickerProps: {
|
||||
|
||||
@@ -10,6 +10,11 @@ publicWidget.registry.SaleUpdateLineButton = publicWidget.Widget.extend({
|
||||
'change .js_quantity': '_onChangeOptionQuantity',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -28,10 +33,7 @@ publicWidget.registry.SaleUpdateLineButton = publicWidget.Widget.extend({
|
||||
* @return {Deferred}
|
||||
*/
|
||||
_callUpdateLineRoute(order_id, params) {
|
||||
return this._rpc({
|
||||
route: "/my/orders/" + order_id + "/update_line_dict",
|
||||
params: params,
|
||||
});
|
||||
return this.rpc("/my/orders/" + order_id + "/update_line_dict", params);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -98,10 +100,10 @@ publicWidget.registry.SaleUpdateLineButton = publicWidget.Widget.extend({
|
||||
// to avoid double click on link with href.
|
||||
$target.css('pointer-events', 'none');
|
||||
|
||||
this._rpc({
|
||||
route: "/my/orders/" + self.orderDetail.orderId + "/add_option/" + $target.data('optionId'),
|
||||
params: {access_token: self.orderDetail.token}
|
||||
}).then((data) => {
|
||||
this.rpc(
|
||||
"/my/orders/" + self.orderDetail.orderId + "/add_option/" + $target.data('optionId'),
|
||||
{access_token: self.orderDetail.token}
|
||||
).then((data) => {
|
||||
this._refreshOrderUI(data);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -39,6 +39,11 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend(SurveyPreloa
|
||||
// Widget
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -326,9 +331,9 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend(SurveyPreloa
|
||||
this.preventEnterSubmit = false;
|
||||
this.readonly = false;
|
||||
this._nextScreen(
|
||||
this._rpc({
|
||||
route: `/survey/next_question/${this.options.surveyToken}/${this.options.answerToken}`,
|
||||
}), {
|
||||
this.rpc(
|
||||
`/survey/next_question/${this.options.surveyToken}/${this.options.answerToken}`
|
||||
), {
|
||||
initTimer: true,
|
||||
isFinish: nextPageEvent.type === 'end_session'
|
||||
}
|
||||
@@ -392,10 +397,10 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend(SurveyPreloa
|
||||
this.readonly = true;
|
||||
}
|
||||
|
||||
var submitPromise = self._rpc({
|
||||
route: `${route}/${self.options.surveyToken}/${self.options.answerToken}`,
|
||||
params: params,
|
||||
});
|
||||
var submitPromise = self.rpc(
|
||||
`${route}/${self.options.surveyToken}/${self.options.answerToken}`,
|
||||
params
|
||||
);
|
||||
this._nextScreen(submitPromise, options);
|
||||
},
|
||||
|
||||
|
||||
@@ -14,6 +14,12 @@ publicWidget.registry.SurveyQuickAccessWidget = publicWidget.Widget.extend({
|
||||
// Widget
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -35,11 +41,11 @@ publicWidget.registry.SurveyQuickAccessWidget = publicWidget.Widget.extend({
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
_onLaunchSessionClick: async function () {
|
||||
const sessionResult = await this._rpc({
|
||||
'model': 'survey.survey',
|
||||
'method': 'action_start_session',
|
||||
'args': [[this.$('.o_survey_launch_session').data('surveyId')]],
|
||||
});
|
||||
const sessionResult = await this.orm.call(
|
||||
"survey.survey",
|
||||
"action_start_session",
|
||||
[[this.$(".o_survey_launch_session").data("surveyId")]]
|
||||
);
|
||||
window.location = sessionResult.url;
|
||||
},
|
||||
|
||||
@@ -69,9 +75,7 @@ publicWidget.registry.SurveyQuickAccessWidget = publicWidget.Widget.extend({
|
||||
self.$('.o_survey_session_error_invalid_code').removeClass('d-none');
|
||||
return;
|
||||
}
|
||||
this._rpc({
|
||||
route: `/survey/check_session_code/${sessionCodeInputVal}`,
|
||||
}).then(function (response) {
|
||||
this.rpc(`/survey/check_session_code/${sessionCodeInputVal}`).then(function (response) {
|
||||
if (response.survey_url) {
|
||||
window.location = response.survey_url;
|
||||
} else {
|
||||
|
||||
@@ -13,6 +13,8 @@ publicWidget.registry.SurveySessionLeaderboard = publicWidget.Widget.extend({
|
||||
this.BAR_MIN_WIDTH = '3rem';
|
||||
this.BAR_WIDTH = '24rem';
|
||||
this.BAR_HEIGHT = '3.8rem';
|
||||
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -43,9 +45,7 @@ publicWidget.registry.SurveySessionLeaderboard = publicWidget.Widget.extend({
|
||||
self.$('.o_survey_session_leaderboard_container').empty();
|
||||
}
|
||||
|
||||
var leaderboardPromise = this._rpc({
|
||||
route: `/survey/session/leaderboard/${this.surveyAccessToken}`,
|
||||
});
|
||||
var leaderboardPromise = this.rpc(`/survey/session/leaderboard/${this.surveyAccessToken}`);
|
||||
|
||||
Promise.all([fadeOutPromise, leaderboardPromise]).then(function (results) {
|
||||
var leaderboardResults = results[1];
|
||||
|
||||
@@ -26,6 +26,12 @@ publicWidget.registry.SurveySessionManage = publicWidget.Widget.extend(SurveyPre
|
||||
'click .o_survey_session_close': '_onEndSessionClick',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* Overridden to set a few properties that come from the python template rendering.
|
||||
*
|
||||
@@ -243,11 +249,11 @@ publicWidget.registry.SurveySessionManage = publicWidget.Widget.extend(SurveyPre
|
||||
var self = this;
|
||||
ev.preventDefault();
|
||||
|
||||
this._rpc({
|
||||
model: 'survey.survey',
|
||||
method: 'action_end_session',
|
||||
args: [[this.surveyId]],
|
||||
}).then(function () {
|
||||
this.orm.call(
|
||||
"survey.survey",
|
||||
"action_end_session",
|
||||
[[this.surveyId]]
|
||||
).then(function () {
|
||||
if ($(ev.currentTarget).data('showResults')) {
|
||||
document.location = `/survey/results/${encodeURIComponent(self.surveyId)}`;
|
||||
} else {
|
||||
@@ -354,12 +360,12 @@ publicWidget.registry.SurveySessionManage = publicWidget.Widget.extend(SurveyPre
|
||||
delete this.resultsRefreshInterval;
|
||||
}
|
||||
|
||||
var nextQuestionPromise = this._rpc({
|
||||
route: `/survey/session/next_question/${self.surveyAccessToken}`,
|
||||
params: {
|
||||
var nextQuestionPromise = this.rpc(
|
||||
`/survey/session/next_question/${self.surveyAccessToken}`,
|
||||
{
|
||||
'go_back': goBack,
|
||||
}
|
||||
}).then(function (result) {
|
||||
).then(function (result) {
|
||||
self.nextQuestion = result;
|
||||
if (self.refreshBackground && result.background_image_url) {
|
||||
return self._preloadBackground(result.background_image_url);
|
||||
@@ -467,9 +473,9 @@ publicWidget.registry.SurveySessionManage = publicWidget.Widget.extend(SurveyPre
|
||||
_refreshResults: function () {
|
||||
var self = this;
|
||||
|
||||
return this._rpc({
|
||||
route: `/survey/session/results/${self.surveyAccessToken}`,
|
||||
}).then(function (questionResults) {
|
||||
return this.rpc(
|
||||
`/survey/session/results/${self.surveyAccessToken}`
|
||||
).then(function (questionResults) {
|
||||
if (questionResults) {
|
||||
self.attendeesCount = questionResults.attendees_count;
|
||||
|
||||
@@ -507,11 +513,10 @@ publicWidget.registry.SurveySessionManage = publicWidget.Widget.extend(SurveyPre
|
||||
_refreshAttendeesCount: function () {
|
||||
var self = this;
|
||||
|
||||
return self._rpc({
|
||||
model: 'survey.survey',
|
||||
method: 'read',
|
||||
args: [[self.surveyId], ['session_answer_count']],
|
||||
}).then(function (result) {
|
||||
return self.orm.read(
|
||||
"survey.survey",
|
||||
[[self.surveyId], ['session_answer_count']]
|
||||
).then(function (result) {
|
||||
if (result && result.length === 1){
|
||||
self.$('.o_survey_session_attendees_count').text(
|
||||
result[0].session_answer_count
|
||||
|
||||
@@ -8,6 +8,11 @@ publicWidget.registry.testError = publicWidget.Widget.extend({
|
||||
'click a': '_onRpcErrorClick',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Handlers
|
||||
//----------------------------------------------------------------------
|
||||
@@ -21,8 +26,6 @@ publicWidget.registry.testError = publicWidget.Widget.extend({
|
||||
_onRpcErrorClick: function (ev) {
|
||||
ev.preventDefault();
|
||||
var $link = $(ev.currentTarget);
|
||||
return this._rpc({
|
||||
route: $link.attr('href'),
|
||||
});
|
||||
return this.rpc($link.attr('href'));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import ajax from "@web/legacy/js/core/ajax";
|
||||
import { jsonrpc } from "@web/core/network/rpc_service";
|
||||
|
||||
registry.category("web_tour.tours").add('test_json_auth', {
|
||||
test: true,
|
||||
steps: () => [{
|
||||
trigger: 'body',
|
||||
run: async function () {
|
||||
await ajax.rpc('/test_get_dbname').then( function (result){
|
||||
return ajax.rpc("/web/session/authenticate", {
|
||||
await jsonrpc('/test_get_dbname').then( function (result){
|
||||
return jsonrpc("/web/session/authenticate", {
|
||||
db: result,
|
||||
login: 'admin',
|
||||
password: 'admin'
|
||||
|
||||
@@ -97,14 +97,12 @@ This module provides the core of the Odoo Web Client.
|
||||
'web/static/src/legacy/js/libs/bootstrap.js',
|
||||
'web/static/src/legacy/js/libs/jquery.js',
|
||||
'web/static/src/legacy/js/libs/jSignatureCustom.js',
|
||||
'web/static/src/legacy/js/core/ajax.js',
|
||||
'web/static/src/legacy/js/core/bus.js',
|
||||
'web/static/src/legacy/js/core/class.js',
|
||||
'web/static/src/legacy/js/core/dialog.js',
|
||||
'web/static/src/legacy/xml/dialog.xml',
|
||||
'web/static/src/legacy/js/core/dom.js',
|
||||
'web/static/src/legacy/js/core/mixins.js',
|
||||
'web/static/src/legacy/js/core/rpc.js',
|
||||
'web/static/src/legacy/js/core/service_mixins.js',
|
||||
'web/static/src/legacy/js/core/time.js',
|
||||
'web/static/src/legacy/js/core/widget.js',
|
||||
@@ -234,14 +232,12 @@ This module provides the core of the Odoo Web Client.
|
||||
'web/static/src/legacy/js/libs/bootstrap.js',
|
||||
'web/static/src/legacy/js/libs/jquery.js',
|
||||
'web/static/src/legacy/js/libs/jSignatureCustom.js',
|
||||
'web/static/src/legacy/js/core/ajax.js',
|
||||
'web/static/src/legacy/js/core/bus.js',
|
||||
'web/static/src/legacy/js/core/class.js',
|
||||
'web/static/src/legacy/js/core/dialog.js',
|
||||
'web/static/src/legacy/xml/dialog.xml',
|
||||
'web/static/src/legacy/js/core/dom.js',
|
||||
'web/static/src/legacy/js/core/mixins.js',
|
||||
'web/static/src/legacy/js/core/rpc.js',
|
||||
'web/static/src/legacy/js/core/service_mixins.js',
|
||||
'web/static/src/legacy/js/core/time.js',
|
||||
'web/static/src/legacy/js/core/widget.js',
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { browser } from "@web/core/browser/browser";
|
||||
import { registry } from "../registry";
|
||||
|
||||
function checkResponseStatus(response) {
|
||||
@@ -8,35 +9,28 @@ function checkResponseStatus(response) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function get(route, readMethod = "json") {
|
||||
const response = await browser.fetch(route, { method: "GET" });
|
||||
checkResponseStatus(response);
|
||||
return response[readMethod]();
|
||||
}
|
||||
|
||||
export async function post(route, params = {}, readMethod = "json") {
|
||||
const formData = new FormData();
|
||||
for (const key in params) {
|
||||
formData.append(key, params[key]);
|
||||
}
|
||||
const response = await browser.fetch(route, {
|
||||
body: formData,
|
||||
method: "POST",
|
||||
});
|
||||
checkResponseStatus(response);
|
||||
return response[readMethod]();
|
||||
}
|
||||
|
||||
export const httpService = {
|
||||
start() {
|
||||
return {
|
||||
async get(route, readMethod = "json") {
|
||||
const response = await fetch(route, { method: "GET" });
|
||||
checkResponseStatus(response);
|
||||
return response[readMethod]();
|
||||
},
|
||||
async post(route, params = {}, readMethod = "json") {
|
||||
const formData = new FormData();
|
||||
for (const key in params) {
|
||||
const value = params[key];
|
||||
if (Array.isArray(value) && value.length) {
|
||||
for (const val of value) {
|
||||
formData.append(key, val);
|
||||
}
|
||||
} else {
|
||||
formData.append(key, value);
|
||||
}
|
||||
}
|
||||
const info = {
|
||||
body: formData,
|
||||
method: "POST",
|
||||
};
|
||||
const response = await fetch(route, info);
|
||||
checkResponseStatus(response);
|
||||
return response[readMethod]();
|
||||
},
|
||||
};
|
||||
return { get, post };
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -43,11 +43,12 @@ export function makeErrorFromResponse(reponse) {
|
||||
return error;
|
||||
}
|
||||
|
||||
export function jsonrpc(env, rpcId, url, params, settings = {}) {
|
||||
const bus = env.bus;
|
||||
let rpcId = 0;
|
||||
export function jsonrpc(url, params = {}, settings = {}) {
|
||||
const bus = settings.bus;
|
||||
const XHR = browser.XMLHttpRequest;
|
||||
const data = {
|
||||
id: rpcId,
|
||||
id: rpcId++,
|
||||
jsonrpc: "2.0",
|
||||
method: "call",
|
||||
params: params,
|
||||
@@ -56,13 +57,13 @@ export function jsonrpc(env, rpcId, url, params, settings = {}) {
|
||||
let rejectFn;
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
rejectFn = reject;
|
||||
bus.trigger("RPC:REQUEST", { data, settings });
|
||||
bus?.trigger("RPC:REQUEST", { data, settings });
|
||||
// handle success
|
||||
request.addEventListener("load", () => {
|
||||
if (request.status === 502) {
|
||||
// If Odoo is behind another server (eg.: nginx)
|
||||
const error = new ConnectionLostError(url);
|
||||
bus.trigger("RPC:RESPONSE", { data, settings, error });
|
||||
bus?.trigger("RPC:RESPONSE", { data, settings, error });
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
@@ -73,22 +74,22 @@ export function jsonrpc(env, rpcId, url, params, settings = {}) {
|
||||
// the response isn't json parsable, which probably means that the rpc request could
|
||||
// not be handled by the server, e.g. PoolError('The Connection Pool Is Full')
|
||||
const error = new ConnectionLostError(url);
|
||||
bus.trigger("RPC:RESPONSE", { data, settings, error });
|
||||
bus?.trigger("RPC:RESPONSE", { data, settings, error });
|
||||
return reject(error);
|
||||
}
|
||||
const { error: responseError, result: responseResult } = params;
|
||||
if (!params.error) {
|
||||
bus.trigger("RPC:RESPONSE", { data, settings, result: params.result });
|
||||
bus?.trigger("RPC:RESPONSE", { data, settings, result: params.result });
|
||||
return resolve(responseResult);
|
||||
}
|
||||
const error = makeErrorFromResponse(responseError);
|
||||
bus.trigger("RPC:RESPONSE", { data, settings, error });
|
||||
bus?.trigger("RPC:RESPONSE", { data, settings, error });
|
||||
reject(error);
|
||||
});
|
||||
// handle failure
|
||||
request.addEventListener("error", () => {
|
||||
const error = new ConnectionLostError(url);
|
||||
bus.trigger("RPC:RESPONSE", { data, settings, error });
|
||||
bus?.trigger("RPC:RESPONSE", { data, settings, error });
|
||||
reject(error);
|
||||
});
|
||||
// configure and send request
|
||||
@@ -105,7 +106,7 @@ export function jsonrpc(env, rpcId, url, params, settings = {}) {
|
||||
request.abort();
|
||||
}
|
||||
const error = new ConnectionAbortedError("XmlHttpRequestError abort");
|
||||
bus.trigger("RPC:RESPONSE", { data, settings, error });
|
||||
bus?.trigger("RPC:RESPONSE", { data, settings, error });
|
||||
if (rejectError) {
|
||||
rejectFn(error);
|
||||
}
|
||||
@@ -119,7 +120,6 @@ export function jsonrpc(env, rpcId, url, params, settings = {}) {
|
||||
export const rpcService = {
|
||||
async: true,
|
||||
start(env) {
|
||||
let rpcId = 0;
|
||||
/**
|
||||
* @param {string} route
|
||||
* @param {Object} params
|
||||
@@ -127,8 +127,8 @@ export const rpcService = {
|
||||
* @param {boolean} settings.silent
|
||||
* @param {XMLHttpRequest} settings.xhr
|
||||
*/
|
||||
return function rpc(route, params = {}, settings) {
|
||||
return jsonrpc(env, rpcId++, route, params, settings);
|
||||
return function rpc(route, params = {}, settings = {}) {
|
||||
return jsonrpc(route, params, { bus: env.bus, ...settings });
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,225 +0,0 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import core from "@web/legacy/js/services/core";
|
||||
import time from "@web/legacy/js/core/time";
|
||||
import { session } from "@web/session";
|
||||
|
||||
import { markup } from "@odoo/owl";
|
||||
|
||||
// Create the final object containing all the functions first to allow monkey
|
||||
// patching them correctly if ever needed.
|
||||
var ajax = {};
|
||||
|
||||
function _genericJsonRpc (fct_name, params, settings, fct) {
|
||||
var shadow = settings.shadow || false;
|
||||
delete settings.shadow;
|
||||
var data = {
|
||||
jsonrpc: "2.0",
|
||||
method: fct_name,
|
||||
params: params,
|
||||
id: Math.floor(Math.random() * 1000 * 1000 * 1000)
|
||||
};
|
||||
|
||||
if (!shadow) {
|
||||
core.bus.trigger('rpc_request', data.id);
|
||||
}
|
||||
|
||||
var xhr = fct(data);
|
||||
var result = xhr.then(function(result) {
|
||||
core.bus.trigger('rpc:result', data, result);
|
||||
if (result.error !== undefined) {
|
||||
console.debug(
|
||||
"Server application error\n",
|
||||
"Error code:", result.error.code, "\n",
|
||||
"Error message:", result.error.message, "\n",
|
||||
"Error data message:\n", result.error.data.message, "\n",
|
||||
"Error data debug:\n", result.error.data.debug
|
||||
);
|
||||
return Promise.reject({type: "server", error: result.error});
|
||||
} else {
|
||||
return result.result;
|
||||
}
|
||||
}, function() {
|
||||
//console.error("JsonRPC communication error", [...arguments]);
|
||||
var reason = {
|
||||
type: 'communication',
|
||||
error: arguments[0],
|
||||
textStatus: arguments[1],
|
||||
errorThrown: arguments[2],
|
||||
};
|
||||
return Promise.reject(reason);
|
||||
});
|
||||
|
||||
var rejection;
|
||||
var promise = new Promise(function (resolve, reject) {
|
||||
rejection = reject;
|
||||
|
||||
result.then(function (result) {
|
||||
if (!shadow) {
|
||||
core.bus.trigger('rpc_response', data.id);
|
||||
}
|
||||
resolve(result);
|
||||
}, function (reason) {
|
||||
var type = reason.type;
|
||||
var error = reason.error;
|
||||
var textStatus = reason.textStatus;
|
||||
var errorThrown = reason.errorThrown;
|
||||
if (type === "server") {
|
||||
if (!shadow) {
|
||||
core.bus.trigger('rpc_response', data.id);
|
||||
}
|
||||
reject({message: error, event: $.Event()});
|
||||
} else {
|
||||
if (!shadow) {
|
||||
core.bus.trigger('rpc_response_failed', data.id);
|
||||
}
|
||||
var nerror = {
|
||||
code: -32098,
|
||||
message: "XmlHttpRequestError " + errorThrown,
|
||||
data: {
|
||||
type: "xhr"+textStatus,
|
||||
debug: error.responseText,
|
||||
objects: [error, errorThrown],
|
||||
arguments: [reason || textStatus]
|
||||
},
|
||||
};
|
||||
reject({message: nerror, event: $.Event()});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// FIXME: jsonp?
|
||||
promise.abort = function () {
|
||||
rejection({
|
||||
message: "XmlHttpRequestError abort",
|
||||
event: $.Event('abort')
|
||||
});
|
||||
|
||||
if (!shadow) {
|
||||
core.bus.trigger('rpc_response');
|
||||
}
|
||||
|
||||
if (xhr.abort) {
|
||||
xhr.abort();
|
||||
}
|
||||
};
|
||||
promise.guardedCatch(function (reason) { // Allow promise user to disable rpc_error call in case of failure
|
||||
setTimeout(function () {
|
||||
// we want to execute this handler after all others (hence
|
||||
// setTimeout) to let the other handlers prevent the event
|
||||
if (!reason.event.isDefaultPrevented()) {
|
||||
core.bus.trigger('rpc_error', reason.message, reason.event);
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
return promise;
|
||||
};
|
||||
|
||||
export function jsonRpc(url, fct_name, params, settings) {
|
||||
settings = settings || {};
|
||||
return _genericJsonRpc(fct_name, params, settings, function(data) {
|
||||
return $.ajax(url, Object.assign({}, settings, {
|
||||
url: url,
|
||||
dataType: 'json',
|
||||
type: 'POST',
|
||||
data: JSON.stringify(data, time.date_to_utc),
|
||||
contentType: 'application/json'
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
// helper function to make a rpc with a function name hardcoded to 'call'
|
||||
function rpc(url, params, settings) {
|
||||
return jsonRpc(url, 'call', params, settings);
|
||||
}
|
||||
|
||||
function post (controller_url, data) {
|
||||
var postData = new FormData();
|
||||
|
||||
$.each(data, function(i,val) {
|
||||
postData.append(i, val);
|
||||
});
|
||||
if (odoo.csrf_token) {
|
||||
postData.append('csrf_token', odoo.csrf_token);
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
$.ajax(controller_url, {
|
||||
data: postData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
type: 'POST'
|
||||
}).then(resolve).fail(reject);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads a template file according to the given xmlId.
|
||||
*
|
||||
* @param {string} [xmlId] - the template xmlId
|
||||
* @param {Object} [context]
|
||||
* additionnal rpc context to be merged with the default one
|
||||
* @param {string} [tplRoute='/web/dataset/call_kw/']
|
||||
* @returns {Deferred} resolved with an object
|
||||
* cssLibs: list of css files
|
||||
* cssContents: list of style tag contents
|
||||
* jsLibs: list of JS files
|
||||
* jsContents: list of script tag contents
|
||||
*/
|
||||
var loadAsset = (function () {
|
||||
var cache = {};
|
||||
|
||||
var load = function loadAsset(xmlId, context, tplRoute = '/web/dataset/call_kw/') {
|
||||
if (cache[xmlId]) {
|
||||
return cache[xmlId];
|
||||
}
|
||||
context = Object.assign({}, session.user_context, context);
|
||||
const params = {
|
||||
args: [xmlId, {
|
||||
debug: !!odoo.debug
|
||||
}],
|
||||
kwargs: {
|
||||
context: context,
|
||||
},
|
||||
};
|
||||
if (tplRoute === '/web/dataset/call_kw/') {
|
||||
Object.assign(params, {
|
||||
model: 'ir.ui.view',
|
||||
method: 'render_public_asset',
|
||||
});
|
||||
}
|
||||
cache[xmlId] = rpc(tplRoute, params).then(function (xml) {
|
||||
var $xml = $(xml);
|
||||
return {
|
||||
cssLibs: $xml.filter('link[href]:not([type="image/x-icon"])').map(function () {
|
||||
return $(this).attr('href');
|
||||
}).get(),
|
||||
cssContents: $xml.filter('style').map(function () {
|
||||
return markup($(this).html());
|
||||
}).get(),
|
||||
jsLibs: $xml.filter('script[src]').map(function () {
|
||||
return $(this).attr('src');
|
||||
}).get(),
|
||||
jsContents: $xml.filter('script:not([src])').map(function () {
|
||||
return markup($(this).html());
|
||||
}).get(),
|
||||
};
|
||||
}).guardedCatch(reason => {
|
||||
reason.event.preventDefault();
|
||||
throw `Unable to render the required templates for the assets to load: ${reason.message.message}`;
|
||||
});
|
||||
return cache[xmlId];
|
||||
};
|
||||
|
||||
return load;
|
||||
})();
|
||||
|
||||
Object.assign(ajax, {
|
||||
jsonRpc: jsonRpc,
|
||||
rpc: rpc,
|
||||
loadAsset: loadAsset,
|
||||
post: post,
|
||||
});
|
||||
|
||||
export default ajax;
|
||||
@@ -1,107 +0,0 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import ajax from "@web/legacy/js/core/ajax";
|
||||
|
||||
const rpc = {
|
||||
/**
|
||||
* Perform a RPC. Please note that this is not the preferred way to do a
|
||||
* rpc if you are in the context of a widget. In that case, you should use
|
||||
* the this._rpc method.
|
||||
*
|
||||
* @param {Object} params @see buildQuery for a description
|
||||
* @param {Object} options
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
query: function (params, options) {
|
||||
var query = rpc.buildQuery(params);
|
||||
return ajax.rpc(query.route, query.params, options);
|
||||
},
|
||||
/**
|
||||
* @param {Object} options
|
||||
* @param {any[]} [options.args]
|
||||
* @param {Object} [options.context]
|
||||
* @param {any[]} [options.domain]
|
||||
* @param {string[]} [options.fields]
|
||||
* @param {string[]} [options.groupBy]
|
||||
* @param {Object} [options.kwargs]
|
||||
* @param {integer|false} [options.limit]
|
||||
* @param {string} [options.method]
|
||||
* @param {string} [options.model]
|
||||
* @param {integer} [options.offset]
|
||||
* @param {string[]} [options.orderBy]
|
||||
* @param {Object} [options.params]
|
||||
* @param {string} [options.route]
|
||||
* @returns {Object} with 2 keys: route and params
|
||||
*/
|
||||
buildQuery: function (options) {
|
||||
var route;
|
||||
var params = options.params || {};
|
||||
var orderBy;
|
||||
if (options.route) {
|
||||
route = options.route;
|
||||
} else if (options.model && options.method) {
|
||||
route = '/web/dataset/call_kw/' + options.model + '/' + options.method;
|
||||
}
|
||||
if (options.method) {
|
||||
params.args = options.args || [];
|
||||
params.model = options.model;
|
||||
params.method = options.method;
|
||||
params.kwargs = Object.assign(params.kwargs || {}, options.kwargs);
|
||||
params.kwargs.context = options.context || params.context || params.kwargs.context;
|
||||
}
|
||||
|
||||
if (options.method === 'read_group' || options.method === 'web_read_group') {
|
||||
if (!(params.args && params.args[0] !== undefined)) {
|
||||
params.kwargs.domain = options.domain || params.domain || params.kwargs.domain || [];
|
||||
}
|
||||
if (!(params.args && params.args[1] !== undefined)) {
|
||||
params.kwargs.fields = options.fields || params.fields || params.kwargs.fields || [];
|
||||
}
|
||||
if (!(params.args && params.args[2] !== undefined)) {
|
||||
params.kwargs.groupby = options.groupBy || params.groupBy || params.kwargs.groupby || [];
|
||||
}
|
||||
params.kwargs.offset = options.offset || params.offset || params.kwargs.offset;
|
||||
params.kwargs.limit = options.limit || params.limit || params.kwargs.limit;
|
||||
// In kwargs, we look for "orderby" rather than "orderBy" (note the absence of capital B),
|
||||
// since the Python argument to the actual function is "orderby".
|
||||
orderBy = options.orderBy || params.orderBy || params.kwargs.orderby;
|
||||
params.kwargs.orderby = orderBy ? rpc._serializeSort(orderBy) : orderBy;
|
||||
params.kwargs.lazy = 'lazy' in options ? options.lazy : params.lazy;
|
||||
}
|
||||
|
||||
if (options.method === 'search_read') {
|
||||
// call the model method
|
||||
params.kwargs.domain = options.domain || params.domain || params.kwargs.domain;
|
||||
params.kwargs.fields = options.fields || params.fields || params.kwargs.fields;
|
||||
params.kwargs.offset = options.offset || params.offset || params.kwargs.offset;
|
||||
params.kwargs.limit = options.limit || params.limit || params.kwargs.limit;
|
||||
// In kwargs, we look for "order" rather than "orderBy" since the Python
|
||||
// argument to the actual function is "order".
|
||||
orderBy = options.orderBy || params.orderBy || params.kwargs.order;
|
||||
params.kwargs.order = orderBy ? rpc._serializeSort(orderBy) : orderBy;
|
||||
}
|
||||
|
||||
return {
|
||||
route: route,
|
||||
params: JSON.parse(JSON.stringify(params)),
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Helper method, generates a string to describe a ordered by sequence for
|
||||
* SQL.
|
||||
*
|
||||
* For example, [{name: 'foo'}, {name: 'bar', asc: false}] will
|
||||
* be converted into 'foo ASC, bar DESC'
|
||||
*
|
||||
* @param {Object[]} orderBy list of objects {name:..., [asc: ...]}
|
||||
* @returns {string}
|
||||
*/
|
||||
_serializeSort: function (orderBy) {
|
||||
return orderBy
|
||||
.map((order) => order.name + (order.asc !== false ? " ASC" : " DESC"))
|
||||
.join(", ");
|
||||
},
|
||||
};
|
||||
|
||||
export const buildQuery = rpc.buildQuery
|
||||
export default rpc;
|
||||
@@ -1,12 +1,59 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import rpc from "@web/legacy/js/core/rpc";
|
||||
import { SERVICES_METADATA } from "@web/env";
|
||||
import {
|
||||
ConnectionAbortedError,
|
||||
ConnectionLostError,
|
||||
RPCError,
|
||||
} from "@web/core/network/rpc_service";
|
||||
|
||||
function protectMethod(widget, fn) {
|
||||
return function (...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
Promise.resolve(fn.call(this, ...args))
|
||||
.then((result) => {
|
||||
if (!widget.isDestroyed()) {
|
||||
resolve(result);
|
||||
}
|
||||
})
|
||||
.catch((reason) => {
|
||||
if (!widget.isDestroyed()) {
|
||||
if (reason instanceof RPCError || reason instanceof ConnectionLostError) {
|
||||
// we do not reject an error here because we want to pass through
|
||||
// the legacy guardedCatch code
|
||||
reject({ message: reason, event: $.Event(), legacy: true });
|
||||
} else if (reason instanceof ConnectionAbortedError) {
|
||||
reject({ message: reason.message, event: $.Event("abort") });
|
||||
} else {
|
||||
reject(reason);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @mixin
|
||||
* @name ServicesMixin
|
||||
*/
|
||||
var ServicesMixin = {
|
||||
bindService: function (serviceName) {
|
||||
const { services } = owl.Component.env;
|
||||
const service = services[serviceName];
|
||||
if (!service) {
|
||||
throw new Error(`Service ${serviceName} is not available`);
|
||||
}
|
||||
if (serviceName in SERVICES_METADATA) {
|
||||
if (service instanceof Function) {
|
||||
return protectMethod(this, service);
|
||||
} else {
|
||||
const methods = SERVICES_METADATA[serviceName];
|
||||
const result = Object.create(service);
|
||||
for (const method of methods) {
|
||||
result[method] = protectMethod(this, service[method]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return service;
|
||||
},
|
||||
/**
|
||||
* @param {string} service
|
||||
* @param {string} method
|
||||
@@ -25,97 +72,6 @@ var ServicesMixin = {
|
||||
});
|
||||
return result;
|
||||
},
|
||||
/**
|
||||
* Builds and executes RPC query. Returns a promise resolved with
|
||||
* the RPC result.
|
||||
*
|
||||
* @param {string} params either a route or a model
|
||||
* @param {string} options if a model is given, this argument is a method
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_rpc: function (params, options) {
|
||||
var query = rpc.buildQuery(params);
|
||||
var prom = this.call('ajax', 'rpc', query.route, query.params, options, this);
|
||||
if (!prom) {
|
||||
prom = new Promise(function () {});
|
||||
prom.abort = function () {};
|
||||
}
|
||||
var abort = prom.abort ? prom.abort : prom.reject;
|
||||
if (abort) {
|
||||
prom.abort = abort.bind(prom);
|
||||
}
|
||||
return prom;
|
||||
},
|
||||
loadFieldView: function (modelName, context, view_id, view_type, options) {
|
||||
return this.loadViews(modelName, context, [[view_id, view_type]], options).then(function (result) {
|
||||
return result[view_type];
|
||||
});
|
||||
},
|
||||
loadViews: function (modelName, context, views, options) {
|
||||
var self = this;
|
||||
return new Promise(function (resolve) {
|
||||
self.trigger_up('load_views', {
|
||||
modelName: modelName,
|
||||
context: context,
|
||||
views: views,
|
||||
options: options,
|
||||
on_success: resolve,
|
||||
});
|
||||
});
|
||||
},
|
||||
loadFilters: function (modelName, actionId, context) {
|
||||
var self = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
self.trigger_up('load_filters', {
|
||||
modelName: modelName,
|
||||
actionId: actionId,
|
||||
context: context,
|
||||
on_success: resolve,
|
||||
});
|
||||
});
|
||||
},
|
||||
createFilter: function (filter) {
|
||||
var self = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
self.trigger_up('create_filter', {
|
||||
filter: filter,
|
||||
on_success: resolve,
|
||||
});
|
||||
});
|
||||
},
|
||||
deleteFilter: function (filterId) {
|
||||
var self = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
self.trigger_up('delete_filter', {
|
||||
filterId: filterId,
|
||||
on_success: resolve,
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Informs the action manager to do an action. This supposes that the action
|
||||
* manager can be found amongst the ancestors of the current widget.
|
||||
* If that's not the case this method will simply return an unresolved
|
||||
* promise.
|
||||
*
|
||||
* @param {any} action
|
||||
* @param {any} options
|
||||
* @returns {Promise}
|
||||
*/
|
||||
do_action: function (action, options) {
|
||||
var self = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
self.trigger_up('do_action', {
|
||||
action: action,
|
||||
options: options,
|
||||
on_success: resolve,
|
||||
on_fail: (reason) => {
|
||||
reject(reason);
|
||||
return "alreadyThrown"
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Displays a notification.
|
||||
*
|
||||
|
||||
@@ -11,7 +11,6 @@ import lazyloader from "@web/legacy/js/public/lazyloader";
|
||||
import {
|
||||
makeLegacyNotificationService,
|
||||
mapLegacyEnvToWowlEnv,
|
||||
makeLegacyRPCService,
|
||||
createWidgetParent,
|
||||
} from "../../utils";
|
||||
|
||||
@@ -22,7 +21,6 @@ import { browser } from '@web/core/browser/browser';
|
||||
import { jsonrpc } from '@web/core/network/rpc_service';
|
||||
import { renderToString } from "@web/core/utils/render";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { omit } from "@web/core/utils/objects";
|
||||
import { App, whenReady } from "@odoo/owl";
|
||||
import { getOrigin } from '@web/core/utils/urls';
|
||||
|
||||
@@ -227,37 +225,9 @@ export const PublicRoot = publicWidget.RootWidget.extend({
|
||||
* @param {OdooEvent} event
|
||||
*/
|
||||
_onCallService: function (ev) {
|
||||
function _computeContext(context, noContextKeys) {
|
||||
context = Object.assign({}, this._getContext(), context);
|
||||
if (noContextKeys) {
|
||||
context = omit(context, ...noContextKeys);
|
||||
}
|
||||
return JSON.parse(JSON.stringify(context));
|
||||
}
|
||||
|
||||
const payload = ev.data;
|
||||
let args = payload.args || [];
|
||||
if (payload.service === 'ajax' && payload.method === 'rpc') {
|
||||
// ajax service uses an extra 'target' argument for rpc
|
||||
args = args.concat(ev.target);
|
||||
|
||||
var route = args[0];
|
||||
if (String(route).startsWith("/web/dataset/call_kw/")) {
|
||||
var params = args[1];
|
||||
var options = args[2];
|
||||
var noContextKeys;
|
||||
if (options) {
|
||||
noContextKeys = options.noContextKeys;
|
||||
args[2] = omit(options, 'noContextKeys');
|
||||
}
|
||||
params.kwargs.context = _computeContext.call(this, params.kwargs.context, noContextKeys);
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
const service = this.env.services[payload.service];
|
||||
const result = service[payload.method].apply(service, args);
|
||||
const result = service[payload.method].apply(service, payload.args || []);
|
||||
payload.callback(result);
|
||||
ev.stopPropagation();
|
||||
},
|
||||
@@ -358,7 +328,6 @@ export async function createPublicRoot(RootWidget) {
|
||||
await lazyloader.allScriptsLoaded;
|
||||
// add a bunch of mapping services that will redirect service calls from the legacy env
|
||||
// to the wowl env
|
||||
serviceRegistry.add("legacy_rpc", makeLegacyRPCService(legacyEnv));
|
||||
serviceRegistry.add("legacy_notification", makeLegacyNotificationService(legacyEnv));
|
||||
const wowlToLegacyServiceMappers = registry.category('wowlToLegacyServiceMappers').getEntries();
|
||||
for (const [legacyServiceName, wowlToLegacyServiceMapper] of wowlToLegacyServiceMappers) {
|
||||
@@ -379,12 +348,17 @@ export async function createPublicRoot(RootWidget) {
|
||||
serviceRegistry.add("rpc", {
|
||||
async: true,
|
||||
start(env) {
|
||||
let rpcId = 0;
|
||||
return function rpc(route, params = {}, settings) {
|
||||
return function rpc(route, params = {}, settings = {}) {
|
||||
if (!route.match(/^(?:https?:)?\/\//)) {
|
||||
route = baseUrl + route;
|
||||
}
|
||||
return jsonrpc(env, rpcId++, route, params, settings);
|
||||
if (String(route).includes("/web/dataset/call_kw/")) {
|
||||
params.kwargs.context = {
|
||||
...publicRoot._getContext(),
|
||||
...params.kwargs.context,
|
||||
};
|
||||
}
|
||||
return jsonrpc(route, params, { bus: env.bus, ...settings });
|
||||
};
|
||||
},
|
||||
}, { force: true });
|
||||
|
||||
@@ -78,6 +78,7 @@ export var NameAndSignature = Widget.extend({
|
||||
this.drawTimeout = null;
|
||||
this.drawPreviewTimeout = null;
|
||||
this.signatureAreaHidden = false;
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
/**
|
||||
* Loads the fonts.
|
||||
@@ -94,7 +95,7 @@ export var NameAndSignature = Widget.extend({
|
||||
}
|
||||
return Promise.all([
|
||||
this._super.apply(this, arguments),
|
||||
this._rpc({route: '/web/sign/get_fonts/' + this.defaultFont}).then(data => {
|
||||
this.rpc('/web/sign/get_fonts/' + this.defaultFont).then(data => {
|
||||
this.fonts = data;
|
||||
})
|
||||
]);
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
/** @odoo-module alias=web.legacySetup **/
|
||||
|
||||
import { registry } from "../core/registry";
|
||||
import {
|
||||
makeLegacyNotificationService,
|
||||
makeLegacyRPCService,
|
||||
} from "./utils";
|
||||
import { makeLegacyNotificationService } from "./utils";
|
||||
import { makeLegacyActionManagerService } from "./backend_utils";
|
||||
import legacyEnv from "@web/legacy/js/env";
|
||||
import { templates } from "@web/core/assets";
|
||||
@@ -25,7 +22,6 @@ export const legacySetupProm = new Promise((resolve) => {
|
||||
serviceRegistry.add("legacy_action_manager", legacyActionManagerService);
|
||||
// add a service to redirect rpc events triggered on the bus in the
|
||||
// legacy env on the bus in the wowl env
|
||||
serviceRegistry.add("legacy_rpc", makeLegacyRPCService(legacyEnv));
|
||||
serviceRegistry.add("legacy_notification", makeLegacyNotificationService(legacyEnv));
|
||||
const wowlToLegacyServiceMappers = registry.category("wowlToLegacyServiceMappers").getEntries();
|
||||
for (const [legacyServiceName, wowlToLegacyServiceMapper] of wowlToLegacyServiceMappers) {
|
||||
|
||||
@@ -16,11 +16,6 @@ import {
|
||||
} from "@odoo/owl";
|
||||
import { templates } from "@web/core/assets";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import {
|
||||
ConnectionAbortedError,
|
||||
ConnectionLostError,
|
||||
RPCError,
|
||||
} from "@web/core/network/rpc_service";
|
||||
|
||||
export const wowlServicesSymbol = Symbol("wowlServices");
|
||||
|
||||
@@ -116,46 +111,6 @@ export function makeLegacyNotificationService(legacyEnv) {
|
||||
};
|
||||
}
|
||||
|
||||
export function makeLegacyRPC(wowlRPC) {
|
||||
return function rpc(route, args, options, target) {
|
||||
let rpcPromise = null;
|
||||
const promise = new Promise(function (resolve, reject) {
|
||||
rpcPromise = wowlRPC(route, args, options);
|
||||
rpcPromise
|
||||
.then(function (result) {
|
||||
if (!target.isDestroyed()) {
|
||||
resolve(result);
|
||||
}
|
||||
})
|
||||
.catch(function (reason) {
|
||||
if (!target.isDestroyed()) {
|
||||
if (reason instanceof RPCError || reason instanceof ConnectionLostError) {
|
||||
// we do not reject an error here because we want to pass through
|
||||
// the legacy guardedCatch code
|
||||
reject({ message: reason, event: $.Event(), legacy: true });
|
||||
} else if (reason instanceof ConnectionAbortedError) {
|
||||
reject({ message: reason.message, event: $.Event("abort") });
|
||||
} else {
|
||||
reject(reason);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
promise.abort = rpcPromise.abort.bind(rpcPromise);
|
||||
return promise;
|
||||
};
|
||||
}
|
||||
|
||||
export function makeLegacyRPCService(legacyEnv) {
|
||||
return {
|
||||
dependencies: ["rpc"],
|
||||
start(_, { rpc: wowlRPC }) {
|
||||
const rpc = makeLegacyRPC(wowlRPC);
|
||||
legacyEnv.services.ajax = { rpc };
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This hook allows legacy owl Components to use services coming from the wowl env.
|
||||
* @param {string} serviceName
|
||||
@@ -175,13 +130,8 @@ export function createWidgetParent(env) {
|
||||
env,
|
||||
_trigger_up: (ev) => {
|
||||
if (ev.name === "call_service") {
|
||||
let args = ev.data.args || [];
|
||||
if (ev.data.service === "ajax" && ev.data.method === "rpc") {
|
||||
// ajax service uses an extra 'target' argument for rpc
|
||||
args = args.concat(ev.target);
|
||||
}
|
||||
const service = env.services[ev.data.service];
|
||||
const result = service[ev.data.method].apply(service, args);
|
||||
const result = service[ev.data.method].apply(service, ev.data.args || []);
|
||||
ev.data.callback(result);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import testUtils from "@web/../tests/legacy/helpers/test_utils";
|
||||
import Widget from "@web/legacy/js/core/widget";
|
||||
|
||||
QUnit.module('core', {}, function () {
|
||||
|
||||
QUnit.module('mixins');
|
||||
|
||||
QUnit.test('perform a do_action properly', function (assert) {
|
||||
assert.expect(3);
|
||||
var done = assert.async();
|
||||
|
||||
var widget = new Widget();
|
||||
|
||||
testUtils.mock.intercept(widget, 'do_action', function (event) {
|
||||
assert.strictEqual(event.data.action, 'test.some_action_id',
|
||||
"should have sent proper action name");
|
||||
assert.deepEqual(event.data.options, {clear_breadcrumbs: true},
|
||||
"should have sent proper options");
|
||||
event.data.on_success();
|
||||
});
|
||||
|
||||
widget.do_action('test.some_action_id', {clear_breadcrumbs: true}).then(function () {
|
||||
assert.ok(true, 'deferred should have been resolved');
|
||||
widget.destroy();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,277 +0,0 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import rpc from "@web/legacy/js/core/rpc";
|
||||
|
||||
QUnit.module('core', {}, function () {
|
||||
|
||||
QUnit.module('RPC Builder');
|
||||
|
||||
QUnit.test('basic rpc (route)', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var query = rpc.buildQuery({
|
||||
route: '/my/route',
|
||||
});
|
||||
assert.strictEqual(query.route, '/my/route', "should have the proper route");
|
||||
});
|
||||
|
||||
QUnit.test('rpc on route with parameters', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var query = rpc.buildQuery({
|
||||
route: '/my/route',
|
||||
params: {hey: 'there', model: 'test'},
|
||||
});
|
||||
|
||||
assert.deepEqual(query.params, {hey: 'there', model: 'test'},
|
||||
"should transfer the proper parameters");
|
||||
});
|
||||
|
||||
QUnit.test('basic rpc, with no context', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'test',
|
||||
kwargs: {},
|
||||
});
|
||||
assert.notOk(query.params.kwargs.context,
|
||||
"does not automatically add a context");
|
||||
});
|
||||
|
||||
QUnit.test('basic rpc, with context', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'test',
|
||||
context: {a: 1},
|
||||
});
|
||||
|
||||
assert.deepEqual(query.params.kwargs.context, {a: 1},
|
||||
"properly transfer the context");
|
||||
});
|
||||
|
||||
QUnit.test('basic rpc, with context, part 2', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'test',
|
||||
kwargs: {context: {a: 1}},
|
||||
});
|
||||
|
||||
assert.deepEqual(query.params.kwargs.context, {a: 1},
|
||||
"properly transfer the context");
|
||||
|
||||
});
|
||||
|
||||
QUnit.test('basic rpc (method of model)', function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'test',
|
||||
kwargs: {context: {a: 1}},
|
||||
});
|
||||
|
||||
assert.strictEqual(query.route, '/web/dataset/call_kw/partner/test',
|
||||
"should call the proper route");
|
||||
assert.strictEqual(query.params.model, 'partner',
|
||||
"should correctly specify the model");
|
||||
assert.strictEqual(query.params.method, 'test',
|
||||
"should correctly specify the method");
|
||||
});
|
||||
|
||||
QUnit.test('rpc with args and kwargs', function (assert) {
|
||||
assert.expect(4);
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'test',
|
||||
args: ['arg1', 2],
|
||||
kwargs: {k: 78},
|
||||
});
|
||||
|
||||
assert.strictEqual(query.route, '/web/dataset/call_kw/partner/test',
|
||||
"should call the proper route");
|
||||
assert.strictEqual(query.params.args[0], 'arg1',
|
||||
"should call with correct args");
|
||||
assert.strictEqual(query.params.args[1], 2,
|
||||
"should call with correct args");
|
||||
assert.strictEqual(query.params.kwargs.k, 78,
|
||||
"should call with correct kargs");
|
||||
});
|
||||
|
||||
QUnit.test('search_read method', function (assert) {
|
||||
assert.expect(1);
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'search_read',
|
||||
domain: ['a', '=', 1],
|
||||
fields: ['name'],
|
||||
limit: 32,
|
||||
offset: 2,
|
||||
orderBy: [{name: 'yop', asc: true}, {name: 'aa', asc: false}],
|
||||
});
|
||||
assert.deepEqual(query.params, {
|
||||
args: [],
|
||||
kwargs: {
|
||||
domain: ['a', '=', 1],
|
||||
fields: ['name'],
|
||||
offset: 2,
|
||||
limit: 32,
|
||||
order: 'yop ASC, aa DESC'
|
||||
},
|
||||
method: 'search_read',
|
||||
model: 'partner'
|
||||
}, "should have correct kwargs");
|
||||
});
|
||||
|
||||
QUnit.test('search_read with args', function (assert) {
|
||||
assert.expect(1);
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'search_read',
|
||||
args: [
|
||||
['a', '=', 1],
|
||||
['name'],
|
||||
2,
|
||||
32,
|
||||
'yop ASC, aa DESC',
|
||||
]
|
||||
});
|
||||
assert.deepEqual(query.params, {
|
||||
args: [['a', '=', 1], ['name'], 2, 32, 'yop ASC, aa DESC'],
|
||||
kwargs: {},
|
||||
method: 'search_read',
|
||||
model: 'partner'
|
||||
}, "should have correct args");
|
||||
});
|
||||
|
||||
QUnit.test('read_group', function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'read_group',
|
||||
domain: ['a', '=', 1],
|
||||
fields: ['name'],
|
||||
groupBy: ['product_id'],
|
||||
context: {abc: 'def'},
|
||||
lazy: true,
|
||||
});
|
||||
|
||||
assert.deepEqual(query.params, {
|
||||
args: [],
|
||||
kwargs: {
|
||||
context: {abc: 'def'},
|
||||
domain: ['a', '=', 1],
|
||||
fields: ['name'],
|
||||
groupby: ['product_id'],
|
||||
lazy: true,
|
||||
},
|
||||
method: 'read_group',
|
||||
model: 'partner',
|
||||
}, "should have correct args");
|
||||
assert.equal(query.route, '/web/dataset/call_kw/partner/read_group',
|
||||
"should call correct route");
|
||||
});
|
||||
|
||||
QUnit.test('read_group with kwargs', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'read_group',
|
||||
domain: ['a', '=', 1],
|
||||
fields: ['name'],
|
||||
groupBy: ['product_id'],
|
||||
lazy: false,
|
||||
kwargs: {context: {abc: 'def'}}
|
||||
});
|
||||
|
||||
assert.deepEqual(query.params, {
|
||||
args: [],
|
||||
kwargs: {
|
||||
context: {abc: 'def'},
|
||||
domain: ['a', '=', 1],
|
||||
fields: ['name'],
|
||||
groupby: ['product_id'],
|
||||
lazy: false,
|
||||
},
|
||||
method: 'read_group',
|
||||
model: 'partner',
|
||||
}, "should have correct args");
|
||||
});
|
||||
|
||||
QUnit.test('read_group with no domain, nor fields', function (assert) {
|
||||
assert.expect(7);
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'read_group',
|
||||
});
|
||||
|
||||
assert.deepEqual(query.params.kwargs.domain, [], "should have [] as default domain");
|
||||
assert.deepEqual(query.params.kwargs.fields, [], "should have false as default fields");
|
||||
assert.deepEqual(query.params.kwargs.groupby, [], "should have false as default groupby");
|
||||
assert.deepEqual(query.params.kwargs.offset, undefined, "should not enforce a default value for offst");
|
||||
assert.deepEqual(query.params.kwargs.limit, undefined, "should not enforce a default value for limit");
|
||||
assert.deepEqual(query.params.kwargs.orderby, undefined, "should not enforce a default value for orderby");
|
||||
assert.deepEqual(query.params.kwargs.lazy, undefined, "should not enforce a default value for lazy");
|
||||
});
|
||||
|
||||
QUnit.test('read_group with args and kwargs', function (assert) {
|
||||
assert.expect(9);
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'read_group',
|
||||
kwargs: {
|
||||
domain: ['name', '=', 'saucisse'],
|
||||
fields: ['category_id'],
|
||||
groupby: ['country_id'],
|
||||
},
|
||||
});
|
||||
|
||||
assert.deepEqual(query.params.kwargs.domain, ['name', '=', 'saucisse'], "should have ['name', '=', 'saucisse'] category_id as default domain");
|
||||
assert.deepEqual(query.params.kwargs.fields, ['category_id'], "should have category_id as default fields");
|
||||
assert.deepEqual(query.params.kwargs.groupby, ['country_id'], "should have country_id as default groupby");
|
||||
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'read_group',
|
||||
args: [['name', '=', 'saucisse']],
|
||||
kwargs: {
|
||||
fields: ['category_id'],
|
||||
groupby: ['country_id'],
|
||||
},
|
||||
});
|
||||
|
||||
assert.deepEqual(query.params.kwargs.domain, undefined, "should not enforce a default value for domain");
|
||||
assert.deepEqual(query.params.kwargs.fields, ['category_id'], "should have category_id as default fields");
|
||||
assert.deepEqual(query.params.kwargs.groupby, ['country_id'], "should have country_id as default groupby");
|
||||
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'read_group',
|
||||
args: [['name', '=', 'saucisse'], ['category_id'], ['country_id']],
|
||||
});
|
||||
|
||||
assert.deepEqual(query.params.kwargs.domain, undefined, "should not enforce a default value for domain");
|
||||
assert.deepEqual(query.params.kwargs.fields, undefined, "should not enforce a default value for fields");
|
||||
assert.deepEqual(query.params.kwargs.groupby, undefined, "should not enforce a default value for groupby");
|
||||
});
|
||||
|
||||
QUnit.test('search_read with no domain, nor fields', function (assert) {
|
||||
assert.expect(5);
|
||||
var query = rpc.buildQuery({
|
||||
model: 'partner',
|
||||
method: 'search_read',
|
||||
});
|
||||
|
||||
assert.deepEqual(query.params.kwargs.domain, undefined, "should not enforce a default value for domain");
|
||||
assert.deepEqual(query.params.kwargs.fields, undefined, "should not enforce a default value for fields");
|
||||
assert.deepEqual(query.params.kwargs.offset, undefined, "should not enforce a default value for offset");
|
||||
assert.deepEqual(query.params.kwargs.limit, undefined, "should not enforce a default value for limit");
|
||||
assert.deepEqual(query.params.kwargs.order, undefined, "should not enforce a default value for orderby");
|
||||
});
|
||||
});
|
||||
@@ -4,7 +4,8 @@ import Dialog from "@web/legacy/js/core/dialog";
|
||||
import Widget from "@web/legacy/js/core/widget";
|
||||
import testUtils from "@web/../tests/legacy/helpers/test_utils";
|
||||
import { renderToString } from "@web/core/utils/render";
|
||||
import { makeLegacyRPC } from "@web/legacy/utils";
|
||||
import makeTestEnvironment from "../helpers/test_env";
|
||||
import { SERVICES_METADATA } from "@web/env";
|
||||
|
||||
QUnit.module('core', {}, function () {
|
||||
|
||||
@@ -399,31 +400,31 @@ QUnit.module('core', {}, function () {
|
||||
});
|
||||
|
||||
QUnit.test("calling _rpc on destroyed widgets", async function (assert) {
|
||||
assert.expect(3);
|
||||
assert.expect(2);
|
||||
|
||||
const rpc = makeLegacyRPC(() => {
|
||||
SERVICES_METADATA.rpc = true;
|
||||
var def;
|
||||
owl.Component.env = await makeTestEnvironment({}, () => {
|
||||
def = testUtils.makeTestPromise();
|
||||
def.abort = def.reject;
|
||||
return def;
|
||||
});
|
||||
|
||||
var def;
|
||||
var parent = new Widget();
|
||||
testUtils.mock.intercept(parent, 'call_service', function ({ data }) {
|
||||
if (data.service === "ajax" && data.method === "rpc") {
|
||||
data.callback(rpc(...data.args));
|
||||
}
|
||||
const ChildWidget = Widget.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
});
|
||||
var widget = new Widget(parent);
|
||||
var widget = new ChildWidget();
|
||||
|
||||
widget._rpc({route: '/a/route'}).then(function () {
|
||||
widget.rpc('/a/route').then(function () {
|
||||
assert.ok(true, "The ajax call should be resolve");
|
||||
});
|
||||
def.resolve();
|
||||
await testUtils.nextMicrotaskTick();
|
||||
def = null;
|
||||
|
||||
widget._rpc({route: '/a/route'}).then(function () {
|
||||
widget.rpc('/a/route').then(function () {
|
||||
throw Error("Calling _rpc on a destroyed widget should return a " +
|
||||
"promise that remains pending forever");
|
||||
}).catch(function () {
|
||||
@@ -435,19 +436,16 @@ QUnit.module('core', {}, function () {
|
||||
await testUtils.nextMicrotaskTick();
|
||||
def = null;
|
||||
|
||||
widget._rpc({route: '/a/route'}).then(function () {
|
||||
widget.rpc('/a/route').then(function () {
|
||||
throw Error("Calling _rpc on a destroyed widget should return a " +
|
||||
"promise that remains pending forever");
|
||||
}).catch(function () {
|
||||
throw Error("Calling _rpc on a destroyed widget should return a " +
|
||||
"promise that remains pending forever");
|
||||
});
|
||||
assert.ok(!def, "trigger_up is not performed and the call returns a " +
|
||||
"promise that remains pending forever");
|
||||
|
||||
assert.ok(true,
|
||||
"there should be no crash when calling _rpc on a destroyed widget");
|
||||
parent.destroy();
|
||||
});
|
||||
|
||||
QUnit.test("calling do_hide on a widget destroyed before being rendered", async function (assert) {
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
},
|
||||
hotkey: { add: () => () => {} }, // fake service
|
||||
notification: { notify() {} },
|
||||
ajax: { rpc },
|
||||
rpc,
|
||||
ui: { activeElement: document }, // fake service
|
||||
...env.services,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { NameAndSignature } from "@web/legacy/js/widgets/name_and_signature";
|
||||
import testUtils from "@web/../tests/legacy/helpers/test_utils";
|
||||
import makeTestEnvironment from "../helpers/test_env";
|
||||
import { patchWithCleanup } from "@web/../tests/helpers/utils";
|
||||
|
||||
const MockedNameAndSignature = NameAndSignature.extend({
|
||||
events: {
|
||||
@@ -14,14 +15,14 @@
|
||||
|
||||
async function MockedNameAndSignatureGenerator (options) {
|
||||
const parent = $("#qunit-fixture");
|
||||
const mockedNameAndSignature = new MockedNameAndSignature(parent, options);
|
||||
testUtils.mock.intercept(mockedNameAndSignature, 'call_service', function ({ data }) {
|
||||
if (data.service === "ajax" && data.method === "rpc") {
|
||||
if (data.args[0] === "/web/sign/get_fonts/") {
|
||||
data.callback(Promise.resolve());
|
||||
patchWithCleanup(owl.Component, {
|
||||
env: await makeTestEnvironment({}, (route) => {
|
||||
if (route === "/web/sign/get_fonts/") {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
}),
|
||||
});
|
||||
const mockedNameAndSignature = new MockedNameAndSignature(parent, options);
|
||||
await mockedNameAndSignature.appendTo(parent);
|
||||
await mockedNameAndSignature.resetSignature();
|
||||
return mockedNameAndSignature;
|
||||
|
||||
@@ -85,14 +85,12 @@ Odoo Web Editor widget.
|
||||
'web/static/src/legacy/js/libs/bootstrap.js',
|
||||
'web/static/src/legacy/js/libs/jquery.js',
|
||||
'web/static/src/legacy/js/libs/jSignatureCustom.js',
|
||||
'web/static/src/legacy/js/core/ajax.js',
|
||||
'web/static/src/legacy/js/core/bus.js',
|
||||
'web/static/src/legacy/js/core/class.js',
|
||||
'web/static/src/legacy/js/core/dialog.js',
|
||||
'web/static/src/legacy/xml/dialog.xml',
|
||||
'web/static/src/legacy/js/core/dom.js',
|
||||
'web/static/src/legacy/js/core/mixins.js',
|
||||
'web/static/src/legacy/js/core/rpc.js',
|
||||
'web/static/src/legacy/js/core/service_mixins.js',
|
||||
'web/static/src/legacy/js/core/time.js',
|
||||
'web/static/src/legacy/js/core/widget.js',
|
||||
|
||||
@@ -7,7 +7,7 @@ import Widget from "@web/legacy/js/core/widget";
|
||||
import { browser } from "@web/core/browser/browser";
|
||||
import { debounce } from "@web/core/utils/timing";
|
||||
import { sortBy } from "@web/core/utils/arrays";
|
||||
import { pick } from "@web/core/utils/objects";
|
||||
import { omit, pick } from "@web/core/utils/objects";
|
||||
import { AlertDialog, ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
||||
import { markup } from "@odoo/owl";
|
||||
|
||||
@@ -209,6 +209,9 @@ var ViewEditor = Widget.extend({
|
||||
this.views = this.resources.xml;
|
||||
this.scss = this.resources.scss;
|
||||
this.js = this.resources.js;
|
||||
|
||||
this.rpc = this.bindService("rpc");
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
/**
|
||||
* Loads everything the ace library needs to work.
|
||||
@@ -459,6 +462,9 @@ var ViewEditor = Widget.extend({
|
||||
this._showErrorLine(check.error.line, check.error.message, this._getSelectedResource());
|
||||
}
|
||||
},
|
||||
_getContext() {
|
||||
return {};
|
||||
},
|
||||
/**
|
||||
* Returns the currently selected resource data.
|
||||
*
|
||||
@@ -502,17 +508,14 @@ var ViewEditor = Widget.extend({
|
||||
this.js = this.resources.js;
|
||||
|
||||
// Load resources
|
||||
return this._rpc({
|
||||
route: '/web_editor/get_assets_editor_resources',
|
||||
params: {
|
||||
key: this.viewKey,
|
||||
get_views: !this.options.doNotLoadViews,
|
||||
get_scss: !this.options.doNotLoadSCSS,
|
||||
get_js: !this.options.doNotLoadJS,
|
||||
bundles: this.options.includeBundles,
|
||||
bundles_restriction: this.options.filesFilter === 'all' ? [] : this.options.defaultBundlesRestriction,
|
||||
only_user_custom_files: this.options.filesFilter === 'custom',
|
||||
},
|
||||
return this.rpc('/web_editor/get_assets_editor_resources', {
|
||||
key: this.viewKey,
|
||||
get_views: !this.options.doNotLoadViews,
|
||||
get_scss: !this.options.doNotLoadSCSS,
|
||||
get_js: !this.options.doNotLoadJS,
|
||||
bundles: this.options.includeBundles,
|
||||
bundles_restriction: this.options.filesFilter === 'all' ? [] : this.options.defaultBundlesRestriction,
|
||||
only_user_custom_files: this.options.filesFilter === 'custom',
|
||||
}).then((function (resources) {
|
||||
_processViews.call(this, resources.views || []);
|
||||
_processJSorSCSS.call(this, resources.scss || [], 'scss');
|
||||
@@ -600,10 +603,8 @@ var ViewEditor = Widget.extend({
|
||||
return Promise.reject(_t("Reseting views is not supported yet"));
|
||||
} else {
|
||||
var resource = type === 'scss' ? this.scss[resID] : this.js[resID];
|
||||
return this._rpc({
|
||||
model: 'web_editor.assets',
|
||||
method: 'reset_asset',
|
||||
args: [resID, resource.bundle],
|
||||
return this.orm.call("web_editor.assets", "reset_asset", [resID, resource.bundle], {
|
||||
context: this._getContext(),
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -621,11 +622,17 @@ var ViewEditor = Widget.extend({
|
||||
var sessionIdEndsWithJS = String(session.id).endsWith(".js");
|
||||
var bundle = sessionIdEndsWithJS ? this.js[session.id].bundle : this.scss[session.id].bundle;
|
||||
var fileType = sessionIdEndsWithJS ? 'js' : 'scss';
|
||||
return self._rpc({
|
||||
model: 'web_editor.assets',
|
||||
method: 'save_asset',
|
||||
args: [session.id, bundle, session.text, fileType],
|
||||
}).then(function () {
|
||||
return this.orm.call(
|
||||
"web_editor.assets",
|
||||
"save_asset",
|
||||
[
|
||||
session.id,
|
||||
bundle,
|
||||
session.text,
|
||||
fileType,
|
||||
],
|
||||
{ context: this._getContext() }
|
||||
).then(function () {
|
||||
self._toggleDirtyInfo(session.id, fileType, false);
|
||||
});
|
||||
},
|
||||
@@ -714,13 +721,13 @@ var ViewEditor = Widget.extend({
|
||||
_saveView: function (session) {
|
||||
var self = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
self._rpc({
|
||||
model: 'ir.ui.view',
|
||||
method: 'write',
|
||||
args: [[session.id], {arch: session.text}],
|
||||
}, {
|
||||
noContextKeys: 'lang',
|
||||
}).then(function () {
|
||||
self.orm.write(
|
||||
"ir.ui.view",
|
||||
[session.id],
|
||||
{ arch: session.text },
|
||||
{ context: omit(self._getContext(), "lang") }
|
||||
).then(
|
||||
function () {
|
||||
self._toggleDirtyInfo(session.id, 'xml', false);
|
||||
resolve();
|
||||
}, function (source, error) {
|
||||
|
||||
@@ -447,10 +447,7 @@ export async function loadImageInfo(img, rpc, attachmentSrc = '') {
|
||||
return;
|
||||
}
|
||||
|
||||
const {original} = await rpc({
|
||||
route: '/web_editor/get_image_info',
|
||||
params: {src: src.split(/[?#]/)[0]},
|
||||
});
|
||||
const {original} = await rpc('/web_editor/get_image_info', {src: src.split(/[?#]/)[0]});
|
||||
// Check that url is local.
|
||||
const isLocal = original && new URL(original.image_src, window.location.origin).origin === window.location.origin
|
||||
&& !/\/web\/image\/\d+-redirect\//.test(original.image_src);
|
||||
|
||||
@@ -1767,6 +1767,8 @@ var SnippetsMenu = Widget.extend({
|
||||
this.loadingElements = {};
|
||||
this._loadingEffectDisabled = false;
|
||||
this._onClick = this._onClick.bind(this);
|
||||
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -2090,14 +2092,12 @@ var SnippetsMenu = Widget.extend({
|
||||
context.lang = this.options.context.user_lang;
|
||||
context.snippet_lang = this.options.context.lang;
|
||||
}
|
||||
this._defLoadSnippets = this._rpc({
|
||||
model: 'ir.ui.view',
|
||||
method: 'render_public_asset',
|
||||
args: [this.options.snippets, {}],
|
||||
kwargs: {
|
||||
context: context,
|
||||
},
|
||||
}, { shadow: true });
|
||||
this._defLoadSnippets = this.orm.silent.call(
|
||||
"ir.ui.view",
|
||||
"render_public_asset",
|
||||
[this.options.snippets, {}],
|
||||
{ context }
|
||||
);
|
||||
cacheSnippetTemplate[this.options.snippets] = this._defLoadSnippets;
|
||||
return this._defLoadSnippets;
|
||||
},
|
||||
@@ -3817,11 +3817,7 @@ var SnippetsMenu = Widget.extend({
|
||||
classes: 'btn-primary',
|
||||
click: function () {
|
||||
this.$footer.find('.btn').toggleClass('o_hidden');
|
||||
this._rpc({
|
||||
model: 'ir.module.module',
|
||||
method: 'button_immediate_install',
|
||||
args: [[moduleID]],
|
||||
}).then(() => {
|
||||
this.orm.call("ir.module.module", "button_immediate_install", [[moduleID]]).then(() => {
|
||||
self.trigger_up('request_save', {
|
||||
invalidateSnippetCache: true,
|
||||
_toMutex: true,
|
||||
@@ -3897,13 +3893,9 @@ var SnippetsMenu = Widget.extend({
|
||||
close: true,
|
||||
classes: 'btn-primary',
|
||||
click: async () => {
|
||||
await this._rpc({
|
||||
model: 'ir.ui.view',
|
||||
method: 'delete_snippet',
|
||||
kwargs: {
|
||||
'view_id': snippetId,
|
||||
'template_key': this.options.snippets,
|
||||
},
|
||||
await this.orm.call("ir.ui.view", "delete_snippet", [], {
|
||||
'view_id': snippetId,
|
||||
'template_key': this.options.snippets,
|
||||
});
|
||||
await this._loadSnippetsTemplates(true);
|
||||
},
|
||||
@@ -3940,14 +3932,10 @@ var SnippetsMenu = Widget.extend({
|
||||
const name = $textInput.val();
|
||||
if (name !== snippetName) {
|
||||
this._execWithLoadingEffect(async () => {
|
||||
await this._rpc({
|
||||
model: 'ir.ui.view',
|
||||
method: 'rename_snippet',
|
||||
kwargs: {
|
||||
'name': name,
|
||||
'view_id': parseInt(ev.target.dataset.snippetId),
|
||||
'template_key': this.options.snippets,
|
||||
},
|
||||
await this.orm.call("ir.ui.view", "rename_snippet", [], {
|
||||
'name': name,
|
||||
'view_id': parseInt(ev.target.dataset.snippetId),
|
||||
'template_key': this.options.snippets,
|
||||
});
|
||||
}, true);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import { attachComponent } from "@web/legacy/utils";
|
||||
import { MediaDialog } from "@web_editor/components/media_dialog/media_dialog";
|
||||
import Dialog from "@web/legacy/js/core/dialog";
|
||||
import dom from "@web/legacy/js/core/dom";
|
||||
import rpc from "@web/legacy/js/core/rpc";
|
||||
import { throttleForAnimation, debounce } from "@web/core/utils/timing";
|
||||
import { clamp } from "@web/core/utils/numbers";
|
||||
import Widget from "@web/legacy/js/core/widget";
|
||||
@@ -41,6 +40,7 @@ import {
|
||||
normalizeCSSColor,
|
||||
} from '@web/core/utils/colors';
|
||||
import { renderToElement } from "@web/core/utils/render";
|
||||
import { jsonrpc } from "@web/core/network/rpc_service";
|
||||
|
||||
const preserveCursor = OdooEditorLib.preserveCursor;
|
||||
const { DateTime } = luxon;
|
||||
@@ -2552,6 +2552,9 @@ const Many2oneUserValueWidget = SelectUserValueWidget.extend({
|
||||
options.domainComponents = {};
|
||||
options.nullText = $target[0].dataset.nullText ||
|
||||
JSON.parse($target[0].dataset.oeContactOptions || '{}')['null_text'];
|
||||
|
||||
this.orm = this._withCache(this.bindService("orm"));
|
||||
|
||||
return this._super(...arguments);
|
||||
},
|
||||
/**
|
||||
@@ -2660,12 +2663,11 @@ const Many2oneUserValueWidget = SelectUserValueWidget.extend({
|
||||
async setFilterInDomainIds(linkedRecordsIds) {
|
||||
const allowedIds = new Set();
|
||||
if (linkedRecordsIds) {
|
||||
const parentRecordsData = await this._rpc({
|
||||
model: this.options.filterInModel,
|
||||
method: 'search_read',
|
||||
fields: [this.options.filterInField],
|
||||
domain: [['id', 'in', linkedRecordsIds]],
|
||||
});
|
||||
const parentRecordsData = await this.orm.searchRead(
|
||||
this.options.filterInModel,
|
||||
[['id', 'in', linkedRecordsIds]],
|
||||
[this.options.filterInField]
|
||||
);
|
||||
parentRecordsData.forEach(record => {
|
||||
record[this.options.filterInField].forEach(item => allowedIds.add(item));
|
||||
});
|
||||
@@ -2684,12 +2686,17 @@ const Many2oneUserValueWidget = SelectUserValueWidget.extend({
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
async _rpc() {
|
||||
const cacheId = JSON.stringify(...arguments);
|
||||
if (!this._rpcCache[cacheId]) {
|
||||
this._rpcCache[cacheId] = this._super(...arguments);
|
||||
}
|
||||
return this._rpcCache[cacheId];
|
||||
_withCache(orm) {
|
||||
const cache = this._rpcCache;
|
||||
return Object.assign(Object.create(orm), {
|
||||
call() {
|
||||
const cacheId = JSON.stringify(arguments);
|
||||
if (!cache[cacheId]) {
|
||||
cache[cacheId] = orm.call(...arguments);
|
||||
}
|
||||
return cache[cacheId];
|
||||
},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Searches the database for corresponding records and updates the dropdown
|
||||
@@ -2697,23 +2704,19 @@ const Many2oneUserValueWidget = SelectUserValueWidget.extend({
|
||||
* @private
|
||||
*/
|
||||
async _search(needle) {
|
||||
const recTuples = await this._rpc({
|
||||
model: this.options.model,
|
||||
method: 'name_search',
|
||||
kwargs: {
|
||||
name: needle,
|
||||
args: (await this._getSearchDomain()).concat(
|
||||
Object.values(this.options.domainComponents).filter(item => item !== null)
|
||||
),
|
||||
operator: "ilike",
|
||||
limit: this.options.limit + 1,
|
||||
},
|
||||
});
|
||||
const records = await this._rpc({
|
||||
model: this.options.model,
|
||||
method: 'read',
|
||||
args: [recTuples.map(([id, _name]) => id), this.options.fields],
|
||||
const recTuples = await this.orm.call(this.options.model, "name_search", [], {
|
||||
name: needle,
|
||||
args: (await this._getSearchDomain()).concat(
|
||||
Object.values(this.options.domainComponents).filter(item => item !== null)
|
||||
),
|
||||
operator: "ilike",
|
||||
limit: this.options.limit + 1,
|
||||
});
|
||||
const records = await this.orm.read(
|
||||
this.options.model,
|
||||
recTuples.map(([id, _name]) => id),
|
||||
this.options.fields
|
||||
);
|
||||
// Remove select options.
|
||||
this._userValueWidgets.filter(widget => {
|
||||
return widget instanceof ButtonUserValueWidget &&
|
||||
@@ -2801,11 +2804,7 @@ const Many2oneUserValueWidget = SelectUserValueWidget.extend({
|
||||
*/
|
||||
async _getDisplayName(recordId) {
|
||||
if (!this.displayNameCache.hasOwnProperty(recordId)) {
|
||||
this.displayNameCache[recordId] = (await this._rpc({
|
||||
model: this.options.model,
|
||||
method: 'read',
|
||||
args: [[recordId], ['display_name']],
|
||||
}))[0].display_name;
|
||||
this.displayNameCache[recordId] = (await this.orm.read(this.options.model, [recordId], ['display_name']))[0].display_name;
|
||||
}
|
||||
return this.displayNameCache[recordId];
|
||||
},
|
||||
@@ -2917,6 +2916,8 @@ const Many2manyUserValueWidget = UserValueWidget.extend({
|
||||
dataAttributes.filterInModel = options.model;
|
||||
dataAttributes.filterInField = options.m2oField;
|
||||
}
|
||||
this.orm = this.bindService("orm");
|
||||
this.fields = this.bindService("field");
|
||||
return this._super(...arguments);
|
||||
},
|
||||
/**
|
||||
@@ -2931,27 +2932,15 @@ const Many2manyUserValueWidget = UserValueWidget.extend({
|
||||
return;
|
||||
}
|
||||
const { model, recordId, m2oField } = this.options;
|
||||
const [record] = await this._rpc({
|
||||
model: model,
|
||||
method: 'read',
|
||||
args: [[parseInt(recordId)], [m2oField]],
|
||||
});
|
||||
const [record] = await this.orm.read(model, [parseInt(recordId)], [m2oField]);
|
||||
const selectedRecordIds = record[m2oField];
|
||||
// TODO: handle no record
|
||||
const modelData = await this._rpc({
|
||||
model: model,
|
||||
method: 'fields_get',
|
||||
args: [[m2oField]],
|
||||
});
|
||||
const modelData = await this.fields.loadFields(model, { fieldNames: [m2oField] });
|
||||
// TODO: simultaneously fly both RPCs
|
||||
this.m2oModel = modelData[m2oField].relation;
|
||||
this.m2oName = modelData[m2oField].field_description; // Use as string attr?
|
||||
|
||||
const selectedRecords = await this._rpc({
|
||||
model: this.m2oModel,
|
||||
method: 'read',
|
||||
args: [selectedRecordIds, ['display_name']],
|
||||
});
|
||||
const selectedRecords = await this.orm.read(this.m2oModel, selectedRecordIds, ['display_name']);
|
||||
// TODO: reconcile the fact that this widget sets its own initial value
|
||||
// instead of it coming through setValue(_computeWidgetState)
|
||||
this._value = JSON.stringify(selectedRecords);
|
||||
@@ -5603,6 +5592,13 @@ registry.ReplaceMedia = SnippetOptionWidget.extend({
|
||||
* options that handles all the common parts.
|
||||
*/
|
||||
const ImageHandlerOption = SnippetOptionWidget.extend({
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -5849,7 +5845,7 @@ const ImageHandlerOption = SnippetOptionWidget.extend({
|
||||
*/
|
||||
async _loadImageInfo(attachmentSrc = '') {
|
||||
const img = this._getImg();
|
||||
await loadImageInfo(img, this._rpc.bind(this), attachmentSrc);
|
||||
await loadImageInfo(img, this.rpc, attachmentSrc);
|
||||
if (!img.dataset.originalId) {
|
||||
this.originalId = null;
|
||||
this.originalSrc = null;
|
||||
@@ -5987,6 +5983,7 @@ registry.ImageTools = ImageHandlerOption.extend({
|
||||
*/
|
||||
init() {
|
||||
this.shapeCache = {};
|
||||
this.rpc = this.bindService("rpc");
|
||||
return this._super(...arguments);
|
||||
},
|
||||
/**
|
||||
@@ -6022,7 +6019,7 @@ registry.ImageTools = ImageHandlerOption.extend({
|
||||
const imageCropWrapperElement = document.createElement('div');
|
||||
document.body.append(imageCropWrapperElement);
|
||||
const imageCropWrapper = await attachComponent(this, imageCropWrapperElement, ImageCrop, {
|
||||
rpc: this._rpc.bind(this),
|
||||
rpc: this.rpc,
|
||||
activeOnStart: true,
|
||||
media: img,
|
||||
mimetype: this._getImageMimetype(img),
|
||||
@@ -6085,7 +6082,7 @@ registry.ImageTools = ImageHandlerOption.extend({
|
||||
const imageCropWrapperElement = document.createElement('div');
|
||||
document.body.append(imageCropWrapperElement);
|
||||
const imageCropWrapper = await attachComponent(this, imageCropWrapperElement, ImageCrop, {
|
||||
rpc: this._rpc.bind(this),
|
||||
rpc: this.rpc,
|
||||
activeOnStart: true,
|
||||
media: img,
|
||||
mimetype: this._getImageMimetype(img),
|
||||
@@ -8265,6 +8262,11 @@ registry.ContainerWidth = SnippetOptionWidget.extend({
|
||||
* @todo replace this mechanism with real backend m2o field ?
|
||||
*/
|
||||
registry.many2one = SnippetOptionWidget.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -8273,11 +8275,7 @@ registry.many2one = SnippetOptionWidget.extend({
|
||||
this.fields = ['name', 'display_name'];
|
||||
return Promise.all([
|
||||
this._super(...arguments),
|
||||
this._rpc({
|
||||
model: oeMany2oneModel,
|
||||
method: 'read',
|
||||
args: [[parseInt(oeMany2oneId)], this.fields],
|
||||
}).then(([initialRecord]) => {
|
||||
this.orm.read(oeMany2oneModel, [parseInt(oeMany2oneId)], this.fields).then(([initialRecord]) => {
|
||||
this.initialRecord = initialRecord;
|
||||
}),
|
||||
]);
|
||||
@@ -8344,11 +8342,7 @@ registry.many2one = SnippetOptionWidget.extend({
|
||||
many2oneWidget.dataset.changeRecord = '';
|
||||
|
||||
const model = this.$target[0].dataset.oeMany2oneModel;
|
||||
const [{name: modelName}] = await this._rpc({
|
||||
model: 'ir.model',
|
||||
method: 'search_read',
|
||||
args: [[['model', '=', model]], ['name']],
|
||||
});
|
||||
const [{name: modelName}] = await this.orm.searchRead("ir.model", [['model', '=', model]], ['name']);
|
||||
many2oneWidget.setAttribute('String', modelName);
|
||||
many2oneWidget.dataset.model = model;
|
||||
many2oneWidget.dataset.fields = JSON.stringify(this.fields);
|
||||
@@ -8377,12 +8371,12 @@ registry.many2one = SnippetOptionWidget.extend({
|
||||
.attr('data-oe-many2one-id', contactId).data('oe-many2one-id', contactId)
|
||||
.map(async (i, node) => {
|
||||
if (node.dataset.oeType === 'contact') {
|
||||
const html = await this._rpc({
|
||||
model: 'ir.qweb.field.contact',
|
||||
method: 'get_record_to_html',
|
||||
args: [[contactId]],
|
||||
kwargs: {options: JSON.parse(node.dataset.oeContactOptions)},
|
||||
});
|
||||
const html = await this.orm.call(
|
||||
"ir.qweb.field.contact",
|
||||
"get_record_to_html",
|
||||
[[contactId]],
|
||||
{options: JSON.parse(node.dataset.oeContactOptions)}
|
||||
);
|
||||
$(node).html(html);
|
||||
} else {
|
||||
node.textContent = defaultText;
|
||||
@@ -8455,9 +8449,10 @@ registry.SnippetSave = SnippetOptionWidget.extend({
|
||||
// current widget has been destroyed and is orphaned, so this._rpc
|
||||
// will not work as it can't trigger_up. For this reason, we need
|
||||
// to bypass the service provider and use the global RPC directly
|
||||
await rpc.query({
|
||||
model: 'ir.ui.view',
|
||||
method: 'save_snippet',
|
||||
await jsonrpc(`/web/dataset/call_kw/ir.ui.view/save_snippet`, {
|
||||
model: "ir.ui.view",
|
||||
method: "save_snippet",
|
||||
args: [],
|
||||
kwargs: {
|
||||
'name': defaultSnippetName,
|
||||
'arch': targetCopyEl.outerHTML,
|
||||
@@ -8653,6 +8648,7 @@ registry.SelectTemplate = SnippetOptionWidget.extend({
|
||||
this._super(...arguments);
|
||||
this.containerSelector = '';
|
||||
this.selectTemplateWidgetName = '';
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
/**
|
||||
* @constructor
|
||||
@@ -8725,14 +8721,12 @@ registry.SelectTemplate = SnippetOptionWidget.extend({
|
||||
*/
|
||||
async _getTemplate(xmlid) {
|
||||
if (!this._templates[xmlid]) {
|
||||
this._templates[xmlid] = await this._rpc({
|
||||
model: 'ir.ui.view',
|
||||
method: 'render_public_asset',
|
||||
args: [`${xmlid}`, {}],
|
||||
kwargs: {
|
||||
context: this.options.context,
|
||||
},
|
||||
});
|
||||
this._templates[xmlid] = await this.orm.call(
|
||||
"ir.ui.view",
|
||||
"render_public_asset",
|
||||
[`${xmlid}`, {}],
|
||||
{ context: this.options.context }
|
||||
);
|
||||
}
|
||||
return this._templates[xmlid];
|
||||
},
|
||||
|
||||
@@ -3058,31 +3058,9 @@ export class Wysiwyg extends Component {
|
||||
}
|
||||
}
|
||||
_callService(payload) {
|
||||
let args = payload.args || [];
|
||||
if (payload.service === 'ajax' && payload.method === 'rpc') {
|
||||
// ajax service uses an extra 'target' argument for rpc
|
||||
const [route, params, settings = {}] = args;
|
||||
if (params && params.kwargs) {
|
||||
params.kwargs.context = {
|
||||
...this.env.services.user.context,
|
||||
...params.kwargs.context,
|
||||
};
|
||||
}
|
||||
const result = this._serviceRpc(route, params, settings);
|
||||
payload.callback(result);
|
||||
return;
|
||||
}
|
||||
const service = this.env.services[payload.service];
|
||||
// If the service doesn't exist it means that it was translated to Owl
|
||||
if (service) {
|
||||
const result = service[payload.method].apply(service, args);
|
||||
payload.callback(result);
|
||||
} else {
|
||||
throw new Error(
|
||||
`The service "${payload.service}" is not present in the legacy owl environment.
|
||||
You should probably create a mapper in @web/legacy/utils`
|
||||
);
|
||||
}
|
||||
const result = service[payload.method].apply(service, payload.args || []);
|
||||
payload.callback(result);
|
||||
}
|
||||
_serviceRpc(route, params, settings = {}) {
|
||||
if (params && params.kwargs) {
|
||||
|
||||
@@ -6,6 +6,11 @@ publicWidget.registry.UnsplashBeacon = publicWidget.Widget.extend({
|
||||
// /!\ To adapt the day the beacon makes sense for backend customizations
|
||||
selector: '#wrapwrap',
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -15,9 +20,7 @@ publicWidget.registry.UnsplashBeacon = publicWidget.Widget.extend({
|
||||
return img.src.split('/unsplash/')[1].split('/')[0];
|
||||
});
|
||||
if (unsplashImages.length) {
|
||||
this._rpc({
|
||||
route: '/web_unsplash/get_app_id',
|
||||
}).then(function (appID) {
|
||||
this.rpc('/web_unsplash/get_app_id').then(function (appID) {
|
||||
if (!appID) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,12 @@ export const WebsiteAceEditor = AceEditor.extend({
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_getContext() {
|
||||
return this.options.getContext();
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -38,12 +44,17 @@ export const WebsiteAceEditor = AceEditor.extend({
|
||||
// got copy/unlink).
|
||||
const selectedView = Object.values(this.views).find(view => view.id === this._getSelectedResource());
|
||||
const context = this.options.getContext();
|
||||
defs.push(this._rpc({
|
||||
model: 'ir.ui.view',
|
||||
method: 'search_read',
|
||||
fields: ['id'],
|
||||
domain: [['key', '=', selectedView.key], ['website_id', '=', context.website_id]],
|
||||
}));
|
||||
defs.push(
|
||||
this.orm.searchRead(
|
||||
"ir.ui.view",
|
||||
[
|
||||
["key", "=", selectedView.key],
|
||||
["website_id", "=", context.website_id],
|
||||
],
|
||||
["id"],
|
||||
{ context: this.options.getContext() }
|
||||
)
|
||||
);
|
||||
}
|
||||
return Promise.all(defs).then((async () => {
|
||||
await this._updateEditor();
|
||||
@@ -88,12 +99,6 @@ export const WebsiteAceEditor = AceEditor.extend({
|
||||
return this._displayResource(this._getSelectedResource());
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_rpc(options) {
|
||||
return this._super({ ...options, context: this.options.getContext() });
|
||||
},
|
||||
});
|
||||
|
||||
export class AceEditorAdapterComponent extends Component {
|
||||
|
||||
@@ -44,21 +44,16 @@ export class MenuDialog extends Component {
|
||||
|
||||
useEffect(() => {
|
||||
const $input = $(this.urlInputRef.el);
|
||||
// wUtils.autocompleteWithPages rely on a widget that has a _rpc and
|
||||
// trigger_up method.
|
||||
const fakeWidget = {
|
||||
_rpc: ({ route, params }) => this.rpc(route, params),
|
||||
trigger_up: () => {
|
||||
this.url.input.value = this.urlInputRef.el.value;
|
||||
},
|
||||
};
|
||||
const options = {
|
||||
body: this.website.pageDocument.body,
|
||||
classes: {
|
||||
'ui-autocomplete': 'o_edit_menu_autocomplete'
|
||||
},
|
||||
urlChosen: () => {
|
||||
this.url.input.value = this.urlInputRef.el.value;
|
||||
},
|
||||
};
|
||||
wUtils.autocompleteWithPages(fakeWidget, $input, options);
|
||||
wUtils.autocompleteWithPages(this.rpc.bind(this), $input, options);
|
||||
return () => $input.urlcomplete('destroy');
|
||||
}, () => []);
|
||||
}
|
||||
|
||||
@@ -787,22 +787,9 @@ export class WysiwygAdapterComponent extends Wysiwyg {
|
||||
if (evType in triggers) {
|
||||
triggers[evType](ev);
|
||||
} else if (evType === 'call_service') {
|
||||
let args = payload.args || [];
|
||||
if (payload.service === 'ajax' && payload.method === 'rpc') {
|
||||
// ajax service uses an extra 'target' argument for rpc
|
||||
args = args.concat(ev.target);
|
||||
}
|
||||
const service = legacyEnv.services[payload.service];
|
||||
//If the service doesn't exist it means that it was translated to Owl
|
||||
if (service) {
|
||||
const result = service[payload.method].apply(service, args);
|
||||
payload.callback(result);
|
||||
} else {
|
||||
throw new Error(
|
||||
`The service "${payload.service}" is not present in the legacy owl environment.
|
||||
You should probably create a mapper in @web/legacy/utils`
|
||||
);
|
||||
}
|
||||
const result = service[payload.method].apply(service, payload.args || []);
|
||||
payload.callback(result);
|
||||
} else {
|
||||
super._trigger_up(...arguments);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ export const WebsiteRoot = publicRootData.PublicRoot.extend({
|
||||
*/
|
||||
init() {
|
||||
this.isFullscreen = false;
|
||||
this.rpc = this.bindService("rpc");
|
||||
return this._super(...arguments);
|
||||
},
|
||||
/**
|
||||
@@ -71,9 +72,7 @@ export const WebsiteRoot = publicRootData.PublicRoot.extend({
|
||||
async _getGMapAPIKey(refetch) {
|
||||
if (refetch || !this._gmapAPIKeyProm) {
|
||||
this._gmapAPIKeyProm = new Promise(async resolve => {
|
||||
const data = await this._rpc({
|
||||
route: '/website/google_maps_api_key',
|
||||
});
|
||||
const data = await this.rpc('/website/google_maps_api_key');
|
||||
resolve(JSON.parse(data).google_maps_api_key || '');
|
||||
});
|
||||
}
|
||||
@@ -227,12 +226,9 @@ export const WebsiteRoot = publicRootData.PublicRoot.extend({
|
||||
}
|
||||
|
||||
var $data = $(ev.currentTarget).parents(".js_publish_management:first");
|
||||
this._rpc({
|
||||
route: $data.data('controller') || '/website/publish',
|
||||
params: {
|
||||
id: +$data.data('id'),
|
||||
object: $data.data('object'),
|
||||
},
|
||||
this.rpc($data.data('controller') || '/website/publish', {
|
||||
id: +$data.data('id'),
|
||||
object: $data.data('object'),
|
||||
})
|
||||
.then(function (result) {
|
||||
$data.toggleClass("css_published", result).toggleClass("css_unpublished", !result);
|
||||
|
||||
@@ -20,13 +20,7 @@ patch(LinkDialog.prototype, {
|
||||
body: this.$link && this.$link[0].ownerDocument.body,
|
||||
};
|
||||
const result = await super.start(...arguments);
|
||||
// wUtils.autocompleteWithPages rely on a widget that has a _rpc and
|
||||
// trigger_up method.
|
||||
const fakeWidget = {
|
||||
_rpc: ({ route, params }) => this.rpc(route, params),
|
||||
trigger_up: () => {},
|
||||
};
|
||||
wUtils.autocompleteWithPages(fakeWidget, this.$el.find('input[name="url"]'), options);
|
||||
wUtils.autocompleteWithPages(this.rpc.bind(this), this.$el.find('input[name="url"]'), options);
|
||||
return result;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -144,14 +144,7 @@ const wSnippetMenu = weSnippetEditor.SnippetsMenu.extend({
|
||||
$button.prop('disabled', true);
|
||||
const res = await this._validateGMapAPIKey(valueAPIKey);
|
||||
if (res.isValid) {
|
||||
await this._rpc({
|
||||
model: 'website',
|
||||
method: 'write',
|
||||
args: [
|
||||
[websiteId],
|
||||
{google_maps_api_key: valueAPIKey},
|
||||
],
|
||||
});
|
||||
await this.orm.write("website", [websiteId], { google_maps_api_key: valueAPIKey });
|
||||
invalidated = true;
|
||||
dialog.close();
|
||||
} else {
|
||||
|
||||
@@ -47,6 +47,11 @@ options.UserValueWidget.include({
|
||||
});
|
||||
|
||||
Many2oneUserValueWidget.include({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.fields = this.bindService("field");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -54,10 +59,8 @@ Many2oneUserValueWidget.include({
|
||||
// Add the current website's domain if the model has a website_id field.
|
||||
// Note that the `_rpc` method is cached in Many2X user value widget,
|
||||
// see `_rpcCache`.
|
||||
const websiteIdField = await this._rpc({
|
||||
model: this.options.model,
|
||||
method: "fields_get",
|
||||
args: [["website_id"]],
|
||||
const websiteIdField = await this.fields.loadFields(this.options.model, {
|
||||
fieldNames: ["website_id"],
|
||||
});
|
||||
const modelHasWebsiteId = !!websiteIdField["website_id"];
|
||||
if (modelHasWebsiteId && !this.options.domain.find(arr => arr[0] === "website_id")) {
|
||||
@@ -69,13 +72,15 @@ Many2oneUserValueWidget.include({
|
||||
});
|
||||
|
||||
const UrlPickerUserValueWidget = InputUserValueWidget.extend({
|
||||
custom_events: Object.assign({}, InputUserValueWidget.prototype.custom_events || {}, {
|
||||
'website_url_chosen': '_onWebsiteURLChosen',
|
||||
}),
|
||||
events: Object.assign({}, InputUserValueWidget.prototype.events || {}, {
|
||||
'click .o_we_redirect_to': '_onRedirectTo',
|
||||
}),
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -98,8 +103,9 @@ const UrlPickerUserValueWidget = InputUserValueWidget.extend({
|
||||
"ui-autocomplete": 'o_website_ui_autocomplete'
|
||||
},
|
||||
body: this.getParent().$target[0].ownerDocument.body,
|
||||
urlChosen: this._onWebsiteURLChosen.bind(this),
|
||||
};
|
||||
wUtils.autocompleteWithPages(this, $(this.inputEl), options);
|
||||
wUtils.autocompleteWithPages(this.rpc.bind(this), $(this.inputEl), options);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -627,6 +633,9 @@ options.Class.include({
|
||||
// triggers a custom event, only that same jQuery instance will
|
||||
// trigger handlers set with `.on`.
|
||||
this.$bsTarget = this.ownerDocument.defaultView.$(this.$target[0]);
|
||||
|
||||
this.rpc = this.bindService("rpc");
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -831,14 +840,11 @@ options.Class.include({
|
||||
const disableDataKeys = allDataKeys.filter(value => !enableDataKeys.includes(value));
|
||||
const resetViewArch = !!params.resetViewArch;
|
||||
|
||||
return this._rpc({
|
||||
route: '/website/theme_customize_data',
|
||||
params: {
|
||||
'is_view_data': isViewData,
|
||||
'enable': enableDataKeys,
|
||||
'disable': disableDataKeys,
|
||||
'reset_view_arch': resetViewArch,
|
||||
},
|
||||
return this.rpc('/website/theme_customize_data', {
|
||||
'is_view_data': isViewData,
|
||||
'enable': enableDataKeys,
|
||||
'disable': disableDataKeys,
|
||||
'reset_view_arch': resetViewArch,
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -859,12 +865,9 @@ options.Class.include({
|
||||
*/
|
||||
async _getEnabledCustomizeValues(possibleValues, isViewData) {
|
||||
const allDataKeys = this._getDataKeysFromPossibleValues(possibleValues);
|
||||
const enabledValues = await this._rpc({
|
||||
route: '/website/theme_customize_data_get',
|
||||
params: {
|
||||
'keys': allDataKeys,
|
||||
'is_view_data': isViewData,
|
||||
},
|
||||
const enabledValues = await this.rpc('/website/theme_customize_data_get', {
|
||||
'keys': allDataKeys,
|
||||
'is_view_data': isViewData,
|
||||
});
|
||||
let mostValuesStr = '';
|
||||
let mostValuesNb = 0;
|
||||
@@ -885,11 +888,7 @@ options.Class.include({
|
||||
Object.keys(values).forEach((key) => {
|
||||
values[key] = values[key] || defaultValue;
|
||||
});
|
||||
return this._rpc({
|
||||
model: 'web_editor.assets',
|
||||
method: 'make_scss_customization',
|
||||
args: [url, values],
|
||||
});
|
||||
return this.orm.call("web_editor.assets", "make_scss_customization", [url, values]);
|
||||
},
|
||||
/**
|
||||
* Refreshes all public widgets related to the given element.
|
||||
@@ -1206,6 +1205,7 @@ options.registry.OptionsTab = options.Class.extend({
|
||||
this._super(...arguments);
|
||||
this.grayParams = {};
|
||||
this.grays = {};
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -1369,11 +1369,11 @@ options.registry.OptionsTab = options.Class.extend({
|
||||
});
|
||||
|
||||
let website;
|
||||
const dataProm = this._rpc({
|
||||
model: 'website',
|
||||
method: 'read',
|
||||
args: [[websiteId], ['custom_code_head', 'custom_code_footer']],
|
||||
}).then(websites => {
|
||||
const dataProm = this.orm.read(
|
||||
"website",
|
||||
[websiteId],
|
||||
['custom_code_head', 'custom_code_footer']
|
||||
).then(websites => {
|
||||
website = websites[0];
|
||||
});
|
||||
|
||||
@@ -1403,13 +1403,8 @@ options.registry.OptionsTab = options.Class.extend({
|
||||
text: _t("Save"),
|
||||
classes: 'btn-primary',
|
||||
click: async () => {
|
||||
await this._rpc({
|
||||
model: 'website',
|
||||
method: 'write',
|
||||
args: [
|
||||
[websiteId],
|
||||
{[fieldName]: aceEditor.getValue()},
|
||||
],
|
||||
await this.orm.write("website", [websiteId], {
|
||||
[fieldName]: aceEditor.getValue(),
|
||||
});
|
||||
},
|
||||
close: true,
|
||||
@@ -1657,6 +1652,12 @@ options.registry.ThemeColors = options.registry.OptionsTab.extend({
|
||||
});
|
||||
|
||||
options.registry.menu_data = options.Class.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.user = this.bindService("user");
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* When the users selects a menu, a popover is shown with 4 possible
|
||||
* actions: follow the link in a new tab, copy the menu link, edit the menu,
|
||||
@@ -1674,11 +1675,7 @@ options.registry.menu_data = options.Class.extend({
|
||||
wysiwyg,
|
||||
container: popoverContainer,
|
||||
notify: this.displayNotification.bind(this),
|
||||
checkIsWebsiteDesigner: () => this._rpc({
|
||||
'model': 'res.users',
|
||||
'method': 'has_group',
|
||||
'args': ['website.group_website_designer'],
|
||||
}),
|
||||
checkIsWebsiteDesigner: () => this.user.hasGroup("website.group_website_designer"),
|
||||
onEditLinkClick: (widget) => {
|
||||
var $menu = widget.$target.find('[data-oe-id]');
|
||||
this.trigger_up('menu_dialog', {
|
||||
@@ -1694,11 +1691,11 @@ options.registry.menu_data = options.Class.extend({
|
||||
name,
|
||||
url,
|
||||
};
|
||||
return this._rpc({
|
||||
model: 'website.menu',
|
||||
method: 'save',
|
||||
args: [websiteId, {'data': [data]}],
|
||||
}).then(function () {
|
||||
return this.orm.call(
|
||||
"website.menu",
|
||||
"save",
|
||||
[websiteId, {'data': [data]}]
|
||||
).then(function () {
|
||||
widget.wysiwyg.odooEditor.observerUnactive();
|
||||
widget.$target.attr('href', url);
|
||||
$menu.text(name);
|
||||
@@ -1731,6 +1728,12 @@ options.registry.menu_data = options.Class.extend({
|
||||
});
|
||||
|
||||
options.registry.company_data = options.Class.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetches data to determine the URL where the user can edit its company
|
||||
* data. Saves the info in the prototype to do this only once.
|
||||
@@ -1742,12 +1745,8 @@ options.registry.company_data = options.Class.extend({
|
||||
var prom;
|
||||
var self = this;
|
||||
if (proto.__link === undefined) {
|
||||
prom = this._rpc({route: '/web/session/get_session_info'}).then(function (session) {
|
||||
return self._rpc({
|
||||
model: 'res.users',
|
||||
method: 'read',
|
||||
args: [session.uid, ['company_id']],
|
||||
});
|
||||
prom = this.rpc('/web/session/get_session_info').then(function (session) {
|
||||
return self.orm.read("res.users", [session.uid], ["company_id"]);
|
||||
}).then(function (res) {
|
||||
proto.__link = '/web#action=base.action_res_company_form&view_type=form&id=' + encodeURIComponent(res && res[0] && res[0].company_id[0] || 1);
|
||||
});
|
||||
|
||||
@@ -38,15 +38,10 @@ patch(LinkTools.prototype, {
|
||||
"ui-autocomplete": 'o_website_ui_autocomplete'
|
||||
},
|
||||
body: this.$editable[0].ownerDocument.body,
|
||||
};
|
||||
// wUtils.autocompleteWithPages rely on a widget that has a _rpc and
|
||||
// trigger_up method.
|
||||
const fakeWidget = {
|
||||
_rpc: ({ route, params }) => this.rpc(route, params),
|
||||
trigger_up: this._onAutocompleteClose.bind(this),
|
||||
urlChosen: this._onAutocompleteClose.bind(this),
|
||||
isDestroyed: () => status(this) === 'destroyed',
|
||||
};
|
||||
wUtils.autocompleteWithPages(fakeWidget, this.$el.find('input[name="url"]'), options);
|
||||
wUtils.autocompleteWithPages(this.rpc.bind(this), this.$el.find('input[name="url"]'), options);
|
||||
this._adaptPageAnchor();
|
||||
return def;
|
||||
},
|
||||
|
||||
@@ -45,10 +45,10 @@ function loadAnchors(url, body) {
|
||||
/**
|
||||
* Allows the given input to propose existing website URLs.
|
||||
*
|
||||
* @param {ServicesMixin|Widget} self - an element capable to trigger an RPC
|
||||
* @param {Function} rpc
|
||||
* @param {jQuery} $input
|
||||
*/
|
||||
function autocompleteWithPages(self, $input, options) {
|
||||
function autocompleteWithPages(rpc, $input, options) {
|
||||
$.widget("website.urlcomplete", $.ui.autocomplete, {
|
||||
options: options || {},
|
||||
_create: function () {
|
||||
@@ -88,15 +88,12 @@ function autocompleteWithPages(self, $input, options) {
|
||||
// avoid useless call to /website/get_suggested_links
|
||||
response();
|
||||
} else {
|
||||
if (self.isDestroyed?.()) {
|
||||
return ;
|
||||
if (options.isDestroyed?.()) {
|
||||
return;
|
||||
}
|
||||
return self._rpc({
|
||||
route: '/website/get_suggested_links',
|
||||
params: {
|
||||
needle: request.term,
|
||||
limit: 15,
|
||||
}
|
||||
return rpc('/website/get_suggested_links', {
|
||||
needle: request.term,
|
||||
limit: 15,
|
||||
}).then(function (res) {
|
||||
let choices = res.matching_pages;
|
||||
res.others.forEach(other => {
|
||||
@@ -115,7 +112,7 @@ function autocompleteWithPages(self, $input, options) {
|
||||
// choose url in dropdown with arrow change ev.target.value without trigger_up
|
||||
// so cannot check here if value has been updated
|
||||
ev.target.value = ui.item.value;
|
||||
self.trigger_up('website_url_chosen');
|
||||
options?.urlChosen();
|
||||
ev.preventDefault();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -35,6 +35,8 @@ const DynamicSnippet = publicWidget.Widget.extend({
|
||||
this.isDesplayedAsMobile = uiUtils.isSmall();
|
||||
this.unique_id = uniqueId("s_dynamic_snippet_");
|
||||
this.template_key = 'website.s_dynamic_snippet.grid';
|
||||
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
/**
|
||||
*
|
||||
@@ -117,16 +119,16 @@ const DynamicSnippet = publicWidget.Widget.extend({
|
||||
async _fetchData() {
|
||||
if (this._isConfigComplete()) {
|
||||
const nodeData = this.el.dataset;
|
||||
const filterFragments = await this._rpc({
|
||||
'route': '/website/snippet/filters',
|
||||
'params': Object.assign({
|
||||
const filterFragments = await this.rpc(
|
||||
'/website/snippet/filters',
|
||||
Object.assign({
|
||||
'filter_id': parseInt(nodeData.filterId),
|
||||
'template_key': nodeData.templateKey,
|
||||
'limit': parseInt(nodeData.numberOfRecords),
|
||||
'search_domain': this._getSearchDomain(),
|
||||
'with_sample': this.editableMode,
|
||||
}, this._getRpcParameters()),
|
||||
});
|
||||
}, this._getRpcParameters())
|
||||
);
|
||||
this.data = filterFragments.map(markup);
|
||||
} else {
|
||||
this.data = [];
|
||||
|
||||
@@ -33,6 +33,8 @@ const dynamicSnippetOptions = options.Class.extend({
|
||||
this.dynamicFilterTemplates = {};
|
||||
// Indicates that some current options are a default selection.
|
||||
this.isOptionDefault = {};
|
||||
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -149,10 +151,10 @@ const dynamicSnippetOptions = options.Class.extend({
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async _fetchDynamicFilters() {
|
||||
const dynamicFilters = await this._rpc({route: '/website/snippet/options_filters', params: {
|
||||
const dynamicFilters = await this.rpc('/website/snippet/options_filters', {
|
||||
model_name: this.modelNameFilter,
|
||||
search_domain: this.contextualFilterDomain,
|
||||
}});
|
||||
});
|
||||
if (!dynamicFilters.length) {
|
||||
// Additional modules are needed for dynamic filters to be defined.
|
||||
return;
|
||||
@@ -174,9 +176,9 @@ const dynamicSnippetOptions = options.Class.extend({
|
||||
if (!filter) {
|
||||
return [];
|
||||
}
|
||||
const dynamicFilterTemplates = await this._rpc({route: '/website/snippet/filter_templates', params: {
|
||||
const dynamicFilterTemplates = await this.rpc('/website/snippet/filter_templates', {
|
||||
filter_name: filter.model_name.replaceAll('.', '_'),
|
||||
}});
|
||||
});
|
||||
for (let index in dynamicFilterTemplates) {
|
||||
this.dynamicFilterTemplates[dynamicFilterTemplates[index].key] = dynamicFilterTemplates[index];
|
||||
}
|
||||
|
||||
@@ -4,6 +4,11 @@ import { pick } from "@web/core/utils/objects";
|
||||
import options from "@web_editor/js/editor/snippets.options";
|
||||
|
||||
options.registry.facebookPage = options.Class.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes the required facebook page data to create the iframe.
|
||||
*
|
||||
@@ -25,10 +30,7 @@ options.registry.facebookPage = options.Class.extend({
|
||||
if (!this.fbData.href) {
|
||||
// Fetches the default url for facebook page from website config
|
||||
var self = this;
|
||||
defs.push(this._rpc({
|
||||
model: 'website',
|
||||
method: 'search_read',
|
||||
args: [[], ['social_facebook']],
|
||||
defs.push(this.orm.searchRead("website", [], ["social_facebook"], {
|
||||
limit: 1,
|
||||
}).then(function (res) {
|
||||
if (res) {
|
||||
|
||||
@@ -28,6 +28,8 @@ publicWidget.registry.searchBar = publicWidget.Widget.extend({
|
||||
|
||||
this._onInput = debounce(this._onInput, 400);
|
||||
this._onFocusOut = debounce(this._onFocusOut, 100);
|
||||
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -111,16 +113,13 @@ publicWidget.registry.searchBar = publicWidget.Widget.extend({
|
||||
* @private
|
||||
*/
|
||||
async _fetch() {
|
||||
const res = await this._rpc({
|
||||
route: '/website/snippet/autocomplete',
|
||||
params: {
|
||||
'search_type': this.searchType,
|
||||
'term': this.$input.val(),
|
||||
'order': this.order,
|
||||
'limit': this.limit,
|
||||
'max_nb_chars': Math.round(Math.max(this.autocompleteMinWidth, parseInt(this.$el.width())) * 0.22),
|
||||
'options': this.options,
|
||||
},
|
||||
const res = await this.rpc('/website/snippet/autocomplete', {
|
||||
'search_type': this.searchType,
|
||||
'term': this.$input.val(),
|
||||
'order': this.order,
|
||||
'limit': this.limit,
|
||||
'max_nb_chars': Math.round(Math.max(this.autocompleteMinWidth, parseInt(this.$el.width())) * 0.22),
|
||||
'options': this.options,
|
||||
});
|
||||
const fieldNames = this._getFieldsNames();
|
||||
res.results.forEach(record => {
|
||||
|
||||
@@ -13,6 +13,11 @@ const clearDbSocialValuesCache = () => {
|
||||
};
|
||||
|
||||
options.registry.SocialMedia = options.Class.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -55,11 +60,7 @@ options.registry.SocialMedia = options.Class.extend({
|
||||
websiteId = ctx['website_id'];
|
||||
},
|
||||
});
|
||||
await this._rpc({
|
||||
model: 'website',
|
||||
method: 'write',
|
||||
args: [[websiteId], dbSocialValues],
|
||||
});
|
||||
await this.orm.write("website", [websiteId], dbSocialValues);
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -251,12 +252,15 @@ options.registry.SocialMedia = options.Class.extend({
|
||||
},
|
||||
});
|
||||
// Fetch URLs for db links.
|
||||
dbSocialValuesProm = this._rpc({
|
||||
model: 'website',
|
||||
method: 'read',
|
||||
args: [websiteId, ['social_facebook', 'social_twitter', 'social_linkedin',
|
||||
'social_youtube', 'social_instagram', 'social_github', 'social_tiktok']],
|
||||
}).then(function (values) {
|
||||
dbSocialValuesProm = this.orm.read("website", [websiteId], [
|
||||
"social_facebook",
|
||||
"social_twitter",
|
||||
"social_linkedin",
|
||||
"social_youtube",
|
||||
"social_instagram",
|
||||
"social_github",
|
||||
"social_tiktok",
|
||||
]).then(function (values) {
|
||||
[dbSocialValues] = values;
|
||||
delete dbSocialValues.id;
|
||||
});
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
import {ReCaptcha} from "@google_recaptcha/js/recaptcha";
|
||||
import { session } from "@web/session";
|
||||
import ajax from "@web/legacy/js/core/ajax";
|
||||
import publicWidget from "@web/legacy/js/public/public_widget";
|
||||
import dom from "@web/legacy/js/core/dom";
|
||||
import { delay } from "@web/core/utils/concurrency";
|
||||
import { debounce } from "@web/core/utils/timing";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { renderToElement } from "@web/core/utils/render";
|
||||
import { post } from "@web/core/network/http_service";
|
||||
import {
|
||||
formatDate,
|
||||
formatDateTime,
|
||||
@@ -62,6 +62,7 @@ const { DateTime } = luxon;
|
||||
this._visibilityFunctionByFieldName = new Map();
|
||||
this._visibilityFunctionByFieldEl = new Map();
|
||||
this.__started = new Promise(resolve => this.__startResolve = resolve);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
willStart: async function () {
|
||||
const res = this._super(...arguments);
|
||||
@@ -72,11 +73,11 @@ const { DateTime } = luxon;
|
||||
// fetch user data (required by fill-with behavior)
|
||||
this.preFillValues = {};
|
||||
if (session.user_id) {
|
||||
this.preFillValues = (await this._rpc({
|
||||
model: 'res.users',
|
||||
method: 'read',
|
||||
args: [session.user_id, this._getUserPreFillFields()],
|
||||
}))[0] || {};
|
||||
this.preFillValues = (await this.orm.read(
|
||||
"res.users",
|
||||
[session.user_id],
|
||||
this._getUserPreFillFields()
|
||||
))[0] || {};
|
||||
}
|
||||
return res;
|
||||
},
|
||||
@@ -351,14 +352,17 @@ const { DateTime } = luxon;
|
||||
}
|
||||
}
|
||||
|
||||
if (odoo.csrf_token) {
|
||||
form_values.csrf_token = odoo.csrf_token;
|
||||
}
|
||||
|
||||
// Post form and handle result
|
||||
ajax.post(this.$el.attr('action') + (this.$el.data('force_action') || this.$el.data('model_name')), form_values)
|
||||
post(this.$el.attr('action') + (this.$el.data('force_action') || this.$el.data('model_name')), form_values)
|
||||
.then(async function (result_data) {
|
||||
// Restore send button behavior
|
||||
self.$el.find('.s_website_form_send, .o_website_form_send')
|
||||
.removeAttr('disabled')
|
||||
.removeClass('disabled'); // !compatibility
|
||||
result_data = JSON.parse(result_data);
|
||||
if (!result_data.id) {
|
||||
// Failure, the server didn't return the created record ID
|
||||
self.update_status('error', result_data.error ? result_data.error : false);
|
||||
|
||||
@@ -39,6 +39,11 @@ function _getDomain(formEl, name, type, relation) {
|
||||
}
|
||||
|
||||
const FormEditor = options.Class.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Private
|
||||
//----------------------------------------------------------------------
|
||||
@@ -66,14 +71,7 @@ const FormEditor = options.Class.extend({
|
||||
display_name: el[1],
|
||||
}));
|
||||
} else if (field.relation && field.relation !== 'ir.attachment') {
|
||||
field.records = await this._rpc({
|
||||
model: field.relation,
|
||||
method: 'search_read',
|
||||
args: [
|
||||
field.domain,
|
||||
['display_name']
|
||||
],
|
||||
});
|
||||
field.records = await this.orm.searchRead(field.relation, field.domain, ["display_name"]);
|
||||
}
|
||||
return field.records;
|
||||
},
|
||||
@@ -376,10 +374,7 @@ options.registry.WebsiteFormEditor = FormEditor.extend({
|
||||
}
|
||||
|
||||
// Get list of website_form compatible models.
|
||||
this.models = await this._rpc({
|
||||
model: 'ir.model',
|
||||
method: 'get_compatible_form_models',
|
||||
});
|
||||
this.models = await this.orm.call("ir.model", "get_compatible_form_models");
|
||||
|
||||
const targetModelName = this.$target[0].dataset.model_name || 'mail.mail';
|
||||
this.activeForm = this.models.find(m => m.model === targetModelName);
|
||||
@@ -430,11 +425,7 @@ options.registry.WebsiteFormEditor = FormEditor.extend({
|
||||
if (fields.length) {
|
||||
// ideally we'd only do this if saving the form
|
||||
// succeeds... but no idea how to do that
|
||||
this._rpc({
|
||||
model: 'ir.model.fields',
|
||||
method: 'formbuilder_whitelist',
|
||||
args: [model, unique(fields)],
|
||||
});
|
||||
this.orm.call("ir.model.fields", "formbuilder_whitelist", [model, unique(fields)]);
|
||||
}
|
||||
}
|
||||
if (this.$message.length) {
|
||||
@@ -887,11 +878,7 @@ options.registry.WebsiteFieldEditor = FieldEditor.extend({
|
||||
if (model in authorizedFieldsCache) {
|
||||
getFields = authorizedFieldsCache[model];
|
||||
} else {
|
||||
getFields = this._rpc({
|
||||
model: "ir.model",
|
||||
method: "get_authorized_fields",
|
||||
args: [model],
|
||||
});
|
||||
getFields = this.orm.call("ir.model", "get_authorized_fields", [model]);
|
||||
authorizedFieldsCache[model] = getFields;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/** @odoo-module **/
|
||||
import { jsonrpc } from "@web/core/network/rpc_service";
|
||||
import { registry } from "@web/core/registry";
|
||||
import rpc from '@web/legacy/js/core/rpc';
|
||||
|
||||
registry.category("web_tour.tours").add("website_form_editor_tour_submit", {
|
||||
test: true,
|
||||
@@ -165,17 +165,18 @@ registry.category("web_tour.tours").add("website_form_editor_tour_results", {
|
||||
content: "Check mail.mail records have been created",
|
||||
trigger: "body",
|
||||
run: function () {
|
||||
var mailDef = rpc.query({
|
||||
model: 'mail.mail',
|
||||
method: 'search_count',
|
||||
args: [[
|
||||
['email_to', '=', 'test@test.test'],
|
||||
['body_html', 'like', 'A useless message'],
|
||||
['body_html', 'like', 'Service : Development Service'],
|
||||
['body_html', 'like', 'State : 44 - UK'],
|
||||
['body_html', 'like', 'Products : Xperia,Wiko Stairway']
|
||||
]],
|
||||
});
|
||||
var mailDef = jsonrpc(`/web/dataset/call_kw/mail.mail/search_count`, {
|
||||
model: "mail.mail",
|
||||
method: "search_count",
|
||||
args: [[
|
||||
['email_to', '=', 'test@test.test'],
|
||||
['body_html', 'like', 'A useless message'],
|
||||
['body_html', 'like', 'Service : Development Service'],
|
||||
['body_html', 'like', 'State : 44 - UK'],
|
||||
['body_html', 'like', 'Products : Xperia,Wiko Stairway']
|
||||
]],
|
||||
kwargs: {},
|
||||
});
|
||||
var success = function(model, count) {
|
||||
if (count > 0) {
|
||||
$('body').append('<div id="website_form_editor_success_test_tour_'+model+'"></div>');
|
||||
|
||||
@@ -58,6 +58,11 @@ options.registry.CoverProperties.include({
|
||||
});
|
||||
|
||||
options.registry.BlogPostTagSelection = options.Class.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -66,11 +71,11 @@ options.registry.BlogPostTagSelection = options.Class.extend({
|
||||
|
||||
this.blogPostID = parseInt(this.$target[0].dataset.blogId);
|
||||
this.isEditingTags = false;
|
||||
const tags = await this._rpc({
|
||||
model: 'blog.tag',
|
||||
method: 'search_read',
|
||||
args: [[], ['id', 'name', 'display_name', 'post_ids']],
|
||||
});
|
||||
const tags = await this.orm.searchRead(
|
||||
"blog.tag",
|
||||
[],
|
||||
["id", "name", "display_name", "post_ids"]
|
||||
);
|
||||
this.allTagsByID = {};
|
||||
this.tagIDs = [];
|
||||
for (const tag of tags) {
|
||||
|
||||
@@ -37,14 +37,7 @@ const dynamicSnippetBlogPostsOptions = dynamicSnippetOptions.extend({
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_fetchBlogs: function () {
|
||||
return this._rpc({
|
||||
model: 'blog.blog',
|
||||
method: 'search_read',
|
||||
kwargs: {
|
||||
domain: wUtils.websiteDomain(this),
|
||||
fields: ['id', 'name'],
|
||||
}
|
||||
});
|
||||
return this.orm.searchRead("blog.blog", wUtils.websiteDomain(this), ["id", "name"]);
|
||||
},
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -19,6 +19,11 @@ publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
|
||||
'change #new-opp-dialog .contact_name': '_onChangeContactName',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -41,14 +46,10 @@ publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_confirmInterestedPartner: function () {
|
||||
return this._rpc({
|
||||
model: 'crm.lead',
|
||||
method: 'partner_interested',
|
||||
args: [
|
||||
[parseInt($('.interested_partner_assign_form .assign_lead_id').val())],
|
||||
$('.interested_partner_assign_form .comment_interested').val()
|
||||
],
|
||||
}).then(function () {
|
||||
return this.orm.call("crm.lead", "partner_interested", [
|
||||
[parseInt($('.interested_partner_assign_form .assign_lead_id').val())],
|
||||
$('.interested_partner_assign_form .comment_interested').val()
|
||||
]).then(function () {
|
||||
window.location.href = '/my/leads';
|
||||
});
|
||||
},
|
||||
@@ -57,16 +58,12 @@ publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_confirmDesinterestedPartner: function () {
|
||||
return this._rpc({
|
||||
model: 'crm.lead',
|
||||
method: 'partner_desinterested',
|
||||
args: [
|
||||
[parseInt($('.desinterested_partner_assign_form .assign_lead_id').val())],
|
||||
$('.desinterested_partner_assign_form .comment_desinterested').val(),
|
||||
$('.desinterested_partner_assign_form .contacted_desinterested').prop('checked'),
|
||||
$('.desinterested_partner_assign_form .customer_mark_spam').prop('checked'),
|
||||
],
|
||||
}).then(function () {
|
||||
return this.orm.call("crm.lead", "partner_desinterested", [
|
||||
[parseInt($('.desinterested_partner_assign_form .assign_lead_id').val())],
|
||||
$('.desinterested_partner_assign_form .comment_desinterested').val(),
|
||||
$('.desinterested_partner_assign_form .contacted_desinterested').prop('checked'),
|
||||
$('.desinterested_partner_assign_form .customer_mark_spam').prop('checked'),
|
||||
]).then(function () {
|
||||
window.location.href = '/my/leads';
|
||||
});
|
||||
},
|
||||
@@ -76,12 +73,7 @@ publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_changeOppStage: function (leadID, stageID) {
|
||||
return this._rpc({
|
||||
model: 'crm.lead',
|
||||
method: 'write',
|
||||
args: [[leadID], {
|
||||
stage_id: stageID,
|
||||
}],
|
||||
return this.orm.write("crm.lead", [leadID], { stage_id: stageID }, {
|
||||
context: Object.assign({website_partner_assign: 1}),
|
||||
}).then(function () {
|
||||
window.location.reload();
|
||||
@@ -92,10 +84,9 @@ publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_editContact: function () {
|
||||
return this._rpc({
|
||||
model: 'crm.lead',
|
||||
method: 'update_contact_details_from_portal',
|
||||
args: [[parseInt($('.edit_contact_form .opportunity_id').val())], {
|
||||
return this.orm.call("crm.lead", "update_contact_details_from_portal", [
|
||||
[parseInt($('.edit_contact_form .opportunity_id').val())],
|
||||
{
|
||||
partner_name: $('.edit_contact_form .partner_name').val(),
|
||||
phone: $('.edit_contact_form .phone').val(),
|
||||
mobile: $('.edit_contact_form .mobile').val(),
|
||||
@@ -106,8 +97,8 @@ publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
|
||||
zip: $('.edit_contact_form .zip').val(),
|
||||
state_id: parseInt($('.edit_contact_form .state_id').find(':selected').attr('value')),
|
||||
country_id: parseInt($('.edit_contact_form .country_id').find(':selected').attr('value')),
|
||||
}],
|
||||
}).then(function () {
|
||||
},
|
||||
]).then(function () {
|
||||
window.location.reload();
|
||||
});
|
||||
},
|
||||
@@ -116,15 +107,11 @@ publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_createOpportunity: function () {
|
||||
return this._rpc({
|
||||
model: 'crm.lead',
|
||||
method: 'create_opp_portal',
|
||||
args: [{
|
||||
contact_name: $('.new_opp_form .contact_name').val(),
|
||||
title: $('.new_opp_form .title').val(),
|
||||
description: $('.new_opp_form .description').val(),
|
||||
}],
|
||||
}).then(function (response) {
|
||||
return this.orm.call("crm.lead", "create_opp_portal", [{
|
||||
contact_name: $('.new_opp_form .contact_name').val(),
|
||||
title: $('.new_opp_form .title').val(),
|
||||
description: $('.new_opp_form .description').val(),
|
||||
}]).then(function (response) {
|
||||
if (response.errors) {
|
||||
$('#new-opp-dialog .alert').remove();
|
||||
$('#new-opp-dialog div:first').prepend('<div class="alert alert-danger">' + response.errors + '</div>');
|
||||
@@ -139,10 +126,9 @@ publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_editOpportunity: function () {
|
||||
return this._rpc({
|
||||
model: 'crm.lead',
|
||||
method: 'update_lead_portal',
|
||||
args: [[parseInt($('.edit_opp_form .opportunity_id').val())], {
|
||||
return this.orm.call("crm.lead", "update_lead_portal", [
|
||||
[parseInt($('.edit_opp_form .opportunity_id').val())],
|
||||
{
|
||||
date_deadline: this._parse_date($('.edit_opp_form .date_deadline').val()),
|
||||
expected_revenue: parseFloat($('.edit_opp_form .expected_revenue').val()),
|
||||
probability: parseFloat($('.edit_opp_form .probability').val()),
|
||||
@@ -150,8 +136,8 @@ publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
|
||||
activity_summary: $('.edit_opp_form .activity_summary').val(),
|
||||
activity_date_deadline: this._parse_date($('.edit_opp_form .activity_date_deadline').val()),
|
||||
priority: $('input[name="PriorityRadioOptions"]:checked').val(),
|
||||
}],
|
||||
}).then(function () {
|
||||
},
|
||||
]).then(function () {
|
||||
window.location.reload();
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import ajax from "@web/legacy/js/core/ajax";
|
||||
import publicWidget from "@web/legacy/js/public/public_widget";
|
||||
import { jsonrpc } from "@web/core/network/rpc_service";
|
||||
|
||||
// Catch registration form event, because of JS for attendee details
|
||||
var EventRegistrationForm = publicWidget.Widget.extend({
|
||||
@@ -47,7 +47,7 @@ var EventRegistrationForm = publicWidget.Widget.extend({
|
||||
var $button = $(ev.currentTarget).closest('[type="submit"]');
|
||||
const post = this._getPost();
|
||||
$button.attr('disabled', true);
|
||||
return ajax.jsonRpc($form.attr('action'), 'call', post).then(function (modal) {
|
||||
return jsonrpc($form.attr('action'), post).then(function (modal) {
|
||||
var $modal = $(modal);
|
||||
$modal.find('.modal-body > div').removeClass('container'); // retrocompatibility - REMOVE ME in master / saas-19
|
||||
$modal.appendTo(document.body);
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
import options from '@web_editor/js/editor/snippets.options';
|
||||
|
||||
options.registry.WebsiteEvent = options.Class.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
@@ -13,14 +17,7 @@ options.registry.WebsiteEvent = options.Class.extend({
|
||||
this.eventId = this._getEventObjectId();
|
||||
// Only need for one RPC request as the option will be destroyed if a
|
||||
// change is made.
|
||||
const rpcData = await this._rpc({
|
||||
model: 'event.event',
|
||||
method: 'read',
|
||||
args: [
|
||||
[this.eventId],
|
||||
['website_menu'],
|
||||
],
|
||||
});
|
||||
const rpcData = await this.orm.read("event.event", [this.eventId], ["website_menu"]);
|
||||
this.data.reload = this.currentWebsiteUrl;
|
||||
this.websiteMenu = rpcData[0]['website_menu'];
|
||||
return res;
|
||||
@@ -34,11 +31,7 @@ options.registry.WebsiteEvent = options.Class.extend({
|
||||
* @see this.selectClass for parameters
|
||||
*/
|
||||
displaySubmenu(previewMode, widgetValue, params) {
|
||||
return this._rpc({
|
||||
model: 'event.event',
|
||||
method: 'toggle_website_menu',
|
||||
args: [[this.eventId], widgetValue],
|
||||
});
|
||||
return this.orm.call("event.event", "toggle_website_menu", [[this.eventId], widgetValue]);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -13,6 +13,11 @@ publicWidget.registry.boothRegistration = publicWidget.Widget.extend({
|
||||
'click .o_wbooth_registration_confirm': '_onConfirmRegistrationClick',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
start() {
|
||||
this.eventId = parseInt(this.el.dataset.eventId);
|
||||
this.activeBoothCategoryId = false;
|
||||
@@ -35,11 +40,8 @@ publicWidget.registry.boothRegistration = publicWidget.Widget.extend({
|
||||
|
||||
_check_booths_availability(eventBoothIds) {
|
||||
const self = this;
|
||||
return this._rpc({
|
||||
route: "/event/booth/check_availability",
|
||||
params: {
|
||||
event_booth_ids: eventBoothIds,
|
||||
},
|
||||
return this.rpc("/event/booth/check_availability", {
|
||||
event_booth_ids: eventBoothIds,
|
||||
}).then(function (result) {
|
||||
if (result.unavailable_booths.length) {
|
||||
self.$('input[name="event_booth_ids"]').each(function (i, el) {
|
||||
@@ -162,12 +164,9 @@ publicWidget.registry.boothRegistration = publicWidget.Widget.extend({
|
||||
_fetchBoothsAndUpdateUI() {
|
||||
if (this.boothCache[this.activeBoothCategoryId] === undefined) {
|
||||
var self = this;
|
||||
this._rpc({
|
||||
route: '/event/booth_category/get_available_booths',
|
||||
params: {
|
||||
event_id: this.eventId,
|
||||
booth_category_id: this.activeBoothCategoryId,
|
||||
},
|
||||
this.rpc('/event/booth_category/get_available_booths', {
|
||||
event_id: this.eventId,
|
||||
booth_category_id: this.activeBoothCategoryId,
|
||||
}).then(function (result) {
|
||||
self.boothCache[self.activeBoothCategoryId] = result;
|
||||
self._updateUiAfterBoothCategoryChange();
|
||||
|
||||
@@ -12,12 +12,8 @@ options.registry.WebsiteEvent.include({
|
||||
* @see this.selectClass for parameters
|
||||
*/
|
||||
allowRoomCreation(previewMode, widgetValue, params) {
|
||||
this._rpc({
|
||||
model: this.modelName,
|
||||
method: 'write',
|
||||
args: [[this.eventId], {
|
||||
meeting_room_allow_creation: widgetValue
|
||||
}],
|
||||
this.orm.write(this.modelName, [this.eventId], {
|
||||
meeting_room_allow_creation: widgetValue,
|
||||
}).then(() => this.trigger_up('request_save', {reload: true, optionSelector: this.data.selector}));
|
||||
},
|
||||
|
||||
|
||||
@@ -9,15 +9,18 @@ publicWidget.registry.websiteEventCreateMeetingRoom = publicWidget.Widget.extend
|
||||
'click': '_onClickCreate',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
_onClickCreate: async function () {
|
||||
if (!this.$createModal) {
|
||||
const langs = await this._rpc({
|
||||
route: "/event/active_langs",
|
||||
});
|
||||
const langs = await this.rpc("/event/active_langs");
|
||||
|
||||
this.$createModal = $(renderToElement(
|
||||
'event_meet_create_room_modal',
|
||||
|
||||
@@ -12,6 +12,11 @@ publicWidget.registry.websiteEventMeetingRoom = publicWidget.Widget.extend({
|
||||
'click .o_wevent_meeting_room_is_pinned': '_onPinClick',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
start: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.csrf_token = odoo.csrf_token;
|
||||
@@ -34,12 +39,12 @@ publicWidget.registry.websiteEventMeetingRoom = publicWidget.Widget.extend({
|
||||
this.call("dialog", "add", ConfirmationDialog, {
|
||||
body: _t("Are you sure you want to close this room?"),
|
||||
confirm: async () => {
|
||||
await this._rpc({
|
||||
model: "event.meeting.room",
|
||||
method: "write",
|
||||
args: [this.meetingRoomId, { is_published: false }],
|
||||
context: this.context,
|
||||
});
|
||||
await this.orm.write(
|
||||
"event.meeting.room",
|
||||
[this.meetingRoomId],
|
||||
{ is_published: false },
|
||||
{ context: this.context }
|
||||
);
|
||||
|
||||
// remove the element so we do not need to refresh the page
|
||||
this.$el.remove();
|
||||
@@ -58,10 +63,7 @@ publicWidget.registry.websiteEventMeetingRoom = publicWidget.Widget.extend({
|
||||
this.call("dialog", "add", ConfirmationDialog, {
|
||||
body: _t("Are you sure you want to duplicate this room?"),
|
||||
confirm: async () => {
|
||||
await this._rpc({
|
||||
model: "event.meeting.room",
|
||||
method: "copy",
|
||||
args: [this.meetingRoomId],
|
||||
await this.orm.call("event.meeting.room", "copy", [this.meetingRoomId], {
|
||||
context: this.context,
|
||||
});
|
||||
|
||||
@@ -82,12 +84,12 @@ publicWidget.registry.websiteEventMeetingRoom = publicWidget.Widget.extend({
|
||||
const pinnedButtonClass = "o_wevent_meeting_room_pinned";
|
||||
const isPinned = event.currentTarget.classList.contains(pinnedButtonClass);
|
||||
|
||||
await this._rpc({
|
||||
model: 'event.meeting.room',
|
||||
method: 'write',
|
||||
args: [this.meetingRoomId, {is_pinned: !isPinned}],
|
||||
context: this.context,
|
||||
});
|
||||
await this.orm.write(
|
||||
"event.meeting.room",
|
||||
[this.meetingRoomId],
|
||||
{ is_pinned: !isPinned },
|
||||
{ context: this.context }
|
||||
);
|
||||
|
||||
// TDE FIXME: addclass ?
|
||||
if (isPinned) {
|
||||
|
||||
@@ -17,6 +17,7 @@ publicWidget.registry.websiteEventTrackReminder = publicWidget.Widget.extend({
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this._onReminderToggleClick = debounce(this._onReminderToggleClick, 500, true);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -39,12 +40,9 @@ publicWidget.registry.websiteEventTrackReminder = publicWidget.Widget.extend({
|
||||
|
||||
var reminderOnValue = !this.reminderOn;
|
||||
|
||||
this._rpc({
|
||||
route: '/event/track/toggle_reminder',
|
||||
params: {
|
||||
track_id: $trackLink.data('trackId'),
|
||||
set_reminder_on: reminderOnValue,
|
||||
},
|
||||
this.rpc('/event/track/toggle_reminder', {
|
||||
track_id: $trackLink.data('trackId'),
|
||||
set_reminder_on: reminderOnValue,
|
||||
}).then(function (result) {
|
||||
if (result.error && result.error === 'ignored') {
|
||||
self.displayNotification({
|
||||
|
||||
@@ -6,6 +6,11 @@ import publicWidget from "@web/legacy/js/public/public_widget";
|
||||
publicWidget.registry.websiteEventTrackProposalFormTags = publicWidget.Widget.extend({
|
||||
selector: '.o_website_event_track_proposal_form_tags',
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
start: function () {
|
||||
var self = this;
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
@@ -22,12 +27,9 @@ publicWidget.registry.websiteEventTrackProposalFormTags = publicWidget.Widget.ex
|
||||
var self = this;
|
||||
this.$('.o_wetrack_select2_tags').select2(this._select2Wrapper(_t('Select categories'),
|
||||
function () {
|
||||
return self._rpc({
|
||||
route: "/event/track_tag/search_read",
|
||||
params: {
|
||||
fields: ['name', 'category_id'],
|
||||
domain: [],
|
||||
}
|
||||
return self.rpc("/event/track_tag/search_read", {
|
||||
fields: ['name', 'category_id'],
|
||||
domain: [],
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -11,6 +11,11 @@ publicWidget.registry.websiteEventTrackLive = publicWidget.Widget.extend({
|
||||
'video-ended': '_onVideoEnded'
|
||||
}),
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
start: function () {
|
||||
var self = this;
|
||||
return this._super(...arguments).then(function () {
|
||||
@@ -45,11 +50,8 @@ publicWidget.registry.websiteEventTrackLive = publicWidget.Widget.extend({
|
||||
class: 'owevent_track_suggestion_loading position-absolute w-100'
|
||||
}));
|
||||
var self = this;
|
||||
this._rpc({
|
||||
route: '/event_track/get_track_suggestion',
|
||||
params: {
|
||||
track_id: this.$el.data('trackId'),
|
||||
}
|
||||
this.rpc('/event_track/get_track_suggestion', {
|
||||
track_id: this.$el.data('trackId'),
|
||||
}).then(function (suggestion) {
|
||||
self.nextSuggestion = suggestion;
|
||||
self._showSuggestion();
|
||||
|
||||
@@ -36,11 +36,8 @@ var WebsiteEventTrackSuggestionQuiz = Quiz.include({
|
||||
|
||||
_getTrackSuggestion: function () {
|
||||
var self = this;
|
||||
return this._rpc({
|
||||
route: '/event_track/get_track_suggestion',
|
||||
params: {
|
||||
track_id: this.track.id,
|
||||
}
|
||||
return this.rpc('/event_track/get_track_suggestion', {
|
||||
track_id: this.track.id,
|
||||
}).then(function (suggestion) {
|
||||
self.nextSuggestion = suggestion;
|
||||
return Promise.resolve();
|
||||
|
||||
@@ -45,6 +45,8 @@ var Quiz = publicWidget.Widget.extend({
|
||||
this.isMember = data.isMember || false;
|
||||
this.userId = session.user_id;
|
||||
this.redirectURL = encodeURIComponent(document.URL);
|
||||
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -208,13 +210,10 @@ var Quiz = publicWidget.Widget.extend({
|
||||
_submitQuiz: function () {
|
||||
var self = this;
|
||||
|
||||
return this._rpc({
|
||||
route: '/event_track/quiz/submit',
|
||||
params: {
|
||||
event_id: self.track.eventId,
|
||||
track_id: self.track.id,
|
||||
answer_ids: this._getQuizAnswers(),
|
||||
}
|
||||
return this.rpc('/event_track/quiz/submit', {
|
||||
event_id: self.track.eventId,
|
||||
track_id: self.track.id,
|
||||
answer_ids: this._getQuizAnswers(),
|
||||
}).then(function (data) {
|
||||
if (data.error) {
|
||||
self._alertShow(data.error);
|
||||
@@ -257,12 +256,9 @@ var Quiz = publicWidget.Widget.extend({
|
||||
* @private
|
||||
*/
|
||||
_onClickReset: function () {
|
||||
this._rpc({
|
||||
route: '/event_track/quiz/reset',
|
||||
params: {
|
||||
event_id: this.track.eventId,
|
||||
track_id: this.track.id
|
||||
}
|
||||
this.rpc('/event_track/quiz/reset', {
|
||||
event_id: this.track.eventId,
|
||||
track_id: this.track.id
|
||||
}).then(this._resetQuiz.bind(this));
|
||||
},
|
||||
|
||||
|
||||
@@ -33,6 +33,12 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
'submit .js_wforum_submit_form:has(:not(.karma_required).o_wforum_submit_post)': '_onSubmitForm',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -323,9 +329,9 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
_onFlagAlertClick: function (ev) {
|
||||
ev.preventDefault();
|
||||
const elem = ev.currentTarget;
|
||||
this._rpc({
|
||||
route: elem.dataset.href || (elem.getAttribute('href') !== '#' && elem.getAttribute('href')) || elem.closest('form').getAttribute('action'),
|
||||
}).then(data => {
|
||||
this.rpc(
|
||||
elem.dataset.href || (elem.getAttribute('href') !== '#' && elem.getAttribute('href')) || elem.closest('form').getAttribute('action'),
|
||||
).then(data => {
|
||||
if (data.error) {
|
||||
const message = data.error === 'anonymous_user'
|
||||
? _t("Sorry you must be logged to flag a post")
|
||||
@@ -365,9 +371,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
_onVotePostClick: function (ev) {
|
||||
ev.preventDefault();
|
||||
var $btn = $(ev.currentTarget);
|
||||
this._rpc({
|
||||
route: $btn.data('href'),
|
||||
}).then(data => {
|
||||
this.rpc($btn.data('href')).then(data => {
|
||||
if (data.error) {
|
||||
const message = data.error === 'own_post'
|
||||
? _t('Sorry, you cannot vote for your own posts')
|
||||
@@ -465,7 +469,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
ev.preventDefault();
|
||||
const link = ev.currentTarget;
|
||||
const target = link.dataset.target;
|
||||
const data = await this._rpc({ route: link.dataset.href });
|
||||
const data = await this.rpc(link.dataset.href);
|
||||
if (data.error) {
|
||||
const message = data.error === 'anonymous_user'
|
||||
? _t('Sorry, anonymous users cannot choose correct answers.')
|
||||
@@ -500,7 +504,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
_onFavoriteQuestionClick: async function (ev) {
|
||||
ev.preventDefault();
|
||||
const link = ev.currentTarget;
|
||||
const data = await this._rpc({ route: link.dataset.href });
|
||||
const data = await this.rpc(link.dataset.href);
|
||||
link.classList.toggle('opacity-50', !data);
|
||||
link.classList.toggle('opacity-100-hover', !data);
|
||||
const link_icon = link.querySelector('.fa');
|
||||
@@ -517,9 +521,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
var $link = $(ev.currentTarget);
|
||||
var $container = $link.closest('.o_wforum_post_comments_container');
|
||||
|
||||
this._rpc({
|
||||
route: $link.closest('form').attr('action'),
|
||||
}).then(function () {
|
||||
this.rpc($link.closest('form').attr('action')).then(function () {
|
||||
$link.closest('.o_wforum_post_comment').remove();
|
||||
|
||||
var count = $container.find('.o_wforum_post_comment').length;
|
||||
@@ -547,11 +549,9 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
async _onFlagValidatorClick(ev) {
|
||||
ev.preventDefault();
|
||||
const currentTarget = ev.currentTarget;
|
||||
await this._rpc({
|
||||
model: 'forum.post',
|
||||
method: currentTarget.dataset.action,
|
||||
args: [parseInt(currentTarget.dataset.postId)],
|
||||
});
|
||||
await this.orm.call("forum.post", currentTarget.dataset.action, [
|
||||
parseInt(currentTarget.dataset.postId),
|
||||
]);
|
||||
this._findParent(currentTarget, '.o_wforum_flag_alert')?.classList.toggle('d-none');
|
||||
const flaggedButton = currentTarget.parentElement.firstElementChild,
|
||||
child = flaggedButton.firstElementChild,
|
||||
@@ -571,9 +571,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
*/
|
||||
async _onFlagMarkAsOffensiveClick(ev) {
|
||||
ev.preventDefault();
|
||||
const template = await this._rpc({
|
||||
route: $(ev.currentTarget).data('action'),
|
||||
});
|
||||
const template = await this.rpc($(ev.currentTarget).data('action'));
|
||||
this.call("dialog", "add", FlagMarkAsOffensiveDialog, {
|
||||
title: _t("Offensive Post"),
|
||||
body: markup(template),
|
||||
@@ -597,6 +595,11 @@ publicWidget.registry.websiteForumSpam = publicWidget.Widget.extend({
|
||||
'input #spamSearch': '_onSpamSearchInput',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -625,18 +628,14 @@ publicWidget.registry.websiteForumSpam = publicWidget.Widget.extend({
|
||||
_onSpamSearchInput: function (ev) {
|
||||
var self = this;
|
||||
var toSearch = $(ev.currentTarget).val();
|
||||
return this._rpc({
|
||||
model: 'forum.post',
|
||||
method: 'search_read',
|
||||
args: [
|
||||
[['id', 'in', self.spamIDs],
|
||||
'|',
|
||||
['name', 'ilike', toSearch],
|
||||
['content', 'ilike', toSearch]],
|
||||
['name', 'content']
|
||||
],
|
||||
kwargs: {}
|
||||
}).then(function (o) {
|
||||
return this.orm.searchRead(
|
||||
"forum.post",
|
||||
[['id', 'in', self.spamIDs],
|
||||
'|',
|
||||
['name', 'ilike', toSearch],
|
||||
['content', 'ilike', toSearch]],
|
||||
['name', 'content']
|
||||
).then(function (o) {
|
||||
Object.values(o).forEach((r) => {
|
||||
r.content = $('<p>' + $(r.content).html() + '</p>').text().substring(0, 250);
|
||||
});
|
||||
@@ -654,10 +653,11 @@ publicWidget.registry.websiteForumSpam = publicWidget.Widget.extend({
|
||||
var key = this.$('.modal .tab-pane.active').data('key');
|
||||
var $inputs = this.$('.modal .tab-pane.active input.form-check-input:checked');
|
||||
var values = Array.from($inputs).map((o) => parseInt(o.value));
|
||||
return this._rpc({model: 'forum.post',
|
||||
method: 'mark_as_offensive_batch',
|
||||
args: [this.spamIDs, key, values],
|
||||
}).then(function () {
|
||||
return this.orm.call("forum.post", "mark_as_offensive_batch", [
|
||||
this.spamIDs,
|
||||
key,
|
||||
values,
|
||||
]).then(function () {
|
||||
window.location.reload();
|
||||
});
|
||||
},
|
||||
|
||||
@@ -10,6 +10,11 @@ publicWidget.registry.ChatRoom = publicWidget.Widget.extend({
|
||||
'click .o_wjitsi_room_link': '_onChatRoomClick',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* Manage the chat room (Jitsi), update the participant count...
|
||||
*
|
||||
@@ -59,12 +64,7 @@ publicWidget.registry.ChatRoom = publicWidget.Widget.extend({
|
||||
if (this.checkFull) {
|
||||
// maybe we didn't refresh the page for a while and so we might join a room
|
||||
// which is full, so we perform a RPC call to verify that we can really join
|
||||
let isChatRoomFull = await this._rpc({
|
||||
route: '/jitsi/is_full',
|
||||
params: {
|
||||
room_name: this.roomName,
|
||||
},
|
||||
});
|
||||
let isChatRoomFull = await this.rpc('/jitsi/is_full', { room_name: this.roomName });
|
||||
|
||||
if (isChatRoomFull) {
|
||||
window.location.reload();
|
||||
@@ -204,13 +204,10 @@ publicWidget.registry.ChatRoom = publicWidget.Widget.extend({
|
||||
* @param {boolean} joined, true if someone joined the room
|
||||
*/
|
||||
_updateParticipantCount: async function (count, joined) {
|
||||
await this._rpc({
|
||||
route: '/jitsi/update_status',
|
||||
params: {
|
||||
room_name: this.roomName,
|
||||
participant_count: count,
|
||||
joined: joined,
|
||||
},
|
||||
await this.rpc('/jitsi/update_status', {
|
||||
room_name: this.roomName,
|
||||
participant_count: count,
|
||||
joined: joined,
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ var SelectBox = publicWidget.Widget.extend({
|
||||
this._super.apply(this, arguments);
|
||||
this.obj = obj;
|
||||
this.placeholder = placeholder;
|
||||
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -25,13 +27,7 @@ var SelectBox = publicWidget.Widget.extend({
|
||||
willStart: function () {
|
||||
var self = this;
|
||||
var defs = [this._super.apply(this, arguments)];
|
||||
defs.push(this._rpc({
|
||||
model: this.obj,
|
||||
method: 'search_read',
|
||||
kwargs: {
|
||||
fields: ['id', 'name'],
|
||||
},
|
||||
}).then(function (result) {
|
||||
defs.push(this.orm.searchRead(this.obj, [], ["id", "name"]).then(function (result) {
|
||||
self.objects = result.map((val) => {
|
||||
return {id: val.id, text: val.name};
|
||||
});
|
||||
@@ -82,11 +78,7 @@ var SelectBox = publicWidget.Widget.extend({
|
||||
if (this.obj === "utm.campaign"){
|
||||
args.is_auto_campaign = true;
|
||||
}
|
||||
return this._rpc({
|
||||
model: this.obj,
|
||||
method: 'create',
|
||||
args: [args],
|
||||
}).then(function (record) {
|
||||
return this.orm.create(this.obj, [args]).then(function (record) {
|
||||
self.$el.attr('value', record);
|
||||
self.objects.push({'id': record, 'text': name});
|
||||
});
|
||||
@@ -127,6 +119,7 @@ var RecentLinkBox = publicWidget.Widget.extend({
|
||||
this._super.apply(this, arguments);
|
||||
this.link_obj = obj;
|
||||
this.animating_copy = false;
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -236,12 +229,9 @@ var RecentLinkBox = publicWidget.Widget.extend({
|
||||
if (initCode === newCode) {
|
||||
showNewCode(newCode);
|
||||
} else {
|
||||
this._rpc({
|
||||
route: '/website_links/add_code',
|
||||
params: {
|
||||
init_code: initCode,
|
||||
new_code: newCode,
|
||||
},
|
||||
this.rpc('/website_links/add_code', {
|
||||
init_code: initCode,
|
||||
new_code: newCode,
|
||||
}).then(function (result) {
|
||||
showNewCode(result[0].code);
|
||||
}, function () {
|
||||
@@ -282,6 +272,10 @@ var RecentLinkBox = publicWidget.Widget.extend({
|
||||
});
|
||||
|
||||
var RecentLinks = publicWidget.Widget.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
@@ -292,12 +286,9 @@ var RecentLinks = publicWidget.Widget.extend({
|
||||
*/
|
||||
getRecentLinks: function (filter) {
|
||||
var self = this;
|
||||
return this._rpc({
|
||||
route: '/website_links/recent_links',
|
||||
params: {
|
||||
filter: filter,
|
||||
limit: 20,
|
||||
},
|
||||
return this.rpc('/website_links/recent_links', {
|
||||
filter: filter,
|
||||
limit: 20,
|
||||
}).then(function (result) {
|
||||
result.reverse().forEach((link) => {
|
||||
self._addLink(link);
|
||||
@@ -354,6 +345,11 @@ publicWidget.registry.websiteLinks = publicWidget.Widget.extend({
|
||||
'submit #o_website_links_link_tracker_form': '_onFormSubmit',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -493,10 +489,7 @@ publicWidget.registry.websiteLinks = publicWidget.Widget.extend({
|
||||
|
||||
$('#btn_shorten_url').text(_t("Generating link..."));
|
||||
|
||||
this._rpc({
|
||||
route: '/website_links/new',
|
||||
params: params,
|
||||
}).then(function (result) {
|
||||
this.rpc('/website_links/new', params).then(function (result) {
|
||||
if ('error' in result) {
|
||||
// Handle errors
|
||||
if (result.error === 'empty_url') {
|
||||
|
||||
@@ -126,6 +126,11 @@ publicWidget.registry.websiteLinksCharts = publicWidget.Widget.extend({
|
||||
'click .copy-to-clipboard': '_onCopyToClipboardClick',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -221,33 +226,29 @@ publicWidget.registry.websiteLinksCharts = publicWidget.Widget.extend({
|
||||
* @private
|
||||
*/
|
||||
_totalClicks: function () {
|
||||
return this._rpc({
|
||||
model: 'link.tracker.click',
|
||||
method: 'search_count',
|
||||
args: [[this.links_domain]],
|
||||
});
|
||||
return this.orm.searchCount("link.tracker.click", [this.links_domain]);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_clicksByDay: function () {
|
||||
return this._rpc({
|
||||
model: 'link.tracker.click',
|
||||
method: 'read_group',
|
||||
args: [[this.links_domain], ['create_date']],
|
||||
kwargs: {groupby: 'create_date:day'},
|
||||
});
|
||||
return this.orm.readGroup(
|
||||
"link.tracker.click",
|
||||
[this.links_domain],
|
||||
["create_date"],
|
||||
["create_date:day"]
|
||||
);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_clicksByCountry: function () {
|
||||
return this._rpc({
|
||||
model: 'link.tracker.click',
|
||||
method: 'read_group',
|
||||
args: [[this.links_domain], ['country_id']],
|
||||
kwargs: {groupby: 'country_id'},
|
||||
});
|
||||
return this.orm.readGroup(
|
||||
"link.tracker.click",
|
||||
[this.links_domain],
|
||||
["country_id"],
|
||||
["country_id"]
|
||||
);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
@@ -257,12 +258,12 @@ publicWidget.registry.websiteLinksCharts = publicWidget.Widget.extend({
|
||||
const aWeekAgoDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
|
||||
// get the date in the format YYYY-MM-DD.
|
||||
const aWeekAgoString = aWeekAgoDate.toISOString().split("T")[0];
|
||||
return this._rpc({
|
||||
model: 'link.tracker.click',
|
||||
method: 'read_group',
|
||||
args: [[this.links_domain, ["create_date", ">", aWeekAgoString]], ["country_id"]],
|
||||
kwargs: {groupby: 'country_id'},
|
||||
});
|
||||
return this.orm.readGroup(
|
||||
"link.tracker.click",
|
||||
[this.links_domain, ["create_date", ">", aWeekAgoString]],
|
||||
["country_id"],
|
||||
["country_id"]
|
||||
);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
@@ -272,12 +273,12 @@ publicWidget.registry.websiteLinksCharts = publicWidget.Widget.extend({
|
||||
const aMonthAgoDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
|
||||
// get the date in the format YYYY-MM-DD.
|
||||
const aMonthAgoString = aMonthAgoDate.toISOString().split("T")[0];
|
||||
return this._rpc({
|
||||
model: 'link.tracker.click',
|
||||
method: 'read_group',
|
||||
args: [[this.links_domain, ["create_date", ">", aMonthAgoString]], ["country_id"]],
|
||||
kwargs: {groupby: 'country_id'},
|
||||
});
|
||||
return this.orm.readGroup(
|
||||
"link.tracker.click",
|
||||
[this.links_domain, ["create_date", ">", aMonthAgoString]],
|
||||
["country_id"],
|
||||
["country_id"]
|
||||
);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -12,6 +12,11 @@ publicWidget.registry.websiteLinksCodeEditor = publicWidget.Widget.extend({
|
||||
'click .o_website_links_ok_edit': '_onEditCodeFormSubmit',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -58,12 +63,9 @@ publicWidget.registry.websiteLinksCodeEditor = publicWidget.Widget.extend({
|
||||
if (initCode === newCode) {
|
||||
this._showNewCode(newCode);
|
||||
} else {
|
||||
return this._rpc({
|
||||
route: '/website_links/add_code',
|
||||
params: {
|
||||
init_code: initCode,
|
||||
new_code: newCode,
|
||||
},
|
||||
return this.rpc('/website_links/add_code', {
|
||||
init_code: initCode,
|
||||
new_code: newCode,
|
||||
}).then(function (result) {
|
||||
self._showNewCode(result[0].code);
|
||||
}, function () {
|
||||
|
||||
@@ -6,6 +6,11 @@ publicWidget.registry.follow = publicWidget.Widget.extend({
|
||||
selector: '#wrapwrap:has(.js_follow)',
|
||||
disabledInEditableMode: false,
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -34,11 +39,8 @@ publicWidget.registry.follow = publicWidget.Widget.extend({
|
||||
records[model].push(parseInt(el.dataset.id));
|
||||
}
|
||||
|
||||
this._rpc({
|
||||
route: '/website_mail/is_follower',
|
||||
params: {
|
||||
records: records,
|
||||
},
|
||||
this.rpc('/website_mail/is_follower', {
|
||||
records: records,
|
||||
}).then(always).guardedCatch(always);
|
||||
|
||||
// not if editable mode to allow designer to edit
|
||||
@@ -111,14 +113,11 @@ publicWidget.registry.follow = publicWidget.Widget.extend({
|
||||
|
||||
var email = $email.length ? $email.val() : false;
|
||||
if (email || this.isUser) {
|
||||
this._rpc({
|
||||
route: '/website_mail/follow',
|
||||
params: {
|
||||
'id': +$jsFollow.data('id'),
|
||||
'object': $jsFollow.data('object'),
|
||||
'message_is_follower': $jsFollow.attr("data-follow") || "off",
|
||||
'email': email,
|
||||
},
|
||||
this.rpc('/website_mail/follow', {
|
||||
'id': +$jsFollow.data('id'),
|
||||
'object': $jsFollow.data('object'),
|
||||
'message_is_follower': $jsFollow.attr("data-follow") || "off",
|
||||
'email': email,
|
||||
}).then(function (follow) {
|
||||
self._toggleSubscription(follow, email, $jsFollow);
|
||||
});
|
||||
|
||||
@@ -12,13 +12,10 @@ MailGroup.include({
|
||||
// Because it's rendered only once when the admin add the snippets
|
||||
// for the first time, we make a RPC call to setup the widget properly
|
||||
const email = (new URL(document.location.href)).searchParams.get('email');
|
||||
const response = await this._rpc({
|
||||
route: '/group/is_member',
|
||||
params: {
|
||||
'group_id': this.mailgroupId,
|
||||
'email': email,
|
||||
'token': this.token,
|
||||
},
|
||||
const response = await this.rpc('/group/is_member', {
|
||||
'group_id': this.mailgroupId,
|
||||
'email': email,
|
||||
'token': this.token,
|
||||
});
|
||||
|
||||
if (!response) {
|
||||
|
||||
@@ -5,6 +5,11 @@ import options from "@web_editor/js/editor/snippets.options";
|
||||
import wUtils from "@website/js/utils";
|
||||
|
||||
options.registry.Group = options.Class.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -57,13 +62,7 @@ options.registry.Group = options.Class.extend({
|
||||
return;
|
||||
}
|
||||
|
||||
const groupId = await this._rpc({
|
||||
model: 'mail.group',
|
||||
method: 'create',
|
||||
args: [{
|
||||
name: name,
|
||||
}],
|
||||
});
|
||||
const groupId = await this.orm.create("mail.group", [{ name: name }]);
|
||||
|
||||
this.$target.attr("data-id", groupId);
|
||||
return this._rerenderXML();
|
||||
@@ -91,10 +90,6 @@ options.registry.Group = options.Class.extend({
|
||||
* @return {Promise}
|
||||
*/
|
||||
_getMailGroups() {
|
||||
return this._rpc({
|
||||
model: 'mail.group',
|
||||
method: 'name_search',
|
||||
args: [''],
|
||||
});
|
||||
return this.orm.call("mail.group", "name_search", [""]);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -6,6 +6,11 @@ import { renderToElement } from "@web/core/utils/render";
|
||||
import options from "@web_editor/js/editor/snippets.options";
|
||||
|
||||
options.registry.mailing_list_subscribe = options.Class.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -80,12 +85,12 @@ options.registry.mailing_list_subscribe = options.Class.extend({
|
||||
* @override
|
||||
*/
|
||||
async _renderCustomXML(uiFragment) {
|
||||
this.mailingLists = await this._rpc({
|
||||
model: 'mailing.list',
|
||||
method: 'name_search',
|
||||
args: ['', [['is_public', '=', true]]],
|
||||
context: this.options.recordInfo.context,
|
||||
});
|
||||
this.mailingLists = await this.orm.call(
|
||||
"mailing.list",
|
||||
"name_search",
|
||||
["", [["is_public", "=", true]]],
|
||||
{ context: this.options.recordInfo.context }
|
||||
);
|
||||
if (this.mailingLists.length) {
|
||||
const selectEl = uiFragment.querySelector('we-select[data-attribute-name="listId"]');
|
||||
for (const mailingList of this.mailingLists) {
|
||||
|
||||
@@ -17,6 +17,7 @@ publicWidget.registry.subscribe = publicWidget.Widget.extend({
|
||||
init: function () {
|
||||
this._super(...arguments);
|
||||
this._recaptcha = new ReCaptcha();
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -38,12 +39,9 @@ publicWidget.registry.subscribe = publicWidget.Widget.extend({
|
||||
}
|
||||
const always = this._updateView.bind(this);
|
||||
const inputName = this.el.querySelector('input').name;
|
||||
return Promise.all([def, this._rpc({
|
||||
route: '/website_mass_mailing/is_subscriber',
|
||||
params: {
|
||||
'list_id': this._getListId(),
|
||||
'subscription_type': inputName,
|
||||
},
|
||||
return Promise.all([def, this.rpc('/website_mass_mailing/is_subscriber', {
|
||||
'list_id': this._getListId(),
|
||||
'subscription_type': inputName,
|
||||
}).then(always).guardedCatch(always)]);
|
||||
},
|
||||
/**
|
||||
@@ -109,14 +107,11 @@ publicWidget.registry.subscribe = publicWidget.Widget.extend({
|
||||
});
|
||||
return false;
|
||||
}
|
||||
this._rpc({
|
||||
route: '/website_mass_mailing/subscribe',
|
||||
params: {
|
||||
'list_id': this._getListId(),
|
||||
'value': $input.length ? $input.val() : false,
|
||||
'subscription_type': inputName,
|
||||
recaptcha_token_response: tokenObj.token,
|
||||
},
|
||||
this.rpc('/website_mass_mailing/subscribe', {
|
||||
'list_id': this._getListId(),
|
||||
'value': $input.length ? $input.val() : false,
|
||||
'subscription_type': inputName,
|
||||
recaptcha_token_response: tokenObj.token,
|
||||
}).then(function (result) {
|
||||
let toastType = result.toast_type;
|
||||
if (toastType === 'success') {
|
||||
|
||||
@@ -13,6 +13,13 @@ publicWidget.registry.DonationSnippet = publicWidget.Widget.extend({
|
||||
'click .s_donation_donate_btn': '_onClickDonateNowButton',
|
||||
'input #s_donation_range_slider': '_onInputRangeSlider',
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
@@ -81,9 +88,7 @@ publicWidget.registry.DonationSnippet = publicWidget.Widget.extend({
|
||||
* @private
|
||||
*/
|
||||
_displayCurrencies() {
|
||||
return this._rpc({
|
||||
route: '/website/get_current_currency',
|
||||
}).then((result) => {
|
||||
return this.rpc('/website/get_current_currency').then((result) => {
|
||||
this.currency = result;
|
||||
this.$('.s_donation_currency').remove();
|
||||
const $prefilledButtons = this.$('.s_donation_btn, .s_range_bubble');
|
||||
|
||||
@@ -10,6 +10,11 @@ publicWidget.registry.websiteProfile = publicWidget.Widget.extend({
|
||||
'click .validated_email_close': '_onCloseValidatedEmailClick',
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -20,9 +25,8 @@ publicWidget.registry.websiteProfile = publicWidget.Widget.extend({
|
||||
_onSendValidationEmailClick: function (ev) {
|
||||
ev.preventDefault();
|
||||
var $element = $(ev.currentTarget);
|
||||
this._rpc({
|
||||
route: '/profile/send_validation_email',
|
||||
params: {'redirect_url': $element.data('redirect_url')},
|
||||
this.rpc('/profile/send_validation_email', {
|
||||
'redirect_url': $element.data('redirect_url'),
|
||||
}).then(function (data) {
|
||||
if (data) {
|
||||
window.location = $element.data('redirect_url');
|
||||
@@ -34,9 +38,7 @@ publicWidget.registry.websiteProfile = publicWidget.Widget.extend({
|
||||
* @private
|
||||
*/
|
||||
_onCloseValidatedEmailClick: function () {
|
||||
this._rpc({
|
||||
route: '/profile/validate_email/close',
|
||||
});
|
||||
this.rpc('/profile/validate_email/close');
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { KeepLast } from "@web/core/utils/concurrency";
|
||||
import ajax from "@web/legacy/js/core/ajax";
|
||||
import { memoize, uniqueId } from "@web/core/utils/functions";
|
||||
import { throttleForAnimation } from "@web/core/utils/timing";
|
||||
import { insertThousandsSep } from "@web/core/utils/numbers";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { localization } from "@web/core/l10n/localization";
|
||||
import { jsonrpc } from "@web/core/network/rpc_service";
|
||||
|
||||
var VariantMixin = {
|
||||
events: {
|
||||
@@ -70,7 +70,7 @@ var VariantMixin = {
|
||||
const $currentOptionalProduct = $(optionalProduct);
|
||||
const childCombination = this.getSelectedVariantValues($currentOptionalProduct);
|
||||
const productTemplateId = parseInt($currentOptionalProduct.find('.product_template_id').val());
|
||||
ajax.jsonRpc('/website_sale/get_combination_info', 'call', {
|
||||
jsonrpc('/website_sale/get_combination_info', {
|
||||
'product_template_id': productTemplateId,
|
||||
'product_id': this._getProductId($currentOptionalProduct),
|
||||
'combination': childCombination,
|
||||
@@ -89,7 +89,7 @@ var VariantMixin = {
|
||||
);
|
||||
}
|
||||
|
||||
return ajax.jsonRpc('/website_sale/get_combination_info', 'call', {
|
||||
return jsonrpc('/website_sale/get_combination_info', {
|
||||
'product_template_id': parseInt($parent.find('.product_template_id').val()),
|
||||
'product_id': this._getProductId($parent),
|
||||
'combination': combination,
|
||||
@@ -317,7 +317,7 @@ var VariantMixin = {
|
||||
* @param {$.Element} $container the container to look into
|
||||
* @param {integer} productId the product id
|
||||
* @param {integer} productTemplateId the corresponding product template id
|
||||
* @param {boolean} useAjax wether the rpc call should be done using ajax.jsonRpc or using _rpc
|
||||
* @param {boolean} useAjax wether the rpc call should be done using jsonrpc or using _rpc
|
||||
* @returns {Promise} the promise that will be resolved with a {integer} productId
|
||||
*/
|
||||
selectOrCreateProduct: function ($container, productId, productTemplateId, useAjax) {
|
||||
@@ -335,10 +335,7 @@ var VariantMixin = {
|
||||
|
||||
var route = '/sale/create_product_variant';
|
||||
if (useAjax) {
|
||||
productReady = ajax.jsonRpc(route, 'call', params);
|
||||
} else if (Boolean(this._rpc)) {
|
||||
// HACK to combine owl and non owl calls
|
||||
productReady = this._rpc({route: route, params: params});
|
||||
productReady = jsonrpc(route, params);
|
||||
} else {
|
||||
productReady = this.rpc(route, params);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ import "@website/js/editor/snippets.options";
|
||||
import { renderToElement } from "@web/core/utils/render";
|
||||
|
||||
options.registry.WebsiteSaleGridLayout = options.Class.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
@@ -40,36 +44,21 @@ options.registry.WebsiteSaleGridLayout = options.Class.extend({
|
||||
return false;
|
||||
}
|
||||
this.ppg = Math.min(ppg, PPG_LIMIT);
|
||||
return this._rpc({
|
||||
route: '/shop/config/website',
|
||||
params: {
|
||||
'shop_ppg': this.ppg,
|
||||
},
|
||||
});
|
||||
return this.rpc('/shop/config/website', { 'shop_ppg': this.ppg });
|
||||
},
|
||||
/**
|
||||
* @see this.selectClass for params
|
||||
*/
|
||||
setPpr: function (previewMode, widgetValue, params) {
|
||||
this.ppr = parseInt(widgetValue);
|
||||
this._rpc({
|
||||
route: '/shop/config/website',
|
||||
params: {
|
||||
'shop_ppr': this.ppr,
|
||||
},
|
||||
});
|
||||
this.rpc('/shop/config/website', { 'shop_ppr': this.ppr });
|
||||
},
|
||||
/**
|
||||
* @see this.selectClass for params
|
||||
*/
|
||||
setDefaultSort: function (previewMode, widgetValue, params) {
|
||||
this.default_sort = widgetValue;
|
||||
this._rpc({
|
||||
route: '/shop/config/website',
|
||||
params: {
|
||||
'shop_default_sort': this.default_sort,
|
||||
},
|
||||
});
|
||||
this.rpc('/shop/config/website', { 'shop_default_sort': this.default_sort });
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -116,6 +105,11 @@ options.registry.WebsiteSaleProductsItem = options.Class.extend({
|
||||
'click .o_wsale_soptions_menu_sizes td': '_onTableItemClick',
|
||||
}),
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -234,12 +228,9 @@ options.registry.WebsiteSaleProductsItem = options.Class.extend({
|
||||
* @see this.selectClass for params
|
||||
*/
|
||||
changeSequence: function (previewMode, widgetValue, params) {
|
||||
this._rpc({
|
||||
route: '/shop/config/product',
|
||||
params: {
|
||||
product_id: this.productTemplateID,
|
||||
sequence: widgetValue,
|
||||
},
|
||||
this.rpc('/shop/config/product', {
|
||||
product_id: this.productTemplateID,
|
||||
sequence: widgetValue,
|
||||
}).then(() => this._reloadEditable());
|
||||
},
|
||||
|
||||
@@ -437,13 +428,10 @@ options.registry.WebsiteSaleProductsItem = options.Class.extend({
|
||||
var $td = $(ev.currentTarget);
|
||||
var x = $td.index() + 1;
|
||||
var y = $td.parent().index() + 1
|
||||
this._rpc({
|
||||
route: '/shop/config/product',
|
||||
params: {
|
||||
product_id: this.productTemplateID,
|
||||
x: x,
|
||||
y: y,
|
||||
},
|
||||
this.rpc('/shop/config/product', {
|
||||
product_id: this.productTemplateID,
|
||||
x: x,
|
||||
y: y,
|
||||
}).then(() => this._reloadEditable());
|
||||
},
|
||||
_reloadEditable() {
|
||||
@@ -467,6 +455,11 @@ class AttachmentMediaDialog extends MediaDialog {
|
||||
}
|
||||
|
||||
options.registry.WebsiteSaleProductPage = options.Class.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
@@ -489,10 +482,7 @@ options.registry.WebsiteSaleProductPage = options.Class.extend({
|
||||
},
|
||||
|
||||
_updateWebsiteConfig(params) {
|
||||
this._rpc({
|
||||
route: '/shop/config/website',
|
||||
params,
|
||||
}).then(() => this.trigger_up('request_save', {reload: true, optionSelector: this.data.selector}));
|
||||
this.rpc('/shop/config/website', params).then(() => this.trigger_up('request_save', {reload: true, optionSelector: this.data.selector}));
|
||||
},
|
||||
|
||||
_getZoomOptionData() {
|
||||
@@ -593,14 +583,11 @@ options.registry.WebsiteSaleProductPage = options.Class.extend({
|
||||
await this._convertAttachmentToWebp(attachment, extraImageEls[index]);
|
||||
}
|
||||
}
|
||||
this._rpc({
|
||||
route: `/shop/product/extra-images`,
|
||||
params: {
|
||||
images: attachments,
|
||||
product_product_id: this.productProductID,
|
||||
product_template_id: this.productTemplateID,
|
||||
combination_ids: this._getSelectedVariantValues(this.$target.find('.js_add_cart_variants')),
|
||||
}
|
||||
this.rpc(`/shop/product/extra-images`, {
|
||||
images: attachments,
|
||||
product_product_id: this.productProductID,
|
||||
product_template_id: this.productTemplateID,
|
||||
combination_ids: this._getSelectedVariantValues(this.$target.find('.js_add_cart_variants')),
|
||||
}).then(() => {
|
||||
this.trigger_up('request_save', {reload: true, optionSelector: this.data.selector});
|
||||
});
|
||||
@@ -629,18 +616,14 @@ options.registry.WebsiteSaleProductPage = options.Class.extend({
|
||||
ctx.fillStyle = "rgb(255, 255, 255)";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.drawImage(imgEl, 0, 0, imgEl.width, imgEl.height, 0, 0, canvas.width, canvas.height);
|
||||
const [resizedId] = await this._rpc({
|
||||
model: "ir.attachment",
|
||||
method: "create_unique",
|
||||
args: [[{
|
||||
name: webpName,
|
||||
description: size === originalSize ? "" : `resize: ${size}`,
|
||||
datas: canvas.toDataURL("image/webp", 0.75).split(",")[1],
|
||||
res_id: referenceId,
|
||||
res_model: "ir.attachment",
|
||||
mimetype: "image/webp",
|
||||
}]],
|
||||
});
|
||||
const [resizedId] = await this.orm.call("ir.attachment", "create_unique", [[{
|
||||
name: webpName,
|
||||
description: size === originalSize ? "" : `resize: ${size}`,
|
||||
datas: canvas.toDataURL("image/webp", 0.75).split(",")[1],
|
||||
res_id: referenceId,
|
||||
res_model: "ir.attachment",
|
||||
mimetype: "image/webp",
|
||||
}]]);
|
||||
if (size === originalSize) {
|
||||
attachment.original_id = attachment.id;
|
||||
attachment.id = resizedId;
|
||||
@@ -648,18 +631,14 @@ options.registry.WebsiteSaleProductPage = options.Class.extend({
|
||||
attachment.mimetype = "image/webp";
|
||||
}
|
||||
referenceId = referenceId || resizedId; // Keep track of original.
|
||||
await this._rpc({
|
||||
model: "ir.attachment",
|
||||
method: "create_unique",
|
||||
args: [[{
|
||||
name: webpName.replace(/\.webp$/, ".jpg"),
|
||||
description: "format: jpeg",
|
||||
datas: canvas.toDataURL("image/jpeg", 0.75).split(",")[1],
|
||||
res_id: resizedId,
|
||||
res_model: "ir.attachment",
|
||||
mimetype: "image/jpeg",
|
||||
}]],
|
||||
});
|
||||
await this.orm.call("ir.attachment", "create_unique", [[{
|
||||
name: webpName.replace(/\.webp$/, ".jpg"),
|
||||
description: "format: jpeg",
|
||||
datas: canvas.toDataURL("image/jpeg", 0.75).split(",")[1],
|
||||
res_id: resizedId,
|
||||
res_model: "ir.attachment",
|
||||
mimetype: "image/jpeg",
|
||||
}]]);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -667,14 +646,11 @@ options.registry.WebsiteSaleProductPage = options.Class.extend({
|
||||
* Removes all extra-images from the product.
|
||||
*/
|
||||
clearImages: function () {
|
||||
this._rpc({
|
||||
route: `/shop/product/clear-images`,
|
||||
params: {
|
||||
model: this.mode,
|
||||
product_product_id: this.productProductID,
|
||||
product_template_id: this.productTemplateID,
|
||||
combination_ids: this._getSelectedVariantValues(this.$target.find('.js_add_cart_variants')),
|
||||
}
|
||||
this.rpc(`/shop/product/clear-images`, {
|
||||
model: this.mode,
|
||||
product_product_id: this.productProductID,
|
||||
product_template_id: this.productTemplateID,
|
||||
combination_ids: this._getSelectedVariantValues(this.$target.find('.js_add_cart_variants')),
|
||||
}).then(() => {
|
||||
this.trigger_up('request_save', {reload: true, optionSelector: this.data.selector});
|
||||
});
|
||||
@@ -690,21 +666,15 @@ options.registry.WebsiteSaleProductPage = options.Class.extend({
|
||||
2: 'medium',
|
||||
3: 'big',
|
||||
}[widgetValue];
|
||||
this._rpc({
|
||||
route: '/shop/config/website',
|
||||
params: {
|
||||
'product_page_image_spacing': spacing,
|
||||
},
|
||||
this.rpc('/shop/config/website', {
|
||||
'product_page_image_spacing': spacing,
|
||||
}).then(() => this.trigger_up('request_save', {reload: true, optionSelector: this.data.selector}));
|
||||
this.productPageGrid.dataset.image_spacing = spacing;
|
||||
},
|
||||
|
||||
setColumns(previewMode, widgetValue, params) {
|
||||
this._rpc({
|
||||
route: '/shop/config/website',
|
||||
params: {
|
||||
'product_page_grid_columns': widgetValue,
|
||||
},
|
||||
this.rpc('/shop/config/website', {
|
||||
'product_page_grid_columns': widgetValue,
|
||||
}).then(() => this.trigger_up('request_save', {reload: true, optionSelector: this.data.selector}));
|
||||
this.productPageGrid.dataset.grid_columns = widgetValue;
|
||||
},
|
||||
@@ -758,6 +728,11 @@ options.registry.WebsiteSaleProductPage = options.Class.extend({
|
||||
});
|
||||
|
||||
options.registry.WebsiteSaleProductAttribute = options.Class.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -770,12 +745,9 @@ options.registry.WebsiteSaleProductAttribute = options.Class.extend({
|
||||
* @see this.selectClass for params
|
||||
*/
|
||||
setDisplayType: function (previewMode, widgetValue, params) {
|
||||
this._rpc({
|
||||
route: '/shop/config/attribute',
|
||||
params: {
|
||||
attribute_id: this.attributeID,
|
||||
display_type: widgetValue,
|
||||
},
|
||||
this.rpc('/shop/config/attribute', {
|
||||
attribute_id: this.attributeID,
|
||||
display_type: widgetValue,
|
||||
}).then(() => this.trigger_up('request_save', {reload: true, optionSelector: this.data.selector}));
|
||||
},
|
||||
|
||||
@@ -803,6 +775,10 @@ options.registry.SnippetSave.include({
|
||||
});
|
||||
|
||||
options.registry.ReplaceMedia.include({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.orm = this.bindService("orm");
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -821,11 +797,7 @@ options.registry.ReplaceMedia.include({
|
||||
if (this.recordModel === "product.image") {
|
||||
// Unlink the "product.image" record as it is not the main product
|
||||
// image.
|
||||
await this._rpc({
|
||||
model: "product.image",
|
||||
method: "unlink",
|
||||
args: [[this.recordId]],
|
||||
});
|
||||
await this.orm.unlink("product.image", [this.recordId]);
|
||||
}
|
||||
this.$target[0].remove();
|
||||
this.trigger_up("request_save", {reload: true, optionSelector: "#product_detail_main"});
|
||||
@@ -835,13 +807,10 @@ options.registry.ReplaceMedia.include({
|
||||
*
|
||||
*/
|
||||
async setPosition(previewMode, widgetValue, params) {
|
||||
this._rpc({
|
||||
route: '/shop/product/resequence-image',
|
||||
params: {
|
||||
image_res_model: this.recordModel,
|
||||
image_res_id: this.recordId,
|
||||
move: widgetValue,
|
||||
},
|
||||
this.rpc('/shop/product/resequence-image', {
|
||||
image_res_model: this.recordModel,
|
||||
image_res_id: this.recordId,
|
||||
move: widgetValue,
|
||||
}).then(() => this.trigger_up('request_save', {reload: true, optionSelector: '#product_detail_main'}));
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -60,6 +60,8 @@ export const WebsiteSale = publicWidget.Widget.extend(VariantMixin, cartHandlerM
|
||||
|
||||
delete this.events['change .main_product:not(.in_cart) input.js_quantity'];
|
||||
delete this.events['change [data-attribute_exclusions]'];
|
||||
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -202,14 +204,11 @@ export const WebsiteSale = publicWidget.Widget.extend(VariantMixin, cartHandlerM
|
||||
});
|
||||
$input.data('update_change', true);
|
||||
|
||||
this._rpc({
|
||||
route: "/shop/cart/update_json",
|
||||
params: {
|
||||
line_id: line_id,
|
||||
product_id: parseInt($input.data('product-id'), 10),
|
||||
set_qty: value,
|
||||
display: true,
|
||||
},
|
||||
this.rpc("/shop/cart/update_json", {
|
||||
line_id: line_id,
|
||||
product_id: parseInt($input.data('product-id'), 10),
|
||||
set_qty: value,
|
||||
display: true,
|
||||
}).then(function (data) {
|
||||
$input.data('update_change', false);
|
||||
var check_value = parseInt($input.val() || 0, 10);
|
||||
@@ -239,11 +238,8 @@ export const WebsiteSale = publicWidget.Widget.extend(VariantMixin, cartHandlerM
|
||||
if (!$("#country_id").val()) {
|
||||
return;
|
||||
}
|
||||
this._rpc({
|
||||
route: "/shop/country_infos/" + $("#country_id").val(),
|
||||
params: {
|
||||
mode: $("#country_id").attr('mode'),
|
||||
},
|
||||
this.rpc("/shop/country_infos/" + $("#country_id").val(), {
|
||||
mode: $("#country_id").attr('mode'),
|
||||
}).then(function (data) {
|
||||
// placeholder phone_code
|
||||
$("input[name='phone']").attr('placeholder', data.phone_code !== 0 ? '+'+ data.phone_code : '');
|
||||
@@ -772,11 +768,8 @@ publicWidget.registry.WebsiteSaleLayout = publicWidget.Widget.extend({
|
||||
var clickedValue = $(ev.target).val();
|
||||
var isList = clickedValue === 'list';
|
||||
if (!this.editableMode) {
|
||||
this._rpc({
|
||||
route: '/shop/save_shop_layout_mode',
|
||||
params: {
|
||||
'layout_mode': isList ? 'list' : 'grid',
|
||||
},
|
||||
this.rpc('/shop/save_shop_layout_mode', {
|
||||
'layout_mode': isList ? 'list' : 'grid',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
|
||||
"click .o_payment_option_card": "_onClickPaymentMethod"
|
||||
},
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.rpc = this.bindService("rpc");
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -53,9 +58,7 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
|
||||
* @private
|
||||
*/
|
||||
_getCurrentLocation: async function () {
|
||||
const data = await this._rpc({
|
||||
route: "/shop/access_point/get",
|
||||
})
|
||||
const data = await this.rpc("/shop/access_point/get");
|
||||
const carriers = document.querySelectorAll('.o_delivery_carrier_select')
|
||||
for (let carrier of carriers) {
|
||||
const deliveryType = carrier.querySelector('input[type="radio"]').getAttribute("delivery_type");
|
||||
@@ -125,11 +128,8 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
|
||||
* @params {Object} carrier: The carrier element
|
||||
*/
|
||||
_getCarrierRateShipment: async function(carrierInput) {
|
||||
const result = await this._rpc({
|
||||
route: '/shop/carrier_rate_shipment',
|
||||
params: {
|
||||
'carrier_id': carrierInput.value,
|
||||
}
|
||||
const result = await this.rpc('/shop/carrier_rate_shipment', {
|
||||
'carrier_id': carrierInput.value,
|
||||
});
|
||||
this._handleCarrierUpdateResultBadge(result);
|
||||
},
|
||||
@@ -138,11 +138,8 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
|
||||
* @param {Object} result
|
||||
*/
|
||||
_handleCarrierUpdateResult: async function (carrierInput) {
|
||||
const result = await this._rpc({
|
||||
route: '/shop/update_carrier',
|
||||
params: {
|
||||
'carrier_id': carrierInput.value,
|
||||
},
|
||||
const result = await this.rpc('/shop/update_carrier', {
|
||||
'carrier_id': carrierInput.value,
|
||||
})
|
||||
this.result = result;
|
||||
this._handleCarrierUpdateResultBadge(result);
|
||||
@@ -216,11 +213,8 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
|
||||
|
||||
_checkCarrier: async function (ev, carrier_id) {
|
||||
ev.stopPropagation();
|
||||
await this.keepLast.add(this._rpc({
|
||||
route: '/shop/update_carrier',
|
||||
params: {
|
||||
carrier_id: carrier_id,
|
||||
},
|
||||
await this.keepLast.add(this.rpc('/shop/update_carrier', {
|
||||
carrier_id: carrier_id,
|
||||
}))
|
||||
var closestDocElement = ev.currentTarget.closest('.o_delivery_carrier_select');
|
||||
var radio = closestDocElement.querySelector('input[type="radio"]');
|
||||
@@ -240,11 +234,8 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
|
||||
return;
|
||||
}
|
||||
const carrier_id = carrierChecked?.querySelector('input')?.value;
|
||||
const result = await this._rpc({
|
||||
route: '/shop/update_carrier',
|
||||
params: {
|
||||
'carrier_id': carrier_id,
|
||||
},
|
||||
const result = await this.rpc('/shop/update_carrier', {
|
||||
'carrier_id': carrier_id,
|
||||
})
|
||||
this._enableButton(result.status);
|
||||
},
|
||||
@@ -311,11 +302,8 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
|
||||
*/
|
||||
_onClickRemoveLocation: async function (ev) {
|
||||
ev.stopPropagation();
|
||||
await this._rpc({
|
||||
route: "/shop/access_point/set",
|
||||
params: {
|
||||
access_point_encoded: null,
|
||||
},
|
||||
await this.rpc("/shop/access_point/set", {
|
||||
access_point_encoded: null,
|
||||
})
|
||||
const deliveryTypeInput = ev.currentTarget.closest(".o_delivery_carrier_select").querySelector('input[name="delivery_type"]');
|
||||
const deliveryTypeId = deliveryTypeInput.value;
|
||||
@@ -346,9 +334,7 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
|
||||
const deliveryTypeId = deliveryTypeInput.value;
|
||||
await this._checkCarrier(ev,deliveryTypeId)
|
||||
$(renderToElement(deliveryType + "_pickup_location_loading")).appendTo($(modal));
|
||||
const data = await this._rpc({
|
||||
route: "/shop/access_point/close_locations",
|
||||
})
|
||||
const data = await this.rpc("/shop/access_point/close_locations");
|
||||
if (modal.firstChild){
|
||||
modal.firstChild.remove();
|
||||
}
|
||||
@@ -398,23 +384,17 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
|
||||
await this._checkCarrier(ev,carrierId)
|
||||
const modal = ev.target.closest(".o_list_pickup_locations");
|
||||
const encodedLocation = ev.target.previousElementSibling.innerText;
|
||||
await this._rpc({
|
||||
route: "/shop/access_point/set",
|
||||
params: {
|
||||
access_point_encoded: encodedLocation,
|
||||
},
|
||||
await this.rpc("/shop/access_point/set", {
|
||||
access_point_encoded: encodedLocation,
|
||||
})
|
||||
while (modal.firstChild) {
|
||||
modal.lastChild.remove();
|
||||
}
|
||||
await this._getCurrentLocation();
|
||||
document.querySelectorAll('.error_no_pick_up_point').forEach(el => el.remove());
|
||||
const result = await this._rpc({
|
||||
route: '/shop/update_carrier',
|
||||
params: {
|
||||
'carrier_id': carrierId,
|
||||
'no_reset_access_point_address': true,
|
||||
},
|
||||
const result = await this.rpc('/shop/update_carrier', {
|
||||
'carrier_id': carrierId,
|
||||
'no_reset_access_point_address': true,
|
||||
})
|
||||
this._enableButton(result.status);
|
||||
},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user