@odoo/o-spreadsheet 18.3.0-alpha.3 → 18.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  <!--
2
2
  This file is generated by o-spreadsheet build tools. Do not edit it.
3
3
  @see https://github.com/odoo/o-spreadsheet
4
- @version 18.3.0-alpha.3
5
- @date 2025-03-07T10:41:46.620Z
6
- @hash f59f5f6
4
+ @version 18.3.1
5
+ @date 2025-05-02T12:34:13.360Z
6
+ @hash 7b9574b
7
7
  -->
8
8
  <odoo>
9
9
  <t t-name="o-spreadsheet-ValidationMessages">
@@ -28,12 +28,10 @@
28
28
  </t>
29
29
 
30
30
  <t t-name="o-spreadsheet-TopBar">
31
- <t t-set="text_color">Text Color</t>
32
- <t t-set="fill_color">Fill Color</t>
33
31
  <div
34
32
  class="o-spreadsheet-topbar o-two-columns d-flex flex-column user-select-none"
35
33
  t-on-click="props.onClick">
36
- <div class="o-topbar-top d-flex justify-content-between flex-wrap">
34
+ <div class="o-topbar-top d-flex justify-content-between">
37
35
  <!-- Menus -->
38
36
  <div class="o-topbar-topleft d-flex">
39
37
  <t t-foreach="menus" t-as="menu" t-key="menu_index">
@@ -122,10 +120,11 @@
122
120
  </div>
123
121
  <Menu
124
122
  t-if="state.menuState.isOpen"
125
- position="state.menuState.position"
123
+ anchorRect="state.menuState.anchorRect"
126
124
  menuItems="state.menuState.menuItems"
127
125
  onClose="() => this.closeMenus()"
128
126
  onMenuClicked="() => this.props.onClick()"
127
+ popoverPositioning="'bottom-left'"
129
128
  />
130
129
  <Popover t-if="state.toolsPopoverState.isOpen" t-props="toolsPopoverProps">
131
130
  <div class="d-flex px-2 py-1 flex-wrap" style="background-color:white;">
@@ -156,7 +155,13 @@
156
155
  onClick.bind="toggleMenu"
157
156
  class="props.class"
158
157
  />
159
- <Menu t-if="isActive" position="state.position" menuItems="state.menuItems" onClose="() => {}"/>
158
+ <Menu
159
+ t-if="isActive"
160
+ anchorRect="state.anchorRect"
161
+ menuItems="state.menuItems"
162
+ onClose="() => {}"
163
+ popoverPositioning="'bottom-left'"
164
+ />
160
165
  </div>
161
166
 
162
167
  <t t-name="o-spreadsheet-TopBarFontSizeEditor">
@@ -200,7 +205,6 @@
200
205
  onColorPicked="(color) => this.setColor(color)"
201
206
  title="props.title"
202
207
  icon="props.icon"
203
- dropdownMaxHeight="dropdownMaxHeight"
204
208
  class="props.class"
205
209
  />
206
210
  </div>
@@ -285,7 +289,7 @@
285
289
  <Menu
286
290
  t-if="menu.isOpen"
287
291
  menuItems="menu.menuItems"
288
- position="menu.position"
292
+ anchorRect="menu.anchorRect"
289
293
  onClose.bind="this.closeMenu"
290
294
  />
291
295
  </t>
@@ -345,7 +349,7 @@
345
349
  </t>
346
350
 
347
351
  <t t-name="o-spreadsheet-Spreadsheet">
348
- <div class="o-spreadsheet" t-ref="spreadsheet" t-att-style="getStyle()">
352
+ <div class="o-spreadsheet h-100 w-100" t-ref="spreadsheet" t-att-style="getStyle()">
349
353
  <t t-if="env.isDashboard()">
350
354
  <SpreadsheetDashboard/>
351
355
  </t>
@@ -656,9 +660,10 @@
656
660
  <Menu
657
661
  t-if="state.isMenuOpen"
658
662
  menuItems="props.menuItems"
659
- position="menuPosition"
663
+ anchorRect="menuAnchorRect"
660
664
  onClose.bind="onMenuClosed"
661
665
  menuId="menuId"
666
+ popoverPositioning="'bottom-left'"
662
667
  />
663
668
  </t>
664
669
 
@@ -730,42 +735,44 @@
730
735
 
731
736
  <t t-name="o-spreadsheet-PivotSpreadsheetSidePanel">
732
737
  <t t-set="isReadonly" t-value="env.model.getters.isReadonly()"/>
733
- <div
734
- class="d-flex flex-column h-100 justify-content-between overflow-hidden"
735
- t-att="isReadonly ? ['inert', 1] : []"
736
- t-att-class="{ 'pe-none': isReadonly, 'opacity-50': isReadonly }">
738
+ <div class="d-flex flex-column h-100 justify-content-between overflow-hidden">
737
739
  <div class="h-100 position-relative overflow-x-hidden overflow-y-auto" t-ref="pivotSidePanel">
738
- <PivotTitleSection pivotId="props.pivotId" flipAxis.bind="flipAxis"/>
739
- <Section title.translate="Range">
740
- <SelectionInput
741
- ranges="ranges"
742
- required="true"
743
- isInvalid="shouldDisplayInvalidRangeError"
744
- hasSingleRange="true"
745
- onSelectionChanged="(ranges) => this.onSelectionChanged(ranges)"
746
- onSelectionConfirmed="() => this.onSelectionConfirmed()"
747
- />
748
- <span
749
- class="text-danger sp_range_error_message"
750
- t-if="shouldDisplayInvalidRangeError"
751
- t-esc="pivot.invalidRangeMessage"
752
- />
753
- </Section>
740
+ <div
741
+ t-att="isReadonly ? ['inert', 1] : []"
742
+ t-att-class="{ 'pe-none opacity-50': isReadonly }">
743
+ <PivotTitleSection pivotId="props.pivotId" flipAxis.bind="flipAxis"/>
744
+ <Section title.translate="Range">
745
+ <SelectionInput
746
+ ranges="ranges"
747
+ required="true"
748
+ isInvalid="shouldDisplayInvalidRangeError"
749
+ hasSingleRange="true"
750
+ onSelectionChanged="(ranges) => this.onSelectionChanged(ranges)"
751
+ onSelectionConfirmed="() => this.onSelectionConfirmed()"
752
+ />
753
+ <span
754
+ class="text-danger sp_range_error_message"
755
+ t-if="shouldDisplayInvalidRangeError"
756
+ t-esc="pivot.invalidRangeMessage"
757
+ />
758
+ </Section>
754
759
 
755
- <PivotLayoutConfigurator
756
- t-if="!pivot.isInvalidRange"
757
- unusedGroupableFields="store.unusedGroupableFields"
758
- measureFields="store.measureFields"
759
- unusedGranularities="store.unusedGranularities"
760
- dateGranularities="store.dateGranularities"
761
- datetimeGranularities="store.datetimeGranularities"
762
- definition="definition"
763
- onDimensionsUpdated.bind="onDimensionsUpdated"
764
- getScrollableContainerEl.bind="getScrollableContainerEl"
765
- pivotId="props.pivotId"
766
- />
760
+ <PivotLayoutConfigurator
761
+ t-if="!pivot.isInvalidRange"
762
+ unusedGroupableFields="store.unusedGroupableFields"
763
+ measureFields="store.measureFields"
764
+ unusedGranularities="store.unusedGranularities"
765
+ dateGranularities="store.dateGranularities"
766
+ datetimeGranularities="store.datetimeGranularities"
767
+ definition="definition"
768
+ onDimensionsUpdated.bind="onDimensionsUpdated"
769
+ getScrollableContainerEl.bind="getScrollableContainerEl"
770
+ pivotId="props.pivotId"
771
+ />
772
+ </div>
767
773
  </div>
768
774
  <PivotDeferUpdate
775
+ t-if="!isReadonly"
769
776
  deferUpdate="store.updatesAreDeferred"
770
777
  toggleDeferUpdate="(value) => store.deferUpdates(value)"
771
778
  isDirty="store.isDirty"
@@ -2065,25 +2072,26 @@
2065
2072
  <div class="" t-att-class="props.class">
2066
2073
  <div class="o_side_panel_collapsible_title o-fw-bold d-flex align-items-center">
2067
2074
  <div
2068
- t-att-id="'btn-collapse-'+currentId"
2069
- t-att-class="{ 'collapsed': props.collapsedAtInit }"
2070
2075
  class="collapsor w-100 d-flex align-items-center ps-1"
2071
- data-bs-toggle="collapse"
2072
- t-att-data-bs-target="'#box-collapse-'+currentId">
2076
+ t-att-class="state.isCollapsed ? 'collapsed' : ''"
2077
+ t-on-click="() => this.toggle()">
2073
2078
  <span class="collapsor-arrow">
2074
2079
  <t t-call="o-spreadsheet-Icon.ANGLE_DOWN"/>
2075
2080
  </span>
2076
2081
  <div class="ps-2" t-esc="props.title"/>
2077
2082
  </div>
2078
2083
  </div>
2079
- <div
2080
- t-att-id="'box-collapse-'+currentId"
2081
- t-att-class="{'show': !props.collapsedAtInit}"
2082
- class="collapsible_section collapse">
2084
+ <Collapse isCollapsed="state.isCollapsed">
2083
2085
  <div class="pt-2">
2084
2086
  <t t-slot="content"/>
2085
2087
  </div>
