-
Notifications
You must be signed in to change notification settings - Fork 479
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #36786 from code-dot-org/dtl_candidate_47d176a2
- Loading branch information
Showing
47 changed files
with
2,306 additions
and
323 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
139 changes: 139 additions & 0 deletions
139
apps/src/lib/levelbuilder/lesson-editor/ActivitiesEditor.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import React, {Component} from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import color from '@cdo/apps/util/color'; | ||
import ActivityCard from '@cdo/apps/lib/levelbuilder/lesson-editor/ActivityCard'; | ||
import Activity from '@cdo/apps/templates/lessonOverview/activities/Activity'; | ||
import {connect} from 'react-redux'; | ||
import {addActivity} from '@cdo/apps/lib/levelbuilder/lesson-editor/activitiesEditorRedux'; | ||
|
||
const styles = { | ||
activityEditAndPreview: { | ||
display: 'flex', | ||
flexDirection: 'row' | ||
}, | ||
editor: { | ||
width: '50%' | ||
}, | ||
preview: { | ||
width: '45%', | ||
marginLeft: 20 | ||
}, | ||
previewBox: { | ||
border: '1px solid black', | ||
padding: 10 | ||
}, | ||
addActivity: { | ||
fontSize: 14, | ||
color: 'white', | ||
background: color.cyan, | ||
border: `1px solid ${color.cyan}`, | ||
boxShadow: 'none' | ||
} | ||
}; | ||
|
||
/* | ||
A GUI for editing activities in a lesson. Shows | ||
the editing fields side by side with a preview of how they will | ||
look in the lesson plan. | ||
*/ | ||
|
||
class ActivitiesEditor extends Component { | ||
static propTypes = { | ||
//redux | ||
activities: PropTypes.array, | ||
addActivity: PropTypes.func | ||
}; | ||
|
||
constructor(props) { | ||
super(props); | ||
|
||
this.state = { | ||
targetActivitySectionPos: null | ||
}; | ||
} | ||
|
||
handleAddActivity = () => { | ||
this.props.addActivity( | ||
this.props.activities.length, | ||
this.generateActivityKey() | ||
); | ||
}; | ||
|
||
generateActivityKey = () => { | ||
let activityNumber = this.props.activities.length + 1; | ||
while ( | ||
this.props.activities.some( | ||
activity => activity.key === `activity-${activityNumber}` | ||
) | ||
) { | ||
activityNumber++; | ||
} | ||
|
||
return `activity-${activityNumber}`; | ||
}; | ||
|
||
setTargetActivitySection = targetActivitySectionPos => { | ||
this.setState({targetActivitySectionPos}); | ||
}; | ||
|
||
// To be populated with the bounding client rect of each ActivitySectionCard element. | ||
activitySectionMetrics = {}; | ||
|
||
setActivitySectionMetrics = (metrics, activitySectionPosition) => { | ||
this.activitySectionMetrics[activitySectionPosition] = metrics; | ||
}; | ||
|
||
render() { | ||
const {activities} = this.props; | ||
|
||
return ( | ||
<div> | ||
<div style={styles.activityEditAndPreview}> | ||
<div style={styles.editor}> | ||
{activities.map(activity => { | ||
return ( | ||
<ActivityCard | ||
activity={activity} | ||
activitiesCount={activities.length} | ||
key={activity.key} | ||
setActivitySectionMetrics={this.setActivitySectionMetrics} | ||
setTargetActivitySection={this.setTargetActivitySection} | ||
targetActivitySectionPos={this.state.targetActivitySectionPos} | ||
activitySectionMetrics={this.activitySectionMetrics} | ||
/> | ||
); | ||
})} | ||
<button | ||
onMouseDown={this.handleAddActivity} | ||
className="btn" | ||
style={styles.addActivity} | ||
type="button" | ||
> | ||
<i style={{marginRight: 7}} className="fa fa-plus-circle" /> | ||
Add Activity | ||
</button> | ||
</div> | ||
<div style={styles.preview}> | ||
<h2>Preview</h2> | ||
<div style={styles.previewBox}> | ||
{activities.map(activity => { | ||
return <Activity activity={activity} key={activity.key} />; | ||
})} | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export const UnconnectedActivitiesEditor = ActivitiesEditor; | ||
|
||
export default connect( | ||
state => ({ | ||
activities: state.activities | ||
}), | ||
{ | ||
addActivity | ||
} | ||
)(ActivitiesEditor); |
167 changes: 167 additions & 0 deletions
167
apps/src/lib/levelbuilder/lesson-editor/ActivitiesEditor.story.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
import React from 'react'; | ||
import ActivitiesEditor from '@cdo/apps/lib/levelbuilder/lesson-editor/ActivitiesEditor'; | ||
import {createStoreWithReducers, registerReducers} from '@cdo/apps/redux'; | ||
import reducers, { | ||
init | ||
} from '@cdo/apps/lib/levelbuilder/lesson-editor/activitiesEditorRedux'; | ||
import {Provider} from 'react-redux'; | ||
|
||
const activities = [ | ||
{ | ||
key: 'activity-1', | ||
displayName: 'Main Activity', | ||
position: 1, | ||
time: 20, | ||
activitySections: [ | ||
{ | ||
key: 'section-3', | ||
position: 1, | ||
displayName: 'Making programs', | ||
remarks: true, | ||
slide: false, | ||
levels: [], | ||
text: | ||
'Today we are going to be looking at some sample apps to explore their purpose and function.', | ||
tips: [] | ||
}, | ||
{ | ||
key: 'section-1', | ||
position: 2, | ||
displayName: '', | ||
remarks: false, | ||
slide: true, | ||
levels: [], | ||
text: 'In this activity you will be learning about making activities.', | ||
tips: [ | ||
{ | ||
key: 'tip-1', | ||
type: 'teachingTip', | ||
markdown: | ||
'After students are finished writing in their journals, discuss as a class or collect the journals to review student answers. \n- An input could be a user clicking a button or tapping the screen. \n- An output could be an image displayed or a sound played' | ||
} | ||
] | ||
}, | ||
{ | ||
tips: [], | ||
key: 'progression-1', | ||
position: 3, | ||
displayName: 'Programming Progression', | ||
remarks: false, | ||
slide: false, | ||
text: 'This progression teaches you programming!', | ||
levels: [ | ||
{ | ||
status: 'not started', | ||
url: 'https://levelbuilder-studio.code.org/levels/598/edit', | ||
name: 'Level 1', | ||
icon: 'fa-desktop', | ||
isUnplugged: false, | ||
levelNumber: 1, | ||
isCurrentLevel: false, | ||
isConceptLevel: true, | ||
sublevels: [], | ||
position: 1, | ||
activeId: 1, | ||
ids: [1], | ||
kind: 'puzzle', | ||
skin: null, | ||
videoKey: null, | ||
concepts: '', | ||
conceptDifficulty: '', | ||
named: false, | ||
assessment: false, | ||
challenge: false | ||
}, | ||
{ | ||
status: 'not started', | ||
url: 'https://levelbuilder-studio.code.org/levels/598/edit', | ||
icon: 'fa-desktop', | ||
name: 'Level 2', | ||
isUnplugged: false, | ||
levelNumber: 2, | ||
isCurrentLevel: false, | ||
isConceptLevel: false, | ||
sublevels: [], | ||
position: 2, | ||
activeId: 2, | ||
ids: [2, 3], | ||
kind: 'assessment', | ||
skin: null, | ||
videoKey: null, | ||
concepts: '', | ||
conceptDifficulty: '', | ||
named: false, | ||
assessment: true, | ||
challenge: false | ||
} | ||
] | ||
}, | ||
{ | ||
key: 'section-2', | ||
displayName: 'Discussion', | ||
position: 4, | ||
remarks: false, | ||
slide: false, | ||
levels: [], | ||
text: | ||
'**Prompt:** With a partner, discuss the following and note down in your journal:\n - How does the user interact with the app?\n - What is the overall purpose of this app?\n - Who is the target audience?\n\n**Share Out:** As a class, discuss student answers to the discussion questions.', | ||
tips: [ | ||
{ | ||
key: 'tip-2', | ||
type: 'discussionGoal', | ||
markdown: 'Make sure to get to the point' | ||
}, | ||
{ | ||
key: 'tip-3', | ||
type: 'assessmentOpportunity', | ||
markdown: 'Are students getting it?' | ||
} | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
key: 'activity-2', | ||
displayName: '', | ||
time: 0, | ||
position: 2, | ||
activitySections: [ | ||
{ | ||
key: 'section-1', | ||
text: '', | ||
displayName: '', | ||
remarks: false, | ||
slide: false, | ||
tips: [], | ||
levels: [], | ||
position: 1 | ||
} | ||
] | ||
} | ||
]; | ||
|
||
const levelKeyList = { | ||
1: 'Level 1', | ||
2: 'Level 2 - 1', | ||
3: 'Level 2 - 2', | ||
4: 'blockly:Studio:playlab_1' | ||
}; | ||
|
||
const createStore = () => { | ||
registerReducers({...reducers}); | ||
const store = createStoreWithReducers(); | ||
store.dispatch(init(activities, levelKeyList)); | ||
return store; | ||
}; | ||
export default storybook => { | ||
storybook.storiesOf('ActivitiesEditor', module).addStoryTable([ | ||
{ | ||
name: 'ActivitiesEditor', | ||
story: () => ( | ||
<Provider store={createStore()}> | ||
<ActivitiesEditor /> | ||
</Provider> | ||
) | ||
} | ||
]); | ||
}; |
Oops, something went wrong.