From c4275f3e46deb9dda4eafe1205ee5bc3bce2434e Mon Sep 17 00:00:00 2001 From: Yordan Date: Wed, 5 Nov 2025 16:19:45 +0100 Subject: [PATCH 1/4] chore: update changelog --- .../datagrid-web/CHANGELOG.md | 3 + .../datagrid-web/src/Datagrid.editorConfig.ts | 4 ++ .../datagrid-web/src/Datagrid.xml | 65 +++++++++++++++++++ .../datagrid-web/typings/DatagridProps.d.ts | 2 + .../src/selection/helpers.ts | 25 ++++++- 5 files changed, 98 insertions(+), 1 deletion(-) diff --git a/packages/pluggableWidgets/datagrid-web/CHANGELOG.md b/packages/pluggableWidgets/datagrid-web/CHANGELOG.md index 1f7339aa51..fec24dfbba 100644 --- a/packages/pluggableWidgets/datagrid-web/CHANGELOG.md +++ b/packages/pluggableWidgets/datagrid-web/CHANGELOG.md @@ -15,6 +15,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added - We added configurable selection count visibility and clear selection button label template for improved row selection management. +- We added the possiblity to configure the first row of a DataGrid to be auto-selected on first load, facilitating master-detail views. + +### Fixed ### Fixed diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts index b58eaf95c2..d89c1b396a 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts @@ -142,6 +142,10 @@ function hideSelectionProperties(defaultProperties: Properties, values: Datagrid hidePropertyIn(defaultProperties, values, "itemSelectionMode"); } + if (itemSelection !== "Single") { + hidePropertyIn(defaultProperties, values, "selectFirstRow"); + } + if (itemSelection !== "Multi" || itemSelectionMethod !== "checkbox") { hidePropertyIn(defaultProperties, values, "showSelectAllToggle"); } diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml index 1366fbe612..39a9fd7f33 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml @@ -16,6 +16,71 @@ Refresh time (in seconds) + + Selection + + + + + + + + + Selection method + + + Checkbox + Row click + + + + Auto select first row + Automatically select the first row + + + Toggle on click + Defines item selection behavior. + + Yes + No + + + + Show (un)check all toggle + Show a checkbox in the grid header to check or uncheck multiple items. + + + Keep selection + If enabled, selected items will stay selected unless cleared by the user or a Nanoflow. + + + Show selection count + + + Top + Bottom + Off + + + + Clear selection label + Customize the label of the 'Clear section' button + + Clear selection + + + + Loading type + + + Spinner + Skeleton + + + + Show refresh indicator + Show a refresh indicator when the data is being loaded. + diff --git a/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts b/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts index 056c487def..eac12e62b9 100644 --- a/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts +++ b/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts @@ -108,6 +108,7 @@ export interface DatagridContainerProps { filtersPlaceholder?: ReactNode; itemSelection?: SelectionSingleValue | SelectionMultiValue; itemSelectionMethod: ItemSelectionMethodEnum; + selectFirstRow: boolean; itemSelectionMode: ItemSelectionModeEnum; showSelectAllToggle: boolean; enableSelectAll: boolean; @@ -167,6 +168,7 @@ export interface DatagridPreviewProps { filtersPlaceholder: { widgetCount: number; renderer: ComponentType<{ children: ReactNode; caption?: string }> }; itemSelection: "None" | "Single" | "Multi"; itemSelectionMethod: ItemSelectionMethodEnum; + selectFirstRow: boolean; itemSelectionMode: ItemSelectionModeEnum; showSelectAllToggle: boolean; enableSelectAll: boolean; diff --git a/packages/shared/widget-plugin-grid/src/selection/helpers.ts b/packages/shared/widget-plugin-grid/src/selection/helpers.ts index 507e1f7bda..720143eb82 100644 --- a/packages/shared/widget-plugin-grid/src/selection/helpers.ts +++ b/packages/shared/widget-plugin-grid/src/selection/helpers.ts @@ -346,10 +346,12 @@ export function useSelectionHelper( selection: SelectionSingleValue | SelectionMultiValue | undefined, dataSource: ListValue, onSelectionChange: ActionValue | undefined, - keepSelection: Parameters[0] + keepSelection: Parameters[0], + selectFirstRow?: boolean ): SelectionHelper | undefined { const prevObjectListRef = useRef([]); const firstLoadDone = useRef(false); + const hasAutoSelected = useRef(false); useState(() => { if (selection) { selection.setKeepSelection(selectionStateHandler(keepSelection)); @@ -357,6 +359,27 @@ export function useSelectionHelper( }); firstLoadDone.current ||= dataSource?.status !== "loading"; + useEffect(() => { + if ( + selectFirstRow && + dataSource.status === "available" && + dataSource.items && + dataSource.items.length > 0 && + selection && + selection.type === "Single" && + !selection.selection && + !hasAutoSelected.current + ) { + setTimeout(() => { + if (!selection.selection) { + const firstItem = dataSource.items![0]; + selection.setSelection(firstItem); + hasAutoSelected.current = true; + } + }, 100); + } + }, [dataSource.status, dataSource.items, selectFirstRow, selection]); + useEffect(() => { const prevObjectList = prevObjectListRef.current; const current = selection?.selection ?? []; From 08266b1d69cafe438c56ae2505c46f6f330386a3 Mon Sep 17 00:00:00 2001 From: Yordan Stoyanov Date: Fri, 28 Nov 2025 15:33:11 +0100 Subject: [PATCH 2/4] refactor: improve naming and autoselect logic, update config position --- .../datagrid-web/src/Datagrid.editorConfig.ts | 2 +- .../datagrid-web/src/Datagrid.xml | 11 +------- .../src/model/configs/Datagrid.config.ts | 2 ++ .../datagrid-web/src/utils/test-utils.tsx | 1 + .../datagrid-web/typings/DatagridProps.d.ts | 26 +++++++++++++++++-- .../src/selection/createSelectionHelper.ts | 12 +++++++-- 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts index d89c1b396a..1fde960cf6 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts @@ -143,7 +143,7 @@ function hideSelectionProperties(defaultProperties: Properties, values: Datagrid } if (itemSelection !== "Single") { - hidePropertyIn(defaultProperties, values, "selectFirstRow"); + hidePropertyIn(defaultProperties, values, "autoSelect"); } if (itemSelection !== "Multi" || itemSelectionMethod !== "checkbox") { diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml index 39a9fd7f33..2a45b76d59 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml @@ -33,7 +33,7 @@ Row click - + Auto select first row Automatically select the first row @@ -53,15 +53,6 @@ Keep selection If enabled, selected items will stay selected unless cleared by the user or a Nanoflow. - - Show selection count - - - Top - Bottom - Off - - Clear selection label Customize the label of the 'Clear section' button diff --git a/packages/pluggableWidgets/datagrid-web/src/model/configs/Datagrid.config.ts b/packages/pluggableWidgets/datagrid-web/src/model/configs/Datagrid.config.ts index 1ce8da4b69..9d858994d4 100644 --- a/packages/pluggableWidgets/datagrid-web/src/model/configs/Datagrid.config.ts +++ b/packages/pluggableWidgets/datagrid-web/src/model/configs/Datagrid.config.ts @@ -19,6 +19,7 @@ export interface DatagridConfig { settingsStorageEnabled: boolean; enableSelectAll: boolean; keepSelection: boolean; + autoSelect: boolean; pagingPosition: PagingPositionEnum; multiselectable: true | undefined; loadingType: LoadingTypeEnum; @@ -48,6 +49,7 @@ export function datagridConfig(props: DatagridContainerProps): DatagridConfig { settingsStorageEnabled: isSettingsStorageEnabled(props), enableSelectAll: props.enableSelectAll, keepSelection: props.keepSelection, + autoSelect: props.autoSelect, pagingPosition: props.pagingPosition, multiselectable: isMultiselectable(props), loadingType: props.loadingType, diff --git a/packages/pluggableWidgets/datagrid-web/src/utils/test-utils.tsx b/packages/pluggableWidgets/datagrid-web/src/utils/test-utils.tsx index e8bc5eb194..690a2084f6 100644 --- a/packages/pluggableWidgets/datagrid-web/src/utils/test-utils.tsx +++ b/packages/pluggableWidgets/datagrid-web/src/utils/test-utils.tsx @@ -64,6 +64,7 @@ export function mockContainerProps(overrides?: Partial): columnsResizable: true, columns: [column("Col1"), column("Col2")], itemSelectionMethod: "checkbox", + autoSelect: false, itemSelectionMode: "clear", enableSelectAll: false, keepSelection: false, diff --git a/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts b/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts index eac12e62b9..e7f420e1e3 100644 --- a/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts +++ b/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts @@ -7,6 +7,12 @@ import { ComponentType, CSSProperties, ReactNode } from "react"; import { ActionValue, DynamicValue, EditableValue, ListValue, ListActionValue, ListAttributeValue, ListAttributeListValue, ListExpressionValue, ListWidgetValue, SelectionSingleValue, SelectionMultiValue } from "mendix"; import { Big } from "big.js"; +export type ItemSelectionMethodEnum = "checkbox" | "rowClick"; + +export type ItemSelectionModeEnum = "toggle" | "clear"; + +export type LoadingTypeEnum = "spinner" | "skeleton"; + export type ShowContentAsEnum = "attribute" | "dynamicText" | "customContent"; export type ExportTypeEnum = "default" | "number" | "date" | "boolean"; @@ -100,6 +106,15 @@ export interface DatagridContainerProps { tabIndex?: number; datasource: ListValue; refreshInterval: number; + itemSelection?: SelectionSingleValue | SelectionMultiValue; + itemSelectionMethod: ItemSelectionMethodEnum; + autoSelect: boolean; + itemSelectionMode: ItemSelectionModeEnum; + showSelectAllToggle: boolean; + keepSelection: boolean; + clearSelectionButtonLabel?: DynamicValue; + loadingType: LoadingTypeEnum; + refreshIndicator: boolean; columns: ColumnsType[]; columnsFilterable: boolean; onClickTrigger: OnClickTriggerEnum; @@ -108,7 +123,6 @@ export interface DatagridContainerProps { filtersPlaceholder?: ReactNode; itemSelection?: SelectionSingleValue | SelectionMultiValue; itemSelectionMethod: ItemSelectionMethodEnum; - selectFirstRow: boolean; itemSelectionMode: ItemSelectionModeEnum; showSelectAllToggle: boolean; enableSelectAll: boolean; @@ -160,6 +174,15 @@ export interface DatagridPreviewProps { translate: (text: string) => string; datasource: {} | { caption: string } | { type: string } | null; refreshInterval: number | null; + itemSelection: "None" | "Single" | "Multi"; + itemSelectionMethod: ItemSelectionMethodEnum; + autoSelect: boolean; + itemSelectionMode: ItemSelectionModeEnum; + showSelectAllToggle: boolean; + keepSelection: boolean; + clearSelectionButtonLabel: string; + loadingType: LoadingTypeEnum; + refreshIndicator: boolean; columns: ColumnsPreviewType[]; columnsFilterable: boolean; onClickTrigger: OnClickTriggerEnum; @@ -168,7 +191,6 @@ export interface DatagridPreviewProps { filtersPlaceholder: { widgetCount: number; renderer: ComponentType<{ children: ReactNode; caption?: string }> }; itemSelection: "None" | "Single" | "Multi"; itemSelectionMethod: ItemSelectionMethodEnum; - selectFirstRow: boolean; itemSelectionMode: ItemSelectionModeEnum; showSelectAllToggle: boolean; enableSelectAll: boolean; diff --git a/packages/shared/widget-plugin-grid/src/selection/createSelectionHelper.ts b/packages/shared/widget-plugin-grid/src/selection/createSelectionHelper.ts index 3902487856..b88891cbb4 100644 --- a/packages/shared/widget-plugin-grid/src/selection/createSelectionHelper.ts +++ b/packages/shared/widget-plugin-grid/src/selection/createSelectionHelper.ts @@ -9,7 +9,7 @@ import { MultiSelectionHelper, SingleSelectionHelper } from "./helpers"; export function createSelectionHelper( host: SetupComponentHost, gate: DerivedPropsGate, - config: { keepSelection: boolean } = { keepSelection: false } + config: { keepSelection: boolean; autoSelect: boolean } = { keepSelection: false, autoSelect: false } ): SelectionHelperService { const { selection, datasource } = gate.props; @@ -58,7 +58,15 @@ export function createSelectionHelper( ); add(cleanup); } - + if (helper.type === "Single" && config.autoSelect) { + const dispose = autorun(() => { + const firstItem = gate.props.datasource.items?.[0]; + if (!firstItem) return; + helper.reduceTo(firstItem); + dispose(); + }); + add(dispose); + } return disposeAll; } From 597fd6b4d6d2baa89ac56c024102ae5c606f8892 Mon Sep 17 00:00:00 2001 From: Yordan Stoyanov Date: Mon, 1 Dec 2025 15:47:50 +0100 Subject: [PATCH 3/4] fix: update changelog formatting --- packages/pluggableWidgets/datagrid-web/CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/pluggableWidgets/datagrid-web/CHANGELOG.md b/packages/pluggableWidgets/datagrid-web/CHANGELOG.md index fec24dfbba..b383e557ec 100644 --- a/packages/pluggableWidgets/datagrid-web/CHANGELOG.md +++ b/packages/pluggableWidgets/datagrid-web/CHANGELOG.md @@ -15,9 +15,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added - We added configurable selection count visibility and clear selection button label template for improved row selection management. -- We added the possiblity to configure the first row of a DataGrid to be auto-selected on first load, facilitating master-detail views. -### Fixed +- We added the possiblity to configure the first row of a DataGrid to be auto-selected on first load, facilitating master-detail views. ### Fixed From a77208e3c00ca77f5b567b04ed17ee79ed1c007a Mon Sep 17 00:00:00 2001 From: Yordan Stoyanov Date: Tue, 2 Dec 2025 13:35:06 +0100 Subject: [PATCH 4/4] refactor: remove unused properties and logic from deprecated hook --- .../datagrid-web/src/Datagrid.xml | 52 ------------------- .../src/selection/helpers.ts | 26 +--------- 2 files changed, 2 insertions(+), 76 deletions(-) diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml index 2a45b76d59..8eed056b01 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml @@ -16,62 +16,10 @@ Refresh time (in seconds) - - Selection - - - - - - - - - Selection method - - - Checkbox - Row click - - Auto select first row Automatically select the first row - - Toggle on click - Defines item selection behavior. - - Yes - No - - - - Show (un)check all toggle - Show a checkbox in the grid header to check or uncheck multiple items. - - - Keep selection - If enabled, selected items will stay selected unless cleared by the user or a Nanoflow. - - - Clear selection label - Customize the label of the 'Clear section' button - - Clear selection - - - - Loading type - - - Spinner - Skeleton - - - - Show refresh indicator - Show a refresh indicator when the data is being loaded. - diff --git a/packages/shared/widget-plugin-grid/src/selection/helpers.ts b/packages/shared/widget-plugin-grid/src/selection/helpers.ts index 720143eb82..cb979c06da 100644 --- a/packages/shared/widget-plugin-grid/src/selection/helpers.ts +++ b/packages/shared/widget-plugin-grid/src/selection/helpers.ts @@ -346,12 +346,11 @@ export function useSelectionHelper( selection: SelectionSingleValue | SelectionMultiValue | undefined, dataSource: ListValue, onSelectionChange: ActionValue | undefined, - keepSelection: Parameters[0], - selectFirstRow?: boolean + keepSelection: Parameters[0] ): SelectionHelper | undefined { const prevObjectListRef = useRef([]); const firstLoadDone = useRef(false); - const hasAutoSelected = useRef(false); + useState(() => { if (selection) { selection.setKeepSelection(selectionStateHandler(keepSelection)); @@ -359,27 +358,6 @@ export function useSelectionHelper( }); firstLoadDone.current ||= dataSource?.status !== "loading"; - useEffect(() => { - if ( - selectFirstRow && - dataSource.status === "available" && - dataSource.items && - dataSource.items.length > 0 && - selection && - selection.type === "Single" && - !selection.selection && - !hasAutoSelected.current - ) { - setTimeout(() => { - if (!selection.selection) { - const firstItem = dataSource.items![0]; - selection.setSelection(firstItem); - hasAutoSelected.current = true; - } - }, 100); - } - }, [dataSource.status, dataSource.items, selectFirstRow, selection]); - useEffect(() => { const prevObjectList = prevObjectListRef.current; const current = selection?.selection ?? [];