Skip to content

Commit b2a14ee

Browse files
committed
[IMP] dv: autofocus input
When switching a data validation to "Value In Range", automatically focus the range input to allow selecting a range right away without an additional click to focus the input. We do the same for all validation types that have an associated input. Task: 4862354
1 parent 0c2d9ba commit b2a14ee

File tree

13 files changed

+84
-7
lines changed

13 files changed

+84
-7
lines changed

src/components/composer/standalone_composer/standalone_composer.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component } from "@odoo/owl";
1+
import { Component, onMounted } from "@odoo/owl";
22
import { Token } from "../../../formulas";
33
import { AutoCompleteProviderDefinition } from "../../../registries/auto_completes";
44
import { Store, useLocalStore, useStore } from "../../../store_engine";
@@ -20,6 +20,7 @@ interface Props {
2020
title?: string;
2121
class?: string;
2222
invalid?: boolean;
23+
autofocus?: boolean;
2324
getContextualColoredSymbolToken?: (token: Token) => Color;
2425
}
2526

@@ -35,6 +36,7 @@ export class StandaloneComposer extends Component<Props, SpreadsheetChildEnv> {
3536
title: { type: String, optional: true },
3637
class: { type: String, optional: true },
3738
invalid: { type: Boolean, optional: true },
39+
autofocus: { type: Boolean, optional: true },
3840
getContextualColoredSymbolToken: { type: Function, optional: true },
3941
};
4042
static components = { Composer };
@@ -68,6 +70,12 @@ export class StandaloneComposer extends Component<Props, SpreadsheetChildEnv> {
6870
setCurrentContent: this.standaloneComposerStore.setCurrentContent,
6971
stopEdition: this.standaloneComposerStore.stopEdition,
7072
};
73+
onMounted(() => {
74+
if (this.props.autofocus && this.focus === "inactive") {
75+
this.composerFocusStore.focusComposer(this.composerInterface, {});
76+
this.composerFocusStore.activeComposer.editionMode;
77+
}
78+
});
7179
}
7280

