<commit_before>/**
 * Yii GridView widget.
 *
 * This is the JavaScript widget used by the yii\grid\GridView widget.
 *
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
(function ($) {
    $.fn.yiiGridView = function (method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.yiiGridView');
            return false;
        }
    };

    var defaults = {
        filterUrl: undefined,
        filterSelector: undefined
    };

    var gridData = {};

    var gridEvents = {
        /**
         * beforeFilter event is triggered before filtering the grid.
         * The signature of the event handler should be:
         *     function (event)
         * where
         *  - event: an Event object.
         *
         * If the handler returns a boolean false, it will stop filter form submission after this event. And as
         * a result, afterFilter event will not be triggered.
         */
        beforeFilter: 'beforeFilter.yiiGridView',
        /**
         * afterFilter event is triggered after filtering the grid and filtered results are fetched.
         * The signature of the event handler should be:
         *     function (event)
         * where
         *  - event: an Event object.
         */
        afterFilter: 'afterFilter.yiiGridView'
    };

    var methods = {
        init: function (options) {
            return this.each(function () {
                var $e = $(this);
                var settings = $.extend({}, defaults, options || {});
                gridData[$e.prop('id')] = {settings: settings};

                var enterPressed = false;
                $(document).off('change.yiiGridView keydown.yiiGridView', settings.filterSelector)
                    .on('change.yiiGridView keydown.yiiGridView', settings.filterSelector, function (event) {
                        if (event.type === 'keydown') {
                            if (event.keyCode !== 13) {
                                return; // only react to enter key
                            } else {
                                enterPressed = true;
                            }
                        } else {
                            // prevent processing for both keydown and change events
                            if (enterPressed) {
                                enterPressed = false;
                                return;
                            }
                        }

                        methods.applyFilter.apply($e);

                        return false;
                    });
            });
        },

        applyFilter: function () {
            var $grid = $(this), event;
            var settings = gridData[$grid.prop('id')].settings;
            var data = {};
            $.each($(settings.filterSelector).serializeArray(), function () {
                data[this.name] = this.value;
            });

            $.each(yii.getQueryParams(settings.filterUrl), function (name, value) {
                if (data[name] === undefined) {
                    data[name] = value;
                }
            });

            var pos = settings.filterUrl.indexOf('?');
            var url = pos < 0 ? settings.filterUrl : settings.filterUrl.substring(0, pos);

            $grid.find('form.gridview-filter-form').remove();
            var $form = $('<form action="' + url + '" method="get" class="gridview-filter-form" style="display:none" data-pjax></form>').appendTo($grid);
            $.each(data, function (name, value) {
                $form.append($('<input type="hidden" name="t" value="" />').attr('name', name).val(value));
            });

            // triggers `beforeFilter` grid event with the filter form as a parameter
            event = $.Event(gridEvents.beforeFilter);
            $grid.trigger(event);
            if (event.result === false) {
                return;
            }

            $form.submit();

            // triggers `afterFilter` grid event with the filter form as a parameter
            $grid.trigger(gridEvents.afterFilter);
        },

        setSelectionColumn: function (options) {
            var $grid = $(this);
            var id = $(this).prop('id');
            gridData[id].selectionColumn = options.name;
            if (!options.multiple) {
                return;
            }
            var inputs = "#" + id + " input[name='" + options.checkAll + "']";
            $(document).off('click.yiiGridView', inputs).on('click.yiiGridView', inputs, function () {
                $grid.find("input[name='" + options.name + "']:enabled").prop('checked', this.checked);
            });
            $(document).off('click.yiiGridView', inputs + ":enabled").on('click.yiiGridView', inputs + ":enabled", function () {
                var all = $grid.find("input[name='" + options.name + "']").length == $grid.find("input[name='" + options.name + "']:checked").length;
                $grid.find("input[name='" + options.checkAll + "']").prop('checked', all);
            });
        },

        getSelectedRows: function () {
            var $grid = $(this);
            var data = gridData[$grid.prop('id')];
            var keys = [];
            if (data.selectionColumn) {
                $grid.find("input[name='" + data.selectionColumn + "']:checked").each(function () {
                    keys.push($(this).parent().closest('tr').data('key'));
                });
            }
            return keys;
        },

        destroy: function () {
            return this.each(function () {
                $(window).unbind('.yiiGridView');
                $(this).removeData('yiiGridView');
            });
        },

        data: function () {
            var id = $(this).prop('id');
            return gridData[id];
        }
    };
})(window.jQuery);
<commit_msg>Updated formatting - Created beforeFilter and afterFilter grid events<commit_after>/**
 * Yii GridView widget.
 *
 * This is the JavaScript widget used by the yii\grid\GridView widget.
 *
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
(function ($) {
    $.fn.yiiGridView = function (method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.yiiGridView');
            return false;
        }
    };

    var defaults = {
        filterUrl: undefined,
        filterSelector: undefined
    };

    var gridData = {};

    var gridEvents = {
        /**
         * beforeFilter event is triggered before filtering the grid.
         * The signature of the event handler should be:
         *     function (event)
         * where
         *  - event: an Event object.
         *
         * If the handler returns a boolean false, it will stop filter form submission after this event. And as
         * a result, afterFilter event will not be triggered.
         */
        beforeFilter: 'beforeFilter.yiiGridView',
        /**
         * afterFilter event is triggered after filtering the grid and filtered results are fetched.
         * The signature of the event handler should be:
         *     function (event)
         * where
         *  - event: an Event object.
         */
        afterFilter: 'afterFilter.yiiGridView'
    };

    var methods = {
        init: function (options) {
            return this.each(function () {
                var $e = $(this);
                var settings = $.extend({}, defaults, options || {});
                gridData[$e.prop('id')] = {settings: settings};

                var enterPressed = false;
                $(document).off('change.yiiGridView keydown.yiiGridView', settings.filterSelector)
                    .on('change.yiiGridView keydown.yiiGridView', settings.filterSelector, function (event) {
                        if (event.type === 'keydown') {
                            if (event.keyCode !== 13) {
                                return; // only react to enter key
                            } else {
                                enterPressed = true;
                            }
                        } else {
                            // prevent processing for both keydown and change events
                            if (enterPressed) {
                                enterPressed = false;
                                return;
                            }
                        }

                        methods.applyFilter.apply($e);

                        return false;
                    });
            });
        },

        applyFilter: function () {
            var $grid = $(this), event;
            var settings = gridData[$grid.prop('id')].settings;
            var data = {};
            $.each($(settings.filterSelector).serializeArray(), function () {
                data[this.name] = this.value;
            });

            $.each(yii.getQueryParams(settings.filterUrl), function (name, value) {
                if (data[name] === undefined) {
                    data[name] = value;
                }
            });

            var pos = settings.filterUrl.indexOf('?');
            var url = pos < 0 ? settings.filterUrl : settings.filterUrl.substring(0, pos);

            $grid.find('form.gridview-filter-form').remove();
            var $form = $('<form action="' + url + '" method="get" class="gridview-filter-form" style="display:none" data-pjax></form>').appendTo($grid);
            $.each(data, function (name, value) {
                $form.append($('<input type="hidden" name="t" value="" />').attr('name', name).val(value));
            });

            // triggers `beforeFilter` grid event with the filter form as a parameter
            event = $.Event(gridEvents.beforeFilter);
            $grid.trigger(event);
            if (event.result === false) {
                return;
            }

            $form.submit();

            // triggers `afterFilter` grid event with the filter form as a parameter
            $grid.trigger(gridEvents.afterFilter);
        },

        setSelectionColumn: function (options) {
            var $grid = $(this);
            var id = $(this).prop('id');
            gridData[id].selectionColumn = options.name;
            if (!options.multiple) {
                return;
            }
            var inputs = "#" + id + " input[name='" + options.checkAll + "']";
            $(document).off('click.yiiGridView', inputs).on('click.yiiGridView', inputs, function () {
                $grid.find("input[name='" + options.name + "']:enabled").prop('checked', this.checked);
            });
            $(document).off('click.yiiGridView', inputs + ":enabled").on('click.yiiGridView', inputs + ":enabled", function () {
                var all = $grid.find("input[name='" + options.name + "']").length == $grid.find("input[name='" + options.name + "']:checked").length;
                $grid.find("input[name='" + options.checkAll + "']").prop('checked', all);
            });
        },

        getSelectedRows: function () {
            var $grid = $(this);
            var data = gridData[$grid.prop('id')];
            var keys = [];
            if (data.selectionColumn) {
                $grid.find("input[name='" + data.selectionColumn + "']:checked").each(function () {
                    keys.push($(this).parent().closest('tr').data('key'));
                });
            }
            return keys;
        },

        destroy: function () {
            return this.each(function () {
                $(window).unbind('.yiiGridView');
                $(this).removeData('yiiGridView');
            });
        },

        data: function () {
            var id = $(this).prop('id');
            return gridData[id];
        }
    };
})(window.jQuery);
<|endoftext|>


<commit_before>import moment from 'moment'
import Immutable from 'immutable'
import { ADD_REPO, FETCHING_HOSTED_REPOS, EDIT_REPO, EXIT_EDIT_REPO, RECEIVED_HOSTED_REPOS, SET_REPO } from '../actions/repo'

const Repo = Immutable.Record({
    id: null,
    isDeploying: false,
    lastCommit: null,
    lastCommitDate: null,
    url: null
})

