<commit_before>'use babel';

import Redmine from 'promised-redmine';

import {CompositeDisposable} from 'atom';
import CSON from 'season';
import _path from 'path';

import shell from 'shell';

import IssuesListView from './views/issues-list-view';

var redmine;

const CONFIG_PATH = '.atom-redmine';

export default {
  config: {
    host: {
      title: 'Redmine Host',
      description: 'The hostname of the Redmine instance.',
      type: 'string',
      default: null
    },
    apiKey: {
      title: 'Redmine API Key',
      description: 'The Redmine api key which can be found on the My Account page',
      type: 'string',
      default: null
    }
  },

  subscriptions: null,

  redmine: null,
  projectId: null,

  issuesListView: null,

  activate(state) {
    this.redmine = new Redmine({
      host: atom.config.get('redmine.host'),
      apiKey: atom.config.get('redmine.apiKey')
    });
    if(!this.readConfigFile()) {
      atom.notifications.addError(
        `Atom Redmine Error

        ${CONFIG_PATH} config file not found. See the README for details.`,
        { dismissable: true }
      );
      return false;
    }

    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'redmine:my-issues': ()=> this.listIssues({ assigned_to_id: 'me' }),
      'redmine:all-issues': ()=> this.listIssues(),
      'redmine:open-project': ()=> this.openProject()
    }));
  },

  deactivate() {
    this.subscriptions.dispose();
  },

  readConfigFile() {
    var configured = false;
    atom.project.getPaths().forEach((path)=> {
      var configPath = path + _path.sep + CONFIG_PATH;
      if(atom.project.contains(configPath)) {
        var config = CSON.readFileSync(configPath);
        if(config) {
          var complete = true;
          if(config.projectId) {
            this.projectId = config.projectId;
          } else {
            complete = false;
          }
          configured = configured || complete;
        }
      }
    });
    return configured;
  },

  listIssues(options={}) {
    var params = { project_id: this.projectId };
    Object.getOwnPropertyNames(options).forEach(key => params[key] = options[key]);
    var issues = this.redmine.getIssues(params);
    this.createIssuesListView().show(issues);
    issues.then(undefined, this.showError);
  },

  createIssuesListView() {
    return this.issuesListView || (this.issuesListView = new IssuesListView());
  },

  openProject() {
    shell.openExternal(`http://${atom.config.get('redmine.host')}/projects/${this.projectId}`);
  },

  showError(error) {
    console.error('error in atom-redmine', error);
    // ["STATUSCODE_REJECTION 404"]
  }
};
<commit_msg>Sorting by last changed issues by default<commit_after>'use babel';

import Redmine from 'promised-redmine';

import {CompositeDisposable} from 'atom';
import CSON from 'season';
import _path from 'path';

import shell from 'shell';

import IssuesListView from './views/issues-list-view';

var redmine;

const CONFIG_PATH = '.atom-redmine';

export default {
  config: {
    host: {
      title: 'Redmine Host',
      description: 'The hostname of the Redmine instance.',
      type: 'string',
      default: null
    },
    apiKey: {
      title: 'Redmine API Key',
      description: 'The Redmine api key which can be found on the My Account page',
      type: 'string',
      default: null
    }
  },

  subscriptions: null,

  redmine: null,
  projectId: null,

  issuesListView: null,

  activate(state) {
    this.redmine = new Redmine({
      host: atom.config.get('redmine.host'),
      apiKey: atom.config.get('redmine.apiKey')
    });
    if(!this.readConfigFile()) {
      atom.notifications.addError(
        `Atom Redmine Error

        ${CONFIG_PATH} config file not found. See the README for details.`,
        { dismissable: true }
      );
      return false;
    }

    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'redmine:my-issues': ()=> this.listIssues({ assigned_to_id: 'me' }),
      'redmine:all-issues': ()=> this.listIssues(),
      'redmine:open-project': ()=> this.openProject()
    }));
  },

  deactivate() {
    this.subscriptions.dispose();
  },

  readConfigFile() {
    var configured = false;
    atom.project.getPaths().forEach((path)=> {
      var configPath = path + _path.sep + CONFIG_PATH;
      if(atom.project.contains(configPath)) {
        var config = CSON.readFileSync(configPath);
        if(config) {
          var complete = true;
          if(config.projectId) {
            this.projectId = config.projectId;
          } else {
            complete = false;
          }
          configured = configured || complete;
        }
      }
    });
    return configured;
  },

  listIssues(options={}) {
    var params = {
      project_id: this.projectId,
      sort: 'updated_on:desc'
    };
    Object.getOwnPropertyNames(options).forEach(key => params[key] = options[key]);
    var issues = this.redmine.getIssues(params);
    this.createIssuesListView().show(issues);
    issues.then(undefined, this.showError);
  },

  createIssuesListView() {
    return this.issuesListView || (this.issuesListView = new IssuesListView());
  },

  openProject() {
    shell.openExternal(`http://${atom.config.get('redmine.host')}/projects/${this.projectId}`);
  },

  showError(error) {
    console.error('error in atom-redmine', error);
    // ["STATUSCODE_REJECTION 404"]
  }
};
<|endoftext|>


<commit_before>/**
 *
 * @constructor
 * @augments TextEditorBaseBuilder
 */
function DatePickerBuilder() {
    _.superClass(DatePickerBuilder, this);
}

_.inherit(DatePickerBuilder, TextEditorBaseBuilder);

DatePickerBuilder.prototype.createElement = function (params) {
    return new DatePicker(params.parent);
};

DatePickerBuilder.prototype.applyMetadata = function (params) {
    var element = params.element;
    var metadata = params.metadata;
    this.applyDefaultMetadata(params);
    TextEditorBaseBuilder.prototype.applyMetadata.call(this, params);

    element.setMinValue(metadata.MinValue);
    element.setMaxValue(metadata.MaxValue);
    element.setMode(metadata.Mode);

    //var format = params.builder.buildType(params.parent, 'DateFormat', {}, null);
    //element.setDateFormat(format);
};

DatePickerBuilder.prototype.applyDefaultMetadata = function (params) {
    var metadata = params.metadata;

    var defaultFormat = {
            Date: '{:d}',
            DateTime: '{:g}',
            Time: '{:t}'
        },
        defaultEditMask = {
            Date: {DateTimeEditMask: {Mask: 'd'}},
            DateTime: {DateTimeEditMask: {Format: 'g'}},
            Time: {DateTimeEditMask: {Format: 't'}}
        };

    _.defaults(metadata, {Mode: 'Date'});
    _.defaults(metadata, {DisplayFormat: defaultFormat[metadata.Mode], EditMask: defaultEditMask[metadata.Mode]});
};
<commit_msg>UI-1546: Не обновляется Binding в DatePicker#progress Исправлены маски по умолчанию<commit_after>/**
 *
 * @constructor
 * @augments TextEditorBaseBuilder
 */
function DatePickerBuilder() {
    _.superClass(DatePickerBuilder, this);
}

_.inherit(DatePickerBuilder, TextEditorBaseBuilder);

DatePickerBuilder.prototype.createElement = function (params) {
    return new DatePicker(params.parent);
};

DatePickerBuilder.prototype.applyMetadata = function (params) {
    var element = params.element;
    var metadata = params.metadata;
    this.applyDefaultMetadata(params);
    TextEditorBaseBuilder.prototype.applyMetadata.call(this, params);

    element.setMinValue(metadata.MinValue);
    element.setMaxValue(metadata.MaxValue);
    element.setMode(metadata.Mode);

    //var format = params.builder.buildType(params.parent, 'DateFormat', {}, null);
    //element.setDateFormat(format);
};

