<commit_before>// the eslint "no-unused-expressions" rule is triggered by the `expect`
// assertions in the tests. So, in order to avoid problems with eslint, I'm
// disabling that rule in this file
//
/* eslint-disable no-unused-expressions */

import React from 'react';
import { shallow, mount } from 'enzyme';
import chai from 'chai';
import sinon from 'sinon';
import NumericInput from './NumericInput';

const expect = chai.expect;

/* *****************************************************************************
the onValidation handler for the NumericInput component
    should be called on initialization with required=true, value=valid
    should be called on initialization with required=true, value=invalid
    should be called on initialization with required=true, value=blank
    should be called on initialization with required=false, value=valid
    should be called on initialization with required=false, value=invalid
    should be called on initialization with required=false, value=blank
    should not be called after change without prior blur event
    should be called on blur event
    should be called after change following a previous blur event
*/
describe('the onValidation handler for the NumericInput component', () => {

    const description = 'a numeric input';
    const expectedMessage = `${description} is required`;

    it('should be called on initialization with required=true, value=valid', () => {
        const onValidation = sinon.spy();

        const required = true;
        const value = 123.456;

        const component = mount(<NumericInput required={required} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);
        expect(onValidation.args[0][0]).to.equal(false, 'args[0][0]');
        expect(onValidation.args[0][1]).to.equal(true, 'args[0][1]');
        expect(onValidation.args[0][2]).to.equal(null, 'args[0][2]');
    });

    it('should be called on initialization with required=true, value=invalid', () => {
        const onValidation = sinon.spy();

        const required = true;
        const value = 'this is not a number';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);
        expect(onValidation.args[0][0]).to.equal(false, 'args[0][0]');
        expect(onValidation.args[0][1]).to.equal(false, 'args[0][1]');
        expect(onValidation.args[0][2]).to.equal(expectedMessage, 'args[0][2]');
    });

    it('should be called on initialization with required=true, value=blank', () => {
        const onValidation = sinon.spy();

        const required = true;
        const value = '';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);
        expect(onValidation.args[0][0]).to.equal(false, 'args[0][0]');
        expect(onValidation.args[0][1]).to.equal(false, 'args[0][1]');
        expect(onValidation.args[0][2]).to.equal(expectedMessage, 'args[0][2]');
    });

    it('should be called on initialization with required=false, value=valid', () => {
        const onValidation = sinon.spy();

        const required = false;
        const value = '101.9';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);
        expect(onValidation.args[0][0]).to.equal(false, 'args[0][0]');
        expect(onValidation.args[0][1]).to.equal(true, 'args[0][1]');
        expect(onValidation.args[0][2]).to.equal(null, 'args[0][2]');
    });

    it('should be called on initialization with required=false, value=invalid', () => {
        const onValidation = sinon.spy();

        const required = false;
        const value = 'woohoo!';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);
        expect(onValidation.args[0][0]).to.equal(false, 'args[0][0]');
        expect(onValidation.args[0][1]).to.equal(true, 'args[0][1]');
        expect(onValidation.args[0][2]).to.equal(null, 'args[0][2]');
    });

    it('should be called on initialization with required=false, value=blank', () => {
        const onValidation = sinon.spy();

        const required = false;
        const value = '';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);
        expect(onValidation.args[0][0]).to.equal(false, 'args[0][0]');
        expect(onValidation.args[0][1]).to.equal(true, 'args[0][1]');
        expect(onValidation.args[0][2]).to.equal(null, 'args[0][2]');
    });

    it('should not be called after change without prior blur event', () => {
        const onValidation = sinon.spy();

        const required = false;
        const value = '';
        const newValue = '33.3';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);

        component.find('input').simulate('change', {
            target: { value: newValue }
        });

        expect(onValidation.callCount).to.equal(1);
    });

    it('should be called on blur event', () => {
        const onValidation = sinon.spy();

        const required = true;
        const value = '';
        const newValue = '33.3';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);

        component.find('input').simulate('blur', {
            target: { value: newValue }
        });

        expect(onValidation.callCount).to.equal(2);
        expect(onValidation.args[1][0]).to.equal(true, 'args[1][0]');
        expect(onValidation.args[1][1]).to.equal(true, 'args[1][1]');
        expect(onValidation.args[1][2]).to.equal(null, 'args[1][2]');
    });

    it('should be called after change following a previous blur event', () => {
        const onValidation = sinon.spy();

        const required = true;
        const value = '';
        const newValue = '33.3';
        const finalValue = '';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);

        component.find('input').simulate('blur', {
            target: { value: newValue }
        });

        expect(onValidation.callCount).to.equal(2);

        component.find('input').simulate('change', {
            target: { value: finalValue }
        });

        expect(onValidation.callCount).to.equal(3);

        expect(onValidation.args[2][0]).to.equal(true, 'args[2][0]');
        expect(onValidation.args[2][1]).to.equal(false, 'args[2][1]');
        expect(onValidation.args[2][2]).to.equal(expectedMessage, 'args[2][2]');
    });

});

/* *****************************************************************************
in terms of basic markup, the NumericInput component
    should be a div.form-group
    should include an input[type="text"]
    should include an input.form-control
    should include a label with the appropriate text if a label is specified
    should include a placeholder if a placeholder is specified
    should include a label with the the required flag if a label is specified & required is set
    should not include a label with the the required flag if a label is
        specified & required is not set
    should not include a label with the the required flag if a label is not
        specified & required is set
*/
describe('in terms of basic markup, the NumericInput component', () => {

    it('should be a div.form-group', () => {
        const component = shallow(<NumericInput />);

        expect(component.is('div.form-group')).to.equal(true);
    });

    it('should include an input[type="text"]', () => {
        const component = shallow(<NumericInput />);

        expect(component.find('input').length).to.equal(1);
        expect(component.find('input[type="text"]').length).to.equal(1);
    });

    it('should include an input.form-control', () => {
        const component = shallow(<NumericInput />);

        expect(component.find('input').length).to.equal(1);
        expect(component.find('input.form-control').length).to.equal(1);
    });

    it('should include a label with the appropriate text if a label is specified', () => {
        const label = 'some label';

        const component = shallow(<NumericInput label={label} />);

        expect(component.find('Label').length).to.equal(1);
        expect(component.find('Label').props().label).to.equal(label);
    });

    it('should include a placeholder if a placeholder is specified', () => {
        const placeholder = 'a number goes here';

        const component = shallow(<NumericInput placeholder={placeholder} />);

        expect(component.find('input').length).to.equal(1);
        expect(component.find('input').props().placeholder).to.equal(placeholder);
    });

    it('should include a label with the the required flag if a label is ' +
        'specified & required is set', () => {
        const label = 'some label';
        const required = true;

        const component = shallow(<NumericInput required={required} label={label} />);

        expect(component.find('Label').length).to.equal(1);
        expect(component.find('Label').props().required).to.equal(required);
    });

    it('should not include a label with the the required flag if a label is ' +
        'specified & required is not set', () => {
        const label = 'some label';
        const required = false;

        const component = shallow(<NumericInput required={required} label={label} />);

        expect(component.find('Label').length).to.equal(1);
        expect(component.find('Label').props().required).to.equal(required);
    });

    it('should not include a label with the the required flag if a label is ' +
        'not specified & required is set', () => {
        const required = false;

        const component = shallow(<NumericInput required={required} />);

        expect(component.find('Label').length).to.equal(0);
    });
});
<commit_msg>updated notes<commit_after>// the eslint "no-unused-expressions" rule is triggered by the `expect`
// assertions in the tests. So, in order to avoid problems with eslint, I'm
// disabling that rule in this file
//
/* eslint-disable no-unused-expressions */

import React from 'react';
import { shallow, mount } from 'enzyme';
import chai from 'chai';
import sinon from 'sinon';
import NumericInput from './NumericInput';

const expect = chai.expect;

/* *****************************************************************************
the onChange handler for the NumericInput component
    should not be called on initialization
    should be called on edit when the value has changed
    should not be called on edit when the value has not changed
    should be called on blur when the value has changed
    should not be called on blur when the value has not changed
*/

/* *****************************************************************************
the onValidation handler for the NumericInput component
    should be called on initialization with required=true, value=valid
    should be called on initialization with required=true, value=invalid
    should be called on initialization with required=true, value=blank
    should be called on initialization with required=false, value=valid
    should be called on initialization with required=false, value=invalid
    should be called on initialization with required=false, value=blank
    should not be called after change without prior blur event
    should be called on blur event
    should be called after change following a previous blur event
*/
describe('the onValidation handler for the NumericInput component', () => {

    const description = 'a numeric input';
    const expectedMessage = `${description} is required`;

    it('should be called on initialization with required=true, value=valid', () => {
        const onValidation = sinon.spy();

        const required = true;
        const value = 123.456;

        const component = mount(<NumericInput required={required} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);
        expect(onValidation.args[0][0]).to.equal(false, 'args[0][0]');
        expect(onValidation.args[0][1]).to.equal(true, 'args[0][1]');
        expect(onValidation.args[0][2]).to.equal(null, 'args[0][2]');
    });

    it('should be called on initialization with required=true, value=invalid', () => {
        const onValidation = sinon.spy();

        const required = true;
        const value = 'this is not a number';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);
        expect(onValidation.args[0][0]).to.equal(false, 'args[0][0]');
        expect(onValidation.args[0][1]).to.equal(false, 'args[0][1]');
        expect(onValidation.args[0][2]).to.equal(expectedMessage, 'args[0][2]');
    });

    it('should be called on initialization with required=true, value=blank', () => {
        const onValidation = sinon.spy();

        const required = true;
        const value = '';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);
        expect(onValidation.args[0][0]).to.equal(false, 'args[0][0]');
        expect(onValidation.args[0][1]).to.equal(false, 'args[0][1]');
        expect(onValidation.args[0][2]).to.equal(expectedMessage, 'args[0][2]');
    });

    it('should be called on initialization with required=false, value=valid', () => {
        const onValidation = sinon.spy();

        const required = false;
        const value = '101.9';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);
        expect(onValidation.args[0][0]).to.equal(false, 'args[0][0]');
        expect(onValidation.args[0][1]).to.equal(true, 'args[0][1]');
        expect(onValidation.args[0][2]).to.equal(null, 'args[0][2]');
    });

    it('should be called on initialization with required=false, value=invalid', () => {
        const onValidation = sinon.spy();

        const required = false;
        const value = 'woohoo!';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);
        expect(onValidation.args[0][0]).to.equal(false, 'args[0][0]');
        expect(onValidation.args[0][1]).to.equal(true, 'args[0][1]');
        expect(onValidation.args[0][2]).to.equal(null, 'args[0][2]');
    });

    it('should be called on initialization with required=false, value=blank', () => {
        const onValidation = sinon.spy();

        const required = false;
        const value = '';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);
        expect(onValidation.args[0][0]).to.equal(false, 'args[0][0]');
        expect(onValidation.args[0][1]).to.equal(true, 'args[0][1]');
        expect(onValidation.args[0][2]).to.equal(null, 'args[0][2]');
    });

    it('should not be called after change without prior blur event', () => {
        const onValidation = sinon.spy();

        const required = false;
        const value = '';
        const newValue = '33.3';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);

        component.find('input').simulate('change', {
            target: { value: newValue }
        });

        expect(onValidation.callCount).to.equal(1);
    });

    it('should be called on blur event', () => {
        const onValidation = sinon.spy();

        const required = true;
        const value = '';
        const newValue = '33.3';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);

        component.find('input').simulate('blur', {
            target: { value: newValue }
        });

        expect(onValidation.callCount).to.equal(2);
        expect(onValidation.args[1][0]).to.equal(true, 'args[1][0]');
        expect(onValidation.args[1][1]).to.equal(true, 'args[1][1]');
        expect(onValidation.args[1][2]).to.equal(null, 'args[1][2]');
    });

    it('should be called after change following a previous blur event', () => {
        const onValidation = sinon.spy();

        const required = true;
        const value = '';
        const newValue = '33.3';
        const finalValue = '';

        const component = mount(<NumericInput required={required} description={description} value={value} onValidation={onValidation} />);

        expect(onValidation.callCount).to.equal(1);

        component.find('input').simulate('blur', {
            target: { value: newValue }
        });

        expect(onValidation.callCount).to.equal(2);

        component.find('input').simulate('change', {
            target: { value: finalValue }
        });

        expect(onValidation.callCount).to.equal(3);

        expect(onValidation.args[2][0]).to.equal(true, 'args[2][0]');
        expect(onValidation.args[2][1]).to.equal(false, 'args[2][1]');
        expect(onValidation.args[2][2]).to.equal(expectedMessage, 'args[2][2]');
    });

});

