Skip to content

Commit 0d838f6

Browse files
authored
feat(FilterBar): add reset warning MessageBox & improve docs (#5536)
1 parent f96482b commit 0d838f6

File tree

6 files changed

+301
-155
lines changed

6 files changed

+301
-155
lines changed

packages/main/src/components/FilterBar/FilterBar.cy.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,13 @@ describe('FilterBar.cy.tsx', () => {
176176
cy.findAllByTestId('SELECT').should('exist');
177177
} else {
178178
if (action === 'Reset') {
179-
cy.get('@restoreSpy').should('have.callCount', 1);
179+
cy.get('[data-component-name="FilterBarDialogResetMessageBox"]').contains('Cancel').click();
180+
cy.get('@restoreSpy').should('have.callCount', 0);
181+
cy.findByText(action).click();
182+
cy.closeUi5PopupWithEsc();
183+
cy.get('@restoreSpy').should('have.callCount', 0);
184+
cy.findByText(action).click();
185+
cy.get('[data-component-name="FilterBarDialogResetMessageBox"]').contains('OK').click();
180186
cy.findByText('OK').click();
181187
cy.get('@saveSpy').should('have.callCount', saveCallCount);
182188
saveCallCount++;

packages/main/src/components/FilterBar/FilterBar.mdx

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,38 +35,88 @@ This is a basic example of how the FilterBar could be used inside an app.
3535
<summary>Show Code</summary>
3636

3737
```jsx
38+
const initialState = {
39+
age: 37,
40+
countries: {},
41+
currency: 'USD',
42+
date: '',
43+
dateRange: '',
44+
search: ''
45+
};
46+
47+
function reducer(state, action) {
48+
switch (action.type) {
49+
case 'SET_AGE':
50+
return { ...state, age: action.payload };
51+
case 'SET_COUNTRIES':
52+
return { ...state, countries: action.payload };
53+
case 'SET_CURRENCY':
54+
return { ...state, currency: action.payload };
55+
case 'SET_DATE':
56+
return { ...state, date: action.payload };
57+
case 'SET_DATE_RANGE':
58+
return { ...state, dateRange: action.payload };
59+
case 'SET_SEARCH':
60+
return { ...state, search: action.payload };
61+
case 'DIALOG_RESTORE':
62+
return action.payload;
63+
default:
64+
return state;
65+
}
66+
}
67+
3868
const FilterBarComponent = (args) => {
39-
const [age, setAge] = useState(37);
40-
const [countries, setCountries] = useState({});
41-
const [currency, setCurrency] = useState('USD');
42-
const [date, setDate] = useState('');
43-
const [dateRange, setDateRange] = useState('');
69+
const [state, dispatch] = useReducer(reducer, initialState);
70+
const { age, countries, currency, date, dateRange, search } = state;
71+
const prevDialogOpenState = useRef();
72+
73+
const handleSearch = (e) => {
74+
dispatch({ type: 'SET_SEARCH', payload: e.target.value });
75+
};
76+
4477
const handleAgeChange = (e) => {
45-
setAge(e.target.value);
78+
dispatch({ type: 'SET_AGE', payload: e.target.value });
4679
};
80+
4781
const handleCountriesChange = (e) => {
48-
setCountries(
49-
e.detail.items.reduce((acc, cur) => {
50-
return { ...acc, [cur.getAttribute('text').toLowerCase()]: true };
51-
}, {})
52-
);
82+
const newCountries = e.detail.items.reduce((acc, cur) => {
83+
return { ...acc, [cur.getAttribute('text').toLowerCase()]: true };
84+
}, {});
85+
dispatch({ type: 'SET_COUNTRIES', payload: newCountries });
5386
};
87+
5488
const handleCurrencyChange = (e) => {
55-
setCurrency(e.detail.selectedOption.textContent);
89+
dispatch({ type: 'SET_CURRENCY', payload: e.detail.selectedOption.textContent });
5690
};
91+
5792
const handleDateChange = (e) => {
5893
if (e.detail.valid) {
59-
setDate(e.detail.value);
94+
dispatch({ type: 'SET_DATE', payload: e.detail.value });
6095
}
6196
};
97+
6298
const handleDateRangeChange = (e) => {
6399
if (e.detail.valid) {
64-
setDateRange(e.detail.value);
100+
dispatch({ type: 'SET_DATE_RANGE', payload: e.detail.value });
65101
}
66102
};
103+
104+
const handleFiltersDialogOpen = () => {
105+
prevDialogOpenState.current = state;
106+
};
107+
108+
const handleRestore = () => {
109+
dispatch({ type: 'DIALOG_RESTORE', payload: prevDialogOpenState.current });
110+
};
111+
67112
return (
68113
<>
69-
<FilterBar>
114+
<FilterBar
115+
showResetButton
116+
search={<Input onInput={handleSearch} />}
117+
onRestore={handleRestore}
118+
onFiltersDialogOpen={handleFiltersDialogOpen}
119+
>
70120
<FilterGroupItem label="Age" active={!!age} required>
71121
<StepInput value={age} onChange={handleAgeChange} required />
72122
</FilterGroupItem>
@@ -108,6 +158,10 @@ const FilterBarComponent = (args) => {
108158
</FilterGroupItem>
109159
</FilterBar>
110160
<FlexBox direction={FlexBoxDirection.Column}>
161+
<FlexBox>
162+
<Label showColon>Search</Label>
163+
<Text>{search}</Text>
164+
</FlexBox>
111165
<FlexBox>
112166
<Label showColon>Age</Label>
113167
<Text>{age}</Text>

packages/main/src/components/FilterBar/FilterBar.stories.tsx

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Meta, StoryObj } from '@storybook/react';
2-
import { useState } from 'react';
2+
import React, { useReducer, useRef, useState } from 'react';
3+
import { createPortal } from 'react-dom';
34
import { FlexBoxDirection } from '../../enums/index.js';
45
import {
56
ComboBox,
@@ -131,45 +132,89 @@ export const Default: Story = {
131132
}
132133
};
133134

135+
const initialState = {
136+
age: 37,
137+
countries: {},
138+
currency: 'USD',
139+
date: '',
140+
dateRange: '',
141+
search: ''
142+
};
143+
144+
function reducer(state, action) {
145+
switch (action.type) {
146+
case 'SET_AGE':
147+
return { ...state, age: action.payload };
148+
case 'SET_COUNTRIES':
149+
return { ...state, countries: action.payload };
150+
case 'SET_CURRENCY':
151+
return { ...state, currency: action.payload };
152+
case 'SET_DATE':
153+
return { ...state, date: action.payload };
154+
case 'SET_DATE_RANGE':
155+
return { ...state, dateRange: action.payload };
156+
case 'SET_SEARCH':
157+
return { ...state, search: action.payload };
158+
case 'DIALOG_RESTORE':
159+
return action.payload;
160+
default:
161+
return state;
162+
}
163+
}
164+
134165
export const WithLogic: Story = {
135166
render: (args) => {
136-
const [age, setAge] = useState(37);
137-
const [countries, setCountries] = useState<Record<string, boolean>>({});
138-
const [currency, setCurrency] = useState('USD');
139-
const [date, setDate] = useState('');
140-
const [dateRange, setDateRange] = useState('');
141-
const [search, setSearch] = useState('');
167+
const [state, dispatch] = useReducer(reducer, initialState);
168+
const { age, countries, currency, date, dateRange, search } = state;
169+
const prevDialogOpenState = useRef();
142170

143171
const handleSearch = (e) => {
144-
setSearch(e.target.value);
172+
dispatch({ type: 'SET_SEARCH', payload: e.target.value });
145173
};
146174

147175
const handleAgeChange = (e) => {
148-
setAge(e.target.value);
176+
dispatch({ type: 'SET_AGE', payload: e.target.value });
149177
};
178+
150179
const handleCountriesChange = (e) => {
151-
setCountries(
152-
e.detail.items.reduce((acc, cur) => {
153-
return { ...acc, [cur.getAttribute('text').toLowerCase()]: true };
154-
}, {})
155-
);
180+
const newCountries = e.detail.items.reduce((acc, cur) => {
181+
return { ...acc, [cur.getAttribute('text').toLowerCase()]: true };
182+
}, {});
183+
dispatch({ type: 'SET_COUNTRIES', payload: newCountries });
156184
};
185+
157186
const handleCurrencyChange = (e) => {
158-
setCurrency(e.detail.selectedOption.textContent);
187+
dispatch({ type: 'SET_CURRENCY', payload: e.detail.selectedOption.textContent });
159188
};
189+
160190
const handleDateChange = (e) => {
161191
if (e.detail.valid) {
162-
setDate(e.detail.value);
192+
dispatch({ type: 'SET_DATE', payload: e.detail.value });
163193
}
164194
};
195+
165196
const handleDateRangeChange = (e) => {
166197
if (e.detail.valid) {
167-
setDateRange(e.detail.value);
198+
dispatch({ type: 'SET_DATE_RANGE', payload: e.detail.value });
168199
}
169200
};
201+
202+
const handleFiltersDialogOpen = () => {
203+
prevDialogOpenState.current = state;
204+
};
205+
206+
const handleRestore = () => {
207+
dispatch({ type: 'DIALOG_RESTORE', payload: prevDialogOpenState.current });
208+
};
209+
170210
return (
171211
<>
172-
<FilterBar {...args} search={<Input onInput={handleSearch} />}>
212+
<FilterBar
213+
showResetButton
214+
search={<Input onInput={handleSearch} />}
215+
onRestore={handleRestore}
216+
onFiltersDialogOpen={handleFiltersDialogOpen}
217+
>
173218
<FilterGroupItem label="Age" active={!!age} required>
174219
<StepInput value={age} onChange={handleAgeChange} required />
175220
</FilterGroupItem>

0 commit comments

Comments
 (0)