Skip to content

Commit e1478a3

Browse files
author
Illia Obukhau
authored
[WC-1716] Issue dg inf loop (#493)
2 parents 4a167ba + 32dd867 commit e1478a3

36 files changed

+477
-233
lines changed

packages/modules/data-widgets/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "data-widgets",
33
"moduleName": "Data Widgets",
4-
"version": "2.7.0",
4+
"version": "2.7.1",
55
"license": "Apache-2.0",
66
"copyright": "© Mendix Technology BV 2023. All rights reserved.",
77
"private": true,

packages/pluggableWidgets/datagrid-date-filter-web/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
### Fixed
10+
11+
- We fixed an issue with widget rendering and performance.
12+
13+
### Breaking changes
14+
15+
- We introduce a breaking change that affects how widget is reacting on default value changes. Starting with this version, widget use the default value attribute only as an initial value, and any further changes to the default value attribute will be ignored.
16+
917
## [2.4.2] - 2022-09-29
1018

1119
### Fixed

packages/pluggableWidgets/datagrid-date-filter-web/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "datagrid-date-filter-web",
33
"widgetName": "DatagridDateFilter",
4-
"version": "2.4.2",
4+
"version": "2.5.0",
55
"description": "",
66
"copyright": "© Mendix Technology BV 2023. All rights reserved.",
77
"private": true,

packages/pluggableWidgets/datagrid-date-filter-web/src/DatagridDateFilter.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ export default function DatagridDateFilter(props: DatagridDateFilterContainerPro
9797
return <Alert bootstrapStyle="danger">{errorMessage}</Alert>;
9898
}
9999

100+
if (isLoadingDefaultValues(props)) {
101+
return null;
102+
}
103+
100104
return (
101105
<FilterComponent
102106
adjustable={props.adjustable}
@@ -245,3 +249,8 @@ function getFilterCondition(
245249
return lessThanOrEqual(filterAttribute, literal(new Date(addDays(dateValue, 1).getTime() - 1)));
246250
}
247251
}
252+
253+
function isLoadingDefaultValues(props: DatagridDateFilterContainerProps): boolean {
254+
const statusList = [props.defaultValue?.status, props.defaultStartDate?.status, props.defaultEndDate?.status];
255+
return statusList.some(status => status === "loading");
256+
}

packages/pluggableWidgets/datagrid-date-filter-web/src/components/FilterComponent.tsx

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,6 @@ export function FilterComponent(props: FilterComponentProps): ReactElement {
3333
const [rangeValues, setRangeValues] = useState<RangeDateValue>([props.defaultStartDate, props.defaultEndDate]);
3434
const pickerRef = useRef<DatePickerComponent | null>(null);
3535

36-
useEffect(() => {
37-
setValue(prev => {
38-
if (prev?.toISOString() === props.defaultValue?.toISOString()) {
39-
return prev;
40-
}
41-
42-
return props.defaultValue;
43-
});
44-
}, [props.defaultValue]);
45-
46-
useEffect(() => {
47-
if (props.defaultStartDate || props.defaultEndDate) {
48-
setRangeValues([props.defaultStartDate, props.defaultEndDate]);
49-
}
50-
}, [props.defaultStartDate, props.defaultEndDate]);
51-
5236
useEffect(() => {
5337
props.updateFilters?.(value, rangeValues, type);
5438
}, [value, rangeValues, type]);

packages/pluggableWidgets/datagrid-date-filter-web/src/components/__tests__/DatagridDateFilter.spec.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,17 @@ describe("Date Filter", () => {
102102
expect(screen.getByRole("textbox")).toHaveValue("01/01/2000");
103103
});
104104

105-
it("sync value when defaultValue changes from undefined to date", async () => {
105+
it("don't sync value when defaultValue changes from undefined to date", async () => {
106106
// 946684800000 = 01.01.2000
107107
const date = new Date(946684800000);
108108
const { rerender } = render(<DatagridDateFilter {...commonProps} defaultValue={undefined} />);
109109
expect(screen.getByRole("textbox")).toHaveValue("");
110110

111111
rerender(<DatagridDateFilter {...commonProps} defaultValue={dynamicValue<Date>(date)} />);
112-
expect(screen.getByRole("textbox")).toHaveValue("01/01/2000");
112+
expect(screen.getByRole("textbox")).toHaveValue("");
113113
});
114114

115-
it("sync value when defaultValue changes from date to undefined", async () => {
115+
it("don't sync value when defaultValue changes from date to undefined", async () => {
116116
// 946684800000 = 01.01.2000
117117
const date = new Date(946684800000);
118118
const { rerender } = render(
@@ -121,7 +121,7 @@ describe("Date Filter", () => {
121121
expect(screen.getByRole("textbox")).toHaveValue("01/01/2000");
122122

123123
rerender(<DatagridDateFilter {...commonProps} defaultValue={undefined} />);
124-
expect(screen.getByRole("textbox")).toHaveValue("");
124+
expect(screen.getByRole("textbox")).toHaveValue("01/01/2000");
125125
});
126126
});
127127

packages/pluggableWidgets/datagrid-date-filter-web/src/components/__tests__/FilterComponent.spec.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ describe("Filter component", () => {
4040
});
4141

4242
describe("with defaultValue", () => {
43-
it("call updateFilters when defaultValue get new value", () => {
43+
it("don't call updateFilters when defaultValue get new value", () => {
4444
const date = new Date(946684800000);
4545
const updateFilters = jest.fn();
4646
const { rerender } = render_fromTestingLibrary(
@@ -49,7 +49,7 @@ describe("Filter component", () => {
4949

5050
// First time updateFilters is called on initial mount
5151
expect(updateFilters).toBeCalledTimes(1);
52-
expect(updateFilters.mock.calls[0][0]).toBe(date);
52+
expect(updateFilters).toHaveBeenLastCalledWith(date, [undefined, undefined], "equal");
5353

5454
const nextValue = new Date(999999900000);
5555

@@ -62,8 +62,8 @@ describe("Filter component", () => {
6262
/>
6363
);
6464

65-
expect(updateFilters).toBeCalledTimes(2);
66-
expect(updateFilters.mock.calls[1][0]).toBe(nextValue);
65+
expect(updateFilters).toBeCalledTimes(1);
66+
expect(updateFilters).toHaveBeenLastCalledWith(date, [undefined, undefined], "equal");
6767
});
6868

6969
it("don't call updateFilters when defaultValue get same value", () => {

packages/pluggableWidgets/datagrid-date-filter-web/src/package.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8" ?>
22
<package xmlns="http://www.mendix.com/package/1.0/">
3-
<clientModule name="DatagridDateFilter" version="2.4.2" xmlns="http://www.mendix.com/clientModule/1.0/">
3+
<clientModule name="DatagridDateFilter" version="2.5.0" xmlns="http://www.mendix.com/clientModule/1.0/">
44
<widgetFiles>
55
<widgetFile path="DatagridDateFilter.xml" />
66
</widgetFiles>

packages/pluggableWidgets/datagrid-dropdown-filter-web/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
### Fixed
10+
11+
- We fixed an issue with widget rendering and performance.
12+
13+
### Breaking changes
14+
15+
- We introduce a breaking change that affects how widget is reacting on default value changes. Starting with this version, widget use the default value attribute only as an initial value, and any further changes to the default value attribute will be ignored.
16+
917
## [2.3.0] - 2023-02-17
1018

1119
### Changed

packages/pluggableWidgets/datagrid-dropdown-filter-web/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "datagrid-dropdown-filter-web",
33
"widgetName": "DatagridDropdownFilter",
4-
"version": "2.3.0",
4+
"version": "2.4.0",
55
"description": "",
66
"copyright": "© Mendix Technology BV 2023. All rights reserved.",
77
"private": true,

packages/pluggableWidgets/datagrid-dropdown-filter-web/src/DatagridDropdownFilter.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useFilterContextValue } from "@mendix/pluggable-widgets-commons/components/web";
2-
import { createElement, ReactElement } from "react";
2+
import { createElement, Fragment, ReactElement } from "react";
33
import { DatagridDropdownFilterContainerProps } from "../typings/DatagridDropdownFilterProps";
44
import { EnumerationFilter } from "./components/EnumerationFilter";
55
import { ErrorBox } from "./components/ErrorBox";
@@ -13,6 +13,10 @@ export default function DatagridDropdownFilter(props: DatagridDropdownFilterCont
1313
return <ErrorBox error={new OutOfProviderError()} />;
1414
}
1515

16+
if (props.defaultValue?.status === "loading") {
17+
return <Fragment />;
18+
}
19+
1620
const Filter = context.value.associationProperties ? AssociationFilter : EnumerationFilter;
1721

1822
return <Filter context={context.value} widgetProps={props} />;

packages/pluggableWidgets/datagrid-dropdown-filter-web/src/components/FilterComponent.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export function FilterComponent(props: FilterComponentProps): ReactElement {
6464
const [selectedFilters, setSelectedFilters] = useState<FilterOption[]>([]);
6565
const [show, setShow] = useState(false);
6666
const [dropdownWidth, setDropdownWidth] = useState(0);
67+
const { current: initialFilterValue } = useRef(defaultValue);
6768
const defaultValuesLoaded = useRef<boolean>(false);
6869

6970
const componentRef = useRef<HTMLDivElement>(null);
@@ -108,8 +109,8 @@ export function FilterComponent(props: FilterComponentProps): ReactElement {
108109
useEffect(() => {
109110
if (!defaultValuesLoaded.current && options.length > 0) {
110111
if (multiSelect) {
111-
if (defaultValue) {
112-
const initialOptions = defaultValue
112+
if (initialFilterValue) {
113+
const initialOptions = initialFilterValue
113114
.split(",")
114115
.map(value => options.find(option => option.value === value))
115116
.filter(Boolean) as FilterOption[];
@@ -121,7 +122,7 @@ export function FilterComponent(props: FilterComponentProps): ReactElement {
121122
}
122123
} else {
123124
// We want to add empty option caption
124-
const initialOption = options.find(option => option.value === defaultValue) ?? options[0];
125+
const initialOption = options.find(option => option.value === initialFilterValue) ?? options[0];
125126

126127
setValueInput(initialOption?.caption ?? "");
127128
setSelectedFilters(prev => {
@@ -134,7 +135,7 @@ export function FilterComponent(props: FilterComponentProps): ReactElement {
134135
}
135136
defaultValuesLoaded.current = true;
136137
}
137-
}, [defaultValue, emptyOptionCaption, multiSelect, options, setMultiSelectFilters]);
138+
}, [initialFilterValue, emptyOptionCaption, multiSelect, options, setMultiSelectFilters]);
138139

139140
useEffect(() => {
140141
const emptyOption = multiSelect
@@ -155,7 +156,7 @@ export function FilterComponent(props: FilterComponentProps): ReactElement {
155156

156157
// Resets the option to reload default values
157158
defaultValuesLoaded.current = false;
158-
}, [emptyOptionCaption, multiSelect, optionsProp, defaultValue]);
159+
}, [emptyOptionCaption, multiSelect, optionsProp, initialFilterValue]);
159160

160161
// This side effect meant to sync filter value with parents
161162
// But, because updateFilters is might be "unstable" function

packages/pluggableWidgets/datagrid-dropdown-filter-web/src/components/__tests__/DataGridDropdownFilter.spec.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ describe("Dropdown Filter", () => {
109109
expect(screen.getByRole("textbox")).toHaveValue("enum_value_1");
110110
});
111111

112-
it("sync defaultValue with state when defaultValue changes from undefined to string", async () => {
112+
it("don't sync defaultValue with state when defaultValue changes from undefined to string", async () => {
113113
const { rerender } = render(
114114
<DatagridDropdownFilter
115115
{...commonProps}
@@ -145,11 +145,11 @@ describe("Dropdown Filter", () => {
145145
);
146146

147147
await waitFor(() => {
148-
expect(screen.getByRole("textbox")).toHaveValue("enum_value_1");
148+
expect(screen.getByRole("textbox")).toHaveValue("");
149149
});
150150
});
151151

152-
it("sync defaultValue with state when defaultValue changes from string to undefined", async () => {
152+
it("don't sync defaultValue with state when defaultValue changes from string to undefined", async () => {
153153
mockCtx(["xyz", "abc"]);
154154
const { rerender } = render(
155155
<DatagridDropdownFilter
@@ -184,7 +184,7 @@ describe("Dropdown Filter", () => {
184184
);
185185

186186
await waitFor(() => {
187-
expect(screen.getByRole("textbox")).toHaveValue("");
187+
expect(screen.getByRole("textbox")).toHaveValue("xyz");
188188
});
189189
});
190190
});

packages/pluggableWidgets/datagrid-dropdown-filter-web/src/package.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8" ?>
22
<package xmlns="http://www.mendix.com/package/1.0/">
3-
<clientModule name="DatagridDropdownFilter" version="2.3.0" xmlns="http://www.mendix.com/clientModule/1.0/">
3+
<clientModule name="DatagridDropdownFilter" version="2.4.0" xmlns="http://www.mendix.com/clientModule/1.0/">
44
<widgetFiles>
55
<widgetFile path="DatagridDropdownFilter.xml" />
66
</widgetFiles>

packages/pluggableWidgets/datagrid-number-filter-web/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
### Fixed
10+
11+
- We fixed an issue with widget rendering and performance.
12+
13+
### Breaking changes
14+
15+
- We introduce a breaking change that affects how widget is reacting on default value changes. Starting with this version, widget use the default value attribute only as an initial value, and any further changes to the default value attribute will be ignored.
16+
917
## [2.3.1] - 2022-08-11
1018

1119
### Fixed

packages/pluggableWidgets/datagrid-number-filter-web/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "datagrid-number-filter-web",
33
"widgetName": "DatagridNumberFilter",
4-
"version": "2.3.1",
4+
"version": "2.4.0",
55
"description": "",
66
"copyright": "© Mendix Technology BV 2023. All rights reserved.",
77
"private": true,

packages/pluggableWidgets/datagrid-number-filter-web/src/DatagridNumberFilter.editorPreview.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ export function preview(props: DatagridNumberFilterPreviewProps): ReactElement {
88
<FilterComponent
99
adjustable={props.adjustable}
1010
className={props.className}
11-
defaultFilter={props.defaultFilter}
12-
delay={props.delay ?? 500}
11+
initialFilterType={props.defaultFilter}
12+
inputChangeDelay={props.delay ?? 500}
1313
placeholder={props.placeholder}
1414
screenReaderButtonCaption={props.screenReaderButtonCaption}
1515
screenReaderInputCaption={props.screenReaderInputCaption}

packages/pluggableWidgets/datagrid-number-filter-web/src/DatagridNumberFilter.tsx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { createElement, ReactElement, useRef } from "react";
22
import { DatagridNumberFilterContainerProps, DefaultFilterEnum } from "../typings/DatagridNumberFilterProps";
3-
43
import { FilterComponent } from "./components/FilterComponent";
54
import { Alert, FilterType, getFilterDispatcher, generateUUID } from "@mendix/pluggable-widgets-commons/components/web";
65
import { Big } from "big.js";
@@ -75,26 +74,26 @@ export default function DatagridNumberFilter(props: DatagridNumberFilterContaine
7574
return <Alert bootstrapStyle="danger">{errorMessage}</Alert>;
7675
}
7776

77+
if (props.defaultValue?.status === "loading") {
78+
return null;
79+
}
80+
7881
return (
7982
<FilterComponent
8083
adjustable={props.adjustable}
8184
className={props.class}
82-
defaultFilter={defaultFilter?.type ?? props.defaultFilter}
83-
delay={props.delay}
85+
initialFilterType={defaultFilter?.type ?? props.defaultFilter}
86+
initialFilterValue={defaultFilter?.value ?? props.defaultValue?.value}
87+
inputChangeDelay={props.delay}
8488
id={id.current}
8589
placeholder={props.placeholder?.value}
8690
screenReaderButtonCaption={props.screenReaderButtonCaption?.value}
8791
screenReaderInputCaption={props.screenReaderInputCaption?.value}
8892
styles={props.style}
8993
tabIndex={props.tabIndex}
9094
updateFilters={(value: Big | undefined, type: DefaultFilterEnum): void => {
91-
if (
92-
(value && !props.valueAttribute?.value?.eq(value)) ||
93-
value !== props.valueAttribute?.value
94-
) {
95-
props.valueAttribute?.setValue(value);
96-
props.onChange?.execute();
97-
}
95+
props.valueAttribute?.setValue(value);
96+
props.onChange?.execute();
9897
const conditions = attributes
9998
?.map(attribute => getFilterCondition(attribute, value, type))
10099
.filter((filter): filter is FilterCondition => filter !== undefined);
@@ -104,7 +103,6 @@ export default function DatagridNumberFilter(props: DatagridNumberFilterContaine
104103
filterType: FilterType.NUMBER
105104
});
106105
}}
107-
value={defaultFilter?.value ?? props.defaultValue?.value}
108106
/>
109107
);
110108
}}

0 commit comments

Comments
 (0)