<commit_before>/*jslint node: true */

/*
 * #%L
 * %%
 * Copyright (C) 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

var joynr = require("joynr");
var ComplexStruct = require("../generated-javascript/joynr/tests/performance/Types/ComplexStruct.js");
var testbase = require("test-base");
var PerformanceUtilities = require("./performanceutilities.js");
var Promise = require("bluebird").Promise;

var error = testbase.logging.error;
var log = testbase.logging.log;
var options = PerformanceUtilities.getCommandLineOptionsOrDefaults(process.env);
var timeout = 600000;

var consumerBase = {
    echoProxy : undefined,
    initialize: function() {
        if (consumerBase.echoProxy === undefined) {
            console.log("Using domain " + options.domain);
            console.error("Performing " + options.numRuns + " runs");
            error ("test runs: " + options.testRuns);
            var viaClusterController = options.viacc == "true";
            console.log("Via cluster-contoller: " + viaClusterController);
            var provisioning = testbase.provisioning_common;
            if (viaClusterController) {
                provisioning.ccAddress.host = options.cchost;
                provisioning.ccAddress.port = options.ccport;
                joynr.selectRuntime("websocket.libjoynr");
            } else {
                provisioning.bounceProxyBaseUrl = options.bounceProxyBaseUrl;
                provisioning.brokerUri = options.brokerUri;
                provisioning.bounceProxyUrl = provisioning.bounceProxyBaseUrl + "/bounceproxy/";
                joynr.selectRuntime("inprocess");
            }
            provisioning.logging.configuration.loggers.root.level = "error";
            return joynr.load(provisioning).then(function(loadedJoynr) {
                joynr = loadedJoynr;
                log("joynr started");
                if (!viaClusterController) {
                    consumerBase.registerProvider();
                }
                return loadedJoynr;
            }).then(function(loadedJoynr) {
                var messagingQos = new loadedJoynr.messaging.MessagingQos({
                    ttl: timeout
                });
                var EchoProxy = require("../generated-javascript/joynr/tests/performance/EchoProxy.js");
                return loadedJoynr.proxyBuilder.build(EchoProxy, {
                    domain      : options.domain,
                    messagingQos: messagingQos
                });
            }).then(function(echoProxy) {
                consumerBase.echoProxy = echoProxy;
                return null;
            }).catch(function(error) {
                throw error;
            });
        } else {
            return Promise.resolve();
        }
    },
    shutdown: function() {
        return joynr.shutdown();
    },
    registerProvider: function() {
        var providerQos = new joynr.types.ProviderQos({
            customParameters             : [],
            priority                     : Date.now(),
            scope                        : joynr.types.ProviderScope.LOCAL,
            supportsOnChangeSubscriptions: true
        });

        var EchoProvider = require("../generated-javascript/joynr/tests/performance/EchoProvider.js");
        var EchoProviderImpl = require("./EchoProviderImpl.js");
        var echoProvider = joynr.providerBuilder.build( EchoProvider, EchoProviderImpl.implementation);

        joynr.registration.registerProvider(options.domain, echoProvider, providerQos).then(function() {
            log("provider registered successfully");
        }).catch(function(e) {
            error("error registering provider: " + e.toString());
        });
    },

    executeBenchmark: function(benchmarkName, benchmarkData, benchmark){
        var numRuns = benchmarkData.length;
        log("call " + benchmarkName + " " + numRuns + " times");
        PerformanceUtilities.forceGC();
        var startTime = Date.now();

        return Promise.map(benchmarkData, function(data){
            return benchmark(data);
        }).then(function(){
            log("all the numRuns were executed");
            var elapsedTimeMs = Date.now() - startTime;

            error(benchmarkName + " runs: " + numRuns + " took " + elapsedTimeMs + " ms. " + numRuns / (elapsedTimeMs / 1000) + " msgs/s");
            return elapsedTimeMs;
        });
    },

    excecuteMultipleBenchmarks: function(benchmarkName, generateBenchmarkData, benchmark) {
        var numRuns = options.numRuns;
        var testRuns = options.testRuns ? Number.parseInt(options.testRuns) : 1;
        var totalRuns = numRuns * testRuns;
        var totalTime = 0;
        var testIndex = 0;
        var dummyArray = new Array(testRuns);
        var runsTime = [];
        return Promise.map(dummyArray, function(){
            var data = [];
            for (var j = 0; j < numRuns; j++){
                data.push(generateBenchmarkData(j));
            }
            testIndex++;
            var name = benchmarkName + " Test: " + testIndex;
            return consumerBase.executeBenchmark(name, data, benchmark )
                .then(function(time){
                    totalTime += time;
                    runsTime.push(time);
                });
        }, { concurrency: 1 })
            .then(function () {
                var averageTime = totalRuns / (totalTime / 1000);
                var variance = 0;
                runsTime.map(function(time){
                    return numRuns / (time / 1000);
                }).forEach(function (time) {
                    variance += Math.pow(time - averageTime, 2);
                });
                variance /= runsTime.length;
                var deviation = Math.sqrt(variance);
                error("the total runtime was: " + totalTime + " runs: " + totalRuns + " msgs/s: " + averageTime + " +/- " + deviation);
            });
    },
    echoString: function() {
        var generateData = function(i) {
            return {
                data: PerformanceUtilities.createString(options.stringLength - 2, "x") + "-" + i
            };
        };
        var testProcedure = function(args) {
            return consumerBase.echoProxy.echoString(args).then(function(returnValues) {
                if (args.data !== returnValues.responseData) {
                    throw new Error("Echo " + JSON.stringify(returnValues.responseData) + " does not match input data: " + JSON.stringify(args.data));
                }
                return returnValues;
            });
        };
        return consumerBase.excecuteMultipleBenchmarks("echoString", generateData, testProcedure);
    },
    echoComplexStruct: function() {
        var generateData = function(i){
            return {
                data: new ComplexStruct({
                    num32: PerformanceUtilities.createRandomNumber(100000),
                    num64: PerformanceUtilities.createRandomNumber(1000000),
                    data : PerformanceUtilities.createByteArray(options.byteArrayLength, 1),
                    str  : PerformanceUtilities.createString(options.stringLength - 2, "x") + "-" + i
                })
            };
        };
        var testProcedure = function(args) {
            return consumerBase.echoProxy.echoComplexStruct(args).then(function(returnValues) {
                if (args.data.num32 !== returnValues.responseData.num32 ||
                args.data.num64 !== returnValues.responseData.num64 ||
                args.data.data.length !== returnValues.responseData.data.length ||
                args.data.str.length !== returnValues.responseData.str.length) {
                    throw new Error("Echo " + JSON.stringify(returnValues.responseData) + " does not match input data: " + JSON.stringify(args.data));
                }
                return returnValues;
            });
        };
        return consumerBase.excecuteMultipleBenchmarks("echoComplexStruct", generateData, testProcedure);
    },
    echoByteArray: function(byteArraySizeFactor) {
        byteArraySizeFactor = byteArraySizeFactor || 1;
        var byteArraySize = byteArraySizeFactor * options.byteArrayLength;
        var generateData = function(i){
            var args = {
                data: PerformanceUtilities.createByteArray(byteArraySize, 1)
            };
            var firstElement = i % 128;
            args.data[0] = firstElement;
            return args;
        };
        var testProcedure = function(args) {
            return consumerBase.echoProxy.echoByteArray(args).then(function(returnValues, i) {
                var firstElement = args.data[0];
                if (args.data.length !== returnValues.responseData.length ||
                firstElement !== returnValues.responseData[0]) {
                    throw new Error("Echo " + JSON.stringify(returnValues.responseData) + " does not match input data: " + JSON.stringify(args.data));
                }

                return returnValues;
            });
        };
        // the larger this byteArraySizeFactor is, the longer this test takes
        // in order to mitigate that, we scale the numer of runs by byteArraySizeFactor
        var numRuns = options.numRuns;
        if (byteArraySizeFactor > 1) {
            numRuns = numRuns / Math.sqrt(byteArraySizeFactor);
        }
        return consumerBase.excecuteMultipleBenchmarks("echoByteArray " + byteArraySize, generateData, testProcedure, numRuns);
    },
    echoByteArrayWithSizeTimesK: function() {
        if (options.skipByteArraySizeTimesK === undefined || options.skipByteArraySizeTimesK === true) {
            consumerBase.echoByteArray(1000);
        }
    }
};
module.exports = consumerBase;
<commit_msg>[JS] performance-tests: avoid shadow in error handler<commit_after>/*jslint node: true */

