Skip to content

Commit 8d943f5

Browse files
Merge pull request #4007 from OneCommunityGlobal/peterson-implement-no-badges-found-message
Peterson implement no badges found message
2 parents ecfadc2 + 34c41f3 commit 8d943f5

2 files changed

Lines changed: 110 additions & 66 deletions

File tree

src/components/UserProfile/AssignBadgePopup.jsx

Lines changed: 79 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
1-
import { useState, useEffect } from 'react';
1+
import { useState, useEffect, useMemo } from 'react';
22
import { Table, Button, UncontrolledTooltip } from 'reactstrap';
33
import { connect } from 'react-redux';
44
import axios from 'axios';
55
import AssignTableRow from '../Badge/AssignTableRow';
6-
import { assignBadgesByUserID, clearNameAndSelected, addSelectBadge } from '../../actions/badgeManagement';
6+
import {
7+
assignBadgesByUserID,
8+
clearNameAndSelected,
9+
addSelectBadge,
10+
} from '../../actions/badgeManagement';
711
import { ENDPOINTS } from '~/utils/URL';
812
import { boxStyle, boxStyleDark } from '../../styles';
913
import { toast } from 'react-toastify';
1014
import { PROTECTED_ACCOUNT_MODIFICATION_WARNING_MESSAGE } from '~/utils/constants';
15+
import { Spinner } from 'reactstrap';
1116