/* *****************************************************************************
in terms of basic markup, the NumericInput component
    should be a div.form-group
    should include an input[type="text"]
    should include an input.form-control
    should include a label with the appropriate text if a label is specified
    should include a placeholder if a placeholder is specified
    should include a label with the the required flag if a label is specified & required is set
    should not include a label with the the required flag if a label is
        specified & required is not set
    should not include a label with the the required flag if a label is not
        specified & required is set
*/
describe('in terms of basic markup, the NumericInput component', () => {

    it('should be a div.form-group', () => {
        const component = shallow(<NumericInput />);

        expect(component.is('div.form-group')).to.equal(true);
    });

    it('should include an input[type="text"]', () => {
        const component = shallow(<NumericInput />);

        expect(component.find('input').length).to.equal(1);
        expect(component.find('input[type="text"]').length).to.equal(1);
    });

    it('should include an input.form-control', () => {
        const component = shallow(<NumericInput />);

        expect(component.find('input').length).to.equal(1);
        expect(component.find('input.form-control').length).to.equal(1);
    });

    it('should include a label with the appropriate text if a label is specified', () => {
        const label = 'some label';

        const component = shallow(<NumericInput label={label} />);

        expect(component.find('Label').length).to.equal(1);
        expect(component.find('Label').props().label).to.equal(label);
    });

    it('should include a placeholder if a placeholder is specified', () => {
        const placeholder = 'a number goes here';

        const component = shallow(<NumericInput placeholder={placeholder} />);

        expect(component.find('input').length).to.equal(1);
        expect(component.find('input').props().placeholder).to.equal(placeholder);
    });

    it('should include a label with the the required flag if a label is ' +
        'specified & required is set', () => {
        const label = 'some label';
        const required = true;

        const component = shallow(<NumericInput required={required} label={label} />);

        expect(component.find('Label').length).to.equal(1);
        expect(component.find('Label').props().required).to.equal(required);
    });

    it('should not include a label with the the required flag if a label is ' +
        'specified & required is not set', () => {
        const label = 'some label';
        const required = false;

        const component = shallow(<NumericInput required={required} label={label} />);

        expect(component.find('Label').length).to.equal(1);
        expect(component.find('Label').props().required).to.equal(required);
    });

    it('should not include a label with the the required flag if a label is ' +
        'not specified & required is set', () => {
        const required = false;

        const component = shallow(<NumericInput required={required} />);

        expect(component.find('Label').length).to.equal(0);
    });
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {
    Text,
    View,
    ListView,
    Button,
    RefreshControl
} from 'react-native';
import { connect } from 'react-redux';
import { Actions } from 'react-native-router-flux';
import { fetchWeek } from '../actions';
import i18n from 'react-native-i18n';
import bundledTranslations from '../translations';

class WeekView extends Component {
    componentDidMount() {
        Actions.refresh({key: 'timetable', title: i18n.t('week_view')});
    }

    renderTimeslots() {
        let slots = this.props.slots;
        slots.splice(0, 1);

        return slots.map((slots) =>
            <Text key={slots.start}>
                {slots.start} - {slots.end}
            </Text>
        );
    }

    render() {
        return (
            <View style={styles.flex}>
                <View>
                    {this.renderTimeslots()}
                </View>
            </View>
        );
    }
}

i18n.locale = 'de';
i18n.fallbacks = true;
i18n.translations = bundledTranslations;

const styles = {
    flex: {
        flex: 1
    }
};

const mapStateToProps = state => {
    return {
        user: state.login.user,
        program: state.login.program,
        masterdata: state.timetable.masterdata,
        slots: state.timetable.timeslots,
        currentWeek: state.timetable.currentWeek,
        semester: state.settings.semester,
        special_subject: state.settings.special_subject
    }
};

export default connect(mapStateToProps, { fetchWeek })(WeekView);
<commit_msg>Scaffoled the column-based layout of the 'WeekView'<commit_after>import React, { Component } from 'react';
import {
    Text,
    View,
    ListView,
    Button,
    RefreshControl
} from 'react-native';
import { connect } from 'react-redux';
import { Actions } from 'react-native-router-flux';
import { fetchWeek } from '../actions';
import i18n from 'react-native-i18n';
import bundledTranslations from '../translations';

class WeekView extends Component {
    componentDidMount() {
        Actions.refresh({key: 'timetable', title: i18n.t('week_view')});
    }

    renderTimeslots() {
        let slots = this.props.slots;
        slots.splice(0, 1);

        return slots.map((slots) =>
            <Text key={slots.start} style={styles.slotsText}>
                {slots.start}{"\n    -\n"}{slots.end}
            </Text>
        );
    }

    render() {
        return (
            <View style={styles.columnContainer}>
                <View style={styles.column}>
                    <Text style={styles.columnHeader}>{i18n.t('timeslots')}</Text>
                    {this.renderTimeslots()}
                </View>
            </View>
        );
    }
}

i18n.locale = 'de';
i18n.fallbacks = true;
i18n.translations = bundledTranslations;

const styles = {
    columnContainer: {
        flex: 1,
        flexDirection: "row"
    },
    column: {
        flex: 1,
        flexDirection: "column",
        marginLeft: 10,
        marginRight: 10
    },
    columnHeader: {
        fontSize: 20,
        fontWeight: "bold",
        marginBottom: 10
    },
    slotsText: {
        fontSize: 15,
        fontWeight: "bold",
        marginTop: 10,
        marginBottom: 10
    }
};

const mapStateToProps = state => {
    return {
        user: state.login.user,
        program: state.login.program,
        masterdata: state.timetable.masterdata,
        slots: state.timetable.timeslots,
        currentWeek: state.timetable.currentWeek,
        semester: state.settings.semester,
        special_subject: state.settings.special_subject
    }
};

export default connect(mapStateToProps, { fetchWeek })(WeekView);
<|endoftext|>


<commit_before>/* eslint no-underscore-dangle: "off" */
import { getDocument } from 'ssr-window';
import { nextTick, bindModuleMethods } from '../../utils/utils';

const Autoplay = {
  run() {
    const swiper = this;
    const $activeSlideEl = swiper.slides.eq(swiper.activeIndex);
    let delay = swiper.params.autoplay.delay;
    if ($activeSlideEl.attr('data-swiper-autoplay')) {
      delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay;
    }
    clearTimeout(swiper.autoplay.timeout);
    swiper.autoplay.timeout = nextTick(() => {
      let autoplayResult;
      if (swiper.params.autoplay.reverseDirection) {
        if (swiper.params.loop) {
          swiper.loopFix();
          autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
          swiper.emit('autoplay');
        } else if (!swiper.isBeginning) {
          autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
          swiper.emit('autoplay');
        } else if (!swiper.params.autoplay.stopOnLastSlide) {
          autoplayResult = swiper.slideTo(
            swiper.slides.length - 1,
            swiper.params.speed,
            true,
            true,
          );
          swiper.emit('autoplay');
        } else {
          swiper.autoplay.stop();
        }
      } else if (swiper.params.loop) {
        swiper.loopFix();
        autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
        swiper.emit('autoplay');
      } else if (!swiper.isEnd) {
        autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
        swiper.emit('autoplay');
      } else if (!swiper.params.autoplay.stopOnLastSlide) {
        autoplayResult = swiper.slideTo(0, swiper.params.speed, true, true);
        swiper.emit('autoplay');
      } else {
        swiper.autoplay.stop();
      }
      if (swiper.params.cssMode && swiper.autoplay.running) swiper.autoplay.run();
      else if (autoplayResult === false) {
        swiper.autoplay.run();
      }
    }, delay);
  },
  start() {
    const swiper = this;
    if (typeof swiper.autoplay.timeout !== 'undefined') return false;
    if (swiper.autoplay.running) return false;
    swiper.autoplay.running = true;
    swiper.emit('autoplayStart');
    swiper.autoplay.run();
    return true;
  },
  stop() {
    const swiper = this;
    if (!swiper.autoplay.running) return false;
    if (typeof swiper.autoplay.timeout === 'undefined') return false;

    if (swiper.autoplay.timeout) {
      clearTimeout(swiper.autoplay.timeout);
      swiper.autoplay.timeout = undefined;
    }
    swiper.autoplay.running = false;
    swiper.emit('autoplayStop');
    return true;
  },
  pause(speed) {
    const swiper = this;
    if (!swiper.autoplay.running) return;
    if (swiper.autoplay.paused) return;
    if (swiper.autoplay.timeout) clearTimeout(swiper.autoplay.timeout);
    swiper.autoplay.paused = true;
    if (speed === 0 || !swiper.params.autoplay.waitForTransition) {
      swiper.autoplay.paused = false;
      swiper.autoplay.run();
    } else {
      ['transitionend', 'webkitTransitionEnd'].forEach((event) => {
        swiper.$wrapperEl[0].addEventListener(event, swiper.autoplay.onTransitionEnd);
      });
    }
  },
  onVisibilityChange() {
    const swiper = this;
    const document = getDocument();
    if (document.visibilityState === 'hidden' && swiper.autoplay.running) {
      swiper.autoplay.pause();
    }
    if (document.visibilityState === 'visible' && swiper.autoplay.paused) {
      swiper.autoplay.run();
      swiper.autoplay.paused = false;
    }
  },
  onTransitionEnd(e) {
    const swiper = this;
    if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return;
    if (e.target !== swiper.$wrapperEl[0]) return;
    ['transitionend', 'webkitTransitionEnd'].forEach((event) => {
      swiper.$wrapperEl[0].removeEventListener(event, swiper.autoplay.onTransitionEnd);
    });
    swiper.autoplay.paused = false;
    if (!swiper.autoplay.running) {
      swiper.autoplay.stop();
    } else {
      swiper.autoplay.run();
    }
  },
  onMouseEnter() {
    const swiper = this;
    swiper.autoplay.pause();
    ['transitionend', 'webkitTransitionEnd'].forEach((event) => {
      swiper.$wrapperEl[0].removeEventListener(event, swiper.autoplay.onTransitionEnd);
    });
  },
  onMouseLeave() {
    const swiper = this;
    swiper.autoplay.run();
  },
  attachMouseEvents() {
    const swiper = this;
    if (swiper.params.autoplay.pauseOnMouseEnter) {
      swiper.$el.on('mouseenter', swiper.autoplay.onMouseEnter);
      swiper.$el.on('mouseleave', swiper.autoplay.onMouseLeave);
    }
  },
  detachMouseEvents() {
    const swiper = this;
    swiper.$el.off('mouseenter', swiper.autoplay.onMouseEnter);
    swiper.$el.off('mouseleave', swiper.autoplay.onMouseLeave);
  },
};

export default {
  name: 'autoplay',
  params: {
    autoplay: {
      enabled: false,
      delay: 3000,
      waitForTransition: true,
      disableOnInteraction: true,
      stopOnLastSlide: false,
      reverseDirection: false,
      pauseOnMouseEnter: false,
    },
  },
  create() {
    const swiper = this;
    bindModuleMethods(swiper, {
      autoplay: {
        ...Autoplay,
        running: false,
        paused: false,
      },
    });
  },
  on: {
    init(swiper) {
      if (swiper.params.autoplay.enabled) {
        swiper.autoplay.start();
        const document = getDocument();
        document.addEventListener('visibilitychange', swiper.autoplay.onVisibilityChange);
        swiper.autoplay.attachMouseEvents();
      }
    },
    beforeTransitionStart(swiper, speed, internal) {
      if (swiper.autoplay.running) {
        if (internal || !swiper.params.autoplay.disableOnInteraction) {
          swiper.autoplay.pause(speed);
        } else {
          swiper.autoplay.stop();
        }
      }
    },
    sliderFirstMove(swiper) {
      if (swiper.autoplay.running) {
        if (swiper.params.autoplay.disableOnInteraction) {
          swiper.autoplay.stop();
        } else {
          swiper.autoplay.pause();
        }
      }
    },
    touchEnd(swiper) {
      if (
        swiper.params.cssMode &&
        swiper.autoplay.paused &&
        !swiper.params.autoplay.disableOnInteraction
      ) {
        swiper.autoplay.run();
      }
    },
    destroy(swiper) {
      swiper.autoplay.detachMouseEvents();
      if (swiper.autoplay.running) {
        swiper.autoplay.stop();
      }
      const document = getDocument();
      document.removeEventListener('visibilitychange', swiper.autoplay.onVisibilityChange);
    },
  },
};
<commit_msg>fix(autoplay): fix resume after pause on mouseenter<commit_after>/* eslint no-underscore-dangle: "off" */
import { getDocument } from 'ssr-window';
import { nextTick, bindModuleMethods } from '../../utils/utils';

const Autoplay = {
  run() {
    const swiper = this;
    const $activeSlideEl = swiper.slides.eq(swiper.activeIndex);
    let delay = swiper.params.autoplay.delay;
    if ($activeSlideEl.attr('data-swiper-autoplay')) {
      delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay;
    }
    clearTimeout(swiper.autoplay.timeout);
    swiper.autoplay.timeout = nextTick(() => {
      let autoplayResult;
      if (swiper.params.autoplay.reverseDirection) {
        if (swiper.params.loop) {
          swiper.loopFix();
          autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
          swiper.emit('autoplay');
        } else if (!swiper.isBeginning) {
          autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
          swiper.emit('autoplay');
        } else if (!swiper.params.autoplay.stopOnLastSlide) {
          autoplayResult = swiper.slideTo(
            swiper.slides.length - 1,
            swiper.params.speed,
            true,
            true,
          );
          swiper.emit('autoplay');
        } else {
          swiper.autoplay.stop();
        }
      } else if (swiper.params.loop) {
        swiper.loopFix();
        autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
        swiper.emit('autoplay');
      } else if (!swiper.isEnd) {
        autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
        swiper.emit('autoplay');
      } else if (!swiper.params.autoplay.stopOnLastSlide) {
        autoplayResult = swiper.slideTo(0, swiper.params.speed, true, true);
        swiper.emit('autoplay');
      } else {
        swiper.autoplay.stop();
      }
      if (swiper.params.cssMode && swiper.autoplay.running) swiper.autoplay.run();
      else if (autoplayResult === false) {
        swiper.autoplay.run();
      }
    }, delay);
  },
  start() {
    const swiper = this;
    if (typeof swiper.autoplay.timeout !== 'undefined') return false;
    if (swiper.autoplay.running) return false;
    swiper.autoplay.running = true;
    swiper.emit('autoplayStart');
    swiper.autoplay.run();
    return true;
  },
  stop() {
    const swiper = this;
    if (!swiper.autoplay.running) return false;
    if (typeof swiper.autoplay.timeout === 'undefined') return false;

    if (swiper.autoplay.timeout) {
      clearTimeout(swiper.autoplay.timeout);
      swiper.autoplay.timeout = undefined;
    }
    swiper.autoplay.running = false;
    swiper.emit('autoplayStop');
    return true;
  },
  pause(speed) {
    const swiper = this;
    if (!swiper.autoplay.running) return;
    if (swiper.autoplay.paused) return;
    if (swiper.autoplay.timeout) clearTimeout(swiper.autoplay.timeout);
    swiper.autoplay.paused = true;
    if (speed === 0 || !swiper.params.autoplay.waitForTransition) {
      swiper.autoplay.paused = false;
      swiper.autoplay.run();
    } else {
      ['transitionend', 'webkitTransitionEnd'].forEach((event) => {
        swiper.$wrapperEl[0].addEventListener(event, swiper.autoplay.onTransitionEnd);
      });
    }
  },
  onVisibilityChange() {
    const swiper = this;
    const document = getDocument();
    if (document.visibilityState === 'hidden' && swiper.autoplay.running) {
      swiper.autoplay.pause();
    }
    if (document.visibilityState === 'visible' && swiper.autoplay.paused) {
      swiper.autoplay.run();
      swiper.autoplay.paused = false;
    }
  },
  onTransitionEnd(e) {
    const swiper = this;
    if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return;
    if (e.target !== swiper.$wrapperEl[0]) return;
    ['transitionend', 'webkitTransitionEnd'].forEach((event) => {
      swiper.$wrapperEl[0].removeEventListener(event, swiper.autoplay.onTransitionEnd);
    });
    swiper.autoplay.paused = false;
    if (!swiper.autoplay.running) {
      swiper.autoplay.stop();
    } else {
      swiper.autoplay.run();
    }
  },
  onMouseEnter() {
    const swiper = this;
    swiper.autoplay.pause();
    ['transitionend', 'webkitTransitionEnd'].forEach((event) => {
      swiper.$wrapperEl[0].removeEventListener(event, swiper.autoplay.onTransitionEnd);
    });
  },
  onMouseLeave() {
    const swiper = this;
    swiper.autoplay.paused = false;
    swiper.autoplay.run();
  },
  attachMouseEvents() {
    const swiper = this;
    if (swiper.params.autoplay.pauseOnMouseEnter) {
      swiper.$el.on('mouseenter', swiper.autoplay.onMouseEnter);
      swiper.$el.on('mouseleave', swiper.autoplay.onMouseLeave);
    }
  },
  detachMouseEvents() {
    const swiper = this;
    swiper.$el.off('mouseenter', swiper.autoplay.onMouseEnter);
    swiper.$el.off('mouseleave', swiper.autoplay.onMouseLeave);
  },
};

export default {
  name: 'autoplay',
  params: {
    autoplay: {
      enabled: false,
      delay: 3000,
      waitForTransition: true,
      disableOnInteraction: true,
      stopOnLastSlide: false,
      reverseDirection: false,
      pauseOnMouseEnter: false,
    },
  },
  create() {
    const swiper = this;
    bindModuleMethods(swiper, {
      autoplay: {
        ...Autoplay,
        running: false,
        paused: false,
      },
    });
  },
  on: {
    init(swiper) {
      if (swiper.params.autoplay.enabled) {
        swiper.autoplay.start();
        const document = getDocument();
        document.addEventListener('visibilitychange', swiper.autoplay.onVisibilityChange);
        swiper.autoplay.attachMouseEvents();
      }
    },
    beforeTransitionStart(swiper, speed, internal) {
      if (swiper.autoplay.running) {
        if (internal || !swiper.params.autoplay.disableOnInteraction) {
          swiper.autoplay.pause(speed);
        } else {
          swiper.autoplay.stop();
        }
      }
    },
    sliderFirstMove(swiper) {
      if (swiper.autoplay.running) {
        if (swiper.params.autoplay.disableOnInteraction) {
          swiper.autoplay.stop();
        } else {
          swiper.autoplay.pause();
        }
      }
    },
    touchEnd(swiper) {
      if (
        swiper.params.cssMode &&
        swiper.autoplay.paused &&
        !swiper.params.autoplay.disableOnInteraction
      ) {
        swiper.autoplay.run();
      }
    },
    destroy(swiper) {
      swiper.autoplay.detachMouseEvents();
      if (swiper.autoplay.running) {
        swiper.autoplay.stop();
      }
      const document = getDocument();
      document.removeEventListener('visibilitychange', swiper.autoplay.onVisibilityChange);
    },
  },
};
<|endoftext|>


<commit_before>/* eslint-env mocha */
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {shallow, mount} from 'enzyme';
import {assert} from 'chai';
import TextField from './TextField';
import TextFieldHint from './TextFieldHint';
import TextFieldLabel from './TextFieldLabel';
import getMuiTheme from '../styles/getMuiTheme';

describe('<TextField />', () => {
  const muiTheme = getMuiTheme();
  const shallowWithContext = (node) => shallow(node, {context: {muiTheme}});
  const mountWithContext = (node) => mount(node, {
    context: {muiTheme},
    childContextTypes: {muiTheme: PropTypes.object},
  });

  it('passes event and value to the onChange callback', (done) => {
    const wrapper = shallowWithContext(
      <TextField
        onChange={(event, value) => {
          assert.strictEqual(event.target.value, 'woof');
          assert.strictEqual(value, 'woof', 'should pass the value as the 2nd arg');
          done();
        }}
        id="unique"
      />
    );

    wrapper.find('input').simulate('change', {target: {value: 'woof'}});
  });

  it('shrinks TextFieldLabel when defaultValue', () => {
    const wrapper = shallowWithContext(
      <TextField
        floatingLabelText="floating label text"
        defaultValue="default value"
      />
    );

    assert.strictEqual(wrapper.find(TextFieldLabel).props().shrink, true, 'should shrink TextFieldLabel');
    wrapper.update();
    assert.strictEqual(wrapper.find(TextFieldLabel).props().shrink, true, 'should shrink TextFieldLabel');
  });

  it('TextFieldLabel has reference to parent TextField', () => {
    const textFieldId = 'test-text-field';
    const wrapper = mountWithContext(
      <TextField
        floatingLabelText="floating label text"
        id={textFieldId}
      />
    );

    assert.strictEqual(wrapper.find(TextFieldLabel).props().htmlFor,
      textFieldId, 'should have ref to parent TextField');
  });

  describe('prop: children', () => {
    it('should forward any property to the root', () => {
      const wrapper = shallowWithContext(
        <TextField data-test="hello" id="unique">

        </TextField>
      );

      assert.strictEqual(
        wrapper.is('[data-test="hello"]'), true,
        'The root element should receive any additional properties'
      );
    });
  });

  describe('isValid', () => {
    it('should consider the input as empty', () => {
      const values = [
        undefined,
        null,
        '',
      ];

      values.forEach((value) => {
        const wrapper = shallowWithContext(
          <TextField value={value} id="unique" />
        );

        assert.strictEqual(wrapper.state().hasValue, false,
          `Should consider '${value}' as empty`);
      });
    });

    it('should consider the input as not empty', () => {
      const values = [
        ' ',
        0,
        false,
      ];

      values.forEach((value) => {
        const wrapper = shallowWithContext(
          <TextField value={value} id="unique" />
        );

        assert.strictEqual(wrapper.state().hasValue, true,
          `Should consider '${value}' as not empty`);
      });
    });
  });

  describe('<TextFieldHint>', () => {
    it('should be hidden when the component is rerender with the same props', () => {
      class MyComponent1 extends Component {
        state = {
          value: '',
        };

        handleChange = () => {
          this.setState({value: ''});
        };

        render() {
          return (
            <TextField
              id="foo"
              value={this.state.value}
              hintText="bar"
              onChange={this.handleChange}
            />
          );
        }
      }

      const wrapper = mountWithContext(<MyComponent1 />);
      const input = wrapper.find('input');
      input.simulate('change', {target: {value: 'a'}});
      assert.strictEqual(wrapper.find(TextFieldHint).props().show, true,
        'The hint text should keep the same state');
    });
  });

  describe('prop: floatingLabelFocusStyle', () => {
    it('should be applied when the input is focused', () => {
      const wrapper = shallowWithContext(
        <TextField
          floatingLabelText="Name"
          floatingLabelFixed={true}
          floatingLabelFocusStyle={{color: 'blue'}}
          floatingLabelStyle={{color: 'red'}}
        />
      );
      wrapper.setState({
        isFocused: true,
      });
      assert.strictEqual(wrapper.find(TextFieldLabel).props().style.color, 'blue');
    });
  });

  describe('prop: floatingLabelFocusStyle', () => {
    it('should be applied', () => {
      const wrapper = shallowWithContext(
        <TextField
          floatingLabelText="Name"
          floatingLabelShrinkStyle={{transform: 'none'}}
        />
      );
      assert.strictEqual(wrapper.find(TextFieldLabel).props().shrinkStyle.transform, 'none');
    });
  });

  describe('prop: errorStyle', () => {
    it('should override the errorText', () => {
      const wrapper = shallowWithContext(
        <TextField
          id="foo"
          floatingLabelText="password"
          errorStyle={{
            color: 'red',
            bottom: 10,
          }}
          errorText="error message"
        />
      );

      const errorWrapper = wrapper.children().last();
      assert.strictEqual(errorWrapper.props().style.bottom, 10, 'Users should have the higher priority');
    });
  });

  describe('state: hasValue', () => {
    describe('of uncontrolled component', () => {
      it('should change depending on the input', () => {
        const wrapper = shallowWithContext(
          <TextField id="unique" />
        );
        const input = wrapper.find('input');
        assert.strictEqual(wrapper.state().hasValue, false);
        input.simulate('change', {target: {value: 'a'}});
        assert.strictEqual(wrapper.state().hasValue, true);
        input.simulate('change', {target: {value: ''}});
        assert.strictEqual(wrapper.state().hasValue, false);
      });
    });

    describe('of controlled component', () => {
      it('should be false if onChange does nothing despite the input', () => {
        const wrapper = shallowWithContext(
          <TextField value="" id="unique" />
        );
        wrapper.find('input').simulate('change', {target: {value: 'a'}});
        assert.strictEqual(wrapper.state().hasValue, false, 'because props.value is still invalid.');
      });

      it('should be true if and only if props.value is set', () => {
        const wrapper = shallowWithContext(
          <TextField value="" id="unique" />
        );
        assert.strictEqual(wrapper.state().hasValue, false);
        wrapper.setProps({value: 'a'});
        assert.strictEqual(wrapper.state().hasValue, true, 'it is consistent with props.value');
      });
    });
  });

  describe('ID handeling and generation', () => {
    it('should use the supplied id without overriding', () => {
      const id = '12345';
      const wrapper = shallowWithContext(
        <TextField id={id} />
      );
      assert.strictEqual(wrapper.prop('id'), id, 'should use provided id');
    });

    it('should generate an id if one not supplied', () => {
      const classname = 'abcde';
      const wrapper = shallowWithContext(
        <TextField name={classname} />
      );
      assert.ok(wrapper.prop('id'), 'should generate an id if not supplied');
    });
  });
});
<commit_msg>TextField - updated tests for text field label so it checked the id in the for tag against the id on the input box (issue #241)<commit_after>/* eslint-env mocha */
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {shallow, mount} from 'enzyme';
import {assert} from 'chai';
import TextField from './TextField';
import TextFieldHint from './TextFieldHint';
import TextFieldLabel from './TextFieldLabel';
import getMuiTheme from '../styles/getMuiTheme';

describe('<TextField />', () => {
  const muiTheme = getMuiTheme();
  const shallowWithContext = (node) => shallow(node, {context: {muiTheme}});
  const mountWithContext = (node) => mount(node, {
    context: {muiTheme},
    childContextTypes: {muiTheme: PropTypes.object},
  });

  it('passes event and value to the onChange callback', (done) => {
    const wrapper = shallowWithContext(
      <TextField
        onChange={(event, value) => {
          assert.strictEqual(event.target.value, 'woof');
          assert.strictEqual(value, 'woof', 'should pass the value as the 2nd arg');
          done();
        }}
        id="unique"
      />
    );

    wrapper.find('input').simulate('change', {target: {value: 'woof'}});
  });

  it('shrinks TextFieldLabel when defaultValue', () => {
    const wrapper = shallowWithContext(
      <TextField
        floatingLabelText="floating label text"
        defaultValue="default value"
      />
    );

    assert.strictEqual(wrapper.find(TextFieldLabel).props().shrink, true, 'should shrink TextFieldLabel');
    wrapper.update();
    assert.strictEqual(wrapper.find(TextFieldLabel).props().shrink, true, 'should shrink TextFieldLabel');
  });

  it('TextFieldLabel has reference to parent TextField', () => {
    const wrapper = shallowWithContext(<TextField floatingLabelText="somehting" />);

    // the html for should be pointing the label to the input box
    assert.strictEqual(wrapper.find(TextFieldLabel).props().htmlFor,
      wrapper.find('input').prop('id'), 'should have ref to parent TextField');
  });

  describe('prop: children', () => {
    it('should forward any property to the root', () => {
      const wrapper = shallowWithContext(
        <TextField data-test="hello" id="unique">

        </TextField>
      );

      assert.strictEqual(
        wrapper.is('[data-test="hello"]'), true,
        'The root element should receive any additional properties'
      );
    });
  });

  describe('isValid', () => {
    it('should consider the input as empty', () => {
      const values = [
        undefined,
        null,
        '',
      ];

      values.forEach((value) => {
        const wrapper = shallowWithContext(
          <TextField value={value} id="unique" />
        );

        assert.strictEqual(wrapper.state().hasValue, false,
          `Should consider '${value}' as empty`);
      });
    });

    it('should consider the input as not empty', () => {
      const values = [
        ' ',
        0,
        false,
      ];

      values.forEach((value) => {
        const wrapper = shallowWithContext(
          <TextField value={value} id="unique" />
        );

        assert.strictEqual(wrapper.state().hasValue, true,
          `Should consider '${value}' as not empty`);
      });
    });
  });

  describe('<TextFieldHint>', () => {
    it('should be hidden when the component is rerender with the same props', () => {
      class MyComponent1 extends Component {
        state = {
          value: '',
        };

        handleChange = () => {
          this.setState({value: ''});
        };

        render() {
          return (
            <TextField
              id="foo"
              value={this.state.value}
              hintText="bar"
              onChange={this.handleChange}
            />
          );
        }
      }

      const wrapper = mountWithContext(<MyComponent1 />);
      const input = wrapper.find('input');
      input.simulate('change', {target: {value: 'a'}});
      assert.strictEqual(wrapper.find(TextFieldHint).props().show, true,
        'The hint text should keep the same state');
    });
  });

  describe('prop: floatingLabelFocusStyle', () => {
    it('should be applied when the input is focused', () => {
      const wrapper = shallowWithContext(
        <TextField
          floatingLabelText="Name"
          floatingLabelFixed={true}
          floatingLabelFocusStyle={{color: 'blue'}}
          floatingLabelStyle={{color: 'red'}}
        />
      );
      wrapper.setState({
        isFocused: true,
      });
      assert.strictEqual(wrapper.find(TextFieldLabel).props().style.color, 'blue');
    });
  });

  describe('prop: floatingLabelFocusStyle', () => {
    it('should be applied', () => {
      const wrapper = shallowWithContext(
        <TextField
          floatingLabelText="Name"
          floatingLabelShrinkStyle={{transform: 'none'}}
        />
      );
      assert.strictEqual(wrapper.find(TextFieldLabel).props().shrinkStyle.transform, 'none');
    });
  });

  describe('prop: errorStyle', () => {
    it('should override the errorText', () => {
      const wrapper = shallowWithContext(
        <TextField
          id="foo"
          floatingLabelText="password"
          errorStyle={{
            color: 'red',
            bottom: 10,
          }}
          errorText="error message"
        />
      );

      const errorWrapper = wrapper.children().last();
      assert.strictEqual(errorWrapper.props().style.bottom, 10, 'Users should have the higher priority');
    });
  });

  describe('state: hasValue', () => {
    describe('of uncontrolled component', () => {
      it('should change depending on the input', () => {
        const wrapper = shallowWithContext(
          <TextField id="unique" />
        );
        const input = wrapper.find('input');
        assert.strictEqual(wrapper.state().hasValue, false);
        input.simulate('change', {target: {value: 'a'}});
        assert.strictEqual(wrapper.state().hasValue, true);
        input.simulate('change', {target: {value: ''}});
        assert.strictEqual(wrapper.state().hasValue, false);
      });
    });

    describe('of controlled component', () => {
      it('should be false if onChange does nothing despite the input', () => {
        const wrapper = shallowWithContext(
          <TextField value="" id="unique" />
        );
        wrapper.find('input').simulate('change', {target: {value: 'a'}});
        assert.strictEqual(wrapper.state().hasValue, false, 'because props.value is still invalid.');
      });

      it('should be true if and only if props.value is set', () => {
        const wrapper = shallowWithContext(
          <TextField value="" id="unique" />
        );
        assert.strictEqual(wrapper.state().hasValue, false);
        wrapper.setProps({value: 'a'});
        assert.strictEqual(wrapper.state().hasValue, true, 'it is consistent with props.value');
      });
    });
  });

  describe('ID handeling and generation', () => {
    it('should use the supplied id without overriding', () => {
      const id = '12345';
      const wrapper = shallowWithContext(
        <TextField id={id} />
      );
      assert.strictEqual(wrapper.prop('id'), id, 'should use provided id');
    });

    it('should generate an id if one not supplied', () => {
      const classname = 'abcde';
      const wrapper = shallowWithContext(
        <TextField name={classname} />
      );
      assert.ok(wrapper.prop('id'), 'should generate an id if not supplied');
    });
  });
});
<|endoftext|>


<commit_before>/* eslint no-underscore-dangle: "off" */
import Utils from '../../utils/utils';

const Autoplay = {
  run() {
    const swiper = this;
    const $activeSlideEl = swiper.slides.eq(swiper.activeIndex);
    let delay = swiper.params.autoplay.delay;
    if ($activeSlideEl.attr('data-swiper-autoplay')) {
      delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay;
    }
    clearTimeout(swiper.autoplay.timeout);
    swiper.autoplay.timeout = Utils.nextTick(() => {
      if (swiper.params.autoplay.reverseDirection) {
        if (swiper.params.loop) {
          swiper.loopFix();
          swiper.slidePrev(swiper.params.speed, true, true);
          swiper.emit('autoplay');
        } else if (!swiper.isBeginning) {
          swiper.slidePrev(swiper.params.speed, true, true);
          swiper.emit('autoplay');
        } else if (!swiper.params.autoplay.stopOnLastSlide) {
          swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true);
          swiper.emit('autoplay');
        } else {
          swiper.autoplay.stop();
        }
      } else if (swiper.params.loop) {
        swiper.loopFix();
        swiper.slideNext(swiper.params.speed, true, true);
        swiper.emit('autoplay');
      } else if (!swiper.isEnd) {
        swiper.slideNext(swiper.params.speed, true, true);
        swiper.emit('autoplay');
      } else if (!swiper.params.autoplay.stopOnLastSlide) {
        swiper.slideTo(0, swiper.params.speed, true, true);
        swiper.emit('autoplay');
      } else {
        swiper.autoplay.stop();
      }
    }, delay);
  },
  start() {
    const swiper = this;
    if (typeof swiper.autoplay.timeout !== 'undefined') return false;
    if (swiper.autoplay.running) return false;
    swiper.autoplay.running = true;
    swiper.emit('autoplayStart');
    swiper.autoplay.run();
    return true;
  },
  stop() {
    const swiper = this;
    if (!swiper.autoplay.running) return false;
    if (typeof swiper.autoplay.timeout === 'undefined') return false;

    if (swiper.autoplay.timeout) {
      clearTimeout(swiper.autoplay.timeout);
      swiper.autoplay.timeout = undefined;
    }
    swiper.autoplay.running = false;
    swiper.emit('autoplayStop');
    return true;
  },
  pause(speed) {
    const swiper = this;
    if (!swiper.autoplay.running) return;
    if (swiper.autoplay.paused) return;
    if (swiper.autoplay.timeout) clearTimeout(swiper.autoplay.timeout);
    swiper.autoplay.paused = true;
    if (speed === 0 || !swiper.params.autoplay.waitForTransition) {
      swiper.autoplay.paused = false;
      swiper.autoplay.run();
    } else {
      swiper.$wrapperEl[0].addEventListener('transitionend', swiper.autoplay.onTransitionEnd);
      swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd);
    }
  },
};

export default {
  name: 'autoplay',
  params: {
    autoplay: {
      enabled: false,
      delay: 3000,
      waitForTransition: true,
      disableOnInteraction: true,
      stopOnLastSlide: false,
      reverseDirection: false,
    },
  },
  create() {
    const swiper = this;
    Utils.extend(swiper, {
      autoplay: {
        running: false,
        paused: false,
        run: Autoplay.run.bind(swiper),
        start: Autoplay.start.bind(swiper),
        stop: Autoplay.stop.bind(swiper),
        pause: Autoplay.pause.bind(swiper),
        onTransitionEnd(e) {
          if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return;
          if (e.target !== this) return;
          swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.autoplay.onTransitionEnd);
          swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd);
          swiper.autoplay.paused = false;
          if (!swiper.autoplay.running) {
            swiper.autoplay.stop();
          } else {
            swiper.autoplay.run();
          }
        },
      },
    });
  },
  on: {
    init() {
      const swiper = this;
      if (swiper.params.autoplay.enabled) {
        swiper.autoplay.start();
      }
    },
    beforeTransitionStart(speed, internal) {
      const swiper = this;
      if (swiper.autoplay.running) {
        if (internal || !swiper.params.autoplay.disableOnInteraction) {
          swiper.autoplay.pause(speed);
        } else {
          swiper.autoplay.stop();
        }
      }
    },
    sliderFirstMove() {
      const swiper = this;
      if (swiper.autoplay.running) {
        if (swiper.params.autoplay.disableOnInteraction) {
          swiper.autoplay.stop();
        } else {
          swiper.autoplay.pause();
        }
      }
    },
    destroy() {
      const swiper = this;
      if (swiper.autoplay.running) {
        swiper.autoplay.stop();
      }
    },
  },
};
<commit_msg>v5: Autoplay - pause on document hidden and add compat with cssMode<commit_after>/* eslint no-underscore-dangle: "off" */
import Utils from '../../utils/utils';