/*
 * #%L
 * %%
 * Copyright (C) 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

var joynr = require("joynr");
var ComplexStruct = require("../generated-javascript/joynr/tests/performance/Types/ComplexStruct.js");
var testbase = require("test-base");
var PerformanceUtilities = require("./performanceutilities.js");
var Promise = require("bluebird").Promise;

var error = testbase.logging.error;
var log = testbase.logging.log;
var options = PerformanceUtilities.getCommandLineOptionsOrDefaults(process.env);
var timeout = 600000;

var consumerBase = {
    echoProxy : undefined,
    initialize: function() {
        if (consumerBase.echoProxy === undefined) {
            console.log("Using domain " + options.domain);
            console.error("Performing " + options.numRuns + " runs");
            error ("test runs: " + options.testRuns);
            var viaClusterController = options.viacc == "true";
            console.log("Via cluster-contoller: " + viaClusterController);
            var provisioning = testbase.provisioning_common;
            if (viaClusterController) {
                provisioning.ccAddress.host = options.cchost;
                provisioning.ccAddress.port = options.ccport;
                joynr.selectRuntime("websocket.libjoynr");
            } else {
                provisioning.bounceProxyBaseUrl = options.bounceProxyBaseUrl;
                provisioning.brokerUri = options.brokerUri;
                provisioning.bounceProxyUrl = provisioning.bounceProxyBaseUrl + "/bounceproxy/";
                joynr.selectRuntime("inprocess");
            }
            provisioning.logging.configuration.loggers.root.level = "error";
            return joynr.load(provisioning).then(function(loadedJoynr) {
                joynr = loadedJoynr;
                log("joynr started");
                if (!viaClusterController) {
                    consumerBase.registerProvider();
                }
                return loadedJoynr;
            }).then(function(loadedJoynr) {
                var messagingQos = new loadedJoynr.messaging.MessagingQos({
                    ttl: timeout
                });
                var EchoProxy = require("../generated-javascript/joynr/tests/performance/EchoProxy.js");
                return loadedJoynr.proxyBuilder.build(EchoProxy, {
                    domain      : options.domain,
                    messagingQos: messagingQos
                });
            }).then(function(echoProxy) {
                consumerBase.echoProxy = echoProxy;
                return null;
            }).catch(function(e) {
                throw e;
            });
        } else {
            return Promise.resolve();
        }
    },
    shutdown: function() {
        return joynr.shutdown();
    },
    registerProvider: function() {
        var providerQos = new joynr.types.ProviderQos({
            customParameters             : [],
            priority                     : Date.now(),
            scope                        : joynr.types.ProviderScope.LOCAL,
            supportsOnChangeSubscriptions: true
        });

        var EchoProvider = require("../generated-javascript/joynr/tests/performance/EchoProvider.js");
        var EchoProviderImpl = require("./EchoProviderImpl.js");
        var echoProvider = joynr.providerBuilder.build( EchoProvider, EchoProviderImpl.implementation);

        joynr.registration.registerProvider(options.domain, echoProvider, providerQos).then(function() {
            log("provider registered successfully");
        }).catch(function(e) {
            error("error registering provider: " + e.toString());
        });
    },

    executeBenchmark: function(benchmarkName, benchmarkData, benchmark){
        var numRuns = benchmarkData.length;
        log("call " + benchmarkName + " " + numRuns + " times");
        PerformanceUtilities.forceGC();
        var startTime = Date.now();

        return Promise.map(benchmarkData, function(data){
            return benchmark(data);
        }).then(function(){
            log("all the numRuns were executed");
            var elapsedTimeMs = Date.now() - startTime;

            error(benchmarkName + " runs: " + numRuns + " took " + elapsedTimeMs + " ms. " + numRuns / (elapsedTimeMs / 1000) + " msgs/s");
            return elapsedTimeMs;
        });
    },

    excecuteMultipleBenchmarks: function(benchmarkName, generateBenchmarkData, benchmark) {
        var numRuns = options.numRuns;
        var testRuns = options.testRuns ? Number.parseInt(options.testRuns) : 1;
        var totalRuns = numRuns * testRuns;
        var totalTime = 0;
        var testIndex = 0;
        var dummyArray = new Array(testRuns);
        var runsTime = [];
        return Promise.map(dummyArray, function(){
            var data = [];
            for (var j = 0; j < numRuns; j++){
                data.push(generateBenchmarkData(j));
            }
            testIndex++;
            var name = benchmarkName + " Test: " + testIndex;
            return consumerBase.executeBenchmark(name, data, benchmark )
                .then(function(time){
                    totalTime += time;
                    runsTime.push(time);
                });
        }, { concurrency: 1 })
            .then(function () {
                var averageTime = totalRuns / (totalTime / 1000);
                var variance = 0;
                runsTime.map(function(time){
                    return numRuns / (time / 1000);
                }).forEach(function (time) {
                    variance += Math.pow(time - averageTime, 2);
                });
                variance /= runsTime.length;
                var deviation = Math.sqrt(variance);
                error("the total runtime was: " + totalTime + " runs: " + totalRuns + " msgs/s: " + averageTime + " +/- " + deviation);
            });
    },
    echoString: function() {
        var generateData = function(i) {
            return {
                data: PerformanceUtilities.createString(options.stringLength - 2, "x") + "-" + i
            };
        };
        var testProcedure = function(args) {
            return consumerBase.echoProxy.echoString(args).then(function(returnValues) {
                if (args.data !== returnValues.responseData) {
                    throw new Error("Echo " + JSON.stringify(returnValues.responseData) + " does not match input data: " + JSON.stringify(args.data));
                }
                return returnValues;
            });
        };
        return consumerBase.excecuteMultipleBenchmarks("echoString", generateData, testProcedure);
    },
    echoComplexStruct: function() {
        var generateData = function(i){
            return {
                data: new ComplexStruct({
                    num32: PerformanceUtilities.createRandomNumber(100000),
                    num64: PerformanceUtilities.createRandomNumber(1000000),
                    data : PerformanceUtilities.createByteArray(options.byteArrayLength, 1),
                    str  : PerformanceUtilities.createString(options.stringLength - 2, "x") + "-" + i
                })
            };
        };
        var testProcedure = function(args) {
            return consumerBase.echoProxy.echoComplexStruct(args).then(function(returnValues) {
                if (args.data.num32 !== returnValues.responseData.num32 ||
                args.data.num64 !== returnValues.responseData.num64 ||
                args.data.data.length !== returnValues.responseData.data.length ||
                args.data.str.length !== returnValues.responseData.str.length) {
                    throw new Error("Echo " + JSON.stringify(returnValues.responseData) + " does not match input data: " + JSON.stringify(args.data));
                }
                return returnValues;
            });
        };
        return consumerBase.excecuteMultipleBenchmarks("echoComplexStruct", generateData, testProcedure);
    },
    echoByteArray: function(byteArraySizeFactor) {
        byteArraySizeFactor = byteArraySizeFactor || 1;
        var byteArraySize = byteArraySizeFactor * options.byteArrayLength;
        var generateData = function(i){
            var args = {
                data: PerformanceUtilities.createByteArray(byteArraySize, 1)
            };
            var firstElement = i % 128;
            args.data[0] = firstElement;
            return args;
        };
        var testProcedure = function(args) {
            return consumerBase.echoProxy.echoByteArray(args).then(function(returnValues, i) {
                var firstElement = args.data[0];
                if (args.data.length !== returnValues.responseData.length ||
                firstElement !== returnValues.responseData[0]) {
                    throw new Error("Echo " + JSON.stringify(returnValues.responseData) + " does not match input data: " + JSON.stringify(args.data));
                }

                return returnValues;
            });
        };
        // the larger this byteArraySizeFactor is, the longer this test takes
        // in order to mitigate that, we scale the numer of runs by byteArraySizeFactor
        var numRuns = options.numRuns;
        if (byteArraySizeFactor > 1) {
            numRuns = numRuns / Math.sqrt(byteArraySizeFactor);
        }
        return consumerBase.excecuteMultipleBenchmarks("echoByteArray " + byteArraySize, generateData, testProcedure, numRuns);
    },
    echoByteArrayWithSizeTimesK: function() {
        if (options.skipByteArraySizeTimesK === undefined || options.skipByteArraySizeTimesK === true) {
            consumerBase.echoByteArray(1000);
        }
    }
};
module.exports = consumerBase;
<|endoftext|>


<commit_before>import React from "react";
import uuid from "uniqid";

import { reduxForm, formValues } from "redux-form";

import {
  InputField,
  ReactSelectField,
  withDialog,
  InfoHelper
} from "teselagen-react-components";
import { compose } from "redux";
import { Button, Intent, Classes } from "@blueprintjs/core";
import { flatMap } from "lodash";
import classNames from "classnames";
import withEditorProps from "../../withEditorProps";
import { CheckboxField } from "teselagen-react-components";
import "./style.css";

export class MergeFeaturesDialog extends React.Component {
  render() {
    const {
      // editorName,
      hideModal,
      handleSubmit,
      selectedAnnotations,
      sequenceData,
      selectionLayerUpdate,
      id1,
      upsertFeature,
      deleteFeature,
      id2,
      change
    } = this.props;
    const { features } = sequenceData;
    const feat1 = features[id1];
    const feat2 = features[id2];
    const [id1default, id2default] = flatMap(
      selectedAnnotations.idStack,
      id => {
        const ann = selectedAnnotations.idMap[id];
        if (ann.annotationTypePlural === "features") {
          return id;
        }
        return [];
      }
    );
    return (

        <InfoHelper displayToSide>

            Choose features in the dropdown or shift click directly on the
            plasmid map

        </InfoHelper>

        <ReactSelectField
          inlineLabel
          required
          defaultValue={id1default}
          enableReinitialize
          name="id1"
          label={

              <InfoHelper
                {...{
                  popoverProps: {
                    position: "top"
                  }
                }}
                onClick={() => {
                  feat1 && change("name", feat1.name);
                }}
                disabled={!feat1}
                icon="small-plus"
                isButton
              >
                Use Name
              </InfoHelper>

                Feature 1:

          }
          options={flatMap(features, feat => {
            if (feat.id === (feat2 && feat2.id)) return []; //filter out other feature as an option
            return {
              value: feat.id,
              label: feat.name
            };
          })}
        />

          <Button
            onClick={() => {
              const id1Holder = id1;
              change("id1", id2);
              change("id2", id1Holder);
            }}
            icon="swap-vertical"
          >
            {" "}
            Swap{" "}
          </Button>{" "}
           {" "}

        <ReactSelectField
          inlineLabel
          required
          defaultValue={id2default}
          enableReinitialize
          name="id2"
          label={

              <InfoHelper
                onClick={() => {
                  feat2 && change("name", feat2.name);
                }}
                disabled={!feat2}
                icon="small-plus"
                isButton
              >
                Use Name
              </InfoHelper>

                Feature 2:

          }
          options={flatMap(features, feat => {
            if (feat.id === (feat1 && feat1.id)) return []; //filter out other feature as an option
            return {
              value: feat.id,
              label: feat.name
            };
          })}
        />
        <InputField
          autoFocus
          inlineLabel
          enableReinitialize
          defaultValue={feat1 && feat1.name}
          validate={required}
          name="name"
          label="New Name:"
        />

          <InputField
            inlineLabel
            disabled
            enableReinitialize
            defaultValue={!feat1 ? "" : feat1.start + 1}
            validate={required}
            name="start"
            label="New Start:"
          />

          <InputField
            inlineLabel
            disabled
            enableReinitialize
            defaultValue={!feat2 ? "" : feat2.end + 1}
            validate={required}
            name="end"
            label="New End:"
          />

        <CheckboxField
          name="preserveFeatures"
          defaultValue={false}
          label="Preserve features (by default they will be removed once merged)"
        />

          <Button
            onClick={handleSubmit(
              ({ id1, id2, name, preserveFeatures, start, end }) => {
                if (!preserveFeatures) {
                  deleteFeature([id1, id2], {
                    batchUndoStart: true
                  });
                }
                upsertFeature(
                  {
                    ...feat1,
                    id: uuid(),
                    start: start - 1,
                    end: end - 1,
                    name
                  },
                  {
                    batchUndoEnd: true
                  }
                );
                selectionLayerUpdate({
                  start: start - 1,
                  end: end - 1
                });
                hideModal();
              }
            )}
            intent={Intent.PRIMARY}
          >
            Create Merged Feature
          </Button>

    );
  }
}

function required(val) {
  if (!val) return "Required";
}
export default compose(
  withDialog({
    isDraggable: true,
    height: 480,
    width: 400
  }),
  withEditorProps,
  reduxForm({
    form: "MergeFeaturesDialog"
  }),
  formValues("id1", "id2")
)(MergeFeaturesDialog);
<commit_msg>fixing error handling in merge feature dialog<commit_after>import React from "react";
import uuid from "uniqid";

import { reduxForm, formValues } from "redux-form";

import {
  InputField,
  ReactSelectField,
  withDialog,
  InfoHelper
} from "teselagen-react-components";
import { compose } from "redux";
import { Button, Intent, Classes } from "@blueprintjs/core";
import { flatMap } from "lodash";
import classNames from "classnames";
import withEditorProps from "../../withEditorProps";
import { CheckboxField } from "teselagen-react-components";
import "./style.css";

export class MergeFeaturesDialog extends React.Component {
  render() {
    const {
      // editorName,
      hideModal,
      handleSubmit,
      selectedAnnotations,
      sequenceData,
      selectionLayerUpdate,
      id1,
      upsertFeature,
      deleteFeature,
      id2,
      change
    } = this.props;
    const { features } = sequenceData;
    const feat1 = features[id1];
    const feat2 = features[id2];
    const [id1default, id2default] = flatMap(
      selectedAnnotations.idStack,
      id => {
        const ann = selectedAnnotations.idMap[id];
        if (ann.annotationTypePlural === "features") {
          return id;
        }
        return [];
      }
    );
    return (

        <InfoHelper displayToSide>

            Choose features in the dropdown or shift click directly on the
            plasmid map

        </InfoHelper>

        <ReactSelectField
          inlineLabel
          required
          defaultValue={id1default}
          enableReinitialize
          name="id1"
          label={

              <InfoHelper
                {...{
                  popoverProps: {
                    position: "top"
                  }
                }}
                onClick={() => {
                  feat1 && change("name", feat1.name);
                }}
                disabled={!feat1}
                icon="small-plus"
                isButton
              >
                Use Name
              </InfoHelper>

                Feature 1:

          }
          options={flatMap(features, feat => {
            if (feat.id === (feat2 && feat2.id)) return []; //filter out other feature as an option
            return {
              value: feat.id,
              label: feat.name
            };
          })}
        />

          <Button
            onClick={() => {
              const id1Holder = id1;
              change("id1", id2);
              change("id2", id1Holder);
            }}
            icon="swap-vertical"
          >
            {" "}
            Swap{" "}
          </Button>{" "}
           {" "}

        <ReactSelectField
          inlineLabel
          required
          defaultValue={id2default}
          enableReinitialize
          name="id2"
          label={

              <InfoHelper
                onClick={() => {
                  feat2 && change("name", feat2.name);
                }}
                disabled={!feat2}
                icon="small-plus"
                isButton
              >
                Use Name
              </InfoHelper>

                Feature 2:

          }
          options={flatMap(features, feat => {
            if (feat.id === (feat1 && feat1.id)) return []; //filter out other feature as an option
            return {
              value: feat.id,
              label: feat.name
            };
          })}
        />
        <InputField
          autoFocus
          inlineLabel
          enableReinitialize
          defaultValue={feat1 && feat1.name}
          validate={required}
          name="name"
          label="New Name:"
        />

          <InputField
            inlineLabel
            disabled
            enableReinitialize
            defaultValue={!feat1 ? "" : feat1.start + 1}
            validate={required}
            name="start"
            label="New Start:"
          />

          <InputField
            inlineLabel
            disabled
            enableReinitialize
            defaultValue={!feat2 ? "" : feat2.end + 1}
            validate={required}
            name="end"
            label="New End:"
          />

        <CheckboxField
          name="preserveFeatures"
          defaultValue={false}
          label="Preserve features (by default they will be removed once merged)"
        />

          <Button
            onClick={handleSubmit(
              ({ id1, id2, name, preserveFeatures, start, end }) => {
                if (!preserveFeatures) {
                  deleteFeature([id1, id2], {
                    batchUndoStart: true
                  });
                }
                upsertFeature(
                  {
                    ...feat1,
                    id: uuid(),
                    start: start - 1,
                    end: end - 1,
                    name
                  },
                  {
                    batchUndoEnd: true
                  }
                );
                selectionLayerUpdate({
                  start: start - 1,
                  end: end - 1
                });
                hideModal();
              }
            )}
            intent={Intent.PRIMARY}
          >
            Create Merged Feature
          </Button>

    );
  }
}

function required(val) {
  if (!val) return "Required";
}
export default compose(
  withDialog({
    isDraggable: true,
    height: 480,
    width: 400
  }),
  withEditorProps,
  reduxForm({
    form: "MergeFeaturesDialog",
    validate: ({ id1, id2 }) => {
      const errors = {};
      if (!id1 || Array.isArray(id1)) {
        errors.id1 = "Please select a feature";
      }
      if (!id2 || Array.isArray(id2)) {
        errors.id2 = "Please select a feature";
      }
      return errors;
    }
  }),
  formValues("id1", "id2")
)(MergeFeaturesDialog);
<|endoftext|>


<commit_before>/* global angular */

