Skip to content

Commit

Permalink
Merge pull request #24541 from code-dot-org/dtp_candidate_147f4371
Browse files Browse the repository at this point in the history
DTP (Test > Production: 147f437)
  • Loading branch information
joshlory committed Aug 29, 2018
2 parents cd1d0de + c943151 commit eb8b704
Show file tree
Hide file tree
Showing 190 changed files with 39,311 additions and 1,545 deletions.
41 changes: 25 additions & 16 deletions apps/Gruntfile.js
Expand Up @@ -331,7 +331,7 @@ describe('entry tests', () => {
var OUTPUT_DIR = 'build/package/js/';
config.exec = {
convertScssVars: './script/convert-scss-variables.js',
generateSharedConstants: './script/generateSharedConstants.rb'
generateSharedConstants: 'bundle exec ./script/generateSharedConstants.rb'
};

var junitReporterBaseConfig = {
Expand Down Expand Up @@ -441,19 +441,10 @@ describe('entry tests', () => {
var appsEntries = _.fromPairs(appsToBuild.map(function (app) {
return [app, './src/sites/studio/pages/levels-' + app + '-main.js'];
}));

var codeStudioEntries = {
'blockly': './src/sites/studio/pages/blockly.js',
'code-studio': './src/sites/studio/pages/code-studio.js',
'levelbuilder': './src/sites/studio/pages/levelbuilder.js',
'levelbuilder_applab': './src/sites/studio/pages/levelbuilder_applab.js',
'levelbuilder_craft': './src/sites/studio/pages/levelbuilder_craft.js',
'levelbuilder_edit_script': './src/sites/studio/pages/levelbuilder_edit_script.js',
'levelbuilder_gamelab': './src/sites/studio/pages/levelbuilder_gamelab.js',
'levelbuilder_studio': './src/sites/studio/pages/levelbuilder_studio.js',
'levelbuilder_pixelation': './src/sites/studio/pages/levelbuilder_pixelation.js',
'blocks/edit': './src/sites/studio/pages/blocks/edit.js',
'shared_blockly_functions/edit':'./src/sites/studio/pages/shared_blockly_functions/edit.js',
'libraries/edit': './src/sites/studio/pages/libraries/edit.js',
'levels/contract_match': './src/sites/studio/pages/levels/contract_match.jsx',
'levels/_curriculum_reference': './src/sites/studio/pages/levels/_curriculum_reference.js',
'levels/_dialog': './src/sites/studio/pages/levels/_dialog.js',
Expand All @@ -465,10 +456,6 @@ describe('entry tests', () => {
'levels/textMatch': './src/sites/studio/pages/levels/textMatch.js',
'levels/widget': './src/sites/studio/pages/levels/widget.js',
'levels/_external_link': './src/sites/studio/pages/levels/_external_link.js',
'levels/editors/_blockly': './src/sites/studio/pages/levels/editors/_blockly.js',
'levels/editors/_droplet': './src/sites/studio/pages/levels/editors/_droplet.js',
'levels/editors/_all': './src/sites/studio/pages/levels/editors/_all.js',
'levels/editors/_dsl': './src/sites/studio/pages/levels/editors/_dsl.js',
'projects/index': './src/sites/studio/pages/projects/index.js',
'projects/public': './src/sites/studio/pages/projects/public.js',
'projects/featured': './src/sites/studio/pages/projects/featured.js',
Expand All @@ -486,10 +473,27 @@ describe('entry tests', () => {
'congrats/index': './src/sites/studio/pages/congrats/index.js',
'courses/index': './src/sites/studio/pages/courses/index.js',
'courses/show': './src/sites/studio/pages/courses/show.js',
'courses/edit': './src/sites/studio/pages/courses/edit.js',
'devise/registrations/edit': './src/sites/studio/pages/devise/registrations/edit.js',
};

var internalEntries = {
'blocks/edit': './src/sites/studio/pages/blocks/edit.js',
'courses/edit': './src/sites/studio/pages/courses/edit.js',
'levelbuilder': './src/sites/studio/pages/levelbuilder.js',
'levelbuilder_applab': './src/sites/studio/pages/levelbuilder_applab.js',
'levelbuilder_craft': './src/sites/studio/pages/levelbuilder_craft.js',
'levelbuilder_edit_script': './src/sites/studio/pages/levelbuilder_edit_script.js',
'levelbuilder_gamelab': './src/sites/studio/pages/levelbuilder_gamelab.js',
'levelbuilder_pixelation': './src/sites/studio/pages/levelbuilder_pixelation.js',
'levelbuilder_studio': './src/sites/studio/pages/levelbuilder_studio.js',
'levels/editors/_all': './src/sites/studio/pages/levels/editors/_all.js',
'levels/editors/_blockly': './src/sites/studio/pages/levels/editors/_blockly.js',
'levels/editors/_droplet': './src/sites/studio/pages/levels/editors/_droplet.js',
'levels/editors/_dsl': './src/sites/studio/pages/levels/editors/_dsl.js',
'libraries/edit': './src/sites/studio/pages/libraries/edit.js',
'shared_blockly_functions/edit':'./src/sites/studio/pages/shared_blockly_functions/edit.js',
};

var otherEntries = {
essential: './src/sites/studio/pages/essential.js',
plc: './src/sites/studio/pages/plc.js',
Expand Down Expand Up @@ -527,6 +531,7 @@ describe('entry tests', () => {
'pd/application/principal_approval_application/new': './src/sites/studio/pages/pd/application/principal_approval_application/new.js',
'pd/teachercon1819_registration/new': './src/sites/studio/pages/pd/teachercon1819_registration/new.js',
'pd/fit_weekend1819_registration/new': './src/sites/studio/pages/pd/fit_weekend1819_registration/new.js',
'pd/workshop_enrollment/new': './src/sites/studio/pages/pd/workshop_enrollment/new.js',
'pd/workshop_enrollment/cancel': './src/sites/studio/pages/pd/workshop_enrollment/cancel.js',

'pd/professional_learning_landing/index': './src/sites/studio/pages/pd/professional_learning_landing/index.js',
Expand Down Expand Up @@ -571,6 +576,7 @@ describe('entry tests', () => {
{},
appsEntries,
codeStudioEntries,
internalEntries,
otherEntries
),
function (val) {
Expand Down Expand Up @@ -617,6 +623,9 @@ describe('entry tests', () => {
...(process.env.ANALYZE_BUNDLE ? [
new BundleAnalyzerPlugin({
analyzerMode: 'static',
excludeAssets: [
...Object.keys(internalEntries),
],
}),
] : []),
new StatsWriterPlugin({
Expand Down
4 changes: 2 additions & 2 deletions apps/package.json
Expand Up @@ -43,9 +43,9 @@
"@cdo/apps": "file:src",
"@cdo/interpreted": "link:../dashboard/config/libraries",
"@code-dot-org/artist": "0.2.1",
"@code-dot-org/blockly": "3.0.2",
"@code-dot-org/blockly": "3.1.0",
"@code-dot-org/bramble": "0.1.26",
"@code-dot-org/craft": "0.1.3",
"@code-dot-org/craft": "0.1.4",
"@code-dot-org/johnny-five": "0.11.1-cdo.2",
"@code-dot-org/js-interpreter-tyrant": "0.2.2",
"@code-dot-org/js-numbers": "0.1.0-cdo.0",
Expand Down
1 change: 1 addition & 0 deletions apps/script/generateSharedConstants.rb
Expand Up @@ -66,6 +66,7 @@ def parse_raw(raw)

def main
shared_content = generate_multiple_constants %w(
ARTIST_AUTORUN_OPTIONS
GAMELAB_AUTORUN_OPTIONS
LEVEL_KIND
LEVEL_STATUS
Expand Down
28 changes: 28 additions & 0 deletions apps/src/StudioApp.js
Expand Up @@ -837,6 +837,32 @@ StudioApp.prototype.reset = function (shouldPlayOpeningAnimation) {
*/
StudioApp.prototype.runButtonClick = function () {};

StudioApp.prototype.addChangeHandler = function (newHandler) {
if (!this.changeHandlers) {
this.changeHandlers = [];
}
this.changeHandlers.push(newHandler);
};

StudioApp.prototype.runChangeHandlers = function () {
if (!this.changeHandlers) {
return;
}
this.changeHandlers.forEach(handler => handler());
};

StudioApp.prototype.setupChangeHandlers = function () {
const runAllHandlers = this.runChangeHandlers.bind(this);
if (this.isUsingBlockly()) {
const blocklyCanvas = Blockly.mainBlockSpace.getCanvas();
blocklyCanvas.addEventListener('blocklyBlockSpaceChange', runAllHandlers);
} else {
this.editor.on('change', runAllHandlers);
// Droplet doesn't automatically bubble up aceEditor changes
this.editor.aceEditor.on('change', runAllHandlers);
}
};

/**
* Toggle whether run button or reset button is shown
* @param {string} button Button to show, either "run" or "reset"
Expand Down Expand Up @@ -2062,6 +2088,7 @@ StudioApp.prototype.handleEditCode_ = function (config) {
!!config.level.textModeAtStart
),
});
this.setupChangeHandlers();

if (config.level.paletteCategoryAtStart) {
this.editor.changePaletteGroup(config.level.paletteCategoryAtStart);
Expand Down Expand Up @@ -2449,6 +2476,7 @@ StudioApp.prototype.handleUsingBlockly_ = function (config) {
});
this.inject(div, options);
this.onResize();
this.setupChangeHandlers();

if (config.afterInject) {
config.afterInject();
Expand Down
3 changes: 2 additions & 1 deletion apps/src/applab/applab.js
Expand Up @@ -60,6 +60,7 @@ import {
} from '../lib/tools/jsdebugger/redux';
import JavaScriptModeErrorHandler from '../JavaScriptModeErrorHandler';
import * as makerToolkit from '../lib/kits/maker/toolkit';
import * as makerToolkitRedux from '../lib/kits/maker/redux';
import project from '../code-studio/initApp/project';
import * as thumbnailUtils from '../util/thumbnail';
import Sounds from '../Sounds';
Expand Down Expand Up @@ -1009,7 +1010,7 @@ Applab.execute = function () {
}
}

if (makerToolkit.isEnabled()) {
if (makerToolkitRedux.isEnabled(getStore().getState())) {
makerToolkit.connect({
interpreter: Applab.JSInterpreter,
onDisconnect: () => studioApp().resetButtonClick(),
Expand Down
36 changes: 25 additions & 11 deletions apps/src/code-studio/components/AudioRecorder.jsx
Expand Up @@ -33,7 +33,8 @@ export default class AudioRecorder extends React.Component {
this.slices = [];
this.state = {
audioName: "",
recording: false
recording: false,
cancelling: false
};
}

Expand Down Expand Up @@ -68,21 +69,34 @@ export default class AudioRecorder extends React.Component {
};

saveAudio = (blob) => {
assetsApi.putAsset(this.state.audioName + ".mp3", blob,
(xhr) => {
this.setState({audioName: ""});
this.props.onUploadDone(JSON.parse(xhr.response));
this.props.afterAudioSaved(AudioErrorType.NONE);
}, error => {
console.error(`Audio Failed to Save: ${error}`);
this.props.afterAudioSaved(AudioErrorType.SAVE);
});
if (!this.state.cancelling) {
assetsApi.putAsset(this.state.audioName + ".mp3", blob,
(xhr) => {
this.setState({audioName: ""});
this.props.onUploadDone(JSON.parse(xhr.response));
this.props.afterAudioSaved(AudioErrorType.NONE);
}, error => {
console.error(`Audio Failed to Save: ${error}`);
this.props.afterAudioSaved(AudioErrorType.SAVE);
});
}
};

onNameChange = (event) => {
this.setState({audioName: event.target.value});
};

onCancel = () => {
this.setState({audioName: "", recording: false, cancelling: true}, () => {
this.props.afterAudioSaved(AudioErrorType.NONE);
// Only stop recording if it's been started
if (this.recorder.state !== "inactive") {
this.recorder.stop();
}
this.setState({cancelling: false});
});
};

toggleRecord = () => {
if (this.state.recording) {
this.stopRecording();
Expand Down Expand Up @@ -129,7 +143,7 @@ export default class AudioRecorder extends React.Component {
disabled={this.state.audioName.length === 0}
/>
<Button
onClick={()=>{}}
onClick={this.onCancel}
id="cancel-record"
style={assetButtonStyles.button}
color={Button.ButtonColor.gray}
Expand Down
15 changes: 15 additions & 0 deletions apps/src/code-studio/pd/components/constants.jsx
@@ -0,0 +1,15 @@
import {PropTypes} from 'react';

const SchoolInfoPropType = PropTypes.shape({
school_id: PropTypes.string,
school_name: PropTypes.string,
school_state: PropTypes.string,
school_type: PropTypes.string,
school_zip: PropTypes.string,
school_district_name: PropTypes.string,
school_district_other: PropTypes.oneOf(["true", "false"])
});

export {
SchoolInfoPropType
};
116 changes: 116 additions & 0 deletions apps/src/code-studio/pd/components/customSchoolInfo.jsx
@@ -0,0 +1,116 @@
import React, {PropTypes} from 'react';
import {FormGroup, ControlLabel, HelpBlock} from 'react-bootstrap';
import Select from "react-select";
import {ButtonList} from '../form_components/ButtonList.jsx';
import FieldGroup from '../form_components/FieldGroup';
import {STATES} from '../../../geographyConstants';
import {SchoolInfoPropType} from './constants';

const VALIDATION_STATE_ERROR = "error";

const SCHOOL_TYPES = {
PUBLIC: "Public school",
PRIVATE: "Private school",
CHARTER: "Charter school",
OTHER: "Other"
};

export default class CustomSchoolInfo extends React.Component {
static propTypes = {
school_info: SchoolInfoPropType,
onSchoolInfoChange: PropTypes.func.isRequired,
errors: PropTypes.object
};

handleSchoolStateChange = (selection) => {
const school_info = {...this.props.school_info, ...{school_state: selection.value}};
this.props.onSchoolInfoChange({school_info});
};

handleSchoolInfoChange = (change) => {
const school_info = {...this.props.school_info, ...change};
this.props.onSchoolInfoChange({school_info});
};

handleSchoolDistrictChange = (change) => {
const school_info = {...this.props.school_info, ...change};
school_info.school_district_other = "true";
this.props.onSchoolInfoChange({school_info});
};

handleSchoolTypeChange = (change) => {
const school_info = {...this.props.school_info, ...change};
if ([SCHOOL_TYPES.PRIVATE, SCHOOL_TYPES.OTHER].includes(change["school_type"])) {
delete(school_info.school_district_other);
delete(school_info.school_district_name);
}
this.props.onSchoolInfoChange({school_info});
};

render() {
return (
<FormGroup>
<FieldGroup
id="school_name"
label="School Name"
type="text"
required={true}
onChange={this.handleSchoolInfoChange}
validationState={this.props.errors.hasOwnProperty("school_name") ? VALIDATION_STATE_ERROR : null}
errorMessage={this.props.errors.school_name}
/>
<ButtonList
key="school_type"
answers={Object.values(SCHOOL_TYPES)}
groupName="school_type"
label="My school is a"
onChange={this.handleSchoolTypeChange}
selectedItems={this.props.school_info ? this.props.school_info.school_type : null}
validationState={this.props.errors.hasOwnProperty("school_type") ? VALIDATION_STATE_ERROR : null}
errorText={this.props.errors.school_type}
type="radio"
required={true}
/>
{
this.props.school_info && [SCHOOL_TYPES.PUBLIC, SCHOOL_TYPES.CHARTER].includes(this.props.school_info.school_type) &&
<FieldGroup
id="school_district_name"
label="School District"
type="text"
required={true}
onChange={this.handleSchoolDistrictChange}
validationState={this.props.errors.hasOwnProperty("school_district_name") ? VALIDATION_STATE_ERROR : null}
errorMessage={this.props.errors.school_district}
/>
}
{
this.props.school_info && this.props.school_info.school_type &&
<FormGroup>
<FormGroup
id="school_state"
validationState={this.props.errors.hasOwnProperty("school_state") ? VALIDATION_STATE_ERROR : null}
>
<ControlLabel>School State<span className="form-required-field"> *</span></ControlLabel>
<Select
value={this.props.school_info ? this.props.school_info.school_state : null}
onChange={this.handleSchoolStateChange}
options={STATES.map(v => ({value: v, label: v}))}
clearable={false}
/>
<HelpBlock>{this.props.errors.school_state}</HelpBlock>
</FormGroup>
<FieldGroup
id="school_zip"
label="School Zip Code"
type="text"
required={true}
onChange={this.handleSchoolInfoChange}
validationState={this.props.errors.hasOwnProperty("school_zip") ? VALIDATION_STATE_ERROR : null}
errorMessage={this.props.errors.school_zip}
/>
</FormGroup>
}
</FormGroup>
);
}
}

0 comments on commit eb8b704

Please sign in to comment.