const Autoplay = {
  run() {
    const swiper = this;
    const $activeSlideEl = swiper.slides.eq(swiper.activeIndex);
    let delay = swiper.params.autoplay.delay;
    if ($activeSlideEl.attr('data-swiper-autoplay')) {
      delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay;
    }
    clearTimeout(swiper.autoplay.timeout);
    swiper.autoplay.timeout = Utils.nextTick(() => {
      if (swiper.params.autoplay.reverseDirection) {
        if (swiper.params.loop) {
          swiper.loopFix();
          swiper.slidePrev(swiper.params.speed, true, true);
          swiper.emit('autoplay');
        } else if (!swiper.isBeginning) {
          swiper.slidePrev(swiper.params.speed, true, true);
          swiper.emit('autoplay');
        } else if (!swiper.params.autoplay.stopOnLastSlide) {
          swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true);
          swiper.emit('autoplay');
        } else {
          swiper.autoplay.stop();
        }
      } else if (swiper.params.loop) {
        swiper.loopFix();
        swiper.slideNext(swiper.params.speed, true, true);
        swiper.emit('autoplay');
      } else if (!swiper.isEnd) {
        swiper.slideNext(swiper.params.speed, true, true);
        swiper.emit('autoplay');
      } else if (!swiper.params.autoplay.stopOnLastSlide) {
        swiper.slideTo(0, swiper.params.speed, true, true);
        swiper.emit('autoplay');
      } else {
        swiper.autoplay.stop();
      }
      if (swiper.params.cssMode && swiper.autoplay.running) swiper.autoplay.run();
    }, delay);
  },
  start() {
    const swiper = this;
    if (typeof swiper.autoplay.timeout !== 'undefined') return false;
    if (swiper.autoplay.running) return false;
    swiper.autoplay.running = true;
    swiper.emit('autoplayStart');
    swiper.autoplay.run();
    return true;
  },
  stop() {
    const swiper = this;
    if (!swiper.autoplay.running) return false;
    if (typeof swiper.autoplay.timeout === 'undefined') return false;

    if (swiper.autoplay.timeout) {
      clearTimeout(swiper.autoplay.timeout);
      swiper.autoplay.timeout = undefined;
    }
    swiper.autoplay.running = false;
    swiper.emit('autoplayStop');
    return true;
  },
  pause(speed) {
    const swiper = this;
    if (!swiper.autoplay.running) return;
    if (swiper.autoplay.paused) return;
    if (swiper.autoplay.timeout) clearTimeout(swiper.autoplay.timeout);
    swiper.autoplay.paused = true;
    if (speed === 0 || !swiper.params.autoplay.waitForTransition) {
      swiper.autoplay.paused = false;
      swiper.autoplay.run();
    } else {
      swiper.$wrapperEl[0].addEventListener('transitionend', swiper.autoplay.onTransitionEnd);
      swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd);
    }
  },
};