2086
- </div>
2088
+ </Collapse>
2089
+ </div>
2090
+ </t>
2091
+
2092
+ <t t-name="o-spreadsheet-Collapse">
2093
+ <div t-ref="content" class="os-collapse">
2094
+ <t t-slot="default"/>
2087
2095
  </div>
2088
2096
  </t>
2089
2097
 
@@ -2096,7 +2104,7 @@
2096
2104
  <Menu
2097
2105
  t-if="menuState.isOpen"
2098
2106
  menuId="menuId"
2099
- position="menuState.position"
2107
+ anchorRect="menuState.anchorRect"
2100
2108
  menuItems="menuState.menuItems"
2101
2109
  onClose="() => this.menuState.isOpen=false"
2102
2110
  width="160"
@@ -2165,7 +2173,7 @@
2165
2173
  </Section>
2166
2174
  </t>
2167
2175
  </GeneralDesignEditor>
2168
- <SidePanelCollapsible collapsedAtInit="true" title.translate="Waterfall design">
2176
+ <SidePanelCollapsible isInitiallyCollapsed="true" title.translate="Waterfall design">
2169
2177
  <t t-set-slot="content">
2170
2178
  <Section class="'pt-0'" title.translate="Options">
2171
2179
  <t t-set="firstValueAsSubtotal">Use first value as subtotal</t>
@@ -2217,7 +2225,7 @@
2217
2225
  </Section>
2218
2226
  </t>
2219
2227
  </SidePanelCollapsible>
2220
- <SidePanelCollapsible collapsedAtInit="true" title.translate="Axes">
2228
+ <SidePanelCollapsible isInitiallyCollapsed="true" title.translate="Axes">
2221
2229
  <t t-set-slot="content">
2222
2230
  <AxisDesignEditor
2223
2231
  axesList="axesList"
@@ -2229,6 +2237,199 @@
2229
2237
  </SidePanelCollapsible>
2230
2238
  </t>
2231
2239
 
2240
+ <t t-name="o-spreadsheet-TreeMapChartDesignPanel">
2241
+ <GeneralDesignEditor
2242
+ figureId="props.figureId"
2243
+ definition="props.definition"
2244
+ updateChart="props.updateChart"
2245
+ />
2246
+
2247
+ <SidePanelCollapsible isInitiallyCollapsed="false" title.translate="Tree map colors">
2248
+ <t t-set-slot="content">
2249
+ <Section class="'pt-0'">
2250
+ <BadgeSelection
2251
+ choices="coloringOptionChoices"
2252
+ onChange.bind="changeColoringOption"
2253
+ selectedValue="coloringOptions.type"
2254
+ />
2255
+
2256
+ <t t-if="coloringOptions.type === 'categoryColor'">
2257
+ <TreeMapCategoryColors
2258
+ figureId="props.figureId"
2259
+ definition="props.definition"
2260
+ onColorChanged.bind="onCategoryColorChange"
2261
+ />
2262
+ </t>
2263
+ <t t-else="">
2264
+ <TreeMapColorScale
2265
+ figureId="props.figureId"
2266
+ definition="props.definition"
2267
+ onColorChanged.bind="onColorScaleChange"
2268
+ />
2269
+ </t>
2270
+ </Section>
2271
+ </t>
2272
+ </SidePanelCollapsible>
2273
+
2274
+ <SidePanelCollapsible isInitiallyCollapsed="false" title.translate="Headers and labels">
2275
+ <t t-set-slot="content">
2276
+ <Section title.translate="Headers" class="'pt-0 pb-0'">
2277
+ <Checkbox
2278
+ name="'showHeaders'"
2279
+ label.translate="Show headers"
2280
+ value="showHeaders"
2281
+ onChange="(showHeaders) => props.updateChart(this.props.figureId, { showHeaders })"
2282
+ />
2283
+ </Section>
2284
+ <Section class="'pt-0'" t-if="showHeaders">
2285
+ <TextStyler
2286
+ class="'pt-0 o-header-style'"
2287
+ updateStyle="(headerDesign) => props.updateChart(this.props.figureId, { headerDesign })"
2288
+ style="props.definition.headerDesign || {}"
2289
+ defaultStyle="defaults.headerDesign"
2290
+ hasBackgroundColor="true"
2291
+ />
2292
+ </Section>
2293
+
2294
+ <Section title.translate="Labels" class="'pt-0 pb-0'">
2295
+ <div class="d-flex flex-row gap-4">
2296
+ <Checkbox
2297
+ name="'showLabels'"
2298
+ label.translate="Show labels"
2299
+ value="showLabels"
2300
+ onChange="(showLabels) => props.updateChart(this.props.figureId, { showLabels })"
2301
+ />
2302
+ <Checkbox
2303
+ name="'showValues'"
2304
+ label.translate="Show values"
2305
+ value="showValues"
2306
+ onChange="(showValues) => props.updateChart(this.props.figureId, { showValues })"
2307
+ />
2308
+ </div>
2309
+ </Section>
2310
+ <Section class="'pt-0'" t-if="showValues || showLabels">
2311
+ <TextStyler
2312
+ class="'pt-0 o-values-style'"
2313
+ updateStyle="(valuesDesign) => props.updateChart(this.props.figureId, { valuesDesign })"
2314
+ style="props.definition.valuesDesign || {}"
2315
+ defaultStyle="defaults.valuesDesign"
2316
+ hasVerticalAlign="true"
2317
+ />
2318
+ </Section>
2319
+ </t>
2320
+ </SidePanelCollapsible>
2321
+ </t>
2322
+
2323
+ <t t-name="o-spreadsheet-TreeMapColorScale">
2324
+ <div class="o-min-color d-flex align-items-center mb-2 mt-4">
2325
+ <RoundColorPicker
2326
+ currentColor="coloringOptions.minColor"
2327
+ onColorPicked="(color) => this.setColorScaleColor('minColor', color)"
2328
+ disableNoColor="true"
2329
+ />
2330
+ <span class="ps-2">Color of minimum values</span>
2331
+ </div>
2332
+ <div class="o-mid-color d-flex align-items-center mb-2">
2333
+ <RoundColorPicker
2334
+ currentColor="coloringOptions.midColor"
2335
+ onColorPicked="(color) => this.setColorScaleColor('midColor', color)"
2336
+ />
2337
+ <span class="ps-2">Color of middle values</span>
2338
+ </div>
2339
+ <div class="o-max-color d-flex align-items-center">
2340
+ <RoundColorPicker
2341
+ currentColor="coloringOptions.maxColor"
2342
+ onColorPicked="(color) => this.setColorScaleColor('maxColor', color)"
2343
+ disableNoColor="true"
2344
+ />
2345
+ <span class="ps-2">Color of maximum values</span>
2346
+ </div>
2347
+ </t>
2348
+
2349
+ <t t-name="o-spreadsheet-TreeMapCategoryColors">
2350
+ <div class="mt-3">
2351
+ <div class="o-fw-bold mb-2">Category</div>
2352
+ <t t-foreach="getTreeGroupAndColors()" t-as="group" t-key="group_index">
2353
+ <div class="d-flex align-items-center mb-2" t-att-data-id="group.label">
2354
+ <RoundColorPicker
2355
+ currentColor="group.color"
2356
+ onColorPicked="(color) => this.onGroupColorChanged(group_index, color)"
2357
+ />
2358
+ <span class="ps-2">
2359
+ <span t-esc="'(#' + (group_index +1 ) + ')'" class="o-text-bolder pe-1"/>
2360
+ <span class="text-muted" t-esc="group.label"/>
2361
+ </span>
2362
+ </div>
2363
+ </t>
2364
+
2365
+ <Checkbox
2366
+ name="'useValueBasedGradient'"
2367
+ label.translate="Use value-based gradient"
2368
+ value="coloringOptions.useValueBasedGradient"
2369
+ onChange.bind="useValueBasedGradient"
2370
+ className="'mt-4'"
2371
+ />
2372
+ </div>
2373
+ </t>
2374
+
2375
+ <t t-name="o-spreadsheet-SunburstChartDesignPanel">
2376
+ <GeneralDesignEditor
2377
+ figureId="props.figureId"
2378
+ definition="props.definition"
2379
+ updateChart="props.updateChart">
2380
+ <t t-set-slot="general-extension">
2381
+ <ChartLegend
2382
+ figureId="props.figureId"
2383
+ definition="props.definition"
2384
+ updateChart="props.updateChart"
2385
+ />
2386
+ </t>
2387
+ </GeneralDesignEditor>
2388
+
2389
+ <SidePanelCollapsible isInitiallyCollapsed="false" title.translate="Sunburst options">
2390
+ <t t-set-slot="content">
2391
+ <Section class="'pt-0 o-sunburst-colors'" title.translate="Colors">
2392
+ <t t-foreach="groupColors" t-as="item" t-key="item.label">
2393
+ <div class="d-flex align-items-center mb-2" t-att-data-id="item.label">
2394
+ <RoundColorPicker
2395
+ currentColor="item.color"
2396
+ onColorPicked="(color) => this.onGroupColorChanged(item_index, color)"
2397
+ />
2398
+ <span class="ps-2">
2399
+ <span t-esc="'(#' + (item_index +1 ) + ')'" class="o-text-bolder pe-1"/>
2400
+ <span class="text-muted" t-esc="item.label"/>
2401
+ </span>
2402
+ </div>
2403
+ </t>
2404
+ </Section>
2405
+ <Section title.translate="Labels" class="'pt-0 pb-0'">
2406
+ <div class="d-flex flex-row gap-4">
2407
+ <Checkbox
2408
+ name="'showLabels'"
2409
+ label.translate="Show labels"
2410
+ value="showLabels"
2411
+ onChange="(showLabels) => props.updateChart(this.props.figureId, { showLabels })"
2412
+ />
2413
+ <Checkbox
2414
+ name="'showValues'"
2415
+ label.translate="Show values"
2416
+ value="showValues"
2417
+ onChange="(showValues) => props.updateChart(this.props.figureId, { showValues })"
2418
+ />
2419
+ </div>
2420
+ </Section>
2421
+ <Section class="'pt-0'" t-if="showValues || showLabels">
2422
+ <TextStyler
2423
+ class="'o-values-style'"
2424
+ updateStyle="(valuesDesign) => props.updateChart(this.props.figureId, { valuesDesign })"
2425
+ style="props.definition.valuesDesign || {}"
2426
+ defaultStyle="defaults.valuesDesign"
2427
+ />
2428
+ </Section>
2429
+ </t>
2430
+ </SidePanelCollapsible>
2431
+ </t>
2432
+
2232
2433
  <t t-name="o-spreadsheet-ScorecardChartDesignPanel">