(function () {
    "use strict";

    angular
        .module('documents')
        .component('scientillaDocumentForm', {
            templateUrl: 'partials/scientilla-document-form.html',
            controller: scientillaDocumentFormController,
            controllerAs: 'vm',
            bindings: {
                document: "<",
                researchEntity: "<",
                checkAndClose: "&"
            }
        });

    scientillaDocumentFormController.$inject = [
        'EventsService',
        'documentFieldsRules',
        '$scope',
        '$timeout',
        'DocumentTypesService',
        'context',
        'Restangular',
        'ModalService',
        'documentCategories',
        'languages',
        'PhdThesisService'
    ];

    function scientillaDocumentFormController(
        EventsService,
        documentFieldsRules,
        $scope,
        $timeout,
        DocumentTypesService,
        context,
        Restangular,
        ModalService,
        documentCategories,
        languages,
        PhdThesisService
    ) {
        const vm = this;

        vm.saveStatus = saveStatus();
        vm.verifyStatus = verifyStatus();

        vm.cancel = close;
        vm.verify = verify;
        vm.save = save;
        vm.documentTypes = DocumentTypesService.getDocumentTypes();
        vm.getSources = getSources;
        vm.getItSources = getItSources;
        vm.openSourceTypeModal = openSourceTypeModal;
        vm.checkSource = checkSource;
        vm.documentFieldsRules = documentFieldsRules;
        const allSourceTypes = DocumentTypesService.getSourceTypes();
        vm.sourceLabel = _.get(_.find(allSourceTypes, {id: vm.document.sourceType}), 'label');

        let documentBackup = null;
        const documentService = context.getDocumentService();
        const deregisteres = [];

        vm.newSource = {};

        vm.errors = {};
        vm.errorText = '';
        vm.unsavedData = false;
        vm.mode = 'draft';
        vm.resetErrors = resetErrors;
        vm.checkValidation = checkValidation;
        vm.fieldValueHasChanged = fieldValueHasChanged;

        let timeout;

        const delay = 500;

         /* jshint ignore:start */
        vm.$onInit = async function () {
            if (_.isFunction(vm.document.clone))
                documentBackup = vm.document.clone();
            else
                documentBackup = _.cloneDeep(vm.document);

            if (vm.document.type === 'phd_thesis') {
                vm.institutes = await PhdThesisService.getInstitutes();

                if (vm.document.phdInstitute) {
                    vm.phdInstituteId = vm.document.phdInstitute.id;
                    await getCoursesOfInstitute();
                }

                if (vm.document.phdCourse) {
                    vm.phdCourseId = vm.document.phdCourse.id;
                    await getCyclesOfCourse();
                }

                if (vm.document.phdCycle) {
                    vm.phdCycleId = vm.document.phdCycle.id;
                }
            }

            watchDocumentSourceType();
            watchDocumentType();
            watchRealizedAtIIT();
            watchPhdInstitutionId();
            watchPhdCourseId();
            watchPhdCycleId();

            $scope.$watch('form.$pristine', formUntouched => vm.unsavedData = !formUntouched);

            if (vm.document.id) {
                vm.errorText = '';
                vm.errors = vm.document.validateDocument();

                if (Object.keys(vm.errors).length > 0) {
                    vm.errorText = 'The draft has been saved but please fix the warnings before verifying!';
                }
            }

            vm.languageOptions = [];
            Object.keys(languages).map(language => {
                vm.languageOptions.push({
                    label: languages[language].name,
                    value: language
                });
            });
            vm.languageOptions = _.orderBy(vm.languageOptions, 'label');
        };
         /* jshint ignore:end */

        vm.$onDestroy = function () {
            for (const deregisterer of deregisteres)
                deregisterer();
        };

        function resetErrors() {
            vm.errors = {};
            vm.errorText = '';
        }

        function checkValidation(field = false) {
            if (field) {
                vm.errors[field] = vm.document.validateDocument(field);

                if (typeof vm.errors[field] === 'undefined') {
                    delete vm.errors[field];
                }
            } else {
                vm.errors = vm.document.validateDocument();
            }

            if (Object.keys(vm.errors).length > 0) {
                vm.errorText = 'The draft has been saved but please fix the warnings before verifying!';
            } else {
                vm.errorText = '';
            }
        }

        function fieldValueHasChanged(field = false) {
            $timeout.cancel(timeout);

            timeout = $timeout(function () {
                checkValidation(field);
            }, delay);
        }

        function watchDocumentSourceType() {
            const dereg = $scope.$watch('vm.document.sourceType', (newValue, oldValue) => {
                if (newValue === oldValue)
                    return;

                if (!newValue) {
                    vm.sourceLabel = '';
                    return;
                }

                vm.sourceLabel = _.find(allSourceTypes, {id: newValue}).label;
                if (vm.document.source && vm.document.source.type !== vm.document.sourceType)
                    vm.document.source = null;
            });

            deregisteres.push(dereg);
        }

        function watchDocumentType() {
            const dereg = $scope.$watch('vm.document.type', newValue => {
                const allowedSources = _.find(vm.documentTypes, {key: newValue}).allowedSources;
                vm.sourceTypes = _.filter(allSourceTypes, s => allowedSources.includes(s.id));

                if (newValue === 'phd_thesis') {
                    if (!_.has(vm.document, 'isPhdThesisInstitutional')) {
                        vm.document.isPhdThesisInstitutional = false;
                    }

                    if (!_.has(vm.document, 'sourceType') || vm.document.sourceType !== 'book') {
                        vm.document.sourceType = 'book';
                    }

                    if (!_.has(vm.document, 'language') || !vm.document.language) {
                        vm.document.language = 'en';
                    }
                }
            });
            deregisteres.push(dereg);
        }

        /* jshint ignore:start */
        async function getCoursesOfInstitute() {
            vm.courses = await PhdThesisService.getCourses(vm.document.phdInstitute);
        }

        async function getCyclesOfCourse() {
            vm.cycles = await PhdThesisService.getCycles(vm.document.phdCourse);
        }

        function watchRealizedAtIIT() {
            const dereg = $scope.$watch('vm.document.isPhdThesisInstitutional', async (newValue, oldValue) => {
                if (newValue === oldValue) {
                    return;
                }

                if (newValue) {
                    if (!vm.institutes) {
                        vm.institutes = await PhdThesisService.getInstitutes();
                    }
                } else {
                    vm.document.phdInstitute = null;
                    vm.document.phdCourse = null;
                    vm.document.phdCycle = null;
                }
            });
            deregisteres.push(dereg);
        }

        function watchPhdInstitutionId() {
            const dereg = $scope.$watch('vm.phdInstituteId', async (newValue, oldValue) => {
                if (newValue === oldValue) {
                    return;
                }

                if (newValue && vm.institutes) {
                    const institute = vm.institutes.find(i => i.id === newValue);
                    if (!institute) {
                        return;
                    }
                    vm.phdCourseId = null;
                    vm.phdCycleId = null;
                    vm.document.phdInstitute = institute;
                    vm.document.phdCourse = null;
                    vm.document.phdCycle = null;
                    await getCoursesOfInstitute();
                }
            });
            deregisteres.push(dereg);
        }

        function watchPhdCourseId() {
            const dereg = $scope.$watch('vm.phdCourseId', async (newValue, oldValue) => {
                if (newValue === oldValue) {
                    return;
                }

                if (newValue) {
                    const course = vm.courses.find(c => c.id === newValue);
                    if (!course) {
                        return;
                    }
                    vm.phdCycleId = null;
                    vm.document.phdCourse = course;
                    vm.document.phdCycle = null;
                    await getCyclesOfCourse()
                }
            });
            deregisteres.push(dereg);
        }
        /* jshint ignore:end */

        function watchPhdCycleId() {
            const dereg = $scope.$watch('vm.phdCycleId', (newValue, oldValue) => {
                if (newValue === oldValue) {
                    return;
                }

                if (newValue) {
                    const cycle = vm.cycles.find(c => c.id === newValue);
                    if (!cycle) {
                        return;
                    }
                    vm.document.phdCycle = cycle;
                }
            });
            deregisteres.push(dereg);
        }

        function saveStatus() {
            return {
                setState: function (state) {
                    this.state = state;

                    vm.mode = 'draft';

                    switch (state) {
                        case 'ready to save':
                            this.message = 'Save draft';
                            break;
                        case 'saving':
                            this.message = 'Saving draft';
                            break;
                        case 'saved':
                            this.message = 'Draft is saved!';
                            $scope.form.$setPristine();
                            break;
                        case 'failed':
                            this.message = 'Failed to save draft!';
                            $scope.form.$setPristine();
                            break;
                    }
                },
                state: 'ready to save',
                message: 'Save draft'
            };
        }

        function verifyStatus() {
            return {
                setState: function (state) {
                    this.state = state;

                    vm.mode = 'verify';

                    switch (state) {
                        case 'ready to verify':
                            this.message = 'Save & verify';
                            break;
                        case 'verifying':
                            this.message = 'Verifying draft';
                            break;
                        case 'verified':
                            this.message = 'Draft is Verified!';
                            $scope.form.$setPristine();
                            break;
                        case 'failed':
                            this.message = 'Failed to verify!';
                            $scope.form.$setPristine();
                            break;
                    }
                },
                state: 'ready to verify',
                message: 'Save & verify'
            };
        }

        /* jshint ignore:start */

        async function save() {
            vm.errors = {};
            vm.errorText = '';
            await saveDocument(true);
        }

        async function saveDocument(updateState = false) {
            if (updateState)
                vm.saveStatus.setState('saving');

            vm.errorText = '';
            vm.errors = vm.document.validateDocument();

            if (updateState && Object.keys(vm.errors).length > 0)
                vm.errorText = 'The draft has been saved but please fix the warnings before verifying!';

            if (vm.document.id) await vm.document.save();
            else vm.document = await documentService.createDraft(vm.document);

            if (updateState)
                vm.saveStatus.setState('saved');

            EventsService.publish(EventsService.DRAFT_UPDATED, vm.document);

            vm.unsavedData = false;

            if (updateState)
                $timeout(function () {
                    vm.saveStatus.setState('ready to save');
                }, 1000);

            return vm.document;
        }

        async function verify() {
            vm.errorText = '';
            vm.errors = {};
            vm.verifyStatus.setState('verifying');

            await saveDocument();

            vm.errors = vm.document.validateDocument();
            if (Object.keys(vm.errors).length === 0) {
                // Is valid
                if (vm.document.getComparisonDuplicates().length > 0)
                    documentService.compareDocuments(vm.document, vm.document.getComparisonDuplicates(), documentCategories.DRAFT);
                else
                    documentService.verifyDraft(vm.document);

                vm.verifyStatus.setState('verified');
                close();
            } else {
                // Is not valid
                vm.verifyStatus.setState('failed');
                vm.errorText = 'The draft has been saved but not been verified! Please correct the errors on this form!';

                $timeout(function () {
                    vm.verifyStatus.setState('ready to verify');
                }, 1000);
            }
        }

        /* jshint ignore:end */

        function close() {
            if (_.isFunction(vm.checkAndClose()))
                vm.checkAndClose()(() => !vm.unsavedData);
        }

        function getSources(searchText) {
            const qs = {where: {title: {contains: searchText}, type: vm.document.sourceType}};
            return Restangular.all('sources').getList(qs);
        }

        function getItSources(searchText) {
            const sourcesData = {
                'institute': {
                    query: {where: {name: {contains: searchText}}},
                    model: 'institutes'
                },
                'scientific_conference': {
                    query: {where: {title: {contains: searchText}, type: 'conference'}},
                    model: 'sources'
                }
            };
            const sourceData = sourcesData[vm.document.sourceType];
            if (!sourceData)
                return [];
            return Restangular.all(sourceData.model).getList(sourceData.query);
        }

        function openSourceTypeModal($event) {

            $event.stopPropagation();

            EventsService.subscribe(vm, EventsService.SOURCE_CREATED, function (event, source) {
                vm.document.source = source;
                vm.getSources(source.title);

                vm.errors = vm.document.validateDocument();

                checkValidation();
            });

            ModalService.openSourceTypeModal(vm.document.sourceType);
        }

        function checkSource($event) {
            if (!$event.target.value) {
                vm.document.source = null;
            }

            checkValidation('source');
        }
    }
})();
<commit_msg>Set default value radio button isPhdThesisInstitutional<commit_after>/* global angular */