const repoReducer = (state, action) => {
    if (typeof state === 'undefined') {
        return Immutable.Map({
            hosted: Immutable.Map({
                isFetching: false,
                bitbucket: Immutable.List()
            }),
            isEditing: false,
            object: undefined
        })
    }

    switch ( action.type ) {

        case ADD_REPO:
            return state.set('object', new Repo())

        case EDIT_REPO:
            return state.set('isEditing', true)

        case EXIT_EDIT_REPO:
            return state.set('isEditing', false)

        case FETCHING_HOSTED_REPOS:
            var hosted = state.get('hosted').set('isFetching', true)
            return state.set('hosted', hosted)

        case 'RECEIVED_ADDONS':
            if (typeof action.items.repo === 'undefined') {
                return state
            }

            var addon = action.items.repo
            var attrs = {
                kind: addon.kind,
                url: addon.data.url
            }

            if (typeof addon.data.is_deploying !== 'undefined') {
                attrs.isDeploying = addon.data.is_deploying
            }

            if (typeof addon.data.last_commit !== 'undefined') {
                attrs.lastCommit = addon.data.last_commit
                attrs.lastCommitDate = moment.utc(addon.data.last_commit_date)
            }

            return state.set('object', new Repo(attrs))
            break;

        case RECEIVED_HOSTED_REPOS:
            var hosted = state.get('hosted')
            var bitbucket = hosted.get('bitbucket').withMutations(list => {
                action.repos.bitbucket.map(repo => {
                    list.push(repo)
                })
            })

            hosted = hosted.set('isFetching', false)
            hosted = hosted.set('bitbucket', bitbucket)

            return state.set('hosted', hosted)

        case SET_REPO:
            debugger
            var object = state.get('object')
            object = object.set('id', action.id)
            object = object.set('url', action.repo)
            return state.set('object', object)

        default:
            return state

    }
}

export default repoReducer<commit_msg>remove debugger<commit_after>import moment from 'moment'
import Immutable from 'immutable'
import { ADD_REPO, FETCHING_HOSTED_REPOS, EDIT_REPO, EXIT_EDIT_REPO, RECEIVED_HOSTED_REPOS, SET_REPO } from '../actions/repo'

const Repo = Immutable.Record({
    id: null,
    isDeploying: false,
    lastCommit: null,
    lastCommitDate: null,
    url: null
})

const repoReducer = (state, action) => {
    if (typeof state === 'undefined') {
        return Immutable.Map({
            hosted: Immutable.Map({
                isFetching: false,
                bitbucket: Immutable.List()
            }),
            isEditing: false,
            object: undefined
        })
    }

    switch ( action.type ) {

        case ADD_REPO:
            return state.set('object', new Repo())

        case EDIT_REPO:
            return state.set('isEditing', true)

        case EXIT_EDIT_REPO:
            return state.set('isEditing', false)

        case FETCHING_HOSTED_REPOS:
            var hosted = state.get('hosted').set('isFetching', true)
            return state.set('hosted', hosted)

        case 'RECEIVED_ADDONS':
            if (typeof action.items.repo === 'undefined') {
                return state
            }

            var addon = action.items.repo
            var attrs = {
                kind: addon.kind,
                url: addon.data.url
            }

            if (typeof addon.data.is_deploying !== 'undefined') {
                attrs.isDeploying = addon.data.is_deploying
            }

            if (typeof addon.data.last_commit !== 'undefined') {
                attrs.lastCommit = addon.data.last_commit
                attrs.lastCommitDate = moment.utc(addon.data.last_commit_date)
            }

            return state.set('object', new Repo(attrs))
            break;

        case RECEIVED_HOSTED_REPOS:
            var hosted = state.get('hosted')
            var bitbucket = hosted.get('bitbucket').withMutations(list => {
                action.repos.bitbucket.map(repo => {
                    list.push(repo)
                })
            })

            hosted = hosted.set('isFetching', false)
            hosted = hosted.set('bitbucket', bitbucket)

            return state.set('hosted', hosted)

        case SET_REPO:
            var object = state.get('object')
            object = object.set('id', action.id)
            object = object.set('url', action.repo)
            return state.set('object', object)

        default:
            return state

    }
}

export default repoReducer<|endoftext|>


<commit_before>// @flow weak
import React, { Component } from 'react';
import { FormattedMessage } from 'react-intl';
import _ from 'lodash';
import classnames from 'classnames';
import CallToolDrillDown from './CallToolDrillDown';
import FieldShape from '../../components/FieldShape/FieldShape';
import type { Choice } from '../../components/FieldShape/FieldShape';
import type {
  Country,
  CountryPhoneCode,
  Target,
  FormType,
  Errors,
} from '../../call_tool/CallToolView';
import type { Field } from '../../components/FieldShape/FieldShape';

type OwnProps = {
  allowManualTargetSelection: boolean,
  restrictToSingleCountry: boolean,
  countries: Country[],
  targets: Target[],
  countriesPhoneCodes: CountryPhoneCode[],
  selectedTarget: Target,
  form: FormType,
  errors: Errors,
  onCountryCodeChange: string => void,
  onMemberPhoneNumberChange: string => void,
  onMemberPhoneCountryCodeChange: string => void,
  onTargetSelected: (id: string) => void,
  onSubmit: any => void,
  targetByAttributes: string[],
  loading: boolean,
};

const memberPhoneNumberField: Field = {
  data_type: 'phone',
  name: 'call_tool[member_phone_number]',
  label: <FormattedMessage id="call_tool.form.phone_number" />,
  default_value: '',
  required: true,
  disabled: false,
};

const memberPhoneCountryCodeField: Field = {
  data_type: 'phone',
  name: 'call_tool[member_phone_number]',
  label: <FormattedMessage id="call_tool.form.phone_country_code" />,
  default_value: '',
  required: true,
  disabled: false,
};

const countryCodeField: Field = {
  data_type: 'select',
  name: 'call_tool[country_code]',
  label: <FormattedMessage id="call_tool.form.country" />,
  default_value: null,
  required: true,
  disabled: false,
  choices: [],
};

const targetField: Field = {
  data_type: 'select',
  name: 'call_tool[target]',
  label: <FormattedMessage id="call_tool.manual_target_selection" />,
  default_value: null,
  required: true,
  disabled: false,
  choices: [],
};

class Form extends Component {
  props: OwnProps;
  state: {
    filters: { [string]: string },
  };

  fields: { [key: string]: Field };

  constructor(props: OwnProps) {
    super(props);

    // FIXME: Use this.state for all these
    // that way this.setState(...) updates these and triggers a re-render
    this.fields = {
      memberPhoneNumberField: memberPhoneNumberField,
      memberPhoneCountryCodeField: memberPhoneCountryCodeField,
      countryCodeField: {
        ...countryCodeField,
        choices: this.countryCodeOptions(),
      },
    };

    this.state = {
      filters: {},
    };
  }

  countryCodeOptions() {
    return this.props.countries.map(country => {
      return { id: country.code, value: country.code, label: country.name };
    });
  }

  targetFields() {
    return {
      ...targetField,
      choices: this.targetOptions(),
    };
  }

  targetOptions(): Choice[] {
    return this.filteredTargets(this.state.filters).map((target: Target) => ({
      id: `target-${target.id}`,
      value: target.id,
      label: (

            {target.postalCode && ({target.postalCode})}
            {' - '}
            {target.name}
            {' '}
            {target.title}

      ),
    }));
  }

  phoneNumberCountryName() {
    const strippedCountryCode = this.props.form.memberPhoneCountryCode.replace(
      '+',
      ''
    );
    const countryPhoneCode = _.find(
      this.props.countriesPhoneCodes,
      countryCode => {
        return countryCode.code === strippedCountryCode;
      }
    );

    return countryPhoneCode ? countryPhoneCode.name : '';
  }

  updateFilters = (filters: { [string]: string }) => {
    this.setState(
      prevState => ({ ...prevState, filters }),
      () => {
        // TODO:
        // reset selected target if selectedTarget is not in this.filteredTargets
      }
    );
  };

  targetsWithFields() {
    return this.props.targets.map(t => ({
      ..._.omit(t, 'fields'),
      ..._.get(t, 'fields', {}),
    }));
  }

  filteredTargets(filters: { [string]: string }): Target[] {
    const targets = this.targetsWithFields();
    if (!Object.keys(filters).length) return targets;
    return targets.filter((target: Target) => {
      return _.isMatch(target, filters);
    });
  }

  render() {
    const formClassNames = classnames({
      'action-form': true,
      'form--big': true,
      'single-country': this.props.restrictToSingleCountry,
    });
    return (
      <form className={formClassNames} data-remote="true">
        {!this.props.restrictToSingleCountry &&
          <FieldShape
            key="memberPhoneCountryCode"
            errorMessage={this.props.errors.memberPhoneCountryCode}
            onChange={this.props.onMemberPhoneCountryCodeChange}
            value={this.props.form.memberPhoneCountryCode}
            field={this.fields.memberPhoneCountryCodeField}
            className="phoneCountryCodeField"
          />}

        <FieldShape
          key="memberPhoneNumber"
          errorMessage={this.props.errors.memberPhoneNumber}
          onChange={this.props.onMemberPhoneNumberChange}
          value={this.props.form.memberPhoneNumber}
          field={this.fields.memberPhoneNumberField}
          className="phoneNumberField"
        />

        {!this.props.restrictToSingleCountry &&

              {this.phoneNumberCountryName()}

}

        {this.props.allowManualTargetSelection &&
          <CallToolDrillDown
            targetByAttributes={_.compact(this.props.targetByAttributes)}
            filters={this.state.filters}
            targets={this.targetsWithFields()}
            onUpdate={this.updateFilters}
          />}
        {this.props.allowManualTargetSelection &&
          this.props.selectedTarget &&
          <FieldShape
            key="selectedTarget"
            onChange={this.props.onTargetSelected}
            value={this.props.selectedTarget.id}
            field={this.targetFields()}
          />}

        {!_.isEmpty(this.props.selectedTarget) &&
          <SelectedTarget {...this.props.selectedTarget} />}

        <button
          type="submit"
          onClick={this.props.onSubmit}
          className="button action-form__submit-button"
          disabled={this.props.loading ? 'disabled' : ''}
        >
          <FormattedMessage id="call_tool.form.submit" />
        </button>
      </form>
    );
  }
}

