-
Notifications
You must be signed in to change notification settings - Fork 667
T1312423 - CardView – Missing translation for Filter Panel title and related texts #32491
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 26_1
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adjusts several grid/CardView-related option defaults so that localized strings are resolved at usage time (via messageLocalization.format(...)) rather than being precomputed in defaultOptions, and adds a comprehensive Jest localization test suite + supporting page-object models to prevent regressions.
Changes:
- Replace many localized string defaults in option objects with
undefinedand add runtime localization fallbacks in views/controllers. - Add CardView localization Jest tests covering column chooser, filter panel, filter builder operations, pager aria-label, sorting context menu, boolean display text, no-data text, header filter texts, search placeholder, and editing texts.
- Add/extend test page-object models (Popup, Pager, HeaderPanel, CardView, etc.) to support the new localization tests.
Reviewed changes
Copilot reviewed 40 out of 40 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/devextreme/js/__internal/ui/tests/mock/model/tree_view.ts | Exposes getNodeByText for tests. |
| packages/devextreme/js/__internal/ui/tests/mock/model/textbox.ts | Adds input accessor for placeholder assertions. |
| packages/devextreme/js/__internal/ui/tests/mock/model/popup.ts | New popup POM used by multiple test models. |
| packages/devextreme/js/__internal/pagination/content.tsx | Adds localized fallback for navigation aria-label. |
| packages/devextreme/js/__internal/pagination/common/base_pagination_props.ts | Removes eager localization from default props (label: undefined). |
| packages/devextreme/js/__internal/pagination/tests/mock/model/pager.ts | New Pager POM for aria-label tests. |
| packages/devextreme/js/__internal/grids/new/grid_core/sorting_controller/options.ts | Removes eager localization from sorting option defaults. |
| packages/devextreme/js/__internal/grids/new/grid_core/search/view.tsx | Adds localized fallback for search placeholder in the view. |
| packages/devextreme/js/__internal/grids/new/grid_core/search/options.ts | Removes eager localization from search placeholder default. |
| packages/devextreme/js/__internal/grids/new/grid_core/pager/options.ts | Removes eager localization from pager aria label default. |
| packages/devextreme/js/__internal/grids/new/grid_core/filtering/header_filter/options.ts | Removes eager localization from header filter texts defaults. |
| packages/devextreme/js/__internal/grids/new/grid_core/filtering/header_filter/legacy_header_filter.ts | Adds localized fallback for header filter empty value text. |
| packages/devextreme/js/__internal/grids/new/grid_core/filtering/filter_panel/options.ts | Removes eager localization from filter panel / filter builder text defaults. |
| packages/devextreme/js/__internal/grids/new/grid_core/editing/popup/view.ts | Adds localized fallbacks for editing popup texts. |
| packages/devextreme/js/__internal/grids/new/grid_core/editing/options.ts | Removes eager localization from editing text defaults. |
| packages/devextreme/js/__internal/grids/new/grid_core/editing/controller.ts | Adds localized fallback for confirm delete message; adjusts awaits. |
| packages/devextreme/js/__internal/grids/new/grid_core/content_view/view.tsx | Adds localized fallback for no-data text rendering. |
| packages/devextreme/js/__internal/grids/new/grid_core/content_view/options.ts | Removes eager localization from no-data text default. |
| packages/devextreme/js/__internal/grids/new/grid_core/columns_controller/options.ts | Removes eager localization for boolean true/false texts and adds runtime fallback. |
| packages/devextreme/js/__internal/grids/new/grid_core/column_chooser/view.tsx | Adds localized fallback for empty panel text; simplifies popup toolbar usage. |
| packages/devextreme/js/__internal/grids/new/grid_core/column_chooser/column_chooser.tsx | Ensures toolbar title has a localized fallback at render time. |
| packages/devextreme/js/__internal/grids/new/card_view/context_menu/controller.ts | Adds localized fallbacks for sorting context menu item texts. |
| packages/devextreme/js/__internal/grids/new/card_view/tests/cardview.localization.test.ts | New end-to-end localization coverage for CardView behaviors. |
| packages/devextreme/js/__internal/grids/new/card_view/tests/mock/model/header_panel.ts | New HeaderPanel POM for context-menu / header filter tests. |
| packages/devextreme/js/__internal/grids/new/card_view/tests/mock/model/header_item.ts | New HeaderItem POM for header interactions. |
| packages/devextreme/js/__internal/grids/new/card_view/tests/mock/model/card_view.ts | New CardView POM integrating common grid-core POMs. |
| packages/devextreme/js/__internal/grids/new/card_view/tests/mock/model/card.ts | New Card POM for boolean localization assertions. |
| packages/devextreme/js/__internal/grids/new/card_view/tests/mock/helpers/utils.ts | New CardView test harness (setup/teardown/flush helpers). |
| packages/devextreme/js/__internal/grids/grid_core/header_filter/m_header_filter_core.ts | Adds localized fallbacks for OK/Cancel button texts. |
| packages/devextreme/js/__internal/grids/grid_core/filter/m_filter_panel.ts | Adds localized fallbacks for filter panel texts and makes defaults undefined. |
| packages/devextreme/js/__internal/grids/grid_core/column_chooser/const.ts | Changes column chooser defaults to undefined. |
| packages/devextreme/js/__internal/grids/grid_core/tests/mock/model/header_filter.ts | New HeaderFilter POM built atop Popup POM. |
| packages/devextreme/js/__internal/grids/grid_core/tests/mock/model/grid_core.ts | Enhances shared grid-core POM and adds CardView compatibility/helpers. |
| packages/devextreme/js/__internal/grids/grid_core/tests/mock/model/filter_panel.ts | New FilterPanel POM (supports different widget prefixes). |
| packages/devextreme/js/__internal/grids/grid_core/tests/mock/model/edit_form.ts | Extends edit-form POM with popup toolbar accessors. |
| packages/devextreme/js/__internal/grids/grid_core/tests/mock/model/data_grid_base.ts | New base POM restoring DataGrid-only APIs removed from GridCoreModel. |
| packages/devextreme/js/__internal/grids/grid_core/tests/mock/model/confirmation_dialog.ts | New ConfirmationDialog POM for delete-confirmation localization. |
| packages/devextreme/js/__internal/grids/grid_core/tests/mock/model/column_chooser.ts | Refactors ColumnChooser POM to reuse PopupModel and support multiple widgets. |
| packages/devextreme/js/__internal/grids/data_grid/tests/mock/model/data_grid.ts | Switches DataGrid POM to extend the new DataGridBaseModel. |
| packages/devextreme/js/__internal/filter_builder/tests/mock/model/filter_builder.ts | New FilterBuilder POM for verifying localized operations. |
packages/devextreme/js/__internal/ui/__tests__/__mock__/model/textbox.ts
Show resolved
Hide resolved
packages/devextreme/js/__internal/grids/new/grid_core/editing/controller.ts
Show resolved
Hide resolved
packages/devextreme/js/__internal/grids/new/grid_core/column_chooser/column_chooser.tsx
Show resolved
Hide resolved
packages/devextreme/js/__internal/grids/grid_core/column_chooser/const.ts
Outdated
Show resolved
Hide resolved
packages/devextreme/js/__internal/grids/new/grid_core/editing/controller.ts
Show resolved
Hide resolved
packages/devextreme/js/__internal/grids/new/grid_core/column_chooser/view.tsx
Show resolved
Hide resolved
packages/devextreme/js/__internal/grids/grid_core/filter/m_filter_panel.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 41 out of 41 changed files in this pull request and generated 8 comments.
| @@ -1,7 +1,8 @@ | |||
| import messageLocalization from '@js/common/core/localization/message'; | |||
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
messageLocalization is imported from @js/common/core/localization/message, which is marked as deprecated (see packages/devextreme/js/common/core/localization/message.js). In the new grid core code most files use @js/localization/message; consider switching to that import here to avoid relying on the deprecated alias and to keep localization imports consistent.
| import messageLocalization from '@js/common/core/localization/message'; | |
| import messageLocalization from '@js/localization/message'; |
| private readonly dragAndDropModeConfig: ReadonlySignal<TreeViewProperties> = computed(() => ({ | ||
| noDataText: this.options.oneWay('columnChooser.emptyPanelText').value, | ||
| noDataText: this.options.oneWay('columnChooser.emptyPanelText').value | ||
| || messageLocalization.format('dxDataGrid-columnChooserEmptyText'), |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
noDataText falls back using ||, which treats an empty string as “unset”. If a consumer intentionally sets columnChooser.emptyPanelText to '' (or another falsy value) it will be replaced by the default localized text. Using nullish coalescing (??) would preserve explicit empty-string values while still providing a fallback for null/undefined.
| || messageLocalization.format('dxDataGrid-columnChooserEmptyText'), | |
| ?? messageLocalization.format('dxDataGrid-columnChooserEmptyText'), |
| const removingArgs = { | ||
| cancel: false, | ||
| data, | ||
| key: change.key, | ||
| }; | ||
|
|
||
| this.onCardRemoving.peek()(removingArgs); | ||
|
|
||
| // eslint-disable-next-line no-await-in-loop, @typescript-eslint/await-thenable | ||
| // eslint-disable-next-line no-await-in-loop | ||
| if (await removingArgs.cancel) { | ||
| break; | ||
| } |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removingArgs.cancel is initialized as a boolean and then awaited. With the @typescript-eslint/await-thenable suppression removed, this is likely to trigger a lint error. Consider typing cancel as boolean | PromiseLike<boolean> for these event args (or avoid awaiting a non-thenable).
| const insertingArgs = { | ||
| cancel: false, | ||
| data: change.data, | ||
| }; | ||
|
|
||
| this.onCardInserting.peek()(insertingArgs); | ||
|
|
||
| // eslint-disable-next-line no-await-in-loop, @typescript-eslint/await-thenable | ||
| // eslint-disable-next-line no-await-in-loop | ||
| if (await insertingArgs.cancel) { | ||
| break; | ||
| } |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
insertingArgs.cancel is initialized as a boolean and then awaited. With the @typescript-eslint/await-thenable suppression removed, this is likely to fail linting. Consider aligning the event arg typing with the intended behavior (e.g. boolean | PromiseLike<boolean>) or avoid awaiting here.
| export class ColumnChooserModel extends PopupModel { | ||
| private readonly columnChooserListClass: string; | ||
|
|
||
| export class ColumnChooserModel { | ||
| constructor(protected readonly root: HTMLElement) {} | ||
|
|
||
| private getPopupWrapper(): HTMLElement | null { | ||
| return document.body.querySelector(`.${CLASSES.popupWrapper}.${CLASSES.columnChooser}`); | ||
| } | ||
|
|
||
| private getOverlay(): HTMLElement | null { | ||
| const wrapper = this.getPopupWrapper(); | ||
| return wrapper?.querySelector('.dx-overlay-content') ?? null; | ||
| constructor(widgetName: string) { | ||
| super(); | ||
| this.columnChooserListClass = `dx-${widgetName}-column-chooser-list`; | ||
| } | ||
|
|
||
| private getTreeView(): TreeViewModel | null { | ||
| const overlay = this.getOverlay(); | ||
| const overlay = this.getOverlayContent(); | ||
| if (!overlay) return null; | ||
|
|
||
| const treeViewElement = overlay.querySelector(`.${CLASSES.columnChooserList}`) as HTMLElement; | ||
| const treeViewElement = overlay.querySelector(`.${this.columnChooserListClass}`) as HTMLElement; | ||
| return treeViewElement ? new TreeViewModel(treeViewElement) : null; | ||
| } |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ColumnChooserModel now relies on PopupModel’s generic .dx-popup-wrapper lookup, so it may attach to the wrong popup when multiple overlays are present. Previously the model targeted the column chooser popup specifically. Consider overriding getPopupWrapper() (or passing a specific selector/class into PopupModel) to scope this model to the column chooser popup wrapper (e.g. the wrapper class added by the widget).
| const eventArgs = { | ||
| promise: undefined, | ||
| data: {}, | ||
| }; | ||
|
|
||
| this.onInitNewCard.peek()(eventArgs); | ||
|
|
||
| // eslint-disable-next-line @typescript-eslint/await-thenable | ||
| await eventArgs.promise; | ||
|
|
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eventArgs.promise is initialized as undefined, so await eventArgs.promise will be flagged by @typescript-eslint/await-thenable (the rule that was previously suppressed here). If this is meant to support async onInitNewCard, consider typing promise as PromiseLike<void> | undefined and only awaiting when it’s set (or wrapping with await Promise.resolve(...)) so lint/type checking stays clean.
| const eventArgs = { | ||
| promise: undefined, | ||
| cancel: false, | ||
| changes, | ||
| }; | ||
|
|
||
| this.onSaving.peek()(eventArgs); | ||
|
|
||
| // eslint-disable-next-line @typescript-eslint/await-thenable | ||
| await eventArgs.promise; | ||
|
|
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same issue as in addCard(): eventArgs.promise is initialized as undefined, and await eventArgs.promise is likely to violate @typescript-eslint/await-thenable now that the suppression was removed. Consider making promise a properly typed optional thenable and guarding before awaiting (or otherwise ensuring the awaited expression is always a Promise).
| const updatingArgs = { | ||
| oldData: this.itemsController.getCardByKey(change.key)!.data, | ||
| newData: change.data, | ||
| cancel: false, | ||
| key: change.key, | ||
| }; | ||
|
|
||
| this.onCardUpdating.peek()(updatingArgs); | ||
|
|
||
| // eslint-disable-next-line no-await-in-loop, @typescript-eslint/await-thenable | ||
| // eslint-disable-next-line no-await-in-loop | ||
| if (await updatingArgs.cancel) { | ||
| break; | ||
| } |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updatingArgs.cancel is initialized as a boolean, but then awaited. Without the previously present @typescript-eslint/await-thenable suppression this is likely to fail linting. If event handlers can set cancel to a Promise, consider explicitly typing cancel as boolean | PromiseLike<boolean> (and updating the event arg type) so await is valid without suppressions.
No description provided.