<commit_before>import React from "react";
import ReactDOM from "react-dom";
import { connect } from "react-redux";
import { push } from "redux-router";

import { CardOverlay } from "../CardOverlay";
import { Card, CardText } from 'material-ui/Card';

import { Actions } from "./redux/actions";
import {
    Actions as ServiceActions,
    ActionKeyStore as ServiceActionKeyStore
} from "../../services/servicemanager/redux/actions";
import {
    Actions as ConfigurationsActions,
    ActionKeyStore as ConfigurationsActionKeyStore
} from "../../services/configurations/redux/actions";

import { resizeVisualization } from "../../utils/resize"

import { GraphManager } from "../Graphs/index";
import { ServiceManager } from "../../services/servicemanager/index";

import style from "./styles"

import FontAwesome from "react-fontawesome";

class VisualizationView extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            parameterizable: true,
            hasResults: false,
            showDescription: false,
        }
    }

    componentWillMount() {
        this.initialize(this.props.id);
    }

    componentDidMount() {
        this.updateSize();

        // If present, register the resize callback
        // to respond to interactive resizes from react-grid-layout.
        if (this.props.registerResize) {
            this.props.registerResize(this.updateSize.bind(this))
        }
    }

    componentWillReceiveProps(nextProps) {
        this.initialize(nextProps.id);
    }

    componentDidUpdate() {
        this.updateSize();
    }

    updateSize() {
        if (this._element) {
            const { width, height } = resizeVisualization(this._element);

            if (width !== this.state.width || height !== this.state.height) {
                this.setState({ width, height });
            }
        }
    }

    initialize(id) {

        this.props.fetchConfigurationIfNeeded(id).then((c) => {
            const { configuration } = this.props

            if (!configuration)
                return;

            this.props.fetchQueryIfNeeded(configuration.get("query")).then(() => {
                const { queryConfiguration, executeQueryIfNeeded, context } = this.props;

                if (!queryConfiguration)
                    return;

                executeQueryIfNeeded(queryConfiguration, context).then(
                    () => {
                        this.setState({
                            parameterizable: true,
                        });
                    },
                    (error) => {
                        this.setState({
                            parameterizable: false,
                        });
                    },
                );
            });

            // Handle configured listeners (e.g. navigate when clicking on a bar).
            if(configuration.get("listeners")){

                // Use this.state.listeners to store the listeners that will be
                // passed into the visualization components.
                this.setState({

                    // This will be an object whose keys are event names,
                    // and whose values are functions that accept the data object
                    // corresponding to the clicked visual element.
                    listeners: configuration.get("listeners").reduce((listeners, listener) => {
                        // Use ES6 destructuring with defaults.
                        const {

                            // By default, use the "onMarkClick" event.
                            event = "onMarkClick",

                            // By default, stay on the current route.
                            redirect = window.location.pathname,

                            // By default, specify no additional query params.
                            params = {}
                        } = listener.toJS();

                        // Each listener expects the data object `d`,
                        // which corresponds to a row of data visualized.
                        listeners[event] = (d) => {

                            // Compute the query params from the data object.
                            let queryParams = Object.keys(params)
                                .reduce((queryParams, destinationParam) => {
                                    const sourceColumn = params[destinationParam];
                                    queryParams[destinationParam] = d[sourceColumn];
                                    return queryParams;
                                }, {});

                            // Override the existing context with the new params.
                            queryParams = Object.assign({}, this.props.context, queryParams);

                            // Perform the navigation via react-router.
                            this.props.goTo(redirect, queryParams);
                        };

                        return listeners;
                    }, {})
                });
            }
        });
    }

    shouldShowVisualization() {
        const { configuration, response } = this.props;

        return configuration && response && !response.isFetching;
    }

    renderVisualization() {
        const { configuration, queryConfiguration, response } = this.props;

        const graphName      = configuration.get("graph"),
              GraphComponent = GraphManager.getGraphComponent(graphName);

        let description;

        if (this.state.showDescription) {
            description = <CardOverlay
                                overlayStyle={style.descriptionContainer}
                                textStyle={style.descriptionText}
                                text={configuration.get("description")}
                                onTouchTapOverlay={() => { this.setState({showDescription: false}); }}
                                />
        }

        return (

                <GraphComponent
                  response={response}
                  configuration={configuration.toJS()}
                  queryConfiguration={queryConfiguration}
                  width={this.state.width}
                  height={this.state.height}
                  {...this.state.listeners}
                />
                {description}

        )
    }

    renderVisualizationIfNeeded() {
        if (this.shouldShowVisualization()) {
            return this.renderVisualization();
        }

        if (!this.state.parameterizable) {
            return (
                <CardOverlay
                    overlayStyle={style.overlayContainer}
                    textStyle={style.overlayText}
                    text={(

                            <FontAwesome
                                name="meh-o"
                                size="2x"
                                />

                            Oops, we are missing some parameters here!

                    )}
                    onTouchTapOverlay={() => { this.setState({showDescription: false}); }}
                    />
            )
        }

        return (

                    <FontAwesome
                        name="circle-o-notch"
                        spin
                        />

                    Please wait while loading...

        )
    }

    shouldShowTitle() {
        const { configuration } = this.props;

        return configuration && configuration.get("title") && this.state.parameterizable;
    }

    renderTitleIfNeeded() {
        const { configuration } = this.props;

        if (!this.shouldShowTitle())
            return;

        const descriptionIcon = !configuration.get("description") ? null : (

                <FontAwesome
                    name="info-circle"
                    onTouchTap={() => { this.setState({showDescription: !!configuration.get("description")}); }}
                    />

        )

        return (

                {configuration.get("title")}
                {descriptionIcon}

        )
    }

    cardTextReference = (c) => {
        if (this._element)
            return;

        this._element = ReactDOM.findDOMNode(c).parentElement;
    }

    render() {
        return (
            <Card
              style={style.card}
              containerStyle={style.cardContainer}
              ref={this.cardTextReference}
            >
                { this.renderTitleIfNeeded() };
                <CardText style={style.cardText}>
                    { this.renderVisualizationIfNeeded() }
                </CardText>
            </Card>
        );
    }
}

const mapStateToProps = (state, ownProps) => {

    const configurationID = ownProps.id || ownProps.params.id,
          context         = ownProps.context || ownProps.location.query;

    const props = {
        id: configurationID,
        context: context,

        configuration: state.configurations.getIn([
            ConfigurationsActionKeyStore.VISUALIZATIONS,
            configurationID,
            ConfigurationsActionKeyStore.DATA
        ]),

        error: state.configurations.getIn([
            ConfigurationsActionKeyStore.VISUALIZATIONS,
            configurationID,
            ConfigurationsActionKeyStore.ERROR
        ])

    };

    // Expose the query template as a JS object if it is available.
    if (props.configuration) {
        const queryConfiguration = state.configurations.getIn([
            ConfigurationsActionKeyStore.QUERIES,
            props.configuration.get("query")
        ]);

        if (queryConfiguration && !queryConfiguration.get(
            ConfigurationsActionKeyStore.IS_FETCHING
        )) {
            props.queryConfiguration = queryConfiguration.get(
                ConfigurationsActionKeyStore.DATA
            ).toJS();
        }

        // Expose received response if it is available
        if (props.queryConfiguration) {
            const requestID = ServiceManager.getRequestID(props.queryConfiguration, context);

            let response = state.services.getIn([
                ServiceActionKeyStore.REQUESTS,
                requestID
            ]);

            if (response && !response.get(ServiceActionKeyStore.IS_FETCHING))
                props.response = response.toJS();
        }
    }

    return props;
};

const actionCreators = (dispatch) => ({

    setPageTitle: function(aTitle) {
        dispatch(Actions.updateTitle(aTitle));
    },

    goTo: function(link, filters) {
        dispatch(push({pathname:link, query:filters}));
    },

    fetchConfigurationIfNeeded: function(id) {
        return dispatch(ConfigurationsActions.fetchIfNeeded(
            id,
            ConfigurationsActionKeyStore.VISUALIZATIONS
        ));
    },

    fetchQueryIfNeeded: function(id) {
        return dispatch(ConfigurationsActions.fetchIfNeeded(
            id,
            ConfigurationsActionKeyStore.QUERIES
        ));
    },

    executeQueryIfNeeded: function(queryConfiguration, context) {
        return dispatch(ServiceActions.fetchIfNeeded(queryConfiguration, context));
    }

 });

export default connect(mapStateToProps, actionCreators)(VisualizationView);
<commit_msg>Display a nice message when having a connection issue<commit_after>import React from "react";
import ReactDOM from "react-dom";
import parse from "json-templates";

import { fromJS, Map } from "immutable";

import { connect } from "react-redux";
import { push } from "redux-router";