1217
function AssignBadgePopup(props) {
13-
const {darkMode} = props;
18+
const { darkMode } = props;
1419
const [searchedName, setSearchedName] = useState('');
1520
const [badgeList, setBadgeList] = useState([]);
1621
// Added state to disable confirm button while updating.
1722
const [shouldConfirmButtonDisable, setConfirmButtonDisable] = useState(false);
23+
const [isLoadingBadge, setisLoadingBadge] = useState(true);
1824

1925
const onSearch = text => {
2026
setSearchedName(text);
@@ -53,18 +59,21 @@ function AssignBadgePopup(props) {
5359
try {
5460
const response = await axios.get(ENDPOINTS.BADGE());
5561
setBadgeList(response.data);
62+
setisLoadingBadge(false);
5663
} catch (error) {}
5764
};
5865

59-
const filterBadges = (allBadges = []) => {
60-
// guard against non-array inputs
61-
if (!Array.isArray(allBadges)) return [];
62-
return allBadges.filter(({ badgeName }) =>
63-
badgeName.toLowerCase().includes(searchedName.toLowerCase())
64-
);
65-
};
66+
const filterBadges = (allBadges = []) => {
67+
// guard against non-array inputs
68+
if (!Array.isArray(allBadges)) return [];
69+
return allBadges.filter(({ badgeName }) =>
70+
badgeName.toLowerCase().includes(searchedName.toLowerCase()),
71+
);
72+
};
6673

67-
let filteredBadges = filterBadges(badgeList);
74+
const filteredBadges = useMemo(() => {
75+
return filterBadges(badgeList);
76+
}, [badgeList, searchedName]);
6877

6978
const addExistBadges = () => {
7079
if (props.userProfile && props.userProfile.badgeCollection) {
@@ -78,8 +87,6 @@ function AssignBadgePopup(props) {
7887
};
7988
let existBadges = addExistBadges();
8089

81-
82-
8390
return (
8491
<div data-testid="test-assignbadgepopup">
8592
<input
@@ -92,47 +99,72 @@ function AssignBadgePopup(props) {
9299
}}
93100
/>
94101
<div style={{ overflowY: 'scroll', height: '75vh' }}>
95-
<Table data-testid="test-badgeResults" className={darkMode ? 'text-light' : ''}>
96-
<thead>
97-
<tr>
98-
<th>Badge</th>
99-
<th>Name</th>
100-
<th style={{ zIndex: '10' }}>
101-
<i className="fa fa-info-circle" id="SelectInfo" data-testid="test-selectinfo" />
102-
<UncontrolledTooltip
103-
placement="right"
104-
target="SelectInfo"
105-
style={{ backgroundColor: '#666', color: '#fff' }}
106-
data-testid="test-tooltip"
107-
>
108-
<p className="badge_info_icon_text" data-testid="test-tip1">
109-
Hmmm, little blank boxes... what could they mean? Yep, you guessed it, check
110-
those boxes to select the badges you wish to assign a person. Click the
111-
&quot;Confirm&quot; button at the bottom when you&apos;ve selected all you wish
112-
to add.
113-
</p>
114-
<p className="badge_info_icon_text" data-testid="test-tip2">
115-
Want to assign multiple of the same badge to a person? Repeat the process!!
116-
</p>
117-
</UncontrolledTooltip>
118-
</th>
119-
</tr>
120-
</thead>
121-
<tbody>
122-
{filteredBadges.map((value, index) => (
123-
<AssignTableRow badge={value} index={index} key={index} existBadges={existBadges} />
124-
))}
125-
</tbody>
126-
</Table>
102+
{!isLoadingBadge && (props.isTableOpen ?? filteredBadges.length > 0) ? (
103+
<Table data-testid="test-badgeResults" className={darkMode ? 'text-light' : ''}>
104+
<thead
105+
style={
106+
darkMode
107+
? { backgroundColor: '#1c2541', color: '#fff' }
108+
: { backgroundColor: '#f0f8ff', color: 'black' }
109+
}
110+
>
111+
<tr>
112+
<th>Badge</th>
113+
<th>Name</th>
114+
<th style={{ zIndex: '10' }}>
115+
<i className="fa fa-info-circle" id="SelectInfo" data-testid="test-selectinfo" />
116+
<UncontrolledTooltip
117+
placement="right"
118+
target="SelectInfo"
119+
style={{ backgroundColor: '#666', color: '#fff' }}
120+
data-testid="test-tooltip"
121+
>
122+
<p className="badge_info_icon_text" data-testid="test-tip1">
123+
Hmmm, little blank boxes... what could they mean? Yep, you guessed it, check
124+
those boxes to select the badges you wish to assign a person. Click the
125+
&quot;Confirm&quot; button at the bottom when you&apos;ve selected all you
126+
wish to add.
127+
</p>
128+
<p className="badge_info_icon_text" data-testid="test-tip2">
129+
Want to assign multiple of the same badge to a person? Repeat the process!!
130+
</p>
131+
</UncontrolledTooltip>
132+
</th>
133+
</tr>
134+
</thead>
135+
<tbody>
136+
{filteredBadges.map((value, index) => (
137+
<AssignTableRow badge={value} index={index} key={index} existBadges={existBadges} />
138+
))}
139+
</tbody>
140+
</Table>
141+
) : isLoadingBadge && filteredBadges.length === 0 ? (
142+
<div
143+
style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '10px' }}
144+
>
145+
<h3 className={`text-center ${darkMode ? 'text-light' : 'text-dark'}`}>
146+
Loading Badges...
147+
</h3>
148+
149+
<Spinner color="primary" />
150+
</div>
151+
) : (
152+
!isLoadingBadge &&
153+
filteredBadges.length === 0 && (
154+
<h3 className={`text-center ${darkMode ? 'text-light' : 'text-dark'}`}>
155+
No badges found
156+
</h3>
157+
)
158+
)}
127159
</div>
128160
<Button
129161
className="btn--dark-sea-green float-right"
130-
style={darkMode ? {...boxStyleDark, margin: 5 } : { ...boxStyle, margin: 5 }}
162+
style={darkMode ? { ...boxStyleDark, margin: 5 } : { ...boxStyle, margin: 5 }}
131163
onClick={assignBadges}
132164
disabled={shouldConfirmButtonDisable}
133165
data-testid="test-button"
134166
>
135-
{!shouldConfirmButtonDisable ? 'Confirm' : 'Updating...'}
167+
{!shouldConfirmButtonDisable ? 'Confirm' : 'Updating...'}
136168
</Button>
137169
</div>
138170
);

src/components/UserProfile/__tests__/AssignBadgePopup.test.jsx

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const mockStore = configureStore([]);
1111
const initialState = {
1212
badge: {
1313
selectedBadges: [],
14-
allBadges: [],
14+
allBadges: [],
1515
},
1616
theme: themeMock,
1717
};
@@ -32,7 +32,7 @@ const tip2 = 'Want to assign multiple of the same badge to a person? Repeat the
3232
const renderComponent = () => {
3333
render(
3434
<Provider store={store}>
35-
<AssignBadgePopup />
35+
<AssignBadgePopup isTableOpen={true} />
3636
</Provider>,
3737
);
3838
};
@@ -69,6 +69,8 @@ describe('Userprofile/AssignBadgePopup Test Suite', () => {
6969
it('Test case 4 : Assert the pop up contains only one table with 3 columns ', async () => {
7070
renderComponent();
7171

72+
await new Promise(resolve => setTimeout(resolve, 1000));
73+
7274
// / Find all tables within the component
7375
const tables = screen.getAllByRole('table');
7476

@@ -85,6 +87,8 @@ describe('Userprofile/AssignBadgePopup Test Suite', () => {
8587
it('Test case 5 : Assert the presnce of objects associated with the search results: a table and three columns', async () => {
8688
renderComponent();
8789

90+
await new Promise(resolve => setTimeout(resolve, 1000));
91+
8892
const table = screen.getByTestId('test-badgeResults');
8993
const badge = screen.getByText('Badge');
9094
const name = screen.getByText('Name');
@@ -102,30 +106,38 @@ describe('Userprofile/AssignBadgePopup Test Suite', () => {
102106
expect(message1).toBeNull();
103107
expect(message2).toBeNull();
104108
});
105-
it('Test case 7 : Assert the tool tip message displayed when hovered', async () => {
106-
renderComponent();
107-
108-
const infoIcon = screen.getByTestId('test-selectinfo');
109-
fireEvent.mouseOver(infoIcon); // trigger the tooltip
110-
111-
// now grab the two <p> elements by their test IDs
112-
const tip1El = await screen.findByTestId('test-tip1');
113-
const tip2El = await screen.findByTestId('test-tip2');
114-
115-
expect(tip1El).toBeInTheDocument();
116-
// just check the unique leading phrase
117-
expect(tip1El).toHaveTextContent('Hmmm, little blank boxes');
118-
119-
expect(tip2El).toBeInTheDocument();
120-
expect(tip2El).toHaveTextContent('Want to assign multiple of the same badge');
121-
});
109+
it('Test case 7 : Assert the tool tip message displayed when hovered', async () => {
110+
renderComponent();
111+
112+
await new Promise(resolve => setTimeout(resolve, 1000));
113+
114+
const infoIcon = screen.getByTestId('test-selectinfo');
115+
fireEvent.mouseOver(infoIcon); // trigger the tooltip
116+
117+
// now grab the two <p> elements by their test IDs
118+
const tip1El = await screen.findByTestId('test-tip1');
119+
const tip2El = await screen.findByTestId('test-tip2');
120+
121+
expect(tip1El).toBeInTheDocument();
122+
// just check the unique leading phrase
123+
expect(tip1El).toHaveTextContent('Hmmm, little blank boxes');
124+
125+
expect(tip2El).toBeInTheDocument();
126+
expect(tip2El).toHaveTextContent('Want to assign multiple of the same badge');
127+
});
122128
it('Test case 8 : Assert if the pop up has a submit button ', async () => {
123129
renderComponent();
130+
131+
await new Promise(resolve => setTimeout(resolve, 1000));
132+
124133
const button = screen.getByTestId('test-button');
125134
expect(button).toBeInTheDocument();
126135
});
127136
it('Test case 9 : Assert if the popup renders badge data correctly ', async () => {
128137
renderComponent();
138+
139+
await new Promise(resolve => setTimeout(resolve, 1000));
140+
129141
// Find the AssignTableRow component within AssignBadgePopup
130142
const assignTableRowComponent = screen.getByTestId('test-badgeResults'); // Assuming you have a data-testid on the AssignTableRow
131143

0 commit comments

Comments
 (0)