DatePickerBuilder.prototype.applyDefaultMetadata = function (params) {
    var metadata = params.metadata;

    var defaultFormat = {
            Date: '{:d}',
            DateTime: '{:g}',
            Time: '{:t}'
        },
        defaultEditMask = {
            Date: {DateTimeEditMask: {Mask: 'd'}},
            DateTime: {DateTimeEditMask: {Mask: 'g'}},
            Time: {DateTimeEditMask: {Mask: 't'}}
        };

    _.defaults(metadata, {Mode: 'Date'});
    _.defaults(metadata, {DisplayFormat: defaultFormat[metadata.Mode], EditMask: defaultEditMask[metadata.Mode]});
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import moment from 'moment';
import { Container, Header, Card, Divider, Loader, Grid } from 'semantic-ui-react';
import { getAllListings, changeSearchField, changeFilterCategory, changeDistanceRadius, changeSortFilter, clearClickedListing } from '../../../actions/allListingActions';
import { changeCenter, sortMarkersByDistance } from '../../../actions/googleMapActions';
import Listing from '../../shared/Listing';
import AllListingsSearch from './AllListingsComponents/AllListingsSearch';
import AllListingsFilter from './AllListingsComponents/AllListingsFilter';
import GoogleMapContainer from './AllListingsComponents/GoogleMap/GoogleMapContainer';
import filterListings from '../../helpers/filterListings';
import ListingInfoCard from './AllListingsComponents/ListingInfoCard';
import Pagination from '../../Pagination/Pagination';
import getPaginationItems from '../../Pagination/helpers/getPaginationItems';

class AllListings extends Component {
  constructor(props) {
    super(props);
    this.onChange = this.onChange.bind(this);
    this.onSelectFilter = this.onSelectFilter.bind(this);
    this.onSelectDistance = this.onSelectDistance.bind(this);
    this.onSelectSort = this.onSelectSort.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }

  componentWillMount() {
     if (this.props.loggedInUser.state !== '') {
        this.props.dispatch(changeCenter(this.props.loggedInUser));
      }
    if (this.props.allListings.length === 0) {
      this.props.dispatch(getAllListings());
    }
  }

  convertTime(time) {
    return moment(time).fromNow();
  }

  onSubmit(e) {
    e.preventDefault();
    this.props.dispatch(changeCenter(this.props.searchField));
  }

  onChange(e) {
    e.preventDefault();
    this.props.dispatch(changeSearchField(e.target.value));
    this.props.dispatch(sortMarkersByDistance(this.props.allListings));
  }

  onSelectFilter(e) {
    this.props.dispatch(changeFilterCategory(e));
  }

  onSelectDistance(e, data) {
    this.props.dispatch(changeDistanceRadius(data.value));
  }

  onSelectSort(e, data) {
    this.props.dispatch(changeSortFilter(data.value));
  }

  cutBody(body) {
    if (body.length > 20) {
      body = body.slice(0, 20) + '...';
    }
    return body;
  }

  componentWillUnmount() {
    this.props.dispatch(clearClickedListing());
  }

  render() {
    const { isFetching, allListings, cutBody, filters, clickedListing, activeItem } = this.props;
    const distanceArray = [
      { key: 0, text: '10 Miles', value: 10 },
      { key: 1, text: '30 Miles', value: 30 },
      { key: 2, text: 'All', value: 0 },
    ];
    const sortArray = [
      { key: 0, text: 'Distance', value: 'distance' },
      { key: 1, text: 'Time Created', value: 'time' },
    ];
    const onListingClick = (listingId) => {
      this.props.dispatch(push(`/listings/${listingId}`));
    };
    const startingIdx = 8 * (activeItem - 1);
    const filteredListings = filterListings(allListings, filters);
    const filteredMarkers = filteredListings.slice(startingIdx, startingIdx + 8);
    if (isFetching) {
      return <Loader active inline='centered' />;
    } else {
      return (
        <Container textAlign="center">
          <AllListingsFilter
            filters={filters}
            onSelect={this.onSelect}
            distanceArray={distanceArray}
            onSelectFilter={this.onSelectFilter}
            onSelectDistance={this.onSelectDistance}
            onSelectSort={this.onSelectSort}
            sortArray={sortArray}
          />
          <Grid width={16} stackable>
            <Grid.Column width={8}>
              <GoogleMapContainer markers={filteredMarkers} />
            </Grid.Column>
            <Grid.Column width={8}>
              <AllListingsSearch
                onClick={this.onClick}
                onChange={this.onChange}
                onSubmit={this.onSubmit}
              />
              <ListingInfoCard
                card={clickedListing}
                onListingClick={onListingClick}
              />
            </Grid.Column>
          </Grid>
          Listings
          <Divider />
          <Card.Group itemsPerRow={4} stackable>
            {filteredMarkers.map(listing =>
              <Listing
                key={listing.id}
                listingId={listing.id}
                title={listing.title}
                createdAt={this.convertTime(listing.createdAt)}
                body={listing.body}
                type={listing.type}
                onClick={this.onClick}
                handleDelete={this.handleDelete}
                cutBody={this.cutBody}
                onListingClick={onListingClick}
              />
            )}
          </Card.Group>
          <Divider hidden />
          <Pagination
            items={getPaginationItems(filteredListings, 8)}
          />
        </Container>
      );
    }
  }
}

const mapStateToProps = (state) => {
  const { allListings, isFetching, searchField, filters, clickedListing } = state.listings;
  const { id } = state.auth.loggedInUser;
  const loggedInUser = state.auth.loggedInUser;
  const { activeItem } = state.pagination;

  return { allListings, isFetching, id, searchField, loggedInUser, filters, clickedListing, activeItem };
};

export default connect(mapStateToProps)(AllListings);
<commit_msg>add prop types to all listings<commit_after>import React, { Component } from 'react';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import moment from 'moment';
import { Container, Header, Card, Divider, Loader, Grid } from 'semantic-ui-react';
import { getAllListings, changeSearchField, changeFilterCategory, changeDistanceRadius, changeSortFilter, clearClickedListing } from '../../../actions/allListingActions';
import { changeCenter, sortMarkersByDistance } from '../../../actions/googleMapActions';
import Listing from '../../shared/Listing';
import AllListingsSearch from './AllListingsComponents/AllListingsSearch';
import AllListingsFilter from './AllListingsComponents/AllListingsFilter';
import GoogleMapContainer from './AllListingsComponents/GoogleMap/GoogleMapContainer';
import filterListings from '../../helpers/filterListings';
import ListingInfoCard from './AllListingsComponents/ListingInfoCard';
import Pagination from '../../Pagination/Pagination';
import getPaginationItems from '../../Pagination/helpers/getPaginationItems';

class AllListings extends Component {
  constructor(props) {
    super(props);
    this.onChange = this.onChange.bind(this);
    this.onSelectFilter = this.onSelectFilter.bind(this);
    this.onSelectDistance = this.onSelectDistance.bind(this);
    this.onSelectSort = this.onSelectSort.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }

  componentWillMount() {
     if (this.props.loggedInUser.state !== '') {
        this.props.dispatch(changeCenter(this.props.loggedInUser));
      }
    if (this.props.allListings.length === 0) {
      this.props.dispatch(getAllListings());
    }
  }

  convertTime(time) {
    return moment(time).fromNow();
  }

  onSubmit(e) {
    e.preventDefault();
    this.props.dispatch(changeCenter(this.props.searchField));
  }

  onChange(e) {
    e.preventDefault();
    this.props.dispatch(changeSearchField(e.target.value));
    this.props.dispatch(sortMarkersByDistance(this.props.allListings));
  }

  onSelectFilter(e) {
    this.props.dispatch(changeFilterCategory(e));
  }

  onSelectDistance(e, data) {
    this.props.dispatch(changeDistanceRadius(data.value));
  }

  onSelectSort(e, data) {
    this.props.dispatch(changeSortFilter(data.value));
  }

  cutBody(body) {
    if (body.length > 20) {
      body = body.slice(0, 20) + '...';
    }
    return body;
  }

  componentWillUnmount() {
    this.props.dispatch(clearClickedListing());
  }

  render() {
    const { isFetching, allListings, cutBody, filters, clickedListing, activeItem } = this.props;
    const distanceArray = [
      { key: 0, text: '10 Miles', value: 10 },
      { key: 1, text: '30 Miles', value: 30 },
      { key: 2, text: 'All', value: 0 },
    ];
    const sortArray = [
      { key: 0, text: 'Distance', value: 'distance' },
      { key: 1, text: 'Time Created', value: 'time' },
    ];
    const onListingClick = (listingId) => {
      this.props.dispatch(push(`/listings/${listingId}`));
    };
    const startingIdx = 8 * (activeItem - 1);
    const filteredListings = filterListings(allListings, filters);
    const filteredMarkers = filteredListings.slice(startingIdx, startingIdx + 8);
    if (isFetching) {
      return <Loader active inline='centered' />;
    } else {
      return (
        <Container textAlign="center">
          <AllListingsFilter
            filters={filters}
            onSelect={this.onSelect}
            distanceArray={distanceArray}
            onSelectFilter={this.onSelectFilter}
            onSelectDistance={this.onSelectDistance}
            onSelectSort={this.onSelectSort}
            sortArray={sortArray}
          />
          <Grid width={16} stackable>
            <Grid.Column width={8}>
              <GoogleMapContainer markers={filteredMarkers} />
            </Grid.Column>
            <Grid.Column width={8}>
              <AllListingsSearch
                onClick={this.onClick}
                onChange={this.onChange}
                onSubmit={this.onSubmit}
              />
              <ListingInfoCard
                card={clickedListing}
                onListingClick={onListingClick}
              />
            </Grid.Column>
          </Grid>
          Listings
          <Divider />
          <Card.Group itemsPerRow={4} stackable>
            {filteredMarkers.map(listing =>
              <Listing
                key={listing.id}
                listingId={listing.id}
                title={listing.title}
                createdAt={this.convertTime(listing.createdAt)}
                body={listing.body}
                type={listing.type}
                onClick={this.onClick}
                handleDelete={this.handleDelete}
                cutBody={this.cutBody}
                onListingClick={onListingClick}
              />
            )}
          </Card.Group>
          <Divider hidden />
          <Pagination
            items={getPaginationItems(filteredListings, 8)}
          />
        </Container>
      );
    }
  }
}

AllListings.propTypes = {
  allListings: React.PropTypes.array.isRequired,
  isFetching: React.PropTypes.bool,
  searchField: React.PropTypes.string.isRequired,
  filters: React.PropTypes.object.isRequired,
  clickedListing: React.PropTypes.object,
  id: React.PropTypes.number.isRequired,
  loggedInUser: React.PropTypes.object.isRequired,
  activeItem: React.PropTypes.number.isRequired,
};

const mapStateToProps = (state) => {
  const { allListings, isFetching, searchField, filters, clickedListing } = state.listings;
  const { id } = state.auth.loggedInUser;
  const loggedInUser = state.auth.loggedInUser;
  const { activeItem } = state.pagination;

  return { allListings, isFetching, id, searchField, loggedInUser, filters, clickedListing, activeItem };
};

export default connect(mapStateToProps)(AllListings);
<|endoftext|>


<commit_before>const
	log = require( 'log' ),
	_ = require( 'underscore' ),
	JSHINT = require ( 'jshint' ).JSHINT;

function lint ( buffer , path ) {

	log.processing( path , 'jshint.JSHINT' );

	try {

		JSHINT( buffer , { esnext : true , undef : true , predef : ['console' , 'define' , '_' , 'Polymer' ] } );

		const data = JSHINT.data();

		if ( (_.isArray( data.errors ) && data.errors.length > 0) ||
			 (_.isArray( data.warnings ) && data.warnings.length > 0) ||
			 (_.isArray( data.unused ) && data.unused.length > 0) ) {

			_.isArray( data.unused ) && _.each( data.unused , variable => {

				log.warning( `JSHint discovered an unused variable named ${variable.name} in ${path}` , `line ${variable.line}, char ${variable.character}` );

			});

			_.isArray( data.warnings ) && _.each( data.warnings , warning => {

				log.warning(	`JSHint discovered the issue "${warning.reason}" in ${path}`,
									`line  ${warning.line}, char ${warning.character}`,
									{ issue : warning.raw , code : warning.evidence } );

			});

			_.isArray( data.errors ) && _.each( data.errors , error => {

				log.warning(	`JSHint discovered the error " ${error.reason}" in ${path}`,
									`line  ${error.line}, char ${error.character}`,
									{ issue : error.raw , code : error.evidence } );

			});

			log.error( `JSHint has found issues with ${path}` , __filename );

			process.exit(1);

		}

	} catch ( error ) {

		log.error( `JSHint has failed to parse the buffer for ${path}` , __filename );

		process.exit(1);

	}

	return buffer;

}

function analyze ( buffer ) {

	JSHINT( buffer , { esnext : true , undef : true , predef : [ 'define' , 'window' ] } );

	const
		funcs = JSHINT.data().functions,
		data = _.chain( funcs )
		.map( func => { return func.metrics } )
		.reduce( ( memo , metric ) => {
			memo.complexity += metric.complexity;
			memo.parameters += metric.parameters;
			memo.statements += metric.statements;
			return memo;
		} ).value();

	return {
		numberOfFunctions : funcs.length,
		avgComplexity : data.complexity / funcs.length,
		avgParameters : data.parameters / funcs.length,
		avgStatements : data.statements / funcs.length
	};

}

module.exports = { lint , analyze };<commit_msg>added window as an acceptable undefined variable<commit_after>const
	log = require( 'log' ),
	_ = require( 'underscore' ),
	JSHINT = require ( 'jshint' ).JSHINT;

function lint ( buffer , path ) {

	log.processing( path , 'jshint.JSHINT' );

	try {

		JSHINT( buffer , { esnext : true , undef : true , predef : [ 'console' , 'define' , '_' , 'Polymer' , 'window' ] } );

		const data = JSHINT.data();

		if ( (_.isArray( data.errors ) && data.errors.length > 0) ||
			 (_.isArray( data.warnings ) && data.warnings.length > 0) ||
			 (_.isArray( data.unused ) && data.unused.length > 0) ) {

			_.isArray( data.unused ) && _.each( data.unused , variable => {

				log.warning( `JSHint discovered an unused variable named ${variable.name} in ${path}` , `line ${variable.line}, char ${variable.character}` );

			});

			_.isArray( data.warnings ) && _.each( data.warnings , warning => {

				log.warning(	`JSHint discovered the issue "${warning.reason}" in ${path}`,
									`line  ${warning.line}, char ${warning.character}`,
									{ issue : warning.raw , code : warning.evidence } );

			});

			_.isArray( data.errors ) && _.each( data.errors , error => {

				log.warning(	`JSHint discovered the error " ${error.reason}" in ${path}`,
									`line  ${error.line}, char ${error.character}`,
									{ issue : error.raw , code : error.evidence } );

			});

			log.error( `JSHint has found issues with ${path}` , __filename );

			process.exit(1);

		}

	} catch ( error ) {

		log.error( `JSHint has failed to parse the buffer for ${path}` , __filename );

		process.exit(1);

	}

	return buffer;

}

function analyze ( buffer ) {

	JSHINT( buffer , { esnext : true , undef : true , predef : [ 'define' , 'window' ] } );

	const
		funcs = JSHINT.data().functions,
		data = _.chain( funcs )
		.map( func => { return func.metrics } )
		.reduce( ( memo , metric ) => {
			memo.complexity += metric.complexity;
			memo.parameters += metric.parameters;
			memo.statements += metric.statements;
			return memo;
		} ).value();

	return {
		numberOfFunctions : funcs.length,
		avgComplexity : data.complexity / funcs.length,
		avgParameters : data.parameters / funcs.length,
		avgStatements : data.statements / funcs.length
	};

}

module.exports = { lint , analyze };<|endoftext|>


<commit_before>/* eslint-disable jasmine/no-global-setup */
import $ from 'jquery';
import 'vendor/jasmine-jquery';
import '~/commons';

import Vue from 'vue';
import VueResource from 'vue-resource';

import { getDefaultAdapter } from '~/lib/utils/axios_utils';

const isHeadlessChrome = /\bHeadlessChrome\//.test(navigator.userAgent);
Vue.config.devtools = !isHeadlessChrome;
Vue.config.productionTip = false;

let hasVueWarnings = false;
Vue.config.warnHandler = (msg, vm, trace) => {
  hasVueWarnings = true;
  fail(`${msg}${trace}`);
};

let hasVueErrors = false;
Vue.config.errorHandler = function (err) {
  hasVueErrors = true;
  fail(err);
};

Vue.use(VueResource);

// enable test fixtures
jasmine.getFixtures().fixturesPath = '/base/spec/javascripts/fixtures';
jasmine.getJSONFixtures().fixturesPath = '/base/spec/javascripts/fixtures';

// globalize common libraries
window.$ = window.jQuery = $;

// stub expected globals
window.gl = window.gl || {};
window.gl.TEST_HOST = 'http://test.host';
window.gon = window.gon || {};

let hasUnhandledPromiseRejections = false;

window.addEventListener('unhandledrejection', (event) => {
  hasUnhandledPromiseRejections = true;
  console.error('Unhandled promise rejection:');
  console.error(event.reason.stack || event.reason);
});

// HACK: Chrome 59 disconnects if there are too many synchronous tests in a row
// because it appears to lock up the thread that communicates to Karma's socket
// This async beforeEach gets called on every spec and releases the JS thread long
// enough for the socket to continue to communicate.
// The downside is that it creates a minor performance penalty in the time it takes
// to run our unit tests.
beforeEach(done => done());

const builtinVueHttpInterceptors = Vue.http.interceptors.slice();

beforeEach(() => {
  // restore interceptors so we have no remaining ones from previous tests
  Vue.http.interceptors = builtinVueHttpInterceptors.slice();
});

const axiosDefaultAdapter = getDefaultAdapter();

// render all of our tests
const testsContext = require.context('.', true, /_spec$/);
testsContext.keys().forEach(function (path) {
  try {
    testsContext(path);
  } catch (err) {
    console.error('[ERROR] Unable to load spec: ', path);
    describe('Test bundle', function () {
      it(`includes '${path}'`, function () {
        expect(err).toBeNull();
      });
    });
  }
});

describe('test errors', () => {
  beforeAll((done) => {
    if (hasUnhandledPromiseRejections || hasVueWarnings || hasVueErrors) {
      setTimeout(done, 1000);
    } else {
      done();
    }
  });

  it('has no unhandled Promise rejections', () => {
    expect(hasUnhandledPromiseRejections).toBe(false);
  });

  it('has no Vue warnings', () => {
    expect(hasVueWarnings).toBe(false);
  });

  it('has no Vue error', () => {
    expect(hasVueErrors).toBe(false);
  });

  it('restores axios adapter after mocking', () => {
    if (getDefaultAdapter() !== axiosDefaultAdapter) {
      fail('axios adapter is not restored! Did you forget a restore() on MockAdapter?');
    }
  });
});

// if we're generating coverage reports, make sure to include all files so
// that we can catch files with 0% coverage
// see: https://github.com/deepsweet/istanbul-instrumenter-loader/issues/15
if (process.env.BABEL_ENV === 'coverage') {
  // exempt these files from the coverage report
  const troubleMakers = [
    './blob_edit/blob_bundle.js',
    './cycle_analytics/cycle_analytics_bundle.js',
    './cycle_analytics/components/stage_plan_component.js',
    './cycle_analytics/components/stage_staging_component.js',
    './cycle_analytics/components/stage_test_component.js',
    './commit/pipelines/pipelines_bundle.js',
    './diff_notes/diff_notes_bundle.js',
    './diff_notes/components/jump_to_discussion.js',
    './diff_notes/components/resolve_count.js',
    './dispatcher.js',
    './environments/environments_bundle.js',
    './filtered_search/filtered_search_bundle.js',
    './graphs/graphs_bundle.js',
    './issuable/time_tracking/time_tracking_bundle.js',
    './main.js',
    './merge_conflicts/merge_conflicts_bundle.js',
    './merge_conflicts/components/inline_conflict_lines.js',
    './merge_conflicts/components/parallel_conflict_lines.js',
    './monitoring/monitoring_bundle.js',
    './network/network_bundle.js',
    './network/branch_graph.js',
    './profile/profile_bundle.js',
    './protected_branches/protected_branches_bundle.js',
    './snippet/snippet_bundle.js',
    './terminal/terminal_bundle.js',
    './users/users_bundle.js',
    './issue_show/index.js',
  ];

  describe('Uncovered files', function () {
    const sourceFiles = require.context('~', true, /\.js$/);

    $.holdReady(true);

    sourceFiles.keys().forEach(function (path) {
      // ignore if there is a matching spec file
      if (testsContext.keys().indexOf(`${path.replace(/\.js$/, '')}_spec`) > -1) {
        return;
      }

      it(`includes '${path}'`, function () {
        try {
          sourceFiles(path);
        } catch (err) {
          if (troubleMakers.indexOf(path) === -1) {
            expect(err).toBeNull();
          }
        }
      });
    });
  });
}
<commit_msg>Explicitly add uncovered files to troubleMakers<commit_after>/* eslint-disable jasmine/no-global-setup */
import $ from 'jquery';
import 'vendor/jasmine-jquery';
import '~/commons';

import Vue from 'vue';
import VueResource from 'vue-resource';

import { getDefaultAdapter } from '~/lib/utils/axios_utils';

const isHeadlessChrome = /\bHeadlessChrome\//.test(navigator.userAgent);
Vue.config.devtools = !isHeadlessChrome;
Vue.config.productionTip = false;

let hasVueWarnings = false;
Vue.config.warnHandler = (msg, vm, trace) => {
  hasVueWarnings = true;
  fail(`${msg}${trace}`);
};

let hasVueErrors = false;
Vue.config.errorHandler = function (err) {
  hasVueErrors = true;
  fail(err);
};

Vue.use(VueResource);

// enable test fixtures
jasmine.getFixtures().fixturesPath = '/base/spec/javascripts/fixtures';
jasmine.getJSONFixtures().fixturesPath = '/base/spec/javascripts/fixtures';

// globalize common libraries
window.$ = window.jQuery = $;

// stub expected globals
window.gl = window.gl || {};
window.gl.TEST_HOST = 'http://test.host';
window.gon = window.gon || {};

let hasUnhandledPromiseRejections = false;

window.addEventListener('unhandledrejection', (event) => {
  hasUnhandledPromiseRejections = true;
  console.error('Unhandled promise rejection:');
  console.error(event.reason.stack || event.reason);
});

// HACK: Chrome 59 disconnects if there are too many synchronous tests in a row
// because it appears to lock up the thread that communicates to Karma's socket
// This async beforeEach gets called on every spec and releases the JS thread long
// enough for the socket to continue to communicate.
// The downside is that it creates a minor performance penalty in the time it takes
// to run our unit tests.
beforeEach(done => done());

const builtinVueHttpInterceptors = Vue.http.interceptors.slice();

beforeEach(() => {
  // restore interceptors so we have no remaining ones from previous tests
  Vue.http.interceptors = builtinVueHttpInterceptors.slice();
});

const axiosDefaultAdapter = getDefaultAdapter();

// render all of our tests
const testsContext = require.context('.', true, /_spec$/);
testsContext.keys().forEach(function (path) {
  try {
    testsContext(path);
  } catch (err) {
    console.error('[ERROR] Unable to load spec: ', path);
    describe('Test bundle', function () {
      it(`includes '${path}'`, function () {
        expect(err).toBeNull();
      });
    });
  }
});

describe('test errors', () => {
  beforeAll((done) => {
    if (hasUnhandledPromiseRejections || hasVueWarnings || hasVueErrors) {
      setTimeout(done, 1000);
    } else {
      done();
    }
  });

  it('has no unhandled Promise rejections', () => {
    expect(hasUnhandledPromiseRejections).toBe(false);
  });

  it('has no Vue warnings', () => {
    expect(hasVueWarnings).toBe(false);
  });

  it('has no Vue error', () => {
    expect(hasVueErrors).toBe(false);
  });

  it('restores axios adapter after mocking', () => {
    if (getDefaultAdapter() !== axiosDefaultAdapter) {
      fail('axios adapter is not restored! Did you forget a restore() on MockAdapter?');
    }
  });
});

// if we're generating coverage reports, make sure to include all files so
// that we can catch files with 0% coverage
// see: https://github.com/deepsweet/istanbul-instrumenter-loader/issues/15
if (process.env.BABEL_ENV === 'coverage') {
  // exempt these files from the coverage report
  const troubleMakers = [
    './blob_edit/blob_bundle.js',
    './boards/components/modal/empty_state.js',
    './boards/components/modal/footer.js',
    './boards/components/modal/header.js',
    './cycle_analytics/cycle_analytics_bundle.js',
    './cycle_analytics/components/stage_plan_component.js',
    './cycle_analytics/components/stage_staging_component.js',
    './cycle_analytics/components/stage_test_component.js',
    './commit/pipelines/pipelines_bundle.js',
    './diff_notes/diff_notes_bundle.js',
    './diff_notes/components/jump_to_discussion.js',
    './diff_notes/components/resolve_count.js',
    './dispatcher.js',
    './environments/environments_bundle.js',
    './filtered_search/filtered_search_bundle.js',
    './graphs/graphs_bundle.js',
    './issuable/time_tracking/time_tracking_bundle.js',
    './main.js',
    './merge_conflicts/merge_conflicts_bundle.js',
    './merge_conflicts/components/inline_conflict_lines.js',
    './merge_conflicts/components/parallel_conflict_lines.js',
    './monitoring/monitoring_bundle.js',
    './network/network_bundle.js',
    './network/branch_graph.js',
    './profile/profile_bundle.js',
    './protected_branches/protected_branches_bundle.js',
    './snippet/snippet_bundle.js',
    './terminal/terminal_bundle.js',
    './users/users_bundle.js',
    './issue_show/index.js',
  ];

  describe('Uncovered files', function () {
    const sourceFiles = require.context('~', true, /\.js$/);

    $.holdReady(true);

    sourceFiles.keys().forEach(function (path) {
      // ignore if there is a matching spec file
      if (testsContext.keys().indexOf(`${path.replace(/\.js$/, '')}_spec`) > -1) {
        return;
      }

      it(`includes '${path}'`, function () {
        try {
          sourceFiles(path);
        } catch (err) {
          if (troubleMakers.indexOf(path) === -1) {
            expect(err).toBeNull();
          }
        }
      });
    });
  });
}
<|endoftext|>


<commit_before>/**
 * OpenEyes
 *
 * (C) Moorfields Eye Hospital NHS Foundation Trust, 2008-2011
 * (C) OpenEyes Foundation, 2011-2013
 * This file is part of OpenEyes.
 * OpenEyes is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 * OpenEyes is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License along with OpenEyes in a file titled COPYING. If not, see <http://www.gnu.org/licenses/>.
 *
 * @package OpenEyes
 * @link http://www.openeyes.org.uk
 * @author OpenEyes <info@openeyes.org.uk>
 * @copyright Copyright (c) 2008-2011, Moorfields Eye Hospital NHS Foundation Trust
 * @copyright Copyright (c) 2011-2013, OpenEyes Foundation
 * @license http://www.gnu.org/licenses/gpl-3.0.html The GNU General Public License V3.0
 */

$(document).ready(function(){
	$collapsed = true;

	$('button.addEvent').click(function(e) {
		var subspecialty_id = $(this).attr('data-attr-subspecialty-id');
		var returnUrl = window.location.href.replace(/#$/,'')+'#addEvent';

		$.ajax({
			'type': 'POST',
			'url': baseUrl+'/patient/addNewEvent',
			'data': 'subspecialty_id='+subspecialty_id+'&patient_id='+OE_patient_id+'&returnUrl='+returnUrl+"&YII_CSRF_TOKEN="+YII_CSRF_TOKEN,
			'success': function(html) {
				if (html == "0") {
					alert("Sorry, you cannot add an event to this episode because you are not in any firms with the same subspecialty.");
				} else {
					$('#user_panel').before(html);
				}
			}
		});
	});

	$('button.cancelAddEvent').die('click').live('click',function(e) {
		$('#add-new-event-dialog').dialog('close');
		$('#add-new-event-dialog').parent().remove();
		e.preventDefault();
	});

	if (window.location.href.match(/#addEvent$/)) {
		$('button.addEvent[data-attr-subspecialty-id="'+OE_subspecialty_id+'"]').click();
	}

	$('button.addEpisode').click(function(e) {
		$.ajax({
			'type': 'POST',
			'data': "YII_CSRF_TOKEN="+YII_CSRF_TOKEN,
			'url': baseUrl+'/patient/verifyAddNewEpisode?patient_id='+OE_patient_id,
			'success': function(response) {
				if (response != '1') {
					alert("There is already an open episode for your firm's subspecialty.\n\nIf you wish to create a new episode in a different subspecialty please switch to a firm that has the subspecialty you want.");
				} else {
					$.ajax({
						'type': 'POST',
						'url': baseUrl+'/patient/addNewEpisode',
						'data': 'patient_id='+OE_patient_id+"&YII_CSRF_TOKEN="+YII_CSRF_TOKEN,
						'success': function(html) {
							$('#user_panel').before(html);
						}
					});
				}
			}
		});

		e.preventDefault();
	});

	$('label').die('click').live('click',function() {
		if ($(this).prev().is('input:radio')) {
			$(this).prev().click();
		}
	});

	$(this).undelegate('select.dropDownTextSelection','change').delegate('select.dropDownTextSelection','change',function() {
		if ($(this).val() != '') {
			var target = $('#' + $(this).attr('id').replace(/^dropDownTextSelection_/,''));
			var currentVal = target.val();

			if($(this).hasClass('delimited')) {
				var newText = $(this).val();
			} else {
				var newText = $(this).children('option:selected').text();
			}

			if (currentVal.length > 0 && !$(this).hasClass('delimited')) {
				if (newText.toUpperCase() == newText) {
					newText = ', ' + newText;
				} else {
					newText = ', ' + newText.charAt(0).toLowerCase() + newText.slice(1);
				}
			} else if (currentVal.length == 0 && $(this).hasClass('delimited')) {
				newText = newText.charAt(0).toUpperCase() + newText.slice(1)
			}

			target.val(currentVal + newText);
			target.trigger('autosize');

			$(this).val('');
		}
	});

});

function WidgetSlider() {if (this.init) this.init.apply(this, arguments); }

WidgetSlider.prototype = {
	init : function(params) {
		for (var i in params) {
			this[i] = params[i];
		}

		var thiz = this;

		$(document).ready(function() {
			thiz.bindElement();
		});
	},

	bindElement : function() {
		var thiz = this;

		$('#'+this.range_id).change(function() {
			thiz.handleChange($(this));
		});
	},

	handleChange : function(element) {
		var val = element.val();

		for (var value in this.remap) {
			if (val == value) {
				val = this.remap[value];
			}
		}

		if (this.null.length >0) {
			if (val.match(/\./)) {
				val = String(parseFloat(val) - 1);
			} else {
				val = String(parseInt(val) - 1);
			}
		}

		var min = $('#'+this.range_id).attr('min');

		if (min.match(/\./)) {
			min = parseFloat(min);
		} else {
			min = parseInt(min);
		}

		if (val < min && this.null.length >0) {
			val = this.null;
		} else {
			if (this.force_dp) {
				if (!val.match(/\./)) {
					val += '.';
					for (var i in this.force_dp) {
						val += '00';
					}
				} else {
					var dp = val.replace(/^.*?\./,'');

					while (dp.length < this.force_dp) {
						dp += '0';
						val += '0';
					}

					while (dp.length > this.force_dp) {
						dp = dp.replace(/.$/,'');
						val = val.replace(/.$/,'');
					}
				}
			}

			if (this.prefix_positive && parseFloat(val) >0) {
				var val = this.prefix_positive + val;
			}
		}

		$('#'+this.range_id+'_value_span').text(val+this.append);
	}
}

function WidgetSliderTable() {if (this.init) this.init.apply(this, arguments); }

WidgetSliderTable.prototype = {
	init : function(params) {
		for (var i in params) {
			this[i] = params[i];
		}

		var thiz = this;

		$(document).ready(function() {
			thiz.bindElement();
		});
	},

	bindElement : function() {
		var thiz = this;

		$('#'+this.range_id).change(function() {
			thiz.handleChange($(this));
		});
	},

	handleChange : function(element) {
		var val = element.val();

		$('#'+this.range_id+'_value_span').text(this.data[val]);
	}
}
<commit_msg>Add space if required before inserting delimited text slugs (resolves OE-2937)<commit_after>/**
 * OpenEyes
 *
 * (C) Moorfields Eye Hospital NHS Foundation Trust, 2008-2011
 * (C) OpenEyes Foundation, 2011-2013
 * This file is part of OpenEyes.
 * OpenEyes is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 * OpenEyes is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License along with OpenEyes in a file titled COPYING. If not, see <http://www.gnu.org/licenses/>.
 *
 * @package OpenEyes
 * @link http://www.openeyes.org.uk
 * @author OpenEyes <info@openeyes.org.uk>
 * @copyright Copyright (c) 2008-2011, Moorfields Eye Hospital NHS Foundation Trust
 * @copyright Copyright (c) 2011-2013, OpenEyes Foundation
 * @license http://www.gnu.org/licenses/gpl-3.0.html The GNU General Public License V3.0
 */

$(document).ready(function(){
	$collapsed = true;

	$('button.addEvent').click(function(e) {
		var subspecialty_id = $(this).attr('data-attr-subspecialty-id');
		var returnUrl = window.location.href.replace(/#$/,'')+'#addEvent';

		$.ajax({
			'type': 'POST',
			'url': baseUrl+'/patient/addNewEvent',
			'data': 'subspecialty_id='+subspecialty_id+'&patient_id='+OE_patient_id+'&returnUrl='+returnUrl+"&YII_CSRF_TOKEN="+YII_CSRF_TOKEN,
			'success': function(html) {
				if (html == "0") {
					alert("Sorry, you cannot add an event to this episode because you are not in any firms with the same subspecialty.");
				} else {
					$('#user_panel').before(html);
				}
			}
		});
	});

	$('button.cancelAddEvent').die('click').live('click',function(e) {
		$('#add-new-event-dialog').dialog('close');
		$('#add-new-event-dialog').parent().remove();
		e.preventDefault();
	});

	if (window.location.href.match(/#addEvent$/)) {
		$('button.addEvent[data-attr-subspecialty-id="'+OE_subspecialty_id+'"]').click();
	}

	$('button.addEpisode').click(function(e) {
		$.ajax({
			'type': 'POST',
			'data': "YII_CSRF_TOKEN="+YII_CSRF_TOKEN,
			'url': baseUrl+'/patient/verifyAddNewEpisode?patient_id='+OE_patient_id,
			'success': function(response) {
				if (response != '1') {
					alert("There is already an open episode for your firm's subspecialty.\n\nIf you wish to create a new episode in a different subspecialty please switch to a firm that has the subspecialty you want.");
				} else {
					$.ajax({
						'type': 'POST',
						'url': baseUrl+'/patient/addNewEpisode',
						'data': 'patient_id='+OE_patient_id+"&YII_CSRF_TOKEN="+YII_CSRF_TOKEN,
						'success': function(html) {
							$('#user_panel').before(html);
						}
					});
				}
			}
		});

		e.preventDefault();
	});

	$('label').die('click').live('click',function() {
		if ($(this).prev().is('input:radio')) {
			$(this).prev().click();
		}
	});

	$(this).undelegate('select.dropDownTextSelection','change').delegate('select.dropDownTextSelection','change',function() {
		if ($(this).val() != '') {
			var target = $('#' + $(this).attr('id').replace(/^dropDownTextSelection_/,''));
			var currentVal = target.val();

			if($(this).hasClass('delimited')) {
				var newText = $(this).val();
			} else {
				var newText = $(this).children('option:selected').text();
			}

			if (currentVal.length > 0 && !$(this).hasClass('delimited')) {
				if (newText.toUpperCase() == newText) {
					newText = ', ' + newText;
				} else {
					newText = ', ' + newText.charAt(0).toLowerCase() + newText.slice(1);
				}
			} else if (currentVal.length == 0 && $(this).hasClass('delimited')) {
				newText = newText.charAt(0).toUpperCase() + newText.slice(1);
			} else if ($(this).hasClass('delimited') && currentVal.slice(-1) != ' ') {
				newText = ' ' + newText;
			}

			target.val(currentVal + newText);
			target.trigger('autosize');

			$(this).val('');
		}
	});

});

function WidgetSlider() {if (this.init) this.init.apply(this, arguments); }

WidgetSlider.prototype = {
	init : function(params) {
		for (var i in params) {
			this[i] = params[i];
		}

		var thiz = this;

		$(document).ready(function() {
			thiz.bindElement();
		});
	},

	bindElement : function() {
		var thiz = this;

		$('#'+this.range_id).change(function() {
			thiz.handleChange($(this));
		});
	},

	handleChange : function(element) {
		var val = element.val();

		for (var value in this.remap) {
			if (val == value) {
				val = this.remap[value];
			}
		}

		if (this.null.length >0) {
			if (val.match(/\./)) {
				val = String(parseFloat(val) - 1);
			} else {
				val = String(parseInt(val) - 1);
			}
		}

		var min = $('#'+this.range_id).attr('min');

		if (min.match(/\./)) {
			min = parseFloat(min);
		} else {
			min = parseInt(min);
		}

		if (val < min && this.null.length >0) {
			val = this.null;
		} else {
			if (this.force_dp) {
				if (!val.match(/\./)) {
					val += '.';
					for (var i in this.force_dp) {
						val += '00';
					}
				} else {
					var dp = val.replace(/^.*?\./,'');

					while (dp.length < this.force_dp) {
						dp += '0';
						val += '0';
					}

					while (dp.length > this.force_dp) {
						dp = dp.replace(/.$/,'');
						val = val.replace(/.$/,'');
					}
				}
			}

			if (this.prefix_positive && parseFloat(val) >0) {
				var val = this.prefix_positive + val;
			}
		}

		$('#'+this.range_id+'_value_span').text(val+this.append);
	}
}

function WidgetSliderTable() {if (this.init) this.init.apply(this, arguments); }

WidgetSliderTable.prototype = {
	init : function(params) {
		for (var i in params) {
			this[i] = params[i];
		}

		var thiz = this;

		$(document).ready(function() {
			thiz.bindElement();
		});
	},

	bindElement : function() {
		var thiz = this;

		$('#'+this.range_id).change(function() {
			thiz.handleChange($(this));
		});
	},

	handleChange : function(element) {
		var val = element.val();

		$('#'+this.range_id+'_value_span').text(this.data[val]);
	}
}
<|endoftext|>


<commit_before>import React from 'react';
import { shallow } from 'enzyme';
import { theme as defaultTheme, withTheme } from '../../src';

describe('withTheme', () => {
  it('should be a fn', () => {
    expect(withTheme).toBeInstanceOf(Function);
  });

  it('should return a fn', () => {
    expect(withTheme()).toBeInstanceOf(Function);
  });
});

describe('HOC', () => {
  it('has a wrapped displayName', () => {
    function MyComponent() {
      return null;
    }
    function WithDisplayName() {
      return null;
    }
    WithDisplayName.displayName = 'MyDisplayName';

    const hoc1 = withTheme({})(MyComponent);
    expect(hoc1.displayName).toBe('withTheme(MyComponent)');

    const hoc2 = withTheme({})(WithDisplayName);
    expect(hoc2.displayName).toBe('withTheme(MyDisplayName)');
  });

  it('passes the theme prop to the wrapped component', () => {
    expect.assertions(1);
    const testTheme = { my: 'theme' };
    function MyComponent({ theme }) {
      expect(theme).toBe(testTheme);

      return null;
    }
    const HOC = withTheme(testTheme)(MyComponent);
    shallow(<HOC />).dive();
  });

  it('passes the default theme when no theme is passed', () => {
    expect.assertions(1);
    function MyComponent({ theme }) {
      expect(theme).toBe(defaultTheme);

      return null;
    }
    const HOC = withTheme()(MyComponent);
    shallow(<HOC />).dive();
  });

  it('allows theme keys to be overridden', () => {
    const overrideTheme = { override: 'theme' };
    function MyComponent() {
      return null;
    }
    const HOC = withTheme()(MyComponent);

    let wrapper = shallow(<HOC />);
    expect(wrapper.find(MyComponent).prop('theme')).toBe(defaultTheme);

    wrapper = shallow(<HOC theme={overrideTheme} />);
    expect(wrapper.find(MyComponent).prop('theme').override).toBe(overrideTheme.override);
  });
});
<commit_msg>[xy-chart][tests] fix withTheme tests<commit_after>import React from 'react';
import { shallow } from 'enzyme';
import { theme as defaultTheme, withTheme } from '../../src';

describe('withTheme', () => {
  it('should be a fn', () => {
    expect(withTheme).toBeInstanceOf(Function);
  });

  it('should return a fn', () => {
    expect(withTheme()).toBeInstanceOf(Function);
  });
});

describe('HOC', () => {
  it('has a wrapped displayName', () => {
    function MyComponent() {
      return null;
    }
    function WithDisplayName() {
      return null;
    }
    WithDisplayName.displayName = 'MyDisplayName';

    const hoc1 = withTheme({})(MyComponent);
    expect(hoc1.displayName).toBe('withTheme(MyComponent)');

    const hoc2 = withTheme({})(WithDisplayName);
    expect(hoc2.displayName).toBe('withTheme(MyDisplayName)');
  });

  it('passes the theme prop to the wrapped component', () => {
    expect.assertions(1);
    const testTheme = { my: 'theme' };
    function MyComponent({ theme }) {
      expect(theme).toEqual(expect.objectContaining(testTheme));

      return null;
    }
    const HOC = withTheme(testTheme)(MyComponent);
    shallow(<HOC />).dive();
  });

  it('passes the default theme when no theme is passed', () => {
    expect.assertions(1);
    function MyComponent({ theme }) {
      expect(theme).toEqual(expect.objectContaining(defaultTheme));

      return null;
    }
    const HOC = withTheme()(MyComponent);
    shallow(<HOC />).dive();
  });

  it('allows theme keys to be overridden', () => {
    const overrideTheme = { colors: 'my-colors' };
    function MyComponent() {
      return null;
    }
    const HOC = withTheme()(MyComponent);

    let wrapper = shallow(<HOC />);
    expect(wrapper.find(MyComponent).prop('theme')).toEqual(expect.objectContaining(defaultTheme));

    wrapper = shallow(<HOC theme={overrideTheme} />);
    expect(wrapper.find(MyComponent).prop('theme')).toEqual(expect.objectContaining(overrideTheme));
  });
});
<|endoftext|>


<commit_before>import { ApolloServer } from 'apollo-server-express';
import cookieParser from 'cookie-parser';
import express from 'express';
import hopsConfig from 'hops-config';
import schema from 'hops-graphql/schema';

const apolloAppPromise = Promise.resolve(
  typeof schema === 'function' ? schema() : schema
).then(resolvedSchema => {
  const app = express();
  app.use(cookieParser());

  const server = new ApolloServer({
    schema: resolvedSchema,
    context: context => ({ ...context, config: hopsConfig }),
  });

  server.applyMiddleware({
    app,
    path: hopsConfig.graphqlMockServerPath,
    cors: {
      credentials: true,
      origin: true,
      methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
      allowedHeaders: 'content-type',
    },
  });

  return app;
});

export default (req, res, next) => {
  apolloAppPromise.then(app => app.handle(req, res, next), next);
};
<commit_msg>fix(graphql): enable playground requests to include credentials<commit_after>import { ApolloServer } from 'apollo-server-express';
import cookieParser from 'cookie-parser';
import express from 'express';
import hopsConfig from 'hops-config';
import schema from 'hops-graphql/schema';

const apolloAppPromise = Promise.resolve(
  typeof schema === 'function' ? schema() : schema
).then(resolvedSchema => {
  const app = express();
  app.use(cookieParser());

  const server = new ApolloServer({
    schema: resolvedSchema,
    playground: {
      settings: {
        'request.credentials': 'same-origin',
      },
    },
    context: context => ({ ...context, config: hopsConfig }),
  });

  server.applyMiddleware({
    app,
    path: hopsConfig.graphqlMockServerPath,
    cors: {
      credentials: true,
      origin: true,
      methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
      allowedHeaders: 'content-type',
    },
  });

  return app;
});

export default (req, res, next) => {
  apolloAppPromise.then(app => app.handle(req, res, next), next);
};
<|endoftext|>


<commit_before>'use babel';

import Redmine from 'promised-redmine';

import {CompositeDisposable} from 'atom';
import CSON from 'season';
import _path from 'path';

import IssuesListView from './views/issues-list-view';

var redmine;

const CONFIG_PATH = '.atom-redmine';

export default {
  config: {
    host: {
      title: 'Redmine Host',
      description: 'The hostname of the Redmine instance.',
      type: 'string',
      default: null
    },
    apiKey: {
      title: 'Redmine API Key',
      description: 'The Redmine api key which can be found on the My Account page',
      type: 'string',
      default: null
    }
  },

  subscriptions: null,

  redmine: null,
  projectId: null,

  issuesListView: null,

  activate(state) {
    this.redmine = new Redmine({
      host: atom.config.get('redmine.host'),
      apiKey: atom.config.get('redmine.apiKey')
    });
    if(!this.readConfigFile()) {
      atom.notifications.addError(
        `Atom Redmine Error

        ${CONFIG_PATH} config file not found. See the README for details.`,
        { dismissable: true }
      );
      return false;
    }

    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'redmine:my-issues': ()=> this.listIssues({ assigned_to_id: 'me' }),
      'redmine:all-issues': ()=> this.listIssues()
    }));
  },

  deactivate() {
    this.subscriptions.dispose();
  },

  readConfigFile() {
    var configured = false;
    atom.project.getPaths().forEach((path)=> {
      var configPath = path + _path.sep + CONFIG_PATH;
      if(atom.project.contains(configPath)) {
        var config = CSON.readFileSync(configPath);
        if(config) {
          var complete = true;
          if(config.projectId) {
            this.projectId = config.projectId;
          } else {
            complete = false;
          }
          configured = configured || complete;
        }
      }
    });
    return configured;
  },

  listIssues(options={}) {
    var params = { project_id: this.projectId };
    Object.getOwnPropertyNames(options).forEach(key => params[key] = options[key]);
    var issues = this.redmine.getIssues(params);
    this.createIssuesListView().show(issues);
    issues.then(undefined, this.showError);
  },

  createIssuesListView() {
    return this.issuesListView || (this.issuesListView = new IssuesListView());
  },

  setProject() {
    console.log('setting project!');
  },

  showError(error) {
    console.error('error in atom-redmine', error);
    // ["STATUSCODE_REJECTION 404"]
  }
};
<commit_msg>Added "Redmine: Open Project" command<commit_after>'use babel';

import Redmine from 'promised-redmine';

import {CompositeDisposable} from 'atom';
import CSON from 'season';
import _path from 'path';

import shell from 'shell';

import IssuesListView from './views/issues-list-view';

var redmine;

const CONFIG_PATH = '.atom-redmine';

export default {
  config: {
    host: {
      title: 'Redmine Host',
      description: 'The hostname of the Redmine instance.',
      type: 'string',
      default: null
    },
    apiKey: {
      title: 'Redmine API Key',
      description: 'The Redmine api key which can be found on the My Account page',
      type: 'string',
      default: null
    }
  },

  subscriptions: null,

  redmine: null,
  projectId: null,

  issuesListView: null,

  activate(state) {
    this.redmine = new Redmine({
      host: atom.config.get('redmine.host'),
      apiKey: atom.config.get('redmine.apiKey')
    });
    if(!this.readConfigFile()) {
      atom.notifications.addError(
        `Atom Redmine Error

        ${CONFIG_PATH} config file not found. See the README for details.`,
        { dismissable: true }
      );
      return false;
    }

    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'redmine:my-issues': ()=> this.listIssues({ assigned_to_id: 'me' }),
      'redmine:all-issues': ()=> this.listIssues(),
      'redmine:open-project': ()=> this.openProject()
    }));
  },

  deactivate() {
    this.subscriptions.dispose();
  },

  readConfigFile() {
    var configured = false;
    atom.project.getPaths().forEach((path)=> {
      var configPath = path + _path.sep + CONFIG_PATH;
      if(atom.project.contains(configPath)) {
        var config = CSON.readFileSync(configPath);
        if(config) {
          var complete = true;
          if(config.projectId) {
            this.projectId = config.projectId;
          } else {
            complete = false;
          }
          configured = configured || complete;
        }
      }
    });
    return configured;
  },

  listIssues(options={}) {
    var params = { project_id: this.projectId };
    Object.getOwnPropertyNames(options).forEach(key => params[key] = options[key]);
    var issues = this.redmine.getIssues(params);
    this.createIssuesListView().show(issues);
    issues.then(undefined, this.showError);
  },

  createIssuesListView() {
    return this.issuesListView || (this.issuesListView = new IssuesListView());
  },

  openProject() {
    shell.openExternal(`http://${atom.config.get('redmine.host')}/projects/${this.projectId}`);
  },

  showError(error) {
    console.error('error in atom-redmine', error);
    // ["STATUSCODE_REJECTION 404"]
  }
};
<|endoftext|>


