@odoo/o-spreadsheet 17.3.0-alpha.1 → 17.3.0-alpha.10

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 17.3.0-alpha.1
5
- @date 2024-03-25T09:44:13.802Z
6
- @hash 4095c41
4
+ @version 17.3.0-alpha.10
5
+ @date 2024-05-29T15:28:51.457Z
6
+ @hash f95d4f5
7
7
  -->
8
8
  <odoo>
9
9
  <t t-name="o-spreadsheet-ActionButton">
@@ -18,7 +18,7 @@
18
18
  <t t-call="{{iconTitle}}"/>
19
19
  </span>
20
20
  <t t-if="props.hasTriangleDownIcon">
21
- <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
21
+ <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
22
22
  </t>
23
23
  </span>
24
24
  </t>
@@ -103,7 +103,7 @@
103
103
  dropdownMaxHeight="this.props.dropdownMaxHeight"
104
104
  class="'o-dropdown-button o-border-picker-button'"
105
105
  />
106
- <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
106
+ <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
107
107
  </div>
108
108
  <div
109
109
  class="o-border-style-tool d-flex align-items-center justify-content-center o-hoverable-button"
@@ -111,7 +111,7 @@
111
111
  t-ref="lineStyleButton"
112
112
  t-on-click.stop="(ev) => this.toggleDropdownTool('borderTypeTool')">
113
113
  <t t-call="o-spreadsheet-Icon.BORDER_TYPE"/>
114
- <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
114
+ <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
115
115
  <Popover
116
116
  t-props="lineStylePickerPopoverProps"
117
117
  t-if="state.activeTool === 'borderTypeTool'">
@@ -276,24 +276,24 @@
276
276
  t-on-dblclick="() => this.onDblClick()"
277
277
  t-on-focusout="() => this.onFocusOut()"
278
278
  t-on-keydown="(ev) => this.onKeyDown(ev)"
279
- t-att-contenteditable="state.isEditing ? 'plaintext-only': 'false'"
279
+ t-att-contenteditable="state.isEditing ? 'true': 'false'"
280
280
  />
281
281
  <span class="o-sheet-icon ms-1" t-on-click.stop="(ev) => this.onIconClick(ev)">
282
- <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
282
+ <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
283
283
  </span>
284
284
  </div>
285
285
  </Ripple>
286
286
  </t>
287
287
 
288
- <t t-name="o-spreadsheet-BottomBarStatisic">
288
+ <t t-name="o-spreadsheet-BottomBarStatistic">
289
289
  <t t-set="selectedStatistic" t-value="getSelectedStatistic()"/>
290
290
  <Ripple class="'ms-auto'" t-if="selectedStatistic !== undefined">
291
291
  <div
292
- class="o-selection-statistic text-truncate user-select-none me-4 bg-white rounded shadow"
292
+ class="o-selection-statistic text-truncate user-select-none me-4 bg-white rounded shadow d-flex align-items-center"
293
293
  t-on-click="listSelectionStatistics">
294
294
  <t t-esc="selectedStatistic"/>
295
295
  <span class="ms-2">
296
- <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
296
+ <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
297
297
  </span>
298
298
  </div>
299
299
  </Ripple>
@@ -365,7 +365,7 @@
365
365
  <div class="o-hue-container" t-on-pointerdown="dragHuePointer">
366
366
  <div class="o-hue-picker" t-on-click.stop=""/>
367
367
  <div class="o-hue-slider pe-none" t-att-style="sliderStyle">
368
- <t t-call="o-spreadsheet-Icon.TRIANGLE_UP"/>
368
+ <t t-call="o-spreadsheet-Icon.CARET_UP"/>
369
369
  </div>
370
370
  </div>
371
371
  <div class="o-custom-input-preview">
@@ -471,6 +471,7 @@
471
471
  t-on-compositionstart="onCompositionStart"
472
472
  t-on-compositionend="onCompositionEnd"
473
473
  t-on-dblclick="onDblClick"
474
+ t-on-contextmenu="onContextMenu"
474
475
  />
475
476
 
476
477
  <div
@@ -515,7 +516,7 @@
515
516
  <span t-esc="context.functionName"/>
