Skip to content

Commit fc4126f

Browse files
committed
feat(gallery-web): add new pagination settings
1 parent d036145 commit fc4126f

File tree

9 files changed

+80
-49
lines changed

9 files changed

+80
-49
lines changed

packages/pluggableWidgets/gallery-web/src/Gallery.editorConfig.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ import {
1010
import { GalleryPreviewProps } from "../typings/GalleryProps";
1111

1212
export function getProperties(values: GalleryPreviewProps, defaultProperties: Properties): Properties {
13-
if (values.pagination !== "buttons") {
14-
hidePropertyIn(defaultProperties, values, "pagingPosition");
15-
}
16-
1713
if (values.showEmptyPlaceholder === "none") {
1814
hidePropertyIn(defaultProperties, values, "emptyPlaceholder");
1915
}
@@ -22,8 +18,21 @@ export function getProperties(values: GalleryPreviewProps, defaultProperties: Pr
2218
hidePropertiesIn(defaultProperties, values, ["onSelectionChange", "itemSelectionMode"]);
2319
}
2420

25-
// Hide scrolling settings for now.
26-
hidePropertiesIn(defaultProperties, values, ["showPagingButtons", "showTotalCount"]);
21+
/** Pagination */
22+
23+
if (values.pagination === "buttons") {
24+
hidePropertyIn(defaultProperties, values, "showTotalCount");
25+
} else {
26+
hidePropertyIn(defaultProperties, values, "showPagingButtons");
27+
28+
if (values.showTotalCount === false) {
29+
hidePropertyIn(defaultProperties, values, "pagingPosition");
30+
}
31+
}
32+
33+
if (values.pagination !== "loadMore") {
34+
hidePropertyIn(defaultProperties, values, "loadMoreButtonCaption");
35+
}
2736

2837
return defaultProperties;
2938
}

packages/pluggableWidgets/gallery-web/src/Gallery.editorPreview.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ function Preview(props: GalleryPreviewProps): ReactElement {
9595
pageSize={props.pageSize ?? numberOfItems}
9696
paging={props.pagination === "buttons"}
9797
paginationPosition={props.pagingPosition}
98+
paginationType={props.pagination}
99+
showPagingButtons={props.showPagingButtons}
98100
showEmptyStatePreview={props.showEmptyPlaceholder === "custom"}
99101
phoneItems={props.phoneItems!}
100102
tabletItems={props.tabletItems!}

packages/pluggableWidgets/gallery-web/src/Gallery.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
1-
import { observer } from "mobx-react-lite";
21
import { useOnResetFiltersEvent } from "@mendix/widget-plugin-external-events/hooks";
32
import { useClickActionHelper } from "@mendix/widget-plugin-grid/helpers/ClickActionHelper";
43
import { useFocusTargetController } from "@mendix/widget-plugin-grid/keyboard-navigation/useFocusTargetController";
54
import { getColumnAndRowBasedOnIndex, useSelectionHelper } from "@mendix/widget-plugin-grid/selection";
5+
import { useConst } from "@mendix/widget-plugin-mobx-kit/react/useConst";
6+
import { observer } from "mobx-react-lite";
67
import { ReactElement, ReactNode, createElement, useCallback } from "react";
78
import { GalleryContainerProps } from "../typings/GalleryProps";
89
import { Gallery as GalleryComponent } from "./components/Gallery";
10+
import { HeaderWidgetsHost } from "./components/HeaderWidgetsHost";
911
import { useItemEventsController } from "./features/item-interaction/ItemEventsController";
1012
import { GridPositionsProps, useGridPositions } from "./features/useGridPositions";
1113
import { useItemHelper } from "./helpers/ItemHelper";
12-
import { useItemSelectHelper } from "./helpers/useItemSelectHelper";
14+
import { GalleryContext, GalleryRootScope, useGalleryRootScope } from "./helpers/root-context";
1315
import { useGalleryStore } from "./helpers/useGalleryStore";
14-
import { useConst } from "@mendix/widget-plugin-mobx-kit/react/useConst";
15-
import { GalleryRootScope, GalleryContext, useGalleryRootScope } from "./helpers/root-context";
16-
import { HeaderWidgetsHost } from "./components/HeaderWidgetsHost";
16+
import { useItemSelectHelper } from "./helpers/useItemSelectHelper";
1717

1818
const Container = observer(function GalleryContainer(props: GalleryContainerProps): ReactElement {
1919
const { rootStore, itemSelectHelper } = useGalleryRootScope();
20+
2021
const items = props.datasource.items ?? [];
2122
const config: GridPositionsProps = {
2223
desktopItems: props.desktopItems,
@@ -76,10 +77,12 @@ const Container = observer(function GalleryContainer(props: GalleryContainerProp
7677
numberOfItems={props.datasource.totalCount}
7778
page={rootStore.paging.currentPage}
7879
pageSize={props.pageSize}
79-
paging={props.pagination === "buttons"}
80+
paging={rootStore.paging.showPagination}
8081
paginationPosition={props.pagingPosition}
81-
phoneItems={props.phoneItems}
82+
paginationType={props.pagination}
8283
setPage={rootStore.paging.setPage}
84+
showPagingButtons={props.showPagingButtons}
85+
phoneItems={props.phoneItems}
8386
style={props.style}
8487
tabletItems={props.tabletItems}
8588
tabIndex={props.tabIndex}

packages/pluggableWidgets/gallery-web/src/Gallery.xml

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
<description />
5353
</property>
5454
</propertyGroup>
55-
<propertyGroup caption="Items">
55+
<propertyGroup caption="Pagination">
5656
<property key="pageSize" type="integer" defaultValue="20">
5757
<caption>Page size</caption>
5858
<description />
@@ -63,15 +63,12 @@
6363
<enumerationValues>
6464
<enumerationValue key="buttons">Paging buttons</enumerationValue>
6565
<enumerationValue key="virtualScrolling">Virtual scrolling</enumerationValue>
66+
<enumerationValue key="loadMore">Load more</enumerationValue>
6667
</enumerationValues>
6768
</property>
68-
<property key="pagingPosition" type="enumeration" defaultValue="below">
69-
<caption>Position of paging buttons</caption>
69+
<property key="showTotalCount" type="boolean" defaultValue="false">
70+
<caption>Show total count</caption>
7071
<description />
71-
<enumerationValues>
72-
<enumerationValue key="below">Below grid</enumerationValue>
73-
<enumerationValue key="above">Above grid</enumerationValue>
74-
</enumerationValues>
7572
</property>
7673
<property key="showPagingButtons" type="enumeration" defaultValue="always">
7774
<caption>Show paging buttons</caption>
@@ -81,10 +78,24 @@
8178
<enumerationValue key="auto">Auto</enumerationValue>
8279
</enumerationValues>
8380
</property>
84-
<property key="showTotalCount" type="boolean" defaultValue="false">
85-
<caption>Show total count</caption>
81+
<property key="pagingPosition" type="enumeration" defaultValue="bottom">
82+
<caption>Position of pagination</caption>
8683
<description />
84+
<enumerationValues>
85+
<enumerationValue key="bottom">Below grid</enumerationValue>
86+
<enumerationValue key="top">Above grid</enumerationValue>
87+
<enumerationValue key="both">Both</enumerationValue>
88+
</enumerationValues>
89+
</property>
90+
<property key="loadMoreButtonCaption" type="textTemplate" required="false">
91+
<caption>Load more caption</caption>
92+
<description />
93+
<translations>
94+
<translation lang="en_US">Load More</translation>
95+
</translations>
8796
</property>
97+
</propertyGroup>
98+
<propertyGroup caption="Items">
8899
<property key="showEmptyPlaceholder" type="enumeration" defaultValue="none">
89100
<caption>Empty message</caption>
90101
<description />

packages/pluggableWidgets/gallery-web/src/components/Gallery.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ import { PositionInGrid, SelectActionHandler } from "@mendix/widget-plugin-grid/
55
import { ObjectItem } from "mendix";
66
import { createElement, ReactElement, ReactNode } from "react";
77
import { GalleryItemHelper } from "../typings/GalleryItem";
8-
import { ListBox } from "./ListBox";
9-
import { ListItem } from "./ListItem";
108
import { GalleryContent } from "./GalleryContent";
119
import { GalleryFooter } from "./GalleryFooter";
1210
import { GalleryHeader } from "./GalleryHeader";
1311
import { GalleryRoot } from "./GalleryRoot";
1412
import { GalleryTopBar } from "./GalleryTopBar";
13+
import { ListBox } from "./ListBox";
14+
import { ListItem } from "./ListItem";
1515

16+
import { PaginationEnum, ShowPagingButtonsEnum } from "typings/GalleryProps";
1617
import { ItemEventsController } from "../typings/ItemEventsController";
1718

1819
export interface GalleryProps<T extends ObjectItem> {
@@ -29,7 +30,9 @@ export interface GalleryProps<T extends ObjectItem> {
2930
paging: boolean;
3031
page: number;
3132
pageSize: number;
32-
paginationPosition?: "below" | "above";
33+
paginationPosition?: "top" | "bottom" | "both";
34+
paginationType: PaginationEnum;
35+
showPagingButtons: ShowPagingButtonsEnum;
3336
showEmptyStatePreview?: boolean;
3437
phoneItems: number;
3538
setPage?: (computePage: (prevPage: number) => number) => void;
@@ -60,13 +63,14 @@ export function Gallery<T extends ObjectItem>(props: GalleryProps<T>): ReactElem
6063
page={props.page}
6164
pageSize={props.pageSize}
6265
previousPage={() => props.setPage && props.setPage(prev => prev - 1)}
63-
pagination={props.paging ? "buttons" : "virtualScrolling"}
66+
pagination={props.paginationType}
67+
showPagingButtons={props.showPagingButtons}
6468
/>
6569
</div>
6670
) : null;
6771

68-
const showTopBar = props.paging && props.paginationPosition === "above";
69-
const showFooter = props.paging && props.paginationPosition === "below";
72+
const showTopBar = props.paging && (props.paginationPosition === "top" || props.paginationPosition === "both");
73+
const showFooter = props.paging && (props.paginationPosition === "bottom" || props.paginationPosition === "both");
7074

7175
return (
7276
<GalleryRoot

packages/pluggableWidgets/gallery-web/src/components/__tests__/Gallery.spec.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import "@testing-library/jest-dom";
21
import { listAction, listExp, setupIntersectionObserverStub } from "@mendix/widget-plugin-test-utils";
3-
import { waitFor, render } from "@testing-library/react";
2+
import "@testing-library/jest-dom";
3+
import { render, waitFor } from "@testing-library/react";
4+
import { ObjectItem } from "mendix";
45
import { createElement } from "react";
5-
import { Gallery } from "../Gallery";
66
import { ItemHelperBuilder } from "../../utils/builders/ItemHelperBuilder";
7-
import { mockProps, mockItemHelperWithAction, setup } from "../../utils/test-utils";
8-
import { ObjectItem } from "mendix";
7+
import { mockItemHelperWithAction, mockProps, setup } from "../../utils/test-utils";
8+
import { Gallery } from "../Gallery";
99

1010
describe("Gallery", () => {
1111
beforeAll(() => {
@@ -96,7 +96,7 @@ describe("Gallery", () => {
9696
describe("with pagination", () => {
9797
it("renders correctly", () => {
9898
const { asFragment } = render(
99-
<Gallery {...mockProps()} paging paginationPosition="above" numberOfItems={20} hasMoreItems />
99+
<Gallery {...mockProps()} paging paginationPosition="top" numberOfItems={20} hasMoreItems />
100100
);
101101

102102
expect(asFragment()).toMatchSnapshot();
@@ -108,7 +108,7 @@ describe("Gallery", () => {
108108
<Gallery
109109
{...mockProps()}
110110
paging
111-
paginationPosition="above"
111+
paginationPosition="top"
112112
numberOfItems={20}
113113
hasMoreItems
114114
setPage={setPage}

packages/pluggableWidgets/gallery-web/src/helpers/useGalleryStore.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ import { GalleryPropsGate, GalleryStore } from "../stores/GalleryStore";
77

88
export function useGalleryStore(props: GalleryContainerProps): GalleryStore {
99
const gate = useGate(props);
10-
const store = useSetup(
11-
() => new GalleryStore({ gate, ...props, showPagingButtons: "auto", showTotalCount: false })
12-
);
10+
const store = useSetup(() => new GalleryStore({ gate, ...props }));
1311
return store;
1412
}
1513

packages/pluggableWidgets/gallery-web/src/utils/test-utils.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
import { createElement } from "react";
21
import { ClickActionHelper } from "@mendix/widget-plugin-grid/helpers/ClickActionHelper";
32
import { FocusTargetController } from "@mendix/widget-plugin-grid/keyboard-navigation/FocusTargetController";
4-
import { SelectActionHandler, getColumnAndRowBasedOnIndex } from "@mendix/widget-plugin-grid/selection";
3+
import { PositionController } from "@mendix/widget-plugin-grid/keyboard-navigation/PositionController";
4+
import { VirtualGridLayout } from "@mendix/widget-plugin-grid/keyboard-navigation/VirtualGridLayout";
5+
import { getColumnAndRowBasedOnIndex, SelectActionHandler } from "@mendix/widget-plugin-grid/selection";
56
import { listAction, objectItems } from "@mendix/widget-plugin-test-utils";
67
import { render, RenderResult } from "@testing-library/react";
78
import userEvent, { UserEvent } from "@testing-library/user-event";
89
import { ObjectItem } from "mendix";
10+
import { createElement } from "react";
911
import { GalleryProps } from "../components/Gallery";
1012
import { ItemEventsController } from "../features/item-interaction/ItemEventsController";
1113
import { ItemHelper } from "../helpers/ItemHelper";
1214
import { ItemHelperBuilder } from "./builders/ItemHelperBuilder";
13-
import { PositionController } from "@mendix/widget-plugin-grid/keyboard-navigation/PositionController";
14-
import { VirtualGridLayout } from "@mendix/widget-plugin-grid/keyboard-navigation/VirtualGridLayout";
1515

1616
export function setup(jsx: React.ReactElement): { user: UserEvent } & RenderResult {
1717
return {
@@ -76,6 +76,8 @@ export function mockProps(params: Helpers & Mocks = {}): GalleryProps<ObjectItem
7676
page: 0,
7777
pageSize: 10,
7878
paging: false,
79+
paginationType: "buttons",
80+
showPagingButtons: "always",
7981
phoneItems: 2,
8082
tabletItems: 3,
8183
desktopItems: 4,

packages/pluggableWidgets/gallery-web/typings/GalleryProps.d.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import { ActionValue, DynamicValue, ListValue, ListActionValue, ListExpressionVa
88

99
export type ItemSelectionModeEnum = "toggle" | "clear";
1010

11-
export type PaginationEnum = "buttons" | "virtualScrolling";
12-
13-
export type PagingPositionEnum = "below" | "above";
11+
export type PaginationEnum = "buttons" | "virtualScrolling" | "loadMore";
1412

1513
export type ShowPagingButtonsEnum = "always" | "auto";
1614

15+
export type PagingPositionEnum = "bottom" | "top" | "both";
16+
1717
export type ShowEmptyPlaceholderEnum = "none" | "custom";
1818

1919
export type OnClickTriggerEnum = "single" | "double";
@@ -33,9 +33,10 @@ export interface GalleryContainerProps {
3333
phoneItems: number;
3434
pageSize: number;
3535
pagination: PaginationEnum;
36-
pagingPosition: PagingPositionEnum;
37-
showPagingButtons: ShowPagingButtonsEnum;
3836
showTotalCount: boolean;
37+
showPagingButtons: ShowPagingButtonsEnum;
38+
pagingPosition: PagingPositionEnum;
39+
loadMoreButtonCaption?: DynamicValue<string>;
3940
showEmptyPlaceholder: ShowEmptyPlaceholderEnum;
4041
emptyPlaceholder?: ReactNode;
4142
itemClass?: ListExpressionValue<string>;
@@ -69,9 +70,10 @@ export interface GalleryPreviewProps {
6970
phoneItems: number | null;
7071
pageSize: number | null;
7172
pagination: PaginationEnum;
72-
pagingPosition: PagingPositionEnum;
73-
showPagingButtons: ShowPagingButtonsEnum;
7473
showTotalCount: boolean;
74+
showPagingButtons: ShowPagingButtonsEnum;
75+
pagingPosition: PagingPositionEnum;
76+
loadMoreButtonCaption: string;
7577
showEmptyPlaceholder: ShowEmptyPlaceholderEnum;
7678
emptyPlaceholder: { widgetCount: number; renderer: ComponentType<{ children: ReactNode; caption?: string }> };
7779
itemClass: string;

0 commit comments

Comments
 (0)