Skip to content

Commit

Permalink
fix(dashboard): add fallback data, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pyphilia committed Oct 29, 2020
1 parent 5eeb624 commit 9b1dd21
Show file tree
Hide file tree
Showing 8 changed files with 338 additions and 40 deletions.
8 changes: 5 additions & 3 deletions src/components/dashboard/ActionBarChart.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,17 @@ class ActionBarChart extends PureComponent {
t: PropTypes.func.isRequired,
actions: PropTypes.arrayOf(PropTypes.object),
spaces: PropTypes.arrayOf(PropTypes.object),
id: PropTypes.string,
};

static defaultProps = {
actions: [],
spaces: [],
id: null,
};

renderChart = actions => {
const { spaces, theme, t } = this.props;
renderChart = (actions) => {
const { spaces, theme, t, id: elementId } = this.props;
const {
palette: { primary, type },
} = theme;
Expand All @@ -75,7 +77,7 @@ class ActionBarChart extends PureComponent {
});

return (
<ResponsiveContainer width="100%" height="100%">
<ResponsiveContainer id={elementId} width="100%" height="100%">
<BarChart
width="100%"
height="100%"
Expand Down
10 changes: 6 additions & 4 deletions src/components/dashboard/ActionLineChart.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,21 @@ class ActionLineChart extends PureComponent {
}).isRequired,
t: PropTypes.func.isRequired,
actions: PropTypes.arrayOf(PropTypes.object),
id: PropTypes.string,
};

static defaultProps = {
actions: [],
id: null,
};

