Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"@codemirror/state": "^6.5.2",
"@codemirror/view": "^6.38.1",
"@mendix/pluggable-widgets-tools": "10.21.2",
"@prettier/plugin-xml": ">=3.4.1",
"@testing-library/react": ">=15.0.6",
"@types/big.js": "^6.2.2",
"@types/node": "~22.14.0",
Expand All @@ -75,7 +76,6 @@
"mime-types": "patches/mime-types.patch",
"mobx-react-lite@4.0.7": "patches/mobx-react-lite@4.0.7.patch",
"mobx@6.12.3": "patches/mobx@6.12.3.patch",
"rc-trigger": "patches/rc-trigger.patch",
"react-big-calendar@0.19.2": "patches/react-big-calendar@0.19.2.patch",
"react-dropzone": "patches/react-dropzone.patch"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,52 +307,6 @@ $root: ".widget-datagrid";
width: 100%;
}

.pagination-bar {
display: flex;
justify-content: flex-end;
white-space: nowrap;
align-items: baseline;
margin: 16px;
color: $pagination-caption-color;

.paging-status {
padding: 0 8px 0;
}

.pagination-button {
padding: 6px;
color: var(--gray-darker, $gray-darker);
border-color: transparent;
background-color: transparent;

&:hover {
color: var(--brand-primary, $brand-primary);
border-color: transparent;
background-color: transparent;
}

&:disabled {
border-color: transparent;
background-color: transparent;
}

&:focus:not(:focus-visible) {
outline: none;
}

&:focus-visible {
outline: 1px solid var(--brand-primary, $brand-primary);
}
}
.pagination-icon {
position: relative;
top: 4px;
display: inline-block;
width: 20px;
height: 20px;
}
}

/* Column selector for hidable columns outside DG context */
/* List of columns to select */
.column-selectors {
Expand Down Expand Up @@ -522,6 +476,10 @@ $root: ".widget-datagrid";
}
}

.widget-datagrid .progress-bar {
margin: var(--spacing-medium, 16px);
}

.widget-datagrid .widget-datagrid-load-more {
display: block !important;
margin: var(--spacing-small, 8px) 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
========================================================================== */
$gallery-screen-lg: $screen-lg;
$gallery-screen-md: $screen-md;
$root: ".widget-gallery";

@mixin grid-items($number, $suffix) {
@for $i from 1 through $number {
Expand Down Expand Up @@ -162,3 +163,19 @@ $gallery-screen-md: $screen-md;
}
}
}

#{$root}-btn-link {
cursor: pointer;
background: transparent;
border: none;
color: var(--link-color);
padding: 0.3em 0.5em;
border-radius: 6px;
display: inline-block;
white-space: nowrap;

