OWL
data_display
Pivot Renderer
Odoo 19 OWL component — Pivot Renderer (views)
Live preview
Interactive
Source excerpt
web/static/src/views/pivot/pivot_renderer.js
import { Component, onWillUpdateProps, useRef } from "@odoo/owl";
import { CheckBox } from "@web/core/checkbox/checkbox";
import { Dropdown } from "@web/core/dropdown/dropdown";
import { DropdownState } from "@web/core/dropdown/dropdown_hooks";
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
import { localization } from "@web/core/l10n/localization";
import { _t } from "@web/core/l10n/translation";
import { download } from "@web/core/network/download";
import { usePopover } from "@web/core/popover/popover_hook";
import { registry } from "@web/core/registry";
import { user } from "@web/core/user";
import { sortBy } from "@web/core/utils/arrays";
import { useService } from "@web/core/utils/hooks";
import { CustomGroupByItem } from "@web/search/custom_group_by_item/custom_group_by_item";
import { PropertiesGroupByItem } from "@web/search/properties_group_by_item/properties_group_by_item";
import { getIntervalOptions } from "@web/search/utils/dates";
import { GROUPABLE_TYPES } from "@web/search/utils/misc";
import { MultiCurrencyPopover } from "@web/views/view_components/multi_currency_popover";
import { ReportViewMeasures } from "@web/views/view_components/report_view_measures";
const formatters = registry.category("formatters");
class PivotDropdown extends Dropdown {
/**
* @override
*/
get position() {
return this.props.state.position || "bottom-start";
}
/**
* @override
*/
get target() {
return this.props.state.target;
}
}
export class PivotRenderer extends Component {
static template = "web.PivotRenderer";
static components = {
CheckBox,
CustomGroupByItem,
Dropdown,
DropdownItem,
PivotDropdown,
PropertiesGroupByItem,
ReportViewMeasures,
};
static props = ["model", "buttonTemplate"];
setup() {
this.actionService = useService("action");
this.model = this.props.model;
this.table = this.model.getTable();
this.l10n = localization;
this.tableRef = useRef("table");
this.dropdown = {
state: new DropdownState({
onClose: () => {
delete this.dropdown.cellInfo;
delete this.dropdown.state.target;
delete this.dropdown.state.position;
},
}),
};
this.multiCurrencyPopover = usePopover(MultiCurrencyPopover, {
position: "right",
});
const fields = [];
for (const [fieldName, field] of Object.entries(this.env.searchModel.searchViewFields)) {
if (this.validateField(fieldName, field)) {
fields.push(Object.assign({ name: fieldName }, field));
}
}
this.fields = sortBy(fields, "string");
onWillUpdateProps(this.onWillUpdateProps);
}
onWillUpdateProps() {
this.table = this.model.getTable();
}
/**
* Get the formatted value of the cell.
*
* @private
* @param {Object} cell
* @returns {string} Formatted value
*/
getFormattedValue(cell) {
const field = this.model.metaData.measures[cell.measure];
const fieldAttrs = this.model.metaData.fieldAttrs[cell.measure] ?? {};
const fieldInfo = {
options: fieldAttrs.options ?? {},
attrs: fieldAttrs,
};
let formatType = this.model.metaData.widgets[cell.measure];
if (!formatType) {
const fieldType = field.type;
formatType = ["many2one", "reference"].includes(fieldType) ? "integer" : fieldType;
}
const formatter = formatters.get(formatType);
const formatOptions = { field };
if (formatter.extractOptions) {
Object.assign(formatOptions, formatter.extractOptions(fieldInfo));
}
if (formatType === "monetary") {
if (cell.currencyIds.length > 1) {
formatOptions.currencyId = user.activeCompany.currency_id;
return {
rawValue: cell.value,
value: formatter(cell.value, formatOptions),
currencies: cell.currencyIds,
};
}
formatOptions.currencyId = cell.currencyIds[0];
}
return { value: formatter(cell.value, formatOptions) };
}
Registry / API
- Registry name
PivotRenderer- Category
—- Module
web- Slug
pivot-renderer- Nav group
data_display