(function () {
    "use strict";

    angular
        .module('documents')
        .component('scientillaDocumentForm', {
            templateUrl: 'partials/scientilla-document-form.html',
            controller: scientillaDocumentFormController,
            controllerAs: 'vm',
            bindings: {
                document: "<",
                researchEntity: "<",
                checkAndClose: "&"
            }
        });

    scientillaDocumentFormController.$inject = [
        'EventsService',
        'documentFieldsRules',
        '$scope',
        '$timeout',
        'DocumentTypesService',
        'context',
        'Restangular',
        'ModalService',
        'documentCategories',
        'languages',
        'PhdThesisService'
    ];

    function scientillaDocumentFormController(
        EventsService,
        documentFieldsRules,
        $scope,
        $timeout,
        DocumentTypesService,
        context,
        Restangular,
        ModalService,
        documentCategories,
        languages,
        PhdThesisService
    ) {
        const vm = this;

        vm.saveStatus = saveStatus();
        vm.verifyStatus = verifyStatus();

        vm.cancel = close;
        vm.verify = verify;
        vm.save = save;
        vm.documentTypes = DocumentTypesService.getDocumentTypes();
        vm.getSources = getSources;
        vm.getItSources = getItSources;
        vm.openSourceTypeModal = openSourceTypeModal;
        vm.checkSource = checkSource;
        vm.documentFieldsRules = documentFieldsRules;
        const allSourceTypes = DocumentTypesService.getSourceTypes();
        vm.sourceLabel = _.get(_.find(allSourceTypes, {id: vm.document.sourceType}), 'label');

        let documentBackup = null;
        const documentService = context.getDocumentService();
        const deregisteres = [];

        vm.newSource = {};

        vm.errors = {};
        vm.errorText = '';
        vm.unsavedData = false;
        vm.mode = 'draft';
        vm.resetErrors = resetErrors;
        vm.checkValidation = checkValidation;
        vm.fieldValueHasChanged = fieldValueHasChanged;

        let timeout;

        const delay = 500;

         /* jshint ignore:start */
        vm.$onInit = async function () {
            if (_.isFunction(vm.document.clone))
                documentBackup = vm.document.clone();
            else
                documentBackup = _.cloneDeep(vm.document);

            if (vm.document.type === 'phd_thesis') {
                vm.institutes = await PhdThesisService.getInstitutes();

                if (vm.document.phdInstitute) {
                    vm.phdInstituteId = vm.document.phdInstitute.id;
                    await getCoursesOfInstitute();
                }

                if (vm.document.phdCourse) {
                    vm.phdCourseId = vm.document.phdCourse.id;
                    await getCyclesOfCourse();
                }

                if (vm.document.phdCycle) {
                    vm.phdCycleId = vm.document.phdCycle.id;
                }
            }

            watchDocumentSourceType();
            watchDocumentType();
            watchRealizedAtIIT();
            watchPhdInstitutionId();
            watchPhdCourseId();
            watchPhdCycleId();

            $scope.$watch('form.$pristine', formUntouched => vm.unsavedData = !formUntouched);

            if (vm.document.id) {
                vm.errorText = '';
                vm.errors = vm.document.validateDocument();

                if (Object.keys(vm.errors).length > 0) {
                    vm.errorText = 'The draft has been saved but please fix the warnings before verifying!';
                }
            }

            vm.languageOptions = [];
            Object.keys(languages).map(language => {
                vm.languageOptions.push({
                    label: languages[language].name,
                    value: language
                });
            });
            vm.languageOptions = _.orderBy(vm.languageOptions, 'label');
        };
         /* jshint ignore:end */

        vm.$onDestroy = function () {
            for (const deregisterer of deregisteres)
                deregisterer();
        };

        function resetErrors() {
            vm.errors = {};
            vm.errorText = '';
        }

        function checkValidation(field = false) {
            if (field) {
                vm.errors[field] = vm.document.validateDocument(field);

                if (typeof vm.errors[field] === 'undefined') {
                    delete vm.errors[field];
                }
            } else {
                vm.errors = vm.document.validateDocument();
            }

            if (Object.keys(vm.errors).length > 0) {
                vm.errorText = 'The draft has been saved but please fix the warnings before verifying!';
            } else {
                vm.errorText = '';
            }
        }

        function fieldValueHasChanged(field = false) {
            $timeout.cancel(timeout);

            timeout = $timeout(function () {
                checkValidation(field);
            }, delay);
        }

        function watchDocumentSourceType() {
            const dereg = $scope.$watch('vm.document.sourceType', (newValue, oldValue) => {
                if (newValue === oldValue)
                    return;

                if (!newValue) {
                    vm.sourceLabel = '';
                    return;
                }

                vm.sourceLabel = _.find(allSourceTypes, {id: newValue}).label;
                if (vm.document.source && vm.document.source.type !== vm.document.sourceType)
                    vm.document.source = null;
            });

            deregisteres.push(dereg);
        }

        function watchDocumentType() {
            const dereg = $scope.$watch('vm.document.type', (newValue, oldValue) => {
                const allowedSources = _.find(vm.documentTypes, {key: newValue}).allowedSources;
                vm.sourceTypes = _.filter(allSourceTypes, s => allowedSources.includes(s.id));

                if (newValue !== oldValue && newValue === 'phd_thesis') {
                    if (!_.has(vm.document, 'isPhdThesisInstitutional') || !vm.document.isPhdThesisInstitutional) {
                        vm.document.isPhdThesisInstitutional = false;
                    }

                    if (!_.has(vm.document, 'sourceType') || vm.document.sourceType !== 'book') {
                        vm.document.sourceType = 'book';
                    }

                    if (!_.has(vm.document, 'language') || !vm.document.language) {
                        vm.document.language = 'en';
                    }
                }
            });
            deregisteres.push(dereg);
        }

        /* jshint ignore:start */
        async function getCoursesOfInstitute() {
            vm.courses = await PhdThesisService.getCourses(vm.document.phdInstitute);
        }

        async function getCyclesOfCourse() {
            vm.cycles = await PhdThesisService.getCycles(vm.document.phdCourse);
        }

        function watchRealizedAtIIT() {
            const dereg = $scope.$watch('vm.document.isPhdThesisInstitutional', async (newValue, oldValue) => {
                if (newValue === oldValue) {
                    return;
                }

                if (newValue) {
                    if (!vm.institutes) {
                        vm.institutes = await PhdThesisService.getInstitutes();
                    }
                } else {
                    vm.document.phdInstitute = null;
                    vm.document.phdCourse = null;
                    vm.document.phdCycle = null;
                }
            });
            deregisteres.push(dereg);
        }

        function watchPhdInstitutionId() {
            const dereg = $scope.$watch('vm.phdInstituteId', async (newValue, oldValue) => {
                if (newValue === oldValue) {
                    return;
                }

                if (newValue && vm.institutes) {
                    const institute = vm.institutes.find(i => i.id === newValue);
                    if (!institute) {
                        return;
                    }
                    vm.phdCourseId = null;
                    vm.phdCycleId = null;
                    vm.document.phdInstitute = institute;
                    vm.document.phdCourse = null;
                    vm.document.phdCycle = null;
                    await getCoursesOfInstitute();
                }
            });
            deregisteres.push(dereg);
        }

        function watchPhdCourseId() {
            const dereg = $scope.$watch('vm.phdCourseId', async (newValue, oldValue) => {
                if (newValue === oldValue) {
                    return;
                }

                if (newValue) {
                    const course = vm.courses.find(c => c.id === newValue);
                    if (!course) {
                        return;
                    }
                    vm.phdCycleId = null;
                    vm.document.phdCourse = course;
                    vm.document.phdCycle = null;
                    await getCyclesOfCourse()
                }
            });
            deregisteres.push(dereg);
        }
        /* jshint ignore:end */

        function watchPhdCycleId() {
            const dereg = $scope.$watch('vm.phdCycleId', (newValue, oldValue) => {
                if (newValue === oldValue) {
                    return;
                }

                if (newValue) {
                    const cycle = vm.cycles.find(c => c.id === newValue);
                    if (!cycle) {
                        return;
                    }
                    vm.document.phdCycle = cycle;
                }
            });
            deregisteres.push(dereg);
        }

        function saveStatus() {
            return {
                setState: function (state) {
                    this.state = state;

                    vm.mode = 'draft';

                    switch (state) {
                        case 'ready to save':
                            this.message = 'Save draft';
                            break;
                        case 'saving':
                            this.message = 'Saving draft';
                            break;
                        case 'saved':
                            this.message = 'Draft is saved!';
                            $scope.form.$setPristine();
                            break;
                        case 'failed':
                            this.message = 'Failed to save draft!';
                            $scope.form.$setPristine();
                            break;
                    }
                },
                state: 'ready to save',
                message: 'Save draft'
            };
        }

        function verifyStatus() {
            return {
                setState: function (state) {
                    this.state = state;

                    vm.mode = 'verify';

                    switch (state) {
                        case 'ready to verify':
                            this.message = 'Save & verify';
                            break;
                        case 'verifying':
                            this.message = 'Verifying draft';
                            break;
                        case 'verified':
                            this.message = 'Draft is Verified!';
                            $scope.form.$setPristine();
                            break;
                        case 'failed':
                            this.message = 'Failed to verify!';
                            $scope.form.$setPristine();
                            break;
                    }
                },
                state: 'ready to verify',
                message: 'Save & verify'
            };
        }

        /* jshint ignore:start */

        async function save() {
            vm.errors = {};
            vm.errorText = '';
            await saveDocument(true);
        }

        async function saveDocument(updateState = false) {
            if (updateState)
                vm.saveStatus.setState('saving');

            vm.errorText = '';
            vm.errors = vm.document.validateDocument();

            if (updateState && Object.keys(vm.errors).length > 0)
                vm.errorText = 'The draft has been saved but please fix the warnings before verifying!';

            if (vm.document.id) await vm.document.save();
            else vm.document = await documentService.createDraft(vm.document);

            if (updateState)
                vm.saveStatus.setState('saved');

            EventsService.publish(EventsService.DRAFT_UPDATED, vm.document);

            vm.unsavedData = false;

            if (updateState)
                $timeout(function () {
                    vm.saveStatus.setState('ready to save');
                }, 1000);

            return vm.document;
        }

        async function verify() {
            vm.errorText = '';
            vm.errors = {};
            vm.verifyStatus.setState('verifying');

            await saveDocument();

            vm.errors = vm.document.validateDocument();
            if (Object.keys(vm.errors).length === 0) {
                // Is valid
                if (vm.document.getComparisonDuplicates().length > 0)
                    documentService.compareDocuments(vm.document, vm.document.getComparisonDuplicates(), documentCategories.DRAFT);
                else
                    documentService.verifyDraft(vm.document);

                vm.verifyStatus.setState('verified');
                close();
            } else {
                // Is not valid
                vm.verifyStatus.setState('failed');
                vm.errorText = 'The draft has been saved but not been verified! Please correct the errors on this form!';

                $timeout(function () {
                    vm.verifyStatus.setState('ready to verify');
                }, 1000);
            }
        }

        /* jshint ignore:end */

        function close() {
            if (_.isFunction(vm.checkAndClose()))
                vm.checkAndClose()(() => !vm.unsavedData);
        }

        function getSources(searchText) {
            const qs = {where: {title: {contains: searchText}, type: vm.document.sourceType}};
            return Restangular.all('sources').getList(qs);
        }

        function getItSources(searchText) {
            const sourcesData = {
                'institute': {
                    query: {where: {name: {contains: searchText}}},
                    model: 'institutes'
                },
                'scientific_conference': {
                    query: {where: {title: {contains: searchText}, type: 'conference'}},
                    model: 'sources'
                }
            };
            const sourceData = sourcesData[vm.document.sourceType];
            if (!sourceData)
                return [];
            return Restangular.all(sourceData.model).getList(sourceData.query);
        }

        function openSourceTypeModal($event) {

            $event.stopPropagation();

            EventsService.subscribe(vm, EventsService.SOURCE_CREATED, function (event, source) {
                vm.document.source = source;
                vm.getSources(source.title);

                vm.errors = vm.document.validateDocument();

                checkValidation();
            });

            ModalService.openSourceTypeModal(vm.document.sourceType);
        }

        function checkSource($event) {
            if (!$event.target.value) {
                vm.document.source = null;
            }

            checkValidation('source');
        }
    }
})();
<|endoftext|>


