[IMP] spreadsheet: update o_spreadsheet to latest version

### Contains the following commits:

https://github.com/odoo/o-spreadsheet/commit/ec749cf1 [REL] 16.2.0-alpha.3
https://github.com/odoo/o-spreadsheet/commit/d7267cfa [IMP] selection input: dynamic highlight followup
https://github.com/odoo/o-spreadsheet/commit/de0cdc02 [FIX] figure,chart: Enforce unicity of figure ids
https://github.com/odoo/o-spreadsheet/commit/2410e9d2 [IMP] color_picker: make the color picker a popover
https://github.com/odoo/o-spreadsheet/commit/5ff12582 [FIX] bundle_xml: small fixes for script bundling the xmls
https://github.com/odoo/o-spreadsheet/commit/cf82dbd6 [REV] charts: Fix chart duplicated ids
https://github.com/odoo/o-spreadsheet/commit/a4d593fb [REV] figure,chart: Prevent destructive creation
https://github.com/odoo/o-spreadsheet/commit/eb626ad0 [REL] 16.2.0-alpha.2
https://github.com/odoo/o-spreadsheet/commit/2afe3505 [FIX] chart: Remove forwardport comments Task: 3210689
https://github.com/odoo/o-spreadsheet/commit/2048d9ac [IMP] config: GH release follow semantic versions of package
https://github.com/odoo/o-spreadsheet/commit/00bd206c [IMP] config: tag npm publications
https://github.com/odoo/o-spreadsheet/commit/c66113b3 [FIX] server: server checking the wrong dir to watch for changes
https://github.com/odoo/o-spreadsheet/commit/38af1607 [FIX] config: Fix the action version extractor
https://github.com/odoo/o-spreadsheet/commit/162451a3 [REL] 16.2.0-alpha.1
https://github.com/odoo/o-spreadsheet/commit/92eaf0f5 [FIX] figures: menu not displayed for small figures positioned left
https://github.com/odoo/o-spreadsheet/commit/2855f543 [REL] 16.2.0-alpha.0
https://github.com/odoo/o-spreadsheet/commit/e3653157 [IMP] config: Add Github Action to automatically release and publish on npm
https://github.com/odoo/o-spreadsheet/commit/dfc2cf96 [IMP] config,*: Prepare introduction of releases
https://github.com/odoo/o-spreadsheet/commit/bf7c536e [IMP] doc: adapt the doc to the new API for arguments
https://github.com/odoo/o-spreadsheet/commit/270c02e2 [FIX] figure,chart,image: Prevent destructive creation
https://github.com/odoo/o-spreadsheet/commit/34fc5622 [FIX] charts: Fix chart duplicated ids
https://github.com/odoo/o-spreadsheet/commit/8f75a4f3 [FIX] chart,image: Prevent destructed charts on duplicated sheet
https://github.com/odoo/o-spreadsheet/commit/a815a167 [IMP] functions: translate argument description
https://github.com/odoo/o-spreadsheet/commit/c215783e [IMP] helpers: export lazy function
https://github.com/odoo/o-spreadsheet/commit/f6dfe33f [REM/IMP] css: remove unused classes and improved a bit the css
https://github.com/odoo/o-spreadsheet/commit/fbd86375 [REF] port: run server on 9090 instead of 9000
https://github.com/odoo/o-spreadsheet/commit/8cbfba42 [IMP] top_bar: added and updated tooltips
https://github.com/odoo/o-spreadsheet/commit/7421765d [IMP] figure: remove useless chart registry filling
https://github.com/odoo/o-spreadsheet/commit/7b31778f [FIX] selection input: dynamic highlights
https://github.com/odoo/o-spreadsheet/commit/84ae26f2 [FIX] composer: fix wrong style attribute
https://github.com/odoo/o-spreadsheet/commit/58b09153 [FIX] corner: Fix missing background color
https://github.com/odoo/o-spreadsheet/commit/155c6af3 [IMP] bottom_bar: Add drag&drop on sheet tab.
https://github.com/odoo/o-spreadsheet/commit/d641b2cf [FIX] menus,charts: missing translations
https://github.com/odoo/o-spreadsheet/commit/36df3326 [FIX] selection: uncomment test
https://github.com/odoo/o-spreadsheet/commit/990c158b [FIX] font_size_editor: add props definition
https://github.com/odoo/o-spreadsheet/commit/4dfa6d3e [IMP] autofill: support edge scrolling
https://github.com/odoo/o-spreadsheet/commit/a198f5c9 [IMP] Components: extract color picker entry component

closes odoo/odoo#114388