import { CardOverlay } from "../CardOverlay";
import { Card, CardText } from 'material-ui/Card';

import { Actions } from "./redux/actions";
import {
    Actions as ServiceActions,
    ActionKeyStore as ServiceActionKeyStore
} from "../../services/servicemanager/redux/actions";
import {
    Actions as ConfigurationsActions,
    ActionKeyStore as ConfigurationsActionKeyStore
} from "../../services/configurations/redux/actions";

import { resizeVisualization } from "../../utils/resize"
import { shouldUpdateVisualization } from "../../utils/configurations"

import { GraphManager } from "../Graphs/index";
import { ServiceManager } from "../../services/servicemanager/index";

import style from "./styles"

import FontAwesome from "react-fontawesome";

class VisualizationView extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            parameterizable: true,
            hasResults: false,
            showDescription: false,
        }
    }

    componentWillMount() {
        this.initialize(this.props.id);
    }

    componentDidMount() {
        this.updateSize();

        // If present, register the resize callback
        // to respond to interactive resizes from react-grid-layout.
        if (this.props.registerResize) {
            this.props.registerResize(this.updateSize.bind(this))
        }
    }

    componentWillReceiveProps(nextProps) {
        this.initialize(nextProps.id);
    }

    componentDidUpdate() {
        this.updateSize();
    }

    updateSize() {
        if (this._element) {
            const { width, height } = resizeVisualization(this._element);

            if (width !== this.state.width || height !== this.state.height) {
                this.setState({ width, height });
            }
        }
    }

    initialize(id) {

        this.props.fetchConfigurationIfNeeded(id).then((c) => {
            const { configuration } = this.props

            if (!configuration)
                return;

            this.props.fetchQueryIfNeeded(configuration.get("query")).then(() => {
                const { queryConfiguration, executeQueryIfNeeded, context } = this.props;

                if (!queryConfiguration)
                    return;

                executeQueryIfNeeded(queryConfiguration, context).then(
                    () => {
                        this.setState({
                            parameterizable: true,
                        });
                    },
                    (error) => {
                        this.setState({
                            parameterizable: false,
                        });
                    },
                );
            });

            // Handle configured listeners (e.g. navigate when clicking on a bar).
            if(configuration.get("listeners")){

                // Use this.state.listeners to store the listeners that will be
                // passed into the visualization components.
                this.setState({

                    // This will be an object whose keys are event names,
                    // and whose values are functions that accept the data object
                    // corresponding to the clicked visual element.
                    listeners: configuration.get("listeners").reduce((listeners, listener) => {
                        // Use ES6 destructuring with defaults.
                        const {

                            // By default, use the "onMarkClick" event.
                            event = "onMarkClick",

                            // By default, stay on the current route.
                            redirect = window.location.pathname,

                            // By default, specify no additional query params.
                            params = {}
                        } = listener.toJS();

                        // Each listener expects the data object `d`,
                        // which corresponds to a row of data visualized.
                        listeners[event] = (d) => {

                            // Compute the query params from the data object.
                            let queryParams = Object.keys(params)
                                .reduce((queryParams, destinationParam) => {
                                    const sourceColumn = params[destinationParam];
                                    queryParams[destinationParam] = d[sourceColumn];
                                    return queryParams;
                                }, {});

                            // Override the existing context with the new params.
                            queryParams = Object.assign({}, this.props.context, queryParams);

                            // Perform the navigation via react-router.
                            this.props.goTo(redirect, queryParams);
                        };

                        return listeners;
                    }, {})
                });
            }
        });
    }

    shouldShowVisualization() {
        const { configuration, response } = this.props;

        return configuration && response && !response.isFetching;
    }

    renderVisualization() {
        const { configuration, queryConfiguration, response } = this.props;

        const graphName      = configuration.get("graph"),
              GraphComponent = GraphManager.getGraphComponent(graphName);

        if (response.error) {
            return (
                <CardOverlay
                    overlayStyle={style.overlayContainer}
                    textStyle={style.overlayText}
                    text={(

                            <FontAwesome
                                name="meh-o"
                                size="2x"
                                />

                            Wow, it seems the connection is lost!

                    )}
                    />
            )
        }

        let description;

        if (this.state.showDescription) {
            description = <CardOverlay
                                overlayStyle={style.descriptionContainer}
                                textStyle={style.descriptionText}
                                text={configuration.get("description")}
                                onTouchTapOverlay={() => { this.setState({showDescription: false}); }}
                                />
        }

        return (

                <GraphComponent
                  response={response}
                  configuration={configuration.toJS()}
                  queryConfiguration={queryConfiguration}
                  width={this.state.width}
                  height={this.state.height}
                  {...this.state.listeners}
                />
                {description}

        )
    }

    renderVisualizationIfNeeded() {
        if (this.shouldShowVisualization()) {
            return this.renderVisualization();
        }

        if (!this.state.parameterizable) {
            return (
                <CardOverlay
                    overlayStyle={style.overlayContainer}
                    textStyle={style.overlayText}
                    text={(

                            <FontAwesome
                                name="meh-o"
                                size="2x"
                                />

                            Oops, we are missing some parameters here!

                    )}
                    onTouchTapOverlay={() => { this.setState({showDescription: false}); }}
                    />
            )
        }

        return (
            <CardOverlay
                overlayStyle={style.overlayContainer}
                textStyle={style.overlayText}
                text={(

                        <FontAwesome
                            name="circle-o-notch"
                            spin
                            />

                        Please wait while loading

                )}
                />
        )
    }

    shouldShowTitle() {
        const { configuration } = this.props;

        return configuration && configuration.get("title") && this.state.parameterizable;
    }

    renderTitleIfNeeded() {
        const { configuration } = this.props;

        if (!this.shouldShowTitle())
            return;

        const descriptionIcon = !configuration.get("description") ? null : (

                <FontAwesome
                    name="info-circle"
                    onTouchTap={() => { this.setState({showDescription: !!configuration.get("description")}); }}
                    />

        )

        return (

                {configuration.get("title")}
                {descriptionIcon}

        )
    }

    cardTextReference = (c) => {
        if (this._element)
            return;

        this._element = ReactDOM.findDOMNode(c).parentElement;
    }

    render() {
        return (
            <Card
              style={style.card}
              containerStyle={style.cardContainer}
              ref={this.cardTextReference}
            >
                { this.renderTitleIfNeeded() };
                <CardText style={style.cardText}>
                    { this.renderVisualizationIfNeeded() }
                </CardText>
            </Card>
        );
    }
}

const mapStateToProps = (state, ownProps) => {

    const configurationID = ownProps.id || ownProps.params.id,
          context         = ownProps.context || ownProps.location.query;

    const props = {
        id: configurationID,
        context: context,

        configuration: state.configurations.getIn([
            ConfigurationsActionKeyStore.VISUALIZATIONS,
            configurationID,
            ConfigurationsActionKeyStore.DATA
        ]),

        error: state.configurations.getIn([
            ConfigurationsActionKeyStore.VISUALIZATIONS,
            configurationID,
            ConfigurationsActionKeyStore.ERROR
        ])

    };

    // Expose the query template as a JS object if it is available.
    if (props.configuration) {
        const queryConfiguration = state.configurations.getIn([
            ConfigurationsActionKeyStore.QUERIES,
            props.configuration.get("query")
        ]);

        if (queryConfiguration && !queryConfiguration.get(
            ConfigurationsActionKeyStore.IS_FETCHING
        )) {
            props.queryConfiguration = queryConfiguration.get(
                ConfigurationsActionKeyStore.DATA
            ).toJS();
        }

        // Expose received response if it is available
        if (props.queryConfiguration) {
            const requestID = ServiceManager.getRequestID(props.queryConfiguration, context);

            let response = state.services.getIn([
                ServiceActionKeyStore.REQUESTS,
                requestID
            ]);

            if (response && !response.get(ServiceActionKeyStore.IS_FETCHING))
                props.response = response.toJS();
        }
    }

    return props;
};

const actionCreators = (dispatch) => ({

    setPageTitle: function(aTitle) {
        dispatch(Actions.updateTitle(aTitle));
    },

    goTo: function(link, filters) {
        dispatch(push({pathname:link, query:filters}));
    },

    fetchConfigurationIfNeeded: function(id) {
        return dispatch(ConfigurationsActions.fetchIfNeeded(
            id,
            ConfigurationsActionKeyStore.VISUALIZATIONS
        ));
    },

    fetchQueryIfNeeded: function(id) {
        return dispatch(ConfigurationsActions.fetchIfNeeded(
            id,
            ConfigurationsActionKeyStore.QUERIES
        ));
    },

    executeQueryIfNeeded: function(queryConfiguration, context) {
        return dispatch(ServiceActions.fetchIfNeeded(queryConfiguration, context));
    }

 });