export default {
  name: 'autoplay',
  params: {
    autoplay: {
      enabled: false,
      delay: 3000,
      waitForTransition: true,
      disableOnInteraction: true,
      stopOnLastSlide: false,
      reverseDirection: false,
    },
  },
  create() {
    const swiper = this;
    Utils.extend(swiper, {
      autoplay: {
        running: false,
        paused: false,
        run: Autoplay.run.bind(swiper),
        start: Autoplay.start.bind(swiper),
        stop: Autoplay.stop.bind(swiper),
        pause: Autoplay.pause.bind(swiper),
        onVisibilityChange() {
          if (document.visibilityState === 'hidden' && swiper.autoplay.running) {
            swiper.autoplay.pause();
          }
          if (document.visibilityState === 'visible' && swiper.autoplay.paused) {
            swiper.autoplay.run();
          }
        },
        onTransitionEnd(e) {
          if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return;
          if (e.target !== this) return;
          swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.autoplay.onTransitionEnd);
          swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd);
          swiper.autoplay.paused = false;
          if (!swiper.autoplay.running) {
            swiper.autoplay.stop();
          } else {
            swiper.autoplay.run();
          }
        },
      },
    });
  },
  on: {
    init() {
      const swiper = this;
      if (swiper.params.autoplay.enabled) {
        swiper.autoplay.start();
        document.addEventListener('visibilitychange', swiper.autoplay.onVisibilityChange);
      }
    },
    beforeTransitionStart(speed, internal) {
      const swiper = this;
      if (swiper.autoplay.running) {
        if (internal || !swiper.params.autoplay.disableOnInteraction) {
          swiper.autoplay.pause(speed);
        } else {
          swiper.autoplay.stop();
        }
      }
    },
    sliderFirstMove() {
      const swiper = this;
      if (swiper.autoplay.running) {
        if (swiper.params.autoplay.disableOnInteraction) {
          swiper.autoplay.stop();
        } else {
          swiper.autoplay.pause();
        }
      }
    },
    touchEnd() {
      const swiper = this;
      if (swiper.params.cssMode && swiper.autoplay.paused && !swiper.params.autoplay.disableOnInteraction) {
        swiper.autoplay.run();
      }
    },
    destroy() {
      const swiper = this;
      if (swiper.autoplay.running) {
        swiper.autoplay.stop();
      }
      document.removeEventListener('visibilitychange', swiper.autoplay.onVisibilityChange);
    },
  },
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { submit } from 'redux-form';
import Loader from '../../../common/loader';
import ControlledModal from '../../../common/modals/controlledModal';
import { newCfeiProcessed, updateCfei } from '../../../../reducers/newCfei';
import CallPartnersForm from './callPartnersForm';