function SelectedTarget(props: { name: string, title?: string }) {
  return (

          <FormattedMessage id="call_tool.you_will_be_calling" />

            {props.name}

          {props.title && , {props.title} }

  );
}

export default Form;
<commit_msg>fix formatting of targets in call tool dropdown<commit_after>// @flow weak
import React, { Component } from 'react';
import { FormattedMessage } from 'react-intl';
import _ from 'lodash';
import classnames from 'classnames';
import CallToolDrillDown from './CallToolDrillDown';
import FieldShape from '../../components/FieldShape/FieldShape';
import type { Choice } from '../../components/FieldShape/FieldShape';
import type {
  Country,
  CountryPhoneCode,
  Target,
  FormType,
  Errors,
} from '../../call_tool/CallToolView';
import type { Field } from '../../components/FieldShape/FieldShape';

type OwnProps = {
  allowManualTargetSelection: boolean,
  restrictToSingleCountry: boolean,
  countries: Country[],
  targets: Target[],
  countriesPhoneCodes: CountryPhoneCode[],
  selectedTarget: Target,
  form: FormType,
  errors: Errors,
  onCountryCodeChange: string => void,
  onMemberPhoneNumberChange: string => void,
  onMemberPhoneCountryCodeChange: string => void,
  onTargetSelected: (id: string) => void,
  onSubmit: any => void,
  targetByAttributes: string[],
  loading: boolean,
};

const memberPhoneNumberField: Field = {
  data_type: 'phone',
  name: 'call_tool[member_phone_number]',
  label: <FormattedMessage id="call_tool.form.phone_number" />,
  default_value: '',
  required: true,
  disabled: false,
};

const memberPhoneCountryCodeField: Field = {
  data_type: 'phone',
  name: 'call_tool[member_phone_number]',
  label: <FormattedMessage id="call_tool.form.phone_country_code" />,
  default_value: '',
  required: true,
  disabled: false,
};

const countryCodeField: Field = {
  data_type: 'select',
  name: 'call_tool[country_code]',
  label: <FormattedMessage id="call_tool.form.country" />,
  default_value: null,
  required: true,
  disabled: false,
  choices: [],
};

const targetField: Field = {
  data_type: 'select',
  name: 'call_tool[target]',
  label: <FormattedMessage id="call_tool.manual_target_selection" />,
  default_value: null,
  required: true,
  disabled: false,
  choices: [],
};

class Form extends Component {
  props: OwnProps;
  state: {
    filters: { [string]: string },
  };

  fields: { [key: string]: Field };

  constructor(props: OwnProps) {
    super(props);

    // FIXME: Use this.state for all these
    // that way this.setState(...) updates these and triggers a re-render
    this.fields = {
      memberPhoneNumberField: memberPhoneNumberField,
      memberPhoneCountryCodeField: memberPhoneCountryCodeField,
      countryCodeField: {
        ...countryCodeField,
        choices: this.countryCodeOptions(),
      },
    };

    this.state = {
      filters: {},
    };
  }

  countryCodeOptions() {
    return this.props.countries.map(country => {
      return { id: country.code, value: country.code, label: country.name };
    });
  }

  targetFields() {
    return {
      ...targetField,
      choices: this.targetOptions(),
    };
  }

  targetOptions(): Choice[] {
    return this.filteredTargets(this.state.filters).map((target: Target) => ({
      id: `target-${target.id}`,
      value: target.id,
      label: `${target.name}, ${target.title}`,
    }));
  }

  phoneNumberCountryName() {
    const strippedCountryCode = this.props.form.memberPhoneCountryCode.replace(
      '+',
      ''
    );
    const countryPhoneCode = _.find(
      this.props.countriesPhoneCodes,
      countryCode => {
        return countryCode.code === strippedCountryCode;
      }
    );

    return countryPhoneCode ? countryPhoneCode.name : '';
  }

  updateFilters = (filters: { [string]: string }) => {
    this.setState(
      prevState => ({ ...prevState, filters }),
      () => {
        // TODO:
        // reset selected target if selectedTarget is not in this.filteredTargets
      }
    );
  };

  targetsWithFields() {
    return this.props.targets.map(t => ({
      ..._.omit(t, 'fields'),
      ..._.get(t, 'fields', {}),
    }));
  }

  filteredTargets(filters: { [string]: string }): Target[] {
    const targets = this.targetsWithFields();
    if (!Object.keys(filters).length) return targets;
    return targets.filter((target: Target) => {
      return _.isMatch(target, filters);
    });
  }

  render() {
    const formClassNames = classnames({
      'action-form': true,
      'form--big': true,
      'single-country': this.props.restrictToSingleCountry,
    });
    return (
      <form className={formClassNames} data-remote="true">
        {!this.props.restrictToSingleCountry &&
          <FieldShape
            key="memberPhoneCountryCode"
            errorMessage={this.props.errors.memberPhoneCountryCode}
            onChange={this.props.onMemberPhoneCountryCodeChange}
            value={this.props.form.memberPhoneCountryCode}
            field={this.fields.memberPhoneCountryCodeField}
            className="phoneCountryCodeField"
          />}

        <FieldShape
          key="memberPhoneNumber"
          errorMessage={this.props.errors.memberPhoneNumber}
          onChange={this.props.onMemberPhoneNumberChange}
          value={this.props.form.memberPhoneNumber}
          field={this.fields.memberPhoneNumberField}
          className="phoneNumberField"
        />

        {!this.props.restrictToSingleCountry &&

              {this.phoneNumberCountryName()}

}

        {this.props.allowManualTargetSelection &&
          <CallToolDrillDown
            targetByAttributes={_.compact(this.props.targetByAttributes)}
            filters={this.state.filters}
            targets={this.targetsWithFields()}
            onUpdate={this.updateFilters}
          />}
        {this.props.allowManualTargetSelection &&
          this.props.selectedTarget &&
          <FieldShape
            key="selectedTarget"
            onChange={this.props.onTargetSelected}
            value={this.props.selectedTarget.id}
            field={this.targetFields()}
          />}

        {!_.isEmpty(this.props.selectedTarget) &&
          <SelectedTarget {...this.props.selectedTarget} />}

        <button
          type="submit"
          onClick={this.props.onSubmit}
          className="button action-form__submit-button"
          disabled={this.props.loading ? 'disabled' : ''}
        >
          <FormattedMessage id="call_tool.form.submit" />
        </button>
      </form>
    );
  }
}

function SelectedTarget(props: { name: string, title?: string }) {
  return (

          <FormattedMessage id="call_tool.you_will_be_calling" />

            {props.name}

          {props.title && , {props.title} }

  );
}

export default Form;
<|endoftext|>


<commit_before>var async               = require("async"),
    wifi_manager        = require("./helper/wifi_manager")(),
    dependency_manager  = require("./helper/dependency_manager")(),

    logger              = require("./helper/logger")(),

    express             = require('express'),
    app                 = express(),
    morgan              = require('morgan'),
    bodyParser          = require('body-parser'),
    methodOverride      = require('method-override'),

    config              = require("./config.json");