export default connect(mapStateToProps, actionCreators)(VisualizationView);
<|endoftext|>


<commit_before>import request                          from "superagent";

import { Constants as AppConstants }          from "../actions/app";
import { Constants as AssessmentConstants }   from "../actions/assessment_offered";
import { Constants as BanksConstants }        from "../actions/banks";
import { Constants as ItemsConstants }        from "../actions/items";
import { DONE }                               from "../constants/wrapper";

export default (store) => (next) => {
  function startApp(action) {

    const state = store.getState();
    switch(action.type) {

      case AppConstants.APP_START:
        const qBankHost = action.qBankHost || "";
        request.get(`${state.settings.rootEndpoint}proxy?qBankHost=${qBankHost}`).then(
          function (response) {
            store.dispatch({
              type:     BanksConstants.GET_BANK_HIERARCHY,
              payload:  response.body
            });
          },
          function (err) {
            console.log("error", err.url, err.message);
          }
        );
        break;

      case AssessmentConstants.ASSESSMENT_OFFER:
        store.dispatch({
          type:     AssessmentConstants.ASSESSMENT_CLEAR_SNIPPET
        });

        const url = `${state.settings.rootEndpoint}offer`;

        const body = {
          bank_id:       action.bankId,
          assessment_id: action.assessmentId,
          qBankHost: action.qBankHost
        };
        request.post(url).send(body).then(
          function (response) {
            store.dispatch({
              type:     AssessmentConstants.ASSESSMENT_OFFER + DONE,
              payload:  response.body
            });
          },
          function (err) {
            console.log("error", err.url, err.message);
          }
        );
        break;

      case ItemsConstants.ASSESSMENT_ITEMS:
        const qBankHost = action.qBankHost || "";
        request.get(`${state.settings.rootEndpoint}items?qBankHost=${qBankHost}&bankId=${action.bankId}&assessmentId=${action.assessmentId}`).then(
          function (response) {
            store.dispatch({
              type:     ItemsConstants.ASSESSMENT_ITEMS + DONE,
              payload:  response.body
            });
          },
          function (err) {
            console.log("error", err.url, err.message);
          }
        );
        break;
    }

    next(action);
  }

  return startApp;
};
<commit_msg>Fix declaring qbankhost multiple times<commit_after>import request                          from "superagent";

import { Constants as AppConstants }          from "../actions/app";
import { Constants as AssessmentConstants }   from "../actions/assessment_offered";
import { Constants as BanksConstants }        from "../actions/banks";
import { Constants as ItemsConstants }        from "../actions/items";
import { DONE }                               from "../constants/wrapper";

export default (store) => (next) => {
  function startApp(action) {
    let qBankHost = "";
    const state = store.getState();
    switch(action.type) {

      case AppConstants.APP_START:
        qBankHost = action.qBankHost || "";
        request.get(`${state.settings.rootEndpoint}proxy?qBankHost=${qBankHost}`).then(
          function (response) {
            store.dispatch({
              type:     BanksConstants.GET_BANK_HIERARCHY,
              payload:  response.body
            });
          },
          function (err) {
            console.log("error", err.url, err.message);
          }
        );
        break;

      case AssessmentConstants.ASSESSMENT_OFFER:
        store.dispatch({
          type:     AssessmentConstants.ASSESSMENT_CLEAR_SNIPPET
        });

        const url = `${state.settings.rootEndpoint}offer`;

        const body = {
          bank_id:       action.bankId,
          assessment_id: action.assessmentId,
          qBankHost: action.qBankHost
        };
        request.post(url).send(body).then(
          function (response) {
            store.dispatch({
              type:     AssessmentConstants.ASSESSMENT_OFFER + DONE,
              payload:  response.body
            });
          },
          function (err) {
            console.log("error", err.url, err.message);
          }
        );
        break;

      case ItemsConstants.ASSESSMENT_ITEMS:
        qBankHost = action.qBankHost || "";
        request.get(`${state.settings.rootEndpoint}items?qBankHost=${qBankHost}&bankId=${action.bankId}&assessmentId=${action.assessmentId}`).then(
          function (response) {
            store.dispatch({
              type:     ItemsConstants.ASSESSMENT_ITEMS + DONE,
              payload:  response.body
            });
          },
          function (err) {
            console.log("error", err.url, err.message);
          }
        );
        break;
    }

    next(action);
  }

  return startApp;
};
<|endoftext|>


<commit_before>import React from 'react';
import TestUtils from 'react-addons-test-utils';
import expect from 'expect';
import expectJSX from 'expect-jsx';
expect.extend(expectJSX);

import File from '../file';
import Progress from '../progress';
import FileViewModel from '../../viewmodels/file.viewmodel';

describe('file component', () => {
    it('should render file', () => {
        const file = new FileViewModel();
        file.name = 'test.jpg';
        file.size = 1024;
        file.mimeType = 'image/jpeg';
        file.date = new Date();

        const renderer = TestUtils.createRenderer();
        renderer.render(<File file={file} />);

        const actualElement = renderer.getRenderOutput();
        const expectedElement = (

test.jpg

1.00 Kb

);
        expect(actualElement).toEqualJSX(expectedElement);
    });

    it('should render file and delete button', () => {
        const file = new FileViewModel();
        file.name = 'test.jpg';
        file.size = 1024;
        file.mimeType = 'image/jpeg';
        file.date = new Date();

        const renderer = TestUtils.createRenderer();
        renderer.render(<File file={file} showDeleteButton="true" />);

        const noRefCheck = () => {};

        let actualElement = renderer.getRenderOutput();
        let expectedElement = (

test.jpg

1.00 Kb

                delete

);
        expect(actualElement).toEqualJSX(expectedElement);
    });

    it('should render file with progress bar while uploading', () => {
        const file = new FileViewModel();
        file.name = 'test.jpg';
        file.size = 1024;
        file.mimeType = 'image/jpeg';
        file.date = new Date();
        file.isUploading = true;
        file.uploadedPercentage = 17;

        const renderer = TestUtils.createRenderer();
        renderer.render(<File file={file} />);

        let actualElement = renderer.getRenderOutput();
        let expectedElement = (

test.jpg

1.00 Kb

            <Progress value={17} />

);
        expect(actualElement).toEqualJSX(expectedElement);
    });
});
<commit_msg>optimized test (prepared for ESlint rules) fixed missing "onDeleteFile" property at File component<commit_after>import React from 'react';
import TestUtils from 'react-addons-test-utils';
import expect from 'expect';
import expectJSX from 'expect-jsx';
expect.extend(expectJSX);

import File from '../file';
import Progress from '../progress';
import FileViewModel from '../../viewmodels/file.viewmodel';

const noRefCheck = () => {};

describe('file component', () => {
    it('should render file', () => {
        const file = new FileViewModel();
        file.name = 'test.jpg';
        file.size = 1024;
        file.mimeType = 'image/jpeg';
        file.date = new Date();

        const renderer = TestUtils.createRenderer();
        renderer.render(<File file={file} onDeleteFile={noRefCheck} />);

        const actualElement = renderer.getRenderOutput();
        const expectedElement = (

test.jpg

1.00 Kb

);
        expect(actualElement).toEqualJSX(expectedElement);
    });

    it('should render file and delete button', () => {
        const file = new FileViewModel();
        file.name = 'test.jpg';
        file.size = 1024;
        file.mimeType = 'image/jpeg';
        file.date = new Date();

        const renderer = TestUtils.createRenderer();
        renderer.render(<File file={file} showDeleteButton onDeleteFile={noRefCheck} />);

        const actualElement = renderer.getRenderOutput();
        const expectedElement = (

test.jpg

1.00 Kb

                delete

);
        expect(actualElement).toEqualJSX(expectedElement);
    });

    it('should render file with progress bar while uploading', () => {
        const file = new FileViewModel();
        file.name = 'test.jpg';
        file.size = 1024;
        file.mimeType = 'image/jpeg';
        file.date = new Date();
        file.isUploading = true;
        file.uploadedPercentage = 17;

        const renderer = TestUtils.createRenderer();
        renderer.render(<File file={file} onDeleteFile={noRefCheck} />);

        const actualElement = renderer.getRenderOutput();
        const expectedElement = (

test.jpg

1.00 Kb

            <Progress value={17} />

);
        expect(actualElement).toEqualJSX(expectedElement);
    });
});
<|endoftext|>


<commit_before>import React from 'react';
import { storiesOf } from '@storybook/react';
import { boolean, text, select } from '@storybook/addon-knobs';
import { State, Store } from '@sambego/storybook-state';
import { action } from '@storybook/addon-actions';
import OptionsHelper from '../../utils/helpers/options-helper';
import Button from '../button/button';
import Alert from '.';
import { notes, info } from './documentation';