const messages = {
  title: 'A new Call for Expressions of Interest was created.',
  header: {
    title: 'You can inform Partners registered to work in the country(ies) selected about this ' +
    'offer.',
    body: 'This CFEI will be publicly viewable to all, but you can also notify specific partners of this opportunity. If you would like to invite specific partners ' +
    'registered in the portal to apply for the CFEI, enter their names below, and they will receive an e-mail notification. You can also skip this step.',
  },
  skip: 'skip',
  send: 'send',
};

class CallPartnersModal extends Component {
  constructor(props) {
    super(props);
    this.onDialogSubmit = this.onDialogSubmit.bind(this);
    this.onDialogClose = this.onDialogClose.bind(this);
    this.onFormSubmit = this.onFormSubmit.bind(this);
  }

  onFormSubmit(values) {
    return this.props.updateCfei(values).then(() => {
      this.props.newCfeiProcessed();
    });
  }

  onDialogSubmit() {
    this.props.submit();
  }

  onDialogClose() {
    this.props.newCfeiProcessed();
  }

  render() {
    const { openDialog, showLoading } = this.props;
    return (
      <Loader loading={showLoading} fullscreen>
        <ControlledModal
          maxWidth="md"
          title={messages.title}
          trigger={openDialog}
          info={messages.header}
          handleDialogClose={this.onDialogClose}
          buttons={{
            flat: {
              handleClick: this.onDialogClose,
              label: messages.skip,
            },
            raised: {
              handleClick: this.onDialogSubmit,
              label: messages.send,
            },
          }}
          content={<CallPartnersForm overlap={false} onSubmit={this.onFormSubmit} />}
        />
      </Loader>
    );
  }
}