(function () {
    'use strict';

    angular
        .module('DeezerKids')
        .controller('StartupController', StartupController);

    StartupController.$inject = ['$http', '$rootScope', '$location'];

    function StartupController($http, $rootScope, $location) {

        // Declarations
        var vm = this;

        (function initController() {
            async.waterfall([
                /////////////////////////////////////////////////////////////////////
                // STEP 1: Check if we have the required dependencies installed
                /////////////////////////////////////////////////////////////////////
                function test_deps(next_step) {
                    logger.info("checking required dependencies installed");
                    dependency_manager.check_deps({
                        "binaries": ["dhcpd", "hostapd", "iw"],
                        "files":    ["/etc/init.d/isc-dhcp-server"]
                    }, function(error) {
                        if (error) {
                            logger.error("dependency error, did you run `sudo npm run-script provision`?");
                            //next_step(error, null);
                        } else {
                            logger.success("dependencies successfully installed");
                            //next_step(null, true);
                        }
                    });
                },

                /////////////////////////////////////////////////////////////////////
                // STEP 2: Check if wifi is enabled / connected
                /////////////////////////////////////////////////////////////////////
                function test_is_wifi_enabled(result, next_step) {
                    // Prüfung nur durchlaufen, wenn vorherige Prüfung erfolgreich war
                    if (!result) next_step(null, false);

                    logger.info("checking wifi connection on WLAN0");
                    wifi_manager.is_wifi_enabled(function(error, result_ip) {
                        if (result_ip) {
                            logger.success("Wifi is enabled, and IP " + result_ip + " assigned");
                            next_step(null, true);
                        } else {
                            logger.error("Wifi is not enabled, enabling setup-mode");
                            next_step(null, false);
                        }
                        next_step(error, null);
                    });
                },

                /////////////////////////////////////////////////////////////////////
                // STEP 3: Check if device-ID already set
                /////////////////////////////////////////////////////////////////////
                function test_deviceID(result, next_step) {
                    // Prüfung nur durchlaufen, wenn vorherige Prüfung erfolgreich war
                    if (!result) next_step(null, false);

                    logger.info("checking device-ID");

                    /*if (config.device.ID) {
                        next_step(null, true);
                    } else {
                        next_step(null, false);
                    }*/
                },

                /////////////////////////////////////////////////////////////////////
                // STEP 4: Validate AccessToken
                /////////////////////////////////////////////////////////////////////
                function test_accesstoken(result, next_step) {
                    // Prüfung nur durchlaufen, wenn vorherige Prüfung erfolgreich war
                    if (!result) next_step(null, false);

                    logger.info("checking access-token");
                    next_step(null, true);
                },

                /////////////////////////////////////////////////////////////////////
                // STEP 5: Validate Playlist
                /////////////////////////////////////////////////////////////////////
                function test_playlist(result, next_step) {
                    // Prüfung nur durchlaufen, wenn vorherige Prüfung erfolgreich war
                    if (!result) next_step(null, false);

                    logger.info("checking playlist");
                    next_step(null, true);
                },

         ], function(error, result) {
                if (error) {
                    logger.error(error);
                } else {
                    /*logger.info("starting webserver for user-interfaces");
                    app.use(express.static(__dirname + '/public'));                 // set the static files location /public/img will be /img for users
                    app.use(morgan('dev'));                                         // log every request to the console
                    app.use(bodyParser.urlencoded({'extended':'true'}));            // parse application/x-www-form-urlencoded
                    app.use(bodyParser.json());                                     // parse application/json
                    app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
                    app.use(methodOverride());

                    // application -------------------------------------------------------------
                    app.get('*', function(req, res) {
                        res.sendfile('../../../pu/index.html'); // load the single view file (angular will handle the page changes on the front-end)
                    });

                    // listen (start app with node server.js) ======================================
                    app.listen(config.server.port);
                    logger.success("listening on port " + config.server.port);*/

                    if (result) {
                        vm.mode = 'player';
                    } else {
                        vm.mode = 'setup';
                    }

                    logger.info('Starte im Modus:' + vm.mode);
                }
            });
        })();
    }
})();
<commit_msg>Update controller.js<commit_after>var wifi_manager        = require("./helper/wifi_manager")(),
    dependency_manager  = require("./helper/dependency_manager")(),
    logger              = require("./helper/logger")(),
    config              = require("./config.json");

(function () {
    'use strict';

    angular
        .module('DeezerKids')
        .controller('StartupController', StartupController);

    StartupController.$inject = ['$http', '$rootScope', '$location', '$q'];

    function StartupController($http, $rootScope, $location, $q) {

        // Declarations
        var vm = this;

        /////////////////////////////////////////////////////////////////////
        // STEP 1: Check if we have the required dependencies installed
        /////////////////////////////////////////////////////////////////////
        function test_deps() {
            return $q(function (resolve, reject) {
                logger.info("checking required dependencies installed");
                dependency_manager.check_deps({
                    "binaries": ["dhcpd", "hostapd", "iw"],
                    "files":    ["/etc/init.d/isc-dhcp-server"]
                }, function(error) {
                    if (error) {
                        logger.error("dependency error, did you run `sudo npm run-script provision`?");
                        reject(error);
                    } else {
                        logger.success("dependencies successfully installed");
                        resolve();
                    }
                });
            });
        }

        /////////////////////////////////////////////////////////////////////
        // STEP 2: Check if wifi is enabled / connected
        /////////////////////////////////////////////////////////////////////
        function test_is_wifi_enabled() {
            return $q(function (resolve, reject) {
				logger.info("checking wifi connection on WLAN0");
				wifi_manager.is_wifi_enabled(function(error, result_ip) {
					if (result_ip) {
						logger.success("Wifi is enabled, and IP " + result_ip + " assigned");
						resolve();
					} else {
						logger.error("Wifi is not enabled, enabling setup-mode");
						reject(error);
					}
				});
            });
        }

        /////////////////////////////////////////////////////////////////////
        // STEP 3: Check if device-ID already set
        /////////////////////////////////////////////////////////////////////
        function test_deviceID() {
            return $q(function (resolve, reject) {
                logger.info("checking device-ID");
                resolve();
                /*if (config.device.ID) {
                    next_step(null, true);
                } else {
                    next_step(null, false);
                }*/
            });
        }

        /////////////////////////////////////////////////////////////////////
        // STEP 4: Validate AccessToken
        /////////////////////////////////////////////////////////////////////
        function test_accesstoken() {
            return $q(function (resolve, reject) {
                logger.info("checking access-token");
                resolve();
            });
        }

        /////////////////////////////////////////////////////////////////////
        // STEP 5: Validate Playlist
        /////////////////////////////////////////////////////////////////////
        function test_playlist() {
            return $q(function (resolve, reject) {
                logger.info("checking playlist");
                resolve();
            });
        }

        function start_setup() {
            /*logger.info("starting webserver for user-interfaces");
            app.use(express.static(__dirname + '/public'));                 // set the static files location /public/img will be /img for users
            app.use(morgan('dev'));                                         // log every request to the console
            app.use(bodyParser.urlencoded({'extended':'true'}));            // parse application/x-www-form-urlencoded
            app.use(bodyParser.json());                                     // parse application/json
            app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
            app.use(methodOverride());

            // application -------------------------------------------------------------
            app.get('*', function(req, res) {
                res.sendfile('../../../pu/index.html'); // load the single view file (angular will handle the page changes on the front-end)
            });

            // listen (start app with node server.js) ======================================
            app.listen(config.server.port);
            logger.success("listening on port " + config.server.port);*/

            vm.mode = 'setup';
            logger.info('Starte im Modus:' + vm.mode);
        }

        function start_player() {
            vm.mode = 'player';
            logger.info('Starte im Modus:' + vm.mode);
        }

        test_deps()
        .then(test_is_wifi_enabled())
        .then(test_deviceID())
        .then(test_accesstoken())
        .then(test_playlist())
        .then(start_player(), start_setup());
    }
})();
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

const program = require('commander');
const pkg = require('../package.json');
const minimist = require('minimist');
const Config = require('../src/config');

function msg() {
  console.log.apply(null, arguments); // eslint-disable-line no-console,prefer-rest-params
}

function handleResult(text, code) {
  code = code || 0;

  if (text) {
    msg(text);
  }

  process.exit(code);
}

process.on('uncaughtException', (err) => {
  msg(err.message);
  if (program.verbose) {
    msg(err.stack);
  }
  process.exit(1);
});

program.version(pkg.version);
program.option('-v, --verbose', 'Be more verbose');

program
  .command('diff [left] [right]')
  .description('Diff 2 URLs')
  .option('-c, --config [config]', 'Set a custom config')
  .option('-H, --header [header]', 'Add a HTTP header to both sides')
  .option('-L, --header-left [headerLeft]', 'Add a HTTP header to left side')
  .option('-r, --rate [rateLimit]', 'Rate limit for concurrent requests')
  .option('-R, --header-right [headerRight]', 'Add a HTTP header to right side')
  .option('-t, --tag [tag]', 'Only include routes with this tag')
  .action((left, right, options) => {
    options = options || {};
    options.args = minimist(process.argv);
    const config = new Config();

    if (options.config) {
      if (left) {
        return handleResult('No arguments allowed when using "-c"!', 1);
      }
      config.parseOptions(options);
      config.load(options.config);
    } else if (!left) {
      config.parseOptions(options);
      config.load();
    } else {
      config.parseArguments(left, right, options);
    }

    handleResult(JSON.stringify(config, null, 2)); // TODO Replace with dumpinator diff
  });

program.parse(process.argv);

if (!process.argv.slice(2).length) {
  program.help();
}
<commit_msg>Better description<commit_after>#!/usr/bin/env node

'use strict';

const program = require('commander');
const pkg = require('../package.json');
const minimist = require('minimist');
const Config = require('../src/config');

function msg() {
  console.log.apply(null, arguments); // eslint-disable-line no-console,prefer-rest-params
}

function handleResult(text, code) {
  code = code || 0;

  if (text) {
    msg(text);
  }

  process.exit(code);
}

process.on('uncaughtException', (err) => {
  msg(err.message);
  if (program.verbose) {
    msg(err.stack);
  }
  process.exit(1);
});

program.version(pkg.version);
program.option('-v, --verbose', 'Be more verbose');

program
  .command('diff [left] [right]')
  .description('Diff the given routes')
  .option('-c, --config [config]', 'Set a custom config')
  .option('-H, --header [header]', 'Add a HTTP header to both sides')
  .option('-L, --header-left [headerLeft]', 'Add a HTTP header to left side')
  .option('-r, --rate [rateLimit]', 'Rate limit for concurrent requests')
  .option('-R, --header-right [headerRight]', 'Add a HTTP header to right side')
  .option('-t, --tag [tag]', 'Only include routes with this tag')
  .action((left, right, options) => {
    options = options || {};
    options.args = minimist(process.argv);
    const config = new Config();

    if (options.config) {
      if (left) {
        return handleResult('No arguments allowed when using "-c"!', 1);
      }
      config.parseOptions(options);
      config.load(options.config);
    } else if (!left) {
      config.parseOptions(options);
      config.load();
    } else {
      config.parseArguments(left, right, options);
    }

    handleResult(JSON.stringify(config, null, 2)); // TODO Replace with dumpinator diff
  });