<commit_before>'use strict';

angular.module('openSenseMapApp')
.controller('InterpolationCtrl',
	["$scope", "$stateParams", "$http", "OpenSenseBoxAPI", "leafletData", "$timeout", "moment", function($scope, $stateParams, $http, OpenSenseBoxAPI, leafletData, $timeout, moment){

    $scope.calculating = false;
    $scope.interpolationPickerStart = {
      date: moment().toDate(),
      open: false,
      buttonBar: {
        show: false
      },
      timepickerOptions: {
        readonlyInput: false,
        showMeridian: false,
        max: moment().toDate()
      }
    };
    $scope.interpolationPickerEnd = {
      date: moment().toDate(),
      open: false,
      buttonBar: {
        show: false
      },
      timepickerOptions: {
        readonlyInput: false,
        showMeridian: false,
        max: moment().toDate()
      }
    };

    $scope.visible = false;
    var dates = [];
    $scope.selectedTimeStep = Date.now();
    $scope.slider = {
      options: {
        stepsArray: dates,
        showTicks: true,
        hidePointerLabels: true,
        hideLimitLabels: true,
        onChange: function(id, value) {
          $scope.selectedTimeStep = value;
          $scope.map.removeLayer($scope.layer);
          $scope.layer = createGeoJsonLayer(featureCollections[dates.indexOf(value)], breaks);
          $scope.map.addLayer($scope.layer);
        }
      }
    };
    $scope.refreshSlider = function () {
      $timeout(function () {
        $scope.$broadcast('rzSliderForceRender');
      });
    };

    $scope.$watch('interpolationPickerEnd.open', function(newValue) {
      console.log($scope.interpolationPickerEnd.open);
    });

    $scope.legendTitle = '';
    $scope.legendEntries = [];

    $scope.alerts = [];
    $scope.closeAlert = function(index) {
      $scope.alerts.splice(index, 1);
    };

    $scope.idwPower = 3;
    $scope.cellWidth = 1;
    $scope.numTimeSteps = 1;
    $scope.exposure = "outdoor";
    $scope.layerGroup;
    $scope.selectedPhenomenon = "";
    $scope.map;

    $scope.minIDWPower = 1;
    $scope.maxIDWPower = 9;

    $scope.changeIDWPower = function(number) {
      var newValue = $scope.idwPower + number;
      if (newValue >= $scope.minIDWPower && newValue <= $scope.maxIDWPower) {
        $scope.idwPower += number;
      }
    }

    $scope.minNumTimeSteps = 1;
    $scope.maxNumTimeSteps = 9;

    $scope.changeNumTimeSteps = function(number) {
      var newValue = $scope.numTimeSteps + number;
      if (newValue >= $scope.minNumTimeSteps && newValue <= $scope.maxNumTimeSteps) {
        $scope.numTimeSteps += number;
      }
    }

    $scope.layer;
    var colors = "#A2F689,#B1E36F,#BCD05B,#C4BD4C,#C8AA44,#C99840".split(",");
    var breaks = [];
    var idwLayers = [];
    var featureCollections = [];
    $scope.calculateInterpolation = function () {
      clearInterpolation();
      $scope.calculating = true;

      leafletData.getMap('map_main').then(function (map) {
        if (!angular.isUndefined($scope.layer)) {
          $scope.map.removeLayer($scope.layer);
        }
        $scope.map = map;
        return map.getBounds().toBBoxString();
      }).then(function (bbox) {
        $http.get(OpenSenseBoxAPI.url+'/statistics/idw', {
          params: {
            'phenomenon': $scope.selectedPhenomenon,
            'from-date': moment($scope.interpolationPickerStart.date).toISOString(),
            'to-date': moment($scope.interpolationPickerEnd.date).toISOString(),
            'exposure': $scope.exposure,
            'cellWidth': $scope.cellWidth,
            'power': $scope.idwPower,
            'numClasses': 6,
            'bbox': bbox,
            'numTimeSteps': $scope.numTimeSteps
          }
        })
        .then(function (response) {
          if (response.data.code === 'NotFoundError') {
            return response;
          }

          dates = [];
          response.data.data.timesteps.forEach(function (element, index) {
            dates.push(new Date(element));
            featureCollections.push({type: "FeatureCollection", features: []});
          });

          $scope.slider.value = dates[0];
          $scope.slider.options.stepsArray = dates;
          $scope.selectedTimeStep = dates[0];

          breaks = response.data.data.breaks;

          // Set legend title
          switch ($scope.selectedPhenomenon) {
            case 'Temperatur':
              $scope.legendTitle = $scope.selectedPhenomenon + " in °C"
              break;
            case 'rel. Luftfeuchte':
              $scope.legendTitle = $scope.selectedPhenomenon + " in %"
              break;
            case 'Luftdruck':
              $scope.legendTitle = $scope.selectedPhenomenon + " in hPa"
              break;
            case 'Beleuchtungsstärke':
              $scope.legendTitle = $scope.selectedPhenomenon + " in lx"
              break;
            case 'UV-Intensität':
              $scope.legendTitle = $scope.selectedPhenomenon + " in μW/cm²"
              break;
          }

          // Generate legend
          for (var j = 0; j < breaks.length; j++) {
            var caption = "";
            if (j === breaks.length-1) {
              caption = "> " + breaks[j].toFixed(2);
            } else {
              caption = breaks[j].toFixed(2) +' - '+ breaks[j+1].toFixed(2);
            }
            $scope.legendEntries.push({
              caption: caption,
              style:{
                'background': colors[j]
              }
            });
          }

          response.data.data.featureCollection.features.map(function (feature) {
            for (var i = 0; i < feature.properties.idwValues.length; i++) {
              var newFeature = {};
              angular.copy(feature, newFeature);
              newFeature.properties.idwValues = [];
              var value = feature.properties.idwValues[i];
              newFeature.properties.idwValues.push(value);
              featureCollections[i].features.push(newFeature);
            }
          });

          $scope.layer = createGeoJsonLayer(featureCollections[0], breaks);
          $scope.map.addLayer($scope.layer);

          if (featureCollections.length > 1) {
            $scope.visible = true;
          }
          $scope.refreshSlider();

          return;
        }, function(error) {
          return error;
        })
        .then(function (error) {
          if (angular.isUndefined(error)) {
            return;
          }

          switch (error.data.message) {
            case "planned computation too expensive ((area in square kilometers / cellWidth) > 2500)":
              $scope.alerts.push({msg: 'Der gewählte Kartenausschnitt ist zu groß!'});
              break;
            case "Invalid time frame specified: to-date is in the future":
              $scope.alerts.push({msg: 'Das gewählte Datum darf nicht in der Zukunft liegen!'});
              break;
            case "no senseBoxes found":
              $scope.alerts.push({msg: 'Es konnten keine senseBoxen für die Filtereinstellungen gefunden werden!'});
              break;
            case "no measurements found":
              $scope.alerts.push({msg: 'Es wurden keine Messungen für den angegebenen Zeitpunkt gefunden!'});
              break;
            default:
              $scope.alerts.push({msg: 'Bei der Interpolation ist ein unbekannter Fehler aufgetreten! Bitte überprüfe die Filtereinstellungen.'});
              break;
          }
        })
        .finally(function () {
          $scope.calculating = false;
        });
      });
    };

    function createGeoJsonLayer (featureCollection, breaks) {
      var idwLayer = L.geoJson(featureCollection, {
        style: function (feature) {
          var props = feature.properties;
          for (var key in props) {
            var z = props[key];
            if (!Number.isNaN(z)) {
              var fillColor = colors[0];
              for (var i = 0; i < breaks.length; i++) {
                if (z >= breaks[i]) {
                  fillColor = colors[i];
                } else {
                  break;
                }
              }
              return {
                weight: 0.1,
                fillOpacity: 0.6,
                fillColor: fillColor
              }
            }
            return {
              weight: 0,
              fillColor: "red",
              fillOpacity: 1
            };
          }
        }
      });
      return idwLayer;
    }

    function clearInterpolation () {
      $scope.alerts.length = 0;
      $scope.legendEntries.length = 0;
      $scope.legendTitle = '';
      idwLayers = [];
      featureCollections = [];
      breaks = [];
      if (!angular.isUndefined($scope.map) && !angular.isUndefined($scope.layer)) {
        $scope.map.removeLayer($scope.layer);
        delete $scope.layer;
        $scope.visible = false;
      }
    }

    $scope.removeInterpolation = function () {
      clearInterpolation();
    }

    $scope.showRemoveInterpolation = function () {
      if (!angular.isUndefined($scope.map) && !angular.isUndefined($scope.layer)) {
        return true;
      }
      return false;
    }

    $scope.openCalendar = function(e, picker) {
      e.preventDefault();
      e.stopPropagation();
      switch(picker) {
        case 'interpolationPickerStart':
          $scope.interpolationPickerStart.open = true;
          $scope.interpolationPickerStart.timepickerOptions.max = moment($scope.interpolationPickerEnd.date).toISOString();
          break;
        case 'interpolationPickerEnd':
          console.log(angular.element('#interpolationPickerEnd').parent());
          $scope.interpolationPickerEnd.open = true;
          $scope.interpolationPickerEnd.timepickerOptions.max = moment().toDate();
          break;
      }
    };

    $scope.selectExposure = function (exposure) {
      $scope.exposure = exposure;
    };

    $scope.closeSidebar = function () {
      if (!angular.isUndefined($scope.map) && !angular.isUndefined($scope.layer)) {
        clearInterpolation()
      }
    }
}]);
<commit_msg>place popup on bottom-right<commit_after>'use strict';

