Skip to content

Commit 9b1dd21

Browse files
committed
fix(dashboard): add fallback data, add tests
1 parent 5eeb624 commit 9b1dd21

8 files changed

+338
-40
lines changed

src/components/dashboard/ActionBarChart.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,17 @@ class ActionBarChart extends PureComponent {
4747
t: PropTypes.func.isRequired,
4848
actions: PropTypes.arrayOf(PropTypes.object),
4949
spaces: PropTypes.arrayOf(PropTypes.object),
50+
id: PropTypes.string,
5051
};
5152

5253
static defaultProps = {
5354
actions: [],
5455
spaces: [],
56+
id: null,
5557
};
5658

57-
renderChart = actions => {
58-
const { spaces, theme, t } = this.props;
59+
renderChart = (actions) => {
60+
const { spaces, theme, t, id: elementId } = this.props;
5961
const {
6062
palette: { primary, type },
6163
} = theme;
@@ -75,7 +77,7 @@ class ActionBarChart extends PureComponent {
7577
});
7678

7779
return (
78-
<ResponsiveContainer width="100%" height="100%">
80+
<ResponsiveContainer id={elementId} width="100%" height="100%">
7981
<BarChart
8082
width="100%"
8183
height="100%"

src/components/dashboard/ActionLineChart.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,21 @@ class ActionLineChart extends PureComponent {
4646
}).isRequired,
4747
t: PropTypes.func.isRequired,
4848
actions: PropTypes.arrayOf(PropTypes.object),
49+
id: PropTypes.string,
4950
};
5051

5152
static defaultProps = {
5253
actions: [],
54+
id: null,
5355
};
5456