&:hover,
&:focus-visible {
background-color: var(--brand-primary-50, #e6e7f2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.pagination-bar {
display: flex;
justify-content: flex-end;
white-space: nowrap;
align-items: baseline;
color: $pagination-caption-color;

.paging-status {
padding: 0 8px 0;
}

.pagination-button {
padding: 6px;
color: var(--gray-darker, $gray-darker);
border-color: transparent;
background-color: transparent;

&:hover {
color: var(--brand-primary, $brand-primary);
border-color: transparent;
background-color: transparent;
}

&:disabled {
border-color: transparent;
background-color: transparent;
}

&:focus:not(:focus-visible) {
outline: none;
}

&:focus-visible {
outline: 1px solid var(--brand-primary, $brand-primary);
}
}
.pagination-icon {
position: relative;
top: 4px;
display: inline-block;
width: 20px;
height: 20px;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@import "../../../theme/web/custom-variables";
@import "variables";
@import "pagination-bar";
@import "datagrid";
@import "datagrid-filters";
@import "datagrid-dropdown-filter";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { If } from "@mendix/widget-plugin-component-kit/If";
import { Pagination as PagingButtons } from "@mendix/widget-plugin-grid/components/Pagination";
import cn from "classnames";
import { GUID, ObjectItem } from "mendix";
import { Selectable } from "mendix/preview/Selectable";
Expand Down Expand Up @@ -51,13 +52,18 @@ const numberOfItems = 3;
const cls = {
root: "widget-datagrid",
topBar: "widget-datagrid-top-bar table-header",
pagingTop: "widget-datagrid-padding-top",
ptStart: "widget-datagrid-tb-start",
ptEnd: "widget-datagrid-tb-end",
header: "widget-datagrid-header header-filters",
content: "widget-datagrid-content",
grid: "widget-datagrid-grid table",
gridHeader: "widget-datagrid-grid-head",
gridBody: "widget-datagrid-grid-body table-content",
footer: "widget-datagrid-footer table-footer",
pb: "widget-datagrid-padding-bottom",
pbStart: "widget-datagrid-pb-start",
pbMid: "widget-datagrid-pb-middle",
pbEnd: "widget-datagrid-pb-end"
};

Expand All @@ -79,9 +85,7 @@ export function preview(props: DatagridPreviewProps): ReactElement {
<GridBody />
</Grid>
</WidgetContent>
<WidgetFooter>
<PaddingBottom />
</WidgetFooter>
<WidgetFooter />
</WidgetRoot>
</PropsCtx.Provider>
);
Expand All @@ -96,8 +100,15 @@ function WidgetRoot({ children }: PropsWithChildren): ReactElement {
);
}

function WidgetTopBar({ children }: PropsWithChildren): ReactElement {
return <div className={cls.topBar}>{children}</div>;
function WidgetTopBar(): ReactElement {
return (
<div className={cls.topBar}>
<div className={cls.pagingTop}>
<div className={cls.ptStart}>{useTopCounter() ? <SelectionCounter /> : null}</div>
<div className={cls.ptEnd}>{usePagingTop() ? <Pagination /> : null}</div>
</div>
</div>
);
}

function WidgetHeader(): ReactNode {
Expand All @@ -113,8 +124,23 @@ function WidgetContent({ children }: PropsWithChildren): ReactElement {
return <div className={cls.content}>{children}</div>;
}

function WidgetFooter({ children }: PropsWithChildren): ReactElement {
return <div className="widget-datagrid-footer">{children}</div>;
function WidgetFooter(): ReactElement {
const props = useProps();
return (
<div className={cls.footer}>
<div className={cls.pb}>
<div className={cls.pbStart}>{useBottomCounter() ? <SelectionCounter /> : null}</div>
<div className={cls.pbMid}>
{props.pagination === "loadMore" ? (
<button className="btn btn-primary widget-datagrid-load-more">
{props.loadMoreButtonCaption}
</button>
) : null}
</div>
<div className={cls.pbEnd}>{usePagingBot() ? <Pagination /> : null}</div>
</div>
</div>
);
}

function Grid({ children }: PropsWithChildren): ReactElement {
Expand Down Expand Up @@ -269,14 +295,36 @@ function EmptyPlaceholder(): ReactElement {
);
}

function PaddingBottom(): ReactElement {
const SelectionCounter = (): ReactNode => {
const props = useProps();
return (
<div className={cls.pb}>
<div className={cls.pbStart} />
<div className={cls.pbEnd} />
<div className="widget-datagrid-selection-counter">
<span className="widget-gallery-selection-counter-text" aria-live="polite" aria-atomic="true">
{props.selectedCountTemplateSingular}
</span>
&nbsp;|&nbsp;
<button className="widget-gallery-btn-link">{props.clearSelectionButtonLabel}</button>
</div>
);
}
};

const Pagination = (): ReactNode => {
const props = useProps();
return (
<PagingButtons
canNextPage
canPreviousPage
gotoPage={() => {}}
nextPage={() => {}}
numberOfItems={props.pageSize ?? 20}
page={0}
pageSize={props.pageSize ?? 10}
showPagingButtons={"always"}
previousPage={() => {}}
pagination={props.pagination}
/>
);
};

function useColumns(): ColumnsPreviewType[] {
const { columns } = useProps();
Expand Down Expand Up @@ -320,3 +368,25 @@ function useGridStyle(): CSSProperties {
"--widgets-grid-template-columns": sizes.join(" ")
} as CSSProperties;
}

function useTopCounter(): boolean {
const { itemSelection, selectionCounterPosition } = useProps();
return itemSelection === "Multi" && selectionCounterPosition === "top";
}

function useBottomCounter(): boolean {
const { itemSelection, selectionCounterPosition } = useProps();
return itemSelection === "Multi" && selectionCounterPosition === "bottom";
}

function usePagingTop(): boolean {
const props = useProps();
const visible = props.showNumberOfRows || props.pagination === "buttons";
return visible && props.pagingPosition !== "bottom";
}

function usePagingBot(): boolean {
const props = useProps();
const visible = props.showNumberOfRows || props.pagination === "buttons";
return visible && props.pagingPosition !== "top";
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ export const WidgetFooter = observer(function WidgetFooter(): ReactElement | nul
const selectionCounterVM = useSelectionCounterViewModel();
const customPagination = useCustomPagination();

const showFooter =
selectionCounterVM.isBottomCounterVisible ||
paging.paginationVisible ||
paging.showVirtualScrollingWithRowCount ||
paging.showLoadMore;
const showFooter = selectionCounterVM.isBottomCounterVisible || paging.paginationVisible || paging.loadMoreVisible;

if (!showFooter) {
return null;
Expand All @@ -31,7 +27,7 @@ export const WidgetFooter = observer(function WidgetFooter(): ReactElement | nul
<SelectionCounter />
</If>
</div>
<If condition={paging.hasMoreItems && paging.pagination === "loadMore"}>
<If condition={paging.loadMoreVisible}>
<div className="widget-datagrid-pb-middle">
<button
className="btn btn-primary widget-datagrid-load-more"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { observer } from "mobx-react-lite";
import { PropsWithChildren, ReactElement } from "react";
import { useDatagridRootVM } from "../model/hooks/injection-hooks";

/** @remark vm source `WidgetRoot.viewModel.ts` */
export const WidgetRoot = observer(function WidgetRoot({ children }: PropsWithChildren): ReactElement {
const vm = useDatagridRootVM();

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function datagridConfig(props: DatagridContainerProps): DatagridConfig {
settingsStorageEnabled: isSettingsStorageEnabled(props),
enableSelectAll: props.enableSelectAll,
keepSelection: props.keepSelection,
autoSelect: props.autoSelect,
autoSelect: isAutoSelectEnabled(props),
multiselectable: isMultiselectable(props),
loadingType: props.loadingType,
columnsHidable: props.columnsHidable,
Expand All @@ -67,6 +67,10 @@ function isMultiselectable(props: DatagridContainerProps): true | undefined {
return type === "Multi" ? true : undefined;
}

function isAutoSelectEnabled(props: DatagridContainerProps): boolean {
return props.itemSelection?.type === "Multi" && props.autoSelect;
}

function isSelectionEnabled(props: DatagridContainerProps): boolean {
return props.itemSelection !== undefined;
}
Expand Down
Loading
Loading