2233
2434
  <t t-set="color_up">Color Up</t>
2234
2435
  <t t-set="color_down">Color Down</t>
@@ -2248,7 +2449,7 @@
2248
2449
  </Section>
2249
2450
  </t>
2250
2451
  </GeneralDesignEditor>
2251
- <SidePanelCollapsible collapsedAtInit="false" title.translate="Baseline">
2452
+ <SidePanelCollapsible isInitiallyCollapsed="false" title.translate="Baseline">
2252
2453
  <t t-set-slot="content">
2253
2454
  <Section class="'pt-0'" title.translate="Baseline description">
2254
2455
  <input
@@ -2466,6 +2667,29 @@
2466
2667
  </div>
2467
2668
  </t>
2468
2669
 
2670
+ <t t-name="o-spreadsheet-HierarchicalChartConfigPanel">
2671
+ <div>
2672
+ <ChartDataSeries
2673
+ ranges="this.getDataSeriesRanges()"
2674
+ onSelectionChanged.bind="onDataSeriesRangesChanged"
2675
+ onSelectionConfirmed.bind="onDataSeriesConfirmed"
2676
+ onSelectionReordered.bind="onDataSeriesReordered"
2677
+ onSelectionRemoved.bind="onDataSeriesRemoved"
2678
+ title.translate="Hierarchy"
2679
+ />
2680
+ <ChartLabelRange
2681
+ range="this.getLabelRange()"
2682
+ isInvalid="isLabelInvalid"
2683
+ onSelectionChanged.bind="onLabelRangeChanged"
2684
+ onSelectionConfirmed.bind="onLabelRangeConfirmed"
2685
+ options="this.getLabelRangeOptions()"
2686
+ title.translate="Values"
2687
+ />
2688
+
2689
+ <ChartErrorSection t-if="errorMessages.length" messages="errorMessages"/>
2690
+ </div>
2691
+ </t>
2692
+
2469
2693
  <t t-name="o-spreadsheet-GeoChartRegionSelectSection">
2470
2694
  <Section class="'o-geo-region'" title.translate="Region">
2471
2695
  <select class="o-input" t-on-change="this.updateSelectedRegion">
@@ -2501,7 +2725,7 @@
2501
2725
  </t>
2502
2726
  </GeneralDesignEditor>
2503
2727
 
2504
- <SidePanelCollapsible collapsedAtInit="false" title.translate="Geo chart options">
2728
+ <SidePanelCollapsible isInitiallyCollapsed="false" title.translate="Geo chart options">
2505
2729
  <t t-set-slot="content">
2506
2730
  <Section class="'pt-0 o-color-scale'" title.translate="Color Scale">
2507
2731
  <select class="o-input" t-on-change="this.updateColorScaleType">
@@ -2586,7 +2810,7 @@
2586
2810
  definition="props.definition"
2587
2811
  updateChart="props.updateChart"
2588
2812
  />
2589
- <SidePanelCollapsible collapsedAtInit="false" title.translate="Gauge Design">
2813
+ <SidePanelCollapsible isInitiallyCollapsed="false" title.translate="Gauge Design">
2590
2814
  <t t-set-slot="content">
2591
2815
  <Section class="'pt-0'" title.translate="Range">
2592
2816
  <div class="o-subsection-left">
@@ -2738,7 +2962,7 @@
2738
2962
  </t>
2739
2963
  </GeneralDesignEditor>
2740
2964
 
2741
- <SidePanelCollapsible collapsedAtInit="false" title.translate="Funnel options">
2965
+ <SidePanelCollapsible isInitiallyCollapsed="false" title.translate="Funnel options">
2742
2966
  <t t-set-slot="content">
2743
2967
  <Section class="'o-funnel-colors pt-0'" title.translate="Funnel colors">
2744
2968
  <t t-foreach="getFunnelColorItems()" t-as="item" t-key="item_index">
@@ -2789,7 +3013,7 @@
2789
3013
  </Section>
2790
3014
  </t>
2791
3015
  </SeriesWithAxisDesignEditor>
2792
- <SidePanelCollapsible collapsedAtInit="true" title.translate="Axes">
3016
+ <SidePanelCollapsible isInitiallyCollapsed="true" title.translate="Axes">
2793
3017
  <t t-set-slot="content">
2794
3018
  <AxisDesignEditor
2795
3019
  axesList="axesList"
@@ -2823,7 +3047,7 @@
2823
3047
  </t>
2824
3048
  </GeneralDesignEditor>
2825
3049
  <SeriesWithAxisDesignEditor t-props="props"/>
2826
- <SidePanelCollapsible collapsedAtInit="true" title.translate="Axes">
3050
+ <SidePanelCollapsible isInitiallyCollapsed="true" title.translate="Axes">
2827
3051
  <t t-set-slot="content">
2828
3052
  <AxisDesignEditor
2829
3053
  axesList="axesList"
@@ -3152,104 +3376,108 @@
3152
3376
  <path stroke="#eb6d00" fill="#ffe1c8" d="M21.5,35.5 h5 l-2.5,7 l-2.5,-7 h1"/>
3153
3377
  </svg>
3154
3378
  </t>
3155
-
3156
- <t t-name="o-spreadsheet.ChartTitle">
3157
- <t t-set="placeholder">Add a title</t>
3158
- <t t-set="title">
3159
- <t t-if="props.name" t-esc="props.name"/>
3160
- <t t-else="">Title</t>
3161
- </t>
3162
- <Section class="'o-chart-title'" title="title.toString()">
3163
- <input
3164
- type="text"
3165
- class="o-input"
3166
- t-att-value="props.title"
3167
- t-on-change="updateTitle"
3168
- t-att-placeholder="placeholder"
3379
+ <t t-name="o-spreadsheet-ChartPreview.SUNBURST_CHART">
3380
+ <svg viewBox="0 0 48 48" class="o-chart-preview" xmlns="http://www.w3.org/2000/svg">
3381
+ <path
3382
+ fill="#ffe1c8"
3383
+ stroke="#eb6d00"
3384
+ d="M24,12 v8A4,4,0,1,0,27.46,26 L41.32, 34 A20,20,0,0,1,8.679,36.856 L14.807,31.713 A12,12,0,0,1,24,12 M34.4,30 A12,12,0,0,1,14.807,31.713"
3169
3385
  />
