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

Finalize on TeacherDashboardHeader after A/B test #33830

Merged
merged 3 commits into from
Mar 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 10 additions & 30 deletions apps/src/templates/teacherDashboard/TeacherDashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import {Route, Switch} from 'react-router-dom';
import TeacherDashboardNavigation, {
TeacherDashboardPath
} from './TeacherDashboardNavigation';
import experiments from '@cdo/apps/util/experiments';
import TeacherDashboardHeader from './TeacherDashboardHeader';
import TeacherDashboardHeaderWithButtons from './TeacherDashboardHeaderWithButtons';
import StatsTableWithData from './StatsTableWithData';
import SectionProgress from '@cdo/apps/templates/sectionProgress/SectionProgress';
import ManageStudents from '@cdo/apps/templates/manageStudents/ManageStudents';
Expand All @@ -18,34 +16,7 @@ import EmptySection from './EmptySection';
import _ from 'lodash';
import firehoseClient from '../../lib/util/firehose';
import StandardsReport from '../sectionProgress/standards/StandardsReport';
import {recordImpression} from './impressionHelpers';

function Header(props) {
if (experiments.isEnabled(experiments.TEACHER_DASHBOARD_SECTION_BUTTONS)) {
if (
experiments.isEnabled(
experiments.TEACHER_DASHBOARD_SECTION_BUTTONS_ALTERNATE_TEXT
)
) {
recordImpression('teacher_dashboard_header_with_buttons_switch_section');
} else {
recordImpression('teacher_dashboard_header_with_buttons_select_section');
}
return (
<div>
{/* TeacherDashboardNavigation must be outside of
TeacherDashboardHeader. Routing components do not work with
components using Connect/Redux. Library we could use to fix issue:
https://github.com/supasate/connected-react-router */}
<TeacherDashboardHeaderWithButtons />
<TeacherDashboardNavigation />
</div>
);
} else {
recordImpression('teacher_dashboard_header_no_buttons');
return <TeacherDashboardHeader sectionName={props.sectionName} />;
}
}
class TeacherDashboard extends Component {
static propTypes = {
studioUrlPrefix: PropTypes.string.isRequired,
Expand Down Expand Up @@ -106,7 +77,16 @@ class TeacherDashboard extends Component {

return (
<div>
{includeHeader && <Header {...this.props} />}
{includeHeader && (
<div>
{/* TeacherDashboardNavigation must be outside of
TeacherDashboardHeader. Routing components do not work with
components using Connect/Redux. Library we could use to fix issue:
https://github.com/supasate/connected-react-router */}
<TeacherDashboardHeader />
<TeacherDashboardNavigation />
</div>
)}
<Switch>
<Route
path={TeacherDashboardPath.manageStudents}
Expand Down
131 changes: 121 additions & 10 deletions apps/src/templates/teacherDashboard/TeacherDashboardHeader.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,80 @@
import FontAwesome from './../FontAwesome';
import React from 'react';
import {connect} from 'react-redux';
import {
switchToSection,
recordSwitchToSection,
recordOpenEditSectionDetails
} from './sectionHelpers';
import PropTypes from 'prop-types';
import i18n from '@cdo/locale';
import SmallChevronLink from '../SmallChevronLink';
import SelectSectionDropdown from './SelectSectionDropdown';
import TeacherDashboardNavigation from './TeacherDashboardNavigation';
import {ReloadAfterEditSectionDialog} from './EditSectionDialog';
import {beginEditingSection} from './teacherSectionsRedux';
import Button from '../Button';
import DropdownButton from '../DropdownButton';

const styles = {
headerContainer: {
sectionPrompt: {
fontWeight: 'bold'
},
header: {
display: 'flex',
justifyContent: 'space-between'
justifyContent: 'space-between',
marginBottom: '5px'
},
rightColumn: {
display: 'flex',
flexDirection: 'column-reverse'
},
buttonSection: {
display: 'flex'
},
buttonWithMargin: {
marginRight: '5px'
}
};

export default class TeacherDashboardHeader extends React.Component {
class TeacherDashboardHeader extends React.Component {
static propTypes = {
sectionName: PropTypes.string.isRequired
sections: PropTypes.object.isRequired,
selectedSectionId: PropTypes.number.isRequired,
selectedSectionScript: PropTypes.object.isRequired,
openEditSectionDialog: PropTypes.func.isRequired
};

constructor(props) {
super(props);
this.getDropdownOptions = this.getDropdownOptions.bind(this);
this.selectedSection = this.props.sections[this.props.selectedSectionId];
}

getDropdownOptions(optionMetricName) {
let self = this;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen the self = this pattern in a while.

let sections = this.props.sections;
let options = Object.keys(sections).map(function(key, i) {
let section = sections[key];
let optionOnClick = () => {
switchToSection(section.id, self.selectedSection.id);
recordSwitchToSection(
section.id,
self.selectedSection.id,
optionMetricName
);
};
let icon = undefined;
if (section.id === self.selectedSection.id) {
icon = <FontAwesome icon="check" />;
}
return (
<a key={i} id={section.id} onClick={optionOnClick}>
{icon} {section.name}
</a>
);
});
return options;
}

render() {
return (
<div>
Expand All @@ -26,12 +84,65 @@ export default class TeacherDashboardHeader extends React.Component {
isRtl={true}
chevronSide="left"
/>
<div style={styles.headerContainer}>
<h1>{this.props.sectionName}</h1>
<SelectSectionDropdown />
<div style={styles.header}>
<div>
<h1>{this.selectedSection.name}</h1>
<div>
<span style={styles.sectionPrompt}>
{i18n.assignedToWithColon()}{' '}
</span>
{this.props.selectedSectionScript.name}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could combine these strings and pass the script name as a variable like this:

"assignConfirm": "Are you sure you want to assign \"{assignmentName}\" to \"{sectionName}\"?",
.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will ask you more about this over slack

</div>
</div>
<div style={styles.rightColumn}>
<div style={styles.buttonSection}>
<Button
__useDeprecatedTag
onClick={() => {
this.props.openEditSectionDialog(this.selectedSection.id);
recordOpenEditSectionDetails(
this.selectedSection.id,
'dashboard_header'
);
}}
icon="gear"
size="narrow"
color="gray"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the Button component's specified gray just in case we decide to change that default down the road? Like this:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will implement this in a follow up PR! trying to get this merged asap right now, ty for the pointer

text={i18n.editSectionDetails()}
style={styles.buttonWithMargin}
/>
<DropdownButton
size="narrow"
color="gray"
text={i18n.switchSection()}
>
{this.getDropdownOptions('from_button_switch_section')}
</DropdownButton>
</div>
</div>
</div>
<TeacherDashboardNavigation />
<ReloadAfterEditSectionDialog />
</div>
);
}
}

export const UnconnectedTeacherDashboardHeader = TeacherDashboardHeader;

export default connect(
state => {
let sections = state.teacherSections.sections;
let selectedSectionId = state.teacherSections.selectedSectionId;

let selectedSectionScriptId = state.scriptSelection.scriptId;
let selectedSectionScript = state.scriptSelection.validScripts.filter(
script => script.id === selectedSectionScriptId
)[0];
return {sections, selectedSectionId, selectedSectionScript};
},
dispatch => {
return {
openEditSectionDialog: id => dispatch(beginEditingSection(id))
};
}
)(TeacherDashboardHeader);

This file was deleted.