<commit_before>import assert from 'assert';

import {
  generateImageListHistory,
  BACK,
  FORWARD,
  UPDATE,
  SET_OMIT_BASE_POSITION,
  OMIT,
} from '../generateImageListHistory';

describe('generateImageListHistory', () => {
  let originalHistory;
  beforeEach(() => {
    originalHistory = {
      history: [['a'], ['b'], ['c']],
      position: 0,
      omitBasePosition: null,
    };
  });

  describe('back', () => {
    it('positionの数値を一つ増やす', () => {
      const newHistory = generateImageListHistory({
        type: BACK,
        currentState: originalHistory,
      });
      assert(newHistory.position === 1);
    });
    it('positionが(history.length - 1)の場合、positionは変わらない', () => {
      originalHistory.position = 2;
      assert(originalHistory.position === originalHistory.history.length - 1);
      const newHistory = generateImageListHistory({
        type: BACK,
        currentState: originalHistory,
      });
      assert(newHistory.position === 2);
      assert(newHistory !== originalHistory);
    });
    it('新しいhistoryを返すため、副作用がない', () => {
      const newHistory = generateImageListHistory({
        type: BACK,
        currentState: originalHistory,
      });
      assert(newHistory.history !== originalHistory.history);
      assert(originalHistory.position === 0);
      assert(newHistory.position === 1);
    });
  });

  describe('forward', () => {
    it('positionの数値を一つ減らす', () => {
      originalHistory.position = 1;
      const newHistory = generateImageListHistory({
        type: FORWARD,
        currentState: originalHistory,
      });
      assert(newHistory.position === 0);
    });
    it('positionが0の場合、positionは変わらない', () => {
      assert(originalHistory.position === 0);
      const newHistory = generateImageListHistory({
        type: FORWARD,
        currentState: originalHistory,
      });
      assert(newHistory.position === 0);
      assert(newHistory !== originalHistory);
    });
    it('新しいhistoryを返すため、副作用がない', () => {
      originalHistory.position = 2;
      const newHistory = generateImageListHistory({
        type: FORWARD,
        currentState: originalHistory,
      });
      assert(newHistory.history !== originalHistory.history);
      assert(originalHistory.position === 2);
      assert(newHistory.position === 1);
    });
  });

  describe('update', () => {
    it('渡された要素が、historyの先頭の要素になる', () => {
      const newHistory = generateImageListHistory({
        type: UPDATE,
        imageList: ['d'],
        currentState: originalHistory,
      });
      assert(newHistory.history[0][0] === 'd');
      assert(newHistory.history[1][0] === 'a');
    });
    it('position > 0 の場合、positionより前の要素は全て消去し前に詰める', () => {
      originalHistory.position = 1;
      const newHistory = generateImageListHistory({
        type: UPDATE,
        imageList: ['d'],
        currentState: originalHistory,
      });
      assert(newHistory.history[0][0] === 'd');
      assert(newHistory.history[1][0] === 'b');
    });
    it('positionが0になる', () => {
      originalHistory.position = 1;
      const newHistory = generateImageListHistory({
        type: UPDATE,
        imageList: ['d'],
        currentState: originalHistory,
      });
      assert(newHistory.position === 0);
    });
    it('新しいhistoryを返すため、副作用がない', () => {
      const newHistory = generateImageListHistory({
        type: UPDATE,
        imageList: ['d'],
        currentState: originalHistory,
      });
      assert(newHistory !== originalHistory);
      assert(newHistory.history !== originalHistory.history);
    });
  });

  describe('setOmitBasePosition', () => {
    it('指定した数値が omitBasePosition に設定される', () => {
      const newHistory = generateImageListHistory({
        type: SET_OMIT_BASE_POSITION,
        currentState: originalHistory,
        target: 0,
      });
      assert(originalHistory.omitBasePosition === null);
      assert(newHistory.omitBasePosition === 0);
    });
    it('omitBasePosition が null でないときに呼び出されると例外を投げる', () => {
      originalHistory.omitBasePosition = 1;
      let error = false;
      try {
        generateImageListHistory({
          type: SET_OMIT_BASE_POSITION,
          currentState: originalHistory,
          target: 0,
        });
      } catch (e) {
        error = true;
      }
      assert(error === true);
    });
    it('history.length 以上の値を指定された場合は例外を投げる', () => {
      let error = false;
      try {
        generateImageListHistory({
          type: SET_OMIT_BASE_POSITION,
          currentState: originalHistory,
          target: originalHistory.length,
        });
      } catch (e) {
        error = true;
      }
      assert(error === true);
    });
    it('新しいhistoryを返すため、副作用がない', () => {
      const newHistory = generateImageListHistory({
        type: SET_OMIT_BASE_POSITION,
        currentState: originalHistory,
        target: 1,
      });
      assert(originalHistory.omitBasePosition === null);
      assert(newHistory.omitBasePosition === 1);
      assert(originalHistory.history !== newHistory.history);
    });
  });

  describe('omit', () => {
    it('指定した値と omitBasePosition の間にある history が削除される', () => {
      originalHistory.omitBasePosition = 2;
      const newHistory = generateImageListHistory({
        type: OMIT,
        currentState: originalHistory,
        target: 0,
      });
      const {history} = newHistory;
      assert(history.length === 2);
      assert(history[0][0] === 'a');
      assert(history[1][0] === 'c');
    });
    it('omitBasePosition が null になる', () => {
      originalHistory.omitBasePosition = 2;
      const newHistory = generateImageListHistory({
        type: OMIT,
        currentState: originalHistory,
        target: 0,
      });
      assert(newHistory.omitBasePosition === null);
    });
    it('omitBasePosition が null のときに呼び出されると、例外を投げる', () => {
      assert(originalHistory.omitBasePosition === null);
      let error = false;
      try {
        generateImageListHistory({
          type: OMIT,
          currentState: originalHistory,
          target: 0,
        });
      } catch (e) {
        error = true;
      }
      assert(error === true);
    });
    it('omitBasePosition 以上の値を指定された場合は例外を投げる', () => {
      originalHistory.omitBasePosition = 1;
      let error = false;
      try {
        generateImageListHistory({
          type: OMIT,
          currentState: originalHistory,
          target: 1,
        });
      } catch (e) {
        error = true;
      }
      assert(error === true);
      error = false;
      try {
        generateImageListHistory({
          type: OMIT,
          currentState: originalHistory,
          target: 2,
        });
      } catch (e) {
        error = true;
      }
      assert(error === true);
    });
    it('新しいhistoryを返すため、副作用がない', () => {
      originalHistory.omitBasePosition = 2;
      const newHistory = generateImageListHistory({
        type: OMIT,
        currentState: originalHistory,
        target: 1,
      });
      const {history} = newHistory;
      assert(history.length === 3);
      assert(originalHistory.history !== newHistory.history);
    });
  });
});
<commit_msg>仕様変更に伴い、テストを書き換えた。<commit_after>import assert from 'assert';