3170
- <div class="o-chart-title-designer position-relative d-flex align-items-center">
3171
- <span
3172
- class="o-menu-item-button o-hoverable-button"
3173
- title="Bold"
3174
- t-att-class="{active: props.style.bold}"
3175
- t-on-click="(ev) => this.props.toggleBold()">
3176
- <span>
3177
- <t t-call="o-spreadsheet-Icon.BOLD"/>
3178
- </span>
3179
- </span>
3180
- <span
3181
- class="o-menu-item-button o-hoverable-button"
3182
- title="Italic"
3183
- t-att-class="{active: props.style.italic}"
3184
- t-on-click="(ev) => this.props.toggleItalic()">
3185
- <span>
3186
- <t t-call="o-spreadsheet-Icon.ITALIC"/>
3187
- </span>
3188
- </span>
3189
- <div class="o-divider"/>
3190
- <span
3191
- class="o-menu-item-button o-hoverable-button"
3192
- title="Horizontal alignment"
3193
- t-on-click="(ev) => this.toggleDropdownTool('horizontalChartAlignTool', ev)">
3194
- <span>
3195
- <t t-if="props.style.align === 'center'" t-call="o-spreadsheet-Icon.ALIGN_CENTER"/>
3196
- <t t-elif="props.style.align === 'right'" t-call="o-spreadsheet-Icon.ALIGN_RIGHT"/>
3197
- <t t-else="" t-call="o-spreadsheet-Icon.ALIGN_LEFT"/>
3198
- </span>
3199
- <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
3200
- </span>
3386
+ <path
3387
+ fill="#c4e4ff"
3388
+ stroke="#0074d9"
3389
+ d="M24,20 v-16 A20 20, 0, 0, 1, 41.32, 34 L27.46,26 A4,4,0,0,0,24,20 M24,12 A12,12,0,0,1,34.4,30 M33.193,16.287 L39.321,11.144 M36,24 L44,24"
3390
+ />
3391
+ </svg>
3392
+ </t>
3393
+ <t t-name="o-spreadsheet-ChartPreview.TREE_MAP_CHART">
3394
+ <svg viewBox="0 0 48 48" class="o-chart-preview" xmlns="http://www.w3.org/2000/svg">
3395
+ <path fill="#444" d="M2,4 h44 v5 h-44"/>
3396
+ <path fill="#444" d="M2,10 h28 v5 h-28"/>
3397
+ <path fill="#444" d="M31,10 h15 v5 h-15"/>
3398
+ <path fill="#0074d9" d="M2,16 h28 v14 h-28"/>
3399
+ <path fill="#c4e4ff" d="M3,17 h26 v12 h-26"/>
3400
+ <path fill="#0074d9" d="M2,31 h15 v12 h-15"/>
3401
+ <path fill="#c4e4ff" d="M3,32 h13 v10 h-13"/>
3402
+ <path fill="#0074d9" d="M18,31 h12 v12 h-12"/>
3403
+ <path fill="#c4e4ff" d="M19,32 h10 v10 h-10"/>
3404
+ <path fill="#eb6d00" d="M31,16 h15 v27 h-15"/>
3405
+ <path fill="#ffe1c8" d="M32,17 h13 v25 h-13"/>
3406
+ </svg>
3407
+ </t>
3408
+
3409
+ <t t-name="o-spreadsheet.TextStyler">
3410
+ <div
3411
+ class="o-chart-title-designer position-relative d-flex align-items-center"
3412
+ t-att-class="props.class">
3413
+ <ActionButton action="boldButtonAction" class="'o-hoverable-button'"/>
3414
+ <ActionButton action="italicButtonAction" class="'o-hoverable-button'"/>
3415
+ <div class="o-divider" t-if="props.hasHorizontalAlign || props.hasVerticalAlign"/>
3416
+ <div class="o-dropdown position-relative" t-if="props.hasHorizontalAlign">
3417
+ <ActionButton
3418
+ action="horizontalAlignButtonAction"
3419
+ hasTriangleDownIcon="true"
3420
+ t-on-click="(ev) => this.toggleDropdownTool('horizontalAlignTool', ev)"
3421
+ class="'o-hoverable-button'"
3422
+ />
3201
3423
  <div
3202
3424
  class="o-dropdown-content position-absolute top-100 start-0 bg-white"
3203
- t-if="state.activeTool === 'horizontalChartAlignTool'"
3425
+ t-if="state.activeTool === 'horizontalAlignTool'"
3426
+ t-att-style="dropdownStyle"
3204
3427
  t-on-click.stop="">
3205
3428
  <div class="o-dropdown-line d-flex">
3206
- <span
3207
- class="o-menu-item-button o-hoverable-button"
3208
- t-att-class="{active: props.style.align === 'left'}"
3209
- title="Left"
3210
- t-on-click="(ev) => this.updateAlignment('left')">
3211
- <span>
3212
- <t t-call="o-spreadsheet-Icon.ALIGN_LEFT"/>
3213
- </span>
3214
- </span>
3215
- <span
3216
- class="o-menu-item-button o-hoverable-button"
3217
- t-att-class="{active: props.style.align === 'center'}"
3218
- title="Center"
3219
- t-on-click="(ev) => this.updateAlignment('center')">
3220
- <span>
3221
- <t t-call="o-spreadsheet-Icon.ALIGN_CENTER"/>
3222
- </span>
3223
- </span>
3224
- <span
3225
- class="o-menu-item-button o-hoverable-button"
3226
- t-att-class="{active: props.style.align === 'right'}"
3227
- title="Right"
3228
- t-on-click="(ev) => this.updateAlignment('right')">
3229
- <span>
3230
- <t t-call="o-spreadsheet-Icon.ALIGN_RIGHT"/>
3231
- </span>
3232
- </span>
3429
+ <t t-foreach="horizontalAlignActions" t-as="action" t-key="action_index">
3430
+ <ActionButton action="action" class="'o-hoverable-button'"/>
3431
+ </t>
3233
3432
  </div>
3234
3433
  </div>
3235
- <div class="o-divider"/>
3236
- <FontSizeEditor
3237
- currentFontSize="props.style.fontSize"
3238
- onFontSizeChanged.bind="this.updateFontSize"
3434
+ </div>
3435
+ <div class="o-dropdown position-relative" t-if="props.hasVerticalAlign">
3436
+ <ActionButton
3437
+ action="verticalAlignButtonAction"
3438
+ hasTriangleDownIcon="true"
3439
+ t-on-click="(ev) => this.toggleDropdownTool('verticalAlignTool', ev)"
3239
3440
  class="'o-hoverable-button'"
3240
3441
  />
3241
- <div class="o-divider"/>
3242
- <ColorPickerWidget
3243
- currentColor="props.style.color"
3244
- toggleColorPicker="(ev) => this.toggleDropdownTool('fillChartColorTool', ev)"
3245
- showColorPicker="state.activeTool === 'fillChartColorTool'"
3246
- onColorPicked.bind="onColorPicked"
3247
- title="fill_color"
3248
- icon="'o-spreadsheet-Icon.TEXT_COLOR'"
3249
- class="'o-hoverable-button o-menu-item-button'"
3250
- />
3442
+ <div
3443
+ class="o-dropdown-content position-absolute top-100 start-0 bg-white"
3444
+ t-if="state.activeTool === 'verticalAlignTool'"
3445
+ t-att-style="dropdownStyle"
3446
+ t-on-click.stop="">
3447
+ <div class="o-dropdown-line d-flex">
3448
+ <t t-foreach="verticalAlignActions" t-as="action" t-key="action_index">
3449
+ <ActionButton action="action" class="'o-hoverable-button'"/>
3450
+ </t>
3451
+ </div>
3452
+ </div>
3251
3453
  </div>
3252
- </Section>
3454
+ <div class="o-divider"/>
3455
+ <FontSizeEditor
3456
+ currentFontSize="currentFontSize"
3457
+ onFontSizeChanged.bind="this.updateFontSize"
3458
+ class="'o-hoverable-button'"
3459
+ />
3460
+ <div class="o-divider"/>
3461
+ <ColorPickerWidget
3462
+ currentColor="props.style.color ?? props.defaultStyle?.color"
3463
+ toggleColorPicker="(ev) => this.toggleDropdownTool('fillChartColorTool', ev)"
3464
+ showColorPicker="state.activeTool === 'fillChartColorTool'"
3465
+ onColorPicked.bind="onTextColorChange"
3466
+ title.translate="Text color"
3467
+ icon="'o-spreadsheet-Icon.TEXT_COLOR'"
3468
+ class="'o-hoverable-button o-menu-item-button'"
3469
+ />
3470
+ <ColorPickerWidget
3471
+ t-if="props.hasBackgroundColor"
3472
+ currentColor="props.style.fillColor || props.defaultStyle?.fillColor"
3473
+ toggleColorPicker="(ev) => this.toggleDropdownTool('fillcolorTool', ev)"
3474
+ showColorPicker="state.activeTool === 'fillcolorTool'"
3475
+ onColorPicked.bind="onFillColorChange"
3476
+ title.translate="Fill color"
3477
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
3478
+ class="'o-hoverable-button o-menu-item-button'"
3479
+ />
3480
+ </div>
3253
3481
  </t>
3254
3482
 
3255
3483
  <t t-name="o-spreadsheet-SeriesWithAxisDesignEditor">
@@ -3344,13 +3572,13 @@
3344
3572
  </t>
3345
3573
 
3346
3574
  <t t-name="o-spreadsheet-SeriesDesignEditor">
3347
- <SidePanelCollapsible collapsedAtInit="true" title.translate="Data Series">
3575
+ <SidePanelCollapsible isInitiallyCollapsed="true" title.translate="Data Series">
3348
3576
  <t t-set-slot="content">
3349
3577
  <Section class="'pt-0 pb-0'">
3350
3578
  <select
3351
3579
  class="o-input data-series-selector"
3352
3580
  t-model="state.label"
3353
- t-on-change="(ev) => this.updateSerieEditor(ev)">
3581
+ t-on-change="(ev) => this.updateEditedSeries(ev)">
3354
3582
  <t t-foreach="getDataSeries()" t-as="serie" t-key="serie_index">
3355
3583
  <option
3356
3584
  t-att-value="serie"
@@ -3363,7 +3591,7 @@
3363
3591
  <div class="d-flex align-items-center">
3364
3592
  <span class="o-section-title mb-0 pe-2">Series color</span>
3365
3593
  <RoundColorPicker
3366
- currentColor="getDataSerieColor()"
3594
+ currentColor="getDataSeriesColor()"
3367
3595
  onColorPicked.bind="updateDataSeriesColor"
3368
3596
  />
3369
3597
  </div>
@@ -3372,7 +3600,7 @@
3372
3600
  <input
3373
3601
  class="o-input o-serie-label-editor"
3374
3602
  type="text"
3375
- t-att-value="getDataSerieLabel()"
3603
+ t-att-value="getDataSeriesLabel()"
3376
3604
  t-on-change="(ev) => this.updateDataSeriesLabel(ev)"
3377
3605
  />
3378
3606
  </Section>
@@ -3441,7 +3669,7 @@
3441
3669
 
3442
3670
  <t t-name="o-spreadsheet-GeneralDesignEditor">
3443
3671
  <t t-set="chart_title">Chart title</t>
3444
- <SidePanelCollapsible collapsedAtInit="false" title.translate="General">
3672
+ <SidePanelCollapsible isInitiallyCollapsed="false" title.translate="General">
3445
3673
  <t t-set-slot="content">