55-
formatDate = date => {
57+
formatDate = (date) => {
5658
const d = new Date(date);
5759
return `${d.getDate()}/${d.getMonth()}/${d.getFullYear()}`;
5860
};
5961

6062
render() {
61-
const { theme, t, actions } = this.props;
63+
const { theme, t, actions, id: elementId } = this.props;
6264
const {
6365
palette: { primary, type },
6466
} = theme;
@@ -71,7 +73,7 @@ class ActionLineChart extends PureComponent {
7173
return <p>{t('No action has been recorded.')}</p>;
7274
}
7375

74-
const dataWithDateFormatted = actions.map(action => ({
76+
const dataWithDateFormatted = actions.map((action) => ({
7577
date: [this.formatDate(action.createdAt)],
7678
data: action.data,
7779
}));
@@ -88,7 +90,7 @@ class ActionLineChart extends PureComponent {
8890
return (
8991
<>
9092
<Typography variant="h5">{t('Action Count Per Space')}</Typography>
91-
<ResponsiveContainer width="100%" height="100%">
93+
<ResponsiveContainer id={elementId} width="100%" height="100%">
9294
<LineChart
9395
data={data}
9496
margin={{

src/components/dashboard/ActionPieChart.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { ACCENT_COLORS } from '../../config/constants';
1010

1111
const RADIAN = Math.PI / 180;
1212

13-
const styles = theme => ({
13+
const styles = (theme) => ({
1414
customTooltip: {
1515
backgroundColor: 'white',
1616
padding: '0.05rem 0.5rem',
@@ -86,10 +86,12 @@ class ActionPieChart extends PureComponent {
8686
}).isRequired,
8787
t: PropTypes.func.isRequired,
8888
actions: PropTypes.arrayOf(PropTypes.object),
89+
id: PropTypes.string,
8990
};
9091

9192
static defaultProps = {
9293
actions: [],
94+
id: null,
9395
};
9496

9597
renderCustomizedLabel = ({
@@ -118,7 +120,7 @@ class ActionPieChart extends PureComponent {
118120
};
119121

120122
render() {
121-
const { actions, classes, t } = this.props;
123+
const { actions, classes, t, id } = this.props;
122124

123125
if (!actions) {
124126
return <Loader />;
@@ -141,7 +143,7 @@ class ActionPieChart extends PureComponent {
141143
return (
142144
<>
143145
<Typography variant="h5">{t('Action Type Chart')}</Typography>
144-
<ResponsiveContainer width="100%" height="100%">
146+
<ResponsiveContainer id={id} width="100%" height="100%">
145147
<PieChart>
146148
<Pie
147149
data={data}

src/components/dashboard/ActionTotalCount.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,16 @@ class ActionTotalCount extends PureComponent {
2222
classes: PropTypes.shape({
2323
actionCounter: PropTypes.string.isRequired,
2424
}).isRequired,
25+
id: PropTypes.string,
2526
};
2627

2728
static defaultProps = {
2829
actions: [],
30+
id: null,
2931
};
3032

3133
render() {
32-
const { classes, t, actions } = this.props;
34+
const { classes, t, actions, id } = this.props;
3335

3436
if (!actions) {
3537
return <Loader />;
@@ -38,12 +40,12 @@ class ActionTotalCount extends PureComponent {
3840
const count = actions.length;
3941

4042
return (
41-
<>
43+
<div id={id}>
4244
<Typography variant="h5">{t('Total Action Count')}</Typography>
4345
<Grid container justify="center" alignItems="center">
4446
<CountUp end={count} duration={5} className={classes.actionCounter} />
4547
</Grid>
46-
</>
48+
</div>
4749
);
4850
}
4951
}

src/components/dashboard/Dashboard.js

+48-20
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,19 @@ import {
2424
SELECT_ALL_USERS_ID,
2525
USER_MODES,
2626
} from '../../config/constants';
27-
import { DASHBOARD_MAIN_ID } from '../../config/selectors';
28-
29-
const styles = theme => ({
27+
import {
28+
DASHBOARD_BAR_CHART_ID,
29+
DASHBOARD_ACTION_EDITOR_ID,
30+
DASHBOARD_MAIN_ID,
31+
DASHBOARD_NO_ACTION_MESSAGE_ID,
32+
DASHBOARD_LINE_CHART_ID,
33+
DASHBOARD_PIE_CHART_ID,
34+
DASHBOARD_TOTAL_COUNT_ID,
35+
DASHBOARD_USER_FILTER_ID,
36+
DASHBOARD_SPACE_FILTER_ID,
37+
} from '../../config/selectors';
38+
39+
const styles = (theme) => ({
3040
dashboard: { padding: theme.spacing(3) },
3141
dashboardGridItem: { height: '350px' },
3242
drawerHeader: {
@@ -91,24 +101,25 @@ export class Dashboard extends Component {
91101
dispatchGetDatabase();
92102
}
93103

94-
handleSpaceChange = event => {
104+
handleSpaceChange = (event) => {
95105
this.setState({ spaceId: event.target.value });
96106
};
97107

98-
handleUserChange = event => {
108+
handleUserChange = (event) => {
99109
this.setState({ filteredUserId: event.target.value });
100110
};
101111

102112
renderSpaceFilter = () => {
103113
const { database, t } = this.props;
104114
const { spaceId } = this.state;
115+
const { spaces = [] } = database;
105116

106117
if (!database) {
107118
return <Loader />;
108119
}
109120

110121
return (
111-
<FormControl variant="outlined" fullWidth>
122+
<FormControl id={DASHBOARD_SPACE_FILTER_ID} variant="outlined" fullWidth>
112123
<InputLabel>{t('Filter by Space')}</InputLabel>
113124
<Select
114125
label="Filter by Space"
@@ -118,7 +129,7 @@ export class Dashboard extends Component {
118129
<MenuItem value={SELECT_ALL_SPACES_ID}>
119130
<em>{t('All Spaces')}</em>
120131
</MenuItem>
121-
{database.spaces.map(space => (
132+
{spaces.map((space) => (
122133
<MenuItem value={space.id}>{space.name}</MenuItem>
123134
))}
124135
</Select>
@@ -139,7 +150,7 @@ export class Dashboard extends Component {
139150
}
140151

141152
return (
142-
<FormControl variant="outlined" fullWidth>
153+
<FormControl id={DASHBOARD_USER_FILTER_ID} variant="outlined" fullWidth>
143154
<InputLabel>{t('Filter by User')}</InputLabel>
144155
<Select
145156
label="Filter by User"
@@ -149,15 +160,15 @@ export class Dashboard extends Component {
149160
<MenuItem value={SELECT_ALL_USERS_ID}>
150161
<em>{t('All Users')}</em>
151162
</MenuItem>
152-
{database.users.map(user => (
163+
{database.users.map((user) => (
153164
<MenuItem value={user.id}>{user.username}</MenuItem>
154165
))}
155166
</Select>
156167
</FormControl>
157168
);
158169
};
159170

160-
renderActionWidgets = filteredActions => {
171+
renderActionWidgets = (filteredActions) => {
161172
const { database, classes } = this.props;
162173

163174
return (
@@ -169,16 +180,29 @@ export class Dashboard extends Component {
169180
alignItems="center"
170181
>
171182
<Grid item xs={12} sm={6} className={classes.dashboardGridItem}>
172-
<ActionBarChart spaces={database.spaces} actions={filteredActions} />
183+
<ActionBarChart
184+
id={DASHBOARD_BAR_CHART_ID}
185+
spaces={database.spaces}
186+
actions={filteredActions}
187+
/>
173188
</Grid>
174189
<Grid item xs={12} sm={6} className={classes.dashboardGridItem}>
175-
<ActionLineChart actions={filteredActions} />
190+
<ActionLineChart
191+
id={DASHBOARD_LINE_CHART_ID}
192+
actions={filteredActions}
193+
/>
176194
</Grid>
177195
<Grid item xs={12} sm={6} className={classes.dashboardGridItem}>
178-
<ActionPieChart actions={filteredActions} />
196+
<ActionPieChart
197+
id={DASHBOARD_PIE_CHART_ID}
198+
actions={filteredActions}
199+
/>
179200
</Grid>
180201
<Grid item xs={12} sm={6} className={classes.dashboardGridItem}>
181-
<ActionTotalCount actions={filteredActions} />
202+
<ActionTotalCount
203+
id={DASHBOARD_TOTAL_COUNT_ID}
204+
actions={filteredActions}
205+
/>
182206
</Grid>
183207
</Grid>
184208
);
@@ -188,15 +212,14 @@ export class Dashboard extends Component {
188212
const { t, database, userMode, userId } = this.props;
189213
const { spaceId, filteredUserId } = this.state;
190214

191-
let filteredActions = database.actions;
192-
const { users } = database;
215+
let filteredActions = database.actions || [];
216+
const { users = [] } = database;
193217
const isStudent = userMode === USER_MODES.STUDENT;
194218

195219
filteredActions = filteredActions.filter(({ user }) => {
196220
const isOwnAction = user === userId;
197221
const actionUser = users.find(({ id }) => id === user);
198-
const isAccessible =
199-
actionUser && actionUser.settings.actionAccessibility;
222+
const isAccessible = actionUser?.settings?.actionAccessibility;
200223
const filteredUserSelected = filteredUserId !== SELECT_ALL_USERS_ID;
201224

202225
// filter action per user if userMode is student
@@ -222,10 +245,15 @@ export class Dashboard extends Component {
222245
return filteredActions.length ? (
223246
<>
224247
{this.renderActionWidgets(filteredActions)}
225-
<ActionEditor actions={filteredActions} />
248+
<ActionEditor
249+
id={DASHBOARD_ACTION_EDITOR_ID}
250+
actions={filteredActions}
251+
/>
226252
</>
227253
) : (
228-
<Typography>{t('No action has been recorded.')}</Typography>
254+
<Typography id={DASHBOARD_NO_ACTION_MESSAGE_ID}>
255+
{t('No action has been recorded.')}
256+
</Typography>
229257
);
230258
};
231259

0 commit comments

Comments
 (0)