@odoo/o-spreadsheet 16.3.15 → 16.3.17

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.
@@ -0,0 +1,3882 @@
1
+ <odoo>
2
+ <t t-name="o-spreadsheet-ActionButton" owl="1">
3
+ <span
4
+ t-if="isVisible"
5
+ class="o-menu-item-button"
6
+ t-att-title="title"
7
+ t-att-class="{'o-disabled': !isEnabled, active: isActive}"
8
+ t-attf-class="{{props.class}}"
9
+ t-on-click="onClick">
10
+ <span t-if="iconTitle" t-att-style="buttonStyle">
11
+ <t t-call="{{iconTitle}}"/>
12
+ </span>
13
+ <t t-if="props.hasTriangleDownIcon">
14
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
15
+ </t>
16
+ </span>
17
+ </t>
18
+
19
+ <t t-name="o-spreadsheet-Ripple" owl="1">
20
+ <div
21
+ class="o-ripple-container position-relative"
22
+ t-att-class="props.class"
23
+ t-on-click="onClick">
24
+ <div class="position-absolute w-100 h-100">
25
+ <t t-foreach="state.ripples" t-as="ripple" t-key="ripple.id">
26
+ <RippleEffect t-props="getRippleEffectProps(ripple.id)"/>
27
+ </t>
28
+ </div>
29
+ <div class="position-relative" t-ref="childContainer">
30
+ <t t-slot="default"/>
31
+ </div>
32
+ </div>
33
+ </t>
34
+
35
+ <t t-name="o-spreadsheet-RippleEffect" owl="1">
36
+ <div
37
+ class="position-absolute"
38
+ t-att-class="{ 'overflow-hidden': !props.allowOverflow }"
39
+ t-att-style="props.style">
40
+ <div class="o-ripple position-relative pe-none" t-ref="ripple" t-att-style="rippleStyle"/>
41
+ </div>
42
+ </t>
43
+
44
+ <t t-name="o-spreadsheet-Autofill" owl="1">
45
+ <div class="o-autofill" t-att-style="style"/>
46
+ <div
47
+ class="o-autofill-handler"
48
+ t-att-style="handlerStyle"
49
+ t-on-mousedown="onMouseDown"
50
+ t-on-dblclick="onDblClick"
51
+ />
52
+ <t t-set="tooltip" t-value="getTooltip()"/>
53
+ <div t-if="tooltip" class="o-autofill-nextvalue" t-att-style="styleNextValue">
54
+ <t t-component="tooltip.component" t-props="tooltip.props"/>
55
+ </div>
56
+ </t>
57
+
58
+ <t t-name="o-spreadsheet-BorderEditor" owl="1">
59
+ <Popover t-props="popoverProps">
60
+ <div
61
+ class="d-flex o-border-selector"
62
+ t-on-click.stop=""
63
+ t-att-class="props.class ? props.class : ''">
64
+ <div class="o-border-selector-section">
65
+ <div
66
+ t-foreach="BORDER_POSITIONS"
67
+ t-as="borderPositionsRow"
68
+ t-key="borderPositionsRow"
69
+ class="d-flex o-dropdown-button o-dropdown-line">
70
+ <span
71
+ t-foreach="borderPositionsRow"
72
+ t-as="borderPosition"
73
+ t-key="borderPosition"
74
+ class="o-line-item o-hoverable-button"
75
+ t-att-class="{active:props.currentBorderPosition === borderPosition[0]}"
76
+ t-att-name="borderPosition[0]"
77
+ t-on-click.stop="() => this.setBorderPosition(borderPosition[0])">
78
+ <t t-call="{{borderPosition[1]}}"/>
79
+ </span>
80
+ </div>
81
+ </div>
82
+ <div class="o-divider"/>
83
+ <div class="o-border-selector-section">
84
+ <div
85
+ class="m-0 p-0 d-flex align-items-center justify-content-center o-with-color o-hoverable-button"
86
+ title="Border color"
87
+ t-on-click.stop="(ev) => this.toggleDropdownTool('borderColorTool')">
88
+ <ColorPickerWidget
89
+ currentColor="props.currentBorderColor"
90
+ toggleColorPicker="(ev) => this.toggleDropdownTool('borderColorTool')"
91
+ showColorPicker="state.activeTool === 'borderColorTool'"
92
+ onColorPicked="(color) => this.setBorderColor(color)"
93
+ title="env._t('Border Color')"
94
+ icon="props.currentBorderColor === '' ? 'o-spreadsheet-Icon.BORDER_NO_COLOR' : 'o-spreadsheet-Icon.BORDER_COLOR'"
95
+ dropdownMaxHeight="this.props.dropdownMaxHeight"
96
+ class="'o-dropdown-button o-border-picker-button'"
97
+ />
98
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
99
+ </div>
100
+ <div
101
+ class="o-border-style-tool d-flex align-items-center justify-content-center o-hoverable-button"
102
+ title="Line style"
103
+ t-ref="lineStyleButton"
104
+ t-on-click.stop="(ev) => this.toggleDropdownTool('borderTypeTool')">
105
+ <t t-call="o-spreadsheet-Icon.BORDER_TYPE"/>
106
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
107
+ <Popover
108
+ t-props="lineStylePickerPopoverProps"
109
+ t-if="state.activeTool === 'borderTypeTool'">
110
+ <div class="o-border-style-dropdown">
111
+ <t t-foreach="borderStyles" t-as="borderStyle" t-key="borderStyle">
112
+ <div
113
+ t-att-title="borderStyle"
114
+ t-on-click.stop="() => this.setBorderStyle(borderStyle)">
115
+ <div class="d-flex o-dropdown-border-type">
116
+ <div class="o-dropdown-border-check">
117
+ <t
118
+ t-if="props.currentBorderStyle === borderStyle"
119
+ t-call="o-spreadsheet-Icon.CHECK"
120
+ />
121
+ </div>
122
+ <div t-attf-class="o-style-preview o-style-{{borderStyle}}"/>
123
+ </div>
124
+ </div>
125
+ </t>
126
+ </div>
127
+ </Popover>
128
+ </div>
129
+ </div>
130
+ </div>
131
+ </Popover>
132
+ </t>
133
+
134
+ <t t-name="o-spreadsheet-BorderEditorWidget" owl="1">
135
+ <div class="d-flex position-relative" title="Borders">
136
+ <span
137
+ t-ref="borderEditorButton"
138
+ t-on-click.stop="props.toggleBorderEditor"
139
+ t-att-class="props.class ? props.class : ''"
140
+ t-att-disabled="props.disabled">
141
+ <span t-att-style="iconStyle">
142
+ <t t-call="o-spreadsheet-Icon.BORDERS"/>
143
+ </span>
144
+ </span>
145
+ <BorderEditor
146
+ t-if="props.showBorderEditor"
147
+ onBorderColorPicked.bind="onBorderColorPicked"
148
+ onBorderStylePicked.bind="onBorderStylePicked"
149
+ onBorderPositionPicked.bind="onBorderPositionPicked"
150
+ currentBorderColor="state.currentColor"
151
+ currentBorderStyle="state.currentStyle"
152
+ currentBorderPosition="state.currentPosition"
153
+ maxHeight="props.dropdownMaxHeight"
154
+ anchorRect="borderEditorAnchorRect"
155
+ />
156
+ </div>
157
+ </t>
158
+
159
+ <t t-name="o-spreadsheet-BottomBar" owl="1">
160
+ <div
161
+ class="o-spreadsheet-bottom-bar o-two-columns d-flex align-items-center overflow-hidden"
162
+ t-on-click="props.onClick"
163
+ t-ref="bottomBar"
164
+ t-on-contextmenu.prevent="">
165
+ <Ripple>
166
+ <div
167
+ class="o-sheet-item o-add-sheet me-2 p-1"
168
+ t-if="!env.model.getters.isReadonly()"
169
+ t-on-click="clickAddSheet">
170
+ <t t-call="o-spreadsheet-Icon.PLUS"/>
171
+ </div>
172
+ </Ripple>
173
+ <Ripple>
174
+ <div class="o-sheet-item o-list-sheets me-2 p-1" t-on-click="clickListSheets">
175
+ <t t-call="o-spreadsheet-Icon.LIST"/>
176
+ </div>
177
+ </Ripple>
178
+ <div class="o-all-sheets position-relative flex-shrink-0 d-flex h-100 me-3">
179
+ <div
180
+ class="o-bottom-bar-fade-in position-absolute h-100 w-100 pe-none"
181
+ t-if="state.isSheetListScrollableLeft"
182
+ />
183
+ <div
184
+ class="o-sheet-list d-flex w-100 overflow-hidden px-1"
185
+ t-ref="sheetList"
186
+ t-on-wheel="onWheel"
187
+ t-on-scroll="onScroll">
188
+ <t t-foreach="getSheets()" t-as="sheet" t-key="sheet.id">
189
+ <BottomBarSheet
190
+ style="getSheetStyle(sheet.id)"
191
+ sheetId="sheet.id"
192
+ openContextMenu="(registry, ev) => this.onSheetContextMenu(sheet.id, registry, ev)"
193
+ onMouseDown="(ev) => this.onSheetMouseDown(sheet.id, ev)"
194
+ />
195
+ </t>
196
+ </div>
197
+ <div
198
+ class="o-bottom-bar-fade-out position-absolute h-100 w-100 pe-none"
199
+ t-if="state.isSheetListScrollableRight"
200
+ />
201
+ </div>
202
+ <div
203
+ class="o-bottom-bar-arrows d-flex h-100 me-5 align-items-center"
204
+ t-if="state.isSheetListScrollableLeft || state.isSheetListScrollableRight">
205
+ <Ripple
206
+ ignoreClickPosition="true"
207
+ width="20"
208
+ height="20"
209
+ offsetX="1"
210
+ allowOverflow="true"
211
+ enabled="state.isSheetListScrollableLeft">
212
+ <div
213
+ class="o-bottom-bar-arrow o-bottom-bar-arrow-left d-flex align-items-center me-2"
214
+ t-att-class="{'o-disabled': !state.isSheetListScrollableLeft}"
215
+ t-on-click="onArrowLeft">
216
+ <t t-call="o-spreadsheet-Icon.CARET_LEFT"/>
217
+ </div>
218
+ </Ripple>
219
+ <Ripple
220
+ ignoreClickPosition="true"
221
+ width="20"
222
+ height="20"
223
+ offsetX="-1"
224
+ allowOverflow="true"
225
+ enabled="state.isSheetListScrollableRight">
226
+ <div
227
+ class="o-bottom-bar-arrow o-bottom-bar-arrow-right d-flex align-items-center me-4"
228
+ t-att-class="{'o-disabled': !state.isSheetListScrollableRight}"
229
+ t-on-click="onArrowRight">
230
+ <t t-call="o-spreadsheet-Icon.CARET_RIGHT"/>
231
+ </div>
232
+ </Ripple>
233
+ </div>
234
+
235
+ <BottomBarStatistic
236
+ openContextMenu="(x, y, registry) => this.openContextMenu(x, y, 'listSelectionStatistics', registry)"
237
+ closeContextMenu="() => this.closeContextMenuWithId('listSelectionStatistics')"
238
+ />
239
+
240
+ <Menu
241
+ t-if="menuState.isOpen"
242
+ position="menuState.position"
243
+ menuItems="menuState.menuItems"
244
+ maxHeight="menuMaxHeight"
245
+ onClose="() => this.closeMenu()"
246
+ menuId="menuState.menuId"
247
+ />
248
+ </div>
249
+ </t>
250
+
251
+ <t t-name="o-spreadsheet-BottomBarSheet" owl="1">
252
+ <Ripple>
253
+ <div
254
+ class="o-sheet d-flex align-items-center user-select-none text-nowrap "
255
+ t-on-mousedown="(ev) => this.onMouseDown(ev)"
256
+ t-on-contextmenu.prevent="(ev) => this.onContextMenu(ev)"
257
+ t-ref="sheetDiv"
258
+ t-att-style="props.style"
259
+ t-att-title="sheetName"
260
+ t-att-data-id="props.sheetId"
261
+ t-att-class="{active: isSheetActive}">
262
+ <span
263
+ class="o-sheet-name"
264
+ t-att-class="{'o-sheet-name-editable': state.isEditing }"
265
+ t-ref="sheetNameSpan"
266
+ t-esc="sheetName"
267
+ t-on-click="(ev) => this.onClickSheetName(ev)"
268
+ t-on-dblclick="() => this.onDblClick()"
269
+ t-on-focusout="() => this.onFocusOut()"
270
+ t-on-keydown="(ev) => this.onKeyDown(ev)"
271
+ t-att-contenteditable="state.isEditing.toString()"
272
+ />
273
+ <span class="o-sheet-icon ms-1" t-on-click.stop="(ev) => this.onIconClick(ev)">
274
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
275
+ </span>
276
+ </div>
277
+ </Ripple>
278
+ </t>
279
+
280
+ <t t-name="o-spreadsheet-BottomBarStatisic" owl="1">
281
+ <t t-set="selectedStatistic" t-value="getSelectedStatistic()"/>
282
+ <Ripple class="'ms-auto'" t-if="selectedStatistic !== undefined">
283
+ <div
284
+ class="o-selection-statistic text-truncate user-select-none me-4 bg-white rounded shadow"
285
+ t-on-click="listSelectionStatistics">
286
+ <t t-esc="selectedStatistic"/>
287
+ <span class="ms-2">
288
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
289
+ </span>
290
+ </div>
291
+ </Ripple>
292
+ </t>
293
+
294
+ <t t-name="o-spreadsheet-ClientTag" owl="1">
295
+ <div>
296
+ <div class="o-client-tag" t-att-style="tagStyle" t-esc="props.name"/>
297
+ </div>
298
+ </t>
299
+
300
+ <t t-name="o-spreadsheet-ColorPicker" owl="1">
301
+ <Popover t-props="popoverProps">
302
+ <div class="o-color-picker" t-on-click.stop="" t-att-style="colorPickerStyle">
303
+ <div class="o-color-picker-section-name">Standard</div>
304
+ <div class="colors-grid">
305
+ <div
306
+ t-foreach="COLORS"
307
+ t-as="color"
308
+ t-key="color"
309
+ class="o-color-picker-line-item"
310
+ t-att-data-color="color"
311
+ t-on-click="() => this.onColorClick(color)"
312
+ t-attf-style="background-color:{{color}};">
313
+ <div
314
+ t-if="isSameColor(props.currentColor, color)"
315
+ align="center"
316
+ t-attf-style="color:{{getCheckMarkColor()}}">
317
+ ✓
318
+ </div>
319
+ </div>
320
+ </div>
321
+ <div class="o-separator"/>
322
+ <div
323
+ class="o-color-picker-section-name o-color-picker-toggler"
324
+ t-on-click="toggleColorPicker">
325
+ <span>Custom</span>
326
+ </div>
327
+ <div class="colors-grid o-color-picker-toggler" t-on-click.stop="toggleColorPicker">
328
+ <div class="o-color-picker-line-item o-color-picker-toggler-button">
329
+ <div class="o-color-picker-toggler-sign">
330
+ <t t-call="o-spreadsheet-Icon.PLUS"/>
331
+ </div>
332
+ </div>
333
+ <div
334
+ t-foreach="env.model.getters.getCustomColors()"
335
+ t-as="color"
336
+ t-key="color"
337
+ class="o-color-picker-line-item"
338
+ t-att-data-color="color"
339
+ t-attf-style="background-color:{{color}};"
340
+ t-on-click="() => this.onColorClick(color)">
341
+ <div
342
+ t-if="props.currentColor === color"
343
+ align="center"
344
+ t-attf-style="color:{{getCheckMarkColor()}}">
345
+ ✓
346
+ </div>
347
+ </div>
348
+ </div>
349
+ <div t-if="state.showGradient" class="o-custom-selector">
350
+ <div class="o-magnifier-glass" t-att-style="magnifyingGlassStyle"/>
351
+ <div
352
+ class="o-gradient"
353
+ t-on-click.stop="computeCustomColor"
354
+ t-on-mouseout="hideMagnifier"
355
+ t-on-mousemove="moveMagnifier"
356
+ t-on-mouseover="showMagnifier"
357
+ />
358
+ <div class="o-custom-input-preview">
359
+ <input
360
+ type="text"
361
+ t-att-class="{'o-wrong-color': state.isCurrentColorInvalid }"
362
+ t-on-click.stop=""
363
+ t-model="state.currentColor"
364
+ />
365
+ <div class="o-color-preview" t-attf-style="background-color:{{state.currentColor}}"/>
366
+ </div>
367
+ <div class="o-custom-input-buttons">
368
+ <button class="o-add-button" t-on-click="setCustomColor">Add</button>
369
+ </div>
370
+ </div>
371
+ <div class="o-separator"/>
372
+ <div class="o-buttons">
373
+ <button t-on-click="resetColor" class="o-cancel">Reset</button>
374
+ </div>
375
+ </div>
376
+ </Popover>
377
+ </t>
378
+
379
+ <t t-name="o-spreadsheet-ColorPickerWidget" owl="1">
380
+ <div class="o-color-picker-widget">
381
+ <span
382
+ class="o-color-picker-button"
383
+ t-ref="colorPickerButton"
384
+ t-on-click.stop="props.toggleColorPicker"
385
+ t-att-title="props.title"
386
+ t-att-class="props.class ? props.class : 'o-color-picker-button-style'"
387
+ t-att-disabled="props.disabled">
388
+ <span t-att-style="iconStyle">
389
+ <t t-call="{{props.icon}}"/>
390
+ </span>
391
+ </span>
392
+ <ColorPicker
393
+ t-if="props.showColorPicker"
394
+ anchorRect="colorPickerAnchorRect"
395
+ onColorPicked="props.onColorPicked"
396
+ currentColor="props.currentColor"
397
+ maxHeight="props.dropdownMaxHeight"
398
+ />
399
+ </div>
400
+ </t>
401
+
402
+ <t t-name="o-spreadsheet-TextValueProvider" owl="1">
403
+ <div
404
+ t-att-class="{
405
+ 'o-autocomplete-dropdown':props.values.length,
406
+ 'shadow':props.values.length}">
407
+ <t t-foreach="props.values" t-as="v" t-key="v.text">
408
+ <div
409
+ class="d-flex flex-column"
410
+ t-att-class="{'o-autocomplete-value-focus': props.selectedIndex === v_index}"
411
+ t-on-click="() => this.props.onValueSelected(v.text)">
412
+ <div class="o-autocomplete-value" t-esc="v.text"/>
413
+ <div
414
+ class="o-autocomplete-description text-truncate"
415
+ t-esc="v.description"
416
+ t-if="props.selectedIndex === v_index"
417
+ />
418
+ </div>
419
+ </t>
420
+ </div>
421
+ </t>
422
+
423
+ <t t-name="o-spreadsheet-Composer" owl="1">
424
+ <div class="o-composer-container w-100 h-100">
425
+ <div
426
+ class="o-composer w-100 text-start"
427
+ t-att-class="{ 'text-muted': env.model.getters.isReadonly(), 'unfocusable': env.model.getters.isReadonly(), 'active': props.focus !== 'inactive' }"
428
+ t-att-style="props.inputStyle"
429
+ t-ref="o_composer"
430
+ tabindex="1"
431
+ t-att-contenteditable="env.model.getters.isReadonly() ? 'false' : 'true'"
432
+ spellcheck="false"
433
+ t-on-keydown="onKeydown"
434
+ t-on-mousedown="onMousedown"
435
+ t-on-mousewheel.stop=""
436
+ t-on-input="onInput"
437
+ t-on-keyup="onKeyup"
438
+ t-on-click="onClick"
439
+ t-on-blur="onBlur"
440
+ t-on-paste.stop=""
441
+ t-on-compositionstart="onCompositionStart"
442
+ t-on-compositionend="onCompositionEnd"
443
+ />
444
+
445
+ <div
446
+ t-if="props.focus !== 'inactive' and (autoCompleteState.showProvider or functionDescriptionState.showDescription)"
447
+ class="o-composer-assistant"
448
+ t-att-style="assistantStyle"
449
+ t-on-mousedown.prevent.stop=""
450
+ t-on-click.prevent.stop=""
451
+ t-on-mouseup.prevent.stop="">
452
+ <TextValueProvider
453
+ t-if="autoCompleteState.showProvider"
454
+ values="autoCompleteState.values"
455
+ selectedIndex="autoCompleteState.selectedIndex"
456
+ onValueSelected.bind="this.autoComplete"
457
+ />
458
+ <FunctionDescriptionProvider
459
+ t-if="functionDescriptionState.showDescription"
460
+ functionName="functionDescriptionState.functionName"
461
+ functionDescription="functionDescriptionState.functionDescription"
462
+ argToFocus="functionDescriptionState.argToFocus"
463
+ />
464
+ </div>
465
+ </div>
466
+ </t>
467
+
468
+ <t t-name="o-spreadsheet-FunctionDescriptionProvider" owl="1">
469
+ <div
470
+ class="o-formula-assistant-container user-select-none shadow"
471
+ t-att-class="{
472
+ 'pe-none': assistantState.allowCellSelectionBehind,
473
+ 'pe-auto': !assistantState.allowCellSelectionBehind
474
+ }">
475
+ <t t-set="context" t-value="getContext()"/>
476
+ <div
477
+ class="o-formula-assistant bg-white"
478
+ t-if="context.functionName"
479
+ t-on-mousemove="onMouseMove"
480
+ t-att-class="{'opacity-25': assistantState.allowCellSelectionBehind}">
481
+ <div class="o-formula-assistant-head">
482
+ <span t-esc="context.functionName"/>
483
+ (
484
+ <t t-foreach="context.functionDescription.args" t-as="arg" t-key="arg.name">
485
+ <span t-if="arg_index > '0'">,&#xA0;</span>
486
+ <span t-att-class="{ 'o-formula-assistant-focus': context.argToFocus === arg_index }">
487
+ <span>
488
+ <span t-if="arg.optional || arg.repeating || arg.default">[</span>
489
+ <span t-esc="arg.name"/>
490
+ <span t-if="arg.repeating">, ...</span>
491
+ <span t-if="arg.optional || arg.repeating || arg.default">]</span>
492
+ </span>
493
+ </span>
494
+ </t>
495
+ )
496
+ </div>
497
+
498
+ <div class="o-formula-assistant-core pb-3 m-3">
499
+ <div class="o-formula-assistant-gray">ABOUT</div>
500
+ <div t-esc="context.functionDescription.description"/>
501
+ </div>
502
+
503
+ <t t-foreach="context.functionDescription.args" t-as="arg" t-key="arg.name">
504
+ <div
505
+ class="o-formula-assistant-arg p-3 pt-0 display-flex flex-column"
506
+ t-att-class="{
507
+ 'o-formula-assistant-gray': context.argToFocus >= '0',
508
+ 'o-formula-assistant-focus': context.argToFocus === arg_index,
509
+ }">
510
+ <div>
511
+ <span t-esc="arg.name"/>
512
+ <span
513
+ t-if="arg.optional || arg.repeating || arg.default ">&#xA0;- [optional]&#xA0;</span>
514
+ <span t-if="arg.default">
515
+ <span>default:&#xA0;</span>
516
+ <t t-esc="arg.defaultValue"/>
517
+ </span>
518
+ <span t-if="arg.repeating">repeatable</span>
519
+ </div>
520
+ <div class="o-formula-assistant-arg-description" t-esc="arg.description"/>
521
+ </div>
522
+ </t>
523
+ </div>
524
+ </div>
525
+ </t>
526
+
527
+ <t t-name="o-spreadsheet-GridComposer" owl="1">
528
+ <div
529
+ class="o-cell-reference"
530
+ t-if="shouldDisplayCellReference"
531
+ t-att-style="cellReferenceStyle"
532
+ t-esc="cellReference"
533
+ />
534
+ <div class="o-grid-composer" t-att-style="containerStyle" t-ref="gridComposer">
535
+ <Composer
536
+ focus="props.focus"
537
+ inputStyle="composerStyle"
538
+ rect="composerState.rect"
539
+ delimitation="composerState.delimitation"
540
+ onComposerUnmounted="props.onComposerUnmounted"
541
+ onComposerContentFocused="props.onComposerContentFocused"
542
+ />
543
+ </div>
544
+ </t>
545
+
546
+ <t t-name="o-spreadsheet-TopBarComposer" owl="1">
547
+ <div class="o-topbar-composer bg-white" t-att-style="containerStyle">
548
+ <Composer
549
+ focus="props.focus"
550
+ inputStyle="composerStyle"
551
+ onComposerContentFocused="props.onComposerContentFocused"
552
+ />
553
+ </div>
554
+ </t>
555
+
556
+ <t t-name="o-spreadsheet-SpreadsheetDashboard" owl="1">
557
+ <div
558
+ class="o-grid o-two-columns"
559
+ tabindex="-1"
560
+ t-on-wheel="onMouseWheel"
561
+ t-on-click="onClosePopover">
562
+ <div class="mx-auto h-100 position-relative" t-ref="grid" t-att-style="gridContainer">
563
+ <GridOverlay
564
+ onCellHovered.bind="onCellHovered"
565
+ onGridResized.bind="onGridResized"
566
+ onGridMoved.bind="moveCanvas"
567
+ gridOverlayDimensions="gridOverlayDimensions"
568
+ />
569
+ <canvas t-ref="canvas"/>
570
+ <GridPopover
571
+ hoveredCell="hoveredCell"
572
+ gridRect="getGridRect()"
573
+ onMouseWheel.bind="onMouseWheel"
574
+ onClosePopover.bind="onClosePopover"
575
+ />
576
+ <div
577
+ t-foreach="getClickableCells()"
578
+ t-as="clickableCell"
579
+ t-key="clickableCell.tKey"
580
+ class="o-dashboard-clickable-cell"
581
+ t-on-click="() => this.selectClickableCell(clickableCell)"
582
+ t-on-contextmenu.prevent=""
583
+ t-att-style="getCellClickableStyle(clickableCell.coordinates)"
584
+ />
585
+ <FilterIconsOverlay/>
586
+ </div>
587
+ <VerticalScrollBar/>
588
+ <HorizontalScrollBar/>
589
+ <div class="o-scrollbar corner"/>
590
+ </div>
591
+ </t>
592
+
593
+ <t t-name="o-spreadsheet-ErrorToolTip" owl="1">
594
+ <div class="o-error-tooltip">
595
+ <t t-esc="props.text"/>
596
+ </div>
597
+ </t>
598
+
599
+ <t t-name="o-spreadsheet-ChartJsComponent" owl="1">
600
+ <canvas class="o-figure-canvas w-100 h-100" t-att-style="canvasStyle" t-ref="graphContainer"/>
601
+ </t>
602
+
603
+ <t t-name="o-spreadsheet-ScorecardChart" owl="1">
604
+ <div class="o-scorecard w-100 h-100" t-att-style="chartStyle" t-ref="chart">
605
+ <t t-set="textStyles" t-value="getTextStyles()"/>
606
+ <div t-if="title" class="o-title-text" t-esc="title" t-att-style="textStyles.titleStyle"/>
607
+ <div class="o-scorecard-content" t-att-style="chartContentStyle">
608
+ <div class="o-key-text" t-if="keyValue" t-esc="keyValue" t-att-style="textStyles.keyStyle"/>
609
+ <t t-if="baseline || baselineDescr">
610
+ <div class="o-baseline-text" t-att-style="textStyles.baselineStyle">
611
+ <t t-if="baseline">
612
+ <t t-if="baselineArrowDirection === 'up'">
613
+ <t t-call="o-spreadsheet-Icon.ARROW_UP">
614
+ <t t-set="color" t-value="'fill : ' + runtime.baselineColor"/>
615
+ </t>
616
+ </t>
617
+ <t t-if="baselineArrowDirection === 'down'">
618
+ <t t-call="o-spreadsheet-Icon.ARROW_DOWN">
619
+ <t t-set="color" t-value="'fill : ' + runtime.baselineColor"/>
620
+ </t>
621
+ </t>
622
+ <span t-att-style="textStyles.baselineValueStyle" class="o-baseline-text-value">
623
+ <t t-esc="baseline"/>
624
+ </span>
625
+ </t>
626
+ <span t-att-style="textStyles.baselineDescrStyle" class="o-baseline-text-description">
627
+ <t t-esc="env._t(baselineDescr)"/>
628
+ </span>
629
+ </div>
630
+ </t>
631
+ </div>
632
+ </div>
633
+ </t>
634
+
635
+ <t t-name="o-spreadsheet-FigureComponent" owl="1">
636
+ <div class="o-figure-wrapper pe-auto" t-att-style="wrapperStyle">
637
+ <div
638
+ class="o-figure w-100 h-100"
639
+ t-on-mousedown.stop="(ev) => this.onMouseDown(ev)"
640
+ t-on-contextmenu.prevent.stop="(ev) => !env.model.getters.isReadonly() and this.onContextMenu(ev)"
641
+ t-ref="figure"
642
+ t-att-style="props.style"
643
+ t-att-data-id="props.figure.id"
644
+ tabindex="0"
645
+ t-on-keydown="(ev) => this.onKeyDown(ev)"
646
+ t-on-keyup.stop="">
647
+ <t
648
+ t-component="figureRegistry.get(props.figure.tag).Component"
649
+ t-key="props.figure.id"
650
+ onFigureDeleted="props.onFigureDeleted"
651
+ figure="props.figure"
652
+ />
653
+ <div class="o-figure-menu position-absolute m-2" t-if="!env.isDashboard()">
654
+ <div
655
+ class="o-figure-menu-item"
656
+ t-if="!env.model.getters.isReadonly()"
657
+ t-on-click="showMenu"
658
+ t-ref="menuButton"
659
+ t-on-contextmenu.prevent.stop="showMenu">
660
+ <t t-call="o-spreadsheet-Icon.LIST"/>
661
+ </div>
662
+ <Menu
663
+ t-if="menuState.isOpen"
664
+ position="menuState.position"
665
+ menuItems="menuState.menuItems"
666
+ onClose="() => this.menuState.isOpen=false"
667
+ />
668
+ </div>
669
+ </div>
670
+ <div class="o-figure-border w-100 h-100 position-absolute pe-none" t-att-style="borderStyle"/>
671
+ <t t-if="isSelected">
672
+ <div
673
+ class="o-fig-anchor o-top"
674
+ t-att-style="this.getResizerPosition('top')"
675
+ t-on-mousedown="(ev) => this.clickAnchor(0,-1, ev)"
676
+ />
677
+ <div
678
+ class="o-fig-anchor o-topRight"
679
+ t-att-style="this.getResizerPosition('top right')"
680
+ t-on-mousedown="(ev) => this.clickAnchor(1,-1, ev)"
681
+ />
682
+ <div
683
+ class="o-fig-anchor o-right"
684
+ t-att-style="this.getResizerPosition('right')"
685
+ t-on-mousedown="(ev) => this.clickAnchor(1,0, ev)"
686
+ />
687
+ <div
688
+ class="o-fig-anchor o-bottomRight"
689
+ t-att-style="this.getResizerPosition('bottom right')"
690
+ t-on-mousedown="(ev) => this.clickAnchor(1,1, ev)"
691
+ />
692
+ <div
693
+ class="o-fig-anchor o-bottom"
694
+ t-att-style="this.getResizerPosition('bottom')"
695
+ t-on-mousedown="(ev) => this.clickAnchor(0,1, ev)"
696
+ />
697
+ <div
698
+ class="o-fig-anchor o-bottomLeft"
699
+ t-att-style="this.getResizerPosition('bottom left')"
700
+ t-on-mousedown="(ev) => this.clickAnchor(-1,1, ev)"
701
+ />
702
+ <div
703
+ class="o-fig-anchor o-left"
704
+ t-att-style="this.getResizerPosition('left')"
705
+ t-on-mousedown="(ev) => this.clickAnchor(-1,0, ev)"
706
+ />
707
+ <div
708
+ class="o-fig-anchor o-topLeft"
709
+ t-att-style="this.getResizerPosition('top left')"
710
+ t-on-mousedown="(ev) => this.clickAnchor(-1,-1, ev)"
711
+ />
712
+ </t>
713
+ </div>
714
+ </t>
715
+
716
+ <t t-name="o-spreadsheet-ChartFigure" owl="1">
717
+ <div class="o-chart-container w-100 h-100" t-on-dblclick="onDoubleClick">
718
+ <t
719
+ t-component="chartComponent"
720
+ figure="this.props.figure"
721
+ t-key="this.props.figure.id + '-' + chartType"
722
+ />
723
+ </div>
724
+ </t>
725
+
726
+ <t t-name="o-spreadsheet-FiguresContainer" owl="1">
727
+ <div>
728
+ <t t-foreach="containers" t-as="container" t-key="container.type">
729
+ <div
730
+ class="o-figure-container position-absolute pe-none overflow-hidden"
731
+ t-att-style="container.style"
732
+ t-att-data-id="container.type + 'Container'">
733
+ <div
734
+ class="o-figure-viewport-inverse w-0 h-0 overflow-visible position-absolute"
735
+ t-att-style="container.inverseViewportStyle">
736
+ <t t-foreach="container.figures" t-as="figure" t-key="figure.id">
737
+ <FigureComponent
738
+ onFigureDeleted="this.props.onFigureDeleted"
739
+ figure="figure"
740
+ style="getFigureStyle(figure)"
741
+ onMouseDown="(ev) => this.startDraggingFigure(figure, ev)"
742
+ onClickAnchor="(dirX, dirY, ev) => this.startResize(figure, dirX, dirY, ev)"
743
+ />
744
+ </t>
745
+ </div>
746
+ </div>
747
+ </t>
748
+ </div>
749
+ <div
750
+ class="o-figure-container position-absolute pe-none overflow-hidden"
751
+ t-if="dnd.horizontalSnap"
752
+ t-att-style="dnd.horizontalSnap.containerStyle"
753
+ t-att-data-id="'HorizontalSnapContainer'">
754
+ <div class="o-figure-snap-line horizontal" t-att-style="dnd.horizontalSnap.lineStyle"/>
755
+ </div>
756
+ <div
757
+ class="o-figure-container position-absolute pe-none overflow-hidden"
758
+ t-if="dnd.verticalSnap"
759
+ t-att-style="dnd.verticalSnap.containerStyle"
760
+ t-att-data-id="'VerticalSnapContainer'">
761
+ <div class="o-figure-snap-line vertical" t-att-style="dnd.verticalSnap.lineStyle"/>
762
+ </div>
763
+ </t>
764
+
765
+ <t t-name="o-spreadsheet-ImageFigure" owl="1">
766
+ <img t-att-src="getImagePath" class="w-100 h-100"/>
767
+ </t>
768
+
769
+ <t t-name="o-spreadsheet-FilterIcon" owl="1">
770
+ <div class="o-filter-icon" t-att-style="style" t-on-click.stop="props.onClick">
771
+ <t t-if="props.isActive" t-call="o-spreadsheet-Icon.FILTER_ICON_ACTIVE"/>
772
+ <t t-else="" t-call="o-spreadsheet-Icon.FILTER_ICON"/>
773
+ </div>
774
+ </t>
775
+
776
+ <t t-name="o-spreadsheet-FilterIconsOverlay" owl="1">
777
+ <t
778
+ t-foreach="getVisibleFilterHeaders()"
779
+ t-as="header"
780
+ t-key="'filter'+header.col + '_' + header.row">
781
+ <FilterIcon
782
+ position="getFilterHeaderPosition(header)"
783
+ isActive="isFilterActive(header)"
784
+ t-key="'icon_'+header.col + '_' + header.row"
785
+ onClick="() => this.toggleFilterMenu(header)"
786
+ />
787
+ </t>
788
+ </t>
789
+
790
+ <t t-name="o-spreadsheet-FilterMenu" owl="1">
791
+ <div class="o-filter-menu d-flex flex-column bg-white" t-on-wheel.stop="">
792
+ <div t-if="!isReadonly">
793
+ <div class="o-filter-menu-item" t-on-click="() => this.sortFilterZone('ascending')">
794
+ Sort ascending (A ⟶ Z)
795
+ </div>
796
+ <div class="o-filter-menu-item" t-on-click="() => this.sortFilterZone('descending')">
797
+ Sort descending (Z ⟶ A)
798
+ </div>
799
+ </div>
800
+ <div class="o-separator" t-if="!isReadonly"/>
801
+ <div class="o-filter-menu-actions">
802
+ <div class="o-filter-menu-action-text" t-on-click="selectAll">Select all</div>
803
+ <div class="o-filter-menu-action-text" t-on-click="clearAll">Clear</div>
804
+ </div>
805
+ <div class="position-relative">
806
+ <input
807
+ class="w-100"
808
+ t-ref="filterMenuSearchBar"
809
+ type="text"
810
+ t-model="state.textFilter"
811
+ placeholder="Search..."
812
+ t-on-keydown="onKeyDown"
813
+ />
814
+ <i class="o-search-icon position-absolute">
815
+ <t t-call="o-spreadsheet-Icon.SEARCH"/>
816
+ </i>
817
+ </div>
818
+ <div
819
+ class="o-filter-menu-list d-flex flex-column rounded"
820
+ t-ref="filterValueList"
821
+ t-on-click="this.clearScrolledToValue"
822
+ t-on-scroll="this.clearScrolledToValue">
823
+ <t t-foreach="displayedValues" t-as="value" t-key="value.string">
824
+ <FilterMenuValueItem
825
+ onClick="() => this.checkValue(value)"
826
+ onMouseMove="() => this.onMouseMove(value)"
827
+ value="value.string"
828
+ isChecked="value.checked"
829
+ isSelected="value.string === state.selectedValue"
830
+ scrolledTo="value.scrolledTo"
831
+ />
832
+ </t>
833
+ <div
834
+ t-if="displayedValues.length === 0"
835
+ class="o-filter-menu-no-values d-flex align-items-center justify-content-center w-100 h-100 ">
836
+ No results
837
+ </div>
838
+ </div>
839
+ <div class="o-filter-menu-buttons d-flex justify-content-end">
840
+ <div class="o-filter-menu-button o-filter-menu-button-cancel" t-on-click="cancel">
841
+ Cancel
842
+ </div>
843
+ <div class="o-filter-menu-button o-filter-menu-button-primary" t-on-click="confirm">
844
+ Confirm
845
+ </div>
846
+ </div>
847
+ </div>
848
+ </t>
849
+
850
+ <t t-name="o-spreadsheet-FilterMenuValueItem" owl="1">
851
+ <div
852
+ t-on-click="this.props.onClick"
853
+ t-on-mousemove="this.props.onMouseMove"
854
+ class="o-filter-menu-item o-filter-menu-value"
855
+ t-ref="menuValueItem"
856
+ t-att-class="{'selected': this.props.isSelected}">
857
+ <div>
858
+ <div class="o-filter-menu-value-checked">
859
+ <span t-if="this.props.isChecked">✓</span>
860
+ </div>
861
+ </div>
862
+ <div class="o-filter-menu-value-text text-truncate">
863
+ <t t-if="this.props.value === ''">(Blanks)</t>
864
+ <t t-else="" t-esc="this.props.value"/>
865
+ </div>
866
+ </div>
867
+ </t>
868
+
869
+ <t t-name="o-spreadsheet-FontSizeEditor" owl="1">
870
+ <div class="o-dropdown" t-ref="FontSizeEditor">
871
+ <div
872
+ class=" o-font-size-editor d-flex align-items-center"
873
+ t-att-class="props.class"
874
+ title="Font Size"
875
+ t-on-click="this.toggleFontList">
876
+ <input
877
+ type="number"
878
+ min="1"
879
+ max="400"
880
+ class="o-font-size bg-transparent border-0"
881
+ t-on-keydown="onInputKeydown"
882
+ t-on-click.stop=""
883
+ t-on-focus.stop="onInputFocused"
884
+ t-att-value="currentFontSize"
885
+ t-on-change="setSizeFromInput"
886
+ t-ref="inputFontSize"
887
+ />
888
+ <span>
889
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
890
+ </span>
891
+ </div>
892
+ <div
893
+ class="o-dropdown-content o-text-options"
894
+ t-if="dropdown.isOpen"
895
+ t-on-click.stop=""
896
+ t-att-style="props.dropdownStyle">
897
+ <t t-foreach="fontSizes" t-as="fontSize" t-key="fontSize">
898
+ <div
899
+ t-esc="fontSize"
900
+ t-att-data-size="fontSize"
901
+ t-on-click="() => this.setSizeFromList(fontSize)"
902
+ />
903
+ </t>
904
+ </div>
905
+ </div>
906
+ </t>
907
+
908
+ <t t-name="o-spreadsheet-Grid" owl="1">
909
+ <div
910
+ class="o-grid"
911
+ tabindex="-1"
912
+ t-att-class="{'o-two-columns': !props.sidePanelIsOpen}"
913
+ t-on-click="focus"
914
+ t-on-keydown="onKeydown"
915
+ t-on-wheel="onMouseWheel"
916
+ t-ref="grid">
917
+ <GridOverlay
918
+ onCellClicked.bind="onCellClicked"
919
+ onCellDoubleClicked.bind="onCellDoubleClicked"
920
+ onCellRightClicked.bind="onCellRightClicked"
921
+ onCellHovered.bind="onCellHovered"
922
+ onGridResized.bind="onGridResized"
923
+ onGridMoved.bind="moveCanvas"
924
+ gridOverlayDimensions="gridOverlayDimensions"
925
+ onFigureDeleted.bind="focus"
926
+ />
927
+ <HeadersOverlay onOpenContextMenu="(type, x, y) => this.toggleContextMenu(type, x, y)"/>
928
+
929
+ <t t-if="env.model.getters.getEditionMode() !== 'inactive'">
930
+ <GridComposer
931
+ onComposerUnmounted="() => this.focus()"
932
+ onComposerContentFocused="props.onComposerContentFocused"
933
+ focus="props.focusComposer"
934
+ gridDims="env.model.getters.getSheetViewDimensionWithHeaders()"
935
+ />
936
+ </t>
937
+ <t else="1">
938
+ <input
939
+ class="position-absolute"
940
+ style="z-index:-1000;"
941
+ t-on-input="onInput"
942
+ t-on-contextmenu="onInputContextMenu"
943
+ t-ref="hiddenInput"
944
+ />
945
+ </t>
946
+ <canvas t-ref="canvas"/>
947
+ <t
948
+ t-foreach="env.model.getters.getClientsToDisplay()"
949
+ t-as="client"
950
+ t-key="getClientPositionKey(client)">
951
+ <ClientTag
952
+ name="client.name"
953
+ color="client.color"
954
+ col="client.position.col"
955
+ row="client.position.row"
956
+ active="isCellHovered(client.position.col, client.position.row)"
957
+ />
958
+ </t>
959
+ <GridPopover
960
+ t-if="!menuState.isOpen"
961
+ hoveredCell="hoveredCell"
962
+ gridRect="getGridRect()"
963
+ onMouseWheel.bind="onMouseWheel"
964
+ onClosePopover.bind="onClosePopover"
965
+ />
966
+ <t t-if="env.model.getters.getEditionMode() === 'inactive'">
967
+ <Autofill position="getAutofillPosition()" isVisible="isAutofillVisible"/>
968
+ </t>
969
+ <t t-if="env.model.getters.getEditionMode() !== 'inactive'">
970
+ <t t-foreach="env.model.getters.getHighlights()" t-as="highlight" t-key="highlight_index">
971
+ <t t-if="highlight.sheetId === env.model.getters.getActiveSheetId()">
972
+ <Highlight zone="highlight.zone" color="highlight.color"/>
973
+ </t>
974
+ </t>
975
+ </t>
976
+ <Menu
977
+ t-if="menuState.isOpen"
978
+ menuItems="menuState.menuItems"
979
+ position="menuState.position"
980
+ onClose="() => this.closeMenu()"
981
+ />
982
+ <FilterIconsOverlay gridPosition="{ x: HEADER_WIDTH, y : HEADER_HEIGHT }"/>
983
+ <VerticalScrollBar topOffset="HEADER_HEIGHT"/>
984
+ <HorizontalScrollBar leftOffset="HEADER_WIDTH"/>
985
+ <div class="o-scrollbar corner"/>
986
+ </div>
987
+ </t>
988
+
989
+ <t t-name="o-spreadsheet-GridOverlay" owl="1">
990
+ <div
991
+ t-ref="gridOverlay"
992
+ class="o-grid-overlay overflow-hidden"
993
+ t-att-style="props.gridOverlayDimensions"
994
+ t-on-mousedown="onMouseDown"
995
+ t-on-dblclick.self="onDoubleClick"
996
+ t-on-contextmenu="onContextMenu">
997
+ <FiguresContainer onFigureDeleted="props.onFigureDeleted"/>
998
+ </div>
999
+ </t>
1000
+
1001
+ <t t-name="o-spreadsheet-GridPopover" owl="1">
1002
+ <Popover
1003
+ t-if="cellPopover.isOpen"
1004
+ positioning="cellPopover.cellCorner"
1005
+ maxHeight="cellPopover.Component.size and cellPopover.Component.size.maxHeight"
1006
+ maxWidth="cellPopover.Component.size and cellPopover.Component.size.maxHidth"
1007
+ anchorRect="cellPopover.anchorRect"
1008
+ containerRect="env.getPopoverContainerRect()"
1009
+ onMouseWheel="props.onMouseWheel"
1010
+ zIndex="zIndex">
1011
+ <t
1012
+ t-component="cellPopover.Component"
1013
+ t-props="{...cellPopover.props, onClosed : () => props.onClosePopover()}"
1014
+ />
1015
+ </Popover>
1016
+ </t>
1017
+
1018
+ <t t-name="o-spreadsheet-HeadersOverlay" owl="1">
1019
+ <div class="o-overlay">
1020
+ <ColResizer onOpenContextMenu="props.onOpenContextMenu"/>
1021
+ <RowResizer onOpenContextMenu="props.onOpenContextMenu"/>
1022
+ <div class="all" t-on-mousedown.self="selectAll"/>
1023
+ </div>
1024
+ </t>
1025
+
1026
+ <t t-name="o-spreadsheet-RowResizer" owl="1">
1027
+ <div
1028
+ class="o-row-resizer"
1029
+ t-on-mousemove.self="onMouseMove"
1030
+ t-on-mouseleave="onMouseLeave"
1031
+ t-on-mousedown.self.prevent="select"
1032
+ t-ref="rowResizer"
1033
+ t-on-mouseup.self="onMouseUp"
1034
+ t-on-contextmenu.self="onContextMenu"
1035
+ t-att-class="{'o-grab': state.waitingForMove, 'o-dragging': state.isMoving}">
1036
+ <div
1037
+ t-if="state.isMoving"
1038
+ class="dragging-row-line"
1039
+ t-attf-style="top:{{state.draggerLinePosition}}px;"
1040
+ />
1041
+ <div
1042
+ t-if="state.isMoving"
1043
+ class="dragging-row-shadow"
1044
+ t-attf-style="top:{{state.draggerShadowPosition}}px; height:{{state.draggerShadowThickness}}px;"
1045
+ />
1046
+ <t t-if="state.resizerIsActive">
1047
+ <div
1048
+ class="o-handle"
1049
+ t-on-mousedown="onMouseDown"
1050
+ t-on-dblclick="onDblClick"
1051
+ t-on-contextmenu.prevent=""
1052
+ t-attf-style="top:{{state.draggerLinePosition - 2}}px;">
1053
+ <div class="dragging-resizer" t-if="state.isResizing"/>
1054
+ </div>
1055
+ </t>
1056
+ <t
1057
+ t-foreach="env.model.getters.getHiddenRowsGroups(env.model.getters.getActiveSheetId())"
1058
+ t-as="hiddenItem"
1059
+ t-key="hiddenItem_index">
1060
+ <t t-if="!hiddenItem.includes(0)">
1061
+ <div
1062
+ class="o-unhide"
1063
+ t-att-data-index="hiddenItem_index"
1064
+ t-attf-style="top:{{unhideStyleValue(hiddenItem[0]) - 17}}px;"
1065
+ t-on-click="() => this.unhide(hiddenItem)">
1066
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_UP"/>
1067
+ </div>
1068
+ </t>
1069
+ <t
1070
+ t-if="!hiddenItem.includes(env.model.getters.getNumberRows(env.model.getters.getActiveSheetId())-1)">
1071
+ <div
1072
+ class="o-unhide"
1073
+ t-att-data-index="hiddenItem_index"
1074
+ t-attf-style="top:{{unhideStyleValue(hiddenItem[0]) + 3}}px;"
1075
+ t-on-click="() => this.unhide(hiddenItem)">
1076
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
1077
+ </div>
1078
+ </t>
1079
+ </t>
1080
+ </div>
1081
+ </t>
1082
+
1083
+ <t t-name="o-spreadsheet-ColResizer" owl="1">
1084
+ <div
1085
+ class="o-col-resizer"
1086
+ t-on-mousemove.self="onMouseMove"
1087
+ t-on-mouseleave="onMouseLeave"
1088
+ t-on-mousedown.self.prevent="select"
1089
+ t-ref="colResizer"
1090
+ t-on-mouseup.self="onMouseUp"
1091
+ t-on-contextmenu.self="onContextMenu"
1092
+ t-att-class="{'o-grab': state.waitingForMove, 'o-dragging': state.isMoving, }">
1093
+ <div
1094
+ t-if="state.isMoving"
1095
+ class="dragging-col-line"
1096
+ t-attf-style="left:{{state.draggerLinePosition}}px;"
1097
+ />
1098
+ <div
1099
+ t-if="state.isMoving"
1100
+ class="dragging-col-shadow"
1101
+ t-attf-style="left:{{state.draggerShadowPosition}}px; width:{{state.draggerShadowThickness}}px"
1102
+ />
1103
+ <t t-if="state.resizerIsActive">
1104
+ <div
1105
+ class="o-handle"
1106
+ t-on-mousedown="onMouseDown"
1107
+ t-on-dblclick="onDblClick"
1108
+ t-on-contextmenu.prevent=""
1109
+ t-attf-style="left:{{state.draggerLinePosition - 2}}px;">
1110
+ <div class="dragging-resizer" t-if="state.isResizing"/>
1111
+ </div>
1112
+ </t>
1113
+ <t
1114
+ t-foreach="env.model.getters.getHiddenColsGroups(env.model.getters.getActiveSheetId())"
1115
+ t-as="hiddenItem"
1116
+ t-key="hiddenItem_index">
1117
+ <t t-if="!hiddenItem.includes(0)">
1118
+ <div
1119
+ class="o-unhide"
1120
+ t-att-data-index="hiddenItem_index"
1121
+ t-attf-style="left:{{unhideStyleValue(hiddenItem[0]) - 17}}px; margin-right:6px;"
1122
+ t-on-click="() => this.unhide(hiddenItem)">
1123
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_LEFT"/>
1124
+ </div>
1125
+ </t>
1126
+ <t
1127
+ t-if="!hiddenItem.includes(env.model.getters.getNumberCols(env.model.getters.getActiveSheetId())-1)">
1128
+ <div
1129
+ class="o-unhide"
1130
+ t-att-data-index="hiddenItem_index"
1131
+ t-attf-style="left:{{unhideStyleValue(hiddenItem[0]) + 3}}px;"
1132
+ t-on-click="() => this.unhide(hiddenItem)">
1133
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_RIGHT"/>
1134
+ </div>
1135
+ </t>
1136
+ </t>
1137
+ </div>
1138
+ </t>
1139
+
1140
+ <t t-name="o-spreadsheet-Border" owl="1">
1141
+ <div
1142
+ class="o-border"
1143
+ t-on-mousedown.prevent="onMouseDown"
1144
+ t-att-style="style"
1145
+ t-att-class="{
1146
+ 'o-moving': props.isMoving,
1147
+ 'o-border-n': props.orientation === 'n',
1148
+ 'o-border-s': props.orientation === 's',
1149
+ 'o-border-w': props.orientation === 'w',
1150
+ 'o-border-e': props.orientation === 'e',
1151
+ }"
1152
+ />
1153
+ </t>
1154
+
1155
+ <t t-name="o-spreadsheet-Corner" owl="1">
1156
+ <div
1157
+ class="o-corner"
1158
+ t-on-mousedown.prevent="onMouseDown"
1159
+ t-att-style="style"
1160
+ t-att-class="{
1161
+ 'o-resizing': props.isResizing,
1162
+ 'o-corner-nw': props.orientation === 'nw',
1163
+ 'o-corner-ne': props.orientation === 'ne',
1164
+ 'o-corner-sw': props.orientation === 'sw',
1165
+ 'o-corner-se': props.orientation === 'se',
1166
+ }"
1167
+ />
1168
+ </t>
1169
+
1170
+ <t t-name="o-spreadsheet-Highlight" owl="1">
1171
+ <div class="o-highlight" t-ref="highlight">
1172
+ <t t-foreach="['n', 's', 'w', 'e']" t-as="orientation" t-key="orientation">
1173
+ <Border
1174
+ onMoveHighlight="(x, y) => this.onMoveHighlight(x,y)"
1175
+ isMoving='highlightState.shiftingMode === "isMoving"'
1176
+ orientation="orientation"
1177
+ zone="props.zone"
1178
+ />
1179
+ </t>
1180
+ <t t-foreach="['nw', 'ne', 'sw', 'se']" t-as="orientation" t-key="orientation">
1181
+ <Corner
1182
+ onResizeHighlight="(isLeft, isTop) => this.onResizeHighlight(isLeft, isTop)"
1183
+ isResizing='highlightState.shiftingMode === "isResizing"'
1184
+ orientation="orientation"
1185
+ zone="props.zone"
1186
+ color="props.color"
1187
+ />
1188
+ </t>
1189
+ </div>
1190
+ </t>
1191
+
1192
+ <t t-name="o-spreadsheet-IconPicker" owl="1">
1193
+ <div class="o-icon-picker">
1194
+ <t t-foreach="iconSets" t-as="iconSet" t-key="iconSet">
1195
+ <div class="o-cf-icon-line">
1196
+ <div
1197
+ class="o-icon-picker-item"
1198
+ t-on-click="() => this.onIconClick(iconSets[iconSet].good)">
1199
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].good].template}}"/>
1200
+ </div>
1201
+ <div
1202
+ class="o-icon-picker-item"
1203
+ t-on-click="() => this.onIconClick(iconSets[iconSet].neutral)">
1204
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].neutral].template}}"/>
1205
+ </div>
1206
+ <div
1207
+ class="o-icon-picker-item"
1208
+ t-on-click="() => this.onIconClick(iconSets[iconSet].bad)">
1209
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].bad].template}}"/>
1210
+ </div>
1211
+ </div>
1212
+ </t>
1213
+ </div>
1214
+ </t>
1215
+
1216
+ <t t-name="o-spreadsheet-Icon.CLEAR_AND_RELOAD" owl="1">
1217
+ <svg class="o-icon">
1218
+ <path
1219
+ fill="currentColor"
1220
+ d="M14 15H4V3h6v3h4M4 1.5A1.5 1.5 0 0 0 2.5 3v12a1.5 1.5 0 0 0 1.4 1.5h10a1.5 1.5 0 0 0 1.5-1.5V5l-3.5-3.5
1221
+ "
1222
+ />
1223
+ </svg>
1224
+ </t>
1225
+ <t t-name="o-spreadsheet-Icon.EXPORT_XLSX" owl="1">
1226
+ <svg class="o-icon">
1227
+ <path
1228
+ fill="currentColor"
1229
+ d="M0 1a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1m4-4V1H1v3m7 0V1H5v3M4 8V5H1v3m7 0V5H5v3m-3.5 2h2v4h3v-1.5l3 2.5-3 2.5V16h-5m9.5-6h6a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1m1.7 7 1.3-2 1.3 2h2l-2-3 2-3h-2L14 13l-1.3-2h-2l2 3-2 3"
1230
+ />
1231
+ </svg>
1232
+ </t>
1233
+ <t t-name="o-spreadsheet-Icon.OPEN_READ_ONLY" owl="1">
1234
+ <svg class="o-icon">
1235
+ <path
1236
+ fill="currentColor"
1237
+ d="M13 7V5c0-2.5-2-4-4-4S5 2.5 5 5v2h-.5C3.5 7 3 7.5 3 8.5v7c0 1 .5 1.5 1.5 1.5h9c1 0 1.5-.5 1.5-1.5v-7c0-1-.5-1.5-1.5-1.5m-7-2c0-1.5 1-2.5 2.5-2.5s2.5 1 2.5 2.5v2h-5V5m1 7a1.5 1.5 0 0 1 3 0 1.5 1.5 0 0 1-3 0"
1238
+ />
1239
+ </svg>
1240
+ </t>
1241
+ <t t-name="o-spreadsheet-Icon.OPEN_DASHBOARD" owl="1">
1242
+ <svg class="o-icon">
1243
+ <path
1244
+ fill="currentColor"
1245
+ d="M13 2.07A8 8 0 1 0 15.93 5L14.2 6A6 6 0 1 1 12 3.8m-2 3.47a2 2 0 1 0 .73.73l5.5-5.5-.6-.6M9.3 3.8a.6.6 0 1 1-.01-.01m1.81.51a.6.6 0 1 1-.01-.01M7.5 4.3a.6.6 0 1 1-.01-.01M5.9 5.4a.6.6 0 1 1-.01-.01M4.8 6.9a.6.6 0 1 1-.01-.01m8.71.61a.6.6 0 1 0-.01 0"
1246
+ />
1247
+ </svg>
1248
+ </t>
1249
+ <t t-name="o-spreadsheet-Icon.OPEN_READ_WRITE" owl="1">
1250
+ <svg class="o-icon">
1251
+ <path
1252
+ fill="currentColor"
1253
+ d="M13 7V5a4 4 0 0 0-8 0v2h-.5C3.5 7 3 7.5 3 8.5v7c0 1 .5 1.5 1.5 1.5h9c1 0 1.5-.5 1.5-1.5v-7c0-1-.5-1.5-1.5-1.5m-7-2a2 2 0 0 1 5 0v2h-5m1 5a1.5 1.5 0 0 1 3 0 1.5 1.5 0 0 1-3 0m6 3.5h-9v-7h9"
1254
+ />
1255
+ </svg>
1256
+ </t>
1257
+ <t t-name="o-spreadsheet-Icon.IMPORT_XLSX" owl="1">
1258
+ <svg class="o-icon">
1259
+ <path
1260
+ fill="currentColor"
1261
+ d="M9 10a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1m4-4v-3h-3v3m7 0v-3h-3v3m-1 4v-3h-3v3m7 0v-3h-3v3M.5 9h2v4h3v-1.5l3 2.5-3 2.5V15h-5M1 0h6a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V1a1 1 0 0 1 1-1m1.7 7L4 5l1.3 2h2l-2-3 2-3h-2L4 3 2.7 1h-2l2 3-2 3"
1262
+ />
1263
+ </svg>
1264
+ </t>
1265
+ <t t-name="o-spreadsheet-Icon.UNDO" owl="1">
1266
+ <svg class="o-icon">
1267
+ <path
1268
+ fill="currentColor"
1269
+ d="M5.43 9.43 8 12H1V5l2.96 2.958A8.29 8.29 0 0 1 9.32 6c3.46 0 6.42 2.11 7.68 5l-2 1c-.94-2.39-3.13-3.92-5.68-4a6.57 6.57 0 0 0-3.89 1.43"
1270
+ />
1271
+ </svg>
1272
+ </t>
1273
+ <t t-name="o-spreadsheet-Icon.REDO" owl="1">
1274
+ <svg class="o-icon">
1275
+ <path
1276
+ fill="currentColor"
1277
+ d="M12.57 9.43 10 12h7V5l-2.96 2.96A8.29 8.29 0 0 0 8.68 6C5.22 6 2.26 8.11 1 11l2 1c.94-2.39 3.13-3.92 5.68-4a6.58 6.58 0 0 1 3.89 1.43"
1278
+ />
1279
+ </svg>
1280
+ </t>
1281
+ <t t-name="o-spreadsheet-Icon.COPY" owl="1">
1282
+ <svg class="o-icon">
1283
+ <path
1284
+ fill="currentColor"
1285
+ 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"
1286
+ />
1287
+ </svg>
1288
+ </t>
1289
+ <t t-name="o-spreadsheet-Icon.CUT" owl="1">
1290
+ <svg class="o-icon">
1291
+ <path
1292
+ fill="currentColor"
1293
+ d="M3 2v2l4.5 5-1.2 1.3c-.4-.2-.8-.3-1.3-.3-1.7 0-3 1.3-3 3s1.3 3 3 3 3-1.3 3-3c0-.5-.1-.9-.3-1.3L9 10.4l1.3 1.3c-.2.4-.3.8-.3 1.3 0 1.7 1.3 3 3 3s3-1.3 3-3-1.3-3-3-3c-.5 0-.9.1-1.3.3L10.4 9 15 4.4V2h-.4L9 7.6 3.4 2H3Zm2 12.5c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5 1.5.7 1.5 1.5-.7 1.5-1.5 1.5Zm9.5-1.5c0 .8-.7 1.5-1.5 1.5s-1.5-.7-1.5-1.5.7-1.5 1.5-1.5 1.5.7 1.5 1.5ZM9 8.5c.3 0 .5.2.5.5s-.2.5-.5.5-.5-.2-.5-.5.2-.5.5-.5"
1294
+ />
1295
+ </svg>
1296
+ </t>
1297
+ <t t-name="o-spreadsheet-Icon.PASTE" owl="1">
1298
+ <svg class="o-icon">
1299
+ <path
1300
+ fill="currentColor"
1301
+ d="M14.5 2.5H11C10.7 1.6 10 1 9 1s-1.5.5-2 1.5H3.5C2.5 2.5 2 3 2 4v11c0 1 .5 1.5 1.5 1.5h11c1 0 1.5-.5 1.5-1.5V4c0-1-.5-1.5-1.5-1.5Zm-4.75.75c0 .5-.34.75-.75.75s-.75-.34-.75-.75.34-.75.75-.75.75.34.75.75ZM14.5 15h-11V4H5v2.5h8V4h1.5v11"
1302
+ />
1303
+ </svg>
1304
+ </t>
1305
+ <t t-name="o-spreadsheet-Icon.FIND_AND_REPLACE" owl="1">
1306
+ <svg class="o-icon">
1307
+ <path
1308
+ fill="currentColor"
1309
+ 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"
1310
+ />
1311
+ </svg>
1312
+ </t>
1313
+ <t t-name="o-spreadsheet-Icon.DELETE" owl="1">
1314
+ <svg class="o-icon">
1315
+ <path
1316
+ fill="currentColor"
1317
+ 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"
1318
+ />
1319
+ </svg>
1320
+ </t>
1321
+ <t t-name="o-spreadsheet-Icon.CLEAR" owl="1">
1322
+ <svg class="o-icon">
1323
+ <path
1324
+ fill="currentColor"
1325
+ d="M1.5 15a.75.75 0 0 0 0 1.5h15a.75.75 0 0 0 0-1.5M5.3 12.75c.1.1.3.2.5.2h4c.2 0 .4-.1.5-.2l5.5-5.5c.2-.3.2-.6 0-.8l-4.4-4.4c-.3-.2-.6-.2-.8 0l-4.8 4.8c-2.7 2.9-3.1 2.8-2.4 4M7 7.25l3.6 3.6-1 1-3.6.1-1.8-1.9"
1326
+ />
1327
+ </svg>
1328
+ </t>
1329
+ <t t-name="o-spreadsheet-Icon.FREEZE" owl="1">
1330
+ <svg class="o-icon">
1331
+ <path
1332
+ fill="currentColor"
1333
+ d="M.5 17.5h16a1 1 0 0 0 1-1v-15a1 1 0 0 0-1-1h-15a1 1 0 0 0-1 1v15a1 1 0 0 0 1 1m9-10.5v4.5H6V7m0 9v-3.5h4.5V16M5 16H3.5L5 14.5M5 13l-3 3v-1.5l3-3M2 13v-2l3-3v2m-3-.5v-2l3-3v2M2 6V4l2-2h1v1m11 13h-4.5v-3.5H16m0-1h-4.5V7H16m0-5v4h-4.5V2m-1 4H6V2h4.5"
1334
+ />
1335
+ </svg>
1336
+ </t>
1337
+ <t t-name="o-spreadsheet-Icon.UNFREEZE" owl="1">
1338
+ <svg class="o-icon">
1339
+ <path
1340
+ fill="currentColor"
1341
+ d="M.5 17.5h16a1 1 0 0 0 1-1v-15a1 1 0 0 0-1-1h-15a1 1 0 0 0-1 1v15a1 1 0 0 0 1 1M5 6H2V2h3m0 9.5H2V7h3m0 9H2v-3.5h3M10.5 7v4.5H6V7m0 9v-3.5h4.5V16m5.5 0h-4.5v-3.5H16m0-1h-4.5V7H16m0-5v4h-4.5V2m-1 4H6V2h4.5"
1342
+ />
1343
+ </svg>
1344
+ </t>
1345
+ <t t-name="o-spreadsheet-Icon.SHOW_HIDE_GRID" owl="1">
1346
+ <svg class="o-icon">
1347
+ <path
1348
+ fill="currentColor"
1349
+ d="M.5 2A1.5 1.5 0 0 1 2 .5h14A1.5 1.5 0 0 1 17.5 2v7H11V7H7v4s-.5 0-1.5 1h-1v5h-3a1.5 1.5 0 0 1-1-1M6 6V2H2v4m9 0V2H7v4m9 0V2h-4v4m-6 5V7H2v4m14-2V7h-4v2m-7.5 6.5V12H2v3.5 M14 10.5c1 0 1 .5 1 1-1.5 2.5-3.5 4.5-5 6.5-.5 0-1-.5-1-1-1-.5-1.5-1-2.5-2 0 0-.5-.5 0-1 1.5-2 4-3 7-3m-1 1.5C13.5 12 4 14 10 16c0 0-1.5-2 2.5-3.5m5 1.5c.5.5.5 1 .5 1-1.5 2-3.5 3-6 2.5.5-.5.5-1 1-1s5.5-1 2-3.5l1-1"
1350
+ />
1351
+ </svg>
1352
+ </t>
1353
+ <t t-name="o-spreadsheet-Icon.SHOW_HIDE_FORMULA" owl="1">
1354
+ <svg class="o-icon">
1355
+ <path
1356
+ fill="currentColor"
1357
+ d="M7 14.25q-.25.75-.75 1.25T5 16q-.75 0-1.5-.5Q3 15 3 14.25q0-.5.25-.75t.75-.25q.25 0 .25.75v.5H5q.5 0 .5-.5l1.25-6.5H5V6h2l.5-2.25q.25-.75.75-1.25T9.5 2q1 0 1.5.5t.5 1q0 .5-.25.75t-.5.25q-.5 0-.75-.25t-.25-.5V3H9.5q-.25 0-.5.5L8.5 6H10v1.5H8.25m1.25 1H15v1h-4l2 2-2 2h4v1H9V14l2.5-2.5L9 9"
1358
+ />
1359
+ </svg>
1360
+ </t>
1361
+ <t t-name="o-spreadsheet-Icon.HIDE_ROW" owl="1">
1362
+ <svg class="o-icon">
1363
+ <path
1364
+ fill="currentColor"
1365
+ 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 16V2H2v3.5h14V2H2v9h14V7H2v9h14v-3.5H2M1 12l4-5h2l-4 5m2 0 4-5h2l-4 5m2 0 4-5h2l-4 5m2 0 4-5v4"
1366
+ />
1367
+ </svg>
1368
+ </t>
1369
+ <t t-name="o-spreadsheet-Icon.HIDE_COL" owl="1">
1370
+ <svg class="o-icon">
1371
+ <path
1372
+ fill="currentColor"
1373
+ d="M16 .5A1.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 16V2A1.5 1.5 0 0 1 2 .5h14V2h-3.5v14H16V2H7v14h4V2H2v14h3.5V2M6 1l5 4v2L6 3m0 2 5 4v2L6 7m0 2 5 4v2l-5-4m0 2 5 4H"
1374
+ />
1375
+ </svg>
1376
+ </t>
1377
+ <t t-name="o-spreadsheet-Icon.INSERT_ROW" owl="1">
1378
+ <svg class="o-icon">
1379
+ <path
1380
+ fill="currentColor"
1381
+ 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 16V2H2v3.5h14V2H2v9h14V7H2v9h14v-3.5H2"
1382
+ />
1383
+ </svg>
1384
+ </t>
1385
+ <t t-name="o-spreadsheet-Icon.INSERT_ROW_BEFORE" owl="1">
1386
+ <svg class="o-icon">
1387
+ <path
1388
+ fill="currentColor"
1389
+ d="M3.5 14.5A1.5 1.5 0 0 0 5 16h10a1.5 1.5 0 0 0 1.5-1.5v-7h-3V5h3V1.5A1.5 1.5 0 0 0 15 0H5a1.5 1.5 0 0 0-1.5 1.5v2h-3V9h3M15 12.5v2H5v-2M15 9v2H5V9m10-7.5v2H5v-2M12 5v2.5H2V5"
1390
+ />
1391
+ </svg>
1392
+ </t>
1393
+ <t t-name="o-spreadsheet-Icon.INSERT_ROW_AFTER" owl="1">
1394
+ <svg class="o-icon">
1395
+ <path
1396
+ fill="currentColor"
1397
+ d="M3.5 1.5A1.5 1.5 0 0 1 5 0h10a1.5 1.5 0 0 1 1.5 1.5v7h-3V11h3v3.5A1.5 1.5 0 0 1 15 16H5a1.5 1.5 0 0 1-1.5-1.5v-2h-3V7h3M15 3.5v-2H5v2M15 7V5H5v2m10 7.5v-2H5v2m7-3.5V8.5H2V11"
1398
+ />
1399
+ </svg>
1400
+ </t>
1401
+ <t t-name="o-spreadsheet-Icon.INSERT_COL" owl="1">
1402
+ <svg class="o-icon">
1403
+ <path
1404
+ fill="currentColor"
1405
+ 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 16V2H2v14h3.5V2H2h5v14h4V2H2h10.5v14H16V2H2"
1406
+ />
1407
+ </svg>
1408
+ </t>
1409
+ <t t-name="o-spreadsheet-Icon.INSERT_COL_AFTER" owl="1">
1410
+ <svg class="o-icon">
1411
+ <path
1412
+ fill="currentColor"
1413
+ d="M2.5 3A1.5 1.5 0 0 0 1 4.5v10A1.5 1.5 0 0 0 2.5 16h7v-3H12v3h3.5a1.5 1.5 0 0 0 1.5-1.5v-10A1.5 1.5 0 0 0 15.5 3h-2V0H8v3M4.5 14.5h-2v-10h2m3.5 10H6v-10h2m7.5 10h-2v-10h2m-3.5 7H9.5v-10H12"
1414
+ />
1415
+ </svg>
1416
+ </t>
1417
+ <t t-name="o-spreadsheet-Icon.INSERT_COL_BEFORE" owl="1">
1418
+ <svg class="o-icon">
1419
+ <path
1420
+ fill="currentColor"
1421
+ d="M15.5 3A1.5 1.5 0 0 1 17 4.5v10a1.5 1.5 0 0 1-1.5 1.5h-7v-3H6v3H2.5A1.5 1.5 0 0 1 1 14.5v-10A1.5 1.5 0 0 1 2.5 3h2V0H10v3m3.5 11.5h2v-10h-2m-3.5 10h2v-10h-2m-7.5 10h2v-10h-2m3.5 7h2.5v-10H6"
1422
+ />
1423
+ </svg>
1424
+ </t>
1425
+ <t t-name="o-spreadsheet-Icon.INSERT_CELL" owl="1">
1426
+ <svg class="o-icon">
1427
+ <path
1428
+ fill="currentColor"
1429
+ 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 16V2H2v14h14V2H2"
1430
+ />
1431
+ </svg>
1432
+ </t>
1433
+ <t t-name="o-spreadsheet-Icon.INSERT_CELL_SHIFT_DOWN" owl="1">
1434
+ <svg class="o-icon">
1435
+ <path
1436
+ fill="currentColor"
1437
+ d="M5 2.5A1.5 1.5 0 0 1 6.5 1h10A1.5 1.5 0 0 1 18 2.5v13a1.5 1.5 0 0 1-1.5 1.5h-10A1.5 1.5 0 0 1 5 15.5v-5h5.25v-3H5m11.5-2v-3h-4.75v3m-1.5 0v-3H6.5v3m10 5v-3h-4.75v3m-1.5 5v-3H6.5v3m10 0v-3h-4.75v3M0 12.5l2.5 4 2.5-4H3.25v-6h-1.5v6"
1438
+ />
1439
+ </svg>
1440
+ </t>
1441
+ <t t-name="o-spreadsheet-Icon.INSERT_CELL_SHIFT_RIGHT" owl="1">
1442
+ <svg class="o-icon">
1443
+ <path
1444
+ fill="currentColor"
1445
+ d="M2.5 5A1.5 1.5 0 0 0 1 6.5v10A1.5 1.5 0 0 0 2.5 18h13a1.5 1.5 0 0 0 1.5-1.5v-10A1.5 1.5 0 0 0 15.5 5h-5v5.25h-3V5m-2 11.5h-3v-4.75h3m0-1.5h-3V6.5h3m5 10h-3v-4.75h3m5-1.5h-3V6.5h3m0 10h-3v-4.75h3M12.5 0l4 2.5-4 2.5V3.25h-6v-1.5h6"
1446
+ />
1447
+ </svg>
1448
+ </t>
1449
+ <t t-name="o-spreadsheet-Icon.DELETE_CELL_SHIFT_UP" owl="1">
1450
+ <svg class="o-icon">
1451
+ <path
1452
+ fill="currentColor"
1453
+ d="M5 2.5A1.5 1.5 0 0 1 6.5 1h10A1.5 1.5 0 0 1 18 2.5v13a1.5 1.5 0 0 1-1.5 1.5h-10A1.5 1.5 0 0 1 5 15.5v-5h5.25v-3H5m11.5-2v-3h-4.75v3m-1.5 0v-3H6.5v3m10 5v-3h-4.75v3m-1.5 5v-3H6.5v3m10 0v-3h-4.75v3M0 10l2.5-4L5 10H3.25v6h-1.5v-6"
1454
+ />
1455
+ </svg>
1456
+ </t>
1457
+ <t t-name="o-spreadsheet-Icon.DELETE_CELL_SHIFT_LEFT" owl="1">
1458
+ <svg class="o-icon">
1459
+ <path
1460
+ fill="currentColor"
1461
+ d="M2.5 5A1.5 1.5 0 0 0 1 6.5v10A1.5 1.5 0 0 0 2.5 18h13a1.5 1.5 0 0 0 1.5-1.5v-10A1.5 1.5 0 0 0 15.5 5h-5v5.25h-3V5m-2 11.5h-3v-4.75h3m0-1.5h-3V6.5h3m5 10h-3v-4.75h3m5-1.5h-3V6.5h3m0 10h-3v-4.75h3M10 0 6 2.5 10 5V3.25h6v-1.5h-6"
1462
+ />
1463
+ </svg>
1464
+ </t>
1465
+ <t t-name="o-spreadsheet-Icon.INSERT_CHART" owl="1">
1466
+ <svg class="o-icon">
1467
+ <path
1468
+ fill="currentColor"
1469
+ 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"
1470
+ />
1471
+ </svg>
1472
+ </t>
1473
+ <t t-name="o-spreadsheet-Icon.INSERT_IMAGE" owl="1">
1474
+ <svg class="o-icon" fill="currentColor">
1475
+ <path
1476
+ 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"
1477
+ />
1478
+ </svg>
1479
+ </t>
1480
+ <t t-name="o-spreadsheet-Icon.INSERT_LINK" owl="1">
1481
+ <svg class="o-icon" fill="currentColor">
1482
+ <path
1483
+ 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"
1484
+ />
1485
+ </svg>
1486
+ </t>
1487
+ <t t-name="o-spreadsheet-Icon.INSERT_SHEET" owl="1">
1488
+ <svg class="o-icon" fill="currentColor">
1489
+ <path
1490
+ d="M17.5 5.5V16a1.5 1.5 0 0 1-1.5 1.5H2A1.5 1.5 0 0 1 .5 16V2A1.5 1.5 0 0 1 2 .5h10.5M2 5.5h3.5V2H2m5.25 3.5h3.5V2h-3.5M2 10.75h3.5v-3.5H2m5.25 3.5h3.5v-3.5h-3.5m5.25 3.5H16v-3.5h-3.5M2 16h3.5v-3.5H2M7.25 16h3.5v-3.5h-3.5M12.5 16H16v-3.5h-3.5"
1491
+ />
1492
+ </svg>
1493
+ </t>
1494
+ <t t-name="o-spreadsheet-Icon.PAINT_FORMAT" owl="1">
1495
+ <svg class="o-icon">
1496
+ <path
1497
+ fill="currentColor"
1498
+ d="M9,0 L1,0 C0.45,0 0,0.45 0,1 L0,4 C0,4.55 0.45,5 1,5 L9,5 C9.55,5 10,4.55 10,4 L10,3 L11,3 L11,6 L4,6 L4,14 L6,14 L6,8 L13,8 L13,2 L10,2 L10,1 C10,0.45 9.55,0 9,0 Z"
1499
+ transform="translate(3 2)"
1500
+ />
1501
+ </svg>
1502
+ </t>
1503
+ <t t-name="o-spreadsheet-Icon.CONDITIONAL_FORMAT" owl="1">
1504
+ <svg class="o-icon">
1505
+ <path
1506
+ fill="currentColor"
1507
+ d="M12.25.5c2 0 3.5 1.5 3.5 3.5v6.5c0 .5 0 2-2 2h-2.5v4c0 .5-.5 1-1 1h-2.5c-.5 0-1-.5-1-1v-4h-2.5c-1 0-2-1-2-2V.5m12 3a1.5 1.5 0 0 0-1.5-1.5h-3v2h-1.5V2h-1v4h-2V2h-1.5v8.5h10.5m-12-3h12.5V9H2.25"
1508
+ />
1509
+ </svg>
1510
+ </t>
1511
+ <t t-name="o-spreadsheet-Icon.CLEAR_FORMAT" owl="1">
1512
+ <svg class="o-icon">
1513
+ <path
1514
+ fill="currentColor"
1515
+ d="M2.12 4.05 7.28 9.2l-2.43 5.3h2.5l1.64-3.58 4.59 4.58 1.27-1.27L3.4 2.77 2.12 4.05ZM5.67 2.5l2 2h1.76l-.55 1.21 1.71 1.71 1.34-2.92h3.92v-2H5.67"
1516
+ />
1517
+ </svg>
1518
+ </t>
1519
+ <t t-name="o-spreadsheet-Icon.TRIANGLE_DOWN" owl="1">
1520
+ <svg class="o-icon">
1521
+ <polygon fill="currentColor" points="0 0 4 4 8 0" transform="translate(5 7)"/>
1522
+ </svg>
1523
+ </t>
1524
+ <t t-name="o-spreadsheet-Icon.TRIANGLE_UP" owl="1">
1525
+ <svg class="o-icon">
1526
+ <polygon fill="currentColor" points="4 0 0 4 8 4" transform="translate(5 7)"/>
1527
+ </svg>
1528
+ </t>
1529
+ <t t-name="o-spreadsheet-Icon.TRIANGLE_RIGHT" owl="1">
1530
+ <svg class="o-icon">
1531
+ <polygon fill="currentColor" points="0 0 4 4 0 8" transform="translate(5 5)"/>
1532
+ </svg>
1533
+ </t>
1534
+ <t t-name="o-spreadsheet-Icon.TRIANGLE_LEFT" owl="1">
1535
+ <svg class="o-icon">
1536
+ <polygon fill="currentColor" points="4 0 0 4 4 8" transform="translate(5 5)"/>
1537
+ </svg>
1538
+ </t>
1539
+ <t t-name="o-spreadsheet-Icon.BOLD" owl="1">
1540
+ <svg class="o-icon">
1541
+ <path
1542
+ fill="currentColor"
1543
+ d="M13.5 6.5C13.5 4.57 11.93 3 10 3H4.5v12h6.25c1.79 0 3.25-1.46 3.25-3.25 0-1.3-.77-2.41-1.87-2.93.83-.58 1.37-1.44 1.37-2.32M9.5 5c.83 0 1.5.67 1.5 1.5S10.33 8 9.5 8h-2V5h2m-2 8v-3H10c.83 0 1.5.67 1.5 1.5S10.83 13 10 13H7.5"
1544
+ />
1545
+ </svg>
1546
+ </t>
1547
+ <t t-name="o-spreadsheet-Icon.ITALIC" owl="1">
1548
+ <svg class="o-icon">
1549
+ <path fill="currentColor" d="M7 3v2h2.58l-3.66 8H3v2h8v-2H8.42l3.66-8H15V3"/>
1550
+ </svg>
1551
+ </t>
1552
+ <t t-name="o-spreadsheet-Icon.UNDERLINE" owl="1">
1553
+ <svg class="o-icon">
1554
+ <path
1555
+ fill="currentColor"
1556
+ d="M9 15c2.76 0 5-2.24 5-5V3h-2v7c0 1.75-1.5 3-3 3s-3-1.242-3-3V3H4v7c0 2.76 2.24 5 5 5Zm-6 1v2h12v-2H3"
1557
+ />
1558
+ </svg>
1559
+ </t>
1560
+ <t t-name="o-spreadsheet-Icon.STRIKE" owl="1">
1561
+ <svg class="o-icon">
1562
+ <path
1563
+ fill="currentColor"
1564
+ d="M4.89 6.06c0-.46.1-.87.3-1.25.2-.38.46-.7.84-.97s.78-.47 1.28-.62A5.71 5.71 0 0 1 8.93 3c.61 0 1.16.08 1.65.25.5.17.92.4 1.27.7.35.3.62.66.81 1.07.19.41.28.87.28 1.36h-2.26a1.85 1.85 0 0 0-.11-.64 1.26 1.26 0 0 0-.33-.51 1.53 1.53 0 0 0-.56-.33A2.42 2.42 0 0 0 8.89 4.8c-.3 0-.55.03-.77.1a1.52 1.52 0 0 0-.54.27 1.14 1.14 0 0 0-.43.9c0 .36.18.66.55.91l.06.04C8.02 7.19 8.5 7.5 9 8H6s-.79-.62-.82-.69c-.19-.36-.29-.77-.29-1.25M16 9H2v2h7.22c.14.05.3.1.41.15.28.12.5.26.65.38.16.13.26.27.32.42.06.15.08.33.08.51 0 .18-.03.34-.1.49a1.02 1.02 0 0 1-.31.39 1.6 1.6 0 0 1-.53.26 2.71 2.71 0 0 1-.76.09c-.33 0-.62-.03-.89-.1a1.8 1.8 0 0 1-.68-.31 1.45 1.45 0 0 1-.44-.56c-.11-.23-.19-.57-.19-.74H4.55c0 .25.06.69.18 1.02a3.15 3.15 0 0 0 1.22 1.6c.28.2.58.36.92.49.33.13.67.23 1.04.29.36.06.72.09 1.08.09.6 0 1.15-.07 1.64-.21a3.88 3.88 0 0 0 1.25-.59 2.69 2.69 0 0 0 .8-.95c.19-.38.28-.81.28-1.29 0-.45-.08-.86-.23-1.211a2.26 2.26 0 0 0-.13-.25L16 11V9"
1565
+ />
1566
+ </svg>
1567
+ </t>
1568
+ <t t-name="o-spreadsheet-Icon.TEXT_COLOR" owl="1">
1569
+ <svg class="o-icon">
1570
+ <path
1571
+ fill="currentColor"
1572
+ d="M10 1H8L3.5 13h2l1.12-3h4.75l1.12 3h2L10 1ZM7.38 8 9 3.67 10.62 8H7.38"
1573
+ />
1574
+ </svg>
1575
+ </t>
1576
+ <t t-name="o-spreadsheet-Icon.FILL_COLOR" owl="1">
1577
+ <svg class="o-icon">
1578
+ <path
1579
+ fill="currentColor"
1580
+ d="M14.5 8.87S13 10.49 13 11.49c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5c0-.99-1.5-2.62-1.5-2.62m-1.79-2.08L5.91 0 4.85 1.06l1.59 1.59-4.15 4.14a.996.996 0 0 0 0 1.41l4.5 4.5c.2.2.45.3.71.3.26 0 .51-.1.71-.29l4.5-4.5c.39-.39.39-1.03 0-1.42M4.21 7 7.5 3.71 10.79 7H4.21"
1581
+ />
1582
+ </svg>
1583
+ </t>
1584
+ <t t-name="o-spreadsheet-Icon.MERGE_CELL" owl="1">
1585
+ <svg class="o-icon">
1586
+ <path
1587
+ fill="currentColor"
1588
+ d="M3 6H1V2h7v2H3v2m7-2V2h7v4h-2V4h-5m0 10h5v-2h2v4h-7v-2m-9-2h2v2h5v2H1v-4m0-4h4V6l3 3-3 3v-2H1V8m9 1 3-3v2h4v2h-4v2l-3-3"
1589
+ />
1590
+ </svg>
1591
+ </t>
1592
+ <t t-name="o-spreadsheet-Icon.ALIGN_LEFT" owl="1">
1593
+ <svg class="o-icon align-left">
1594
+ <path fill="currentColor" d="M2 16h10v-2H2v2M12 6H2v2h10V6M2 2v2h14V2H2m0 10h14v-2H2v2"/>
1595
+ </svg>
1596
+ </t>
1597
+ <t t-name="o-spreadsheet-Icon.ALIGN_CENTER" owl="1">
1598
+ <svg class="o-icon align-center">
1599
+ <path fill="currentColor" d="M4 14v2h10v-2H4m0-8v2h10V6H4m-2 6h14v-2H2v2M2 2v2h14V2H2"/>
1600
+ </svg>
1601
+ </t>
1602
+ <t t-name="o-spreadsheet-Icon.ALIGN_RIGHT" owl="1">
1603
+ <svg class="o-icon align-right">
1604
+ <path fill="currentColor" d="M6 16h10v-2H6v2m-4-4h14v-2H2v2M2 2v2h14V2H2m4 6h10V6H6v2"/>
1605
+ </svg>
1606
+ </t>
1607
+ <t t-name="o-spreadsheet-Icon.ALIGN_TOP" owl="1">
1608
+ <svg class="o-icon align-top">
1609
+ <path d="M3 2h12v2H3m2.5 5H8v7h2V9h2.5L9 5.5" fill="currentColor"/>
1610
+ </svg>
1611
+ </t>
1612
+ <t t-name="o-spreadsheet-Icon.ALIGN_MIDDLE" owl="1">
1613
+ <svg class="o-icon align-middle">
1614
+ <path
1615
+ d="M12.5 3H10V0H8v3H5.5L9 6.5M5.5 15H8v3h2v-3h2.5L9 11.5M3 8v2h12V8"
1616
+ fill="currentColor"
1617
+ />
1618
+ </svg>
1619
+ </t>
1620
+ <t t-name="o-spreadsheet-Icon.ALIGN_BOTTOM" owl="1">
1621
+ <svg class="o-icon align-bottom">
1622
+ <path d="M5.5 9H8V2h2v7h2.5L9 12.5M3 14v2h12v-2" fill="currentColor"/>
1623
+ </svg>
1624
+ </t>
1625
+ <t t-name="o-spreadsheet-Icon.WRAPPING_OVERFLOW" owl="1">
1626
+ <svg class="o-icon wrapping-overflow">
1627
+ <path d="M13 8H6v2h7v2l3-3-3-3M2 2h2v14H2M9 2h2v4H9m0 6h2v4H9" fill="currentColor"/>
1628
+ </svg>
1629
+ </t>
1630
+ <t t-name="o-spreadsheet-Icon.WRAPPING_WRAP" owl="1">
1631
+ <svg class="o-icon wrapping-wrap">
1632
+ <path
1633
+ fill="currentColor"
1634
+ d="M6 5v2h3.75c.75 0 1.5.67 1.5 1.5 0 .75-.75 1.5-1.5 1.5H8V8l-3 3 3 3v-2h1.5c2 0 3.5-1.5 3.5-3.5S11.5 5 9.5 5M2 2h2v14H2M14 2M14,2,h2v14h-2"
1635
+ />
1636
+ </svg>
1637
+ </t>
1638
+ <t t-name="o-spreadsheet-Icon.WRAPPING_CLIP" owl="1">
1639
+ <svg class="o-icon wrapping-clip">
1640
+ <path fill="currentColor" d="M2 2h2v14H2M14 2h2v14h-2v-6H6V8h8"/>
1641
+ </svg>
1642
+ </t>
1643
+ <t t-name="o-spreadsheet-Icon.BORDERS" owl="1">
1644
+ <svg class="o-icon">
1645
+ <path
1646
+ fill="currentColor"
1647
+ d="M2 2v14h14V2H2m6 12H4v-4h4v4m0-6H4V4h4v4m6 6h-4v-4h4v4m0-6h-4V4h4v4"
1648
+ />
1649
+ </svg>
1650
+ </t>
1651
+ <t t-name="o-spreadsheet-Icon.BORDER_HV" owl="1">
1652
+ <svg class="o-icon" fill="currentColor">
1653
+ <path
1654
+ d="M2 16h2v-2H2v2M4 5H2v2h2V5m1 11h2v-2H5v2m8-14h-2v2h2V2M4 2H2v2h2V2m3 0H5v2h2V2M2 13h2v-2H2v2m9 3h2v-2h-2v2m3-14v2h2V2h-2m0 5h2V5h-2v2m0 9h2v-2h-2v2m0-3h2v-2h-2v2"
1655
+ opacity=".54"
1656
+ />
1657
+ <path d="M10 2H8v6H2v2h6v6h2v-6h6V8h-6"/>
1658
+ </svg>
1659
+ </t>
1660
+ <t t-name="o-spreadsheet-Icon.BORDER_H" owl="1">
1661
+ <svg class="o-icon" fill="currentColor">
1662
+ <path
1663
+ d="M8 16h2v-2H8v2M5 4h2V2H5v2m3 9h2v-2H8v2m-3 3h2v-2H5v2M2 7h2V5H2v2m0 9h2v-2H2v2M2 4h2V2H2v2m0 9h2v-2H2v2m12 0h2v-2h-2v2m0 3h2v-2h-2v2m0-9h2V5h-2v2m0-5v2h2V2h-2M8 4h2V2H8v2m3 0h2V2h-2v2M8 7h2V5H8v2m3 9h2v-2h-2v2"
1664
+ opacity=".54"
1665
+ />
1666
+ <path d="M2 10h14V8H2"/>
1667
+ </svg>
1668
+ </t>
1669
+ <t t-name="o-spreadsheet-Icon.BORDER_V" owl="1">
1670
+ <svg class="o-icon" fill="currentColor">
1671
+ <path
1672
+ d="M5 16h2v-2H5v2M2 7h2V5H2v2m0-3h2V2H2v2m3 6h2V8H5v2m0-6h2V2H5v2M2 16h2v-2H2v2m0-6h2V8H2v2m0 3h2v-2H2v2M14 2v2h2V2h-2m0 8h2V8h-2v2m0 6h2v-2h-2v2m0-9h2V5h-2v2m0 6h2v-2h-2v2m-3 3h2v-2h-2v2m0-6h2V8h-2v2m0-6h2V2h-2v2"
1673
+ opacity=".54"
1674
+ />
1675
+ <path d="M8 16h2V2H8"/>
1676
+ </svg>
1677
+ </t>
1678
+ <t t-name="o-spreadsheet-Icon.BORDER_EXTERNAL" owl="1">
1679
+ <svg class="o-icon" fill="currentColor">
1680
+ <path d="M10 5H8v2h2V5m3 3h-2v2h2V8m-3 0H8v2h2V8m0 3H8v2h2v-2M7 8H5v2h2V8" opacity=".54"/>
1681
+ <path d="M2 2h14v14H2V2m12 12V4H4v10h10"/>
1682
+ </svg>
1683
+ </t>
1684
+ <t t-name="o-spreadsheet-Icon.BORDER_LEFT" owl="1">
1685
+ <svg class="o-icon" fill="currentColor">
1686
+ <path
1687
+ d="M8 10h2V8H8v2m0-3h2V5H8v2m0 6h2v-2H8v2m0 3h2v-2H8v2m-3 0h2v-2H5v2M5 4h2V2H5v2m0 6h2V8H5v2m9 6h2v-2h-2v2m0-6h2V8h-2v2m0 3h2v-2h-2v2m0-6h2V5h-2v2M8 4h2V2H8v2m6-2v2h2V2h-2m-3 14h2v-2h-2v2m0-6h2V8h-2v2m0-6h2V2h-2v2"
1688
+ opacity=".54"
1689
+ />
1690
+ <path d="M2 16h2V2H2"/>
1691
+ </svg>
1692
+ </t>
1693
+ <t t-name="o-spreadsheet-Icon.BORDER_TOP" owl="1">
1694
+ <svg class="o-icon" fill="currentColor">
1695
+ <path
1696
+ d="M5 10h2V8H5v2m-3 6h2v-2H2v2m6 0h2v-2H8v2m0-3h2v-2H8v2m-3 3h2v-2H5v2m-3-3h2v-2H2v2m6-3h2V8H8v2M2 7h2V5H2v2m0 3h2V8H2v2m12 0h2V8h-2v2m0 3h2v-2h-2v2m0-6h2V5h-2v2M8 7h2V5H8v2m3 9h2v-2h-2v2m0-6h2V8h-2v2m3 6h2v-2h-2v2"
1697
+ opacity=".54"
1698
+ />
1699
+ <path d="M2 2v2h14V2"/>
1700
+ </svg>
1701
+ </t>
1702
+ <t t-name="o-spreadsheet-Icon.BORDER_RIGHT" owl="1">
1703
+ <svg class="o-icon" fill="currentColor">
1704
+ <path
1705
+ d="M2 4h2V2H2v2m3 0h2V2H5v2m0 6h2V8H5v2m0 6h2v-2H5v2M2 7h2V5H2v2m0 3h2V8H2v2m0 6h2v-2H2v2m0-3h2v-2H2v2m9-3h2V8h-2v2m-3 6h2v-2H8v2m3 0h2v-2h-2v2M8 4h2V2H8v2m3 0h2V2h-2v2m-3 9h2v-2H8v2m0-6h2V5H8v2m0 3h2V8H8v2"
1706
+ opacity=".54"
1707
+ />
1708
+ <path d="M14 2v14h2V2"/>
1709
+ </svg>
1710
+ </t>
1711
+ <t t-name="o-spreadsheet-Icon.BORDER_BOTTOM" owl="1">
1712
+ <svg class="o-icon" fill="currentColor">
1713
+ <path
1714
+ d="M7 2H5v2h2V2m3 6H8v2h2V8m0 3H8v2h2v-2m3-3h-2v2h2V8M7 8H5v2h2V8m6-6h-2v2h2V2m-3 3H8v2h2V5m0-3H8v2h2V2m-6 9H2v2h2v-2m10 2h2v-2h-2v2m0-6h2V5h-2v2m0 3h2V8h-2v2m0-8v2h2V2h-2M4 2H2v2h2V2m0 3H2v2h2V5m0 3H2v2h2V8"
1715
+ opacity=".54"
1716
+ />
1717
+ <path d="M2 16h14v-2H2"/>
1718
+ </svg>
1719
+ </t>
1720
+ <t t-name="o-spreadsheet-Icon.BORDER_CLEAR" owl="1">
1721
+ <svg class="o-icon">
1722
+ <path
1723
+ fill="currentColor"
1724
+ d="M8 16h2v-2H8v2m-3-6h2V8H5v2m0-6h2V2H5v2m3 9h2v-2H8v2m-3 3h2v-2H5v2M2 7h2V5H2v2m0 9h2v-2H2v2M2 4h2V2H2v2m0 6h2V8H2v2m6 0h2V8H8v2m-6 3h2v-2H2v2m12 0h2v-2h-2v2m0 3h2v-2h-2v2m0-6h2V8h-2v2m0-3h2V5h-2v2m0-5v2h2V2h-2M8 4h2V2H8v2m3 0h2V2h-2v2M8 7h2V5H8v2m3 9h2v-2h-2v2m0-6h2V8h-2v2"
1725
+ opacity=".54"
1726
+ />
1727
+ </svg>
1728
+ </t>
1729
+ <t t-name="o-spreadsheet-Icon.BORDER_TYPE" owl="1">
1730
+ <svg class="o-icon">
1731
+ <g fill="currentColor" transform="translate(2 2)">
1732
+ <polygon points="0 0 0 2 14 2 14 0"/>
1733
+ <polygon points="0 6 0 8 5 8 5 6"/>
1734
+ <polygon points="9 6 9 8 14 8 14 6"/>
1735
+ <polygon points="0 12 0 14 2 14 2 12"/>
1736
+ <polygon points="4 12 4 14 6 14 6 12"/>
1737
+ <polygon points="8 12 8 14 10 14 10 12"/>
1738
+ <polygon points="12 12 12 14 14 14 14 12"/>
1739
+ </g>
1740
+ </svg>
1741
+ </t>
1742
+ <t t-name="o-spreadsheet-Icon.BORDER_COLOR" owl="1">
1743
+ <svg class="o-icon">
1744
+ <g fill="currentColor" transform="translate(4 2)">
1745
+ <polygon points="0 12 0 9 7 2 10 5 3 12"/>
1746
+ <polygon points="8 1 9 0 12 3 11 4"/>
1747
+ </g>
1748
+ </svg>
1749
+ </t>
1750
+ <t t-name="o-spreadsheet-Icon.BORDER_NO_COLOR" owl="1">
1751
+ <svg class="o-icon">
1752
+ <g fill="currentColor">
1753
+ <polygon points="4 12 4 9 11 2 14 5 7 12"/>
1754
+ <polygon points="12 1 13 0 16 3 15 4"/>
1755
+ </g>
1756
+ <g>
1757
+ <rect x="0" y="14" width="18" height="4" stroke="black" fill="none"/>
1758
+ </g>
1759
+ </svg>
1760
+ </t>
1761
+
1762
+ <t t-name="o-spreadsheet-Icon.PLUS" owl="1">
1763
+ <svg class="o-icon" viewBox="0 0 18 18">
1764
+ <path fill="currentColor" d="M8 0h2v8h8v2h-8v8H8v-8H0V8h8"/>
1765
+ </svg>
1766
+ </t>
1767
+ <t t-name="o-spreadsheet-Icon.LIST" owl="1">
1768
+ <svg class="o-icon" viewBox="0 0 384 384">
1769
+ <rect x="0" y="277.333" width="384" height="42.667" fill="currentColor"/>
1770
+ <rect x="0" y="170.667" width="384" height="42.667" fill="currentColor"/>
1771
+ <rect x="0" y="64" width="384" height="42.667" fill="currentColor"/>
1772
+ </svg>
1773
+ </t>
1774
+
1775
+ <t t-name="o-spreadsheet-Icon.EDIT" owl="1">
1776
+ <svg class="o-icon" viewBox="0 0 576 512">
1777
+ <path
1778
+ fill="currentColor"
1779
+ 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"
1780
+ />
1781
+ </svg>
1782
+ </t>
1783
+ <t t-name="o-spreadsheet-Icon.UNLINK" owl="1">
1784
+ <svg class="o-icon" viewBox="0 0 512 512">
1785
+ <path
1786
+ fill="currentColor"
1787
+ 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"
1788
+ />
1789
+ </svg>
1790
+ </t>
1791
+ /** Font Awesome by Dave Gandy
1792
+ * http://fontawesome.io/
1793
+ * https://fontawesome.com/license
1794
+ */
1795
+ <t t-name="o-spreadsheet-Icon.CARET_UP" owl="1">
1796
+ <svg class="caret-up" viewBox="0 0 320 512">
1797
+ <path
1798
+ fill="currentColor"
1799
+ 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"
1800
+ />
1801
+ </svg>
1802
+ </t>
1803
+ <t t-name="o-spreadsheet-Icon.CARET_DOWN" owl="1">
1804
+ <svg class="caret-down" viewBox="0 0 320 512">
1805
+ <path
1806
+ fill="currentColor"
1807
+ 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"
1808
+ />
1809
+ </svg>
1810
+ </t>
1811
+ <t t-name="o-spreadsheet-Icon.CARET_RIGHT" owl="1">
1812
+ <svg class="o-icon caret-right" viewBox="0 0 192 512">
1813
+ <path
1814
+ 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"
1815
+ />
1816
+ </svg>
1817
+ </t>
1818
+ <t t-name="o-spreadsheet-Icon.CARET_LEFT" owl="1">
1819
+ <svg class="o-icon caret-left" viewBox="0 0 192 512">
1820
+ <path
1821
+ 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"
1822
+ />
1823
+ </svg>
1824
+ </t>
1825
+
1826
+ <t t-name="o-spreadsheet-Icon.TRASH" owl="1">
1827
+ <svg class="o-cf-icon trash" viewBox="0 0 448 512">
1828
+ <path
1829
+ fill="currentColor"
1830
+ 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"
1831
+ />
1832
+ </svg>
1833
+ </t>
1834
+ <t t-name="o-spreadsheet-Icon.REFRESH" owl="1">
1835
+ <svg class="o-cf-icon refresh" viewBox="0 0 512 512">
1836
+ <path
1837
+ fill="currentColor"
1838
+ 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"
1839
+ />
1840
+ </svg>
1841
+ </t>
1842
+
1843
+ <t t-name="o-spreadsheet-Icon.ARROW_DOWN" owl="1">
1844
+ <svg
1845
+ class="o-cf-icon arrow-down"
1846
+ width="10"
1847
+ height="10"
1848
+ focusable="false"
1849
+ viewBox="0 0 448 512">
1850
+ <path
1851
+ fill="#DC6965"
1852
+ t-att-style="color"
1853
+ d="M413.1 222.5l22.2 22.2c9.4 9.4 9.4 24.6 0 33.9L241 473c-9.4 9.4-24.6 9.4-33.9 0L12.7 278.6c-9.4-9.4-9.4-24.6 0-33.9l22.2-22.2c9.5-9.5 25-9.3 34.3.4L184 343.4V56c0-13.3 10.7-24 24-24h32c13.3 0 24 10.7 24 24v287.4l114.8-120.5c9.3-9.8 24.8-10 34.3-.4z"
1854
+ />
1855
+ </svg>
1856
+ </t>
1857
+ <t t-name="o-spreadsheet-Icon.ARROW_UP" owl="1">
1858
+ <svg class="o-cf-icon arrow-up" width="10" height="10" focusable="false" viewBox="0 0 448 512">
1859
+ <path
1860
+ fill="#00A04A"
1861
+ t-att-style="color"
1862
+ d="M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z"
1863
+ />
1864
+ </svg>
1865
+ </t>
1866
+ <t t-name="o-spreadsheet-Icon.ARROW_RIGHT" owl="1">
1867
+ <svg
1868
+ class="o-cf-icon arrow-right"
1869
+ width="10"
1870
+ height="10"
1871
+ focusable="false"
1872
+ viewBox="0 0 448 512">
1873
+ <path
1874
+ fill="#F0AD4E"
1875
+ d="M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z"
1876
+ />
1877
+ </svg>
1878
+ </t>
1879
+
1880
+ <t t-name="o-spreadsheet-Icon.SMILE" owl="1">
1881
+ <svg class="o-cf-icon smile" width="10" height="10" focusable="false" viewBox="0 0 496 512">
1882
+ <path
1883
+ fill="#00A04A"
1884
+ d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160 0c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm4 72.6c-20.8 25-51.5 39.4-84 39.4s-63.2-14.3-84-39.4c-8.5-10.2-23.7-11.5-33.8-3.1-10.2 8.5-11.5 23.6-3.1 33.8 30 36 74.1 56.6 120.9 56.6s90.9-20.6 120.9-56.6c8.5-10.2 7.1-25.3-3.1-33.8-10.1-8.4-25.3-7.1-33.8 3.1z"
1885
+ />
1886
+ </svg>
1887
+ </t>
1888
+ <t t-name="o-spreadsheet-Icon.MEH" owl="1">
1889
+ <svg class="o-cf-icon meh" width="10" height="10" focusable="false" viewBox="0 0 496 512">
1890
+ <path
1891
+ fill="#F0AD4E"
1892
+ d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-64c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm8 144H160c-13.2 0-24 10.8-24 24s10.8 24 24 24h176c13.2 0 24-10.8 24-24s-10.8-24-24-24z"
1893
+ />
1894
+ </svg>
1895
+ </t>
1896
+ <t t-name="o-spreadsheet-Icon.FROWN" owl="1">
1897
+ <svg class="o-cf-icon frown" width="10" height="10" focusable="false" viewBox="0 0 496 512">
1898
+ <path
1899
+ fill="#DC6965"
1900
+ d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-64c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm-80 128c-40.2 0-78 17.7-103.8 48.6-8.5 10.2-7.1 25.3 3.1 33.8 10.2 8.4 25.3 7.1 33.8-3.1 16.6-19.9 41-31.4 66.9-31.4s50.3 11.4 66.9 31.4c8.1 9.7 23.1 11.9 33.8 3.1 10.2-8.5 11.5-23.6 3.1-33.8C326 321.7 288.2 304 248 304z"
1901
+ />
1902
+ </svg>
1903
+ </t>
1904
+
1905
+ <t t-name="o-spreadsheet-Icon.GREEN_DOT" owl="1">
1906
+ <svg class="o-cf-icon green-dot" width="10" height="10" focusable="false" viewBox="0 0 512 512">
1907
+ <path
1908
+ fill="#00A04A"
1909
+ d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"
1910
+ />
1911
+ </svg>
1912
+ </t>
1913
+ <t t-name="o-spreadsheet-Icon.YELLOW_DOT" owl="1">
1914
+ <svg
1915
+ class="o-cf-icon yellow-dot"
1916
+ width="10"
1917
+ height="10"
1918
+ focusable="false"
1919
+ viewBox="0 0 512 512">
1920
+ <path
1921
+ fill="#F0AD4E"
1922
+ d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"
1923
+ />
1924
+ </svg>
1925
+ </t>
1926
+ <t t-name="o-spreadsheet-Icon.RED_DOT" owl="1">
1927
+ <svg class="o-cf-icon red-dot" width="10" height="10" focusable="false" viewBox="0 0 512 512">
1928
+ <path
1929
+ fill="#DC6965"
1930
+ d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"
1931
+ />
1932
+ </svg>
1933
+ </t>
1934
+ <t t-name="o-spreadsheet-Icon.SORT_RANGE" owl="1">
1935
+ <svg class="o-icon">
1936
+ <path
1937
+ fill="currentColor"
1938
+ d="M9 3.5h8v2H9M9 8h6v2H9m0 2.5h3v2H9M6 6l1-1-3-3-3 3 1 1 1-1v8l-1-1-1 1 3 3 3-3-1-1-1 1V5"
1939
+ />
1940
+ </svg>
1941
+ </t>
1942
+ <t t-name="o-spreadsheet-Icon.SORT_ASCENDING" owl="1">
1943
+ <svg class="o-icon" fill="currentColor">
1944
+ <path d="m3 13-1-1-1 1 3 3 3-3-1-1-1 1V0H3"/>
1945
+ <text x="9" y="7" class="small-text">A</text>
1946
+ <text x="9.3" y="15" class="small-text">Z</text>
1947
+ </svg>
1948
+ </t>
1949
+ <t t-name="o-spreadsheet-Icon.SORT_DESCENDING" owl="1">
1950
+ <svg class="o-icon" fill="currentColor">
1951
+ <path d="m3 13.9-1-1-1 1 3 3 3-3-1-1-1 1V.9H3"/>
1952
+ <text x="9.3" y="7.9" class="small-text">Z</text>
1953
+ <text x="9" y="15.9" class="small-text">A</text>
1954
+ </svg>
1955
+ </t>
1956
+ <t t-name="o-spreadsheet-Icon.FILTER_ICON" owl="1">
1957
+ <svg
1958
+ class="o-cf-icon filter-icon"
1959
+ width="10"
1960
+ height="10"
1961
+ focusable="false"
1962
+ viewBox="0 0 850 850">
1963
+ <path
1964
+ fill="currentColor"
1965
+ d="M 339.667 681 L 510.333 681 L 510.333 595.667 L 339.667 595.667 L 339.667 681 Z M 41 169 L 41 254.333 L 809 254.333 L 809 169 L 41 169 Z M 169 467.667 L 681 467.667 L 681 382.333 L 169 382.333 L 169 467.667 Z"
1966
+ />
1967
+ </svg>
1968
+ </t>
1969
+ <t t-name="o-spreadsheet-Icon.FILTER_ICON_ACTIVE" owl="1">
1970
+ <svg
1971
+ class="o-cf-icon filter-icon-active"
1972
+ width="10"
1973
+ height="10"
1974
+ focusable="false"
1975
+ viewBox="0 0 512 512">
1976
+ <path
1977
+ fill="currentColor"
1978
+ d="M487.976 0H24.028C2.71 0-8.047 25.866 7.058 40.971L192 225.941V432c0 7.831 3.821 15.17 10.237 19.662l80 55.98C298.02 518.69 320 507.493 320 487.98V225.941l184.947-184.97C520.021 25.896 509.338 0 487.976 0z"
1979
+ />
1980
+ </svg>
1981
+ </t>
1982
+ <t t-name="o-spreadsheet-Icon.FILTER_ICON_INACTIVE" owl="1">
1983
+ <svg
1984
+ class="o-cf-icon filter-icon-inactive"
1985
+ width="10"
1986
+ height="10"
1987
+ focusable="false"
1988
+ viewBox="0 0 512 512">
1989
+ <path
1990
+ fill="currentColor"
1991
+ d="M487.976 0H24.028C2.71 0-8.047 25.866 7.058 40.971L192 225.941V432c0 7.831 3.821 15.17 10.237 19.662l80 55.98C298.02 518.69 320 507.493 320 487.98V225.941l184.947-184.97C520.021 25.896 509.338 0 487.976 0z"
1992
+ />
1993
+ </svg>
1994
+ </t>
1995
+ <t t-name="o-spreadsheet-Icon.MENU_FILTER_ICON" owl="1">
1996
+ <svg class="o-icon">
1997
+ <path
1998
+ fill="currentColor"
1999
+ 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"
2000
+ />
2001
+ </svg>
2002
+ </t>
2003
+ <t t-name="o-spreadsheet-Icon.SEARCH" owl="1">
2004
+ <svg class="search-icon" width="10" height="10" focusable="false" viewBox="0 0 512 512">
2005
+ <path
2006
+ fill="currentColor"
2007
+ 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"
2008
+ />
2009
+ </svg>
2010
+ </t>
2011
+ <t t-name="o-spreadsheet-Icon.CHECK" owl="1">
2012
+ <svg class="o-icon" viewBox="0 0 24 24">
2013
+ <path
2014
+ fill="currentColor"
2015
+ d="M18.707 7.293a1 1 0 0 1 0 1.414L11.414 16a2 2 0 0 1-2.828 0l-3.293-3.293a1 1 0 1 1 1.414-1.414L10 14.586l7.293-7.293a1 1 0 0 1 1.414 0z"
2016
+ />
2017
+ </svg>
2018
+ </t>
2019
+ <t t-name="o-spreadsheet-Icon.PERCENT" owl="1">
2020
+ <span class="o-text-icon">%</span>
2021
+ </t>
2022
+ <t t-name="o-spreadsheet-Icon.DECRASE_DECIMAL" owl="1">
2023
+ <span class="o-text-icon">.0</span>
2024
+ </t>
2025
+ <t t-name="o-spreadsheet-Icon.INCREASE_DECIMAL" owl="1">
2026
+ <span class="o-text-icon">.00</span>
2027
+ </t>
2028
+ <t t-name="o-spreadsheet-Icon.NUMBER_FORMATS" owl="1">
2029
+ <svg class="o-icon" fill="currentColor">
2030
+ <path
2031
+ d="M0 6h2v8h2V4H0m9 0H5v2h4v2H6.5A1.5 1.5 0 0 0 5 9.5V14h6v-2H7v-2h2.5A1.5 1.5 0 0 0 11 8.5v-3A1.5 1.5 0 0 0 9.5 4M12 4v2h4v2h-2v2h2v2h-4v2h4.5a1.5 1.5 0 0 0 1.5-1.5v-2A1.5 1.5 0 0 0 16.5 9 1.5 1.5 0 0 0 18 7.5v-2A1.5 1.5 0 0 0 16.5 4"
2032
+ />
2033
+ </svg>
2034
+ </t>
2035
+ <t t-name="o-spreadsheet-Icon.FONT_SIZE" owl="1">
2036
+ <svg class="o-icon" fill="currentColor">
2037
+ <text x="2" y="15" class="small-text">A</text>
2038
+ <text x="6" y="15" class="heavy-text">A</text>
2039
+ </svg>
2040
+ </t>
2041
+ <t t-name="o-spreadsheet-Icon.TRIANGLE_EXCLAMATION" owl="1">
2042
+ <svg class="o-icon" viewBox="0 0 512 512">
2043
+ <path
2044
+ fill="currentColor"
2045
+ 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"
2046
+ />
2047
+ </svg>
2048
+ </t>
2049
+ <t t-name="o-spreadsheet-Icon.SPLIT_TEXT" owl="1">
2050
+ <svg class="o-icon">
2051
+ <path
2052
+ fill="currentColor"
2053
+ d="M14 6v2h-4v2h4v2l3-3m-9 1V8H4V6L1 9l3 3v-2m3.5-6.5h3V7H12V3.5h3V2H3v1.5h3V7h1.5m3 7.5h-3V11H6v3.5H3V16h12v-1.5h-3V11h-1.5"
2054
+ />
2055
+ </svg>
2056
+ </t>
2057
+ <t t-name="o-spreadsheet-Icon.DISPLAY_HEADER" owl="1">
2058
+ <svg class="o-icon" width="18" height="18">
2059
+ <path
2060
+ fill="currentColor"
2061
+ d="M.75.5h16.5v17H.75m1.5-12H.75V7h1.5v1.5H.75V10h1.5v1.5H.75V13h1.5v1.5H.75V16h1.5v1.5h1.5V16h1.5v1.5h1.5V16h1.5v1.5h1.5V16h1.5v1.5h1.5V16h1.5v1.5h1.5V16h1.5v-1.5h-1.5V13h1.5v-1.5h-1.5V10h1.5V8.5h-1.5V7h1.5V5.5M2.75 2.25v1.5h2v-1.5m2.5 0v1.5h7v-1.5"
2062
+ />
2063
+ </svg>
2064
+ </t>
2065
+
2066
+ <t t-name="o-spreadsheet-LinkDisplay" owl="1">
2067
+ <div class="o-link-tool d-flex align-items-center">
2068
+ <!-- t-key to prevent owl from re-using the previous img element when the link changes.
2069
+ The wrong/previous image would be displayed while the new one loads -->
2070
+ <img
2071
+ t-if="link.isExternal"
2072
+ t-key="link.url"
2073
+ t-attf-src="https://www.google.com/s2/favicons?sz=16&amp;domain={{link.url}}"
2074
+ />
2075
+ <a
2076
+ t-if="link.isExternal"
2077
+ class="o-link"
2078
+ t-att-href="link.url"
2079
+ target="_blank"
2080
+ t-on-click.prevent="openLink"
2081
+ t-att-title="link.url">
2082
+ <t t-esc="getUrlRepresentation(link)"/>
2083
+ </a>
2084
+ <a
2085
+ t-else=""
2086
+ class="o-link"
2087
+ t-on-click.prevent="openLink"
2088
+ t-att-title="getUrlRepresentation(link)">
2089
+ <t t-esc="getUrlRepresentation(link)"/>
2090
+ </a>
2091
+ <span
2092
+ t-if="!env.model.getters.isReadonly()"
2093
+ class="o-link-icon o-unlink"
2094
+ t-on-click="unlink"
2095
+ title="Remove link">
2096
+ <t t-call="o-spreadsheet-Icon.UNLINK"/>
2097
+ </span>
2098
+ <span
2099
+ t-if="!env.model.getters.isReadonly()"
2100
+ class="o-link-icon o-edit-link"
2101
+ t-on-click="edit"
2102
+ title="Edit link">
2103
+ <t t-call="o-spreadsheet-Icon.EDIT"/>
2104
+ </span>
2105
+ </div>
2106
+ </t>
2107
+
2108
+ <t t-name="o-spreadsheet-LinkEditor" owl="1">
2109
+ <div
2110
+ class="o-link-editor"
2111
+ t-on-click.stop="() => this.menu.isOpen=false"
2112
+ t-on-keydown="onKeyDown"
2113
+ t-ref="linkEditor">
2114
+ <div class="o-section">
2115
+ <div class="o-section-title">Text</div>
2116
+ <div class="d-flex">
2117
+ <input type="text" title="Link label" class="o-input flex-grow-1" t-model="link.label"/>
2118
+ </div>
2119
+
2120
+ <div class="o-section-title mt-3">Link</div>
2121
+ <div class="o-link-url">
2122
+ <t t-if="link.isUrlEditable">
2123
+ <input type="text" title="Link URL" t-ref="urlInput" t-model="link.url"/>
2124
+ </t>
2125
+ <t t-else="">
2126
+ <input
2127
+ type="text"
2128
+ title="Link URL"
2129
+ t-att-value="getUrlRepresentation(link)"
2130
+ disabled="1"
2131
+ />
2132
+ </t>
2133
+ <button t-if="link.url" t-on-click="removeLink" class="o-remove-url">✖</button>
2134
+ <button t-if="!link.url" t-on-click.stop="openMenu" class="o-special-link">
2135
+ <t t-call="o-spreadsheet-Icon.LIST"/>
2136
+ </button>
2137
+ </div>
2138
+ </div>
2139
+ <Menu
2140
+ t-if="menu.isOpen"
2141
+ position="menuPosition"
2142
+ menuItems="menuItems"
2143
+ onMenuClicked="(ev) => this.onSpecialLink(ev)"
2144
+ onClose="() => this.menu.isOpen=false"
2145
+ />
2146
+ <div class="o-buttons">
2147
+ <button t-on-click="cancel" class="o-button o-cancel">Cancel</button>
2148
+ <button t-on-click="save" class="o-button o-save" t-att-disabled="!link.url">
2149
+ Confirm
2150
+ </button>
2151
+ </div>
2152
+ </div>
2153
+ </t>
2154
+
2155
+ <t t-name="o-spreadsheet-Menu" owl="1">
2156
+ <Popover t-if="menuItemsAndSeparators.length" t-props="popoverProps">
2157
+ <div
2158
+ t-ref="menu"
2159
+ class="o-menu"
2160
+ t-on-scroll="onScroll"
2161
+ t-on-wheel.stop=""
2162
+ t-on-click.stop=""
2163
+ t-on-contextmenu.prevent="">
2164
+ <t t-foreach="menuItemsAndSeparators" t-as="menuItem" t-key="menuItem_index">
2165
+ <div t-if="menuItem === 'separator'" class="o-separator"/>
2166
+ <t t-else="">
2167
+ <t t-set="isMenuRoot" t-value="isRoot(menuItem)"/>
2168
+ <t t-set="isMenuEnabled" t-value="isEnabled(menuItem)"/>
2169
+ <div
2170
+ t-att-title="getName(menuItem)"
2171
+ t-att-data-name="menuItem.id"
2172
+ t-on-click="(ev) => this.onClickMenu(menuItem, menuItem_index, ev)"
2173
+ t-on-mouseover="(ev) => this.onMouseOver(menuItem, menuItem_index, ev)"
2174
+ class="o-menu-item"
2175
+ t-att-class="{ 'o-menu-root': isMenuRoot, 'disabled': !isMenuEnabled, 'o-menu-item-active': isParentMenu(subMenu, menuItem)}"
2176
+ t-att-style="getColor(menuItem)">
2177
+ <div class="d-flex w-100">
2178
+ <div t-if="childrenHaveIcon" class="o-menu-item-icon align-middle">
2179
+ <t t-if="getIconName(menuItem)" t-call="{{getIconName(menuItem)}}"/>
2180
+ </div>
2181
+ <div class="o-menu-item-name align-middle text-truncate" t-esc="getName(menuItem)"/>
2182
+ <div
2183
+ t-if="menuItem.description"
2184
+ class="o-menu-item-description ms-auto"
2185
+ t-esc="menuItem.description"
2186
+ />
2187
+ <div
2188
+ t-if="isMenuRoot"
2189
+ class="o-menu-item-root align-middle ms-auto"
2190
+ t-call="o-spreadsheet-Icon.TRIANGLE_RIGHT"
2191
+ />
2192
+ </div>
2193
+ </div>
2194
+ </t>
2195
+ </t>
2196
+ </div>
2197
+ <Menu
2198
+ t-if="subMenu.isOpen"
2199
+ position="subMenuPosition"
2200
+ menuItems="subMenu.menuItems"
2201
+ depth="props.depth + 1"
2202
+ maxHeight="props.maxHeight"
2203
+ onMenuClicked="props.onMenuClicked"
2204
+ onClose="() => this.close()"
2205
+ menuId="props.menuId"
2206
+ />
2207
+ </Popover>
2208
+ </t>
2209
+
2210
+ <t t-name="o-spreadsheet-Popover" owl="1">
2211
+ <t t-portal="'.o-spreadsheet'">
2212
+ <div
2213
+ class="o-popover"
2214
+ t-ref="popover"
2215
+ t-on-wheel="props.onMouseWheel"
2216
+ t-att-style="popoverStyle">
2217
+ <t t-slot="default"/>
2218
+ </div>
2219
+ </t>
2220
+ </t>
2221
+
2222
+ <t t-name="o-spreadsheet-ScrollBar" owl="1">
2223
+ <div class="o-scrollbar" t-on-scroll="onScroll" t-ref="scrollbar" t-att-style="positionCss">
2224
+ <div t-att-style="sizeCss"/>
2225
+ </div>
2226
+ </t>
2227
+
2228
+ <t t-name="o-spreadsheet-SelectionInput" owl="1">
2229
+ <div class="o-selection">
2230
+ <div
2231
+ t-foreach="ranges"
2232
+ t-as="range"
2233
+ t-key="range.id"
2234
+ class="o-selection-input"
2235
+ t-att-class="props.class">
2236
+ <input
2237
+ type="text"
2238
+ spellcheck="false"
2239
+ t-on-input="(ev) => this.onInputChanged(range.id, ev)"
2240
+ t-on-focus="() => this.focus(range.id)"
2241
+ t-on-keydown="onKeydown"
2242
+ t-att-value="range.xc"
2243
+ t-att-style="getColor(range)"
2244
+ t-att-class="{
2245
+ 'o-focused' : range.isFocused,
2246
+ 'o-required': props.required,
2247
+ 'o-optional': !props.required,
2248
+ 'o-invalid': isInvalid || !range.isValidRange,
2249
+ 'text-decoration-underline': range.isFocused and state.mode === 'select-range'
2250
+ }"
2251
+ t-ref="{{range.isFocused ? 'focusedInput' : 'unfocusedInput' + range_index}}"
2252
+ />
2253
+ <button
2254
+ class="o-btn o-remove-selection"
2255
+ t-if="ranges.length > 1"
2256
+ t-on-click="() => this.removeInput(range.id)">
2257
+ ✕
2258
+ </button>
2259
+ </div>
2260
+
2261
+ <div class="o-selection-input">
2262
+ <button class="o-btn-action o-add-selection" t-if="canAddRange" t-on-click="addEmptyInput">
2263
+ Add range
2264
+ </button>
2265
+ <button class="o-btn-action o-selection-ok" t-if="hasFocus" t-on-click="confirm">
2266
+ Confirm
2267
+ </button>
2268
+ </div>
2269
+ </div>
2270
+ </t>
2271
+
2272
+ <t t-name="o-spreadsheet-BarConfigPanel" owl="1">
2273
+ <div>
2274
+ <div class="o-section pt-0">
2275
+ <div class="o-checkbox">
2276
+ <label>
2277
+ <input
2278
+ type="checkbox"
2279
+ name="stacked"
2280
+ t-att-checked="props.definition.stacked"
2281
+ t-on-change="onUpdateStacked"
2282
+ class="align-middle"
2283
+ />
2284
+ Stacked barchart
2285
+ </label>
2286
+ </div>
2287
+ </div>
2288
+ <div class="o-section o-data-series">
2289
+ <div class="o-section-title">Data Series</div>
2290
+ <SelectionInput
2291
+ ranges="dataSeriesRanges"
2292
+ isInvalid="isDatasetInvalid"
2293
+ required="true"
2294
+ onSelectionChanged="(ranges) => this.onDataSeriesRangesChanged(ranges)"
2295
+ onSelectionConfirmed="() => this.onDataSeriesConfirmed()"
2296
+ />
2297
+ </div>
2298
+ <div class="o-section o-data-labels">
2299
+ <div class="o-section-title">Categories / Labels</div>
2300
+ <SelectionInput
2301
+ ranges="[props.definition.labelRange || '']"
2302
+ isInvalid="isLabelInvalid"
2303
+ hasSingleRange="true"
2304
+ onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
2305
+ onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
2306
+ />
2307
+ <label>
2308
+ <input
2309
+ type="checkbox"
2310
+ name="aggregated"
2311
+ t-att-checked="props.definition.aggregated"
2312
+ t-on-change="onUpdateAggregated"
2313
+ class="align-middle"
2314
+ />
2315
+ Aggregate
2316
+ </label>
2317
+ </div>
2318
+ <div class="o-section o-use-row-as-headers" t-if="calculateHeaderPosition()">
2319
+ <label>
2320
+ <input
2321
+ type="checkbox"
2322
+ t-att-checked="props.definition.dataSetsHaveTitle"
2323
+ t-on-change="onUpdateDataSetsHaveTitle"
2324
+ class="align-middle"
2325
+ />
2326
+ Use row
2327
+ <span t-esc="calculateHeaderPosition()"/>
2328
+ as headers
2329
+ </label>
2330
+ </div>
2331
+ <div class="o-section o-sidepanel-error" t-if="errorMessages">
2332
+ <div t-foreach="errorMessages" t-as="error" t-key="error">
2333
+ <t t-esc="error"/>
2334
+ </div>
2335
+ </div>
2336
+ </div>
2337
+ </t>
2338
+
2339
+ <t t-name="o-spreadsheet-BarChartDesignPanel" owl="1">
2340
+ <div>
2341
+ <div class="o-section o-chart-background-color">
2342
+ <div class="o-section-title">Background color</div>
2343
+ <div class="d-flex align-items-center">
2344
+ <span class="pe-1">Select a color...</span>
2345
+ <ColorPickerWidget
2346
+ currentColor="props.definition.background"
2347
+ toggleColorPicker="() => this.toggleColorPicker()"
2348
+ showColorPicker="state.fillColorTool"
2349
+ onColorPicked="(color) => this.updateBackgroundColor(color)"
2350
+ title="env._t('Background Color')"
2351
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2352
+ />
2353
+ </div>
2354
+ </div>
2355
+ <div class="o-section o-chart-title">
2356
+ <div class="o-section-title">Title</div>
2357
+ <input
2358
+ type="text"
2359
+ t-att-value="env._t(props.definition.title)"
2360
+ t-on-change="updateTitle"
2361
+ class="o-input o-optional"
2362
+ placeholder="New Chart"
2363
+ />
2364
+ </div>
2365
+ <div class="o-section">
2366
+ <div class="o-section-title">Vertical axis position</div>
2367
+ <select
2368
+ t-att-value="props.definition.verticalAxisPosition"
2369
+ class="o-input o-type-selector"
2370
+ t-on-change="(ev) => this.updateSelect('verticalAxisPosition', ev)">
2371
+ <option value="left">Left</option>
2372
+ <option value="right">Right</option>
2373
+ </select>
2374
+ </div>
2375
+ <div class="o-section">
2376
+ <div class="o-section-title">Legend position</div>
2377
+ <select
2378
+ t-att-value="props.definition.legendPosition"
2379
+ class="o-input o-type-selector"
2380
+ t-on-change="(ev) => this.updateSelect('legendPosition', ev)">
2381
+ <option value="none">None</option>
2382
+ <option value="top">Top</option>
2383
+ <option value="bottom">Bottom</option>
2384
+ <option value="left">Left</option>
2385
+ <option value="right">Right</option>
2386
+ </select>
2387
+ </div>
2388
+ </div>
2389
+ </t>
2390
+
2391
+ <t t-name="o-spreadsheet-GaugeChartConfigPanel" owl="1">
2392
+ <div>
2393
+ <div class="o-section o-data-series">
2394
+ <div class="o-section-title">Data range</div>
2395
+ <SelectionInput
2396
+ ranges="[props.definition.dataRange || '']"
2397
+ isInvalid="isDataRangeInvalid"
2398
+ hasSingleRange="true"
2399
+ required="true"
2400
+ onSelectionChanged="(ranges) => this.onDataRangeChanged(ranges)"
2401
+ onSelectionConfirmed="() => this.updateDataRange()"
2402
+ />
2403
+ </div>
2404
+ <div class="o-section o-sidepanel-error" t-if="configurationErrorMessages">
2405
+ <div t-foreach="configurationErrorMessages" t-as="error" t-key="error">
2406
+ <t t-esc="error"/>
2407
+ </div>
2408
+ </div>
2409
+ </div>
2410
+ </t>
2411
+
2412
+ <t t-name="o-spreadsheet-GaugeChartDesignPanel" owl="1">
2413
+ <div>
2414
+ <div class="o-section o-chart-background-color">
2415
+ <div class="o-section-title">Background color</div>
2416
+ <div class="d-flex align-items-center">
2417
+ <span class="pe-1">Select a color...</span>
2418
+ <ColorPickerWidget
2419
+ currentColor="props.definition.background"
2420
+ toggleColorPicker="() => this.toggleMenu('backgroundColor', ev)"
2421
+ showColorPicker="state.openedMenu === 'backgroundColor'"
2422
+ onColorPicked="(color) => this.updateBackgroundColor(color)"
2423
+ title="env._t('Background Color')"
2424
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2425
+ />
2426
+ </div>
2427
+ </div>
2428
+
2429
+ <div class="o-section o-chart-title">
2430
+ <div class="o-section-title">Title</div>
2431
+ <input
2432
+ type="text"
2433
+ t-att-value="env._t(props.definition.title)"
2434
+ t-on-change="updateTitle"
2435
+ class="o-input o-optional"
2436
+ placeholder="New Chart"
2437
+ />
2438
+ </div>
2439
+
2440
+ <div class="o-section">
2441
+ <div class="o-section-title">Range</div>
2442
+ <div class="o-subsection-left">
2443
+ <input
2444
+ type="text"
2445
+ t-att-value="props.definition.sectionRule.rangeMin"
2446
+ t-on-change="updateRangeMin"
2447
+ class="o-input o-data-range-min"
2448
+ t-att-class="{ 'o-invalid': isRangeMinInvalid() }"
2449
+ />
2450
+ </div>
2451
+ <div class="o-subsection-right">
2452
+ <input
2453
+ type="text"
2454
+ t-att-value="props.definition.sectionRule.rangeMax"
2455
+ t-on-change="updateRangeMax"
2456
+ class="o-input o-data-range-max"
2457
+ t-att-class="{ 'o-invalid': isRangeMaxInvalid() }"
2458
+ />
2459
+ </div>
2460
+ </div>
2461
+
2462
+ <div class="o-section">
2463
+ <div class="o-section-title">Thresholds</div>
2464
+ <t t-call="o-spreadsheet-GaugeChartColorSectionTemplate">
2465
+ <t t-set="sectionRule" t-value="props.definition.sectionRule"/>
2466
+ </t>
2467
+ </div>
2468
+
2469
+ <div class="o-section o-sidepanel-error" t-if="designErrorMessages.length">
2470
+ <div t-foreach="designErrorMessages" t-as="error" t-key="error">
2471
+ <t t-esc="error"/>
2472
+ </div>
2473
+ </div>
2474
+ </div>
2475
+ </t>
2476
+
2477
+ <t t-name="o-spreadsheet-GaugeChartColorSectionTemplate" owl="1">
2478
+ <div class="o-gauge-color-set">
2479
+ <table>
2480
+ <tr>
2481
+ <th class="o-gauge-color-set-colorPicker"/>
2482
+ <th class="o-gauge-color-set-text"/>
2483
+ <th class="o-gauge-color-set-value">Value</th>
2484
+ <th class="o-gauge-color-set-type">Type</th>
2485
+ </tr>
2486
+
2487
+ <t t-call="o-spreadsheet-GaugeChartColorSectionTemplateRow">
2488
+ <t t-set="sectionColor" t-value="sectionRule.colors.lowerColor"/>
2489
+ <t t-set="sectionType" t-value="'lowerColor'"/>
2490
+ <t t-set="inflectionPoint" t-value="sectionRule.lowerInflectionPoint"/>
2491
+ <t t-set="isInvalid" t-value="isLowerInflectionPointInvalid"/>
2492
+ <t t-set="inflectionPointName" t-value="'lowerInflectionPoint'"/>
2493
+ </t>
2494
+
2495
+ <t t-call="o-spreadsheet-GaugeChartColorSectionTemplateRow">
2496
+ <t t-set="sectionColor" t-value="sectionRule.colors.middleColor"/>
2497
+ <t t-set="sectionType" t-value="'middleColor'"/>
2498
+ <t t-set="inflectionPoint" t-value="sectionRule.upperInflectionPoint"/>
2499
+ <t t-set="isInvalid" t-value="isUpperInflectionPointInvalid"/>
2500
+ <t t-set="inflectionPointName" t-value="'upperInflectionPoint'"/>
2501
+ </t>
2502
+
2503
+ <tr>
2504
+ <td>
2505
+ <ColorPickerWidget
2506
+ currentColor="sectionRule.colors.upperColor"
2507
+ toggleColorPicker="(ev) => this.toggleMenu('sectionColor-upperColor', ev)"
2508
+ showColorPicker="state.openedMenu === 'sectionColor-upperColor'"
2509
+ onColorPicked="(color) => this.updateSectionColor('upperColor', color)"
2510
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2511
+ />
2512
+ </td>
2513
+ <td>Else</td>
2514
+ <td/>
2515
+ <td/>
2516
+ <td/>
2517
+ </tr>
2518
+ </table>
2519
+ </div>
2520
+ </t>
2521
+
2522
+ <t t-name="o-spreadsheet-GaugeChartColorSectionTemplateRow" owl="1">
2523
+ <tr>
2524
+ <td>
2525
+ <ColorPickerWidget
2526
+ currentColor="sectionColor"
2527
+ toggleColorPicker="(ev) => this.toggleMenu('sectionColor-'+sectionType, ev)"
2528
+ showColorPicker="state.openedMenu === 'sectionColor-'+sectionType"
2529
+ onColorPicked="(color) => this.updateSectionColor(sectionType, color)"
2530
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2531
+ />
2532
+ </td>
2533
+ <td>When value is below</td>
2534
+ <td>
2535
+ <input
2536
+ type="text"
2537
+ class="o-input"
2538
+ t-on-change="(ev) => this.updateInflectionPointValue(inflectionPointName, ev)"
2539
+ t-attf-class="o-input-{{inflectionPointName}}"
2540
+ t-att-class="{ 'o-invalid': isInvalid }"
2541
+ t-model="inflectionPoint.value"
2542
+ />
2543
+ </td>
2544
+ <td>
2545
+ <select
2546
+ class="o-input"
2547
+ name="valueType"
2548
+ t-model="inflectionPoint.type"
2549
+ t-on-change="(ev) => this.updateInflectionPointType(inflectionPointName, ev)">
2550
+ <option value="number">Number</option>
2551
+ <option value="percentage">Percentage</option>
2552
+ </select>
2553
+ </td>
2554
+ </tr>
2555
+ </t>
2556
+
2557
+ <t t-name="o-spreadsheet-LineBarPieConfigPanel" owl="1">
2558
+ <div>
2559
+ <div class="o-section o-data-series">
2560
+ <div class="o-section-title">Data Series</div>
2561
+ <SelectionInput
2562
+ ranges="dataSeriesRanges"
2563
+ isInvalid="isDatasetInvalid"
2564
+ required="true"
2565
+ onSelectionChanged="(ranges) => this.onDataSeriesRangesChanged(ranges)"
2566
+ onSelectionConfirmed="() => this.onDataSeriesConfirmed()"
2567
+ />
2568
+ </div>
2569
+ <div class="o-section o-data-labels">
2570
+ <div class="o-section-title">Categories / Labels</div>
2571
+ <SelectionInput
2572
+ ranges="[props.definition.labelRange || '']"
2573
+ isInvalid="isLabelInvalid"
2574
+ hasSingleRange="true"
2575
+ onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
2576
+ onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
2577
+ />
2578
+ <label>
2579
+ <input
2580
+ type="checkbox"
2581
+ name="aggregated"
2582
+ t-att-checked="props.definition.aggregated"
2583
+ t-on-change="onUpdateAggregated"
2584
+ class="align-middle"
2585
+ />
2586
+ Aggregate
2587
+ </label>
2588
+ </div>
2589
+ <div class="o-section o-use-row-as-headers" t-if="calculateHeaderPosition()">
2590
+ <label>
2591
+ <input
2592
+ type="checkbox"
2593
+ t-att-checked="props.definition.dataSetsHaveTitle"
2594
+ t-on-change="onUpdateDataSetsHaveTitle"
2595
+ class="align-middle"
2596
+ />
2597
+ Use row
2598
+ <span t-esc="calculateHeaderPosition()"/>
2599
+ as headers
2600
+ </label>
2601
+ </div>
2602
+ <div class="o-section o-sidepanel-error" t-if="errorMessages">
2603
+ <div t-foreach="errorMessages" t-as="error" t-key="error">
2604
+ <t t-esc="error"/>
2605
+ </div>
2606
+ </div>
2607
+ </div>
2608
+ </t>
2609
+
2610
+ <t t-name="o-spreadsheet-LineBarPieDesignPanel" owl="1">
2611
+ <div>
2612
+ <div class="o-section o-chart-background-color">
2613
+ <div class="o-section-title">Background color</div>
2614
+ <div class="d-flex align-items-center">
2615
+ <span class="pe-1">Select a color...</span>
2616
+ <ColorPickerWidget
2617
+ currentColor="props.definition.background"
2618
+ toggleColorPicker="() => this.toggleColorPicker()"
2619
+ showColorPicker="state.fillColorTool"
2620
+ onColorPicked="(color) => this.updateBackgroundColor(color)"
2621
+ title="env._t('Background Color')"
2622
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2623
+ />
2624
+ </div>
2625
+ </div>
2626
+ <div class="o-section o-chart-title">
2627
+ <div class="o-section-title">Title</div>
2628
+ <input
2629
+ type="text"
2630
+ t-att-value="env._t(props.definition.title)"
2631
+ t-on-change="updateTitle"
2632
+ class="o-input o-optional"
2633
+ placeholder="New Chart"
2634
+ />
2635
+ </div>
2636
+ <div class="o-section">
2637
+ <div class="o-section-title">Legend position</div>
2638
+ <select
2639
+ t-att-value="props.definition.legendPosition"
2640
+ class="o-input o-type-selector"
2641
+ t-on-change="(ev) => this.updateSelect('legendPosition', ev)">
2642
+ <option value="none">None</option>
2643
+ <option value="top">Top</option>
2644
+ <option value="bottom">Bottom</option>
2645
+ <option value="left">Left</option>
2646
+ <option value="right">Right</option>
2647
+ </select>
2648
+ </div>
2649
+ </div>
2650
+ </t>
2651
+
2652
+ <t t-name="o-spreadsheet-LineConfigPanel" owl="1">
2653
+ <div>
2654
+ <div class="o-section pt-0">
2655
+ <div class="o-checkbox">
2656
+ <label>
2657
+ <input
2658
+ type="checkbox"
2659
+ name="stacked"
2660
+ t-att-checked="props.definition.stacked"
2661
+ t-on-change="onUpdateStacked"
2662
+ class="align-middle"
2663
+ />
2664
+ Stacked linechart
2665
+ </label>
2666
+ </div>
2667
+ <div class="o-checkbox">
2668
+ <label>
2669
+ <input
2670
+ type="checkbox"
2671
+ name="cumulative"
2672
+ t-att-checked="props.definition.cumulative"
2673
+ t-on-change="onUpdateCumulative"
2674
+ class="align-middle"
2675
+ />
2676
+ Cumulative data
2677
+ </label>
2678
+ </div>
2679
+ </div>
2680
+ <div class="o-section o-data-series">
2681
+ <div class="o-section-title">Data Series</div>
2682
+ <SelectionInput
2683
+ ranges="dataSeriesRanges"
2684
+ isInvalid="isDatasetInvalid"
2685
+ required="true"
2686
+ onSelectionChanged="(ranges) => this.onDataSeriesRangesChanged(ranges)"
2687
+ onSelectionConfirmed="() => this.onDataSeriesConfirmed()"
2688
+ />
2689
+ </div>
2690
+ <div class="o-section o-data-labels">
2691
+ <div class="o-section-title">Categories / Labels</div>
2692
+ <SelectionInput
2693
+ ranges="[props.definition.labelRange || '']"
2694
+ isInvalid="isLabelInvalid"
2695
+ hasSingleRange="true"
2696
+ onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
2697
+ onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
2698
+ />
2699
+ <label>
2700
+ <input
2701
+ type="checkbox"
2702
+ name="aggregated"
2703
+ t-att-checked="props.definition.aggregated"
2704
+ t-on-change="onUpdateAggregated"
2705
+ class="align-middle"
2706
+ />
2707
+ Aggregate
2708
+ </label>
2709
+ <div t-if="canTreatLabelsAsText">
2710
+ <label>
2711
+ <input
2712
+ type="checkbox"
2713
+ name="labelsAsText"
2714
+ t-att-checked="props.definition.labelsAsText"
2715
+ t-on-change="onUpdateLabelsAsText"
2716
+ />
2717
+ Treat labels as text
2718
+ </label>
2719
+ </div>
2720
+ </div>
2721
+ <div class="o-section o-use-row-as-headers" t-if="calculateHeaderPosition()">
2722
+ <label>
2723
+ <input
2724
+ type="checkbox"
2725
+ t-att-checked="props.definition.dataSetsHaveTitle"
2726
+ t-on-change="onUpdateDataSetsHaveTitle"
2727
+ class="align-middle"
2728
+ />
2729
+ Use row
2730
+ <span t-esc="calculateHeaderPosition()"/>
2731
+ as headers
2732
+ </label>
2733
+ </div>
2734
+ <div class="o-section o-sidepanel-error" t-if="errorMessages">
2735
+ <div t-foreach="errorMessages" t-as="error" t-key="error">
2736
+ <t t-esc="error"/>
2737
+ </div>
2738
+ </div>
2739
+ </div>
2740
+ </t>
2741
+
2742
+ <t t-name="o-spreadsheet-LineChartDesignPanel" owl="1">
2743
+ <div>
2744
+ <div class="o-section o-chart-background-color">
2745
+ <div class="o-section-title">Background color</div>
2746
+ <div class="d-flex align-items-center">
2747
+ <span class="pe-1">Select a color...</span>
2748
+ <ColorPickerWidget
2749
+ currentColor="props.definition.background"
2750
+ toggleColorPicker="() => this.toggleColorPicker()"
2751
+ showColorPicker="state.fillColorTool"
2752
+ onColorPicked="(color) => this.updateBackgroundColor(color)"
2753
+ title="env._t('Background Color')"
2754
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2755
+ />
2756
+ </div>
2757
+ </div>
2758
+ <div class="o-section o-chart-title">
2759
+ <div class="o-section-title">Title</div>
2760
+ <input
2761
+ type="text"
2762
+ t-att-value="props.definition.title"
2763
+ t-on-change="updateTitle"
2764
+ class="o-input o-optional"
2765
+ placeholder="New Chart"
2766
+ />
2767
+ </div>
2768
+ <div class="o-section">
2769
+ <div class="o-section-title">Vertical axis position</div>
2770
+ <select
2771
+ t-att-value="props.definition.verticalAxisPosition"
2772
+ class="o-input o-type-selector"
2773
+ t-on-change="(ev) => this.updateSelect('verticalAxisPosition', ev)">
2774
+ <option value="left">Left</option>
2775
+ <option value="right">Right</option>
2776
+ </select>
2777
+ </div>
2778
+ <div class="o-section">
2779
+ <div class="o-section-title">Legend position</div>
2780
+ <select
2781
+ t-att-value="props.definition.legendPosition"
2782
+ class="o-input o-type-selector"
2783
+ t-on-change="(ev) => this.updateSelect('legendPosition', ev)">
2784
+ <option value="none">None</option>
2785
+ <option value="top">Top</option>
2786
+ <option value="bottom">Bottom</option>
2787
+ <option value="left">Left</option>
2788
+ <option value="right">Right</option>
2789
+ </select>
2790
+ </div>
2791
+ </div>
2792
+ </t>
2793
+
2794
+ <t t-name="o-spreadsheet-ChartPanel" owl="1">
2795
+ <div class="o-chart">
2796
+ <div class="o-panel">
2797
+ <div
2798
+ class="o-panel-element o-panel-configuration"
2799
+ t-att-class="state.panel !== 'configuration' ? 'inactive' : ''"
2800
+ t-on-click="() => this.activatePanel('configuration')">
2801
+ <i class="fa fa-sliders"/>
2802
+ Configuration
2803
+ </div>
2804
+ <div
2805
+ class="o-panel-element o-panel-design"
2806
+ t-att-class="state.panel !== 'design' ? 'inactive' : ''"
2807
+ t-on-click="() => this.activatePanel('design')">
2808
+ <i class="fa fa-paint-brush"/>
2809
+ Design
2810
+ </div>
2811
+ </div>
2812
+
2813
+ <t t-set="definition" t-value="getChartDefinition()"/>
2814
+ <t t-if="state.panel === 'configuration'">
2815
+ <div class="o-section">
2816
+ <div class="o-section-title">Chart type</div>
2817
+ <t t-set="types" t-value="chartTypes"/>
2818
+ <select
2819
+ class="o-input o-type-selector"
2820
+ t-on-change="(ev) => this.onTypeChange(ev.target.value)">
2821
+ <option
2822
+ t-foreach="chartTypes"
2823
+ t-as="type"
2824
+ t-key="type"
2825
+ t-att-value="type"
2826
+ t-esc="types[type]"
2827
+ t-att-selected="definition.type === type"
2828
+ />
2829
+ </select>
2830
+ </div>
2831
+ <t
2832
+ t-component="chartPanel.configuration"
2833
+ definition="definition"
2834
+ figureId="figureId"
2835
+ updateChart.bind="updateChart"
2836
+ t-key="figureId + definition.type"
2837
+ />
2838
+ </t>
2839
+ <t t-else="">
2840
+ <t
2841
+ t-component="chartPanel.design"
2842
+ definition="definition"
2843
+ figureId="figureId"
2844
+ updateChart.bind="updateChart"
2845
+ t-key="figureId + definition.type"
2846
+ />
2847
+ </t>
2848
+ </div>
2849
+ </t>
2850
+
2851
+ <t t-name="o-spreadsheet-ScorecardChartConfigPanel" owl="1">
2852
+ <div>
2853
+ <div class="o-section o-data-series">
2854
+ <div class="o-section-title">Key value</div>
2855
+ <SelectionInput
2856
+ ranges="[props.definition.keyValue || '']"
2857
+ isInvalid="isKeyValueInvalid"
2858
+ hasSingleRange="true"
2859
+ required="true"
2860
+ onSelectionChanged="(ranges) => this.onKeyValueRangeChanged(ranges)"
2861
+ onSelectionConfirmed="() => this.updateKeyValueRange()"
2862
+ />
2863
+ </div>
2864
+ <div class="o-section o-data-labels">
2865
+ <div class="o-section-title">Baseline configuration</div>
2866
+ <div class="o-section-subtitle">Baseline value</div>
2867
+ <SelectionInput
2868
+ ranges="[props.definition.baseline || '']"
2869
+ isInvalid="isBaselineInvalid"
2870
+ hasSingleRange="true"
2871
+ onSelectionChanged="(ranges) => this.onBaselineRangeChanged(ranges)"
2872
+ onSelectionConfirmed="() => this.updateBaselineRange()"
2873
+ />
2874
+ <div class="o-section-subtitle">Baseline format</div>
2875
+ <select
2876
+ t-att-value="props.definition.baselineMode"
2877
+ class="o-input o-type-selector o-optional"
2878
+ t-on-change="(ev) => this.updateBaselineMode(ev)">
2879
+ <option value="text">Absolute value</option>
2880
+ <option value="difference">Value change from key value</option>
2881
+ <option value="percentage">Percentage change from key value</option>
2882
+ </select>
2883
+ </div>
2884
+ <div class="o-section o-sidepanel-error" t-if="errorMessages">
2885
+ <div t-foreach="errorMessages" t-as="error" t-key="error">
2886
+ <t t-esc="error"/>
2887
+ </div>
2888
+ </div>
2889
+ </div>
2890
+ </t>
2891
+
2892
+ <t t-name="o-spreadsheet-ScorecardChartDesignPanel" owl="1">
2893
+ <div>
2894
+ <div class="o-section o-chart-background-color">
2895
+ <div class="o-section-title">Background color</div>
2896
+ <div class="d-flex align-items-center">
2897
+ <span class="pe-1">Select a color...</span>
2898
+ <ColorPickerWidget
2899
+ currentColor="props.definition.background"
2900
+ toggleColorPicker="() => this.toggleColorPicker('backgroundColor')"
2901
+ showColorPicker="state.openedColorPicker === 'backgroundColor'"
2902
+ onColorPicked="(color) => this.setColor(color, 'backgroundColor')"
2903
+ title="env._t('Background Color')"
2904
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2905
+ />
2906
+ </div>
2907
+ </div>
2908
+
2909
+ <div class="o-section o-chart-title">
2910
+ <div class="o-section-title">Title</div>
2911
+ <input
2912
+ type="text"
2913
+ t-att-value="env._t(props.definition.title)"
2914
+ t-on-change="updateTitle"
2915
+ class="o-input o-optional"
2916
+ placeholder="New Chart"
2917
+ />
2918
+ </div>
2919
+ <div class="o-section">
2920
+ <div class="o-section-title">Baseline description</div>
2921
+ <input
2922
+ type="text"
2923
+ t-att-value="env._t(props.definition.baselineDescr)"
2924
+ t-on-change="updateBaselineDescr"
2925
+ class="o-input o-optional"
2926
+ />
2927
+ </div>
2928
+ </div>
2929
+ <div class="o-section o-chart-baseline-color">
2930
+ <div class="o-section-title">Baseline color</div>
2931
+ <div class="d-flex align-items-center">
2932
+ <span class="pe-1">Color on value increase</span>
2933
+ <ColorPickerWidget
2934
+ currentColor="props.definition.baselineColorUp"
2935
+ toggleColorPicker="() => this.toggleColorPicker('baselineColorUp')"
2936
+ showColorPicker="state.openedColorPicker === 'baselineColorUp'"
2937
+ onColorPicked="(color) => this.setColor(color, 'baselineColorUp')"
2938
+ title="env._t('Color Up')"
2939
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2940
+ />
2941
+ </div>
2942
+ <div class="d-flex align-items-center">
2943
+ <span class="pe-1">Color on value decrease</span>
2944
+ <ColorPickerWidget
2945
+ currentColor="props.definition.baselineColorDown"
2946
+ toggleColorPicker="() => this.toggleColorPicker('baselineColorDown')"
2947
+ showColorPicker="state.openedColorPicker === 'baselineColorDown'"
2948
+ onColorPicked="(color) => this.setColor(color, 'baselineColorDown')"
2949
+ title="env._t('Color Down')"
2950
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2951
+ />
2952
+ </div>
2953
+ </div>
2954
+ </t>
2955
+
2956
+ <t t-name="o-spreadsheet-CellIsRuleEditorPreview" owl="1">
2957
+ <div
2958
+ class="o-cf-preview-line"
2959
+ t-attf-style="font-weight:{{currentStyle.bold ?'bold':'normal'}};
2960
+ text-decoration:{{getTextDecoration(currentStyle)}};
2961
+ font-style:{{currentStyle.italic?'italic':'normal'}};
2962
+ color:{{currentStyle.textColor || '#000'}};
2963
+ border-radius: 4px;
2964
+ background-color:{{currentStyle.fillColor}};">
2965
+ <t t-if="previewText" t-esc="previewText"/>
2966
+ <t t-else="">Preview text</t>
2967
+ </div>
2968
+ </t>
2969
+
2970
+ <t t-name="o-spreadsheet-CellIsRuleEditor" owl="1">
2971
+ <div class="o-cf-cell-is-rule">
2972
+ <div class="o-section-subtitle">Format cells if...</div>
2973
+ <select t-model="rule.operator" class="o-input o-cell-is-operator">
2974
+ <t t-foreach="Object.keys(cellIsOperators)" t-as="op" t-key="op_index">
2975
+ <option t-att-value="op" t-esc="cellIsOperators[op]"/>
2976
+ </t>
2977
+ </select>
2978
+ <t t-if="rule.operator !== 'IsEmpty' and rule.operator !== 'IsNotEmpty'">
2979
+ <input
2980
+ type="text"
2981
+ placeholder="Value"
2982
+ t-model="rule.values[0]"
2983
+ t-att-class="{ 'o-invalid': isValue1Invalid }"
2984
+ class="o-input o-cell-is-value o-required"
2985
+ />
2986
+ <t t-if="rule.operator === 'Between' || rule.operator === 'NotBetween'">
2987
+ <input
2988
+ type="text"
2989
+ placeholder="and value"
2990
+ t-model="rule.values[1]"
2991
+ t-att-class="{ 'o-invalid': isValue2Invalid }"
2992
+ class="o-input o-cell-is-value o-required"
2993
+ />
2994
+ </t>
2995
+ </t>
2996
+ <div class="o-section-subtitle">Formatting style</div>
2997
+
2998
+ <t t-call="o-spreadsheet-CellIsRuleEditorPreview">
2999
+ <t t-set="currentStyle" t-value="rule.style"/>
3000
+ </t>
3001
+ <div class="o-sidePanel-tools">
3002
+ <div
3003
+ class="o-tool"
3004
+ title="Bold"
3005
+ t-att-class="{active:rule.style.bold}"
3006
+ t-on-click="() => this.toggleStyle('bold')">
3007
+ <t t-call="o-spreadsheet-Icon.BOLD"/>
3008
+ </div>
3009
+ <div
3010
+ class="o-tool"
3011
+ title="Italic"
3012
+ t-att-class="{active:rule.style.italic}"
3013
+ t-on-click="() => this.toggleStyle('italic')">
3014
+ <t t-call="o-spreadsheet-Icon.ITALIC"/>
3015
+ </div>
3016
+ <div
3017
+ class="o-tool"
3018
+ title="Underline"
3019
+ t-att-class="{active:rule.style.underline}"
3020
+ t-on-click="(ev) => this.toggleStyle('underline', ev)">
3021
+ <t t-call="o-spreadsheet-Icon.UNDERLINE"/>
3022
+ </div>
3023
+ <div
3024
+ class="o-tool"
3025
+ title="Strikethrough"
3026
+ t-att-class="{active:rule.style.strikethrough}"
3027
+ t-on-click="(ev) => this.toggleStyle('strikethrough', ev)">
3028
+ <t t-call="o-spreadsheet-Icon.STRIKE"/>
3029
+ </div>
3030
+ <ColorPickerWidget
3031
+ currentColor="rule.style.textColor || '#000000'"
3032
+ toggleColorPicker="(ev) => this.toggleMenu('cellIsRule-textColor', ev)"
3033
+ showColorPicker="state.openedMenu === 'cellIsRule-textColor'"
3034
+ onColorPicked="(color) => this.setColor('textColor', color)"
3035
+ title="env._t('Text Color')"
3036
+ icon="'o-spreadsheet-Icon.TEXT_COLOR'"
3037
+ class="'o-tool'"
3038
+ />
3039
+ <div class="o-divider"/>
3040
+ <ColorPickerWidget
3041
+ currentColor="rule.style.fillColor"
3042
+ toggleColorPicker="(ev) => this.toggleMenu('cellIsRule-fillColor', ev)"
3043
+ showColorPicker="state.openedMenu === 'cellIsRule-fillColor'"
3044
+ onColorPicked="(color) => this.setColor('fillColor', color)"
3045
+ title="env._t('Fill Color')"
3046
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
3047
+ class="'o-tool'"
3048
+ />
3049
+ </div>
3050
+ </div>
3051
+ </t>
3052
+
3053
+ <t t-name="o-spreadsheet-ColorScaleRuleEditorPreview" owl="1">
3054
+ <div class="o-cf-preview-gradient" t-attf-style="{{getPreviewGradient()}}">Preview text</div>
3055
+ </t>
3056
+
3057
+ <t t-name="o-spreadsheet-ColorScaleRuleEditorThreshold" owl="1">
3058
+ <div t-attf-class="o-threshold o-threshold-{{thresholdType}}">
3059
+ <t t-if="thresholdType === 'midpoint'">
3060
+ <t t-set="type" t-value="threshold and threshold.type"/>
3061
+ <select
3062
+ class="o-input"
3063
+ name="valueType"
3064
+ t-on-change="onMidpointChange"
3065
+ t-on-click="closeMenus">
3066
+ <option value="none" t-att-selected="threshold === undefined">None</option>
3067
+ <option value="number" t-att-selected="type === 'number'">FixedNumber</option>
3068
+ <option value="percentage" t-att-selected="type === 'percentage'">Percentage</option>
3069
+ <option value="percentile" t-att-selected="type === 'percentile'">Percentile</option>
3070
+ <option value="formula" t-att-selected="type === 'formula'">Formula</option>
3071
+ </select>
3072
+ </t>
3073
+ <t t-else="">
3074
+ <select class="o-input" name="valueType" t-model="threshold.type" t-on-click="closeMenus">
3075
+ <option value="value">Cell values</option>
3076
+ <option value="number">Number</option>
3077
+ <option value="percentage">Percentage</option>
3078
+ <option value="percentile">Percentile</option>
3079
+ <option value="formula">Formula</option>
3080
+ </select>
3081
+ </t>
3082
+ <input
3083
+ type="text"
3084
+ class="o-input o-threshold-value o-required"
3085
+ t-model="rule[thresholdType].value"
3086
+ t-att-class="{ 'o-invalid': isValueInvalid(thresholdType) }"
3087
+ t-if="threshold !== undefined and threshold.type !== 'value'"
3088
+ />
3089
+ <input type="text" class="o-input o-threshold-value" t-else="" disabled="1"/>
3090
+ <ColorPickerWidget
3091
+ currentColor="getThresholdColor(threshold)"
3092
+ toggleColorPicker="(ev) => this.toggleMenu('colorScale-'+thresholdType+'Color', ev)"
3093
+ showColorPicker="state.openedMenu === 'colorScale-'+thresholdType+'Color'"
3094
+ onColorPicked="(color) => this.setColorScaleColor(thresholdType, color)"
3095
+ title="env._t('Fill Color')"
3096
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
3097
+ disabled="threshold === undefined"
3098
+ />
3099
+ </div>
3100
+ </t>
3101
+
3102
+ <t t-name="o-spreadsheet-ColorScaleRuleEditor" owl="1">
3103
+ <div class="o-cf-color-scale-editor">
3104
+ <div class="o-section-subtitle">Preview</div>
3105
+ <t t-call="o-spreadsheet-ColorScaleRuleEditorPreview"/>
3106
+ <div class="o-section-subtitle">Minpoint</div>
3107
+ <t t-call="o-spreadsheet-ColorScaleRuleEditorThreshold">
3108
+ <t t-set="threshold" t-value="rule.minimum"/>
3109
+ <t t-set="thresholdType" t-value="'minimum'"/>
3110
+ </t>
3111
+ <div class="o-section-subtitle">MidPoint</div>
3112
+ <t t-call="o-spreadsheet-ColorScaleRuleEditorThreshold">
3113
+ <t t-set="threshold" t-value="rule.midpoint"/>
3114
+ <t t-set="thresholdType" t-value="'midpoint'"/>
3115
+ </t>
3116
+ <div class="o-section-subtitle">MaxPoint</div>
3117
+ <t t-call="o-spreadsheet-ColorScaleRuleEditorThreshold">
3118
+ <t t-set="threshold" t-value="rule.maximum"/>
3119
+ <t t-set="thresholdType" t-value="'maximum'"/>
3120
+ </t>
3121
+ </div>
3122
+ </t>
3123
+
3124
+ <t t-name="o-spreadsheet-ConditionalFormattingPanel" owl="1">
3125
+ <div class="o-cf">
3126
+ <t t-if="state.mode === 'list' || state.mode === 'reorder'">
3127
+ <div class="o-cf-preview-list">
3128
+ <div
3129
+ t-on-click="(ev) => this.editConditionalFormat(cf, ev)"
3130
+ t-foreach="conditionalFormats"
3131
+ t-as="cf"
3132
+ t-key="cf.id">
3133
+ <t t-call="o-spreadsheet-ConditionalFormattingPanelPreview"/>
3134
+ </div>
3135
+ </div>
3136
+ <t t-if="state.mode === 'list'">
3137
+ <div
3138
+ class="btn btn-link o-cf-btn-link o-cf-add"
3139
+ t-on-click.prevent.stop="addConditionalFormat">
3140
+ + Add another rule
3141
+ </div>
3142
+ <div
3143
+ class="btn btn-link o-cf-btn-link o-cf-reorder"
3144
+ t-on-click="reorderConditionalFormats">
3145
+ Reorder rules
3146
+ </div>
3147
+ </t>
3148
+ <t t-if="state.mode === 'reorder'">
3149
+ <div class="btn btn-link o-cf-btn-link o-cf-exit-reorder" t-on-click="switchToList">
3150
+ Stop reordering rules
3151
+ </div>
3152
+ </t>
3153
+ </t>
3154
+ <t t-if="state.mode === 'edit' || state.mode === 'add'" t-key="state.currentCF.id">
3155
+ <div class="o-cf-ruleEditor">
3156
+ <div class="o-section o-cf-range">
3157
+ <div class="o-section-title">Apply to range</div>
3158
+ <div class="o-selection-cf">
3159
+ <SelectionInput
3160
+ ranges="state.currentCF.ranges"
3161
+ class="'o-range'"
3162
+ isInvalid="isRangeValid"
3163
+ onSelectionChanged="(ranges) => this.onRangesChanged(ranges)"
3164
+ required="true"
3165
+ />
3166
+ </div>
3167
+ <div class="o-section-title">Format rules</div>
3168
+ <div class="o_field_radio o_horizontal o_field_widget o-cf-type-selector">
3169
+ <div
3170
+ class="custom-control form-check o_cf_radio_item"
3171
+ t-on-click="() => this.changeRuleType('CellIsRule')">
3172
+ <input
3173
+ class="form-check-input o_radio_input"
3174
+ t-att-checked="state.currentCFType === 'CellIsRule'"
3175
+ type="radio"
3176
+ id="cellIsRule"
3177
+ name="ruleType"
3178
+ value="CellIsRule"
3179
+ />
3180
+ <label for="cellIsRule" class="form-check-label o_form_label">Single color</label>
3181
+ </div>
3182
+ <div
3183
+ class="custom-control form-check o_cf_radio_item"
3184
+ t-on-click="() => this.changeRuleType('ColorScaleRule')">
3185
+ <input
3186
+ class="form-check-input o_radio_input"
3187
+ t-att-checked="state.currentCFType === 'ColorScaleRule'"
3188
+ type="radio"
3189
+ id="colorScaleRule"
3190
+ name="ruleType"
3191
+ value="ColorScaleRule"
3192
+ />
3193
+ <label for="colorScaleRule" class="form-check-label o_form_label">
3194
+ Color scale
3195
+ </label>
3196
+ </div>
3197
+
3198
+ <div
3199
+ class="custom-control form-check o_cf_radio_item"
3200
+ t-on-click="() => this.changeRuleType('IconSetRule')">
3201
+ <input
3202
+ class="form-check-input o_radio_input"
3203
+ t-att-checked="state.currentCFType === 'IconSetRule'"
3204
+ type="radio"
3205
+ id="iconSetRule"
3206
+ name="ruleType"
3207
+ value="IconSetRule"
3208
+ />
3209
+ <label for="iconSetRule" class="form-check-label o_form_label">Icon set</label>
3210
+ </div>
3211
+ </div>
3212
+ </div>
3213
+ <div class="o-section o-cf-editor">
3214
+ <t t-if="state.currentCFType === 'CellIsRule'" t-call="o-spreadsheet-CellIsRuleEditor">
3215
+ <t t-set="rule" t-value="state.rules.cellIs"/>
3216
+ </t>
3217
+ <t
3218
+ t-if="state.currentCFType === 'ColorScaleRule'"
3219
+ t-call="o-spreadsheet-ColorScaleRuleEditor">
3220
+ <t t-set="rule" t-value="state.rules.colorScale"/>
3221
+ </t>
3222
+ <t t-if="state.currentCFType === 'IconSetRule'" t-call="o-spreadsheet-IconSetEditor">
3223
+ <t t-set="rule" t-value="state.rules.iconSet"/>
3224
+ </t>
3225
+ <div class="o-sidePanelButtons">
3226
+ <button t-on-click="switchToList" class="o-sidePanelButton o-cf-cancel">
3227
+ Cancel
3228
+ </button>
3229
+ <button t-on-click="saveConditionalFormat" class="o-sidePanelButton o-cf-save">
3230
+ Save
3231
+ </button>
3232
+ </div>
3233
+ </div>
3234
+ <div class="o-section">
3235
+ <div class="o-cf-error" t-foreach="state.errors || []" t-as="error" t-key="error_index">
3236
+ <t t-esc="errorMessage(error)"/>
3237
+ </div>
3238
+ </div>
3239
+ </div>
3240
+ </t>
3241
+ </div>
3242
+ </t>
3243
+
3244
+ <t t-name="o-spreadsheet-ConditionalFormattingPanelPreview" owl="1">
3245
+ <div class="o-cf-preview" t-att-class="{ 'o-cf-cursor-ptr': state.mode !== 'reorder' }">
3246
+ <t t-if="cf.rule.type==='IconSetRule'">
3247
+ <div class="o-cf-preview-icon">
3248
+ <t t-call="o-spreadsheet-Icon.{{icons[cf.rule.icons.upper].template}}"/>
3249
+ <t t-call="o-spreadsheet-Icon.{{icons[cf.rule.icons.middle].template}}"/>
3250
+ <t t-call="o-spreadsheet-Icon.{{icons[cf.rule.icons.lower].template}}"/>
3251
+ </div>
3252
+ </t>
3253
+ <t t-else="">
3254
+ <div t-att-style="getStyle(cf.rule)" class="o-cf-preview-image">123</div>
3255
+ </t>
3256
+ <div class="o-cf-preview-description">
3257
+ <div class="o-cf-preview-ruletype">
3258
+ <div class="o-cf-preview-description-rule">
3259
+ <t t-esc="getDescription(cf)"/>
3260
+ </div>
3261
+ </div>
3262
+ <div class="o-cf-preview-range" t-esc="cf.ranges"/>
3263
+ </div>
3264
+ <t t-if="state.mode === 'reorder'">
3265
+ <div class="o-cf-reorder">
3266
+ <t t-if="!cf_first">
3267
+ <div
3268
+ class="o-cf-reorder-button-up o-cf-reorder-button"
3269
+ t-on-click="(ev) => this.reorderRule(cf, 'up', ev)">
3270
+ <t t-call="o-spreadsheet-Icon.CARET_UP"/>
3271
+ </div>
3272
+ </t>
3273
+ <t t-if="!cf_last">
3274
+ <div
3275
+ class="o-cf-reorder-button-down o-cf-reorder-button"
3276
+ t-on-click="(ev) => this.reorderRule(cf, 'down', ev)">
3277
+ <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
3278
+ </div>
3279
+ </t>
3280
+ </div>
3281
+ </t>
3282
+ <t t-else="">
3283
+ <div class="o-cf-delete">
3284
+ <div
3285
+ class="o-cf-delete-button"
3286
+ t-on-click.stop="(ev) => this.deleteConditionalFormat(cf, ev)"
3287
+ aria-label="Remove rule">
3288
+ <t t-call="o-spreadsheet-Icon.TRASH"/>
3289
+ </div>
3290
+ </div>
3291
+ </t>
3292
+ </div>
3293
+ </t>
3294
+
3295
+ <t t-name="o-spreadsheet-IconSets" owl="1">
3296
+ <div>
3297
+ <div class="o-section-subtitle">Icons</div>
3298
+ <div class="o-cf-iconsets">
3299
+ <div
3300
+ class="o-cf-iconset"
3301
+ t-foreach="['arrows', 'smiley', 'dots']"
3302
+ t-as="iconSet"
3303
+ t-key="iconSet"
3304
+ t-on-click="(ev) => this.setIconSet(iconSet, ev)">
3305
+ <div class="o-cf-icon">
3306
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].good].template}}"/>
3307
+ </div>
3308
+ <div class="o-cf-icon">
3309
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].neutral].template}}"/>
3310
+ </div>
3311
+ <div class="o-cf-icon">
3312
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].bad].template}}"/>
3313
+ </div>
3314
+ </div>
3315
+ </div>
3316
+ </div>
3317
+ </t>
3318
+
3319
+ <t t-name="o-spreadsheet-IconSetInflexionPointRow" owl="1">
3320
+ <tr>
3321
+ <td>
3322
+ <div t-on-click.stop="(ev) => this.toggleMenu('iconSet-'+icon+'Icon', ev)">
3323
+ <div class="o-cf-icon-button">
3324
+ <t t-call="o-spreadsheet-Icon.{{icons[iconValue].template}}"/>
3325
+ </div>
3326
+ </div>
3327
+ <IconPicker
3328
+ t-if="state.openedMenu === 'iconSet-'+icon+'Icon'"
3329
+ onIconPicked="(i) => this.setIcon(icon, i)"
3330
+ />
3331
+ </td>
3332
+ <td>When value is</td>
3333
+ <td>
3334
+ <select class="o-input" name="valueType" t-model="inflectionPointValue.operator">
3335
+ <option value="gt">
3336
+ <span>&#62;</span>
3337
+ </option>
3338
+ <option value="ge">
3339
+ <span>&#8805;</span>
3340
+ </option>
3341
+ </select>
3342
+ </td>
3343
+ <td>
3344
+ <input
3345
+ type="text"
3346
+ class="o-input"
3347
+ t-att-class="{ 'o-invalid': isInflectionPointInvalid(inflectionPoint) }"
3348
+ t-model="rule[inflectionPoint].value"
3349
+ />
3350
+ </td>
3351
+ <td>
3352
+ <select class="o-input" name="valueType" t-model="inflectionPointValue.type">
3353
+ <option value="number">Number</option>
3354
+ <option value="percentage">Percentage</option>
3355
+ <option value="percentile">Percentile</option>
3356
+ <option value="formula">Formula</option>
3357
+ </select>
3358
+ </td>
3359
+ </tr>
3360
+ </t>
3361
+
3362
+ <t t-name="o-spreadsheet-IconSetInflexionPoints" owl="1">
3363
+ <div class="o-inflection">
3364
+ <table>
3365
+ <tr>
3366
+ <th class="o-cf-iconset-icons"/>
3367
+ <th class="o-cf-iconset-text"/>
3368
+ <th class="o-cf-iconset-operator"/>
3369
+ <th class="o-cf-iconset-value">Value</th>
3370
+ <th class="o-cf-iconset-type">Type</th>
3371
+ </tr>
3372
+ <t t-call="o-spreadsheet-IconSetInflexionPointRow">
3373
+ <t t-set="iconValue" t-value="rule.icons.upper"/>
3374
+ <t t-set="icon" t-value="'upper'"/>
3375
+ <t t-set="inflectionPointValue" t-value="rule.upperInflectionPoint"/>
3376
+ <t t-set="inflectionPoint" t-value="'upperInflectionPoint'"/>
3377
+ </t>
3378
+ <t t-call="o-spreadsheet-IconSetInflexionPointRow">
3379
+ <t t-set="iconValue" t-value="rule.icons.middle"/>
3380
+ <t t-set="icon" t-value="'middle'"/>
3381
+ <t t-set="inflectionPointValue" t-value="rule.lowerInflectionPoint"/>
3382
+ <t t-set="inflectionPoint" t-value="'lowerInflectionPoint'"/>
3383
+ </t>
3384
+ <tr>
3385
+ <td>
3386
+ <div t-on-click.stop="(ev) => this.toggleMenu('iconSet-lowerIcon', ev)">
3387
+ <div class="o-cf-icon-button">
3388
+ <t t-call="o-spreadsheet-Icon.{{icons[rule.icons.lower].template}}"/>
3389
+ </div>
3390
+ </div>
3391
+ <IconPicker
3392
+ t-if="state.openedMenu === 'iconSet-lowerIcon'"
3393
+ onIconPicked="(icon) => this.setIcon('lower', icon)"
3394
+ />
3395
+ </td>
3396
+ <td>Else</td>
3397
+ <td/>
3398
+ <td/>
3399
+ <td/>
3400
+ </tr>
3401
+ </table>
3402
+ </div>
3403
+ </t>
3404
+ <t t-name="o-spreadsheet-IconSetEditor" owl="1">
3405
+ <div class="o-cf-iconset-rule">
3406
+ <t t-call="o-spreadsheet-IconSets"/>
3407
+ <t t-call="o-spreadsheet-IconSetInflexionPoints"/>
3408
+ <div class="btn btn-link o_refresh_measures o-cf-iconset-reverse" t-on-click="reverseIcons">
3409
+ <div class="me-1 d-inline-block">
3410
+ <t t-call="o-spreadsheet-Icon.REFRESH"/>
3411
+ </div>
3412
+ Reverse icons
3413
+ </div>
3414
+ </div>
3415
+ </t>
3416
+
3417
+ <t t-name="o-spreadsheet-CustomCurrencyPanel" owl="1">
3418
+ <div class="o-custom-currency">
3419
+ <div class="o-section" t-if="availableCurrencies.length > 1">
3420
+ <div class="o-section-title">Currency</div>
3421
+ <select
3422
+ class="o-input o-available-currencies"
3423
+ t-on-change="(ev) => this.updateSelectCurrency(ev)">
3424
+ <t t-foreach="availableCurrencies" t-as="currency" t-key="currency_index">
3425
+ <option
3426
+ t-att-value="currency_index"
3427
+ t-esc="currencyDisplayName(currency)"
3428
+ t-att-selected="currency_index === state.selectedCurrencyIndex"
3429
+ />
3430
+ </t>
3431
+ </select>
3432
+ </div>
3433
+ <div class="o-section">
3434
+ <div class="o-subsection-left">
3435
+ <div class="o-section-title">Code</div>
3436
+ <input
3437
+ type="text"
3438
+ class="o-input"
3439
+ t-model="state.currencyCode"
3440
+ t-on-input="(ev) => this.updateCode(ev)"
3441
+ />
3442
+ </div>
3443
+ <div class="o-subsection-right">
3444
+ <div class="o-section-title">Symbol</div>
3445
+ <input
3446
+ type="text"
3447
+ class="o-input"
3448
+ t-model="state.currencySymbol"
3449
+ t-on-input="(ev) => this.updateSymbol(ev)"
3450
+ />
3451
+ </div>
3452
+ </div>
3453
+ <div class="o-section">
3454
+ <div class="o-section-title">Format</div>
3455
+ <select
3456
+ class="o-input o-format-proposals"
3457
+ t-on-change="(ev) => this.updateSelectFormat(ev)"
3458
+ t-att-disabled="!formatProposals.length">
3459
+ <t t-foreach="formatProposals" t-as="proposal" t-key="proposal_index">
3460
+ <option
3461
+ t-att-value="proposal_index"
3462
+ t-esc="proposal.example"
3463
+ t-att-selected="proposal_index === state.selectedFormatIndex"
3464
+ />
3465
+ </t>
3466
+ </select>
3467
+ </div>
3468
+ <div class="o-sidePanelButtons">
3469
+ <button
3470
+ class="o-sidePanelButton"
3471
+ t-on-click="() => this.apply()"
3472
+ t-att-disabled="!formatProposals.length || isSameFormat">
3473
+ Apply
3474
+ </button>
3475
+ </div>
3476
+ </div>
3477
+ </t>
3478
+
3479
+ <t t-name="o-spreadsheet-FindAndReplacePanel" owl="1">
3480
+ <div class="o-find-and-replace" tabindex="0" t-ref="findAndReplace">
3481
+ <div class="o-section">
3482
+ <div class="o-section-title">Search</div>
3483
+ <div class="o-input-search-container">
3484
+ <input
3485
+ type="text"
3486
+ class="o-input o-input-with-count"
3487
+ t-on-input="onInput"
3488
+ t-on-keydown="onKeydownSearch"
3489
+ />
3490
+ <div class="o-input-count" t-if="hasSearchResult">
3491
+ <t t-esc="env.model.getters.getCurrentSelectedMatchIndex()+1"/>
3492
+ /
3493
+ <t t-esc="env.model.getters.getSearchMatches().length"/>
3494
+ </div>
3495
+ <div t-elif="!pendingSearch and state.toSearch !== ''" class="o-input-count">0 / 0</div>
3496
+ </div>
3497
+ <div>
3498
+ <!-- TODO: go through this css, the group misses a padding and could profit from BootStrap -->
3499
+ <div class="o-far-item">
3500
+ <label class="o-far-checkbox">
3501
+ <input
3502
+ t-model="state.searchOptions.matchCase"
3503
+ t-on-change="updateSearch"
3504
+ class="o-far-input"
3505
+ type="checkbox"
3506
+ />
3507
+ <span class="o-far-label">Match case</span>
3508
+ </label>
3509
+ </div>
3510
+ <div class="o-far-item">
3511
+ <label class="o-far-checkbox">
3512
+ <input
3513
+ t-model="state.searchOptions.exactMatch"
3514
+ t-on-change="updateSearch"
3515
+ class="o-far-input"
3516
+ type="checkbox"
3517
+ />
3518
+ <span class="o-far-label">Match entire cell content</span>
3519
+ </label>
3520
+ </div>
3521
+ <div class="o-far-item">
3522
+ <label class="o-far-checkbox">
3523
+ <input
3524
+ t-model="state.searchOptions.searchFormulas"
3525
+ t-on-change="searchFormulas"
3526
+ class="o-far-input"
3527
+ type="checkbox"
3528
+ />
3529
+ <span class="o-far-label">Search in formulas</span>
3530
+ </label>
3531
+ </div>
3532
+ </div>
3533
+ </div>
3534
+ <div class="o-sidePanelButtons">
3535
+ <button
3536
+ t-att-disabled="!hasSearchResult"
3537
+ t-on-click="onSelectPreviousCell"
3538
+ class="o-sidePanelButton">
3539
+ Previous
3540
+ </button>
3541
+ <button
3542
+ t-att-disabled="!hasSearchResult"
3543
+ t-on-click="onSelectNextCell"
3544
+ class="o-sidePanelButton">
3545
+ Next
3546
+ </button>
3547
+ </div>
3548
+ <div class="o-section" t-if="!env.model.getters.isReadonly()">
3549
+ <div class="o-section-title">Replace</div>
3550
+ <div class="o-input-search-container">
3551
+ <input
3552
+ type="text"
3553
+ class="o-input o-input-without-count"
3554
+ t-model="state.replaceWith"
3555
+ t-on-keydown="onKeydownReplace"
3556
+ />
3557
+ </div>
3558
+ </div>
3559
+
3560
+ <div class="o-sidePanelButtons" t-if="!env.model.getters.isReadonly()">
3561
+ <button
3562
+ t-att-disabled="env.model.getters.getCurrentSelectedMatchIndex() === null"
3563
+ t-on-click="replace"
3564
+ class="o-sidePanelButton">
3565
+ Replace
3566
+ </button>
3567
+ <button
3568
+ t-att-disabled="env.model.getters.getCurrentSelectedMatchIndex() === null"
3569
+ t-on-click="replaceAll"
3570
+ class="o-sidePanelButton">
3571
+ Replace all
3572
+ </button>
3573
+ </div>
3574
+ </div>
3575
+ </t>
3576
+
3577
+ <t t-name="o-spreadsheet-SidePanel" owl="1">
3578
+ <div class="o-sidePanel">
3579
+ <div class="o-sidePanelHeader">
3580
+ <div class="o-sidePanelTitle" t-esc="getTitle()"/>
3581
+ <div class="o-sidePanelClose" t-on-click="() => this.props.onCloseSidePanel()">✕</div>
3582
+ </div>
3583
+ <div class="o-sidePanelBody">
3584
+ <t
3585
+ t-component="state.panel.Body"
3586
+ t-props="props.panelProps"
3587
+ onCloseSidePanel="props.onCloseSidePanel"
3588
+ t-key="'Body_' + props.component"
3589
+ />
3590
+ </div>
3591
+ <div class="o-sidePanelFooter" t-if="state.panel.Footer">
3592
+ <t
3593
+ t-component="state.panel.Footer"
3594
+ t-props="props.panelProps"
3595
+ t-key="'Footer_' + props.component"
3596
+ />
3597
+ </div>
3598
+ </div>
3599
+ </t>
3600
+
3601
+ <t t-name="o-spreadsheet-SplitIntoColumnsPanel" owl="1">
3602
+ <div class="o-split-to-cols-panel">
3603
+ <div class="o-section">
3604
+ <div class="o-section-title">Separator</div>
3605
+ <select
3606
+ class="o-input o-type-selector"
3607
+ t-on-change="(ev) => this.onSeparatorChange(ev.target.value)">
3608
+ <option
3609
+ t-foreach="separators"
3610
+ t-as="separator"
3611
+ t-key="separator.value"
3612
+ t-att-value="separator.value"
3613
+ t-esc="separator.name"
3614
+ t-att-selected="state.separatorValue === separator.value"
3615
+ />
3616
+ </select>
3617
+
3618
+ <input
3619
+ class="o-input o-required mt-3"
3620
+ type="text"
3621
+ t-if="state.separatorValue === 'custom'"
3622
+ t-att-value="state.customSeparator"
3623
+ t-on-input="updateCustomSeparator"
3624
+ placeholder="Add any characters or symbol"
3625
+ />
3626
+
3627
+ <div class="o-checkbox">
3628
+ <label>
3629
+ <input
3630
+ type="checkbox"
3631
+ name="add columns"
3632
+ t-att-checked="state.addNewColumns"
3633
+ t-on-change="updateAddNewColumnsCheckbox"
3634
+ />
3635
+ Add new columns to avoid overwriting cells
3636
+ </label>
3637
+ </div>
3638
+
3639
+ <div class="o-sidePanelButtons">
3640
+ <button
3641
+ class="o-sidePanelButton"
3642
+ t-att-class="{'o-disabled': isConfirmDisabled}"
3643
+ t-on-click="confirm">
3644
+ Confirm
3645
+ </button>
3646
+ </div>
3647
+
3648
+ <t t-foreach="errorMessages" t-as="error" t-key="error">
3649
+ <div class="o-sidepanel-error d-flex align-items-center text-danger">
3650
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_EXCLAMATION"/>
3651
+ <span t-esc="error"/>
3652
+ </div>
3653
+ </t>
3654
+ <t t-foreach="warningMessages" t-as="warning" t-key="warning">
3655
+ <div class="o-sidepanel-warning d-flex align-items-center text-warning">
3656
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_EXCLAMATION"/>
3657
+ <span t-esc="warning"/>
3658
+ </div>
3659
+ </t>
3660
+ </div>
3661
+ </div>
3662
+ </t>
3663
+
3664
+ <t t-name="o-spreadsheet-Spreadsheet" owl="1">
3665
+ <div
3666
+ class="o-spreadsheet"
3667
+ t-on-keydown="(ev) => !env.isDashboard() and this.onKeydown(ev)"
3668
+ t-att-style="getStyle()">
3669
+ <t t-if="env.isDashboard()">
3670
+ <SpreadsheetDashboard/>
3671
+ </t>
3672
+ <t t-else="">
3673
+ <TopBar
3674
+ onClick="() => this.focusGrid()"
3675
+ onComposerContentFocused="(selection) => this.onTopBarComposerFocused(selection)"
3676
+ focusComposer="focusTopBarComposer"
3677
+ dropdownMaxHeight="gridHeight"
3678
+ />
3679
+ <Grid
3680
+ sidePanelIsOpen="sidePanel.isOpen"
3681
+ focusComposer="focusGridComposer"
3682
+ exposeFocus="(focus) => this._focusGrid = focus"
3683
+ onComposerContentFocused="() => this.onGridComposerContentFocused()"
3684
+ onGridComposerCellFocused="(content, selection) => this.onGridComposerCellFocused(content, selection)"
3685
+ />
3686
+ <SidePanel
3687
+ t-if="sidePanel.isOpen"
3688
+ onCloseSidePanel="() => this.closeSidePanel()"
3689
+ component="sidePanel.component"
3690
+ panelProps="sidePanel.panelProps"
3691
+ />
3692
+ <BottomBar onClick="() => this.focusGrid()"/>
3693
+ </t>
3694
+ </div>
3695
+ </t>
3696
+
3697
+ <t t-name="o-spreadsheet-TopBar" owl="1">
3698
+ <div
3699
+ class="o-spreadsheet-topbar o-two-columns d-flex flex-column user-select-none"
3700
+ t-on-click="props.onClick">
3701
+ <div class="o-topbar-top d-flex justify-content-between">
3702
+ <!-- Menus -->
3703
+ <div class="o-topbar-topleft d-flex">
3704
+ <t t-foreach="menus" t-as="menu" t-key="menu_index">
3705
+ <div
3706
+ t-if="menu.children.length !== 0"
3707
+ class="o-topbar-menu o-hoverable-button rounded"
3708
+ t-att-class="{'active': state.menuState.parentMenu and state.menuState.parentMenu.id === menu.id}"
3709
+ t-on-click="(ev) => this.toggleContextMenu(menu, ev)"
3710
+ t-on-mouseover="(ev) => this.onMenuMouseOver(menu, ev)"
3711
+ t-att-data-id="menu.id">
3712
+ <t t-esc="getMenuName(menu)"/>
3713
+ </div>
3714
+ </t>
3715
+ </div>
3716
+ <div class="o-topbar-topright d-flex justify-content-end">
3717
+ <div t-foreach="topbarComponents" t-as="comp" t-key="comp.id">
3718
+ <t t-component="comp.component"/>
3719
+ </div>
3720
+ </div>
3721
+ </div>
3722
+ <!-- Toolbar and Cell Content -->
3723
+ <div class="d-flex">
3724
+ <div class="o-topbar-toolbar d-flex flex-shrink-0">
3725
+ <!-- Toolbar -->
3726
+ <div
3727
+ t-if="env.model.getters.isReadonly()"
3728
+ class="o-readonly-toolbar d-flex align-items-center text-muted">
3729
+ <span>
3730
+ <i class="fa fa-eye"/>
3731
+ Readonly Access
3732
+ </span>
3733
+ </div>
3734
+ <div t-else="" class="o-toolbar-tools d-flex flex-shrink-0 ms-4">
3735
+ <ActionButton action="EDIT.undo" class="'o-hoverable-button'"/>
3736
+ <ActionButton action="EDIT.redo" class="'o-hoverable-button'"/>
3737
+ <ActionButton action="FORMAT.paintFormat" class="'o-hoverable-button'"/>
3738
+ <ActionButton action="FORMAT.clearFormat" class="'o-hoverable-button'"/>
3739
+
3740
+ <div class="o-divider"/>
3741
+
3742
+ <ActionButton action="FORMAT.formatPercent" class="'o-hoverable-button'"/>
3743
+ <ActionButton action="FORMAT.decraseDecimalPlaces" class="'o-hoverable-button'"/>
3744
+ <ActionButton action="FORMAT.incraseDecimalPlaces" class="'o-hoverable-button'"/>
3745
+ <ActionButton
3746
+ action="formatNumberMenuItemSpec"
3747
+ onClick="(ev) => this.toggleToolbarContextMenu(formatNumberMenuItemSpec, ev)"
3748
+ hasTriangleDownIcon="true"
3749
+ class="'o-hoverable-button'"
3750
+ />
3751
+
3752
+ <div class="o-divider"/>
3753
+ <FontSizeEditor
3754
+ class="'o-hoverable-button'"
3755
+ onToggle.bind="this.onClick"
3756
+ dropdownStyle="this.dropdownStyle"
3757
+ />
3758
+ <div class="o-divider"/>
3759
+
3760
+ <ActionButton action="FORMAT.formatBold" class="'o-hoverable-button'"/>
3761
+ <ActionButton action="FORMAT.formatItalic" class="'o-hoverable-button'"/>
3762
+ <ActionButton action="FORMAT.formatStrikethrough" class="'o-hoverable-button'"/>
3763
+
3764
+ <ColorPickerWidget
3765
+ currentColor="state.textColor"
3766
+ toggleColorPicker="(ev) => this.toggleDropdownTool('textColorTool', ev)"
3767
+ showColorPicker="state.activeTool === 'textColorTool'"
3768
+ onColorPicked="(color) => this.setColor('textColor', color)"
3769
+ title="env._t('Text Color')"
3770
+ icon="'o-spreadsheet-Icon.TEXT_COLOR'"
3771
+ dropdownMaxHeight="this.props.dropdownMaxHeight"
3772
+ class="'o-hoverable-button o-menu-item-button'"
3773
+ />
3774
+
3775
+ <div class="o-divider"/>
3776
+
3777
+ <ColorPickerWidget
3778
+ currentColor="state.fillColor"
3779
+ toggleColorPicker="(ev) => this.toggleDropdownTool('fillColorTool', ev)"
3780
+ showColorPicker="state.activeTool === 'fillColorTool'"
3781
+ onColorPicked="(color) => this.setColor('fillColor', color)"
3782
+ title="env._t('Fill Color')"
3783
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
3784
+ dropdownMaxHeight="this.props.dropdownMaxHeight"
3785
+ class="'o-hoverable-button o-menu-item-button'"
3786
+ />
3787
+
3788
+ <BorderEditorWidget
3789
+ class="'o-hoverable-button o-menu-item-button'"
3790
+ toggleBorderEditor="(ev) => this.toggleDropdownTool('borderTool', ev)"
3791
+ showBorderEditor="state.activeTool === 'borderTool'"
3792
+ dropdownMaxHeight="this.props.dropdownMaxHeight"
3793
+ />
3794
+ <ActionButton action="EDIT.mergeCells" class="'o-hoverable-button'"/>
3795
+ <div class="o-divider"/>
3796
+
3797
+ <div class="o-dropdown">
3798
+ <ActionButton
3799
+ action="FORMAT.formatAlignmentHorizontal"
3800
+ hasTriangleDownIcon="true"
3801
+ t-on-click="(ev) => this.toggleDropdownTool('horizontalAlignTool', ev)"
3802
+ class="'o-hoverable-button'"
3803
+ />
3804
+ <div
3805
+ class="o-dropdown-content"
3806
+ t-if="state.activeTool === 'horizontalAlignTool'"
3807
+ t-att-style="dropdownStyle"
3808
+ t-on-click.stop="">
3809
+ <div class="o-dropdown-line">
3810
+ <ActionButton action="FORMAT.formatAlignmentLeft" class="'o-hoverable-button'"/>
3811
+ <ActionButton action="FORMAT.formatAlignmentCenter" class="'o-hoverable-button'"/>
3812
+ <ActionButton action="FORMAT.formatAlignmentRight" class="'o-hoverable-button'"/>
3813
+ </div>
3814
+ </div>
3815
+ </div>
3816
+ <div class="o-dropdown">
3817
+ <ActionButton
3818
+ action="FORMAT.formatAlignmentVertical"
3819
+ hasTriangleDownIcon="true"
3820
+ t-on-click="(ev) => this.toggleDropdownTool('verticalAlignTool', ev)"
3821
+ class="'o-hoverable-button'"
3822
+ />
3823
+ <div
3824
+ class="o-dropdown-content"
3825
+ t-att-style="dropdownStyle"
3826
+ t-if="state.activeTool === 'verticalAlignTool'"
3827
+ t-on-click.stop="">
3828
+ <div class="o-dropdown-line">
3829
+ <ActionButton action="FORMAT.formatAlignmentTop" class="'o-hoverable-button'"/>
3830
+ <ActionButton action="FORMAT.formatAlignmentMiddle" class="'o-hoverable-button'"/>
3831
+ <ActionButton action="FORMAT.formatAlignmentBottom" class="'o-hoverable-button'"/>
3832
+ </div>
3833
+ </div>
3834
+ </div>
3835
+ <div class="o-dropdown">
3836
+ <ActionButton
3837
+ action="FORMAT.formatWrapping"
3838
+ hasTriangleDownIcon="true"
3839
+ t-on-click="(ev) => this.toggleDropdownTool('textWrappingTool', ev)"
3840
+ class="'o-hoverable-button'"
3841
+ />
3842
+ <div
3843
+ class="o-dropdown-content"
3844
+ t-att-style="dropdownStyle"
3845
+ t-if="state.activeTool === 'textWrappingTool'"
3846
+ t-on-click.stop="">
3847
+ <div class="o-dropdown-line">
3848
+ <ActionButton
3849
+ action="FORMAT.formatWrappingOverflow"
3850
+ class="'o-hoverable-button'"
3851
+ />
3852
+ <ActionButton action="FORMAT.formatWrappingWrap" class="'o-hoverable-button'"/>
3853
+ <ActionButton action="FORMAT.formatWrappingClip" class="'o-hoverable-button'"/>
3854
+ </div>
3855
+ </div>
3856
+ </div>
3857
+
3858
+ <div class="o-divider"/>
3859
+
3860
+ <ActionButton action="VIEW.createRemoveFilter" class="'o-hoverable-button'"/>
3861
+ </div>
3862
+ </div>
3863
+ <TopBarComposer
3864
+ focus="props.focusComposer"
3865
+ onComposerContentFocused="props.onComposerContentFocused"
3866
+ />
3867
+ </div>
3868
+ </div>
3869
+ <Menu
3870
+ t-if="state.menuState.isOpen"
3871
+ position="state.menuState.position"
3872
+ menuItems="state.menuState.menuItems"
3873
+ onClose="() => this.closeMenus()"
3874
+ onMenuClicked="() => this.props.onClick()"
3875
+ />
3876
+ </t>
3877
+ </odoo>
3878
+ <!--
3879
+ __info__.version = '16.3.17';
3880
+ __info__.date = '2023-11-16T11:59:54.711Z';
3881
+ __info__.hash = '4049460';
3882
+ -->