formatDate = date => {
formatDate = (date) => {
const d = new Date(date);
return `${d.getDate()}/${d.getMonth()}/${d.getFullYear()}`;
};

render() {
const { theme, t, actions } = this.props;
const { theme, t, actions, id: elementId } = this.props;
const {
palette: { primary, type },
} = theme;
Expand All @@ -71,7 +73,7 @@ class ActionLineChart extends PureComponent {
return <p>{t('No action has been recorded.')}</p>;
}

const dataWithDateFormatted = actions.map(action => ({
const dataWithDateFormatted = actions.map((action) => ({
date: [this.formatDate(action.createdAt)],
data: action.data,
}));
Expand All @@ -88,7 +90,7 @@ class ActionLineChart extends PureComponent {
return (
<>
<Typography variant="h5">{t('Action Count Per Space')}</Typography>
<ResponsiveContainer width="100%" height="100%">
<ResponsiveContainer id={elementId} width="100%" height="100%">
<LineChart
data={data}
margin={{
Expand Down
8 changes: 5 additions & 3 deletions src/components/dashboard/ActionPieChart.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ACCENT_COLORS } from '../../config/constants';

const RADIAN = Math.PI / 180;

const styles = theme => ({
const styles = (theme) => ({
customTooltip: {
backgroundColor: 'white',
padding: '0.05rem 0.5rem',
Expand Down Expand Up @@ -86,10 +86,12 @@ class ActionPieChart extends PureComponent {
}).isRequired,
t: PropTypes.func.isRequired,
actions: PropTypes.arrayOf(PropTypes.object),
id: PropTypes.string,
};

static defaultProps = {
actions: [],
id: null,
};

renderCustomizedLabel = ({
Expand Down Expand Up @@ -118,7 +120,7 @@ class ActionPieChart extends PureComponent {
};

render() {
const { actions, classes, t } = this.props;
const { actions, classes, t, id } = this.props;

if (!actions) {
return <Loader />;
Expand All @@ -141,7 +143,7 @@ class ActionPieChart extends PureComponent {
return (
<>
<Typography variant="h5">{t('Action Type Chart')}</Typography>
<ResponsiveContainer width="100%" height="100%">
<ResponsiveContainer id={id} width="100%" height="100%">
<PieChart>
<Pie
data={data}
Expand Down
8 changes: 5 additions & 3 deletions src/components/dashboard/ActionTotalCount.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@ class ActionTotalCount extends PureComponent {
classes: PropTypes.shape({
actionCounter: PropTypes.string.isRequired,
}).isRequired,
id: PropTypes.string,
};

static defaultProps = {
actions: [],
id: null,
};

render() {
const { classes, t, actions } = this.props;
const { classes, t, actions, id } = this.props;

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

return (
<>
<div id={id}>
<Typography variant="h5">{t('Total Action Count')}</Typography>
<Grid container justify="center" alignItems="center">
<CountUp end={count} duration={5} className={classes.actionCounter} />
</Grid>
</>
</div>
);
}
}
Expand Down
68 changes: 48 additions & 20 deletions src/components/dashboard/Dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,19 @@ import {
SELECT_ALL_USERS_ID,
USER_MODES,
} from '../../config/constants';
import { DASHBOARD_MAIN_ID } from '../../config/selectors';

const styles = theme => ({
import {
DASHBOARD_BAR_CHART_ID,
DASHBOARD_ACTION_EDITOR_ID,
DASHBOARD_MAIN_ID,
DASHBOARD_NO_ACTION_MESSAGE_ID,
DASHBOARD_LINE_CHART_ID,
DASHBOARD_PIE_CHART_ID,
DASHBOARD_TOTAL_COUNT_ID,
DASHBOARD_USER_FILTER_ID,
DASHBOARD_SPACE_FILTER_ID,
} from '../../config/selectors';

const styles = (theme) => ({
dashboard: { padding: theme.spacing(3) },
dashboardGridItem: { height: '350px' },
drawerHeader: {
Expand Down Expand Up @@ -91,24 +101,25 @@ export class Dashboard extends Component {
dispatchGetDatabase();
}

handleSpaceChange = event => {
handleSpaceChange = (event) => {
this.setState({ spaceId: event.target.value });
};

handleUserChange = event => {
handleUserChange = (event) => {
this.setState({ filteredUserId: event.target.value });
};

renderSpaceFilter = () => {
const { database, t } = this.props;
const { spaceId } = this.state;
const { spaces = [] } = database;

if (!database) {
return <Loader />;
}

return (
<FormControl variant="outlined" fullWidth>
<FormControl id={DASHBOARD_SPACE_FILTER_ID} variant="outlined" fullWidth>
<InputLabel>{t('Filter by Space')}</InputLabel>
<Select
label="Filter by Space"
Expand All @@ -118,7 +129,7 @@ export class Dashboard extends Component {
<MenuItem value={SELECT_ALL_SPACES_ID}>
<em>{t('All Spaces')}</em>
</MenuItem>
{database.spaces.map(space => (
{spaces.map((space) => (
<MenuItem value={space.id}>{space.name}</MenuItem>
))}
</Select>
Expand All @@ -139,7 +150,7 @@ export class Dashboard extends Component {
}

return (
<FormControl variant="outlined" fullWidth>
<FormControl id={DASHBOARD_USER_FILTER_ID} variant="outlined" fullWidth>
<InputLabel>{t('Filter by User')}</InputLabel>
<Select
label="Filter by User"
Expand All @@ -149,15 +160,15 @@ export class Dashboard extends Component {
<MenuItem value={SELECT_ALL_USERS_ID}>
<em>{t('All Users')}</em>
</MenuItem>
{database.users.map(user => (
{database.users.map((user) => (
<MenuItem value={user.id}>{user.username}</MenuItem>
))}
</Select>
</FormControl>
);
};

renderActionWidgets = filteredActions => {
renderActionWidgets = (filteredActions) => {
const { database, classes } = this.props;

return (
Expand All @@ -169,16 +180,29 @@ export class Dashboard extends Component {
alignItems="center"
>
<Grid item xs={12} sm={6} className={classes.dashboardGridItem}>
<ActionBarChart spaces={database.spaces} actions={filteredActions} />
<ActionBarChart
id={DASHBOARD_BAR_CHART_ID}
spaces={database.spaces}
actions={filteredActions}
/>
</Grid>
<Grid item xs={12} sm={6} className={classes.dashboardGridItem}>
<ActionLineChart actions={filteredActions} />
<ActionLineChart
id={DASHBOARD_LINE_CHART_ID}
actions={filteredActions}
/>
</Grid>
<Grid item xs={12} sm={6} className={classes.dashboardGridItem}>
<ActionPieChart actions={filteredActions} />
<ActionPieChart
id={DASHBOARD_PIE_CHART_ID}
actions={filteredActions}
/>
</Grid>
<Grid item xs={12} sm={6} className={classes.dashboardGridItem}>
<ActionTotalCount actions={filteredActions} />
<ActionTotalCount
id={DASHBOARD_TOTAL_COUNT_ID}
actions={filteredActions}
/>
</Grid>
</Grid>
);
Expand All @@ -188,15 +212,14 @@ export class Dashboard extends Component {
const { t, database, userMode, userId } = this.props;
const { spaceId, filteredUserId } = this.state;

let filteredActions = database.actions;
const { users } = database;
let filteredActions = database.actions || [];
const { users = [] } = database;
const isStudent = userMode === USER_MODES.STUDENT;

filteredActions = filteredActions.filter(({ user }) => {
const isOwnAction = user === userId;
const actionUser = users.find(({ id }) => id === user);
const isAccessible =
actionUser && actionUser.settings.actionAccessibility;
const isAccessible = actionUser?.settings?.actionAccessibility;
const filteredUserSelected = filteredUserId !== SELECT_ALL_USERS_ID;

// filter action per user if userMode is student
Expand All @@ -222,10 +245,15 @@ export class Dashboard extends Component {
return filteredActions.length ? (
<>
{this.renderActionWidgets(filteredActions)}
<ActionEditor actions={filteredActions} />
<ActionEditor
id={DASHBOARD_ACTION_EDITOR_ID}
actions={filteredActions}
/>
</>
) : (
<Typography>{t('No action has been recorded.')}</Typography>
<Typography id={DASHBOARD_NO_ACTION_MESSAGE_ID}>
{t('No action has been recorded.')}
</Typography>
);
};

Expand Down
Loading

0 comments on commit 9b1dd21

Please sign in to comment.