3446
3674
  <Section class="'o-chart-background-color pt-0 pb-0'" title.translate="Background color">
3447
3675
  <RoundColorPicker
@@ -3453,12 +3681,9 @@
3453
3681
  title="title.text"
3454
3682
  updateTitle.bind="updateTitle"
3455
3683
  name="chart_title"
3456
- toggleItalic.bind="toggleItalicChartTitle"
3457
- toggleBold.bind="toggleBoldChartTitle"
3458
- updateAlignment.bind="updateChartTitleAlignment"
3459
- updateColor.bind="updateChartTitleColor"
3460
- style="titleStyle"
3461
- onFontSizeChanged.bind="updateChartTitleFontSize"
3684
+ updateStyle.bind="updateChartTitleStyle"
3685
+ style="title"
3686
+ defaultStyle="{align: 'left', fontSize: this.props.defaultChartTitleFontSize}"
3462
3687
  />
3463
3688
  <t t-slot="general-extension"/>
3464
3689
  </t>
@@ -3486,6 +3711,29 @@
3486
3711
  </Section>
3487
3712
  </t>
3488
3713
 
3714
+ <t t-name="o-spreadsheet.ChartTitle">
3715
+ <t t-set="placeholder">Add a title</t>
3716
+ <t t-set="title">
3717
+ <t t-if="props.name" t-esc="props.name"/>
3718
+ <t t-else="">Title</t>
3719
+ </t>
3720
+ <Section class="'o-chart-title'" title="title.toString()">
3721
+ <input
3722
+ type="text"
3723
+ class="o-input"
3724
+ t-att-value="props.title"
3725
+ t-on-change="updateTitle"
3726
+ t-att-placeholder="placeholder"
3727
+ />
3728
+ <TextStyler
3729
+ style="props.style"
3730
+ updateStyle="props.updateStyle"
3731
+ defaultStyle="props.defaultStyle"
3732
+ hasHorizontalAlign="true"
3733
+ />
3734
+ </Section>
3735
+ </t>
3736
+
3489
3737
  <t t-name="o-spreadsheet-AxisDesignEditor">
3490
3738
  <t t-set="editor_label">Axis title</t>
3491
3739
  <Section class="'py-0'">
@@ -3498,13 +3746,10 @@
3498
3746
  <ChartTitle
3499
3747
  title="this.getAxisTitle()"
3500
3748
  updateTitle.bind="updateAxisTitle"
3749
+ updateStyle.bind="updateAxisTitleStyle"
3501
3750
  name="editor_label"
3502
- toggleItalic.bind="toggleItalicAxisTitle"
3503
- toggleBold.bind="toggleBoldAxisTitle"
3504
- updateAlignment.bind="updateAxisTitleAlignment"
3505
- updateColor.bind="updateAxisTitleColor"
3506
3751
  style="axisTitleStyle"
3507
- onFontSizeChanged.bind="updateAxisTitleFontSize"
3752
+ defaultStyle="{align: 'center', color: '', fontSize: defaultFontSize}"
3508
3753
  />
3509
3754
  </t>
3510
3755
 
@@ -3648,6 +3893,7 @@
3648
3893
  t-att-style="menuStyle"
3649
3894
  t-on-scroll="onScroll"
3650
3895
  t-on-wheel.stop=""
3896
+ t-on-pointerdown.prevent=""
3651
3897
  t-on-click.stop=""
3652
3898
  t-on-mouseover="onMouseOverMainMenu"
3653
3899
  t-on-contextmenu.prevent="">
@@ -3700,7 +3946,7 @@
3700
3946
  <Menu
3701
3947
  t-if="subMenu.isOpen"
3702
3948
  t-key="subMenu.parentMenu.id"
3703
- position="subMenuPosition"
3949
+ anchorRect="subMenuAnchorRect"
3704
3950
  menuItems="subMenu.menuItems"
3705
3951
  depth="props.depth + 1"
3706
3952
  maxHeight="props.maxHeight"
@@ -3717,8 +3963,7 @@
3717
3963
  <div
3718
3964
  class="o-link-editor"
3719
3965
  t-on-click.stop="() => this.menu.isOpen=false"
3720
- t-on-keydown="onKeyDown"
3721
- t-ref="linkEditor">
3966
+ t-on-keydown="onKeyDown">
3722
3967
  <div class="o-section">
3723
3968
  <div class="o-section-title">Text</div>
3724
3969
  <div class="d-flex">
@@ -3755,14 +4000,18 @@
3755
4000
  <button t-if="link.url" t-on-click="removeLink" class="o-remove-url o-button-icon">
3756
4001
 
3757
4002
  </button>
3758
- <button t-if="!link.url" t-on-click.stop="openMenu" class="o-special-link o-button-icon">
4003
+ <button
4004
+ t-if="!link.url"
4005
+ t-on-click.stop="openMenu"
4006
+ class="o-special-link o-button-icon"
4007
+ t-ref="linkEditorMenuButton">
3759
4008
  <t t-call="o-spreadsheet-Icon.LIST"/>
3760
4009
  </button>
3761
4010
  </div>
3762
4011
  </div>
3763
4012
  <Menu
3764
4013
  t-if="menu.isOpen"
3765
- position="menuPosition"
4014
+ anchorRect="menuButtonRect"
3766
4015
  menuItems="menuItems"
3767
4016
  onMenuClicked="(ev) => this.onSpecialLink(ev)"
3768
4017
  onClose="() => this.menu.isOpen=false"
@@ -4838,7 +5087,7 @@
4838
5087
  <div class="o-highlight" t-ref="highlight">
4839
5088
  <t t-foreach="['n', 's', 'w', 'e']" t-as="orientation" t-key="orientation">
4840
5089
  <Border
4841
- onMoveHighlight="(x, y) => this.onMoveHighlight(x,y)"
5090
+ onMoveHighlight.bind="this.onMoveHighlight"
4842
5091
  isMoving='highlightState.shiftingMode === "isMoving"'
4843
5092
  orientation="orientation"
4844
5093
  zone="props.zone"
@@ -4846,7 +5095,7 @@
4846
5095
  </t>
4847
5096
  <t t-foreach="['nw', 'ne', 'sw', 'se']" t-as="orientation" t-key="orientation">
4848
5097
  <Corner
4849
- onResizeHighlight="(isLeft, isTop) => this.onResizeHighlight(isLeft, isTop)"
5098
+ onResizeHighlight.bind="onResizeHighlight"
4850
5099
  isResizing='highlightState.shiftingMode === "isResizing"'
4851
5100
  orientation="orientation"
4852
5101
  zone="props.zone"
@@ -4886,6 +5135,72 @@
4886
5135
  />
4887
5136
  </t>
4888
5137
 
5138
+ <t t-name="o-spreadsheet-UnhideRowHeaders">
5139
+ <t t-foreach="props.headersGroups" t-as="hiddenItem" t-key="hiddenItem_index">
5140
+ <t t-if="isVisible(hiddenItem[0]-1)">
5141
+ <div
5142
+ class="position-absolute w-100 pe-none"
5143
+ t-att-style="getUnhidePreviousButtonStyle(hiddenItem[0]-1)">
5144
+ <div
5145
+ class="o-unhide rounded end-0 position-absolute pe-auto"
5146
+ t-att-data-index="hiddenItem_index"
5147
+ t-attf-style="bottom: 2px;"
5148
+ t-att-data-direction="'up'"
5149
+ t-on-click="() => this.unhide(hiddenItem)">
5150
+ <t t-call="o-spreadsheet-Icon.CARET_UP"/>
5151
+ </div>
5152
+ </div>
5153
+ </t>
5154
+ <t t-if="isVisible(hiddenItem.at(-1)+1)">
5155
+ <div
5156
+ class="position-absolute w-100 pe-none"
5157
+ t-att-style="getUnhideNextButtonStyle(hiddenItem.at(-1)+1)">
5158
+ <div
5159
+ class="o-unhide rounded end-0 position-absolute pe-auto"
5160
+ t-att-data-index="hiddenItem_index"
5161
+ t-att-data-direction="'down'"
5162
+ t-attf-style="top: 1px;"
5163
+ t-on-click="() => this.unhide(hiddenItem)">
5164
+ <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
5165
+ </div>
5166
+ </div>
5167
+ </t>
5168
+ </t>
5169
+ </t>
5170
+
5171
+ <t t-name="o-spreadsheet-UnhideColumnHeaders">
5172
+ <t t-foreach="props.headersGroups" t-as="hiddenItem" t-key="hiddenItem_index">
5173
+ <t t-if="isVisible(hiddenItem[0]-1)">
5174
+ <div
5175
+ class="position-absolute d-flex align-items-center pe-none h-100"
5176
+ t-att-style="getUnhidePreviousButtonStyle(hiddenItem[0]-1)">
5177
+ <div
5178
+ class="o-unhide position-absolute rounded pe-auto"
5179
+ t-att-data-index="hiddenItem_index"
5180
+ t-att-data-direction="'left'"
5181
+ t-attf-style="right: 1px;"
5182
+ t-on-click="() => this.unhide(hiddenItem)">
5183
+ <t t-call="o-spreadsheet-Icon.CARET_LEFT"/>
5184
+ </div>
5185
+ </div>
5186
+ </t>
5187
+ <t t-if="isVisible(hiddenItem.at(-1)+1)">
5188
+ <div
5189
+ class="position-absolute d-flex align-items-center pe-none h-100"
5190
+ t-att-style="getUnhideNextButtonStyle(hiddenItem.at(-1)+1)">
5191
+ <div
5192
+ class="o-unhide position-absolute rounded pe-auto"
5193
+ t-att-data-index="hiddenItem_index"
5194
+ t-att-data-direction="'right'"
5195
+ t-attf-style="left: 1px;"
5196
+ t-on-click="() => this.unhide(hiddenItem)">
5197
+ <t t-call="o-spreadsheet-Icon.CARET_RIGHT"/>
5198
+ </div>
5199
+ </div>
5200
+ </t>
5201
+ </t>
5202
+ </t>
5203
+
4889
5204
  <t t-name="o-spreadsheet-HeadersOverlay">