import {
  generateImageListHistory,
  BACK,
  FORWARD,
  UPDATE,
  START_OMIT_LENGTH_COUNT,
  OMIT,
} from '../generateImageListHistory';

describe('generateImageListHistory', () => {
  let originalHistory;
  beforeEach(() => {
    originalHistory = {
      history: [['a'], ['b'], ['c']],
      position: 0,
      omitLength: null,
    };
  });

  describe('back', () => {
    it('positionの数値を一つ増やす', () => {
      const newHistory = generateImageListHistory({
        type: BACK,
        currentState: originalHistory,
      });
      assert(newHistory.position === 1);
    });
    it('positionが(history.length - 1)の場合、positionは変わらない', () => {
      originalHistory.position = 2;
      assert(originalHistory.position === originalHistory.history.length - 1);
      const newHistory = generateImageListHistory({
        type: BACK,
        currentState: originalHistory,
      });
      assert(newHistory.position === 2);
      assert(newHistory !== originalHistory);
    });
    it('omitLength が null でないときは、例外を投げる', () => {
      originalHistory.omitLength = 0;
      let error = false;
      try {
        generateImageListHistory({
          type: BACK,
          currentState: originalHistory,
        });
      } catch (e) {
        error = true;
      }
      assert(error === true);
    });
    it('新しいhistoryを返すため、副作用がない', () => {
      const newHistory = generateImageListHistory({
        type: BACK,
        currentState: originalHistory,
      });
      assert(newHistory.history !== originalHistory.history);
      assert(originalHistory.position === 0);
      assert(newHistory.position === 1);
    });
  });

  describe('forward', () => {
    it('positionの数値を一つ減らす', () => {
      originalHistory.position = 1;
      const newHistory = generateImageListHistory({
        type: FORWARD,
        currentState: originalHistory,
      });
      assert(newHistory.position === 0);
    });
    it('positionが0の場合、positionは変わらない', () => {
      assert(originalHistory.position === 0);
      const newHistory = generateImageListHistory({
        type: FORWARD,
        currentState: originalHistory,
      });
      assert(newHistory.position === 0);
      assert(newHistory !== originalHistory);
    });
    it('omitLength が null でないときは、例外を投げる', () => {
      originalHistory.omitLength = 0;
      let error = false;
      try {
        generateImageListHistory({
          type: FORWARD,
          currentState: originalHistory,
        });
      } catch (e) {
        error = true;
      }
      assert(error === true);
    });
    it('新しいhistoryを返すため、副作用がない', () => {
      originalHistory.position = 2;
      const newHistory = generateImageListHistory({
        type: FORWARD,
        currentState: originalHistory,
      });
      assert(newHistory.history !== originalHistory.history);
      assert(originalHistory.position === 2);
      assert(newHistory.position === 1);
    });
  });

  describe('update', () => {
    it('渡された要素が、historyの先頭の要素になる', () => {
      const newHistory = generateImageListHistory({
        type: UPDATE,
        imageList: ['d'],
        currentState: originalHistory,
      });
      assert(newHistory.history[0][0] === 'd');
      assert(newHistory.history[1][0] === 'a');
    });
    it('position > 0 の場合、positionより前の要素は全て消去し前に詰める', () => {
      originalHistory.position = 1;
      const newHistory = generateImageListHistory({
        type: UPDATE,
        imageList: ['d'],
        currentState: originalHistory,
      });
      assert(newHistory.history[0][0] === 'd');
      assert(newHistory.history[1][0] === 'b');
    });
    it('positionが0になる', () => {
      originalHistory.position = 1;
      const newHistory = generateImageListHistory({
        type: UPDATE,
        imageList: ['d'],
        currentState: originalHistory,
      });
      assert(newHistory.position === 0);
    });
    it('omitLength が null でないときは、カウントアップしていく', () => {
      originalHistory.omitLength = -1;
      const newHistory = generateImageListHistory({
        type: UPDATE,
        imageList: ['d'],
        currentState: originalHistory,
      });
      assert(newHistory.omitLength === 0);
    });
    it('新しいhistoryを返すため、副作用がない', () => {
      const newHistory = generateImageListHistory({
        type: UPDATE,
        imageList: ['d'],
        currentState: originalHistory,
      });
      assert(newHistory !== originalHistory);
      assert(newHistory.history !== originalHistory.history);
    });
  });

  describe('startOmitLengthCount', () => {
    it('omitLength が null から -1 になる', () => {
      const newHistory = generateImageListHistory({
        type: START_OMIT_LENGTH_COUNT,
        currentState: originalHistory,
      });
      assert(originalHistory.omitLength === null);
      assert(newHistory.omitLength === -1);
    });
    it('omitLength が null でないときに呼び出されると例外を投げる', () => {
      originalHistory.omitLength = 1;
      let error = false;
      try {
        generateImageListHistory({
          type: START_OMIT_LENGTH_COUNT,
          currentState: originalHistory,
        });
      } catch (e) {
        error = true;
      }
      assert(error === true);
    });
    it('新しいhistoryを返すため、副作用がない', () => {
      const newHistory = generateImageListHistory({
        type: START_OMIT_LENGTH_COUNT,
        currentState: originalHistory,
      });
      assert(originalHistory.omitLength === null);
      assert(newHistory.omitLength === -1);
      assert(originalHistory.history !== newHistory.history);
    });
  });

  describe('omit', () => {
    it('history[1] 以降の要素を、 omitLength の数だけ削除される', () => {
      originalHistory.omitLength = 1;
      const newHistory = generateImageListHistory({
        type: OMIT,
        currentState: originalHistory,
      });
      const {history} = newHistory;
      assert(history.length === 2);
      assert(history[0][0] === 'a');
      assert(history[1][0] === 'c');
    });
    it('omitLength が 0 以下だった時は、history に変化はない', () => {
      originalHistory.omitLength = 0;
      const newHistory = generateImageListHistory({
        type: OMIT,
        currentState: originalHistory,
      });
      const {history} = newHistory;
      assert(history.length === 3);
      assert(history[0][0] === 'a');
      assert(history[1][0] === 'b');
    });
    it('omitLength が null になる', () => {
      originalHistory.omitLength = 1;
      const newHistory = generateImageListHistory({
        type: OMIT,
        currentState: originalHistory,
      });
      assert(newHistory.omitLength === null);
    });
    it('omitLength が null のときに呼び出されると、例外を投げる', () => {
      assert(originalHistory.omitLength === null);
      let error = false;
      try {
        generateImageListHistory({
          type: OMIT,
          currentState: originalHistory,
        });
      } catch (e) {
        error = true;
      }
      assert(error === true);
    });
    it('新しいhistoryを返すため、副作用がない', () => {
      originalHistory.omitLength = 0;
      const newHistory = generateImageListHistory({
        type: OMIT,
        currentState: originalHistory,
      });
      const {history} = newHistory;
      assert(history.length === 3);
      assert(originalHistory.history !== newHistory.history);
    });
  });
});
<|endoftext|>