const store = new Store({
  open: false
});

const handleCancel = () => {
  store.set({ open: false });
  action('cancel')();
};
const handleOpen = () => {
  store.set({ open: true });
  action('open')();
};

storiesOf('Alert', module)
  .addParameters({
    info: { text: info },
    notes: { markdown: notes }
  })
  .add('default', () => {
    const title = text('title', 'Attention');
    const subtitle = text('subtitle', '');
    const children = text('children', 'This is an example of a alert.');
    const enableBackgroundUI = boolean('enableBackgroundUI', false);
    const disableEscKey = boolean('disableEscKey', false);
    const ariaRole = text('ariaRole', 'dialog');
    const height = text('height', '');
    const showCloseIcon = boolean('showCloseIcon', true);
    const size = select('size', OptionsHelper.sizesFull, Alert.defaultProps.size);
    const stickyFormFooter = boolean('stickyFormFooter', false);
    const open = boolean('open', false);

    return (
      <Alert
        onCancel={ handleCancel }
        title={ title }
        enableBackgroundUI={ enableBackgroundUI }
        disableEscKey={ disableEscKey }
        ariaRole={ ariaRole }
        height={ height }
        showCloseIcon={ showCloseIcon }
        size={ size }
        stickyFormFooter={ stickyFormFooter }
        subtitle={ subtitle }
        open={ open }
      >
        {children}
      </Alert>
    );
  })
  .add('with button', () => {
    const title = text('title', 'Attention');
    const subtitle = text('subtitle', '');
    const children = text('children', 'This is an example of a alert.');
    const enableBackgroundUI = boolean('enableBackgroundUI', false);
    const disableEscKey = boolean('disableEscKey', false);
    const ariaRole = text('ariaRole', 'dialog');
    const height = text('height', '');
    const showCloseIcon = boolean('showCloseIcon', true);
    const size = select('size', OptionsHelper.sizesFull, Alert.defaultProps.size);
    const stickyFormFooter = boolean('stickyFormFooter', false);

    return (
      <State store={ store }>
        <Button key='button' onClick={ handleOpen }>Open Preview</Button>
        <Alert
          key='alert'
          onCancel={ handleCancel }
          title={ title }
          enableBackgroundUI={ enableBackgroundUI }
          disableEscKey={ disableEscKey }
          ariaRole={ ariaRole }
          height={ height }
          showCloseIcon={ showCloseIcon }
          size={ size }
          stickyFormFooter={ stickyFormFooter }
          subtitle={ subtitle }
          open={ store.get('open') }
        >
          {children}
        </Alert>
      </State>
    );
  });
<commit_msg>remove not necessary propTypes<commit_after>import React from 'react';
import { storiesOf } from '@storybook/react';
import { boolean, text, select } from '@storybook/addon-knobs';
import { State, Store } from '@sambego/storybook-state';
import { action } from '@storybook/addon-actions';
import OptionsHelper from '../../utils/helpers/options-helper';
import Button from '../button/button';
import Alert from '.';
import { notes, info } from './documentation';

const store = new Store({
  open: false
});

const handleCancel = () => {
  store.set({ open: false });
  action('cancel')();
};
const handleOpen = () => {
  store.set({ open: true });
  action('open')();
};

storiesOf('Alert', module)
  .addParameters({
    info: {
      text: info,
      propTablesExclude: [State, Button]
    },
    notes: { markdown: notes }
  })
  .add('default', () => {
    const title = text('title', 'Attention');
    const subtitle = text('subtitle', '');
    const children = text('children', 'This is an example of a alert.');
    const enableBackgroundUI = boolean('enableBackgroundUI', false);
    const disableEscKey = boolean('disableEscKey', false);
    const ariaRole = text('ariaRole', 'dialog');
    const height = text('height', '');
    const showCloseIcon = boolean('showCloseIcon', true);
    const size = select('size', OptionsHelper.sizesFull, Alert.defaultProps.size);
    const stickyFormFooter = boolean('stickyFormFooter', false);
    const open = boolean('open', false);

    return (
      <Alert
        onCancel={ handleCancel }
        title={ title }
        enableBackgroundUI={ enableBackgroundUI }
        disableEscKey={ disableEscKey }
        ariaRole={ ariaRole }
        height={ height }
        showCloseIcon={ showCloseIcon }
        size={ size }
        stickyFormFooter={ stickyFormFooter }
        subtitle={ subtitle }
        open={ open }
      >
        {children}
      </Alert>
    );
  })
  .add('with button', () => {
    const title = text('title', 'Attention');
    const subtitle = text('subtitle', '');
    const children = text('children', 'This is an example of a alert.');
    const enableBackgroundUI = boolean('enableBackgroundUI', false);
    const disableEscKey = boolean('disableEscKey', false);
    const ariaRole = text('ariaRole', 'dialog');
    const height = text('height', '');
    const showCloseIcon = boolean('showCloseIcon', true);
    const size = select('size', OptionsHelper.sizesFull, Alert.defaultProps.size);
    const stickyFormFooter = boolean('stickyFormFooter', false);

    return (
      <State store={ store }>
        <Button key='button' onClick={ handleOpen }>Open Preview</Button>
        <Alert
          key='alert'
          onCancel={ handleCancel }
          title={ title }
          enableBackgroundUI={ enableBackgroundUI }
          disableEscKey={ disableEscKey }
          ariaRole={ ariaRole }
          height={ height }
          showCloseIcon={ showCloseIcon }
          size={ size }
          stickyFormFooter={ stickyFormFooter }
          subtitle={ subtitle }
          open={ store.get('open') }
        >
          {children}
        </Alert>
      </State>
    );
  });
<|endoftext|>


<commit_before>import React from 'react';

const styles = require('./ContentPage.css');

const ContentPage = () => (

Node.js Travis CI demo application

Simple Node.js in React application to test Travis CI with GitHub and Azure CI. It pushes build stright to Azure if all tests are passed.

);

export default ContentPage;
<commit_msg>ContentPage paragraph updated<commit_after>import React from 'react';

const styles = require('./ContentPage.css');

const ContentPage = () => (

Node.js Travis CI demo application

Simple Node.js application written in in React to test Travis CI with GitHub and Azure CI. It pushes build stright to Azure if all tests are passed.

);

export default ContentPage;
<|endoftext|>


<commit_before>var app

app = angular.module("cloudStorm.wizard", [])

