<commit_before>import PortMixin from "ember-debug/mixins/port-mixin";
import ProfileManager from "ember-debug/models/profile-manager";

var Ember = window.Ember;
var computed = Ember.computed;
var oneWay = computed.oneWay;
var later = Ember.run.later;

var profileManager = new ProfileManager();

var queue = [];

function push(info) {
  var index = queue.push(info);
  if (1 === index) {
    later(flush, 50);
  }
  return index - 1;
}

function flush() {
  var entry, i;
  for (i = 0; i < queue.length; i++) {
    entry = queue[i];
    if (entry.type === 'began') {
      queue[entry.endedIndex].profileNode = profileManager.began(entry.timestamp, entry.payload, entry.now);
    } else {
      profileManager.ended(entry.timestamp, entry.payload, entry.profileNode);
    }

  }
  queue.length = 0;
}

Ember.subscribe("render", {
  before: function(name, timestamp, payload) {
    var info = {
      type: 'began',
      timestamp: timestamp,
      payload: payload,
      now: Date.now()
    };
    return push(info);
  },

  after: function(name, timestamp, payload, beganIndex) {
    var endedInfo = {
      type: 'ended',
      timestamp: timestamp,
      payload: payload
    };

    var index = push(endedInfo);
    queue[beganIndex].endedIndex = index;
  }
});

export default Ember.Object.extend(PortMixin, {
  namespace: null,
  port: oneWay('namespace.port').readOnly(),
  application: oneWay('namespace.application').readOnly(),
  viewDebug: oneWay('namespace.viewDebug').readOnly(),
  portNamespace: 'render',

  profileManager: profileManager,

  init: function() {
    this._super();
    this._subscribeForViewTrees();
  },

  willDestroy: function() {
    this._super();
    this.profileManager.offProfilesAdded(this, this.sendAdded);
    this.profileManager.offProfilesAdded(this, this._updateViewTree);
  },

  _subscribeForViewTrees: function() {
    this.profileManager.onProfilesAdded(this, this._updateViewTree);
  },

  _updateViewTree: function(profiles) {
    var viewDurations = {};
    this._flatten(profiles).forEach(function(node) {
      if (node.viewGuid) {
        viewDurations[node.viewGuid] = node.duration;
      }
    });
    this.get('viewDebug').updateDurations(viewDurations);
  },

  _flatten: function(profiles, array) {
    var self = this;
    array = array || [];
    profiles.forEach(function(profile) {
      array.push(profile);
      self._flatten(profile.children, array);
    });
    return array;
  },

  sendAdded: function(profiles) {
    this.sendMessage('profilesAdded', { profiles: profiles });
  },

  messages: {
    watchProfiles: function() {
      this.sendMessage('profilesAdded', { profiles: this.profileManager.profiles });
      this.profileManager.onProfilesAdded(this, this.sendAdded);
    },

    releaseProfiles: function() {
      this.profileManager.offProfilesAdded(this, this.sendAdded);
    },

    clear: function() {
      this.profileManager.clearProfiles();
      this.sendMessage('profilesUpdated', {profiles: []});
    }
  }
});
<commit_msg>Fail silently during render errors<commit_after>import PortMixin from "ember-debug/mixins/port-mixin";
import ProfileManager from "ember-debug/models/profile-manager";

var Ember = window.Ember;
var computed = Ember.computed;
var oneWay = computed.oneWay;
var later = Ember.run.later;

var profileManager = new ProfileManager();

var queue = [];

function push(info) {
  var index = queue.push(info);
  if (1 === index) {
    later(flush, 50);
  }
  return index - 1;
}

function flush() {
  var entry, i;
  for (i = 0; i < queue.length; i++) {
    entry = queue[i];
    if (entry.type === 'began') {
      // If there was an error during rendering `entry.endedIndex` never gets set.
      if (entry.endedIndex) {
        queue[entry.endedIndex].profileNode = profileManager.began(entry.timestamp, entry.payload, entry.now);
      }
    } else {
      profileManager.ended(entry.timestamp, entry.payload, entry.profileNode);
    }

  }
  queue.length = 0;
}

Ember.subscribe("render", {
  before: function(name, timestamp, payload) {
    var info = {
      type: 'began',
      timestamp: timestamp,
      payload: payload,
      now: Date.now()
    };
    return push(info);
  },

  after: function(name, timestamp, payload, beganIndex) {
    var endedInfo = {
      type: 'ended',
      timestamp: timestamp,
      payload: payload
    };

    var index = push(endedInfo);
    queue[beganIndex].endedIndex = index;
  }
});

export default Ember.Object.extend(PortMixin, {
  namespace: null,
  port: oneWay('namespace.port').readOnly(),
  application: oneWay('namespace.application').readOnly(),
  viewDebug: oneWay('namespace.viewDebug').readOnly(),
  portNamespace: 'render',

  profileManager: profileManager,

  init: function() {
    this._super();
    this._subscribeForViewTrees();
  },

  willDestroy: function() {
    this._super();
    this.profileManager.offProfilesAdded(this, this.sendAdded);
    this.profileManager.offProfilesAdded(this, this._updateViewTree);
  },

  _subscribeForViewTrees: function() {
    this.profileManager.onProfilesAdded(this, this._updateViewTree);
  },

  _updateViewTree: function(profiles) {
    var viewDurations = {};
    this._flatten(profiles).forEach(function(node) {
      if (node.viewGuid) {
        viewDurations[node.viewGuid] = node.duration;
      }
    });
    this.get('viewDebug').updateDurations(viewDurations);
  },

  _flatten: function(profiles, array) {
    var self = this;
    array = array || [];
    profiles.forEach(function(profile) {
      array.push(profile);
      self._flatten(profile.children, array);
    });
    return array;
  },

  sendAdded: function(profiles) {
    this.sendMessage('profilesAdded', { profiles: profiles });
  },

  messages: {
    watchProfiles: function() {
      this.sendMessage('profilesAdded', { profiles: this.profileManager.profiles });
      this.profileManager.onProfilesAdded(this, this.sendAdded);
    },

    releaseProfiles: function() {
      this.profileManager.offProfilesAdded(this, this.sendAdded);
    },

    clear: function() {
      this.profileManager.clearProfiles();
      this.sendMessage('profilesUpdated', {profiles: []});
    }
  }
});
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Reciprocity, Inc - All Rights Reserved
 * Unauthorized use, copying, distribution, displaying, or public performance
 * of this file, via any medium, is strictly prohibited. All information
 * contained herein is proprietary and confidential and may not be shared
 * with any third party without the express written consent of Reciprocity, Inc.
 * Created By: silas@reciprocitylabs.com
 * Maintained By: silas@reciprocitylabs.com
 */

(function ($, CMS, GGRC) {
  var RisksExtension = {};

  // Insert risk mappings to all gov/business object types
  var _risk_object_types = [
      "Program",
      "Regulation", "Standard", "Policy", "Contract",
      "Objective", "Control", "Section", "Clause",
      "System", "Process",
      "DataAsset", "Facility", "Market", "Product", "Project",
      "MultitypeSearch", "Issue", "ControlAssessment", "AccessGroup",
      "Person", "OrgGroup", "Vendor"
    ],
    related_object_descriptors = {},
    threat_actor_descriptor, risk_descriptor;

  // Register `risks` extension with GGRC
  GGRC.extensions.push(RisksExtension);

  RisksExtension.name = "risks";

  // Register Risk Assessment models for use with `infer_object_type`
  RisksExtension.object_type_decision_tree = function () {
    return {
      "risk": CMS.Models.Risk,
      "threat_actor": CMS.Models.ThreatActor
    };
  };

  // Configure mapping extensions for ggrc_risks
  RisksExtension.init_mappings = function init_mappings() {
    var Proxy = GGRC.MapperHelpers.Proxy,
      Direct = GGRC.MapperHelpers.Direct,
      Cross = GGRC.MapperHelpers.Cross,
      CustomFilter = GGRC.MapperHelpers.CustomFilter,
      Reify = GGRC.MapperHelpers.Reify,
      Search = GGRC.MapperHelpers.Search,
      TypeFilter = GGRC.MapperHelpers.TypeFilter,
      Multi = GGRC.MapperHelpers.Multi,
      Indirect = GGRC.MapperHelpers.Indirect;

    // Add mappings for risk objects
    var mappings = {

      related: {
        related_objects_as_source: Proxy(
          null, "destination", "Relationship", "source", "related_destinations"),
        related_objects_as_destination: Proxy(
          null, "source", "Relationship", "destination", "related_sources"),
        related_objects: Multi(["related_objects_as_source", "related_objects_as_destination"]),
      },
      related_objects: {
        _canonical: {
          "related_objects_as_source": _risk_object_types,
        },
        related_programs: TypeFilter("related_objects", "Program"),
        related_data_assets: TypeFilter("related_objects", "DataAsset"),
        related_access_groups: TypeFilter("related_objects", "AccessGroup"),
        related_facilities: TypeFilter("related_objects", "Facility"),
        related_markets: TypeFilter("related_objects", "Market"),
        related_processes: TypeFilter("related_objects", "Process"),
        related_products: TypeFilter("related_objects", "Product"),
        related_projects: TypeFilter("related_objects", "Project"),
        related_systems: TypeFilter("related_objects", "System"),
        related_controls: TypeFilter("related_objects", "Control"),
        related_clauses: TypeFilter("related_objects", "Clause"),
        related_sections: TypeFilter("related_objects", "Section"),
        related_regulations: TypeFilter("related_objects", "Regulation"),
        related_contracts: TypeFilter("related_objects", "Contract"),
        related_policies: TypeFilter("related_objects", "Policy"),
        related_standards: TypeFilter("related_objects", "Standard"),
        related_objectives: TypeFilter("related_objects", "Objective"),
        related_issues: TypeFilter("related_objects", "Issue"),
        related_people: TypeFilter("related_objects", "Person"),
        related_org_groups: TypeFilter("related_objects", "OrgGroup"),
        related_vendors: TypeFilter("related_objects", "Vendor")
      },
      related_risk: {
        _canonical: {
          "related_objects_as_source": ['Risk'].concat(_risk_object_types)
        },
        related_risks: TypeFilter("related_objects", "Risk"),
      },
      related_threat_actor: {
        _canonical: {
          "related_objects_as_source": ['ThreatActor'].concat(_risk_object_types)
        },
        related_threat_actors: TypeFilter("related_objects", "ThreatActor"),
      },
      Risk: {
        _mixins: ['related', 'related_objects', 'related_threat_actor'],
        orphaned_objects: Multi([]),
      },
      ThreatActor: {
        _mixins: ['related', 'related_objects', 'related_risk'],
        orphaned_objects: Multi([])
      },
      Person: {
        owned_risks: Indirect("Risk", "contact"),
        owned_threat_actors: Indirect("ThreatActor", "contact"),
      },
    };

    can.each(_risk_object_types, function (type) {
        mappings[type] = {
          _canonical: {
            "related_objects_as_source": ['Risk', 'ThreatActor']
          },
          _mixins: ['related', 'related_risk', 'related_threat_actor'],
        };
    });
    new GGRC.Mappings("ggrc_risks", mappings);
  };

  // Override GGRC.extra_widget_descriptors and GGRC.extra_default_widgets
  // Initialize widgets for risk page
  RisksExtension.init_widgets = function init_widgets() {
    var page_instance = GGRC.page_instance(),
        is_my_work = function is_my_work() {
          return page_instance.type === "Person";
        },
        related_or_owned = is_my_work() ? 'owned_' : 'related_',
        sorted_widget_types = _.sortBy(_risk_object_types, function(type) {
          var model = CMS.Models[type] || {};
          return model.title_plural || type;
        });

    // Init widget descriptors:
    can.each(sorted_widget_types, function (model_name) {

      if (model_name === 'MultitypeSearch') {
        return;
      }

      var model = CMS.Models[model_name],
          widgets_by_type = GGRC.tree_view.base_widgets_by_type;

      widgets_by_type[model_name] = widgets_by_type[model_name].concat(["Risk", "ThreatActor"]);

      related_object_descriptors[model_name] = {
        content_controller: CMS.Controllers.TreeView,
        content_controller_selector: "ul",
        widget_initial_content: '

',
        widget_id: model.table_plural,
        widget_name: model.model_plural,
        widget_icon: model.table_singular,
        content_controller_options: {
          child_options: [],
          draw_children: false,
          parent_instance: page_instance,
          model: model,
          mapping: "related_" + model.table_plural,
        }
      };
    });
    threat_actor_descriptor = {
      content_controller: CMS.Controllers.TreeView,
      content_controller_selector: "ul",
      widget_initial_content: '

',
      widget_id: CMS.Models.ThreatActor.table_plural,
      widget_name: CMS.Models.ThreatActor.title_plural,
      widget_icon: CMS.Models.ThreatActor.table_singular,
      content_controller_options: {
        child_options: [],
        draw_children: false,
        parent_instance: page_instance,
        model: CMS.Models.ThreatActor,
        mapping: related_or_owned + CMS.Models.ThreatActor.table_plural,
        footer_view: is_my_work() ? null : GGRC.mustache_path + "/base_objects/tree_footer.mustache"
      }
    };
    risk_descriptor = {
      content_controller: CMS.Controllers.TreeView,
      content_controller_selector: "ul",
      widget_initial_content: '

',
      widget_id: CMS.Models.Risk.table_plural,
      widget_name: CMS.Models.Risk.title_plural,
      widget_icon: CMS.Models.Risk.table_singular,
      content_controller_options: {
        child_options: [],
        draw_children: false,
        parent_instance: page_instance,
        model: CMS.Models.Risk,
        mapping: related_or_owned + CMS.Models.Risk.table_plural,
        footer_view: is_my_work() ? null : GGRC.mustache_path + "/base_objects/tree_footer.mustache"
      }
    };

    if (page_instance instanceof CMS.Models.Risk) {
      RisksExtension.init_widgets_for_risk_page();
    } else if (page_instance instanceof CMS.Models.ThreatActor) {
      RisksExtension.init_widgets_for_threat_actor_page();
    } else if (page_instance instanceof CMS.Models.Person) {
      RisksExtension.init_widgets_for_person_page();
    } else {
      RisksExtension.init_widgets_for_other_pages();
    }
  };

  RisksExtension.init_widgets_for_risk_page =
    function init_widgets_for_risk_page() {
      var risk_descriptors = $.extend({},
        related_object_descriptors, {
          ThreatActor: threat_actor_descriptor
        }
      );
      new GGRC.WidgetList("ggrc_risks", {
        Risk: risk_descriptors
      });
  };

  RisksExtension.init_widgets_for_threat_actor_page =
    function init_widgets_for_threat_actor_page() {
      var threat_actor_descriptors = $.extend({},
        related_object_descriptors, {
          Risk: risk_descriptor
        }
      );
      new GGRC.WidgetList("ggrc_risks", {
        ThreatActor: threat_actor_descriptors
      });
  };

  RisksExtension.init_widgets_for_person_page =
    function init_widgets_for_person_page() {
      var people_widgets = $.extend({}, {
          ThreatActor: threat_actor_descriptor
        }, {
          Risk: risk_descriptor
        }
      );

      new GGRC.WidgetList("ggrc_risks", {
        Person: people_widgets,
      });
  };

  RisksExtension.init_widgets_for_other_pages =
    function init_widgets_for_other_pages() {
      var descriptor = {},
          page_instance = GGRC.page_instance();
      if (page_instance && ~can.inArray(page_instance.constructor.shortName, _risk_object_types)) {
        descriptor[page_instance.constructor.shortName] = {
          risk: risk_descriptor,
          threat_actor: threat_actor_descriptor,
        };
      }
      new GGRC.WidgetList("ggrc_risks", descriptor);
  };

  GGRC.register_hook("LHN.Sections_risk", GGRC.mustache_path + "/dashboard/lhn_risks");

  RisksExtension.init_mappings();

})(this.can.$, this.CMS, this.GGRC);
<commit_msg>Revert accidental removal of `related_control_assessments`.<commit_after>/*
 * Copyright (C) 2015 Reciprocity, Inc - All Rights Reserved
 * Unauthorized use, copying, distribution, displaying, or public performance
 * of this file, via any medium, is strictly prohibited. All information
 * contained herein is proprietary and confidential and may not be shared
 * with any third party without the express written consent of Reciprocity, Inc.
 * Created By: silas@reciprocitylabs.com
 * Maintained By: silas@reciprocitylabs.com
 */