516
517
  (
517
518
  <t t-foreach="context.functionDescription.args" t-as="arg" t-key="arg.name">
518
- <span t-if="arg_index > '0'">,&#xA0;</span>
519
+ <span t-if="arg_index > '0'" t-esc="formulaArgSeparator"/>
519
520
  <span t-att-class="{ 'o-formula-assistant-focus': context.argToFocus === arg_index }">
520
521
  <span>
521
522
  <span t-if="arg.optional || arg.repeating || arg.default">[</span>
@@ -574,16 +575,17 @@
574
575
  class="o-topbar-composer bg-white user-select-text"
575
576
  t-on-click.stop=""
576
577
  t-att-style="containerStyle">
577
- <Composer focus="focus" inputStyle="composerStyle" onComposerContentFocused.bind="onFocus"/>
578
+ <Composer
579
+ focus="focus"
580
+ inputStyle="composerStyle"
581
+ onComposerContentFocused.bind="onFocus"
582
+ delimitation="delimitation"
583
+ />
578
584
  </div>
579
585
  </t>
580
586
 
581
587
  <t t-name="o-spreadsheet-SpreadsheetDashboard">
582
- <div
583
- class="o-grid o-two-columns"
584
- tabindex="-1"
585
- t-on-wheel="onMouseWheel"
586
- t-on-click="onClosePopover">
588
+ <div class="o-grid o-two-columns" tabindex="-1" t-on-wheel="onMouseWheel">
587
589
  <div class="mx-auto h-100 position-relative" t-ref="grid" t-att-style="gridContainer">
588
590
  <GridOverlay
589
591
  onCellHovered.bind="onCellHovered"
@@ -600,13 +602,12 @@
600
602
  <div
601
603
  t-foreach="getClickableCells()"
602
604
  t-as="clickableCell"
603
- t-key="clickableCell.tKey"
605
+ t-key="clickableCell_index"
604
606
  class="o-dashboard-clickable-cell"
605
607
  t-on-click="() => this.selectClickableCell(clickableCell)"
606
608
  t-on-contextmenu.prevent=""
607
609
  t-att-style="getCellClickableStyle(clickableCell.coordinates)"
608
610
  />
609
- <FilterIconsOverlay/>
610
611
  </div>
611
612
  <VerticalScrollBar/>
612
613
  <HorizontalScrollBar/>
@@ -806,7 +807,7 @@
806
807
  </t>
807
808
 
808
809
  <t t-name="o-spreadsheet-FilterIcon">
809
- <div class="o-filter-icon" t-att-class="iconClass" t-on-click.stop="onClick">
810
+ <div class="o-filter-icon" t-att-class="iconClass" t-on-click="onClick">
810
811
  <t t-if="isFilterActive" t-call="o-spreadsheet-Icon.FILTER_ICON_ACTIVE"/>
811
812
  <t t-else="" t-call="o-spreadsheet-Icon.FILTER_ICON"/>
812
813
  </div>
@@ -817,7 +818,7 @@
817
818
  t-foreach="getFilterHeadersPositions()"
818
819
  t-as="position"
819
820
  t-key="'filter'+position.col + '_' + position.row">
820
- <GridCellIcon cellPosition="position" offset="props.gridPosition" horizontalAlign="'right'">
821
+ <GridCellIcon cellPosition="position" horizontalAlign="'right'">
821
822
  <FilterIcon cellPosition="position"/>
822
823
  </GridCellIcon>
823
824
  </t>
@@ -825,15 +826,17 @@
825
826
 
826
827
  <t t-name="o-spreadsheet-FilterMenu">
827
828
  <div class="o-filter-menu d-flex flex-column bg-white" t-on-wheel.stop="">
828
- <div t-if="!isReadonly">
829
- <div class="o-filter-menu-item" t-on-click="() => this.sortFilterZone('ascending')">
830
- Sort ascending (A ⟶ Z)
831
- </div>
832
- <div class="o-filter-menu-item" t-on-click="() => this.sortFilterZone('descending')">
833
- Sort descending (Z ⟶ A)
829
+ <t t-if="isSortable">
830
+ <div>
831
+ <div class="o-filter-menu-item" t-on-click="() => this.sortFilterZone('ascending')">
832
+ Sort ascending (A ⟶ Z)
833
+ </div>
834
+ <div class="o-filter-menu-item" t-on-click="() => this.sortFilterZone('descending')">
835
+ Sort descending (Z ⟶ A)
836
+ </div>
834
837
  </div>
835
- </div>
836
- <div class="o-separator" t-if="!isReadonly"/>
838
+ <div class="o-separator"/>
839
+ </t>
837
840
  <div class="o-filter-menu-actions">
838
841
  <div class="o-filter-menu-action-text" t-on-click="selectAll">Select all</div>
839
842
  <div class="o-filter-menu-action-text" t-on-click="clearAll">Clear</div>
@@ -922,7 +925,7 @@
922
925
  t-ref="inputFontSize"
923
926
  />
924
927
  <span>
925
- <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
928
+ <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
926
929
  </span>
927
930
  </div>
928
931
  <div
@@ -947,8 +950,7 @@
947
950
  tabindex="-1"
948
951
  t-on-click="focusDefaultElement"
949
952
  t-on-keydown="onKeydown"
950
- t-on-wheel="onMouseWheel"
951
- t-on-contextmenu="onInputContextMenu"
953
+ t-on-wheel.prevent="onMouseWheel"
952
954
  t-ref="grid">
953
955
  <GridOverlay
954
956
  onCellClicked.bind="onCellClicked"
@@ -961,7 +963,10 @@
961
963
  onFigureDeleted.bind="focusDefaultElement"
962
964
  />
963
965
  <HeadersOverlay onOpenContextMenu="(type, x, y) => this.toggleContextMenu(type, x, y)"/>
964
- <GridComposer gridDims="env.model.getters.getSheetViewDimensionWithHeaders()"/>
966
+ <GridComposer
967
+ gridDims="env.model.getters.getSheetViewDimensionWithHeaders()"
968
+ onInputContextMenu.bind="onInputContextMenu"
969
+ />
965
970
  <canvas t-ref="canvas"/>
966
971
  <t
967
972
  t-foreach="env.model.getters.getClientsToDisplay()"
@@ -996,7 +1001,9 @@
996
1001
  position="menuState.position"
997
1002
  onClose="() => this.closeMenu()"
998
1003
  />
999
- <FilterIconsOverlay gridPosition="{ x: HEADER_WIDTH, y : HEADER_HEIGHT }"/>
1004
+ <t t-foreach="staticTables" t-as="table" t-key="table.id">
1005
+ <TableResizer table="table"/>
1006
+ </t>
1000
1007
  <VerticalScrollBar topOffset="HEADER_HEIGHT"/>
1001
1008
  <HorizontalScrollBar leftOffset="HEADER_WIDTH"/>
1002
1009
  <div class="o-scrollbar corner"/>
@@ -1049,6 +1056,7 @@
1049
1056
  t-on-contextmenu.stop.prevent="onContextMenu">
1050
1057
  <FiguresContainer onFigureDeleted="props.onFigureDeleted"/>
1051
1058
  <DataValidationOverlay/>
1059
+ <FilterIconsOverlay/>
1052
1060
  <GridAddRowsFooter
1053
1061
  t-if="!env.model.getters.isReadonly()"
1054
1062
  t-key="env.model.getters.getActiveSheetId()"
@@ -1209,25 +1217,22 @@
1209
1217
  t-as="hiddenItem"
1210
1218
  t-key="hiddenItem_index">
1211
1219
  <div
1212
- class="o-unhide-buttons position-relative float-end"
1220
+ class="position-absolute end-0 translate-middle-y"
1213
1221
  t-att-style="getUnhideButtonStyle(hiddenItem[0])">
1214
- <t t-if="!hiddenItem.includes(0)">
1215
- <div
1216
- class="o-unhide rounded mb-1"
1217
- t-att-data-index="hiddenItem_index"
1218
- t-on-click="() => this.unhide(hiddenItem)">
1219
- <t t-call="o-spreadsheet-Icon.TRIANGLE_UP"/>
1220
- </div>
1221
- </t>
1222
- <t
1223
- t-if="!hiddenItem.includes(env.model.getters.getNumberRows(env.model.getters.getActiveSheetId())-1)">
1224
- <div
1225
- class="o-unhide rounded"
1226
- t-att-data-index="hiddenItem_index"
1227
- t-on-click="() => this.unhide(hiddenItem)">
1228
- <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
1229
- </div>
1230
- </t>
1222
+ <div
1223
+ class="o-unhide rounded mb-1"
1224
+ t-att-class="{'invisible': hiddenItem.includes(0)}"
1225
+ t-att-data-index="hiddenItem_index"
1226
+ t-on-click="() => this.unhide(hiddenItem)">
1227
+ <t t-call="o-spreadsheet-Icon.CARET_UP"/>
1228
+ </div>
1229
+ <div
1230
+ class="o-unhide rounded"
1231
+ t-att-class="{'invisible': hiddenItem.includes(env.model.getters.getNumberRows(env.model.getters.getActiveSheetId())-1)}"
1232
+ t-att-data-index="hiddenItem_index"
1233
+ t-on-click="() => this.unhide(hiddenItem)">
1234
+ <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
1235
+ </div>
1231
1236
  </div>
1232
1237
  </t>
1233
1238
  </div>
@@ -1268,25 +1273,22 @@
1268
1273
  t-as="hiddenItem"
1269
1274
  t-key="hiddenItem_index">
1270
1275
  <div
1271
- class="o-unhide-buttons position-relative h-100 d-flex align-items-center"
1276
+ class="position-absolute h-100 d-flex align-items-center translate-middle-x gap-2"
1272
1277
  t-att-style="getUnhideButtonStyle(hiddenItem[0])">
1273
- <t t-if="!hiddenItem.includes(0)">
1274
- <div
1275
- class="o-unhide rounded"
1276
- t-att-data-index="hiddenItem_index"
1277
- t-on-click="() => this.unhide(hiddenItem)">
1278
- <t t-call="o-spreadsheet-Icon.TRIANGLE_LEFT"/>
1279
- </div>
1280
- </t>
1281
- <t
1282
- t-if="!hiddenItem.includes(env.model.getters.getNumberCols(env.model.getters.getActiveSheetId())-1)">
1283
- <div
1284
- class="o-unhide rounded"
1285
- t-att-data-index="hiddenItem_index"
1286
- t-on-click="() => this.unhide(hiddenItem)">
1287
- <t t-call="o-spreadsheet-Icon.TRIANGLE_RIGHT"/>
1288
- </div>
1289
- </t>
1278
+ <div
1279
+ class="o-unhide rounded"
1280
+ t-att-class="{'invisible': hiddenItem.includes(0)}"
1281
+ t-att-data-index="hiddenItem_index"
1282
+ t-on-click="() => this.unhide(hiddenItem)">
1283
+ <t t-call="o-spreadsheet-Icon.CARET_LEFT"/>
1284
+ </div>
1285
+ <div
1286
+ class="o-unhide rounded"
1287
+ t-att-class="{'invisible': hiddenItem.includes(env.model.getters.getNumberCols(env.model.getters.getActiveSheetId())-1)}"
1288
+ t-att-data-index="hiddenItem_index"
1289
+ t-on-click="() => this.unhide(hiddenItem)">
1290
+ <t t-call="o-spreadsheet-Icon.CARET_RIGHT"/>
1291
+ </div>
1290
1292
  </div>
1291
1293
  </t>
1292
1294
  </div>
@@ -1434,12 +1436,9 @@
1434
1436
  </svg>
1435
1437
  </t>
1436
1438
  <t t-name="o-spreadsheet-Icon.COPY">
1437
- <svg class="o-icon">
1438
- <path
1439
- fill="currentColor"
1440
- d="M14.5 15.23v1.5H3a1 1 0 0 1-1-1V3.23h1.5v11a1 1 0 0 0 1 1h10m0-3.5a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1v-8a1 1 0 0 1 1-1h6.5a1 1 0 0 1 1 1m-9-2.5a1 1 0 0 0-1 1v11a1 1 0 0 0 1 1H15a1 1 0 0 0 1-1v-11a1 1 0 0 0-1-1"
1441
- />
1442
- </svg>
1439
+ <div class="o-icon">
1440
+ <i class="fa fa-clone"/>
1441
+ </div>
1443
1442
  </t>
1444
1443
  <t t-name="o-spreadsheet-Icon.CUT">
1445
1444
  <svg class="o-icon">
@@ -1457,22 +1456,6 @@
1457
1456
  />
1458
1457
  </svg>
1459
1458
  </t>
1460
- <t t-name="o-spreadsheet-Icon.FIND_AND_REPLACE">
1461
- <svg class="o-icon">
1462
- <path
1463
- fill="currentColor"
1464
- d="M10.75 11.25c-1 .75-2.25 1.25-3.5 1.25-3 0-5.5-2.5-5.5-5.5s2.5-5.5 5.5-5.5 5.5 2.5 5.5 5.5c0 1.25-.5 2.5-1.25 3.5l.25.25h.75l4 4-1.5 1.5-4-4v-.75l-.25-.25ZM7.25 11c2.25 0 4-1.75 4-4s-1.75-4-4-4-4 1.75-4 4 1.75 4 4 4"
1465
- />
1466
- </svg>
1467
- </t>
1468
- <t t-name="o-spreadsheet-Icon.DELETE">
1469
- <svg class="o-icon">
1470
- <path
1471
- fill="currentColor"
1472
- d="M12 1.75v-1H6v1H1.5v2h1v12a1.5 1.5 0 0 0 1.5 1.5h10a1.5 1.5 0 0 0 1.5-1.5v-12h1v-2M4 15.75v-12h10v12Zm2-10.5h2v9H6Zm4 0h2v9h-2"
1473
- />
1474
- </svg>
1475
- </t>
1476
1459
  <t t-name="o-spreadsheet-Icon.CLEAR">
1477
1460
  <svg class="o-icon">
1478
1461
  <path
@@ -1498,12 +1481,9 @@
1498
1481
  </svg>
1499
1482
  </t>
1500
1483
  <t t-name="o-spreadsheet-Icon.SHOW">
1501
- <svg class="o-icon" viewBox="0 0 24 24" fill="none" stroke="currentcolor">
1502
- <path stroke-width="1.35" d="M1,12 S11.5,0 23,12 M1,12 S11.5,24 23,12"/>
1503
- <path d="M1.26,11.7 A .4 .3 1 0 0 1.2,12.3"/>
1504
- <path d="M22.8,11.7 A .4 .3 1 0 1 22.75,12.3"/>
1505
- <circle stroke-width="1.35" stroke="currentcolor" cx="12" cy="12" r="3"/>
1506
- </svg>
1484
+ <div class="o-icon">
1485
+ <i class="fa fa-eye"/>
1486
+ </div>
1507
1487
  </t>
1508
1488
  <t t-name="o-spreadsheet-Icon.FORMULA">
1509
1489
  <svg class="o-icon">
@@ -1618,34 +1598,24 @@
1618
1598
  </svg>
1619
1599
  </t>
1620
1600
  <t t-name="o-spreadsheet-Icon.INSERT_CHART">
1621
- <svg class="o-icon">
1622
- <path
1623
- fill="currentColor"
1624
- d="M.5 2A1.5 1.5 0 0 1 2 .5h14A1.5 1.5 0 0 1 17.5 2v14a1.5 1.5 0 0 1-1.5 1.5H2A1.5 1.5 0 0 1 .5 16V2H2v14h14V2H2m1.5 12.5h2v-7h-2m3 7h2v-10h-2m3 10h2v-5h-2m3 5h2v-11h-2M2 14.5h14v1H2"
1625
- />
1626
- </svg>
1601
+ <div class="o-icon">
1602
+ <i class="fa fa-bar-chart"/>
1603
+ </div>
1627
1604
  </t>
1628
1605
  <t t-name="o-spreadsheet-Icon.INSERT_IMAGE">
1629
- <svg class="o-icon" fill="currentColor">
1630
- <path
1631
- d="M.5 2A1.5 1.5 0 0 1 2 .5h14A1.5 1.5 0 0 1 17.5 2v14a1.5 1.5 0 0 1-1.5 1.5H2A1.5 1.5 0 0 1 .5 16V2H2v14h14V2H2m10 4.5L10 11 8.5 9.5l-2 2.5L5 10.5l-2 3h12M3.5,5a1.5,1.5,0,0,1,3,0a1.5,1.5,0,0,1,-3,0"
1632
- />
1633
- </svg>
1606
+ <div class="o-icon">
1607
+ <i class="fa fa-file-image-o"/>
1608
+ </div>
1634
1609
  </t>
1635
1610
  <t t-name="o-spreadsheet-Icon.INSERT_LINK">
1636
- <svg class="o-icon" fill="currentColor">
1637
- <path
1638
- d="M6.88 13.69c.19-.19.41-.28.68-.28.27 0 .51.09.72.28.43.45.43.92 0 1.4l-.84.8c-.75.75-1.63 1.12-2.64 1.12-1.04 0-1.93-.37-2.68-1.12C1.37 15.14 1 14.26 1 13.25c0-1.04.37-1.93 1.12-2.68l2.96-2.96c.93-.9 1.89-1.42 2.88-1.54.98-.12 1.84.17 2.56.86.21.21.32.45.32.72 0 .26-.1.51-.32.72-.48.43-.95.43-1.4 0-.67-.64-1.55-.41-2.67.68l-2.93 2.92c-.35.35-.52.77-.52 1.28s.17.92.52 1.24c.35.35.76.52 1.26.52.49 0 .91-.17 1.26-.52l.84-.8m9-11.48c.75.75 1.12 1.63 1.12 2.64 0 1.04-.37 1.94-1.12 2.68l-3.16 3.16c-.99.96-1.99 1.44-3 1.44-.83 0-1.57-.33-2.24-1a.913.913 0 0 1-.28-.68c0-.27.09-.5.27-.72.19-.19.43-.28.71-.28.28 0 .51.09.7.28.66.64 1.48.48 2.44-.48l3.16-3.12c.37-.37.56-.8.56-1.28 0-.51-.19-.92-.56-1.24-.32-.35-.7-.56-1.12-.62-.43-.07-.83.07-1.2.42l-1 1c-.22.19-.45.28-.72.28-.26 0-.5-.09-.68-.28-.46-.45-.46-.92 0-1.4l1-1c.72-.72 1.56-1.06 2.54-1.02.97.04 1.83.45 2.58 1.22"
1639
- />
1640
- </svg>
1611
+ <div class="o-icon">
1612
+ <i class="fa fa-link"/>
1613
+ </div>
1641
1614
  </t>
1642
1615
  <t t-name="o-spreadsheet-Icon.INSERT_CHECKBOX">
1643
- <svg class="o-icon">
1644
- <path
1645
- fill="currentColor"
1646
- d="M.5 2A1.5 1.5 0 0 1 2 .5h14A1.5 1.5 0 0 1 17.5 2v14a1.5 1.5 0 0 1-1.5 1.5H2A1.5 1.5 0 0 1 .5 16V2H2v14h14V2H2m13 4-1.4-1.4L7 11.2 4.4 8.6 3 10l4 4z"
1647
- />
1648
- </svg>
1616
+ <div class="o-icon">
1617
+ <i class="fa fa-check-square-o"/>
1618
+ </div>
1649
1619
  </t>
1650
1620
  <t t-name="o-spreadsheet-Icon.INSERT_DROPDOWN">
1651
1621
  <svg class="o-icon">
@@ -1687,26 +1657,6 @@
1687
1657
  />
1688
1658
  </svg>
1689
1659
  </t>
1690
- <t t-name="o-spreadsheet-Icon.TRIANGLE_DOWN">
1691
- <svg class="o-icon" viewBox="0 0 18 18">
1692
- <polygon fill="currentColor" points="5 7 9 11 13 7"/>
1693
- </svg>
1694
- </t>
1695
- <t t-name="o-spreadsheet-Icon.TRIANGLE_UP">
1696
- <svg class="o-icon" transform="rotate(180)">
1697
- <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
1698
- </svg>
1699
- </t>
1700
- <t t-name="o-spreadsheet-Icon.TRIANGLE_RIGHT">
1701
- <svg class="o-icon" transform="rotate(-90)">
1702
- <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
1703
- </svg>
1704
- </t>
1705
- <t t-name="o-spreadsheet-Icon.TRIANGLE_LEFT">
1706
- <svg class="o-icon" transform="rotate(90)" viewBox="0 0 18 18">
1707
- <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
1708
- </svg>
1709
- </t>
1710
1660
  <t t-name="o-spreadsheet-Icon.BOLD">
1711
1661
  <svg class="o-icon">
1712
1662
  <path
@@ -1949,70 +1899,44 @@
1949
1899
  </t>
1950
1900
 
1951
1901
  <t t-name="o-spreadsheet-Icon.EDIT">
1952
- <svg class="o-icon" viewBox="0 0 576 512">
1953
- <path
1954
- fill="currentColor"
1955
- d="M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"
1956
- />
1957
- </svg>
1902
+ <div class="o-icon">
1903
+ <i class="fa fa-pencil-square-o"/>
1904
+ </div>
1958
1905
  </t>
1959
1906
  <t t-name="o-spreadsheet-Icon.UNLINK">
1960
- <svg class="o-icon" viewBox="0 0 512 512">
1961
- <path
1962
- fill="currentColor"
1963
- d="M304.083 405.907c4.686 4.686 4.686 12.284 0 16.971l-44.674 44.674c-59.263 59.262-155.693 59.266-214.961 0-59.264-59.265-59.264-155.696 0-214.96l44.675-44.675c4.686-4.686 12.284-4.686 16.971 0l39.598 39.598c4.686 4.686 4.686 12.284 0 16.971l-44.675 44.674c-28.072 28.073-28.072 73.75 0 101.823 28.072 28.072 73.75 28.073 101.824 0l44.674-44.674c4.686-4.686 12.284-4.686 16.971 0l39.597 39.598zm-56.568-260.216c4.686 4.686 12.284 4.686 16.971 0l44.674-44.674c28.072-28.075 73.75-28.073 101.824 0 28.072 28.073 28.072 73.75 0 101.823l-44.675 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.598 39.598c4.686 4.686 12.284 4.686 16.971 0l44.675-44.675c59.265-59.265 59.265-155.695 0-214.96-59.266-59.264-155.695-59.264-214.961 0l-44.674 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.597 39.598zm234.828 359.28l22.627-22.627c9.373-9.373 9.373-24.569 0-33.941L63.598 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 29.657c-9.373 9.373-9.373 24.569 0 33.941l441.373 441.373c9.373 9.372 24.569 9.372 33.941 0z"
1964
- />
1965
- </svg>
1907
+ <div class="o-icon">
1908
+ <i class="fa fa-chain-broken"/>
1909
+ </div>
1966
1910
  </t>
1967
- <!-- Font Awesome by Dave Gandy
1968
- http://fontawesome.io/
1969
- https://fontawesome.com/license -->
1970
1911
  <t t-name="o-spreadsheet-Icon.CARET_UP">
1971
- <svg class="caret-up" viewBox="0 0 320 512">
1972
- <path
1973
- fill="currentColor"
1974
- d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"
1975
- />
1976
- </svg>
1912
+ <div class="o-icon fa-small">
1913
+ <i class="fa fa-caret-up"/>
1914
+ </div>
1977
1915
  </t>
1978
1916
  <t t-name="o-spreadsheet-Icon.CARET_DOWN">
1979
- <svg class="caret-down" viewBox="0 0 320 512">
1980
- <path
1981
- fill="currentColor"
1982
- d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
1983
- />
1984
- </svg>
1917
+ <div class="o-icon fa-small">
1918
+ <i class="fa fa-caret-down"/>
1919
+ </div>
1985
1920
  </t>
1986
1921
  <t t-name="o-spreadsheet-Icon.CARET_RIGHT">
1987
- <svg class="o-icon caret-right" viewBox="0 0 192 512">
1988
- <path
1989
- d="M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"
1990
- />
1991
- </svg>
1922
+ <div class="o-icon fa-small">
1923
+ <i class="fa fa-caret-right"/>
1924
+ </div>
1992
1925
  </t>
1993
1926
  <t t-name="o-spreadsheet-Icon.CARET_LEFT">
1994
- <svg class="o-icon caret-left" viewBox="0 0 192 512">
1995
- <path
1996
- d="M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142z"
1997
- />
1998
- </svg>
1927
+ <div class="o-icon fa-small">
1928
+ <i class="fa fa-caret-left"/>
1929
+ </div>
1999
1930
  </t>
2000
-
2001
1931
  <t t-name="o-spreadsheet-Icon.TRASH">
2002
- <svg class="o-cf-icon trash" viewBox="0 0 448 512">
2003
- <path
2004
- fill="currentColor"
2005
- d="M432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM53.2 467a48 48 0 0 0 47.9 45h245.8a48 48 0 0 0 47.9-45L416 128H32z"
2006
- />
2007
- </svg>
1932
+ <div class="o-icon">
1933
+ <i class="fa fa-trash-o"/>
1934
+ </div>
2008
1935
  </t>
2009
1936
  <t t-name="o-spreadsheet-Icon.REFRESH">
2010
- <svg class="o-cf-icon refresh" viewBox="0 0 512 512">
2011
- <path
2012
- fill="currentColor"
2013
- d="M440.65 12.57l4 82.77A247.16 247.16 0 0 0 255.83 8C134.73 8 33.91 94.92 12.29 209.82A12 12 0 0 0 24.09 224h49.05a12 12 0 0 0 11.67-9.26 175.91 175.91 0 0 1 317-56.94l-101.46-4.86a12 12 0 0 0-12.57 12v47.41a12 12 0 0 0 12 12H500a12 12 0 0 0 12-12V12a12 12 0 0 0-12-12h-47.37a12 12 0 0 0-11.98 12.57zM255.83 432a175.61 175.61 0 0 1-146-77.8l101.8 4.87a12 12 0 0 0 12.57-12v-47.4a12 12 0 0 0-12-12H12a12 12 0 0 0-12 12V500a12 12 0 0 0 12 12h47.35a12 12 0 0 0 12-12.6l-4.15-82.57A247.17 247.17 0 0 0 255.83 504c121.11 0 221.93-86.92 243.55-201.82a12 12 0 0 0-11.8-14.18h-49.05a12 12 0 0 0-11.67 9.26A175.86 175.86 0 0 1 255.83 432z"
2014
- />
2015
- </svg>
1937
+ <div class="o-icon">
1938
+ <i class="fa fa-refresh"/>
1939
+ </div>
2016
1940
  </t>
2017
1941
 
2018
1942
  <t t-name="o-spreadsheet-Icon.ARROW_DOWN">
@@ -2115,25 +2039,19 @@ https://fontawesome.com/license -->
2115
2039
  </svg>
2116
2040
  </t>
2117
2041
  <t t-name="o-spreadsheet-Icon.SORT_ASCENDING">
2118
- <svg class="o-icon" fill="currentColor">
2119
- <path d="m3 13-1-1-1 1 3 3 3-3-1-1-1 1V0H3"/>
2120
- <text x="9" y="7" class="small-text">A</text>
2121
- <text x="9.3" y="15" class="small-text">Z</text>
2122
- </svg>
2042
+ <div class="o-icon">
2043
+ <i class="fa fa-sort-alpha-asc"/>
2044
+ </div>
2123
2045
  </t>
2124
2046
  <t t-name="o-spreadsheet-Icon.SORT_DESCENDING">
2125
- <svg class="o-icon" fill="currentColor">
2126
- <path d="m3 13.9-1-1-1 1 3 3 3-3-1-1-1 1V.9H3"/>
2127
- <text x="9.3" y="7.9" class="small-text">Z</text>
2128
- <text x="9" y="15.9" class="small-text">A</text>
2129
- </svg>
2047
+ <div class="o-icon">
2048
+ <i class="fa fa-sort-alpha-desc"/>
2049
+ </div>
2130
2050
  </t>
2131
2051
  <t t-name="o-spreadsheet-Icon.DATA_CLEANUP">
2132
- <svg class="o-icon" fill="currentColor">
2133
- <path
2134
- d="m13.6 6.4-2.1-2.1c-.4-.4-1-.4-1.4 0l-8.8 8.9c-.4.4-.4 1 0 1.4l2.1 2.1c.4.4 1 .4 1.4 0l8.8-8.9c.4-.4.4-1 0-1.4M8 8.5 10.5 6l1.4 1.4-2.5 2.5m3-7 1.8.8.8 1.8.8-1.8 1.8-.8-1.8-.8L14.9.4l-.8 1.8M3.5 4l1.7.7.8 1.8.8-1.8 1.8-.8-1.8-.8-.8-1.8-.8 1.8zm13.5 7.7-1.8-.8-.8-1.8-.8 1.8-1.8.8 1.8.8.8 1.8.7-1.8"
2135
- />
2136
- </svg>
2052
+ <div class="o-icon">
2053
+ <i class="fa fa-magic"/>
2054
+ </div>
2137
2055
  </t>
2138
2056
  <t t-name="o-spreadsheet-Icon.FILTER_ICON">
2139
2057
  <svg class="o-cf-icon filter-icon" viewBox="0 0 850 850">
@@ -2144,20 +2062,14 @@ https://fontawesome.com/license -->
2144
2062
  </svg>
2145
2063
  </t>
2146
2064
  <t t-name="o-spreadsheet-Icon.FILTER_ICON_ACTIVE">
2147
- <svg class="o-cf-icon filter-icon-active" viewBox="0 0 18 18">
2148
- <path
2149
- fill="currentColor"
2150
- d="M16.6.5H1.29C.59.5.23 1.35.73 1.85l6.1 6.1v6.8c0 .26.13.5.34.65l2.64 1.85a.79.79 0 0 0 1.25-.65V7.96l6.1-6.1A.79.79 0 0 0 16.6.51"
2151
- />
2152
- </svg>
2065
+ <div class="o-icon filter-icon-active">
2066
+ <i class="fa fa-filter"/>
2067
+ </div>
2153
2068
  </t>
2154
2069
  <t t-name="o-spreadsheet-Icon.SEARCH">
2155
- <svg class="search-icon" width="10" height="10" focusable="false" viewBox="0 0 512 512">
2156
- <path
2157
- fill="currentColor"
2158
- d="M500.3 443.7l-119.7-119.7c27.22-40.41 40.65-90.9 33.46-144.7C401.8 87.79 326.8 13.32 235.2 1.723C99.01-15.51-15.51 99.01 1.724 235.2c11.6 91.64 86.08 166.7 177.6 178.9c53.8 7.189 104.3-6.236 144.7-33.46l119.7 119.7c15.62 15.62 40.95 15.62 56.57 0C515.9 484.7 515.9 459.3 500.3 443.7zM79.1 208c0-70.58 57.42-128 128-128s128 57.42 128 128c0 70.58-57.42 128-128 128S79.1 278.6 79.1 208z"
2159
- />
2160
- </svg>
2070
+ <div class="o-icon">
2071
+ <i class="fa fa-search"/>
2072
+ </div>
2161
2073
  </t>
2162
2074
  <t t-name="o-spreadsheet-Icon.CHECK">
2163
2075
  <svg class="o-icon" viewBox="0 0 24 24">
@@ -2190,12 +2102,9 @@ https://fontawesome.com/license -->
2190
2102
  </svg>
2191
2103
  </t>
2192
2104
  <t t-name="o-spreadsheet-Icon.TRIANGLE_EXCLAMATION">
2193
- <svg class="o-icon" viewBox="0 0 512 512">
2194
- <path
2195
- fill="currentColor"
2196
- d="M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480H40c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24V296c0 13.3 10.7 24 24 24s24-10.7 24-24V184c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"
2197
- />
2198
- </svg>
2105
+ <div class="o-icon fa-small">
2106
+ <i class="fa fa-exclamation-triangle"/>
2107
+ </div>
2199
2108
  </t>
2200
2109
  <t t-name="o-spreadsheet-Icon.SPLIT_TEXT">
2201
2110
  <svg class="o-icon">
@@ -2206,12 +2115,9 @@ https://fontawesome.com/license -->
2206
2115
  </svg>
2207
2116
  </t>
2208
2117
  <t t-name="o-spreadsheet-Icon.ERROR">
2209
- <svg class="error-icon" width="14" height="14" viewBox="0 0 512 512">
2210
- <path
2211
- fill="currentColor"
2212
- d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
2213
- />
2214
- </svg>
2118
+ <div class="o-icon">
2119
+ <i class="fa fa-exclamation-circle"/>
2120
+ </div>
2215
2121
  </t>
2216
2122
  <t t-name="o-spreadsheet-Icon.DISPLAY_HEADER">
2217
2123
  <svg class="o-icon" width="18" height="18">
@@ -2325,6 +2231,19 @@ https://fontawesome.com/license -->
2325
2231
  />
2326
2232
  </svg>
2327
2233
  </t>
2234
+ <t t-name="o-spreadsheet-Icon.PIVOT">
2235
+ <svg class="o-icon" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
2236
+ <path
2237
+ fill="currentColor"
2238
+ d="M17 2v14H1V6h4V2h12m-1 1H6v3h10M2 7v2h3V7m-3 3v2h3v-2m-3 3v2h3v-2m1-6v2h6V7m-6 3v2h6v-2m-6 3v2h6v-2m1-6v2h3V7m-3 3v2h3v-2m-3 3v2h3v-2"
2239
+ />
2240
+ </svg>
2241
+ </t>
2242
+ <t t-name="o-spreadsheet-Icon.UNUSED_PIVOT_WARNING">
2243
+ <div class="o-unused-pivot-icon text-warning" title="This pivot is not used">
2244
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_EXCLAMATION"/>
2245
+ </div>
2246
+ </t>
2328
2247
 
2329
2248
  <t t-name="o-spreadsheet-LinkDisplay">
2330
2249
  <div class="o-link-tool d-flex align-items-center">
@@ -2441,7 +2360,9 @@ https://fontawesome.com/license -->
2441
2360
  t-att-class="{'disabled': !isMenuEnabled, 'o-menu-item-active': isActive(menuItem)}"
2442
2361
  t-att-style="getColor(menuItem)">
2443
2362
  <div class="d-flex w-100">
2444
- <div t-if="childrenHaveIcon" class="o-menu-item-icon align-middle">
2363
+ <div
2364
+ t-if="childrenHaveIcon"
2365
+ class="o-menu-item-icon d-flex align-items-center flex-shrink-0">
2445
2366
  <t t-if="getIconName(menuItem)" t-call="{{getIconName(menuItem)}}"/>
2446
2367
  </div>
2447
2368
  <div class="o-menu-item-name align-middle text-truncate" t-esc="getName(menuItem)"/>
@@ -2455,7 +2376,7 @@ https://fontawesome.com/license -->
2455
2376
  <div
2456
2377
  t-if="isMenuRoot"
2457
2378
  class="o-menu-item-root align-middle ms-auto"
2458
- t-call="o-spreadsheet-Icon.TRIANGLE_RIGHT"
2379
+ t-call="o-spreadsheet-Icon.CARET_RIGHT"
2459
2380
  />
2460
2381
  <div
2461
2382
  t-elif="secondaryIcon"
@@ -2614,66 +2535,41 @@ https://fontawesome.com/license -->
2614
2535
  </div>
2615
2536
  </t>
2616
2537
 
2617
- <t t-name="o-spreadsheet-BarChartDesignPanel">
2618
- <div>
2619
- <ChartColor
2620
- currentColor="props.definition.background"
2621
- onColorPicked.bind="updateBackgroundColor"
2622
- />
2623
- <ChartTitle title="title" update.bind="updateTitle"/>
2624
- <Section>
2625
- <t t-set-slot="title">Vertical axis position</t>
2626
- <select
2627
- t-att-value="props.definition.verticalAxisPosition"
2628
- class="o-input"
2629
- t-on-change="(ev) => this.updateSelect('verticalAxisPosition', ev)">
2630
- <option value="left">Left</option>
2631
- <option value="right">Right</option>
2632
- </select>
2633
- </Section>
2634
- <Section>
2635
- <t t-set-slot="title">Legend position</t>
2636
- <select
2637
- t-att-value="props.definition.legendPosition"
2638
- class="o-input"
2639
- t-on-change="(ev) => this.updateSelect('legendPosition', ev)">
2640
- <option value="none">None</option>
2641
- <option value="top">Top</option>
2642
- <option value="bottom">Bottom</option>
2643
- <option value="left">Left</option>
2644
- <option value="right">Right</option>
2645
- </select>
2646
- </Section>
2647
- </div>
2648
- </t>
2649
-
2650
- <t t-name="o-spreadsheet.ChartColor">
2651
- <Section class="'o-chart-background-color'">
2652
- <t t-set-slot="title">Background color</t>
2653
- <div class="d-flex align-items-center">
2654
- <span class="pe-1">Select a color...</span>
2655
- <t t-set="background_color">Background color</t>
2656
- <ColorPickerWidget
2657
- currentColor="props.currentColor"
2658
- showColorPicker="state.pickerOpened"
2659
- toggleColorPicker.bind="togglePicker"
2660
- onColorPicked="props.onColorPicked"
2661
- title="background_color"
2662
- icon="'o-spreadsheet-Icon.FILL_COLOR'"
2663
- />
2664
- </div>
2538
+ <t t-name="o-spreadsheet-AxisDesignEditor">
2539
+ <t t-set="editor_label">Axis Title</t>
2540
+ <Section class="'py-0'">
2541
+ <select class="o-input o-axis-selector" t-on-change="this.updateAxisEditor">
2542
+ <t t-foreach="props.axesList" t-as="axis" t-key="axis.id">
2543
+ <option
2544
+ t-att-value="axis.id"
2545
+ t-att-selected="state.currentAxis === axis.id"
2546
+ t-esc="axis.name"
2547
+ />
2548
+ </t>
2549
+ </select>
2665
2550
  </Section>
2551
+ <ChartTitle
2552
+ title="this.getAxisTitle()"
2553
+ updateTitle.bind="updateAxisTitle"
2554
+ name="editor_label"
2555
+ toggleItalic.bind="toggleItalicAxisTitle"
2556
+ toggleBold.bind="toggleBoldAxisTitle"
2557
+ updateAlignment.bind="updateAxisTitleAlignment"
2558
+ updateColor.bind="updateAxisTitleColor"
2559
+ style="axisTitleStyle"
2560
+ />
2666
2561
  </t>
2667
2562
 
2668
2563
  <t t-name="o-spreadsheet.ChartDataSeries">
2669
2564
  <Section class="'o-data-series'">
2670
2565
  <t t-set-slot="title" t-esc="title"/>
2671
2566
  <SelectionInput
2672
- ranges="props.ranges"
2567
+ ranges="ranges"
2673
2568
  required="true"
2674
2569
  hasSingleRange="props.hasSingleRange"
2675
2570
  onSelectionChanged="(ranges) => props.onSelectionChanged(ranges)"
2676
2571
  onSelectionConfirmed="() => props.onSelectionConfirmed()"
2572
+ colors="colors"
2677
2573
  />
2678
2574
  </Section>
2679
2575
  </t>
@@ -2684,6 +2580,62 @@ https://fontawesome.com/license -->
2684
2580
  </Section>
2685
2581
  </t>
2686
2582
 
2583
+ <t t-name="o-spreadsheet-GeneralDesignEditor">
2584
+ <t t-set="chart_title">Chart Title</t>
2585
+ <SidePanelCollapsible collapsedAtInit="false">
2586
+ <t t-set-slot="title">General</t>
2587
+ <t t-set-slot="content">
2588
+ <Section class="'o-chart-background-color pt-0 pb-0'">
2589
+ <div class="d-flex align-items-center mt-0">
2590
+ <span class="o-section-title mb-0 pe-2">Background Color</span>
2591
+ <RoundColorPicker
2592
+ currentColor="props.definition.background"
2593
+ onColorPicked.bind="updateBackgroundColor"
2594
+ />
2595
+ </div>
2596
+ </Section>
2597
+ <ChartTitle
2598
+ title="title.text"
2599
+ updateTitle.bind="updateTitle"
2600
+ name="chart_title"
2601
+ toggleItalic.bind="toggleItalicChartTitle"
2602
+ toggleBold.bind="toggleBoldChartTitle"
2603
+ updateAlignment.bind="updateChartTitleAlignment"
2604
+ updateColor.bind="updateChartTitleColor"
2605
+ style="titleStyle"
2606
+ />
2607
+ <t t-slot="general-extension"/>
2608
+ </t>
2609
+ </SidePanelCollapsible>
2610
+ </t>
2611
+
2612
+ <t t-name="o-spreadsheet-GenericChartConfigPanel">
2613
+ <div>
2614
+ <ChartDataSeries
2615
+ ranges="this.getDataSeriesRanges()"
2616
+ onSelectionChanged="(ranges) => this.onDataSeriesRangesChanged(ranges)"
2617
+ onSelectionConfirmed="() => this.onDataSeriesConfirmed()"
2618
+ />
2619
+ <ChartLabelRange
2620
+ range="this.getLabelRange()"
2621
+ isInvalid="isLabelInvalid"
2622
+ onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
2623
+ onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
2624
+ options="this.getLabelRangeOptions()"
2625
+ />
2626
+ <Section class="'o-use-row-as-headers'" t-if="calculateHeaderPosition()">
2627
+ <Checkbox
2628
+ name="'dataSetsHaveTitle'"
2629
+ label="dataSetsHaveTitleLabel"
2630
+ value="props.definition.dataSetsHaveTitle"
2631
+ onChange.bind="onUpdateDataSetsHaveTitle"
2632
+ />
2633
+ </Section>
2634
+
2635
+ <ChartErrorSection t-if="errorMessages.length" messages="errorMessages"/>
2636
+ </div>
2637
+ </t>
2638
+
2687
2639
  <t t-name="o-spreadsheet.ChartLabelRange">
2688
2640
  <Section class="'o-data-labels'">
2689
2641
  <t t-set-slot="title" t-esc="props.title"/>
@@ -2707,9 +2659,12 @@ https://fontawesome.com/license -->
2707
2659
  </t>
2708
2660
 
2709
2661
  <t t-name="o-spreadsheet.ChartTitle">
2710
- <t t-set="placeholder">New Chart</t>
2711
- <Section class="'o-chart-title'">
2712
- <t t-set-slot="title">Title</t>
2662
+ <t t-set="placeholder">Add a title</t>
2663
+ <Section class="'o-chart-title pb-0'">
2664
+ <t t-set-slot="title">
2665
+ <t t-if="props.name" t-esc="props.name"/>
2666
+ <t t-else="">Title</t>
2667
+ </t>
2713
2668
  <input
2714
2669
  type="text"
2715
2670
  class="o-input o-optional"
@@ -2717,17 +2672,200 @@ https://fontawesome.com/license -->
2717
2672
  t-on-change="updateTitle"
2718
2673
  t-att-placeholder="placeholder"
2719
2674
  />
2675
+ <Section class="'pt-0 px-0'">
2676
+ <div class="o-chart-title-designer position-relative d-flex align-items-center">
2677
+ <span
2678
+ class="o-menu-item-button o-hoverable-button"
2679
+ title="Bold"
2680
+ t-att-class="{active: props.style.bold}"
2681
+ t-on-click="(ev) => this.props.toggleBold()">
2682
+ <span>
2683
+ <t t-call="o-spreadsheet-Icon.BOLD"/>
2684
+ </span>
2685
+ </span>
2686
+ <span
2687
+ class="o-menu-item-button o-hoverable-button"
2688
+ title="Italic"
2689
+ t-att-class="{active: props.style.italic}"
2690
+ t-on-click="(ev) => this.props.toggleItalic()">
2691
+ <span>
2692
+ <t t-call="o-spreadsheet-Icon.ITALIC"/>
2693
+ </span>
2694
+ </span>
2695
+ <span
2696
+ class="o-menu-item-button o-hoverable-button"
2697
+ title="Horizontal alignment"
2698
+ t-on-click="(ev) => this.toggleDropdownTool('horizontalChartAlignTool', ev)">
2699
+ <span>
2700
+ <t t-if="props.style.align === 'center'" t-call="o-spreadsheet-Icon.ALIGN_CENTER"/>
2701
+ <t t-elif="props.style.align === 'right'" t-call="o-spreadsheet-Icon.ALIGN_RIGHT"/>
2702
+ <t t-else="" t-call="o-spreadsheet-Icon.ALIGN_LEFT"/>
2703
+ </span>
2704
+ <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
2705
+ </span>
2706
+ <div
2707
+ class="o-dropdown-content position-absolute top-100 start-0 bg-white"
2708
+ t-if="state.activeTool === 'horizontalChartAlignTool'"
2709
+ t-on-click.stop="">
2710
+ <div class="o-dropdown-line d-flex">
2711
+ <span
2712
+ class="o-menu-item-button o-hoverable-button"
2713
+ t-att-class="{active: props.style.align === 'left'}"
2714
+ title="Left"
2715
+ t-on-click="(ev) => this.updateAlignment('left')">
2716
+ <span>
2717
+ <t t-call="o-spreadsheet-Icon.ALIGN_LEFT"/>
2718
+ </span>
2719
+ </span>
2720
+ <span
2721
+ class="o-menu-item-button o-hoverable-button"
2722
+ t-att-class="{active: props.style.align === 'center'}"
2723
+ title="Center"
2724
+ t-on-click="(ev) => this.updateAlignment('center')">
2725
+ <span>
2726
+ <t t-call="o-spreadsheet-Icon.ALIGN_CENTER"/>
2727
+ </span>
2728
+ </span>
2729
+ <span
2730
+ class="o-menu-item-button o-hoverable-button"
2731
+ t-att-class="{active: props.style.align === 'right'}"
2732
+ title="Right"
2733
+ t-on-click="(ev) => this.updateAlignment('right')">
2734
+ <span>
2735
+ <t t-call="o-spreadsheet-Icon.ALIGN_RIGHT"/>
2736
+ </span>
2737
+ </span>
2738
+ </div>
2739
+ </div>
2740
+ <ColorPickerWidget
2741
+ currentColor="props.style.color"
2742
+ toggleColorPicker="(ev) => this.toggleDropdownTool('fillChartColorTool', ev)"
2743
+ showColorPicker="state.activeTool === 'fillChartColorTool'"
2744
+ onColorPicked.bind="onColorPicked"
2745
+ title="fill_color"
2746
+ icon="'o-spreadsheet-Icon.TEXT_COLOR'"
2747
+ class="'o-hoverable-button o-menu-item-button'"
2748
+ />
2749
+ </div>
2750
+ </Section>
2720
2751
  </Section>
2721
2752
  </t>
2722
2753
 
2723
- <t t-name="o-spreadsheet-GaugeChartConfigPanel">
2724
- <div>
2725
- <ChartDataSeries
2726
- ranges="[this.getDataRange()]"
2727
- onSelectionChanged="(ranges) => this.onDataRangeChanged(ranges)"
2728
- onSelectionConfirmed="() => this.updateDataRange()"
2729
- hasSingleRange="true"
2730
- />
2754
+ <t t-name="o-spreadsheet-ChartWithAxisDesignPanel">
2755
+ <GeneralDesignEditor
2756
+ figureId="props.figureId"
2757
+ definition="props.definition"
2758
+ updateChart="props.updateChart">
2759
+ <t t-set-slot="general-extension">
2760
+ <Section class="'pt-0'">
2761
+ <t t-set-slot="title">Legend position</t>
2762
+ <select
2763
+ t-att-value="props.definition.legendPosition ?? 'top'"
2764
+ class="o-input"
2765
+ t-on-change="this.updateLegendPosition">
2766
+ <option value="none">None</option>
2767
+ <option value="top">Top</option>
2768
+ <option value="bottom">Bottom</option>
2769
+ <option value="left">Left</option>
2770
+ <option value="right">Right</option>
2771
+ </select>
2772
+ </Section>
2773
+ </t>
2774
+ </GeneralDesignEditor>
2775
+ <SidePanelCollapsible collapsedAtInit="true">
2776
+ <t t-set-slot="title">Data Series</t>
2777
+ <t t-set-slot="content">
2778
+ <Section class="'pt-0 pb-0'">
2779
+ <select
2780
+ class="o-input data-series-selector"
2781
+ t-model="state.label"
2782
+ t-on-change="(ev) => this.updateSerieEditor(ev)">
2783
+ <t t-foreach="getDataSeries()" t-as="serie" t-key="serie" t-index="index">
2784
+ <option
2785
+ t-att-value="serie"
2786
+ t-att-selected="state.index === serie_index"
2787
+ t-esc="serie"
2788
+ />
2789
+ </t>
2790
+ </select>
2791
+ <Section class="'px-0'">
2792
+ <div class="d-flex align-items-center">
2793
+ <span class="o-section-title mb-0 pe-2">Serie Color</span>
2794
+ <RoundColorPicker
2795
+ currentColor="getDataSerieColor()"
2796
+ onColorPicked.bind="updateDataSeriesColor"
2797
+ />
2798
+ </div>
2799
+ </Section>
2800
+ <Section class="'pt-0 px-0'">
2801
+ <t t-set-slot="title">Vertical axis</t>
2802
+ <select
2803
+ t-att-value="getDataSerieAxis()"
2804
+ class="o-input o-vertical-axis-selection"
2805
+ t-on-change="(ev) => this.updateDataSeriesAxis(ev)">
2806
+ <option value="left">Left</option>
2807
+ <option value="right">Right</option>
2808
+ </select>
2809
+ </Section>
2810
+ <Section class="'pt-0 px-0'">
2811
+ <t t-set-slot="title">Serie name</t>
2812
+ <input
2813
+ class="o-input o-serie-label-editor"
2814
+ t-att-value="getDataSerieLabel()"
2815
+ t-on-change="(ev) => this.updateDataSeriesLabel(ev)"
2816
+ />
2817
+ </Section>
2818
+ </Section>
2819
+ </t>
2820
+ </SidePanelCollapsible>
2821
+ <SidePanelCollapsible collapsedAtInit="true">
2822
+ <t t-set-slot="title">Axis</t>
2823
+ <t t-set-slot="content">
2824
+ <AxisDesignEditor
2825
+ axesList="axesList"
2826
+ figureId="props.figureId"
2827
+ definition="props.definition"
2828
+ updateChart="props.updateChart"
2829
+ />
2830
+ </t>
2831
+ </SidePanelCollapsible>
2832
+ </t>
2833
+
2834
+ <t t-name="o-spreadsheet-ComboChartConfigPanel">
2835
+ <div>
2836
+ <ChartDataSeries
2837
+ ranges="this.getDataSeriesRanges()"
2838
+ onSelectionChanged="(ranges) => this.onDataSeriesRangesChanged(ranges)"
2839
+ onSelectionConfirmed="() => this.onDataSeriesConfirmed()"
2840
+ />
2841
+ <ChartLabelRange
2842
+ range="this.getLabelRange()"
2843
+ isInvalid="isLabelInvalid"
2844
+ onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
2845
+ onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
2846
+ options="this.getLabelRangeOptions()"
2847
+ />
2848
+ <Section class="'o-use-row-as-headers py-0'" t-if="calculateHeaderPosition()">
2849
+ <Checkbox
2850
+ name="'dataSetsHaveTitle'"
2851
+ label="dataSetsHaveTitleLabel"
2852
+ value="props.definition.dataSetsHaveTitle"
2853
+ onChange.bind="onUpdateDataSetsHaveTitle"
2854
+ />
2855
+ </Section>
2856
+
2857
+ <ChartErrorSection t-if="errorMessages.length" messages="errorMessages"/>
2858
+ </div>
2859
+ </t>
2860
+
2861
+ <t t-name="o-spreadsheet-GaugeChartConfigPanel">
2862
+ <div>
2863
+ <ChartDataSeries
2864
+ ranges="[this.getDataRange()]"
2865
+ onSelectionChanged="(ranges) => this.onDataRangeChanged(ranges)"
2866
+ onSelectionConfirmed="() => this.updateDataRange()"
2867
+ hasSingleRange="true"
2868
+ />
2731
2869
 
2732
2870
  <ChartErrorSection
2733
2871
  t-if="configurationErrorMessages.length"
@@ -2737,45 +2875,48 @@ https://fontawesome.com/license -->
2737
2875
  </t>
2738
2876
 
2739
2877
  <t t-name="o-spreadsheet-GaugeChartDesignPanel">
2740
- <div>
2741
- <ChartColor
2742
- currentColor="props.definition.background"
2743
- onColorPicked.bind="updateBackgroundColor"
2744
- />
2745
- <ChartTitle title="title" update.bind="updateTitle"/>
2746
- <Section>
2747
- <t t-set-slot="title">Range</t>
2748
- <div class="o-subsection-left">
2749
- <input
2750
- type="text"
2751
- t-model="state.sectionRule.rangeMin"
2752
- t-on-change="() => this.updateSectionRule(state.sectionRule)"
2753
- t-on-input="() => this.canUpdateSectionRule(state.sectionRule)"
2754
- class="o-input o-data-range-min"
2755
- t-att-class="{ 'o-invalid': isRangeMinInvalid() }"
2756
- />
2757
- </div>
2758
- <div class="o-subsection-right">
2759
- <input
2760
- type="text"
2761
- t-model="state.sectionRule.rangeMax"
2762
- t-on-change="() => this.updateSectionRule(state.sectionRule)"
2763
- t-on-input="() => this.canUpdateSectionRule(state.sectionRule)"
2764
- class="o-input o-data-range-max"
2765
- t-att-class="{ 'o-invalid': isRangeMaxInvalid() }"
2766
- />
2767
- </div>
2768
- </Section>
2878
+ <GeneralDesignEditor
2879
+ figureId="props.figureId"
2880
+ definition="props.definition"
2881
+ updateChart="props.updateChart"
2882
+ />
2883
+ <SidePanelCollapsible collapsedAtInit="true">
2884
+ <t t-set-slot="title">Gauge Design</t>
2885
+ <t t-set-slot="content">
2886
+ <Section class="'pt-0'">
2887
+ <t t-set-slot="title">Range</t>
2888
+ <div class="o-subsection-left">
2889
+ <input
2890
+ type="text"
2891
+ t-model="state.sectionRule.rangeMin"
2892
+ t-on-change="() => this.updateSectionRule(state.sectionRule)"
2893
+ t-on-input="() => this.canUpdateSectionRule(state.sectionRule)"
2894
+ class="o-input o-data-range-min"
2895
+ t-att-class="{ 'o-invalid': isRangeMinInvalid() }"
2896
+ />
2897
+ </div>
2898
+ <div class="o-subsection-right">
2899
+ <input
2900
+ type="text"
2901
+ t-model="state.sectionRule.rangeMax"
2902
+ t-on-change="() => this.updateSectionRule(state.sectionRule)"
2903
+ t-on-input="() => this.canUpdateSectionRule(state.sectionRule)"
2904
+ class="o-input o-data-range-max"
2905
+ t-att-class="{ 'o-invalid': isRangeMaxInvalid() }"
2906
+ />
2907
+ </div>
2908
+ </Section>
2769
2909
 
2770
- <Section>
2771
- <t t-set-slot="title">Thresholds</t>
2772
- <t t-call="o-spreadsheet-GaugeChartColorSectionTemplate">
2773
- <t t-set="sectionRule" t-value="state.sectionRule"/>
2774
- </t>
2775
- </Section>
2910
+ <Section>
2911
+ <t t-set-slot="title">Thresholds</t>
2912
+ <t t-call="o-spreadsheet-GaugeChartColorSectionTemplate">
2913
+ <t t-set="sectionRule" t-value="state.sectionRule"/>
2914
+ </t>
2915
+ </Section>
2776
2916
 
2777
- <ChartErrorSection t-if="designErrorMessages.length" messages="designErrorMessages"/>
2778
- </div>
2917
+ <ChartErrorSection t-if="designErrorMessages.length" messages="designErrorMessages"/>
2918
+ </t>
2919
+ </SidePanelCollapsible>
2779
2920
  </t>
2780
2921
 
2781
2922
  <t t-name="o-spreadsheet-GaugeChartColorSectionTemplate">
@@ -2806,12 +2947,9 @@ https://fontawesome.com/license -->
2806
2947
 
2807
2948
  <tr>
2808
2949
  <td>
2809
- <ColorPickerWidget
2950
+ <RoundColorPicker
2810
2951
  currentColor="sectionRule.colors.upperColor"
2811
- toggleColorPicker="(ev) => this.toggleMenu('sectionColor-upperColor', ev)"
2812
- showColorPicker="state.openedMenu === 'sectionColor-upperColor'"
2813
2952
  onColorPicked="(color) => this.updateSectionColor('upperColor', color)"
2814
- icon="'o-spreadsheet-Icon.FILL_COLOR'"
2815
2953
  />
2816
2954
  </td>
2817
2955
  <td>Else</td>
@@ -2826,12 +2964,9 @@ https://fontawesome.com/license -->
2826
2964
  <t t-name="o-spreadsheet-GaugeChartColorSectionTemplateRow">
2827
2965
  <tr>
2828
2966
  <td>
2829
- <ColorPickerWidget
2967
+ <RoundColorPicker
2830
2968
  currentColor="sectionColor"
2831
- toggleColorPicker="(ev) => this.toggleMenu('sectionColor-'+sectionType, ev)"
2832
- showColorPicker="state.openedMenu === 'sectionColor-'+sectionType"
2833
2969
  onColorPicked="(color) => this.updateSectionColor(sectionType, color)"
2834
- icon="'o-spreadsheet-Icon.FILL_COLOR'"
2835
2970
  />
2836
2971
  </td>
2837
2972
  <td>When value is below</td>
@@ -2859,56 +2994,6 @@ https://fontawesome.com/license -->
2859
2994
  </tr>
2860
2995
  </t>
2861
2996
 
2862
- <t t-name="o-spreadsheet-LineBarPieConfigPanel">
2863
- <div>
2864
- <ChartDataSeries
2865
- ranges="this.getDataSeriesRanges()"
2866
- onSelectionChanged="(ranges) => this.onDataSeriesRangesChanged(ranges)"
2867
- onSelectionConfirmed="() => this.onDataSeriesConfirmed()"
2868
- />
2869
- <ChartLabelRange
2870
- range="this.getLabelRange()"
2871
- isInvalid="isLabelInvalid"
2872
- onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
2873
- onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
2874
- options="this.getLabelRangeOptions()"
2875
- />
2876
- <Section class="'o-use-row-as-headers'" t-if="calculateHeaderPosition()">
2877
- <Checkbox
2878
- name="'dataSetsHaveTitle'"
2879
- label="dataSetsHaveTitleLabel"
2880
- value="props.definition.dataSetsHaveTitle"
2881
- onChange.bind="onUpdateDataSetsHaveTitle"
2882
- />
2883
- </Section>
2884
-
2885
- <ChartErrorSection t-if="errorMessages.length" messages="errorMessages"/>
2886
- </div>
2887
- </t>
2888
-
2889
- <t t-name="o-spreadsheet-LineBarPieDesignPanel">
2890
- <div>
2891
- <ChartColor
2892
- currentColor="props.definition.background"
2893
- onColorPicked.bind="updateBackgroundColor"
2894
- />
2895
- <ChartTitle title="title" update.bind="updateTitle"/>
2896
- <Section>
2897
- <t t-set-slot="title">Legend position</t>
2898
- <select
2899
- t-att-value="props.definition.legendPosition"
2900
- class="o-input"
2901
- t-on-change="(ev) => this.updateSelect('legendPosition', ev)">
2902
- <option value="none">None</option>
2903
- <option value="top">Top</option>
2904
- <option value="bottom">Bottom</option>
2905
- <option value="left">Left</option>
2906
- <option value="right">Right</option>
2907
- </select>
2908
- </Section>
2909
- </div>
2910
- </t>
2911
-
2912
2997
  <t t-name="o-spreadsheet-LineConfigPanel">
2913
2998
  <div>
2914
2999
  <Section class="'pt-0'">
@@ -2950,39 +3035,6 @@ https://fontawesome.com/license -->
2950
3035
  </div>
2951
3036
  </t>
2952
3037
 
2953
- <t t-name="o-spreadsheet-LineChartDesignPanel">
2954
- <div>
2955
- <ChartColor
2956
- currentColor="props.definition.background"
2957
- onColorPicked.bind="updateBackgroundColor"
2958
- />
2959
- <ChartTitle title="title" update.bind="updateTitle"/>
2960
- <Section>
2961
- <t t-set-slot="title">Vertical axis position</t>
2962
- <select
2963
- t-att-value="props.definition.verticalAxisPosition"
2964
- class="o-input"
2965
- t-on-change="(ev) => this.updateSelect('verticalAxisPosition', ev)">
2966
- <option value="left">Left</option>
2967
- <option value="right">Right</option>
2968
- </select>
2969
- </Section>
2970
- <Section>
2971
- <t t-set-slot="title">Legend position</t>
2972
- <select
2973
- t-att-value="props.definition.legendPosition"
2974
- class="o-input"
2975
- t-on-change="(ev) => this.updateSelect('legendPosition', ev)">
2976
- <option value="none">None</option>
2977
- <option value="top">Top</option>
2978
- <option value="bottom">Bottom</option>
2979
- <option value="left">Left</option>
2980
- <option value="right">Right</option>
2981
- </select>
2982
- </Section>
2983
- </div>
2984
- </t>
2985
-
2986
3038
  <t t-name="o-spreadsheet-ChartPanel">
2987
3039
  <div class="o-chart" t-if="figureId">
2988
3040
  <div class="o-panel">
@@ -3042,6 +3094,29 @@ https://fontawesome.com/license -->
3042
3094
  </div>
3043
3095
  </t>
3044
3096
 
3097
+ <t t-name="o-spreadsheet-PieChartDesignPanel">
3098
+ <GeneralDesignEditor
3099
+ figureId="props.figureId"
3100
+ definition="props.definition"
3101
+ updateChart="props.updateChart">
3102
+ <t t-set-slot="general-extension">
3103
+ <Section class="'pt-0'">
3104
+ <t t-set-slot="title">Legend position</t>
3105
+ <select
3106
+ t-att-value="props.definition.legendPosition ?? 'top'"
3107
+ class="o-input"
3108
+ t-on-change="(ev) => this.updateLegendPosition(ev)">
3109
+ <option value="none">None</option>
3110
+ <option value="top">Top</option>
3111
+ <option value="bottom">Bottom</option>
3112
+ <option value="left">Left</option>
3113
+ <option value="right">Right</option>
3114
+ </select>
3115
+ </Section>
3116
+ </t>
3117
+ </GeneralDesignEditor>
3118
+ </t>
3119
+
3045
3120
  <t t-name="o-spreadsheet-ScatterConfigPanel">
3046
3121
  <div>
3047
3122
  <ChartDataSeries
@@ -3101,6 +3176,7 @@ https://fontawesome.com/license -->
3101
3176
  <option value="text">Absolute value</option>
3102
3177
  <option value="difference">Value change from key value</option>
3103
3178
  <option value="percentage">Percentage change from key value</option>
3179
+ <option value="progress">Progress bar</option>
3104
3180
  </select>
3105
3181
  </Section>
3106
3182
 
@@ -3111,54 +3187,160 @@ https://fontawesome.com/license -->
3111
3187
  <t t-name="o-spreadsheet-ScorecardChartDesignPanel">
3112
3188
  <t t-set="color_up">Color Up</t>
3113
3189
  <t t-set="color_down">Color Down</t>
3114
- <div>
3115
- <ChartColor
3116
- currentColor="props.definition.background"
3117
- onColorPicked="(color) => this.setColor(color, 'backgroundColor')"
3118
- />
3119
- <ChartTitle title="title" update.bind="updateTitle"/>
3120
- <Section>
3121
- <t t-set-slot="title">Baseline description</t>
3122
- <input
3123
- type="text"
3124
- t-att-value="translate(props.definition.baselineDescr)"
3125
- t-on-change="updateBaselineDescr"
3126
- class="o-input o-optional"
3127
- />
3128
- </Section>
3129
- </div>
3130
- <Section class="'o-chart-baseline-color'">
3131
- <t t-set-slot="title">Baseline color</t>
3132
- <div class="d-flex align-items-center">
3133
- <span class="pe-1">Color on value increase</span>
3134
- <ColorPickerWidget
3135
- currentColor="props.definition.baselineColorUp"
3136
- toggleColorPicker="() => this.toggleColorPicker('baselineColorUp')"
3137
- showColorPicker="state.openedColorPicker === 'baselineColorUp'"
3138
- onColorPicked="(color) => this.setColor(color, 'baselineColorUp')"
3139
- title="color_up"
3140
- icon="'o-spreadsheet-Icon.FILL_COLOR'"
3141
- />
3142
- </div>
3143
- <div class="d-flex align-items-center">
3144
- <span class="pe-1">Color on value decrease</span>
3145
- <ColorPickerWidget
3146
- currentColor="props.definition.baselineColorDown"
3147
- toggleColorPicker="() => this.toggleColorPicker('baselineColorDown')"
3148
- showColorPicker="state.openedColorPicker === 'baselineColorDown'"
3149
- onColorPicked="(color) => this.setColor(color, 'baselineColorDown')"
3150
- title="color_down"
3151
- icon="'o-spreadsheet-Icon.FILL_COLOR'"
3190
+ <GeneralDesignEditor
3191
+ figureId="props.figureId"
3192
+ definition="props.definition"
3193
+ updateChart="props.updateChart">
3194
+ <t t-set-slot="general-extension">
3195
+ <Section class="'pt-1'">
3196
+ <t t-set-slot="title">Number formatting</t>
3197
+ <Checkbox
3198
+ name="'humanizeNumbers'"
3199
+ label="humanizeNumbersLabel"
3200
+ value="props.definition.humanize"
3201
+ onChange.bind="updateHumanizeNumbers"
3202
+ />
3203
+ </Section>
3204
+ </t>
3205
+ </GeneralDesignEditor>
3206
+ <SidePanelCollapsible collapsedAtInit="true">
3207
+ <t t-set-slot="title">Baseline</t>
3208
+ <t t-set-slot="content">
3209
+ <Section>
3210
+ <t t-set-slot="title">Baseline description</t>
3211
+ <input
3212
+ type="text"
3213
+ t-att-value="translate(props.definition.baselineDescr)"
3214
+ t-on-change="updateBaselineDescr"
3215
+ class="o-input o-optional"
3216
+ />
3217
+ </Section>
3218
+ <Section class="'o-chart-baseline-color'">
3219
+ <t t-set-slot="title" t-esc="colorsSectionTitle"/>
3220
+ <div class="d-flex align-items-center mb-2">
3221
+ <RoundColorPicker
3222
+ currentColor="props.definition.baselineColorUp"
3223
+ onColorPicked="(color) => this.setColor(color, 'baselineColorUp')"
3224
+ title="color_up"
3225
+ />
3226
+ <span class="ps-2">Color on value increase</span>
3227
+ </div>
3228
+ <div class="d-flex align-items-center">
3229
+ <RoundColorPicker
3230
+ currentColor="props.definition.baselineColorDown"
3231
+ onColorPicked="(color) => this.setColor(color, 'baselineColorDown')"
3232
+ title="color_down"
3233
+ />
3234
+ <span class="ps-2">Color on value decrease</span>
3235
+ </div>
3236
+ </Section>
3237
+ </t>
3238
+ </SidePanelCollapsible>
3239
+ </t>
3240
+
3241
+ <t t-name="o-spreadsheet-WaterfallChartDesignPanel">
3242
+ <GeneralDesignEditor
3243
+ figureId="props.figureId"
3244
+ definition="props.definition"
3245
+ updateChart="props.updateChart">
3246
+ <t t-set-slot="general-extension">
3247
+ <Section>
3248
+ <t t-set-slot="title">Vertical axis position</t>
3249
+ <select
3250
+ t-att-value="props.definition.verticalAxisPosition"
3251
+ class="o-input o-chart-vertical-axis-position"
3252
+ t-on-change="(ev) => this.updateVerticalAxisPosition(ev)">
3253
+ <option value="left">Left</option>
3254
+ <option value="right">Right</option>
3255
+ </select>
3256
+ </Section>
3257
+ <Section>
3258
+ <t t-set-slot="title">Legend position</t>
3259
+ <select
3260
+ t-att-value="props.definition.legendPosition"
3261
+ class="o-input o-chart-legend-position"
3262
+ t-on-change="(ev) => this.updateLegendPosition(ev)">
3263
+ <option value="none">None</option>
3264
+ <option value="top">Top</option>
3265
+ <option value="bottom">Bottom</option>
3266
+ <option value="left">Left</option>
3267
+ <option value="right">Right</option>
3268
+ </select>
3269
+ </Section>
3270
+ </t>
3271
+ </GeneralDesignEditor>
3272
+ <SidePanelCollapsible collapsedAtInit="true">
3273
+ <t t-set-slot="title">Waterfall Design</t>
3274
+ <t t-set-slot="content">
3275
+ <Section class="'pt-0'">
3276
+ <t t-set-slot="title">Waterfall options</t>
3277
+ <t t-set="firstValueAsSubtotal">Use first value as subtotal</t>
3278
+ <Checkbox
3279
+ name="'firstValueAsSubtotal'"
3280
+ label="firstValueAsSubtotal"
3281
+ value="props.definition.firstValueAsSubtotal"
3282
+ onChange.bind="onUpdateFirstValueAsSubtotal"
3283
+ />
3284
+ <t t-set="showSubTotalsLabel">Show subtotals at the end of series</t>
3285
+ <Checkbox
3286
+ name="'showSubTotals'"
3287
+ label="showSubTotalsLabel"
3288
+ value="props.definition.showSubTotals"
3289
+ onChange.bind="onUpdateShowSubTotals"
3290
+ />
3291
+ <t t-set="showConnectorLinesLabel">Show connector lines</t>
3292
+ <Checkbox
3293
+ name="'showConnectorLines'"
3294
+ label="showConnectorLinesLabel"
3295
+ value="props.definition.showConnectorLines"
3296
+ onChange.bind="onUpdateShowConnectorLines"
3297
+ />
3298
+ </Section>
3299
+ <Section>
3300
+ <t t-set-slot="title">Waterfall colors</t>
3301
+ <div class="o-waterfall-positive-color d-flex align-items-center mb-1">
3302
+ <RoundColorPicker
3303
+ currentColor="positiveValuesColor"
3304
+ onColorPicked="(color) => this.updateColor('positiveValuesColor', color)"
3305
+ />
3306
+ <span class="ps-2">Color of positive values</span>
3307
+ </div>
3308
+ <div class="o-waterfall-negative-color d-flex align-items-center mb-1">
3309
+ <RoundColorPicker
3310
+ currentColor="negativeValuesColor"
3311
+ onColorPicked="(color) => this.updateColor('negativeValuesColor', color)"
3312
+ />
3313
+ <span class="ps-2">Color of negative values</span>
3314
+ </div>
3315
+ <div class="o-waterfall-subtotal-color d-flex align-items-center">
3316
+ <RoundColorPicker
3317
+ currentColor="subTotalValuesColor"
3318
+ onColorPicked="(color) => this.updateColor('subTotalValuesColor', color)"
3319
+ />
3320
+ <span class="ps-2">Color of subtotals</span>
3321
+ </div>
3322
+ </Section>
3323
+ </t>
3324
+ </SidePanelCollapsible>
3325
+ <SidePanelCollapsible collapsedAtInit="true">
3326
+ <t t-set-slot="title">Axis Title</t>
3327
+ <t t-set-slot="content">
3328
+ <AxisDesignEditor
3329
+ axesList="axesList"
3330
+ figureId="props.figureId"
3331
+ definition="props.definition"
3332
+ updateChart="props.updateChart"
3152
3333
  />
3153
- </div>
3154
- </Section>
3334
+ </t>
3335
+ </SidePanelCollapsible>
3155
3336
  </t>
3156
3337
 
3157
3338
  <t t-name="o-spreadsheet.Checkbox">
3158
3339
  <label
3159
3340
  class="o-checkbox"
3160
3341
  t-att-title="props.title"
3161
- t-att-class="{'text-muted': props.disabled }">
3342
+ t-att-class="{'text-muted': props.disabled }"
3343
+ t-attf-class="{{props.className}}">
3162
3344
  <input
3163
3345
  type="checkbox"
3164
3346
  t-att-disabled="props.disabled"
@@ -3171,6 +3353,43 @@ https://fontawesome.com/license -->
3171
3353
  </label>
3172
3354
  </t>
3173
3355
 
3356
+ <t t-name="o-spreadsheet-SidePanelCollapsible">
3357
+ <div class="p-1 m-1" t-att-class="props.class">
3358
+ <div class="o_side_panel_collapsible_title d-flex align-items-center">
3359
+ <span
3360
+ t-att-id="'btn-collapse-'+currentId"
3361
+ t-att-class="{ 'collapsed': props.collapsedAtInit }"
3362
+ class="collapsor w-100"
3363
+ data-bs-toggle="collapse"
3364
+ t-att-data-bs-target="'#box-collapse-'+currentId">
3365
+ <t t-slot="title"/>
3366
+ </span>
3367
+ </div>
3368
+ <div
3369
+ t-att-id="'box-collapse-'+currentId"
3370
+ t-att-class="{'show': !props.collapsedAtInit}"
3371
+ class="collapsible_section collapse">
3372
+ <t t-slot="content"/>
3373
+ </div>
3374
+ </div>
3375
+ </t>
3376
+
3377
+ <t t-name="o-spreadsheet.RoundColorPicker">
3378
+ <div
3379
+ class="o-round-color-picker-button rounded-circle"
3380
+ t-ref="colorPickerButton"
3381
+ t-on-click.stop="togglePicker"
3382
+ t-att-title="props.title"
3383
+ t-att-style="buttonStyle"
3384
+ />
3385
+ <ColorPicker
3386
+ t-if="state.pickerOpened"
3387
+ anchorRect="colorPickerAnchorRect"
3388
+ onColorPicked.bind="onColorPicked"
3389
+ currentColor="props.currentColor"
3390
+ />
3391
+ </t>
3392
+
3174
3393
  <t t-name="o_spreadsheet.Section">
3175
3394
  <div class="o-section" t-att-class="props.class">
3176
3395
  <t t-if="props.slots.title">
@@ -3405,19 +3624,22 @@ https://fontawesome.com/license -->
3405
3624
  type="text"
3406
3625
  class="o-input o-threshold-value o-required"
3407
3626
  t-model="rule[thresholdType].value"
3408
- t-att-class="{ 'o-invalid': isValueInvalid(thresholdType) }"
3627
+ t-att-class="{ 'o-invalid': isValueInvalid(thresholdType), 'invisible': threshold === undefined }"
3409
3628
  t-if="threshold !== undefined and threshold.type !== 'value'"
3410
3629
  />
3411
- <input type="text" class="o-input o-threshold-value" t-else="" disabled="1"/>
3412
- <ColorPickerWidget
3413
- currentColor="getThresholdColor(threshold)"
3414
- toggleColorPicker="(ev) => this.toggleMenu('colorScale-'+thresholdType+'Color', ev)"
3415
- showColorPicker="state.openedMenu === 'colorScale-'+thresholdType+'Color'"
3416
- onColorPicked="(color) => this.setColorScaleColor(thresholdType, color)"
3417
- title="fill_color"
3418
- icon="'o-spreadsheet-Icon.FILL_COLOR'"
3419
- disabled="threshold === undefined"
3630
+ <input
3631
+ type="text"
3632
+ t-attf-class="o-input o-threshold-value {{ threshold === undefined ? 'invisible' : ''}}"
3633
+ t-else=""
3634
+ disabled="1"
3420
3635
  />
3636
+ <div t-attf-class="flex-shrink-0 ms-1 {{ threshold === undefined ? 'invisible' : ''}}">
3637
+ <RoundColorPicker
3638
+ currentColor="getThresholdColor(threshold)"
3639
+ onColorPicked="(color) => this.setColorScaleColor(thresholdType, color)"
3640
+ title="fill_color"
3641
+ />
3642
+ </div>
3421
3643
  </div>
3422
3644
  </t>
3423
3645
 
@@ -4046,6 +4268,285 @@ https://fontawesome.com/license -->
4046
4268
  </div>
4047
4269
  </t>
4048
4270
 
4271
+ <t t-name="o-spreadsheet-EditableName">
4272
+ <t t-if="state.isEditing">
4273
+ <div>
4274
+ <input type="text" class="o_input o_sp_en_name" t-model="state.name"/>
4275
+ </div>
4276
+ <div class="btn btn-link o_sp_en_save" t-on-click="save">Save</div>
4277
+ <br/>
4278
+ </t>
4279
+ <t t-else="">
4280
+ <div class="o_sp_en_display_name" t-esc="props.displayName"/>
4281
+ <div class="btn btn-link o_sp_en_rename" t-on-click="rename">
4282
+ <i class="fa fa-pencil me-1"/>
4283
+ Rename
4284
+ </div>
4285
+ <br/>
4286
+ </t>
4287
+ </t>
4288
+
4289
+ <t t-name="o-spreadsheet-AddDimensionButton">
4290
+ <span class="btn btn-sm btn-link add-dimension" t-on-click="togglePopover" t-ref="button">
4291
+ Add
4292
+ </span>
4293
+ <Popover t-if="popover.isOpen" t-props="popoverProps">
4294
+ <div
4295
+ class="p-2 bg-white border-bottom d-flex sticky-top align-items-baseline pivot-dimension-search">
4296
+ <i class="pe-1 pivot-dimension-search-field-icon">
4297
+ <t t-call="o-spreadsheet-Icon.SEARCH"/>
4298
+ </i>
4299
+ <input
4300
+ t-on-input="(ev) => this.updateSearch(ev.target.value)"
4301
+ t-on-keydown="onKeyDown"
4302
+ class="border-0 w-100 pivot-dimension-search-field"
4303
+ t-ref="autofocus"
4304
+ />
4305
+ </div>
4306
+ <TextValueProvider
4307
+ proposals="autoComplete.provider.proposals"
4308
+ selectedIndex="autoComplete.selectedIndex"
4309
+ onValueSelected="autoComplete.provider.selectProposal"
4310
+ onValueHovered="() => {}"
4311
+ />
4312
+ </Popover>
4313
+ </t>
4314
+
4315
+ <t t-name="o-spreadsheet-PivotDimension">
4316
+ <div
4317
+ class="border py-1 px-2 d-flex flex-column shadow-sm pivot-dimension"
4318
+ t-att-class="{'bg-danger': !props.dimension.isValid}">
4319
+ <div class="d-flex flex-row justify-content-between align-items-center">
4320
+ <span class="fw-bold" t-esc="props.dimension.displayName"/>
4321
+ <i
4322
+ class="btn fa fa-times pe-0"
4323
+ t-if="props.onRemoved"
4324
+ t-on-click="() => props.onRemoved(props.dimension)"
4325
+ />
4326
+ </div>
4327
+ <t t-slot="default"/>
4328
+ </div>
4329
+ </t>
4330
+
4331
+ <t t-name="o-spreadsheet-PivotDimensionGranularity">
4332
+ <div class="d-flex flex-row">
4333
+ <div class="d-flex flex-row py-1 px-2 w-100 small">
4334
+ <t t-set="granularity" t-value="props.dimension.granularity"/>
4335
+ <div class="flex-basis-50">Granularity</div>
4336
+ <select
4337
+ class="o_input flex-basis-50"
4338
+ t-on-change="(ev) => props.onUpdated(props.dimension, ev.target.value)">
4339
+ <option
4340
+ t-foreach="props.allGranularities"
4341
+ t-as="granularity"
4342
+ t-key="granularity"
4343
+ t-if="props.availableGranularities.has(granularity) || granularity === props.dimension.granularity"
4344
+ t-att-value="granularity"
4345
+ t-esc="periods[granularity]"
4346
+ t-att-selected="granularity === props.dimension.granularity or (granularity === 'month' and !props.dimension.granularity)"
4347
+ />
4348
+ </select>
4349
+ </div>
4350
+ </div>
4351
+ </t>
4352
+
4353
+ <t t-name="o-spreadsheet-PivotDimensionOrder">
4354
+ <div class="d-flex">
4355
+ <div class="d-flex py-1 px-2 w-100 small">
4356
+ <div class="flex-basis-50">Order by</div>
4357
+ <select
4358
+ class="o_input flex-basis-50"
4359
+ t-on-change="(ev) => props.onUpdated(props.dimension, ev.target.value)">
4360
+ <option value="asc" t-att-selected="props.dimension.order === 'asc'">Ascending</option>
4361
+ <option value="desc" t-att-selected="props.dimension.order === 'desc'">Descending</option>
4362
+ <option
4363
+ t-if="props.dimension.type !== 'date'"
4364
+ value=""
4365
+ t-att-selected="props.dimension.order === undefined">
4366
+ Unsorted
4367
+ </option>
4368
+ </select>
4369
+ </div>
4370
+ </div>
4371
+ </t>
4372
+
4373
+ <t t-name="o-spreadsheet-PivotLayoutConfigurator">
4374
+ <div class="o_side_panel_section pivot-dimensions o-section" t-ref="pivot-dimensions">
4375
+ <div
4376
+ class="fw-bold py-1 d-flex flex-row justify-content-between align-items-center o-section-title">
4377
+ Columns
4378
+ <AddDimensionButton
4379
+ onFieldPicked.bind="addColumnDimension"
4380
+ fields="props.unusedGroupableFields"
4381
+ />
4382
+ </div>
4383
+ <t t-foreach="props.definition.columns" t-as="col" t-key="col.nameWithGranularity">
4384
+ <div
4385
+ t-on-pointerdown="(ev) => this.startDragAndDrop(col, ev)"
4386
+ t-att-style="dragAndDrop.itemsStyle[col.nameWithGranularity]"
4387
+ class="pt-1">
4388
+ <PivotDimension dimension="col" onRemoved.bind="removeDimension">
4389
+ <PivotDimensionGranularity
4390
+ t-if="isDateField(col)"
4391
+ dimension="col"
4392
+ onUpdated.bind="this.updateGranularity"
4393
+ availableGranularities="props.unusedDateTimeGranularities[col.name]"
4394
+ allGranularities="props.allGranularities"
4395
+ />
4396
+ <PivotDimensionOrder dimension="col" onUpdated.bind="this.updateOrder"/>
4397
+ </PivotDimension>
4398
+ </div>
4399
+ </t>
4400
+ <div
4401
+ class="fw-bold pt-4 pb-1 d-flex flex-row justify-content-between align-items-center o-section-title"
4402
+ t-att-style="dragAndDrop.itemsStyle['__rows_title__']">
4403
+ Rows
4404
+ <AddDimensionButton
4405
+ onFieldPicked.bind="addRowDimension"
4406
+ fields="props.unusedGroupableFields"
4407
+ />
4408
+ </div>
4409
+ <t t-foreach="props.definition.rows" t-as="row" t-key="row.nameWithGranularity">
4410
+ <div
4411
+ t-on-pointerdown="(ev) => this.startDragAndDrop(row, ev)"
4412
+ t-att-style="dragAndDrop.itemsStyle[row.nameWithGranularity]"
4413
+ class="pt-1">
4414
+ <PivotDimension dimension="row" onRemoved.bind="removeDimension">
4415
+ <PivotDimensionGranularity
4416
+ t-if="isDateField(row)"
4417
+ dimension="row"
4418
+ onUpdated.bind="this.updateGranularity"
4419
+ availableGranularities="props.unusedDateTimeGranularities[row.name]"
4420
+ allGranularities="props.allGranularities"
4421
+ />
4422
+ <PivotDimensionOrder dimension="row" onUpdated.bind="this.updateOrder"/>
4423
+ </PivotDimension>
4424
+ </div>
4425
+ </t>
4426
+ <div
4427
+ class="fw-bold pt-4 pb-1 d-flex flex-row justify-content-between align-items-center o-section-title">
4428
+ Measures
4429
+ <AddDimensionButton
4430
+ onFieldPicked.bind="addMeasureDimension"
4431
+ fields="props.unusedMeasureFields"
4432
+ />
4433
+ </div>
4434
+ <t t-foreach="props.definition.measures" t-as="measure" t-key="measure.nameWithAggregator">
4435
+ <div
4436
+ t-on-pointerdown="(ev) => this.startDragAndDropMeasures(measure, ev)"
4437
+ t-att-style="dragAndDrop.itemsStyle[measure.name]"
4438
+ class="pt-1 pivot-measure">
4439
+ <PivotDimension dimension="measure" onRemoved.bind="removeMeasureDimension">
4440
+ <div class="d-flex flex-row small">
4441
+ <div class="d-flex flex-row py-1 px-2 w-100">
4442
+ <div class="flex-basis-50">Aggregated by</div>
4443
+ <select
4444
+ class="o_input flex-basis-50"
4445
+ t-on-change="(ev) => this.updateAggregator(measure, ev.target.value)">
4446
+ <option
4447
+ t-foreach="Object.keys(AGGREGATORS[measure.type])"
4448
+ t-as="agg"
4449
+ t-key="agg"
4450
+ t-att-value="agg"
4451
+ t-att-selected="agg === measure.aggregator"
4452
+ t-esc="AGGREGATORS[measure.type][agg]"
4453
+ />
4454
+ </select>
4455
+ </div>
4456
+ </div>
4457
+ </PivotDimension>
4458
+ </div>
4459
+ </t>
4460
+ </div>
4461
+ </t>
4462
+
4463
+ <t t-name="o-spreadsheet-PivotListItem">
4464
+ <div
4465
+ class="o_pivot_list_item p-4 border-bottom"
4466
+ t-ref="pivotListItem"
4467
+ t-on-click="this.selectPivot">
4468
+ <span t-esc="env.model.getters.getPivotDisplayName(props.pivotId)"/>
4469
+ </div>
4470
+ </t>
4471
+
4472
+ <t t-name="o-spreadsheet-PivotSidePanel">
4473
+ <t t-if="props.pivotId" t-component="sidePanelEditor" t-props="props"/>
4474
+ <t t-else="">
4475
+ <t t-foreach="env.model.getters.getPivotIds()" t-as="pivotId" t-key="pivotId">
4476
+ <PivotListItem pivotId="pivotId"/>
4477
+ </t>
4478
+ </t>
4479
+ </t>
4480
+
4481
+ <t t-name="o-spreadsheet-PivotSpreadsheetSidePanel">
4482
+ <div class="d-flex flex-column h-100 justify-content-between overflow-hidden">
4483
+ <div class="h-100 overflow-auto">
4484
+ <Section>
4485
+ <t t-set-slot="title">Name</t>
4486
+ <EditableName name="name" displayName="displayName" onChanged.bind="onNameChanged"/>
4487
+ <div class="btn btn-link o_duplicate_pivot" t-on-click="duplicatePivot">
4488
+ <i class="fa fa-solid fa-copy me-1"/>
4489
+ Duplicate Pivot
4490
+ </div>
4491
+ </Section>
4492
+ <Section>
4493
+ <t t-set-slot="title">Range</t>
4494
+ <SelectionInput
4495
+ ranges="ranges"
4496
+ required="true"
4497
+ isInvalid="shouldDisplayInvalidRangeError"
4498
+ hasSingleRange="true"
4499
+ onSelectionChanged="(ranges) => this.onSelectionChanged(ranges)"
4500
+ onSelectionConfirmed="() => this.onSelectionConfirmed()"
4501
+ />
4502
+ <span
4503
+ class="text-danger sp_range_error_message"
4504
+ t-if="shouldDisplayInvalidRangeError"
4505
+ t-esc="pivot.invalidRangeMessage"
4506
+ />
4507
+ </Section>
4508
+
4509
+ <PivotLayoutConfigurator
4510
+ t-if="!pivot.isInvalidRange"
4511
+ unusedGroupableFields="store.unusedGroupableFields"
4512
+ unusedMeasureFields="store.unusedMeasureFields"
4513
+ unusedDateTimeGranularities="store.unusedDateTimeGranularities"
4514
+ allGranularities="store.allGranularities"
4515
+ definition="definition"
4516
+ onDimensionsUpdated.bind="onDimensionsUpdated"
4517
+ />
4518
+ <Section>
4519
+ <button class="btn btn-link sp_back" t-on-click="back">Back</button>
4520
+ <button class="btn btn-link sp_delete" t-on-click="delete">Delete</button>
4521
+ </Section>
4522
+ </div>
4523
+ <Section
4524
+ class="'align-items-center border-top d-flex flex-row justify-content-between py-1 pivot-defer-update'">
4525
+ <Checkbox
4526
+ label="deferUpdatesLabel"
4527
+ title="deferUpdatesTooltip"
4528
+ value="store.updatesAreDeferred"
4529
+ onChange="(value) => store.deferUpdates(value)"
4530
+ />
4531
+ <div>
4532
+ <i
4533
+ t-if="store.isDirty"
4534
+ class="btn btn-sm pe-0 fa fa-undo"
4535
+ title="Discard all changes"
4536
+ t-on-click="() => store.discardPendingUpdate()"
4537
+ />
4538
+ <span
4539
+ t-if="store.isDirty"
4540
+ class="btn btm-sm btn-link sp_apply_update"
4541
+ title="Apply all changes"
4542
+ t-on-click="() => store.applyUpdate()">
4543
+ Update
4544
+ </span>
4545
+ </div>
4546
+ </Section>
4547
+ </div>
4548
+ </t>
4549
+
4049
4550
  <t t-name="o-spreadsheet-RemoveDuplicatesPanel">
4050
4551
  <div class="o-remove-duplicates">
4051
4552
  <Section>
@@ -4315,6 +4816,48 @@ https://fontawesome.com/license -->
4315
4816
  </div>
4316
4817
  </t>
4317
4818
 
4819
+ <t t-name="o-spreadsheet-TableStyleEditorPanel">
4820
+ <div class="o-table-style-editor-panel">
4821
+ <Section>
4822
+ <t t-set-slot="title">Style name</t>
4823
+ <input type="text" class="o-input o-optional" t-model="state.styleName"/>
4824
+ </Section>
4825
+ <Section class="'pt-1'">
4826
+ <t t-set-slot="title">Style color</t>
4827
+ <div class="d-flex align-items-center">
4828
+ <span class="pe-2">Primary table style color</span>
4829
+ <RoundColorPicker currentColor="state.primaryColor" onColorPicked.bind="onColorPicked"/>
4830
+ </div>
4831
+ </Section>
4832
+ <Section class="'pt-1'">
4833
+ <t t-set-slot="title">Style template</t>
4834
+ <div class="d-flex flex-wrap">
4835
+ <t t-foreach="tableTemplates" t-as="templateName" t-key="templateName">
4836
+ <TableStylePreview
4837
+ class="'o-table-style-edit-template-preview'"
4838
+ selected="templateName === state.selectedTemplateName"
4839
+ tableConfig="previewTableConfig"
4840
+ tableStyle="computeTableStyle(templateName)"
4841
+ onClick="() => this.onTemplatePicked(templateName)"
4842
+ />
4843
+ </t>
4844
+ </div>
4845
+ <div class="o-sidePanelButtons">
4846
+ <button
4847
+ t-if="props.styleId"
4848
+ t-on-click="onDelete"
4849
+ class="o-delete o-button o-button-grey danger">
4850
+ Delete
4851
+ </button>
4852
+ <button t-on-click="onCancel" class="o-cancel o-button o-button-grey">Cancel</button>
4853
+ <button t-on-click="onConfirm" class="o-confirm o-button o-button-grey primary">
4854
+ Confirm
4855
+ </button>
4856
+ </div>
4857
+ </Section>
4858
+ </div>
4859
+ </t>
4860
+
4318
4861
  <t t-name="o-spreadsheet-Spreadsheet">
4319
4862
  <div
4320
4863
  class="o-spreadsheet"
@@ -4365,26 +4908,32 @@ https://fontawesome.com/license -->
4365
4908
  />
4366
4909
  </t>
4367
4910
 
4911
+ <t t-name="o-spreadsheet-TableResizer">
4912
+ <div
4913
+ class="o-table-resizer position-absolute"
4914
+ t-att-style="containerStyle"
4915
+ t-on-pointerdown="onMouseDown"
4916
+ />
4917
+ </t>
4918
+
4368
4919
  <t t-name="o-spreadsheet-TableStylePicker">
4369
4920
  <div class="o-table-style-picker d-flex flew-row justify-content-between ps-1">
4370
4921
  <div class="d-flex flex-row overflow-hidden">
4371
- <div
4372
- class="o-table-style-list-item"
4373
- t-att-class="{ 'selected': styleId === props.table.config.styleId }"
4374
- t-foreach="getDisplayedTableStyles()"
4375
- t-as="styleId"
4376
- t-key="styleId"
4377
- t-att-title="getStyleName(styleId)"
4378
- t-on-click="() => this.onStylePicked(styleId)">
4379
- <div class="o-table-style-picker-preview">
4380
- <TableStylePreview tableConfig="getTableConfig(styleId)"/>
4381
- </div>
4382
- </div>
4922
+ <t t-foreach="getDisplayedTableStyles()" t-as="styleId" t-key="styleId">
4923
+ <TableStylePreview
4924
+ class="'o-table-style-picker-preview'"
4925
+ selected="styleId === props.table.config.styleId"
4926
+ tableConfig="props.table.config"
4927
+ tableStyle="env.model.getters.getTableStyle(styleId)"
4928
+ styleId="styleId"
4929
+ onClick="() => this.onStylePicked(styleId)"
4930
+ />
4931
+ </t>
4383
4932
  </div>
4384
4933
  <div
4385
4934
  class="o-table-style-picker-arrow d-flex align-items-center px-1"
4386
4935
  t-on-click.stop="onArrowButtonClick">
4387
- <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
4936
+ <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
4388
4937
  </div>
4389
4938
  </div>
4390
4939
  <TableStylesPopover
@@ -4397,31 +4946,77 @@ https://fontawesome.com/license -->
4397
4946
  </t>
4398
4947
 
4399
4948
  <t t-name="o-spreadsheet-TableStylePreview">
4400
- <canvas t-ref="canvas" class="w-100 h-100"/>
4949
+ <div
4950
+ class="o-table-style-list-item position-relative"
4951
+ t-att-class="{ 'selected': props.selected }"
4952
+ t-att-data-id="props.styleId"
4953
+ t-att-title="styleName"
4954
+ t-on-click="props.onClick"
4955
+ t-on-contextmenu.prevent="(ev) => this.onContextMenu(ev)">
4956
+ <div t-att-class="props.class">
4957
+ <canvas t-ref="canvas" class="w-100 h-100"/>
4958
+ </div>
4959
+ <div
4960
+ class="o-table-style-edit-button position-absolute d-none"
4961
+ t-if="isStyleEditable"
4962
+ t-on-click="this.editTableStyle"
4963
+ title="Edit custom table style">
4964
+ <t t-call="o-spreadsheet-Icon.EDIT"/>
4965
+ </div>
4966
+ </div>
4967
+ <Menu
4968
+ t-if="menu.isOpen"
4969
+ menuItems="menu.menuItems"
4970
+ position="menu.position"
4971
+ onClose.bind="this.closeMenu"
4972
+ />
4401
4973
  </t>
4402
4974
 
4403
4975
  <t t-name="o-spreadsheet-TableStylesPopover">
4404
4976
  <Popover t-if="props.popoverProps" t-props="props.popoverProps">
4405
- <div class="o-table-style-popover d-flex flex-column px-4 py-1" t-ref="tableStyleList">
4406
- <div t-foreach="categories" t-as="category" t-key="category">
4407
- <div class="mt-2 mb-1">
4408
- <b t-esc="category_value"/>
4977
+ <div
4978
+ class="o-table-style-popover d-flex flex-column px-4 py-3"
4979
+ t-ref="tableStyleList"
4980
+ t-on-contextmenu.prevent="">
4981
+ <div class="d-flex">
4982
+ <div
4983
+ t-foreach="Object.keys(categories)"
4984
+ t-as="category"
4985
+ t-key="category"
4986
+ class="form-check d-flex align-items-center">
4987
+ <input
4988
+ class="form-check-input me-1"
4989
+ type="radio"
4990
+ t-att-id="category_value"
4991
+ t-att-value="category_value"
4992
+ name="category"
4993
+ t-model="state.selectedCategory"
4994
+ />
4995
+ <label
4996
+ class="form-check-label pe-4"
4997
+ t-att-for="category_value"
4998
+ t-esc="categories[category_value]"
4999
+ />
4409
5000
  </div>
4410
- <div class="d-flex flex-wrap">
4411
- <div
4412
- class="o-table-style-list-item"
4413
- t-att-class="{ 'selected': styleId === props.selectedStyleId }"
4414
- t-foreach="getPresetsByCategory(category)"
4415
- t-as="styleId"
4416
- t-key="styleId"
4417
- t-att-title="getStyleName(styleId)"
4418
- t-on-click="() => this.props.onStylePicked(styleId)">
4419
- <div class="o-table-style-popover-preview">
4420
- <TableStylePreview tableConfig="getTableConfig(styleId)"/>
4421
- </div>
4422
- </div>
5001
+ </div>
5002
+ <hr class="hr my-2"/>
5003
+ <div class="d-flex flex-wrap">
5004
+ <t t-foreach="displayedStyles" t-as="styleId" t-key="styleId">
5005
+ <TableStylePreview
5006
+ class="'o-table-style-popover-preview'"
5007
+ styleId="styleId"
5008
+ selected="styleId === props.selectedStyleId"
5009
+ tableConfig="props.tableConfig"
5010
+ tableStyle="env.model.getters.getTableStyle(styleId)"
5011
+ onClick="() => this.props.onStylePicked(styleId)"
5012
+ />
5013
+ </t>
5014
+ <div
5015
+ t-if="state.selectedCategory === 'custom'"
5016
+ class="o-new-table-style o-table-style-list-item o-table-style-popover-preview d-flex justify-content-center align-items-center"
5017
+ t-on-click="newTableStyle">
5018
+ +
4423
5019
  </div>
4424
- <hr t-if="!category_last" class="hr mt-2 mb-0"/>
4425
5020
  </div>
4426
5021
  </div>
4427
5022
  </Popover>