app.component("csWizard", {

    bindings : {
        csWizardOptions: '=?',
        panelNumberCallback: '=',
        pageType: "=",
        itemId: "=",
        resourceType: "=?",
    },
    templateUrl : "components/cs-wizard/cs-wizard-template.html",
    controller : ['$scope', '$rootScope', 'ResourceService', '$document', 'csDescriptorService', 'csLog', 'csAlertService', 'csRoute', function($scope, $rootScope, ResourceService, $document, csDescriptorService, csLog, csAlertService, csRoute){

      csLog.set(this, 'csWizard')

      var self = this
      var formMode, item, resource, wizardMaxDepth;

      this.loading = true
      this.errors = []

      this.setOptions = function(resource, item, formMode, wizardMaxDepth, parent, directive){

        this.log("setOptions");
        var panelDescriptor = {
          resource: resource,
          item: item,
          formMode: formMode,
          wizardMaxDepth: wizardMaxDepth,
          parent: parent,
          directive: directive
        };
        this.panelStack = [panelDescriptor];
      }

      this.finish = function(error) {

        this.log("finished: " + error);
        this.loading = false;
        if (error) {
          this.errors = [error];
          throw new Error(error);
        }
      };

      //Runs on the development
      var override = null;
      this.$onInit = function() {

        if (this.csWizardOptions) {
          this.singlePage = false
          this.log("wizardOptions branch");
          this.resourceType = this.csWizardOptions['resource-type'];
          resource = angular.copy(ResourceService.get(this.resourceType));
          item = this.csWizardOptions['form-item'];
          formMode = this.formMode || this.csWizardOptions['form-mode'];
          wizardMaxDepth = this.csWizardOptions['max-depth'] || 5;
          if(this.csWizardOptions['resource-overrides']){
            override = this.csWizardOptions['resource-overrides'][resource_type]
            if (override && override.directive != null) {
              override = override.directive;
            }
          }
          this.setOptions(resource, item, formMode, wizardMaxDepth, null, override);
          this.finish();

        } else {

          //This branch sets the following fields of the csWizardOptions object:
          // [form-mode, events]

          this.log("singlePage branch");
          this.singlePage = true
          this.csWizardOptions = {};

          if (this.pageType !== 'show' && this.pageType !== 'edit') {
            //It throws an error
            this.finish("'" + formMode + "' is not a valid page type!");
          }

          this.csWizardOptions['form-mode'] = this.pageType

          csDescriptorService.getPromises()
          .then(function(){
            var error;
            try {
              resource = ResourceService.get(self.resourceType);
            } catch (error) {
              var errorMsg = "'" + self.resourceType + "' is not a registered resource.";
              self.finish(errorMsg);
            }

            resource = angular.copy(resource)

            resource.$get(self.itemId, {include: '*'})
            .then(function(item) {

              var wizardCanceled = (function() {
                return csRoute.go("index", {
                  resourceType: resource.descriptor.type
                });
              }).bind(resource);

              formMode = self.pageType
              var wizardSubmitted = (function() {
                switch (formMode) {
                  case "create":
                    csAlertService.success('new_resource_created');
                    break;
                  case "edit":
                    csAlertService.success("changes_saved");
                }
                return csRoute.go("index", {
                  resourceType: resource.descriptor.type
                });
              }).bind(formMode, resource);

              self.csWizardOptions.events = {
                'wizard-canceled': wizardCanceled,
                'wizard-submited': wizardSubmitted
              };

              wizardMaxDepth = 5;
              self.setOptions(resource, item, formMode, wizardMaxDepth);
              return self.finish();

            }).catch(function(error) {
              // Process the reason
              var errorMsg = "There is no " + resource.descriptor.name + " with the id: " + self.itemId;
              self.finish(errorMsg);
            })
          });
        }
      }

      //================= Lifecycle events =====================

      $scope.$on('create-resource', (function(event, resource, attribute, parent) {
        return this.pushPanel(resource, attribute, parent);
      }).bind(this));

      $scope.$on('form-cancel', (function(event, resource, attribute) {
        this.popPanel();
        if (this.panelStack.length === 0) {
          return this.notify_listeners($scope, 'wizard-canceled', resource);
        }
      }).bind(this));

      $scope.$on('wizard-cancel', (function(event, resource, attribute) {
        this.popAllPanels();
        if (this.panelStack.length === 0) {
          return this.notify_listeners($scope, 'wizard-canceled', resource);
        }
      }).bind(this));

      $scope.$on('form-submit', (function(event, resource, attribute) {
        if (this.panelStack.length === 1) {
          this.notify_listeners($scope, 'wizard-submited', resource);
          if (!this.csWizardOptions['keep-first']) {
            return this.popPanel();
          }
        } else {
          return this.popPanel();
        }
      }).bind(this));

      $scope.$on('form-error', (function(event, resource, attribute) {
        if (resource.status !== 422) {
          $scope.$emit('wizard-error', resource.data);
          if (this.csWizardOptions.events['wizard-error'] && this.panelStack.length === 1) {
            return this.csWizardOptions.events['wizard-error'](resource);
          }
        }
      }).bind(this));

      $scope.$on('transitioned', (function(event, child, parent) {
        var i, len, results, transition, transitions;
        if (child && parent) {
          if (this.csWizardOptions.transitions) {
            if (transitions = this.csWizardOptions.transitions[parent.type] && this.csWizardOptions.transitions[parent.type][child.type]) {
              results = [];
              for (i = 0, len = transitions.length; i < len; i++) {
                transition = transitions[i];
                results.push(transition(child, parent));
              }
              return results;
            }
          }
        }
      }).bind(this));

      var keyPressed = function(keyEvent) {
        if (keyEvent.keyCode === 27) {
          popPanel($scope);
          if ($scope.panelStack.length === 0) {
            notify_listeners($scope, 'wizard-canceled', null);
          }
          return $scope.$apply();
        }
      };

      $document.on('keydown', keyPressed);

      $scope.$on('$destroy', function() {
        return $document.off('keydown', keyPressed);
      });

      $scope.$on('$destroy', function() {
        return $document.off('keydown', keyPressed);
      });

      this.shouldShowNewButton = function() {
        if (this.panelStack.length >= wizardMaxDepth) {
          return false;
        }
        return true;
      };

      this.panelHover = function(hoveredIndex) {
        return _.forEach(this.panelStack, function(panel, panelIndex) {
          if (panelIndex < hoveredIndex) {
            return panel.hoverOrder = -1;
          } else if (panelIndex > hoveredIndex) {
            return panel.hoverOrder = 1;
          } else {
            return panel.hoverOrder = 0;
          }
        });
      };

      this.pushPanel = function(resource_type, attribute, parent) {

        var override, panelIndex;
        panelIndex = this.panelStack.length - 1;
        _.forEach(this.panelStack[panelIndex].resource.descriptor.fields, function(value) {
          return value.inactive = true;
        });
        var activeField = _.find(this.panelStack[panelIndex].resource.descriptor.fields, function(o) {
          return o.attribute === attribute;
        });
        if (activeField) {
          activeField.inactive = false;
        }
        var panelDescriptor = {
          resource: angular.copy(ResourceService.get(resource_type)),
          parent: parent,
          formMode: 'create',
          attribute: attribute
        };
        if (this.csWizardOptions['resource-overrides'] && (override = this.csWizardOptions['resource-overrides'][resource_type])) {
          if (override.directive != null) {
            panelDescriptor.directive = override.directive;
          }
        }
        this.panelStack.push(panelDescriptor);
        this.panelHover(panelIndex + 1);
        if (this.panelNumberCallback) {
          this.panelNumberCallback(this.panelStack.length);
        }
      };

      var overriden_resource_descriptors = {};

      this.resource_descriptor = function(panel) {
        var descriptor, field, field_name, field_override, field_overrides, overrides;
        if (overriden_resource_descriptors[panel.resource.descriptor.type]) {
          return overriden_resource_descriptors[panel.resource.descriptor.type];
        } else {
          descriptor = angular.copy(panel.resource.descriptor);
          overriden_resource_descriptors[panel.resource.descriptor.type] = descriptor;
          if (this.csWizardOptions['resource-overrides']) {
            if (overrides = this.csWizardOptions['resource-overrides'][panel.resource.descriptor.type]) {
              if (field_overrides = overrides['fields']) {
                for (field_name in field_overrides) {
                  field_override = field_overrides[field_name];
                  field = _.find(descriptor.fields, function(f) {
                    return f.attribute === field_name;
                  });
                  angular.merge(field, field_override);
                }
              }
            }
          }
          return descriptor;
        }
      };

      this.popPanel = function() {

        var panelIndex;
        this.panelStack.pop();
        panelIndex = this.panelStack.length - 1;
        if (this.panelStack[panelIndex]) {
          _.forEach(this.panelStack[panelIndex].resource.descriptor.fields, function(value) {
            return value.inactive = false;
          });
        }
        this.panelHover(panelIndex + 1);
        if (this.panelNumberCallback) {
          return this.panelNumberCallback(this.panelStack.length);
        }
      };

      this.popAllPanels = function($scope) {
        this.panelStack = [];
        if (this.panelNumberCallback) {
          return this.panelNumberCallback(this.panelStack.length);
        }
      };

      this.notify_listeners = function($scope, event, resource) {

        $scope.$emit(event);
        if (this.csWizardOptions && this.csWizardOptions.events) {
          if (this.csWizardOptions.events[event]) {
            this.csWizardOptions.events[event](resource);
          }
        }
        if (this.panelStack.length === 0) {
          $scope.$emit('wizard-finished');
          if (this.csWizardOptions && this.csWizardOptions.events) {
            if (this.csWizardOptions.events['wizard-finished']) {
              return this.csWizardOptions.events['wizard-finished'](resource);
            }
          }
        }
      };

    }]
})
<commit_msg>removed unnecessary injected module<commit_after>var app

app = angular.module("cloudStorm.wizard", [])