(function ($, CMS, GGRC) {
  var RisksExtension = {};

  // Insert risk mappings to all gov/business object types
  var _risk_object_types = [
      "Program",
      "Regulation", "Standard", "Policy", "Contract",
      "Objective", "Control", "Section", "Clause",
      "System", "Process",
      "DataAsset", "Facility", "Market", "Product", "Project",
      "MultitypeSearch", "Issue", "ControlAssessment", "AccessGroup",
      "Person", "OrgGroup", "Vendor"
    ],
    related_object_descriptors = {},
    threat_actor_descriptor, risk_descriptor;

  // Register `risks` extension with GGRC
  GGRC.extensions.push(RisksExtension);

  RisksExtension.name = "risks";

  // Register Risk Assessment models for use with `infer_object_type`
  RisksExtension.object_type_decision_tree = function () {
    return {
      "risk": CMS.Models.Risk,
      "threat_actor": CMS.Models.ThreatActor
    };
  };

  // Configure mapping extensions for ggrc_risks
  RisksExtension.init_mappings = function init_mappings() {
    var Proxy = GGRC.MapperHelpers.Proxy,
      Direct = GGRC.MapperHelpers.Direct,
      Cross = GGRC.MapperHelpers.Cross,
      CustomFilter = GGRC.MapperHelpers.CustomFilter,
      Reify = GGRC.MapperHelpers.Reify,
      Search = GGRC.MapperHelpers.Search,
      TypeFilter = GGRC.MapperHelpers.TypeFilter,
      Multi = GGRC.MapperHelpers.Multi,
      Indirect = GGRC.MapperHelpers.Indirect;

    // Add mappings for risk objects
    var mappings = {

      related: {
        related_objects_as_source: Proxy(
          null, "destination", "Relationship", "source", "related_destinations"),
        related_objects_as_destination: Proxy(
          null, "source", "Relationship", "destination", "related_sources"),
        related_objects: Multi(["related_objects_as_source", "related_objects_as_destination"]),
      },
      related_objects: {
        _canonical: {
          "related_objects_as_source": _risk_object_types,
        },
        related_programs: TypeFilter("related_objects", "Program"),
        related_data_assets: TypeFilter("related_objects", "DataAsset"),
        related_access_groups: TypeFilter("related_objects", "AccessGroup"),
        related_facilities: TypeFilter("related_objects", "Facility"),
        related_markets: TypeFilter("related_objects", "Market"),
        related_processes: TypeFilter("related_objects", "Process"),
        related_products: TypeFilter("related_objects", "Product"),
        related_projects: TypeFilter("related_objects", "Project"),
        related_systems: TypeFilter("related_objects", "System"),
        related_controls: TypeFilter("related_objects", "Control"),
        related_clauses: TypeFilter("related_objects", "Clause"),
        related_sections: TypeFilter("related_objects", "Section"),
        related_regulations: TypeFilter("related_objects", "Regulation"),
        related_contracts: TypeFilter("related_objects", "Contract"),
        related_policies: TypeFilter("related_objects", "Policy"),
        related_standards: TypeFilter("related_objects", "Standard"),
        related_objectives: TypeFilter("related_objects", "Objective"),
        related_issues: TypeFilter("related_objects", "Issue"),
        related_control_assessments: TypeFilter("related_objects", "ControlAssessment"),
        related_people: TypeFilter("related_objects", "Person"),
        related_org_groups: TypeFilter("related_objects", "OrgGroup"),
        related_vendors: TypeFilter("related_objects", "Vendor")
      },
      related_risk: {
        _canonical: {
          "related_objects_as_source": ['Risk'].concat(_risk_object_types)
        },
        related_risks: TypeFilter("related_objects", "Risk"),
      },
      related_threat_actor: {
        _canonical: {
          "related_objects_as_source": ['ThreatActor'].concat(_risk_object_types)
        },
        related_threat_actors: TypeFilter("related_objects", "ThreatActor"),
      },
      Risk: {
        _mixins: ['related', 'related_objects', 'related_threat_actor'],
        orphaned_objects: Multi([]),
      },
      ThreatActor: {
        _mixins: ['related', 'related_objects', 'related_risk'],
        orphaned_objects: Multi([])
      },
      Person: {
        owned_risks: Indirect("Risk", "contact"),
        owned_threat_actors: Indirect("ThreatActor", "contact"),
      },
    };

    can.each(_risk_object_types, function (type) {
        mappings[type] = {
          _canonical: {
            "related_objects_as_source": ['Risk', 'ThreatActor']
          },
          _mixins: ['related', 'related_risk', 'related_threat_actor'],
        };
    });
    new GGRC.Mappings("ggrc_risks", mappings);
  };

  // Override GGRC.extra_widget_descriptors and GGRC.extra_default_widgets
  // Initialize widgets for risk page
  RisksExtension.init_widgets = function init_widgets() {
    var page_instance = GGRC.page_instance(),
        is_my_work = function is_my_work() {
          return page_instance.type === "Person";
        },
        related_or_owned = is_my_work() ? 'owned_' : 'related_',
        sorted_widget_types = _.sortBy(_risk_object_types, function(type) {
          var model = CMS.Models[type] || {};
          return model.title_plural || type;
        });

    // Init widget descriptors:
    can.each(sorted_widget_types, function (model_name) {

      if (model_name === 'MultitypeSearch') {
        return;
      }

      var model = CMS.Models[model_name],
          widgets_by_type = GGRC.tree_view.base_widgets_by_type;

      widgets_by_type[model_name] = widgets_by_type[model_name].concat(["Risk", "ThreatActor"]);

      related_object_descriptors[model_name] = {
        content_controller: CMS.Controllers.TreeView,
        content_controller_selector: "ul",
        widget_initial_content: '

',
        widget_id: model.table_plural,
        widget_name: model.model_plural,
        widget_icon: model.table_singular,
        content_controller_options: {
          child_options: [],
          draw_children: false,
          parent_instance: page_instance,
          model: model,
          mapping: "related_" + model.table_plural,
        }
      };
    });
    threat_actor_descriptor = {
      content_controller: CMS.Controllers.TreeView,
      content_controller_selector: "ul",
      widget_initial_content: '

',
      widget_id: CMS.Models.ThreatActor.table_plural,
      widget_name: CMS.Models.ThreatActor.title_plural,
      widget_icon: CMS.Models.ThreatActor.table_singular,
      content_controller_options: {
        child_options: [],
        draw_children: false,
        parent_instance: page_instance,
        model: CMS.Models.ThreatActor,
        mapping: related_or_owned + CMS.Models.ThreatActor.table_plural,
        footer_view: is_my_work() ? null : GGRC.mustache_path + "/base_objects/tree_footer.mustache"
      }
    };
    risk_descriptor = {
      content_controller: CMS.Controllers.TreeView,
      content_controller_selector: "ul",
      widget_initial_content: '

',
      widget_id: CMS.Models.Risk.table_plural,
      widget_name: CMS.Models.Risk.title_plural,
      widget_icon: CMS.Models.Risk.table_singular,
      content_controller_options: {
        child_options: [],
        draw_children: false,
        parent_instance: page_instance,
        model: CMS.Models.Risk,
        mapping: related_or_owned + CMS.Models.Risk.table_plural,
        footer_view: is_my_work() ? null : GGRC.mustache_path + "/base_objects/tree_footer.mustache"
      }
    };

    if (page_instance instanceof CMS.Models.Risk) {
      RisksExtension.init_widgets_for_risk_page();
    } else if (page_instance instanceof CMS.Models.ThreatActor) {
      RisksExtension.init_widgets_for_threat_actor_page();
    } else if (page_instance instanceof CMS.Models.Person) {
      RisksExtension.init_widgets_for_person_page();
    } else {
      RisksExtension.init_widgets_for_other_pages();
    }
  };

  RisksExtension.init_widgets_for_risk_page =
    function init_widgets_for_risk_page() {
      var risk_descriptors = $.extend({},
        related_object_descriptors, {
          ThreatActor: threat_actor_descriptor
        }
      );
      new GGRC.WidgetList("ggrc_risks", {
        Risk: risk_descriptors
      });
  };

  RisksExtension.init_widgets_for_threat_actor_page =
    function init_widgets_for_threat_actor_page() {
      var threat_actor_descriptors = $.extend({},
        related_object_descriptors, {
          Risk: risk_descriptor
        }
      );
      new GGRC.WidgetList("ggrc_risks", {
        ThreatActor: threat_actor_descriptors
      });
  };

  RisksExtension.init_widgets_for_person_page =
    function init_widgets_for_person_page() {
      var people_widgets = $.extend({}, {
          ThreatActor: threat_actor_descriptor
        }, {
          Risk: risk_descriptor
        }
      );

      new GGRC.WidgetList("ggrc_risks", {
        Person: people_widgets,
      });
  };

  RisksExtension.init_widgets_for_other_pages =
    function init_widgets_for_other_pages() {
      var descriptor = {},
          page_instance = GGRC.page_instance();
      if (page_instance && ~can.inArray(page_instance.constructor.shortName, _risk_object_types)) {
        descriptor[page_instance.constructor.shortName] = {
          risk: risk_descriptor,
          threat_actor: threat_actor_descriptor,
        };
      }
      new GGRC.WidgetList("ggrc_risks", descriptor);
  };

  GGRC.register_hook("LHN.Sections_risk", GGRC.mustache_path + "/dashboard/lhn_risks");

  RisksExtension.init_mappings();

})(this.can.$, this.CMS, this.GGRC);
<|endoftext|>