CallPartnersModal.propTypes = {
  openDialog: PropTypes.bool,
  showLoading: PropTypes.bool,
  submit: PropTypes.func,
  newCfeiProcessed: PropTypes.func,
  updateCfei: PropTypes.func,
};

const mapStateToProps = state => ({
  showLoading: state.newCfei.openCfeiSubmitting,
  openDialog: state.newCfei.openCfeiProcessing,
});

const mapDispatchToProps = (dispatch, ownProps) => ({
  newCfeiProcessed: () => dispatch(newCfeiProcessed()),
  updateCfei: body => dispatch(updateCfei(body, ownProps.id)),
  submit: () => dispatch(submit('callPartners')),
});

const containerCallPartnersModal = connect(
  mapStateToProps,
  mapDispatchToProps,
)(CallPartnersModal);

export default containerCallPartnersModal;
<commit_msg>Tweaked all the other instances<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { submit } from 'redux-form';
import Loader from '../../../common/loader';
import ControlledModal from '../../../common/modals/controlledModal';
import { newCfeiProcessed, updateCfei } from '../../../../reducers/newCfei';
import CallPartnersForm from './callPartnersForm';

const messages = {
  title: 'A new Call for Expressions of Interest was created.',
  header: {
    title: 'You can inform Partners registered to work in the country(ies) selected about this ' +
    'offer.',
    body: 'This CFEI will be publicly viewable to all, but you can also notify specific partners of this opportunity. If you would like to invite specific partners ' +
    'registered in the portal to apply for the CFEI, enter their names below, and they will receive an e-mail notification. You can also skip this step.',
  },
  skip: 'skip',
  send: 'send',
};

class CallPartnersModal extends Component {
  constructor(props) {
    super(props);
    this.onDialogSubmit = this.onDialogSubmit.bind(this);
    this.onDialogClose = this.onDialogClose.bind(this);
    this.onFormSubmit = this.onFormSubmit.bind(this);
  }

  onFormSubmit({ invited_partners: partnerIds }) {
    const { partners } = this.props;

    const selectedPartners = partnerIds
        .map(selectedId => partners.find(({ id }) => id === selectedId))
        .filter(Boolean);

    return this.props.updateCfei({
      invited_partners: selectedPartners,
    }).then(() => {
      this.props.newCfeiProcessed();
    });
  }

  onDialogSubmit() {
    this.props.submit();
  }

  onDialogClose() {
    this.props.newCfeiProcessed();
  }

  render() {
    const { openDialog, showLoading } = this.props;
    return (
      <Loader loading={showLoading} fullscreen>
        <ControlledModal
          maxWidth="md"
          title={messages.title}
          trigger={openDialog}
          info={messages.header}
          handleDialogClose={this.onDialogClose}
          buttons={{
            flat: {
              handleClick: this.onDialogClose,
              label: messages.skip,
            },
            raised: {
              handleClick: this.onDialogSubmit,
              label: messages.send,
            },
          }}
          content={<CallPartnersForm overlap={false} onSubmit={this.onFormSubmit} />}
        />
      </Loader>
    );
  }
}

CallPartnersModal.propTypes = {
  openDialog: PropTypes.bool,
  showLoading: PropTypes.bool,
  submit: PropTypes.func,
  newCfeiProcessed: PropTypes.func,
  updateCfei: PropTypes.func,
  partners: PropTypes.array,
};

const mapStateToProps = state => ({
  showLoading: state.newCfei.openCfeiSubmitting,
  openDialog: state.newCfei.openCfeiProcessing,
  partners: state.cache.partners,
});

const mapDispatchToProps = (dispatch, ownProps) => ({
  newCfeiProcessed: () => dispatch(newCfeiProcessed()),
  updateCfei: body => dispatch(updateCfei(body, ownProps.id)),
  submit: () => dispatch(submit('callPartners')),
});

const containerCallPartnersModal = connect(
  mapStateToProps,
  mapDispatchToProps,
)(CallPartnersModal);

export default containerCallPartnersModal;
<|endoftext|>


<commit_before>/**
 * Created by janeluck on 17/6/29.
 */
const scrm = {
  //todo: 根据token具体用途还需要再改
  url: function (str) {

    const token = window.location.search.match(/token=([^&]*)/) && window.location.search.match(/token=([^&]*)/)[1]
    if (/localhost|10.10.3.195/.test(window.location.host)) {
      str = '/api' + str
    }

    return str + "?token=" + token
  },
  // 返回app内部
  goBack: function () {

    alert(window.jsObj.goBack)
    window.jsObj && window.jsObj.goBack()
  }
}

export default scrm
<commit_msg>goBack<commit_after>/**
 * Created by janeluck on 17/6/29.
 */
const scrm = {
  //todo: 根据token具体用途还需要再改
  url: function (str) {

    const token = window.location.search.match(/token=([^&]*)/) && window.location.search.match(/token=([^&]*)/)[1]
    if (/localhost|10.10.3.195/.test(window.location.host)) {
      str = '/api' + str
    }

    return str + "?token=" + token
  },
  // 返回app内部
  goBack: function () {
    window.jsObj && window.jsObj.goBack && window.jsObj.goBack()
  }
}

export default scrm
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import ContractResponse from "./ContractResponse";

//redux
import { connect, subscribe } from "react-redux";
import { saveContract } from "./ContractActions";

export class Contract extends Component {
    constructor() {
        super();
        this.state = {
            serverResponseReceived: "",
            completionEta: "",
            supervision: "",
            misc: "",
            form: {
                studentName: "",
                studentNumber: "",
                studentAddress: "",
                studentPhone: "",
                studentEmail: "",
                studentMajor: "",

                thesisTitle: "",
                thesisStartDate: "",
                thesisCompletionEta: "",
                thesisPerformancePlace: "",

                thesisSupervisorMain: "",
                thesisSupervisorSecond: "",
                thesisSupervisorOther: "",

                thesisWorkStudentTime: "",
                thesisWorkSupervisorTime: "",
                thesisWorkIntermediateGoal: "",
                thesisWorkMeetingAgreement: "",
                thesisWorkOther: "",

                studentGradeGoal: "",
            }
        }
    }

    handleChange() {
        let currentValue = this.props.store.getState();

        console.log(currentValue);
    }

    componentDidMount() {
        document.title = "Contract page";
        console.log(this.props.contract);
        //this.props.store.subscribe(this.handleChange);
    }

    componentDidUpdate() {
        //document.title = "Contract page";
        console.log(this.props.contract);
        //this.props.store.subscribe(this.handleChange);
    }

    handleContractChange = (event) => {
        //console.log("handler called " + event.target.name + " " + event.target.value);

        let oldState = this.state.form;
        let newState = this.state.form;
        newState[event.target.name] = event.target.value;

        this.setState({ oldState: newState })
    }

    sendForm = (event) => {
        this.setState({ serverResponseReceived: "" });

        if (event !== undefined)
            event.preventDefault();

        this.props.saveContract(this.state.form);

    }

