Upgrade instructure-ui to 1.0

fixes CNVS-34969

test plan:
  - go /profile/settings and turn on high contrast
  - go to the course people page (/courses/#/users)
  - click on the +People button
  > expected result: the modal honors high contrast

  - enter some text in he text area
  > expected result: nothing bad happens, as the event
    handler for TextArea has changed.
  - there's a TextArea in MessageStudents also, but I don't
    know where to find it in the UI. You should probalby
    test it doesn't blow up either.

Change-Id: Ia8102dacfa2b01ee043002ee0f5c27943abe5743
Reviewed-on: https://gerrit.instructure.com/102133
Tested-by: Jenkins
Reviewed-by: Ryan Shaw <ryan@instructure.com>
QA-Review: Dan Sasaki
Product-Review: Ryan Shaw <ryan@instructure.com>
Product-Review: Ed Schiebel <eschiebel@instructure.com>
This commit is contained in:
Ed Schiebel 2017-02-14 16:54:51 -05:00
parent 7b024780c6
commit d1664390e2
34 changed files with 274 additions and 205 deletions

View File

@ -7,6 +7,7 @@ require [
'compiled/helpDialog'
'jsx/subnav_menu/updateSubnavMenuToggle'
'jsx/new_user_tutorial/initializeNewUserTutorials'
'instructure-ui/ApplyTheme'
# modules that do their own thing on every page that simply need to
# be required
@ -30,6 +31,7 @@ require [
'compiled/behaviors/ping'
'LtiThumbnailLauncher'
'compiled/badge_counts'
'instructure-ui-themes/canvas'
# Other stuff several bundles use.
# If any of these really arn't used on most pages,
@ -41,7 +43,7 @@ require [
'jqueryui/tabs'
'compiled/registration/incompleteRegistrationWarning'
'moment'
], ($, _, I18n, Backbone, helpDialog, updateSubnavMenuToggle, initializeNewUserTutorials) ->
], ($, _, I18n, Backbone, helpDialog, updateSubnavMenuToggle, initializeNewUserTutorials, ApplyTheme) ->
helpDialog.initTriggers()
@ -80,3 +82,9 @@ require [
$('body').on 'click', '[data-pushstate]', (event) ->
event.preventDefault()
Backbone.history.navigate $(this).attr('href'), yes
# setup the inst-ui default theme
if ENV.use_high_contrast
ApplyTheme.default.setDefaultTheme('canvas-a11y')
else
ApplyTheme.default.setDefaultTheme('canvas')

View File

@ -2,16 +2,21 @@ define([
'i18n!roster',
'react',
'react-dom',
'instructure-ui',
'instructure-ui/Modal',
'instructure-ui/Heading',
'instructure-ui/Button',
'instructure-ui/Spinner',
'instructure-ui/Alert',
'instructure-ui/ScreenReaderContent',
'./shapes',
'./people_search',
'./people_ready_list',
'./people_validation_issues',
'./api_error'
], (I18n, React, ReactDOM,
{Modal, ModalHeader, ModalBody, ModalFooter,
Heading, Button, Spinner, Alert,
ScreenReaderContent, ApplyTheme},
{default: Modal, ModalHeader, ModalBody, ModalFooter},
{default: Heading}, {default: Button}, {default: Spinner}, {default: Alert},
{default: ScreenReaderContent},
{courseParamsShape, apiStateShape, inputParamsShape, validateResultShape, personReadyToEnrollShape},
PeopleSearch, PeopleReadyList, PeopleValidationIssues, APIError) => {
const PEOPLESEARCH = 'peoplesearch';
@ -307,13 +312,5 @@ define([
);
}
}
const DeleteMe = props => (
<ApplyTheme theme={ApplyTheme.generateTheme('a11y')}>
<AddPeople {...props} />
</ApplyTheme>
)
/* TODO: after instui gets updated, just return AddPeople */
return ENV.use_high_contrast ? DeleteMe : AddPeople;
return AddPeople;
});

View File

@ -1,8 +1,8 @@
define([
'i18n!roster',
'react',
'instructure-ui'
], (I18n, React, {Alert}) => {
'instructure-ui/Alert'
], (I18n, React, {default: Alert}) => {
class ApiError extends React.Component {
static propTypes = {
error: React.PropTypes.oneOfType([
@ -17,7 +17,7 @@ define([
{I18n.t('The following users could not be created.')}
<ul className="apierror__error_list">
{
this.props.error.map((e, i) => <li key={i}>{e}</li>)
this.props.error.map(e => <li key={Date.now()}>{e}</li>)
}
</ul>
</div>

View File

@ -2,9 +2,14 @@ define([
'i18n!roster',
'react',
'./shapes',
'instructure-ui'
], (I18n, React, shapes, {Table, ScreenReaderContent,
TextInput, RadioInput, Typography, Link}) => {
'instructure-ui/Table',
'instructure-ui/ScreenReaderContent',
'instructure-ui/TextInput',
'instructure-ui/RadioInput',
'instructure-ui/Typography',
'instructure-ui/Link'
], (I18n, React, shapes, {default: Table}, {default: ScreenReaderContent},
{default: TextInput}, {default: RadioInput}, {default: Typography}, {default: Link}) => {
const CREATE_NEW = '__CREATE_NEW__';
const SKIP = '__SKIP';
const nameLabel = I18n.t("New user's name");
@ -39,7 +44,9 @@ define([
onSelectNewForDuplicate = (event) => {
// if the event was not from the radio button, find and focus it
if (!(event.target.tagName === 'input' && event.target.getAttribute('type') === 'radio')) {
const radioButton = event.target.parentElement.parentElement.querySelector('input[type="radio"]');
let elem = event.target;
for (; elem.tagName !== 'TR'; elem = elem.parentElement);
const radioButton = elem.querySelector('input[type="radio"]');
radioButton.focus();
}
this.props.onNewForDuplicate(this.props.duplicates.address, this.props.duplicates.newUserInfo);

View File

@ -2,9 +2,13 @@ define([
'i18n!roster',
'react',
'./shapes',
'instructure-ui'
], (I18n, React, shapes, {Table, ScreenReaderContent,
TextInput, Checkbox, Link}) => {
'instructure-ui/Table',
'instructure-ui/ScreenReaderContent',
'instructure-ui/TextInput',
'instructure-ui/Checkbox',
'instructure-ui/Link'
], (I18n, React, shapes, {default: Table}, {default: ScreenReaderContent},
{default: TextInput}, {default: Checkbox}, {default: Link}) => {
const namePrompt = I18n.t('Click to add a name');
const nameLabel = I18n.t("New user's name");
const emailLabel = I18n.t('Required Email Address');
@ -31,6 +35,7 @@ define([
this.state = {
selectAll: false
};
this.tbodyNode = null;
}
componentWillReceiveProps (nextProps) {
@ -44,11 +49,14 @@ define([
eatEvent(event);
// user may have clicked on the link. if so, put focus on the adjacent checkbox
if (!(event.target.tagName === 'input' && event.target.getAttribute('type') === 'checkbox')) {
const checkbox = event.target.parentElement.parentElement.querySelector('input[type="checkbox"]');
checkbox.focus();
if (!(event.target.tagName === 'INPUT' && event.target.getAttribute('type') === 'checkbox')) {
// The link was rendered with the attribute data-address=address for this row.
// Use it to find the checkbox with the matching value.
const checkbox = this.tbodyNode.querySelector(`input[type="checkbox"][value="${event.target.getAttribute('data-address')}"]`);
if (checkbox) {
checkbox.focus();
}
}
const address = event.target.value || event.target.getAttribute('data-address');
this.onSelectNewForMissingByAddress(address);
}
@ -288,7 +296,7 @@ define([
<div className="addpeople__missing namelist">
<Table caption={<ScreenReaderContent>{I18n.t('Unmatched login list')}</ScreenReaderContent>}>
{this.renderTableHead()}
<tbody>
<tbody ref={(n) => { this.tbodyNode = n; }} >
{this.props.searchType === 'cc_path' ? this.renderMissingEmail() : this.renderMissingIds()}
</tbody>
</Table>

View File

@ -2,9 +2,11 @@ define([
'i18n!roster',
'react',
'./shapes',
'instructure-ui'
'instructure-ui/Alert',
'instructure-ui/Table',
'instructure-ui/ScreenReaderContent'
], (I18n, React, {personReadyToEnrollShape},
{Alert, Table, ScreenReaderContent}) => {
{default: Alert}, {default: Table}, {default: ScreenReaderContent}) => {
class PeopleReadyList extends React.Component {
static propTypes = {
nameList: React.PropTypes.arrayOf(React.PropTypes.shape(personReadyToEnrollShape)),

View File

@ -1,12 +1,22 @@
define([
'i18n!roster',
'react',
'instructure-ui',
'instructure-ui/Button',
'instructure-ui/Typography',
'instructure-ui/RadioInputGroup',
'instructure-ui/RadioInput',
'instructure-ui/Select',
'instructure-ui/TextArea',
'instructure-ui/ScreenReaderContent',
'instructure-ui/Checkbox',
'instructure-ui/Alert',
'instructure-icons/react/Solid/IconUserSolid',
'./shapes',
'../helpers'
], (I18n, React, {Button, Typography, RadioInputGroup,
RadioInput, Select, TextArea, ScreenReaderContent,
Checkbox, Alert}, {courseParamsShape, inputParamsShape},
], (I18n, React, {default: Button}, {default: Typography}, {default: RadioInputGroup},
{default: RadioInput}, {default: Select}, {default: TextArea}, {default: ScreenReaderContent},
{default: Checkbox}, {default: Alert}, {default: IconUserSolid},
{courseParamsShape, inputParamsShape},
{parseNameList, findEmailInEntry, emailValidator}) => {
class PeopleSearch extends React.Component {
static propTypes = Object.assign({}, inputParamsShape, courseParamsShape);
@ -38,8 +48,8 @@ define([
onChangeSearchType = (newValue) => {
this.props.onChange({searchType: newValue});
}
onChangeNameList = (newValue) => {
this.props.onChange({nameList: newValue});
onChangeNameList = (event) => {
this.props.onChange({nameList: event.target.value});
}
onChangeSection = (event) => {
@ -98,17 +108,16 @@ define([
defaultValue={this.props.searchType}
description={I18n.t('Add user(s) by')}
onChange={this.onChangeSearchType}
layout="columns"
>
<RadioInput
id="peoplesearch_radio_cc_path"
isBlock={false}
key="cc_path"
value="cc_path"
label={I18n.t('Email Address')}
/>
<RadioInput
id="peoplesearch_radio_unique_id"
isBlock={false}
key="unique_id"
value="unique_id"
label={I18n.t('Login ID')}
@ -116,7 +125,6 @@ define([
{this.props.canReadSIS
? <RadioInput
id="peoplesearch_radio_sis_user_id"
isBlock={false}
key="sis_user_id"
value="sis_user_id"
label={I18n.t('SIS ID')}
@ -173,7 +181,9 @@ define([
</div>
</fieldset>
<div className="peoplesearch__instructions">
<i className="icon-user" />
<div className="usericon" aria-hidden>
<IconUserSolid />
</div>
<Typography size="medium">
{I18n.t('When adding multiple users, use a comma or line break to separate users.')}
</Typography>

View File

@ -4,8 +4,8 @@ define([
'./shapes',
'./duplicate_section',
'./missing_people_section',
'instructure-ui'
], (I18n, React, shapes, DuplicateSection, MissingPeopleSection, {Alert}) => {
'instructure-ui/Alert'
], (I18n, React, shapes, DuplicateSection, MissingPeopleSection, {default: Alert}) => {
class PeopleValidationIssues extends React.Component {
static propTypes = {
searchType: React.PropTypes.string.isRequired,

View File

@ -10,7 +10,7 @@ define([
const apiStateShape = {
pendingCount: PropTypes.number, // number of api calls in-flight
error: PropTypes.string // error message or undefined
error: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]) // error message or undefined
};
const inputParamsShape = {

View File

@ -1,19 +1,24 @@
import ApplyTheme from 'instructure-ui/ApplyTheme'
import 'instructure-ui-themes/canvas'
import moment from 'moment'
import tz from 'timezone_core'
import './fakeRequireJSFallback'
// Sets up moment to use the right locale
const moment = require('moment')
// we already put a <script> tag for the locale corresponding ENV.MOMENT_LOCALE
// on the page from rails, so this should not cause a new network request.
moment().locale(ENV.MOMENT_LOCALE)
// These timezones and locales should already be put on the page as <script>
// tags from rails. this block should not create any network requests.
const tz = require('timezone_core')
if (typeof ENV !== 'undefined') {
if (ENV.TIMEZONE) tz.changeZone(ENV.TIMEZONE)
if (ENV.CONTEXT_TIMEZONE) tz.preload(ENV.CONTEXT_TIMEZONE)
if (ENV.BIGEASY_LOCALE) tz.changeLocale(ENV.BIGEASY_LOCALE, ENV.MOMENT_LOCALE)
}
require('./fakeRequireJSFallback')
// setup the inst-ui default theme
if (ENV.use_high_contrast) {
ApplyTheme.setDefaultTheme('canvas-a11y')
} else {
ApplyTheme.setDefaultTheme('canvas')
}

View File

@ -31,7 +31,7 @@ define([
/>
{
canMasquerade ? (
<Typography size="x-small" weight="bold" tag="div">
<Typography size="x-small" weight="bold" as="div">
<a
href={`/courses/${courseId}?become_user_id=${user.id}`}
aria-label={I18n.t('Masquerade as %{name}', { name: user.short_name })}

View File

@ -35,7 +35,7 @@ define([
return (
<div
className="StudentContextTray-Rating">
<Heading level="h5" tag="h4">
<Heading level="h5" as="h4">
{this.props.label}
</Heading>
<div className="StudentContextTray-Rating__Stars">

View File

@ -20,7 +20,7 @@ define([
SectionInfo,
SubmissionProgressBars,
MessageStudents,
{Heading, Button, Link, Typography, ScreenReaderContent, Spinner, Tray, ApplyTheme}) {
{Heading, Button, Link, Typography, ScreenReaderContent, Spinner, Tray}) {
class StudentContextTray extends React.Component {
@ -231,7 +231,7 @@ define([
<div className="StudentContextTray-Header__Content">
{this.state.user.short_name ? (
<div className="StudentContextTray-Header__Name">
<Heading level="h3" tag="h2">
<Heading level="h3" as="h2">
<span className="StudentContextTray-Header__NameLink">
<Link
href={`/courses/${this.props.courseId}/users/${this.props.studentId}`}
@ -243,14 +243,14 @@ define([
</div>
) : null}
<div className="StudentContextTray-Header__CourseName">
<Typography size="medium" tag="div" lineHeight="condensed">
<Typography size="medium" as="div" lineHeight="condensed">
{this.state.course.name}
</Typography>
</div>
<Typography size="x-small" color="secondary" tag="div">
<Typography size="x-small" color="secondary" as="div">
<SectionInfo course={this.state.course} user={this.state.user} />
</Typography>
<Typography size="x-small" color="secondary" tag="div">
<Typography size="x-small" color="secondary" as="div">
<LastActivity user={this.state.user} />
</Typography>
</div>
@ -280,7 +280,7 @@ define([
{Object.keys(this.state.analytics).length > 0 ? (
<section
className="StudentContextTray__Section StudentContextTray-Ratings">
<Heading level="h4" tag="h3" border="bottom">
<Heading level="h4" as="h3" border="bottom">
{I18n.t("Activity Compared to Class")}
</Heading>
<div className="StudentContextTray-Ratings__Layout">
@ -301,13 +301,5 @@ define([
)
}
}
const DeleteMe = (props) => (
<ApplyTheme theme={ApplyTheme.generateTheme('a11y')}>
<StudentContextTray {...props}/>
</ApplyTheme>
)
/* TODO: after instui gets updated, just return StudentContextTray */
return ENV.use_high_contrast ? DeleteMe : StudentContextTray
return StudentContextTray;
})

View File

@ -71,7 +71,7 @@ define([
return (
<section
className="StudentContextTray__Section StudentContextTray-Progress">
<Heading level="h4" tag="h3" border="bottom">
<Heading level="h4" as="h3" border="bottom">
{I18n.t("Last %{length} Graded Items", {length: submissions.length})}
</Heading>
{submissions.map((submission) => {

View File

@ -129,7 +129,7 @@ define([
renderBodyContent () {
if (this.props.courses.length > 0) {
return [(
<ScreenReaderContent key="select-all" tag="tr">
<ScreenReaderContent key="select-all" as="tr">
<td>
<Checkbox
onChange={this.onSelectAllToggle}
@ -154,7 +154,7 @@ define([
// in order to create a sticky table header, we'll create a separate table with
// just the visual sticky headers, that will be hidden from screen readers
return (
<PresentationContent tagName="div">
<PresentationContent as="div">
<div className="btps-table__header-wrapper">
<Table caption={<ScreenReaderContent>{I18n.t('Blueprint Courses')}</ScreenReaderContent>}>
{this.renderColGroup()}
@ -193,7 +193,7 @@ define([
<Table caption={<ScreenReaderContent>{I18n.t('Blueprint Courses')}</ScreenReaderContent>}>
{this.renderColGroup()}
{/* on the real table, we'll include the headers again, but make them screen reader only */}
<ScreenReaderContent tag="thead">
<ScreenReaderContent as="thead">
{this.renderHeaders()}
</ScreenReaderContent>
<tbody className="bps-table__body">

View File

@ -73,7 +73,7 @@ define([
static renderMutedIcon (screenreaderText) {
return (
<Typography weight="bold" style="normal" size="small" color="error">
<Typography weight="bold" fontStyle="normal" size="small" color="error">
<IconMutedSolid title={screenreaderText} />
</Typography>
);
@ -81,7 +81,7 @@ define([
static renderWarningIcon (screenreaderText) {
return (
<Typography weight="bold" style="normal" size="small" color="brand">
<Typography weight="bold" fontStyle="normal" size="small" color="brand">
<IconWarningSolid title={screenreaderText} />
</Typography>
);
@ -163,7 +163,7 @@ define([
<div className="Gradebook__ColumnHeaderContent">
<span className="Gradebook__ColumnHeaderDetail">
{this.renderAssignmentLink()}
<Typography weight="normal" style="normal" size="x-small">
<Typography weight="normal" fontStyle="normal" size="x-small">
{this.renderPointsPossible()}
</Typography>
</span>

View File

@ -30,7 +30,7 @@ define([
const weightDesc = I18n.t('%{weight} of grade', { weight: weightStr });
return (
<Typography weight="normal" style="normal" size="x-small">
<Typography weight="normal" fontStyle="normal" size="x-small">
{weightDesc}
</Typography>
);
@ -50,7 +50,7 @@ define([
zIndex="9999"
trigger={
<span className="Gradebook__ColumnHeaderAction">
<Typography weight="bold" style="normal" size="large" color="brand">
<Typography weight="bold" fontStyle="normal" size="large" color="brand">
<IconMoreSolid title={optionsTitle} />
</Typography>
</span>

View File

@ -20,7 +20,7 @@ define([
return (
<div className="Gradebook__ColumnHeaderContent">
<span className="Gradebook__ColumnHeaderDetail">
<Typography weight="normal" style="normal" size="small">
<Typography weight="normal" fontStyle="normal" size="small">
{ I18n.t('Student Name') }
</Typography>
</span>
@ -29,7 +29,7 @@ define([
zIndex="9999"
trigger={
<span className="Gradebook__ColumnHeaderAction">
<Typography weight="bold" style="normal" size="large" color="brand">
<Typography weight="bold" fontStyle="normal" size="large" color="brand">
<IconMoreSolid title={I18n.t('Student Name Options')} />
</Typography>
</span>

View File

@ -20,7 +20,7 @@ define([
return (
<div className="Gradebook__ColumnHeaderContent">
<span className="Gradebook__ColumnHeaderDetail">
<Typography weight="normal" style="normal" size="small">
<Typography weight="normal" fontStyle="normal" size="small">
{ I18n.t('Total') }
</Typography>
</span>
@ -29,7 +29,7 @@ define([
zIndex="9999"
trigger={
<span className="Gradebook__ColumnHeaderAction">
<Typography weight="bold" style="normal" size="large" color="brand">
<Typography weight="bold" fontStyle="normal" size="large" color="brand">
<IconMoreSolid title={I18n.t('Total Options')} />
</Typography>
</span>

View File

@ -5,11 +5,11 @@ define([
], (React, I18n, { Typography, Heading }) => {
const HomeTray = () => (
<div>
<Heading tag="h2" level="h1" >{I18n.t('Home')}</Heading>
<Typography size="large" tag="p">
<Heading as="h2" level="h1" >{I18n.t('Home')}</Heading>
<Typography size="large" as="p">
{I18n.t('This is your course landing page!')}
</Typography>
<Typography tag="p">
<Typography as="p">
{
I18n.t("When people visit your course, this is the first page they'll see. " +
"We've set your home page to Modules, but you have the option to change it.")

View File

@ -5,7 +5,7 @@ define([
], (React, I18n, { Heading }) => {
const HomeTray = () => (
<div>
<Heading tag="h2" level="h1" >{I18n.t('Modules')}</Heading>
<Heading as="h2" level="h1" >{I18n.t('Modules')}</Heading>
</div>
);

View File

@ -223,13 +223,8 @@ define([
return null
}
const onTextInputChange = (field) => {
return (e) => this.handleChange(field, e.target.value)
}
const onTextAreaChange = (field) => {
return (value) => this.handleChange(field, value)
}
const onTextChange = field =>
e => this.handleChange(field, e.target.value)
const tokens = this.state.data.recipients.map((recipient) => {
const displayName = recipient.displayName || recipient.email
@ -277,7 +272,7 @@ define([
<TextInput
label={I18n.t("Subject")}
defaultValue={this.props.subject}
onChange={onTextInputChange('subject')}
onChange={onTextChange('subject')}
messages={this.errorMessagesFor('subject')}
disabled={this.state.sending || this.state.success}
/>
@ -286,7 +281,7 @@ define([
<TextArea
label={I18n.t("Body")}
defaultValue={this.props.body}
onChange={onTextAreaChange('body')}
onChange={onTextChange('body')}
messages={this.errorMessagesFor('body')}
disabled={this.state.sending || this.state.success}
/>

View File

@ -69,21 +69,12 @@
.peoplesearch__instructions {
margin: 1.5em 0;
text-align: center;
i.icon-user {
display:block;
height: 50px;
.usericon {
margin: 0 auto;
}
i.icon-user::before {
font-size: 48px;
line-height: 50px;
}
}
/* need a little space between inline inst-ui <RadioInput>s */
label[for^='peoplesearch_radio'] {
margin-right: 1em;
}
}
.namelist {
margin: 1.5em 0;

View File

@ -93,6 +93,7 @@ module.exports = {
// once we are all-webpack we should remove this line and just change all the 'require's
// to instructure-ui compnentns to have the right path
'instructure-ui': path.resolve(__dirname, '../node_modules/instructure-ui/lib/components'),
'instructure-ui-themes': path.resolve(__dirname, '../node_modules/instructure-ui/lib/themes'),
backbone: 'Backbone',
timezone$: 'timezone_core',

View File

@ -75,6 +75,7 @@ module Canvas
{name: 'ic-ajax', location: 'symlink_to_node_modules/ic-ajax/dist/amd'},
{name: 'ic-tabs', location: 'symlink_to_node_modules/ic-tabs'},
{name: 'instructure-ui', location: 'symlink_to_node_modules/instructure-ui/dist', main: 'instructure-ui'},
{name: 'instructure-ui-themes', location: 'symlink_to_node_modules/instructure-ui/dist/themes'},
{name: 'instructure-icons', location: 'symlink_to_node_modules/instructure-icons', main: 'react/index'},
{name: 'lodash', location: 'symlink_to_node_modules/lodash', main: 'lodash'},
{name: 'moxios', location: 'symlink_to_node_modules/moxios', main: 'dist/moxios'},

View File

@ -5,19 +5,17 @@
"engines": {
"node": "0.12 || >=6.3"
},
"dependencies": "only the things that need to be on the job servers in prod so they can generate brand css when someone uses the theme editor. (brandable_css and things that include css files that we @import from our scss files)",
"dependencies": {
"brandable_css": "0.0.68",
"canvas_offline_course_viewer": "https://github.com/instructure/canvas_offline_course_viewer.git#0.2.1",
"fullcalendar": "https://github.com/ryankshaw/fullcalendar.git#aa686b36d10cee1e1e3ec7c7784145e46667d47d",
"instructure-ui": "0.18.2-bugfix.12",
"instructure-icons": "1.2.1",
"instructure-ui": "1.0.1",
"tinymce": "4.1.9"
},
"devDependencies": "the first group is all the things our build tooling needs",
"devDependencies": "the second group is the client-side stuff we send to browsers",
"devDependencies": {
"axe-core": "2.1.7",
"axios": "0.15.2",
"babel-cli": "^6.10.1",
"babel-core": "^6.10.4",
"babel-eslint": "^7.1.0",
@ -28,11 +26,15 @@
"babel-preset-react": "^6.11.1",
"babel-preset-stage-1": "^6.5.0",
"babel-register": "^6.9.0",
"backbone": "1.1.1",
"classnames": "~2.2.5",
"coffee-loader": "^0.7.2",
"coffee-script": "1.6.2",
"color-slicer": "0.8.0",
"compute-cluster": "0.0.9",
"core-js-builder": "^2.4.1",
"css-loader": "0.26.1",
"d3": "3.4.1",
"ember-template-compiler": "^1.8.0",
"enzyme": "2.7.1",
"eslint": "^3.13.0",
@ -44,13 +46,17 @@
"eslint-plugin-react": "^6.9.0",
"exports-loader": "^0.6.2",
"expose-loader": "^0.7.0",
"fontfaceobserver": "^2.0.8",
"gglobby": "0.0.3",
"glob": "^7.0.3",
"gulp": "^3.9",
"gulp-load-plugins": "^1.5.0",
"gulp-rev": "^7.0.0",
"happypack": "^3.0.2",
"handlebars": "1.3.0",
"handlebars-loader": "^1.1.4",
"happypack": "^3.0.2",
"ic-ajax": "~2.0.1",
"ic-tabs": "0.1.3",
"imports-loader": "0.7.0",
"istanbul-instrumenter-loader": "0.2.0",
"json-loader": "^0.5.3",
@ -81,7 +87,6 @@
"axios": "0.15.2",
"backbone": "1.1.1",
"classnames": "~2.2.5",
"color-slicer": "0.8.0",
@ -95,16 +100,18 @@
"moxios": "^0.3.0",
"page": "visionmedia/page.js#1.6.4",
"parse-decimal-number": "0.1.1",
"phantomjs-prebuilt": "^2.1.4",
"qs": "https://github.com/hapijs/qs.git#a341cdf2fadba5ede1ce6c95c7051f6f31f37b81",
"qunitjs": "^1.14.0",
"react": "0.14.8",
"react-crop": "^4.0.2",
"react-dom": "0.14.8",
"react-dnd": "2.1.4",
"react-dnd-html5-backend": "2.1.2",
"react-addons-css-transition-group": "0.14.8",
"react-addons-pure-render-mixin": "0.14.8",
"react-addons-test-utils": "0.14.8",
"react-addons-update": "0.14.8",
"react-crop": "^4.0.2",
"react-dnd": "2.1.4",
"react-dnd-html5-backend": "2.1.2",
"react-dom": "0.14.8",
"react-modal": "1.6.5",
"react-redux": "4.4.5",
"react-select-box": "https://github.com/instructure-react/react-select-box.git#b1ddd39223d48793fbe3dc4e87aca00d57197b5f",
@ -115,7 +122,17 @@
"redux-actions": "0.11.0",
"redux-logger": "2.6.1",
"redux-thunk": "2.1.0",
"spin.js": "2.3.2"
"requirejs": "~2.2.0",
"script-loader": "^0.7.0",
"sinon": "2.0.0-pre.5",
"spin.js": "2.3.2",
"style-loader": "^0.13.1",
"stylelint": "7.8.0",
"timezone": "1.0.5",
"uglify-js": "~2.7.0",
"webpack": "2.2.1",
"webpack-manifest-plugin": "^1.0.1",
"webpack-parallel-uglify-plugin": "0.2.0"
},
"repository": "instructure/canvas-lms",
"scripts": {

View File

@ -38,15 +38,14 @@ define([
/>)
const missingPeopleSection = TestUtils.findRenderedDOMComponentWithClass(component, 'namelist')
const rows = missingPeopleSection.querySelectorAll('tr');
equal(rows.length, 3, 'three rows')
const headings = rows[0].querySelectorAll('th');
const headings = missingPeopleSection.querySelectorAll('thead tr th');
equal(headings.length, 4, 'four column headings');
const createUserBtn = rows[1].querySelectorAll('td')[1].firstChild;
equal(createUserBtn.tagName, 'BUTTON', 'create new user button');
const nameInput = rows[2].querySelector('input[type="text"]');
const rows = missingPeopleSection.querySelectorAll('tbody tr');
const createUserBtn = rows[0].querySelectorAll('td')[1].querySelector('button')
equal(createUserBtn.innerHTML, 'Click to add a name', 'create new user button');
const nameInput = rows[1].querySelector('input[type="text"]');
ok(nameInput, 'name input');
const emailInput = rows[2].querySelector('input[type="email"]');
const emailInput = rows[1].querySelector('input[type="email"]');
ok(emailInput, 'email input');
});
test('cannot create users because we don\'t have the URL', () => {

View File

@ -36,7 +36,7 @@ define([
...previousExportProps()
};
this.wrapper = mount(<ActionMenu {...propsWithPreviousExport} />);
this.wrapper.find('PopoverMenu').simulate('click');
this.wrapper.find('button').simulate('click');
},
teardown () {
@ -163,7 +163,7 @@ define([
this.wrapper = mount(<ActionMenu {...workingMenuProps()} />, { attachTo: document.querySelector('#fixture')});
this.trigger = this.wrapper.find('PopoverMenu');
this.trigger = this.wrapper.find('button');
this.trigger.simulate('click');
this.menuItem = document.querySelector('[role="menuitem"] [data-menu-id="export"]');
@ -211,7 +211,7 @@ define([
this.menuItem = document.querySelector('[role="menuitem"] [data-menu-id="export"]');
equal(this.menuItem.textContent, 'Export in progress');
equal(this.menuItem.parentElement.getAttribute('aria-disabled'), 'true');
equal(this.menuItem.parentElement.parentElement.getAttribute('aria-disabled'), 'true');
return exportResult;
});
@ -303,7 +303,7 @@ define([
this.spies.gotoUrl = this.stub(ActionMenu, 'gotoUrl');
this.wrapper = mount(<ActionMenu {...workingMenuProps()} />);
this.wrapper.find('PopoverMenu').simulate('click');
this.wrapper.find('button').simulate('click');
this.menuItem = document.querySelectorAll('[role="menuitem"] [data-menu-id="import"]')[0];
},

View File

@ -105,9 +105,12 @@ define([
title: undefined,
href: createAssignmentProp().htmlUrl
};
const actualProps = actualElements.props();
equal(actualElements.length, 1);
deepEqual(actualElements.props(), expectedLinkProps);
deepEqual(actualProps.children, expectedLinkProps.children);
equal(actualProps.title, expectedLinkProps.title);
equal(actualProps.href, expectedLinkProps.href);
});
test('renders the points possible', function () {
@ -164,28 +167,28 @@ define([
test('shows the menu item in an enabled state', function () {
this.renderOutput = mount(<AssignmentColumnHeader {...this.props} />);
this.renderOutput.find('PopoverMenu').simulate('click');
this.renderOutput.find('.Gradebook__ColumnHeaderAction').simulate('click');
const specificMenuItem = document.querySelector('[data-menu-item-id="show-assignment-details"]');
equal(specificMenuItem.textContent, 'Assignment Details');
notOk(specificMenuItem.parentElement.getAttribute('aria-disabled'));
notOk(specificMenuItem.parentElement.parentElement.getAttribute('aria-disabled'));
});
test('disables the menu item when the disabled prop is true', function () {
this.props.assignmentDetailsAction.disabled = true;
this.renderOutput = mount(<AssignmentColumnHeader {...this.props} />);
this.renderOutput.find('PopoverMenu').simulate('click');
this.renderOutput.find('.Gradebook__ColumnHeaderAction').simulate('click');
const specificMenuItem = document.querySelector('[data-menu-item-id="show-assignment-details"]');
equal(specificMenuItem.parentElement.getAttribute('aria-disabled'), 'true');
equal(specificMenuItem.parentElement.parentElement.getAttribute('aria-disabled'), 'true');
});
test('clicking the menu item invokes the Assignment Details dialog', function () {
this.renderOutput = mount(<AssignmentColumnHeader {...this.props} />);
this.renderOutput.find('PopoverMenu').simulate('click');
this.renderOutput.find('.Gradebook__ColumnHeaderAction').simulate('click');
const specificMenuItem = document.querySelector('[data-menu-item-id="show-assignment-details"]');
@ -206,7 +209,7 @@ define([
submissionsLoaded
/>
);
this.wrapper.find('PopoverMenu').simulate('click');
this.wrapper.find('.Gradebook__ColumnHeaderAction').simulate('click');
const menuItem = document.querySelector('[data-menu-item-id="curve-grades"]');
menuItem.click();
return menuItem;
@ -221,17 +224,17 @@ define([
const menuItem = this.setupAndClick();
equal(menuItem.textContent, 'Curve Grades');
notOk(menuItem.parentElement.getAttribute('aria-disabled'));
notOk(menuItem.parentElement.parentElement.getAttribute('aria-disabled'));
});
test('Curve Grades menu item is disabled when isDisabled is true', function () {
const menuItem = this.setupAndClick({ isDisabled: true });
ok(menuItem.parentElement.getAttribute('aria-disabled'));
ok(menuItem.parentElement.parentElement.getAttribute('aria-disabled'));
});
test('Curve Grades menu item is enabled when isDisabled is false', function () {
const menuItem = this.setupAndClick({ isDisabled: false });
notOk(menuItem.parentElement.getAttribute('aria-disabled'));
notOk(menuItem.parentElement.parentElement.getAttribute('aria-disabled'));
});
test('onSelect is called when menu item is clicked', function () {
@ -268,25 +271,25 @@ define([
test('shows the menu item in an enabled state', function () {
this.wrapper = mount(<AssignmentColumnHeader {...this.props} />);
this.wrapper.find('PopoverMenu').simulate('click');
this.wrapper.find('.Gradebook__ColumnHeaderAction').simulate('click');
const menuItem = document.querySelector('[data-menu-item-id="message-students-who"]');
equal(menuItem.textContent, 'Message Students Who');
notOk(menuItem.parentElement.getAttribute('aria-disabled'));
notOk(menuItem.parentElement.parentElement.getAttribute('aria-disabled'));
});
test('disables the menu item when submissions are not loaded', function () {
this.props.submissionsLoaded = false;
this.wrapper = mount(<AssignmentColumnHeader {...this.props} />);
this.wrapper.find('PopoverMenu').simulate('click');
this.wrapper.find('.Gradebook__ColumnHeaderAction').simulate('click');
const menuItem = document.querySelector('[data-menu-item-id="message-students-who"]');
equal(menuItem.parentElement.getAttribute('aria-disabled'), 'true');
equal(menuItem.parentElement.parentElement.getAttribute('aria-disabled'), 'true');
});
test('clicking the menu item invokes the Message Students Who dialog', function () {
this.wrapper = mount(<AssignmentColumnHeader {...this.props} />);
this.wrapper.find('PopoverMenu').simulate('click');
this.wrapper.find('.Gradebook__ColumnHeaderAction').simulate('click');
const messageStudentsStub = this.stub(window, 'messageStudents');
const menuItem = document.querySelector('[data-menu-item-id="message-students-who"]');
menuItem.click();
@ -394,7 +397,7 @@ define([
test('shows the menu item in an enabled state', function () {
this.renderOutput = mount(<AssignmentColumnHeader {...this.props} />);
this.renderOutput.find('PopoverMenu').simulate('click');
this.renderOutput.find('.Gradebook__ColumnHeaderAction').simulate('click');
const specificMenuItem = document.querySelector('[data-menu-item-id="set-default-grade"]');
@ -406,16 +409,16 @@ define([
this.props.setDefaultGradeAction.disabled = true;
this.renderOutput = mount(<AssignmentColumnHeader {...this.props} />);
this.renderOutput.find('PopoverMenu').simulate('click');
this.renderOutput.find('.Gradebook__ColumnHeaderAction').simulate('click');
const specificMenuItem = document.querySelector('[data-menu-item-id="set-default-grade"]');
equal(specificMenuItem.parentElement.getAttribute('aria-disabled'), 'true');
equal(specificMenuItem.parentElement.parentElement.getAttribute('aria-disabled'), 'true');
});
test('clicking the menu item invokes the onSelect handler', function () {
this.renderOutput = mount(<AssignmentColumnHeader {...this.props} />);
this.renderOutput.find('PopoverMenu').simulate('click');
this.renderOutput.find('.Gradebook__ColumnHeaderAction').simulate('click');
const specificMenuItem = document.querySelector('[data-menu-item-id="set-default-grade"]');

View File

@ -44,7 +44,7 @@ define([
test('#handleIndividualGradebookSelect calls setLocation', function () {
const setLocationStub = this.stub(GradebookMenu.prototype, 'setLocation');
this.wrapper.find('PopoverMenu').simulate('click');
this.wrapper.find('button').simulate('click');
document.querySelector('[data-menu-item-id="individual-gradebook"]').click();
const url = `${this.wrapper.props().courseUrl}/gradebook/change_gradebook_version?version=individual`;
ok(setLocationStub.withArgs(url).calledOnce);
@ -52,7 +52,7 @@ define([
test('#handleGradeHistorySelect calls setLocation', function () {
const setLocationStub = this.stub(GradebookMenu.prototype, 'setLocation');
this.wrapper.find('PopoverMenu').simulate('click');
this.wrapper.find('button').simulate('click');
document.querySelector('[data-menu-item-id="grade-history"]').click();
const url = `${this.wrapper.props().courseUrl}/gradebook/history`;
ok(setLocationStub.withArgs(url).calledOnce);
@ -69,7 +69,7 @@ define([
navigate={this.navigateStub}
/>
);
this.wrapper.find('PopoverMenu').simulate('click');
this.wrapper.find('button').simulate('click');
this.menuItems = document.querySelector('[role="menu"]').children;
},
teardown () {
@ -108,7 +108,7 @@ define([
navigate={() => {}}
/>
);
this.wrapper.find('PopoverMenu').simulate('click');
this.wrapper.find('button').simulate('click');
this.menuItems = document.querySelector('[role="menu"]').children;
},
teardown () {
@ -139,7 +139,7 @@ define([
navigate={this.navigateStub}
/>
);
this.wrapper.find('PopoverMenu').simulate('click');
this.wrapper.find('button').simulate('click');
this.menuItems = document.querySelector('[role="menu"]').children;
},
teardown () {

View File

@ -34,3 +34,12 @@ requirejs.config({
deps: thingsToLoadWithRequireJS, // dynamically load all test files
callback: window.__karma__.start
});
require(['instructure-ui/ApplyTheme', 'instructure-ui-themes/canvas'],
function(ApplyTheme) {
if (ENV.use_high_contrast) {
ApplyTheme.defualt.setDefaultTheme('canvas-a11y')
} else {
ApplyTheme.default.setDefaultTheme('canvas')
}
});

View File

@ -1,4 +1,6 @@
import 'vendor/ie11-polyfill.js'
import ApplyTheme from 'instructure-ui/ApplyTheme'
import 'instructure-ui-themes/canvas'
import './support/sinon/sinon-qunit-1.0.0'
const fixturesDiv = document.createElement('div')
@ -7,7 +9,16 @@ document.body.appendChild(fixturesDiv)
if (!window.ENV) window.ENV = {}
const requireAll = requireContext => requireContext.keys().map(requireContext)
// setup the inst-ui default theme
if (ENV.use_high_contrast) {
ApplyTheme.setDefaultTheme('canvas-a11y')
} else {
ApplyTheme.setDefaultTheme('canvas')
}
function requireAll (requireContext) {
return requireContext.keys().map(requireContext);
}
if (__SPEC_FILE) {
require(__SPEC_FILE)

View File

@ -247,7 +247,7 @@ describe "Gradezilla" do
gradezilla_page.visit(@course)
# And I click the dropdown menu on the assignment
f('.gradebook-header-drop').click
f('.Gradebook__ColumnHeaderAction').click
# And I click the download submissions button
f('[data-action="downloadSubmissions"]').click
@ -256,7 +256,7 @@ describe "Gradezilla" do
fj("div:contains('Download Assignment Submissions'):first .ui-dialog-titlebar-close").click
# And I click the dropdown menu on the assignment again
f('.gradebook-header-drop').click
f('.Gradebook__ColumnHeaderAction').click
# And I click the re-upload submissions link
f('[data-action="reuploadSubmissions"]').click
@ -292,7 +292,7 @@ describe "Gradezilla" do
gradezilla_page.visit(@course)
f('.gradebook-header-drop').click
f('.Gradebook__ColumnHeaderAction').click
expect(f('.gradebook-header-menu')).not_to include_text("SpeedGrader")
end

115
yarn.lock
View File

@ -30,7 +30,7 @@ acorn-dynamic-import@^2.0.0:
dependencies:
acorn "^4.0.3"
acorn-jsx@^3.0.0:
acorn-jsx@^3.0.0, acorn-jsx@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
dependencies:
@ -987,7 +987,7 @@ babel-template@^6.22.0, babel-template@^6.23.0:
babylon "^6.11.0"
lodash "^4.2.0"
babel-traverse@^6.0.0, babel-traverse@^6.15.0, babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-traverse@^6.23.1:
babel-traverse@^6.15.0, babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-traverse@^6.23.1:
version "6.23.1"
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.23.1.tgz#d3cb59010ecd06a97d81310065f966b699e14f48"
dependencies:
@ -1010,7 +1010,7 @@ babel-types@^6.15.0, babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23
lodash "^4.2.0"
to-fast-properties "^1.0.1"
babylon@^6.0.0, babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0:
babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0:
version "6.16.1"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3"
@ -1394,7 +1394,7 @@ clap@^1.0.9:
dependencies:
chalk "^1.1.3"
classnames@2.2.5, classnames@^2.1.3, classnames@^2.2.0, classnames@^2.2.1, classnames@~2.2.5:
classnames@2.2.5, classnames@^2.2.0, classnames@^2.2.1, classnames@~2.2.5:
version "2.2.5"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
@ -2143,13 +2143,9 @@ doiuse@^2.4.1:
through2 "^0.6.3"
yargs "^3.5.4"
dom-helpers@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.0.0.tgz#124869cea3f09dbff84256fede7f36616ccfee23"
dom-helpers@^2.3.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-2.4.0.tgz#9bb4b245f637367b1fa670274272aa28fe06c367"
dom-helpers@3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.0.tgz#70af056e6b1507a71084abc1aac0f93a23f7ea1c"
dom-serialize@^2.2.0:
version "2.2.1"
@ -2244,6 +2240,12 @@ encodeurl@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20"
encoding@^0.1.11:
version "0.1.12"
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
dependencies:
iconv-lite "~0.4.13"
end-of-stream@~0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf"
@ -2733,6 +2735,18 @@ fbjs@^0.6.1:
ua-parser-js "^0.7.9"
whatwg-fetch "^0.9.0"
fbjs@^0.8.8:
version "0.8.9"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.9.tgz#180247fbd347dcc9004517b904f865400a0c8f14"
dependencies:
core-js "^1.0.0"
isomorphic-fetch "^2.1.1"
loose-envify "^1.0.0"
object-assign "^4.1.0"
promise "^7.1.1"
setimmediate "^1.0.5"
ua-parser-js "^0.7.9"
fd-slicer@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65"
@ -3059,6 +3073,14 @@ gglobby@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/gglobby/-/gglobby-0.0.3.tgz#c7d686c1ff2ca4e882a58adf38a7de2691ba7f99"
glamor@2.20.22:
version "2.20.22"
resolved "https://registry.yarnpkg.com/glamor/-/glamor-2.20.22.tgz#86c11a143deee7d4c051de50d69387d8b4e700ba"
dependencies:
babel-runtime "^6.18.0"
fbjs "^0.8.8"
object-assign "^4.1.0"
glob-base@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
@ -3540,7 +3562,7 @@ ic-tabs@0.1.3:
dependencies:
ic-styled "^1.1.6"
iconv-lite@0.4.15, iconv-lite@^0.4.5:
iconv-lite@0.4.15, iconv-lite@^0.4.5, iconv-lite@~0.4.13:
version "0.4.15"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb"
@ -3640,31 +3662,25 @@ install@~0.1.7:
version "0.1.8"
resolved "https://registry.yarnpkg.com/install/-/install-0.1.8.tgz#9980ef93e30dfb534778d163bc86ddd472ad5fe8"
instructure-icons@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/instructure-icons/-/instructure-icons-0.1.0.tgz#4aba133373de129081579344c8d2b1ebba313bd8"
dependencies:
shortid "2.2.6"
instructure-icons@1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/instructure-icons/-/instructure-icons-1.2.1.tgz#6ae4e8de07ff6821192746bef79a2cab01a179be"
dependencies:
shortid "2.2.6"
instructure-ui@0.18.2-bugfix.12:
version "0.18.2-bugfix.12"
resolved "https://registry.yarnpkg.com/instructure-ui/-/instructure-ui-0.18.2-bugfix.12.tgz#95cee0932d9aafa3cb7b11ce92db9f5c32544dd4"
instructure-ui@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/instructure-ui/-/instructure-ui-1.0.1.tgz#9d84525fd6cd73c6f9168f1d36ca8001017b48e1"
dependencies:
classnames "2.2.5"
deep-equal "1.0.1"
dom-helpers "3.0.0"
instructure-icons "0.1.0"
dom-helpers "3.2.0"
glamor "2.20.22"
instructure-icons "1.2.1"
invariant "2.2.2"
keycode "2.1.7"
keycode "2.1.8"
object.omit "2.0.1"
object.pick "1.2.0"
react-overlays "0.6.3"
shortid "2.2.6"
tinycolor2 "1.4.1"
@ -3904,6 +3920,13 @@ isobject@^2.0.0, isobject@^2.1.0:
dependencies:
isarray "1.0.0"
isomorphic-fetch@^2.1.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
dependencies:
node-fetch "^1.0.1"
whatwg-fetch ">=0.10.0"
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@ -4192,9 +4215,9 @@ kew@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b"
keycode@2.1.7:
version "2.1.7"
resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.1.7.tgz#7b9255919f6cff562b09a064d222dca70b020f5c"
keycode@2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.1.8.tgz#94d2b7098215eff0e8f9a8931d5a59076c4532fb"
kind-of@^3.0.2:
version "3.1.0"
@ -4773,6 +4796,13 @@ neo-async@^1.0.0:
version "1.8.2"
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-1.8.2.tgz#31795888b79dd04357a7c52113a65183e93b6735"
node-fetch@^1.0.1:
version "1.6.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04"
dependencies:
encoding "^0.1.11"
is-stream "^1.0.1"
node-gyp@^3.3.1:
version "3.5.0"
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.5.0.tgz#a8fe5e611d079ec16348a3eb960e78e11c85274a"
@ -5664,7 +5694,7 @@ progress@^1.1.8, progress@~1.1.8:
version "1.1.8"
resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"
promise@^7.0.3:
promise@^7.0.3, promise@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf"
dependencies:
@ -5834,21 +5864,6 @@ react-modal@1.6.5:
exenv "1.2.0"
lodash.assign "^4.2.0"
react-overlays@0.6.3:
version "0.6.3"
resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-0.6.3.tgz#e4e1f5b04b2cc5fc167083b9414ad42e9949b9bd"
dependencies:
classnames "^2.1.3"
dom-helpers "^2.3.0"
react-prop-types "^0.2.1"
warning "^2.1.0"
react-prop-types@^0.2.1:
version "0.2.2"
resolved "https://registry.yarnpkg.com/react-prop-types/-/react-prop-types-0.2.2.tgz#ae49914d4952382113d0e210b2e51016f0bd7f19"
dependencies:
warning "^2.0.0"
react-redux@4.4.5:
version "4.4.5"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-4.4.5.tgz#f509a2981be2252d10c629ef7c559347a4aec457"
@ -6344,7 +6359,7 @@ set-immediate-shim@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
setimmediate@^1.0.4:
setimmediate@^1.0.4, setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
@ -7190,12 +7205,6 @@ vows@0.6.0:
dependencies:
eyes ">=0.1.6"
warning@^2.0.0, warning@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/warning/-/warning-2.1.0.tgz#21220d9c63afc77a8c92111e011af705ce0c6901"
dependencies:
loose-envify "^1.0.0"
watchpack@^0.2.1:
version "0.2.9"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-0.2.9.tgz#62eaa4ab5e5ba35fdfc018275626e3c0f5e3fb0b"
@ -7297,6 +7306,10 @@ webpack@2.2.1:
webpack-sources "^0.1.4"
yargs "^6.0.0"
whatwg-fetch@>=0.10.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
whatwg-fetch@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-0.9.0.tgz#0e3684c6cb9995b43efc9df03e4c365d95fd9cc0"