diff --git a/packages/pluggableWidgets/datagrid-web/CHANGELOG.md b/packages/pluggableWidgets/datagrid-web/CHANGELOG.md index ce1b24708c..6a03a504de 100644 --- a/packages/pluggableWidgets/datagrid-web/CHANGELOG.md +++ b/packages/pluggableWidgets/datagrid-web/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Fixed - We fixed an issue where the top bar did not stack its content vertically in narrow containers. +- We fixed an issue where custom pagination ignored "Position of pagination" and always rendered below the grid. It now renders above the grid, below the grid, or — for "Both" — once, below the grid. ### Added diff --git a/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/.openspec.yaml b/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/.openspec.yaml new file mode 100644 index 0000000000..e8cda9e50e --- /dev/null +++ b/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-09-10 diff --git a/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/design.md b/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/design.md new file mode 100644 index 0000000000..8c8714186b --- /dev/null +++ b/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/design.md @@ -0,0 +1,50 @@ +## Context + +`pagingPosition` (`"top" | "bottom" | "both"`) already drives the built-in `Pagination` control: + +- `WidgetTopBar.tsx`: `` +- `WidgetFooter.tsx`: `` + +Custom pagination (the `customPagination` widgets placeholder, shown when `useCustomPagination` is true and `pagination === "buttons"`) is wired separately and ignores position: + +- `WidgetFooter.tsx`: `{customPagination.get()}` — always renders, no position check. +- `WidgetTopBar.tsx`: no custom pagination branch at all. +- `Datagrid.editorPreview.tsx`: `useCustomPagination()` returns `props.useCustomPagination` with no position check; only rendered in the footer's `CustomPagination`. +- `Datagrid.editorConfig.ts` currently hides `pagingPosition` from the properties panel whenever `useCustomPagination` is true (added when custom pagination shipped, as a stopgap since the property had no effect). Once position has an effect, hiding it is wrong. + +Gallery (`gallery-web`) had the exact same defect and fixed it under WC-3505 (`GalleryFooterControls.tsx`, `GalleryTopBarControls.tsx`), which was explicitly scoped to exclude Data Grid 2 to keep that PR reviewable. This change ports the same rule to Data Grid 2. Data Grid 2's bars have no alignment/slot-resolution machinery (`resolveSlots`) — that part of the Gallery change was about a _different_, already-working design property (pagination alignment) that Data Grid 2 doesn't have — so none of that machinery is needed here. + +## Goals / Non-Goals + +**Goals:** + +- Custom pagination widgets render in the top bar when `pagingPosition === "top"`, in the footer when `"bottom"`, and exactly once (footer) when `"both"`. +- Editor preview matches runtime for all three positions. +- `pagingPosition` stays visible/editable in Studio Pro when custom pagination is enabled. +- A `check()` warning fires for `useCustomPagination && pagingPosition === "both"`, mirroring Gallery's wording/severity. + +**Non-Goals:** + +- No pagination-alignment design property for Data Grid 2 (out of scope per WC-3505's own scoping note — Data Grid 2 doesn't have this property; adding one is a feature request, not this fix). +- No changes to `widget-plugin-grid` or `data-widgets` — the built-in `Pagination` component's own position logic is already correct and untouched. +- No changes to the unrelated `_datagrid.scss` top-bar container-query typo noted in the Gallery proposal as a separate, deliberately excluded fix. + +## Decisions + +- **Reuse the existing `pgConfig.pagingPosition` value already threaded into both bars** rather than introducing new state. `usePaginationConfig()` already exposes `pagingPosition` and `customPaginationEnabled`; both bars just need an additional condition. +- **"Both" resolves to footer-only, not top-bar-only or duplicated.** Same reasoning as Gallery: `customPagination.get()` returns the actual configured widgets placeholder — rendering it in two places would duplicate widget instances, DOM ids, and MobX-backed state. Footer is chosen (not top bar) purely for consistency with Gallery's precedent and because it's the current de facto behavior developers have already built pages against. +- **Condition shape mirrors Gallery exactly** for auditability: + - Footer: `pgConfig.customPaginationEnabled && pgConfig.pagingPosition !== "top"` + - Top bar: `pgConfig.customPaginationEnabled && pgConfig.pagingPosition === "top"` +- **Drop `pagingPosition` from the `hidePropertiesIn` call** in `Datagrid.editorConfig.ts` for the `useCustomPagination` branch; keep `showPagingButtons` hidden there since it only affects the built-in control's prev/next buttons, which custom pagination replaces entirely. +- **Warning lives in `consistency-check.ts`** (not inlined in `editorConfig.ts`) to match this package's existing convention — `editorConfig.ts` re-exports `check` from `consistency-check.ts`, and all other structural warnings/errors already live there. +- **No new capability abstraction (no `resolveSlots`-equivalent).** Data Grid 2's bars have exactly one pagination-bearing slot each (`pb-end` / `tb-end`); there's no counter/load-more displacement problem to solve, so a plain boolean condition is the right level of complexity — introducing a slot-resolution function here would be solving a problem this widget doesn't have. + +## Risks / Trade-offs + +- **[Risk]** Existing apps that already set `pagingPosition` to `"top"` or `"both"` while using custom pagination will see a visible layout change (widgets moving from footer to top bar, or a warning appearing) on upgrade. → **Mitigation**: this is the bug fix itself — the property was always meant to have this effect, per its own description in Studio Pro ("Position of pagination"). Documented in the changelog as a behavior fix, not flagged as breaking (no API/prop shape change). +- **[Risk]** Unhiding `pagingPosition` when custom pagination is on could surprise developers who never noticed the property while it was hidden. → **Mitigation**: matches Gallery's existing (never-hidden) behavior for the same property; the new `check()` warning immediately explains the "both" caveat if they hit it. + +## Migration Plan + +No data migration. Widget-level runtime/config-only change, shipped as a normal `datagrid-web` release. No rollback complexity beyond a standard revert. diff --git a/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/proposal.md b/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/proposal.md new file mode 100644 index 0000000000..a2adf458bb --- /dev/null +++ b/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/proposal.md @@ -0,0 +1,40 @@ +## Why + +Data Grid 2's "Position of pagination" property (`pagingPosition`: Above grid / Below grid / Both) already gates the built-in `Pagination` control in both `WidgetTopBar` and `WidgetFooter`. Custom pagination — the developer-supplied widgets placeholder shown when "Custom pagination" is enabled — ignores it completely: `WidgetFooter` renders the custom pagination widgets unconditionally whenever custom pagination is on, and `WidgetTopBar` never renders them at all. Setting "Above grid" has no effect; the widgets always render below the grid (WC-3548). + +Gallery had the identical bug and fixed it under WC-3505, which explicitly scoped Data Grid 2 out to keep that change reviewable ("DataGrid 2's custom-pagination position bug ... needs its own ticket"). This change is that ticket. Unlike Gallery, Data Grid 2's editor preview already agrees with its runtime (both footer-only today), so there is no preview/runtime divergence to fix here — only the ineffective property, plus a related Studio Pro editor-config quirk: when custom pagination is enabled, `pagingPosition` is currently hidden from the properties panel entirely (a pre-existing mitigation for the very bug this change fixes), so once the position has a real effect it must be shown again. + +## What Changes + +- **`WidgetTopBar` renders custom pagination widgets when `pagingPosition` is `"top"`.** Today it only ever renders the built-in `Pagination` component and never checks for custom pagination. +- **`WidgetFooter` renders custom pagination widgets only when `pagingPosition` is not `"top"`** (i.e. `"bottom"` or `"both"`), instead of unconditionally. +- **`"Both"` renders custom pagination once, in the footer**, not in both bars — duplicating the `customPagination` widgets placeholder would duplicate widget instances, DOM ids, and state, exactly as identified in the Gallery fix. +- **A design-time `check()` warning** is added for the `useCustomPagination && pagingPosition === "both"` combination, explaining that custom pagination renders once (below the grid) and suggesting the developer pick a single position. +- **`Datagrid.editorConfig.ts` stops hiding `pagingPosition`** when custom pagination is enabled — the property now has an effect, so it must stay visible and editable (mirrors Gallery, which never hid it in this case). `showPagingButtons` stays hidden for custom pagination since it only affects the built-in control. +- **`Datagrid.editorPreview.tsx`** picks up the same top/footer/both rule so preview continues to agree with runtime. + +## Capabilities + +### New Capabilities + +- `datagrid-custom-pagination-position`: where Data Grid 2's custom pagination widgets render relative to the grid, honouring `Position of pagination` ("Above grid" / "Below grid" / "Both"), including the single-render rule for "Both", the accompanying design-time warning, and parity between runtime and editor preview. + +### Modified Capabilities + +_None — `openspec/specs/` in this package currently documents no pagination-placement capability, so this is captured as a new capability rather than a delta._ + +## Impact + +`packages/pluggableWidgets/datagrid-web` + +- `src/components/WidgetFooter.tsx`, `src/components/WidgetTopBar.tsx` — gate custom pagination rendering on `pagingPosition`. +- `src/Datagrid.editorConfig.ts` — stop hiding `pagingPosition` for custom pagination; add the `"both"` + custom pagination warning (in `src/consistency-check.ts`, which `editorConfig.ts` re-exports `check` from). +- `src/Datagrid.editorPreview.tsx` — mirror the top/footer/both placement rule for the preview's `CustomPagination` placeholder. +- `src/components/__tests__/` — unit tests covering `pagingPosition` × custom pagination for both bars; `consistency-check` tests for the new warning. +- `CHANGELOG.md` — user-facing entry: custom pagination now respects "Position of pagination". + +Cross-cutting + +- No shared-package changes (`widget-plugin-grid` is untouched; Data Grid 2 has no pagination-alignment design property, unlike Gallery, so no `data-widgets` module changes are needed). +- No breaking changes: `pagingPosition` and `useCustomPagination` keep their existing keys and defaults; only the rendering behavior for an already-visible property changes. +- Release vehicle: `datagrid-web` patch/minor release; version bump and changelog entry added at release time per repo convention. diff --git a/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/specs/datagrid-custom-pagination-position/spec.md b/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/specs/datagrid-custom-pagination-position/spec.md new file mode 100644 index 0000000000..dd371d1e41 --- /dev/null +++ b/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/specs/datagrid-custom-pagination-position/spec.md @@ -0,0 +1,55 @@ +## ADDED Requirements + +### Requirement: Custom pagination honors the position setting + +When custom pagination is enabled, Data Grid 2 SHALL render the custom pagination widgets according to the `pagingPosition` property ("Above grid" / "Below grid" / "Both") instead of always rendering them in the footer. + +#### Scenario: Position set to "Above grid" + +- **WHEN** custom pagination is enabled and `pagingPosition` is `"top"` +- **THEN** the custom pagination widgets render in the top bar +- **AND** the custom pagination widgets do not render in the footer + +#### Scenario: Position set to "Below grid" + +- **WHEN** custom pagination is enabled and `pagingPosition` is `"bottom"` +- **THEN** the custom pagination widgets render in the footer +- **AND** the custom pagination widgets do not render in the top bar + +#### Scenario: Position set to "Both" + +- **WHEN** custom pagination is enabled and `pagingPosition` is `"both"` +- **THEN** the custom pagination widgets render exactly once, in the footer +- **AND** the custom pagination widgets do not also render in the top bar + +### Requirement: Editor preview matches runtime placement + +Studio Pro's editor preview for Data Grid 2 SHALL place the custom pagination placeholder using the same `pagingPosition` rule as the runtime, so the page editor never disagrees with the running app. + +#### Scenario: Preview reflects "Above grid" + +- **WHEN** custom pagination is enabled and `pagingPosition` is `"top"` in the page editor +- **THEN** the custom pagination placeholder renders above the grid preview + +#### Scenario: Preview reflects "Below grid" or "Both" + +- **WHEN** custom pagination is enabled and `pagingPosition` is `"bottom"` or `"both"` in the page editor +- **THEN** the custom pagination placeholder renders below the grid preview, exactly once + +### Requirement: Position property remains configurable with custom pagination + +The `pagingPosition` property SHALL remain visible and editable in the Studio Pro properties panel when custom pagination is enabled, since the property now affects rendering. + +#### Scenario: Custom pagination enabled + +- **WHEN** a developer enables custom pagination on a Data Grid 2 configured with `pagination` set to `"buttons"` +- **THEN** the "Position of pagination" property remains visible and editable in the properties panel + +### Requirement: Design-time warning for "Both" with custom pagination + +Data Grid 2's consistency check SHALL emit a warning when custom pagination is enabled and `pagingPosition` is `"both"`, explaining that the widgets render once, below the grid. + +#### Scenario: Custom pagination with "Both" position configured + +- **WHEN** a developer enables custom pagination and sets `pagingPosition` to `"both"` +- **THEN** Studio Pro shows a warning on the `pagingPosition` property explaining that custom pagination renders once, below the grid, and suggesting a single position instead diff --git a/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/tasks.md b/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/tasks.md new file mode 100644 index 0000000000..4b469f6589 --- /dev/null +++ b/packages/pluggableWidgets/datagrid-web/openspec/changes/pagination-position-not-honored/tasks.md @@ -0,0 +1,21 @@ +## 1. Runtime placement + +- [x] 1.1 `WidgetFooter.tsx`: gate the existing `` custom pagination block on `pgConfig.pagingPosition !== "top"`. +- [x] 1.2 `WidgetTopBar.tsx`: add a custom pagination branch that renders `customPagination.get()` when `pgConfig.customPaginationEnabled && pgConfig.pagingPosition === "top"` (needs `useCustomPagination` from `../model/hooks/injection-hooks`, not currently imported there). +- [x] 1.3 Unit tests for `WidgetFooter`/`WidgetTopBar` (or their existing test files) covering `pagingPosition` × `useCustomPagination` for `"top"`, `"bottom"`, `"both"`, and custom pagination disabled. + +## 2. Editor preview + +- [x] 2.1 `Datagrid.editorPreview.tsx`: add a `usePagingTopCustom`/equivalent check (or extend `usePagingTop`) so the top bar's preview renders `` when `useCustomPagination && pagingPosition === "top"`. +- [x] 2.2 `Datagrid.editorPreview.tsx`: change the footer's `useCustomPagination()` check so it excludes `pagingPosition === "top"` (footer renders custom pagination for `"bottom"` and `"both"` only). +- [x] 2.3 ~~Update/add preview snapshot or structure tests~~ — not feasible: `Datagrid.editorPreview.tsx` imports `mendix/preview/Selectable`, which has no jest moduleNameMapper stub anywhere in this repo (confirmed repo-wide: no `*-web` package unit-tests its `editorPreview.tsx`). Adding one would mean changing the shared `@mendix/pluggable-widgets-tools` jest preset, out of scope for this fix. Verified instead by code inspection (mirrors the already-tested `WidgetTopBar`/`WidgetFooter` runtime logic 1:1) plus manual Studio Pro QA. + +## 3. Studio Pro properties panel + +- [x] 3.1 `Datagrid.editorConfig.ts`: in the `useCustomPagination` branch (inside `pagination === "buttons"`), stop hiding `pagingPosition` — only hide `showPagingButtons`. +- [x] 3.2 Add a `checkCustomPaginationPosition` (or similarly named) check to `consistency-check.ts`: emit a `"warning"` on property `pagingPosition` when `values.useCustomPagination && values.pagingPosition === "both"`, wired into `check()` alongside the existing selection/column checks. +- [x] 3.3 Unit test for the new consistency-check warning (present for custom+both, absent for custom+top/bottom and for non-custom pagination). + +## 4. Docs + +- [x] 4.1 Add a `CHANGELOG.md` entry: custom pagination now respects "Position of pagination" (top/bottom/both, with "both" rendering once below the grid). diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts index 0db6fb4b60..f187c68fb4 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts @@ -80,7 +80,7 @@ export function getProperties(values: DatagridPreviewProps, defaultProperties: P if (values.useCustomPagination === false) { hidePropertyIn(defaultProperties, values, "customPagination"); } else { - hidePropertiesIn(defaultProperties, values, ["pagingPosition", "showPagingButtons"]); + hidePropertyIn(defaultProperties, values, "showPagingButtons"); } } else { hidePropertyIn(defaultProperties, values, "showPagingButtons"); diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx index 4a0a0a5743..5b01ef232a 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx @@ -105,7 +105,10 @@ function WidgetTopBar(): ReactElement {
{useTopCounter() ? : null}
-
{usePagingTop() ? : null}
+
+ {usePagingTop() ? : null} + {useCustomPaginationTop() ? : null} +
); @@ -139,7 +142,7 @@ function WidgetFooter(): ReactElement {
{usePagingBot() ? : null} - {useCustomPagination() ? : null} + {useCustomPaginationBottom() ? : null}
@@ -403,7 +406,12 @@ function usePagingBot(): boolean { return visible && props.pagingPosition !== "top"; } -function useCustomPagination(): boolean { +function useCustomPaginationTop(): boolean { + const props = useProps(); + return props.useCustomPagination && props.pagingPosition === "top"; +} + +function useCustomPaginationBottom(): boolean { const props = useProps(); - return props.useCustomPagination; + return props.useCustomPagination && props.pagingPosition !== "top"; } diff --git a/packages/pluggableWidgets/datagrid-web/src/__tests__/__snapshots__/consistency-check.spec.ts.snap b/packages/pluggableWidgets/datagrid-web/src/__tests__/__snapshots__/consistency-check.spec.ts.snap index 50e447d262..b3cee4a735 100644 --- a/packages/pluggableWidgets/datagrid-web/src/__tests__/__snapshots__/consistency-check.spec.ts.snap +++ b/packages/pluggableWidgets/datagrid-web/src/__tests__/__snapshots__/consistency-check.spec.ts.snap @@ -1,5 +1,15 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing +exports[`consistency check custom pagination position warns when custom pagination is enabled and position is both 1`] = ` +[ + { + "message": "Custom pagination cannot be shown in both positions and will render below the grid. Set "Position of pagination" to "Above grid" or "Below grid" to choose a single position.", + "property": "pagingPosition", + "severity": "warning", + }, +] +`; + exports[`consistency check returns error when row select method and action trigger overlap selection: multi by row click 1`] = ` [ { diff --git a/packages/pluggableWidgets/datagrid-web/src/__tests__/consistency-check.spec.ts b/packages/pluggableWidgets/datagrid-web/src/__tests__/consistency-check.spec.ts index ceb3eda982..08494475d0 100644 --- a/packages/pluggableWidgets/datagrid-web/src/__tests__/consistency-check.spec.ts +++ b/packages/pluggableWidgets/datagrid-web/src/__tests__/consistency-check.spec.ts @@ -75,4 +75,54 @@ describe("consistency check", () => { expect(check(props as unknown as DatagridPreviewProps)).toEqual([]); }); }); + + describe("custom pagination position", () => { + test("warns when custom pagination is enabled and position is both", () => { + const props = { + itemSelection: "None", + onClick: null, + columns: [], + useCustomPagination: true, + pagingPosition: "both" + }; + + expect(check(props as unknown as DatagridPreviewProps)).toMatchSnapshot(); + }); + + test("does not warn when custom pagination is enabled and position is top", () => { + const props = { + itemSelection: "None", + onClick: null, + columns: [], + useCustomPagination: true, + pagingPosition: "top" + }; + + expect(check(props as unknown as DatagridPreviewProps)).toEqual([]); + }); + + test("does not warn when custom pagination is enabled and position is bottom", () => { + const props = { + itemSelection: "None", + onClick: null, + columns: [], + useCustomPagination: true, + pagingPosition: "bottom" + }; + + expect(check(props as unknown as DatagridPreviewProps)).toEqual([]); + }); + + test("does not warn when position is both and custom pagination is disabled", () => { + const props = { + itemSelection: "None", + onClick: null, + columns: [], + useCustomPagination: false, + pagingPosition: "both" + }; + + expect(check(props as unknown as DatagridPreviewProps)).toEqual([]); + }); + }); }); diff --git a/packages/pluggableWidgets/datagrid-web/src/components/WidgetFooter.tsx b/packages/pluggableWidgets/datagrid-web/src/components/WidgetFooter.tsx index a58930e18a..a4c9d7b5de 100644 --- a/packages/pluggableWidgets/datagrid-web/src/components/WidgetFooter.tsx +++ b/packages/pluggableWidgets/datagrid-web/src/components/WidgetFooter.tsx @@ -46,7 +46,9 @@ export const WidgetFooter = observer(function WidgetFooter(): ReactElement | nul - {customPagination.get()} + + {customPagination.get()} + diff --git a/packages/pluggableWidgets/datagrid-web/src/components/WidgetTopBar.tsx b/packages/pluggableWidgets/datagrid-web/src/components/WidgetTopBar.tsx index 2ec45e8685..666c741ee6 100644 --- a/packages/pluggableWidgets/datagrid-web/src/components/WidgetTopBar.tsx +++ b/packages/pluggableWidgets/datagrid-web/src/components/WidgetTopBar.tsx @@ -4,11 +4,12 @@ import { If } from "@mendix/widget-plugin-component-kit/If"; import { Pagination } from "./Pagination"; import { useSelectionCounterViewModel } from "../features/selection-counter/injection-hooks"; import { SelectionCounter } from "../features/selection-counter/SelectionCounter"; -import { usePaginationConfig } from "../model/hooks/injection-hooks"; +import { useCustomPagination, usePaginationConfig } from "../model/hooks/injection-hooks"; export const WidgetTopBar = observer(function WidgetTopBar(): ReactElement { const pgConfig = usePaginationConfig(); const selectionCounter = useSelectionCounterViewModel(); + const customPagination = useCustomPagination(); return (
@@ -22,6 +23,9 @@ export const WidgetTopBar = observer(function WidgetTopBar(): ReactElement { + + {customPagination.get()} +
diff --git a/packages/pluggableWidgets/datagrid-web/src/components/__tests__/WidgetFooter.spec.tsx b/packages/pluggableWidgets/datagrid-web/src/components/__tests__/WidgetFooter.spec.tsx new file mode 100644 index 0000000000..868e613500 --- /dev/null +++ b/packages/pluggableWidgets/datagrid-web/src/components/__tests__/WidgetFooter.spec.tsx @@ -0,0 +1,41 @@ +import { render, screen } from "@testing-library/react"; +import { ContainerProvider } from "brandi-react"; +import { setupIntersectionObserverStub } from "@mendix/widget-plugin-test-utils"; +import { createDatagridContainer } from "../../model/containers/createDatagridContainer"; +import { mockContainerProps } from "../../utils/test-utils"; +import { PagingPositionEnum } from "../../../typings/DatagridProps"; +import { WidgetFooter } from "../WidgetFooter"; + +setupIntersectionObserverStub(); + +function renderFooter(pagingPosition: PagingPositionEnum): void { + const [container] = createDatagridContainer( + mockContainerProps({ + useCustomPagination: true, + customPagination:
Custom pagination widgets
, + pagingPosition + }) + ); + render( + + + + ); +} + +describe("WidgetFooter custom pagination", () => { + it("renders custom pagination when position is bottom", () => { + renderFooter("bottom"); + expect(screen.getByText("Custom pagination widgets")).toBeInTheDocument(); + }); + + it("renders custom pagination when position is both", () => { + renderFooter("both"); + expect(screen.getByText("Custom pagination widgets")).toBeInTheDocument(); + }); + + it("does not render custom pagination when position is top", () => { + renderFooter("top"); + expect(screen.queryByText("Custom pagination widgets")).not.toBeInTheDocument(); + }); +}); diff --git a/packages/pluggableWidgets/datagrid-web/src/components/__tests__/WidgetTopBar.spec.tsx b/packages/pluggableWidgets/datagrid-web/src/components/__tests__/WidgetTopBar.spec.tsx new file mode 100644 index 0000000000..214b43b3f7 --- /dev/null +++ b/packages/pluggableWidgets/datagrid-web/src/components/__tests__/WidgetTopBar.spec.tsx @@ -0,0 +1,41 @@ +import { render, screen } from "@testing-library/react"; +import { ContainerProvider } from "brandi-react"; +import { setupIntersectionObserverStub } from "@mendix/widget-plugin-test-utils"; +import { createDatagridContainer } from "../../model/containers/createDatagridContainer"; +import { mockContainerProps } from "../../utils/test-utils"; +import { PagingPositionEnum } from "../../../typings/DatagridProps"; +import { WidgetTopBar } from "../WidgetTopBar"; + +setupIntersectionObserverStub(); + +function renderTopBar(pagingPosition: PagingPositionEnum): void { + const [container] = createDatagridContainer( + mockContainerProps({ + useCustomPagination: true, + customPagination:
Custom pagination widgets
, + pagingPosition + }) + ); + render( + + + + ); +} + +describe("WidgetTopBar custom pagination", () => { + it("renders custom pagination when position is top", () => { + renderTopBar("top"); + expect(screen.getByText("Custom pagination widgets")).toBeInTheDocument(); + }); + + it("does not render custom pagination when position is bottom", () => { + renderTopBar("bottom"); + expect(screen.queryByText("Custom pagination widgets")).not.toBeInTheDocument(); + }); + + it("does not render custom pagination when position is both (renders once, in the footer)", () => { + renderTopBar("both"); + expect(screen.queryByText("Custom pagination widgets")).not.toBeInTheDocument(); + }); +}); diff --git a/packages/pluggableWidgets/datagrid-web/src/consistency-check.ts b/packages/pluggableWidgets/datagrid-web/src/consistency-check.ts index de02c76a80..2c4e7a965c 100644 --- a/packages/pluggableWidgets/datagrid-web/src/consistency-check.ts +++ b/packages/pluggableWidgets/datagrid-web/src/consistency-check.ts @@ -17,6 +17,11 @@ export function check(values: DatagridPreviewProps): Problem[] { errors.push(...checkSelectionSettings(values)); + const customPaginationPositionError = checkCustomPaginationPosition(values); + if (customPaginationPositionError) { + errors.push(customPaginationPositionError); + } + return errors; } @@ -67,6 +72,18 @@ const checkHidableSettings = ( } }; +const checkCustomPaginationPosition = (values: DatagridPreviewProps): Problem | undefined => { + if (values.useCustomPagination && values.pagingPosition === "both") { + return { + property: "pagingPosition", + severity: "warning", + message: + "Custom pagination cannot be shown in both positions and will render below the grid. " + + 'Set "Position of pagination" to "Above grid" or "Below grid" to choose a single position.' + }; + } +}; + const checkSelectionSettings = (values: DatagridPreviewProps): Problem[] => { const errors: Problem[] = [];