@odoo/o-spreadsheet 16.2.20 → 16.2.22

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,3531 @@
1
+ <odoo>
2
+ <t t-name="o-spreadsheet-Ripple" owl="1">
3
+ <div
4
+ class="o-ripple-container position-relative"
5
+ t-att-class="props.class"
6
+ t-on-click="onClick">
7
+ <div class="position-absolute w-100 h-100">
8
+ <t t-foreach="state.ripples" t-as="ripple" t-key="ripple.id">
9
+ <RippleEffect t-props="getRippleEffectProps(ripple.id)"/>
10
+ </t>
11
+ </div>
12
+ <div class="position-relative" t-ref="childContainer">
13
+ <t t-slot="default"/>
14
+ </div>
15
+ </div>
16
+ </t>
17
+
18
+ <t t-name="o-spreadsheet-RippleEffect" owl="1">
19
+ <div
20
+ class="position-absolute"
21
+ t-att-class="{ 'overflow-hidden': !props.allowOverflow }"
22
+ t-att-style="props.style">
23
+ <div class="o-ripple position-relative pe-none" t-ref="ripple" t-att-style="rippleStyle"/>
24
+ </div>
25
+ </t>
26
+
27
+ <t t-name="o-spreadsheet-Autofill" owl="1">
28
+ <div class="o-autofill" t-att-style="style"/>
29
+ <div
30
+ class="o-autofill-handler"
31
+ t-att-style="handlerStyle"
32
+ t-on-mousedown="onMouseDown"
33
+ t-on-dblclick="onDblClick"
34
+ />
35
+ <t t-set="tooltip" t-value="getTooltip()"/>
36
+ <div t-if="tooltip" class="o-autofill-nextvalue" t-att-style="styleNextValue">
37
+ <t t-component="tooltip.component" t-props="tooltip.props"/>
38
+ </div>
39
+ </t>
40
+
41
+ <t t-name="o-spreadsheet-BottomBar" owl="1">
42
+ <div
43
+ class="o-spreadsheet-bottom-bar o-two-columns d-flex align-items-center overflow-hidden"
44
+ t-on-click="props.onClick"
45
+ t-ref="bottomBar"
46
+ t-on-contextmenu.prevent="">
47
+ <Ripple>
48
+ <div
49
+ class="o-sheet-item o-add-sheet me-2 p-1"
50
+ t-att-class="{'disabled': env.model.getters.isReadonly()}"
51
+ t-on-click="clickAddSheet">
52
+ <t t-call="o-spreadsheet-Icon.PLUS"/>
53
+ </div>
54
+ </Ripple>
55
+ <Ripple>
56
+ <div class="o-sheet-item o-list-sheets me-2 p-1" t-on-click="clickListSheets">
57
+ <t t-call="o-spreadsheet-Icon.LIST"/>
58
+ </div>
59
+ </Ripple>
60
+ <div class="o-all-sheets position-relative flex-shrink-0 d-flex h-100 me-3">
61
+ <div
62
+ class="o-bottom-bar-fade-in position-absolute h-100 w-100 pe-none"
63
+ t-if="state.isSheetListScrollableLeft"
64
+ />
65
+ <div
66
+ class="o-sheet-list d-flex w-100 overflow-hidden px-1"
67
+ t-ref="sheetList"
68
+ t-on-wheel="onWheel"
69
+ t-on-scroll="onScroll">
70
+ <t t-foreach="getSheets()" t-as="sheet" t-key="sheet.id">
71
+ <BottomBarSheet
72
+ style="getSheetStyle(sheet.id)"
73
+ sheetId="sheet.id"
74
+ openContextMenu="(registry, ev) => this.onSheetContextMenu(sheet.id, registry, ev)"
75
+ onMouseDown="(ev) => this.onSheetMouseDown(sheet.id, ev)"
76
+ />
77
+ </t>
78
+ </div>
79
+ <div
80
+ class="o-bottom-bar-fade-out position-absolute h-100 w-100 pe-none"
81
+ t-if="state.isSheetListScrollableRight"
82
+ />
83
+ </div>
84
+ <div
85
+ class="o-bottom-bar-arrows d-flex h-100 me-5 align-items-center"
86
+ t-if="state.isSheetListScrollableLeft || state.isSheetListScrollableRight">
87
+ <Ripple
88
+ ignoreClickPosition="true"
89
+ width="20"
90
+ height="20"
91
+ offsetX="1"
92
+ allowOverflow="true"
93
+ enabled="state.isSheetListScrollableLeft">
94
+ <div
95
+ class="o-bottom-bar-arrow o-bottom-bar-arrow-left d-flex align-items-center me-2"
96
+ t-att-class="{'o-disabled': !state.isSheetListScrollableLeft}"
97
+ t-on-click="onArrowLeft">
98
+ <t t-call="o-spreadsheet-Icon.CARET_LEFT"/>
99
+ </div>
100
+ </Ripple>
101
+ <Ripple
102
+ ignoreClickPosition="true"
103
+ width="20"
104
+ height="20"
105
+ offsetX="-1"
106
+ allowOverflow="true"
107
+ enabled="state.isSheetListScrollableRight">
108
+ <div
109
+ class="o-bottom-bar-arrow o-bottom-bar-arrow-right d-flex align-items-center me-4"
110
+ t-att-class="{'o-disabled': !state.isSheetListScrollableRight}"
111
+ t-on-click="onArrowRight">
112
+ <t t-call="o-spreadsheet-Icon.CARET_RIGHT"/>
113
+ </div>
114
+ </Ripple>
115
+ </div>
116
+
117
+ <BottomBarStatistic
118
+ openContextMenu="(x, y, registry) => this.openContextMenu(x, y, 'listSelectionStatistics', registry)"
119
+ closeContextMenu="() => this.closeContextMenuWithId('listSelectionStatistics')"
120
+ />
121
+
122
+ <Menu
123
+ t-if="menuState.isOpen"
124
+ position="menuState.position"
125
+ menuItems="menuState.menuItems"
126
+ maxHeight="menuMaxHeight"
127
+ onClose="() => this.closeMenu()"
128
+ menuId="menuState.menuId"
129
+ />
130
+ </div>
131
+ </t>
132
+
133
+ <t t-name="o-spreadsheet-BottomBarSheet" owl="1">
134
+ <Ripple>
135
+ <div
136
+ class="o-sheet d-flex align-items-center user-select-none text-nowrap "
137
+ t-on-mousedown="(ev) => this.onMouseDown(ev)"
138
+ t-on-contextmenu.prevent="(ev) => this.onContextMenu(ev)"
139
+ t-ref="sheetDiv"
140
+ t-att-style="props.style"
141
+ t-att-title="sheetName"
142
+ t-att-data-id="props.sheetId"
143
+ t-att-class="{active: isSheetActive}">
144
+ <span
145
+ class="o-sheet-name"
146
+ t-att-class="{'o-sheet-name-editable': state.isEditing }"
147
+ t-ref="sheetNameSpan"
148
+ t-esc="sheetName"
149
+ t-on-click="(ev) => this.onClickSheetName(ev)"
150
+ t-on-dblclick="() => this.onDblClick()"
151
+ t-on-focusout="() => this.onFocusOut()"
152
+ t-on-keydown="(ev) => this.onKeyDown(ev)"
153
+ t-att-contenteditable="state.isEditing.toString()"
154
+ />
155
+ <span class="o-sheet-icon ms-1" t-on-click.stop="(ev) => this.onIconClick(ev)">
156
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
157
+ </span>
158
+ </div>
159
+ </Ripple>
160
+ </t>
161
+
162
+ <t t-name="o-spreadsheet-BottomBarStatisic" owl="1">
163
+ <t t-set="selectedStatistic" t-value="getSelectedStatistic()"/>
164
+ <Ripple class="'ms-auto'" t-if="selectedStatistic !== undefined">
165
+ <div
166
+ class="o-selection-statistic text-truncate user-select-none me-4 bg-white rounded shadow"
167
+ t-on-click="listSelectionStatistics">
168
+ <t t-esc="selectedStatistic"/>
169
+ <span class="ms-2">
170
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
171
+ </span>
172
+ </div>
173
+ </Ripple>
174
+ </t>
175
+
176
+ <t t-name="o-spreadsheet-ClientTag" owl="1">
177
+ <div>
178
+ <div class="o-client-tag" t-att-style="tagStyle" t-esc="props.name"/>
179
+ </div>
180
+ </t>
181
+
182
+ <t t-name="o-spreadsheet-ColorPicker" owl="1">
183
+ <Popover t-props="popoverProps">
184
+ <div class="o-color-picker" t-on-click.stop="" t-att-style="colorPickerStyle">
185
+ <div class="o-color-picker-section-name">Standard</div>
186
+ <div class="colors-grid">
187
+ <div
188
+ t-foreach="COLORS"
189
+ t-as="color"
190
+ t-key="color"
191
+ class="o-color-picker-line-item"
192
+ t-att-data-color="color"
193
+ t-on-click="() => this.onColorClick(color)"
194
+ t-attf-style="background-color:{{color}};">
195
+ <div
196
+ t-if="isSameColor(props.currentColor, color)"
197
+ align="center"
198
+ t-attf-style="color:{{getCheckMarkColor()}}">
199
+ ✓
200
+ </div>
201
+ </div>
202
+ </div>
203
+ <div class="o-separator"/>
204
+ <div class="o-color-picker-section-name">
205
+ <span>Custom</span>
206
+ </div>
207
+ <div class="colors-grid">
208
+ <div
209
+ class="o-color-picker-toggler o-color-picker-line-item"
210
+ t-on-click.stop="toggleColorPicker">
211
+ <div class="o-color-picker-toggler-sign">
212
+ <t t-call="o-spreadsheet-Icon.PLUS"/>
213
+ </div>
214
+ </div>
215
+ <div
216
+ t-foreach="env.model.getters.getCustomColors()"
217
+ t-as="color"
218
+ t-key="color"
219
+ class="o-color-picker-line-item"
220
+ t-att-data-color="color"
221
+ t-attf-style="background-color:{{color}};"
222
+ t-on-click="() => this.onColorClick(color)">
223
+ <div
224
+ t-if="props.currentColor === color"
225
+ align="center"
226
+ t-attf-style="color:{{getCheckMarkColor()}}">
227
+ ✓
228
+ </div>
229
+ </div>
230
+ </div>
231
+ <div t-if="state.showGradient" class="o-custom-selector">
232
+ <div class="o-magnifier-glass" t-att-style="magnifyingGlassStyle"/>
233
+ <div
234
+ class="o-gradient"
235
+ t-on-click.stop="computeCustomColor"
236
+ t-on-mouseout="hideMagnifier"
237
+ t-on-mousemove="moveMagnifier"
238
+ t-on-mouseover="showMagnifier"
239
+ />
240
+ <div class="o-custom-input-preview">
241
+ <input
242
+ type="text"
243
+ t-att-class="{'o-wrong-color': state.isCurrentColorInvalid }"
244
+ t-on-click.stop=""
245
+ t-model="state.currentColor"
246
+ />
247
+ <div class="o-color-preview" t-attf-style="background-color:{{state.currentColor}}"/>
248
+ </div>
249
+ <div class="o-custom-input-buttons">
250
+ <button class="o-add-button" t-on-click="setCustomColor">Add</button>
251
+ </div>
252
+ </div>
253
+ <div class="o-separator"/>
254
+ <div class="o-buttons">
255
+ <button t-on-click="resetColor" class="o-cancel">Reset</button>
256
+ </div>
257
+ </div>
258
+ </Popover>
259
+ </t>
260
+
261
+ <t t-name="o-spreadsheet-ColorPickerWidget" owl="1">
262
+ <div class="o-color-picker-widget">
263
+ <div
264
+ class="o-color-picker-button"
265
+ t-ref="colorPickerButton"
266
+ t-on-click.stop="props.toggleColorPicker"
267
+ t-att-title="props.title"
268
+ t-att-class="props.class ? props.class : 'o-color-picker-button-style'"
269
+ t-att-disabled="props.disabled">
270
+ <span t-att-style="iconStyle">
271
+ <t t-call="{{props.icon}}"/>
272
+ </span>
273
+ </div>
274
+ <ColorPicker
275
+ t-if="props.showColorPicker"
276
+ anchorRect="colorPickerAnchorRect"
277
+ onColorPicked="props.onColorPicked"
278
+ currentColor="props.currentColor"
279
+ maxHeight="props.dropdownMaxHeight"
280
+ />
281
+ </div>
282
+ </t>
283
+
284
+ <t t-name="o-spreadsheet-TextValueProvider" owl="1">
285
+ <div
286
+ t-att-class="{
287
+ 'o-autocomplete-dropdown':props.values.length,
288
+ 'shadow':props.values.length}">
289
+ <t t-foreach="props.values" t-as="v" t-key="v.text">
290
+ <div
291
+ class="d-flex flex-column"
292
+ t-att-class="{'o-autocomplete-value-focus': props.selectedIndex === v_index}"
293
+ t-on-click="() => this.props.onValueSelected(v.text)">
294
+ <div class="o-autocomplete-value" t-esc="v.text"/>
295
+ <div
296
+ class="o-autocomplete-description text-truncate"
297
+ t-esc="v.description"
298
+ t-if="props.selectedIndex === v_index"
299
+ />
300
+ </div>
301
+ </t>
302
+ </div>
303
+ </t>
304
+
305
+ <t t-name="o-spreadsheet-Composer" owl="1">
306
+ <div class="o-composer-container w-100 h-100">
307
+ <div
308
+ class="o-composer w-100 text-start"
309
+ t-att-class="{ 'text-muted': env.model.getters.isReadonly(), 'unfocusable': env.model.getters.isReadonly() }"
310
+ t-att-style="props.inputStyle"
311
+ t-ref="o_composer"
312
+ tabindex="1"
313
+ t-att-contenteditable="env.model.getters.isReadonly() ? 'false' : 'true'"
314
+ spellcheck="false"
315
+ t-on-keydown="onKeydown"
316
+ t-on-mousedown="onMousedown"
317
+ t-on-mousewheel.stop=""
318
+ t-on-input="onInput"
319
+ t-on-keyup="onKeyup"
320
+ t-on-click="onClick"
321
+ t-on-blur="onBlur"
322
+ t-on-paste.stop=""
323
+ t-on-compositionstart="onCompositionStart"
324
+ t-on-compositionend="onCompositionEnd"
325
+ />
326
+
327
+ <div
328
+ t-if="props.focus !== 'inactive' and (autoCompleteState.showProvider or functionDescriptionState.showDescription)"
329
+ class="o-composer-assistant"
330
+ t-att-style="assistantStyle"
331
+ t-on-mousedown.prevent.stop=""
332
+ t-on-click.prevent.stop=""
333
+ t-on-mouseup.prevent.stop="">
334
+ <TextValueProvider
335
+ t-if="autoCompleteState.showProvider"
336
+ values="autoCompleteState.values"
337
+ selectedIndex="autoCompleteState.selectedIndex"
338
+ onValueSelected.bind="this.autoComplete"
339
+ />
340
+ <FunctionDescriptionProvider
341
+ t-if="functionDescriptionState.showDescription"
342
+ functionName="functionDescriptionState.functionName"
343
+ functionDescription="functionDescriptionState.functionDescription"
344
+ argToFocus="functionDescriptionState.argToFocus"
345
+ />
346
+ </div>
347
+ </div>
348
+ </t>
349
+
350
+ <t t-name="o-spreadsheet-FunctionDescriptionProvider" owl="1">
351
+ <div
352
+ class="o-formula-assistant-container user-select-none shadow"
353
+ t-att-class="{
354
+ 'pe-none': assistantState.allowCellSelectionBehind,
355
+ 'pe-auto': !assistantState.allowCellSelectionBehind
356
+ }">
357
+ <t t-set="context" t-value="getContext()"/>
358
+ <div
359
+ class="o-formula-assistant bg-white"
360
+ t-if="context.functionName"
361
+ t-on-mousemove="onMouseMove"
362
+ t-att-class="{'opacity-25': assistantState.allowCellSelectionBehind}">
363
+ <div class="o-formula-assistant-head">
364
+ <span t-esc="context.functionName"/>
365
+ (
366
+ <t t-foreach="context.functionDescription.args" t-as="arg" t-key="arg.name">
367
+ <span t-if="arg_index > '0'">,&#xA0;</span>
368
+ <span t-att-class="{ 'o-formula-assistant-focus': context.argToFocus === arg_index }">
369
+ <span>
370
+ <span t-if="arg.optional || arg.repeating || arg.default">[</span>
371
+ <span t-esc="arg.name"/>
372
+ <span t-if="arg.repeating">, ...</span>
373
+ <span t-if="arg.optional || arg.repeating || arg.default">]</span>
374
+ </span>
375
+ </span>
376
+ </t>
377
+ )
378
+ </div>
379
+
380
+ <div class="o-formula-assistant-core pb-3 m-3">
381
+ <div class="o-formula-assistant-gray">ABOUT</div>
382
+ <div t-esc="context.functionDescription.description"/>
383
+ </div>
384
+
385
+ <t t-foreach="context.functionDescription.args" t-as="arg" t-key="arg.name">
386
+ <div
387
+ class="o-formula-assistant-arg p-3 pt-0 display-flex flex-column"
388
+ t-att-class="{
389
+ 'o-formula-assistant-gray': context.argToFocus >= '0',
390
+ 'o-formula-assistant-focus': context.argToFocus === arg_index,
391
+ }">
392
+ <div>
393
+ <span t-esc="arg.name"/>
394
+ <span
395
+ t-if="arg.optional || arg.repeating || arg.default ">&#xA0;- [optional]&#xA0;</span>
396
+ <span t-if="arg.default">
397
+ <span>default:&#xA0;</span>
398
+ <t t-esc="arg.defaultValue"/>
399
+ </span>
400
+ <span t-if="arg.repeating">repeatable</span>
401
+ </div>
402
+ <div class="o-formula-assistant-arg-description" t-esc="arg.description"/>
403
+ </div>
404
+ </t>
405
+ </div>
406
+ </div>
407
+ </t>
408
+
409
+ <t t-name="o-spreadsheet-GridComposer" owl="1">
410
+ <div
411
+ class="o-cell-reference"
412
+ t-if="shouldDisplayCellReference"
413
+ t-att-style="cellReferenceStyle"
414
+ t-esc="cellReference"
415
+ />
416
+ <div class="o-grid-composer" t-att-style="containerStyle" t-ref="gridComposer">
417
+ <Composer
418
+ focus="props.focus"
419
+ inputStyle="composerStyle"
420
+ rect="composerState.rect"
421
+ delimitation="composerState.delimitation"
422
+ onComposerUnmounted="props.onComposerUnmounted"
423
+ onComposerContentFocused="props.onComposerContentFocused"
424
+ />
425
+ </div>
426
+ </t>
427
+
428
+ <t t-name="o-spreadsheet-TopBarComposer" owl="1">
429
+ <div class="o-topbar-composer bg-white" t-att-style="containerStyle">
430
+ <Composer
431
+ focus="props.focus"
432
+ inputStyle="composerStyle"
433
+ onComposerContentFocused="props.onComposerContentFocused"
434
+ />
435
+ </div>
436
+ </t>
437
+
438
+ <t t-name="o-spreadsheet-SpreadsheetDashboard" owl="1">
439
+ <div
440
+ class="o-grid o-two-columns"
441
+ tabindex="-1"
442
+ t-on-wheel="onMouseWheel"
443
+ t-on-click="onClosePopover">
444
+ <div class="mx-auto h-100 position-relative" t-ref="grid" t-att-style="gridContainer">
445
+ <GridOverlay
446
+ onCellHovered.bind="onCellHovered"
447
+ onGridResized.bind="onGridResized"
448
+ onGridMoved.bind="moveCanvas"
449
+ gridOverlayDimensions="gridOverlayDimensions"
450
+ />
451
+ <canvas t-ref="canvas"/>
452
+ <GridPopover
453
+ hoveredCell="hoveredCell"
454
+ gridRect="getGridRect()"
455
+ onMouseWheel.bind="onMouseWheel"
456
+ onClosePopover.bind="onClosePopover"
457
+ />
458
+ <div
459
+ t-foreach="getClickableCells()"
460
+ t-as="clickableCell"
461
+ t-key="clickableCell.tKey"
462
+ class="o-dashboard-clickable-cell"
463
+ t-on-click="() => this.selectClickableCell(clickableCell)"
464
+ t-on-contextmenu.prevent=""
465
+ t-att-style="getCellClickableStyle(clickableCell.coordinates)"
466
+ />
467
+ <FilterIconsOverlay/>
468
+ </div>
469
+ <VerticalScrollBar/>
470
+ <HorizontalScrollBar/>
471
+ <div class="o-scrollbar corner"/>
472
+ </div>
473
+ </t>
474
+
475
+ <t t-name="o-spreadsheet-ErrorToolTip" owl="1">
476
+ <div class="o-error-tooltip">
477
+ <t t-esc="props.text"/>
478
+ </div>
479
+ </t>
480
+
481
+ <t t-name="o-spreadsheet-ChartJsComponent" owl="1">
482
+ <canvas class="o-figure-canvas w-100 h-100" t-att-style="canvasStyle" t-ref="graphContainer"/>
483
+ </t>
484
+
485
+ <t t-name="o-spreadsheet-ScorecardChart" owl="1">
486
+ <div class="o-scorecard w-100 h-100" t-att-style="chartStyle" t-ref="chart">
487
+ <t t-set="textStyles" t-value="getTextStyles()"/>
488
+ <div t-if="title" class="o-title-text" t-esc="title" t-att-style="textStyles.titleStyle"/>
489
+ <div class="o-scorecard-content" t-att-style="chartContentStyle">
490
+ <div class="o-key-text" t-if="keyValue" t-esc="keyValue" t-att-style="textStyles.keyStyle"/>
491
+ <t t-if="baseline || baselineDescr">
492
+ <div class="o-baseline-text" t-att-style="textStyles.baselineStyle">
493
+ <t t-if="baseline">
494
+ <t t-if="baselineArrowDirection === 'up'">
495
+ <t t-call="o-spreadsheet-Icon.ARROW_UP">
496
+ <t t-set="color" t-value="'fill : ' + runtime.baselineColor"/>
497
+ </t>
498
+ </t>
499
+ <t t-if="baselineArrowDirection === 'down'">
500
+ <t t-call="o-spreadsheet-Icon.ARROW_DOWN">
501
+ <t t-set="color" t-value="'fill : ' + runtime.baselineColor"/>
502
+ </t>
503
+ </t>
504
+ <span t-att-style="textStyles.baselineValueStyle" class="o-baseline-text-value">
505
+ <t t-esc="baseline"/>
506
+ </span>
507
+ </t>
508
+ <span t-att-style="textStyles.baselineDescrStyle" class="o-baseline-text-description">
509
+ <t t-esc="env._t(baselineDescr)"/>
510
+ </span>
511
+ </div>
512
+ </t>
513
+ </div>
514
+ </div>
515
+ </t>
516
+
517
+ <t t-name="o-spreadsheet-FigureComponent" owl="1">
518
+ <div class="o-figure-wrapper pe-auto" t-att-style="wrapperStyle">
519
+ <div
520
+ class="o-figure w-100 h-100"
521
+ t-on-mousedown.stop="(ev) => this.onMouseDown(ev)"
522
+ t-on-contextmenu.prevent.stop="(ev) => !env.model.getters.isReadonly() and this.onContextMenu(ev)"
523
+ t-ref="figure"
524
+ t-att-style="props.style"
525
+ tabindex="0"
526
+ t-on-keydown="(ev) => this.onKeyDown(ev)"
527
+ t-on-keyup.stop="">
528
+ <t
529
+ t-component="figureRegistry.get(props.figure.tag).Component"
530
+ t-key="props.figure.id"
531
+ onFigureDeleted="props.onFigureDeleted"
532
+ figure="props.figure"
533
+ />
534
+ <div class="o-figure-menu position-absolute m-2" t-if="!env.isDashboard()">
535
+ <div
536
+ class="o-figure-menu-item"
537
+ t-if="!env.model.getters.isReadonly()"
538
+ t-on-click="showMenu"
539
+ t-ref="menuButton"
540
+ t-on-contextmenu.prevent.stop="showMenu">
541
+ <t t-call="o-spreadsheet-Icon.LIST"/>
542
+ </div>
543
+ <Menu
544
+ t-if="menuState.isOpen"
545
+ position="menuState.position"
546
+ menuItems="menuState.menuItems"
547
+ onClose="() => this.menuState.isOpen=false"
548
+ />
549
+ </div>
550
+ </div>
551
+ <div class="o-figure-border w-100 h-100 position-absolute pe-none" t-att-style="borderStyle"/>
552
+ <t t-if="isSelected">
553
+ <div
554
+ class="o-fig-anchor o-top"
555
+ t-att-style="this.getResizerPosition('top')"
556
+ t-on-mousedown="(ev) => this.clickAnchor(0,-1, ev)"
557
+ />
558
+ <div
559
+ class="o-fig-anchor o-topRight"
560
+ t-att-style="this.getResizerPosition('top right')"
561
+ t-on-mousedown="(ev) => this.clickAnchor(1,-1, ev)"
562
+ />
563
+ <div
564
+ class="o-fig-anchor o-right"
565
+ t-att-style="this.getResizerPosition('right')"
566
+ t-on-mousedown="(ev) => this.clickAnchor(1,0, ev)"
567
+ />
568
+ <div
569
+ class="o-fig-anchor o-bottomRight"
570
+ t-att-style="this.getResizerPosition('bottom right')"
571
+ t-on-mousedown="(ev) => this.clickAnchor(1,1, ev)"
572
+ />
573
+ <div
574
+ class="o-fig-anchor o-bottom"
575
+ t-att-style="this.getResizerPosition('bottom')"
576
+ t-on-mousedown="(ev) => this.clickAnchor(0,1, ev)"
577
+ />
578
+ <div
579
+ class="o-fig-anchor o-bottomLeft"
580
+ t-att-style="this.getResizerPosition('bottom left')"
581
+ t-on-mousedown="(ev) => this.clickAnchor(-1,1, ev)"
582
+ />
583
+ <div
584
+ class="o-fig-anchor o-left"
585
+ t-att-style="this.getResizerPosition('left')"
586
+ t-on-mousedown="(ev) => this.clickAnchor(-1,0, ev)"
587
+ />
588
+ <div
589
+ class="o-fig-anchor o-topLeft"
590
+ t-att-style="this.getResizerPosition('top left')"
591
+ t-on-mousedown="(ev) => this.clickAnchor(-1,-1, ev)"
592
+ />
593
+ </t>
594
+ </div>
595
+ </t>
596
+
597
+ <t t-name="o-spreadsheet-ChartFigure" owl="1">
598
+ <div class="o-chart-container w-100 h-100">
599
+ <t
600
+ t-component="chartComponent"
601
+ figure="this.props.figure"
602
+ t-key="this.props.figure.id + '-' + chartType"
603
+ />
604
+ </div>
605
+ </t>
606
+
607
+ <t t-name="o-spreadsheet-FiguresContainer" owl="1">
608
+ <div>
609
+ <t t-foreach="containers" t-as="container" t-key="container.type">
610
+ <div
611
+ class="o-figure-container position-absolute pe-none overflow-hidden"
612
+ t-att-style="container.style"
613
+ t-att-data-id="container.type + 'Container'">
614
+ <div
615
+ class="o-figure-viewport-inverse w-0 h-0 overflow-visible position-absolute"
616
+ t-att-style="container.inverseViewportStyle">
617
+ <t t-foreach="container.figures" t-as="figure" t-key="figure.id">
618
+ <FigureComponent
619
+ onFigureDeleted="this.props.onFigureDeleted"
620
+ figure="figure"
621
+ style="getFigureStyle(figure)"
622
+ onMouseDown="(ev) => this.startDraggingFigure(figure, ev)"
623
+ onClickAnchor="(dirX, dirY, ev) => this.startResize(figure, dirX, dirY, ev)"
624
+ />
625
+ </t>
626
+ </div>
627
+ </div>
628
+ </t>
629
+ </div>
630
+ </t>
631
+
632
+ <t t-name="o-spreadsheet-ImageFigure" owl="1">
633
+ <img t-att-src="getImagePath" class="w-100 h-100"/>
634
+ </t>
635
+
636
+ <t t-name="o-spreadsheet-FilterIcon" owl="1">
637
+ <div class="o-filter-icon" t-att-style="style" t-on-click.stop="props.onClick">
638
+ <t t-if="props.isActive" t-call="o-spreadsheet-Icon.FILTER_ICON_ACTIVE"/>
639
+ <t t-else="" t-call="o-spreadsheet-Icon.FILTER_ICON"/>
640
+ </div>
641
+ </t>
642
+
643
+ <t t-name="o-spreadsheet-FilterIconsOverlay" owl="1">
644
+ <t
645
+ t-foreach="getVisibleFilterHeaders()"
646
+ t-as="header"
647
+ t-key="'filter'+header.col + '_' + header.row">
648
+ <FilterIcon
649
+ position="getFilterHeaderPosition(header)"
650
+ isActive="isFilterActive(header)"
651
+ t-key="'icon_'+header.col + '_' + header.row"
652
+ onClick="() => this.toggleFilterMenu(header)"
653
+ />
654
+ </t>
655
+ </t>
656
+
657
+ <t t-name="o-spreadsheet-FilterMenu" owl="1">
658
+ <div class="o-filter-menu d-flex flex-column bg-white" t-on-wheel.stop="">
659
+ <div t-if="!isReadonly">
660
+ <div class="o-filter-menu-item" t-on-click="() => this.sortFilterZone('ascending')">
661
+ Sort ascending (A ⟶ Z)
662
+ </div>
663
+ <div class="o-filter-menu-item" t-on-click="() => this.sortFilterZone('descending')">
664
+ Sort descending (Z ⟶ A)
665
+ </div>
666
+ </div>
667
+ <div class="o-separator" t-if="!isReadonly"/>
668
+ <div class="o-filter-menu-actions">
669
+ <div class="o-filter-menu-action-text" t-on-click="selectAll">Select all</div>
670
+ <div class="o-filter-menu-action-text" t-on-click="clearAll">Clear</div>
671
+ </div>
672
+ <div class="position-relative">
673
+ <input
674
+ class="w-100"
675
+ t-ref="filterMenuSearchBar"
676
+ type="text"
677
+ t-model="state.textFilter"
678
+ placeholder="Search..."
679
+ t-on-keydown="onKeyDown"
680
+ />
681
+ <i class="o-search-icon position-absolute">
682
+ <t t-call="o-spreadsheet-Icon.SEARCH"/>
683
+ </i>
684
+ </div>
685
+ <div
686
+ class="o-filter-menu-list d-flex flex-column rounded"
687
+ t-ref="filterValueList"
688
+ t-on-click="this.clearScrolledToValue"
689
+ t-on-scroll="this.clearScrolledToValue">
690
+ <t t-foreach="displayedValues" t-as="value" t-key="value.string">
691
+ <FilterMenuValueItem
692
+ onClick="() => this.checkValue(value)"
693
+ onMouseMove="() => this.onMouseMove(value)"
694
+ value="value.string"
695
+ isChecked="value.checked"
696
+ isSelected="value.string === state.selectedValue"
697
+ scrolledTo="value.scrolledTo"
698
+ />
699
+ </t>
700
+ <div
701
+ t-if="displayedValues.length === 0"
702
+ class="o-filter-menu-no-values d-flex align-items-center justify-content-center w-100 h-100 ">
703
+ No results
704
+ </div>
705
+ </div>
706
+ <div class="o-filter-menu-buttons d-flex justify-content-end">
707
+ <div class="o-filter-menu-button o-filter-menu-button-cancel" t-on-click="cancel">
708
+ Cancel
709
+ </div>
710
+ <div class="o-filter-menu-button o-filter-menu-button-primary" t-on-click="confirm">
711
+ Confirm
712
+ </div>
713
+ </div>
714
+ </div>
715
+ </t>
716
+
717
+ <t t-name="o-spreadsheet-FilterMenuValueItem" owl="1">
718
+ <div
719
+ t-on-click="this.props.onClick"
720
+ t-on-mousemove="this.props.onMouseMove"
721
+ class="o-filter-menu-item o-filter-menu-value"
722
+ t-ref="menuValueItem"
723
+ t-att-class="{'selected': this.props.isSelected}">
724
+ <div>
725
+ <div class="o-filter-menu-value-checked">
726
+ <span t-if="this.props.isChecked">✓</span>
727
+ </div>
728
+ </div>
729
+ <div class="o-filter-menu-value-text text-truncate">
730
+ <t t-if="this.props.value === ''">(Blanks)</t>
731
+ <t t-else="" t-esc="this.props.value"/>
732
+ </div>
733
+ </div>
734
+ </t>
735
+
736
+ <t t-name="o-spreadsheet-FontSizeEditor" owl="1">
737
+ <div class="o-dropdown" t-ref="FontSizeEditor">
738
+ <div
739
+ class=" o-font-size-editor"
740
+ t-att-class="props.class"
741
+ title="Font Size"
742
+ t-on-click="this.toggleFontList">
743
+ <input
744
+ type="number"
745
+ min="1"
746
+ max="400"
747
+ class="o-font-size bg-transparent border-0"
748
+ t-on-keydown="onInputKeydown"
749
+ t-on-click.stop=""
750
+ t-on-focus.stop="onInputFocused"
751
+ t-att-value="currentFontSize"
752
+ t-on-change="setSizeFromInput"
753
+ t-ref="inputFontSize"
754
+ />
755
+ <span>
756
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
757
+ </span>
758
+ </div>
759
+ <div
760
+ class="o-dropdown-content o-text-options"
761
+ t-if="dropdown.isOpen"
762
+ t-on-click.stop=""
763
+ t-att-style="props.dropdownStyle">
764
+ <t t-foreach="fontSizes" t-as="fontSize" t-key="fontSize">
765
+ <div
766
+ t-esc="fontSize"
767
+ t-att-data-size="fontSize"
768
+ class="o-dropdown-item"
769
+ t-on-click="() => this.setSizeFromList(fontSize)"
770
+ />
771
+ </t>
772
+ </div>
773
+ </div>
774
+ </t>
775
+
776
+ <t t-name="o-spreadsheet-Grid" owl="1">
777
+ <div
778
+ class="o-grid"
779
+ tabindex="-1"
780
+ t-att-class="{'o-two-columns': !props.sidePanelIsOpen}"
781
+ t-on-click="focus"
782
+ t-on-keydown="onKeydown"
783
+ t-on-wheel="onMouseWheel"
784
+ t-ref="grid">
785
+ <GridOverlay
786
+ onCellClicked.bind="onCellClicked"
787
+ onCellDoubleClicked.bind="onCellDoubleClicked"
788
+ onCellRightClicked.bind="onCellRightClicked"
789
+ onCellHovered.bind="onCellHovered"
790
+ onGridResized.bind="onGridResized"
791
+ onGridMoved.bind="moveCanvas"
792
+ gridOverlayDimensions="gridOverlayDimensions"
793
+ onFigureDeleted.bind="focus"
794
+ />
795
+ <HeadersOverlay onOpenContextMenu="(type, x, y) => this.toggleContextMenu(type, x, y)"/>
796
+
797
+ <t t-if="env.model.getters.getEditionMode() !== 'inactive'">
798
+ <GridComposer
799
+ onComposerUnmounted="() => this.focus()"
800
+ onComposerContentFocused="props.onComposerContentFocused"
801
+ focus="props.focusComposer"
802
+ gridDims="env.model.getters.getSheetViewDimensionWithHeaders()"
803
+ />
804
+ </t>
805
+ <t else="1">
806
+ <input
807
+ class="position-absolute"
808
+ style="z-index:-1000;"
809
+ t-on-input="onInput"
810
+ t-on-contextmenu="onInputContextMenu"
811
+ t-ref="hiddenInput"
812
+ />
813
+ </t>
814
+ <canvas t-ref="canvas"/>
815
+ <t
816
+ t-foreach="env.model.getters.getClientsToDisplay()"
817
+ t-as="client"
818
+ t-key="getClientPositionKey(client)">
819
+ <ClientTag
820
+ name="client.name"
821
+ color="client.color"
822
+ col="client.position.col"
823
+ row="client.position.row"
824
+ active="isCellHovered(client.position.col, client.position.row)"
825
+ />
826
+ </t>
827
+ <GridPopover
828
+ t-if="!menuState.isOpen"
829
+ hoveredCell="hoveredCell"
830
+ gridRect="getGridRect()"
831
+ onMouseWheel.bind="onMouseWheel"
832
+ onClosePopover.bind="onClosePopover"
833
+ />
834
+ <t t-if="env.model.getters.getEditionMode() === 'inactive'">
835
+ <Autofill position="getAutofillPosition()" isVisible="isAutofillVisible"/>
836
+ </t>
837
+ <t t-if="env.model.getters.getEditionMode() !== 'inactive'">
838
+ <t t-foreach="env.model.getters.getHighlights()" t-as="highlight" t-key="highlight_index">
839
+ <t t-if="highlight.sheetId === env.model.getters.getActiveSheetId()">
840
+ <Highlight zone="highlight.zone" color="highlight.color"/>
841
+ </t>
842
+ </t>
843
+ </t>
844
+ <Menu
845
+ t-if="menuState.isOpen"
846
+ menuItems="menuState.menuItems"
847
+ position="menuState.position"
848
+ onClose="() => this.closeMenu()"
849
+ />
850
+ <FilterIconsOverlay gridPosition="{ x: HEADER_WIDTH, y : HEADER_HEIGHT }"/>
851
+ <VerticalScrollBar topOffset="HEADER_HEIGHT"/>
852
+ <HorizontalScrollBar leftOffset="HEADER_WIDTH"/>
853
+ <div class="o-scrollbar corner"/>
854
+ </div>
855
+ </t>
856
+
857
+ <t t-name="o-spreadsheet-GridOverlay" owl="1">
858
+ <div
859
+ t-ref="gridOverlay"
860
+ class="o-grid-overlay overflow-hidden"
861
+ t-att-style="props.gridOverlayDimensions"
862
+ t-on-mousedown="onMouseDown"
863
+ t-on-dblclick.self="onDoubleClick"
864
+ t-on-contextmenu="onContextMenu">
865
+ <FiguresContainer onFigureDeleted="props.onFigureDeleted"/>
866
+ </div>
867
+ </t>
868
+
869
+ <t t-name="o-spreadsheet-GridPopover" owl="1">
870
+ <Popover
871
+ t-if="cellPopover.isOpen"
872
+ positioning="cellPopover.cellCorner"
873
+ maxHeight="cellPopover.Component.size and cellPopover.Component.size.maxHeight"
874
+ maxWidth="cellPopover.Component.size and cellPopover.Component.size.maxHidth"
875
+ anchorRect="cellPopover.anchorRect"
876
+ containerRect="env.getPopoverContainerRect()"
877
+ onMouseWheel="props.onMouseWheel"
878
+ zIndex="zIndex">
879
+ <t
880
+ t-component="cellPopover.Component"
881
+ t-props="{...cellPopover.props, onClosed : () => props.onClosePopover()}"
882
+ />
883
+ </Popover>
884
+ </t>
885
+
886
+ <t t-name="o-spreadsheet-HeadersOverlay" owl="1">
887
+ <div class="o-overlay">
888
+ <ColResizer onOpenContextMenu="props.onOpenContextMenu"/>
889
+ <RowResizer onOpenContextMenu="props.onOpenContextMenu"/>
890
+ <div class="all" t-on-mousedown.self="selectAll"/>
891
+ </div>
892
+ </t>
893
+
894
+ <t t-name="o-spreadsheet-RowResizer" owl="1">
895
+ <div
896
+ class="o-row-resizer"
897
+ t-on-mousemove.self="onMouseMove"
898
+ t-on-mouseleave="onMouseLeave"
899
+ t-on-mousedown.self.prevent="select"
900
+ t-ref="rowResizer"
901
+ t-on-mouseup.self="onMouseUp"
902
+ t-on-contextmenu.self="onContextMenu"
903
+ t-att-class="{'o-grab': state.waitingForMove, 'o-dragging': state.isMoving}">
904
+ <div
905
+ t-if="state.isMoving"
906
+ class="dragging-row-line"
907
+ t-attf-style="top:{{state.draggerLinePosition}}px;"
908
+ />
909
+ <div
910
+ t-if="state.isMoving"
911
+ class="dragging-row-shadow"
912
+ t-attf-style="top:{{state.draggerShadowPosition}}px; height:{{state.draggerShadowThickness}}px;"
913
+ />
914
+ <t t-if="state.resizerIsActive">
915
+ <div
916
+ class="o-handle"
917
+ t-on-mousedown="onMouseDown"
918
+ t-on-dblclick="onDblClick"
919
+ t-on-contextmenu.prevent=""
920
+ t-attf-style="top:{{state.draggerLinePosition - 2}}px;">
921
+ <div class="dragging-resizer" t-if="state.isResizing"/>
922
+ </div>
923
+ </t>
924
+ <t
925
+ t-foreach="env.model.getters.getHiddenRowsGroups(env.model.getters.getActiveSheetId())"
926
+ t-as="hiddenItem"
927
+ t-key="hiddenItem_index">
928
+ <t t-if="!hiddenItem.includes(0)">
929
+ <div
930
+ class="o-unhide"
931
+ t-att-data-index="hiddenItem_index"
932
+ t-attf-style="top:{{unhideStyleValue(hiddenItem[0]) - 17}}px;"
933
+ t-on-click="() => this.unhide(hiddenItem)">
934
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_UP"/>
935
+ </div>
936
+ </t>
937
+ <t
938
+ t-if="!hiddenItem.includes(env.model.getters.getNumberRows(env.model.getters.getActiveSheetId())-1)">
939
+ <div
940
+ class="o-unhide"
941
+ t-att-data-index="hiddenItem_index"
942
+ t-attf-style="top:{{unhideStyleValue(hiddenItem[0]) + 3}}px;"
943
+ t-on-click="() => this.unhide(hiddenItem)">
944
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
945
+ </div>
946
+ </t>
947
+ </t>
948
+ </div>
949
+ </t>
950
+
951
+ <t t-name="o-spreadsheet-ColResizer" owl="1">
952
+ <div
953
+ class="o-col-resizer"
954
+ t-on-mousemove.self="onMouseMove"
955
+ t-on-mouseleave="onMouseLeave"
956
+ t-on-mousedown.self.prevent="select"
957
+ t-ref="colResizer"
958
+ t-on-mouseup.self="onMouseUp"
959
+ t-on-contextmenu.self="onContextMenu"
960
+ t-att-class="{'o-grab': state.waitingForMove, 'o-dragging': state.isMoving, }">
961
+ <div
962
+ t-if="state.isMoving"
963
+ class="dragging-col-line"
964
+ t-attf-style="left:{{state.draggerLinePosition}}px;"
965
+ />
966
+ <div
967
+ t-if="state.isMoving"
968
+ class="dragging-col-shadow"
969
+ t-attf-style="left:{{state.draggerShadowPosition}}px; width:{{state.draggerShadowThickness}}px"
970
+ />
971
+ <t t-if="state.resizerIsActive">
972
+ <div
973
+ class="o-handle"
974
+ t-on-mousedown="onMouseDown"
975
+ t-on-dblclick="onDblClick"
976
+ t-on-contextmenu.prevent=""
977
+ t-attf-style="left:{{state.draggerLinePosition - 2}}px;">
978
+ <div class="dragging-resizer" t-if="state.isResizing"/>
979
+ </div>
980
+ </t>
981
+ <t
982
+ t-foreach="env.model.getters.getHiddenColsGroups(env.model.getters.getActiveSheetId())"
983
+ t-as="hiddenItem"
984
+ t-key="hiddenItem_index">
985
+ <t t-if="!hiddenItem.includes(0)">
986
+ <div
987
+ class="o-unhide"
988
+ t-att-data-index="hiddenItem_index"
989
+ t-attf-style="left:{{unhideStyleValue(hiddenItem[0]) - 17}}px; margin-right:6px;"
990
+ t-on-click="() => this.unhide(hiddenItem)">
991
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_LEFT"/>
992
+ </div>
993
+ </t>
994
+ <t
995
+ t-if="!hiddenItem.includes(env.model.getters.getNumberCols(env.model.getters.getActiveSheetId())-1)">
996
+ <div
997
+ class="o-unhide"
998
+ t-att-data-index="hiddenItem_index"
999
+ t-attf-style="left:{{unhideStyleValue(hiddenItem[0]) + 3}}px;"
1000
+ t-on-click="() => this.unhide(hiddenItem)">
1001
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_RIGHT"/>
1002
+ </div>
1003
+ </t>
1004
+ </t>
1005
+ </div>
1006
+ </t>
1007
+
1008
+ <t t-name="o-spreadsheet-Border" owl="1">
1009
+ <div
1010
+ class="o-border"
1011
+ t-on-mousedown.prevent="onMouseDown"
1012
+ t-att-style="style"
1013
+ t-att-class="{
1014
+ 'o-moving': props.isMoving,
1015
+ 'o-border-n': props.orientation === 'n',
1016
+ 'o-border-s': props.orientation === 's',
1017
+ 'o-border-w': props.orientation === 'w',
1018
+ 'o-border-e': props.orientation === 'e',
1019
+ }"
1020
+ />
1021
+ </t>
1022
+
1023
+ <t t-name="o-spreadsheet-Corner" owl="1">
1024
+ <div
1025
+ class="o-corner"
1026
+ t-on-mousedown.prevent="onMouseDown"
1027
+ t-att-style="style"
1028
+ t-att-class="{
1029
+ 'o-resizing': props.isResizing,
1030
+ 'o-corner-nw': props.orientation === 'nw',
1031
+ 'o-corner-ne': props.orientation === 'ne',
1032
+ 'o-corner-sw': props.orientation === 'sw',
1033
+ 'o-corner-se': props.orientation === 'se',
1034
+ }"
1035
+ />
1036
+ </t>
1037
+
1038
+ <t t-name="o-spreadsheet-Highlight" owl="1">
1039
+ <div class="o-highlight" t-ref="highlight">
1040
+ <t t-foreach="['n', 's', 'w', 'e']" t-as="orientation" t-key="orientation">
1041
+ <Border
1042
+ onMoveHighlight="(x, y) => this.onMoveHighlight(x,y)"
1043
+ isMoving='highlightState.shiftingMode === "isMoving"'
1044
+ orientation="orientation"
1045
+ zone="props.zone"
1046
+ />
1047
+ </t>
1048
+ <t t-foreach="['nw', 'ne', 'sw', 'se']" t-as="orientation" t-key="orientation">
1049
+ <Corner
1050
+ onResizeHighlight="(isLeft, isTop) => this.onResizeHighlight(isLeft, isTop)"
1051
+ isResizing='highlightState.shiftingMode === "isResizing"'
1052
+ orientation="orientation"
1053
+ zone="props.zone"
1054
+ color="props.color"
1055
+ />
1056
+ </t>
1057
+ </div>
1058
+ </t>
1059
+
1060
+ <t t-name="o-spreadsheet-IconPicker" owl="1">
1061
+ <div class="o-icon-picker">
1062
+ <t t-foreach="iconSets" t-as="iconSet" t-key="iconSet">
1063
+ <div class="o-cf-icon-line">
1064
+ <div
1065
+ class="o-icon-picker-item"
1066
+ t-on-click="() => this.onIconClick(iconSets[iconSet].good)">
1067
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].good].template}}"/>
1068
+ </div>
1069
+ <div
1070
+ class="o-icon-picker-item"
1071
+ t-on-click="() => this.onIconClick(iconSets[iconSet].neutral)">
1072
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].neutral].template}}"/>
1073
+ </div>
1074
+ <div
1075
+ class="o-icon-picker-item"
1076
+ t-on-click="() => this.onIconClick(iconSets[iconSet].bad)">
1077
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].bad].template}}"/>
1078
+ </div>
1079
+ </div>
1080
+ </t>
1081
+ </div>
1082
+ </t>
1083
+
1084
+ <t t-name="o-spreadsheet-Icon.UNDO" owl="1">
1085
+ <svg class="o-icon">
1086
+ <path
1087
+ fill="#000000"
1088
+ d="M11.5656391,4.43436088 L9,7 L16,7 L16,0 L13.0418424,2.95815758 C11.5936787,1.73635959 9.72260775,1 7.67955083,1 C4.22126258,1 1.25575599,3.10984908 0,6 L2,7 C2.93658775,4.60974406 5.12943697,3.08011229 7.67955083,3 C9.14881247,3.0528747 10.4994783,3.57862053 11.5656391,4.43436088 Z"
1089
+ transform="matrix(-1 0 0 1 17 5)"
1090
+ />
1091
+ </svg>
1092
+ </t>
1093
+ <t t-name="o-spreadsheet-Icon.REDO" owl="1">
1094
+ <svg class="o-icon">
1095
+ <path
1096
+ fill="#000000"
1097
+ d="M11.5656391,4.43436088 L9,7 L16,7 L16,0 L13.0418424,2.95815758 C11.5936787,1.73635959 9.72260775,1 7.67955083,1 C4.22126258,1 1.25575599,3.10984908 0,6 L2,7 C2.93658775,4.60974406 5.12943697,3.08011229 7.67955083,3 C9.14881247,3.0528747 10.4994783,3.57862053 11.5656391,4.43436088 Z"
1098
+ transform="translate(1 5)"
1099
+ />
1100
+ </svg>
1101
+ </t>
1102
+ <t t-name="o-spreadsheet-Icon.PAINT_FORMAT" owl="1">
1103
+ <svg class="o-icon">
1104
+ <path
1105
+ fill="#000000"
1106
+ 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"
1107
+ transform="translate(3 2)"
1108
+ />
1109
+ </svg>
1110
+ </t>
1111
+ <t t-name="o-spreadsheet-Icon.CLEAR_FORMAT" owl="1">
1112
+ <svg class="o-icon">
1113
+ <path
1114
+ fill="#000000"
1115
+ d="M0.27,1.55 L5.43,6.7 L3,12 L5.5,12 L7.14,8.42 L11.73,13 L13,11.73 L1.55,0.27 L0.27,1.55 L0.27,1.55 Z M3.82,0 L5.82,2 L7.58,2 L7.03,3.21 L8.74,4.92 L10.08,2 L14,2 L14,0 L3.82,0 L3.82,0 Z"
1116
+ transform="translate(2 3)"
1117
+ />
1118
+ </svg>
1119
+ </t>
1120
+ <t t-name="o-spreadsheet-Icon.TRIANGLE_DOWN" owl="1">
1121
+ <svg class="o-icon">
1122
+ <polygon fill="#000000" points="0 0 4 4 8 0" transform="translate(5 7)"/>
1123
+ </svg>
1124
+ </t>
1125
+ <t t-name="o-spreadsheet-Icon.TRIANGLE_UP" owl="1">
1126
+ <svg class="o-icon">
1127
+ <polygon fill="#000000" points="4 0 0 4 8 4" transform="translate(5 7)"/>
1128
+ </svg>
1129
+ </t>
1130
+ <t t-name="o-spreadsheet-Icon.TRIANGLE_RIGHT" owl="1">
1131
+ <svg class="o-icon">
1132
+ <polygon fill="#000000" points="0 0 4 4 0 8" transform="translate(5 5)"/>
1133
+ </svg>
1134
+ </t>
1135
+ <t t-name="o-spreadsheet-Icon.TRIANGLE_LEFT" owl="1">
1136
+ <svg class="o-icon">
1137
+ <polygon fill="#000000" points="4 0 0 4 4 8" transform="translate(5 5)"/>
1138
+ </svg>
1139
+ </t>
1140
+ <t t-name="o-spreadsheet-Icon.BOLD" owl="1">
1141
+ <svg class="o-icon">
1142
+ <path
1143
+ fill="#000000"
1144
+ fill-rule="evenodd"
1145
+ d="M9,3.5 C9,1.57 7.43,0 5.5,0 L1.77635684e-15,0 L1.77635684e-15,12 L6.25,12 C8.04,12 9.5,10.54 9.5,8.75 C9.5,7.45 8.73,6.34 7.63,5.82 C8.46,5.24 9,4.38 9,3.5 Z M5,2 C5.82999992,2 6.5,2.67 6.5,3.5 C6.5,4.33 5.82999992,5 5,5 L3,5 L3,2 L5,2 Z M3,10 L3,7 L5.5,7 C6.32999992,7 7,7.67 7,8.5 C7,9.33 6.32999992,10 5.5,10 L3,10 Z"
1146
+ transform="translate(4 3)"
1147
+ />
1148
+ </svg>
1149
+ </t>
1150
+ <t t-name="o-spreadsheet-Icon.ITALIC" owl="1">
1151
+ <svg class="o-icon">
1152
+ <polygon
1153
+ fill="#000000"
1154
+ fill-rule="evenodd"
1155
+ points="4 0 4 2 6.58 2 2.92 10 0 10 0 12 8 12 8 10 5.42 10 9.08 2 12 2 12 0"
1156
+ transform="translate(3 3)"
1157
+ />
1158
+ </svg>
1159
+ </t>
1160
+ <t t-name="o-spreadsheet-Icon.UNDERLINE" owl="1">
1161
+ <svg class="o-icon">
1162
+ <path
1163
+ fill="#000000"
1164
+ d="M6,12 C8.76,12 11,9.76 11,7 L11,0 L9,0 L9,7 C9,8.75029916 7.49912807,10 6,10 C4.50087193,10 3,8.75837486 3,7 L3,0 L1,0 L1,7 C1,9.76 3.24,12 6,12 Z M0,13 L0,15 L12,15 L12,13 L0,13 Z"
1165
+ transform="translate(3 3)"
1166
+ />
1167
+ </svg>
1168
+ </t>
1169
+ <t t-name="o-spreadsheet-Icon.STRIKE" owl="1">
1170
+ <svg class="o-icon">
1171
+ <path
1172
+ fill="#010101"
1173
+ fill-rule="evenodd"
1174
+ d="M2.8875,3.06 C2.8875,2.6025 2.985,2.18625 3.18375,1.8075 C3.3825,1.42875 3.66,1.10625 4.02,0.84 C4.38,0.57375 4.80375,0.3675 5.29875,0.22125 C5.79375,0.075 6.33375,0 6.92625,0 C7.53375,0 8.085,0.0825 8.58,0.25125 C9.075,0.42 9.49875,0.6525 9.85125,0.95625 C10.20375,1.25625 10.47375,1.6125 10.665,2.02875 C10.85625,2.44125 10.95,2.895 10.95,3.38625 L8.6925,3.38625 C8.6925,3.1575 8.655,2.94375 8.58375,2.74875 C8.5125,2.55 8.4,2.38125 8.25,2.2425 C8.1,2.10375 7.9125,1.99125 7.6875,1.91625 C7.4625,1.8375 7.19625,1.8 6.88875,1.8 C6.5925,1.8 6.3375,1.83375 6.11625,1.8975 C5.89875,1.96125 5.71875,2.05125 5.57625,2.1675 C5.43375,2.28375 5.325,2.41875 5.25375,2.5725 C5.1825,2.72625 5.145,2.895 5.145,3.0675 C5.145,3.4275 5.32875,3.73125 5.69625,3.975 C5.71780203,3.98908066 5.73942012,4.00311728 5.76118357,4.01733315 C6.02342923,4.18863185 6.5,4.5 7,5 L4,5 C4,5 3.21375,4.37625 3.17625,4.30875 C2.985,3.9525 2.8875,3.53625 2.8875,3.06 Z M14,6 L0,6 L0,8 L7.21875,8 C7.35375,8.0525 7.51875,8.105 7.63125,8.15375 C7.90875,8.2775 8.12625,8.40875 8.28375,8.53625 C8.44125,8.6675 8.54625,8.81 8.6025,8.96 C8.65875,9.11375 8.685,9.28625 8.685,9.47375 C8.685,9.65 8.65125,9.815 8.58375,9.965 C8.51625,10.11875 8.41125,10.25 8.2725,10.35875 C8.13375,10.4675 7.95375,10.55375 7.74,10.6175 C7.5225,10.68125 7.27125,10.71125 6.97875,10.71125 C6.6525,10.71125 6.35625,10.6775 6.09,10.61375 C5.82375,10.55 5.59875,10.445 5.41125,10.3025 C5.22375,10.16 5.0775,9.9725 4.9725,9.74375 C4.8675,9.515 4.78125,9.17 4.78125,9 L2.55,9 C2.55,9.2525 2.61,9.6875 2.72625,10.025 C2.8425,10.3625 3.0075,10.66625 3.21375,10.9325 C3.42,11.19875 3.6675,11.4275 3.94875,11.6225 C4.23,11.8175 4.53375,11.9825 4.86375,12.11 C5.19375,12.24125 5.535,12.33875 5.89875,12.39875 C6.25875,12.4625 6.6225,12.4925 6.9825,12.4925 C7.5825,12.4925 8.13,12.425 8.6175,12.28625 C9.105,12.1475 9.525,11.94875 9.87,11.69375 C10.215,11.435 10.48125,11.12 10.6725,10.74125 C10.86375,10.3625 10.95375,9.935 10.95375,9.455 C10.95375,9.005 10.875,8.6 10.72125,8.24375 C10.68375,8.1575 10.6425,8.075 10.59375,7.9925 L14,8 L14,6 Z"
1175
+ transform="translate(2 3)"
1176
+ />
1177
+ </svg>
1178
+ </t>
1179
+
1180
+ <t t-name="o-spreadsheet-Icon.TEXT_COLOR" owl="1">
1181
+ <svg class="o-icon">
1182
+ <path
1183
+ fill="#000000"
1184
+ d="M7,0 L5,0 L0.5,12 L2.5,12 L3.62,9 L8.37,9 L9.49,12 L11.49,12 L7,0 L7,0 Z M4.38,7 L6,2.67 L7.62,7 L4.38,7 L4.38,7 Z"
1185
+ transform="translate(3 1)"
1186
+ />
1187
+ </svg>
1188
+ </t>
1189
+ <t t-name="o-spreadsheet-Icon.FILL_COLOR" owl="1">
1190
+ <svg class="o-icon">
1191
+ <path
1192
+ fill="#000000"
1193
+ d="M14.5,8.87 C14.5,8.87 13,10.49 13,11.49 C13,12.32 13.67,12.99 14.5,12.99 C15.33,12.99 16,12.32 16,11.49 C16,10.5 14.5,8.87 14.5,8.87 L14.5,8.87 Z M12.71,6.79 L5.91,0 L4.85,1.06 L6.44,2.65 L2.29,6.79 C1.9,7.18 1.9,7.81 2.29,8.2 L6.79,12.7 C6.99,12.9 7.24,13 7.5,13 C7.76,13 8.01,12.9 8.21,12.71 L12.71,8.21 C13.1,7.82 13.1,7.18 12.71,6.79 L12.71,6.79 Z M4.21,7 L7.5,3.71 L10.79,7 L4.21,7 L4.21,7 Z"
1194
+ />
1195
+ </svg>
1196
+ </t>
1197
+ <t t-name="o-spreadsheet-Icon.MERGE_CELL" owl="1">
1198
+ <svg class="o-icon">
1199
+ <path
1200
+ fill="#000000"
1201
+ d="M3,6 L1,6 L1,2 L8,2 L8,4 L3,4 L3,6 Z M10,4 L10,2 L17,2 L17,6 L15,6 L15,4 L10,4 Z M10,14 L15,14 L15,12 L17,12 L17,16 L10,16 L10,14 Z M1,12 L3,12 L3,14 L8,14 L8,16 L1,16 L1,12 Z M1,8 L5,8 L5,6 L8,9 L5,12 L5,10 L1,10 L1,8 Z M10,9 L13,6 L13,8 L17,8 L17,10 L13,10 L13,12 L10,9 Z"
1202
+ />
1203
+ </svg>
1204
+ </t>
1205
+ <t t-name="o-spreadsheet-Icon.ALIGN_LEFT" owl="1">
1206
+ <svg class="o-icon align-left">
1207
+ <path
1208
+ fill="#000000"
1209
+ d="M0,14 L10,14 L10,12 L0,12 L0,14 Z M10,4 L0,4 L0,6 L10,6 L10,4 Z M0,0 L0,2 L14,2 L14,0 L0,0 Z M0,10 L14,10 L14,8 L0,8 L0,10 Z"
1210
+ transform="translate(2 2)"
1211
+ />
1212
+ </svg>
1213
+ </t>
1214
+ <t t-name="o-spreadsheet-Icon.ALIGN_CENTER" owl="1">
1215
+ <svg class="o-icon align-center">
1216
+ <path
1217
+ fill="#000000"
1218
+ d="M2,12 L2,14 L12,14 L12,12 L2,12 Z M2,4 L2,6 L12,6 L12,4 L2,4 Z M0,10 L14,10 L14,8 L0,8 L0,10 Z M0,0 L0,2 L14,2 L14,0 L0,0 Z"
1219
+ transform="translate(2 2)"
1220
+ />
1221
+ </svg>
1222
+ </t>
1223
+ <t t-name="o-spreadsheet-Icon.ALIGN_RIGHT" owl="1">
1224
+ <svg class="o-icon align-right">
1225
+ <path
1226
+ fill="#000000"
1227
+ d="M4,14 L14,14 L14,12 L4,12 L4,14 Z M0,10 L14,10 L14,8 L0,8 L0,10 Z M0,0 L0,2 L14,2 L14,0 L0,0 Z M4,6 L14,6 L14,4 L4,4 L4,6 Z"
1228
+ transform="translate(2 2)"
1229
+ />
1230
+ </svg>
1231
+ </t>
1232
+ <t t-name="o-spreadsheet-Icon.ALIGN_TOP" owl="1">
1233
+ <svg class="o-icon align-top" width="20" height="20">
1234
+ <rect x="3" y="2" width="12" height="2"/>
1235
+ <rect x="8" y="9" width="2" height="7"/>
1236
+ <polygon points="5.5 9 12.5 9 9 5.5"/>
1237
+ </svg>
1238
+ </t>
1239
+ <t t-name="o-spreadsheet-Icon.ALIGN_MIDDLE" owl="1">
1240
+ <svg class="o-icon align-middle" width="20" height="20">
1241
+ <polygon points="12.5 3 10 3 10 0 8 0 8 3 5.5 3 9 6.5"/>
1242
+ <polygon points="5.5 15 8 15 8 18 10 18 10 15 12.5 15 9 11.5"/>
1243
+ <rect x="3" y="8" width="12" height="2"/>
1244
+ </svg>
1245
+ </t>
1246
+ <t t-name="o-spreadsheet-Icon.ALIGN_BOTTOM" owl="1">
1247
+ <svg class="o-icon align-bottom" width="20" height="20">
1248
+ <rect x="3" y="14" width="12" height="2"/>
1249
+ <rect x="8" y="2" width="2" height="7"/>
1250
+ <polygon points="5.5 9 12.5 9 9 12.5"/>
1251
+ </svg>
1252
+ </t>
1253
+ <t t-name="o-spreadsheet-Icon.WRAPPING_OVERFLOW" owl="1">
1254
+ <svg class="o-icon wrapping-overflow" width="20" height="20">
1255
+ <rect x="2" y="2" width="2" height="14"/>
1256
+ <rect x="9" y="2" width="2" height="4"/>
1257
+ <rect x="9" y="12" width="2" height="4"/>
1258
+ <polygon points="13 8 6 8 6 10 13 10 13 12 16 9 13 6"/>
1259
+ </svg>
1260
+ </t>
1261
+ <t t-name="o-spreadsheet-Icon.WRAPPING_WRAP" owl="1">
1262
+ <svg class="o-icon wrapping-wrap" width="20" height="20">
1263
+ <rect x="2" y="2" width="2" height="14"/>
1264
+ <rect x="14" y="2" width="2" height="14"/>
1265
+ <path
1266
+ d="M6,5 L6,7 L9.75,7 C10.5,7 11.25,7.67 11.25,8.5 C11.25,9.25 10.5,10 9.75,10 L8,10 L8,12 L9.5,12 C11.5,12 13,10.5 13,8.5 C13,6.5 11.5,5 9.5,5 L6,5 Z"
1267
+ />
1268
+ <polygon points="8 10 8 8 5 11 8 14 8 12"/>
1269
+ </svg>
1270
+ </t>
1271
+ <t t-name="o-spreadsheet-Icon.WRAPPING_CLIP" owl="1">
1272
+ <svg class="o-icon wrapping-clip" width="20" height="20">
1273
+ <rect x="2" y="2" width="2" height="14"/>
1274
+ <rect x="14" y="2" width="2" height="14"/>
1275
+ <rect x="6" y="8" width="8" height="2"/>
1276
+ </svg>
1277
+ </t>
1278
+ <t t-name="o-spreadsheet-Icon.BORDERS" owl="1">
1279
+ <svg class="o-icon">
1280
+ <path
1281
+ fill="#000000"
1282
+ d="M0,0 L0,14 L14,14 L14,0 L0,0 L0,0 Z M6,12 L2,12 L2,8 L6,8 L6,12 L6,12 Z M6,6 L2,6 L2,2 L6,2 L6,6 L6,6 Z M12,12 L8,12 L8,8 L12,8 L12,12 L12,12 Z M12,6 L8,6 L8,2 L12,2 L12,6 L12,6 Z"
1283
+ transform="translate(2 2)"
1284
+ />
1285
+ </svg>
1286
+ </t>
1287
+ <t t-name="o-spreadsheet-Icon.BORDER_HV" owl="1">
1288
+ <svg class="o-icon">
1289
+ <g fill="#000000" transform="translate(2 2)">
1290
+ <path
1291
+ d="M0,14 L2,14 L2,12 L0,12 L0,14 L0,14 Z M2,3 L0,3 L0,5 L2,5 L2,3 L2,3 Z M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M11,0 L9,0 L9,2 L11,2 L11,0 L11,0 Z M2,0 L0,0 L0,2 L2,2 L2,0 L2,0 Z M5,0 L3,0 L3,2 L5,2 L5,0 L5,0 Z M0,11 L2,11 L2,9 L0,9 L0,11 L0,11 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z M12,0 L12,2 L14,2 L14,0 L12,0 L12,0 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M12,14 L14,14 L14,12 L12,12 L12,14 L12,14 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z"
1292
+ opacity=".54"
1293
+ />
1294
+ <polygon points="8 0 6 0 6 6 0 6 0 8 6 8 6 14 8 14 8 8 14 8 14 6 8 6"/>
1295
+ </g>
1296
+ </svg>
1297
+ </t>
1298
+ <t t-name="o-spreadsheet-Icon.BORDER_H" owl="1">
1299
+ <svg class="o-icon">
1300
+ <g fill="#000000" transform="translate(2 2)">
1301
+ <path
1302
+ d="M6,14 L8,14 L8,12 L6,12 L6,14 L6,14 Z M3,2 L5,2 L5,0 L3,0 L3,2 L3,2 Z M6,11 L8,11 L8,9 L6,9 L6,11 L6,11 Z M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M0,5 L2,5 L2,3 L0,3 L0,5 L0,5 Z M0,14 L2,14 L2,12 L0,12 L0,14 L0,14 Z M0,2 L2,2 L2,0 L0,0 L0,2 L0,2 Z M0,11 L2,11 L2,9 L0,9 L0,11 L0,11 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z M12,14 L14,14 L14,12 L12,12 L12,14 L12,14 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M12,0 L12,2 L14,2 L14,0 L12,0 L12,0 Z M6,2 L8,2 L8,0 L6,0 L6,2 L6,2 Z M9,2 L11,2 L11,0 L9,0 L9,2 L9,2 Z M6,5 L8,5 L8,3 L6,3 L6,5 L6,5 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z"
1303
+ opacity=".54"
1304
+ />
1305
+ <polygon points="0 8 14 8 14 6 0 6"/>
1306
+ </g>
1307
+ </svg>
1308
+ </t>
1309
+ <t t-name="o-spreadsheet-Icon.BORDER_V" owl="1">
1310
+ <svg class="o-icon">
1311
+ <g fill="#000000" transform="translate(2 2)">
1312
+ <path
1313
+ d="M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M0,5 L2,5 L2,3 L0,3 L0,5 L0,5 Z M0,2 L2,2 L2,0 L0,0 L0,2 L0,2 Z M3,8 L5,8 L5,6 L3,6 L3,8 L3,8 Z M3,2 L5,2 L5,0 L3,0 L3,2 L3,2 Z M0,14 L2,14 L2,12 L0,12 L0,14 L0,14 Z M0,8 L2,8 L2,6 L0,6 L0,8 L0,8 Z M0,11 L2,11 L2,9 L0,9 L0,11 L0,11 Z M12,0 L12,2 L14,2 L14,0 L12,0 L12,0 Z M12,8 L14,8 L14,6 L12,6 L12,8 L12,8 Z M12,14 L14,14 L14,12 L12,12 L12,14 L12,14 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z M9,8 L11,8 L11,6 L9,6 L9,8 L9,8 Z M9,2 L11,2 L11,0 L9,0 L9,2 L9,2 Z"
1314
+ opacity=".54"
1315
+ />
1316
+ <polygon points="6 14 8 14 8 0 6 0"/>
1317
+ </g>
1318
+ </svg>
1319
+ </t>
1320
+ <t t-name="o-spreadsheet-Icon.BORDER_EXTERNAL" owl="1">
1321
+ <svg class="o-icon">
1322
+ <g fill="#000000" transform="translate(2 2)">
1323
+ <path
1324
+ d="M8,3 L6,3 L6,5 L8,5 L8,3 L8,3 Z M11,6 L9,6 L9,8 L11,8 L11,6 L11,6 Z M8,6 L6,6 L6,8 L8,8 L8,6 L8,6 Z M8,9 L6,9 L6,11 L8,11 L8,9 L8,9 Z M5,6 L3,6 L3,8 L5,8 L5,6 L5,6 Z"
1325
+ opacity=".54"
1326
+ />
1327
+ <path d="M0,0 L14,0 L14,14 L0,14 L0,0 Z M12,12 L12,2 L2,2 L2,12 L12,12 Z"/>
1328
+ </g>
1329
+ </svg>
1330
+ </t>
1331
+ <t t-name="o-spreadsheet-Icon.BORDER_LEFT" owl="1">
1332
+ <svg class="o-icon">
1333
+ <g fill="#000000" transform="translate(2 2)">
1334
+ <path
1335
+ d="M6,8 L8,8 L8,6 L6,6 L6,8 L6,8 Z M6,5 L8,5 L8,3 L6,3 L6,5 L6,5 Z M6,11 L8,11 L8,9 L6,9 L6,11 L6,11 Z M6,14 L8,14 L8,12 L6,12 L6,14 L6,14 Z M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M3,2 L5,2 L5,0 L3,0 L3,2 L3,2 Z M3,8 L5,8 L5,6 L3,6 L3,8 L3,8 Z M12,14 L14,14 L14,12 L12,12 L12,14 L12,14 Z M12,8 L14,8 L14,6 L12,6 L12,8 L12,8 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M6,2 L8,2 L8,0 L6,0 L6,2 L6,2 Z M12,0 L12,2 L14,2 L14,0 L12,0 L12,0 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z M9,8 L11,8 L11,6 L9,6 L9,8 L9,8 Z M9,2 L11,2 L11,0 L9,0 L9,2 L9,2 Z"
1336
+ opacity=".54"
1337
+ />
1338
+ <polygon points="0 14 2 14 2 0 0 0"/>
1339
+ </g>
1340
+ </svg>
1341
+ </t>
1342
+ <t t-name="o-spreadsheet-Icon.BORDER_TOP" owl="1">
1343
+ <svg class="o-icon">
1344
+ <g fill="#000000" transform="translate(2 2)">
1345
+ <path
1346
+ d="M3,8 L5,8 L5,6 L3,6 L3,8 L3,8 Z M0,14 L2,14 L2,12 L0,12 L0,14 L0,14 Z M6,14 L8,14 L8,12 L6,12 L6,14 L6,14 Z M6,11 L8,11 L8,9 L6,9 L6,11 L6,11 Z M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M0,11 L2,11 L2,9 L0,9 L0,11 L0,11 Z M6,8 L8,8 L8,6 L6,6 L6,8 L6,8 Z M0,5 L2,5 L2,3 L0,3 L0,5 L0,5 Z M0,8 L2,8 L2,6 L0,6 L0,8 L0,8 Z M12,8 L14,8 L14,6 L12,6 L12,8 L12,8 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M6,5 L8,5 L8,3 L6,3 L6,5 L6,5 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z M9,8 L11,8 L11,6 L9,6 L9,8 L9,8 Z M12,14 L14,14 L14,12 L12,12 L12,14 L12,14 Z"
1347
+ opacity=".54"
1348
+ />
1349
+ <polygon points="0 0 0 2 14 2 14 0"/>
1350
+ </g>
1351
+ </svg>
1352
+ </t>
1353
+ <t t-name="o-spreadsheet-Icon.BORDER_RIGHT" owl="1">
1354
+ <svg class="o-icon">
1355
+ <g fill="#000000" transform="translate(2 2)">
1356
+ <path
1357
+ d="M0,2 L2,2 L2,0 L0,0 L0,2 L0,2 Z M3,2 L5,2 L5,0 L3,0 L3,2 L3,2 Z M3,8 L5,8 L5,6 L3,6 L3,8 L3,8 Z M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M0,5 L2,5 L2,3 L0,3 L0,5 L0,5 Z M0,8 L2,8 L2,6 L0,6 L0,8 L0,8 Z M0,14 L2,14 L2,12 L0,12 L0,14 L0,14 Z M0,11 L2,11 L2,9 L0,9 L0,11 L0,11 Z M9,8 L11,8 L11,6 L9,6 L9,8 L9,8 Z M6,14 L8,14 L8,12 L6,12 L6,14 L6,14 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z M6,2 L8,2 L8,0 L6,0 L6,2 L6,2 Z M9,2 L11,2 L11,0 L9,0 L9,2 L9,2 Z M6,11 L8,11 L8,9 L6,9 L6,11 L6,11 Z M6,5 L8,5 L8,3 L6,3 L6,5 L6,5 Z M6,8 L8,8 L8,6 L6,6 L6,8 L6,8 Z"
1358
+ opacity=".54"
1359
+ />
1360
+ <polygon points="12 0 12 14 14 14 14 0"/>
1361
+ </g>
1362
+ </svg>
1363
+ </t>
1364
+ <t t-name="o-spreadsheet-Icon.BORDER_BOTTOM" owl="1">
1365
+ <svg class="o-icon">
1366
+ <g fill="#000000" transform="translate(2 2)">
1367
+ <path
1368
+ d="M5,0 L3,0 L3,2 L5,2 L5,0 L5,0 Z M8,6 L6,6 L6,8 L8,8 L8,6 L8,6 Z M8,9 L6,9 L6,11 L8,11 L8,9 L8,9 Z M11,6 L9,6 L9,8 L11,8 L11,6 L11,6 Z M5,6 L3,6 L3,8 L5,8 L5,6 L5,6 Z M11,0 L9,0 L9,2 L11,2 L11,0 L11,0 Z M8,3 L6,3 L6,5 L8,5 L8,3 L8,3 Z M8,0 L6,0 L6,2 L8,2 L8,0 L8,0 Z M2,9 L0,9 L0,11 L2,11 L2,9 L2,9 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M12,8 L14,8 L14,6 L12,6 L12,8 L12,8 Z M12,0 L12,2 L14,2 L14,0 L12,0 L12,0 Z M2,0 L0,0 L0,2 L2,2 L2,0 L2,0 Z M2,3 L0,3 L0,5 L2,5 L2,3 L2,3 Z M2,6 L0,6 L0,8 L2,8 L2,6 L2,6 Z"
1369
+ opacity=".54"
1370
+ />
1371
+ <polygon points="0 14 14 14 14 12 0 12"/>
1372
+ </g>
1373
+ </svg>
1374
+ </t>
1375
+ <t t-name="o-spreadsheet-Icon.BORDER_CLEAR" owl="1">
1376
+ <svg class="o-icon">
1377
+ <path
1378
+ fill="#000000"
1379
+ fill-rule="evenodd"
1380
+ d="M6,14 L8,14 L8,12 L6,12 L6,14 L6,14 Z M3,8 L5,8 L5,6 L3,6 L3,8 L3,8 Z M3,2 L5,2 L5,0 L3,0 L3,2 L3,2 Z M6,11 L8,11 L8,9 L6,9 L6,11 L6,11 Z M3,14 L5,14 L5,12 L3,12 L3,14 L3,14 Z M0,5 L2,5 L2,3 L0,3 L0,5 L0,5 Z M0,14 L2,14 L2,12 L0,12 L0,14 L0,14 Z M0,2 L2,2 L2,0 L0,0 L0,2 L0,2 Z M0,8 L2,8 L2,6 L0,6 L0,8 L0,8 Z M6,8 L8,8 L8,6 L6,6 L6,8 L6,8 Z M0,11 L2,11 L2,9 L0,9 L0,11 L0,11 Z M12,11 L14,11 L14,9 L12,9 L12,11 L12,11 Z M12,14 L14,14 L14,12 L12,12 L12,14 L12,14 Z M12,8 L14,8 L14,6 L12,6 L12,8 L12,8 Z M12,5 L14,5 L14,3 L12,3 L12,5 L12,5 Z M12,0 L12,2 L14,2 L14,0 L12,0 L12,0 Z M6,2 L8,2 L8,0 L6,0 L6,2 L6,2 Z M9,2 L11,2 L11,0 L9,0 L9,2 L9,2 Z M6,5 L8,5 L8,3 L6,3 L6,5 L6,5 Z M9,14 L11,14 L11,12 L9,12 L9,14 L9,14 Z M9,8 L11,8 L11,6 L9,6 L9,8 L9,8 Z"
1381
+ transform="translate(2 2)"
1382
+ opacity=".54"
1383
+ />
1384
+ </svg>
1385
+ </t>
1386
+
1387
+ <t t-name="o-spreadsheet-Icon.PLUS" owl="1">
1388
+ <svg class="o-icon" viewBox="0 0 18 18">
1389
+ <path d="M8,0 L10,0 L10,8 L18,8 L18,10 L10,10 L10,18 L8,18 L8,10 L0,10 L0,8 L8,8"/>
1390
+ </svg>
1391
+ </t>
1392
+ <t t-name="o-spreadsheet-Icon.LIST" owl="1">
1393
+ <svg class="o-icon" viewBox="0 0 384 384">
1394
+ <rect x="0" y="277.333" width="384" height="42.667"/>
1395
+ <rect x="0" y="170.667" width="384" height="42.667"/>
1396
+ <rect x="0" y="64" width="384" height="42.667"/>
1397
+ </svg>
1398
+ </t>
1399
+
1400
+ <t t-name="o-spreadsheet-Icon.EDIT" owl="1">
1401
+ <svg class="o-icon" viewBox="0 0 576 512">
1402
+ <path
1403
+ fill="currentColor"
1404
+ 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"
1405
+ />
1406
+ </svg>
1407
+ </t>
1408
+ <t t-name="o-spreadsheet-Icon.UNLINK" owl="1">
1409
+ <svg class="o-icon" viewBox="0 0 512 512">
1410
+ <path
1411
+ fill="currentColor"
1412
+ 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"
1413
+ />
1414
+ </svg>
1415
+ </t>
1416
+ /** Font Awesome by Dave Gandy
1417
+ * http://fontawesome.io/
1418
+ * https://fontawesome.com/license
1419
+ */
1420
+ <t t-name="o-spreadsheet-Icon.CARET_UP" owl="1">
1421
+ <svg class="caret-up" viewBox="0 0 320 512">
1422
+ <path
1423
+ fill="currentColor"
1424
+ 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"
1425
+ />
1426
+ </svg>
1427
+ </t>
1428
+ <t t-name="o-spreadsheet-Icon.CARET_DOWN" owl="1">
1429
+ <svg class="caret-down" viewBox="0 0 320 512">
1430
+ <path
1431
+ fill="currentColor"
1432
+ 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"
1433
+ />
1434
+ </svg>
1435
+ </t>
1436
+ <t t-name="o-spreadsheet-Icon.CARET_RIGHT" owl="1">
1437
+ <svg class="o-icon caret-right" viewBox="0 0 192 512">
1438
+ <path
1439
+ 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"
1440
+ />
1441
+ </svg>
1442
+ </t>
1443
+ <t t-name="o-spreadsheet-Icon.CARET_LEFT" owl="1">
1444
+ <svg class="o-icon caret-left" viewBox="0 0 192 512">
1445
+ <path
1446
+ 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"
1447
+ />
1448
+ </svg>
1449
+ </t>
1450
+
1451
+ <t t-name="o-spreadsheet-Icon.TRASH" owl="1">
1452
+ <svg class="o-cf-icon trash" viewBox="0 0 448 512">
1453
+ <path
1454
+ fill="currentColor"
1455
+ 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"
1456
+ />
1457
+ </svg>
1458
+ </t>
1459
+ <t t-name="o-spreadsheet-Icon.REFRESH" owl="1">
1460
+ <svg class="o-cf-icon refresh" viewBox="0 0 512 512">
1461
+ <path
1462
+ fill="currentColor"
1463
+ 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"
1464
+ />
1465
+ </svg>
1466
+ </t>
1467
+
1468
+ <t t-name="o-spreadsheet-Icon.ARROW_DOWN" owl="1">
1469
+ <svg
1470
+ class="o-cf-icon arrow-down"
1471
+ width="10"
1472
+ height="10"
1473
+ focusable="false"
1474
+ viewBox="0 0 448 512">
1475
+ <path
1476
+ fill="#DC6965"
1477
+ t-att-style="color"
1478
+ 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"
1479
+ />
1480
+ </svg>
1481
+ </t>
1482
+ <t t-name="o-spreadsheet-Icon.ARROW_UP" owl="1">
1483
+ <svg class="o-cf-icon arrow-up" width="10" height="10" focusable="false" viewBox="0 0 448 512">
1484
+ <path
1485
+ fill="#00A04A"
1486
+ t-att-style="color"
1487
+ 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"
1488
+ />
1489
+ </svg>
1490
+ </t>
1491
+ <t t-name="o-spreadsheet-Icon.ARROW_RIGHT" owl="1">
1492
+ <svg
1493
+ class="o-cf-icon arrow-right"
1494
+ width="10"
1495
+ height="10"
1496
+ focusable="false"
1497
+ viewBox="0 0 448 512">
1498
+ <path
1499
+ fill="#F0AD4E"
1500
+ 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"
1501
+ />
1502
+ </svg>
1503
+ </t>
1504
+
1505
+ <t t-name="o-spreadsheet-Icon.SMILE" owl="1">
1506
+ <svg class="o-cf-icon smile" width="10" height="10" focusable="false" viewBox="0 0 496 512">
1507
+ <path
1508
+ fill="#00A04A"
1509
+ 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"
1510
+ />
1511
+ </svg>
1512
+ </t>
1513
+ <t t-name="o-spreadsheet-Icon.MEH" owl="1">
1514
+ <svg class="o-cf-icon meh" width="10" height="10" focusable="false" viewBox="0 0 496 512">
1515
+ <path
1516
+ fill="#F0AD4E"
1517
+ 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"
1518
+ />
1519
+ </svg>
1520
+ </t>
1521
+ <t t-name="o-spreadsheet-Icon.FROWN" owl="1">
1522
+ <svg class="o-cf-icon frown" width="10" height="10" focusable="false" viewBox="0 0 496 512">
1523
+ <path
1524
+ fill="#DC6965"
1525
+ 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"
1526
+ />
1527
+ </svg>
1528
+ </t>
1529
+
1530
+ <t t-name="o-spreadsheet-Icon.GREEN_DOT" owl="1">
1531
+ <svg class="o-cf-icon green-dot" width="10" height="10" focusable="false" viewBox="0 0 512 512">
1532
+ <path
1533
+ fill="#00A04A"
1534
+ d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"
1535
+ />
1536
+ </svg>
1537
+ </t>
1538
+ <t t-name="o-spreadsheet-Icon.YELLOW_DOT" owl="1">
1539
+ <svg
1540
+ class="o-cf-icon yellow-dot"
1541
+ width="10"
1542
+ height="10"
1543
+ focusable="false"
1544
+ viewBox="0 0 512 512">
1545
+ <path
1546
+ fill="#F0AD4E"
1547
+ d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"
1548
+ />
1549
+ </svg>
1550
+ </t>
1551
+ <t t-name="o-spreadsheet-Icon.RED_DOT" owl="1">
1552
+ <svg class="o-cf-icon red-dot" width="10" height="10" focusable="false" viewBox="0 0 512 512">
1553
+ <path
1554
+ fill="#DC6965"
1555
+ d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"
1556
+ />
1557
+ </svg>
1558
+ </t>
1559
+ <t t-name="o-spreadsheet-Icon.FILTER_ICON" owl="1">
1560
+ <svg
1561
+ class="o-cf-icon filter-icon"
1562
+ width="10"
1563
+ height="10"
1564
+ focusable="false"
1565
+ viewBox="0 0 850 850">
1566
+ <path
1567
+ fill="#000"
1568
+ 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"
1569
+ />
1570
+ </svg>
1571
+ </t>
1572
+ <t t-name="o-spreadsheet-Icon.FILTER_ICON_ACTIVE" owl="1">
1573
+ <svg
1574
+ class="o-cf-icon filter-icon-active"
1575
+ width="10"
1576
+ height="10"
1577
+ focusable="false"
1578
+ viewBox="0 0 512 512">
1579
+ <path
1580
+ fill="#188038"
1581
+ 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"
1582
+ />
1583
+ </svg>
1584
+ </t>
1585
+ <t t-name="o-spreadsheet-Icon.FILTER_ICON_INACTIVE" owl="1">
1586
+ <svg
1587
+ class="o-cf-icon filter-icon-inactive"
1588
+ width="10"
1589
+ height="10"
1590
+ focusable="false"
1591
+ viewBox="0 0 512 512">
1592
+ <path
1593
+ fill="#606162"
1594
+ 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"
1595
+ />
1596
+ </svg>
1597
+ </t>
1598
+ <t t-name="o-spreadsheet-Icon.SEARCH" owl="1">
1599
+ <svg class="search-icon" width="10" height="10" focusable="false" viewBox="0 0 512 512">
1600
+ <path
1601
+ fill="#949494"
1602
+ 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"
1603
+ />
1604
+ </svg>
1605
+ </t>
1606
+
1607
+ <t t-name="o-spreadsheet-LinkDisplay" owl="1">
1608
+ <div class="o-link-tool d-flex align-items-center">
1609
+ <!-- t-key to prevent owl from re-using the previous img element when the link changes.
1610
+ The wrong/previous image would be displayed while the new one loads -->
1611
+ <img
1612
+ t-if="link.isExternal"
1613
+ t-key="link.url"
1614
+ t-attf-src="https://www.google.com/s2/favicons?sz=16&amp;domain={{link.url}}"
1615
+ />
1616
+ <a
1617
+ t-if="link.isExternal"
1618
+ class="o-link"
1619
+ t-att-href="link.url"
1620
+ target="_blank"
1621
+ t-on-click.prevent="openLink"
1622
+ t-att-title="link.url">
1623
+ <t t-esc="getUrlRepresentation(link)"/>
1624
+ </a>
1625
+ <a
1626
+ t-else=""
1627
+ class="o-link"
1628
+ t-on-click.prevent="openLink"
1629
+ t-att-title="getUrlRepresentation(link)">
1630
+ <t t-esc="getUrlRepresentation(link)"/>
1631
+ </a>
1632
+ <span
1633
+ t-if="!env.model.getters.isReadonly()"
1634
+ class="o-link-icon o-unlink"
1635
+ t-on-click="unlink"
1636
+ title="Remove link">
1637
+ <t t-call="o-spreadsheet-Icon.UNLINK"/>
1638
+ </span>
1639
+ <span
1640
+ t-if="!env.model.getters.isReadonly()"
1641
+ class="o-link-icon o-edit-link"
1642
+ t-on-click="edit"
1643
+ title="Edit link">
1644
+ <t t-call="o-spreadsheet-Icon.EDIT"/>
1645
+ </span>
1646
+ </div>
1647
+ </t>
1648
+
1649
+ <t t-name="o-spreadsheet-LinkEditor" owl="1">
1650
+ <div
1651
+ class="o-link-editor"
1652
+ t-on-click.stop="() => this.menu.isOpen=false"
1653
+ t-on-keydown="onKeyDown"
1654
+ t-ref="linkEditor">
1655
+ <div class="o-section">
1656
+ <div class="o-section-title">Text</div>
1657
+ <div class="d-flex">
1658
+ <input type="text" title="Link label" class="o-input flex-grow-1" t-model="link.label"/>
1659
+ </div>
1660
+
1661
+ <div class="o-section-title mt-3">Link</div>
1662
+ <div class="o-link-url">
1663
+ <t t-if="link.isUrlEditable">
1664
+ <input type="text" title="Link URL" t-ref="urlInput" t-model="link.url"/>
1665
+ </t>
1666
+ <t t-else="">
1667
+ <input
1668
+ type="text"
1669
+ title="Link URL"
1670
+ t-att-value="getUrlRepresentation(link)"
1671
+ disabled="1"
1672
+ />
1673
+ </t>
1674
+ <button t-if="link.url" t-on-click="removeLink" class="o-remove-url">✖</button>
1675
+ <button t-if="!link.url" t-on-click.stop="openMenu" class="o-special-link">
1676
+ <t t-call="o-spreadsheet-Icon.LIST"/>
1677
+ </button>
1678
+ </div>
1679
+ </div>
1680
+ <Menu
1681
+ t-if="menu.isOpen"
1682
+ position="menuPosition"
1683
+ menuItems="menuItems"
1684
+ onMenuClicked="(ev) => this.onSpecialLink(ev)"
1685
+ onClose="() => this.menu.isOpen=false"
1686
+ />
1687
+ <div class="o-buttons">
1688
+ <button t-on-click="cancel" class="o-button o-cancel">Cancel</button>
1689
+ <button t-on-click="save" class="o-button o-save" t-att-disabled="!link.url">
1690
+ Confirm
1691
+ </button>
1692
+ </div>
1693
+ </div>
1694
+ </t>
1695
+
1696
+ <t t-name="o-spreadsheet-Menu" owl="1">
1697
+ <Popover t-if="visibleMenuItems.length" t-props="popoverProps">
1698
+ <div
1699
+ t-ref="menu"
1700
+ class="o-menu"
1701
+ t-on-scroll="onScroll"
1702
+ t-on-wheel.stop=""
1703
+ t-on-click.stop=""
1704
+ t-on-contextmenu.prevent="">
1705
+ <t t-foreach="visibleMenuItems" t-as="menuItem" t-key="menuItem.id">
1706
+ <t t-set="isMenuRoot" t-value="isRoot(menuItem)"/>
1707
+ <t t-set="isMenuEnabled" t-value="isEnabled(menuItem)"/>
1708
+ <div
1709
+ t-att-title="getName(menuItem)"
1710
+ t-att-data-name="menuItem.id"
1711
+ t-on-click="() => this.onClickMenu(menuItem, menuItem_index)"
1712
+ t-on-mouseover="() => this.onMouseOver(menuItem, menuItem_index)"
1713
+ class="o-menu-item"
1714
+ t-att-class="{ 'o-menu-root': isMenuRoot, 'disabled': !isMenuEnabled, 'o-menu-item-active': isParentMenu(subMenu, menuItem)}"
1715
+ t-att-style="getColor(menuItem)">
1716
+ <span class="o-menu-item-name" t-esc="getName(menuItem)"/>
1717
+ <span
1718
+ t-if="menuItem.description"
1719
+ class="o-menu-item-description"
1720
+ t-esc="menuItem.description"
1721
+ />
1722
+ <t t-if="isMenuRoot">
1723
+ <span t-call="o-spreadsheet-Icon.TRIANGLE_RIGHT"/>
1724
+ </t>
1725
+ <t t-elif="menuItem.icon">
1726
+ <i t-att-class="menuItem.icon" class="o-menu-item-icon"/>
1727
+ </t>
1728
+ </div>
1729
+ <div t-if="menuItem.separator and !menuItem_last" class="o-separator"/>
1730
+ </t>
1731
+ </div>
1732
+ <Menu
1733
+ t-if="subMenu.isOpen"
1734
+ position="subMenuPosition"
1735
+ menuItems="subMenu.menuItems"
1736
+ depth="props.depth + 1"
1737
+ maxHeight="props.maxHeight"
1738
+ onMenuClicked="props.onMenuClicked"
1739
+ onClose="() => this.close()"
1740
+ menuId="props.menuId"
1741
+ />
1742
+ </Popover>
1743
+ </t>
1744
+
1745
+ <t t-name="o-spreadsheet-Popover" owl="1">
1746
+ <t t-portal="'.o-spreadsheet'">
1747
+ <div
1748
+ class="o-popover"
1749
+ t-ref="popover"
1750
+ t-on-wheel="props.onMouseWheel"
1751
+ t-att-style="popoverStyle">
1752
+ <t t-slot="default"/>
1753
+ </div>
1754
+ </t>
1755
+ </t>
1756
+
1757
+ <t t-name="o-spreadsheet-ScrollBar" owl="1">
1758
+ <div class="o-scrollbar" t-on-scroll="onScroll" t-ref="scrollbar" t-att-style="positionCss">
1759
+ <div t-att-style="sizeCss"/>
1760
+ </div>
1761
+ </t>
1762
+
1763
+ <t t-name="o-spreadsheet-SelectionInput" owl="1">
1764
+ <div class="o-selection">
1765
+ <div
1766
+ t-foreach="ranges"
1767
+ t-as="range"
1768
+ t-key="range.id"
1769
+ class="o-selection-input"
1770
+ t-att-class="props.class">
1771
+ <input
1772
+ type="text"
1773
+ spellcheck="false"
1774
+ t-on-input="(ev) => this.onInputChanged(range.id, ev)"
1775
+ t-on-focus="() => this.focus(range.id)"
1776
+ t-on-keydown="onKeydown"
1777
+ t-att-value="range.xc"
1778
+ t-att-style="getColor(range)"
1779
+ t-att-class="{
1780
+ 'o-focused' : range.isFocused,
1781
+ 'o-required': props.required,
1782
+ 'o-optional': !props.required,
1783
+ 'o-invalid': isInvalid || !range.isValidRange,
1784
+ 'text-decoration-underline': range.isFocused and state.mode === 'select-range'
1785
+ }"
1786
+ t-ref="{{range.isFocused ? 'focusedInput' : 'unfocusedInput' + range_index}}"
1787
+ />
1788
+ <button
1789
+ class="o-btn o-remove-selection"
1790
+ t-if="ranges.length > 1"
1791
+ t-on-click="() => this.removeInput(range.id)">
1792
+ ✕
1793
+ </button>
1794
+ </div>
1795
+
1796
+ <div class="o-selection-input">
1797
+ <button class="o-btn-action o-add-selection" t-if="canAddRange" t-on-click="addEmptyInput">
1798
+ Add range
1799
+ </button>
1800
+ <button class="o-btn-action o-selection-ok" t-if="hasFocus" t-on-click="confirm">
1801
+ Confirm
1802
+ </button>
1803
+ </div>
1804
+ </div>
1805
+ </t>
1806
+
1807
+ <t t-name="o-spreadsheet-BarConfigPanel" owl="1">
1808
+ <div>
1809
+ <div class="o-section pt-0">
1810
+ <div class="o-checkbox">
1811
+ <label>
1812
+ <input
1813
+ type="checkbox"
1814
+ name="stacked"
1815
+ t-att-checked="props.definition.stacked"
1816
+ t-on-change="onUpdateStacked"
1817
+ class="align-middle"
1818
+ />
1819
+ Stacked barchart
1820
+ </label>
1821
+ </div>
1822
+ </div>
1823
+ <div class="o-section o-data-series">
1824
+ <div class="o-section-title">Data Series</div>
1825
+ <SelectionInput
1826
+ ranges="dataSeriesRanges"
1827
+ isInvalid="isDatasetInvalid"
1828
+ required="true"
1829
+ onSelectionChanged="(ranges) => this.onDataSeriesRangesChanged(ranges)"
1830
+ onSelectionConfirmed="() => this.onDataSeriesConfirmed()"
1831
+ />
1832
+ <label>
1833
+ <input
1834
+ type="checkbox"
1835
+ t-att-checked="props.definition.dataSetsHaveTitle"
1836
+ t-on-change="onUpdateDataSetsHaveTitle"
1837
+ class="align-middle"
1838
+ />
1839
+ Data series include title
1840
+ </label>
1841
+ </div>
1842
+ <div class="o-section o-data-labels">
1843
+ <div class="o-section-title">Categories / Labels</div>
1844
+ <SelectionInput
1845
+ ranges="[props.definition.labelRange || '']"
1846
+ isInvalid="isLabelInvalid"
1847
+ hasSingleRange="true"
1848
+ onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
1849
+ onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
1850
+ />
1851
+ <label>
1852
+ <input
1853
+ type="checkbox"
1854
+ name="aggregated"
1855
+ t-att-checked="props.definition.aggregated"
1856
+ t-on-change="onUpdateAggregated"
1857
+ class="align-middle"
1858
+ />
1859
+ Aggregate
1860
+ </label>
1861
+ </div>
1862
+ <div class="o-section o-sidepanel-error" t-if="errorMessages">
1863
+ <div t-foreach="errorMessages" t-as="error" t-key="error">
1864
+ <t t-esc="error"/>
1865
+ </div>
1866
+ </div>
1867
+ </div>
1868
+ </t>
1869
+
1870
+ <t t-name="o-spreadsheet-BarChartDesignPanel" owl="1">
1871
+ <div>
1872
+ <div class="o-section o-chart-background-color">
1873
+ <div class="o-section-title">Background color</div>
1874
+ Select a color...
1875
+ <ColorPickerWidget
1876
+ currentColor="props.definition.background"
1877
+ toggleColorPicker="() => this.toggleColorPicker()"
1878
+ showColorPicker="state.fillColorTool"
1879
+ onColorPicked="(color) => this.updateBackgroundColor(color)"
1880
+ title="env._t('Background Color')"
1881
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
1882
+ />
1883
+ </div>
1884
+ <div class="o-section o-chart-title">
1885
+ <div class="o-section-title">Title</div>
1886
+ <input
1887
+ type="text"
1888
+ t-att-value="env._t(props.definition.title)"
1889
+ t-on-change="updateTitle"
1890
+ class="o-input o-optional"
1891
+ placeholder="New Chart"
1892
+ />
1893
+ </div>
1894
+ <div class="o-section">
1895
+ <div class="o-section-title">Vertical axis position</div>
1896
+ <select
1897
+ t-att-value="props.definition.verticalAxisPosition"
1898
+ class="o-input o-type-selector"
1899
+ t-on-change="(ev) => this.updateSelect('verticalAxisPosition', ev)">
1900
+ <option value="left">Left</option>
1901
+ <option value="right">Right</option>
1902
+ </select>
1903
+ </div>
1904
+ <div class="o-section">
1905
+ <div class="o-section-title">Legend position</div>
1906
+ <select
1907
+ t-att-value="props.definition.legendPosition"
1908
+ class="o-input o-type-selector"
1909
+ t-on-change="(ev) => this.updateSelect('legendPosition', ev)">
1910
+ <option value="none">None</option>
1911
+ <option value="top">Top</option>
1912
+ <option value="bottom">Bottom</option>
1913
+ <option value="left">Left</option>
1914
+ <option value="right">Right</option>
1915
+ </select>
1916
+ </div>
1917
+ </div>
1918
+ </t>
1919
+
1920
+ <t t-name="o-spreadsheet-GaugeChartConfigPanel" owl="1">
1921
+ <div>
1922
+ <div class="o-section o-data-series">
1923
+ <div class="o-section-title">Data range</div>
1924
+ <SelectionInput
1925
+ ranges="[props.definition.dataRange || '']"
1926
+ isInvalid="isDataRangeInvalid"
1927
+ hasSingleRange="true"
1928
+ required="true"
1929
+ onSelectionChanged="(ranges) => this.onDataRangeChanged(ranges)"
1930
+ onSelectionConfirmed="() => this.updateDataRange()"
1931
+ />
1932
+ </div>
1933
+ <div class="o-section o-sidepanel-error" t-if="configurationErrorMessages">
1934
+ <div t-foreach="configurationErrorMessages" t-as="error" t-key="error">
1935
+ <t t-esc="error"/>
1936
+ </div>
1937
+ </div>
1938
+ </div>
1939
+ </t>
1940
+
1941
+ <t t-name="o-spreadsheet-GaugeChartDesignPanel" owl="1">
1942
+ <div>
1943
+ <div class="o-section o-chart-background-color">
1944
+ <div class="o-section-title">Background color</div>
1945
+ Select a color...
1946
+ <ColorPickerWidget
1947
+ currentColor="props.definition.background"
1948
+ toggleColorPicker="() => this.toggleMenu('backgroundColor', ev)"
1949
+ showColorPicker="state.openedMenu === 'backgroundColor'"
1950
+ onColorPicked="(color) => this.updateBackgroundColor(color)"
1951
+ title="env._t('Background Color')"
1952
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
1953
+ />
1954
+ </div>
1955
+
1956
+ <div class="o-section o-chart-title">
1957
+ <div class="o-section-title">Title</div>
1958
+ <input
1959
+ type="text"
1960
+ t-att-value="env._t(props.definition.title)"
1961
+ t-on-change="updateTitle"
1962
+ class="o-input o-optional"
1963
+ placeholder="New Chart"
1964
+ />
1965
+ </div>
1966
+
1967
+ <div class="o-section">
1968
+ <div class="o-section-title">Range</div>
1969
+ <div class="o-subsection-left">
1970
+ <input
1971
+ type="text"
1972
+ t-att-value="props.definition.sectionRule.rangeMin"
1973
+ t-on-change="updateRangeMin"
1974
+ class="o-input o-data-range-min"
1975
+ t-att-class="{ 'o-invalid': isRangeMinInvalid() }"
1976
+ />
1977
+ </div>
1978
+ <div class="o-subsection-right">
1979
+ <input
1980
+ type="text"
1981
+ t-att-value="props.definition.sectionRule.rangeMax"
1982
+ t-on-change="updateRangeMax"
1983
+ class="o-input o-data-range-max"
1984
+ t-att-class="{ 'o-invalid': isRangeMaxInvalid() }"
1985
+ />
1986
+ </div>
1987
+ </div>
1988
+
1989
+ <div class="o-section">
1990
+ <div class="o-section-title">Thresholds</div>
1991
+ <t t-call="o-spreadsheet-GaugeChartColorSectionTemplate">
1992
+ <t t-set="sectionRule" t-value="props.definition.sectionRule"/>
1993
+ </t>
1994
+ </div>
1995
+
1996
+ <div class="o-section o-sidepanel-error" t-if="designErrorMessages.length">
1997
+ <div t-foreach="designErrorMessages" t-as="error" t-key="error">
1998
+ <t t-esc="error"/>
1999
+ </div>
2000
+ </div>
2001
+ </div>
2002
+ </t>
2003
+
2004
+ <t t-name="o-spreadsheet-GaugeChartColorSectionTemplate" owl="1">
2005
+ <div class="o-gauge-color-set">
2006
+ <table>
2007
+ <tr>
2008
+ <th class="o-gauge-color-set-colorPicker"/>
2009
+ <th class="o-gauge-color-set-text"/>
2010
+ <th class="o-gauge-color-set-value">Value</th>
2011
+ <th class="o-gauge-color-set-type">Type</th>
2012
+ </tr>
2013
+
2014
+ <t t-call="o-spreadsheet-GaugeChartColorSectionTemplateRow">
2015
+ <t t-set="sectionColor" t-value="sectionRule.colors.lowerColor"/>
2016
+ <t t-set="sectionType" t-value="'lowerColor'"/>
2017
+ <t t-set="inflectionPoint" t-value="sectionRule.lowerInflectionPoint"/>
2018
+ <t t-set="isInvalid" t-value="isLowerInflectionPointInvalid"/>
2019
+ <t t-set="inflectionPointName" t-value="'lowerInflectionPoint'"/>
2020
+ </t>
2021
+
2022
+ <t t-call="o-spreadsheet-GaugeChartColorSectionTemplateRow">
2023
+ <t t-set="sectionColor" t-value="sectionRule.colors.middleColor"/>
2024
+ <t t-set="sectionType" t-value="'middleColor'"/>
2025
+ <t t-set="inflectionPoint" t-value="sectionRule.upperInflectionPoint"/>
2026
+ <t t-set="isInvalid" t-value="isUpperInflectionPointInvalid"/>
2027
+ <t t-set="inflectionPointName" t-value="'upperInflectionPoint'"/>
2028
+ </t>
2029
+
2030
+ <tr>
2031
+ <td>
2032
+ <ColorPickerWidget
2033
+ currentColor="sectionRule.colors.upperColor"
2034
+ toggleColorPicker="(ev) => this.toggleMenu('sectionColor-upperColor', ev)"
2035
+ showColorPicker="state.openedMenu === 'sectionColor-upperColor'"
2036
+ onColorPicked="(color) => this.updateSectionColor('upperColor', color)"
2037
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2038
+ />
2039
+ </td>
2040
+ <td>Else</td>
2041
+ <td/>
2042
+ <td/>
2043
+ <td/>
2044
+ </tr>
2045
+ </table>
2046
+ </div>
2047
+ </t>
2048
+
2049
+ <t t-name="o-spreadsheet-GaugeChartColorSectionTemplateRow" owl="1">
2050
+ <tr>
2051
+ <td>
2052
+ <ColorPickerWidget
2053
+ currentColor="sectionColor"
2054
+ toggleColorPicker="(ev) => this.toggleMenu('sectionColor-'+sectionType, ev)"
2055
+ showColorPicker="state.openedMenu === 'sectionColor-'+sectionType"
2056
+ onColorPicked="(color) => this.updateSectionColor(sectionType, color)"
2057
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2058
+ />
2059
+ </td>
2060
+ <td>When value is below</td>
2061
+ <td>
2062
+ <input
2063
+ type="text"
2064
+ class="o-input"
2065
+ t-on-change="(ev) => this.updateInflectionPointValue(inflectionPointName, ev)"
2066
+ t-attf-class="o-input-{{inflectionPointName}}"
2067
+ t-att-class="{ 'o-invalid': isInvalid }"
2068
+ t-model="inflectionPoint.value"
2069
+ />
2070
+ </td>
2071
+ <td>
2072
+ <select
2073
+ class="o-input"
2074
+ name="valueType"
2075
+ t-model="inflectionPoint.type"
2076
+ t-on-change="(ev) => this.updateInflectionPointType(inflectionPointName, ev)">
2077
+ <option value="number">Number</option>
2078
+ <option value="percentage">Percentage</option>
2079
+ </select>
2080
+ </td>
2081
+ </tr>
2082
+ </t>
2083
+
2084
+ <t t-name="o-spreadsheet-LineBarPieConfigPanel" owl="1">
2085
+ <div>
2086
+ <div class="o-section o-data-series">
2087
+ <div class="o-section-title">Data Series</div>
2088
+ <SelectionInput
2089
+ ranges="dataSeriesRanges"
2090
+ isInvalid="isDatasetInvalid"
2091
+ required="true"
2092
+ onSelectionChanged="(ranges) => this.onDataSeriesRangesChanged(ranges)"
2093
+ onSelectionConfirmed="() => this.onDataSeriesConfirmed()"
2094
+ />
2095
+ <label>
2096
+ <input
2097
+ type="checkbox"
2098
+ t-att-checked="props.definition.dataSetsHaveTitle"
2099
+ t-on-change="onUpdateDataSetsHaveTitle"
2100
+ class="align-middle"
2101
+ />
2102
+ Data series include title
2103
+ </label>
2104
+ </div>
2105
+ <div class="o-section o-data-labels">
2106
+ <div class="o-section-title">Categories / Labels</div>
2107
+ <SelectionInput
2108
+ ranges="[props.definition.labelRange || '']"
2109
+ isInvalid="isLabelInvalid"
2110
+ hasSingleRange="true"
2111
+ onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
2112
+ onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
2113
+ />
2114
+ <label>
2115
+ <input
2116
+ type="checkbox"
2117
+ name="aggregated"
2118
+ t-att-checked="props.definition.aggregated"
2119
+ t-on-change="onUpdateAggregated"
2120
+ class="align-middle"
2121
+ />
2122
+ Aggregate
2123
+ </label>
2124
+ </div>
2125
+ <div class="o-section o-sidepanel-error" t-if="errorMessages">
2126
+ <div t-foreach="errorMessages" t-as="error" t-key="error">
2127
+ <t t-esc="error"/>
2128
+ </div>
2129
+ </div>
2130
+ </div>
2131
+ </t>
2132
+
2133
+ <t t-name="o-spreadsheet-LineBarPieDesignPanel" owl="1">
2134
+ <div>
2135
+ <div class="o-section o-chart-background-color">
2136
+ <div class="o-section-title">Background color</div>
2137
+ Select a color...
2138
+ <ColorPickerWidget
2139
+ currentColor="props.definition.background"
2140
+ toggleColorPicker="() => this.toggleColorPicker()"
2141
+ showColorPicker="state.fillColorTool"
2142
+ onColorPicked="(color) => this.updateBackgroundColor(color)"
2143
+ title="env._t('Background Color')"
2144
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2145
+ />
2146
+ </div>
2147
+ <div class="o-section o-chart-title">
2148
+ <div class="o-section-title">Title</div>
2149
+ <input
2150
+ type="text"
2151
+ t-att-value="env._t(props.definition.title)"
2152
+ t-on-change="updateTitle"
2153
+ class="o-input o-optional"
2154
+ placeholder="New Chart"
2155
+ />
2156
+ </div>
2157
+ <div class="o-section">
2158
+ <div class="o-section-title">Legend position</div>
2159
+ <select
2160
+ t-att-value="props.definition.legendPosition"
2161
+ class="o-input o-type-selector"
2162
+ t-on-change="(ev) => this.updateSelect('legendPosition', ev)">
2163
+ <option value="none">None</option>
2164
+ <option value="top">Top</option>
2165
+ <option value="bottom">Bottom</option>
2166
+ <option value="left">Left</option>
2167
+ <option value="right">Right</option>
2168
+ </select>
2169
+ </div>
2170
+ </div>
2171
+ </t>
2172
+
2173
+ <t t-name="o-spreadsheet-LineConfigPanel" owl="1">
2174
+ <div>
2175
+ <div class="o-section pt-0">
2176
+ <div class="o-checkbox">
2177
+ <label>
2178
+ <input
2179
+ type="checkbox"
2180
+ name="stacked"
2181
+ t-att-checked="props.definition.stacked"
2182
+ t-on-change="onUpdateStacked"
2183
+ class="align-middle"
2184
+ />
2185
+ Stacked linechart
2186
+ </label>
2187
+ </div>
2188
+ <div class="o-checkbox">
2189
+ <label>
2190
+ <input
2191
+ type="checkbox"
2192
+ name="cumulative"
2193
+ t-att-checked="props.definition.cumulative"
2194
+ t-on-change="onUpdateCumulative"
2195
+ class="align-middle"
2196
+ />
2197
+ Cumulative data
2198
+ </label>
2199
+ </div>
2200
+ </div>
2201
+ <div class="o-section o-data-series">
2202
+ <div class="o-section-title">Data Series</div>
2203
+ <SelectionInput
2204
+ ranges="dataSeriesRanges"
2205
+ isInvalid="isDatasetInvalid"
2206
+ required="true"
2207
+ onSelectionChanged="(ranges) => this.onDataSeriesRangesChanged(ranges)"
2208
+ onSelectionConfirmed="() => this.onDataSeriesConfirmed()"
2209
+ />
2210
+ <label>
2211
+ <input
2212
+ type="checkbox"
2213
+ t-att-checked="props.definition.dataSetsHaveTitle"
2214
+ t-on-change="onUpdateDataSetsHaveTitle"
2215
+ class="align-middle"
2216
+ />
2217
+ Data series include title
2218
+ </label>
2219
+ </div>
2220
+ <div class="o-section o-data-labels">
2221
+ <div class="o-section-title">Categories / Labels</div>
2222
+ <SelectionInput
2223
+ ranges="[props.definition.labelRange || '']"
2224
+ isInvalid="isLabelInvalid"
2225
+ hasSingleRange="true"
2226
+ onSelectionChanged="(ranges) => this.onLabelRangeChanged(ranges)"
2227
+ onSelectionConfirmed="() => this.onLabelRangeConfirmed()"
2228
+ />
2229
+ <label>
2230
+ <input
2231
+ type="checkbox"
2232
+ name="aggregated"
2233
+ t-att-checked="props.definition.aggregated"
2234
+ t-on-change="onUpdateAggregated"
2235
+ class="align-middle"
2236
+ />
2237
+ Aggregate
2238
+ </label>
2239
+ <div t-if="canTreatLabelsAsText">
2240
+ <label>
2241
+ <input
2242
+ type="checkbox"
2243
+ name="labelsAsText"
2244
+ t-att-checked="props.definition.labelsAsText"
2245
+ t-on-change="onUpdateLabelsAsText"
2246
+ />
2247
+ Treat labels as text
2248
+ </label>
2249
+ </div>
2250
+ </div>
2251
+ <div class="o-section o-sidepanel-error" t-if="errorMessages">
2252
+ <div t-foreach="errorMessages" t-as="error" t-key="error">
2253
+ <t t-esc="error"/>
2254
+ </div>
2255
+ </div>
2256
+ </div>
2257
+ </t>
2258
+
2259
+ <t t-name="o-spreadsheet-LineChartDesignPanel" owl="1">
2260
+ <div>
2261
+ <div class="o-section o-chart-background-color">
2262
+ <div class="o-section-title">Background color</div>
2263
+ Select a color...
2264
+ <ColorPickerWidget
2265
+ currentColor="props.definition.background"
2266
+ toggleColorPicker="() => this.toggleColorPicker()"
2267
+ showColorPicker="state.fillColorTool"
2268
+ onColorPicked="(color) => this.updateBackgroundColor(color)"
2269
+ title="env._t('Background Color')"
2270
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2271
+ />
2272
+ </div>
2273
+ <div class="o-section o-chart-title">
2274
+ <div class="o-section-title">Title</div>
2275
+ <input
2276
+ type="text"
2277
+ t-att-value="props.definition.title"
2278
+ t-on-change="updateTitle"
2279
+ class="o-input o-optional"
2280
+ placeholder="New Chart"
2281
+ />
2282
+ </div>
2283
+ <div class="o-section">
2284
+ <div class="o-section-title">Vertical axis position</div>
2285
+ <select
2286
+ t-att-value="props.definition.verticalAxisPosition"
2287
+ class="o-input o-type-selector"
2288
+ t-on-change="(ev) => this.updateSelect('verticalAxisPosition', ev)">
2289
+ <option value="left">Left</option>
2290
+ <option value="right">Right</option>
2291
+ </select>
2292
+ </div>
2293
+ <div class="o-section">
2294
+ <div class="o-section-title">Legend position</div>
2295
+ <select
2296
+ t-att-value="props.definition.legendPosition"
2297
+ class="o-input o-type-selector"
2298
+ t-on-change="(ev) => this.updateSelect('legendPosition', ev)">
2299
+ <option value="none">None</option>
2300
+ <option value="top">Top</option>
2301
+ <option value="bottom">Bottom</option>
2302
+ <option value="left">Left</option>
2303
+ <option value="right">Right</option>
2304
+ </select>
2305
+ </div>
2306
+ </div>
2307
+ </t>
2308
+
2309
+ <t t-name="o-spreadsheet-ChartPanel" owl="1">
2310
+ <div class="o-chart">
2311
+ <div class="o-panel">
2312
+ <div
2313
+ class="o-panel-element o-panel-configuration"
2314
+ t-att-class="state.panel !== 'configuration' ? 'inactive' : ''"
2315
+ t-on-click="() => this.activatePanel('configuration')">
2316
+ <i class="fa fa-sliders"/>
2317
+ Configuration
2318
+ </div>
2319
+ <div
2320
+ class="o-panel-element o-panel-design"
2321
+ t-att-class="state.panel !== 'design' ? 'inactive' : ''"
2322
+ t-on-click="() => this.activatePanel('design')">
2323
+ <i class="fa fa-paint-brush"/>
2324
+ Design
2325
+ </div>
2326
+ </div>
2327
+
2328
+ <t t-set="definition" t-value="getChartDefinition()"/>
2329
+ <t t-if="state.panel === 'configuration'">
2330
+ <div class="o-section">
2331
+ <div class="o-section-title">Chart type</div>
2332
+ <t t-set="types" t-value="chartTypes"/>
2333
+ <select
2334
+ class="o-input o-type-selector"
2335
+ t-on-change="(ev) => this.onTypeChange(ev.target.value)">
2336
+ <option
2337
+ t-foreach="chartTypes"
2338
+ t-as="type"
2339
+ t-key="type"
2340
+ t-att-value="type"
2341
+ t-esc="types[type]"
2342
+ t-att-selected="definition.type === type"
2343
+ />
2344
+ </select>
2345
+ </div>
2346
+ <t
2347
+ t-component="chartPanel.configuration"
2348
+ definition="definition"
2349
+ figureId="figureId"
2350
+ updateChart.bind="updateChart"
2351
+ t-key="figureId + definition.type"
2352
+ />
2353
+ </t>
2354
+ <t t-else="">
2355
+ <t
2356
+ t-component="chartPanel.design"
2357
+ definition="definition"
2358
+ figureId="figureId"
2359
+ updateChart.bind="updateChart"
2360
+ t-key="figureId + definition.type"
2361
+ />
2362
+ </t>
2363
+ </div>
2364
+ </t>
2365
+
2366
+ <t t-name="o-spreadsheet-ScorecardChartConfigPanel" owl="1">
2367
+ <div>
2368
+ <div class="o-section o-data-series">
2369
+ <div class="o-section-title">Key value</div>
2370
+ <SelectionInput
2371
+ ranges="[props.definition.keyValue || '']"
2372
+ isInvalid="isKeyValueInvalid"
2373
+ hasSingleRange="true"
2374
+ required="true"
2375
+ onSelectionChanged="(ranges) => this.onKeyValueRangeChanged(ranges)"
2376
+ onSelectionConfirmed="() => this.updateKeyValueRange()"
2377
+ />
2378
+ </div>
2379
+ <div class="o-section o-data-labels">
2380
+ <div class="o-section-title">Baseline configuration</div>
2381
+ <div class="o-section-subtitle">Baseline value</div>
2382
+ <SelectionInput
2383
+ ranges="[props.definition.baseline || '']"
2384
+ isInvalid="isBaselineInvalid"
2385
+ hasSingleRange="true"
2386
+ onSelectionChanged="(ranges) => this.onBaselineRangeChanged(ranges)"
2387
+ onSelectionConfirmed="() => this.updateBaselineRange()"
2388
+ />
2389
+ <div class="o-section-subtitle">Baseline format</div>
2390
+ <select
2391
+ t-att-value="props.definition.baselineMode"
2392
+ class="o-input o-type-selector o-optional"
2393
+ t-on-change="(ev) => this.updateBaselineMode(ev)">
2394
+ <option value="text">Absolute value</option>
2395
+ <option value="difference">Value change from key value</option>
2396
+ <option value="percentage">Percentage change from key value</option>
2397
+ </select>
2398
+ </div>
2399
+ <div class="o-section o-sidepanel-error" t-if="errorMessages">
2400
+ <div t-foreach="errorMessages" t-as="error" t-key="error">
2401
+ <t t-esc="error"/>
2402
+ </div>
2403
+ </div>
2404
+ </div>
2405
+ </t>
2406
+
2407
+ <t t-name="o-spreadsheet-ScorecardChartDesignPanel" owl="1">
2408
+ <div>
2409
+ <div class="o-section o-chart-background-color">
2410
+ <div class="o-section-title">Background color</div>
2411
+ Select a color...
2412
+ <ColorPickerWidget
2413
+ currentColor="props.definition.background"
2414
+ toggleColorPicker="() => this.toggleColorPicker('backgroundColor')"
2415
+ showColorPicker="state.openedColorPicker === 'backgroundColor'"
2416
+ onColorPicked="(color) => this.setColor(color, 'backgroundColor')"
2417
+ title="env._t('Background Color')"
2418
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2419
+ />
2420
+ </div>
2421
+
2422
+ <div class="o-section o-chart-title">
2423
+ <div class="o-section-title">Title</div>
2424
+ <input
2425
+ type="text"
2426
+ t-att-value="env._t(props.definition.title)"
2427
+ t-on-change="updateTitle"
2428
+ class="o-input o-optional"
2429
+ placeholder="New Chart"
2430
+ />
2431
+ </div>
2432
+ <div class="o-section">
2433
+ <div class="o-section-title">Baseline description</div>
2434
+ <input
2435
+ type="text"
2436
+ t-att-value="env._t(props.definition.baselineDescr)"
2437
+ t-on-change="updateBaselineDescr"
2438
+ class="o-input o-optional"
2439
+ />
2440
+ </div>
2441
+ </div>
2442
+ <div class="o-section o-chart-baseline-color">
2443
+ <div class="o-section-title">Baseline color</div>
2444
+ Color on value increase
2445
+ <ColorPickerWidget
2446
+ currentColor="props.definition.baselineColorUp"
2447
+ toggleColorPicker="() => this.toggleColorPicker('baselineColorUp')"
2448
+ showColorPicker="state.openedColorPicker === 'baselineColorUp'"
2449
+ onColorPicked="(color) => this.setColor(color, 'baselineColorUp')"
2450
+ title="env._t('Color Up')"
2451
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2452
+ />
2453
+ <br/>
2454
+ Color on value decrease
2455
+ <ColorPickerWidget
2456
+ currentColor="props.definition.baselineColorDown"
2457
+ toggleColorPicker="() => this.toggleColorPicker('baselineColorDown')"
2458
+ showColorPicker="state.openedColorPicker === 'baselineColorDown'"
2459
+ onColorPicked="(color) => this.setColor(color, 'baselineColorDown')"
2460
+ title="env._t('Color Down')"
2461
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2462
+ />
2463
+ </div>
2464
+ </t>
2465
+
2466
+ <t t-name="o-spreadsheet-CellIsRuleEditorPreview" owl="1">
2467
+ <div
2468
+ class="o-cf-preview-line"
2469
+ t-attf-style="font-weight:{{currentStyle.bold ?'bold':'normal'}};
2470
+ text-decoration:{{getTextDecoration(currentStyle)}};
2471
+ font-style:{{currentStyle.italic?'italic':'normal'}};
2472
+ color:{{currentStyle.textColor || '#000'}};
2473
+ border-radius: 4px;
2474
+ background-color:{{currentStyle.fillColor}};">
2475
+ <t t-if="previewText" t-esc="previewText"/>
2476
+ <t t-else="">Preview text</t>
2477
+ </div>
2478
+ </t>
2479
+
2480
+ <t t-name="o-spreadsheet-CellIsRuleEditor" owl="1">
2481
+ <div class="o-cf-cell-is-rule">
2482
+ <div class="o-section-subtitle">Format cells if...</div>
2483
+ <select t-model="rule.operator" class="o-input o-cell-is-operator">
2484
+ <t t-foreach="Object.keys(cellIsOperators)" t-as="op" t-key="op_index">
2485
+ <option t-att-value="op" t-esc="cellIsOperators[op]"/>
2486
+ </t>
2487
+ </select>
2488
+ <t t-if="rule.operator !== 'IsEmpty' and rule.operator !== 'IsNotEmpty'">
2489
+ <input
2490
+ type="text"
2491
+ placeholder="Value"
2492
+ t-model="rule.values[0]"
2493
+ t-att-class="{ 'o-invalid': isValue1Invalid }"
2494
+ class="o-input o-cell-is-value o-required"
2495
+ />
2496
+ <t t-if="rule.operator === 'Between' || rule.operator === 'NotBetween'">
2497
+ <input
2498
+ type="text"
2499
+ placeholder="and value"
2500
+ t-model="rule.values[1]"
2501
+ t-att-class="{ 'o-invalid': isValue2Invalid }"
2502
+ class="o-input o-cell-is-value o-required"
2503
+ />
2504
+ </t>
2505
+ </t>
2506
+ <div class="o-section-subtitle">Formatting style</div>
2507
+
2508
+ <t t-call="o-spreadsheet-CellIsRuleEditorPreview">
2509
+ <t t-set="currentStyle" t-value="rule.style"/>
2510
+ </t>
2511
+ <div class="o-sidePanel-tools">
2512
+ <div
2513
+ class="o-tool"
2514
+ title="Bold"
2515
+ t-att-class="{active:rule.style.bold}"
2516
+ t-on-click="() => this.toggleStyle('bold')">
2517
+ <t t-call="o-spreadsheet-Icon.BOLD"/>
2518
+ </div>
2519
+ <div
2520
+ class="o-tool"
2521
+ title="Italic"
2522
+ t-att-class="{active:rule.style.italic}"
2523
+ t-on-click="() => this.toggleStyle('italic')">
2524
+ <t t-call="o-spreadsheet-Icon.ITALIC"/>
2525
+ </div>
2526
+ <div
2527
+ class="o-tool"
2528
+ title="Underline"
2529
+ t-att-class="{active:rule.style.underline}"
2530
+ t-on-click="(ev) => this.toggleStyle('underline', ev)">
2531
+ <t t-call="o-spreadsheet-Icon.UNDERLINE"/>
2532
+ </div>
2533
+ <div
2534
+ class="o-tool"
2535
+ title="Strikethrough"
2536
+ t-att-class="{active:rule.style.strikethrough}"
2537
+ t-on-click="(ev) => this.toggleStyle('strikethrough', ev)">
2538
+ <t t-call="o-spreadsheet-Icon.STRIKE"/>
2539
+ </div>
2540
+ <ColorPickerWidget
2541
+ currentColor="rule.style.textColor || '#000000'"
2542
+ toggleColorPicker="(ev) => this.toggleMenu('cellIsRule-textColor', ev)"
2543
+ showColorPicker="state.openedMenu === 'cellIsRule-textColor'"
2544
+ onColorPicked="(color) => this.setColor('textColor', color)"
2545
+ title="env._t('Text Color')"
2546
+ icon="'o-spreadsheet-Icon.TEXT_COLOR'"
2547
+ class="'o-tool'"
2548
+ />
2549
+ <div class="o-divider"/>
2550
+ <ColorPickerWidget
2551
+ currentColor="rule.style.fillColor"
2552
+ toggleColorPicker="(ev) => this.toggleMenu('cellIsRule-fillColor', ev)"
2553
+ showColorPicker="state.openedMenu === 'cellIsRule-fillColor'"
2554
+ onColorPicked="(color) => this.setColor('fillColor', color)"
2555
+ title="env._t('Fill Color')"
2556
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2557
+ class="'o-tool'"
2558
+ />
2559
+ </div>
2560
+ </div>
2561
+ </t>
2562
+
2563
+ <t t-name="o-spreadsheet-ColorScaleRuleEditorPreview" owl="1">
2564
+ <div class="o-cf-preview-gradient" t-attf-style="{{getPreviewGradient()}}">Preview text</div>
2565
+ </t>
2566
+
2567
+ <t t-name="o-spreadsheet-ColorScaleRuleEditorThreshold" owl="1">
2568
+ <div t-attf-class="o-threshold o-threshold-{{thresholdType}}">
2569
+ <t t-if="thresholdType === 'midpoint'">
2570
+ <t t-set="type" t-value="threshold and threshold.type"/>
2571
+ <select
2572
+ class="o-input"
2573
+ name="valueType"
2574
+ t-on-change="onMidpointChange"
2575
+ t-on-click="closeMenus">
2576
+ <option value="none" t-att-selected="threshold === undefined">None</option>
2577
+ <option value="number" t-att-selected="type === 'number'">FixedNumber</option>
2578
+ <option value="percentage" t-att-selected="type === 'percentage'">Percentage</option>
2579
+ <option value="percentile" t-att-selected="type === 'percentile'">Percentile</option>
2580
+ <option value="formula" t-att-selected="type === 'formula'">Formula</option>
2581
+ </select>
2582
+ </t>
2583
+ <t t-else="">
2584
+ <select class="o-input" name="valueType" t-model="threshold.type" t-on-click="closeMenus">
2585
+ <option value="value">Cell values</option>
2586
+ <option value="number">Number</option>
2587
+ <option value="percentage">Percentage</option>
2588
+ <option value="percentile">Percentile</option>
2589
+ <option value="formula">Formula</option>
2590
+ </select>
2591
+ </t>
2592
+ <input
2593
+ type="text"
2594
+ class="o-input o-threshold-value o-required"
2595
+ t-model="rule[thresholdType].value"
2596
+ t-att-class="{ 'o-invalid': isValueInvalid(thresholdType) }"
2597
+ t-if="threshold !== undefined and threshold.type !== 'value'"
2598
+ />
2599
+ <input type="text" class="o-input o-threshold-value" t-else="" disabled="1"/>
2600
+ <ColorPickerWidget
2601
+ currentColor="getThresholdColor(threshold)"
2602
+ toggleColorPicker="(ev) => this.toggleMenu('colorScale-'+thresholdType+'Color', ev)"
2603
+ showColorPicker="state.openedMenu === 'colorScale-'+thresholdType+'Color'"
2604
+ onColorPicked="(color) => this.setColorScaleColor(thresholdType, color)"
2605
+ title="env._t('Fill Color')"
2606
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
2607
+ disabled="threshold === undefined"
2608
+ />
2609
+ </div>
2610
+ </t>
2611
+
2612
+ <t t-name="o-spreadsheet-ColorScaleRuleEditor" owl="1">
2613
+ <div class="o-cf-color-scale-editor">
2614
+ <div class="o-section-subtitle">Preview</div>
2615
+ <t t-call="o-spreadsheet-ColorScaleRuleEditorPreview"/>
2616
+ <div class="o-section-subtitle">Minpoint</div>
2617
+ <t t-call="o-spreadsheet-ColorScaleRuleEditorThreshold">
2618
+ <t t-set="threshold" t-value="rule.minimum"/>
2619
+ <t t-set="thresholdType" t-value="'minimum'"/>
2620
+ </t>
2621
+ <div class="o-section-subtitle">MidPoint</div>
2622
+ <t t-call="o-spreadsheet-ColorScaleRuleEditorThreshold">
2623
+ <t t-set="threshold" t-value="rule.midpoint"/>
2624
+ <t t-set="thresholdType" t-value="'midpoint'"/>
2625
+ </t>
2626
+ <div class="o-section-subtitle">MaxPoint</div>
2627
+ <t t-call="o-spreadsheet-ColorScaleRuleEditorThreshold">
2628
+ <t t-set="threshold" t-value="rule.maximum"/>
2629
+ <t t-set="thresholdType" t-value="'maximum'"/>
2630
+ </t>
2631
+ </div>
2632
+ </t>
2633
+
2634
+ <t t-name="o-spreadsheet-ConditionalFormattingPanel" owl="1">
2635
+ <div class="o-cf">
2636
+ <t t-if="state.mode === 'list' || state.mode === 'reorder'">
2637
+ <div class="o-cf-preview-list">
2638
+ <div
2639
+ t-on-click="(ev) => this.editConditionalFormat(cf, ev)"
2640
+ t-foreach="conditionalFormats"
2641
+ t-as="cf"
2642
+ t-key="cf.id">
2643
+ <t t-call="o-spreadsheet-ConditionalFormattingPanelPreview"/>
2644
+ </div>
2645
+ </div>
2646
+ <t t-if="state.mode === 'list'">
2647
+ <div
2648
+ class="btn btn-link o-cf-btn-link o-cf-add"
2649
+ t-on-click.prevent.stop="addConditionalFormat">
2650
+ + Add another rule
2651
+ </div>
2652
+ <div
2653
+ class="btn btn-link o-cf-btn-link o-cf-reorder"
2654
+ t-on-click="reorderConditionalFormats">
2655
+ Reorder rules
2656
+ </div>
2657
+ </t>
2658
+ <t t-if="state.mode === 'reorder'">
2659
+ <div class="btn btn-link o-cf-btn-link o-cf-exit-reorder" t-on-click="switchToList">
2660
+ Stop reordering rules
2661
+ </div>
2662
+ </t>
2663
+ </t>
2664
+ <t t-if="state.mode === 'edit' || state.mode === 'add'" t-key="state.currentCF.id">
2665
+ <div class="o-cf-ruleEditor">
2666
+ <div class="o-section o-cf-range">
2667
+ <div class="o-section-title">Apply to range</div>
2668
+ <div class="o-selection-cf">
2669
+ <SelectionInput
2670
+ ranges="state.currentCF.ranges"
2671
+ class="'o-range'"
2672
+ isInvalid="isRangeValid"
2673
+ onSelectionChanged="(ranges) => this.onRangesChanged(ranges)"
2674
+ required="true"
2675
+ />
2676
+ </div>
2677
+ <div class="o-section-title">Format rules</div>
2678
+ <div class="o_field_radio o_horizontal o_field_widget o-cf-type-selector">
2679
+ <div
2680
+ class="custom-control form-check o_cf_radio_item"
2681
+ t-on-click="() => this.changeRuleType('CellIsRule')">
2682
+ <input
2683
+ class="form-check-input o_radio_input"
2684
+ t-att-checked="state.currentCFType === 'CellIsRule'"
2685
+ type="radio"
2686
+ id="cellIsRule"
2687
+ name="ruleType"
2688
+ value="CellIsRule"
2689
+ />
2690
+ <label for="cellIsRule" class="form-check-label o_form_label">Single color</label>
2691
+ </div>
2692
+ <div
2693
+ class="custom-control form-check o_cf_radio_item"
2694
+ t-on-click="() => this.changeRuleType('ColorScaleRule')">
2695
+ <input
2696
+ class="form-check-input o_radio_input"
2697
+ t-att-checked="state.currentCFType === 'ColorScaleRule'"
2698
+ type="radio"
2699
+ id="colorScaleRule"
2700
+ name="ruleType"
2701
+ value="ColorScaleRule"
2702
+ />
2703
+ <label for="colorScaleRule" class="form-check-label o_form_label">
2704
+ Color scale
2705
+ </label>
2706
+ </div>
2707
+
2708
+ <div
2709
+ class="custom-control form-check o_cf_radio_item"
2710
+ t-on-click="() => this.changeRuleType('IconSetRule')">
2711
+ <input
2712
+ class="form-check-input o_radio_input"
2713
+ t-att-checked="state.currentCFType === 'IconSetRule'"
2714
+ type="radio"
2715
+ id="iconSetRule"
2716
+ name="ruleType"
2717
+ value="IconSetRule"
2718
+ />
2719
+ <label for="iconSetRule" class="form-check-label o_form_label">Icon set</label>
2720
+ </div>
2721
+ </div>
2722
+ </div>
2723
+ <div class="o-section o-cf-editor">
2724
+ <t t-if="state.currentCFType === 'CellIsRule'" t-call="o-spreadsheet-CellIsRuleEditor">
2725
+ <t t-set="rule" t-value="state.rules.cellIs"/>
2726
+ </t>
2727
+ <t
2728
+ t-if="state.currentCFType === 'ColorScaleRule'"
2729
+ t-call="o-spreadsheet-ColorScaleRuleEditor">
2730
+ <t t-set="rule" t-value="state.rules.colorScale"/>
2731
+ </t>
2732
+ <t t-if="state.currentCFType === 'IconSetRule'" t-call="o-spreadsheet-IconSetEditor">
2733
+ <t t-set="rule" t-value="state.rules.iconSet"/>
2734
+ </t>
2735
+ <div class="o-sidePanelButtons">
2736
+ <button t-on-click="switchToList" class="o-sidePanelButton o-cf-cancel">
2737
+ Cancel
2738
+ </button>
2739
+ <button t-on-click="saveConditionalFormat" class="o-sidePanelButton o-cf-save">
2740
+ Save
2741
+ </button>
2742
+ </div>
2743
+ </div>
2744
+ <div class="o-section">
2745
+ <div class="o-cf-error" t-foreach="state.errors || []" t-as="error" t-key="error_index">
2746
+ <t t-esc="errorMessage(error)"/>
2747
+ </div>
2748
+ </div>
2749
+ </div>
2750
+ </t>
2751
+ </div>
2752
+ </t>
2753
+
2754
+ <t t-name="o-spreadsheet-ConditionalFormattingPanelPreview" owl="1">
2755
+ <div class="o-cf-preview" t-att-class="{ 'o-cf-cursor-ptr': state.mode !== 'reorder' }">
2756
+ <t t-if="cf.rule.type==='IconSetRule'">
2757
+ <div class="o-cf-preview-icon">
2758
+ <t t-call="o-spreadsheet-Icon.{{icons[cf.rule.icons.upper].template}}"/>
2759
+ <t t-call="o-spreadsheet-Icon.{{icons[cf.rule.icons.middle].template}}"/>
2760
+ <t t-call="o-spreadsheet-Icon.{{icons[cf.rule.icons.lower].template}}"/>
2761
+ </div>
2762
+ </t>
2763
+ <t t-else="">
2764
+ <div t-att-style="getStyle(cf.rule)" class="o-cf-preview-image">123</div>
2765
+ </t>
2766
+ <div class="o-cf-preview-description">
2767
+ <div class="o-cf-preview-ruletype">
2768
+ <div class="o-cf-preview-description-rule">
2769
+ <t t-esc="getDescription(cf)"/>
2770
+ </div>
2771
+ </div>
2772
+ <div class="o-cf-preview-range" t-esc="cf.ranges"/>
2773
+ </div>
2774
+ <t t-if="state.mode === 'reorder'">
2775
+ <div class="o-cf-reorder">
2776
+ <t t-if="!cf_first">
2777
+ <div
2778
+ class="o-cf-reorder-button-up o-cf-reorder-button"
2779
+ t-on-click="(ev) => this.reorderRule(cf, 'up', ev)">
2780
+ <t t-call="o-spreadsheet-Icon.CARET_UP"/>
2781
+ </div>
2782
+ </t>
2783
+ <t t-if="!cf_last">
2784
+ <div
2785
+ class="o-cf-reorder-button-down o-cf-reorder-button"
2786
+ t-on-click="(ev) => this.reorderRule(cf, 'down', ev)">
2787
+ <t t-call="o-spreadsheet-Icon.CARET_DOWN"/>
2788
+ </div>
2789
+ </t>
2790
+ </div>
2791
+ </t>
2792
+ <t t-else="">
2793
+ <div class="o-cf-delete">
2794
+ <div
2795
+ class="o-cf-delete-button"
2796
+ t-on-click.stop="(ev) => this.deleteConditionalFormat(cf, ev)"
2797
+ aria-label="Remove rule">
2798
+ <t t-call="o-spreadsheet-Icon.TRASH"/>
2799
+ </div>
2800
+ </div>
2801
+ </t>
2802
+ </div>
2803
+ </t>
2804
+
2805
+ <t t-name="o-spreadsheet-IconSets" owl="1">
2806
+ <div>
2807
+ <div class="o-section-subtitle">Icons</div>
2808
+ <div class="o-cf-iconsets">
2809
+ <div
2810
+ class="o-cf-iconset"
2811
+ t-foreach="['arrows', 'smiley', 'dots']"
2812
+ t-as="iconSet"
2813
+ t-key="iconSet"
2814
+ t-on-click="(ev) => this.setIconSet(iconSet, ev)">
2815
+ <div class="o-cf-icon">
2816
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].good].template}}"/>
2817
+ </div>
2818
+ <div class="o-cf-icon">
2819
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].neutral].template}}"/>
2820
+ </div>
2821
+ <div class="o-cf-icon">
2822
+ <t t-call="o-spreadsheet-Icon.{{icons[iconSets[iconSet].bad].template}}"/>
2823
+ </div>
2824
+ </div>
2825
+ </div>
2826
+ </div>
2827
+ </t>
2828
+
2829
+ <t t-name="o-spreadsheet-IconSetInflexionPointRow" owl="1">
2830
+ <tr>
2831
+ <td>
2832
+ <div t-on-click.stop="(ev) => this.toggleMenu('iconSet-'+icon+'Icon', ev)">
2833
+ <div class="o-cf-icon-button">
2834
+ <t t-call="o-spreadsheet-Icon.{{icons[iconValue].template}}"/>
2835
+ </div>
2836
+ </div>
2837
+ <IconPicker
2838
+ t-if="state.openedMenu === 'iconSet-'+icon+'Icon'"
2839
+ onIconPicked="(i) => this.setIcon(icon, i)"
2840
+ />
2841
+ </td>
2842
+ <td>When value is</td>
2843
+ <td>
2844
+ <select class="o-input" name="valueType" t-model="inflectionPointValue.operator">
2845
+ <option value="gt">
2846
+ <span>&#62;</span>
2847
+ </option>
2848
+ <option value="ge">
2849
+ <span>&#8805;</span>
2850
+ </option>
2851
+ </select>
2852
+ </td>
2853
+ <td>
2854
+ <input
2855
+ type="text"
2856
+ class="o-input"
2857
+ t-att-class="{ 'o-invalid': isInflectionPointInvalid(inflectionPoint) }"
2858
+ t-model="rule[inflectionPoint].value"
2859
+ />
2860
+ </td>
2861
+ <td>
2862
+ <select class="o-input" name="valueType" t-model="inflectionPointValue.type">
2863
+ <option value="number">Number</option>
2864
+ <option value="percentage">Percentage</option>
2865
+ <option value="percentile">Percentile</option>
2866
+ <option value="formula">Formula</option>
2867
+ </select>
2868
+ </td>
2869
+ </tr>
2870
+ </t>
2871
+
2872
+ <t t-name="o-spreadsheet-IconSetInflexionPoints" owl="1">
2873
+ <div class="o-inflection">
2874
+ <table>
2875
+ <tr>
2876
+ <th class="o-cf-iconset-icons"/>
2877
+ <th class="o-cf-iconset-text"/>
2878
+ <th class="o-cf-iconset-operator"/>
2879
+ <th class="o-cf-iconset-value">Value</th>
2880
+ <th class="o-cf-iconset-type">Type</th>
2881
+ </tr>
2882
+ <t t-call="o-spreadsheet-IconSetInflexionPointRow">
2883
+ <t t-set="iconValue" t-value="rule.icons.upper"/>
2884
+ <t t-set="icon" t-value="'upper'"/>
2885
+ <t t-set="inflectionPointValue" t-value="rule.upperInflectionPoint"/>
2886
+ <t t-set="inflectionPoint" t-value="'upperInflectionPoint'"/>
2887
+ </t>
2888
+ <t t-call="o-spreadsheet-IconSetInflexionPointRow">
2889
+ <t t-set="iconValue" t-value="rule.icons.middle"/>
2890
+ <t t-set="icon" t-value="'middle'"/>
2891
+ <t t-set="inflectionPointValue" t-value="rule.lowerInflectionPoint"/>
2892
+ <t t-set="inflectionPoint" t-value="'lowerInflectionPoint'"/>
2893
+ </t>
2894
+ <tr>
2895
+ <td>
2896
+ <div t-on-click.stop="(ev) => this.toggleMenu('iconSet-lowerIcon', ev)">
2897
+ <div class="o-cf-icon-button">
2898
+ <t t-call="o-spreadsheet-Icon.{{icons[rule.icons.lower].template}}"/>
2899
+ </div>
2900
+ </div>
2901
+ <IconPicker
2902
+ t-if="state.openedMenu === 'iconSet-lowerIcon'"
2903
+ onIconPicked="(icon) => this.setIcon('lower', icon)"
2904
+ />
2905
+ </td>
2906
+ <td>Else</td>
2907
+ <td/>
2908
+ <td/>
2909
+ <td/>
2910
+ </tr>
2911
+ </table>
2912
+ </div>
2913
+ </t>
2914
+ <t t-name="o-spreadsheet-IconSetEditor" owl="1">
2915
+ <div class="o-cf-iconset-rule">
2916
+ <t t-call="o-spreadsheet-IconSets"/>
2917
+ <t t-call="o-spreadsheet-IconSetInflexionPoints"/>
2918
+ <div class="btn btn-link o_refresh_measures o-cf-iconset-reverse" t-on-click="reverseIcons">
2919
+ <div class="me-1 d-inline-block">
2920
+ <t t-call="o-spreadsheet-Icon.REFRESH"/>
2921
+ </div>
2922
+ Reverse icons
2923
+ </div>
2924
+ </div>
2925
+ </t>
2926
+
2927
+ <t t-name="o-spreadsheet-CustomCurrencyPanel" owl="1">
2928
+ <div class="o-custom-currency">
2929
+ <div class="o-section" t-if="availableCurrencies.length > 1">
2930
+ <div class="o-section-title">Currency</div>
2931
+ <select
2932
+ class="o-input o-available-currencies"
2933
+ t-on-change="(ev) => this.updateSelectCurrency(ev)">
2934
+ <t t-foreach="availableCurrencies" t-as="currency" t-key="currency_index">
2935
+ <option
2936
+ t-att-value="currency_index"
2937
+ t-esc="currencyDisplayName(currency)"
2938
+ t-att-selected="currency_index === state.selectedCurrencyIndex"
2939
+ />
2940
+ </t>
2941
+ </select>
2942
+ </div>
2943
+ <div class="o-section">
2944
+ <div class="o-subsection-left">
2945
+ <div class="o-section-title">Code</div>
2946
+ <input
2947
+ type="text"
2948
+ class="o-input"
2949
+ t-model="state.currencyCode"
2950
+ t-on-input="(ev) => this.updateCode(ev)"
2951
+ />
2952
+ </div>
2953
+ <div class="o-subsection-right">
2954
+ <div class="o-section-title">Symbol</div>
2955
+ <input
2956
+ type="text"
2957
+ class="o-input"
2958
+ t-model="state.currencySymbol"
2959
+ t-on-input="(ev) => this.updateSymbol(ev)"
2960
+ />
2961
+ </div>
2962
+ </div>
2963
+ <div class="o-section">
2964
+ <div class="o-section-title">Format</div>
2965
+ <select
2966
+ class="o-input o-format-proposals"
2967
+ t-on-change="(ev) => this.updateSelectFormat(ev)"
2968
+ t-att-disabled="!formatProposals.length">
2969
+ <t t-foreach="formatProposals" t-as="proposal" t-key="proposal_index">
2970
+ <option
2971
+ t-att-value="proposal_index"
2972
+ t-esc="proposal.example"
2973
+ t-att-selected="proposal_index === state.selectedFormatIndex"
2974
+ />
2975
+ </t>
2976
+ </select>
2977
+ </div>
2978
+ <div class="o-sidePanelButtons">
2979
+ <button
2980
+ class="o-sidePanelButton"
2981
+ t-on-click="() => this.apply()"
2982
+ t-att-disabled="!formatProposals.length || isSameFormat">
2983
+ Apply
2984
+ </button>
2985
+ </div>
2986
+ </div>
2987
+ </t>
2988
+
2989
+ <t t-name="o-spreadsheet-FindAndReplacePanel" owl="1">
2990
+ <div class="o-find-and-replace" tabindex="0" t-ref="findAndReplace">
2991
+ <div class="o-section">
2992
+ <div class="o-section-title">Search</div>
2993
+ <div class="o-input-search-container">
2994
+ <input
2995
+ type="text"
2996
+ class="o-input o-input-with-count"
2997
+ t-on-input="onInput"
2998
+ t-on-keydown="onKeydownSearch"
2999
+ />
3000
+ <div class="o-input-count" t-if="hasSearchResult">
3001
+ <t t-esc="env.model.getters.getCurrentSelectedMatchIndex()+1"/>
3002
+ /
3003
+ <t t-esc="env.model.getters.getSearchMatches().length"/>
3004
+ </div>
3005
+ <div t-elif="!pendingSearch and state.toSearch !== ''" class="o-input-count">0 / 0</div>
3006
+ </div>
3007
+ <div>
3008
+ <!-- TODO: go through this css, the group misses a padding and could profit from BootStrap -->
3009
+ <div class="o-far-item">
3010
+ <label class="o-far-checkbox">
3011
+ <input
3012
+ t-model="state.searchOptions.matchCase"
3013
+ t-on-change="updateSearch"
3014
+ class="o-far-input"
3015
+ type="checkbox"
3016
+ />
3017
+ <span class="o-far-label">Match case</span>
3018
+ </label>
3019
+ </div>
3020
+ <div class="o-far-item">
3021
+ <label class="o-far-checkbox">
3022
+ <input
3023
+ t-model="state.searchOptions.exactMatch"
3024
+ t-on-change="updateSearch"
3025
+ class="o-far-input"
3026
+ type="checkbox"
3027
+ />
3028
+ <span class="o-far-label">Match entire cell content</span>
3029
+ </label>
3030
+ </div>
3031
+ <div class="o-far-item">
3032
+ <label class="o-far-checkbox">
3033
+ <input
3034
+ t-model="state.searchOptions.searchFormulas"
3035
+ t-on-change="searchFormulas"
3036
+ class="o-far-input"
3037
+ type="checkbox"
3038
+ />
3039
+ <span class="o-far-label">Search in formulas</span>
3040
+ </label>
3041
+ </div>
3042
+ </div>
3043
+ </div>
3044
+ <div class="o-sidePanelButtons">
3045
+ <button
3046
+ t-att-disabled="!hasSearchResult"
3047
+ t-on-click="onSelectPreviousCell"
3048
+ class="o-sidePanelButton">
3049
+ Previous
3050
+ </button>
3051
+ <button
3052
+ t-att-disabled="!hasSearchResult"
3053
+ t-on-click="onSelectNextCell"
3054
+ class="o-sidePanelButton">
3055
+ Next
3056
+ </button>
3057
+ </div>
3058
+ <div class="o-section" t-if="!env.model.getters.isReadonly()">
3059
+ <div class="o-section-title">Replace</div>
3060
+ <div class="o-input-search-container">
3061
+ <input
3062
+ type="text"
3063
+ class="o-input o-input-without-count"
3064
+ t-model="state.replaceWith"
3065
+ t-on-keydown="onKeydownReplace"
3066
+ />
3067
+ </div>
3068
+ </div>
3069
+
3070
+ <div class="o-sidePanelButtons" t-if="!env.model.getters.isReadonly()">
3071
+ <button
3072
+ t-att-disabled="env.model.getters.getCurrentSelectedMatchIndex() === null"
3073
+ t-on-click="replace"
3074
+ class="o-sidePanelButton">
3075
+ Replace
3076
+ </button>
3077
+ <button
3078
+ t-att-disabled="env.model.getters.getCurrentSelectedMatchIndex() === null"
3079
+ t-on-click="replaceAll"
3080
+ class="o-sidePanelButton">
3081
+ Replace all
3082
+ </button>
3083
+ </div>
3084
+ </div>
3085
+ </t>
3086
+
3087
+ <t t-name="o-spreadsheet-SidePanel" owl="1">
3088
+ <div class="o-sidePanel">
3089
+ <div class="o-sidePanelHeader">
3090
+ <div class="o-sidePanelTitle" t-esc="getTitle()"/>
3091
+ <div class="o-sidePanelClose" t-on-click="() => this.props.onCloseSidePanel()">✕</div>
3092
+ </div>
3093
+ <div class="o-sidePanelBody">
3094
+ <t
3095
+ t-component="state.panel.Body"
3096
+ t-props="props.panelProps"
3097
+ onCloseSidePanel="props.onCloseSidePanel"
3098
+ t-key="'Body_' + props.component"
3099
+ />
3100
+ </div>
3101
+ <div class="o-sidePanelFooter" t-if="state.panel.Footer">
3102
+ <t
3103
+ t-component="state.panel.Footer"
3104
+ t-props="props.panelProps"
3105
+ t-key="'Footer_' + props.component"
3106
+ />
3107
+ </div>
3108
+ </div>
3109
+ </t>
3110
+
3111
+ <t t-name="o-spreadsheet-Spreadsheet" owl="1">
3112
+ <div
3113
+ class="o-spreadsheet"
3114
+ t-on-keydown="(ev) => !env.isDashboard() and this.onKeydown(ev)"
3115
+ t-att-style="getStyle()">
3116
+ <t t-if="env.isDashboard()">
3117
+ <SpreadsheetDashboard/>
3118
+ </t>
3119
+ <t t-else="">
3120
+ <TopBar
3121
+ onClick="() => this.focusGrid()"
3122
+ onComposerContentFocused="(selection) => this.onTopBarComposerFocused(selection)"
3123
+ focusComposer="focusTopBarComposer"
3124
+ dropdownMaxHeight="gridHeight"
3125
+ />
3126
+ <Grid
3127
+ sidePanelIsOpen="sidePanel.isOpen"
3128
+ focusComposer="focusGridComposer"
3129
+ exposeFocus="(focus) => this._focusGrid = focus"
3130
+ onComposerContentFocused="() => this.onGridComposerContentFocused()"
3131
+ onGridComposerCellFocused="(content, selection) => this.onGridComposerCellFocused(content, selection)"
3132
+ />
3133
+ <SidePanel
3134
+ t-if="sidePanel.isOpen"
3135
+ onCloseSidePanel="() => this.closeSidePanel()"
3136
+ component="sidePanel.component"
3137
+ panelProps="sidePanel.panelProps"
3138
+ />
3139
+ <BottomBar onClick="() => this.focusGrid()"/>
3140
+ </t>
3141
+ </div>
3142
+ </t>
3143
+
3144
+ <t t-name="o-spreadsheet-TopBar" owl="1">
3145
+ <div class="o-spreadsheet-topbar o-two-columns" t-on-click="props.onClick">
3146
+ <div class="o-topbar-top">
3147
+ <!-- Menus -->
3148
+ <div class="o-topbar-topleft">
3149
+ <t t-foreach="menus" t-as="menu" t-key="menu_index">
3150
+ <div
3151
+ t-if="menu.children.length !== 0"
3152
+ class="o-topbar-menu"
3153
+ t-att-class="{'o-topbar-menu-active': state.menuState.parentMenu and state.menuState.parentMenu.id === menu.id}"
3154
+ t-on-click="(ev) => this.toggleContextMenu(menu, ev)"
3155
+ t-on-mouseover="(ev) => this.onMenuMouseOver(menu, ev)"
3156
+ t-att-data-id="menu.id">
3157
+ <t t-esc="getMenuName(menu)"/>
3158
+ </div>
3159
+ </t>
3160
+ <Menu
3161
+ t-if="state.menuState.isOpen"
3162
+ position="state.menuState.position"
3163
+ menuItems="state.menuState.menuItems"
3164
+ onClose="() => this.closeMenus()"
3165
+ onMenuClicked="() => this.props.onClick()"
3166
+ />
3167
+ </div>
3168
+ <div class="o-topbar-topright">
3169
+ <div t-foreach="topbarComponents" t-as="comp" t-key="comp.id">
3170
+ <t t-component="comp.component"/>
3171
+ </div>
3172
+ </div>
3173
+ </div>
3174
+ <!-- Toolbar and Cell Content -->
3175
+ <div class="d-flex">
3176
+ <div class="o-topbar-toolbar">
3177
+ <!-- Toolbar -->
3178
+ <div t-if="env.model.getters.isReadonly()" class="o-readonly-toolbar text-muted">
3179
+ <span>
3180
+ <i class="fa fa-eye"/>
3181
+ Readonly Access
3182
+ </span>
3183
+ </div>
3184
+ <div t-else="" class="o-toolbar-tools">
3185
+ <div
3186
+ class="o-tool"
3187
+ title="Undo (Ctrl+Z)"
3188
+ t-att-class="{'o-disabled': !undoTool}"
3189
+ t-on-click="undo">
3190
+ <t t-call="o-spreadsheet-Icon.UNDO"/>
3191
+ </div>
3192
+ <div
3193
+ class="o-tool"
3194
+ t-att-class="{'o-disabled': !redoTool}"
3195
+ title="Redo (Ctrl+Y)"
3196
+ t-on-click="redo">
3197
+ <t t-call="o-spreadsheet-Icon.REDO"/>
3198
+ </div>
3199
+ <div
3200
+ class="o-tool"
3201
+ title="Paint Format"
3202
+ t-att-class="{active:paintFormatTool}"
3203
+ t-on-click="paintFormat">
3204
+ <t t-call="o-spreadsheet-Icon.PAINT_FORMAT"/>
3205
+ </div>
3206
+ <div class="o-tool" title="Clear Format" t-on-click="clearFormatting">
3207
+ <t t-call="o-spreadsheet-Icon.CLEAR_FORMAT"/>
3208
+ </div>
3209
+ <div class="o-divider"/>
3210
+ <div
3211
+ class="o-tool"
3212
+ title="Format as percent"
3213
+ t-on-click="(ev) => this.toggleFormat('percent', ev)">
3214
+ %
3215
+ </div>
3216
+ <div
3217
+ class="o-tool"
3218
+ title="Decrease decimal places"
3219
+ t-on-click="(ev) => this.setDecimal(-1, ev)">
3220
+ .0
3221
+ </div>
3222
+ <div
3223
+ class="o-tool"
3224
+ title="Increase decimal places"
3225
+ t-on-click="(ev) => this.setDecimal(+1, ev)">
3226
+ .00
3227
+ </div>
3228
+ <div class="o-dropdown">
3229
+ <div
3230
+ class="o-tool o-dropdown-button o-text-icon"
3231
+ title="More formats"
3232
+ t-on-click="(ev) => this.toggleDropdownTool('formatTool', ev)">
3233
+ 123
3234
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
3235
+ </div>
3236
+ <div
3237
+ class="o-dropdown-content o-text-options o-format-tool "
3238
+ t-if="state.activeTool === 'formatTool'"
3239
+ t-att-style="dropdownStyle"
3240
+ t-on-click.stop="">
3241
+ <t t-foreach="commonFormats" t-as="commonFormat" t-key="commonFormat.name">
3242
+ <div
3243
+ class="o-dropdown-item"
3244
+ t-att-data-format="commonFormat.name"
3245
+ t-on-click="() => this.setFormat(commonFormat.name)"
3246
+ t-att-class="{active: currentFormatName === commonFormat.name}">
3247
+ <t t-esc="commonFormat.text"/>
3248
+ <span class="float-end text-muted" t-esc="commonFormat.description"/>
3249
+ </div>
3250
+ </t>
3251
+ <t t-foreach="customFormats" t-as="customFormat" t-key="customFormat.name">
3252
+ <div
3253
+ t-att-data-custom="customFormat.name"
3254
+ class="o-dropdown-item"
3255
+ t-on-click="() => this.setFormat(customFormat.name, true)">
3256
+ <t t-esc="customFormat.text"/>
3257
+ </div>
3258
+ </t>
3259
+ </div>
3260
+ </div>
3261
+ <div class="o-divider"/>
3262
+ <FontSizeEditor
3263
+ class="'o-tool'"
3264
+ onToggle.bind="this.onClick"
3265
+ dropdownStyle="this.dropdownStyle"
3266
+ />
3267
+ <div class="o-divider"/>
3268
+ <div
3269
+ class="o-tool"
3270
+ title="Bold (Ctrl+B)"
3271
+ t-att-class="{active:style.bold}"
3272
+ t-on-click="(ev) => this.toggleStyle('bold', ev)">
3273
+ <t t-call="o-spreadsheet-Icon.BOLD"/>
3274
+ </div>
3275
+ <div
3276
+ class="o-tool"
3277
+ title="Italic (Ctrl+I)"
3278
+ t-att-class="{active:style.italic}"
3279
+ t-on-click="(ev) => this.toggleStyle('italic', ev)">
3280
+ <t t-call="o-spreadsheet-Icon.ITALIC"/>
3281
+ </div>
3282
+ <div
3283
+ class="o-tool"
3284
+ title="Strikethrough"
3285
+ t-att-class="{active:style.strikethrough}"
3286
+ t-on-click="(ev) => this.toggleStyle('strikethrough', ev)">
3287
+ <t t-call="o-spreadsheet-Icon.STRIKE"/>
3288
+ </div>
3289
+ <div class="o-dropdown">
3290
+ <ColorPickerWidget
3291
+ currentColor="textColor"
3292
+ toggleColorPicker="(ev) => this.toggleDropdownTool('textColorTool', ev)"
3293
+ showColorPicker="state.activeTool === 'textColorTool'"
3294
+ onColorPicked="(color) => this.setColor('textColor', color)"
3295
+ title="env._t('Text Color')"
3296
+ icon="'o-spreadsheet-Icon.TEXT_COLOR'"
3297
+ dropdownMaxHeight="this.props.dropdownMaxHeight"
3298
+ class="'o-tool o-dropdown-button'"
3299
+ />
3300
+ </div>
3301
+ <div class="o-divider"/>
3302
+ <div class="o-dropdown">
3303
+ <ColorPickerWidget
3304
+ currentColor="fillColor"
3305
+ toggleColorPicker="(ev) => this.toggleDropdownTool('fillColorTool', ev)"
3306
+ showColorPicker="state.activeTool === 'fillColorTool'"
3307
+ onColorPicked="(color) => this.setColor('fillColor', color)"
3308
+ title="env._t('Fill Color')"
3309
+ icon="'o-spreadsheet-Icon.FILL_COLOR'"
3310
+ dropdownMaxHeight="this.props.dropdownMaxHeight"
3311
+ class="'o-tool o-dropdown-button'"
3312
+ />
3313
+ </div>
3314
+ <div class="o-dropdown">
3315
+ <div
3316
+ class="o-tool o-dropdown-button"
3317
+ title="Borders"
3318
+ t-on-click="(ev) => this.toggleDropdownTool('borderTool', ev)">
3319
+ <span>
3320
+ <t t-call="o-spreadsheet-Icon.BORDERS"/>
3321
+ </span>
3322
+ </div>
3323
+ <div
3324
+ class="o-dropdown-content o-border-dropdown"
3325
+ t-if="state.activeTool === 'borderTool'"
3326
+ t-att-style="dropdownStyle"
3327
+ t-on-click.stop="">
3328
+ <div class="o-dropdown-line">
3329
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('all')">
3330
+ <t t-call="o-spreadsheet-Icon.BORDERS"/>
3331
+ </span>
3332
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('hv')">
3333
+ <t t-call="o-spreadsheet-Icon.BORDER_HV"/>
3334
+ </span>
3335
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('h')">
3336
+ <t t-call="o-spreadsheet-Icon.BORDER_H"/>
3337
+ </span>
3338
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('v')">
3339
+ <t t-call="o-spreadsheet-Icon.BORDER_V"/>
3340
+ </span>
3341
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('external')">
3342
+ <t t-call="o-spreadsheet-Icon.BORDER_EXTERNAL"/>
3343
+ </span>
3344
+ </div>
3345
+ <div class="o-dropdown-line">
3346
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('left')">
3347
+ <t t-call="o-spreadsheet-Icon.BORDER_LEFT"/>
3348
+ </span>
3349
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('top')">
3350
+ <t t-call="o-spreadsheet-Icon.BORDER_TOP"/>
3351
+ </span>
3352
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('right')">
3353
+ <t t-call="o-spreadsheet-Icon.BORDER_RIGHT"/>
3354
+ </span>
3355
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('bottom')">
3356
+ <t t-call="o-spreadsheet-Icon.BORDER_BOTTOM"/>
3357
+ </span>
3358
+ <span class="o-line-item" t-on-click="(ev) => this.setBorder('clear')">
3359
+ <t t-call="o-spreadsheet-Icon.BORDER_CLEAR"/>
3360
+ </span>
3361
+ </div>
3362
+ </div>
3363
+ </div>
3364
+ <div
3365
+ class="o-tool o-merge-tool"
3366
+ title="Merge Cells"
3367
+ t-att-class="{active:inMerge, 'o-disabled': cannotMerge}"
3368
+ t-on-click="toggleMerge">
3369
+ <t t-call="o-spreadsheet-Icon.MERGE_CELL"/>
3370
+ </div>
3371
+ <div class="o-divider"/>
3372
+ <div class="o-dropdown">
3373
+ <div
3374
+ class="o-tool o-dropdown-button"
3375
+ title="Horizontal align"
3376
+ t-on-click="(ev) => this.toggleDropdownTool('horizontalAlignTool', ev)">
3377
+ <span>
3378
+ <t t-if="style.align === 'right'">
3379
+ <t t-call="o-spreadsheet-Icon.ALIGN_RIGHT"/>
3380
+ </t>
3381
+ <t t-elif="style.align === 'center'">
3382
+ <t t-call="o-spreadsheet-Icon.ALIGN_CENTER"/>
3383
+ </t>
3384
+ <t t-else="">
3385
+ <t t-call="o-spreadsheet-Icon.ALIGN_LEFT"/>
3386
+ </t>
3387
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
3388
+ </span>
3389
+ </div>
3390
+ <div
3391
+ t-if="state.activeTool === 'horizontalAlignTool'"
3392
+ class="o-dropdown-content"
3393
+ t-att-style="dropdownStyle"
3394
+ t-on-click.stop="">
3395
+ <div
3396
+ class="o-dropdown-item o-dropdown-align-item"
3397
+ title="Left"
3398
+ t-on-click="() => this.toggleHorizontalAlign('left')">
3399
+ <t t-call="o-spreadsheet-Icon.ALIGN_LEFT"/>
3400
+ </div>
3401
+ <div
3402
+ class="o-dropdown-item o-dropdown-align-item"
3403
+ title="Center"
3404
+ t-on-click="() => this.toggleHorizontalAlign('center')">
3405
+ <t t-call="o-spreadsheet-Icon.ALIGN_CENTER"/>
3406
+ </div>
3407
+ <div
3408
+ class="o-dropdown-item o-dropdown-align-item"
3409
+ title="Right"
3410
+ t-on-click="() => this.toggleHorizontalAlign('right')">
3411
+ <t t-call="o-spreadsheet-Icon.ALIGN_RIGHT"/>
3412
+ </div>
3413
+ </div>
3414
+ </div>
3415
+ <div class="o-dropdown">
3416
+ <div
3417
+ class="o-tool o-dropdown-button"
3418
+ title="Vertical align"
3419
+ t-on-click="(ev) => this.toggleDropdownTool('verticalAlignTool', ev)">
3420
+ <span>
3421
+ <t t-if="style.verticalAlign === 'top'">
3422
+ <t t-call="o-spreadsheet-Icon.ALIGN_TOP"/>
3423
+ </t>
3424
+ <t t-elif="style.verticalAlign === 'bottom'">
3425
+ <t t-call="o-spreadsheet-Icon.ALIGN_BOTTOM"/>
3426
+ </t>
3427
+ <t t-else="">
3428
+ <t t-call="o-spreadsheet-Icon.ALIGN_MIDDLE"/>
3429
+ </t>
3430
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
3431
+ </span>
3432
+ </div>
3433
+ <div
3434
+ t-if="state.activeTool === 'verticalAlignTool'"
3435
+ class="o-dropdown-content"
3436
+ t-att-style="dropdownStyle"
3437
+ t-on-click.stop="">
3438
+ <div
3439
+ class="o-dropdown-item o-dropdown-align-item"
3440
+ title="Top"
3441
+ t-on-click="() => this.toggleVerticalAlign('top')">
3442
+ <t t-call="o-spreadsheet-Icon.ALIGN_TOP"/>
3443
+ </div>
3444
+ <div
3445
+ class="o-dropdown-item o-dropdown-align-item"
3446
+ title="Middle"
3447
+ t-on-click="() => this.toggleVerticalAlign('middle')">
3448
+ <t t-call="o-spreadsheet-Icon.ALIGN_MIDDLE"/>
3449
+ </div>
3450
+ <div
3451
+ class="o-dropdown-item o-dropdown-align-item"
3452
+ title="Bottom"
3453
+ t-on-click="() => this.toggleVerticalAlign('bottom')">
3454
+ <t t-call="o-spreadsheet-Icon.ALIGN_BOTTOM"/>
3455
+ </div>
3456
+ </div>
3457
+ </div>
3458
+ <div class="o-dropdown">
3459
+ <div
3460
+ class="o-tool o-dropdown-button"
3461
+ title="Text wrapping"
3462
+ t-on-click="(ev) => this.toggleDropdownTool('textWrappingTool', ev)">
3463
+ <span>
3464
+ <t t-if="style.wrapping === 'wrap'">
3465
+ <t t-call="o-spreadsheet-Icon.WRAPPING_WRAP"/>
3466
+ </t>
3467
+ <t t-elif="style.wrapping === 'clip'">
3468
+ <t t-call="o-spreadsheet-Icon.WRAPPING_CLIP"/>
3469
+ </t>
3470
+ <t t-else="">
3471
+ <t t-call="o-spreadsheet-Icon.WRAPPING_OVERFLOW"/>
3472
+ </t>
3473
+ <t t-call="o-spreadsheet-Icon.TRIANGLE_DOWN"/>
3474
+ </span>
3475
+ </div>
3476
+ <div
3477
+ t-if="state.activeTool === 'textWrappingTool'"
3478
+ class="o-dropdown-content"
3479
+ t-att-style="dropdownStyle"
3480
+ t-on-click.stop="">
3481
+ <div
3482
+ class="o-dropdown-item o-dropdown-align-item"
3483
+ title="Overflow"
3484
+ t-on-click="() => this.toggleTextWrapping('overflow')">
3485
+ <t t-call="o-spreadsheet-Icon.WRAPPING_OVERFLOW"/>
3486
+ </div>
3487
+ <div
3488
+ class="o-dropdown-item o-dropdown-align-item"
3489
+ title="Wrap"
3490
+ t-on-click="() => this.toggleTextWrapping('wrap')">
3491
+ <t t-call="o-spreadsheet-Icon.WRAPPING_WRAP"/>
3492
+ </div>
3493
+ <div
3494
+ class="o-dropdown-item o-dropdown-align-item"
3495
+ title="Clip"
3496
+ t-on-click="() => this.toggleTextWrapping('clip')">
3497
+ <t t-call="o-spreadsheet-Icon.WRAPPING_CLIP"/>
3498
+ </div>
3499
+ </div>
3500
+ </div>
3501
+ <div class="o-divider"/>
3502
+ <div
3503
+ t-if="selectionContainsFilter"
3504
+ class="o-tool o-filter-tool o-tool-outlined"
3505
+ title="Remove selected filters"
3506
+ t-on-click="removeFilter">
3507
+ <t t-call="o-spreadsheet-Icon.FILTER_ICON_ACTIVE"/>
3508
+ </div>
3509
+ <div
3510
+ t-else=""
3511
+ class="o-tool o-filter-tool"
3512
+ t-att-class="{'o-disabled': cannotCreateFilter}"
3513
+ title="Create a filter"
3514
+ t-on-click="createFilter">
3515
+ <t t-call="o-spreadsheet-Icon.FILTER_ICON_INACTIVE"/>
3516
+ </div>
3517
+ </div>
3518
+ </div>
3519
+ <TopBarComposer
3520
+ focus="props.focusComposer"
3521
+ onComposerContentFocused="props.onComposerContentFocused"
3522
+ />
3523
+ </div>
3524
+ </div>
3525
+ </t>
3526
+ </odoo>
3527
+ <!--
3528
+ __info__.version = '16.2.22';
3529
+ __info__.date = '2023-11-16T11:57:24.917Z';
3530
+ __info__.hash = 'b78d5dd';
3531
+ -->