app.component("csWizard", {

    bindings : {
        csWizardOptions: '=?',
        panelNumberCallback: '=',
        pageType: "=",
        itemId: "=",
        resourceType: "=?",
    },
    templateUrl : "components/cs-wizard/cs-wizard-template.html",
    controller : ['$scope', 'ResourceService', '$document', 'csDescriptorService', 'csLog', 'csAlertService', 'csRoute', function($scope, ResourceService, $document, csDescriptorService, csLog, csAlertService, csRoute){

      csLog.set(this, 'csWizard')

      var self = this
      var formMode, item, resource, wizardMaxDepth;

      this.loading = true
      this.errors = []

      this.setOptions = function(resource, item, formMode, wizardMaxDepth, parent, directive){

        this.log("setOptions");
        var panelDescriptor = {
          resource: resource,
          item: item,
          formMode: formMode,
          wizardMaxDepth: wizardMaxDepth,
          parent: parent,
          directive: directive
        };
        this.panelStack = [panelDescriptor];
      }

      this.finish = function(error) {

        this.log("finished: " + error);
        this.loading = false;
        if (error) {
          this.errors = [error];
          throw new Error(error);
        }
      };

      //Runs on the development
      var override = null;
      this.$onInit = function() {

        if (this.csWizardOptions) {
          this.singlePage = false
          this.log("wizardOptions branch");
          this.resourceType = this.csWizardOptions['resource-type'];
          resource = angular.copy(ResourceService.get(this.resourceType));
          item = this.csWizardOptions['form-item'];
          formMode = this.formMode || this.csWizardOptions['form-mode'];
          wizardMaxDepth = this.csWizardOptions['max-depth'] || 5;
          if(this.csWizardOptions['resource-overrides']){
            override = this.csWizardOptions['resource-overrides'][resource_type]
            if (override && override.directive != null) {
              override = override.directive;
            }
          }
          this.setOptions(resource, item, formMode, wizardMaxDepth, null, override);
          this.finish();

        } else {

          //This branch sets the following fields of the csWizardOptions object:
          // [form-mode, events]

          this.log("singlePage branch");
          this.singlePage = true
          this.csWizardOptions = {};

          if (this.pageType !== 'show' && this.pageType !== 'edit') {
            //It throws an error
            this.finish("'" + formMode + "' is not a valid page type!");
          }

          this.csWizardOptions['form-mode'] = this.pageType

          csDescriptorService.getPromises()
          .then(function(){
            var error;
            try {
              resource = ResourceService.get(self.resourceType);
            } catch (error) {
              var errorMsg = "'" + self.resourceType + "' is not a registered resource.";
              self.finish(errorMsg);
            }

            resource = angular.copy(resource)

            resource.$get(self.itemId, {include: '*'})
            .then(function(item) {

              var wizardCanceled = (function() {
                return csRoute.go("index", {
                  resourceType: resource.descriptor.type
                });
              }).bind(resource);

              formMode = self.pageType
              var wizardSubmitted = (function() {
                switch (formMode) {
                  case "create":
                    csAlertService.success('new_resource_created');
                    break;
                  case "edit":
                    csAlertService.success("changes_saved");
                }
                return csRoute.go("index", {
                  resourceType: resource.descriptor.type
                });
              }).bind(formMode, resource);

              self.csWizardOptions.events = {
                'wizard-canceled': wizardCanceled,
                'wizard-submited': wizardSubmitted
              };

              wizardMaxDepth = 5;
              self.setOptions(resource, item, formMode, wizardMaxDepth);
              return self.finish();

            }).catch(function(error) {
              // Process the reason
              var errorMsg = "There is no " + resource.descriptor.name + " with the id: " + self.itemId;
              self.finish(errorMsg);
            })
          });
        }
      }

      //================= Lifecycle events =====================

      $scope.$on('create-resource', (function(event, resource, attribute, parent) {
        return this.pushPanel(resource, attribute, parent);
      }).bind(this));

      $scope.$on('form-cancel', (function(event, resource, attribute) {
        this.popPanel();
        if (this.panelStack.length === 0) {
          return this.notify_listeners($scope, 'wizard-canceled', resource);
        }
      }).bind(this));

      $scope.$on('wizard-cancel', (function(event, resource, attribute) {
        this.popAllPanels();
        if (this.panelStack.length === 0) {
          return this.notify_listeners($scope, 'wizard-canceled', resource);
        }
      }).bind(this));

      $scope.$on('form-submit', (function(event, resource, attribute) {
        if (this.panelStack.length === 1) {
          this.notify_listeners($scope, 'wizard-submited', resource);
          if (!this.csWizardOptions['keep-first']) {
            return this.popPanel();
          }
        } else {
          return this.popPanel();
        }
      }).bind(this));

      $scope.$on('form-error', (function(event, resource, attribute) {
        if (resource.status !== 422) {
          $scope.$emit('wizard-error', resource.data);
          if (this.csWizardOptions.events['wizard-error'] && this.panelStack.length === 1) {
            return this.csWizardOptions.events['wizard-error'](resource);
          }
        }
      }).bind(this));

      $scope.$on('transitioned', (function(event, child, parent) {
        var i, len, results, transition, transitions;
        if (child && parent) {
          if (this.csWizardOptions.transitions) {
            if (transitions = this.csWizardOptions.transitions[parent.type] && this.csWizardOptions.transitions[parent.type][child.type]) {
              results = [];
              for (i = 0, len = transitions.length; i < len; i++) {
                transition = transitions[i];
                results.push(transition(child, parent));
              }
              return results;
            }
          }
        }
      }).bind(this));

      var keyPressed = function(keyEvent) {
        if (keyEvent.keyCode === 27) {
          popPanel($scope);
          if ($scope.panelStack.length === 0) {
            notify_listeners($scope, 'wizard-canceled', null);
          }
          return $scope.$apply();
        }
      };

      $document.on('keydown', keyPressed);

      $scope.$on('$destroy', function() {
        return $document.off('keydown', keyPressed);
      });

      $scope.$on('$destroy', function() {
        return $document.off('keydown', keyPressed);
      });

      this.shouldShowNewButton = function() {
        if (this.panelStack.length >= wizardMaxDepth) {
          return false;
        }
        return true;
      };

      this.panelHover = function(hoveredIndex) {
        return _.forEach(this.panelStack, function(panel, panelIndex) {
          if (panelIndex < hoveredIndex) {
            return panel.hoverOrder = -1;
          } else if (panelIndex > hoveredIndex) {
            return panel.hoverOrder = 1;
          } else {
            return panel.hoverOrder = 0;
          }
        });
      };

      this.pushPanel = function(resource_type, attribute, parent) {

        var override, panelIndex;
        panelIndex = this.panelStack.length - 1;
        _.forEach(this.panelStack[panelIndex].resource.descriptor.fields, function(value) {
          return value.inactive = true;
        });
        var activeField = _.find(this.panelStack[panelIndex].resource.descriptor.fields, function(o) {
          return o.attribute === attribute;
        });
        if (activeField) {
          activeField.inactive = false;
        }
        var panelDescriptor = {
          resource: angular.copy(ResourceService.get(resource_type)),
          parent: parent,
          formMode: 'create',
          attribute: attribute
        };
        if (this.csWizardOptions['resource-overrides'] && (override = this.csWizardOptions['resource-overrides'][resource_type])) {
          if (override.directive != null) {
            panelDescriptor.directive = override.directive;
          }
        }
        this.panelStack.push(panelDescriptor);
        this.panelHover(panelIndex + 1);
        if (this.panelNumberCallback) {
          this.panelNumberCallback(this.panelStack.length);
        }
      };

      var overriden_resource_descriptors = {};

      this.resource_descriptor = function(panel) {
        var descriptor, field, field_name, field_override, field_overrides, overrides;
        if (overriden_resource_descriptors[panel.resource.descriptor.type]) {
          return overriden_resource_descriptors[panel.resource.descriptor.type];
        } else {
          descriptor = angular.copy(panel.resource.descriptor);
          overriden_resource_descriptors[panel.resource.descriptor.type] = descriptor;
          if (this.csWizardOptions['resource-overrides']) {
            if (overrides = this.csWizardOptions['resource-overrides'][panel.resource.descriptor.type]) {
              if (field_overrides = overrides['fields']) {
                for (field_name in field_overrides) {
                  field_override = field_overrides[field_name];
                  field = _.find(descriptor.fields, function(f) {
                    return f.attribute === field_name;
                  });
                  angular.merge(field, field_override);
                }
              }
            }
          }
          return descriptor;
        }
      };

      this.popPanel = function() {

        var panelIndex;
        this.panelStack.pop();
        panelIndex = this.panelStack.length - 1;
        if (this.panelStack[panelIndex]) {
          _.forEach(this.panelStack[panelIndex].resource.descriptor.fields, function(value) {
            return value.inactive = false;
          });
        }
        this.panelHover(panelIndex + 1);
        if (this.panelNumberCallback) {
          return this.panelNumberCallback(this.panelStack.length);
        }
      };

      this.popAllPanels = function($scope) {
        this.panelStack = [];
        if (this.panelNumberCallback) {
          return this.panelNumberCallback(this.panelStack.length);
        }
      };

      this.notify_listeners = function($scope, event, resource) {

        $scope.$emit(event);
        if (this.csWizardOptions && this.csWizardOptions.events) {
          if (this.csWizardOptions.events[event]) {
            this.csWizardOptions.events[event](resource);
          }
        }
        if (this.panelStack.length === 0) {
          $scope.$emit('wizard-finished');
          if (this.csWizardOptions && this.csWizardOptions.events) {
            if (this.csWizardOptions.events['wizard-finished']) {
              return this.csWizardOptions.events['wizard-finished'](resource);
            }
          }
        }
      };

    }]
})
<|endoftext|>