7381
get focus(): ComposerFocusType {

src/components/selection_input/selection_input.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ interface Props {
1111
ranges: string[];
1212
hasSingleRange?: boolean;
1313
required?: boolean;
14+
autofocus?: boolean;
1415
isInvalid?: boolean;
1516
class?: string;
1617
onSelectionChanged?: (ranges: string[]) => void;
@@ -49,6 +50,7 @@ export class SelectionInput extends Component<Props, SpreadsheetChildEnv> {
4950
ranges: Array,
5051
hasSingleRange: { type: Boolean, optional: true },
5152
required: { type: Boolean, optional: true },
53+
autofocus: { type: Boolean, optional: true },
5254
isInvalid: { type: Boolean, optional: true },
5355
class: { type: String, optional: true },
5456
onSelectionChanged: { type: Function, optional: true },
@@ -104,6 +106,9 @@ export class SelectionInput extends Component<Props, SpreadsheetChildEnv> {
104106
this.props.colors,
105107
this.props.disabledRanges
106108
);
109+
if (this.props.autofocus) {
110+
this.store.focusById(this.store.selectionInputs[0]?.id);
111+
}
107112
onWillUpdateProps((nextProps) => {
108113
if (nextProps.ranges.join() !== this.store.selectionInputValues.join()) {
109114
this.triggerChange();

src/components/side_panel/criterion_form/criterion_form.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, onMounted } from "@odoo/owl";
1+
import { Component } from "@odoo/owl";
22
import { useStore } from "../../../store_engine";
33
import { GenericCriterion, SpreadsheetChildEnv } from "../../../types";
44
import { ComposerFocusStore } from "../../composer/composer_focus_store";
@@ -7,6 +7,7 @@ interface Props<T extends GenericCriterion> {
77
criterion: T;
88
onCriterionChanged: (criterion: T) => void;
99
disableFormulas?: boolean;
10+
autofocus?: boolean;
1011
}
1112

1213
export abstract class CriterionForm<
@@ -16,12 +17,13 @@ export abstract class CriterionForm<
1617
criterion: Object,
1718
onCriterionChanged: Function,
1819
disableFormulas: { type: Boolean, optional: true },
20+
autofocus: { type: Boolean, optional: true },
1921
};
2022
setup() {
2123
const composerFocusStore = useStore(ComposerFocusStore);
22-
onMounted(() => {
24+
if (composerFocusStore.activeComposer.editionMode !== "inactive") {
2325
composerFocusStore.activeComposer.stopEdition();
24-
});
26+
}
2527
}
2628

2729
updateCriterion(criterion: Partial<T>) {

src/components/side_panel/criterion_form/criterion_input/criterion_input.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ export class CriterionInput extends Component<Props, SpreadsheetChildEnv> {
4040
setup() {
4141
useEffect(
4242
() => {
43-
if (this.props.focused) {
44-
this.inputRef.el!.focus();
43+
if (this.props.focused && this.inputRef.el) {
44+
this.inputRef.el.focus();
4545
}
4646
},
4747
() => [this.props.focused, this.inputRef.el]
@@ -93,6 +93,7 @@ export class CriterionInput extends Component<Props, SpreadsheetChildEnv> {
9393
defaultRangeSheetId: this.env.model.getters.getActiveSheetId(),
9494
invalid: this.state.shouldDisplayError && !!this.errorMessage,
9595
defaultStatic: true,
96+
autofocus: this.props.focused,
9697
};
9798
}
9899

src/components/side_panel/criterion_form/date_criterion/date_criterion.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
onValueChanged.bind="onValueChanged"
1818
criterionType="props.criterion.type"
1919
disableFormulas="props.disableFormulas"
20+
focused="props.autofocus"
2021
/>
2122
</t>
2223
</templates>

src/components/side_panel/criterion_form/double_input_criterion/double_input_criterion.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
onValueChanged.bind="onFirstValueChanged"
66
criterionType="props.criterion.type"
77
disableFormulas="props.disableFormulas"
8+
focused="props.autofocus"
89
/>
910
<CriterionInput
1011
value="props.criterion.values[1]"

src/components/side_panel/criterion_form/single_input_criterion/single_input_criterion.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
onValueChanged.bind="onValueChanged"
66
criterionType="props.criterion.type"
77
disableFormulas="props.disableFormulas"
8+
focused="props.autofocus"
89
/>
910
</t>
1011
</templates>

src/components/side_panel/criterion_form/value_in_list_criterion/value_in_list_criterion.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export class ListCriterionForm extends CriterionForm<IsValueInListCriterion> {
1515

1616
state = useState<State>({
1717
numberOfValues: Math.max(this.props.criterion.values.length, 2),
18+
focusedValueIndex: this.props.autofocus ? 0 : undefined,
1819
});
1920

2021
setup() {

src/components/side_panel/criterion_form/value_in_range_criterion/value_in_range_criterion.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
onSelectionChanged="(ranges) => this.onRangeChanged(ranges[0])"
66
required="true"
77
hasSingleRange="true"
8+
autofocus="props.autofocus"
89
/>
910
<t t-foreach="values" t-as="value" t-key="value_index">
1011
<div class="o-dv-list-values p-1 d-flex align-items-center">

src/components/side_panel/data_validation/dv_editor/dv_editor.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ interface Props {
3232
interface State {
3333
rule: DataValidationRuleData;
3434
errors: CancelledReason[];
35+
isTypeUpdated: boolean;
3536
}
3637

3738
export class DataValidationEditor extends Component<Props, SpreadsheetChildEnv> {
@@ -43,7 +44,11 @@ export class DataValidationEditor extends Component<Props, SpreadsheetChildEnv>
4344
onCloseSidePanel: { type: Function, optional: true },
4445
};
4546

46-
state = useState<State>({ rule: this.defaultDataValidationRule, errors: [] });
47+
state = useState<State>({
48+
rule: this.defaultDataValidationRule,
49+
errors: [],
50+
isTypeUpdated: false,
51+
});
4752

4853
setup() {
4954
if (this.props.rule) {
@@ -60,6 +65,7 @@ export class DataValidationEditor extends Component<Props, SpreadsheetChildEnv>
6065

6166
onCriterionTypeChanged(type: DataValidationCriterionType) {
6267
this.state.rule.criterion.type = type;
68+
this.state.isTypeUpdated = true;
6369
}
6470

6571
onRangesChanged(ranges: string[]) {

0 commit comments

Comments
 (0)