[IMP] *: unify sprintf and gettext
Improve gettext to directly handle value injection within translations, removing the need for sprintf. closes odoo/odoo#123932 Related: odoo/enterprise#45370 Signed-off-by: Samuel Degueldre (sad) <sad@odoo.com>
This commit is contained in:
+1
-2
@@ -7,7 +7,6 @@ import { getNextTabableElement, getPreviousTabableElement } from "@web/core/util
|
|||||||
import { usePosition } from "@web/core/position_hook";
|
import { usePosition } from "@web/core/position_hook";
|
||||||
import { getActiveHotkey } from "@web/core/hotkeys/hotkey_service";
|
import { getActiveHotkey } from "@web/core/hotkeys/hotkey_service";
|
||||||
import { shallowEqual } from "@web/core/utils/arrays";
|
import { shallowEqual } from "@web/core/utils/arrays";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { AutoComplete } from "@web/core/autocomplete/autocomplete";
|
import { AutoComplete } from "@web/core/autocomplete/autocomplete";
|
||||||
import { useRecordObserver } from "@web/model/relational_model/utils";
|
import { useRecordObserver } from "@web/model/relational_model/utils";
|
||||||
@@ -272,7 +271,7 @@ export class AnalyticDistribution extends Component {
|
|||||||
if (searchTerm.length) {
|
if (searchTerm.length) {
|
||||||
dynamicFilters = [
|
dynamicFilters = [
|
||||||
{
|
{
|
||||||
description: sprintf(this.env._t("Quick search: %s"), searchTerm),
|
description: this.env._t("Quick search: %s", searchTerm),
|
||||||
domain: this.searchAnalyticDomain(searchTerm),
|
domain: this.searchAnalyticDomain(searchTerm),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { computeScore } from "./password_policy";
|
import { computeScore } from "./password_policy";
|
||||||
|
|
||||||
const { Component, xml } = owl;
|
const { Component, xml } = owl;
|
||||||
|
|
||||||
export class Meter extends Component {
|
export class Meter extends Component {
|
||||||
get title() {
|
get title() {
|
||||||
return sprintf(
|
return this.env._t(
|
||||||
this.env._t(
|
"Required: %s\n\nHint: to increase password strength, increase length, use multiple words, and use non-letter characters.",
|
||||||
"Required: %s\n\nHint: to increase password strength, increase length, use multiple words, and use non-letter characters."
|
|
||||||
),
|
|
||||||
String(this.props.required) || this.env._t("no requirements")
|
String(this.props.required) || this.env._t("no requirements")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
export class Policy {
|
export class Policy {
|
||||||
/**
|
/**
|
||||||
@@ -27,13 +26,13 @@ export class ConcretePolicy extends Policy {
|
|||||||
toString() {
|
toString() {
|
||||||
const msgs = [];
|
const msgs = [];
|
||||||
if (this.minlength > 1) {
|
if (this.minlength > 1) {
|
||||||
msgs.push(sprintf(_t("at least %s characters"), this.minlength));
|
msgs.push(_t("at least %s characters", this.minlength));
|
||||||
}
|
}
|
||||||
if (this.minwords > 1) {
|
if (this.minwords > 1) {
|
||||||
msgs.push(sprintf(_t("at least %s words"), this.minwords));
|
msgs.push(_t("at least %s words", this.minwords));
|
||||||
}
|
}
|
||||||
if (this.minclasses > 1) {
|
if (this.minclasses > 1) {
|
||||||
msgs.push(sprintf(_t("at least %s character classes"), this.minclasses));
|
msgs.push(_t("at least %s character classes", this.minclasses));
|
||||||
}
|
}
|
||||||
return msgs.join(", ");
|
return msgs.join(", ");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import Widget from "@web/legacy/js/core/widget";
|
import Widget from "@web/legacy/js/core/widget";
|
||||||
import { computeScore } from "@auth_password_policy/password_policy";
|
import { computeScore } from "@auth_password_policy/password_policy";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { translationIsReady, _t } from "@web/core/l10n/translation";
|
import { translationIsReady, _t } from "@web/core/l10n/translation";
|
||||||
|
|
||||||
export default Widget.extend({
|
export default Widget.extend({
|
||||||
@@ -27,12 +26,10 @@ export default Widget.extend({
|
|||||||
},
|
},
|
||||||
start() {
|
start() {
|
||||||
var helpMessage = _t(
|
var helpMessage = _t(
|
||||||
"Required: %s.\n\nHint: increase length, use multiple words and use non-letter characters to increase your password's strength."
|
"Required: %s.\n\nHint: increase length, use multiple words and use non-letter characters to increase your password's strength.",
|
||||||
);
|
String(this._required) || _t("no requirements")
|
||||||
this.el.setAttribute(
|
|
||||||
"title",
|
|
||||||
sprintf(helpMessage, String(this._required) || _t("no requirements"))
|
|
||||||
);
|
);
|
||||||
|
this.el.setAttribute("title", helpMessage);
|
||||||
return this._super().then(function () {});
|
return this._super().then(function () {});
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
import { Component, onWillStart, onMounted, useState } from "@odoo/owl";
|
import { Component, onWillStart, onMounted, useState } from "@odoo/owl";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { FileInput } from "@web/core/file_input/file_input";
|
import { FileInput } from "@web/core/file_input/file_input";
|
||||||
import { useImportModel } from "../import_model";
|
import { useImportModel } from "../import_model";
|
||||||
import { ImportDataContent } from "../import_data_content/import_data_content";
|
import { ImportDataContent } from "../import_data_content/import_data_content";
|
||||||
@@ -171,10 +170,9 @@ export class ImportAction extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isTest && res.ids.length) {
|
if (!isTest && res.ids.length) {
|
||||||
this.notification.add(
|
this.notification.add(this.env._t("%s records successfully imported", res.ids.length), {
|
||||||
sprintf(this.env._t("%s records successfully imported"), res.ids.length),
|
type: "success",
|
||||||
{ type: "success" }
|
});
|
||||||
);
|
|
||||||
this.exit();
|
this.exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
import { Component, useState, onWillStart } from "@odoo/owl";
|
import { Component, useState, onWillStart } from "@odoo/owl";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
export class ImportDataOptions extends Component {
|
export class ImportDataOptions extends Component {
|
||||||
static template = "ImportDataOptions";
|
static template = "ImportDataOptions";
|
||||||
@@ -45,7 +44,7 @@ export class ImportDataOptions extends Component {
|
|||||||
const fields = await this.orm.call(this.currentModel, "fields_get");
|
const fields = await this.orm.call(this.currentModel, "fields_get");
|
||||||
const selection = fields[this.props.fieldInfo.name].selection.map((opt) => [
|
const selection = fields[this.props.fieldInfo.name].selection.map((opt) => [
|
||||||
opt[0],
|
opt[0],
|
||||||
sprintf(_t("Set to: %s"), opt[1]),
|
_t("Set to: %s", opt[1]),
|
||||||
]);
|
]);
|
||||||
options.push(...selection);
|
options.push(...selection);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { registry } from "@web/core/registry";
|
|||||||
import { pick } from "@web/core/utils/objects";
|
import { pick } from "@web/core/utils/objects";
|
||||||
import { groupBy, sortBy } from "@web/core/utils/arrays";
|
import { groupBy, sortBy } from "@web/core/utils/arrays";
|
||||||
import { memoize } from "@web/core/utils/functions";
|
import { memoize } from "@web/core/utils/functions";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { useState } from "@odoo/owl";
|
import { useState } from "@odoo/owl";
|
||||||
import { ImportBlockUI } from "./import_block_ui";
|
import { ImportBlockUI } from "./import_block_ui";
|
||||||
|
|
||||||
@@ -281,8 +280,8 @@ export class BaseImportModel {
|
|||||||
if (!importRes.hasError) {
|
if (!importRes.hasError) {
|
||||||
if (importRes.nextrow) {
|
if (importRes.nextrow) {
|
||||||
this._addMessage("warning", [
|
this._addMessage("warning", [
|
||||||
sprintf(
|
_t(
|
||||||
_t("Click 'Resume' to proceed with the import, resuming at line %s."),
|
"Click 'Resume' to proceed with the import, resuming at line %s.",
|
||||||
importRes.nextrow + 1
|
importRes.nextrow + 1
|
||||||
),
|
),
|
||||||
_t("You can test or reload your file before resuming the import."),
|
_t("You can test or reload your file before resuming the import."),
|
||||||
@@ -445,8 +444,8 @@ export class BaseImportModel {
|
|||||||
if (error.record !== undefined) {
|
if (error.record !== undefined) {
|
||||||
this._addMessage("danger", [
|
this._addMessage("danger", [
|
||||||
error.rows.from === error.rows.to
|
error.rows.from === error.rows.to
|
||||||
? sprintf(_t('Error at row %s: "%s"'), error.record, error.message)
|
? _t('Error at row %s: "%s"', error.record, error.message)
|
||||||
: sprintf(_t("%s at multiple rows"), error.message),
|
: _t("%s at multiple rows", error.message),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
// Handle global errors.
|
// Handle global errors.
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
import { Dropdown } from "@web/core/dropdown/dropdown";
|
import { Dropdown } from "@web/core/dropdown/dropdown";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { useAutofocus, useService } from "@web/core/utils/hooks";
|
import { useAutofocus, useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
const { Component, useState } = owl;
|
const { Component, useState } = owl;
|
||||||
const cogMenuRegistry = registry.category("cogMenu");
|
const cogMenuRegistry = registry.category("cogMenu");
|
||||||
@@ -63,7 +62,7 @@ export class AddToBoard extends Component {
|
|||||||
this.notification.add(
|
this.notification.add(
|
||||||
this.env._t("Please refresh your browser for the changes to take effect."),
|
this.env._t("Please refresh your browser for the changes to take effect."),
|
||||||
{
|
{
|
||||||
title: sprintf(this.env._t(`"%s" added to dashboard`), this.state.name),
|
title: this.env._t("“%s” added to dashboard", this.state.name),
|
||||||
type: "warning",
|
type: "warning",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { INTERVAL_OPTIONS } from "@web/search/utils/dates";
|
import { INTERVAL_OPTIONS } from "@web/search/utils/dates";
|
||||||
import { KanbanColumnQuickCreate } from "@web/views/kanban/kanban_column_quick_create";
|
import { KanbanColumnQuickCreate } from "@web/views/kanban/kanban_column_quick_create";
|
||||||
|
|
||||||
@@ -12,7 +11,7 @@ export class ForecastKanbanColumnQuickCreate extends KanbanColumnQuickCreate {
|
|||||||
get relatedFieldName() {
|
get relatedFieldName() {
|
||||||
const { granularity = "month" } = this.props.groupByField;
|
const { granularity = "month" } = this.props.groupByField;
|
||||||
const { description } = INTERVAL_OPTIONS[granularity];
|
const { description } = INTERVAL_OPTIONS[granularity];
|
||||||
return sprintf(_t("Add next %s"), description.toLocaleLowerCase());
|
return _t("Add next %s", description.toLocaleLowerCase());
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { Component, onWillStart, onWillUnmount, useState } from "@odoo/owl";
|
|||||||
import { deserializeDateTime } from "@web/core/l10n/dates";
|
import { deserializeDateTime } from "@web/core/l10n/dates";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { useBus, useService } from "@web/core/utils/hooks";
|
import { useBus, useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
const { Duration } = luxon;
|
const { Duration } = luxon;
|
||||||
|
|
||||||
@@ -73,7 +72,7 @@ export class GreetingMessage extends Component {
|
|||||||
.toFormat("hh-mm")
|
.toFormat("hh-mm")
|
||||||
.split("-");
|
.split("-");
|
||||||
|
|
||||||
this.hours_today = sprintf(this.env._t("%(hours)s hours, %(minutes)s minutes"), {
|
this.hours_today = this.env._t("%(hours)s hours, %(minutes)s minutes", {
|
||||||
hours: duration[0],
|
hours: duration[0],
|
||||||
minutes: duration[1],
|
minutes: duration[1],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { personaService, PersonaService } from "@mail/core/common/persona_servic
|
|||||||
import { deserializeDateTime } from "@web/core/l10n/dates";
|
import { deserializeDateTime } from "@web/core/l10n/dates";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { patch } from "@web/core/utils/patch";
|
import { patch } from "@web/core/utils/patch";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
const { DateTime } = luxon;
|
const { DateTime } = luxon;
|
||||||
|
|
||||||
@@ -35,6 +34,6 @@ patch(PersonaService.prototype, {
|
|||||||
// const fdate = date.toLocaleString(DateTime.TIME_SHORT);
|
// const fdate = date.toLocaleString(DateTime.TIME_SHORT);
|
||||||
const fdate = date.toLocaleString(DateTime.DATE_MED);
|
const fdate = date.toLocaleString(DateTime.DATE_MED);
|
||||||
// const formattedDate = date.toLocaleDateString(localeCode, options);
|
// const formattedDate = date.toLocaleDateString(localeCode, options);
|
||||||
return sprintf(_t("Out of office until %s"), fdate);
|
return _t("Out of office until %s", fdate);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import { AlertDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
import { AlertDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
async function actionGetDrive(env, action, type) {
|
async function actionGetDrive(env, action, type) {
|
||||||
const { drive_id, sign_host: host } = action.params;
|
const { drive_id, sign_host: host } = action.params;
|
||||||
@@ -47,9 +46,7 @@ async function actionGetDrive(env, action, type) {
|
|||||||
unauthorized: _t("Unauthorized"),
|
unauthorized: _t("Unauthorized"),
|
||||||
};
|
};
|
||||||
dialog.add(AlertDialog, {
|
dialog.add(AlertDialog, {
|
||||||
body:
|
body: typeToErrorMessage[result.error] || _t("Unexpected error: “%s”", result.error),
|
||||||
typeToErrorMessage[result.error] ||
|
|
||||||
sprintf(_t(`Unexpected error: "%s"`), result.error),
|
|
||||||
});
|
});
|
||||||
} else if (result[key]) {
|
} else if (result[key]) {
|
||||||
await orm.call("l10n_eg_edi.thumb.drive", method, [[drive_id], result[key]]).catch(() => {
|
await orm.call("l10n_eg_edi.thumb.drive", method, [[drive_id], result[key]]).catch(() => {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { PosStore } from "@point_of_sale/app/store/pos_store";
|
|||||||
import { Order, Orderline } from "@point_of_sale/app/store/models";
|
import { Order, Orderline } from "@point_of_sale/app/store/models";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { patch } from "@web/core/utils/patch";
|
import { patch } from "@web/core/utils/patch";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
||||||
|
|
||||||
patch(PosStore.prototype, {
|
patch(PosStore.prototype, {
|
||||||
@@ -13,7 +12,7 @@ patch(PosStore.prototype, {
|
|||||||
if (!this.company.country) {
|
if (!this.company.country) {
|
||||||
this.env.services.popup.add(ErrorPopup, {
|
this.env.services.popup.add(ErrorPopup, {
|
||||||
title: _t("Missing Country"),
|
title: _t("Missing Country"),
|
||||||
body: sprintf(_t("The company %s doesn't have a country set."), this.company.name),
|
body: _t("The company %s doesn't have a country set.", this.company.name),
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { useState } from "@odoo/owl";
|
import { useState } from "@odoo/owl";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
@@ -37,7 +37,7 @@ export function useKEProxy({onAllSent}) {
|
|||||||
let progress; // keep track of when an error occurs
|
let progress; // keep track of when an error occurs
|
||||||
for (const index in invoices) {
|
for (const index in invoices) {
|
||||||
let { move_id, messages, proxy_address, company_vat, name } = invoices[index];
|
let { move_id, messages, proxy_address, company_vat, name } = invoices[index];
|
||||||
state.message = sprintf(_t("Posting invoice: %s"), name);
|
state.message = _t("Posting invoice: %s", name);
|
||||||
try {
|
try {
|
||||||
progress = 'postToDevice';
|
progress = 'postToDevice';
|
||||||
let deviceResponse = await http.post(
|
let deviceResponse = await http.post(
|
||||||
@@ -59,16 +59,16 @@ export function useKEProxy({onAllSent}) {
|
|||||||
state.error = true;
|
state.error = true;
|
||||||
switch (progress) {
|
switch (progress) {
|
||||||
case 'postToDevice':
|
case 'postToDevice':
|
||||||
state.message = sprintf(_t("Error trying to connect to the middleware. Is the middleware running? \n Error message: %s"), e.message);
|
state.message = _t("Error trying to connect to the middleware. Is the middleware running? \n Error message: %s", e.message);
|
||||||
break;
|
break;
|
||||||
case 'parseResponse':
|
case 'parseResponse':
|
||||||
state.message = sprintf(_t("Posting the invoice %s has failed with the message: \n %s"), name, e.message);
|
state.message = _t("Posting the invoice %s has failed with the message: \n %s", name, e.message);
|
||||||
break;
|
break;
|
||||||
case 'updateInvoice':
|
case 'updateInvoice':
|
||||||
state.message = sprintf(_t("Error trying to connect to Odoo. Check your internet connection. Error message: %s"), e.message);
|
state.message = _t("Error trying to connect to Odoo. Check your internet connection. Error message: %s", e.message);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
state.message = sprintf(_t("Unexpected Error:\n %s"), e.message);
|
state.message = _t("Unexpected Error:\n %s", e.message);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_d
|
|||||||
import { useFileViewer } from "@web/core/file_viewer/file_viewer_hook";
|
import { useFileViewer } from "@web/core/file_viewer/file_viewer_hook";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { url } from "@web/core/utils/urls";
|
import { url } from "@web/core/utils/urls";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,7 +82,7 @@ export class AttachmentList extends Component {
|
|||||||
return this.props.unlinkAttachment(attachment);
|
return this.props.unlinkAttachment(attachment);
|
||||||
}
|
}
|
||||||
this.dialog.add(ConfirmationDialog, {
|
this.dialog.add(ConfirmationDialog, {
|
||||||
body: sprintf(_t('Do you really want to delete "%s"?'), attachment.filename),
|
body: _t('Do you really want to delete "%s"?', attachment.filename),
|
||||||
cancel: () => {},
|
cancel: () => {},
|
||||||
confirm: () => this.onConfirmUnlink(attachment),
|
confirm: () => this.onConfirmUnlink(attachment),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import {
|
|||||||
import { browser } from "@web/core/browser/browser";
|
import { browser } from "@web/core/browser/browser";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { FileUploader } from "@web/views/fields/file_handler";
|
import { FileUploader } from "@web/views/fields/file_handler";
|
||||||
|
|
||||||
const EDIT_CLICK_TYPE = {
|
const EDIT_CLICK_TYPE = {
|
||||||
@@ -82,9 +81,7 @@ export class Composer extends Component {
|
|||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
this.SEND_KEYBIND_TO_SEND = markup(
|
this.SEND_KEYBIND_TO_SEND = markup(
|
||||||
sprintf(_t("<samp>%(send_keybind)s</samp><i> to send</i>"), {
|
_t("<samp>%(send_keybind)s</samp><i> to send</i>", { send_keybind: this.sendKeybind })
|
||||||
send_keybind: this.sendKeybind,
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
this.KEYBOARD = {
|
this.KEYBOARD = {
|
||||||
NONE: "None",
|
NONE: "None",
|
||||||
@@ -211,13 +208,9 @@ export class Composer extends Component {
|
|||||||
}
|
}
|
||||||
if (this.thread) {
|
if (this.thread) {
|
||||||
if (this.thread.type === "channel") {
|
if (this.thread.type === "channel") {
|
||||||
return sprintf(_t("Message #%(thread name)s…"), {
|
return _t("Message #%(thread name)s…", { "thread name": this.thread.displayName });
|
||||||
"thread name": this.thread.displayName,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return sprintf(_t("Message %(thread name)s…"), {
|
return _t("Message %(thread name)s…", { "thread name": this.thread.displayName });
|
||||||
"thread name": this.thread.displayName,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -233,10 +226,8 @@ export class Composer extends Component {
|
|||||||
|
|
||||||
get CANCEL_OR_SAVE_EDIT_TEXT() {
|
get CANCEL_OR_SAVE_EDIT_TEXT() {
|
||||||
return markup(
|
return markup(
|
||||||
sprintf(
|
|
||||||
_t(
|
_t(
|
||||||
"<samp>%(cancel_keybind)s</samp><i> to <a href='#' data-type='%(cancel_type)s'>cancel</a></i>, <samp>%(save_keybind)s</samp><i> to <a href='#' data-type='%(save_type)s'>save</a></i>"
|
"<samp>%(cancel_keybind)s</samp><i> to <a href='#' data-type='%(cancel_type)s'>cancel</a></i>, <samp>%(save_keybind)s</samp><i> to <a href='#' data-type='%(save_type)s'>save</a></i>",
|
||||||
),
|
|
||||||
{
|
{
|
||||||
cancel_keybind: _t("Escape"),
|
cancel_keybind: _t("Escape"),
|
||||||
cancel_type: EDIT_CLICK_TYPE.CANCEL,
|
cancel_type: EDIT_CLICK_TYPE.CANCEL,
|
||||||
@@ -556,7 +547,7 @@ export class Composer extends Component {
|
|||||||
const message = await this.threadService.post(this.thread, value, postData);
|
const message = await this.threadService.post(this.thread, value, postData);
|
||||||
if (this.props.composer.thread.type === "mailbox") {
|
if (this.props.composer.thread.type === "mailbox") {
|
||||||
this.env.services.notification.add(
|
this.env.services.notification.add(
|
||||||
sprintf(_t('Message posted on "%s"'), message.originThread.displayName),
|
_t('Message posted on "%s"', message.originThread.displayName),
|
||||||
{ type: "info" }
|
{ type: "info" }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { Component, useState } from "@odoo/owl";
|
|||||||
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
export class MessageReactions extends Component {
|
export class MessageReactions extends Component {
|
||||||
static props = ["message", "openReactionMenu"];
|
static props = ["message", "openReactionMenu"];
|
||||||
@@ -26,33 +25,33 @@ export class MessageReactions extends Component {
|
|||||||
);
|
);
|
||||||
switch (reaction.count) {
|
switch (reaction.count) {
|
||||||
case 1:
|
case 1:
|
||||||
return sprintf(_t("%s has reacted with %s"), firstUserName, reaction.content);
|
return _t("%s has reacted with %s", firstUserName, reaction.content);
|
||||||
case 2:
|
case 2:
|
||||||
return sprintf(
|
return _t(
|
||||||
_t("%s and %s have reacted with %s"),
|
"%s and %s have reacted with %s",
|
||||||
firstUserName,
|
firstUserName,
|
||||||
secondUserName,
|
secondUserName,
|
||||||
reaction.content
|
reaction.content
|
||||||
);
|
);
|
||||||
case 3:
|
case 3:
|
||||||
return sprintf(
|
return _t(
|
||||||
_t("%s, %s, %s have reacted with %s"),
|
"%s, %s, %s have reacted with %s",
|
||||||
firstUserName,
|
firstUserName,
|
||||||
secondUserName,
|
secondUserName,
|
||||||
thirdUserName,
|
thirdUserName,
|
||||||
reaction.content
|
reaction.content
|
||||||
);
|
);
|
||||||
case 4:
|
case 4:
|
||||||
return sprintf(
|
return _t(
|
||||||
_t("%s, %s, %s and 1 other person have reacted with %s"),
|
"%s, %s, %s and 1 other person have reacted with %s",
|
||||||
firstUserName,
|
firstUserName,
|
||||||
secondUserName,
|
secondUserName,
|
||||||
thirdUserName,
|
thirdUserName,
|
||||||
reaction.content
|
reaction.content
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return sprintf(
|
return _t(
|
||||||
_t("%s, %s, %s and %s other persons have reacted with %s"),
|
"%s, %s, %s and %s other persons have reacted with %s",
|
||||||
firstUserName,
|
firstUserName,
|
||||||
secondUserName,
|
secondUserName,
|
||||||
thirdUserName,
|
thirdUserName,
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import { markup } from "@odoo/owl";
|
|||||||
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
const { DateTime } = luxon;
|
const { DateTime } = luxon;
|
||||||
|
|
||||||
@@ -161,9 +160,7 @@ export class MessageService {
|
|||||||
const thread = message.originThread;
|
const thread = message.originThread;
|
||||||
await this.env.services["mail.thread"].removeFollower(thread.selfFollower);
|
await this.env.services["mail.thread"].removeFollower(thread.selfFollower);
|
||||||
this.env.services.notification.add(
|
this.env.services.notification.add(
|
||||||
sprintf(_t('You are no longer following "%(thread_name)s".'), {
|
_t('You are no longer following "%(thread_name)s".', { thread_name: thread.name }),
|
||||||
thread_name: thread.name,
|
|
||||||
}),
|
|
||||||
{ type: "success" }
|
{ type: "success" }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { htmlToTextContentInline } from "@mail/utils/common/format";
|
|||||||
import { browser } from "@web/core/browser/browser";
|
import { browser } from "@web/core/browser/browser";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { url } from "@web/core/utils/urls";
|
import { url } from "@web/core/utils/urls";
|
||||||
|
|
||||||
const PREVIEW_MSG_MAX_SIZE = 350; // optimal for native English speakers
|
const PREVIEW_MSG_MAX_SIZE = 350; // optimal for native English speakers
|
||||||
@@ -43,7 +42,7 @@ export class OutOfFocusService {
|
|||||||
notificationTitle = _t("New message");
|
notificationTitle = _t("New message");
|
||||||
} else {
|
} else {
|
||||||
if (channel.channel_type === "channel") {
|
if (channel.channel_type === "channel") {
|
||||||
notificationTitle = sprintf(_t("%(author name)s from %(channel name)s"), {
|
notificationTitle = _t("%(author name)s from %(channel name)s", {
|
||||||
"author name": author.name,
|
"author name": author.name,
|
||||||
"channel name": channel.displayName,
|
"channel name": channel.displayName,
|
||||||
});
|
});
|
||||||
@@ -61,10 +60,9 @@ export class OutOfFocusService {
|
|||||||
type: "info",
|
type: "info",
|
||||||
});
|
});
|
||||||
this.counter++;
|
this.counter++;
|
||||||
const titlePattern = this.counter === 1 ? _t("%s Message") : _t("%s Messages");
|
|
||||||
this.busService.trigger("set_title_part", {
|
this.busService.trigger("set_title_part", {
|
||||||
part: "_chat",
|
part: "_chat",
|
||||||
title: sprintf(titlePattern, this.counter),
|
title: this.counter === 1 ? _t("1 Message") : _t("%s Messages", this.counter),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { createLocalId } from "@mail/utils/common/misc";
|
|||||||
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { Deferred } from "@web/core/utils/concurrency";
|
import { Deferred } from "@web/core/utils/concurrency";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef SeenInfo
|
* @typedef SeenInfo
|
||||||
@@ -147,7 +146,7 @@ export class Thread {
|
|||||||
if (!this.authorizedGroupFullName) {
|
if (!this.authorizedGroupFullName) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return sprintf(_t('Access restricted to group "%(groupFullName)s"'), {
|
return _t('Access restricted to group "%(groupFullName)s"', {
|
||||||
groupFullName: this.authorizedGroupFullName,
|
groupFullName: this.authorizedGroupFullName,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import { browser } from "@web/core/browser/browser";
|
|||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { usePopover } from "@web/core/popover/popover_hook";
|
import { usePopover } from "@web/core/popover/popover_hook";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { FileUploader } from "@web/views/fields/file_handler";
|
import { FileUploader } from "@web/views/fields/file_handler";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,7 +45,7 @@ export class Activity extends Component {
|
|||||||
|
|
||||||
get displayName() {
|
get displayName() {
|
||||||
if (this.props.data.summary) {
|
if (this.props.data.summary) {
|
||||||
return sprintf(_t("“%s”"), this.props.data.summary);
|
return _t("“%s”", this.props.data.summary);
|
||||||
}
|
}
|
||||||
return this.props.data.display_name;
|
return this.props.data.display_name;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { Component, useState } from "@odoo/owl";
|
|||||||
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { url } from "@web/core/utils/urls";
|
import { url } from "@web/core/utils/urls";
|
||||||
import { FileUploader } from "@web/views/fields/file_handler";
|
import { FileUploader } from "@web/views/fields/file_handler";
|
||||||
|
|
||||||
@@ -56,11 +55,11 @@ export class ActivityListPopoverItem extends Component {
|
|||||||
} else if (diff === -1) {
|
} else if (diff === -1) {
|
||||||
return _t("Yesterday");
|
return _t("Yesterday");
|
||||||
} else if (diff < 0) {
|
} else if (diff < 0) {
|
||||||
return sprintf(_t("%s days overdue"), Math.round(Math.abs(diff)));
|
return _t("%s days overdue", Math.round(Math.abs(diff)));
|
||||||
} else if (diff === 1) {
|
} else if (diff === 1) {
|
||||||
return _t("Tomorrow");
|
return _t("Tomorrow");
|
||||||
} else {
|
} else {
|
||||||
return sprintf(_t("Due in %s days"), Math.round(Math.abs(diff)));
|
return _t("Due in %s days", Math.round(Math.abs(diff)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { Component, onWillStart, useState } from "@odoo/owl";
|
|||||||
import { Dialog } from "@web/core/dialog/dialog";
|
import { Dialog } from "@web/core/dialog/dialog";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} SubtypeData
|
* @typedef {Object} SubtypeData
|
||||||
@@ -71,8 +70,6 @@ export class FollowerSubtypeDialog extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
return sprintf(_t("Edit Subscription of %(name)s"), {
|
return _t("Edit Subscription of %(name)s", { name: this.props.follower.partner.name });
|
||||||
name: this.props.follower.partner.name,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import { Dropdown } from "@web/core/dropdown/dropdown";
|
|||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
export class MessagingMenu extends Component {
|
export class MessagingMenu extends Component {
|
||||||
static components = { Dropdown, NotificationItem, ImStatus };
|
static components = { Dropdown, NotificationItem, ImStatus };
|
||||||
@@ -90,7 +89,7 @@ export class MessagingMenu extends Component {
|
|||||||
get notificationRequest() {
|
get notificationRequest() {
|
||||||
return {
|
return {
|
||||||
body: _t("Enable desktop notifications to chat"),
|
body: _t("Enable desktop notifications to chat"),
|
||||||
displayName: sprintf(_t("%s has a request"), this.store.odoobot.name),
|
displayName: _t("%s has a request", this.store.odoobot.name),
|
||||||
iconSrc: this.threadService.avatarUrl(this.store.odoobot),
|
iconSrc: this.threadService.avatarUrl(this.store.odoobot),
|
||||||
partner: this.store.odoobot,
|
partner: this.store.odoobot,
|
||||||
isLast: this.threads.length === 0 && this.store.notificationGroups.length === 0,
|
isLast: this.threads.length === 0 && this.store.notificationGroups.length === 0,
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { Component } from "@odoo/owl";
|
|||||||
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog";
|
import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,10 +22,7 @@ export class SuggestedRecipient extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get titleText() {
|
get titleText() {
|
||||||
return sprintf(
|
return _t("Add as recipient and follower (reason: %s)", this.props.recipient.reason);
|
||||||
_t("Add as recipient and follower (reason: %s)"),
|
|
||||||
this.props.recipient.reason
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeCheckbox(ev) {
|
onChangeCheckbox(ev) {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { Component, onMounted, onWillUnmount, useState } from "@odoo/owl";
|
|||||||
import { browser } from "@web/core/browser/browser";
|
import { browser } from "@web/core/browser/browser";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
const PROTOCOLS_TEXT = { host: "HOST", srflx: "STUN", prflx: "STUN", relay: "TURN" };
|
const PROTOCOLS_TEXT = { host: "HOST", srflx: "STUN", prflx: "STUN", relay: "TURN" };
|
||||||
|
|
||||||
@@ -34,7 +33,7 @@ export class CallContextMenu extends Component {
|
|||||||
if (!this.props.rtcSession.remoteCandidateType) {
|
if (!this.props.rtcSession.remoteCandidateType) {
|
||||||
return _t("no connection");
|
return _t("no connection");
|
||||||
}
|
}
|
||||||
return sprintf(_t("%(candidateType)s (%(protocol)s)"), {
|
return _t("%(candidateType)s (%(protocol)s)", {
|
||||||
candidateType: this.props.rtcSession.remoteCandidateType,
|
candidateType: this.props.rtcSession.remoteCandidateType,
|
||||||
protocol: PROTOCOLS_TEXT[this.props.rtcSession.remoteCandidateType],
|
protocol: PROTOCOLS_TEXT[this.props.rtcSession.remoteCandidateType],
|
||||||
});
|
});
|
||||||
@@ -44,7 +43,7 @@ export class CallContextMenu extends Component {
|
|||||||
if (!this.props.rtcSession.localCandidateType) {
|
if (!this.props.rtcSession.localCandidateType) {
|
||||||
return _t("no connection");
|
return _t("no connection");
|
||||||
}
|
}
|
||||||
return sprintf(_t("%(candidateType)s (%(protocol)s)"), {
|
return _t("%(candidateType)s (%(protocol)s)", {
|
||||||
candidateType: this.props.rtcSession.localCandidateType,
|
candidateType: this.props.rtcSession.localCandidateType,
|
||||||
protocol: PROTOCOLS_TEXT[this.props.rtcSession.localCandidateType],
|
protocol: PROTOCOLS_TEXT[this.props.rtcSession.localCandidateType],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import { reactive } from "@odoo/owl";
|
|||||||
import { browser } from "@web/core/browser/browser";
|
import { browser } from "@web/core/browser/browser";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { debounce } from "@web/core/utils/timing";
|
import { debounce } from "@web/core/utils/timing";
|
||||||
|
|
||||||
const ORDERED_TRANSCEIVER_NAMES = ["audio", "video"];
|
const ORDERED_TRANSCEIVER_NAMES = ["audio", "video"];
|
||||||
@@ -492,7 +491,7 @@ export class Rtc {
|
|||||||
if (session.raisingHand) {
|
if (session.raisingHand) {
|
||||||
this.addCallNotification({
|
this.addCallNotification({
|
||||||
id: notificationId,
|
id: notificationId,
|
||||||
text: sprintf(_t("%s raised a hand"), session.name),
|
text: _t("%s raised a hand", session.name),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.removeCallNotification(notificationId);
|
this.removeCallNotification(notificationId);
|
||||||
@@ -1236,9 +1235,9 @@ export class Rtc {
|
|||||||
} catch {
|
} catch {
|
||||||
const str =
|
const str =
|
||||||
type === "camera"
|
type === "camera"
|
||||||
? _t('%s" requires "camera" access')
|
? _t('%s" requires "camera" access', window.location.host)
|
||||||
: _t('%s" requires "screen recording" access');
|
: _t('%s" requires "screen recording" access', window.location.host);
|
||||||
this.notification.add(sprintf(str, window.location.host), { type: "warning" });
|
this.notification.add(str, { type: "warning" });
|
||||||
stopVideo();
|
stopVideo();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1252,10 +1251,7 @@ export class Rtc {
|
|||||||
videoStream = await this.blurManager.stream;
|
videoStream = await this.blurManager.stream;
|
||||||
} catch (_e) {
|
} catch (_e) {
|
||||||
this.notification.add(
|
this.notification.add(
|
||||||
sprintf(_t("%(name)s: %(message)s)"), {
|
_t("%(name)s: %(message)s)", { name: _e.name, message: _e.message }),
|
||||||
name: _e.name,
|
|
||||||
message: _e.message,
|
|
||||||
}),
|
|
||||||
{ type: "warning" }
|
{ type: "warning" }
|
||||||
);
|
);
|
||||||
this.userSettingsService.useBlur = false;
|
this.userSettingsService.useBlur = false;
|
||||||
@@ -1330,7 +1326,7 @@ export class Rtc {
|
|||||||
audioTrack = audioStream.getAudioTracks()[0];
|
audioTrack = audioStream.getAudioTracks()[0];
|
||||||
} catch {
|
} catch {
|
||||||
this.notification.add(
|
this.notification.add(
|
||||||
sprintf(_t('"%(hostname)s" requires microphone access'), {
|
_t('"%(hostname)s" requires microphone access', {
|
||||||
hostname: window.location.host,
|
hostname: window.location.host,
|
||||||
}),
|
}),
|
||||||
{ type: "warning" }
|
{ type: "warning" }
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { markup, reactive, useState } from "@odoo/owl";
|
|||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
export class DiscussCoreCommon {
|
export class DiscussCoreCommon {
|
||||||
/**
|
/**
|
||||||
@@ -45,7 +44,7 @@ export class DiscussCoreCommon {
|
|||||||
});
|
});
|
||||||
if (invitedByUserId && invitedByUserId !== this.store.user?.user?.id) {
|
if (invitedByUserId && invitedByUserId !== this.store.user?.user?.id) {
|
||||||
this.notificationService.add(
|
this.notificationService.add(
|
||||||
sprintf(_t("You have been invited to #%s"), thread.displayName),
|
_t("You have been invited to #%s", thread.displayName),
|
||||||
{ type: "info" }
|
{ type: "info" }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -69,10 +68,9 @@ export class DiscussCoreCommon {
|
|||||||
if (thread.localId === this.store.discuss.threadLocalId) {
|
if (thread.localId === this.store.discuss.threadLocalId) {
|
||||||
this.store.discuss.threadLocalId = undefined;
|
this.store.discuss.threadLocalId = undefined;
|
||||||
}
|
}
|
||||||
this.notificationService.add(
|
this.notificationService.add(_t("You unsubscribed from %s.", thread.displayName), {
|
||||||
sprintf(_t("You unsubscribed from %s."), thread.displayName),
|
type: "info",
|
||||||
{ type: "info" }
|
});
|
||||||
);
|
|
||||||
});
|
});
|
||||||
this.busService.subscribe("discuss.channel/legacy_insert", (payload) => {
|
this.busService.subscribe("discuss.channel/legacy_insert", (payload) => {
|
||||||
this.threadService.insert({
|
this.threadService.insert({
|
||||||
@@ -112,7 +110,7 @@ export class DiscussCoreCommon {
|
|||||||
if (thread) {
|
if (thread) {
|
||||||
thread.is_pinned = false;
|
thread.is_pinned = false;
|
||||||
this.notificationService.add(
|
this.notificationService.add(
|
||||||
sprintf(_t("You unpinned your conversation with %s"), thread.displayName),
|
_t("You unpinned your conversation with %s", thread.displayName),
|
||||||
{ type: "info" }
|
{ type: "info" }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { reactive } from "@odoo/owl";
|
|||||||
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
export class DiscussCoreWeb {
|
export class DiscussCoreWeb {
|
||||||
/**
|
/**
|
||||||
@@ -73,8 +72,8 @@ export class DiscussCoreWeb {
|
|||||||
// If the current user invited a new user, and the new user is
|
// If the current user invited a new user, and the new user is
|
||||||
// connecting for the first time while the current user is present
|
// connecting for the first time while the current user is present
|
||||||
// then open a chat for the current user with the new user.
|
// then open a chat for the current user with the new user.
|
||||||
const notification = sprintf(
|
const notification = _t(
|
||||||
_t("%(user)s connected. This is their first connection. Wish them luck."),
|
"%(user)s connected. This is their first connection. Wish them luck.",
|
||||||
{ user: username }
|
{ user: username }
|
||||||
);
|
);
|
||||||
this.notificationService.add(notification, { type: "info" });
|
this.notificationService.add(notification, { type: "info" });
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { markup, reactive, useState } from "@odoo/owl";
|
|||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
export const OTHER_LONG_TYPING = 60000;
|
export const OTHER_LONG_TYPING = 60000;
|
||||||
|
|
||||||
@@ -159,10 +158,9 @@ export class MessagePin {
|
|||||||
confirmText: _t("Yeah, pin it!"),
|
confirmText: _t("Yeah, pin it!"),
|
||||||
message: message,
|
message: message,
|
||||||
messageComponent: Message,
|
messageComponent: Message,
|
||||||
prompt: sprintf(
|
prompt: _t("You sure want this message pinned to %(conversation)s forever and ever?", {
|
||||||
_t("You sure want this message pinned to %(conversation)s forever and ever?"),
|
conversation: thread.prefix + thread.displayName,
|
||||||
{ conversation: thread.prefix + thread.displayName }
|
}),
|
||||||
),
|
|
||||||
size: "md",
|
size: "md",
|
||||||
title: _t("Pin It"),
|
title: _t("Pin It"),
|
||||||
onConfirm: () => this.setPin(message, true),
|
onConfirm: () => this.setPin(message, true),
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { useTypingService } from "@mail/discuss/typing/common/typing_service";
|
|||||||
import { Component } from "@odoo/owl";
|
import { Component } from "@odoo/owl";
|
||||||
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} Props
|
* @typedef {Object} Props
|
||||||
@@ -34,19 +33,11 @@ export class Typing extends Component {
|
|||||||
.getTypingMembers(this.props.channel)
|
.getTypingMembers(this.props.channel)
|
||||||
.map(({ persona }) => this.props.channel.getMemberName(persona));
|
.map(({ persona }) => this.props.channel.getMemberName(persona));
|
||||||
if (typingMemberNames.length === 1) {
|
if (typingMemberNames.length === 1) {
|
||||||
return sprintf(_t("%s is typing..."), typingMemberNames[0]);
|
return _t("%s is typing...", typingMemberNames[0]);
|
||||||
}
|
}
|
||||||
if (typingMemberNames.length === 2) {
|
if (typingMemberNames.length === 2) {
|
||||||
return sprintf(
|
return _t("%s and %s are typing...", typingMemberNames[0], typingMemberNames[1]);
|
||||||
_t("%s and %s are typing..."),
|
|
||||||
typingMemberNames[0],
|
|
||||||
typingMemberNames[1]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return sprintf(
|
return _t("%s, %s and more are typing...", typingMemberNames[0], typingMemberNames[1]);
|
||||||
_t("%s, %s and more are typing..."),
|
|
||||||
typingMemberNames[0],
|
|
||||||
typingMemberNames[1]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* @odoo-module */
|
/* @odoo-module */
|
||||||
import { Component, useState, onWillUnmount } from "@odoo/owl";
|
import { Component, useState, onWillUnmount } from "@odoo/owl";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { browser } from "@web/core/browser/browser";
|
import { browser } from "@web/core/browser/browser";
|
||||||
import { Mp3Encoder } from "./mp3_encoder";
|
import { Mp3Encoder } from "./mp3_encoder";
|
||||||
@@ -85,7 +84,7 @@ export class VoiceRecorder extends Component {
|
|||||||
});
|
});
|
||||||
} catch {
|
} catch {
|
||||||
this.notification.add(
|
this.notification.add(
|
||||||
sprintf(_t('"%(hostname)s" needs to access your microphone'), {
|
_t('"%(hostname)s" needs to access your microphone', {
|
||||||
hostname: window.location.host,
|
hostname: window.location.host,
|
||||||
}),
|
}),
|
||||||
{ type: "warning" }
|
{ type: "warning" }
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { useMessaging } from "@mail/core/common/messaging_hook";
|
|||||||
import { Component, useState } from "@odoo/owl";
|
import { Component, useState } from "@odoo/owl";
|
||||||
|
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { useModel } from "@web/model/model";
|
import { useModel } from "@web/model/model";
|
||||||
import { extractFieldsFromArchInfo } from "@web/model/relational_model/utils";
|
import { extractFieldsFromArchInfo } from "@web/model/relational_model/utils";
|
||||||
import { CogMenu } from "@web/search/cog_menu/cog_menu";
|
import { CogMenu } from "@web/search/cog_menu/cog_menu";
|
||||||
@@ -48,7 +47,7 @@ export class ActivityController extends Component {
|
|||||||
resModel: this.props.resModel,
|
resModel: this.props.resModel,
|
||||||
searchViewId: this.env.searchModel.searchViewId,
|
searchViewId: this.env.searchModel.searchViewId,
|
||||||
domain: this.model.originalDomain,
|
domain: this.model.originalDomain,
|
||||||
title: sprintf(this.env._t("Search: %s"), this.props.archInfo.title),
|
title: this.env._t("Search: %s", this.props.archInfo.title),
|
||||||
multiSelect: false,
|
multiSelect: false,
|
||||||
context: this.props.context,
|
context: this.props.context,
|
||||||
onSelected: async (resIds) => {
|
onSelected: async (resIds) => {
|
||||||
|
|||||||
+1
-2
@@ -5,7 +5,6 @@ import { onMounted } from "@odoo/owl";
|
|||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { TagsList } from "@web/core/tags_list/tags_list";
|
import { TagsList } from "@web/core/tags_list/tags_list";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import {
|
import {
|
||||||
Many2ManyTagsField,
|
Many2ManyTagsField,
|
||||||
many2ManyTagsField,
|
many2ManyTagsField,
|
||||||
@@ -63,7 +62,7 @@ export class FieldMany2ManyTagsEmail extends Many2ManyTagsField {
|
|||||||
this.openMany2xRecord({
|
this.openMany2xRecord({
|
||||||
resId: record.resId,
|
resId: record.resId,
|
||||||
context: this.props.context,
|
context: this.props.context,
|
||||||
title: sprintf(_t("Edit: %s"), record.data.display_name),
|
title: _t("Edit: %s", record.data.display_name),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import ajax from "@web/legacy/js/core/ajax";
|
import ajax from "@web/legacy/js/core/ajax";
|
||||||
import { sprintf, escape } from "@web/core/utils/strings";
|
import { escape } from "@web/core/utils/strings";
|
||||||
import { whenReady } from "@odoo/owl";
|
import { whenReady } from "@odoo/owl";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import session from "web.session";
|
import session from "web.session";
|
||||||
@@ -45,10 +45,12 @@ whenReady(() => {
|
|||||||
|
|
||||||
var unsubscribed_list = $("input[name='unsubscribed_list']").val();
|
var unsubscribed_list = $("input[name='unsubscribed_list']").val();
|
||||||
if (unsubscribed_list){
|
if (unsubscribed_list){
|
||||||
$('#subscription_info').html(sprintf(
|
$("#subscription_info").html(
|
||||||
_t("You have been <strong>successfully unsubscribed from %s</strong>."),
|
_t(
|
||||||
|
"You have been <strong>successfully unsubscribed from %s</strong>.",
|
||||||
escape(unsubscribed_list)
|
escape(unsubscribed_list)
|
||||||
));
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
$('#subscription_info').html(_t('You have been <strong>successfully unsubscribed</strong>.'));
|
$('#subscription_info').html(_t('You have been <strong>successfully unsubscribed</strong>.'));
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import { escape, sprintf } from "@web/core/utils/strings";
|
import { escape } from "@web/core/utils/strings";
|
||||||
import core from "@web/legacy/js/services/core";
|
import core from "@web/legacy/js/services/core";
|
||||||
import Dialog from "@web/legacy/js/core/dialog";
|
import Dialog from "@web/legacy/js/core/dialog";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
const $checkedRadios = this.$('input[name="o_payment_radio"]:checked');
|
const $checkedRadios = this.$('input[name="o_payment_radio"]:checked');
|
||||||
if ($checkedRadios.length !== 1) { // Cannot find selected payment option, show dialog
|
if ($checkedRadios.length !== 1) { // Cannot find selected payment option, show dialog
|
||||||
return new Dialog(null, {
|
return new Dialog(null, {
|
||||||
title: sprintf(_t("Error: %s"), title),
|
title: _t("Error: %s", title),
|
||||||
size: 'medium',
|
size: 'medium',
|
||||||
$content: `<p>${escape(description) || ''}</p>`,
|
$content: `<p>${escape(description) || ''}</p>`,
|
||||||
buttons: [{text: _t("Ok"), close: true}]
|
buttons: [{text: _t("Ok"), close: true}]
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/** @odoo-module */
|
/** @odoo-module */
|
||||||
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { renderToElement } from "@web/core/utils/render";
|
import { renderToElement } from "@web/core/utils/render";
|
||||||
import { useAutofocus, useService } from "@web/core/utils/hooks";
|
import { useAutofocus, useService } from "@web/core/utils/hooks";
|
||||||
import { parseFloat, InvalidNumberError } from "@web/views/fields/parsers";
|
import { parseFloat, InvalidNumberError } from "@web/views/fields/parsers";
|
||||||
@@ -50,10 +49,7 @@ export class CashMovePopup extends AbstractAwaitablePopup {
|
|||||||
}
|
}
|
||||||
const formattedAmount = this.env.utils.formatCurrency(amount);
|
const formattedAmount = this.env.utils.formatCurrency(amount);
|
||||||
if (!amount) {
|
if (!amount) {
|
||||||
this.notification.add(
|
this.notification.add(_t("Cash in/out of %s is ignored.", formattedAmount), 3000);
|
||||||
sprintf(_t("Cash in/out of %s is ignored."), formattedAmount),
|
|
||||||
3000
|
|
||||||
);
|
|
||||||
return this.props.close();
|
return this.props.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +92,7 @@ export class CashMovePopup extends AbstractAwaitablePopup {
|
|||||||
}
|
}
|
||||||
this.props.close();
|
this.props.close();
|
||||||
this.notification.add(
|
this.notification.add(
|
||||||
sprintf(this.env._t("Successfully made a cash %s of %s."), type, formattedAmount),
|
this.env._t("Successfully made a cash %s of %s.", type, formattedAmount),
|
||||||
3000
|
3000
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import { ConnectionLostError } from "@web/core/network/rpc_service";
|
|||||||
import { identifyError } from "@point_of_sale/app/errors/error_handlers";
|
import { identifyError } from "@point_of_sale/app/errors/error_handlers";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { parseFloat } from "@web/views/fields/parsers";
|
import { parseFloat } from "@web/views/fields/parsers";
|
||||||
import { useValidateCashInput } from "@point_of_sale/app/utils/hooks";
|
import { useValidateCashInput } from "@point_of_sale/app/utils/hooks";
|
||||||
|
|
||||||
@@ -63,11 +62,9 @@ export class ClosePosPopup extends AbstractAwaitablePopup {
|
|||||||
} else {
|
} else {
|
||||||
await this.popup.add(ConfirmPopup, {
|
await this.popup.add(ConfirmPopup, {
|
||||||
title: this.env._t("Payments Difference"),
|
title: this.env._t("Payments Difference"),
|
||||||
body: sprintf(
|
body: this.env._t(
|
||||||
this.env._t(
|
|
||||||
"The maximum difference allowed is %s.\n\
|
"The maximum difference allowed is %s.\n\
|
||||||
Please contact your manager to accept the closing difference."
|
Please contact your manager to accept the closing difference.",
|
||||||
),
|
|
||||||
this.env.utils.formatCurrency(this.amountAuthorizedDiff)
|
this.env.utils.formatCurrency(this.amountAuthorizedDiff)
|
||||||
),
|
),
|
||||||
confirmText: this.env._t("OK"),
|
confirmText: this.env._t("OK"),
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { PartnerLine } from "@point_of_sale/app/screens/partner_list/partner_lin
|
|||||||
import { PartnerDetailsEdit } from "@point_of_sale/app/screens/partner_list/partner_editor/partner_editor";
|
import { PartnerDetailsEdit } from "@point_of_sale/app/screens/partner_list/partner_editor/partner_editor";
|
||||||
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
||||||
import { Component, onWillUnmount, useRef, useState } from "@odoo/owl";
|
import { Component, onWillUnmount, useRef, useState } from "@odoo/owl";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render this screen using `showTempScreen` to select partner.
|
* Render this screen using `showTempScreen` to select partner.
|
||||||
@@ -128,16 +127,12 @@ export class PartnerListScreen extends Component {
|
|||||||
const result = await this.searchPartner();
|
const result = await this.searchPartner();
|
||||||
if (result.length > 0) {
|
if (result.length > 0) {
|
||||||
this.notification.add(
|
this.notification.add(
|
||||||
sprintf(
|
this.env._t('%s customer(s) found for "%s".', result.length, this.state.query),
|
||||||
this.env._t('%s customer(s) found for "%s".'),
|
|
||||||
result.length,
|
|
||||||
this.state.query
|
|
||||||
),
|
|
||||||
3000
|
3000
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.notification.add(
|
this.notification.add(
|
||||||
sprintf(this.env._t('No more customer found for "%s".'), this.state.query),
|
this.env._t('No more customer found for "%s".', this.state.query),
|
||||||
3000
|
3000
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import { PaymentScreenPaymentLines } from "@point_of_sale/app/screens/payment_sc
|
|||||||
import { PaymentScreenStatus } from "@point_of_sale/app/screens/payment_screen/payment_status/payment_status";
|
import { PaymentScreenStatus } from "@point_of_sale/app/screens/payment_screen/payment_status/payment_status";
|
||||||
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
||||||
import { Component, useState } from "@odoo/owl";
|
import { Component, useState } from "@odoo/owl";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
export class PaymentScreen extends Component {
|
export class PaymentScreen extends Component {
|
||||||
static template = "point_of_sale.PaymentScreen";
|
static template = "point_of_sale.PaymentScreen";
|
||||||
@@ -343,8 +342,8 @@ export class PaymentScreen extends Component {
|
|||||||
const paymentMethod = splitPayments[0].payment_method;
|
const paymentMethod = splitPayments[0].payment_method;
|
||||||
const { confirmed } = await this.popup.add(ConfirmPopup, {
|
const { confirmed } = await this.popup.add(ConfirmPopup, {
|
||||||
title: this.env._t("Customer Required"),
|
title: this.env._t("Customer Required"),
|
||||||
body: sprintf(
|
body: this.env._t(
|
||||||
this.env._t("Customer is required for %s payment method."),
|
"Customer is required for %s payment method.",
|
||||||
paymentMethod.name
|
paymentMethod.name
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|||||||
+2
-7
@@ -8,7 +8,6 @@ import { ConnectionLostError, ConnectionAbortedError } from "@web/core/network/r
|
|||||||
import { ProductItem } from "@point_of_sale/app/screens/product_screen/product/product";
|
import { ProductItem } from "@point_of_sale/app/screens/product_screen/product/product";
|
||||||
import { ProductsWidgetControlPanel } from "@point_of_sale/app/screens/product_screen/product_list/control_panel/control_panel";
|
import { ProductsWidgetControlPanel } from "@point_of_sale/app/screens/product_screen/product_list/control_panel/control_panel";
|
||||||
import { Component, useState } from "@odoo/owl";
|
import { Component, useState } from "@odoo/owl";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { OfflineErrorPopup } from "@point_of_sale/app/errors/popups/offline_error_popup";
|
import { OfflineErrorPopup } from "@point_of_sale/app/errors/popups/offline_error_popup";
|
||||||
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
||||||
|
|
||||||
@@ -81,16 +80,12 @@ export class ProductsWidget extends Component {
|
|||||||
const result = await this.loadProductFromDB();
|
const result = await this.loadProductFromDB();
|
||||||
if (result.length > 0) {
|
if (result.length > 0) {
|
||||||
this.notification.add(
|
this.notification.add(
|
||||||
sprintf(
|
this.env._t('%s product(s) found for "%s".', result.length, searchProductWord),
|
||||||
this.env._t('%s product(s) found for "%s".'),
|
|
||||||
result.length,
|
|
||||||
searchProductWord
|
|
||||||
),
|
|
||||||
3000
|
3000
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.notification.add(
|
this.notification.add(
|
||||||
sprintf(this.env._t('No more product found for "%s".'), searchProductWord),
|
this.env._t('No more product found for "%s".', searchProductWord),
|
||||||
3000
|
3000
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -1,7 +1,6 @@
|
|||||||
/** @odoo-module */
|
/** @odoo-module */
|
||||||
|
|
||||||
import { Component } from "@odoo/owl";
|
import { Component } from "@odoo/owl";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { formatFloat } from "@web/views/fields/formatters";
|
import { formatFloat } from "@web/views/fields/formatters";
|
||||||
import { roundPrecision as round_pr } from "@web/core/utils/numbers";
|
import { roundPrecision as round_pr } from "@web/core/utils/numbers";
|
||||||
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
||||||
@@ -72,9 +71,9 @@ export class OrderlineDetails extends Component {
|
|||||||
return this.env.utils.formatProductQty(toRefundDetail && toRefundDetail.qty);
|
return this.env.utils.formatProductQty(toRefundDetail && toRefundDetail.qty);
|
||||||
}
|
}
|
||||||
getRefundingMessage() {
|
getRefundingMessage() {
|
||||||
return sprintf(this.env._t("Refunding %s in "), this.getFormattedToRefundQty());
|
return this.env._t("Refunding %s in ", this.getFormattedToRefundQty());
|
||||||
}
|
}
|
||||||
getToRefundMessage() {
|
getToRefundMessage() {
|
||||||
return sprintf(this.env._t("To Refund: %s"), this.getFormattedToRefundQty());
|
return this.env._t("To Refund: %s", this.getFormattedToRefundQty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import { ReprintReceiptButton } from "@point_of_sale/app/screens/ticket_screen/r
|
|||||||
import { SearchBar } from "@point_of_sale/app/screens/ticket_screen/search_bar/search_bar";
|
import { SearchBar } from "@point_of_sale/app/screens/ticket_screen/search_bar/search_bar";
|
||||||
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
||||||
import { Component, onMounted, useState } from "@odoo/owl";
|
import { Component, onMounted, useState } from "@odoo/owl";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
const { DateTime } = luxon;
|
const { DateTime } = luxon;
|
||||||
|
|
||||||
@@ -128,10 +127,8 @@ export class TicketScreen extends Component {
|
|||||||
) {
|
) {
|
||||||
const { confirmed } = await this.popup.add(ConfirmPopup, {
|
const { confirmed } = await this.popup.add(ConfirmPopup, {
|
||||||
title: this.env._t("Existing orderlines"),
|
title: this.env._t("Existing orderlines"),
|
||||||
body: sprintf(
|
body: this.env._t(
|
||||||
this.env._t(
|
"%s has a total amount of %s, are you sure you want to delete this order?",
|
||||||
"%s has a total amount of %s, are you sure you want to delete this order?"
|
|
||||||
),
|
|
||||||
order.name,
|
order.name,
|
||||||
this.getTotal(order)
|
this.getTotal(order)
|
||||||
),
|
),
|
||||||
@@ -212,10 +209,8 @@ export class TicketScreen extends Component {
|
|||||||
this.numberBuffer.reset();
|
this.numberBuffer.reset();
|
||||||
this.popup.add(ErrorPopup, {
|
this.popup.add(ErrorPopup, {
|
||||||
title: this.env._t("Maximum Exceeded"),
|
title: this.env._t("Maximum Exceeded"),
|
||||||
body: sprintf(
|
body: this.env._t(
|
||||||
this.env._t(
|
"The requested quantity to be refunded is higher than the ordered quantity. %s is requested while only %s can be refunded.",
|
||||||
"The requested quantity to be refunded is higher than the ordered quantity. %s is requested while only %s can be refunded."
|
|
||||||
),
|
|
||||||
quantity,
|
quantity,
|
||||||
refundableQty
|
refundableQty
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
|||||||
import { ProductConfiguratorPopup } from "@point_of_sale/app/store/product_configurator_popup/product_configurator_popup";
|
import { ProductConfiguratorPopup } from "@point_of_sale/app/store/product_configurator_popup/product_configurator_popup";
|
||||||
import { EditListPopup } from "@point_of_sale/app/store/select_lot_popup/select_lot_popup";
|
import { EditListPopup } from "@point_of_sale/app/store/select_lot_popup/select_lot_popup";
|
||||||
import { ConfirmPopup } from "@point_of_sale/app/utils/confirm_popup/confirm_popup";
|
import { ConfirmPopup } from "@point_of_sale/app/utils/confirm_popup/confirm_popup";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { renderToElement } from "@web/core/utils/render";
|
import { renderToElement } from "@web/core/utils/render";
|
||||||
|
|
||||||
@@ -573,10 +572,8 @@ export class Orderline extends PosModel {
|
|||||||
} else {
|
} else {
|
||||||
this.env.services.popup.add(ErrorPopup, {
|
this.env.services.popup.add(ErrorPopup, {
|
||||||
title: _t("Greater than allowed"),
|
title: _t("Greater than allowed"),
|
||||||
body: sprintf(
|
body: _t(
|
||||||
_t(
|
"The requested quantity to be refunded is higher than the refundable quantity of %s.",
|
||||||
"The requested quantity to be refunded is higher than the refundable quantity of %s."
|
|
||||||
),
|
|
||||||
this.env.utils.formatProductQty(maxQtyToRefund)
|
this.env.utils.formatProductQty(maxQtyToRefund)
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
@@ -1267,7 +1264,7 @@ export class Order extends PosModel {
|
|||||||
this.access_token = uuidv4(); // unique uuid used to identify the authenticity of the request from the QR code.
|
this.access_token = uuidv4(); // unique uuid used to identify the authenticity of the request from the QR code.
|
||||||
this.ticketCode = this._generateTicketCode(); // 5-digits alphanum code shown on the receipt
|
this.ticketCode = this._generateTicketCode(); // 5-digits alphanum code shown on the receipt
|
||||||
this.uid = this.generate_unique_id();
|
this.uid = this.generate_unique_id();
|
||||||
this.name = sprintf(_t("Order %s"), this.uid);
|
this.name = _t("Order %s", this.uid);
|
||||||
this.validation_date = undefined;
|
this.validation_date = undefined;
|
||||||
this.fiscal_position = this.pos.fiscal_positions.find(function (fp) {
|
this.fiscal_position = this.pos.fiscal_positions.find(function (fp) {
|
||||||
return fp.id === self.pos.config.default_fiscal_position_id[0];
|
return fp.id === self.pos.config.default_fiscal_position_id[0];
|
||||||
@@ -1314,7 +1311,7 @@ export class Order extends PosModel {
|
|||||||
if (json.name) {
|
if (json.name) {
|
||||||
this.name = json.name;
|
this.name = json.name;
|
||||||
} else {
|
} else {
|
||||||
this.name = sprintf(_t("Order %s"), this.uid);
|
this.name = _t("Order %s", this.uid);
|
||||||
}
|
}
|
||||||
this.validation_date = json.creation_date;
|
this.validation_date = json.creation_date;
|
||||||
this.server_id = json.server_id || json.id || false;
|
this.server_id = json.server_id || json.id || false;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
|||||||
import { ConnectionLostError } from "@web/core/network/rpc_service";
|
import { ConnectionLostError } from "@web/core/network/rpc_service";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { CashOpeningPopup } from "@point_of_sale/app/store/cash_opening_popup/cash_opening_popup";
|
import { CashOpeningPopup } from "@point_of_sale/app/store/cash_opening_popup/cash_opening_popup";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { PaymentScreen } from "@point_of_sale/app/screens/payment_screen/payment_screen";
|
import { PaymentScreen } from "@point_of_sale/app/screens/payment_screen/payment_screen";
|
||||||
import { ProductScreen } from "@point_of_sale/app/screens/product_screen/product_screen";
|
import { ProductScreen } from "@point_of_sale/app/screens/product_screen/product_screen";
|
||||||
import { renderToString } from "@web/core/utils/render";
|
import { renderToString } from "@web/core/utils/render";
|
||||||
@@ -790,8 +789,8 @@ export class PosStore extends Reactive {
|
|||||||
const pricelistsNames = pricelistsJson.map((pricelist) => {
|
const pricelistsNames = pricelistsJson.map((pricelist) => {
|
||||||
return pricelist.display_name;
|
return pricelist.display_name;
|
||||||
});
|
});
|
||||||
message = sprintf(
|
message = _t(
|
||||||
_t("%s fiscal position(s) added to the configuration."),
|
"%s fiscal position(s) added to the configuration.",
|
||||||
pricelistsNames.join(", ")
|
pricelistsNames.join(", ")
|
||||||
);
|
);
|
||||||
return message;
|
return message;
|
||||||
@@ -830,8 +829,8 @@ export class PosStore extends Reactive {
|
|||||||
const fiscalPositionNames = fiscalPositionJson.map((fp) => {
|
const fiscalPositionNames = fiscalPositionJson.map((fp) => {
|
||||||
return fp.display_name;
|
return fp.display_name;
|
||||||
});
|
});
|
||||||
message = sprintf(
|
message = _t(
|
||||||
_t("%s fiscal position(s) added to the configuration."),
|
"%s fiscal position(s) added to the configuration.",
|
||||||
fiscalPositionNames.join(", ")
|
fiscalPositionNames.join(", ")
|
||||||
);
|
);
|
||||||
return message;
|
return message;
|
||||||
@@ -1704,10 +1703,8 @@ export class PosStore extends Reactive {
|
|||||||
// FIXME POSREF this looks like it's dead code.
|
// FIXME POSREF this looks like it's dead code.
|
||||||
reject({
|
reject({
|
||||||
title: _t("HTTPS connection to IoT Box failed"),
|
title: _t("HTTPS connection to IoT Box failed"),
|
||||||
body: sprintf(
|
body: _t(
|
||||||
_t(
|
"Make sure you are using IoT Box v18.12 or higher. Navigate to %s to accept the certificate of your IoT Box.",
|
||||||
"Make sure you are using IoT Box v18.12 or higher. Navigate to %s to accept the certificate of your IoT Box."
|
|
||||||
),
|
|
||||||
url
|
url
|
||||||
),
|
),
|
||||||
popup: "alert",
|
popup: "alert",
|
||||||
@@ -1774,10 +1771,8 @@ export class PosStore extends Reactive {
|
|||||||
if (currentPartner && currentOrder.getHasRefundLines()) {
|
if (currentPartner && currentOrder.getHasRefundLines()) {
|
||||||
this.popup.add(ErrorPopup, {
|
this.popup.add(ErrorPopup, {
|
||||||
title: _t("Can't change customer"),
|
title: _t("Can't change customer"),
|
||||||
body: sprintf(
|
body: _t(
|
||||||
_t(
|
"This order already has refund lines for %s. We can't change the customer associated to it. Create a new order for the new customer.",
|
||||||
"This order already has refund lines for %s. We can't change the customer associated to it. Create a new order for the new customer."
|
|
||||||
),
|
|
||||||
currentPartner.name
|
currentPartner.name
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import { escape, sprintf } from "@web/core/utils/strings";
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
|
import { escape } from "@web/core/utils/strings";
|
||||||
import ajax from "@web/legacy/js/core/ajax";
|
import ajax from "@web/legacy/js/core/ajax";
|
||||||
import core from "@web/legacy/js/services/core";
|
import core from "@web/legacy/js/services/core";
|
||||||
import publicWidget from "@web/legacy/js/public/public_widget";
|
import publicWidget from "@web/legacy/js/public/public_widget";
|
||||||
@@ -125,8 +125,7 @@ var PortalComposer = publicWidget.Widget.extend({
|
|||||||
resolve();
|
resolve();
|
||||||
}).guardedCatch(function (error) {
|
}).guardedCatch(function (error) {
|
||||||
self.displayNotification({
|
self.displayNotification({
|
||||||
message: sprintf(_t("Could not save file <strong>%s</strong>"),
|
message: _t("Could not save file <strong>%s</strong>", escape(file.name)),
|
||||||
escape(file.name)),
|
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
sticky: true,
|
sticky: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import publicWidget from "@web/legacy/js/public/public_widget";
|
import publicWidget from "@web/legacy/js/public/public_widget";
|
||||||
import session from "web.session";
|
import session from "web.session";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { deserializeDateTime } from "@web/core/l10n/dates";
|
import { deserializeDateTime } from "@web/core/l10n/dates";
|
||||||
|
|
||||||
const { DateTime } = luxon;
|
const { DateTime } = luxon;
|
||||||
@@ -41,9 +40,9 @@ var PortalSidebar = publicWidget.Widget.extend({
|
|||||||
} else if (diff > 0) {
|
} else if (diff > 0) {
|
||||||
// Workaround: force uniqueness of these two translations. We use %1d because the string
|
// Workaround: force uniqueness of these two translations. We use %1d because the string
|
||||||
// with %d is already used in mail and mail's translations are not sent to the frontend.
|
// with %d is already used in mail and mail's translations are not sent to the frontend.
|
||||||
displayStr = sprintf(_t('Due in %s days'), Math.abs(diff).toFixed(1));
|
displayStr = _t('Due in %s days', Math.abs(diff).toFixed(1));
|
||||||
} else {
|
} else {
|
||||||
displayStr = sprintf(_t('%s days overdue'), Math.abs(diff).toFixed(1));
|
displayStr = _t('%s days overdue', Math.abs(diff).toFixed(1));
|
||||||
}
|
}
|
||||||
$(el).text(displayStr);
|
$(el).text(displayStr);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ export class PaymentAdyen extends PaymentInterface {
|
|||||||
resolve(true);
|
resolve(true);
|
||||||
} else {
|
} else {
|
||||||
var message = additional_response.get("message");
|
var message = additional_response.get("message");
|
||||||
self._show_error(sprintf(_t("Message from Adyen: %s"), message));
|
self._show_error(_t("Message from Adyen: %s", message));
|
||||||
|
|
||||||
// this means the transaction was cancelled by pressing the cancel button on the device
|
// this means the transaction was cancelled by pressing the cancel button on the device
|
||||||
if (message.startsWith("108 ")) {
|
if (message.startsWith("108 ")) {
|
||||||
@@ -308,9 +308,7 @@ export class PaymentAdyen extends PaymentInterface {
|
|||||||
msg = params.get("message");
|
msg = params.get("message");
|
||||||
}
|
}
|
||||||
|
|
||||||
this._show_error(
|
this._show_error(_t("An unexpected error occurred. Message from Adyen: %s", msg));
|
||||||
sprintf(_t("An unexpected error occurred. Message from Adyen: %s"), msg)
|
|
||||||
);
|
|
||||||
if (line) {
|
if (line) {
|
||||||
line.set_payment_status("force_done");
|
line.set_payment_status("force_done");
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -5,7 +5,6 @@ import { useService } from "@web/core/utils/hooks";
|
|||||||
import { NumberPopup } from "@point_of_sale/app/utils/input_popups/number_popup";
|
import { NumberPopup } from "@point_of_sale/app/utils/input_popups/number_popup";
|
||||||
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
||||||
import { Component } from "@odoo/owl";
|
import { Component } from "@odoo/owl";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
||||||
|
|
||||||
export class DiscountButton extends Component {
|
export class DiscountButton extends Component {
|
||||||
@@ -73,8 +72,8 @@ export class DiscountButton extends Component {
|
|||||||
description:
|
description:
|
||||||
`${pc}%, ` +
|
`${pc}%, ` +
|
||||||
(tax_ids_array.length
|
(tax_ids_array.length
|
||||||
? sprintf(
|
? this.env._t(
|
||||||
this.env._t("Tax: %s"),
|
"Tax: %s",
|
||||||
tax_ids_array
|
tax_ids_array
|
||||||
.map((taxId) => this.pos.taxes_by_id[taxId].amount + "%")
|
.map((taxId) => this.pos.taxes_by_id[taxId].amount + "%")
|
||||||
.join(", ")
|
.join(", ")
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import { BasePrinter } from "@point_of_sale/app/printer/base_printer";
|
import { BasePrinter } from "@point_of_sale/app/printer/base_printer";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { templates } from "@web/core/assets";
|
import { templates } from "@web/core/assets";
|
||||||
import { createElement, append, createTextNode } from "@web/core/utils/xml";
|
import { createElement, append, createTextNode } from "@web/core/utils/xml";
|
||||||
|
|
||||||
@@ -166,10 +165,8 @@ export class EpsonPrinter extends BasePrinter {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
if (window.location.protocol === "https:") {
|
if (window.location.protocol === "https:") {
|
||||||
printRes.message.body += sprintf(
|
printRes.message.body += _t(
|
||||||
_t(
|
"If you are on a secure server (HTTPS) please make sure you manually accepted the certificate by accessing %s",
|
||||||
"If you are on a secure server (HTTPS) please make sure you manually accepted the certificate by accessing %s"
|
|
||||||
),
|
|
||||||
this.url
|
this.url
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
||||||
import { PartnerLine } from "@point_of_sale/app/screens/partner_list/partner_line/partner_line";
|
import { PartnerLine } from "@point_of_sale/app/screens/partner_list/partner_line/partner_line";
|
||||||
import { patch } from "@web/core/utils/patch";
|
import { patch } from "@web/core/utils/patch";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { formatFloat } from "@web/views/fields/formatters";
|
import { formatFloat } from "@web/views/fields/formatters";
|
||||||
|
|
||||||
patch(PartnerLine.prototype, {
|
patch(PartnerLine.prototype, {
|
||||||
@@ -20,6 +19,6 @@ patch(PartnerLine.prototype, {
|
|||||||
if (program.portal_visible) {
|
if (program.portal_visible) {
|
||||||
return `${balanceRepr} ${program.portal_point_name}`;
|
return `${balanceRepr} ${program.portal_point_name}`;
|
||||||
}
|
}
|
||||||
return sprintf(this.env._t("%s Points"), balanceRepr);
|
return this.env._t("%s Points", balanceRepr);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { useBarcodeReader } from "@point_of_sale/app/barcode/barcode_reader_hook
|
|||||||
import { patch } from "@web/core/utils/patch";
|
import { patch } from "@web/core/utils/patch";
|
||||||
import { ConfirmPopup } from "@point_of_sale/app/utils/confirm_popup/confirm_popup";
|
import { ConfirmPopup } from "@point_of_sale/app/utils/confirm_popup/confirm_popup";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
patch(ProductScreen.prototype, {
|
patch(ProductScreen.prototype, {
|
||||||
setup() {
|
setup() {
|
||||||
@@ -43,10 +42,8 @@ patch(ProductScreen.prototype, {
|
|||||||
const reward = this.pos.reward_by_id[selectedLine.reward_id];
|
const reward = this.pos.reward_by_id[selectedLine.reward_id];
|
||||||
const { confirmed } = await this.popup.add(ConfirmPopup, {
|
const { confirmed } = await this.popup.add(ConfirmPopup, {
|
||||||
title: this.env._t("Deactivating reward"),
|
title: this.env._t("Deactivating reward"),
|
||||||
body: sprintf(
|
body: this.env._t(
|
||||||
this.env._t(
|
"Are you sure you want to remove %s from this order?\n You will still be able to claim it through the reward button.",
|
||||||
"Are you sure you want to remove %s from this order?\n You will still be able to claim it through the reward button."
|
|
||||||
),
|
|
||||||
reward.description
|
reward.description
|
||||||
),
|
),
|
||||||
cancelText: this.env._t("No"),
|
cancelText: this.env._t("No"),
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { roundDecimals, roundPrecision } from "@web/core/utils/numbers";
|
|||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { patch } from "@web/core/utils/patch";
|
import { patch } from "@web/core/utils/patch";
|
||||||
import { ConfirmPopup } from "@point_of_sale/app/utils/confirm_popup/confirm_popup";
|
import { ConfirmPopup } from "@point_of_sale/app/utils/confirm_popup/confirm_popup";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
// FIXME: Perhaps MutexedDropPrevious can be replaced by the new KeepLast.
|
// FIXME: Perhaps MutexedDropPrevious can be replaced by the new KeepLast.
|
||||||
// > This might require thorough investigation on how _updateRewards work.
|
// > This might require thorough investigation on how _updateRewards work.
|
||||||
@@ -1556,8 +1555,8 @@ patch(Order.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!rule && this.orderlines.length === 0 && coupon) {
|
if (!rule && this.orderlines.length === 0 && coupon) {
|
||||||
return sprintf(
|
return _t(
|
||||||
_t("Gift Card: %s\nBalance: %s"),
|
"Gift Card: %s\nBalance: %s",
|
||||||
code,
|
code,
|
||||||
this.env.utils.formatCurrency(coupon.balance)
|
this.env.utils.formatCurrency(coupon.balance)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { SelectionPopup } from "@point_of_sale/app/utils/input_popups/selection_
|
|||||||
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
||||||
import { TextInputPopup } from "@point_of_sale/app/utils/input_popups/text_input_popup";
|
import { TextInputPopup } from "@point_of_sale/app/utils/input_popups/text_input_popup";
|
||||||
import { Domain, InvalidDomainError } from "@web/core/domain";
|
import { Domain, InvalidDomainError } from "@web/core/domain";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { PosLoyaltyCard } from "@pos_loyalty/overrides/models/loyalty";
|
import { PosLoyaltyCard } from "@pos_loyalty/overrides/models/loyalty";
|
||||||
|
|
||||||
const COUPON_CACHE_MAX_SIZE = 4096; // Maximum coupon cache size, prevents long run memory issues and (to some extent) invalid data
|
const COUPON_CACHE_MAX_SIZE = 4096; // Maximum coupon cache size, prevents long run memory issues and (to some extent) invalid data
|
||||||
@@ -245,10 +244,8 @@ patch(PosStore.prototype, {
|
|||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
this.env.services.popup.add(ErrorPopup, {
|
this.env.services.popup.add(ErrorPopup, {
|
||||||
title: _t("A reward could not be loaded"),
|
title: _t("A reward could not be loaded"),
|
||||||
body: sprintf(
|
body: _t(
|
||||||
_t(
|
'The reward "%s" contain an error in its domain, your domain must be compatible with the PoS client',
|
||||||
'The reward "%s" contain an error in its domain, your domain must be compatible with the PoS client'
|
|
||||||
),
|
|
||||||
this.rewards[index].description
|
this.rewards[index].description
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { OnlinePaymentPopup } from "@pos_online_payment/app/utils/online_payment
|
|||||||
import { ConfirmPopup } from "@point_of_sale/app/utils/confirm_popup/confirm_popup";
|
import { ConfirmPopup } from "@point_of_sale/app/utils/confirm_popup/confirm_popup";
|
||||||
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
||||||
import { floatIsZero } from "@web/core/utils/numbers";
|
import { floatIsZero } from "@web/core/utils/numbers";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
patch(PaymentScreen.prototype, {
|
patch(PaymentScreen.prototype, {
|
||||||
getRemainingOnlinePaymentLines() {
|
getRemainingOnlinePaymentLines() {
|
||||||
@@ -23,7 +22,11 @@ patch(PaymentScreen.prototype, {
|
|||||||
if (amount <= 0) {
|
if (amount <= 0) {
|
||||||
this.popup.add(ErrorPopup, {
|
this.popup.add(ErrorPopup, {
|
||||||
title: this.env._t("Invalid online payment"),
|
title: this.env._t("Invalid online payment"),
|
||||||
body: sprintf(this.env._t("Online payments cannot have a negative amount (%s: %s)."), line.payment_method.name, this.env.utils.formatCurrency(amount)),
|
body: this.env._t(
|
||||||
|
"Online payments cannot have a negative amount (%s: %s).",
|
||||||
|
line.payment_method.name,
|
||||||
|
this.env.utils.formatCurrency(amount)
|
||||||
|
),
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -32,7 +35,11 @@ patch(PaymentScreen.prototype, {
|
|||||||
if (!floatIsZero(unpaidAmount - remainingAmount, this.pos.currency.decimal_places)) {
|
if (!floatIsZero(unpaidAmount - remainingAmount, this.pos.currency.decimal_places)) {
|
||||||
this.popup.add(ErrorPopup, {
|
this.popup.add(ErrorPopup, {
|
||||||
title: this.env._t("Invalid online payments"),
|
title: this.env._t("Invalid online payments"),
|
||||||
body: sprintf(this.env._t("The total amount of remaining online payments to execute (%s) doesn't correspond to the remaining unpaid amount of the order (%s)."), this.env.utils.formatCurrency(remainingAmount), this.env.utils.formatCurrency(unpaidAmount)),
|
body: this.env._t(
|
||||||
|
"The total amount of remaining online payments to execute (%s) doesn't correspond to the remaining unpaid amount of the order (%s).",
|
||||||
|
this.env.utils.formatCurrency(remainingAmount),
|
||||||
|
this.env.utils.formatCurrency(unpaidAmount)
|
||||||
|
),
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-5
@@ -5,7 +5,6 @@ import { useService } from "@web/core/utils/hooks";
|
|||||||
import { NumberPopup } from "@point_of_sale/app/utils/input_popups/number_popup";
|
import { NumberPopup } from "@point_of_sale/app/utils/input_popups/number_popup";
|
||||||
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
||||||
import { Component } from "@odoo/owl";
|
import { Component } from "@odoo/owl";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
||||||
|
|
||||||
export class TableGuestsButton extends Component {
|
export class TableGuestsButton extends Component {
|
||||||
@@ -36,10 +35,7 @@ export class TableGuestsButton extends Component {
|
|||||||
if (guestCount > max_capacity) {
|
if (guestCount > max_capacity) {
|
||||||
await this.popup.add(ErrorPopup, {
|
await this.popup.add(ErrorPopup, {
|
||||||
title: this.env._t("Blocked action"),
|
title: this.env._t("Blocked action"),
|
||||||
body: sprintf(
|
body: this.env._t("You cannot put a number that exceeds %s ", max_capacity),
|
||||||
this.env._t("You cannot put a number that exceeds %s "),
|
|
||||||
max_capacity
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import {
|
|||||||
useState,
|
useState,
|
||||||
onWillStart,
|
onWillStart,
|
||||||
} from "@odoo/owl";
|
} from "@odoo/owl";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
export class FloorScreen extends Component {
|
export class FloorScreen extends Component {
|
||||||
static components = { EditableTable, EditBar, Table };
|
static components = { EditableTable, EditBar, Table };
|
||||||
@@ -526,8 +525,8 @@ export class FloorScreen extends Component {
|
|||||||
if (this.selectedTables.length == 0) {
|
if (this.selectedTables.length == 0) {
|
||||||
const { confirmed } = await this.popup.add(ConfirmPopup, {
|
const { confirmed } = await this.popup.add(ConfirmPopup, {
|
||||||
title: `Removing floor ${this.activeFloor.name}`,
|
title: `Removing floor ${this.activeFloor.name}`,
|
||||||
body: sprintf(
|
body: this.env._t(
|
||||||
this.env._t("Removing a floor cannot be undone. Do you still wanna remove %s?"),
|
"Removing a floor cannot be undone. Do you still wanna remove %s?",
|
||||||
this.activeFloor.name
|
this.activeFloor.name
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|||||||
+4
-6
@@ -141,8 +141,8 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(Component) {
|
|||||||
await this.pos._loadPartners([sale_order.partner_id[0]]);
|
await this.pos._loadPartners([sale_order.partner_id[0]]);
|
||||||
} catch {
|
} catch {
|
||||||
const title = this.env._t("Customer loading error");
|
const title = this.env._t("Customer loading error");
|
||||||
const body = sprintf(
|
const body = this.env._t(
|
||||||
this.env._t("There was a problem in loading the %s customer."),
|
"There was a problem in loading the %s customer.",
|
||||||
sale_order.partner_id[1]
|
sale_order.partner_id[1]
|
||||||
);
|
);
|
||||||
await this.popup.add(ErrorPopup, { title, body });
|
await this.popup.add(ErrorPopup, { title, body });
|
||||||
@@ -335,10 +335,8 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(Component) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (down_payment > sale_order.amount_unpaid) {
|
if (down_payment > sale_order.amount_unpaid) {
|
||||||
const errorBody = sprintf(
|
const errorBody = this.env._t(
|
||||||
this.env._t(
|
"You have tried to charge a down payment of %s but only %s remains to be paid, %s will be applied to the purchase order line.",
|
||||||
"You have tried to charge a down payment of %s but only %s remains to be paid, %s will be applied to the purchase order line."
|
|
||||||
),
|
|
||||||
this.env.utils.formatCurrency(down_payment),
|
this.env.utils.formatCurrency(down_payment),
|
||||||
this.env.utils.formatCurrency(sale_order.amount_unpaid),
|
this.env.utils.formatCurrency(sale_order.amount_unpaid),
|
||||||
sale_order.amount_unpaid > 0
|
sale_order.amount_unpaid > 0
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { PaymentInterface } from "@point_of_sale/app/payment/payment_interface";
|
import { PaymentInterface } from "@point_of_sale/app/payment/payment_interface";
|
||||||
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
export class PaymentStripe extends PaymentInterface {
|
export class PaymentStripe extends PaymentInterface {
|
||||||
setup() {
|
setup() {
|
||||||
@@ -38,7 +37,7 @@ export class PaymentStripe extends PaymentInterface {
|
|||||||
async discoverReaders() {
|
async discoverReaders() {
|
||||||
const discoverResult = await this.terminal.discoverReaders({});
|
const discoverResult = await this.terminal.discoverReaders({});
|
||||||
if (discoverResult.error) {
|
if (discoverResult.error) {
|
||||||
this._showError(sprintf(_t("Failed to discover: %s"), discoverResult.error));
|
this._showError(_t("Failed to discover: %s", discoverResult.error));
|
||||||
} else if (discoverResult.discoveredReaders.length === 0) {
|
} else if (discoverResult.discoveredReaders.length === 0) {
|
||||||
this._showError(_t("No available Stripe readers."));
|
this._showError(_t("No available Stripe readers."));
|
||||||
} else {
|
} else {
|
||||||
@@ -108,8 +107,8 @@ export class PaymentStripe extends PaymentInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._showError(
|
this._showError(
|
||||||
sprintf(
|
_t(
|
||||||
_t("Stripe readers %s not listed in your account"),
|
"Stripe readers %s not listed in your account",
|
||||||
this.payment_method.stripe_serial_number
|
this.payment_method.stripe_serial_number
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
import { Component, markup, onRendered, onWillStart, useState } from "@odoo/owl";
|
import { Component, markup, onRendered, onWillStart, useState } from "@odoo/owl";
|
||||||
import { Layout } from "@web/search/layout";
|
import { Layout } from "@web/search/layout";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { useSetupAction } from "@web/webclient/actions/action_hook";
|
import { useSetupAction } from "@web/webclient/actions/action_hook";
|
||||||
|
|
||||||
@@ -123,8 +122,8 @@ export class ProductPricelistReport extends Component {
|
|||||||
ev.preventDefault(); // avoid automatic reloading of the page
|
ev.preventDefault(); // avoid automatic reloading of the page
|
||||||
|
|
||||||
if (this.quantities.length >= this.MAX_QTY) {
|
if (this.quantities.length >= this.MAX_QTY) {
|
||||||
let message = sprintf(
|
let message = this.env._t(
|
||||||
this.env._t("At most %s quantities can be displayed simultaneously. Remove a selected quantity to add others."),
|
"At most %s quantities can be displayed simultaneously. Remove a selected quantity to add others.",
|
||||||
this.MAX_QTY
|
this.MAX_QTY
|
||||||
);
|
);
|
||||||
await this.action.doAction(sendCustomNotification("warning", message));
|
await this.action.doAction(sendCustomNotification("warning", message));
|
||||||
@@ -139,7 +138,7 @@ export class ProductPricelistReport extends Component {
|
|||||||
this.quantities = this.quantities.sort((a, b) => a - b);
|
this.quantities = this.quantities.sort((a, b) => a - b);
|
||||||
this.renderHtml();
|
this.renderHtml();
|
||||||
} else {
|
} else {
|
||||||
let message = sprintf(this.env._t("Quantity already present (%s)."), qty);
|
let message = this.env._t("Quantity already present (%s).", qty);
|
||||||
await this.action.doAction(sendCustomNotification("info", message));
|
await this.action.doAction(sendCustomNotification("info", message));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-2
@@ -1,13 +1,12 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { PriorityField, priorityField } from "@web/views/fields/priority/priority_field";
|
import { PriorityField, priorityField } from "@web/views/fields/priority/priority_field";
|
||||||
|
|
||||||
export class PrioritySwitchField extends PriorityField {
|
export class PrioritySwitchField extends PriorityField {
|
||||||
get commands() {
|
get commands() {
|
||||||
return this.options.map(([id, name]) => [
|
return this.options.map(([id, name]) => [
|
||||||
sprintf(this.env._t("Set priority as %s"), name),
|
this.env._t("Set priority as %s", name),
|
||||||
() => this.updateRecord(id),
|
() => this.updateRecord(id),
|
||||||
{
|
{
|
||||||
category: "smart_action",
|
category: "smart_action",
|
||||||
|
|||||||
+1
-2
@@ -4,7 +4,6 @@ import {
|
|||||||
StateSelectionField,
|
StateSelectionField,
|
||||||
stateSelectionField,
|
stateSelectionField,
|
||||||
} from "@web/views/fields/state_selection/state_selection_field";
|
} from "@web/views/fields/state_selection/state_selection_field";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { useCommand } from "@web/core/commands/command_hook";
|
import { useCommand } from "@web/core/commands/command_hook";
|
||||||
import { formatSelection } from "@web/views/fields/formatters";
|
import { formatSelection } from "@web/views/fields/formatters";
|
||||||
|
|
||||||
@@ -44,7 +43,7 @@ export class ProjectTaskStateSelection extends StateSelectionField {
|
|||||||
if (this.props.viewType != 'form') {
|
if (this.props.viewType != 'form') {
|
||||||
super.setup();
|
super.setup();
|
||||||
} else {
|
} else {
|
||||||
const commandName = sprintf(this.env._t(`Set state as...`));
|
const commandName = this.env._t("Set state as...");
|
||||||
useCommand(
|
useCommand(
|
||||||
commandName,
|
commandName,
|
||||||
() => {
|
() => {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { X2ManyField, x2ManyField } from "@web/views/fields/x2many/x2many_field";
|
import { X2ManyField, x2ManyField } from "@web/views/fields/x2many/x2many_field";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { useSelectCreate, useOpenMany2XRecord} from "@web/views/fields/relational_utils";
|
import { useSelectCreate, useOpenMany2XRecord} from "@web/views/fields/relational_utils";
|
||||||
export class SMLX2ManyField extends X2ManyField {
|
export class SMLX2ManyField extends X2ManyField {
|
||||||
setup() {
|
setup() {
|
||||||
@@ -35,7 +34,7 @@ export class SMLX2ManyField extends X2ManyField {
|
|||||||
tree_view_ref: "stock.view_stock_quant_tree_simple",
|
tree_view_ref: "stock.view_stock_quant_tree_simple",
|
||||||
};
|
};
|
||||||
const productName = this.props.record.data.product_id[1];
|
const productName = this.props.record.data.product_id[1];
|
||||||
const title = sprintf(this.env._t("Add line: %s"), productName);
|
const title = this.env._t("Add line: %s", productName);
|
||||||
const alreadySelected = this.props.record.data.move_line_ids.records.filter((line) => line.data.quant_id?.[0]);
|
const alreadySelected = this.props.record.data.move_line_ids.records.filter((line) => line.data.quant_id?.[0]);
|
||||||
const domain = [
|
const domain = [
|
||||||
["product_id", "=", this.props.record.data.product_id[0]],
|
["product_id", "=", this.props.record.data.product_id[0]],
|
||||||
|
|||||||
+12
-8
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { sprintf } from '@web/core/utils/strings';
|
|
||||||
import { standardWidgetProps } from "@web/views/widgets/standard_widget_props";
|
import { standardWidgetProps } from "@web/views/widgets/standard_widget_props";
|
||||||
|
|
||||||
const { Component, useEffect, useRef, useState } = owl;
|
const { Component, useEffect, useRef, useState } = owl;
|
||||||
@@ -21,21 +20,26 @@ export class SurveyQuestionTriggerWidget extends Component {
|
|||||||
const triggerError = this.surveyQuestionTriggerError;
|
const triggerError = this.surveyQuestionTriggerError;
|
||||||
if (triggerError === "MISPLACED_TRIGGER_WARNING") {
|
if (triggerError === "MISPLACED_TRIGGER_WARNING") {
|
||||||
this.state.surveyIconWarning = true;
|
this.state.surveyIconWarning = true;
|
||||||
this.state.triggerTooltip = sprintf(
|
this.state.triggerTooltip = _t(
|
||||||
'⚠ ' + _t('This question is positioned before its trigger ("%s") and will be skipped.'),
|
'⚠ This question is positioned before its trigger ("%s") and will be skipped.',
|
||||||
triggeringQuestionTitle);
|
triggeringQuestionTitle
|
||||||
|
);
|
||||||
} else if (triggerError === "WRONG_QUESTIONS_SELECTION_WARNING") {
|
} else if (triggerError === "WRONG_QUESTIONS_SELECTION_WARNING") {
|
||||||
this.state.surveyIconWarning = true;
|
this.state.surveyIconWarning = true;
|
||||||
this.state.triggerTooltip = '⚠ ' + _t(
|
this.state.triggerTooltip = _t(
|
||||||
'Conditional display is not available when questions are randomly picked.');
|
"⚠ Conditional display is not available when questions are randomly picked."
|
||||||
|
);
|
||||||
} else if (triggerError === "MISSING_TRIGGER_ERROR") {
|
} else if (triggerError === "MISSING_TRIGGER_ERROR") {
|
||||||
// This case must be handled to not temporarily render the "normal" icon if previously
|
// This case must be handled to not temporarily render the "normal" icon if previously
|
||||||
// on an error state, which would cause a flicker as the trigger itself will be removed
|
// on an error state, which would cause a flicker as the trigger itself will be removed
|
||||||
// at next save (auto on survey form and primary list view).
|
// at next save (auto on survey form and primary list view).
|
||||||
} else {
|
} else {
|
||||||
this.state.surveyIconWarning = false;
|
this.state.surveyIconWarning = false;
|
||||||
this.state.triggerTooltip = sprintf(_t('Displayed if "%s: %s"'),
|
this.state.triggerTooltip = _t(
|
||||||
triggeringQuestionTitle, this.props.record.data.triggering_answer_id[1]);
|
'Displayed if "%s: %s"',
|
||||||
|
triggeringQuestionTitle,
|
||||||
|
this.props.record.data.triggering_answer_id[1]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.state.surveyIconWarning = false;
|
this.state.surveyIconWarning = false;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { formatAST, toPyValue } from "@web/core/py_js/py_utils";
|
|||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { TagsList } from "@web/core/tags_list/tags_list";
|
import { TagsList } from "@web/core/tags_list/tags_list";
|
||||||
import { useOwnedDialogs, useService } from "@web/core/utils/hooks";
|
import { useOwnedDialogs, useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { Expression } from "@web/core/domain_tree";
|
import { Expression } from "@web/core/domain_tree";
|
||||||
|
|
||||||
const SEARCH_LIMIT = 7;
|
const SEARCH_LIMIT = 7;
|
||||||
@@ -89,7 +88,7 @@ class AutoCompleteWithSources extends Component {
|
|||||||
const dynamicFilters = ids.length
|
const dynamicFilters = ids.length
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
description: sprintf(_t("Quick search: %s"), name),
|
description: _t("Quick search: %s", name),
|
||||||
domain: [["id", operator, ids]],
|
domain: [["id", operator, ids]],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -97,7 +96,7 @@ class AutoCompleteWithSources extends Component {
|
|||||||
// fine for now but we don't like this kind of dependence of core to views
|
// fine for now but we don't like this kind of dependence of core to views
|
||||||
const SelectCreateDialog = registry.category("dialogs").get("select_create");
|
const SelectCreateDialog = registry.category("dialogs").get("select_create");
|
||||||
this.addDialog(SelectCreateDialog, {
|
this.addDialog(SelectCreateDialog, {
|
||||||
title: sprintf(_t("Search: %s"), fieldString),
|
title: _t("Search: %s", fieldString),
|
||||||
dynamicFilters,
|
dynamicFilters,
|
||||||
resModel,
|
resModel,
|
||||||
noCreate: true,
|
noCreate: true,
|
||||||
@@ -140,13 +139,13 @@ const getFormat = (val, displayNames) => {
|
|||||||
text =
|
text =
|
||||||
typeof displayNames[val] === "string"
|
typeof displayNames[val] === "string"
|
||||||
? displayNames[val]
|
? displayNames[val]
|
||||||
: sprintf(_t(`Inaccessible/missing record ID: %s`), val);
|
: _t("Inaccessible/missing record ID: %s", val);
|
||||||
colorIndex = typeof displayNames[val] === "string" ? 0 : 2; // 0 = grey, 2 = orange
|
colorIndex = typeof displayNames[val] === "string" ? 0 : 2; // 0 = grey, 2 = orange
|
||||||
} else {
|
} else {
|
||||||
text =
|
text =
|
||||||
val instanceof Expression
|
val instanceof Expression
|
||||||
? String(val)
|
? String(val)
|
||||||
: sprintf(_t(`Invalid record ID: %s`), formatAST(toPyValue(val)));
|
: _t("Invalid record ID: %s", formatAST(toPyValue(val)));
|
||||||
colorIndex = val instanceof Expression ? 2 : 1; // 1 = red
|
colorIndex = val instanceof Expression ? 2 : 1; // 1 = red
|
||||||
}
|
}
|
||||||
return { text, colorIndex };
|
return { text, colorIndex };
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { getDefaultValue, getDefaultOperator } from "./domain_selector_fields";
|
|||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { unique, zip } from "@web/core/utils/arrays";
|
import { unique, zip } from "@web/core/utils/arrays";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import {
|
import {
|
||||||
Expression,
|
Expression,
|
||||||
toValue,
|
toValue,
|
||||||
@@ -183,7 +182,7 @@ function formatValue(val, disambiguate, fieldDef, displayNames) {
|
|||||||
if (typeof displayNames[val] === "string") {
|
if (typeof displayNames[val] === "string") {
|
||||||
val = displayNames[val];
|
val = displayNames[val];
|
||||||
} else {
|
} else {
|
||||||
return sprintf(_t(`Inaccessible/missing record ID: %s`), val);
|
return _t("Inaccessible/missing record ID: %s", val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fieldDef?.type === "selection") {
|
if (fieldDef?.type === "selection") {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import { useService } from "../utils/hooks";
|
import { useService } from "../utils/hooks";
|
||||||
import { sprintf } from "../utils/strings";
|
|
||||||
import { ConfirmationDialog } from "../confirmation_dialog/confirmation_dialog";
|
import { ConfirmationDialog } from "../confirmation_dialog/confirmation_dialog";
|
||||||
|
|
||||||
import { Component } from "@odoo/owl";
|
import { Component } from "@odoo/owl";
|
||||||
@@ -16,7 +15,10 @@ export class FileUploadProgressBar extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.dialogService.add(ConfirmationDialog, {
|
this.dialogService.add(ConfirmationDialog, {
|
||||||
body: sprintf(this.env._t("Do you really want to cancel the upload of %s?"), this.props.fileUpload.title),
|
body: this.env._t(
|
||||||
|
"Do you really want to cancel the upload of %s?",
|
||||||
|
this.props.fileUpload.title
|
||||||
|
),
|
||||||
confirm: () => {
|
confirm: () => {
|
||||||
this.props.fileUpload.xhr.abort();
|
this.props.fileUpload.xhr.abort();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import { sprintf } from "../utils/strings";
|
|
||||||
import { FileUploadProgressBar } from "./file_upload_progress_bar";
|
import { FileUploadProgressBar } from "./file_upload_progress_bar";
|
||||||
|
|
||||||
import { Component } from "@odoo/owl";
|
import { Component } from "@odoo/owl";
|
||||||
@@ -18,8 +17,8 @@ export class FileUploadProgressRecord extends Component {
|
|||||||
const mbLoaded = Math.round(fileUpload.loaded / 1000000);
|
const mbLoaded = Math.round(fileUpload.loaded / 1000000);
|
||||||
const mbTotal = Math.round(fileUpload.total / 1000000);
|
const mbTotal = Math.round(fileUpload.total / 1000000);
|
||||||
return {
|
return {
|
||||||
left: sprintf(this.env._t("Uploading... (%s%)"), percent),
|
left: this.env._t("Uploading... (%s%)", percent),
|
||||||
right: sprintf(this.env._t("(%s/%sMB)"), mbLoaded, mbTotal),
|
right: this.env._t("(%s/%sMB)", mbLoaded, mbTotal),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import { registry } from "../registry";
|
import { registry } from "../registry";
|
||||||
import { sprintf } from "../utils/strings";
|
|
||||||
|
|
||||||
import { EventBus, reactive } from "@odoo/owl";
|
import { EventBus, reactive } from "@odoo/owl";
|
||||||
|
|
||||||
@@ -56,7 +55,7 @@ export const fileUploadService = {
|
|||||||
loaded: 0,
|
loaded: 0,
|
||||||
total: 0,
|
total: 0,
|
||||||
state: "pending",
|
state: "pending",
|
||||||
title: files.length === 1 ? files[0].name : sprintf(env._t("%s Files"), files.length),
|
title: files.length === 1 ? files[0].name : env._t("%s Files", files.length),
|
||||||
type: files.length === 1 ? files[0].type : undefined,
|
type: files.length === 1 ? files[0].type : undefined,
|
||||||
});
|
});
|
||||||
uploads[upload.id] = upload;
|
uploads[upload.id] = upload;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
import { localization } from "@web/core/l10n/localization";
|
import { localization } from "@web/core/l10n/localization";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { memoize } from "@web/core/utils/functions";
|
import { memoize } from "@web/core/utils/functions";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { ensureArray } from "../utils/arrays";
|
import { ensureArray } from "../utils/arrays";
|
||||||
|
|
||||||
const { DateTime, Settings } = luxon;
|
const { DateTime, Settings } = luxon;
|
||||||
@@ -436,7 +435,7 @@ export function parseDateTime(value, options = {}) {
|
|||||||
|
|
||||||
// No working parsing methods: throw an error
|
// No working parsing methods: throw an error
|
||||||
if (!isValidDate(result)) {
|
if (!isValidDate(result)) {
|
||||||
throw new ConversionError(sprintf(_t("'%s' is not a correct date or datetime"), value));
|
throw new ConversionError(_t("'%s' is not a correct date or datetime", value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Revert to original numbering system
|
// Revert to original numbering system
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import { Deferred } from "@web/core/utils/concurrency";
|
import { Deferred } from "@web/core/utils/concurrency";
|
||||||
|
import { sprintf } from "@web/core/utils/strings";
|
||||||
|
|
||||||
export const translationLoaded = Symbol("translationLoaded");
|
export const translationLoaded = Symbol("translationLoaded");
|
||||||
export const translatedTerms = {
|
export const translatedTerms = {
|
||||||
[translationLoaded]: false,
|
[translationLoaded]: false,
|
||||||
@@ -17,11 +19,15 @@ export const translationIsReady = new Deferred();
|
|||||||
* @param {string} term
|
* @param {string} term
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export function _t(term) {
|
export function _t(term, ...values) {
|
||||||
if (translatedTerms[translationLoaded]) {
|
if (translatedTerms[translationLoaded]) {
|
||||||
return translatedTerms[term] || term;
|
const translation = translatedTerms[term] ?? term;
|
||||||
|
if (values.length === 0) {
|
||||||
|
return translation;
|
||||||
|
}
|
||||||
|
return sprintf(translation, ...values);
|
||||||
} else {
|
} else {
|
||||||
return new LazyTranslatedString(term);
|
return new LazyTranslatedString(term, ...values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,13 +41,21 @@ export function _t(term) {
|
|||||||
* @param {string} term
|
* @param {string} term
|
||||||
* @returns {LazyTranslatedString}
|
* @returns {LazyTranslatedString}
|
||||||
*/
|
*/
|
||||||
export const _lt = (term) => _t(term);
|
export const _lt = (term, ...values) => _t(term, ...values);
|
||||||
|
|
||||||
class LazyTranslatedString extends String {
|
class LazyTranslatedString extends String {
|
||||||
|
constructor(term, ...values) {
|
||||||
|
super(term);
|
||||||
|
this.values = values;
|
||||||
|
}
|
||||||
valueOf() {
|
valueOf() {
|
||||||
const term = super.valueOf();
|
const term = super.valueOf();
|
||||||
if (translatedTerms[translationLoaded]) {
|
if (translatedTerms[translationLoaded]) {
|
||||||
return translatedTerms[term] || term;
|
const translation = translatedTerms[term] ?? term;
|
||||||
|
if (this.values.length === 0) {
|
||||||
|
return translation;
|
||||||
|
}
|
||||||
|
return sprintf(translation, ...this.values);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`translation error`);
|
throw new Error(`translation error`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import core from "@web/legacy/js/services/core";
|
import core from "@web/legacy/js/services/core";
|
||||||
import session from "web.session";
|
import session from "web.session";
|
||||||
import time from "@web/legacy/js/core/time";
|
import time from "@web/legacy/js/core/time";
|
||||||
@@ -133,7 +132,7 @@ export function parseDate(value, field, options) {
|
|||||||
return date;
|
return date;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new Error(sprintf(core._t("'%s' is not a correct date"), value));
|
throw new Error(core._t("'%s' is not a correct date", value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -186,5 +185,5 @@ export function parseDateTime(value, field, options) {
|
|||||||
return datetime;
|
return datetime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new Error(sprintf(core._t("'%s' is not a correct datetime"), value));
|
throw new Error(core._t("'%s' is not a correct datetime", value));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import translation from "@web/legacy/js/core/translation";
|
import translation from "@web/legacy/js/core/translation";
|
||||||
import utils from "@web/legacy/js/core/utils";
|
import utils from "@web/legacy/js/core/utils";
|
||||||
|
|
||||||
@@ -190,7 +189,7 @@ export function auto_str_to_date (value) {
|
|||||||
try {
|
try {
|
||||||
return str_to_time(value);
|
return str_to_time(value);
|
||||||
} catch {}
|
} catch {}
|
||||||
throw new Error(sprintf(_t("'%s' is not a correct date, datetime nor time"), value));
|
throw new Error(_t("'%s' is not a correct date, datetime nor time", value));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function auto_date_to_str (value, type) {
|
export function auto_date_to_str (value, type) {
|
||||||
@@ -202,7 +201,7 @@ export function auto_date_to_str (value, type) {
|
|||||||
case 'time':
|
case 'time':
|
||||||
return time_to_str(value);
|
return time_to_str(value);
|
||||||
default:
|
default:
|
||||||
throw new Error(sprintf(_t("'%s' is not convertible to date, datetime nor time"), type));
|
throw new Error(_t("'%s' is not convertible to date, datetime nor time", type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
|
import { sprintf } from "@web/core/utils/strings";
|
||||||
import Class from "@web/legacy/js/core/class";
|
import Class from "@web/legacy/js/core/class";
|
||||||
|
|
||||||
var TranslationDataBase = Class.extend(/** @lends instance.TranslationDataBase# */{
|
var TranslationDataBase = Class.extend(/** @lends instance.TranslationDataBase# */{
|
||||||
@@ -39,9 +40,12 @@ var TranslationDataBase = Class.extend(/** @lends instance.TranslationDataBase#
|
|||||||
},
|
},
|
||||||
build_translation_function: function() {
|
build_translation_function: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var fcnt = function(str) {
|
var fcnt = function(term, ...values) {
|
||||||
var tmp = self.get(str);
|
const translation = self.get(term) ?? term;
|
||||||
return tmp === undefined ? str : tmp;
|
if (values.length === 0) {
|
||||||
|
return translation;
|
||||||
|
}
|
||||||
|
return sprintf(translation, ...values);
|
||||||
};
|
};
|
||||||
fcnt.database = this;
|
fcnt.database = this;
|
||||||
return fcnt;
|
return fcnt;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import { AlertDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
import { AlertDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { DataPoint } from "./datapoint";
|
import { DataPoint } from "./datapoint";
|
||||||
import { Record } from "./record";
|
import { Record } from "./record";
|
||||||
|
|
||||||
@@ -200,8 +199,8 @@ export class DynamicList extends DataPoint {
|
|||||||
resIds.length === this.model.activeIdsLimit &&
|
resIds.length === this.model.activeIdsLimit &&
|
||||||
resIds.length < this.count
|
resIds.length < this.count
|
||||||
) {
|
) {
|
||||||
const msg = sprintf(
|
const msg = _t(
|
||||||
_t(`Only the first %s records have been deleted (out of %s selected)`),
|
`Only the first %s records have been deleted (out of %s selected)`,
|
||||||
resIds.length,
|
resIds.length,
|
||||||
this.count
|
this.count
|
||||||
);
|
);
|
||||||
@@ -366,8 +365,8 @@ export class DynamicList extends DataPoint {
|
|||||||
resIds.length === this.model.activeIdsLimit &&
|
resIds.length === this.model.activeIdsLimit &&
|
||||||
resIds.length < this.count
|
resIds.length < this.count
|
||||||
) {
|
) {
|
||||||
const msg = sprintf(
|
const msg = _t(
|
||||||
_t("Of the %s records selected, only the first %s have been archived/unarchived."),
|
"Of the %s records selected, only the first %s have been archived/unarchived.",
|
||||||
resIds.length,
|
resIds.length,
|
||||||
this.count
|
this.count
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { useService } from "@web/core/utils/hooks";
|
|||||||
import { SearchBar } from "../search_bar/search_bar";
|
import { SearchBar } from "../search_bar/search_bar";
|
||||||
import { Dropdown } from "@web/core/dropdown/dropdown";
|
import { Dropdown } from "@web/core/dropdown/dropdown";
|
||||||
import { useCommand } from "@web/core/commands/command_hook";
|
import { useCommand } from "@web/core/commands/command_hook";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
|
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
|
||||||
|
|
||||||
import { Component, useState, onMounted, useExternalListener, useRef, useEffect } from "@odoo/owl";
|
import { Component, useState, onMounted, useExternalListener, useRef, useEffect } from "@odoo/owl";
|
||||||
@@ -35,7 +34,7 @@ export class ControlPanel extends Component {
|
|||||||
const { viewSwitcherEntries, viewType } = this.env.config;
|
const { viewSwitcherEntries, viewType } = this.env.config;
|
||||||
for (const view of viewSwitcherEntries || []) {
|
for (const view of viewSwitcherEntries || []) {
|
||||||
useCommand(
|
useCommand(
|
||||||
sprintf(this.env._t("Show %s view"), view.name),
|
this.env._t("Show %s view", view.name),
|
||||||
() => this.onViewClicked(view.type),
|
() => this.onViewClicked(view.type),
|
||||||
{
|
{
|
||||||
category: "view_switcher",
|
category: "view_switcher",
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { Domain } from "@web/core/domain";
|
|||||||
import { evaluateExpr } from "@web/core/py_js/py";
|
import { evaluateExpr } from "@web/core/py_js/py";
|
||||||
import { sortBy } from "@web/core/utils/arrays";
|
import { sortBy } from "@web/core/utils/arrays";
|
||||||
import { deepCopy } from "@web/core/utils/objects";
|
import { deepCopy } from "@web/core/utils/objects";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { SearchArchParser } from "./search_arch_parser";
|
import { SearchArchParser } from "./search_arch_parser";
|
||||||
import {
|
import {
|
||||||
constructDateDomain,
|
constructDateDomain,
|
||||||
@@ -1501,7 +1500,7 @@ export class SearchModel extends EventBus {
|
|||||||
return context;
|
return context;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
sprintf(_t("Failed to evaluate the context: %(context)s.\n%(error)s"), {
|
_t("Failed to evaluate the context: %(context)s.\n%(error)s", {
|
||||||
context,
|
context,
|
||||||
error: error.message,
|
error: error.message,
|
||||||
})
|
})
|
||||||
@@ -1589,7 +1588,7 @@ export class SearchModel extends EventBus {
|
|||||||
return params.raw ? domain : domain.toList(this.domainEvalContext);
|
return params.raw ? domain : domain.toList(this.domainEvalContext);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
sprintf(_t("Failed to evaluate the domain: %(domain)s.\n%(error)s"), {
|
_t("Failed to evaluate the domain: %(domain)s.\n%(error)s", {
|
||||||
domain: domain.toString(),
|
domain: domain.toString(),
|
||||||
error: error.message,
|
error: error.message,
|
||||||
})
|
})
|
||||||
@@ -1991,7 +1990,7 @@ export class SearchModel extends EventBus {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
sprintf(_t("Failed to evaluate the context: %(context)s.\n%(error)s"), {
|
_t("Failed to evaluate the context: %(context)s.\n%(error)s", {
|
||||||
context: searchItem.context,
|
context: searchItem.context,
|
||||||
error: error.message,
|
error: error.message,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { useOwnedDialogs, useService } from "@web/core/utils/hooks";
|
import { useOwnedDialogs, useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { Layout } from "@web/search/layout";
|
import { Layout } from "@web/search/layout";
|
||||||
import { useModelWithSampleData } from "@web/model/model";
|
import { useModelWithSampleData } from "@web/model/model";
|
||||||
import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog";
|
import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog";
|
||||||
@@ -175,7 +174,7 @@ export class CalendarController extends Component {
|
|||||||
resModel: this.model.resModel,
|
resModel: this.model.resModel,
|
||||||
resId: record.id || false,
|
resId: record.id || false,
|
||||||
context,
|
context,
|
||||||
title: record.id ? sprintf(_t("Open: %s"), record.title) : _t("New Event"),
|
title: record.id ? _t("Open: %s", record.title) : _t("New Event"),
|
||||||
viewId: this.model.formViewId,
|
viewId: this.model.formViewId,
|
||||||
onRecordSaved: () => this.model.load(),
|
onRecordSaved: () => this.model.load(),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { _t } from "@web/core/l10n/translation";
|
|||||||
import { AutoComplete } from "@web/core/autocomplete/autocomplete";
|
import { AutoComplete } from "@web/core/autocomplete/autocomplete";
|
||||||
import { Transition } from "@web/core/transition";
|
import { Transition } from "@web/core/transition";
|
||||||
import { useOwnedDialogs, useService } from "@web/core/utils/hooks";
|
import { useOwnedDialogs, useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { SelectCreateDialog } from "@web/views/view_dialogs/select_create_dialog";
|
import { SelectCreateDialog } from "@web/views/view_dialogs/select_create_dialog";
|
||||||
import { getColor } from "../colors";
|
import { getColor } from "../colors";
|
||||||
import { Component, useState } from "@odoo/owl";
|
import { Component, useState } from "@odoo/owl";
|
||||||
@@ -29,7 +28,7 @@ export class CalendarFilterPanel extends Component {
|
|||||||
return {
|
return {
|
||||||
autoSelect: true,
|
autoSelect: true,
|
||||||
resetOnSelect: true,
|
resetOnSelect: true,
|
||||||
placeholder: sprintf(_t("+ Add %s"), section.label),
|
placeholder: _t("+ Add %s", section.label),
|
||||||
sources: [
|
sources: [
|
||||||
{
|
{
|
||||||
placeholder: _t("Loading..."),
|
placeholder: _t("Loading..."),
|
||||||
@@ -93,11 +92,11 @@ export class CalendarFilterPanel extends Component {
|
|||||||
context: {},
|
context: {},
|
||||||
});
|
});
|
||||||
dynamicFilters.push({
|
dynamicFilters.push({
|
||||||
description: sprintf(_t("Quick search: %s"), request),
|
description: _t("Quick search: %s", request),
|
||||||
domain: [["id", "in", nameGets.map((nameGet) => nameGet[0])]],
|
domain: [["id", "in", nameGets.map((nameGet) => nameGet[0])]],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const title = sprintf(_t("Search: %s"), section.label);
|
const title = _t("Search: %s", section.label);
|
||||||
this.addDialog(SelectCreateDialog, {
|
this.addDialog(SelectCreateDialog, {
|
||||||
title,
|
title,
|
||||||
noCreate: true,
|
noCreate: true,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/** @odoo-module **/
|
/** @odoo-module **/
|
||||||
|
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { getDataURLFromFile } from "@web/core/utils/urls";
|
import { getDataURLFromFile } from "@web/core/utils/urls";
|
||||||
import { session } from "@web/session";
|
import { session } from "@web/session";
|
||||||
import { formatFloat } from "./formatters";
|
import { formatFloat } from "./formatters";
|
||||||
@@ -32,14 +31,11 @@ export class FileUploader extends Component {
|
|||||||
for (const file of ev.target.files) {
|
for (const file of ev.target.files) {
|
||||||
if (file.size > this.maxUploadSize) {
|
if (file.size > this.maxUploadSize) {
|
||||||
this.notification.add(
|
this.notification.add(
|
||||||
sprintf(
|
this.env._t(
|
||||||
this.env._t("The selected file exceed the maximum file size of %s."),
|
"The selected file exceed the maximum file size of %s.",
|
||||||
formatFloat(this.maxUploadSize, { humanReadable: true })
|
formatFloat(this.maxUploadSize, { humanReadable: true })
|
||||||
),
|
),
|
||||||
{
|
{ title: this.env._t("File upload"), type: "danger" }
|
||||||
title: this.env._t("File upload"),
|
|
||||||
type: "danger",
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.state.isUploading = true;
|
this.state.isUploading = true;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { formatDate, formatDateTime } from "@web/core/l10n/dates";
|
|||||||
import { localization as l10n } from "@web/core/l10n/localization";
|
import { localization as l10n } from "@web/core/l10n/localization";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { escape, intersperse, nbsp, sprintf } from "@web/core/utils/strings";
|
import { escape, intersperse, nbsp } from "@web/core/utils/strings";
|
||||||
import { isBinarySize } from "@web/core/utils/binary";
|
import { isBinarySize } from "@web/core/utils/binary";
|
||||||
|
|
||||||
import { markup } from "@odoo/owl";
|
import { markup } from "@odoo/owl";
|
||||||
@@ -364,7 +364,7 @@ export function formatX2many(value) {
|
|||||||
} else if (count === 1) {
|
} else if (count === 1) {
|
||||||
return _t("1 record");
|
return _t("1 record");
|
||||||
} else {
|
} else {
|
||||||
return sprintf(_t("%s records"), count);
|
return _t("%s records", count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { _t } from "@web/core/l10n/translation";
|
|||||||
import { evaluateExpr } from "@web/core/py_js/py";
|
import { evaluateExpr } from "@web/core/py_js/py";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { useChildRef, useOwnedDialogs, useService } from "@web/core/utils/hooks";
|
import { useChildRef, useOwnedDialogs, useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { Many2XAutocomplete, useOpenMany2XRecord } from "@web/views/fields/relational_utils";
|
import { Many2XAutocomplete, useOpenMany2XRecord } from "@web/views/fields/relational_utils";
|
||||||
import * as BarcodeScanner from "@web/webclient/barcode/barcode_scanner";
|
import * as BarcodeScanner from "@web/webclient/barcode/barcode_scanner";
|
||||||
import { standardFieldProps } from "../standard_field_props";
|
import { standardFieldProps } from "../standard_field_props";
|
||||||
@@ -20,7 +19,7 @@ class CreateConfirmationDialog extends Component {
|
|||||||
static components = { Dialog };
|
static components = { Dialog };
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
return sprintf(this.env._t("New: %s"), this.props.name);
|
return this.env._t("New: %s", this.props.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
async onCreate() {
|
async onCreate() {
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import { DropdownItem } from "@web/core/dropdown/dropdown_item";
|
|||||||
import { PropertyValue } from "./property_value";
|
import { PropertyValue } from "./property_value";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { usePopover } from "@web/core/popover/popover_hook";
|
import { usePopover } from "@web/core/popover/popover_hook";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
||||||
import { reposition } from "@web/core/position_hook";
|
import { reposition } from "@web/core/position_hook";
|
||||||
import { archParseBoolean } from "@web/views/utils";
|
import { archParseBoolean } from "@web/views/utils";
|
||||||
@@ -278,10 +277,8 @@ export class PropertiesField extends Component {
|
|||||||
this.popover.close();
|
this.popover.close();
|
||||||
const dialogProps = {
|
const dialogProps = {
|
||||||
title: _t("Delete Property Field"),
|
title: _t("Delete Property Field"),
|
||||||
body: sprintf(
|
body: _t(
|
||||||
_t(
|
'Are you sure you want to delete this property field? It will be removed for everyone using the "%s" %s.',
|
||||||
'Are you sure you want to delete this property field? It will be removed for everyone using the "%s" %s.'
|
|
||||||
),
|
|
||||||
this.parentName,
|
this.parentName,
|
||||||
this.parentString
|
this.parentString
|
||||||
),
|
),
|
||||||
@@ -325,7 +322,7 @@ export class PropertiesField extends Component {
|
|||||||
|
|
||||||
propertiesDefinitions.push({
|
propertiesDefinitions.push({
|
||||||
name: uuid(),
|
name: uuid(),
|
||||||
string: sprintf(_t("Property %s"), propertiesDefinitions.length + 1),
|
string: _t("Property %s", propertiesDefinitions.length + 1),
|
||||||
type: "char",
|
type: "char",
|
||||||
definition_changed: true,
|
definition_changed: true,
|
||||||
});
|
});
|
||||||
@@ -583,7 +580,7 @@ async function actionAddProperty(env) {
|
|||||||
if (addProperty) {
|
if (addProperty) {
|
||||||
addProperty.click();
|
addProperty.click();
|
||||||
} else {
|
} else {
|
||||||
const message = sprintf(env._t("You can not create a new property."));
|
const message = env._t("You can not create a new property.");
|
||||||
env.services.notification.add(message, { type: "danger" });
|
env.services.notification.add(message, { type: "danger" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import { Many2XAutocomplete } from "@web/views/fields/relational_utils";
|
|||||||
import { useService, useOwnedDialogs } from "@web/core/utils/hooks";
|
import { useService, useOwnedDialogs } from "@web/core/utils/hooks";
|
||||||
import { PropertyDefinitionSelection } from "./property_definition_selection";
|
import { PropertyDefinitionSelection } from "./property_definition_selection";
|
||||||
import { PropertyTags } from "./property_tags";
|
import { PropertyTags } from "./property_tags";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { SelectCreateDialog } from "@web/views/view_dialogs/select_create_dialog";
|
import { SelectCreateDialog } from "@web/views/view_dialogs/select_create_dialog";
|
||||||
import { uuid } from "../../utils";
|
import { uuid } from "../../utils";
|
||||||
|
|
||||||
@@ -341,8 +340,8 @@ export class PropertyDefinition extends Component {
|
|||||||
this.state.resModelDescription = result[0].display_name;
|
this.state.resModelDescription = result[0].display_name;
|
||||||
} catch {
|
} catch {
|
||||||
// can not read the ir.model
|
// can not read the ir.model
|
||||||
this.state.resModelDescription = sprintf(
|
this.state.resModelDescription = _t(
|
||||||
_t('You do not have access to the model "%s".'),
|
'You do not have access to the model "%s".',
|
||||||
newModel
|
newModel
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { _t } from "@web/core/l10n/translation";
|
|||||||
import { usePopover } from "@web/core/popover/popover_hook";
|
import { usePopover } from "@web/core/popover/popover_hook";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { TagsList } from "@web/core/tags_list/tags_list";
|
import { TagsList } from "@web/core/tags_list/tags_list";
|
||||||
|
|
||||||
import { Component } from "@odoo/owl";
|
import { Component } from "@odoo/owl";
|
||||||
@@ -139,7 +138,7 @@ export class PropertyTags extends Component {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
value: { toCreate: true, value: request },
|
value: { toCreate: true, value: request },
|
||||||
label: sprintf(_t('Create "%s"'), request),
|
label: _t('Create "%s"', request),
|
||||||
classList: "o_field_property_dropdown_add",
|
classList: "o_field_property_dropdown_add",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import {
|
|||||||
useOwnedDialogs,
|
useOwnedDialogs,
|
||||||
useService,
|
useService,
|
||||||
} from "@web/core/utils/hooks";
|
} from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { createElement } from "@web/core/utils/xml";
|
import { createElement } from "@web/core/utils/xml";
|
||||||
import { FormArchParser } from "@web/views/form/form_arch_parser";
|
import { FormArchParser } from "@web/views/form/form_arch_parser";
|
||||||
import { loadSubViews } from "@web/views/form/form_controller";
|
import { loadSubViews } from "@web/views/form/form_controller";
|
||||||
@@ -283,7 +282,7 @@ export class Many2XAutocomplete extends Component {
|
|||||||
|
|
||||||
if (this.props.quickCreate && request.length) {
|
if (this.props.quickCreate && request.length) {
|
||||||
options.push({
|
options.push({
|
||||||
label: sprintf(this.env._t(`Create "%s"`), request),
|
label: this.env._t('Create "%s"', request),
|
||||||
classList: "o_m2o_dropdown_option o_m2o_dropdown_option_create",
|
classList: "o_m2o_dropdown_option o_m2o_dropdown_option_create",
|
||||||
action: async (params) => {
|
action: async (params) => {
|
||||||
try {
|
try {
|
||||||
@@ -363,13 +362,13 @@ export class Many2XAutocomplete extends Component {
|
|||||||
|
|
||||||
dynamicFilters = [
|
dynamicFilters = [
|
||||||
{
|
{
|
||||||
description: sprintf(this.env._t("Quick search: %s"), request),
|
description: this.env._t("Quick search: %s", request),
|
||||||
domain: [["id", "in", nameGets.map((nameGet) => nameGet[0])]],
|
domain: [["id", "in", nameGets.map((nameGet) => nameGet[0])]],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
const title = sprintf(this.env._t("Search: %s"), fieldString);
|
const title = this.env._t("Search: %s", fieldString);
|
||||||
this.selectCreate({
|
this.selectCreate({
|
||||||
domain,
|
domain,
|
||||||
context,
|
context,
|
||||||
@@ -461,8 +460,7 @@ export function useOpenMany2XRecord({
|
|||||||
|
|
||||||
let resolve = () => {};
|
let resolve = () => {};
|
||||||
if (!title) {
|
if (!title) {
|
||||||
title = resId ? env._t("Open: %s") : env._t("Create %s");
|
title = resId ? env._t("Open: %s", fieldString) : env._t("Create %s", fieldString);
|
||||||
title = sprintf(title, fieldString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { create: canCreate, write: canWrite } = activeActions;
|
const { create: canCreate, write: canWrite } = activeActions;
|
||||||
@@ -708,8 +706,9 @@ export function useOpenX2ManyRecord({
|
|||||||
|
|
||||||
async function openRecord({ record, mode, context, title, onClose }) {
|
async function openRecord({ record, mode, context, title, onClose }) {
|
||||||
if (!title) {
|
if (!title) {
|
||||||
title = record ? env._t("Open: %s") : env._t("Create %s");
|
title = record
|
||||||
title = sprintf(title, activeField.string);
|
? env._t("Open: %s", activeField.string)
|
||||||
|
: env._t("Create %s", activeField.string);
|
||||||
}
|
}
|
||||||
const list = getList();
|
const list = getList();
|
||||||
const { archInfo, fields: _fields } = await getFormViewInfo({
|
const { archInfo, fields: _fields } = await getFormViewInfo({
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { formatDate, formatDateTime } from "@web/core/l10n/dates";
|
|||||||
import { localization } from "@web/core/l10n/localization";
|
import { localization } from "@web/core/l10n/localization";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { DateTimeField } from "../datetime/datetime_field";
|
import { DateTimeField } from "../datetime/datetime_field";
|
||||||
import { standardFieldProps } from "../standard_field_props";
|
import { standardFieldProps } from "../standard_field_props";
|
||||||
|
|
||||||
@@ -45,9 +44,9 @@ export class RemainingDaysField extends Component {
|
|||||||
return this.formattedValue;
|
return this.formattedValue;
|
||||||
}
|
}
|
||||||
if (this.diffDays < 0) {
|
if (this.diffDays < 0) {
|
||||||
return sprintf(_t("%s days ago"), -this.diffDays);
|
return _t("%s days ago", -this.diffDays);
|
||||||
}
|
}
|
||||||
return sprintf(_t("In %s days"), this.diffDays);
|
return _t("In %s days", this.diffDays);
|
||||||
}
|
}
|
||||||
|
|
||||||
get formattedValue() {
|
get formattedValue() {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { Dropdown } from "@web/core/dropdown/dropdown";
|
|||||||
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
|
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
|
||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { formatSelection } from "../formatters";
|
import { formatSelection } from "../formatters";
|
||||||
import { standardFieldProps } from "../standard_field_props";
|
import { standardFieldProps } from "../standard_field_props";
|
||||||
|
|
||||||
@@ -36,7 +35,7 @@ export class StateSelectionField extends Component {
|
|||||||
const hotkeys = ["D", "F", "G"];
|
const hotkeys = ["D", "F", "G"];
|
||||||
for (const [index, [value, label]] of this.options.entries()) {
|
for (const [index, [value, label]] of this.options.entries()) {
|
||||||
useCommand(
|
useCommand(
|
||||||
sprintf(this.env._t("Set kanban state as %s"), label),
|
this.env._t("Set kanban state as %s", label),
|
||||||
() => {
|
() => {
|
||||||
this.updateRecord(value);
|
this.updateRecord(value);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { DropdownItem } from "@web/core/dropdown/dropdown_item";
|
|||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { groupBy } from "@web/core/utils/arrays";
|
import { groupBy } from "@web/core/utils/arrays";
|
||||||
import { escape, sprintf } from "@web/core/utils/strings";
|
import { escape } from "@web/core/utils/strings";
|
||||||
import { useSpecialData } from "@web/views/fields/relational_utils";
|
import { useSpecialData } from "@web/views/fields/relational_utils";
|
||||||
import { standardFieldProps } from "../standard_field_props";
|
import { standardFieldProps } from "../standard_field_props";
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ export class StatusBarField extends Component {
|
|||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
if (this.props.withCommand) {
|
if (this.props.withCommand) {
|
||||||
const commandName = sprintf(this.env._t(`Move to %s...`), escape(this.displayName));
|
const commandName = this.env._t("Move to %s...", escape(this.displayName));
|
||||||
useCommand(
|
useCommand(
|
||||||
commandName,
|
commandName,
|
||||||
() => {
|
() => {
|
||||||
@@ -61,7 +61,7 @@ export class StatusBarField extends Component {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
useCommand(
|
useCommand(
|
||||||
sprintf(this.env._t(`Move to next %s`), this.displayName),
|
this.env._t("Move to next %s", this.displayName),
|
||||||
() => {
|
() => {
|
||||||
const options = this.computeItems(false);
|
const options = this.computeItems(false);
|
||||||
const nextOption =
|
const nextOption =
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import { Dialog } from "@web/core/dialog/dialog";
|
import { Dialog } from "@web/core/dialog/dialog";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { loadLanguages } from "@web/core/l10n/translation";
|
import { loadLanguages } from "@web/core/l10n/translation";
|
||||||
|
|
||||||
import { Component, onWillStart } from "@odoo/owl";
|
import { Component, onWillStart } from "@odoo/owl";
|
||||||
@@ -10,7 +9,7 @@ import { Component, onWillStart } from "@odoo/owl";
|
|||||||
export class TranslationDialog extends Component {
|
export class TranslationDialog extends Component {
|
||||||
setup() {
|
setup() {
|
||||||
super.setup();
|
super.setup();
|
||||||
this.title = sprintf(this.env._t("Translate: %s"), this.props.fieldName);
|
this.title = this.env._t("Translate: %s", this.props.fieldName);
|
||||||
|
|
||||||
this.orm = useService("orm");
|
this.orm = useService("orm");
|
||||||
this.user = useService("user");
|
this.user = useService("user");
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { evalDomain } from "@web/core/domain";
|
|||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { Pager } from "@web/core/pager/pager";
|
import { Pager } from "@web/core/pager/pager";
|
||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import {
|
import {
|
||||||
useActiveActions,
|
useActiveActions,
|
||||||
useAddInlineRecord,
|
useAddInlineRecord,
|
||||||
@@ -258,7 +257,7 @@ export class X2ManyField extends Component {
|
|||||||
context = makeContext([this.props.context, context]);
|
context = makeContext([this.props.context, context]);
|
||||||
if (this.isMany2Many) {
|
if (this.isMany2Many) {
|
||||||
const { string } = this.props;
|
const { string } = this.props;
|
||||||
const title = sprintf(this.env._t("Add: %s"), string);
|
const title = this.env._t("Add: %s", string);
|
||||||
return this.selectCreate({ domain, context, title });
|
return this.selectCreate({ domain, context, title });
|
||||||
}
|
}
|
||||||
if (editable) {
|
if (editable) {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { getGroupBy } from "@web/search/utils/group_by";
|
|||||||
import { GROUPABLE_TYPES } from "@web/search/utils/misc";
|
import { GROUPABLE_TYPES } from "@web/search/utils/misc";
|
||||||
import { Model } from "@web/model/model";
|
import { Model } from "@web/model/model";
|
||||||
import { computeReportMeasures, processMeasure } from "@web/views/utils";
|
import { computeReportMeasures, processMeasure } from "@web/views/utils";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { Domain } from "@web/core/domain";
|
import { Domain } from "@web/core/domain";
|
||||||
|
|
||||||
export const SEP = " / ";
|
export const SEP = " / ";
|
||||||
@@ -306,7 +305,7 @@ export class GraphModel extends Model {
|
|||||||
if (!description) {
|
if (!description) {
|
||||||
return this.env._t("Sum");
|
return this.env._t("Sum");
|
||||||
} else {
|
} else {
|
||||||
return sprintf(this.env._t("Sum (%s)"), description);
|
return this.env._t("Sum (%s)", description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { DropdownItem } from "@web/core/dropdown/dropdown_item";
|
|||||||
import { usePopover } from "@web/core/popover/popover_hook";
|
import { usePopover } from "@web/core/popover/popover_hook";
|
||||||
import { memoize } from "@web/core/utils/functions";
|
import { memoize } from "@web/core/utils/functions";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { useDebounced } from "@web/core/utils/timing";
|
import { useDebounced } from "@web/core/utils/timing";
|
||||||
import { isRelational } from "@web/model/relational_model/utils";
|
import { isRelational } from "@web/model/relational_model/utils";
|
||||||
import { isNull } from "@web/views/utils";
|
import { isNull } from "@web/views/utils";
|
||||||
@@ -168,7 +167,7 @@ export class KanbanHeader extends Component {
|
|||||||
context,
|
context,
|
||||||
resId: value,
|
resId: value,
|
||||||
resModel: groupByField.relation,
|
resModel: groupByField.relation,
|
||||||
title: sprintf(this.env._t("Edit: %s"), displayName),
|
title: this.env._t("Edit: %s", displayName),
|
||||||
onRecordSaved: async () => {
|
onRecordSaved: async () => {
|
||||||
await this.props.list.load();
|
await this.props.list.load();
|
||||||
this.props.list.model.notify();
|
this.props.list.model.notify();
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { DropdownItem } from "@web/core/dropdown/dropdown_item";
|
|||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { useTooltip } from "@web/core/tooltip/tooltip_hook";
|
import { useTooltip } from "@web/core/tooltip/tooltip_hook";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { url } from "@web/core/utils/urls";
|
import { url } from "@web/core/utils/urls";
|
||||||
import { useRecordObserver } from "@web/model/relational_model/utils";
|
import { useRecordObserver } from "@web/model/relational_model/utils";
|
||||||
import { Field } from "@web/views/fields/field";
|
import { Field } from "@web/views/fields/field";
|
||||||
@@ -334,10 +333,8 @@ export class KanbanRecord extends Component {
|
|||||||
) {
|
) {
|
||||||
this.dialog.add(KanbanCoverImageDialog, { autoOpen, fieldName, record });
|
this.dialog.add(KanbanCoverImageDialog, { autoOpen, fieldName, record });
|
||||||
} else {
|
} else {
|
||||||
const warning = sprintf(
|
const warning = env._t(
|
||||||
env._t(
|
`Could not set the cover image: incorrect field ("%s") is provided in the view.`,
|
||||||
`Could not set the cover image: incorrect field ("%s") is provided in the view.`
|
|
||||||
),
|
|
||||||
fieldName
|
fieldName
|
||||||
);
|
);
|
||||||
this.notification.add({ title: warning, type: "danger" });
|
this.notification.add({ title: warning, type: "danger" });
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { useHotkey } from "@web/core/hotkeys/hotkey_hook";
|
|||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { useBus, useService } from "@web/core/utils/hooks";
|
import { useBus, useService } from "@web/core/utils/hooks";
|
||||||
import { useSortable } from "@web/core/utils/sortable";
|
import { useSortable } from "@web/core/utils/sortable";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { isNull } from "@web/views/utils";
|
import { isNull } from "@web/views/utils";
|
||||||
import { ColumnProgress } from "@web/views/view_components/column_progress";
|
import { ColumnProgress } from "@web/views/view_components/column_progress";
|
||||||
import { useBounceButton } from "@web/views/view_hook";
|
import { useBounceButton } from "@web/views/view_hook";
|
||||||
@@ -329,7 +328,7 @@ export class KanbanRenderer extends Component {
|
|||||||
if (this.exampleData && this.exampleData.ghostColumns) {
|
if (this.exampleData && this.exampleData.ghostColumns) {
|
||||||
colNames = this.exampleData.ghostColumns;
|
colNames = this.exampleData.ghostColumns;
|
||||||
} else {
|
} else {
|
||||||
colNames = [1, 2, 3, 4].map((num) => sprintf(this.env._t("Column %s"), num));
|
colNames = [1, 2, 3, 4].map((num) => this.env._t("Column %s", num));
|
||||||
}
|
}
|
||||||
return colNames.map((colName) => ({
|
return colNames.map((colName) => ({
|
||||||
name: colName,
|
name: colName,
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { evaluateExpr } from "@web/core/py_js/py";
|
|||||||
import { registry } from "@web/core/registry";
|
import { registry } from "@web/core/registry";
|
||||||
import { Deferred, KeepLast } from "@web/core/utils/concurrency";
|
import { Deferred, KeepLast } from "@web/core/utils/concurrency";
|
||||||
import { useBus, useService } from "@web/core/utils/hooks";
|
import { useBus, useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { cleanDomFromBootstrap } from "@web/legacy/utils";
|
import { cleanDomFromBootstrap } from "@web/legacy/utils";
|
||||||
import { View, ViewNotFoundError } from "@web/views/view";
|
import { View, ViewNotFoundError } from "@web/views/view";
|
||||||
import { ActionDialog } from "./action_dialog";
|
import { ActionDialog } from "./action_dialog";
|
||||||
@@ -1306,10 +1305,7 @@ function makeActionManager(env) {
|
|||||||
const view = _getView(viewType);
|
const view = _getView(viewType);
|
||||||
if (!view) {
|
if (!view) {
|
||||||
throw new ViewNotFoundError(
|
throw new ViewNotFoundError(
|
||||||
sprintf(
|
env._t("No view of type '%s' could be found in the current action.", viewType)
|
||||||
env._t("No view of type '%s' could be found in the current action."),
|
|
||||||
viewType
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const newController = controller.action.controllers[viewType] || {
|
const newController = controller.action.controllers[viewType] || {
|
||||||
|
|||||||
@@ -33,10 +33,7 @@ class InvalidAction extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted() {
|
onMounted() {
|
||||||
const message = sprintf(
|
const message = this.env._t("No action with id '%s' could be found", this.props.actionId);
|
||||||
this.env._t("No action with id '%s' could be found"),
|
|
||||||
this.props.actionId
|
|
||||||
);
|
|
||||||
this.notification.add(message, { type: "danger" });
|
this.notification.add(message, { type: "danger" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -4,7 +4,6 @@ import { registry } from "@web/core/registry";
|
|||||||
import { _t } from "@web/core/l10n/translation";
|
import { _t } from "@web/core/l10n/translation";
|
||||||
import { unique } from "@web/core/utils/arrays";
|
import { unique } from "@web/core/utils/arrays";
|
||||||
import { useService } from "@web/core/utils/hooks";
|
import { useService } from "@web/core/utils/hooks";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
|
|
||||||
import { Component, useState, onWillStart } from "@odoo/owl";
|
import { Component, useState, onWillStart } from "@odoo/owl";
|
||||||
import { standardWidgetProps } from "@web/views/widgets/standard_widget_props";
|
import { standardWidgetProps } from "@web/views/widgets/standard_widget_props";
|
||||||
@@ -70,15 +69,15 @@ class ResConfigInviteUsers extends Component {
|
|||||||
});
|
});
|
||||||
switch (invalidEmails.length) {
|
switch (invalidEmails.length) {
|
||||||
case 1:
|
case 1:
|
||||||
return sprintf(_t("Invalid email address: %(address)s"), {
|
return _t("Invalid email address: %(address)s", {
|
||||||
address: invalidEmails[0],
|
address: invalidEmails[0],
|
||||||
});
|
});
|
||||||
case 2:
|
case 2:
|
||||||
return sprintf(_t("Invalid email addresses: %(2 addresses)s"), {
|
return _t("Invalid email addresses: %(2 addresses)s", {
|
||||||
"2 addresses": listFormatter.format(invalidEmails),
|
"2 addresses": listFormatter.format(invalidEmails),
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
return sprintf(_t("Invalid email addresses: %(addresses)s"), {
|
return _t("Invalid email addresses: %(addresses)s", {
|
||||||
addresses: listFormatter.format(invalidEmails),
|
addresses: listFormatter.format(invalidEmails),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,3 +171,23 @@ QUnit.test("tamil has the correct numbering system", async (assert) => {
|
|||||||
"௧௦/௧௨/௨௦௨௧ ௧௨:௦௦:௦௦"
|
"௧௦/௧௨/௨௦௨௧ ௧௨:௦௦:௦௦"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test(
|
||||||
|
"_t fills the format specifiers in translated terms with its extra arguments",
|
||||||
|
async (assert) => {
|
||||||
|
patchWithCleanup(translatedTerms, { "Due in %s days": "Échéance dans %s jours" });
|
||||||
|
const translatedStr = _t("Due in %s days", 513);
|
||||||
|
assert.strictEqual(translatedStr, "Échéance dans 513 jours");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
QUnit.test(
|
||||||
|
"_t fills the format specifiers in lazy translated terms with its extra arguments",
|
||||||
|
async (assert) => {
|
||||||
|
translatedTerms[translationLoaded] = false;
|
||||||
|
const translatedStr = _t("Due in %s days", 513);
|
||||||
|
patchWithCleanup(translatedTerms, { "Due in %s days": "Échéance dans %s jours" });
|
||||||
|
translatedTerms[translationLoaded] = true;
|
||||||
|
assert.equal(translatedStr, "Échéance dans 513 jours");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import dom from "@web/legacy/js/core/dom";
|
|||||||
import Dialog from "@web/legacy/js/core/dialog";
|
import Dialog from "@web/legacy/js/core/dialog";
|
||||||
import Widget from "@web/legacy/js/core/widget";
|
import Widget from "@web/legacy/js/core/widget";
|
||||||
import localStorage from "@web/legacy/js/core/local_storage";
|
import localStorage from "@web/legacy/js/core/local_storage";
|
||||||
import { sprintf } from "@web/core/utils/strings";
|
|
||||||
import { debounce } from "@web/core/utils/timing";
|
import { debounce } from "@web/core/utils/timing";
|
||||||
import { sortBy } from "@web/core/utils/arrays";
|
import { sortBy } from "@web/core/utils/arrays";
|
||||||
import { pick } from "@web/core/utils/objects";
|
import { pick } from "@web/core/utils/objects";
|
||||||
@@ -429,11 +428,11 @@ var ViewEditor = Widget.extend({
|
|||||||
this.aceEditor.setSession(editingSession);
|
this.aceEditor.setSession(editingSession);
|
||||||
|
|
||||||
if (this.currentType === 'xml') {
|
if (this.currentType === 'xml') {
|
||||||
this.$viewID.text(sprintf(_t("Template ID: %s"), this.views[resID].key));
|
this.$viewID.text(_t("Template ID: %s", this.views[resID].key));
|
||||||
} else if (this.currentType === 'scss') {
|
} else if (this.currentType === 'scss') {
|
||||||
this.$viewID.text(sprintf(_t("SCSS file: %s"), resID));
|
this.$viewID.text(_t("SCSS file: %s", resID));
|
||||||
} else {
|
} else {
|
||||||
this.$viewID.text(sprintf(_t("JS file: %s"), resID));
|
this.$viewID.text(_t("JS file: %s", resID));
|
||||||
}
|
}
|
||||||
const isCustomized = this._isCustomResource(resID);
|
const isCustomized = this._isCustomResource(resID);
|
||||||
this.$lists[this.currentType].select2('val', resID);
|
this.$lists[this.currentType].select2('val', resID);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user