angular.module('openSenseMapApp')
.controller('InterpolationCtrl',
	["$scope", "$stateParams", "$http", "OpenSenseBoxAPI", "leafletData", "$timeout", "moment", function($scope, $stateParams, $http, OpenSenseBoxAPI, leafletData, $timeout, moment){

    $scope.calculating = false;
    $scope.interpolationPickerStart = {
      date: moment().toDate(),
      open: false,
      buttonBar: {
        show: false
      },
      timepickerOptions: {
        readonlyInput: false,
        showMeridian: false,
        max: moment().toDate()
      }
    };
    $scope.interpolationPickerEnd = {
      date: moment().toDate(),
      open: false,
      buttonBar: {
        show: false
      },
      timepickerOptions: {
        readonlyInput: false,
        showMeridian: false,
        max: moment().toDate()
      }
    };

    $scope.visible = false;
    var dates = [];
    $scope.selectedTimeStep = Date.now();
    $scope.slider = {
      options: {
        stepsArray: dates,
        showTicks: true,
        hidePointerLabels: true,
        hideLimitLabels: true,
        onChange: function(id, value) {
          $scope.selectedTimeStep = value;
          $scope.map.removeLayer($scope.layer);
          $scope.layer = createGeoJsonLayer(featureCollections[dates.indexOf(value)], breaks);
          $scope.map.addLayer($scope.layer);
        }
      }
    };
    $scope.refreshSlider = function () {
      $timeout(function () {
        $scope.$broadcast('rzSliderForceRender');
      });
    };

    $scope.legendTitle = '';
    $scope.legendEntries = [];

    $scope.alerts = [];
    $scope.closeAlert = function(index) {
      $scope.alerts.splice(index, 1);
    };

    $scope.idwPower = 3;
    $scope.cellWidth = 1;
    $scope.numTimeSteps = 1;
    $scope.exposure = "outdoor";
    $scope.layerGroup;
    $scope.selectedPhenomenon = "";
    $scope.map;

    $scope.minIDWPower = 1;
    $scope.maxIDWPower = 9;

    $scope.changeIDWPower = function(number) {
      var newValue = $scope.idwPower + number;
      if (newValue >= $scope.minIDWPower && newValue <= $scope.maxIDWPower) {
        $scope.idwPower += number;
      }
    }

    $scope.minNumTimeSteps = 1;
    $scope.maxNumTimeSteps = 9;

    $scope.changeNumTimeSteps = function(number) {
      var newValue = $scope.numTimeSteps + number;
      if (newValue >= $scope.minNumTimeSteps && newValue <= $scope.maxNumTimeSteps) {
        $scope.numTimeSteps += number;
      }
    }

    $scope.layer;
    var colors = "#A2F689,#B1E36F,#BCD05B,#C4BD4C,#C8AA44,#C99840".split(",");
    var breaks = [];
    var idwLayers = [];
    var featureCollections = [];
    $scope.calculateInterpolation = function () {
      clearInterpolation();
      $scope.calculating = true;

      leafletData.getMap('map_main').then(function (map) {
        if (!angular.isUndefined($scope.layer)) {
          $scope.map.removeLayer($scope.layer);
        }
        $scope.map = map;
        return map.getBounds().toBBoxString();
      }).then(function (bbox) {
        $http.get(OpenSenseBoxAPI.url+'/statistics/idw', {
          params: {
            'phenomenon': $scope.selectedPhenomenon,
            'from-date': moment($scope.interpolationPickerStart.date).toISOString(),
            'to-date': moment($scope.interpolationPickerEnd.date).toISOString(),
            'exposure': $scope.exposure,
            'cellWidth': $scope.cellWidth,
            'power': $scope.idwPower,
            'numClasses': 6,
            'bbox': bbox,
            'numTimeSteps': $scope.numTimeSteps
          }
        })
        .then(function (response) {
          if (response.data.code === 'NotFoundError') {
            return response;
          }

          dates = [];
          response.data.data.timesteps.forEach(function (element, index) {
            dates.push(new Date(element));
            featureCollections.push({type: "FeatureCollection", features: []});
          });

          $scope.slider.value = dates[0];
          $scope.slider.options.stepsArray = dates;
          $scope.selectedTimeStep = dates[0];

          breaks = response.data.data.breaks;

          // Set legend title
          switch ($scope.selectedPhenomenon) {
            case 'Temperatur':
              $scope.legendTitle = $scope.selectedPhenomenon + " in °C"
              break;
            case 'rel. Luftfeuchte':
              $scope.legendTitle = $scope.selectedPhenomenon + " in %"
              break;
            case 'Luftdruck':
              $scope.legendTitle = $scope.selectedPhenomenon + " in hPa"
              break;
            case 'Beleuchtungsstärke':
              $scope.legendTitle = $scope.selectedPhenomenon + " in lx"
              break;
            case 'UV-Intensität':
              $scope.legendTitle = $scope.selectedPhenomenon + " in μW/cm²"
              break;
          }

          // Generate legend
          for (var j = 0; j < breaks.length; j++) {
            var caption = "";
            if (j === breaks.length-1) {
              caption = "> " + breaks[j].toFixed(2);
            } else {
              caption = breaks[j].toFixed(2) +' - '+ breaks[j+1].toFixed(2);
            }
            $scope.legendEntries.push({
              caption: caption,
              style:{
                'background': colors[j]
              }
            });
          }

          response.data.data.featureCollection.features.map(function (feature) {
            for (var i = 0; i < feature.properties.idwValues.length; i++) {
              var newFeature = {};
              angular.copy(feature, newFeature);
              newFeature.properties.idwValues = [];
              var value = feature.properties.idwValues[i];
              newFeature.properties.idwValues.push(value);
              featureCollections[i].features.push(newFeature);
            }
          });

          $scope.layer = createGeoJsonLayer(featureCollections[0], breaks);
          $scope.map.addLayer($scope.layer);

          if (featureCollections.length > 1) {
            $scope.visible = true;
          }
          $scope.refreshSlider();

          return;
        }, function(error) {
          return error;
        })
        .then(function (error) {
          if (angular.isUndefined(error)) {
            return;
          }

          switch (error.data.message) {
            case "planned computation too expensive ((area in square kilometers / cellWidth) > 2500)":
              $scope.alerts.push({msg: 'Der gewählte Kartenausschnitt ist zu groß!'});
              break;
            case "Invalid time frame specified: to-date is in the future":
              $scope.alerts.push({msg: 'Das gewählte Datum darf nicht in der Zukunft liegen!'});
              break;
            case "no senseBoxes found":
              $scope.alerts.push({msg: 'Es konnten keine senseBoxen für die Filtereinstellungen gefunden werden!'});
              break;
            case "no measurements found":
              $scope.alerts.push({msg: 'Es wurden keine Messungen für den angegebenen Zeitpunkt gefunden!'});
              break;
            default:
              $scope.alerts.push({msg: 'Bei der Interpolation ist ein unbekannter Fehler aufgetreten! Bitte überprüfe die Filtereinstellungen.'});
              break;
          }
        })
        .finally(function () {
          $scope.calculating = false;
        });
      });
    };

    function createGeoJsonLayer (featureCollection, breaks) {
      var idwLayer = L.geoJson(featureCollection, {
        style: function (feature) {
          var props = feature.properties;
          for (var key in props) {
            var z = props[key];
            if (!Number.isNaN(z)) {
              var fillColor = colors[0];
              for (var i = 0; i < breaks.length; i++) {
                if (z >= breaks[i]) {
                  fillColor = colors[i];
                } else {
                  break;
                }
              }
              return {
                weight: 0.1,
                fillOpacity: 0.6,
                fillColor: fillColor
              }
            }
            return {
              weight: 0,
              fillColor: "red",
              fillOpacity: 1
            };
          }
        }
      });
      return idwLayer;
    }

    function clearInterpolation () {
      $scope.alerts.length = 0;
      $scope.legendEntries.length = 0;
      $scope.legendTitle = '';
      idwLayers = [];
      featureCollections = [];
      breaks = [];
      if (!angular.isUndefined($scope.map) && !angular.isUndefined($scope.layer)) {
        $scope.map.removeLayer($scope.layer);
        delete $scope.layer;
        $scope.visible = false;
      }
    }

    $scope.removeInterpolation = function () {
      clearInterpolation();
    }

    $scope.showRemoveInterpolation = function () {
      if (!angular.isUndefined($scope.map) && !angular.isUndefined($scope.layer)) {
        return true;
      }
      return false;
    }

    $scope.openCalendar = function(e, picker) {
      e.preventDefault();
      e.stopPropagation();
      switch(picker) {
        case 'interpolationPickerStart':
          $scope.interpolationPickerStart.open = true;
          $scope.interpolationPickerStart.timepickerOptions.max = moment($scope.interpolationPickerEnd.date).toISOString();
          break;
        case 'interpolationPickerEnd':
          $scope.interpolationPickerEnd.open = true;
          $scope.interpolationPickerEnd.timepickerOptions.max = moment().toDate();
          $timeout(function () {
            angular.element('#interpolationPickerEnd').parent()[0].children[1].style.right = "0px";
            angular.element('#interpolationPickerEnd').parent()[0].children[1].style.left = "auto";
          });
          break;
      }
    };

    $scope.selectExposure = function (exposure) {
      $scope.exposure = exposure;
    };

    $scope.closeSidebar = function () {
      if (!angular.isUndefined($scope.map) && !angular.isUndefined($scope.layer)) {
        clearInterpolation()
      }
    }
}]);
<|endoftext|>