program.parse(process.argv);

if (!process.argv.slice(2).length) {
  program.help();
}
<|endoftext|>


<commit_before>/**
 * Angular JS controllers.
 * Copyright 2013 Google Inc. All Rights Reserved
 * @author Kevin Pollet
 */
function init() {
    window.initGoogleApis();
}

appEngineTckApp.controller('HeaderCtrl', function($scope, $location) {
    $scope.bool = true;

    $scope.isActive = function(path) {
        return $location.path() === path;
    };
});

//TODO should be configured externally!
appEngineTckApp.controller('ReportsCtrl', function($scope, $window) {
    $scope.buildTypes = [
        {
            id: 'AppEngineTck_Capedwarf',
            label: 'CapeDwarf'
        },
        {
            id: 'GaeJavaSdk',
            label: 'GAE Java SDK'
        }
    ];

    $window.initGoogleApis = function() {
        gapi.client.load('reports', 'v1', function() {
            $scope.$apply(function($scope) {
                $scope.isGoogleApisLoaded = true;
            });
        }, 'https://cloud-test-compatibility-kit.appspot.com/_ah/api');
    };
});

appEngineTckApp.controller('TestReportsCtrl', function($scope) {
    $scope.selectedTestReportChart = {
        type: 'PieChart',
        displayed: true,
        cssStyle: 'height: 500px;',
        data: {
            cols: [
                {
                    id: 'type-id',
                    label: 'Type',
                    type: 'string'
                },
                {
                    id: 'number-id',
                    label: 'Number',
                    type: 'number'
                }
            ],
            rows: [
            ]
        },
        options: {
            fill: 20,
            displayExactValues: true,
            chartArea: {
                width: '90%',
                height: '90%'
            }
        },
        drillDownLevel: 0
    };

    $scope.lastTestReportsChart = {
        type: 'LineChart',
        displayed: true,
        cssStyle: 'height: 500px;',
        data: {
            cols: [
                {
                    id: 'build-id',
                    label: 'Build Id',
                    type: 'number'
                },
                {
                    id: 'passed-number-id',
                    label: 'Passed',
                    type: 'number'
                },
                {
                    id: 'failed-number-id',
                    label: 'Failed',
                    type: 'number'
                },
                {
                    id: 'ignored-number-id',
                    label: 'Ignored',
                    type: 'number'
                }
            ],
            rows: [
            ]
        },
        options: {
            fill: 20,
            hAxis: {
                title: 'Id of the build',
                viewWindowMode: 'maximized',
                gridlines: {
                    count: 5
                }
            },
            vAxis: {
                title: 'Number of tests'
            },
            pointSize: 8,
            displayExactValues: true
        }
    };

    $scope.selectedTestReportChartSelect = function(selectedItem) {
        var drillDownLevel = $scope.selectedTestReportChart.drillDownLevel;

        if (drillDownLevel === 1) {
            $scope.selectedTestReportChart.data.rows = testReportToPieChartRows($scope.selectedTestReport);
            $scope.selectedTestReportChart.drillDownLevel--;
        }
        else if (drillDownLevel === 0 && selectedItem.row === 1) {
            $scope.selectedTestReportChart.data.rows = [];
            var failedTestsByClassName = _.countBy($scope.selectedTestReport.failedTests, function(failedTest){ return failedTest.className; });

            for (className in failedTestsByClassName) {
                $scope.selectedTestReportChart.data.rows.push(
                    {
                        c: [
                            { v: className },
                            { v: failedTestsByClassName[className] }
                        ]
                    }
                );
            }

            $scope.selectedTestReportChart.drillDownLevel++;
        }
    };

    $scope.lastTestReportsChartSelect = function(selectedItem) {
        $scope.selectedTestReport = $scope.testReports[selectedItem.row];
    };

    $scope.$watch('selectedTestReport', function(newValue, oldValue) {
        if (newValue !== oldValue) {
            $scope.selectedTestReportChart.data.rows = testReportToPieChartRows(newValue);
            $scope.selectedTestReportChart.drillDownLevel = 0;
        }
    });

    $scope.$watch('testReports', function(newValues, oldValues) {
        if (newValues !== oldValues) {
            var hAxis = $scope.lastTestReportsChart.options.hAxis;
            hAxis.gridlines.count = (newValues[0].buildId - newValues[newValues.length - 1].buildId) + 1;

            for(var i = 0; i < newValues.length; i++) {
                $scope.lastTestReportsChart.data.rows.push({
                    c: [
                        { v: newValues[i].buildId },
                        { v: newValues[i].numberOfPassedTests },
                        { v: newValues[i].numberOfFailedTests },
                        { v: newValues[i].numberOfIgnoredTests }
                    ]
                });
            }
        }
    });

    $scope.init = function(buildTypeId) {
        gapi.client.reports.tests.
            list({ buildTypeId: buildTypeId, limit: 10 }).
            execute(function(resp) {
                if (angular.isArray(resp.items) && resp.items.length > 0) {
                    $scope.$apply(function($scope) {
                        $scope.testReports = resp.items;
                        $scope.selectedTestReport = resp.items[0];
                    });
                }
            });
    };

    var testReportToPieChartRows = function(report) {
        return [
            {
                c: [
                    { v: 'Passed' },
                    { v: report.numberOfPassedTests }
                ]
            },
            {
                c: [
                    { v: 'Failed' },
                    { v: report.numberOfFailedTests }
                ]
            },
            {
                c: [
                    { v: 'Ignored' },
                    { v: report.numberOfIgnoredTests }
                ]
            }
        ];
    };
});<commit_msg>Use stacked area chart instead of regular line chart<commit_after>/**
 * Angular JS controllers.
 * Copyright 2013 Google Inc. All Rights Reserved
 * @author Kevin Pollet
 */
function init() {
    window.initGoogleApis();
}

appEngineTckApp.controller('HeaderCtrl', function($scope, $location) {
    $scope.bool = true;

    $scope.isActive = function(path) {
        return $location.path() === path;
    };
});

//TODO should be configured externally!
appEngineTckApp.controller('ReportsCtrl', function($scope, $window) {
    $scope.buildTypes = [
        {
            id: 'AppEngineTck_Capedwarf',
            label: 'CapeDwarf'
        },
        {
            id: 'GaeJavaSdk',
            label: 'GAE Java SDK'
        }
    ];

    $window.initGoogleApis = function() {
        gapi.client.load('reports', 'v1', function() {
            $scope.$apply(function($scope) {
                $scope.isGoogleApisLoaded = true;
            });
        }, 'https://cloud-test-compatibility-kit.appspot.com/_ah/api');
    };
});

appEngineTckApp.controller('TestReportsCtrl', function($scope) {
    $scope.selectedTestReportChart = {
        type: 'PieChart',
        displayed: true,
        cssStyle: 'height: 500px;',
        data: {
            cols: [
                {
                    id: 'type-id',
                    label: 'Type',
                    type: 'string'
                },
                {
                    id: 'number-id',
                    label: 'Number',
                    type: 'number'
                }
            ],
            rows: [
            ]
        },
        options: {
            fill: 20,
            displayExactValues: true,
            chartArea: {
                width: '90%',
                height: '90%'
            }
        },
        drillDownLevel: 0
    };

    $scope.lastTestReportsChart = {
        type: 'AreaChart',
        displayed: true,
        cssStyle: 'height: 500px;',
        data: {
            cols: [
                {
                    id: 'build-id',
                    label: 'Build Id',
                    type: 'number'
                },
                {
                    id: 'passed-number-id',
                    label: 'Passed',
                    type: 'number'
                },
                {
                    id: 'failed-number-id',
                    label: 'Failed',
                    type: 'number'
                },
                {
                    id: 'ignored-number-id',
                    label: 'Ignored',
                    type: 'number'
                }
            ],
            rows: [
            ]
        },
        options: {
            fill: 20,
            hAxis: {
                title: 'Id of the build',
                viewWindowMode: 'maximized',
                gridlines: {
                    count: 5
                }
            },
            vAxis: {
                title: 'Number of tests'
            },
            pointSize: 8,
            displayExactValues: true,
            isStacked: true
        }
    };

    $scope.selectedTestReportChartSelect = function(selectedItem) {
        var drillDownLevel = $scope.selectedTestReportChart.drillDownLevel;

        if (drillDownLevel === 1) {
            $scope.selectedTestReportChart.data.rows = testReportToPieChartRows($scope.selectedTestReport);
            $scope.selectedTestReportChart.drillDownLevel--;
        }
        else if (drillDownLevel === 0 && selectedItem.row === 1) {
            $scope.selectedTestReportChart.data.rows = [];
            var failedTestsByClassName = _.countBy($scope.selectedTestReport.failedTests, function(failedTest){ return failedTest.className; });

            for (className in failedTestsByClassName) {
                $scope.selectedTestReportChart.data.rows.push(
                    {
                        c: [
                            { v: className },
                            { v: failedTestsByClassName[className] }
                        ]
                    }
                );
            }

            $scope.selectedTestReportChart.drillDownLevel++;
        }
    };

    $scope.lastTestReportsChartSelect = function(selectedItem) {
        $scope.selectedTestReport = $scope.testReports[selectedItem.row];
    };

    $scope.$watch('selectedTestReport', function(newValue, oldValue) {
        if (newValue !== oldValue) {
            $scope.selectedTestReportChart.data.rows = testReportToPieChartRows(newValue);
            $scope.selectedTestReportChart.drillDownLevel = 0;
        }
    });

    $scope.$watch('testReports', function(newValues, oldValues) {
        if (newValues !== oldValues) {
            var hAxis = $scope.lastTestReportsChart.options.hAxis;
            hAxis.gridlines.count = (newValues[0].buildId - newValues[newValues.length - 1].buildId) + 1;

            for(var i = 0; i < newValues.length; i++) {
                $scope.lastTestReportsChart.data.rows.push({
                    c: [
                        { v: newValues[i].buildId },
                        { v: newValues[i].numberOfPassedTests },
                        { v: newValues[i].numberOfFailedTests },
                        { v: newValues[i].numberOfIgnoredTests }
                    ]
                });
            }
        }
    });

    $scope.init = function(buildTypeId) {
        gapi.client.reports.tests.
            list({ buildTypeId: buildTypeId, limit: 10 }).
            execute(function(resp) {
                if (angular.isArray(resp.items) && resp.items.length > 0) {
                    $scope.$apply(function($scope) {
                        $scope.testReports = resp.items;
                        $scope.selectedTestReport = resp.items[0];
                    });
                }
            });
    };

    var testReportToPieChartRows = function(report) {
        return [
            {
                c: [
                    { v: 'Passed' },
                    { v: report.numberOfPassedTests }
                ]
            },
            {
                c: [
                    { v: 'Failed' },
                    { v: report.numberOfFailedTests }
                ]
            },
            {
                c: [
                    { v: 'Ignored' },
                    { v: report.numberOfIgnoredTests }
                ]
            }
        ];
    };
});<|endoftext|>