<commit_before>(function(){

    "use strict";

    /** This controller brings together the touch control and XMOT.FlyControllerBehavior
     *  to provide fly mode navigation using touch.
     *
     *  @constructor
     */
    XMOT.TouchFlyController = new XMOT.Class(XMOT.util.Attachable, {

        /**
         *  @this {XMOT.TouchFlyController}
         *  @param {Element|Transformable} targetViewGroup
         *  @param {Object} options
         *
         *  options:
         *  o behavior: options to be passed to XMOT.FlyControllerBehavior
         *  o touch: options to be passed to XMOT.TouchController
         *
         *  By default, the view can be rotated using the movement of a single finger,
         *  and movement can be done using zoom/pinch gestures.
         */
        initialize: function(targetViewGroup, options) {

            this.callSuper();

            var options = options || {};
            options.behavior = options.behavior || {};
            options.touch = options.touch || {};

            this.target = XMOT.util.getOrCreateTransformable(targetViewGroup);

            this._behavior = new XMOT.FlyControllerBehavior(this.target, options.behavior);

            if(options.touch.eventDispatcher === undefined)
                options.touch.eventDispatcher = this._createTouchEventDispatcher();

            this._touchCtrl = new XMOT.TouchController(this.target, options.touch);
            this._touchCtrl.onDrag = this.callback("_onDrag");
        },

        lookAt: function(point) {
            this._behavior.lookAt(point);
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        setPosition: function(position) {
            this._behavior.setPosition(position);
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        setOrientation: function(orientation) {
            this._behavior.setOrientation(orientation);
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        getPosition: function() {
            return this._behavior.getPosition();
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        getOrientation: function() {
            return this._behavior.getOrientation();
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        getMoveSpeed: function() {
            return this._behavior.getMoveSpeed();
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        setMoveSpeed: function(speed) {
            this._behavior.setMoveSpeed(speed);
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        getRotationSpeed: function() {
            return this._behavior.getRotationSpeed();
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        setRotationSpeed: function(speed) {
            this._behavior.setRotationSpeed(speed);
        },

        /**
         *  @this {XMOT.TouchFlyController}
         *  @protected
         *  @override
         */
        onAttach: function() {
            this._touchCtrl.attach();
        },

        /**
         *  @this {XMOT.TouchFlyController}
         *  @protected
         *  @override
         */
        onDetach: function() {
            this._touchCtrl.detach();
        },

        /**
         *  @this {XMOT.TouchFlyController}
         *  @private
         */
        _onDrag: function(action) {
            if (action.evt.touches.length > 1) {
                if (action.zoom > 1.0) { this._behavior.moveForward(); }
                if (action.zoom < 1.0) { this._behavior.moveBackward(); }
            } else {
                //invert delta to represent touch-"dragging" of a point
                this._behavior.rotate(-action.deltas[0].x, -action.deltas[0].y);
            }
        },

        /**
         *  @this {XMOT.TouchFlyController}
         *  @private
         */
        _createTouchEventDispatcher: function() {

            var disp = new XMOT.util.EventDispatcher();

            disp.registerCustomHandler('touchstart', function(evt){
                if(evt.type === 'touchstart')
                    return true;

                return false;
            });

            return disp;
        }
    });
}());
<commit_msg>camera-touchflyctrl: fixed bug<commit_after>(function(){

    "use strict";

    /** This controller brings together the touch control and XMOT.FlyControllerBehavior
     *  to provide fly mode navigation using touch.
     *
     *  @constructor
     */
    XMOT.TouchFlyController = new XMOT.Class(XMOT.util.Attachable, {

        /**
         *  @this {XMOT.TouchFlyController}
         *  @param {Element|Transformable} targetViewGroup
         *  @param {Object} options
         *
         *  options:
         *  o behavior: options to be passed to XMOT.FlyControllerBehavior
         *  o touch: options to be passed to XMOT.TouchController
         *
         *  By default, the view can be rotated using the movement of a single finger,
         *  and movement can be done using zoom/pinch gestures.
         */
        initialize: function(targetViewGroup, options) {

            this.callSuper();

            var options = options || {};
            options.behavior = options.behavior || {};
            options.touch = options.touch || {};

            this.target = XMOT.util.getOrCreateTransformable(targetViewGroup);

            this._behavior = new XMOT.FlyControllerBehavior(this.target, options.behavior);

            if(options.touch.eventDispatcher === undefined)
                options.touch.eventDispatcher = this._createTouchEventDispatcher();

            this._touchCtrl = new XMOT.TouchController(this.target, options.touch);
            this._touchCtrl.onDrag = this.callback("_onDrag");
        },

        lookAt: function(point) {
            this._behavior.lookAt(point);
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        setPosition: function(position) {
            this._behavior.setPosition(position);
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        setOrientation: function(orientation) {
            this._behavior.setOrientation(orientation);
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        getPosition: function() {
            return this._behavior.getPosition();
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        getOrientation: function() {
            return this._behavior.getOrientation();
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        getMoveSpeed: function() {
            return this._behavior.getMoveSpeed();
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        setMoveSpeed: function(speed) {
            this._behavior.setMoveSpeed(speed);
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        getRotationSpeed: function() {
            return this._behavior.getRotationSpeed();
        },

        /**
         *  @this {XMOT.TouchFlyController}
         */
        setRotationSpeed: function(speed) {
            this._behavior.setRotationSpeed(speed);
        },

        /**
         *  @this {XMOT.TouchFlyController}
         *  @protected
         *  @override
         */
        onAttach: function() {
            this._touchCtrl.attach();
        },

        /**
         *  @this {XMOT.TouchFlyController}
         *  @protected
         *  @override
         */
        onDetach: function() {
            this._touchCtrl.detach();
        },

        /**
         *  @this {XMOT.TouchFlyController}
         *  @private
         */
        _onDrag: function(action) {
            if (action.evt.touches.length > 1) {
                if (action.zoom > 1.0) { this._behavior.moveForward(); }
                if (action.zoom < 1.0) { this._behavior.moveBackward(); }
            } else {
                //invert delta to represent touch-"dragging" of a point
                this._behavior.rotate(-action.deltas[0].y, -action.deltas[0].x);
            }
        },

        /**
         *  @this {XMOT.TouchFlyController}
         *  @private
         */
        _createTouchEventDispatcher: function() {

            var disp = new XMOT.util.EventDispatcher();

            disp.registerCustomHandler('touchstart', function(evt){
                if(evt.type === 'touchstart')
                    return true;

                return false;
            });

            return disp;
        }
    });
}());
<|endoftext|>


<commit_before>//TODO: consider mass import from existing data
Meteor.startup(function() {
  if (Meteor.settings.development.generateFakeActivities) {
    var maxApplications = Meteor.settings.development.generateFakeActivities.maxApplications;
    var maxActivitiesPerApplication = Meteor.settings.development.generateFakeActivities.maxActivitiesPerApplication;
    console.log('regenerating max %d fake activities for %d applications...', maxActivitiesPerApplication, maxApplications);
  } else {
    console.log('WARNING : NOT regenerating fake activities');
    return;
  }

  var applications = Applications.find({}, {limit: maxApplications});
  var recruiter = Meteor.users.findOne({
    roles: 'recruiter',
  }, {
    fields: {
      _id: 1,
      username: 1,
    },
  });

  Activities.remove({});

  if (Activities.find().count() === 0) {
    var activity = {};
    applications.forEach(function(application) {
      var maxActivities = Math.floor(Math.random() * maxActivitiesPerApplication);
      for (i = 0; i < maxActivities; i++) {
        activity = {
          application: {
            _id: application._id,
            firstname: application.firstname,
            lastname: application.lastname,
            socialSecurityNumber: application.socialSecurityNumber,
            phase: application.phases.current.phase,
          },
          createdBy: recruiter.username,
          contactType: randomCollectionElement(ContactTypes).name,
          outcome: randomCollectionElement(ActivityOutcomes).name,
          notes: 'blablabla',
          deadline: new Date(),
          createdAt: new Date(),
          editedAt: new Date(),
        };

        activity._id = Activities.insert(activity);
        Applications.update({_id:application._id}, {$push: {activities: activity._id}});
      }
    });

    console.log('added', Activities.find().count(), 'activities.');
  }
});
<commit_msg>Create activities for applications with phase > 0<commit_after>//TODO: consider mass import from existing data
Meteor.startup(function() {
  if (Meteor.settings.development.generateFakeActivities) {
    var maxApplications = Meteor.settings.development.generateFakeActivities.maxApplications;
    var maxActivitiesPerApplication = Meteor.settings.development.generateFakeActivities.maxActivitiesPerApplication;
    console.log('regenerating max %d fake activities for %d applications...', maxActivitiesPerApplication, maxApplications);
  } else {
    console.log('WARNING : NOT regenerating fake activities');
    return;
  }

  var applications = Applications.find({'phases.current.phase': {$gt: 0}}, {limit: maxApplications});
  var recruiter = Meteor.users.findOne({
    roles: 'recruiter',
  }, {
    fields: {
      _id: 1,
      username: 1,
    },
  });

  Activities.remove({});

  if (Activities.find().count() === 0) {
    var activity = {};
    applications.forEach(function(application) {
      var maxActivities = Math.floor(Math.random() * maxActivitiesPerApplication);
      for (i = 0; i < maxActivities; i++) {
        activity = {
          application: {
            _id: application._id,
            firstname: application.firstname,
            lastname: application.lastname,
            socialSecurityNumber: application.socialSecurityNumber,
            phase: application.phases.current.phase,
          },
          createdBy: recruiter.username,
          contactType: randomCollectionElement(ContactTypes).name,
          outcome: randomCollectionElement(ActivityOutcomes).name,
          notes: Math.random() >= 0.5 ? 'blablabla' : '',
          deadline: new Date(),
          createdAt: new Date(),
          editedAt: new Date(),
        };

        activity._id = Activities.insert(activity);
        Applications.update({_id:application._id}, {$push: {activities: activity._id}});
      }
    });

    console.log('added', Activities.find().count(), 'activities.');
  }
});
<|endoftext|>