4890
5205
  <div class="o-overlay">
4891
5206
  <ColResizer onOpenContextMenu="props.onOpenContextMenu"/>
@@ -4924,27 +5239,14 @@
4924
5239
  <div class="dragging-resizer" t-if="state.isResizing"/>
4925
5240
  </div>
4926
5241
  </t>
4927
- <t
4928
- t-foreach="env.model.getters.getHiddenRowsGroups(env.model.getters.getActiveSheetId())"
4929
- t-as="hiddenItem"
4930
- t-key="hiddenItem_index">
4931
- <div
4932
- class="position-absolute end-0 translate-middle-y"
4933
- t-att-style="getUnhideButtonStyle(hiddenItem[0])">
4934
- <div
4935
- class="o-unhide rounded mb-1"
4936
- t-att-class="{'invisible': hiddenItem.includes(0)}"
4937
- t-att-data-index="hiddenItem_index"
4938
- t-on-click="() => this.unhide(hiddenItem)">
4939
- <t t-call="o-spreadsheet-Icon.CARET_UP"/>
4940
- </div>
4941
- <div
4942
- class="o-unhide rounded"
4943
- t-att-class="{'invisible': hiddenItem.includes(env.model.getters.getNumberRows(env.model.getters.getActiveSheetId())-1)}"
4944
- t-att-data-index="hiddenItem_index"
4945
- t-on-click="() => this.unhide(hiddenItem)">
4946
- <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
5242
+ <t t-if="env.model.getters.getHiddenRowsGroups(sheetId).length">
5243
+ <t t-if="hasFrozenPane">
5244
+ <div class="position-relative pe-none overflow-hidden" t-att-style="frozenContainerStyle">
5245
+ <UnhideRowHeaders t-props="frozenUnhideHeadersProps"/>
4947
5246
  </div>
5247
+ </t>
5248
+ <div class="pe-none overflow-hidden flex-shrink-0 position-relative h-100">
5249
+ <UnhideRowHeaders t-props="mainUnhideHeadersProps"/>
4948
5250
  </div>
4949
5251
  </t>
4950
5252
  </div>
@@ -4952,7 +5254,7 @@
4952
5254
 
4953
5255
  <t t-name="o-spreadsheet-ColResizer">
4954
5256
  <div
4955
- class="o-col-resizer"
5257
+ class="o-col-resizer d-flex"
4956
5258
  t-on-pointermove.self="onMouseMove"
4957
5259
  t-on-mouseleave="onMouseLeave"
4958
5260
  t-on-pointerdown.self.prevent="select"
@@ -4980,27 +5282,16 @@
4980
5282
  <div class="dragging-resizer" t-if="state.isResizing"/>
4981
5283
  </div>
4982
5284
  </t>
4983
- <t
4984
- t-foreach="env.model.getters.getHiddenColsGroups(env.model.getters.getActiveSheetId())"
4985
- t-as="hiddenItem"
4986
- t-key="hiddenItem_index">
4987
- <div
4988
- class="position-absolute h-100 d-flex align-items-center translate-middle-x gap-2"
4989
- t-att-style="getUnhideButtonStyle(hiddenItem[0])">
4990
- <div
4991
- class="o-unhide rounded"
4992
- t-att-class="{'invisible': hiddenItem.includes(0)}"
4993
- t-att-data-index="hiddenItem_index"
4994
- t-on-click="() => this.unhide(hiddenItem)">
4995
- <t t-call="o-spreadsheet-Icon.CARET_LEFT"/>
4996
- </div>
5285
+ <t t-if="env.model.getters.getHiddenColsGroups(sheetId).length">
5286
+ <t t-if="hasFrozenPane">
4997
5287
  <div
4998
- class="o-unhide rounded"
4999
- t-att-class="{'invisible': hiddenItem.includes(env.model.getters.getNumberCols(env.model.getters.getActiveSheetId())-1)}"
5000
- t-att-data-index="hiddenItem_index"
5001
- t-on-click="() => this.unhide(hiddenItem)">
5002
- <t t-call="o-spreadsheet-Icon.CARET_RIGHT"/>
5288
+ class="position-relative pe-none h-100 flex-shrink-0"
5289
+ t-att-style="frozenContainerStyle">
5290
+ <UnhideColumnHeaders t-props="frozenUnhideHeadersProps"/>
5003
5291
  </div>
5292
+ </t>
5293
+ <div class="pe-none overflow-hidden flex-shrink-0 position-relative w-100">
5294
+ <UnhideColumnHeaders t-props="mainUnhideHeadersProps"/>
5004
5295
  </div>
5005
5296
  </t>
5006
5297
  </div>
@@ -5068,7 +5359,7 @@
5068
5359
  <Menu
5069
5360
  t-if="menu.isOpen"
5070
5361
  menuItems="menu.menuItems"
5071
- position="menu.position"
5362
+ anchorRect="menu.anchorRect"
5072
5363
  onClose.bind="this.closeMenu"
5073
5364
  />
5074
5365
  </div>
@@ -5116,6 +5407,9 @@
5116
5407
  </t>
5117
5408
 
5118
5409
  <t t-name="o-spreadsheet-GridOverlay">
5410
+ <div class="position-absolute" t-att-style="style">
5411
+ <FiguresContainer onFigureDeleted="props.onFigureDeleted"/>
5412
+ </div>
5119
5413
  <div
5120
5414
  t-ref="gridOverlay"
5121
5415
  class="o-grid-overlay overflow-hidden"
@@ -5124,7 +5418,6 @@
5124
5418
  t-on-pointerdown="onMouseDown"
5125
5419
  t-on-dblclick.self="onDoubleClick"
5126
5420
  t-on-contextmenu.stop.prevent="onContextMenu">
5127
- <FiguresContainer onFigureDeleted="props.onFigureDeleted"/>
5128
5421
  <DataValidationOverlay/>
5129
5422
  <FilterIconsOverlay/>
5130
5423
  <GridAddRowsFooter
@@ -5132,6 +5425,7 @@
5132
5425
  t-key="env.model.getters.getActiveSheetId()"
5133
5426
  focusGrid="props.onFigureDeleted"
5134
5427
  />
5428
+ <t t-slot="default"/>
5135
5429
  </div>
5136
5430
  </t>
5137
5431
 
@@ -5183,7 +5477,6 @@
5183
5477
  onCellClicked.bind="onCellClicked"
5184
5478
  onCellDoubleClicked.bind="onCellDoubleClicked"
5185
5479
  onCellRightClicked.bind="onCellRightClicked"
5186
- onCellHovered.bind="onCellHovered"
5187
5480
  onGridResized.bind="onGridResized"
5188
5481
  onGridMoved.bind="moveCanvas"
5189
5482
  gridOverlayDimensions="gridOverlayDimensions"
@@ -5225,7 +5518,7 @@
5225
5518
  <Menu
5226
5519
  t-if="menuState.isOpen"
5227
5520
  menuItems="menuState.menuItems"
5228
- position="menuState.position"
5521
+ anchorRect="menuState.anchorRect"
5229
5522
  onClose="() => this.closeMenu()"
5230
5523
  />
5231
5524
  <t t-foreach="staticTables" t-as="table" t-key="table.id">
@@ -5386,13 +5679,13 @@
5386
5679
  <div
5387
5680
  class="o-figure-viewport-inverse w-0 h-0 overflow-visible position-absolute"
5388
5681
  t-att-style="container.inverseViewportStyle">
5389
- <t t-foreach="container.figures" t-as="figure" t-key="figure.id">
5682
+ <t t-foreach="container.figures" t-as="figureUI" t-key="figureUI.id">
5390
5683
  <FigureComponent
5391
5684
  onFigureDeleted="this.props.onFigureDeleted"
5392
- figure="figure"
5393
- style="getFigureStyle(figure)"
5394
- onMouseDown="(ev) => this.startDraggingFigure(figure, ev)"
5395
- onClickAnchor="(dirX, dirY, ev) => this.startResize(figure, dirX, dirY, ev)"
5685
+ figureUI="figureUI"
5686
+ style="getFigureStyle(figureUI)"
5687
+ onMouseDown="(ev) => this.startDraggingFigure(figureUI, ev)"
5688
+ onClickAnchor="(dirX, dirY, ev) => this.startResize(figureUI, dirX, dirY, ev)"
5396
5689
  />
5397
5690
  </t>
5398
5691
  </div>
@@ -5419,8 +5712,8 @@
5419
5712
  <div class="o-chart-container w-100 h-100" t-on-dblclick="onDoubleClick">
5420
5713
  <t
5421
5714
  t-component="chartComponent"
5422
- figure="this.props.figure"
5423
- t-key="this.props.figure.id + '-' + chartType"
5715
+ figureUI="this.props.figureUI"
5716
+ t-key="this.props.figureUI.id"
5424
5717
  />