<commit_before>import React from 'react';
import { translate } from 'react-i18next';
import { FastField, useFormikContext } from 'formik';
import { Box, Flex, Text } from 'rebass/styled-components';
import bows from 'bows';
import isEmpty from 'lodash/isEmpty';
import map from 'lodash/map';
import InputMask from 'react-input-mask';

import { fieldsAreValid, getFieldError } from '../../core/forms';
import i18next from '../../core/language';
import RadioGroup from '../../components/elements/RadioGroup';
import Checkbox from '../../components/elements/Checkbox';
import TextInput from '../../components/elements/TextInput';
import { Headline } from '../../components/elements/FontStyles';
import { sexOptions, cgmDeviceOptions, pumpDeviceOptions } from './prescriptionFormConstants';
import { formWrapperStyles, inputStyles, checkboxGroupStyles, checkboxStyles } from './prescriptionFormStyles';

const t = i18next.t.bind(i18next);
const log = bows('PrescriptionAccount');

export const PatientPhone = translate()(props => {
  const { t, meta } = props;

  const {
    setFieldValue,
    setFieldTouched,
  } = useFormikContext();

  return (
    <Box {...formWrapperStyles}>
      <Headline mb={4}>{t('What is the patient\'s phone number?')}</Headline>
      <FastField
        as={() => (
          <InputMask
            mask="(999) 999-9999"
            alwaysShowMask
            defaultValue={meta.phoneNumber.number.value}
            onBlur={e => {
              setFieldTouched('phoneNumber.number', true);
              setFieldValue('phoneNumber.number', e.target.value);
            }}
          >
            <TextInput
              name="phoneNumber.number"
              id="phoneNumber.number"
              label={t('Patient Phone Number')}
              error={getFieldError(meta.phoneNumber.number)}
              {...inputStyles}
            />
          </InputMask>
        )}
      />
      <Text fontSize={0}>
        {t('The patient\'s phone number may be used to provided direct assistance regarding their Tidepool account. Standard messaging rates may apply.')}
      </Text>
    </Box>
  );
});

export const PatientMRN = translate()(props => {
  const { t, meta } = props;

  return (
    <Box {...formWrapperStyles}>
      <Headline mb={4}>{t('What is the patient\'s Medical Record Number (MRN)?')}</Headline>
      <FastField
        as={TextInput}
        label={t('Medical Record Number')}
        id="mrn"
        name="mrn"
        error={getFieldError(meta.mrn)}
        {...inputStyles}
      />
    </Box>
  );
});

export const PatientGender = translate()(props => {
  const { t, meta } = props;

  return (
    <Box {...formWrapperStyles}>
      <Headline mb={4}>{t('What is the patient\'s gender?')}</Headline>
      <FastField
        as={RadioGroup}
        variant="verticalBordered"
        id="sex"
        name="sex"
        options={sexOptions}
        error={getFieldError(meta.sex)}
      />
    </Box>
  );
});

export const PatientDevices = translate()(props => {
  const { t, meta } = props;

  const {
    setFieldValue,
  } = useFormikContext();

  return (
    <Box {...formWrapperStyles}>
      <Headline mb={4}>{t('Does the patient have the necessary prescriptions for Tidepool Loop compatible devices?')}</Headline>
      <Flex {...checkboxGroupStyles}>
        {map(pumpDeviceOptions, device => (
          <React.Fragment key={device.value}>
            <FastField
              as={Checkbox}
              id="initialSettings.pumpType"
              name="initialSettings.pumpType"
              key={device.value}
              checked={!isEmpty(meta.initialSettings.pumpType.value)}
              label={device.label}
              onChange={e => {
                setFieldValue('initialSettings.pumpType', e.target.checked ? device.value : '')
              }}
              error={getFieldError(meta.initialSettings.pumpType)}
              {...checkboxStyles}
            />
            <Text fontSize={0} mt={1}>{device.extraInfo}</Text>
          </React.Fragment>
        ))}
      </Flex>
      <Flex {...checkboxGroupStyles}>
        {map(cgmDeviceOptions, device => (
          <React.Fragment key={device.value}>
            <FastField
              as={Checkbox}
              id="initialSettings.cgmType"
              name="initialSettings.cgmType"
              checked={!isEmpty(meta.initialSettings.cgmType.value)}
              label={device.label}
              onChange={e => {
                setFieldValue('initialSettings.cgmType', e.target.checked ? device.value : '')
              }}
              error={getFieldError(meta.initialSettings.cgmType)}
              {...checkboxStyles}
            />
            <Text fontSize={0} mt={1}>{device.extraInfo}</Text>
          </React.Fragment>
        ))}
      </Flex>
    </Box>
  );
});

const accountFormSteps = (meta) => ({
  label: t('Complete Patient Profile'),
  subSteps: [
    {
      disableComplete: !fieldsAreValid(['phoneNumber.number'], meta),
      onComplete: () => log('Patient Phone Number Complete'),
      panelContent: <PatientPhone meta={meta} />
    },
    {
      disableComplete: !fieldsAreValid(['mrn'], meta),
      onComplete: () => log('Patient MRN Complete'),
      panelContent: <PatientMRN meta={meta} />,
    },
    {
      disableComplete: !fieldsAreValid(['sex'], meta),
      onComplete: () => log('Patient Gender Complete'),
      panelContent: <PatientGender meta={meta} />,
    },
    {
      disableComplete: !fieldsAreValid(['initialSettings.pumpType', 'initialSettings.cgmType'], meta),
      onComplete: () => log('Patient Devices Complete'),
      panelContent: <PatientDevices meta={meta} />,
    },
  ],
});

export default accountFormSteps;
<commit_msg>Update app/pages/prescription/profileFormSteps.js<commit_after>import React from 'react';
import { translate } from 'react-i18next';
import { FastField, useFormikContext } from 'formik';
import { Box, Flex, Text } from 'rebass/styled-components';
import bows from 'bows';
import isEmpty from 'lodash/isEmpty';
import map from 'lodash/map';
import InputMask from 'react-input-mask';

import { fieldsAreValid, getFieldError } from '../../core/forms';
import i18next from '../../core/language';
import RadioGroup from '../../components/elements/RadioGroup';
import Checkbox from '../../components/elements/Checkbox';
import TextInput from '../../components/elements/TextInput';
import { Headline } from '../../components/elements/FontStyles';
import { sexOptions, cgmDeviceOptions, pumpDeviceOptions } from './prescriptionFormConstants';
import { formWrapperStyles, inputStyles, checkboxGroupStyles, checkboxStyles } from './prescriptionFormStyles';

const t = i18next.t.bind(i18next);
const log = bows('PrescriptionAccount');

export const PatientPhone = translate()(props => {
  const { t, meta } = props;

  const {
    setFieldValue,
    setFieldTouched,
  } = useFormikContext();

  return (
    <Box {...formWrapperStyles}>
      <Headline mb={4}>{t('What is the patient\'s phone number?')}</Headline>
      <FastField
        as={() => (
          <InputMask
            mask="(999) 999-9999"
            alwaysShowMask
            defaultValue={meta.phoneNumber.number.value}
            onBlur={e => {
              setFieldTouched('phoneNumber.number', true);
              setFieldValue('phoneNumber.number', e.target.value);
            }}
          >
            <TextInput
              name="phoneNumber.number"
              id="phoneNumber.number"
              label={t('Patient Phone Number')}
              error={getFieldError(meta.phoneNumber.number)}
              {...inputStyles}
            />
          </InputMask>
        )}
      />
      <Text fontSize={0}>
        {t('The patient\'s phone number may be used to provide direct assistance regarding their Tidepool account. Standard messaging rates may apply.')}
      </Text>
    </Box>
  );
});