<commit_before>/* eslint new-cap: "off" */
'use strict';

const Observer = require('./Observer');
const { isClass } = require('./utils');
const info = require('debug')('cqrs:info');

/**
 * Listens to Saga events,
 * creates new saga or restores it from event store,
 * applies new events
 * and passes command(s) to command bus
 */
module.exports = class SagaEventHandler extends Observer {

	/**
	 * Creates an instance of SagaEventHandler
	 *
	 * @param {object} options
	 * @param {ISagaConstructor | ISagaFactory} options.sagaType
	 * @param {IEventStore} options.eventStore
	 * @param {ICommandBus} options.commandBus
	 * @param {string} [options.queueName]
	 * @param {string[]} [options.startsWith]
	 * @param {string[]} [options.handles]
	 */
	constructor(options) {
		if (!options) throw new TypeError('options argument required');
		if (!options.sagaType) throw new TypeError('options.sagaType argument required');
		if (!options.eventStore) throw new TypeError('options.eventStore argument required');
		if (!options.commandBus) throw new TypeError('options.commandBus argument required');

		super();

		this._eventStore = options.eventStore;
		this._commandBus = options.commandBus;
		this._queueName = options.queueName;

		if (isClass(options.sagaType)) {
			/** @type {ISagaConstructor} */
			// @ts-ignore
			const SagaType = options.sagaType;

			this._sagaFactory = params => new SagaType(params);
			this._startsWith = SagaType.startsWith;
			this._handles = SagaType.handles;
		}
		else {
			this._sagaFactory = options.sagaType;
			this._startsWith = options.startsWith;
			this._handles = options.handles;
		}
	}

	/**
	 * Overrides observer subscribe method
	 */
	subscribe(eventStore) {
		Observer.subscribe(eventStore, this, {
			messageTypes: [...this._startsWith, ...this._handles],
			masterHandler: this.handle,
			queueName: this._queueName
		});
	}

	/**
	 * Handle saga event
	 *
	 * @param {IEvent} event
	 * @returns {Promise<void>}
	 */
	async handle(event) {
		if (!event) throw new TypeError('event argument required');
		if (!event.type) throw new TypeError('event.type argument required');

		const saga = this._startsWith.includes(event.type) ?
			await this._createSaga() :
			await this._restoreSaga(event.sagaId, event);

		const r = saga.apply(event);
		if (r instanceof Promise)
			await r;

		while (saga.uncommittedMessages.length) {

			const commands = saga.uncommittedMessages;
			saga.resetUncommittedMessages();
			info('%s "%s" event processed, %s produced', event.type, commands.map(c => c.type).join(',') || 'no commands');

			for (const command of commands) {

				// attach event context to produced command
				command.context = event.context;

				try {
					await this._commandBus.sendRaw(command);
				}
				catch (err) {
					if (typeof saga.onError === 'function') {
						// let saga to handle the error
						saga.onError(err, { event, command });
					}
					else {
						throw err;
					}
				}
			}
		}
	}

	/**
	 * Create new saga instance
	 *
	 * @returns {Promise<ISaga>}
	 * @private
	 */
	async _createSaga() {
		const id = await this._eventStore.getNewId();

		/** @type {ISaga} */
		const saga = this._sagaFactory.call(null, { id });
		info('%s instance created', saga);

		return saga;
	}

	/**
	 * Restore saga from event store
	 *
	 * @param {Identifier} id
	 * @param {IEvent} event Event that triggered saga execution
	 * @returns {Promise<ISaga>}
	 * @private
	 */
	async _restoreSaga(id, event) {
		if (!id) throw new TypeError('id argument required');

		const events = await this._eventStore.getSagaEvents(id, { beforeEvent: event });

		/** @type {ISaga} */
		const saga = this._sagaFactory.call(null, { id, events });
		info('%s state restored from %s', saga, events);

		return saga;
	}
};
<commit_msg>* minor refactoring<commit_after>/* eslint new-cap: "off" */
'use strict';

const Observer = require('./Observer');
const { isClass } = require('./utils');
const info = require('debug')('cqrs:info');

/**
 * Listens to Saga events,
 * creates new saga or restores it from event store,
 * applies new events
 * and passes command(s) to command bus
 */
module.exports = class SagaEventHandler extends Observer {

	/**
	 * Creates an instance of SagaEventHandler
	 *
	 * @param {object} options
	 * @param {ISagaConstructor | ISagaFactory} options.sagaType
	 * @param {IEventStore} options.eventStore
	 * @param {ICommandBus} options.commandBus
	 * @param {string} [options.queueName]
	 * @param {string[]} [options.startsWith]
	 * @param {string[]} [options.handles]
	 */
	constructor(options) {
		if (!options) throw new TypeError('options argument required');
		if (!options.sagaType) throw new TypeError('options.sagaType argument required');
		if (!options.eventStore) throw new TypeError('options.eventStore argument required');
		if (!options.commandBus) throw new TypeError('options.commandBus argument required');

		super();

		this._eventStore = options.eventStore;
		this._commandBus = options.commandBus;
		this._queueName = options.queueName;

		if (isClass(options.sagaType)) {
			/** @type {ISagaConstructor} */
			// @ts-ignore
			const SagaType = options.sagaType;

			this._sagaFactory = params => new SagaType(params);
			this._startsWith = SagaType.startsWith;
			this._handles = SagaType.handles;
		}
		else {
			if (!Array.isArray(options.startsWith)) throw new TypeError('options.startsWith argument must be an Array');
			if (!Array.isArray(options.handles)) throw new TypeError('options.handles argument must be an Array');

			this._sagaFactory = options.sagaType;
			this._startsWith = options.startsWith;
			this._handles = options.handles;
		}
	}

	/**
	 * Overrides observer subscribe method
	 */
	subscribe(eventStore) {
		Observer.subscribe(eventStore, this, {
			messageTypes: [...this._startsWith, ...this._handles],
			masterHandler: this.handle,
			queueName: this._queueName
		});
	}

	/**
	 * Handle saga event
	 *
	 * @param {IEvent} event
	 * @returns {Promise<void>}
	 */
	async handle(event) {
		if (!event) throw new TypeError('event argument required');
		if (!event.type) throw new TypeError('event.type argument required');

		const saga = this._startsWith.includes(event.type) ?
			await this._createSaga() :
			await this._restoreSaga(event);

		const r = saga.apply(event);
		if (r instanceof Promise)
			await r;

		while (saga.uncommittedMessages.length) {

			const commands = saga.uncommittedMessages;
			saga.resetUncommittedMessages();
			info('%s "%s" event processed, %s produced', event.type, commands.map(c => c.type).join(',') || 'no commands');

			for (const command of commands) {

				// attach event context to produced command
				command.context = event.context;

				try {
					await this._commandBus.sendRaw(command);
				}
				catch (err) {
					if (typeof saga.onError === 'function') {
						// let saga to handle the error
						saga.onError(err, { event, command });
					}
					else {
						throw err;
					}
				}
			}
		}
	}

	/**
	 * Create new saga instance
	 *
	 * @returns {Promise<ISaga>}
	 * @private
	 */
	async _createSaga() {
		const id = await this._eventStore.getNewId();

		/** @type {ISaga} */
		const saga = this._sagaFactory.call(null, { id });
		info('%s instance created', saga);

		return saga;
	}

	/**
	 * Restore saga from event store
	 *
	 * @param {IEvent} event Event that triggered saga execution
	 * @returns {Promise<ISaga>}
	 * @private
	 */
	async _restoreSaga(event) {
		if (!event.sagaId) throw new TypeError('event.sagaId argument required');

		const events = await this._eventStore.getSagaEvents(event.sagaId, { beforeEvent: event });

		/** @type {ISaga} */
		const saga = this._sagaFactory.call(null, { id: event.sagaId, events });
		info('%s state restored from %s', saga, events);

		return saga;
	}
};
<|endoftext|>


<commit_before>'use strict';

var idAux = 0;

