Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assessments: Add Multiple Choice Answer Table Component #22054

Merged
merged 11 commits into from
Apr 26, 2018
3 changes: 3 additions & 0 deletions apps/i18n/common/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
"anotherHoCButton": "Continue learning",
"anotherHoCDesc": "Keep it up! Try your next Hour of Code activity.",
"anotherHoCTitle": "Try another Hour of Code",
"answerOptionA": "A",
"answerOptionB": "B",
"answersVisible": "Answers visible (read-only)",
"archiveSection": "Archive Section",
"applabMarketingButton": "Learn more",
Expand Down Expand Up @@ -667,6 +669,7 @@
"noMenuItemsAvailable": "No menu items available.",
"none": "None",
"note": "*Note:",
"notAnswered": "Not Answered",
"notStarted": "Not started",
"nPoints": "{numPoints, plural, one {1 point} other {# points}}",
"numBlocksNeeded": "Congratulations! You completed Puzzle {puzzleNumber}. (However, you could have used only {numBlocks, plural, one {1 block} other {# blocks}}.)",
Expand Down
155 changes: 155 additions & 0 deletions apps/src/templates/sectionAssessments/MultipleChoiceOverviewTable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import React, {Component, PropTypes} from 'react';
import {Table, sort} from 'reactabular';
import {tableLayoutStyles, sortableOptions} from "../tables/tableConstants";
import commonMsg from '@cdo/locale';
import wrappedSortable from '../tables/wrapped_sortable';
import orderBy from 'lodash/orderBy';

export const COLUMNS = {
QUESTION: 0,
ANSWER_1: 1,
ANSWER_2: 2,
NOT_ANSWERED: 3,
};

const questionAnswerDataPropType = PropTypes.shape({
id: PropTypes.number.isRequired,
question: PropTypes.string,
percentAnsweredOptionOne: PropTypes.string,
percentAnsweredOptionTwo: PropTypes.string,
notAnswered: PropTypes.string,
});

class MultipleChoiceOverviewTable extends Component {
static propTypes= {
questionAnswerData: PropTypes.arrayOf(questionAnswerDataPropType),
};

state = {
[COLUMNS.NAME]: {
direction: 'desc',
position: 0
}
};

getSortingColumns = () => {
return this.state.sortingColumns || {};
};

onSort = (selectedColumn) => {
this.setState({
sortingColumns: sort.byColumn({
sortingColumns: this.state.sortingColumns,
// Custom sortingOrder removes 'no-sort' from the cycle
sortingOrder: {
FIRST: 'asc',
asc: 'desc',
desc: 'asc'
},
selectedColumn
})
});
};

getColumns = (sortable) => {
let dataColumns = [
{
property: 'question',
header: {
label: commonMsg.question(),
props: {
style: {
...tableLayoutStyles.headerCell,
}},
transforms: [sortable],
},
cell: {
props: {
style: {
...tableLayoutStyles.cell,
}}
}
},
{
property: 'percentAnsweredOptionOne',
header: {
label: commonMsg.answerOptionA(),
props: {
style: {
...tableLayoutStyles.headerCell,
width: 90,
}},
},
cell: {
props: {
style: {
...tableLayoutStyles.cell,
width: 90,
}}
}
},
{
property: 'percentAnsweredOptionTwo',
header: {
label: commonMsg.answerOptionB(),
props: {
style: {
...tableLayoutStyles.headerCell,
width: 90,
}},
},
cell: {
props: {
style: {
...tableLayoutStyles.cell,
width: 90,
}}
}
},
{
property: 'notAnswered',
header: {
label: commonMsg.notAnswered(),
props: {
style: {
...tableLayoutStyles.headerCell,
width: 120,
}},
},
cell: {
props: {
style: {
...tableLayoutStyles.cell,
width: 120,
}}
}
},
];
return dataColumns;
};

render() {
// Define a sorting transform that can be applied to each column
const sortable = wrappedSortable(this.getSortingColumns, this.onSort, sortableOptions);
const columns = this.getColumns(sortable);
const sortingColumns = this.getSortingColumns();

const sortedRows = sort.sorter({
columns,
sortingColumns,
sort: orderBy,
})(this.props.questionAnswerData);

return (
<Table.Provider
columns={columns}
style={tableLayoutStyles.table}
>
<Table.Header />
<Table.Body rows={sortedRows} rowKey="id" />
</Table.Provider>
);
}
}

export default MultipleChoiceOverviewTable;
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import MultipleChoiceOverviewTable from './MultipleChoiceOverviewTable';

const multipleChoiceData = [
{
id: 1,
question: '1. What is a variable?',
percentAnsweredOptionOne: '80%',
percentAnsweredOptionTwo: '15%',
notAnswered: '5%',
},
{
id: 2,
question: '2. What is a 4-bit number for the decimal number Ten(10)',
percentAnsweredOptionOne: '20%',
percentAnsweredOptionTwo: '60%',
notAnswered: '20%'
},
{
id: 3,
question: '3. What is the minimum number of bits you will need to encode the 26 letters of the alphabet',
percentAnsweredOptionOne: '35%',
percentAnsweredOptionTwo: '65%',
notAnswered: '0%'
}
];

export default storybook => {
return storybook
.storiesOf('SectionAssessments/MultipleChoiceOverviewTable', module)
.addStoryTable([
{
name: 'Table for assessments',
description: 'Ability to see assessment overview for the entire class',
story: () => (
<MultipleChoiceOverviewTable
questionAnswerData={multipleChoiceData}
/>
)
},
]);
};