Skip to content

Commit

Permalink
Merge pull request #33800 from code-dot-org/dtl_candidate_9666fd2b
Browse files Browse the repository at this point in the history
  • Loading branch information
deploy-code-org committed Mar 23, 2020
2 parents 765d24b + 9666fd2 commit 20169f6
Show file tree
Hide file tree
Showing 71 changed files with 1,486 additions and 692 deletions.
9 changes: 9 additions & 0 deletions apps/i18n/common/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,12 @@
"lockStageInstructions": "Once time is up, \"Lock stage\" to hide questions.",
"lockWhenDone": "Lock when students finish",
"loggedIn": "Logged in: {partner}",
"loginCardForPrint1": "1.) Go to [{directLink}]({directLink}) or to [{joinLink}]({joinLink}) and type in your 6-letter section code: **{sectionCode}**",
"loginCardForPrint2": "2.) Choose your name: **{studentName}**",
"loginCardForPrint3Picture": "3.) Choose your secret picture:",
"loginCardForPrint3Word": "3.) Type in your secret words: **{secretWords}**",
"loginCardForPrint4": "4.) Click the sign in button.",
"loginCardSectionName": "Section name: **{sectionName}**",
"loginCard_directUrl": "Direct URL:",
"loginCard_name": "Name:",
"loginCard_instructions": "Visit {url} and enter {code}",
Expand Down Expand Up @@ -1057,6 +1063,8 @@
"noClassroomsFound": "No classrooms found.",
"noIconsFound": "No icons found",
"noLibraries": "You currently have no libraries.",
"noLibrariesInProject": "You have no libraries in your project. Try adding one from your class list or from an ID.",
"noLibrariesInClass": "No one in your class has published a library. Try adding one from an ID.",
"noMenuItemsAvailable": "No menu items available.",
"nominateATeacher": "Nominate a Teacher",
"noStudentsInSection": "There are no other students in this section.",
Expand Down Expand Up @@ -1145,6 +1153,7 @@
"preview": "Preview",
"printCertificate": "Print Certificate",
"printCertificates": "Print Certificates",
"printLoginCard": "Print login card",
"printLoginCards": "Print Login Cards",
"printLoginCardExplanation": "Print out cards with your students' login information.",
"printLoginCards_button": "Print login cards",
Expand Down
71 changes: 33 additions & 38 deletions apps/src/code-studio/components/libraries/LibraryManagerDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export class LibraryManagerDialog extends React.Component {

state = {
importLibraryId: '',
libraries: [],
projectLibraries: [],
classLibraries: [],
cachedClassLibraries: [],
viewingLibrary: {},
Expand All @@ -114,18 +114,19 @@ export class LibraryManagerDialog extends React.Component {
}

onOpen = () => {
this.setState({libraries: dashboard.project.getProjectLibraries() || []});
const libraries = dashboard.project.getProjectLibraries() || [];
this.setState({projectLibraries: libraries});

let libraryClient = new LibraryClientApi();
libraryClient.getClassLibraries(
classLibraries => {
const projectLibraries = mapUserNameToProjectLibraries(
this.state.libraries,
libraries,
classLibraries
);
this.setState({
classLibraries,
libraries: projectLibraries
projectLibraries: projectLibraries
});
},
error => {
Expand All @@ -139,23 +140,22 @@ export class LibraryManagerDialog extends React.Component {
};

addLibraryToProject = libraryJson => {
const {projectLibraries} = this.state;
if (!libraryJson) {
return;
}

dashboard.project.setProjectLibraries([
...this.state.libraries,
libraryJson
]);
this.setState({libraries: dashboard.project.getProjectLibraries()});
dashboard.project.setProjectLibraries([...projectLibraries, libraryJson]);
this.setState({projectLibraries: dashboard.project.getProjectLibraries()});
};

updateLibraryInProject = libraryJson => {
const {projectLibraries} = this.state;
if (!libraryJson) {
return;
}

let libraries = [...this.state.libraries];
let libraries = [...projectLibraries];
const libraryIndex = libraries.findIndex(
library => library.channelId === libraryJson.channelId
);
Expand All @@ -176,8 +176,8 @@ export class LibraryManagerDialog extends React.Component {
};

fetchLatestLibrary = (channelId, callback) => {
let {cachedClassLibraries} = this.state;
let cachedLibrary = cachedClassLibraries.find(
const {cachedClassLibraries} = this.state;
const cachedLibrary = cachedClassLibraries.find(
library => library.channelId === channelId
);
if (cachedLibrary) {
Expand Down Expand Up @@ -212,25 +212,21 @@ export class LibraryManagerDialog extends React.Component {
};

removeLibrary = libraryName => {
const {projectLibraries} = this.state;
dashboard.project.setProjectLibraries(
this.state.libraries.filter(library => {
projectLibraries.filter(library => {
return library.name !== libraryName;
})
);
this.setState({libraries: dashboard.project.getProjectLibraries()});
this.setState({projectLibraries: dashboard.project.getProjectLibraries()});
};

displayProjectLibraries = () => {
let {libraries} = this.state;
if (!Array.isArray(libraries) || !libraries.length) {
return (
<div style={styles.message}>
You have no libraries in your project. Try adding one from your class
list or from an ID.
</div>
);
const {projectLibraries} = this.state;
if (!Array.isArray(projectLibraries) || !projectLibraries.length) {
return <div style={styles.message}>{i18n.noLibrariesInProject()}</div>;
}
return libraries.map(library => {
return projectLibraries.map(library => {
return (
<LibraryListItem
key={library.name}
Expand All @@ -246,14 +242,9 @@ export class LibraryManagerDialog extends React.Component {
};

displayClassLibraries = () => {
let {classLibraries} = this.state;
const {classLibraries} = this.state;
if (!Array.isArray(classLibraries) || !classLibraries.length) {
return (
<div style={styles.message}>
No one in your class has published a library. Try adding one from an
ID.
</div>
);
return <div style={styles.message}>{i18n.noLibrariesInClass()}</div>;
}
return classLibraries.map(library => {
return (
Expand Down Expand Up @@ -285,8 +276,14 @@ export class LibraryManagerDialog extends React.Component {
};

render() {
let {isOpen} = this.props;
let {isViewingCode, importLibraryId, viewingLibrary} = this.state;
const {isOpen} = this.props;
const {
isViewingCode,
importLibraryId,
viewingLibrary,
isLoading,
error
} = this.state;
return (
<div>
<BaseDialog
Expand Down Expand Up @@ -314,15 +311,13 @@ export class LibraryManagerDialog extends React.Component {
this.fetchLatestLibrary(importLibraryId, this.addLibraryById);
}}
type="button"
disabled={!this.state.importLibraryId}
disabled={!importLibraryId}
>
{this.state.isLoading && (
<FontAwesome icon="spinner" className="fa-spin" />
)}
{!this.state.isLoading && i18n.add()}
{isLoading && <FontAwesome icon="spinner" className="fa-spin" />}
{!isLoading && i18n.add()}
</button>
</div>
<div style={styles.error}>{this.state.error}</div>
<div style={styles.error}>{error}</div>
</BaseDialog>
<LibraryViewCode
isOpen={isViewingCode}
Expand Down
13 changes: 6 additions & 7 deletions apps/src/code-studio/components/libraries/LibraryViewCode.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* globals droplet */
import PropTypes from 'prop-types';
import React from 'react';
import Dialog, {Body, Title} from '@cdo/apps/templates/Dialog';
import BaseDialog from '@cdo/apps/templates/BaseDialog';
import {Body, Title} from '@cdo/apps/templates/Dialog';
import color from '@cdo/apps/util/color';

const DEFAULT_MARGIN = 7;
Expand Down Expand Up @@ -54,19 +55,17 @@ export default class LibraryViewCode extends React.Component {
render() {
const {isOpen, onClose, library} = this.props;
return (
<Dialog isOpen={isOpen} handleClose={onClose} useUpdatedStyles>
<Title>
<div>{library.name}</div>
</Title>
<BaseDialog isOpen={isOpen} handleClose={onClose} useUpdatedStyles>
<Title>{library.name}</Title>
<Body>
<div style={{textAlign: 'left'}}>
<div style={styles.message}>{library.description}</div>
<p style={styles.message}>{library.description}</p>
<div className="libraryCodeViewerContainer" style={styles.code}>
<div ref="libraryCodeViewer" />
</div>
</div>
</Body>
</Dialog>
</BaseDialog>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ export default class ChoiceResponses extends React.Component {
numRespondents: PropTypes.number,
answerType: PropTypes.string.isRequired,
possibleAnswers: PropTypes.array.isRequired,
otherText: PropTypes.string
possibleAnswersMap: PropTypes.object,
otherText: PropTypes.string,
otherAnswers: PropTypes.array
};

getTotalRespondents() {
Expand Down Expand Up @@ -75,12 +77,23 @@ export default class ChoiceResponses extends React.Component {
<tr key={i}>
<td>{this.formatPercentage(count / this.getTotalRespondents())}</td>
<td style={{paddingLeft: '20px'}}>{count}</td>
<td style={{paddingLeft: '20px'}}>{possibleAnswer}</td>
<td style={{paddingLeft: '20px'}}>
{this.getPossibleAnswerText(possibleAnswer)}
</td>
</tr>
);
});
}

getPossibleAnswerText(possibleAnswer) {
const {possibleAnswersMap} = this.props;
if (possibleAnswersMap && possibleAnswersMap[possibleAnswer]) {
return possibleAnswersMap[possibleAnswer];
} else {
return possibleAnswer;
}
}

renderPerFacilitatorAnswerCounts() {
const facilitatorNames = Object.keys(this.props.answers);
const showTotalCount = facilitatorNames.length > 1;
Expand Down Expand Up @@ -120,7 +133,7 @@ export default class ChoiceResponses extends React.Component {

return (
<tr key={i}>
<td>{possibleAnswer}</td>
<td>{this.getPossibleAnswerText(possibleAnswer)}</td>
{countsByFacilitator.map((count, j) => [
<td style={{paddingLeft: '20px'}} key={`${j}.count`}>
{count}
Expand Down Expand Up @@ -155,20 +168,22 @@ export default class ChoiceResponses extends React.Component {
this.props.answerType === 'scale'
? this.props.possibleAnswers.map(x => x.split(' ')[0])
: this.props.possibleAnswers;
let otherAnswers;
if (this.props.perFacilitator) {
let givenAnswers = Object.values(this.props.answers).reduce(
(set, answers) => {
return new Set(Object.keys(answers).concat(...set.values()));
},
new Set()
);
otherAnswers = _.difference(givenAnswers, possibleAnswers);
} else {
otherAnswers = _.difference(
Object.keys(this.props.answers),
possibleAnswers
);
let otherAnswers = this.props.otherAnswers;
if (!otherAnswers) {
if (this.props.perFacilitator) {
let givenAnswers = Object.values(this.props.answers).reduce(
(set, answers) => {
return new Set(Object.keys(answers).concat(...set.values()));
},
new Set()
);
otherAnswers = _.difference(givenAnswers, possibleAnswers);
} else {
otherAnswers = _.difference(
Object.keys(this.props.answers),
possibleAnswers
);
}
}

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// This component renders a survey answer for a matrix question
// It will split the matrix into individual questions and display them with
// the title "matrix title -> question title"

import PropTypes from 'prop-types';
import React from 'react';
import _ from 'lodash';
import ChoiceResponses from './choice_responses.jsx';

export default class MatrixChoiceResponses extends React.Component {
static propTypes = {
answer: PropTypes.object.isRequired,
question: PropTypes.object.isRequired,
section: PropTypes.string.isRequired,
questionId: PropTypes.string.isRequired
};

render() {
const {section, answer, question, questionId} = this.props;

return (
<div>
{_.compact(
Object.keys(question['rows']).map(innerQuestionId => {
const innerAnswer = answer[innerQuestionId];
if (!innerAnswer) {
return null;
}
const numRespondents = answer.num_respondents;
let possibleAnswersMap = question['columns'];
let parsedQuestionName = `${question['title']} -> ${
question['rows'][innerQuestionId]
}`;
return (
<ChoiceResponses
perFacilitator={section === 'facilitator'}
numRespondents={numRespondents}
question={parsedQuestionName}
answers={innerAnswer}
possibleAnswers={Object.keys(possibleAnswersMap)}
possibleAnswersMap={possibleAnswersMap}
key={`${questionId}-${innerQuestionId}`}
answerType={'singleSelect'}
/>
);
})
)}
</div>
);
}
}

0 comments on commit 20169f6

Please sign in to comment.