<commit_before>// @flow
import React from 'react'
import { css } from 'glamor'
import { MainView } from '../views/MainView'
import StyleGuideIcons from './StyleGuideIcons'
import { flex, minBreak2, wrapperPaddingX } from '../../styles/cso'

const headerStyle = {
  ...wrapperPaddingX,
  ...css({
    paddingTop: 20,
    [minBreak2]: {
      paddingTop: 40,
    },
  }),
}
const h1Style = css({ fontSize: 24 })
const navStyle = {
  ...flex,
  ...css({
    paddingTop: 20,
    paddingBottom: 20,
  }),
}
const buttonStyle = {
  ...css({
    fontSize: 18,
    marginRight: 10,
  }),
}

export default() =>
  <MainView className="StyleGuide">

Ello style guide

        <button {...buttonStyle}>Icons</button>


<commit_before>import React, { useEffect, useRef, useCallback } from 'react';

import { focusOnFirstDescendent, focusOnLastDescendent } from './utils';

const FocusRing = ({ topFocusBumperRef, bottomFocusBumperRef, children }) => {
  return (
    <>

      {children}

    </>
  );
};

const openDialogs = new Set();

const useFocusTrap = ({ active, sourceRef }) => {
  const dialogRef = useRef();
  const topFocusBumperRef = useRef();
  const bottomFocusBumperRef = useRef();

  const InternalFocusRing = useCallback(
    ({ children }) => (
      <FocusRing topFocusBumperRef={topFocusBumperRef} bottomFocusBumperRef={bottomFocusBumperRef}>
        {children}
      </FocusRing>
    ),
    [],
  );
  InternalFocusRing.displayName = 'FocusRing';

  useEffect(() => {
    if (active) {
      const currentDialogRef = dialogRef.current;
      if (!currentDialogRef) {
        return;
      }

      if (openDialogs.size > 0) {
        document.removeEventListener('focusin', openDialogs[openDialogs.size - 1]);
      }

      focusOnFirstDescendent(currentDialogRef);

      const trapFocusInDialog = (event) => {
        if (!currentDialogRef.contains(event.target)) {
          if (document.activeElement === event.target) {
            if (event.target === bottomFocusBumperRef.current) {
              // Reset the focus to the first element after reaching the last element
              focusOnFirstDescendent(currentDialogRef);
            } else if (event.target === topFocusBumperRef.current) {
              // Reset the focus to the last element when focusing in reverse (shift-tab)
              focusOnLastDescendent(currentDialogRef);
            }
          }
        }
      };

      openDialogs.add(trapFocusInDialog);
      document.addEventListener('focusin', trapFocusInDialog, true);

      return function cleanup() {
        document.removeEventListener('focusin', trapFocusInDialog, true);
        openDialogs.delete(trapFocusInDialog);

        if (openDialogs.size > 0) {
          document.addEventListener('focusin', openDialogs[openDialogs.size - 1]);
        }
      };
    } else {
      const currentSourceRef = sourceRef?.current;
      // sourceRef will be undefined on initial render, so this is a safe operation
      if (currentSourceRef) {
        currentSourceRef.focus();
      }
    }
  }, [active, sourceRef]);

  return { dialogRef, FocusRing: InternalFocusRing };
};

export default useFocusTrap;
<commit_msg>:bug: return the focus to the sourceRef when cleaning up instead of in the else block<commit_after>import React, { useEffect, useRef, useCallback } from 'react';

import { focusOnFirstDescendent, focusOnLastDescendent } from './utils';

const FocusRing = ({ topFocusBumperRef, bottomFocusBumperRef, children }) => {
  return (
    <>

      {children}

    </>
  );
};

const openDialogs = new Set();

const useFocusTrap = ({ active, sourceRef }) => {
  const dialogRef = useRef();
  const topFocusBumperRef = useRef();
  const bottomFocusBumperRef = useRef();

  const InternalFocusRing = useCallback(
    ({ children }) => (
      <FocusRing topFocusBumperRef={topFocusBumperRef} bottomFocusBumperRef={bottomFocusBumperRef}>
        {children}
      </FocusRing>
    ),
    [],
  );
  InternalFocusRing.displayName = 'FocusRing';

  useEffect(() => {
    if (active) {
      const currentDialogRef = dialogRef.current;
      if (!currentDialogRef) {
        return;
      }

      if (openDialogs.size > 0) {
        document.removeEventListener('focusin', openDialogs[openDialogs.size - 1]);
      }

      focusOnFirstDescendent(currentDialogRef);

      const trapFocusInDialog = (event) => {
        if (!currentDialogRef.contains(event.target)) {
          if (document.activeElement === event.target) {
            if (event.target === bottomFocusBumperRef.current) {
              // Reset the focus to the first element after reaching the last element
              focusOnFirstDescendent(currentDialogRef);
            } else if (event.target === topFocusBumperRef.current) {
              // Reset the focus to the last element when focusing in reverse (shift-tab)
              focusOnLastDescendent(currentDialogRef);
            }
          }
        }
      };

      openDialogs.add(trapFocusInDialog);
      document.addEventListener('focusin', trapFocusInDialog, true);

      return function cleanup() {
        document.removeEventListener('focusin', trapFocusInDialog, true);
        openDialogs.delete(trapFocusInDialog);

        const currentSourceRef = sourceRef?.current;
        if (currentSourceRef) {
          currentSourceRef.focus();
        }

        if (openDialogs.size > 0) {
          document.addEventListener('focusin', openDialogs[openDialogs.size - 1]);
        }
      };
    }
  }, [active, sourceRef]);

  return { dialogRef, FocusRing: InternalFocusRing };
};

export default useFocusTrap;
<|endoftext|>


<commit_before>import useRefInit from '../hooks/useRefInit';

const CL_ROW = 'row__pane-topic not-selected';

const _crMenuItem = (
  name,
  onClick
) => onClick ? ({
  name,
  onClick,
  isClose: true
}) : null;

const useMenuMore = (
  toggleIsLabels,
  toggleIsToolbar,
  toggleIsDates
) => useRefInit(()=>({
  titleCl: CL_ROW,
  pageWidth: 160,
  maxPages: 1,
  p0: [
    _crMenuItem('Toggle Dates', toggleIsDates),
    _crMenuItem('Toggle Labels', toggleIsLabels),
    _crMenuItem('Toggle ToolBar', toggleIsToolbar)
  ].filter(Boolean)
}))[0];

export default useMenuMore
<commit_msg>Edit order of arguments for useMenuMore<commit_after>import useRefInit from '../hooks/useRefInit';

const CL_ROW = 'row__pane-topic not-selected';

const _crMenuItem = (
  name,
  onClick
) => onClick ? ({
  name,
  onClick,
  isClose: true
}) : null;

const useMenuMore = (
  toggleIsToolbar,
  toggleIsLabels,
  toggleIsDates
) => useRefInit(()=>({
  titleCl: CL_ROW,
  pageWidth: 160,
  maxPages: 1,
  p0: [
    _crMenuItem('Toggle Dates', toggleIsDates),
    _crMenuItem('Toggle Labels', toggleIsLabels),
    _crMenuItem('Toggle ToolBar', toggleIsToolbar)
  ].filter(Boolean)
}))[0];

export default useMenuMore
<|endoftext|>


<commit_before>const assert = require('chai').assert

const singpost = require('../src/singpostTracker')
const moment = require('moment-timezone')
moment.tz.setDefault("Asia/Singapore") // +8h

describe('Singpost', function() {
    this.timeout(0)

    describe('#Singpost', function() {
        // Not working at this time
        it('should extract the messages from the website with success', function(done) {
            const id = 'RF427233044SG'
            singpost.getInfo(id, (err, info) => {
                assert.isNull(err)

                assert.equal(info.id, id)
                assert.deepEqual(info.messages, [
                    {
                        "date": "2017-01-25T00:00:00+08:00",
                        "status": "Product Delivered"
                    },
                    {
                        "date": "2016-12-17T00:00:00+08:00",
                        "status": "Held by Custom"
                    },
                    {
                        "date": "2016-12-05T00:00:00+08:00",
                        "status": "Held by Custom"
                    },
                    {
                        "date": "2016-12-02T00:00:00+08:00",
                        "status": "Arrival at Processing Center"
                    },
                    {
                        "date": "2016-11-30T00:00:00+08:00",
                        "status": "Arrival at Destination Post"
                    },
                    {
                        "date": "2016-11-28T00:00:00+08:00",
                        "status": "Despatched to overseas"
                    },
                    {
                        "date": "2016-11-26T00:00:00+08:00",
                        "status": "Received from Customer"
                    }
                ])

                console.log(id + ' attempts: ' + info.retries)
                done()
            })

        });

        it('should fail to extract', function(done) {
            const id = '423423424'
            singpost.getInfo(id, (err, info) => {
                assert.isNotNull(err)

                done()
            })

        });
    });

});<commit_msg>Removed comment<commit_after>const assert = require('chai').assert