5425
5718
  </div>
5426
5719
  </t>
@@ -5433,15 +5726,15 @@
5433
5726
  t-on-contextmenu.prevent.stop="(ev) => !env.model.getters.isReadonly() and this.onContextMenu(ev)"
5434
5727
  t-ref="figure"
5435
5728
  t-att-style="props.style"
5436
- t-att-data-id="props.figure.id"
5729
+ t-att-data-id="props.figureUI.id"
5437
5730
  tabindex="0"
5438
5731
  t-on-keydown="(ev) => this.onKeyDown(ev)"
5439
5732
  t-on-keyup.stop="">
5440
5733
  <t
5441
- t-component="figureRegistry.get(props.figure.tag).Component"
5442
- t-key="props.figure.id"
5734
+ t-component="figureRegistry.get(props.figureUI.tag).Component"
5735
+ t-key="props.figureUI.id"
5443
5736
  onFigureDeleted="props.onFigureDeleted"
5444
- figure="props.figure"
5737
+ figureUI="props.figureUI"
5445
5738
  />
5446
5739
  <div class="o-figure-menu position-absolute m-2" t-if="!env.isDashboard()">
5447
5740
  <div
@@ -5454,7 +5747,7 @@
5454
5747
  </div>
5455
5748
  <Menu
5456
5749
  t-if="menuState.isOpen"
5457
- position="menuState.position"
5750
+ anchorRect="menuState.anchorRect"
5458
5751
  menuItems="menuState.menuItems"
5459
5752
  onClose="() => this.menuState.isOpen=false"
5460
5753
  />
@@ -5580,31 +5873,30 @@
5580
5873
  </t>
5581
5874
 
5582
5875
  <t t-name="o-spreadsheet-SpreadsheetDashboard">
5583
- <div class="o-grid o-two-columns" tabindex="-1" t-on-wheel="onMouseWheel">
5876
+ <div class="o-grid o-two-columns" t-ref="dashboard" tabindex="-1" t-on-wheel="onMouseWheel">
5584
5877
  <div class="mx-auto h-100 position-relative" t-ref="grid" t-att-style="gridContainer">
5585
5878
  <GridOverlay
5586
- onCellHovered.bind="onCellHovered"
5587
5879
  onGridResized.bind="onGridResized"
5588
5880
  onGridMoved.bind="moveCanvas"
5589
- gridOverlayDimensions="gridOverlayDimensions"
5590
- />
5881
+ gridOverlayDimensions="gridOverlayDimensions">
5882
+ <div
5883
+ t-foreach="getClickableCells()"
5884
+ t-as="clickableCell"
5885
+ t-key="clickableCell_index"
5886
+ class="o-dashboard-clickable-cell"
5887
+ t-att-title="clickableCell.title"
5888
+ t-on-click="(ev) => this.selectClickableCell(ev, clickableCell)"
5889
+ t-on-auxclick="(ev) => this.selectClickableCell(ev, clickableCell)"
5890
+ t-on-contextmenu.prevent=""
5891
+ t-att-style="getCellClickableStyle(clickableCell.coordinates)"
5892
+ />
5893
+ </GridOverlay>
5591
5894
  <canvas t-ref="canvas"/>
5592
5895
  <GridPopover
5593
5896
  gridRect="getGridRect()"
5594
5897
  onMouseWheel.bind="onMouseWheel"
5595
5898
  onClosePopover.bind="onClosePopover"
5596
5899
  />
5597
- <div
5598
- t-foreach="getClickableCells()"
5599
- t-as="clickableCell"
5600
- t-key="clickableCell_index"
5601
- class="o-dashboard-clickable-cell"
5602
- t-att-title="clickableCell.title"
5603
- t-on-click="(ev) => this.selectClickableCell(ev, clickableCell)"
5604
- t-on-auxclick="(ev) => this.selectClickableCell(ev, clickableCell)"
5605
- t-on-contextmenu.prevent=""
5606
- t-att-style="getCellClickableStyle(clickableCell.coordinates)"
5607
- />
5608
5900
  </div>
5609
5901
  <VerticalScrollBar/>
5610
5902
  <HorizontalScrollBar/>
@@ -5616,6 +5908,9 @@
5616
5908
  <div class="o-topbar-composer-container w-100">
5617
5909
  <div
5618
5910
  class="o-topbar-composer position-relative bg-white user-select-text d-flex"
5911
+ t-att-class="{
5912
+ 'o-topbar-composer-readonly': env.model.getters.isReadonly(),
5913
+ }"
5619
5914
  t-on-click.stop=""
5620
5915
  t-att-style="containerStyle">
5621
5916
  <Composer
@@ -5646,6 +5941,14 @@
5646
5941
  </div>
5647
5942
  </t>
5648
5943
 
5944
+ <t t-name="o-spreadsheet-SpeechBubble">
5945
+ <t t-portal="'.o-spreadsheet'">
5946
+ <div class="o-speech-bubble position-absolute px-3" t-ref="bubble">
5947
+ <div class="o-speech-content text-truncate pb-1" t-esc="props.content"/>
5948
+ </div>
5949
+ </t>
5950
+ </t>
5951
+
5649
5952
  <t t-name="o-spreadsheet-GridComposer">
5650
5953
  <div
5651
5954
  class="o-cell-reference"
@@ -5661,14 +5964,15 @@
5661
5964
  <t t-name="o-spreadsheet-FunctionDescriptionProvider">
5662
5965
  <div class="o-formula-assistant-container user-select-none shadow">
5663
5966
  <t t-set="context" t-value="getContext()"/>
5664
- <div class="o-formula-assistant" t-if="context.functionName">
5967
+ <div class="o-formula-assistant" t-if="context.functionDescription.name">
5665
5968
  <div class="o-formula-assistant-head d-flex flex-row justify-content-between">
5666
5969
  <div>
5667
- <span t-esc="context.functionName"/>
5970
+ <span t-esc="context.functionDescription.name"/>
5668
5971
  (
5669
5972
  <t t-foreach="context.functionDescription.args" t-as="arg" t-key="arg.name">
5670
5973
  <span t-if="arg_index > '0'" t-esc="formulaArgSeparator"/>
5671
- <span t-att-class="{ 'o-formula-assistant-focus': context.argToFocus === arg_index }">
5974
+ <span
5975
+ t-att-class="{ 'o-formula-assistant-focus': context.argsToFocus.includes(arg_index) }">
5672
5976
  <span>
5673
5977
  <span t-if="arg.optional || arg.repeating || arg.default">[</span>
5674
5978
  <span t-esc="arg.name"/>
@@ -5680,13 +5984,13 @@
5680
5984
  )
5681
5985
  </div>
5682
5986
  <i
5683
- class="fa fa-caret-up px-2 align-self-start collapsed"
5684
- data-bs-toggle="collapse"
5685
- data-bs-target="#formula-assistant-details"
5987
+ class="fa fa-caret-up px-2 align-self-start"
5988
+ t-att-class="state.isCollapsed ? 'collapsed' : ''"
5989
+ t-on-click="() => this.toggle()"
5686
5990
  />
5687
5991
  </div>
5688
5992
 
5689
- <div id="formula-assistant-details" class="collapse">
5993
+ <Collapse isCollapsed="state.isCollapsed">
5690
5994
  <div class="o-formula-assistant-core pb-3 m-3">
5691
5995
  <div class="o-formula-assistant-gray">ABOUT</div>
5692
5996
  <div t-esc="context.functionDescription.description"/>
@@ -5696,8 +6000,8 @@
5696
6000
  <div
5697
6001
  class="o-formula-assistant-arg p-3 pt-0 display-flex flex-column"
5698
6002
  t-att-class="{
5699
- 'o-formula-assistant-gray': context.argToFocus >= '0',
5700
- 'o-formula-assistant-focus': context.argToFocus === arg_index,
6003
+ 'o-formula-assistant-gray': context.argsToFocus.length > 0,
6004
+ 'o-formula-assistant-focus': context.argsToFocus.includes(arg_index),
5701
6005
  }">
5702
6006
  <div>
5703
6007
  <span t-esc="arg.name"/>
@@ -5712,7 +6016,7 @@
5712
6016
  <div class="o-formula-assistant-arg-description" t-esc="arg.description"/>
5713
6017
  </div>
5714
6018
  </t>
5715
- </div>
6019
+ </Collapse>
5716
6020
  </div>
5717
6021
  </div>
5718
6022
  </t>
@@ -5749,6 +6053,7 @@
5749
6053
  t-on-mousewheel.stop=""
5750
6054
  t-on-input="onInput"
5751
6055
  t-on-pointerdown="onMousedown"
6056
+ t-on-pointerup="onMouseup"
5752
6057
  t-on-click="onClick"
5753
6058
  t-on-keyup="onKeyup"
5754
6059
  t-on-paste="onPaste"
@@ -5760,7 +6065,7 @@
5760
6065
  />
5761
6066
  </div>
5762
6067
  <div
5763
- class="o-composer-assistant-container shadow position-absolute"
6068
+ class="o-composer-assistant-container shadow position-absolute z-1"
5764
6069
  t-att-style="assistantContainerStyle"
5765
6070
  t-if="props.focus !== 'inactive' and !assistant.forcedClosed and assistantIsAvailable">
5766
6071
  <span
@@ -5779,9 +6084,8 @@
5779
6084
  t-on-pointerup.prevent.stop="">