    defineFieldClasses = (labelType, fieldType, required) => {
        return ("field ui small " + labelType + " " + fieldType + " " + (required === true ? 'required' : ''));
    }

    createField = (fieldData, fieldKey) => {
        let forReturn = [];
        if (fieldData.inputType === "input") {

            forReturn = [
{fieldData.label}
,
            <input key={fieldKey} name={fieldData.name} type="text" placeholder={fieldData.placeholder} value={this.state.form[fieldData.name]} onChange={this.handleContractChange} />];

            if (fieldData.labelType.includes("right")) {
                forReturn.reverse();
            }
        } else if (fieldData.inputType === "textarea") {
            forReturn = [{fieldData.label},
            <textarea key={fieldKey} name={fieldData.name} rows={fieldData.rows} placeholder={fieldData.placeholder} value={this.state.form[fieldData.name]} onChange={this.handleContractChange}></textarea>];
        }

        return (

                {forReturn}

        );
    }

    createFormSectionLine = (sectionLineData, sectionLineKey) => {
        if (sectionLineData.fields.length === 1) {
            return (this.createField(sectionLineData.fields[0], sectionLineKey + "field0"));
        } else if (sectionLineData.fields.length === 2) {
            return (

                    {this.createField(sectionLineData.fields[0], sectionLineKey + "field0")}
                    {this.createField(sectionLineData.fields[1], sectionLineKey + "field1")}

            );
        }
    }

    createFormSection = (sectionData, sectionKey) => {
        let sectionLineList = sectionData.sectionLines.map(
            (sectionLineData, sectionLineKey) => {
                return this.createFormSectionLine(sectionLineData, "section" + sectionKey + "sectionLine" + sectionLineKey);
            })

        return (

{sectionData.header}

                {sectionLineList}

        );
    }

    getResponseMessage = (type) => {
        return (

{type === "success" && "Tiedot tallennettiin onnistuneesti"} {type === "error" && "Ilmestyi ongelmia"}

);
    }

    createForm = () => {
        const formFieldProperties = {
            sections:
            [{
                header: "Opinnäytetyön tekijä",
                sectionLines: [
                    {
                        fields: [
                            { inputType: "input", name: "studentName", label: "Nimi", labelType: "right labeled", required: true, placeholder: "Etu- ja Sukunimi" },
                            { inputType: "input", name: "studentNumber", label: "Opiskelijanumero", labelType: "right labeled", required: true, placeholder: "XXXXXXX" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "input", name: "studentAddress", label: "Lähiosoite", labelType: "right labeled", required: true, placeholder: "Peräpolku 2 C 45, Nuppulinna" },
                            { inputType: "input", name: "studentPhone", label: "Puhelinnumero", labelType: "right labeled", required: true, placeholder: "000 000 00 00" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "input", name: "studentEmail", label: "Sähköpostiosoite", labelType: "right labeled", required: true, placeholder: "nimi@domain.com" },
                            { inputType: "input", name: "studentMajor", label: "Pääaine", labelType: "right labeled", required: true, placeholder: "(jos muu kuin TKTL)" },
                        ]
                    }
                ]
            },
            {
                header: "Opinnäytetyö",
                sectionLines: [
                    {
                        fields: [
                            { inputType: "textarea", rows: 2, name: "thesisTitle", label: "Opinnäytetyön otsikko (työnimi) tekokielellä", labelType: "fluid", required: true, placeholder: "Opinnäytetyön otsikko (työnimi) tekokielellä" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "input", name: "thesisStartDate", label: "Aloitusajankohta", labelType: "labeled", required: true, placeholder: "" },
                            { inputType: "input", name: "thesisCompletionEta", label: "Arvioitu valmistumisajankohta", labelType: "labeled", required: true, placeholder: "" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "textarea", rows: 2, name: "thesisPerformancePlace", label: "Suorituspaikka", labelType: "fluid labeled", required: true, placeholder: "(projekti, työnantaja, tms.) ja yhteystiedot" },
                        ]
                    },
                ]
            },
            {
                header: "Ohjausvastuut",
                sectionLines: [
                    {
                        fields: [
                            { inputType: "input", name: "thesisSupervisorMain", label: "Vastuuohjaaja", labelType: "labeled fluid", required: true, placeholder: "(nimi, oppiarvo ja/tai tehtävänimike, organisaatio, yhteystiedot)" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "input", name: "thesisSupervisorSecond", label: "2. ohjaaja", labelType: "labeled fluid", required: true, placeholder: "(nimi, oppiarvo ja/tai tehtävänimike, organisaatio, yhteystiedot)" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "input", name: "thesisSupervisorOther", label: "Muu ohjaaja", labelType: "labeled fluid", required: true, placeholder: "(nimi, oppiarvo ja/tai tehtävänimike, organisaatio, yhteystiedot)" },
                        ]
                    },
                ]
            },
            {
                header: "Työskentelyn tavoitteet ja ajankäyttö",
                sectionLines: [
                    {
                        fields: [
                            { inputType: "textarea", rows: 1, name: "thesisWorkStudentTime", label: "Opiskelijan arvioima opinnäytetyöhön käytettävä työaika", labelType: "fluid", required: true, placeholder: "(esim. tuntia / vko)" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "textarea", rows: 2, name: "thesisWorkSupervisorTime", label: "Ohjaajien ohjaukseen varaama aika (työn eri vaiheissa)", labelType: "fluid", required: true, placeholder: "" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "textarea", rows: 2, name: "thesisWorkIntermediateGoal", label: "Välitavoitteet (deadlinet työn eri vaiheille)", labelType: "fluid", required: true, placeholder: "" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "textarea", rows: 2, name: "thesisWorkMeetingAgreement", label: "Sopimus tapaamistiheydestä, yhteydenpitotavoista ja keskusteluun käytettävissä olevasta ajasta", labelType: "fluid", required: true, placeholder: "" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "textarea", rows: 2, name: "thesisWorkOther", label: "Muuta", labelType: "fluid", required: false, placeholder: "(esim. opiskelijan odotukset ohjaajalle / ohjaajan odotukset opiskelijalle" },
                        ]
                    },
                ]
            },
            {
                header: "Tavoitearvosana",
                sectionLines: [
                    {
                        fields: [
                            { inputType: "textarea", rows: 1, name: "studentGradeGoal", label: "Opiskelija on tutustunut laitoksen opinnäytetyön arviointimatriisiin ja määrittää tavoitearvosanakseen:", labelType: "right labeled", required: true, placeholder: "Etu- ja Sukunimi" },
                        ]
                    },
                ]
            }]
        }

        let sectionList = formFieldProperties.sections.map(
            (sectionData, sectionKey) => {
                return this.createFormSection(sectionData, "form" + sectionKey);
            });

        return (

                <form onSubmit={this.handlePost}>
                    {sectionList}

                    <button className="ui primary button" type="submit" onClick={this.sendForm}>Save</button>

                    {this.state.serverResponseReceived === "success" && this.getResponseMessage("success")}
                    {this.state.serverResponseReceived === "error" && this.getResponseMessage("error")}
                </form>

        );
    }

    render() {
        return (

Thesis Contract

Gradusopimus tehdään gradunohjauksen alkaessa

Sopimusta voidaan muuttaa osapuolten yhteisestä päätöksestä.

                    {this.createForm()}

                    <Link to="/"> Go back to HomePage :P </Link>

        );
    }
}

const mapDispatchToProps = (dispatch) => ({
    saveContract(data) {
        dispatch(saveContract(data));
    },
});

export default connect(state => state.contract, mapDispatchToProps)(Contract);
<commit_msg>implementation of state-change-reactive elements<commit_after>import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import ContractResponse from "./ContractResponse";

//redux
import { connect, subscribe } from "react-redux";
import { saveContract } from "./ContractActions";

export class Contract extends Component {
    constructor() {
        super();
        this.state = {
            serverResponseReceived: "",
            completionEta: "",
            supervision: "",
            misc: "",
            form: {
                studentName: "",
                studentNumber: "",
                studentAddress: "",
                studentPhone: "",
                studentEmail: "",
                studentMajor: "",

                thesisTitle: "",
                thesisStartDate: "",
                thesisCompletionEta: "",
                thesisPerformancePlace: "",

                thesisSupervisorMain: "",
                thesisSupervisorSecond: "",
                thesisSupervisorOther: "",

                thesisWorkStudentTime: "",
                thesisWorkSupervisorTime: "",
                thesisWorkIntermediateGoal: "",
                thesisWorkMeetingAgreement: "",
                thesisWorkOther: "",

                studentGradeGoal: "",
            }
        }
    }

    componentDidMount() {
        document.title = "Contract page";
    }

    componentDidUpdate() {
        console.log(this.props.contract[this.props.contract.length - 1]);
    }
    getLastContractAction() {
        return this.props.contract[this.props.contract.length - 1];
    }

    getButton() {
        const lastAction = this.getLastContractAction();
        const workableButton = <button className="ui primary button" type="submit" onClick={this.sendForm}>Save</button>;
        const disabledLoadingButton = <button className="ui primary disabled loading button" type="submit" onClick={this.sendForm}>Save</button>;

        if (lastAction === undefined) { return workableButton }
        else {
            if (lastAction.id == 'CONTRACT_SAVE_ATTEMPT') { return disabledLoadingButton }
            else { return workableButton }
        }
    }

    getResponseMessage = (type) => {

        const lastAction = this.getLastContractAction();
        const successMessage =

Tiedot tallennettiin onnistuneesti

;
        const failedMessage =

Ilmestyi ongelmia

;

        if (lastAction === undefined) { return '' }
        else {console.log(lastAction.id)
            if (lastAction.id == 'CONTRACT_SAVE_SUCCESS') {console.log(successMessage); return successMessage }
            else if (lastAction.id == 'CONTRACT_SAVE_FAILURE') {console.log(failedMessage); return failedMessage }
            else { return '' }
        }
    }

    sendForm = (event) => {
        this.setState({ serverResponseReceived: "" });

        if (event !== undefined)
            event.preventDefault();

        this.props.saveContract(this.state.form);

    }

    defineFieldClasses = (labelType, fieldType, required) => {
        return ("field ui small " + labelType + " " + fieldType + " " + (required === true ? 'required' : ''));
    }

    createField = (fieldData, fieldKey) => {
        let forReturn = [];
        if (fieldData.inputType === "input") {

            forReturn = [
{fieldData.label}
,
            <input key={fieldKey} name={fieldData.name} type="text" placeholder={fieldData.placeholder} value={this.state.form[fieldData.name]} onChange={this.handleContractChange} />];

            if (fieldData.labelType.includes("right")) {
                forReturn.reverse();
            }
        } else if (fieldData.inputType === "textarea") {
            forReturn = [{fieldData.label},
            <textarea key={fieldKey} name={fieldData.name} rows={fieldData.rows} placeholder={fieldData.placeholder} value={this.state.form[fieldData.name]} onChange={this.handleContractChange}></textarea>];
        }

        return (

                {forReturn}

        );
    }