export const PatientMRN = translate()(props => {
  const { t, meta } = props;

  return (
    <Box {...formWrapperStyles}>
      <Headline mb={4}>{t('What is the patient\'s Medical Record Number (MRN)?')}</Headline>
      <FastField
        as={TextInput}
        label={t('Medical Record Number')}
        id="mrn"
        name="mrn"
        error={getFieldError(meta.mrn)}
        {...inputStyles}
      />
    </Box>
  );
});

export const PatientGender = translate()(props => {
  const { t, meta } = props;

  return (
    <Box {...formWrapperStyles}>
      <Headline mb={4}>{t('What is the patient\'s gender?')}</Headline>
      <FastField
        as={RadioGroup}
        variant="verticalBordered"
        id="sex"
        name="sex"
        options={sexOptions}
        error={getFieldError(meta.sex)}
      />
    </Box>
  );
});

export const PatientDevices = translate()(props => {
  const { t, meta } = props;

  const {
    setFieldValue,
  } = useFormikContext();

  return (
    <Box {...formWrapperStyles}>
      <Headline mb={4}>{t('Does the patient have the necessary prescriptions for Tidepool Loop compatible devices?')}</Headline>
      <Flex {...checkboxGroupStyles}>
        {map(pumpDeviceOptions, device => (
          <React.Fragment key={device.value}>
            <FastField
              as={Checkbox}
              id="initialSettings.pumpType"
              name="initialSettings.pumpType"
              key={device.value}
              checked={!isEmpty(meta.initialSettings.pumpType.value)}
              label={device.label}
              onChange={e => {
                setFieldValue('initialSettings.pumpType', e.target.checked ? device.value : '')
              }}
              error={getFieldError(meta.initialSettings.pumpType)}
              {...checkboxStyles}
            />
            <Text fontSize={0} mt={1}>{device.extraInfo}</Text>
          </React.Fragment>
        ))}
      </Flex>
      <Flex {...checkboxGroupStyles}>
        {map(cgmDeviceOptions, device => (
          <React.Fragment key={device.value}>
            <FastField
              as={Checkbox}
              id="initialSettings.cgmType"
              name="initialSettings.cgmType"
              checked={!isEmpty(meta.initialSettings.cgmType.value)}
              label={device.label}
              onChange={e => {
                setFieldValue('initialSettings.cgmType', e.target.checked ? device.value : '')
              }}
              error={getFieldError(meta.initialSettings.cgmType)}
              {...checkboxStyles}
            />
            <Text fontSize={0} mt={1}>{device.extraInfo}</Text>
          </React.Fragment>
        ))}
      </Flex>
    </Box>
  );
});

const accountFormSteps = (meta) => ({
  label: t('Complete Patient Profile'),
  subSteps: [
    {
      disableComplete: !fieldsAreValid(['phoneNumber.number'], meta),
      onComplete: () => log('Patient Phone Number Complete'),
      panelContent: <PatientPhone meta={meta} />
    },
    {
      disableComplete: !fieldsAreValid(['mrn'], meta),
      onComplete: () => log('Patient MRN Complete'),
      panelContent: <PatientMRN meta={meta} />,
    },
    {
      disableComplete: !fieldsAreValid(['sex'], meta),
      onComplete: () => log('Patient Gender Complete'),
      panelContent: <PatientGender meta={meta} />,
    },
    {
      disableComplete: !fieldsAreValid(['initialSettings.pumpType', 'initialSettings.cgmType'], meta),
      onComplete: () => log('Patient Devices Complete'),
      panelContent: <PatientDevices meta={meta} />,
    },
  ],
});

export default accountFormSteps;
<|endoftext|>


<commit_before>'use strict';

angular.module('ximsApp')
  .controller('IncidentNewCtrl', ['ModuleService', 'ProjectService','$routeParams', '$scope',
    function(ModuleService, ProjectService, $routeParams, $scope) {
      ModuleService.name = ModuleService.INCIDENT;
      $scope.incident = {project: null};
      $scope.ProjectService = ProjectService;

      // datepicker
      $scope.format = 'dd-MMMM-yyyy';
      $scope.minDate = new Date();
      $scope.open = function($event, model) {
        $event.preventDefault();
        $event.stopPropagation();
        model.dateOpened = !model.dateOpened;
      };
    }])
  .controller('newProjectCtrl', ['$scope', 'ProjectService', 'PopoverService',
    function($scope, ProjectService, PopoverService) {
    $scope.save = function(event) {
      var newProject = {id: 10, name: $scope.projectName};
      ProjectService.projects.push(newProject);
      PopoverService.optionSelected = newProject;
      $scope.$parent.close(null, true);
      event.preventDefault();
    }
  }]);<commit_msg>injecting IncidentStepsService<commit_after>'use strict';

angular.module('ximsApp')
  .controller('IncidentNewCtrl', ['ModuleService', 'ProjectService', 'IncidentStepsService', '$routeParams', '$scope',
    function(ModuleService, ProjectService, IncidentStepsService, $routeParams, $scope) {
      ModuleService.name = ModuleService.INCIDENT;
      $scope.incident = {project: null};
      $scope.ProjectService = ProjectService;
      $scope.IncidentStepsService = IncidentStepsService;

      // datepicker
      $scope.format = 'dd-MMMM-yyyy';
      $scope.minDate = new Date();
      $scope.open = function($event, model) {
        $event.preventDefault();
        $event.stopPropagation();
        model.dateOpened = !model.dateOpened;
      };
    }])
  .controller('newProjectCtrl', ['$scope', 'ProjectService', 'PopoverService',
    function($scope, ProjectService, PopoverService) {
    $scope.save = function(event) {
      var newProject = {id: 10, name: $scope.projectName};
      ProjectService.projects.push(newProject);
      PopoverService.optionSelected = newProject;
      $scope.$parent.close(null, true);
      event.preventDefault();
    }
  }]);<|endoftext|>