Signed-off-by: Pierre Rousseau (pro) <pro@odoo.com>
This commit is contained in:
Rémi Rahir (rar)
2023-03-07 02:00:06 +01:00
parent 2f992e6cd1
commit 406abe1f6e
8 changed files with 1840 additions and 1764 deletions
@@ -2,7 +2,7 @@
import { _t } from "@web/core/l10n/translation";
import spreadsheet from "../o_spreadsheet/o_spreadsheet_extended";
const { args, toString, toJSDate } = spreadsheet.helpers;
const { arg, toString, toJSDate } = spreadsheet.helpers;
const { functionRegistry } = spreadsheet.registries;
@@ -15,10 +15,10 @@ functionRegistry
const _date = date ? toJSDate(date) : undefined;
return this.getters.getCurrencyRate(from, to, _date);
},
args: args(`
currency_from (string) ${_t("First currency code.")}
currency_to (string) ${_t("Second currency code.")}
date (date, optional) ${_t("Date of the rate.")}
`),
args: [
arg("currency_from (string)", _t("First currency code.")),
arg("currency_to (string)", _t("Second currency code.")),
arg("date (date, optional)", _t("Date of the rate.")),
],
returns: ["NUMBER"],
});
@@ -3,7 +3,7 @@
import { _t } from "web.core";
import spreadsheet from "@spreadsheet/o_spreadsheet/o_spreadsheet_extended";
const { args, toString, toNumber } = spreadsheet.helpers;
const { arg, toString, toNumber } = spreadsheet.helpers;
const { functionRegistry } = spreadsheet.registries;
//--------------------------------------------------------------------------
@@ -18,11 +18,11 @@ function assertListsExists(listId, getters) {
functionRegistry.add("ODOO.LIST", {
description: _t("Get the value from a list."),
args: args(`
list_id (string) ${_t("ID of the list.")}
index (string) ${_t("Position of the record in the list.")}
field_name (string) ${_t("Name of the field.")}
`),
args: [
arg("list_id (string)", _t("ID of the list.")),
arg("index (string)", _t("Position of the record in the list.")),
arg("field_name (string)", _t("Name of the field.")),
],
compute: function (listId, index, fieldName) {
const id = toString(listId);
const position = toNumber(index) - 1;
@@ -60,10 +60,10 @@ functionRegistry.add("ODOO.LIST", {
functionRegistry.add("ODOO.LIST.HEADER", {
description: _t("Get the header of a list."),
args: args(`
list_id (string) ${_t("ID of the list.")}
field_name (string) ${_t("Name of the field.")}
`),
args: [
arg("list_id (string)", _t("ID of the list.")),
arg("field_name (string)", _t("Name of the field.")),
],
compute: function (listId, fieldName) {
const id = toString(listId);
const field = toString(fieldName);
File diff suppressed because it is too large Load Diff
@@ -25,16 +25,16 @@
</t>
<t t-name="o-spreadsheet-Autofill" owl="1">
<div class="o-autofill" t-att-style="style"/>
<div
class="o-autofill"
class="o-autofill-handler"
t-att-style="handlerStyle"
t-on-mousedown="onMouseDown"
t-att-style="style"
t-on-dblclick="onDblClick">
<div class="o-autofill-handler" t-att-style="styleHandler"/>
<t t-set="tooltip" t-value="getTooltip()"/>
<div t-if="tooltip" class="o-autofill-nextvalue" t-att-style="styleNextvalue">
<t t-component="tooltip.component" t-props="tooltip.props"/>
</div>
t-on-dblclick="onDblClick"
/>
<t t-set="tooltip" t-value="getTooltip()"/>
<div t-if="tooltip" class="o-autofill-nextvalue" t-att-style="styleNextValue">
<t t-component="tooltip.component" t-props="tooltip.props"/>
</div>
</t>
@@ -65,14 +65,16 @@
t-if="state.isSheetListScrollableLeft"
/>
<div
class="o-sheet-list d-flex w-100 overflow-hidden"
class="o-sheet-list d-flex w-100 overflow-hidden px-1"
t-ref="sheetList"
t-on-wheel="onWheel"
t-on-scroll="onScroll">
<t t-foreach="getVisibleSheets()" t-as="sheet" t-key="sheet.id">
<t t-foreach="getSheets()" t-as="sheet" t-key="sheet.id">
<BottomBarSheet
style="getSheetStyle(sheet.id)"
sheetId="sheet.id"
openContextMenu="(registry, ev) => this.onSheetContextMenu(sheet.id, registry, ev)"
onMouseDown="(ev) => this.onSheetMouseDown(sheet.id, ev)"
/>
</t>
</div>
@@ -134,9 +136,10 @@
<Ripple>
<div
class="o-sheet position-relative d-flex align-items-center user-select-none text-nowrap "
t-on-click="() => this.clickSheet()"
t-on-mousedown="(ev) => this.onMouseDown(ev)"
t-on-contextmenu.prevent="(ev) => this.onContextMenu(ev)"
t-ref="sheetDiv"
t-att-style="props.style"
t-att-title="sheetName"
t-att-data-id="props.sheetId"
t-att-class="{active: isSheetActive}">
@@ -181,93 +184,118 @@
</t>
<t t-name="o-spreadsheet-ColorPicker" owl="1">
<div
class="o-color-picker"
t-att-class="props.dropdownDirection || 'right'"
t-on-click.stop=""
t-att-style="colorPickerStyle">
<div class="o-color-picker-section-name">Standard</div>
<div class="colors-grid">
<div
t-foreach="COLORS"
t-as="color"
t-key="color"
class="o-color-picker-line-item"
t-att-data-color="color"
t-on-click="() => this.onColorClick(color)"
t-attf-style="background-color:{{color}};">
<Popover t-props="popoverProps">
<div class="o-color-picker" t-on-click.stop="" t-att-style="colorPickerStyle">
<div class="o-color-picker-section-name">Standard</div>
<div class="colors-grid">
<div
t-if="props.currentColor === color"
align="center"
t-attf-style="color:{{getCheckMarkColor()}}">
t-foreach="COLORS"
t-as="color"
t-key="color"
class="o-color-picker-line-item"
t-att-data-color="color"
t-on-click="() => this.onColorClick(color)"
t-attf-style="background-color:{{color}};">
<div
t-if="props.currentColor === color"
align="center"
t-attf-style="color:{{getCheckMarkColor()}}">
&#10004;
</div>
</div>
</div>
<div class="o-separator"/>
<div class="o-color-picker-section-name">
<span>Custom</span>
</div>
<div class="colors-grid">
<div
class="o-color-picker-toggler o-color-picker-line-item"
t-on-click.stop="toggleColorPicker">
<div align="center">+</div>
</div>
<div
t-foreach="env.model.getters.getCustomColors()"
t-as="color"
t-key="color"
class="o-color-picker-line-item"
t-att-data-color="color"
t-attf-style="background-color:{{color}};"
t-on-click="() => this.onColorClick(color)">
<div
t-if="props.currentColor === color"
align="center"
t-attf-style="color:{{getCheckMarkColor()}}">
&#10004;
</div>
</div>
</div>
<div t-if="state.showGradient" class="o-custom-selector">
<div class="o-magnifier-glass" t-att-style="magnifyingGlassStyle"/>
<div
class="o-gradient"
t-on-click.stop="computeCustomColor"
t-on-mouseout="hideMagnifier"
t-on-mousemove="moveMagnifier"
t-on-mouseover="showMagnifier"
/>
<div class="o-custom-input-preview">
<input
type="text"
t-att-class="{'o-wrong-color': state.isCurrentColorInvalid }"
t-on-click.stop=""
t-model="state.currentColor"
<div class="o-separator"/>
<div class="o-color-picker-section-name">
<span>Custom</span>
</div>
<div class="colors-grid">
<div
class="o-color-picker-toggler o-color-picker-line-item"
t-on-click.stop="toggleColorPicker">
<div align="center">+</div>
</div>
<div
t-foreach="env.model.getters.getCustomColors()"
t-as="color"
t-key="color"
class="o-color-picker-line-item"
t-att-data-color="color"
t-attf-style="background-color:{{color}};"
t-on-click="() => this.onColorClick(color)">
<div
t-if="props.currentColor === color"
align="center"
t-attf-style="color:{{getCheckMarkColor()}}">
&#10004;
</div>
</div>
</div>
<div t-if="state.showGradient" class="o-custom-selector">
<div class="o-magnifier-glass" t-att-style="magnifyingGlassStyle"/>
<div
class="o-gradient"
t-on-click.stop="computeCustomColor"
t-on-mouseout="hideMagnifier"
t-on-mousemove="moveMagnifier"
t-on-mouseover="showMagnifier"
/>
<div class="o-color-preview" t-attf-style="background-color:{{state.currentColor}}"/>
<div class="o-custom-input-preview">
<input
type="text"
t-att-class="{'o-wrong-color': state.isCurrentColorInvalid }"
t-on-click.stop=""
t-model="state.currentColor"
/>
<div class="o-color-preview" t-attf-style="background-color:{{state.currentColor}}"/>
</div>
<div class="o-custom-input-buttons">
<button class="o-add-button" t-on-click="setCustomColor">Add</button>
</div>
</div>
<div class="o-custom-input-buttons">
<button class="o-add-button" t-on-click="setCustomColor">Add</button>
<div class="o-separator"/>
<div class="o-buttons">
<button t-on-click="resetColor" class="o-cancel">Reset</button>
</div>
</div>
<div class="o-separator"/>
<div class="o-buttons">
<button t-on-click="resetColor" class="o-cancel">Reset</button>
</Popover>
</t>
<t t-name="o-spreadsheet-ColorPickerWidget" owl="1">
<div class="o-color-picker-widget">
<div
class="o-color-picker-button"
t-ref="colorPickerButton"
t-on-click.stop="props.toggleColorPicker"
t-att-title="props.title"
t-att-class="props.class ? props.class : 'o-color-picker-button-style'"
t-att-disabled="props.disabled">
<span t-att-style="iconStyle">
<t t-call="{{props.icon}}"/>
</span>
</div>
<ColorPicker
t-if="props.showColorPicker"
anchorRect="colorPickerAnchorRect"
onColorPicked="props.onColorPicked"
currentColor="props.currentColor"
maxHeight="props.dropdownMaxHeight"
/>
</div>
</t>
<t t-name="o-spreadsheet-TextValueProvider" owl="1">
<div t-att-class="{'o-autocomplete-dropdown':props.values.length}">
<div
t-att-class="{
'o-autocomplete-dropdown':props.values.length,
'shadow':props.values.length}">
<t t-foreach="props.values" t-as="v" t-key="v.text">
<div
class="d-flex flex-column"
t-att-class="{'o-autocomplete-value-focus': props.selectedIndex === v_index}"
t-on-click="() => this.props.onValueSelected(v.text)">
<div class="o-autocomplete-value" t-esc="v.text"/>
<div
class="o-autocomplete-description"
class="o-autocomplete-description text-truncate"
t-esc="v.description"
t-if="props.selectedIndex === v_index"
/>
@@ -323,17 +351,17 @@
<t t-name="o-spreadsheet-FunctionDescriptionProvider" owl="1">
<div
class="o-formula-assistant-container"
class="o-formula-assistant-container user-select-none shadow"
t-att-class="{
'o-formula-assistant-event-none': assistantState.allowCellSelectionBehind,
'o-formula-assistant-event-auto': !assistantState.allowCellSelectionBehind
'pe-none': assistantState.allowCellSelectionBehind,
'pe-auto': !assistantState.allowCellSelectionBehind
}">
<t t-set="context" t-value="getContext()"/>
<div
class="o-formula-assistant"
class="o-formula-assistant bg-white"
t-if="context.functionName"
t-on-mousemove="onMouseMove"
t-att-class="{'o-formula-assistant-transparency': assistantState.allowCellSelectionBehind}">
t-att-class="{'opacity-25': assistantState.allowCellSelectionBehind}">
<div class="o-formula-assistant-head">
<span t-esc="context.functionName"/>
(
@@ -351,14 +379,14 @@
)
</div>
<div class="o-formula-assistant-core">
<div class="o-formula-assistant-core pb-3 m-3">
<div class="o-formula-assistant-gray">ABOUT</div>
<div t-esc="context.functionDescription.description"/>
</div>
<t t-foreach="context.functionDescription.args" t-as="arg" t-key="arg.name">
<div
class="o-formula-assistant-arg"
class="o-formula-assistant-arg p-3 pt-0 display-flex flex-column"
t-att-class="{
'o-formula-assistant-gray': context.argToFocus >= '0',
'o-formula-assistant-focus': context.argToFocus === arg_index,
@@ -368,8 +396,8 @@
<span
t-if="arg.optional || arg.repeating || arg.default ">&#xA0;- [optional]&#xA0;</span>
<span t-if="arg.default">
<span>default:&#xA0;</span>
<t t-esc="arg.defaultValue"/>
<span>&#xA0;by default</span>
</span>
<span t-if="arg.repeating">repeatable</span>
</div>
@@ -820,8 +848,8 @@
onMouseWheel.bind="onMouseWheel"
onClosePopover.bind="onClosePopover"
/>
<t t-if="env.model.getters.getEditionMode() === 'inactive' and isAutoFillActive()">
<Autofill position="getAutofillPosition()"/>
<t t-if="env.model.getters.getEditionMode() === 'inactive'">
<Autofill position="getAutofillPosition()" isVisible="isAutofillVisible"/>
</t>
<t t-if="env.model.getters.getEditionMode() !== 'inactive'">
<t t-foreach="env.model.getters.getHighlights()" t-as="highlight" t-key="highlight_index">
@@ -1758,7 +1786,7 @@
<input
type="text"
spellcheck="false"
t-on-change="(ev) => this.onInputChanged(range.id, ev)"
t-on-input="(ev) => this.onInputChanged(range.id, ev)"
t-on-focus="() => this.focus(range.id)"
t-on-keydown="onKeydown"
t-att-value="range.xc"
@@ -1770,6 +1798,7 @@
'o-invalid': isInvalid || !range.isValidRange,
'text-decoration-underline': range.isFocused and state.mode === 'select-range'
}"
t-ref="{{range.isFocused ? 'focused' : 'unfocused'}}Input"
/>
<button
class="o-btn o-remove-selection"
@@ -1783,7 +1812,7 @@
<button class="o-btn-action o-add-selection" t-if="canAddRange" t-on-click="addEmptyInput">
Add range
</button>
<button class="o-btn-action o-selection-ok" t-if="hasFocus" t-on-click="disable">
<button class="o-btn-action o-selection-ok" t-if="hasFocus" t-on-click="confirm">
Confirm
</button>
</div>
@@ -1855,22 +1884,17 @@
<t t-name="o-spreadsheet-BarChartDesignPanel" owl="1">
<div>
<div class="o-section">
<div class="o-section o-chart-background-color">
<div class="o-section-title">Background color</div>
<div class="o-with-color-picker">
Select a color...
<span
t-att-style="props.definition.background ? `border-color: ${props.definition.background}` : 'border-bottom-style: hidden'"
t-on-click.stop="toggleColorPicker">
<t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
</span>
<ColorPicker
t-if="state.fillColorTool"
onColorPicked="(color) => this.updateBackgroundColor(color)"
currentColor="props.definition.background"
t-key="backgroundColor"
/>
</div>
Select a color...
<ColorPickerWidget
currentColor="props.definition.background"
toggleColorPicker="() => this.toggleColorPicker()"
showColorPicker="state.fillColorTool"
onColorPicked="(color) => this.updateBackgroundColor(color)"
title="env._t('Background Color')"
icon="'o-spreadsheet-Icon.FILL_COLOR'"
/>
</div>
<div class="o-section o-chart-title">
<div class="o-section-title">Title</div>
@@ -1931,23 +1955,17 @@
<t t-name="o-spreadsheet-GaugeChartDesignPanel" owl="1">
<div>
<div class="o-section">
<div class="o-section o-chart-background-color">
<div class="o-section-title">Background color</div>
<div class="o-with-color-picker">
Select a color...
<span
title="Background Color"
t-att-style="props.definition.background ? `border-color: ${props.definition.background}` : 'border-bottom-style: hidden'"
t-on-click.stop="() => this.toggleMenu('backgroundColor', ev)">
<t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
</span>
<ColorPicker
t-if="state.openedMenu === 'backgroundColor'"
onColorPicked="(color) => this.updateBackgroundColor(color)"
currentColor="props.definition.background"
t-key="backgroundColor"
/>
</div>
Select a color...
<ColorPickerWidget
currentColor="props.definition.background"
toggleColorPicker="() => this.toggleMenu('backgroundColor', ev)"
showColorPicker="state.openedMenu === 'backgroundColor'"
onColorPicked="(color) => this.updateBackgroundColor(color)"
title="env._t('Background Color')"
icon="'o-spreadsheet-Icon.FILL_COLOR'"
/>
</div>
<div class="o-section o-chart-title">
@@ -2026,22 +2044,13 @@
<tr>
<td>
<div class="o-tools">
<div class="o-tool o-dropdown o-with-color">
<span
title="Fill Color"
t-attf-style="border-color:{{sectionRule.colors.upperColor}}"
t-on-click.stop="(ev) => this.toggleMenu('sectionColor-upperColor', ev)">
<t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
</span>
<ColorPicker
t-if="state.openedMenu === 'sectionColor-upperColor'"
onColorPicked="(color) => this.updateSectionColor('upperColor', color)"
currentColor="sectionRule.colors.upperColor"
dropdownDirection="'right'"
/>
</div>
</div>
<ColorPickerWidget
currentColor="sectionRule.colors.upperColor"
toggleColorPicker="(ev) => this.toggleMenu('sectionColor-upperColor', ev)"
showColorPicker="state.openedMenu === 'sectionColor-upperColor'"
onColorPicked="(color) => this.updateSectionColor('upperColor', color)"
icon="'o-spreadsheet-Icon.FILL_COLOR'"
/>
</td>
<td>Else</td>
<td/>
@@ -2055,22 +2064,13 @@
<t t-name="o-spreadsheet-GaugeChartColorSectionTemplateRow" owl="1">
<tr>
<td>
<div class="o-tools">
<div class="o-tool o-dropdown o-with-color">
<span
title="Fill Color"
t-attf-style="border-color:{{sectionColor}}"
t-on-click.stop="(ev) => this.toggleMenu('sectionColor-'+sectionType, ev)">
<t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
</span>
<ColorPicker
t-if="state.openedMenu === 'sectionColor-'+sectionType"
onColorPicked="(color) => this.updateSectionColor(sectionType, color)"
currentColor="sectionColor"
dropdownDirection="'right'"
/>
</div>
</div>
<ColorPickerWidget
currentColor="sectionColor"
toggleColorPicker="(ev) => this.toggleMenu('sectionColor-'+sectionType, ev)"
showColorPicker="state.openedMenu === 'sectionColor-'+sectionType"
onColorPicked="(color) => this.updateSectionColor(sectionType, color)"
icon="'o-spreadsheet-Icon.FILL_COLOR'"
/>
</td>
<td>When value is below</td>
<td>
@@ -2147,22 +2147,17 @@
<t t-name="o-spreadsheet-LineBarPieDesignPanel" owl="1">
<div>
<div class="o-section">
<div class="o-section o-chart-background-color">
<div class="o-section-title">Background color</div>
<div class="o-with-color-picker">
Select a color...
<span
t-att-style="props.definition.background ? `border-color: ${props.definition.background}` : 'border-bottom-style: hidden'"
t-on-click.stop="toggleColorPicker">
<t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
</span>
<ColorPicker
t-if="state.fillColorTool"
onColorPicked="(color) => this.updateBackgroundColor(color)"
currentColor="props.definition.background"
t-key="backgroundColor"
/>
</div>
Select a color...
<ColorPickerWidget
currentColor="props.definition.background"
toggleColorPicker="() => this.toggleColorPicker()"
showColorPicker="state.fillColorTool"
onColorPicked="(color) => this.updateBackgroundColor(color)"
title="env._t('Background Color')"
icon="'o-spreadsheet-Icon.FILL_COLOR'"
/>
</div>
<div class="o-section o-chart-title">
<div class="o-section-title">Title</div>
@@ -2266,22 +2261,17 @@
<t t-name="o-spreadsheet-LineChartDesignPanel" owl="1">
<div>
<div class="o-section">
<div class="o-section o-chart-background-color">
<div class="o-section-title">Background color</div>
<div class="o-with-color-picker">
Select a color...
<span
t-att-style="props.definition.background ? `border-color: ${props.definition.background}` : 'border-bottom-style: hidden'"
t-on-click.stop="toggleColorPicker">
<t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
</span>
<ColorPicker
t-if="state.fillColorTool"
onColorPicked="(color) => this.updateBackgroundColor(color)"
currentColor="props.definition.background"
t-key="backgroundColor"
/>
</div>
Select a color...
<ColorPickerWidget
currentColor="props.definition.background"
toggleColorPicker="() => this.toggleColorPicker()"
showColorPicker="state.fillColorTool"
onColorPicked="(color) => this.updateBackgroundColor(color)"
title="env._t('Background Color')"
icon="'o-spreadsheet-Icon.FILL_COLOR'"
/>
</div>
<div class="o-section o-chart-title">
<div class="o-section-title">Title</div>
@@ -2419,23 +2409,17 @@
<t t-name="o-spreadsheet-ScorecardChartDesignPanel" owl="1">
<div>
<div class="o-section">
<div class="o-section o-chart-background-color">
<div class="o-section-title">Background color</div>
<div class="o-with-color-picker">
Select a color...
<span
title="Background Color"
t-att-style="props.definition.background ? `border-color: ${props.definition.background}` : 'border-bottom-style: hidden'"
t-on-click.stop="() => this.openColorPicker('backgroundColor')">
<t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
</span>
<ColorPicker
t-if="state.openedColorPicker === 'backgroundColor'"
onColorPicked="(color) => this.setColor(color, 'backgroundColor')"
currentColor="props.definition.brackground"
t-key="backgroundColor"
/>
</div>
Select a color...
<ColorPickerWidget
currentColor="props.definition.background"
toggleColorPicker="() => this.toggleColorPicker('backgroundColor')"
showColorPicker="state.openedColorPicker === 'backgroundColor'"
onColorPicked="(color) => this.setColor(color, 'backgroundColor')"
title="env._t('Background Color')"
icon="'o-spreadsheet-Icon.FILL_COLOR'"
/>
</div>
<div class="o-section o-chart-title">
@@ -2458,39 +2442,27 @@
/>
</div>
</div>
<div class="o-section">
<div class="o-section o-chart-baseline-color">
<div class="o-section-title">Baseline color</div>
<div class="o-with-color-picker">
Color on value increase
<span
title="Color Up"
t-attf-style="border-color:{{props.definition.baselineColorUp}}"
t-on-click.stop="() => this.openColorPicker('baselineColorUp')">
<t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
</span>
<ColorPicker
t-if="state.openedColorPicker === 'baselineColorUp'"
onColorPicked="(color) => this.setColor(color, 'baselineColorUp')"
currentColor="props.definition.baselineColorUp"
t-key="baselineColorUp"
/>
</div>
Color on value increase
<ColorPickerWidget
currentColor="props.definition.baselineColorUp"
toggleColorPicker="() => this.toggleColorPicker('baselineColorUp')"
showColorPicker="state.openedColorPicker === 'baselineColorUp'"
onColorPicked="(color) => this.setColor(color, 'baselineColorUp')"
title="env._t('Color Up')"
icon="'o-spreadsheet-Icon.FILL_COLOR'"
/>
<br/>
<div class="o-with-color-picker">
Color on value decrease
<span
title="Background Color"
t-attf-style="border-color:{{props.definition.baselineColorDown}}"
t-on-click.stop="() => this.openColorPicker('baselineColorDown')">
<t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
</span>
<ColorPicker
t-if="state.openedColorPicker === 'baselineColorDown'"
onColorPicked="(color) => this.setColor(color, 'baselineColorDown')"
currentColor="props.definition.baselineColorDown"
t-key="baselineColorDown"
/>
</div>
Color on value decrease
<ColorPickerWidget
currentColor="props.definition.baselineColorDown"
toggleColorPicker="() => this.toggleColorPicker('baselineColorDown')"
showColorPicker="state.openedColorPicker === 'baselineColorDown'"
onColorPicked="(color) => this.setColor(color, 'baselineColorDown')"
title="env._t('Color Down')"
icon="'o-spreadsheet-Icon.FILL_COLOR'"
/>
</div>
</t>
@@ -2539,7 +2511,7 @@
<t t-call="o-spreadsheet-CellIsRuleEditorPreview">
<t t-set="currentStyle" t-value="rule.style"/>
</t>
<div class="o-tools">
<div class="o-sidePanel-tools">
<div
class="o-tool"
title="Bold"
@@ -2568,37 +2540,25 @@
t-on-click="(ev) => this.toggleStyle('strikethrough', ev)">
<t t-call="o-spreadsheet-Icon.STRIKE"/>
</div>
<div class="o-tool o-dropdown o-with-color">
<span
title="TextColor"
t-attf-style="border-color:{{rule.style.textColor}}"
t-on-click.stop="(ev) => this.toggleMenu('cellIsRule-textColor', ev)">
<t t-call="o-spreadsheet-Icon.TEXT_COLOR"/>
</span>
<ColorPicker
t-if="state.openedMenu === 'cellIsRule-textColor'"
dropdownDirection="'center'"
onColorPicked="(color) => this.setColor('textColor', color)"
currentColor="rule.style.textColor"
t-key="textColor"
/>
</div>
<ColorPickerWidget
currentColor="rule.style.textColor || '#000000'"
toggleColorPicker="(ev) => this.toggleMenu('cellIsRule-textColor', ev)"
showColorPicker="state.openedMenu === 'cellIsRule-textColor'"
onColorPicked="(color) => this.setColor('textColor', color)"
title="env._t('Text Color')"
icon="'o-spreadsheet-Icon.TEXT_COLOR'"
class="'o-tool'"
/>
<div class="o-divider"/>
<div class="o-tool o-dropdown o-with-color">
<span
title="FillColor"
t-attf-style="border-color:{{rule.style.fillColor}}"
t-on-click.stop="(ev) => this.toggleMenu('cellIsRule-fillColor', ev)">
<t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
</span>
<ColorPicker
t-if="state.openedMenu === 'cellIsRule-fillColor'"
dropdownDirection="'center'"
onColorPicked="(color) => this.setColor('fillColor', color)"
currentColor="rule.style.fillColor"
t-key="fillColor"
/>
</div>
<ColorPickerWidget
currentColor="rule.style.fillColor"
toggleColorPicker="(ev) => this.toggleMenu('cellIsRule-fillColor', ev)"
showColorPicker="state.openedMenu === 'cellIsRule-fillColor'"
onColorPicked="(color) => this.setColor('fillColor', color)"
title="env._t('Fill Color')"
icon="'o-spreadsheet-Icon.FILL_COLOR'"
class="'o-tool'"
/>
</div>
</div>
</t>
@@ -2640,22 +2600,15 @@
t-if="threshold !== undefined and threshold.type !== 'value'"
/>
<input type="text" class="o-input o-threshold-value" t-else="" disabled="1"/>
<div class="o-tools">
<div class="o-tool o-dropdown o-with-color" t-att-disabled="threshold === undefined">
<span
title="Fill Color"
t-attf-style="border-color:{{getThresholdColor(threshold)}}"
t-on-click.stop="(ev) => this.toggleMenu('colorScale-'+thresholdType+'Color', ev)">
<t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
</span>
<ColorPicker
t-if="state.openedMenu === 'colorScale-'+thresholdType+'Color'"
dropdownDirection="'left'"
onColorPicked="(color) => this.setColorScaleColor(thresholdType, color)"
currentColor="getThresholdColor(threshold)"
/>
</div>
</div>
<ColorPickerWidget
currentColor="getThresholdColor(threshold)"
toggleColorPicker="(ev) => this.toggleMenu('colorScale-'+thresholdType+'Color', ev)"
showColorPicker="state.openedMenu === 'colorScale-'+thresholdType+'Color'"
onColorPicked="(color) => this.setColorScaleColor(thresholdType, color)"
title="env._t('Fill Color')"
icon="'o-spreadsheet-Icon.FILL_COLOR'"
disabled="threshold === undefined"
/>
</div>
</t>
@@ -3237,7 +3190,7 @@
<div t-else="" class="o-toolbar-tools">
<div
class="o-tool"
title="Undo"
title="Undo (Ctrl+Z)"
t-att-class="{'o-disabled': !undoTool}"
t-on-click="undo">
<t t-call="o-spreadsheet-Icon.UNDO"/>
@@ -3245,7 +3198,7 @@
<div
class="o-tool"
t-att-class="{'o-disabled': !redoTool}"
title="Redo"
title="Redo (Ctrl+Y)"
t-on-click="redo">
<t t-call="o-spreadsheet-Icon.REDO"/>
</div>
@@ -3316,14 +3269,14 @@
<div class="o-divider"/>
<div
class="o-tool"
title="Bold"
title="Bold (Ctrl+B)"
t-att-class="{active:style.bold}"
t-on-click="(ev) => this.toggleStyle('bold', ev)">
<t t-call="o-spreadsheet-Icon.BOLD"/>
</div>
<div
class="o-tool"
title="Italic"
title="Italic (Ctrl+I)"
t-att-class="{active:style.italic}"
t-on-click="(ev) => this.toggleStyle('italic', ev)">
<t t-call="o-spreadsheet-Icon.ITALIC"/>
@@ -3336,38 +3289,28 @@
<t t-call="o-spreadsheet-Icon.STRIKE"/>
</div>
<div class="o-dropdown">
<div
class="o-tool o-dropdown-button o-with-color"
title="Text Color"
t-on-click="(ev) => this.toggleDropdownTool('textColorTool', ev)">
<span t-attf-style="border-color:{{textColor}}">
<t t-call="o-spreadsheet-Icon.TEXT_COLOR"/>
</span>
</div>
<ColorPicker
t-if="state.activeTool === 'textColorTool'"
onColorPicked="(color) => this.setColor('textColor', color)"
<ColorPickerWidget
currentColor="textColor"
t-key="textColor"
maxHeight="this.props.dropdownMaxHeight"
toggleColorPicker="(ev) => this.toggleDropdownTool('textColorTool', ev)"
showColorPicker="state.activeTool === 'textColorTool'"
onColorPicked="(color) => this.setColor('textColor', color)"
title="env._t('Text Color')"
icon="'o-spreadsheet-Icon.TEXT_COLOR'"
dropdownMaxHeight="this.props.dropdownMaxHeight"
class="'o-tool o-dropdown-button'"
/>
</div>
<div class="o-divider"/>
<div class="o-dropdown ">
<div
class="o-tool o-dropdown-button o-with-color"
title="Fill Color"
t-on-click="(ev) => this.toggleDropdownTool('fillColorTool', ev)">
<span t-attf-style="border-color:{{fillColor}}">
<t t-call="o-spreadsheet-Icon.FILL_COLOR"/>
</span>
</div>
<ColorPicker
t-if="state.activeTool === 'fillColorTool'"
onColorPicked="(color) => this.setColor('fillColor', color)"
<div class="o-dropdown">
<ColorPickerWidget
currentColor="fillColor"
t-key="fillColor"
maxHeight="this.props.dropdownMaxHeight"
toggleColorPicker="(ev) => this.toggleDropdownTool('fillColorTool', ev)"
showColorPicker="state.activeTool === 'fillColorTool'"
onColorPicked="(color) => this.setColor('fillColor', color)"
title="env._t('Fill Color')"
icon="'o-spreadsheet-Icon.FILL_COLOR'"
dropdownMaxHeight="this.props.dropdownMaxHeight"
class="'o-tool o-dropdown-button'"
/>
</div>
<div class="o-dropdown">
@@ -3453,16 +3396,19 @@
t-on-click.stop="">
<div
class="o-dropdown-item o-dropdown-align-item"
title="Left"
t-on-click="() => this.toggleHorizontalAlign('left')">
<t t-call="o-spreadsheet-Icon.ALIGN_LEFT"/>
</div>
<div
class="o-dropdown-item o-dropdown-align-item"
title="Center"
t-on-click="() => this.toggleHorizontalAlign('center')">
<t t-call="o-spreadsheet-Icon.ALIGN_CENTER"/>
</div>
<div
class="o-dropdown-item o-dropdown-align-item"
title="Right"
t-on-click="() => this.toggleHorizontalAlign('right')">
<t t-call="o-spreadsheet-Icon.ALIGN_RIGHT"/>
</div>
@@ -3493,16 +3439,19 @@
t-on-click.stop="">
<div
class="o-dropdown-item o-dropdown-align-item"
title="Top"
t-on-click="() => this.toggleVerticalAlign('top')">
<t t-call="o-spreadsheet-Icon.ALIGN_TOP"/>
</div>
<div
class="o-dropdown-item o-dropdown-align-item"
title="Middle"
t-on-click="() => this.toggleVerticalAlign('middle')">
<t t-call="o-spreadsheet-Icon.ALIGN_MIDDLE"/>
</div>
<div
class="o-dropdown-item o-dropdown-align-item"
title="Bottom"
t-on-click="() => this.toggleVerticalAlign('bottom')">
<t t-call="o-spreadsheet-Icon.ALIGN_BOTTOM"/>
</div>
@@ -3533,16 +3482,19 @@
t-on-click.stop="">
<div
class="o-dropdown-item o-dropdown-align-item"
title="Overflow"
t-on-click="() => this.toggleTextWrapping('overflow')">
<t t-call="o-spreadsheet-Icon.WRAPPING_OVERFLOW"/>
</div>
<div
class="o-dropdown-item o-dropdown-align-item"
title="Wrap"
t-on-click="() => this.toggleTextWrapping('wrap')">
<t t-call="o-spreadsheet-Icon.WRAPPING_WRAP"/>
</div>
<div
class="o-dropdown-item o-dropdown-align-item"
title="Clip"
t-on-click="() => this.toggleTextWrapping('clip')">
<t t-call="o-spreadsheet-Icon.WRAPPING_CLIP"/>
</div>
@@ -3560,7 +3512,7 @@
t-else=""
class="o-tool o-filter-tool"
t-att-class="{'o-disabled': cannotCreateFilter}"
title="Create filter"
title="Create a filter"
t-on-click="createFilter">
<t t-call="o-spreadsheet-Icon.FILTER_ICON_INACTIVE"/>
</div>
@@ -3,14 +3,12 @@
import spreadsheet from "@spreadsheet/o_spreadsheet/o_spreadsheet_extended";
import { _t } from "@web/core/l10n/translation";
const { args, toString } = spreadsheet.helpers;
const { arg, toString } = spreadsheet.helpers;
const { functionRegistry } = spreadsheet.registries;
functionRegistry.add("_t", {
description: _t("Get the translated value of the given string"),
args: args(`
value (string) ${_t("Value to translate.")}
`),
args: [arg("value (string)", _t("Value to translate."))],
compute: function (value) {
return _t(toString(value));
},
@@ -4,7 +4,7 @@ import { _t } from "@web/core/l10n/translation";
import { sprintf } from "@web/core/utils/strings";
import spreadsheet from "@spreadsheet/o_spreadsheet/o_spreadsheet_extended";
const { args, toString } = spreadsheet.helpers;
const { arg, toString } = spreadsheet.helpers;
const { functionRegistry } = spreadsheet.registries;
//--------------------------------------------------------------------------
@@ -40,9 +40,7 @@ function assertDomainLength(domain) {
functionRegistry
.add("ODOO.FILTER.VALUE", {
description: _t("Return the current value of a spreadsheet filter."),
args: args(`
filter_name (string) ${_t("The label of the filter whose value to return.")}
`),
args: [arg("filter_name (string)", _t("The label of the filter whose value to return."))],
compute: function (filterName) {
return this.getters.getFilterDisplayValue(filterName);
},
@@ -50,12 +48,12 @@ functionRegistry
})
.add("ODOO.PIVOT", {
description: _t("Get the value from a pivot."),
args: args(`
pivot_id (string) ${_t("ID of the pivot.")}
measure_name (string) ${_t("Name of the measure.")}
domain_field_name (string,optional,repeating) ${_t("Field name.")}
domain_value (string,optional,repeating) ${_t("Value.")}
`),
args: [
arg("pivot_id (string)", _t("ID of the pivot.")),
arg("measure_name (string)", _t("Name of the measure.")),
arg("domain_field_name (string,optional,repeating)", _t("Field name.")),
arg("domain_value (string,optional,repeating)", _t("Value.")),
],
compute: function (pivotId, measureName, ...domain) {
pivotId = toString(pivotId);
const measure = toString(measureName);
@@ -87,11 +85,11 @@ functionRegistry
})
.add("ODOO.PIVOT.HEADER", {
description: _t("Get the header of a pivot."),
args: args(`
pivot_id (string) ${_t("ID of the pivot.")}
domain_field_name (string,optional,repeating) ${_t("Field name.")}
domain_value (string,optional,repeating) ${_t("Value.")}
`),
args: [
arg("pivot_id (string)", _t("ID of the pivot.")),
arg("domain_field_name (string,optional,repeating)", _t("Field name.")),
arg("domain_value (string,optional,repeating)", _t("Value.")),
],
compute: function (pivotId, ...domain) {
pivotId = toString(pivotId);
const args = domain.map(toString);
@@ -132,11 +130,11 @@ functionRegistry
})
.add("ODOO.PIVOT.POSITION", {
description: _t("Get the absolute ID of an element in the pivot"),
args: args(`
pivot_id (string) ${_t("ID of the pivot.")}
field_name (string) ${_t("Name of the field.")}
position (number) ${_t("Position in the pivot")}
`),
args: [
arg("pivot_id (string)", _t("ID of the pivot.")),
arg("field_name (string)", _t("Name of the field.")),
arg("position (number)", _t("Position in the pivot")),
],
compute: function () {
throw new Error(_t(`[[FUNCTION_NAME]] cannot be called from the spreadsheet.`));
},
@@ -5,7 +5,7 @@ import { sprintf } from "@web/core/utils/strings";
import spreadsheet from "@spreadsheet/o_spreadsheet/o_spreadsheet_extended";
const { functionRegistry } = spreadsheet.registries;
const { args, toBoolean, toString, toNumber, toJsDate } = spreadsheet.helpers;
const { arg, toBoolean, toString, toNumber, toJsDate } = spreadsheet.helpers;
const QuarterRegexp = /^q([1-4])\/(\d{4})$/i;
const MonthRegexp = /^0?([1-9]|1[0-2])\/(\d{4})$/i;
@@ -128,19 +128,20 @@ export function parseAccountingDate(dateRange) {
}
}
const ODOO_FIN_ARGS = `
account_codes (string) ${_t("The prefix of the accounts.")}
date_range (string, date) ${_t(
`The date range. Supported formats are "21/12/2022", "Q1/2022", "12/2022", and "2022".`
)}
offset (number, default=0) ${_t("Year offset applied to date_range.")}
company_id (number, optional) ${_t("The company to target (Advanced).")}
include_unposted (boolean, default=TRUE) ${_t("Set to TRUE to include unposted entries.")}
`;
const ODOO_FIN_ARGS = () => [
arg("account_codes (string)", _t("The prefix of the accounts.")),
arg(
"date_range (string, date)",
_t(`The date range. Supported formats are "21/12/2022", "Q1/2022", "12/2022", and "2022".`)
),
arg("offset (number, default=0)", _t("Year offset applied to date_range.")),
arg("company_id (number, optional)", _t("The company to target (Advanced).")),
arg("include_unposted (boolean, default=TRUE)", _t("Set to TRUE to include unposted entries.")),
];
functionRegistry.add("ODOO.CREDIT", {
description: _t("Get the total credit for the specified account(s) and period."),
args: args(ODOO_FIN_ARGS),
args: ODOO_FIN_ARGS(),
returns: ["NUMBER"],
compute: function (
accountCodes,
@@ -174,7 +175,7 @@ functionRegistry.add("ODOO.CREDIT", {
functionRegistry.add("ODOO.DEBIT", {
description: _t("Get the total debit for the specified account(s) and period."),
args: args(ODOO_FIN_ARGS),
args: ODOO_FIN_ARGS(),
returns: ["NUMBER"],
compute: function (
accountCodes,
@@ -208,7 +209,7 @@ functionRegistry.add("ODOO.DEBIT", {
functionRegistry.add("ODOO.BALANCE", {
description: _t("Get the total balance for the specified account(s) and period."),
args: args(ODOO_FIN_ARGS),
args: ODOO_FIN_ARGS(),
returns: ["NUMBER"],
compute: function (
accountCodes,
@@ -251,10 +252,10 @@ functionRegistry.add("ODOO.BALANCE", {
functionRegistry.add("ODOO.FISCALYEAR.START", {
description: _t("Returns the starting date of the fiscal year encompassing the provided date."),
args: args(`
date (date) ${_t("Reference date.")}
company_id (number, optional) ${_t("The company.")}
`),
args: [
arg("date (date)", _t("Reference date.")),
arg("company_id (number, optional)", _t("The company.")),
],
returns: ["NUMBER"],
computeFormat: () => "m/d/yyyy",
compute: function (date, companyId = null) {
@@ -268,10 +269,10 @@ functionRegistry.add("ODOO.FISCALYEAR.START", {
functionRegistry.add("ODOO.FISCALYEAR.END", {
description: _t("Returns the ending date of the fiscal year encompassing the provided date."),
args: args(`
date (date) ${_t("Reference date.")}
company_id (number, optional) ${_t("The company.")}
`),
args: [
arg("date (date)", _t("Reference date.")),
arg("company_id (number, optional)", _t("The company.")),
],
returns: ["NUMBER"],
computeFormat: () => "m/d/yyyy",
compute: function (date, companyId = null) {
@@ -285,9 +286,7 @@ functionRegistry.add("ODOO.FISCALYEAR.END", {
functionRegistry.add("ODOO.ACCOUNT.GROUP", {
description: _t("Returns the account ids of a given group."),
args: args(`
type (string) ${_t("Account type.")}
`),
args: [arg("type (string)", _t("Account type."))],
returns: ["NUMBER"],
computeFormat: () => "m/d/yyyy",
compute: function (accountType) {
@@ -8,7 +8,6 @@ import { getBasicData } from "@spreadsheet/../tests/utils/data";
const { Model } = spreadsheet;
const { functionRegistry } = spreadsheet.registries;
const { args } = spreadsheet.helpers;
async function createDashboardWithModel(model) {
const serverData = getDashboardServerData();
@@ -62,7 +61,7 @@ QUnit.test("pivot/list formulas should be clickable", async (assert) => {
const mock = {
description: "Mock function to avoid setup all data sources process",
compute: () => 1,
args: args(``),
args: [],
returns: ["NUMBER"],
};