From f0584c4ecdc895bee3389e99d330943a46ddd1fb Mon Sep 17 00:00:00 2001 From: Roman Vyakhirev Date: Thu, 26 Feb 2026 16:35:37 +0100 Subject: [PATCH] chore: always use captions from props, as those can update --- .../datagrid-dropdown-filter-web/CHANGELOG.md | 4 ++++ .../src/controllers/BaseController.ts | 23 ++++++++++++++++++- .../src/controllers/EnumBaseController.ts | 2 +- .../src/controllers/EnumComboboxController.ts | 3 --- .../src/controllers/EnumSelectController.ts | 3 --- .../controllers/EnumTagPickerController.ts | 3 --- .../src/controllers/RefComboboxController.ts | 3 --- .../src/controllers/RefSelectController.ts | 3 --- .../src/controllers/RefTagPickerController.ts | 3 --- .../mixins/ComboboxControllerMixin.ts | 6 ++--- .../mixins/SelectControllerMixin.ts | 8 +++---- .../mixins/TagPickerControllerMixin.ts | 6 ++--- 12 files changed, 37 insertions(+), 30 deletions(-) diff --git a/packages/pluggableWidgets/datagrid-dropdown-filter-web/CHANGELOG.md b/packages/pluggableWidgets/datagrid-dropdown-filter-web/CHANGELOG.md index 3ec1a1e014..76240584b3 100644 --- a/packages/pluggableWidgets/datagrid-dropdown-filter-web/CHANGELOG.md +++ b/packages/pluggableWidgets/datagrid-dropdown-filter-web/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Fixed + +- We fixed an issue with Dropdown filter captions not updating properly when their template parameters change. + ## [3.8.1] - 2026-02-19 ### Changed diff --git a/packages/shared/widget-plugin-dropdown-filter/src/controllers/BaseController.ts b/packages/shared/widget-plugin-dropdown-filter/src/controllers/BaseController.ts index 65b7667023..f22718c555 100644 --- a/packages/shared/widget-plugin-dropdown-filter/src/controllers/BaseController.ts +++ b/packages/shared/widget-plugin-dropdown-filter/src/controllers/BaseController.ts @@ -20,12 +20,16 @@ export interface BaseControllerProps { multiselect: boolean; onChange?: ActionValue; valueAttribute?: EditableValue; - emptyCaption?: string; + emptySelectionCaption: string; + emptyOptionCaption: string; + ariaLabel: string; + placeholder: string; } type Gate = DerivedPropsGate>; export class BaseController implements IJSActionsControlled { + protected readonly gate: Gate; protected actionHelper: JSActionsHelper; protected changeHelper: ValueChangeHelper; protected defaultValue?: Iterable; @@ -35,6 +39,7 @@ export class BaseController implements IJSActionsControll constructor({ gate, multiselect }: { gate: Gate; multiselect: boolean }) { const props = gate.props; + this.gate = gate; this.filterStore = props.filterStore; this.multiselect = multiselect; this.serializer = new OptionsSerializer({ store: this.filterStore }); @@ -47,6 +52,22 @@ export class BaseController implements IJSActionsControll this.changeHelper = new ValueChangeHelper(gate, () => this.serializer.value); } + get emptyCaption(): string { + return this.gate.props.emptySelectionCaption; + } + + get ariaLabel(): string { + return this.gate.props.ariaLabel; + } + + get emptyOptionCaption(): string { + return this.gate.props.emptyOptionCaption; + } + + get inputPlaceholder(): string { + return this.gate.props.placeholder; + } + parseDefaultValue = (value: string | undefined): Iterable | undefined => { const defaultValue = this.serializer.fromStorableValue(value); if (!defaultValue) { diff --git a/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumBaseController.ts b/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumBaseController.ts index ebe0e1f6b5..755c92d896 100644 --- a/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumBaseController.ts +++ b/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumBaseController.ts @@ -6,7 +6,7 @@ import { EnumFilterStore } from "../stores/EnumFilterStore"; import { BaseController } from "./BaseController"; export class EnumBaseController extends BaseController { - private readonly gate: DerivedPropsGate; + protected readonly gate: DerivedPropsGate; constructor({ gate, multiselect }: { gate: DerivedPropsGate; multiselect: boolean }) { super({ gate, multiselect }); diff --git a/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumComboboxController.ts b/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumComboboxController.ts index 116d9678e4..28481825ef 100644 --- a/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumComboboxController.ts +++ b/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumComboboxController.ts @@ -5,8 +5,5 @@ import { ComboboxControllerMixin } from "./mixins/ComboboxControllerMixin"; export class EnumComboboxController extends ComboboxControllerMixin(EnumBaseController) { constructor({ gate }: { gate: DerivedPropsGate }) { super({ gate, multiselect: false }); - this.inputPlaceholder = gate.props.placeholder; - this.emptyCaption = gate.props.emptySelectionCaption; - this.ariaLabel = gate.props.ariaLabel; } } diff --git a/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumSelectController.ts b/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumSelectController.ts index 348e876649..41064c04bc 100644 --- a/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumSelectController.ts +++ b/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumSelectController.ts @@ -5,8 +5,5 @@ import { SelectControllerMixin } from "./mixins/SelectControllerMixin"; export class EnumSelectController extends SelectControllerMixin(EnumBaseController) { constructor({ gate }: { gate: DerivedPropsGate }) { super({ gate, multiselect: gate.props.multiselect }); - this.emptyOption.caption = gate.props.emptyOptionCaption; - this.emptyCaption = gate.props.emptySelectionCaption; - this.ariaLabel = gate.props.ariaLabel; } } diff --git a/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumTagPickerController.ts b/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumTagPickerController.ts index ea5bcd4c2e..03a10003cf 100644 --- a/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumTagPickerController.ts +++ b/packages/shared/widget-plugin-dropdown-filter/src/controllers/EnumTagPickerController.ts @@ -16,9 +16,6 @@ export class EnumTagPickerController extends TagPickerControllerMixin(EnumBaseCo constructor({ gate }: { gate: DerivedPropsGate }) { super({ gate, multiselect: gate.props.multiselect }); - this.inputPlaceholder = gate.props.placeholder; - this.emptyCaption = gate.props.emptySelectionCaption; - this.ariaLabel = gate.props.ariaLabel; this.filterSelectedOptions = gate.props.selectionMethod === "rowClick"; this.selectedStyle = gate.props.selectedItemsStyle; this.selectionMethod = this.selectedStyle === "boxes" ? gate.props.selectionMethod : "checkbox"; diff --git a/packages/shared/widget-plugin-dropdown-filter/src/controllers/RefComboboxController.ts b/packages/shared/widget-plugin-dropdown-filter/src/controllers/RefComboboxController.ts index c488a63051..d18f574d12 100644 --- a/packages/shared/widget-plugin-dropdown-filter/src/controllers/RefComboboxController.ts +++ b/packages/shared/widget-plugin-dropdown-filter/src/controllers/RefComboboxController.ts @@ -6,9 +6,6 @@ import { RefBaseController, RefBaseControllerProps } from "./RefBaseController"; export class RefComboboxController extends ComboboxControllerMixin(RefBaseController) { constructor({ gate }: { gate: DerivedPropsGate }) { super({ gate, multiselect: false }); - this.inputPlaceholder = gate.props.placeholder; - this.emptyCaption = gate.props.emptySelectionCaption; - this.ariaLabel = gate.props.ariaLabel; } handleFocus = (event: FocusEvent): void => { diff --git a/packages/shared/widget-plugin-dropdown-filter/src/controllers/RefSelectController.ts b/packages/shared/widget-plugin-dropdown-filter/src/controllers/RefSelectController.ts index ea1a382c8f..d3c1c71d00 100644 --- a/packages/shared/widget-plugin-dropdown-filter/src/controllers/RefSelectController.ts +++ b/packages/shared/widget-plugin-dropdown-filter/src/controllers/RefSelectController.ts @@ -5,9 +5,6 @@ import { SelectControllerMixin } from "./mixins/SelectControllerMixin"; export class RefSelectController extends SelectControllerMixin(RefBaseController) { constructor({ gate }: { gate: DerivedPropsGate }) { super({ gate, multiselect: gate.props.multiselect }); - this.emptyOption.caption = gate.props.emptyOptionCaption; - this.emptyCaption = gate.props.emptySelectionCaption; - this.ariaLabel = gate.props.ariaLabel; } handleFocus = (): void => { diff --git a/packages/shared/widget-plugin-dropdown-filter/src/controllers/RefTagPickerController.ts b/packages/shared/widget-plugin-dropdown-filter/src/controllers/RefTagPickerController.ts index ce43fefdd9..1ccfa03dc1 100644 --- a/packages/shared/widget-plugin-dropdown-filter/src/controllers/RefTagPickerController.ts +++ b/packages/shared/widget-plugin-dropdown-filter/src/controllers/RefTagPickerController.ts @@ -16,9 +16,6 @@ export class RefTagPickerController extends TagPickerControllerMixin(RefBaseCont constructor({ gate }: { gate: DerivedPropsGate }) { super({ gate, multiselect: gate.props.multiselect }); - this.inputPlaceholder = gate.props.placeholder; - this.emptyCaption = gate.props.emptySelectionCaption; - this.ariaLabel = gate.props.ariaLabel; this.filterSelectedOptions = gate.props.selectionMethod === "rowClick"; this.selectedStyle = gate.props.selectedItemsStyle; this.selectionMethod = this.selectedStyle === "boxes" ? gate.props.selectionMethod : "checkbox"; diff --git a/packages/shared/widget-plugin-dropdown-filter/src/controllers/mixins/ComboboxControllerMixin.ts b/packages/shared/widget-plugin-dropdown-filter/src/controllers/mixins/ComboboxControllerMixin.ts index e11dbfa0ba..c108223be4 100644 --- a/packages/shared/widget-plugin-dropdown-filter/src/controllers/mixins/ComboboxControllerMixin.ts +++ b/packages/shared/widget-plugin-dropdown-filter/src/controllers/mixins/ComboboxControllerMixin.ts @@ -19,6 +19,9 @@ type BaseController = GConstructor<{ filterStore: FilterStore; multiselect: boolean; setup(): () => void; + inputPlaceholder: string; + emptyCaption: string; + ariaLabel: string; }>; // eslint-disable-next-line @typescript-eslint/explicit-function-return-type @@ -26,9 +29,6 @@ export function ComboboxControllerMixin(Base: TBas return class ComboboxControllerMixin extends Base { touched = false; inputValue = ""; - inputPlaceholder = ""; - emptyCaption = ""; - ariaLabel = ""; constructor(...args: any[]) { super(...args); diff --git a/packages/shared/widget-plugin-dropdown-filter/src/controllers/mixins/SelectControllerMixin.ts b/packages/shared/widget-plugin-dropdown-filter/src/controllers/mixins/SelectControllerMixin.ts index 0190f6e6d3..4838a2d573 100644 --- a/packages/shared/widget-plugin-dropdown-filter/src/controllers/mixins/SelectControllerMixin.ts +++ b/packages/shared/widget-plugin-dropdown-filter/src/controllers/mixins/SelectControllerMixin.ts @@ -15,6 +15,9 @@ export interface FilterStore { type BaseController = GConstructor<{ filterStore: FilterStore; multiselect: boolean; + ariaLabel: string; + emptyCaption: string; + emptyOptionCaption: string; }>; const none = "[[__none__]]" as const; @@ -22,9 +25,6 @@ const none = "[[__none__]]" as const; // eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function SelectControllerMixin(Base: TBase) { return class SelectControllerMixin extends Base { - emptyCaption = ""; - ariaLabel = ""; - readonly emptyOption = { value: none, caption: "", @@ -45,7 +45,7 @@ export function SelectControllerMixin(Base: TBase) if (this.multiselect) { return this.filterStore.options; } - return [this.emptyOption, ...this.filterStore.options]; + return [{ ...this.emptyOption, caption: this.emptyOptionCaption }, ...this.filterStore.options]; } get isEmpty(): boolean { diff --git a/packages/shared/widget-plugin-dropdown-filter/src/controllers/mixins/TagPickerControllerMixin.ts b/packages/shared/widget-plugin-dropdown-filter/src/controllers/mixins/TagPickerControllerMixin.ts index 5cb4342981..c644ead731 100644 --- a/packages/shared/widget-plugin-dropdown-filter/src/controllers/mixins/TagPickerControllerMixin.ts +++ b/packages/shared/widget-plugin-dropdown-filter/src/controllers/mixins/TagPickerControllerMixin.ts @@ -19,6 +19,9 @@ type BaseController = GConstructor<{ filterStore: FilterStore; multiselect: boolean; setup(): () => void; + inputPlaceholder: string; + emptyCaption: string; + ariaLabel: string; }>; // eslint-disable-next-line @typescript-eslint/explicit-function-return-type @@ -26,9 +29,6 @@ export function TagPickerControllerMixin(Base: TBa return class TagPickerControllerMixin extends Base { touched = false; inputValue = ""; - inputPlaceholder = ""; - emptyCaption = ""; - ariaLabel = ""; filterSelectedOptions = false; constructor(...args: any[]) {