Skip to content

Commit ca9b404

Browse files
committed
[FIX] figure: wrong focus change on figure unmount
When a figure is unmounted, the focus is moved to the default focusable element (the grid composer). But this change is done even if the figure wasn't focused. For example, the focus would be removed from the find & replace search input when leaving a sheet with a figure. closes #7333 Task: 5154025 Signed-off-by: Lucas Lefèvre (lul) <lul@odoo.com>
1 parent cd6c2d8 commit ca9b404

File tree

13 files changed

+59
-61
lines changed

13 files changed

+59
-61
lines changed

src/components/figures/figure/figure.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, onWillUnmount, useEffect, useRef, useState } from "@odoo/owl";
1+
import { Component, useEffect, useRef, useState } from "@odoo/owl";
22
import {
33
ComponentsImportance,
44
FIGURE_BORDER_COLOR,
@@ -115,7 +115,6 @@ css/*SCSS*/ `
115115
interface Props {
116116
figure: Figure;
117117
style: string;
118-
onFigureDeleted: () => void;
119118
onMouseDown: (ev: MouseEvent) => void;
120119
onClickAnchor(dirX: ResizeDirection, dirY: ResizeDirection, ev: MouseEvent): void;
121120
}
@@ -125,13 +124,11 @@ export class FigureComponent extends Component<Props, SpreadsheetChildEnv> {
125124
static props = {
126125
figure: Object,
127126
style: { type: String, optional: true },
128-
onFigureDeleted: { type: Function, optional: true },
129127
onMouseDown: { type: Function, optional: true },
130128
onClickAnchor: { type: Function, optional: true },
131129
};
132130
static components = { Menu };
133131
static defaultProps = {
134-
onFigureDeleted: () => {},
135132
onMouseDown: () => {},
136133
onClickAnchor: () => {},
137134
};
@@ -214,10 +211,6 @@ export class FigureComponent extends Component<Props, SpreadsheetChildEnv> {
214211
},
215212
() => [this.env.model.getters.getSelectedFigureId(), this.props.figure.id, this.figureRef.el]
216213
);
217-
218-
onWillUnmount(() => {
219-
this.props.onFigureDeleted();
220-
});
221214
}
222215

223216
clickAnchor(dirX: ResizeDirection, dirY: ResizeDirection, ev: MouseEvent) {
@@ -239,7 +232,6 @@ export class FigureComponent extends Component<Props, SpreadsheetChildEnv> {
239232
sheetId: this.env.model.getters.getActiveSheetId(),
240233
id: figure.id,
241234
});
242-
this.props.onFigureDeleted();
243235
ev.preventDefault();
244236
ev.stopPropagation();
245237
break;
@@ -304,6 +296,6 @@ export class FigureComponent extends Component<Props, SpreadsheetChildEnv> {
304296
this.menuState.position = position;
305297
this.menuState.menuItems = figureRegistry
306298
.get(this.props.figure.tag)
307-
.menuBuilder(this.props.figure.id, this.props.onFigureDeleted, this.env);
299+
.menuBuilder(this.props.figure.id, this.env);
308300
}
309301
}

src/components/figures/figure/figure.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
<t
1515
t-component="figureRegistry.get(props.figure.tag).Component"
1616
t-key="props.figure.id"
17-
onFigureDeleted="props.onFigureDeleted"
1817
figure="props.figure"
1918
/>
2019
<div class="o-figure-menu position-absolute m-2" t-if="!env.isDashboard()">

src/components/figures/figure_chart/figure_chart.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@ interface Props {
1818
// props figure is currently necessary scorecards, we need the chart dimension at render to avoid having to force the
1919
// style by hand in the useEffect()
2020
figure: Figure;
21-
onFigureDeleted: () => void;
2221
}
2322

2423
export class ChartFigure extends Component<Props, SpreadsheetChildEnv> {
2524
static template = "o-spreadsheet-ChartFigure";
2625
static props = {
2726
figure: Object,
28-
onFigureDeleted: Function,
2927
};
3028
static components = {};
3129

src/components/figures/figure_container/figure_container.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ import { FigureComponent } from "../figure/figure";
2222

2323
type ContainerType = "topLeft" | "topRight" | "bottomLeft" | "bottomRight" | "dnd";
2424

25-
interface Props {
26-
onFigureDeleted: () => void;
27-
}
25+
interface Props {}
2826

2927
interface Container {
3028
type: ContainerType;
@@ -127,9 +125,7 @@ css/*SCSS*/ `
127125
*/
128126
export class FiguresContainer extends Component<Props, SpreadsheetChildEnv> {
129127
static template = "o-spreadsheet-FiguresContainer";
130-
static props = {
131-
onFigureDeleted: Function,
132-
};
128+
static props = {};
133129
static components = { FigureComponent };
134130

135131
dnd = useState<DndState>({

src/components/figures/figure_container/figure_container.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
t-att-style="container.inverseViewportStyle">
1212
<t t-foreach="container.figures" t-as="figure" t-key="figure.id">
1313
<FigureComponent
14-
onFigureDeleted="this.props.onFigureDeleted"
1514
figure="figure"
1615
style="getFigureStyle(figure)"
1716
onMouseDown="(ev) => this.startDraggingFigure(figure, ev)"

src/components/figures/figure_image/figure_image.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@ import { Figure, SpreadsheetChildEnv, UID } from "../../../types";
33

44
interface Props {
55
figure: Figure;
6-
onFigureDeleted: () => void;
76
}
87

98
export class ImageFigure extends Component<Props, SpreadsheetChildEnv> {
109
static template = "o-spreadsheet-ImageFigure";
1110
static props = {
1211
figure: Object,
13-
onFigureDeleted: Function,
1412
};
1513
static components = {};
1614

src/components/grid/grid.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
onGridResized.bind="onGridResized"
1717
onGridMoved.bind="moveCanvas"
1818
gridOverlayDimensions="gridOverlayDimensions"
19-
onFigureDeleted.bind="focusDefaultElement"
2019
/>
2120
<HeadersOverlay onOpenContextMenu="(type, x, y) => this.toggleContextMenu(type, x, y)"/>
2221
<GridComposer

src/components/grid_add_rows_footer/grid_add_rows_footer.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { Component, useExternalListener, useRef, useState } from "@odoo/owl";
2+
import { Store, useStore } from "../../store_engine";
3+
import { DOMFocusableElementStore } from "../../stores/DOM_focus_store";
24
import { _t } from "../../translation";
35
import { SpreadsheetChildEnv } from "../../types";
46
import { css, cssPropertiesToCss } from "../helpers";
@@ -20,23 +22,23 @@ css/* scss */ `
2022
}
2123
`;
2224

23-
interface Props {
24-
focusGrid: () => void;
25-
}
25+
interface Props {}
2626

2727
export class GridAddRowsFooter extends Component<Props, SpreadsheetChildEnv> {
2828
static template = "o-spreadsheet-GridAddRowsFooter";
29-
static props = {
30-
focusGrid: Function,
31-
};
29+
static props = {};
3230
static components = { ValidationMessages };
31+
32+
private DOMFocusableElementStore!: Store<DOMFocusableElementStore>;
33+
3334
inputRef = useRef<HTMLInputElement>("inputRef");
3435
state = useState({
3536
inputValue: "100",
3637
errorFlag: false,
3738
});
3839

3940
setup() {
41+
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
4042
useExternalListener(window, "click", this.onExternalClick, { capture: true });
4143
}
4244

@@ -58,7 +60,7 @@ export class GridAddRowsFooter extends Component<Props, SpreadsheetChildEnv> {
5860

5961
onKeydown(ev: KeyboardEvent) {
6062
if (ev.key.toUpperCase() === "ESCAPE") {
61-
this.props.focusGrid();
63+
this.focusDefaultElement();
6264
} else if (ev.key.toUpperCase() === "ENTER") {
6365
this.onConfirm();
6466
}
@@ -85,7 +87,7 @@ export class GridAddRowsFooter extends Component<Props, SpreadsheetChildEnv> {
8587
quantity,
8688
dimension: "ROW",
8789
});
88-
this.props.focusGrid();
90+
this.focusDefaultElement();
8991

9092
// After adding new rows, scroll down to the new last row
9193
const { scrollX } = this.env.model.getters.getActiveSheetDOMScrollInfo();
@@ -103,6 +105,12 @@ export class GridAddRowsFooter extends Component<Props, SpreadsheetChildEnv> {
103105
if (this.inputRef.el !== document.activeElement || ev.target === this.inputRef.el) {
104106
return;
105107
}
106-
this.props.focusGrid();
108+
this.focusDefaultElement();
109+
}
110+
111+
private focusDefaultElement() {
112+
if (document.activeElement === this.inputRef.el) {
113+
this.DOMFocusableElementStore.focus();
114+
}
107115
}
108116
}

src/components/grid_overlay/grid_overlay.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ interface Props {
129129
onGridResized: (dimension: Rect) => void;
130130
onGridMoved: (deltaX: Pixel, deltaY: Pixel) => void;
131131
gridOverlayDimensions: string;
132-
onFigureDeleted: () => void;
133132
}
134133

135134
export class GridOverlay extends Component<Props, SpreadsheetChildEnv> {
@@ -140,7 +139,6 @@ export class GridOverlay extends Component<Props, SpreadsheetChildEnv> {
140139
onCellClicked: { type: Function, optional: true },
141140
onCellRightClicked: { type: Function, optional: true },
142141
onGridResized: { type: Function, optional: true },
143-
onFigureDeleted: { type: Function, optional: true },
144142
onGridMoved: Function,
145143
gridOverlayDimensions: String,
146144
};
@@ -156,7 +154,6 @@ export class GridOverlay extends Component<Props, SpreadsheetChildEnv> {
156154
onCellClicked: () => {},
157155
onCellRightClicked: () => {},
158156
onGridResized: () => {},
159-
onFigureDeleted: () => {},
160157
};
161158
private gridOverlay: Ref<HTMLElement> = useRef("gridOverlay");
162159
private gridOverlayRect = useAbsoluteBoundingRect(this.gridOverlay);

src/components/grid_overlay/grid_overlay.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@
88
t-on-pointerdown="onMouseDown"
99
t-on-dblclick.self="onDoubleClick"
1010
t-on-contextmenu.stop.prevent="onContextMenu">
11-
<FiguresContainer onFigureDeleted="props.onFigureDeleted"/>
11+
<FiguresContainer/>
1212
<DataValidationOverlay/>
1313
<FilterIconsOverlay/>
1414
<GridAddRowsFooter
1515
t-if="!env.model.getters.isReadonly()"
1616
t-key="env.model.getters.getActiveSheetId()"
17-
focusGrid="props.onFigureDeleted"
1817
/>
1918
</div>
2019
</t>

0 commit comments

Comments
 (0)