function carregarDadosNaPagina() {
    $.ajax({ url: urlCavaleiroGet, type: 'GET' })
    .then(
        function onSuccess(res) {
            console.log(res.data);
            var $cavaleiros = $('#cavaleiros');
            res.data.forEach(function (cava) {
                $cavaleiros.append(
                    $('
').attr('data-id-cavaleiro', cava.Id).append(cava.Nome)
                .append(
            $('<button>')
                .attr('data-cavaleiro-id', cava.Id)
                .click(editarCavaleiroNoServidor)
                .text('Editar')
         ).append(
        $('<button>')
                .attr('data-cavaleiro-id', cava.Id)
                .click(excluirCavaleiroNoServidor)
                .text('Excluir')));
                idAux = cava.Id;
            });
        },
        function onError(res) {
            console.error(':(');
            console.error(res);

            var criarSpanComErro = function (msg) {
                return $('').text(msg).addClass('erro');
            };

            $('#feedback')
            .append(criarSpanComErro(res.status))
            .append($('
'))
            .append(criarSpanComErro(res.statusText));
        }
    )
    .always(function (res) {
        console.log('acabouuuuuuuu');
    });
};

setInterval(function () {
    var aux = 0;
    var contador = 0;
    $.ajax({ url: urlCavaleiroGet, type: 'GET' })
    .then(
    function onSuccess(res) {
        var $cavaleiros = $('#cavaleiros');
        res.data.forEach(function (cava) {
            if (cava.Id > idAux) {
                contador++;
                $cavaleiros.append($('
').attr('data-id-cavaleiro', cava.Id).append(cava.Nome).append(
            $('<button>')
                .attr('data-cavaleiro-id', cava.Id)
                .click(editarCavaleiroNoServidor)
                .text('Editar')
         ).append(
        $('<button>')
                .attr('data-cavaleiro-id', cava.Id)
                .click(excluirCavaleiroNoServidor)
                .text('Excluir')));
                idAux = cava.Id;
            }
        });
        notificar(contador);
    }
    );
}, 5000);

function notificar(cavaleirosAdicionados) {
    if (cavaleirosAdicionados !== 0) {
        Notification.requestPermission()
            .then(function (result) {
    if (result === 'granted') {
        var frase = "";
        if (cavaleirosAdicionados === 1) {
            frase = "1 novo cavaleiro foi adicionado."
        } else {
            frase = cavaleirosAdicionados + " novos cavaleiros foram adicionados.";
        }
        var options = { body: frase, icon: 'https://cdn0.iconfinder.com/data/icons/the-middle-ages/500/Knight_knight_helmet-512.png' }
                    new Notification('', options);
       }
     })
    }
};

function excluirCavaleiroNoServidor() {
    var cavaleiroId = parseInt($(this).attr('data-cavaleiro-id'));
    $.ajax({
        url: '/Cavaleiro/Delete',
        type: 'DELETE',
        data: { id: cavaleiroId }
    })
};

carregarDadosNaPagina();

function editarCavaleiroNoServidor() {
    var cavaleiroId = parseInt($(this).attr('data-cavaleiro-id'));
    $.get('/Cavaleiro/GetById', { id: cavaleiroId })
        .done(function (detalhe) {
            cavaleiroHardCoded = detalhe.data;
            cavaleiroHardCoded.Nome = 'Novo nome após update ' + new Date().getTime();
            cavaleiroHardCoded.AlturaCm = 205;
            cavaleiroHardCoded.Signo = 3;
            cavaleiroHardCoded.TipoSanguineo = 2;
            cavaleiroHardCoded.DataNascimento = new Date(2001, 0, 15);
            cavaleiroHardCoded.Golpes[0].Nome = 'Voadora do Sub-Zero Brasileiro'
            cavaleiroHardCoded.Golpes[1].Nome = 'Cólera dos 42 dragões';
            cavaleiroHardCoded.Golpes[2] = { Nome: 'Novo golpe aterrador' };
            cavaleiroHardCoded.LocalNascimento.Texto = 'Porto Alegre';
            cavaleiroHardCoded.LocalTreinamento.Texto = 'Alvorada';
            cavaleiroHardCoded.Imagens[0].Url = 'https://cloud.githubusercontent.com/assets/526075/15443404/5c97dde6-1ebe-11e6-8ae6-83372051dda7.png';
            cavaleiroHardCoded.Imagens[0].IsThumb = true;
            cavaleiroHardCoded.Imagens[1].Url = 'https://cloud.githubusercontent.com/assets/526075/15443410/6e9ba586-1ebe-11e6-8b90-64aca9e18a32.png';
            cavaleiroHardCoded.Imagens[1].IsThumb = false;

            $.ajax({
                url: '/Cavaleiro/Put',
                type: 'PUT',
                data: cavaleiroHardCoded
            });
        });
};

$(function () {

    var $frmNovoCavaleiro = $('#frmNovoCavaleiro');
    $frmNovoCavaleiro.submit(function (e) {
        debugger;
        var cavaleiro = converterFormParaCavaleiro($frmNovoCavaleiro);
        $.ajax({
            url: urlCavaleiroPost,
            type: 'POST',
            data: cavaleiro
        });
        $frmNovoCavaleiro[0].reset();
        return e.preventDefault();
    });

    var $novasImagens = $('#novasImagens');

    $('#btnAdicionarImg').click(function () {
        var $novoLi = gerarElementoLiComInputs();
        $novasImagens.append($novoLi);
    });

    $('#btnAdicionarGolpe').click(function () {
        $('#novosGolpes').append(gerarElementoLiComInputTexto());
    });

});

function converterFormParaCavaleiro($form) {
    var formData = new FormData($form[0]);
    var novasImagens = [];
    $('#novasImagens li').each(function () {
        novasImagens.push({
            url: $(this).find('input[name=urlImagem]').val(),
            isThumb: $(this).find('input[name=isThumb]').is(':checked')
        });
    });
    var novosGolpes = [];
    $('#novosGolpes li').each(function (i) {
        novosGolpes.push($(this).find('input[name=golpe]').val());
    });

    return {
        Nome: formData.get('nome').val(),
        TipoSanguineo: parseInt(formData.get('tipoSanguineo').val()),
        Imagens: novasImagens,
        DataNascimento: (data || new Date()).toISOString(),
        AlturaCm: parseDouble(formData.get('alturaMetros').val()) * 100,
        PesoLb: parseDouble(formData.get('pesoKg').val()) * 2.20462262,
        Signo: parseInt(formData.get('signo').val()),
        LocalNascimento: { Texto: formData.get('localNascimento').val() },
        LocalTreinamento: { Texto: formData.get('localTreinamento').val() },
        Golpes: novosGolpes
    };
};

function gerarElementoLiComInputs() {
    var $novoTxt = $('<input>').attr('name', 'urlImagem').attr('type', 'text').attr('placeholder', 'Ex: bit.ly/shiryu.png');
    var $novoCheckbox =
      $('').append(
        $('<input>')
        .attr('type', 'checkbox')
        .attr('name', 'isThumb')
        .attr('checked', 'checked')
      ).append('É thumbnail?');
    return $('
').append($novoTxt).append($novoCheckbox);
};

function gerarElementoLiComInputTexto() {
    var $novoTxt = $('<input>').attr('name', 'golpe').attr('type', 'text').attr('placeholder', 'Ex: Pó de diamante');
    return $('
').append($novoTxt);
};

function registrarEventoDoBotao() {
    $('#btnCriar').click(function () {

        $.ajax({
            url: urlCavaleiroPost,
            type: 'POST',
            data: {
                Nome: 'Xiru ' + new Date().getTime(),
                AlturaCm: 187,
                Signo: 7,
                TipoSanguineo: 1,
                DataNascimento: new Date(),
                Golpes: ['Cólera do Dragão', 'Cólera dos 100 dragões'],
                LocalNascimento: {
                    Texto: 'Beijing'
                },
                LocalTreinamento: {
                    Texto: '5 picos de rosan'
                },
                Imagens: [{
                    Url: 'http://images.uncyc.org/pt/3/37/Shiryumestrepokemon.jpg',
                    IsThumb: true
                }, {
                    Url: 'http://images.uncyc.org/pt/thumb/5/52/Shyryugyarados.jpg/160px-Shyryugyarados.jpg',
                    IsThumb: false
                }]
            }
        });

    });
};
registrarEventoDoBotao();
<commit_msg>fix(Index.js): corrigir bug de notificações aparecerem em momentos incorretos.<commit_after>'use strict';

var idAux = 0;

function carregarDadosNaPagina() {
    $.ajax({ url: urlCavaleiroGet, type: 'GET' })
    .then(
        function onSuccess(res) {
            console.log(res.data);
            var $cavaleiros = $('#cavaleiros');
            res.data.forEach(function (cava) {
                $cavaleiros.append(
                    $('
').attr('data-id-cavaleiro', cava.Id).append('')
                .append(
            $('<button>')
                .attr('data-cavaleiro-id', cava.Id)
                .click(editarCavaleiroNoServidor)
                .text('Editar')
         ).append(
        $('<button>')
                .attr('data-cavaleiro-id', cava.Id)
                .click(excluirCavaleiroNoServidor)
                .text('Excluir')));
                idAux = cava.Id;
            });
        },
        function onError(res) {
            console.error(':(');
            console.error(res);

            var criarSpanComErro = function (msg) {
                return $('').text(msg).addClass('erro');
            };

            $('#feedback')
            .append(criarSpanComErro(res.status))
            .append($('
'))
            .append(criarSpanComErro(res.statusText));
        }
    )
    .always(function (res) {
        console.log('acabouuuuuuuu');
    });
};

setInterval(function () {
    var contador = 0;
    $.ajax({ url: urlCavaleiroGet, type: 'GET' })
    .then(
    function onSuccess(res) {
        var $cavaleiros = $('#cavaleiros');
        res.data.forEach(function (cava) {
            if (cava.Id > idAux) {
                contador++;
                $cavaleiros.append($('
').attr('data-id-cavaleiro', cava.Id).append('').append(
            $('<button>')
                .attr('data-cavaleiro-id', cava.Id)
                .click(editarCavaleiroNoServidor)
                .text('Editar')
         ).append(
        $('<button>')
                .attr('data-cavaleiro-id', cava.Id)
                .click(excluirCavaleiroNoServidor)
                .text('Excluir')));
                idAux = cava.Id;
            }
        });
        notificar(contador);
        contador = 0;
    }
    );
}, 5000);

function notificar(cavaleirosAdicionados) {
    if (cavaleirosAdicionados !== 0) {
        Notification.requestPermission()
            .then(function (result) {
    if (result === 'granted') {
        var frase = "";
        if (cavaleirosAdicionados === 1) {
            frase = "1 novo cavaleiro foi adicionado."
        } else {
            frase = cavaleirosAdicionados + " novos cavaleiros foram adicionados.";
        }
        var options = { body: frase, icon: 'https://cdn0.iconfinder.com/data/icons/the-middle-ages/500/Knight_knight_helmet-512.png' }
                    new Notification('', options);
       }
     })
    }
};

function excluirCavaleiroNoServidor() {
    var cavaleiroId = parseInt($(this).attr('data-cavaleiro-id'));
    $.ajax({
        url: '/Cavaleiro/Delete',
        type: 'DELETE',
        data: { id: cavaleiroId }
    })
};

carregarDadosNaPagina();

function editarCavaleiroNoServidor() {
    var cavaleiroId = parseInt($(this).attr('data-cavaleiro-id'));
    $.get('/Cavaleiro/GetById', { id: cavaleiroId })
        .done(function (detalhe) {
            cavaleiroHardCoded = detalhe.data;
            cavaleiroHardCoded.Nome = 'Novo nome após update ' + new Date().getTime();
            cavaleiroHardCoded.AlturaCm = 205;
            cavaleiroHardCoded.Signo = 3;
            cavaleiroHardCoded.TipoSanguineo = 2;
            cavaleiroHardCoded.DataNascimento = new Date(2001, 0, 15);
            cavaleiroHardCoded.Golpes[0].Nome = 'Voadora do Sub-Zero Brasileiro'
            cavaleiroHardCoded.Golpes[1].Nome = 'Cólera dos 42 dragões';
            cavaleiroHardCoded.Golpes[2] = { Nome: 'Novo golpe aterrador' };
            cavaleiroHardCoded.LocalNascimento.Texto = 'Porto Alegre';
            cavaleiroHardCoded.LocalTreinamento.Texto = 'Alvorada';
            cavaleiroHardCoded.Imagens[0].Url = 'https://cloud.githubusercontent.com/assets/526075/15443404/5c97dde6-1ebe-11e6-8ae6-83372051dda7.png';
            cavaleiroHardCoded.Imagens[0].IsThumb = true;
            cavaleiroHardCoded.Imagens[1].Url = 'https://cloud.githubusercontent.com/assets/526075/15443410/6e9ba586-1ebe-11e6-8b90-64aca9e18a32.png';
            cavaleiroHardCoded.Imagens[1].IsThumb = false;

            $.ajax({
                url: '/Cavaleiro/Put',
                type: 'PUT',
                data: cavaleiroHardCoded
            });
        });
};

$(function () {

    var $frmNovoCavaleiro = $('#frmNovoCavaleiro');
    $frmNovoCavaleiro.submit(function (e) {
        debugger;
        var cavaleiro = converterFormParaCavaleiro($frmNovoCavaleiro);
        $.ajax({
            url: urlCavaleiroPost,
            type: 'POST',
            data: cavaleiro
        });
        $frmNovoCavaleiro[0].reset();
        return e.preventDefault();
    });

    var $novasImagens = $('#novasImagens');

    $('#btnAdicionarImg').click(function () {
        var $novoLi = gerarElementoLiComInputs();
        $novasImagens.append($novoLi);
    });

    $('#btnAdicionarGolpe').click(function () {
        $('#novosGolpes').append(gerarElementoLiComInputTexto());
    });

});

function converterFormParaCavaleiro($form) {
    var formData = new FormData($form[0]);
    var novasImagens = [];
    $('#novasImagens li').each(function () {
        novasImagens.push({
            url: $(this).find('input[name=urlImagem]').val(),
            isThumb: $(this).find('input[name=isThumb]').is(':checked')
        });
    });
    var novosGolpes = [];
    $('#novosGolpes li').each(function (i) {
        novosGolpes.push($(this).find('input[name=golpe]').val());
    });

    return {
        Nome: formData.get('nome').val(),
        TipoSanguineo: parseInt(formData.get('tipoSanguineo').val()),
        Imagens: novasImagens,
        DataNascimento: (data || new Date()).toISOString(),
        AlturaCm: parseDouble(formData.get('alturaMetros').val()) * 100,
        PesoLb: parseDouble(formData.get('pesoKg').val()) * 2.20462262,
        Signo: parseInt(formData.get('signo').val()),
        LocalNascimento: { Texto: formData.get('localNascimento').val() },
        LocalTreinamento: { Texto: formData.get('localTreinamento').val() },
        Golpes: novosGolpes
    };
};

function gerarElementoLiComInputs() {
    var $novoTxt = $('<input>').attr('name', 'urlImagem').attr('type', 'text').attr('placeholder', 'Ex: bit.ly/shiryu.png');
    var $novoCheckbox =
      $('').append(
        $('<input>')
        .attr('type', 'checkbox')
        .attr('name', 'isThumb')
        .attr('checked', 'checked')
      ).append('É thumbnail?');
    return $('
').append($novoTxt).append($novoCheckbox);
};

function gerarElementoLiComInputTexto() {
    var $novoTxt = $('<input>').attr('name', 'golpe').attr('type', 'text').attr('placeholder', 'Ex: Pó de diamante');
    return $('
').append($novoTxt);
};

function registrarEventoDoBotao() {
    $('#btnCriar').click(function () {

        $.ajax({
            url: urlCavaleiroPost,
            type: 'POST',
            data: {
                Nome: 'Xiru ' + new Date().getTime(),
                AlturaCm: 187,
                Signo: 7,
                TipoSanguineo: 1,
                DataNascimento: new Date(),
                Golpes: ['Cólera do Dragão', 'Cólera dos 100 dragões'],
                LocalNascimento: {
                    Texto: 'Beijing'
                },
                LocalTreinamento: {
                    Texto: '5 picos de rosan'
                },
                Imagens: [{
                    Url: 'http://images.uncyc.org/pt/3/37/Shiryumestrepokemon.jpg',
                    IsThumb: true
                }, {
                    Url: 'http://images.uncyc.org/pt/thumb/5/52/Shyryugyarados.jpg/160px-Shyryugyarados.jpg',
                    IsThumb: false
                }]
            }
        });

    });
};
registrarEventoDoBotao();
<|endoftext|>


<commit_before>sap.ui.define(function () {

	"use strict";
	return {
		name: "TestSuite for app",
		defaults: {
			qunit: {
				version: 2
			},
			beforeBootstrap: "./beforeBootstrap"
		},
		tests: {
			Application: {
				page: "/test-resources/sap/ui/core/qunit/Application.qunit.html",
				title: "Tests for Application.js"
			},
			MessageListBinding: {
				title: "Tests for sap/ui/model/message/MessageListBinding"
			},
			MockServer: {
				title: "Tests for sap/ui/core/util/MockServer",
				ui5: {
					libs: ["sap.ui.commons"]
				},
				loader: {
					paths: {
						"testdata": "test-resources/sap/ui/core/qunit/testdata/"
					}
				}
			},
			MockServerFeature: {
				title: "Tests for sap/ui/core/util/Mockserver: given data and complex filter features"
			},
			MockServerAPF: {
				title: "Tests for sap/ui/core/util/MockServer: APF model"
			},
			DraftEnabledMockServer: {
				title: "Tests for sap/ui/core/util/DraftEnabledMockServer"
			},
			DesignMode: {
				title: "Tests for sap/ui/core/Configuration: DesignMode",
				ui5: {
					noConflict: true,
					"xx-designMode": true,
					resourceroots: {
						"example.designmode": "test-resources/sap/ui/core/qunit/testdata/designmode/"
					}
				}
			},
			DesignModeSupressedDeactivation: {
				title: "Tests for sap/ui/core/Configuration: DesignMode",
				ui5: {
					noConflict: true,
					"xx-designMode": true,
					"xx-suppressDeactivationOfControllerCode": true,
					resourceroots: {
						"example.designmode": "test-resources/sap/ui/core/qunit/testdata/designmode/"
					}
				}
			},
			"ThemeClassParameters(base)": {
				title: "Tests for sap/ui/core/theming/Parameters (base): Theme-Dependent CSS Classes",
				ui5: {
					theme: "base"
				},
				module: "./ThemeClassParameters.qunit"
			},
			"ThemeClassParameters(sap_hcb)": {
				title: "Tests for sap/ui/core/theming/Parameters (sap_hcb): Theme-Dependent CSS Classes",
				ui5: {
					theme: "sap_hcb"
				},
				module: "./ThemeClassParameters.qunit"
			},
			"ThemeClassParameters(sap_bluecrystal)": {
				title: "Tests for sap/ui/core/theming/Parameters (sap_bluecrystal): Theme-Dependent CSS Classes",
				ui5: {
					theme: "sap_bluecrystal"
				},
				module: "./ThemeClassParameters.qunit"
			},
			"ThemeClassParameters(sap_belize)": {
				title: "Tests for sap/ui/core/theming/Parameters (sap_belize): Theme-Dependent CSS Classes",
				ui5: {
					theme: "sap_belize"
				},
				module: "./ThemeClassParameters.qunit"
			}
		}
	};
});
<commit_msg>[INTERNAL] Corrected value for page attribute<commit_after>sap.ui.define(function () {

	"use strict";
	return {
		name: "TestSuite for app",
		defaults: {
			qunit: {
				version: 2
			},
			beforeBootstrap: "./beforeBootstrap"
		},
		tests: {
			Application: {
				page: "test-resources/sap/ui/core/qunit/Application.qunit.html",
				title: "Tests for Application.js"
			},
			MessageListBinding: {
				title: "Tests for sap/ui/model/message/MessageListBinding"
			},
			MockServer: {
				title: "Tests for sap/ui/core/util/MockServer",
				ui5: {
					libs: ["sap.ui.commons"]
				},
				loader: {
					paths: {
						"testdata": "test-resources/sap/ui/core/qunit/testdata/"
					}
				}
			},
			MockServerFeature: {
				title: "Tests for sap/ui/core/util/Mockserver: given data and complex filter features"
			},
			MockServerAPF: {
				title: "Tests for sap/ui/core/util/MockServer: APF model"
			},
			DraftEnabledMockServer: {
				title: "Tests for sap/ui/core/util/DraftEnabledMockServer"
			},
			DesignMode: {
				title: "Tests for sap/ui/core/Configuration: DesignMode",
				ui5: {
					noConflict: true,
					"xx-designMode": true,
					resourceroots: {
						"example.designmode": "test-resources/sap/ui/core/qunit/testdata/designmode/"
					}
				}
			},
			DesignModeSupressedDeactivation: {
				title: "Tests for sap/ui/core/Configuration: DesignMode",
				ui5: {
					noConflict: true,
					"xx-designMode": true,
					"xx-suppressDeactivationOfControllerCode": true,
					resourceroots: {
						"example.designmode": "test-resources/sap/ui/core/qunit/testdata/designmode/"
					}
				}
			},
			"ThemeClassParameters(base)": {
				title: "Tests for sap/ui/core/theming/Parameters (base): Theme-Dependent CSS Classes",
				ui5: {
					theme: "base"
				},
				module: "./ThemeClassParameters.qunit"
			},
			"ThemeClassParameters(sap_hcb)": {
				title: "Tests for sap/ui/core/theming/Parameters (sap_hcb): Theme-Dependent CSS Classes",
				ui5: {
					theme: "sap_hcb"
				},
				module: "./ThemeClassParameters.qunit"
			},
			"ThemeClassParameters(sap_bluecrystal)": {
				title: "Tests for sap/ui/core/theming/Parameters (sap_bluecrystal): Theme-Dependent CSS Classes",
				ui5: {
					theme: "sap_bluecrystal"
				},
				module: "./ThemeClassParameters.qunit"
			},
			"ThemeClassParameters(sap_belize)": {
				title: "Tests for sap/ui/core/theming/Parameters (sap_belize): Theme-Dependent CSS Classes",
				ui5: {
					theme: "sap_belize"
				},
				module: "./ThemeClassParameters.qunit"
			}
		}
	};
});
<|endoftext|>


<commit_before>// @flow

import Icon from '@conveyal/woonerf/components/icon'
import objectPath from 'object-path'
import React, {Component} from 'react'
import {connect} from 'react-redux'
import Select from 'react-select'
import {
  Button,
  ButtonToolbar,
  Checkbox,
  Col,
  ControlLabel,
  FormGroup,
  Glyphicon,
  Panel,
  Row
} from 'react-bootstrap'
import update from 'react-addons-update'

import { getComponentMessages, getConfigProperty } from '../../common/util/config'
import EC2InstanceCard from '../../common/components/EC2InstanceCard'
import FormInput from '../../common/components/FormInput'
import * as adminActions from '../actions/admin'
import * as deploymentActions from '../../manager/actions/deployments'
import CollapsiblePanel from '../../manager/components/CollapsiblePanel'
import {
  getActiveInstanceCount,
  EC2_INFO_FIELDS,
  SERVER_FIELDS
} from '../../manager/util/deployment'

import type { OtpServer, Project, ReactSelectOption } from '../../types'
import type { AppState, AdminServersState } from '../../types/reducers'

type ContainerProps = {editDisabled: boolean}
type Props = ContainerProps & {
  deleteServer: typeof adminActions.deleteServer,
  fetchServers: typeof adminActions.fetchServers,
  otpServers: AdminServersState,
  projects: Array<Project>,
  terminateEC2InstanceForDeployment: typeof deploymentActions.terminateEC2InstanceForDeployment,
  terminateEC2Instances: typeof adminActions.terminateEC2Instances,
  updateServer: typeof adminActions.updateServer
}

type State = {
  hasEdits: boolean,
  otpServers: Array<OtpServer>
}

class ServerSettings extends Component<Props, State> {
  messages = getComponentMessages('ServerSettings')

  state = {
    hasEdits: false,
    otpServers: []
  }

  componentWillMount () {
    this._updateStateFromProps(this.props)
  }

  componentWillReceiveProps (nextProps: Props) {
    this._updateStateFromProps(nextProps)
  }

  _updateStateFromProps = props => {
    if (props.otpServers && props.otpServers.data) {
      this.setState({ otpServers: props.otpServers.data, hasEdits: false })
    }
  }

  _applyEdit = (stateUpdate) => {
    const state = update(this.state, stateUpdate)
    state.hasEdits = true
    this.setState(state)
  }

  _onToggleEc2Info = (evt, index) => {
    const stateUpdate = {}
    objectPath.set(
      stateUpdate,
      `otpServers.${index}.ec2Info.$set`,
      evt.target.checked ? {} : null
    )
    this._applyEdit(stateUpdate)
  }

  _getOnChange = (evt, index) => {
    let item = SERVER_FIELDS.find(f => f.name === evt.target.name)
    if (!item) item = EC2_INFO_FIELDS.find(f => f.name === evt.target.name)
    if (item) {
      const stateUpdate = {}
      item.effects && item.effects.forEach(e => {
        objectPath.set(stateUpdate, `${e.key}.$set`, e.value)
      })
      switch (item.type) {
        case 'checkbox':
          return this._onChangeCheckbox(evt, stateUpdate, index)
        case 'select-bool':
          return this._onSelectBool(evt, stateUpdate, index)
        case 'number':
          return this._onChangeNumber(evt, stateUpdate, index)
        default:
          // check for split property, which indicates that comma-separated list should be split into array
          if (item.split) {
            return this._onChangeSplit(evt, stateUpdate, index)
          } else {
            return this._onChange(evt, stateUpdate, index)
          }
      }
    } else {
      console.warn('no onChange function available')
    }
  }

  _onChangeCheckbox = (evt, stateUpdate = {}, index) => {
    const name = this._getFieldName(evt, index)
    objectPath.set(stateUpdate, `${name}.$set`, evt.target.checked)
    this._applyEdit(stateUpdate)
  }

  _onChangeSplit = (evt, stateUpdate = {}, index) => {
    const name = this._getFieldName(evt, index)
    const splitValues = evt.target.value.split(',').filter(item => item)
    objectPath.set(stateUpdate, `${name}.$set`, splitValues)
    this._applyEdit(stateUpdate)
  }

  _onAddServer = () => {
    const newServer = {
      name: '',
      publicUrl: '',
      internalUrl: [],
      admin: false
    }
    const stateUpdate = { otpServers: { $push: [newServer] } }
    this.setState(update(this.state, stateUpdate))
  }

  _onRefresh = () => this.props.fetchServers()

  _onDeleteServer = (index: number) => {
    if (window.confirm('Are you sure you want to delete this server record?')) {
      const server = this.state.otpServers[index]
      if (!server.id) this.setState(update(this.state, {otpServers: {$splice: [[index, 1]]}}))
      else this.props.deleteServer(this.state.otpServers[index])
    }
  }

  _onSaveServer = (index: number) => this.props.updateServer(this.state.otpServers[index])

  _onChange = (evt, stateUpdate = {}, index) => {
    const name = this._getFieldName(evt, index)
    // If value is empty string or undefined, set to null in settings object.
    // Otherwise, certain fields (such as 'fares') would cause issues with OTP.
    objectPath.set(stateUpdate, `${name}.$set`, evt.target.value || null)
    this._applyEdit(stateUpdate)
  }

  _onChangeNumber = (evt, stateUpdate = {}, index) => {
    const name = this._getFieldName(evt, index)
    objectPath.set(stateUpdate, `${name}.$set`, +evt.target.value)
    this._applyEdit(stateUpdate)
  }

  _onChangeProject = (option, index) => {
    const stateUpdate = {}
    const value = option ? option.value : null
    objectPath.set(stateUpdate, `otpServers.${index}.projectId.$set`, value)
    this._applyEdit(stateUpdate)
  }

  _onSelectBool = (evt, stateUpdate = {}, index) => {
    const name = this._getFieldName(evt, index)
    objectPath.set(stateUpdate, `${name}.$set`, (evt.target.value === 'true'))
    this._applyEdit(stateUpdate)
  }

  _getFieldName = (evt, index) => index !== null
    ? evt.target.name.replace('$index', `${index}`)
    : evt.target.name

  render () {
    const { projects, terminateEC2Instances } = this.props
    const { otpServers } = this.state
    const serverDocRoot = getConfigProperty('application.docs_url')
    const serverDocUrl = serverDocRoot
      ? (serverDocRoot + '/user/setting-up-aws-servers') : null

    return (

        {/* OTP server settings */}
        <Panel
          header={
            <Row>
              <Col xs={12}>
                <ButtonToolbar className='pull-right'>
                  <Button
                    onClick={this._onRefresh}>
                    <Glyphicon glyph='refresh' /> {this.messages('deployment.otpServers.refresh')}
                  </Button>
                  <Button
                    bsStyle='primary'
                    data-test-id='add-server-button'
                    onClick={this._onAddServer}>
                    <Glyphicon glyph='plus' /> {this.messages('deployment.otpServers.new')}
                  </Button>
                </ButtonToolbar>

                  <Icon type='server' /> {this.messages('deployment.otpServers.title')}

              </Col>
            </Row>
          }>

            {otpServers && otpServers.length
              ? otpServers.map((server, index) => (
                <CollapsiblePanel
                  key={`server-${index}`}
                  index={index}
                  fields={SERVER_FIELDS}
                  defaultExpanded={!server.name}
                  testId={server.name
                    ? server.name
                    : `[${this.messages('deployment.otpServers.serverPlaceholder')}]`}
                  title={server.name
                    ?
                      {server.name}{'  '}
                      {server.publicUrl}

                    : `[${this.messages('deployment.otpServers.serverPlaceholder')}]`
                  }
                  data={server}
                  saveDisabled={!this.state.hasEdits}
                  onRemove={this._onDeleteServer}
                  onSave={this._onSaveServer}
                  onChange={this._getOnChange}>
                  <ServerSpecialFields
                    index={index}
                    getOnChange={this._getOnChange}
                    server={server}
                    terminateEC2InstanceForDeployment={this.props.terminateEC2InstanceForDeployment}
                    terminateEC2Instances={terminateEC2Instances}
                    onChangeProject={this._onChangeProject}
                    onToggleEc2Info={this._onToggleEc2Info}
                    projects={projects} />
                </CollapsiblePanel>
              ))
              :
No servers defined

            }

        </Panel>
        <Panel>

Instructions

                Instructions for setting up OTP deployment servers on AWS

        </Panel>

    )
  }
}

type ServerSpecialFieldsProps = {
  getOnChange: any,
  index: number,
  onChangeProject: (ReactSelectOption, number) => void,
  onToggleEc2Info: any,
  projects: Array<Project>,
  server: OtpServer,
  terminateEC2InstanceForDeployment: typeof deploymentActions.terminateEC2InstanceForDeployment,
  terminateEC2Instances: typeof adminActions.terminateEC2Instances
}

class ServerSpecialFields extends Component<ServerSpecialFieldsProps> {
  _onChange = evt => this.props.getOnChange(evt, this.props.index)

  _onChangeProject = (val: ReactSelectOption) =>
    this.props.onChangeProject(val, this.props.index)

  _onToggleEc2Info = (evt) => this.props.onToggleEc2Info(evt, this.props.index)

  _terminateEC2Instances = () => {
    const {server, terminateEC2Instances} = this.props
    const count = getActiveInstanceCount(server.ec2Instances)
    if (window.confirm(`Are you sure you want to terminate ${count} instance(s)?\n\n WARNING: This will kill OTP service for any deployments launched for this server.`)) {
      terminateEC2Instances(server)
    }
  }

  render () {
    const {projects, server} = this.props
    return (

        <Col xs={12}>
          <FormGroup>
            <ControlLabel>Project specific?</ControlLabel>
            <Select
              style={{marginBottom: '20px'}}
              clearable
              placeholder='Assign to a project or leave open for any project'
              options={projects.map(p => ({value: p.id, label: p.name}))}
              value={server.projectId}
              onChange={this._onChangeProject} />
          </FormGroup>
        </Col>
        <Col>
          <Col xs={6}>
            <FormGroup>
              <Checkbox
                checked={!!server.ec2Info}
                onChange={this._onToggleEc2Info}>
                Use Elastic Load Balancer (ELB)?
              </Checkbox>
            </FormGroup>
            {server.ec2Info
              ?

                {EC2_INFO_FIELDS.map((f, i) => {
                  // Make flow happy by putting the ec2 info into a
                  // local variable.
                  const {ec2Info} = server
                  if (!ec2Info) return null
                  return <FormInput
                    key={i}
                    field={f}
                    value={ec2Info[f.name.split('.').slice(-1)[0]]}
                    onChange={this._onChange} />
                })}

              : null
            }
          </Col>
          {server.ec2Info
            ? <Col xs={6}>
              <Button
                block
                style={{marginBottom: '20px'}}
                bsStyle='warning'
                disabled={getActiveInstanceCount(server.ec2Instances) === 0}
                onClick={this._terminateEC2Instances}>
                <Icon type='window-close' /> Terminate EC2 Instances
              </Button>

                {server.ec2Instances && server.ec2Instances.length > 0
                  ? server.ec2Instances.map(instance => (
                    <EC2InstanceCard
                      key={instance.instanceId}
                      showDeploymentLink
                      terminateEC2InstanceForDeployment={this.props.terminateEC2InstanceForDeployment}
                      instance={instance} />
                  ))
                  : 'No EC2 instances associated with server.'
                }

            </Col>
            : null
          }
        </Col>

    )
  }
}

const mapStateToProps = (state: AppState, ownProps: ContainerProps) => {
  return {
    otpServers: state.admin.servers,
    projects: state.projects.all
  }
}

const {
  deleteServer,
  fetchServers,
  terminateEC2Instances,
  updateServer
} = adminActions

const { terminateEC2InstanceForDeployment } = deploymentActions

const mapDispatchToProps = {
  deleteServer,
  fetchServers,
  terminateEC2InstanceForDeployment,
  terminateEC2Instances,
  updateServer
}

export default connect(mapStateToProps, mapDispatchToProps)(ServerSettings)
<commit_msg>refactor(admin): simplify a ternary into a logical or operation<commit_after>// @flow

import Icon from '@conveyal/woonerf/components/icon'
import objectPath from 'object-path'
import React, {Component} from 'react'
import {connect} from 'react-redux'
import Select from 'react-select'
import {
  Button,
  ButtonToolbar,
  Checkbox,
  Col,
  ControlLabel,
  FormGroup,
  Glyphicon,
  Panel,
  Row
} from 'react-bootstrap'
import update from 'react-addons-update'

import { getComponentMessages, getConfigProperty } from '../../common/util/config'
import EC2InstanceCard from '../../common/components/EC2InstanceCard'
import FormInput from '../../common/components/FormInput'
import * as adminActions from '../actions/admin'
import * as deploymentActions from '../../manager/actions/deployments'
import CollapsiblePanel from '../../manager/components/CollapsiblePanel'
import {
  getActiveInstanceCount,
  EC2_INFO_FIELDS,
  SERVER_FIELDS
} from '../../manager/util/deployment'

import type { OtpServer, Project, ReactSelectOption } from '../../types'
import type { AppState, AdminServersState } from '../../types/reducers'

type ContainerProps = {editDisabled: boolean}
type Props = ContainerProps & {
  deleteServer: typeof adminActions.deleteServer,
  fetchServers: typeof adminActions.fetchServers,
  otpServers: AdminServersState,
  projects: Array<Project>,
  terminateEC2InstanceForDeployment: typeof deploymentActions.terminateEC2InstanceForDeployment,
  terminateEC2Instances: typeof adminActions.terminateEC2Instances,
  updateServer: typeof adminActions.updateServer
}

type State = {
  hasEdits: boolean,
  otpServers: Array<OtpServer>
}

class ServerSettings extends Component<Props, State> {
  messages = getComponentMessages('ServerSettings')

  state = {
    hasEdits: false,
    otpServers: []
  }

  componentWillMount () {
    this._updateStateFromProps(this.props)
  }

  componentWillReceiveProps (nextProps: Props) {
    this._updateStateFromProps(nextProps)
  }

  _updateStateFromProps = props => {
    if (props.otpServers && props.otpServers.data) {
      this.setState({ otpServers: props.otpServers.data, hasEdits: false })
    }
  }

  _applyEdit = (stateUpdate) => {
    const state = update(this.state, stateUpdate)
    state.hasEdits = true
    this.setState(state)
  }

  _onToggleEc2Info = (evt, index) => {
    const stateUpdate = {}
    objectPath.set(
      stateUpdate,
      `otpServers.${index}.ec2Info.$set`,
      evt.target.checked ? {} : null
    )
    this._applyEdit(stateUpdate)
  }

  _getOnChange = (evt, index) => {
    let item = SERVER_FIELDS.find(f => f.name === evt.target.name)
    if (!item) item = EC2_INFO_FIELDS.find(f => f.name === evt.target.name)
    if (item) {
      const stateUpdate = {}
      item.effects && item.effects.forEach(e => {
        objectPath.set(stateUpdate, `${e.key}.$set`, e.value)
      })
      switch (item.type) {
        case 'checkbox':
          return this._onChangeCheckbox(evt, stateUpdate, index)
        case 'select-bool':
          return this._onSelectBool(evt, stateUpdate, index)
        case 'number':
          return this._onChangeNumber(evt, stateUpdate, index)
        default:
          // check for split property, which indicates that comma-separated list should be split into array
          if (item.split) {
            return this._onChangeSplit(evt, stateUpdate, index)
          } else {
            return this._onChange(evt, stateUpdate, index)
          }
      }
    } else {
      console.warn('no onChange function available')
    }
  }

  _onChangeCheckbox = (evt, stateUpdate = {}, index) => {
    const name = this._getFieldName(evt, index)
    objectPath.set(stateUpdate, `${name}.$set`, evt.target.checked)
    this._applyEdit(stateUpdate)
  }

  _onChangeSplit = (evt, stateUpdate = {}, index) => {
    const name = this._getFieldName(evt, index)
    const splitValues = evt.target.value.split(',').filter(item => item)
    objectPath.set(stateUpdate, `${name}.$set`, splitValues)
    this._applyEdit(stateUpdate)
  }

  _onAddServer = () => {
    const newServer = {
      name: '',
      publicUrl: '',
      internalUrl: [],
      admin: false
    }
    const stateUpdate = { otpServers: { $push: [newServer] } }
    this.setState(update(this.state, stateUpdate))
  }

  _onRefresh = () => this.props.fetchServers()

  _onDeleteServer = (index: number) => {
    if (window.confirm('Are you sure you want to delete this server record?')) {
      const server = this.state.otpServers[index]
      if (!server.id) this.setState(update(this.state, {otpServers: {$splice: [[index, 1]]}}))
      else this.props.deleteServer(this.state.otpServers[index])
    }
  }

  _onSaveServer = (index: number) => this.props.updateServer(this.state.otpServers[index])

  _onChange = (evt, stateUpdate = {}, index) => {
    const name = this._getFieldName(evt, index)
    // If value is empty string or undefined, set to null in settings object.
    // Otherwise, certain fields (such as 'fares') would cause issues with OTP.
    objectPath.set(stateUpdate, `${name}.$set`, evt.target.value || null)
    this._applyEdit(stateUpdate)
  }

  _onChangeNumber = (evt, stateUpdate = {}, index) => {
    const name = this._getFieldName(evt, index)
    objectPath.set(stateUpdate, `${name}.$set`, +evt.target.value)
    this._applyEdit(stateUpdate)
  }

  _onChangeProject = (option, index) => {
    const stateUpdate = {}
    const value = option ? option.value : null
    objectPath.set(stateUpdate, `otpServers.${index}.projectId.$set`, value)
    this._applyEdit(stateUpdate)
  }

  _onSelectBool = (evt, stateUpdate = {}, index) => {
    const name = this._getFieldName(evt, index)
    objectPath.set(stateUpdate, `${name}.$set`, (evt.target.value === 'true'))
    this._applyEdit(stateUpdate)
  }

  _getFieldName = (evt, index) => index !== null
    ? evt.target.name.replace('$index', `${index}`)
    : evt.target.name

  render () {
    const { projects, terminateEC2Instances } = this.props
    const { otpServers } = this.state
    const serverDocRoot = getConfigProperty('application.docs_url')
    const serverDocUrl = serverDocRoot
      ? (serverDocRoot + '/user/setting-up-aws-servers') : null

    return (

        {/* OTP server settings */}
        <Panel
          header={
            <Row>
              <Col xs={12}>
                <ButtonToolbar className='pull-right'>
                  <Button
                    onClick={this._onRefresh}>
                    <Glyphicon glyph='refresh' /> {this.messages('deployment.otpServers.refresh')}
                  </Button>
                  <Button
                    bsStyle='primary'
                    data-test-id='add-server-button'
                    onClick={this._onAddServer}>
                    <Glyphicon glyph='plus' /> {this.messages('deployment.otpServers.new')}
                  </Button>
                </ButtonToolbar>

                  <Icon type='server' /> {this.messages('deployment.otpServers.title')}

              </Col>
            </Row>
          }>

            {otpServers && otpServers.length
              ? otpServers.map((server, index) => (
                <CollapsiblePanel
                  key={`server-${index}`}
                  index={index}
                  fields={SERVER_FIELDS}
                  defaultExpanded={!server.name}
                  testId={server.name ||
                    `[${this.messages('deployment.otpServers.serverPlaceholder')}]`}
                  title={server.name
                    ?
                      {server.name}{'  '}
                      {server.publicUrl}

                    : `[${this.messages('deployment.otpServers.serverPlaceholder')}]`
                  }
                  data={server}
                  saveDisabled={!this.state.hasEdits}
                  onRemove={this._onDeleteServer}
                  onSave={this._onSaveServer}
                  onChange={this._getOnChange}>
                  <ServerSpecialFields
                    index={index}
                    getOnChange={this._getOnChange}
                    server={server}
                    terminateEC2InstanceForDeployment={this.props.terminateEC2InstanceForDeployment}
                    terminateEC2Instances={terminateEC2Instances}
                    onChangeProject={this._onChangeProject}
                    onToggleEc2Info={this._onToggleEc2Info}
                    projects={projects} />
                </CollapsiblePanel>
              ))
              :
No servers defined

            }

        </Panel>
        <Panel>

Instructions

                Instructions for setting up OTP deployment servers on AWS

        </Panel>

    )
  }
}

type ServerSpecialFieldsProps = {
  getOnChange: any,
  index: number,
  onChangeProject: (ReactSelectOption, number) => void,
  onToggleEc2Info: any,
  projects: Array<Project>,
  server: OtpServer,
  terminateEC2InstanceForDeployment: typeof deploymentActions.terminateEC2InstanceForDeployment,
  terminateEC2Instances: typeof adminActions.terminateEC2Instances
}

class ServerSpecialFields extends Component<ServerSpecialFieldsProps> {
  _onChange = evt => this.props.getOnChange(evt, this.props.index)

  _onChangeProject = (val: ReactSelectOption) =>
    this.props.onChangeProject(val, this.props.index)

  _onToggleEc2Info = (evt) => this.props.onToggleEc2Info(evt, this.props.index)

  _terminateEC2Instances = () => {
    const {server, terminateEC2Instances} = this.props
    const count = getActiveInstanceCount(server.ec2Instances)
    if (window.confirm(`Are you sure you want to terminate ${count} instance(s)?\n\n WARNING: This will kill OTP service for any deployments launched for this server.`)) {
      terminateEC2Instances(server)
    }
  }

  render () {
    const {projects, server} = this.props
    return (

        <Col xs={12}>
          <FormGroup>
            <ControlLabel>Project specific?</ControlLabel>
            <Select
              style={{marginBottom: '20px'}}
              clearable
              placeholder='Assign to a project or leave open for any project'
              options={projects.map(p => ({value: p.id, label: p.name}))}
              value={server.projectId}
              onChange={this._onChangeProject} />
          </FormGroup>
        </Col>
        <Col>
          <Col xs={6}>
            <FormGroup>
              <Checkbox
                checked={!!server.ec2Info}
                onChange={this._onToggleEc2Info}>
                Use Elastic Load Balancer (ELB)?
              </Checkbox>
            </FormGroup>
            {server.ec2Info
              ?

                {EC2_INFO_FIELDS.map((f, i) => {
                  // Make flow happy by putting the ec2 info into a
                  // local variable.
                  const {ec2Info} = server
                  if (!ec2Info) return null
                  return <FormInput
                    key={i}
                    field={f}
                    value={ec2Info[f.name.split('.').slice(-1)[0]]}
                    onChange={this._onChange} />
                })}

              : null
            }
          </Col>
          {server.ec2Info
            ? <Col xs={6}>
              <Button
                block
                style={{marginBottom: '20px'}}
                bsStyle='warning'
                disabled={getActiveInstanceCount(server.ec2Instances) === 0}
                onClick={this._terminateEC2Instances}>
                <Icon type='window-close' /> Terminate EC2 Instances
              </Button>

                {server.ec2Instances && server.ec2Instances.length > 0
                  ? server.ec2Instances.map(instance => (
                    <EC2InstanceCard
                      key={instance.instanceId}
                      showDeploymentLink
                      terminateEC2InstanceForDeployment={this.props.terminateEC2InstanceForDeployment}
                      instance={instance} />
                  ))
                  : 'No EC2 instances associated with server.'
                }

            </Col>
            : null
          }
        </Col>

    )
  }
}

const mapStateToProps = (state: AppState, ownProps: ContainerProps) => {
  return {
    otpServers: state.admin.servers,
    projects: state.projects.all
  }
}

const {
  deleteServer,
  fetchServers,
  terminateEC2Instances,
  updateServer
} = adminActions

const { terminateEC2InstanceForDeployment } = deploymentActions

const mapDispatchToProps = {
  deleteServer,
  fetchServers,
  terminateEC2InstanceForDeployment,
  terminateEC2Instances,
  updateServer
}

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


<commit_before>import React from 'react';
import RaisedButton from 'material-ui/RaisedButton';
import Checkbox from 'material-ui/Checkbox';
import FlatButton from 'material-ui/FlatButton';

import Git from 'nodegit';

class gitFunctions {

	static createCommit(repoPath, oid) {
		let index;
		let repo;

		// repoName = "../"+repoName;

		let pathToRepo = require('path').resolve(repoPath);

		return Git.Repository.open(pathToRepo)
			.then(function(repoResult) {
				repo = repoResult;
			  return Git.Reference.nameToId(repo, "HEAD");
			})
			.then(function(head) {
			  return repo.getCommit(head);
			})
			.then(function(parent) {
				const currTimeInSecs = (new Date()).getTime()/1000;
			  let author = Git.Signature.create("Author name",
			    "emailid@domain.com", currTimeInSecs , 0);
			  let committer = Git.Signature.create("Author name",
			    "emailid@domain.com", currTimeInSecs , 0);

			  return repo.createCommit("HEAD", author, committer, "message", oid, [parent]);
			});
	}

	static getStatus(repoPath) {

		let pathToRepo = require('path').resolve(repoPath);

		return Git.Repository.open(pathToRepo);
	}

	static getIndex(repoPath) {

		let repo;
		let pathToRepo = require('path').resolve(repoPath);

		return Git.Repository.open(pathToRepo)
		.then( (repoResult) => {
			repo = repoResult;
		})
		.then(function() {
		  return repo.refreshIndex();
		});

	}
}

class CheckBoxWrapper extends React.Component {
		constructor(props) {
		super(props);
		this.state={
			checked: this.props.checked
		};
	}

	onEventCheck = (event, isInputChecked) => {
		event.stopPropagation();

		this.changeCheckedState(isInputChecked);
	}

	changeCheckedState = (isInputChecked) => {

		window.setTimeout( () => {
			this.setState({
				checked: isInputChecked? true : false
			});
		}, 0);

		// this.props.onChangeSelected(this.props.uniqueId, isInputChecked );
	}

	componentWillReceiveProps = (newprops) => {
	}

	render = () => {
		const styles={
		  checkbox: {
		    marginBottom: 3
		  }
  	};

		return(

				<Checkbox style={styles.checkbox} label={this.props.label}
				value={this.props.value} onCheck={this.onEventCheck} checked={this.state.checked} />

		)
	}
}

class ChangesList extends React.Component {
	constructor(props) {
		super(props);
		//contains refs to all the CheckBoxWrapper components
		this.checkboxRefs= [];
	}

	toggleWrapperState = () => {
		this.checkboxRefs.forEach( (ref, index) => {
			if(ref !== null)
				ref.changeCheckedState(this.props.selectAll);
		})
	}

	render = () => {
		let renderStatus;
		if(this.props.statuses.length === 0) {
			renderStatus =
No Changes!

		}
		else {
			renderStatus = this.props.statuses.map((status, index) => {
								      return <CheckBoxWrapper key={index} uniqueId={index} label={status.label}
								      ref={(ref) => this.checkboxRefs[index] = ref}
								      onChangeSelected={this.props.onChangeSelected} checked={this.props.selectAll} value={status.value} />;
				});
		}
		return(

				{renderStatus}

		)
	}
}

class StatusTable extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			statuses: [],
			selectAll: true
		};
	}

	getStatus = (repo) => {
		let promise = gitFunctions.getStatus(repo);
		promise.then(function(repo) {
	    repo.getStatus().then(function(status) {
	    	return status;
	    })
	    .done(function(statuses) {
				this.setState({
					statuses:statuses
				});
	    }.bind(this));
	  }.bind(this));
	}

	checkSelectAll = (event, isInputChecked) => {

		event.stopPropagation();

		window.setTimeout( () => {
			this.setState({
				selectAll: isInputChecked? true : false
			});

			//reaches into the changesList component, which
			//in turn reaches into individual CheckBoxWrapper components
			//and sets state accordingly
			this.changesList.toggleWrapperState(this.state.selectAll);
		}, 0);

	}

	componentWillReceiveProps = (newprops) => {
		// console.log('receive props',this.state.selectAll);
			this.getStatus(newprops.repo.path);
	}

	render = () => {
		let localStatus = [];
		if(this.state.statuses.length === 0)
		{
			localStatus = [];
		}
		else {

	    const statusToText=function(status) {
	      let words=[];
	      let flag = 0;
	      let int = 1;

	      if (status.isNew()) { words.push(NEW); flag = 1;}
	      if (status.isModified()) { words.push(MODIFIED); flag = 1;}
	      if (status.isTypechange()) { words.push(TYPECHANGED); flag = 1;}
	      if (status.isRenamed()) { words.push(RENAMED); flag = 1;}
	      if (status.isIgnored()) { words.push(IGNORED); flag = 1; }
	      if(flag == 0) { words.push(DELETED); }

	      return words;
   	 	};

	    localStatus = this.state.statuses.map((file, index) => {

	    	let change=statusToText(file);
	    	let changes =[];
	    	changes.push({file.path()});
	    	changes.push(change);

	    	return ({
	    		label:changes,
	    		value: file.path()
	    	});

	    });
		}

		const styles = {
			root:{
				border: '1px solid black'
			},
			ul:{
				listStyleType: 'none'
			}
		};
		return(

STATUS

				<Checkbox label='Select All:' ref={(ref) => this.selectAll = ref}  style={{width: 200}}
				onCheck={this.checkSelectAll} checked={this.state.selectAll} labelPosition='left' />
				<ChangesList ref={(ref) => this.changesList = ref} selectAll={this.state.selectAll}
				statuses={localStatus} />

		)
	}
}

class IndexTable extends React.Component {
	constructor(props) {
		super(props);
	}

	render = () => {
		return (

				{this.props.indexEntries.map( (entry, index) => {
					return
{entry}

;
				})}

		);
	}
}

class StagingArea extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			indexPaths: []
		};
	}

	addToIndex = () => {

		let checkedChanges = [];
		//reaches into each checkboxWrapper to obtain checked value
		checkedChanges = this.statusTable.changesList.checkboxRefs.map( (ref, index) => {
			if(ref !== null)
				return ref.state.checked;
		});

		let indexPaths =[];

		this.statusTable.changesList.props.statuses.forEach( (status, index) => {

			//if corresponding checkbox has been checked only
			if(checkedChanges[index])
				indexPaths.push(status);
		});

		// console.log('index',indexPaths);

		window.setTimeout( () => {

			this.setState({
				indexPaths: indexPaths
			});
			// console.log(this.state.indexPaths);
		}, 0);
	}

	createCommit = () => {

		let index;
		let oid;

		let promise = gitFunctions.getIndex(this.props.repo.path);
		promise = promise.then((indexResult) => {
			index = indexResult;
		});

		let filePaths = this.state.indexPaths.map( (status) => {
			return status.value;
		});

		// console.log(filePaths);

		//takes in initial promise, uses it to chain a new promise to it, and returns the promise,
		//which is used in the next iteration
		promise = filePaths.reduce( (prevPromise, path, currentIndex) => {
								return prevPromise.then( () => {
									return index.addByPath(path);
								});
							}, promise);

		promise.then(() => {
		  return index.write();
		})
    .then(() => {
    	console.log(index.entries());
    })
    .then(() => {
    	return index.writeTree();
    })
		.then( (oidResult) => {
			oid = oidResult;
			console.log('index tree written!');
		})
		//until here, all entries were added to the index and an index tree was written
		//from here, the new commit is generated using the index tree
		.then( () => {
			let innerPromise = gitFunctions.createCommit(this.props.repo.path, oid);
			innerPromise.done(function(commitId) {
				console.log('Commit Hash:'+commitId);
			});

		});
	}

	componentWillReceiveProps = (newprops) => {
		// console.log(newprops);
	}

	render = () => {
		const styles = {
		  block: {
		    maxWidth: 250,
		  },
		  checkbox: {
		    marginBottom: 16,
		  },
		  main: {
		  	height:350,
		  	overflow: 'scroll',
		  	// backgroundColor: 'black'
		  }
		};
		return (

				<RaisedButton label='Create Commit!' onMouseDown={this.createCommit} />
				<RaisedButton label='Add to Index!' onMouseDown={this.addToIndex} />
				<StatusTable {...this.props} ref={(ref) => this.statusTable = ref} />
				<IndexTable indexEntries={this.state.indexPaths.map( (status) => {return status.label})} />

		)
	}
}

export default StagingArea;
<commit_msg>Misc: converted tabs to spaces in src/StagingAreaPanel<commit_after>import React from 'react';
import RaisedButton from 'material-ui/RaisedButton';
import Checkbox from 'material-ui/Checkbox';
import FlatButton from 'material-ui/FlatButton';

import Git from 'nodegit';

class gitFunctions {

  static createCommit(repoPath, oid) {
    let index;
    let repo;

    // repoName = "../"+repoName;

    let pathToRepo = require('path').resolve(repoPath);

    return Git.Repository.open(pathToRepo)
      .then(function(repoResult) {
        repo = repoResult;
        return Git.Reference.nameToId(repo, "HEAD");
      })
      .then(function(head) {
        return repo.getCommit(head);
      })
      .then(function(parent) {
        const currTimeInSecs = (new Date()).getTime()/1000;
        let author = Git.Signature.create("Author name",
          "emailid@domain.com", currTimeInSecs , 0);
        let committer = Git.Signature.create("Author name",
          "emailid@domain.com", currTimeInSecs , 0);

        return repo.createCommit("HEAD", author, committer, "message", oid, [parent]);
      });
  }

  static getStatus(repoPath) {

    let pathToRepo = require('path').resolve(repoPath);

    return Git.Repository.open(pathToRepo);
  }

  static getIndex(repoPath) {

    let repo;
    let pathToRepo = require('path').resolve(repoPath);

    return Git.Repository.open(pathToRepo)
    .then( (repoResult) => {
      repo = repoResult;
    })
    .then(function() {
      return repo.refreshIndex();
    });

  }
}

class CheckBoxWrapper extends React.Component {
    constructor(props) {
    super(props);
    this.state={
      checked: this.props.checked
    };
  }

  onEventCheck = (event, isInputChecked) => {
    event.stopPropagation();

    this.changeCheckedState(isInputChecked);
  }

  changeCheckedState = (isInputChecked) => {

    window.setTimeout( () => {
      this.setState({
        checked: isInputChecked? true : false
      });
    }, 0);

    // this.props.onChangeSelected(this.props.uniqueId, isInputChecked );
  }

  componentWillReceiveProps = (newprops) => {
  }

  render = () => {
    const styles={
      checkbox: {
        marginBottom: 3
      }
    };

    return(

        <Checkbox style={styles.checkbox} label={this.props.label}
        value={this.props.value} onCheck={this.onEventCheck} checked={this.state.checked} />

    )
  }
}

class ChangesList extends React.Component {
  constructor(props) {
    super(props);
    //contains refs to all the CheckBoxWrapper components
    this.checkboxRefs= [];
  }

  toggleWrapperState = () => {
    this.checkboxRefs.forEach( (ref, index) => {
      if(ref !== null)
        ref.changeCheckedState(this.props.selectAll);
    })
  }

  render = () => {
    let renderStatus;
    if(this.props.statuses.length === 0) {
      renderStatus =
No Changes!

    }
    else {
      renderStatus = this.props.statuses.map((status, index) => {
                      return <CheckBoxWrapper key={index} uniqueId={index} label={status.label}
                      ref={(ref) => this.checkboxRefs[index] = ref}
                      onChangeSelected={this.props.onChangeSelected} checked={this.props.selectAll} value={status.value} />;
        });
    }
    return(

        {renderStatus}

    )
  }
}

class StatusTable extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      statuses: [],
      selectAll: true
    };
  }

  getStatus = (repo) => {
    let promise = gitFunctions.getStatus(repo);
    promise.then(function(repo) {
      repo.getStatus().then(function(status) {
        return status;
      })
      .done(function(statuses) {
        this.setState({
          statuses:statuses
        });
      }.bind(this));
    }.bind(this));
  }

  checkSelectAll = (event, isInputChecked) => {

    event.stopPropagation();

    window.setTimeout( () => {
      this.setState({
        selectAll: isInputChecked? true : false
      });

      //reaches into the changesList component, which
      //in turn reaches into individual CheckBoxWrapper components
      //and sets state accordingly
      this.changesList.toggleWrapperState(this.state.selectAll);
    }, 0);

  }

  componentWillReceiveProps = (newprops) => {
    // console.log('receive props',this.state.selectAll);
      this.getStatus(newprops.repo.path);
  }

  render = () => {
    let localStatus = [];
    if(this.state.statuses.length === 0)
    {
      localStatus = [];
    }
    else {

      const statusToText=function(status) {
        let words=[];
        let flag = 0;
        let int = 1;

        if (status.isNew()) { words.push(NEW); flag = 1;}
        if (status.isModified()) { words.push(MODIFIED); flag = 1;}
        if (status.isTypechange()) { words.push(TYPECHANGED); flag = 1;}
        if (status.isRenamed()) { words.push(RENAMED); flag = 1;}
        if (status.isIgnored()) { words.push(IGNORED); flag = 1; }
        if(flag == 0) { words.push(DELETED); }

        return words;
      };

      localStatus = this.state.statuses.map((file, index) => {

        let change=statusToText(file);
        let changes =[];
        changes.push({file.path()});
        changes.push(change);

        return ({
          label:changes,
          value: file.path()
        });

      });
    }

    const styles = {
      root:{
        border: '1px solid black'
      },
      ul:{
        listStyleType: 'none'
      }
    };
    return(

STATUS

        <Checkbox label='Select All:' ref={(ref) => this.selectAll = ref}  style={{width: 200}}
        onCheck={this.checkSelectAll} checked={this.state.selectAll} labelPosition='left' />
        <ChangesList ref={(ref) => this.changesList = ref} selectAll={this.state.selectAll}
        statuses={localStatus} />

    )
  }
}

class IndexTable extends React.Component {
  constructor(props) {
    super(props);
  }

  render = () => {
    return (

        {this.props.indexEntries.map( (entry, index) => {
          return
{entry}

;
        })}

    );
  }
}

class StagingArea extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      indexPaths: []
    };
  }

  addToIndex = () => {

    let checkedChanges = [];
    //reaches into each checkboxWrapper to obtain checked value
    checkedChanges = this.statusTable.changesList.checkboxRefs.map( (ref, index) => {
      if(ref !== null)
        return ref.state.checked;
    });

    let indexPaths =[];

    this.statusTable.changesList.props.statuses.forEach( (status, index) => {

      //if corresponding checkbox has been checked only
      if(checkedChanges[index])
        indexPaths.push(status);
    });

    // console.log('index',indexPaths);

    window.setTimeout( () => {

      this.setState({
        indexPaths: indexPaths
      });
      // console.log(this.state.indexPaths);
    }, 0);
  }

  createCommit = () => {

    let index;
    let oid;

    let promise = gitFunctions.getIndex(this.props.repo.path);
    promise = promise.then((indexResult) => {
      index = indexResult;
    });

    let filePaths = this.state.indexPaths.map( (status) => {
      return status.value;
    });

    // console.log(filePaths);

    //takes in initial promise, uses it to chain a new promise to it, and returns the promise,
    //which is used in the next iteration
    promise = filePaths.reduce( (prevPromise, path, currentIndex) => {
                return prevPromise.then( () => {
                  return index.addByPath(path);
                });
              }, promise);

    promise.then(() => {
      return index.write();
    })
    .then(() => {
      console.log(index.entries());
    })
    .then(() => {
      return index.writeTree();
    })
    .then( (oidResult) => {
      oid = oidResult;
      console.log('index tree written!');
    })
    //until here, all entries were added to the index and an index tree was written
    //from here, the new commit is generated using the index tree
    .then( () => {
      let innerPromise = gitFunctions.createCommit(this.props.repo.path, oid);
      innerPromise.done(function(commitId) {
        console.log('Commit Hash:'+commitId);
      });

    });
  }

  componentWillReceiveProps = (newprops) => {
    // console.log(newprops);
  }

  render = () => {
    const styles = {
      block: {
        maxWidth: 250,
      },
      checkbox: {
        marginBottom: 16,
      },
      main: {
        height:350,
        overflow: 'scroll',
        // backgroundColor: 'black'
      }
    };
    return (

        <RaisedButton label='Create Commit!' onMouseDown={this.createCommit} />
        <RaisedButton label='Add to Index!' onMouseDown={this.addToIndex} />
        <StatusTable {...this.props} ref={(ref) => this.statusTable = ref} />
        <IndexTable indexEntries={this.state.indexPaths.map( (status) => {return status.label})} />

    )
  }
}

export default StagingArea;
<|endoftext|>