5780
6085
  <FunctionDescriptionProvider
5781
6086
  t-if="functionDescriptionState.showDescription"
5782
- functionName="functionDescriptionState.functionName"
5783
6087
  functionDescription="functionDescriptionState.functionDescription"
5784
- argToFocus="functionDescriptionState.argToFocus"
6088
+ argsToFocus="functionDescriptionState.argsToFocus"
5785
6089
  />
5786
6090
  <div
5787
6091
  t-if="functionDescriptionState.showDescription and autoCompleteState.provider"
@@ -5796,6 +6100,11 @@
5796
6100
  />
5797
6101
  </div>
5798
6102
  </div>
6103
+ <SpeechBubble
6104
+ t-if="displaySpeechBubble"
6105
+ content="props.composerStore.hoveredContentEvaluation"
6106
+ anchorRect="composerState.hoveredRect"
6107
+ />
5799
6108
  </div>
5800
6109
  </t>
5801
6110
 
@@ -5816,7 +6125,7 @@
5816
6125
  t-foreach="htmlContent"
5817
6126
  t-as="content"
5818
6127
  t-key="content_index"
5819
- t-att-class="content.class"
6128
+ t-att-class="content.classes?.join(' ')"
5820
6129
  t-attf-style="color: {{content.color || 'inherit'}};"
5821
6130
  t-esc="content.value"
5822
6131
  />
@@ -5926,7 +6235,6 @@
5926
6235
  t-on-click.stop=""
5927
6236
  t-att-value="state.customHexColor"
5928
6237
  t-on-input="setHexColor"
5929
- maxlength="7"
5930
6238
  />
5931
6239
  <div class="o-color-preview" t-att-style="colorPreviewStyle"/>
5932
6240
  </div>
@@ -5956,10 +6264,11 @@
5956
6264
  <t t-name="o-spreadsheet-BottomBar">
5957
6265
  <div
5958
6266
  class="o-spreadsheet-bottom-bar o-two-columns d-flex align-items-center overflow-hidden"
6267
+ t-att-class="{'mobile': env.isSmall}"
5959
6268
  t-on-click="props.onClick"
5960
6269
  t-ref="bottomBar"
5961
6270
  t-on-contextmenu.prevent="">
5962
- <Ripple>
6271
+ <Ripple class="'add-sheet-container'">
5963
6272
  <div
5964
6273
  class="o-sheet-item o-add-sheet me-2 p-1"
5965
6274
  t-if="!env.model.getters.isReadonly()"
@@ -5968,11 +6277,15 @@
5968
6277
  </div>
5969
6278
  </Ripple>
5970
6279
  <Ripple>
5971
- <div class="o-sheet-item o-list-sheets me-2 p-1" t-on-click="clickListSheets">
6280
+ <div
6281
+ class="o-sheet-item o-list-sheets me-2 p-1"
6282
+ composerFocusableElement="true"
6283
+ tabindex="-1"
6284
+ t-on-click="clickListSheets">
5972
6285
  <t t-call="o-spreadsheet-Icon.LIST"/>
5973
6286
  </div>
5974
6287
  </Ripple>
5975
- <div class="o-all-sheets position-relative flex-shrink-0 d-flex h-100 me-3">
6288
+ <div class="o-all-sheets position-relative d-flex h-100 flex-fill overflow-hidden">
5976
6289
  <div
5977
6290
  class="o-bottom-bar-fade-in position-absolute h-100 w-100 pe-none"
5978
6291
  t-if="state.isSheetListScrollableLeft"
@@ -5996,47 +6309,48 @@
5996
6309
  t-if="state.isSheetListScrollableRight"
5997
6310
  />
5998
6311
  </div>
5999
- <div
6000
- class="o-bottom-bar-arrows d-flex h-100 me-5 align-items-center"
6001
- t-if="state.isSheetListScrollableLeft || state.isSheetListScrollableRight">
6002
- <Ripple
6003
- ignoreClickPosition="true"
6004
- width="20"
6005
- height="20"
6006
- offsetX="1"
6007
- allowOverflow="true"
6008
- enabled="state.isSheetListScrollableLeft">
6009
- <div
6010
- class="o-bottom-bar-arrow o-bottom-bar-arrow-left d-flex align-items-center me-2"
6011
- t-att-class="{'o-disabled': !state.isSheetListScrollableLeft}"
6012
- t-on-click="onArrowLeft">
6013
- <t t-call="o-spreadsheet-Icon.CARET_LEFT"/>
6014
- </div>
6015
- </Ripple>
6016
- <Ripple
6017
- ignoreClickPosition="true"
6018
- width="20"
6019
- height="20"
6020
- offsetX="-1"
6021
- allowOverflow="true"
6022
- enabled="state.isSheetListScrollableRight">
6023
- <div
6024
- class="o-bottom-bar-arrow o-bottom-bar-arrow-right d-flex align-items-center me-4"
6025
- t-att-class="{'o-disabled': !state.isSheetListScrollableRight}"
6026
- t-on-click="onArrowRight">
6027
- <t t-call="o-spreadsheet-Icon.CARET_RIGHT"/>
6028
- </div>
6029
- </Ripple>
6030
- </div>
6031
-
6032
- <BottomBarStatistic
6033
- openContextMenu="(x, y, registry) => this.openContextMenu(x, y, 'listSelectionStatistics', registry)"
6034
- closeContextMenu="() => this.closeContextMenuWithId('listSelectionStatistics')"
6035
- />
6312
+ <t t-if="!env.isSmall">
6313
+ <div
6314
+ class="o-bottom-bar-arrows d-flex h-100 me-4 align-items-center ms-3"
6315
+ t-if="state.isSheetListScrollableLeft || state.isSheetListScrollableRight">
6316
+ <Ripple
6317
+ ignoreClickPosition="true"
6318
+ width="20"
6319
+ height="20"
6320
+ offsetX="1"
6321
+ allowOverflow="true"
6322
+ enabled="state.isSheetListScrollableLeft">
6323
+ <div
6324
+ class="o-bottom-bar-arrow o-bottom-bar-arrow-left d-flex align-items-center"
6325
+ t-att-class="{'o-disabled': !state.isSheetListScrollableLeft}"
6326
+ t-on-click="onArrowLeft">
6327
+ <t t-call="o-spreadsheet-Icon.CARET_LEFT"/>
6328
+ </div>
6329
+ </Ripple>
6330
+ <Ripple
6331
+ ignoreClickPosition="true"
6332
+ width="20"
6333
+ height="20"
6334
+ offsetX="-1"
6335
+ allowOverflow="true"
6336
+ enabled="state.isSheetListScrollableRight">
6337
+ <div
6338
+ class="o-bottom-bar-arrow o-bottom-bar-arrow-right d-flex align-items-center"
6339
+ t-att-class="{'o-disabled': !state.isSheetListScrollableRight}"
6340
+ t-on-click="onArrowRight">
6341
+ <t t-call="o-spreadsheet-Icon.CARET_RIGHT"/>
6342
+ </div>
6343
+ </Ripple>
6344
+ </div>
6345
+ <BottomBarStatistic
6346
+ openContextMenu="(x, y, registry) => this.openContextMenu(x, y, 'listSelectionStatistics', registry)"
6347
+ closeContextMenu="() => this.closeContextMenuWithId('listSelectionStatistics')"
6348
+ />
6349
+ </t>
6036
6350
 
6037
6351
  <Menu
6038
6352
  t-if="menuState.isOpen"
6039
- position="menuState.position"
6353
+ anchorRect="menuState.anchorRect"
6040
6354
  menuItems="menuState.menuItems"
6041
6355
  maxHeight="menuMaxHeight"
6042
6356
  onClose="() => this.closeMenu()"
@@ -6047,7 +6361,7 @@
6047
6361
 
6048
6362
  <t t-name="o-spreadsheet-BottomBarStatistic">
6049
6363
  <t t-set="selectedStatistic" t-value="getSelectedStatistic()"/>
6050
- <Ripple class="'ms-auto'" t-if="selectedStatistic !== undefined">
6364
+ <Ripple class="'ms-auto bottom-statistics'" t-if="selectedStatistic !== undefined">
6051
6365
  <div
6052
6366
  class="o-selection-statistic text-truncate user-select-none me-4 bg-white rounded shadow d-flex align-items-center"
6053
6367
  t-on-click="listSelectionStatistics">
@@ -6077,14 +6391,16 @@
6077
6391
  t-att-class="{'o-sheet-name-editable': state.isEditing }"
6078
6392
  t-ref="sheetNameSpan"
6079
6393
  t-esc="sheetName"
6080
- t-on-click="(ev) => this.onMouseEventSheetName(ev)"
6081
6394
  t-on-pointerdown="(ev) => this.onMouseEventSheetName(ev)"
6082
6395
  t-on-dblclick="() => this.onDblClick()"
6083
6396
  t-on-focusout="() => this.onFocusOut()"
6084
6397
  t-on-keydown="(ev) => this.onKeyDown(ev)"
6085
6398
  t-att-contenteditable="state.isEditing ? 'true': 'false'"
6086
6399
  />
6087
- <span class="o-sheet-icon ms-1" t-on-click.stop="(ev) => this.onIconClick(ev)">
6400
+ <span
6401
+ class="o-sheet-icon ms-1"
6402
+ tabindex="-1"
6403
+ t-on-click.stop="(ev) => this.onIconClick(ev)">
6088
6404
  <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
6089
6405
  </span>
6090
6406
  <div