    createFormSectionLine = (sectionLineData, sectionLineKey) => {
        if (sectionLineData.fields.length === 1) {
            return (this.createField(sectionLineData.fields[0], sectionLineKey + "field0"));
        } else if (sectionLineData.fields.length === 2) {
            return (

                    {this.createField(sectionLineData.fields[0], sectionLineKey + "field0")}
                    {this.createField(sectionLineData.fields[1], sectionLineKey + "field1")}

            );
        }
    }

    createFormSection = (sectionData, sectionKey) => {
        let sectionLineList = sectionData.sectionLines.map(
            (sectionLineData, sectionLineKey) => {
                return this.createFormSectionLine(sectionLineData, "section" + sectionKey + "sectionLine" + sectionLineKey);
            })

        return (

{sectionData.header}

                {sectionLineList}

        );
    }

    createForm = () => {
        const formFieldProperties = {
            sections:
            [{
                header: "Opinnäytetyön tekijä",
                sectionLines: [
                    {
                        fields: [
                            { inputType: "input", name: "studentName", label: "Nimi", labelType: "right labeled", required: true, placeholder: "Etu- ja Sukunimi" },
                            { inputType: "input", name: "studentNumber", label: "Opiskelijanumero", labelType: "right labeled", required: true, placeholder: "XXXXXXX" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "input", name: "studentAddress", label: "Lähiosoite", labelType: "right labeled", required: true, placeholder: "Peräpolku 2 C 45, Nuppulinna" },
                            { inputType: "input", name: "studentPhone", label: "Puhelinnumero", labelType: "right labeled", required: true, placeholder: "000 000 00 00" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "input", name: "studentEmail", label: "Sähköpostiosoite", labelType: "right labeled", required: true, placeholder: "nimi@domain.com" },
                            { inputType: "input", name: "studentMajor", label: "Pääaine", labelType: "right labeled", required: true, placeholder: "(jos muu kuin TKTL)" },
                        ]
                    }
                ]
            },
            {
                header: "Opinnäytetyö",
                sectionLines: [
                    {
                        fields: [
                            { inputType: "textarea", rows: 2, name: "thesisTitle", label: "Opinnäytetyön otsikko (työnimi) tekokielellä", labelType: "fluid", required: true, placeholder: "Opinnäytetyön otsikko (työnimi) tekokielellä" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "input", name: "thesisStartDate", label: "Aloitusajankohta", labelType: "labeled", required: true, placeholder: "" },
                            { inputType: "input", name: "thesisCompletionEta", label: "Arvioitu valmistumisajankohta", labelType: "labeled", required: true, placeholder: "" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "textarea", rows: 2, name: "thesisPerformancePlace", label: "Suorituspaikka", labelType: "fluid labeled", required: true, placeholder: "(projekti, työnantaja, tms.) ja yhteystiedot" },
                        ]
                    },
                ]
            },
            {
                header: "Ohjausvastuut",
                sectionLines: [
                    {
                        fields: [
                            { inputType: "input", name: "thesisSupervisorMain", label: "Vastuuohjaaja", labelType: "labeled fluid", required: true, placeholder: "(nimi, oppiarvo ja/tai tehtävänimike, organisaatio, yhteystiedot)" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "input", name: "thesisSupervisorSecond", label: "2. ohjaaja", labelType: "labeled fluid", required: true, placeholder: "(nimi, oppiarvo ja/tai tehtävänimike, organisaatio, yhteystiedot)" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "input", name: "thesisSupervisorOther", label: "Muu ohjaaja", labelType: "labeled fluid", required: true, placeholder: "(nimi, oppiarvo ja/tai tehtävänimike, organisaatio, yhteystiedot)" },
                        ]
                    },
                ]
            },
            {
                header: "Työskentelyn tavoitteet ja ajankäyttö",
                sectionLines: [
                    {
                        fields: [
                            { inputType: "textarea", rows: 1, name: "thesisWorkStudentTime", label: "Opiskelijan arvioima opinnäytetyöhön käytettävä työaika", labelType: "fluid", required: true, placeholder: "(esim. tuntia / vko)" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "textarea", rows: 2, name: "thesisWorkSupervisorTime", label: "Ohjaajien ohjaukseen varaama aika (työn eri vaiheissa)", labelType: "fluid", required: true, placeholder: "" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "textarea", rows: 2, name: "thesisWorkIntermediateGoal", label: "Välitavoitteet (deadlinet työn eri vaiheille)", labelType: "fluid", required: true, placeholder: "" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "textarea", rows: 2, name: "thesisWorkMeetingAgreement", label: "Sopimus tapaamistiheydestä, yhteydenpitotavoista ja keskusteluun käytettävissä olevasta ajasta", labelType: "fluid", required: true, placeholder: "" },
                        ]
                    },
                    {
                        fields: [
                            { inputType: "textarea", rows: 2, name: "thesisWorkOther", label: "Muuta", labelType: "fluid", required: false, placeholder: "(esim. opiskelijan odotukset ohjaajalle / ohjaajan odotukset opiskelijalle" },
                        ]
                    },
                ]
            },
            {
                header: "Tavoitearvosana",
                sectionLines: [
                    {
                        fields: [
                            { inputType: "textarea", rows: 1, name: "studentGradeGoal", label: "Opiskelija on tutustunut laitoksen opinnäytetyön arviointimatriisiin ja määrittää tavoitearvosanakseen:", labelType: "right labeled", required: true, placeholder: "Etu- ja Sukunimi" },
                        ]
                    },
                ]
            }]
        }

        let sectionList = formFieldProperties.sections.map(
            (sectionData, sectionKey) => {
                return this.createFormSection(sectionData, "form" + sectionKey);
            });

        return (

                <form onSubmit={this.handlePost}>
                    {sectionList}

                    {this.getButton()}

                    {this.getResponseMessage()}
                </form>

        );
    }

    render() {
        return (

Thesis Contract

Gradusopimus tehdään gradunohjauksen alkaessa

Sopimusta voidaan muuttaa osapuolten yhteisestä päätöksestä.

                    {this.createForm()}

                    <Link to="/"> Go back to HomePage :P </Link>

        );
    }
}

const mapDispatchToProps = (dispatch) => ({
    saveContract(data) {
        dispatch(saveContract(data));
    },
});

const mapStateToProps = (state) => {
    return { contract: state.contract };
}

export default connect(mapStateToProps, mapDispatchToProps)(Contract);
<|endoftext|>


<commit_before>import React from 'react';
import { storiesOf } from '@storybook/react';
import {
  boolean, number, text, select
} from '@storybook/addon-knobs';
import OptionsHelper from '../../utils/helpers/options-helper';
import { notes, info } from './documentation';
import DateInput from '.';

storiesOf('Date Input', module)
  .add('default', () => {
    const autoFocus = boolean('autoFocus', true);
    const disabled = boolean('disabled', false);
    const minDate = text('minDate', '');
    const maxDate = text('maxDate', '');
    const readOnly = boolean('readOnly', false);
    const label = text('label', 'Example DateInput');
    const labelWidth = number('labelWidth', 0);
    const labelHelp = text('labelHelp', 'This text provides more information for the label.');
    const fieldHelp = text('fieldHelp', 'This text provides help for the input.');
    const fieldHelpInline = boolean('fieldHelpInline', false);
    const value = text('value', DateInput.defaultProps.value);
    const labelInline = boolean('labelInline', false);
    const inputWidth = labelInline ? number('inputWidth', 0, {
      range: true,
      min: 0,
      max: 50,
      step: 1
    }) : undefined;
    const labelAlign = labelInline ? select(
      'labelAlign',
      OptionsHelper.alignBinary,
      OptionsHelper.alignBinary[0]
    ) : undefined;

    return (
      <DateInput
        autoFocus={ autoFocus }
        disabled={ disabled }
        minDate={ minDate }
        maxDate={ maxDate }
        readOnly={ readOnly }
        label={ label }
        labelInline={ labelInline }
        labelWidth={ labelWidth }
        labelAlign={ labelAlign }
        labelHelp={ labelHelp }
        inputWidth={ inputWidth }
        fieldHelp={ fieldHelp }
        fieldHelpInline={ fieldHelpInline }
        value={ value }
      />
    );
  }, {
    info: { text: info },
    notes: { markdown: notes }
  });
<commit_msg>fixed date not updated on selection in date input story<commit_after>import React from 'react';
import { storiesOf } from '@storybook/react';
import { StateDecorator, Store, State } from '@sambego/storybook-state';
import {
  boolean, number, text, select
} from '@storybook/addon-knobs';
import OptionsHelper from '../../utils/helpers/options-helper';
import { notes, info } from './documentation';
import DateInput from '.';

const store = new Store(
  {
    value: DateInput.defaultProps.value
  }
);

const setValue = (ev) => {
  store.set({ value: ev.target.value });
};

storiesOf('Date Input', module)
  .addDecorator(StateDecorator(store))
  .add('default', () => {
    const autoFocus = boolean('autoFocus', true);
    const disabled = boolean('disabled', false);
    const minDate = text('minDate', '');
    const maxDate = text('maxDate', '');
    const readOnly = boolean('readOnly', false);
    const label = text('label', 'Example DateInput');
    const labelWidth = number('labelWidth', 0);
    const labelHelp = text('labelHelp', 'This text provides more information for the label.');
    const fieldHelp = text('fieldHelp', 'This text provides help for the input.');
    const fieldHelpInline = boolean('fieldHelpInline', false);
    const labelInline = boolean('labelInline', false);
    const inputWidth = labelInline ? number('inputWidth', 0, {
      range: true,
      min: 0,
      max: 50,
      step: 1
    }) : undefined;
    const labelAlign = labelInline ? select(
      'labelAlign',
      OptionsHelper.alignBinary,
      OptionsHelper.alignBinary[0]
    ) : undefined;

    return (
      <DateInput
        autoFocus={ autoFocus }
        disabled={ disabled }
        minDate={ minDate }
        maxDate={ maxDate }
        readOnly={ readOnly }
        label={ label }
        labelInline={ labelInline }
        labelWidth={ labelWidth }
        labelAlign={ labelAlign }
        labelHelp={ labelHelp }
        inputWidth={ inputWidth }
        fieldHelp={ fieldHelp }
        fieldHelpInline={ fieldHelpInline }
        value={ store.get('value') }
        onChange={ setValue }
      />
    );
  }, {
    info: { text: info, propTablesExclude: [State] },
    notes: { markdown: notes }
  });
<|endoftext|>