const singpost = require('../src/singpostTracker')
const moment = require('moment-timezone')
moment.tz.setDefault("Asia/Singapore") // +8h

describe('Singpost', function() {
    this.timeout(0)

    describe('#Singpost', function() {
        it('should extract the messages from the website with success', function(done) {
            const id = 'RF427233044SG'
            singpost.getInfo(id, (err, info) => {
                assert.isNull(err)

                assert.equal(info.id, id)
                assert.deepEqual(info.messages, [
                    {
                        "date": "2017-01-25T00:00:00+08:00",
                        "status": "Product Delivered"
                    },
                    {
                        "date": "2016-12-17T00:00:00+08:00",
                        "status": "Held by Custom"
                    },
                    {
                        "date": "2016-12-05T00:00:00+08:00",
                        "status": "Held by Custom"
                    },
                    {
                        "date": "2016-12-02T00:00:00+08:00",
                        "status": "Arrival at Processing Center"
                    },
                    {
                        "date": "2016-11-30T00:00:00+08:00",
                        "status": "Arrival at Destination Post"
                    },
                    {
                        "date": "2016-11-28T00:00:00+08:00",
                        "status": "Despatched to overseas"
                    },
                    {
                        "date": "2016-11-26T00:00:00+08:00",
                        "status": "Received from Customer"
                    }
                ])

                console.log(id + ' attempts: ' + info.retries)
                done()
            })

        });

        it('should fail to extract', function(done) {
            const id = '423423424'
            singpost.getInfo(id, (err, info) => {
                assert.isNotNull(err)

                done()
            })

        });
    });

});<|endoftext|>


<commit_before>const path = require("path");
const glob = require("glob");
const fs   = require("fs");

const testDir            = path.dirname(__dirname)
const fixtures           = path.join(testDir, "fixtures")
const root               = path.dirname(testDir)
const syntaxes           = path.join(root, "syntaxes")
const eachJsonSyntax     = glob.sync(path.join(syntaxes, "*.json"))
const eachLanguage       = glob.sync(path.join(root, "source/languages/*"))
const languageExtensions = eachLanguage.map(each => path.basename(each))
const languageFileTypes  = eachJsonSyntax.map(each => JSON.parse(fs.readFileSync(each))["fileTypes"] )

module.exports = {
    root,
    fixtures,
    tests:          testDir,
    specDir:        path.join(testDir, "specs"),
    languages:      path.join(root, "source", "languages"),
    eachLanguage:   glob.sync(path.join(root, "source/languages/*")),
    eachJsonSyntax: glob.sync(path.join(syntaxes, "*.json")),
    eachFixture:    glob.sync(path.join(fixtures,`**/*.{${languageFileTypes.flat().join(",")}}`)),
    jsonSyntax:     (extensionName) => path.join(syntaxes, `${extensionName}.tmLanguage.json`)
}<commit_msg>make paths.js not rely on node >= 11.0<commit_after>const path = require("path");
const glob = require("glob");
const fs   = require("fs");
const _ = require("lodash")

const testDir            = path.dirname(__dirname)
const fixtures           = path.join(testDir, "fixtures")
const root               = path.dirname(testDir)
const syntaxes           = path.join(root, "syntaxes")
const eachJsonSyntax     = glob.sync(path.join(syntaxes, "*.json"))
const eachLanguage       = glob.sync(path.join(root, "source/languages/*"))
const languageExtensions = eachLanguage.map(each => path.basename(each))
const languageFileTypes  = eachJsonSyntax.map(each => JSON.parse(fs.readFileSync(each))["fileTypes"] )

module.exports = {
    root,
    fixtures,
    tests:          testDir,
    specDir:        path.join(testDir, "specs"),
    languages:      path.join(root, "source", "languages"),
    eachLanguage:   glob.sync(path.join(root, "source/languages/*")),
    eachJsonSyntax: glob.sync(path.join(syntaxes, "*.json")),
    eachFixture:    glob.sync(path.join(fixtures,`**/*.{${_.flattenDeep(languageFileTypes).join(",")}}`)),
    jsonSyntax:     (extensionName) => path.join(syntaxes, `${extensionName}.tmLanguage.json`)
}
<|endoftext|>


<commit_before>import React, { useEffect, useState, useCallback, useRef } from "react";
import PropTypes from "prop-types";
import propTypes from "@styled-system/prop-types";

import { StyledMenuWrapper } from "./menu.style";
import { menuKeyboardNavigation } from "./__internal__/keyboard-navigation";
import Events from "../../utils/helpers/events";
import MenuContext from "./menu.context";

const Menu = ({ menuType = "light", children, ...rest }) => {
  const [focusedItemIndex, setFocusedItemIndex] = useState(undefined);
  const ref = useRef();

  const handleKeyDown = useCallback(
    (event) => {
      const newIndex = menuKeyboardNavigation(
        event,
        React.Children.toArray(children)
      );

      setFocusedItemIndex(newIndex);
    },
    [children]
  );

  const onClickOutside = useCallback((event) => {
    // Reset the state of the menu when clicking elsewhere
    if (!Events.composedPath(event).includes(ref.current)) {
      setFocusedItemIndex(undefined);
      document.removeEventListener("click", onClickOutside);
    }
  }, []);

  useEffect(() => {
    document.addEventListener("click", onClickOutside);

    return function cleanup() {
      document.removeEventListener("click", onClickOutside);
    };
  });

  return (
    <StyledMenuWrapper
      data-component="menu"
      menuType={menuType}
      {...rest}
      ref={ref}
    >
      {React.Children.map(children, (child, index) => {
        const isFocused = focusedItemIndex === index;

        return (
          <MenuContext.Provider
            value={{
              menuType,
              handleKeyDown: (ev) => handleKeyDown(ev, index),
              isFocused,
            }}
          >
            {child}
          </MenuContext.Provider>
        );
      })}
    </StyledMenuWrapper>
  );
};

Menu.propTypes = {
  /** Styled system flex props */
  ...propTypes.flexbox,
  /** Styled system layout props */
  ...propTypes.layout,
  /** Defines the color scheme of the component */
  menuType: PropTypes.oneOf(["light", "dark"]),
  /** Children elements */
  children: PropTypes.node.isRequired,
};

export { MenuContext };
export default Menu;
<commit_msg>fix(menu): add aria-role to fix accessibility violations<commit_after>import React, { useEffect, useState, useCallback, useRef } from "react";
import PropTypes from "prop-types";
import propTypes from "@styled-system/prop-types";

import { StyledMenuWrapper } from "./menu.style";
import { menuKeyboardNavigation } from "./__internal__/keyboard-navigation";
import Events from "../../utils/helpers/events";
import MenuContext from "./menu.context";

const Menu = ({ menuType = "light", children, ...rest }) => {
  const [focusedItemIndex, setFocusedItemIndex] = useState(undefined);
  const ref = useRef();

  const handleKeyDown = useCallback(
    (event) => {
      const newIndex = menuKeyboardNavigation(
        event,
        React.Children.toArray(children)
      );

      setFocusedItemIndex(newIndex);
    },
    [children]
  );

  const onClickOutside = useCallback((event) => {
    // Reset the state of the menu when clicking elsewhere
    if (!Events.composedPath(event).includes(ref.current)) {
      setFocusedItemIndex(undefined);
      document.removeEventListener("click", onClickOutside);
    }
  }, []);

  useEffect(() => {
    document.addEventListener("click", onClickOutside);

    return function cleanup() {
      document.removeEventListener("click", onClickOutside);
    };
  });

  return (
    <StyledMenuWrapper
      data-component="menu"
      role="menubar"
      menuType={menuType}
      {...rest}
      ref={ref}
    >
      {React.Children.map(children, (child, index) => {
        const isFocused = focusedItemIndex === index;

        return (
          <MenuContext.Provider
            value={{
              menuType,
              handleKeyDown: (ev) => handleKeyDown(ev, index),
              isFocused,
            }}
          >
            {child}
          </MenuContext.Provider>
        );
      })}
    </StyledMenuWrapper>
  );
};

Menu.propTypes = {
  /** Styled system flex props */
  ...propTypes.flexbox,
  /** Styled system layout props */
  ...propTypes.layout,
  /** Defines the color scheme of the component */
  menuType: PropTypes.oneOf(["light", "dark"]),
  /** Children elements */
  children: PropTypes.node.isRequired,
};

export { MenuContext };
export default Menu;
<|endoftext|>