<commit_before>(function() {
  'use strict';

  angular.module('dimApp')
    .controller('dimAppCtrl', DimApp);

  DimApp.$inject = ['ngDialog', '$rootScope', 'loadingTracker', 'dimPlatformService', '$interval', 'hotkeys', '$timeout', 'dimStoreService', 'dimXurService', 'dimSettingsService', '$window', '$scope', '$state', 'dimFeatureFlags', 'dimVendorService'];

  function DimApp(ngDialog, $rootScope, loadingTracker, dimPlatformService, $interval, hotkeys, $timeout, dimStoreService, dimXurService, dimSettingsService, $window, $scope, $state, dimFeatureFlags, dimVendorService) {
    var vm = this;

    vm.settings = dimSettingsService;
    $scope.$watch('app.settings.itemSize', function(size) {
      document.querySelector('html').style.setProperty("--item-size", size + 'px');
    });
    $scope.$watch('app.settings.charCol', function(cols) {
      document.querySelector('html').style.setProperty("--character-columns", cols);
    });

    $scope.$watch('app.settings.vaultMaxCol', function(cols) {
      document.querySelector('html').style.setProperty("--vault-max-columns", cols);
    });

    vm.featureFlags = dimFeatureFlags;
    vm.vendorService = dimVendorService;

    hotkeys.add({
      combo: ['f'],
      description: 'Start a search',
      callback: function(event) {
        $rootScope.$broadcast('dim-focus-filter-input');

        event.preventDefault();
        event.stopPropagation();
      }
    });

    hotkeys.add({
      combo: ['esc'],
      allowIn: ['INPUT', 'SELECT', 'TEXTAREA'],
      callback: function() {
        $rootScope.$broadcast('dim-escape-filter-input');
      }
    });

    hotkeys.add({
      combo: ['r'],
      description: "Refresh inventory",
      callback: function() {
        vm.refresh();
      }
    });

    hotkeys.add({
      combo: ['i'],
      description: "Toggle showing full item details",
      callback: function() {
        $rootScope.$broadcast('dim-toggle-item-details');
      }
    });

/* Add each hotkey manually until hotkeys can be translated.
    _.each(dimSettingsService.itemTags, (tag) => {
      if (tag.hotkey) {
        hotkeys.add({
          combo: [tag.hotkey],
          description: "Mark item as '" + tag.label + "'",
          callback: function() {
            $rootScope.$broadcast('dim-item-tag', { tag: tag.type });
          }
        });
      }
    });
*/
    hotkeys.add({
      combo: ['!'],
      description: "Mark item as 'Favorite'",
      callback: function() {
        $rootScope.$broadcast('dim-item-tag', { tag: 'favorite' });
      }
    });

    hotkeys.add({
      combo: ['@'],
      description: "Mark item as 'Keep'",
      callback: function() {
        $rootScope.$broadcast('dim-item-tag', { tag: 'keep' });
      }
    });

    hotkeys.add({
      combo: ['#'],
      description: "Mark item as 'Junk'",
      callback: function() {
        $rootScope.$broadcast('dim-item-tag', { tag: 'junk' });
      }
    });

    hotkeys.add({
      combo: ['$'],
      description: "Mark item as 'Infuse'",
      callback: function() {
        $rootScope.$broadcast('dim-item-tag', { tag: 'infuse' });
      }
    });

    hotkeys.add({
      combo: ['x'],
      description: "Clear new items",
      callback: function() {
        dimStoreService.clearNewItems();
      }
    });

    hotkeys.add({
      combo: ['ctrl+alt+shift+d'],
      callback: function() {
        dimFeatureFlags.debugMode = true;
        console.log("***** DIM DEBUG MODE ENABLED *****");
      }
    });

    /**
     * Show a popup dialog containing the given template. Its class
     * will be based on the name.
     */
    function showPopupFunction(name, lang) {
      var result;
      return function(e) {
        e.stopPropagation();

        lang = lang ? vm.settings.language + '/' : ''; // set language

        if (result) {
          result.close();
        } else {
          ngDialog.closeAll();
          result = ngDialog.open({
            template: 'views/' + lang + name + '.html',
            className: name,
            name: name,
            appendClassName: 'modal-dialog'
          });

          result.closePromise.then(function() {
            result = null;
          });

          // if (ga) {
            // Disable sending pageviews on popups for now, over concerns that we'll go over our free GA limits.
            // Send a virtual pageview event, even though this is a popup
            // ga('send', 'pageview', { page: '/' + name });
          // }
        }
      };
    }
    var lang = ' '; // assign a value, vm.settings.language still equals 'en' here.
    // by setting and passing lang in showPopupFunction we have a localized version of
    // the popup in the appropriate directory.
    // console.log(vm.settings.language);
    vm.showSetting = showPopupFunction('setting');
    vm.showAbout = showPopupFunction('about', lang);
    vm.showSupport = showPopupFunction('support', lang);
    vm.showFilters = showPopupFunction('filters');
    vm.showXur = showPopupFunction('xur');
    vm.showMatsExchange = showPopupFunction('mats-exchange');

    vm.toggleMinMax = function(e) {
      $state.go($state.is('best') ? 'inventory' : 'best');
    };

    vm.toggleVendors = function(e) {
      $state.go($state.is('vendors') ? 'inventory' : 'vendors');
    };

    dimXurService.updateXur();
    vm.xur = dimXurService;

    vm.refresh = function refresh() {
      loadingTracker.addPromise(dimStoreService.reloadStores());
      dimXurService.updateXur();
    };

    // Don't refresh more than once a minute
    var refresh = _.throttle(vm.refresh, 60 * 1000);

    vm.startAutoRefreshTimer = function() {
      var secondsToWait = 360;

      $rootScope.autoRefreshTimer = $interval(function() {
        // Only Refresh If We're Not Already Doing Something
        // And We're Not Inactive
        if (!loadingTracker.active() && !$rootScope.isUserInactive() && document.visibilityState === 'visible') {
          refresh();
        }
      }, secondsToWait * 1000);
    };

    vm.startAutoRefreshTimer();

    // Refresh when the user comes back to the page
    document.addEventListener("visibilitychange", function() {
      if (!loadingTracker.active() && !$rootScope.isUserInactive() && document.visibilityState === 'visible') {
        refresh();
      }
    }, false);
  }
})();
<commit_msg>remove name from template<commit_after>(function() {
  'use strict';

  angular.module('dimApp')
    .controller('dimAppCtrl', DimApp);

  DimApp.$inject = ['ngDialog', '$rootScope', 'loadingTracker', 'dimPlatformService', '$interval', 'hotkeys', '$timeout', 'dimStoreService', 'dimXurService', 'dimSettingsService', '$window', '$scope', '$state', 'dimFeatureFlags', 'dimVendorService'];

  function DimApp(ngDialog, $rootScope, loadingTracker, dimPlatformService, $interval, hotkeys, $timeout, dimStoreService, dimXurService, dimSettingsService, $window, $scope, $state, dimFeatureFlags, dimVendorService) {
    var vm = this;

    vm.settings = dimSettingsService;
    $scope.$watch('app.settings.itemSize', function(size) {
      document.querySelector('html').style.setProperty("--item-size", size + 'px');
    });
    $scope.$watch('app.settings.charCol', function(cols) {
      document.querySelector('html').style.setProperty("--character-columns", cols);
    });

    $scope.$watch('app.settings.vaultMaxCol', function(cols) {
      document.querySelector('html').style.setProperty("--vault-max-columns", cols);
    });

    vm.featureFlags = dimFeatureFlags;
    vm.vendorService = dimVendorService;

    hotkeys.add({
      combo: ['f'],
      description: 'Start a search',
      callback: function(event) {
        $rootScope.$broadcast('dim-focus-filter-input');

        event.preventDefault();
        event.stopPropagation();
      }
    });

    hotkeys.add({
      combo: ['esc'],
      allowIn: ['INPUT', 'SELECT', 'TEXTAREA'],
      callback: function() {
        $rootScope.$broadcast('dim-escape-filter-input');
      }
    });

    hotkeys.add({
      combo: ['r'],
      description: "Refresh inventory",
      callback: function() {
        vm.refresh();
      }
    });

    hotkeys.add({
      combo: ['i'],
      description: "Toggle showing full item details",
      callback: function() {
        $rootScope.$broadcast('dim-toggle-item-details');
      }
    });

/* Add each hotkey manually until hotkeys can be translated.
    _.each(dimSettingsService.itemTags, (tag) => {
      if (tag.hotkey) {
        hotkeys.add({
          combo: [tag.hotkey],
          description: "Mark item as '" + tag.label + "'",
          callback: function() {
            $rootScope.$broadcast('dim-item-tag', { tag: tag.type });
          }
        });
      }
    });
*/
    hotkeys.add({
      combo: ['!'],
      description: "Mark item as 'Favorite'",
      callback: function() {
        $rootScope.$broadcast('dim-item-tag', { tag: 'favorite' });
      }
    });

    hotkeys.add({
      combo: ['@'],
      description: "Mark item as 'Keep'",
      callback: function() {
        $rootScope.$broadcast('dim-item-tag', { tag: 'keep' });
      }
    });

    hotkeys.add({
      combo: ['#'],
      description: "Mark item as 'Junk'",
      callback: function() {
        $rootScope.$broadcast('dim-item-tag', { tag: 'junk' });
      }
    });

    hotkeys.add({
      combo: ['$'],
      description: "Mark item as 'Infuse'",
      callback: function() {
        $rootScope.$broadcast('dim-item-tag', { tag: 'infuse' });
      }
    });

    hotkeys.add({
      combo: ['x'],
      description: "Clear new items",
      callback: function() {
        dimStoreService.clearNewItems();
      }
    });

    hotkeys.add({
      combo: ['ctrl+alt+shift+d'],
      callback: function() {
        dimFeatureFlags.debugMode = true;
        console.log("***** DIM DEBUG MODE ENABLED *****");
      }
    });

    /**
     * Show a popup dialog containing the given template. Its class
     * will be based on the name.
     */
    function showPopupFunction(name, lang) {
      var result;
      return function(e) {
        e.stopPropagation();

        lang = lang ? vm.settings.language + '/' : ''; // set language

        if (result) {
          result.close();
        } else {
          ngDialog.closeAll();
          result = ngDialog.open({
            template: 'views/' + lang + name + '.html',
            className: name,
            appendClassName: 'modal-dialog'
          });

          result.closePromise.then(function() {
            result = null;
          });

          // if (ga) {
            // Disable sending pageviews on popups for now, over concerns that we'll go over our free GA limits.
            // Send a virtual pageview event, even though this is a popup
            // ga('send', 'pageview', { page: '/' + name });
          // }
        }
      };
    }
    var lang = ' '; // assign a value, vm.settings.language still equals 'en' here.
    // by setting and passing lang in showPopupFunction we have a localized version of
    // the popup in the appropriate directory.
    // console.log(vm.settings.language);
    vm.showSetting = showPopupFunction('setting');
    vm.showAbout = showPopupFunction('about', lang);
    vm.showSupport = showPopupFunction('support', lang);
    vm.showFilters = showPopupFunction('filters');
    vm.showXur = showPopupFunction('xur');
    vm.showMatsExchange = showPopupFunction('mats-exchange');

    vm.toggleMinMax = function(e) {
      $state.go($state.is('best') ? 'inventory' : 'best');
    };

    vm.toggleVendors = function(e) {
      $state.go($state.is('vendors') ? 'inventory' : 'vendors');
    };

    dimXurService.updateXur();
    vm.xur = dimXurService;

    vm.refresh = function refresh() {
      loadingTracker.addPromise(dimStoreService.reloadStores());
      dimXurService.updateXur();
    };

    // Don't refresh more than once a minute
    var refresh = _.throttle(vm.refresh, 60 * 1000);

    vm.startAutoRefreshTimer = function() {
      var secondsToWait = 360;

      $rootScope.autoRefreshTimer = $interval(function() {
        // Only Refresh If We're Not Already Doing Something
        // And We're Not Inactive
        if (!loadingTracker.active() && !$rootScope.isUserInactive() && document.visibilityState === 'visible') {
          refresh();
        }
      }, secondsToWait * 1000);
    };

    vm.startAutoRefreshTimer();

    // Refresh when the user comes back to the page
    document.addEventListener("visibilitychange", function() {
      if (!loadingTracker.active() && !$rootScope.isUserInactive() && document.visibilityState === 'visible') {
        refresh();
      }
    }, false);
  }
})();
<|endoftext|>