<commit_before>/* globals Kinetic */
/* exported startConnector, endConnector, updateActiveLineLocation, getIntersectingShape,
  addElementToContainer, removeElementFromContainer, updateConnectedLines, changeConnectorEndpoints */

'use strict';

var BORDER = 20;

function updateStrokeWidth(kineticObj, normal) {
  var strokeWidth = kineticObj.originalStrokeWidth || 1;
  if (!normal) {
    strokeWidth = strokeWidth + 2;
  }

  if ('Group' === kineticObj.nodeType) {
    var mainRect = kineticObj.find('.mainRect')[0];
    if (mainRect) {
      mainRect.setStrokeWidth(strokeWidth);
    }
  }
  else {
    kineticObj.setStrokeWidth(strokeWidth);
  }
}

function setConnectorLocation(rect, group, connectorName, x, y) {
  // If there are connectors, move them to the appropriate locations
  var connector = group.find('.' + connectorName);
  if (connector.length > 0) {
    connector.each(function(node) {
      if (node.getParent() === group) {
        node.setX(x);
        node.setY(y);
      }
    });
  }
}

function updateSizeOfMainRect(rect, group, width, height) {
  rect.setWidth(width);
  rect.setHeight(height);
  group.setWidth(width);
  group.setHeight(height);

  var y = (rect.getHeight() / 2);
  setConnectorLocation(rect, group, 'rightConnector', rect.getWidth(), y);
  setConnectorLocation(rect, group, 'leftConnector', 0, y);
}

// For a container (represented by group), lay out all contained elements within the
// main rectangle.
function layoutElementsInContainer(group) {
  var header = group.getChildren(function(node) { return node.getClassName() === 'Text'; })[0];
  var rect = group.getChildren(function(node) { return node.getClassName() === 'Rect'; })[0];

  if (group.containedElements.length === 0) {
    updateSizeOfMainRect(rect, group, 200, 200);
    header.setWidth(rect.getWidth());
    return;
  }

  var currentX = BORDER;
  var currentY = header.getHeight() + BORDER;
  var maxHeight = 0;
  var element = null;
  for (var index = 0; index < group.containedElements.length; index ++) {
    element = group.containedElements[index];
    element.moveTo(group);
    element.setX(currentX);
    element.setY(currentY);
    currentX = currentX + element.getWidth() + BORDER;
    maxHeight = Math.max(maxHeight, currentY + element.getHeight() + BORDER);
  }

  updateSizeOfMainRect(rect, group, currentX, maxHeight);
  header.setWidth(rect.getWidth());
}

function findParentElementByName(parent, elementName) {
  var elements = Kinetic.names[elementName];
  var length = elements.length;
  for (var index = 0; index < length; index++) {
    if (elements[index].getParent() === parent) {
      return elements[index];
    }
  }

  return null;
}

// Update a connector line so that it is drawn between a start position and an
// end position.
function changeConnectorEndpoints(stage, line, startPos, endPos) {
  var x = endPos.x;
  var y = endPos.y;
  line.points([0, 0, x - startPos.x, y - startPos.y]);

  // Arrow head: http://jsfiddle.net/cmcculloh/M56w4/
  var fromx = 0;
  var fromy = 0;
  var tox = x - startPos.x;
  var toy = y - startPos.y;
  var headlen = 15;
  var angle = Math.atan2(toy-fromy,tox-fromx);
  line.points(
    [fromx,
     fromy,
     tox,
     toy,
     tox-headlen*Math.cos(angle-Math.PI/6),
     toy-headlen*Math.sin(angle-Math.PI/6),
     tox,
     toy,
     tox-headlen*Math.cos(angle+Math.PI/6),
     toy-headlen*Math.sin(angle+Math.PI/6)]
  );
}

function updateConnectedLines(connector, stage) {
  var i = 0;
  for (i = connector.connections.length - 1; i >= 0; i--) {
    var line = connector.connections[i];
    var startPos = {};
    var endPos = {};
    if (line.connectors.start === connector) {
      line.setAbsolutePosition(connector.getAbsolutePosition());
    }

    startPos = {x: line.getPoints()[0], y: line.getPoints()[1]};
    endPos = {
      x: line.connectors.end.getAbsolutePosition().x - line.connectors.start.getAbsolutePosition().x,
      y: line.connectors.end.getAbsolutePosition().y - line.connectors.start.getAbsolutePosition().y,
    };
    changeConnectorEndpoints(stage, line, startPos, endPos);
  }
}

function _replaceTemporalElement(isEventA, containerParent, container, element, stage) {
  // Connect element connector to line
  var connector = findParentElementByName(element, (isEventA ? 'rightConnector' : 'leftConnector'));
  if (connector === null) {
    return;
  }

  // Clean up the elements that make up the placeholder
  containerParent.find(isEventA ? '.eventALabel' : '.eventBLabel')[0].destroy();
  containerParent.find(isEventA ? '.eventAText' : '.eventBText')[0].destroy();
  var connectorCollection = containerParent.find((isEventA ? '.leftConnector' : '.rightConnector'));
  var connectorIndex = isEventA ? 0 : (connectorCollection.length === 1 ? 0 : 1);
  connectorCollection[connectorIndex].destroy();
  var oldConnector = containerParent.find((isEventA ? '.rightConnector' : '.leftConnector'))[connectorIndex];
  var line = oldConnector.connections[0];
  oldConnector.connections = [];
  oldConnector.destroy();
  container.destroy();

  // Update our tracking collections for how things are connected
  if (isEventA) {
    line.connectors.start = connector;
  }
  else {
    line.connectors.end = connector;
  }
  connector.connections.push(line);
  updateConnectedLines(connector, stage);
}

// Given a droppable container, handle adding the element to that container
function addElementToContainer(stage, container, element) {
  var group = (container.nodeType === 'Group' ? container : container.parent);
  if (group) {
    if (group.element.type === 'TemporalOperator') {
      // Replace container with element
      var containerParent = container.getParent();
      if (container === containerParent.find('.eventA')[0]) {
        _replaceTemporalElement(true, containerParent, container, element, stage);
        // // Connect element right connector to line
        // var connector = findParentElementByName(element, 'rightConnector');
        // if (connector === null) {
        //   return;
        // }

        // // Move the element to be centered in the placeholder

        // // Clean up the elements that make up the placeholder
        // containerParent.find('.eventALabel')[0].destroy();
        // containerParent.find('.eventAText')[0].destroy();
        // containerParent.find('.leftConnector')[0].destroy();
        // var oldConnector = containerParent.find('.rightConnector')[0];
        // var line = oldConnector.connections[0];
        // oldConnector.connections = [];
        // oldConnector.destroy();
        // container.destroy();

        // line.connectors.start = connector;
        // connector.connections.push(line);
        // updateConnectedLines(connector, stage);
      }
      else if (container === container.getParent().find('.eventB')[0]) {
        _replaceTemporalElement(false, containerParent, container, element, stage);
        // // Connect element left connector to line
        // var connector = findParentElementByName(element, 'leftConnector');
        // if (connector === null) {
        //   return;
        // }

        // // Move the element to be centered in the placeholder

        // // Clean up the elements that make up the placeholder
        // containerParent.find('.eventBLabel')[0].destroy();
        // containerParent.find('.eventBText')[0].destroy();
        // containerParent.find('.rightConnector')[1].destroy();
        // var oldConnector = containerParent.find('.leftConnector')[1];
        // var line = oldConnector.connections[0];
        // oldConnector.connections = [];
        // oldConnector.destroy();
        // container.destroy();

        // line.connectors.end = connector;
        // connector.connections.push(line);
        // updateConnectedLines(connector, stage);
      }
    }
    else if (group.element.type === 'DataElement' || group.element.type === 'Category') {
    }
    else if (group.element.type === 'LogicalOperator') {
      // Add the item (if it's not already in the array)
      if (group.containedElements.indexOf(element) === -1) {
        group.containedElements.push(element);
        element.container = group;
      }
      layoutElementsInContainer(group);
      stage.draw();
    }
  }
}

function removeElementFromContainer(stage, element) {
  if (element && element.container) {
    var group = (element.container.nodeType === 'Group' ? element.container : element.container.parent);
    var foundIndex = group.containedElements.indexOf(element);
    if (foundIndex < 0) {
      console.error('Unable to find element to remove from container');
      return;
    }
    group.containedElements.splice(foundIndex, 1);
    element.container = null;
    layoutElementsInContainer(group);
    stage.mainLayer.draw();
  }
}

function selectObject(stage, selectObj) {
  if (stage.connector && stage.connector.status === 'drawing') {
    return;
  }
  selectObj.selected = true;
  updateStrokeWidth(selectObj, false);
  stage.draw();
}

function clearSelections(stage) {
  var layer = stage.find('#mainLayer')[0];
  var counter = 0;
  var children = layer.getChildren();
  for (counter = 0; counter < children.length; counter++) {
    children[counter].selected = false;
    updateStrokeWidth(children[counter], true);
  }
  stage.draw();
}

// Provide the "outline" effect for objects when you move the mouse
// over them.
function addOutlineStyles(kineticObj, originalWidth) {
  var normalWidth = (originalWidth || 1);
  kineticObj.on('mouseover', function (e) {
    if (!e.target.selected) {
      e.target.setStrokeWidth(normalWidth + 2);
      e.target.getParent().draw();
    }
  });
  kineticObj.on('mouseout', function (e) {
    if (!e.target.selected) {
      e.target.setStrokeWidth(normalWidth);
      e.target.getParent().draw();
    }
  });
}

// Responding to a mouse move event, update the current connector line that is being drawn
// to end at the cursor.
function updateActiveLineLocation(stage, evt) {
  if (stage.connector.status === 'drawing') {
    var startPos = {x: stage.connector.line.getX(), y: stage.connector.line.getY()};
    var endPos = {x: evt.evt.layerX, y: evt.evt.layerY};
    changeConnectorEndpoints(stage, stage.connector.line, startPos, endPos);
    stage.drawScene();
  }
}

// Start a connector line, anchored at a connector object
function startConnector(stage, connectorObj) {
  var connectorParent = connectorObj.getParent();
  var line = new Kinetic.Line({
    //x: stage.getPointerPosition().x,
    //y: stage.getPointerPosition().y,
    x: connectorParent.getX() + connectorObj.getX(),
    y: connectorParent.getY() + connectorObj.getY(),
    points: [0, 0],
    stroke: 'black', strokeWidth: 2
  });
  line.connectors = {};
  line.connectors.start = connectorObj;
  line.originalStrokeWidth = 2;
  addOutlineStyles(line, 2);

  stage.find('#mainLayer').add(line);
  line.setZIndex(999);  // Should be on top
  stage.connector.status = 'drawing';
  stage.connector.line = line;
  line.parent.draw();
  stage.connector.anchor = connectorObj;
  connectorObj.getParent().draggable(false);
}

// For a line in progress, end the line at the given connector.  If no connector is present,
// or the connector isn't valid, remove the in progress line.
function endConnector(stage, connectorObj) {
  if (stage.connector.status === 'drawing') {
    // If we are dropping where we started, or there is no end connection point, the line
    // is invalid and we will just clear it
    if (stage.connector.anchor === connectorObj || ('undefined' === typeof connectorObj)) {
      stage.connector.line.destroy();
    }
    // Otherwise we have a valid line.  Update the internal collections tracking how objects
    // are related.
    else {
      stage.connector.line.connectors.end = connectorObj;
      connectorObj.connections.push(stage.connector.line);
      stage.connector.line.connectors.start.connections.push(stage.connector.line);
      stage.connector.line.on('mouseup', function(e) {
        clearSelections(stage);
        selectObject(stage, e.target);
      });
    }
  }

  if ('undefined' !== typeof stage.connector.anchor) {
    stage.connector.anchor.getParent().draggable(true);
  }

  stage.connector = {};
  stage.drawScene();
}

function checkCollide(pointX, pointY, objectx, objecty, objectw, objecth) { // pointX, pointY belong to one rectangle, while the object variables belong to another rectangle
  var oTop = objecty;
  var oLeft = objectx;
  var oRight = objectx+objectw;
  var oBottom = objecty+objecth;

  if(pointX > oLeft && pointX < oRight){
    if(pointY > oTop && pointY < oBottom ){
      return true;
    }
  }
  return false;
}

function getIntersectingShape(layer, pos) {
  var groups = layer.getChildren();
  var shapes = null;
  var intersectingGroup = null;
  for (var groupIndex = 0; groupIndex < groups.length; groupIndex++) {
    if (checkCollide(pos.x, pos.y, groups[groupIndex].getX(), groups[groupIndex].getY(), groups[groupIndex].getWidth(), groups[groupIndex].getHeight())) {
      intersectingGroup = groups[groupIndex];

      // Once we identify an intersected group, we need to look for the underlying droppable Rect that should
      // be considered the actual drop target.  We always use a Rect because our visual indicator of
      // a drop target is to modify the Rect itself.
      shapes = intersectingGroup.getChildren();
      for (var shapeIndex = 0; shapeIndex < shapes.length; shapeIndex++) {
        if (shapes[shapeIndex].droppable) {
          // Shapes within the group are oriented at (0, 0).  Offset the X and Y coordinates with that of the group
          if (checkCollide(pos.x, pos.y, shapes[shapeIndex].getX() + intersectingGroup.getX(), shapes[shapeIndex].getY() + intersectingGroup.getY(),
              shapes[shapeIndex].getWidth(), shapes[shapeIndex].getHeight())) {
            return shapes[shapeIndex];
          }
        }
      }

    }
  }

  return null;
}<commit_msg>Clean up commennted code<commit_after>/* globals Kinetic */
/* exported startConnector, endConnector, updateActiveLineLocation, getIntersectingShape,
  addElementToContainer, removeElementFromContainer, updateConnectedLines, changeConnectorEndpoints */

'use strict';

var BORDER = 20;

function updateStrokeWidth(kineticObj, normal) {
  var strokeWidth = kineticObj.originalStrokeWidth || 1;
  if (!normal) {
    strokeWidth = strokeWidth + 2;
  }

  if ('Group' === kineticObj.nodeType) {
    var mainRect = kineticObj.find('.mainRect')[0];
    if (mainRect) {
      mainRect.setStrokeWidth(strokeWidth);
    }
  }
  else {
    kineticObj.setStrokeWidth(strokeWidth);
  }
}

function setConnectorLocation(rect, group, connectorName, x, y) {
  // If there are connectors, move them to the appropriate locations
  var connector = group.find('.' + connectorName);
  if (connector.length > 0) {
    connector.each(function(node) {
      if (node.getParent() === group) {
        node.setX(x);
        node.setY(y);
      }
    });
  }
}

function updateSizeOfMainRect(rect, group, width, height) {
  rect.setWidth(width);
  rect.setHeight(height);
  group.setWidth(width);
  group.setHeight(height);

  var y = (rect.getHeight() / 2);
  setConnectorLocation(rect, group, 'rightConnector', rect.getWidth(), y);
  setConnectorLocation(rect, group, 'leftConnector', 0, y);
}

// For a container (represented by group), lay out all contained elements within the
// main rectangle.
function layoutElementsInContainer(group) {
  var header = group.getChildren(function(node) { return node.getClassName() === 'Text'; })[0];
  var rect = group.getChildren(function(node) { return node.getClassName() === 'Rect'; })[0];

  if (group.containedElements.length === 0) {
    updateSizeOfMainRect(rect, group, 200, 200);
    header.setWidth(rect.getWidth());
    return;
  }

  var currentX = BORDER;
  var currentY = header.getHeight() + BORDER;
  var maxHeight = 0;
  var element = null;
  for (var index = 0; index < group.containedElements.length; index ++) {
    element = group.containedElements[index];
    element.moveTo(group);
    element.setX(currentX);
    element.setY(currentY);
    currentX = currentX + element.getWidth() + BORDER;
    maxHeight = Math.max(maxHeight, currentY + element.getHeight() + BORDER);
  }

  updateSizeOfMainRect(rect, group, currentX, maxHeight);
  header.setWidth(rect.getWidth());
}

function findParentElementByName(parent, elementName) {
  var elements = Kinetic.names[elementName];
  var length = elements.length;
  for (var index = 0; index < length; index++) {
    if (elements[index].getParent() === parent) {
      return elements[index];
    }
  }

  return null;
}

// Update a connector line so that it is drawn between a start position and an
// end position.
function changeConnectorEndpoints(stage, line, startPos, endPos) {
  var x = endPos.x;
  var y = endPos.y;
  line.points([0, 0, x - startPos.x, y - startPos.y]);

  // Arrow head: http://jsfiddle.net/cmcculloh/M56w4/
  var fromx = 0;
  var fromy = 0;
  var tox = x - startPos.x;
  var toy = y - startPos.y;
  var headlen = 15;
  var angle = Math.atan2(toy-fromy,tox-fromx);
  line.points(
    [fromx,
     fromy,
     tox,
     toy,
     tox-headlen*Math.cos(angle-Math.PI/6),
     toy-headlen*Math.sin(angle-Math.PI/6),
     tox,
     toy,
     tox-headlen*Math.cos(angle+Math.PI/6),
     toy-headlen*Math.sin(angle+Math.PI/6)]
  );
}

function updateConnectedLines(connector, stage) {
  var i = 0;
  for (i = connector.connections.length - 1; i >= 0; i--) {
    var line = connector.connections[i];
    var startPos = {};
    var endPos = {};
    if (line.connectors.start === connector) {
      line.setAbsolutePosition(connector.getAbsolutePosition());
    }

    startPos = {x: line.getPoints()[0], y: line.getPoints()[1]};
    endPos = {
      x: line.connectors.end.getAbsolutePosition().x - line.connectors.start.getAbsolutePosition().x,
      y: line.connectors.end.getAbsolutePosition().y - line.connectors.start.getAbsolutePosition().y,
    };
    changeConnectorEndpoints(stage, line, startPos, endPos);
  }
}

function _replaceTemporalElement(isEventA, containerParent, container, element, stage) {
  // Connect element connector to line
  var connector = findParentElementByName(element, (isEventA ? 'rightConnector' : 'leftConnector'));
  if (connector === null) {
    return;
  }

  // Clean up the elements that make up the placeholder
  containerParent.find(isEventA ? '.eventALabel' : '.eventBLabel')[0].destroy();
  containerParent.find(isEventA ? '.eventAText' : '.eventBText')[0].destroy();
  var connectorCollection = containerParent.find((isEventA ? '.leftConnector' : '.rightConnector'));
  var connectorIndex = isEventA ? 0 : (connectorCollection.length === 1 ? 0 : 1);
  connectorCollection[connectorIndex].destroy();
  var oldConnector = containerParent.find((isEventA ? '.rightConnector' : '.leftConnector'))[connectorIndex];
  var line = oldConnector.connections[0];
  oldConnector.connections = [];
  oldConnector.destroy();
  container.destroy();

  // Update our tracking collections for how things are connected
  if (isEventA) {
    line.connectors.start = connector;
  }
  else {
    line.connectors.end = connector;
  }
  connector.connections.push(line);
  updateConnectedLines(connector, stage);
}

// Given a droppable container, handle adding the element to that container
function addElementToContainer(stage, container, element) {
  var group = (container.nodeType === 'Group' ? container : container.parent);
  if (group) {
    if (group.element.type === 'TemporalOperator') {
      // Replace container with element
      var containerParent = container.getParent();
      if (container === containerParent.find('.eventA')[0]) {
        _replaceTemporalElement(true, containerParent, container, element, stage);
      }
      else if (container === container.getParent().find('.eventB')[0]) {
        _replaceTemporalElement(false, containerParent, container, element, stage);
      }
    }
    else if (group.element.type === 'DataElement' || group.element.type === 'Category') {
    }
    else if (group.element.type === 'LogicalOperator') {
      // Add the item (if it's not already in the array)
      if (group.containedElements.indexOf(element) === -1) {
        group.containedElements.push(element);
        element.container = group;
      }
      layoutElementsInContainer(group);
      stage.draw();
    }
  }
}

function removeElementFromContainer(stage, element) {
  if (element && element.container) {
    var group = (element.container.nodeType === 'Group' ? element.container : element.container.parent);
    var foundIndex = group.containedElements.indexOf(element);
    if (foundIndex < 0) {
      console.error('Unable to find element to remove from container');
      return;
    }
    group.containedElements.splice(foundIndex, 1);
    element.container = null;
    layoutElementsInContainer(group);
    stage.mainLayer.draw();
  }
}

function selectObject(stage, selectObj) {
  if (stage.connector && stage.connector.status === 'drawing') {
    return;
  }
  selectObj.selected = true;
  updateStrokeWidth(selectObj, false);
  stage.draw();
}

function clearSelections(stage) {
  var layer = stage.find('#mainLayer')[0];
  var counter = 0;
  var children = layer.getChildren();
  for (counter = 0; counter < children.length; counter++) {
    children[counter].selected = false;
    updateStrokeWidth(children[counter], true);
  }
  stage.draw();
}

// Provide the "outline" effect for objects when you move the mouse
// over them.
function addOutlineStyles(kineticObj, originalWidth) {
  var normalWidth = (originalWidth || 1);
  kineticObj.on('mouseover', function (e) {
    if (!e.target.selected) {
      e.target.setStrokeWidth(normalWidth + 2);
      e.target.getParent().draw();
    }
  });
  kineticObj.on('mouseout', function (e) {
    if (!e.target.selected) {
      e.target.setStrokeWidth(normalWidth);
      e.target.getParent().draw();
    }
  });
}

// Responding to a mouse move event, update the current connector line that is being drawn
// to end at the cursor.
function updateActiveLineLocation(stage, evt) {
  if (stage.connector.status === 'drawing') {
    var startPos = {x: stage.connector.line.getX(), y: stage.connector.line.getY()};
    var endPos = {x: evt.evt.layerX, y: evt.evt.layerY};
    changeConnectorEndpoints(stage, stage.connector.line, startPos, endPos);
    stage.drawScene();
  }
}

// Start a connector line, anchored at a connector object
function startConnector(stage, connectorObj) {
  var connectorParent = connectorObj.getParent();
  var line = new Kinetic.Line({
    //x: stage.getPointerPosition().x,
    //y: stage.getPointerPosition().y,
    x: connectorParent.getX() + connectorObj.getX(),
    y: connectorParent.getY() + connectorObj.getY(),
    points: [0, 0],
    stroke: 'black', strokeWidth: 2
  });
  line.connectors = {};
  line.connectors.start = connectorObj;
  line.originalStrokeWidth = 2;
  addOutlineStyles(line, 2);

  stage.find('#mainLayer').add(line);
  line.setZIndex(999);  // Should be on top
  stage.connector.status = 'drawing';
  stage.connector.line = line;
  line.parent.draw();
  stage.connector.anchor = connectorObj;
  connectorObj.getParent().draggable(false);
}

// For a line in progress, end the line at the given connector.  If no connector is present,
// or the connector isn't valid, remove the in progress line.
function endConnector(stage, connectorObj) {
  if (stage.connector.status === 'drawing') {
    // If we are dropping where we started, or there is no end connection point, the line
    // is invalid and we will just clear it
    if (stage.connector.anchor === connectorObj || ('undefined' === typeof connectorObj)) {
      stage.connector.line.destroy();
    }
    // Otherwise we have a valid line.  Update the internal collections tracking how objects
    // are related.
    else {
      stage.connector.line.connectors.end = connectorObj;
      connectorObj.connections.push(stage.connector.line);
      stage.connector.line.connectors.start.connections.push(stage.connector.line);
      stage.connector.line.on('mouseup', function(e) {
        clearSelections(stage);
        selectObject(stage, e.target);
      });
    }
  }

  if ('undefined' !== typeof stage.connector.anchor) {
    stage.connector.anchor.getParent().draggable(true);
  }

  stage.connector = {};
  stage.drawScene();
}

function checkCollide(pointX, pointY, objectx, objecty, objectw, objecth) { // pointX, pointY belong to one rectangle, while the object variables belong to another rectangle
  var oTop = objecty;
  var oLeft = objectx;
  var oRight = objectx+objectw;
  var oBottom = objecty+objecth;

  if(pointX > oLeft && pointX < oRight){
    if(pointY > oTop && pointY < oBottom ){
      return true;
    }
  }
  return false;
}

function getIntersectingShape(layer, pos) {
  var groups = layer.getChildren();
  var shapes = null;
  var intersectingGroup = null;
  for (var groupIndex = 0; groupIndex < groups.length; groupIndex++) {
    if (checkCollide(pos.x, pos.y, groups[groupIndex].getX(), groups[groupIndex].getY(), groups[groupIndex].getWidth(), groups[groupIndex].getHeight())) {
      intersectingGroup = groups[groupIndex];

      // Once we identify an intersected group, we need to look for the underlying droppable Rect that should
      // be considered the actual drop target.  We always use a Rect because our visual indicator of
      // a drop target is to modify the Rect itself.
      shapes = intersectingGroup.getChildren();
      for (var shapeIndex = 0; shapeIndex < shapes.length; shapeIndex++) {
        if (shapes[shapeIndex].droppable) {
          // Shapes within the group are oriented at (0, 0).  Offset the X and Y coordinates with that of the group
          if (checkCollide(pos.x, pos.y, shapes[shapeIndex].getX() + intersectingGroup.getX(), shapes[shapeIndex].getY() + intersectingGroup.getY(),
              shapes[shapeIndex].getWidth(), shapes[shapeIndex].getHeight())) {
            return shapes[shapeIndex];
          }
        }
      }

    }
  }

  return null;
}<|endoftext|>


<commit_before>// TODO: this function does way too much: might make sense to extract reviews, assessments, etc.
// into separate functions and make this function call them
function GroupProjectBlock(runtime, element) {
    var message_box = $('.message', element).appendTo($(document.body));
    message_box.on('click', '.button, .close-box', function () {
        message_box.hide();
    });

    // TODO: does not include activity_id - might need fixing when all activities are displayed simultaneously
    $(document).on('select_stage', function (target, selected_stage_id) {
        // can't use $('#'+selected_stage_id) as selected_stage_id contains slashes
        var stage = $("[id='"+selected_stage_id+"']", element);
        if (stage.length > 0) {
            $('.activity_section', element).hide();
            stage.show();
        }
    });

    var initialization_data = JSON.parse($('.initialization_data', element).html());
    if (initialization_data && initialization_data.default_stage_id) {
        $(document).trigger('select_stage', initialization_data.default_stage_id);
    }

    // TODO: a bit hacky solution to allow directly to stages
    // Remove when stages become actual XBlocks and jump_to_id supports jumping to children
    $(document).trigger('activity_initialized', element);
}
<commit_msg>Removed stale comment<commit_after>function GroupProjectBlock(runtime, element) {
    var message_box = $('.message', element).appendTo($(document.body));
    message_box.on('click', '.button, .close-box', function () {
        message_box.hide();
    });

    // TODO: does not include activity_id - might need fixing when all activities are displayed simultaneously
    $(document).on('select_stage', function (target, selected_stage_id) {
        // can't use $('#'+selected_stage_id) as selected_stage_id contains slashes
        var stage = $("[id='"+selected_stage_id+"']", element);
        if (stage.length > 0) {
            $('.activity_section', element).hide();
            stage.show();
        }
    });

    var initialization_data = JSON.parse($('.initialization_data', element).html());
    if (initialization_data && initialization_data.default_stage_id) {
        $(document).trigger('select_stage', initialization_data.default_stage_id);
    }

    // TODO: a bit hacky solution to allow directly to stages
    // Remove when stages become actual XBlocks and jump_to_id supports jumping to children
    $(document).trigger('activity_initialized', element);
}
<|endoftext|>


<commit_before>define(function(require) {
  /*
    DEPENDENCIES
   */

  var Locale = require('utils/locale');
  var Config = require('sunstone-config');
  var Sunstone = require('sunstone');
  var Humanize = require('utils/humanize');
  var StateActions = require('../utils/state-actions');
  var OpenNebulaVM = require('opennebula/vm');
  var Tree = require('utils/tree');

  /*
    CONSTANTS
   */

  var TAB_ID = require('../tabId');
  var PANEL_ID = require('./storage/panelId');
  var ATTACH_DISK_DIALOG_ID = require('../dialogs/attach-disk/dialogId');
  var DISK_SNAPSHOT_DIALOG_ID = require('../dialogs/disk-snapshot/dialogId');
  var DISK_SAVEAS_DIALOG_ID = require('../dialogs/disk-saveas/dialogId');
  var CONFIRM_DIALOG_ID = require('utils/dialogs/generic-confirm/dialogId');
  var RESOURCE = "VM"
  var XML_ROOT = "VM"

  /*
    CONSTRUCTOR
   */

  function Panel(info) {
    this.panelId = PANEL_ID;
    this.title = Locale.tr("Storage");
    this.icon = "fa-tasks";

    this.element = info[XML_ROOT];

    return this;
  };

  Panel.PANEL_ID = PANEL_ID;
  Panel.prototype.html = _html;
  Panel.prototype.setup = _setup;

  return Panel;

  /*
    FUNCTION DEFINITIONS
   */

  function _html() {
    var that = this;
    var html = '<form id="tab_storage_form" vmid="' + that.element.ID + '" >\

\

\

\

\

\
                 	\
                 ' + Locale.tr("ID") + '	\
                 ' + Locale.tr("Target") + '	\
                 ' + Locale.tr("Image / Format-Size") + '	\
                 ' + Locale.tr("Persistent") + '	\
                 ' + Locale.tr("Actions");

    if (Config.isTabActionEnabled("vms-tab", "VM.attachdisk")) {
      if (StateActions.enabledStateAction("VM.attachdisk", that.element.STATE, that.element.LCM_STATE)) {
        html += '\
          \
            <button id="attach_disk" class="button tiny success right radius" >' + Locale.tr("Attach disk") + '</button>\
          ';
      } else {
        html += '\
          \
            <button id="attach_disk" class="button tiny success right radius" disabled="disabled">' + Locale.tr("Attach disk") + '</button>\
          ';
      }
    }

    html +=     '	\

\

\

\

\

\

\

\
    </form>';

    return html;
  }

  function _setup(context) {
    var that = this;

    var snapshots = [];
    if ($.isArray(this.element.SNAPSHOTS)){
      snapshots = this.element.SNAPSHOTS;
    } else if (!$.isEmptyObject(this.element.SNAPSHOTS)) {
      snapshots = [this.element.SNAPSHOTS];
    }

    var snapshotsHtml = {};

    $.each(snapshots, function(){
      var diskId = this.DISK_ID;
      var diskSnapshots = this.SNAPSHOT;

      if (!$.isArray(diskSnapshots)){
        diskSnapshots = [diskSnapshots];
      }

      var treeRoot = {
        htmlStr : '',
        subTree : []
      };

      var indexedSnapshots = {};
      var noParent = [];

      $.each(diskSnapshots, function(){
        indexedSnapshots[this.ID] = this;

        if(this.PARENT == "-1"){
          noParent.push(this.ID);
        }
      });

      $.each(noParent, function(){
        treeRoot.subTree.push(
          _makeTree(indexedSnapshots[this], indexedSnapshots)
        );
      });

      snapshotsHtml[diskId] = Tree.html(treeRoot);
    });

    var disks = [];
    if ($.isArray(that.element.TEMPLATE.DISK))
      disks = that.element.TEMPLATE.DISK;
    else if (!$.isEmptyObject(that.element.TEMPLATE.DISK))
      disks = [that.element.TEMPLATE.DISK];

    if (!$.isEmptyObject(that.element.TEMPLATE.CONTEXT)) {
      var context_disk = that.element.TEMPLATE.CONTEXT;

      context_disk["IMAGE"] = Locale.tr("Context");
      context_disk["CONTEXT"] = true;

      disks.push(context_disk);
    }

    var disk_dt_data = [];
    if (disks.length) {

      for (var i = 0; i < disks.length; i++) {
        var disk = disks[i];

        // Save as
        if (
           (
            that.element.STATE == OpenNebulaVM.STATES.ACTIVE) &&
           (
            that.element.LCM_STATE == OpenNebulaVM.LCM_STATES.HOTPLUG_SAVEAS ||
            that.element.LCM_STATE == OpenNebulaVM.LCM_STATES.HOTPLUG_SAVEAS_POWEROFF ||
            that.element.LCM_STATE == OpenNebulaVM.LCM_STATES.HOTPLUG_SAVEAS_SUSPENDED) &&
           (
            disk.HOTPLUG_SAVE_AS_ACTIVE == "YES")
           ) {
          actions = Locale.tr('Save as in progress');
        }
        // Attach / Detach
        else if (
           (
            that.element.STATE == OpenNebulaVM.STATES.ACTIVE) &&
           (
            that.element.LCM_STATE == OpenNebulaVM.LCM_STATES.HOTPLUG) &&
           (
            disk.ATTACH = "YES")
           ) {
          actions = Locale.tr('attach/detach in progress');
        } else {
          actions = '';

          if (Config.isTabActionEnabled("vms-tab", "VM.disk_saveas")) {
            // Check if it's volatile
            if (disk.IMAGE_ID &&
                 StateActions.enabledStateAction("VM.disk_saveas", that.element.STATE, that.element.LCM_STATE)) {
              actions += '\
              ' + Locale.tr("Save as") + '  ';
            }
          }

          if (Config.isTabActionEnabled("vms-tab", "VM.detachdisk")) {
            if (StateActions.enabledStateAction("VM.detachdisk", that.element.STATE, that.element.LCM_STATE) && !disk.CONTEXT) {
              actions += ('\
              ' + Locale.tr("Detach") +
              '  ');
            }
          }

          if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_create")) {
            // TODO: set disk_snapshot_create in state-actions.js
            //if (StateActions.enabledStateAction("VM.disk_snapshot_create", that.element.STATE, that.element.LCM_STATE) && !disk.CONTEXT) {
            if (!disk.CONTEXT) {
              actions += ('\
              ' + Locale.tr("Snapshot") +
              '');
            }
          }
        }

        disk_dt_data.push({
          DISK_ID : disk.DISK_ID,
          TARGET : disk.TARGET,
          IMAGE : (disk.IMAGE ? disk.IMAGE : (Humanize.sizeFromMB(disk.SIZE) + (disk.FORMAT ? (' - ' + disk.FORMAT) : ''))),
          SAVE : ((disk.SAVE && disk.SAVE == 'YES') ? Locale.tr('YES') : Locale.tr('NO')),
          ACTIONS : actions,
          SNAPSHOTS : snapshotsHtml[disk.DISK_ID]
        });
      }
    }

    var disks_table = $("#tab_storage_form .disks_table", context).DataTable({
      "bDeferRender": true,
      "data": disk_dt_data,
      "columns": [
        {
          "class":          'open-control',
          "orderable":      false,
          "data":           null,
          "defaultContent": ''
        },
        {"data": "DISK_ID",   "defaultContent": ""},
        {"data": "TARGET",    "defaultContent": ""},
        {"data": "IMAGE",     "defaultContent": "", "orderable": false},
        {"data": "SAVE",      "defaultContent": "", "orderable": false},
        {"data": "ACTIONS",   "defaultContent": "", "orderable": false}
      ],

      "fnRowCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {

        if (aData.SNAPSHOTS == undefined ||
            aData.SNAPSHOTS.length == 0) {

          $("td.open-control", nRow).html("").removeClass('open-control');
        }

        $(nRow).attr("disk_id", aData.DISK_ID);
      }
    });

    $("#tab_storage_form .disks_table", context).dataTable().fnSort([[1, 'asc']]);

    // Add event listener for opening and closing each row details
    context.off('click', '#tab_storage_form .disks_table td.open-control')
    context.on('click', '#tab_storage_form .disks_table td.open-control', function () {
      var row = $(this).closest('table').DataTable().row($(this).closest('tr'));

      if (row.child.isShown()) {
        row.child.hide();
        $(this).children("span").addClass('fa-chevron-down');
        $(this).children("span").removeClass('fa-chevron-up');
      } else {
        var html = '
'+
          row.data().SNAPSHOTS+
          '
';

        row.child(html).show();
        $(this).children("span").removeClass('fa-chevron-down');
        $(this).children("span").addClass('fa-chevron-up');
      }
    });

    if (Config.isTabActionEnabled("vms-tab", "VM.disk_saveas")) {
      context.off('click', '.disk_saveas');
      context.on('click', '.disk_saveas', function() {
        var disk_id = $(this).parents('tr').attr('disk_id');

        var dialog = Sunstone.getDialog(DISK_SAVEAS_DIALOG_ID);
        dialog.setParams(
          { element: that.element,
            diskId: disk_id
          });

        dialog.reset();
        dialog.show();
        return false;
      });

      context.off('click', '.disk_snapshot_saveas');
      context.on('click', '.disk_snapshot_saveas', function() {
        var disk_id = $(this).parents('.snapshots').attr('disk_id');
        var snapshot_id = $(this).parents('.snapshot_row').attr('snapshot_id');

        var dialog = Sunstone.getDialog(DISK_SAVEAS_DIALOG_ID);
        dialog.setParams(
          { element: that.element,
            diskId: disk_id,
            snapshotId: snapshot_id
          });

        dialog.reset();
        dialog.show();
        return false;
      });
    }

    if (Config.isTabActionEnabled("vms-tab", "VM.attachdisk")) {
      context.off('click', '#attach_disk');
      context.on('click', '#attach_disk', function() {
        var dialog = Sunstone.getDialog(ATTACH_DISK_DIALOG_ID);
        dialog.setElement(that.element);
        dialog.show();
        return false;
      });
    }

    if (Config.isTabActionEnabled("vms-tab", "VM.detachdisk")) {
      context.off('click', '.detachdisk');
      context.on('click', '.detachdisk', function() {
        var disk_id = $(this).parents('tr').attr('disk_id');
        Sunstone.runAction('VM.detachdisk', that.element.ID, disk_id);
        return false;
      });
    }

    if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_create")) {
      context.off('click', '.disk_snapshot_create');
      context.on('click', '.disk_snapshot_create', function() {
        var disk_id = $(this).parents('tr').attr('disk_id');

        var dialog = Sunstone.getDialog(DISK_SNAPSHOT_DIALOG_ID);
        dialog.setParams(
          { element: that.element,
            diskId: disk_id
          });

        dialog.reset();
        dialog.show();
        return false;
      });
    }

    if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_revert")) {
      context.off('click', '.disk_snapshot_revert');
      context.on('click', '.disk_snapshot_revert', function() {
        var disk_id = $(this).parents('.snapshots').attr('disk_id');
        var snapshot_id = $(this).parents('.snapshot_row').attr('snapshot_id');

        Sunstone.runAction(
          'VM.disk_snapshot_revert',
          that.element.ID,
          { "disk_id": disk_id,
            "snapshot_id": snapshot_id
          });

        return false;
      });
    }

    if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_delete")) {
      context.off('click', '.disk_snapshot_delete');
      context.on('click', '.disk_snapshot_delete', function() {
        var disk_id = $(this).parents('.snapshots').attr('disk_id');
        var snapshot_id = $(this).parents('.snapshot_row').attr('snapshot_id');

        Sunstone.getDialog(CONFIRM_DIALOG_ID).setParams({
          //header :
          body : Locale.tr("This will delete the disk snapshot "+snapshot_id),
          //question :
          submit : function(){
            Sunstone.runAction(
              'VM.disk_snapshot_delete',
              that.element.ID,
              { "disk_id": disk_id,
                "snapshot_id": snapshot_id
              });
          }
        });

        Sunstone.getDialog(CONFIRM_DIALOG_ID).reset();
        Sunstone.getDialog(CONFIRM_DIALOG_ID).show();

        return false;
      });
    }

    Tree.setup(context);
  }

  function _makeTree(snapshot, indexedSnapshots){
    var SPACE = '    ';

    var subTree = [];

    if (snapshot.CHILDREN){
      $.each(snapshot.CHILDREN.split(","), function(){
        subTree.push(
          _makeTree(indexedSnapshots[this], indexedSnapshots)
        );
      });
    }

    var html = '
';

    var active = (snapshot.ACTIVE == "YES");

    if(active){
      html += snapshot.ID + SPACE + '' + SPACE;
    } else {
      html += snapshot.ID + SPACE;
    }

    html += Humanize.prettyTime(snapshot.DATE) + SPACE +
            (snapshot.TAG ? snapshot.TAG + SPACE : '');

    if (Config.isTabActionEnabled("vms-tab", "VM.disk_saveas")) {
      html += '\
              ' + Locale.tr("Save as") + '  ';
    }

    if(!active){
      if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_revert")) {
        html += '' + Locale.tr("Revert") + '  ';
      }

      if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_delete")) {
        html += '' + Locale.tr("Delete") + '';
      }
    }

    html += '
';

    return {
      htmlStr : html,
      subTree : subTree
    };
  }
});<commit_msg>Feature #3782: Allow to revert to active disk snapshot in sunstone<commit_after>define(function(require) {
  /*
    DEPENDENCIES
   */

  var Locale = require('utils/locale');
  var Config = require('sunstone-config');
  var Sunstone = require('sunstone');
  var Humanize = require('utils/humanize');
  var StateActions = require('../utils/state-actions');
  var OpenNebulaVM = require('opennebula/vm');
  var Tree = require('utils/tree');

  /*
    CONSTANTS
   */

  var TAB_ID = require('../tabId');
  var PANEL_ID = require('./storage/panelId');
  var ATTACH_DISK_DIALOG_ID = require('../dialogs/attach-disk/dialogId');
  var DISK_SNAPSHOT_DIALOG_ID = require('../dialogs/disk-snapshot/dialogId');
  var DISK_SAVEAS_DIALOG_ID = require('../dialogs/disk-saveas/dialogId');
  var CONFIRM_DIALOG_ID = require('utils/dialogs/generic-confirm/dialogId');
  var RESOURCE = "VM"
  var XML_ROOT = "VM"

  /*
    CONSTRUCTOR
   */

  function Panel(info) {
    this.panelId = PANEL_ID;
    this.title = Locale.tr("Storage");
    this.icon = "fa-tasks";

    this.element = info[XML_ROOT];

    return this;
  };

  Panel.PANEL_ID = PANEL_ID;
  Panel.prototype.html = _html;
  Panel.prototype.setup = _setup;

  return Panel;

  /*
    FUNCTION DEFINITIONS
   */

  function _html() {
    var that = this;
    var html = '<form id="tab_storage_form" vmid="' + that.element.ID + '" >\

\

\

\

\

\
                 	\
                 ' + Locale.tr("ID") + '	\
                 ' + Locale.tr("Target") + '	\
                 ' + Locale.tr("Image / Format-Size") + '	\
                 ' + Locale.tr("Persistent") + '	\
                 ' + Locale.tr("Actions");

    if (Config.isTabActionEnabled("vms-tab", "VM.attachdisk")) {
      if (StateActions.enabledStateAction("VM.attachdisk", that.element.STATE, that.element.LCM_STATE)) {
        html += '\
          \
            <button id="attach_disk" class="button tiny success right radius" >' + Locale.tr("Attach disk") + '</button>\
          ';
      } else {
        html += '\
          \
            <button id="attach_disk" class="button tiny success right radius" disabled="disabled">' + Locale.tr("Attach disk") + '</button>\
          ';
      }
    }

    html +=     '	\

\

\

\

\

\

\

\
    </form>';

    return html;
  }

  function _setup(context) {
    var that = this;

    var snapshots = [];
    if ($.isArray(this.element.SNAPSHOTS)){
      snapshots = this.element.SNAPSHOTS;
    } else if (!$.isEmptyObject(this.element.SNAPSHOTS)) {
      snapshots = [this.element.SNAPSHOTS];
    }

    var snapshotsHtml = {};

    $.each(snapshots, function(){
      var diskId = this.DISK_ID;
      var diskSnapshots = this.SNAPSHOT;

      if (!$.isArray(diskSnapshots)){
        diskSnapshots = [diskSnapshots];
      }

      var treeRoot = {
        htmlStr : '',
        subTree : []
      };

      var indexedSnapshots = {};
      var noParent = [];

      $.each(diskSnapshots, function(){
        indexedSnapshots[this.ID] = this;

        if(this.PARENT == "-1"){
          noParent.push(this.ID);
        }
      });

      $.each(noParent, function(){
        treeRoot.subTree.push(
          _makeTree(indexedSnapshots[this], indexedSnapshots)
        );
      });

      snapshotsHtml[diskId] = Tree.html(treeRoot);
    });

    var disks = [];
    if ($.isArray(that.element.TEMPLATE.DISK))
      disks = that.element.TEMPLATE.DISK;
    else if (!$.isEmptyObject(that.element.TEMPLATE.DISK))
      disks = [that.element.TEMPLATE.DISK];

    if (!$.isEmptyObject(that.element.TEMPLATE.CONTEXT)) {
      var context_disk = that.element.TEMPLATE.CONTEXT;

      context_disk["IMAGE"] = Locale.tr("Context");
      context_disk["CONTEXT"] = true;

      disks.push(context_disk);
    }

    var disk_dt_data = [];
    if (disks.length) {

      for (var i = 0; i < disks.length; i++) {
        var disk = disks[i];

        // Save as
        if (
           (
            that.element.STATE == OpenNebulaVM.STATES.ACTIVE) &&
           (
            that.element.LCM_STATE == OpenNebulaVM.LCM_STATES.HOTPLUG_SAVEAS ||
            that.element.LCM_STATE == OpenNebulaVM.LCM_STATES.HOTPLUG_SAVEAS_POWEROFF ||
            that.element.LCM_STATE == OpenNebulaVM.LCM_STATES.HOTPLUG_SAVEAS_SUSPENDED) &&
           (
            disk.HOTPLUG_SAVE_AS_ACTIVE == "YES")
           ) {
          actions = Locale.tr('Save as in progress');
        }
        // Attach / Detach
        else if (
           (
            that.element.STATE == OpenNebulaVM.STATES.ACTIVE) &&
           (
            that.element.LCM_STATE == OpenNebulaVM.LCM_STATES.HOTPLUG) &&
           (
            disk.ATTACH = "YES")
           ) {
          actions = Locale.tr('attach/detach in progress');
        } else {
          actions = '';

          if (Config.isTabActionEnabled("vms-tab", "VM.disk_saveas")) {
            // Check if it's volatile
            if (disk.IMAGE_ID &&
                 StateActions.enabledStateAction("VM.disk_saveas", that.element.STATE, that.element.LCM_STATE)) {
              actions += '\
              ' + Locale.tr("Save as") + '  ';
            }
          }

          if (Config.isTabActionEnabled("vms-tab", "VM.detachdisk")) {
            if (StateActions.enabledStateAction("VM.detachdisk", that.element.STATE, that.element.LCM_STATE) && !disk.CONTEXT) {
              actions += ('\
              ' + Locale.tr("Detach") +
              '  ');
            }
          }

          if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_create")) {
            // TODO: set disk_snapshot_create in state-actions.js
            //if (StateActions.enabledStateAction("VM.disk_snapshot_create", that.element.STATE, that.element.LCM_STATE) && !disk.CONTEXT) {
            if (!disk.CONTEXT) {
              actions += ('\
              ' + Locale.tr("Snapshot") +
              '');
            }
          }
        }

        disk_dt_data.push({
          DISK_ID : disk.DISK_ID,
          TARGET : disk.TARGET,
          IMAGE : (disk.IMAGE ? disk.IMAGE : (Humanize.sizeFromMB(disk.SIZE) + (disk.FORMAT ? (' - ' + disk.FORMAT) : ''))),
          SAVE : ((disk.SAVE && disk.SAVE == 'YES') ? Locale.tr('YES') : Locale.tr('NO')),
          ACTIONS : actions,
          SNAPSHOTS : snapshotsHtml[disk.DISK_ID]
        });
      }
    }

    var disks_table = $("#tab_storage_form .disks_table", context).DataTable({
      "bDeferRender": true,
      "data": disk_dt_data,
      "columns": [
        {
          "class":          'open-control',
          "orderable":      false,
          "data":           null,
          "defaultContent": ''
        },
        {"data": "DISK_ID",   "defaultContent": ""},
        {"data": "TARGET",    "defaultContent": ""},
        {"data": "IMAGE",     "defaultContent": "", "orderable": false},
        {"data": "SAVE",      "defaultContent": "", "orderable": false},
        {"data": "ACTIONS",   "defaultContent": "", "orderable": false}
      ],

      "fnRowCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {

        if (aData.SNAPSHOTS == undefined ||
            aData.SNAPSHOTS.length == 0) {

          $("td.open-control", nRow).html("").removeClass('open-control');
        }

        $(nRow).attr("disk_id", aData.DISK_ID);
      }
    });

    $("#tab_storage_form .disks_table", context).dataTable().fnSort([[1, 'asc']]);

    // Add event listener for opening and closing each row details
    context.off('click', '#tab_storage_form .disks_table td.open-control')
    context.on('click', '#tab_storage_form .disks_table td.open-control', function () {
      var row = $(this).closest('table').DataTable().row($(this).closest('tr'));

      if (row.child.isShown()) {
        row.child.hide();
        $(this).children("span").addClass('fa-chevron-down');
        $(this).children("span").removeClass('fa-chevron-up');
      } else {
        var html = '
'+
          row.data().SNAPSHOTS+
          '
';

        row.child(html).show();
        $(this).children("span").removeClass('fa-chevron-down');
        $(this).children("span").addClass('fa-chevron-up');
      }
    });

    if (Config.isTabActionEnabled("vms-tab", "VM.disk_saveas")) {
      context.off('click', '.disk_saveas');
      context.on('click', '.disk_saveas', function() {
        var disk_id = $(this).parents('tr').attr('disk_id');

        var dialog = Sunstone.getDialog(DISK_SAVEAS_DIALOG_ID);
        dialog.setParams(
          { element: that.element,
            diskId: disk_id
          });

        dialog.reset();
        dialog.show();
        return false;
      });

      context.off('click', '.disk_snapshot_saveas');
      context.on('click', '.disk_snapshot_saveas', function() {
        var disk_id = $(this).parents('.snapshots').attr('disk_id');
        var snapshot_id = $(this).parents('.snapshot_row').attr('snapshot_id');

        var dialog = Sunstone.getDialog(DISK_SAVEAS_DIALOG_ID);
        dialog.setParams(
          { element: that.element,
            diskId: disk_id,
            snapshotId: snapshot_id
          });

        dialog.reset();
        dialog.show();
        return false;
      });
    }

    if (Config.isTabActionEnabled("vms-tab", "VM.attachdisk")) {
      context.off('click', '#attach_disk');
      context.on('click', '#attach_disk', function() {
        var dialog = Sunstone.getDialog(ATTACH_DISK_DIALOG_ID);
        dialog.setElement(that.element);
        dialog.show();
        return false;
      });
    }

    if (Config.isTabActionEnabled("vms-tab", "VM.detachdisk")) {
      context.off('click', '.detachdisk');
      context.on('click', '.detachdisk', function() {
        var disk_id = $(this).parents('tr').attr('disk_id');
        Sunstone.runAction('VM.detachdisk', that.element.ID, disk_id);
        return false;
      });
    }

    if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_create")) {
      context.off('click', '.disk_snapshot_create');
      context.on('click', '.disk_snapshot_create', function() {
        var disk_id = $(this).parents('tr').attr('disk_id');

        var dialog = Sunstone.getDialog(DISK_SNAPSHOT_DIALOG_ID);
        dialog.setParams(
          { element: that.element,
            diskId: disk_id
          });

        dialog.reset();
        dialog.show();
        return false;
      });
    }

    if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_revert")) {
      context.off('click', '.disk_snapshot_revert');
      context.on('click', '.disk_snapshot_revert', function() {
        var disk_id = $(this).parents('.snapshots').attr('disk_id');
        var snapshot_id = $(this).parents('.snapshot_row').attr('snapshot_id');

        Sunstone.runAction(
          'VM.disk_snapshot_revert',
          that.element.ID,
          { "disk_id": disk_id,
            "snapshot_id": snapshot_id
          });

        return false;
      });
    }

    if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_delete")) {
      context.off('click', '.disk_snapshot_delete');
      context.on('click', '.disk_snapshot_delete', function() {
        var disk_id = $(this).parents('.snapshots').attr('disk_id');
        var snapshot_id = $(this).parents('.snapshot_row').attr('snapshot_id');

        Sunstone.getDialog(CONFIRM_DIALOG_ID).setParams({
          //header :
          body : Locale.tr("This will delete the disk snapshot "+snapshot_id),
          //question :
          submit : function(){
            Sunstone.runAction(
              'VM.disk_snapshot_delete',
              that.element.ID,
              { "disk_id": disk_id,
                "snapshot_id": snapshot_id
              });
          }
        });

        Sunstone.getDialog(CONFIRM_DIALOG_ID).reset();
        Sunstone.getDialog(CONFIRM_DIALOG_ID).show();

        return false;
      });
    }

    Tree.setup(context);
  }

  function _makeTree(snapshot, indexedSnapshots){
    var SPACE = '    ';

    var subTree = [];

    if (snapshot.CHILDREN){
      $.each(snapshot.CHILDREN.split(","), function(){
        subTree.push(
          _makeTree(indexedSnapshots[this], indexedSnapshots)
        );
      });
    }

    var html = '
';

    var active = (snapshot.ACTIVE == "YES");

    if(active){
      html += snapshot.ID + SPACE + '' + SPACE;
    } else {
      html += snapshot.ID + SPACE;
    }

    html += Humanize.prettyTime(snapshot.DATE) + SPACE +
            (snapshot.TAG ? snapshot.TAG + SPACE : '');

    if (Config.isTabActionEnabled("vms-tab", "VM.disk_saveas")) {
      html += '\
              ' + Locale.tr("Save as") + '  ';
    }

    if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_revert")) {
      html += '' + Locale.tr("Revert") + '  ';
    }

    if(!active){
      if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_delete")) {
        html += '' + Locale.tr("Delete") + '';
      }
    }

    html += '
';

    return {
      htmlStr : html,
      subTree : subTree
    };
  }
});<|endoftext|>


<commit_before>var extend = require('node.extend');
var PersistentCollection = require('./persistent-collection');
var connectionManager = require('../pom/connection-mysql');
var dataTranslator = require('./mysql-translator');
var odata = require('../util/odata-parser');
var stamp = require('../model/stamp');
var ownership = require('../model/ownership');
var catalogueNumber = require('../model/catalogue-number');
var _ = require('../../lib/underscore/underscore');
var q = require('q');
var Logger = require('../util/logger');

var sqlTrace = Logger.getLogger("sql");
var logger = Logger.getLogger("server");

var stamps = extend(true, {}, new PersistentCollection(), function () {

    "use strict";

    function generateColumnExpression(fields, tableRef) {
        var s = "";
        _.each(fields, function (field, indx) {
            var prefix = false;
            if (field.field === 'id' && tableRef !== stamp.getAlias()) {
                prefix = true;
            }
            s += tableRef + "." + field.column;
            if (prefix) {
                s += ' AS ' + tableRef + field.column;
            }
            if (indx < fields.length - 1) {
                s += ',';
            }
        });
        return s;
    }

    function populateChildren(fields, childfields, object, childKey) {
        var child = {};
        _.each(childfields, function (field) {
            if (field.column === 'ID' && typeof object[childKey] !== 'undefined') {
                child[field.column] = object[childKey];
                delete object[childKey];
            } else if (typeof object[field.column] !== 'undefined') {
                child[field.column] = object[field.column];
                delete object[field.column];
            }
        });

        return child;
    }

    function populateKey(stamp, k) {
        if (!_.has(stamp, k)) {
            stamp[k] = [];
        }
    }

    function processRow(rows, row, fieldDef, key) {
        var s = _.findWhere(rows, { ID: row.STAMP_ID });
        if (!s) {
            sqlTrace.log(Logger.TRACE, "No stamp found for " + row.STAMP_ID);
            return;
        }
        s[key].push(populateChildren(stamp.getFieldDefinitions(), fieldDef.getFieldDefinitions(), row, fieldDef.getAlias() + 'ID'));
    }

    function generateChildSelection(supportedFields, fieldDefinition, fromTables, whereClause, inValues) {
        var select = 'SELECT ' + generateColumnExpression(supportedFields, fieldDefinition.getAlias());
        select += ' FROM ' + fromTables + ' WHERE ' + ((whereClause.length > 0) ? (whereClause + ' AND ') : '');
        select += fieldDefinition.getAlias() + '.STAMP_ID IN ' + inValues;
        return select;
    }

    return {
        preCreate: function (obj) {
            obj.catalogueCount = (obj.catalogueNumbers) ? obj.catalogueNumbers.length : 0;
        },
        preCommitUpdate: function (connection, merged, storedObj) {
            var defer = q.defer();
            var that = this;
            var updateList = [], createList = [];
            var parseChildren = function (childName, fieldDef) {
                if (merged[childName] && _.isArray(merged[childName])) {
                    _.each(merged[childName], function (obj) {
                        if (obj.ID) {
                            var current = _.findWhere(storedObj[childName], { ID: obj.ID});
                            var sql = dataTranslator.generateUpdateByFields(fieldDef, obj, current, true);
                            if (sql !== null) {
                                updateList.push(sql);
                            }
                        } else {
                            obj.STAMP_ID = merged.ID;
                            createList.push({ fieldDefinition: fieldDef, object: obj});
                        }
                    });
                }
            };
            parseChildren("CATALOGUENUMBER", catalogueNumber);
            parseChildren("OWNERSHIP", ownership);

            var total = updateList.length + createList.length;
            var count = 0;
            var resolveWhenFinished = function () {
                if (count === total) {
                    defer.resolve({
                        modified: total > 0
                    });
                }
            };
            resolveWhenFinished();
            _.each(updateList, function (sql) {
                sqlTrace.log(Logger.DEBUG, sql);
                connection.query(sql, function (err, data) {
                    if (err !== null) {
                        defer.reject(dataTranslator.getErrorMessage(err));
                    } else {
                        count++;
                        resolveWhenFinished();
                    }

                });
            });
            _.each(createList, function (obj) {
                var creating = obj;
                PersistentCollection.getNextSequence(creating.fieldDefinition, function (err, id) {
                    if (err !== null) {
                        defer.reject(dataTranslator.getErrorMessage(err));
                    } else {
                        creating.object.ID = id;
                        var c_sql = dataTranslator.generateInsertByFields(creating.fieldDefinition, creating.object);
                        sqlTrace.log(Logger.DEBUG, c_sql);
                        connection.query(c_sql, function (err, data) {
                            if (err !== null) {
                                defer.reject(dataTranslator.getErrorMessage(err));
                            } else {
                                count++;
                                resolveWhenFinished();
                            }
                        });
                        PersistentCollection.updateSequence(id, creating.fieldDefinition);
                    }
                });
            });
            return defer.promise;
        },

        postCreate: function (connection, obj) {
            var defer = q.defer();
            var total = ((obj.catalogueNumbers) ? obj.catalogueNumbers.length : 0) + ((obj.stampOwnerships) ? obj.stampOwnerships.length : 0);
            var created = 0;
            var that = this;
            if (obj.catalogueNumbers && _.isArray(obj.catalogueNumbers)) {
                _.each(obj.catalogueNumbers, function (catNum) {
                    catNum.stampRef = obj.id;
                    that.generateId(catalogueNumber, catNum).then(function (id) {
                        catNum.id = id;
                        var sql = dataTranslator.generateInsertStatement(catalogueNumber, catNum);
                        sqlTrace.log(Logger.DEBUG, sql);
                        connection.query(sql, function (err, result) {
                            if (err) {
                                defer.reject(dataTranslator.getErrorMessage(err));
                            } else {
                                created++;
                                if (created === total) {
                                    defer.resolve(obj);
                                }
                            }
                        });
                    }, function (err) {
                        defer.reject(dataTranslator.getErrorMessage(err));
                    });
                });
            }
            if (obj.stampOwnerships && _.isArray(obj.stampOwnerships)) {
                _.each(obj.stampOwnerships, function (owner) {
                    owner.stampRef = obj.id;
                    that.generateId(ownership, owner).then(function (id) {
                        owner.id = id;
                        var sql = dataTranslator.generateInsertStatement(ownership, owner);
                        sqlTrace.log(Logger.DEBUG, sql);
                        connection.query(sql, function (err, result) {
                            if (err) {
                                defer.reject(dataTranslator.getErrorMessage(err));
                            } else {
                                created++;
                                if (created === total) {
                                    defer.resolve(obj);
                                }
                            }

                        });
                    });
                }, function (err) {
                    defer.reject(dataTranslator.getErrorMessage(err));
                });
            }
            return defer.promise;
        },

        getFromTables: function ($filter) {
            var tables = stamp.getTableName() + ' AS ' + stamp.getAlias() + ' JOIN ' + catalogueNumber.getTableName() + ' AS ' + catalogueNumber.getAlias();
            tables += ' ON ' + stamp.getAlias() + '.ID=' + catalogueNumber.getAlias() + '.STAMP_ID ';
            tables += 'LEFT OUTER JOIN ' + ownership.getTableName() + ' AS ' + ownership.getAlias() + ' ON ' + stamp.getAlias() + '.ID = ' + ownership.getAlias() + '.STAMP_ID';
            return tables;
        },

        getWhereClause: function ($filter) {
            return ($filter) ? dataTranslator.toWhereClause($filter, [stamp, catalogueNumber, ownership]) : '';
        },

        find: function ($filter, $limit, $offset, $orderby) {
            var defer = q.defer();
            var that = this;

            if (!$limit) {
                $limit = 1000;
            }
            if (!$offset) {
                $offset = 0;
            }
            var rejectFn = function (field) {
                return (field.internal && field.internal === true && field.required !== true || field.model);
            };
            var stampDef = _.reject(stamp.getFieldDefinitions(), rejectFn);
            var catDef = _.reject(catalogueNumber.getFieldDefinitions(), rejectFn);
            var ownerDef = _.reject(ownership.getFieldDefinitions(), rejectFn);

            var select = 'SELECT SQL_CALC_FOUND_ROWS ' + generateColumnExpression(stampDef, stamp.getAlias()) + ' FROM ' + this.getFromTables();
            var whereClause = this.getWhereClause($filter);
            select += ((whereClause.length > 0) ? (' WHERE ' + whereClause) : '') + ' LIMIT ' + $offset + ',' + $limit;
            sqlTrace.log(Logger.DEBUG, select);
            var t = (new Date()).getTime();
            connectionManager.getConnection().then(function (connection) {
                var query = connection.query(select, function (err, stamps) {
                    if (err) {
                        connection.release();
                        defer.reject(dataTranslator.getErrorMessage(err));
                    } else {
                        connection.query("SELECT FOUND_ROWS() AS ROWCOUNT", function (err, countData) {
                            if (err) {
                                connection.release();
                                defer.reject(dataTranslator.getErrorMessage(err));
                            } else {
                                var result = {
                                    rows: stamps,
                                    total: countData[0].ROWCOUNT
                                };
                                if (result.total === 0) {
                                    connection.release();
                                    defer.resolve(result);
                                } else {
                                    var ids = _.pluck(result.rows, 'ID');
                                    _.each(result.rows, function(row) {
                                        populateKey(row,'CATALOGUENUMBER');
                                        populateKey(row,'OWNERSHIP');
                                    });
                                    var inValues = dataTranslator.generateInValueStatement(ids);
                                    var queries = [
                                        {
                                            sql: generateChildSelection(catDef, catalogueNumber, that.getFromTables(), whereClause, inValues),
                                            fieldDefinition: catalogueNumber,
                                            collectionKey: 'CATALOGUENUMBER'
                                        },
                                        {
                                            sql: generateChildSelection(ownerDef, ownership, that.getFromTables(), whereClause, inValues),
                                            fieldDefinition: ownership,
                                            collectionKey: 'OWNERSHIP'
                                        }
                                    ];
                                    var completed = 0;
                                    var toExecute = queries.length;
                                    _.each(queries, function (query) {
                                        sqlTrace.log(Logger.DEBUG, query.sql);
                                        var _query = connection.query(query.sql);
                                        _query.on('result', function (row) {
                                            processRow(result.rows, row, query.fieldDefinition, query.collectionKey)
                                        }).on('end', function () {
                                            completed++;
                                            if (completed === toExecute) {
                                                connection.release();
                                                sqlTrace.log(Logger.INFO, "Time to query and process rows: " + (new Date().getTime() - t) + "ms");
                                                defer.resolve(result);
                                            }
                                        }).on('error', function (err) {
                                            connection.release();
                                            defer.reject(dataTranslator.getErrorMessage(err));
                                        });
                                    });
                                }
                            }
                        });
                    }
                });
            }, function (err) {
                defer.reject(dataTranslator.getErrorMessage(err));
            });
            return defer.promise;
        },
        collectionName: 'stamps',
        fieldDefinition: stamp
    };
}());

module.exports = stamps;
<commit_msg>Further stamp query improvements<commit_after>var extend = require('node.extend');
var PersistentCollection = require('./persistent-collection');
var connectionManager = require('../pom/connection-mysql');
var dataTranslator = require('./mysql-translator');
var odata = require('../util/odata-parser');
var stamp = require('../model/stamp');
var ownership = require('../model/ownership');
var catalogueNumber = require('../model/catalogue-number');
var _ = require('../../lib/underscore/underscore');
var q = require('q');
var Logger = require('../util/logger');

var sqlTrace = Logger.getLogger("sql");
var logger = Logger.getLogger("server");

var stamps = extend(true, {}, new PersistentCollection(), function () {

    "use strict";

    function generateColumnExpression(fields, tableRef) {
        var s = "";
        _.each(fields, function (field, indx) {
            s += tableRef + "." + field.column;
            if (indx < fields.length - 1) {
                s += ',';
            }
        });
        return s;
    }

    function populateKey(stamp, k) {
        if (!_.has(stamp, k)) {
            stamp[k] = [];
        }
    }

    function processRow(rows, row, fieldDef, key) {
        var s = _.findWhere(rows, { ID: row.STAMP_ID });
        if (!s) {
            sqlTrace.log(Logger.TRACE, "No stamp found for " + row.STAMP_ID);
            return;
        }
        s[key].push(row);
    }

    function getFromTableForChildren (fieldDefinition) {
        var tables = stamp.getTableName() + ' AS ' + stamp.getAlias() + ' JOIN ' + fieldDefinition.getTableName() + ' AS ' + fieldDefinition.getAlias();
        tables += ' ON ' + stamp.getAlias() + '.ID=' + fieldDefinition.getAlias() + '.STAMP_ID';
        return tables;
    }

    function generateChildSelection(supportedFields, fieldDefinition, inValues) {
        var select = 'SELECT ' + generateColumnExpression(supportedFields, fieldDefinition.getAlias());
        select += ' FROM ' + getFromTableForChildren(fieldDefinition) + ' WHERE ' + fieldDefinition.getAlias() + '.STAMP_ID IN ' + inValues;
        return select;
    }

    return {
        preCreate: function (obj) {
            obj.catalogueCount = (obj.catalogueNumbers) ? obj.catalogueNumbers.length : 0;
        },
        preCommitUpdate: function (connection, merged, storedObj) {
            var defer = q.defer();
            var that = this;
            var updateList = [], createList = [];
            var parseChildren = function (childName, fieldDef) {
                if (merged[childName] && _.isArray(merged[childName])) {
                    _.each(merged[childName], function (obj) {
                        if (obj.ID) {
                            var current = _.findWhere(storedObj[childName], { ID: obj.ID});
                            var sql = dataTranslator.generateUpdateByFields(fieldDef, obj, current, true);
                            if (sql !== null) {
                                updateList.push(sql);
                            }
                        } else {
                            obj.STAMP_ID = merged.ID;
                            createList.push({ fieldDefinition: fieldDef, object: obj});
                        }
                    });
                }
            };
            parseChildren("CATALOGUENUMBER", catalogueNumber);
            parseChildren("OWNERSHIP", ownership);

            var total = updateList.length + createList.length;
            var count = 0;
            var resolveWhenFinished = function () {
                if (count === total) {
                    defer.resolve({
                        modified: total > 0
                    });
                }
            };
            resolveWhenFinished();
            _.each(updateList, function (sql) {
                sqlTrace.log(Logger.DEBUG, sql);
                connection.query(sql, function (err, data) {
                    if (err !== null) {
                        defer.reject(dataTranslator.getErrorMessage(err));
                    } else {
                        count++;
                        resolveWhenFinished();
                    }

                });
            });
            _.each(createList, function (obj) {
                var creating = obj;
                PersistentCollection.getNextSequence(creating.fieldDefinition, function (err, id) {
                    if (err !== null) {
                        defer.reject(dataTranslator.getErrorMessage(err));
                    } else {
                        creating.object.ID = id;
                        var c_sql = dataTranslator.generateInsertByFields(creating.fieldDefinition, creating.object);
                        sqlTrace.log(Logger.DEBUG, c_sql);
                        connection.query(c_sql, function (err, data) {
                            if (err !== null) {
                                defer.reject(dataTranslator.getErrorMessage(err));
                            } else {
                                count++;
                                resolveWhenFinished();
                            }
                        });
                        PersistentCollection.updateSequence(id, creating.fieldDefinition);
                    }
                });
            });
            return defer.promise;
        },

        postCreate: function (connection, obj) {
            var defer = q.defer();
            var total = ((obj.catalogueNumbers) ? obj.catalogueNumbers.length : 0) + ((obj.stampOwnerships) ? obj.stampOwnerships.length : 0);
            var created = 0;
            var that = this;
            if (obj.catalogueNumbers && _.isArray(obj.catalogueNumbers)) {
                _.each(obj.catalogueNumbers, function (catNum) {
                    catNum.stampRef = obj.id;
                    that.generateId(catalogueNumber, catNum).then(function (id) {
                        catNum.id = id;
                        var sql = dataTranslator.generateInsertStatement(catalogueNumber, catNum);
                        sqlTrace.log(Logger.DEBUG, sql);
                        connection.query(sql, function (err, result) {
                            if (err) {
                                defer.reject(dataTranslator.getErrorMessage(err));
                            } else {
                                created++;
                                if (created === total) {
                                    defer.resolve(obj);
                                }
                            }
                        });
                    }, function (err) {
                        defer.reject(dataTranslator.getErrorMessage(err));
                    });
                });
            }
            if (obj.stampOwnerships && _.isArray(obj.stampOwnerships)) {
                _.each(obj.stampOwnerships, function (owner) {
                    owner.stampRef = obj.id;
                    that.generateId(ownership, owner).then(function (id) {
                        owner.id = id;
                        var sql = dataTranslator.generateInsertStatement(ownership, owner);
                        sqlTrace.log(Logger.DEBUG, sql);
                        connection.query(sql, function (err, result) {
                            if (err) {
                                defer.reject(dataTranslator.getErrorMessage(err));
                            } else {
                                created++;
                                if (created === total) {
                                    defer.resolve(obj);
                                }
                            }

                        });
                    });
                }, function (err) {
                    defer.reject(dataTranslator.getErrorMessage(err));
                });
            }
            return defer.promise;
        },

        getFromTables: function ($filter) {
            var tables = stamp.getTableName() + ' AS ' + stamp.getAlias() + ' JOIN ' + catalogueNumber.getTableName() + ' AS ' + catalogueNumber.getAlias();
            tables += ' ON ' + stamp.getAlias() + '.ID=' + catalogueNumber.getAlias() + '.STAMP_ID ';
            tables += 'LEFT OUTER JOIN ' + ownership.getTableName() + ' AS ' + ownership.getAlias() + ' ON ' + stamp.getAlias() + '.ID = ' + ownership.getAlias() + '.STAMP_ID';
            return tables;
        },

        getWhereClause: function ($filter) {
            return ($filter) ? dataTranslator.toWhereClause($filter, [stamp, catalogueNumber, ownership]) : '';
        },

        find: function ($filter, $limit, $offset, $orderby) {
            var defer = q.defer();
            var that = this;

            if (!$limit) {
                $limit = 1000;
            }
            if (!$offset) {
                $offset = 0;
            }
            var rejectFn = function (field) {
                return (field.internal && field.internal === true && field.required !== true || field.model);
            };
            var stampDef = _.reject(stamp.getFieldDefinitions(), rejectFn);
            var catDef = _.reject(catalogueNumber.getFieldDefinitions(), rejectFn);
            var ownerDef = _.reject(ownership.getFieldDefinitions(), rejectFn);

            var select = 'SELECT SQL_CALC_FOUND_ROWS ' + generateColumnExpression(stampDef, stamp.getAlias()) + ' FROM ' + this.getFromTables();
            var whereClause = this.getWhereClause($filter);
            select += ((whereClause.length > 0) ? (' WHERE ' + whereClause) : '') + ' LIMIT ' + $offset + ',' + $limit;
            sqlTrace.log(Logger.DEBUG, select);
            var t = (new Date()).getTime();
            connectionManager.getConnection().then(function (connection) {
                var query = connection.query(select, function (err, stamps) {
                    if (err) {
                        connection.release();
                        defer.reject(dataTranslator.getErrorMessage(err));
                    } else {
                        connection.query("SELECT FOUND_ROWS() AS ROWCOUNT", function (err, countData) {
                            if (err) {
                                connection.release();
                                defer.reject(dataTranslator.getErrorMessage(err));
                            } else {
                                var result = {
                                    rows: stamps,
                                    total: countData[0].ROWCOUNT
                                };
                                if (result.total === 0) {
                                    connection.release();
                                    defer.resolve(result);
                                } else {
                                    var ids = _.pluck(result.rows, 'ID');
                                    _.each(result.rows, function(row) {
                                        populateKey(row,'CATALOGUENUMBER');
                                        populateKey(row,'OWNERSHIP');
                                    });
                                    var inValues = dataTranslator.generateInValueStatement(ids);
                                    var queries = [
                                        {
                                            sql: generateChildSelection(catDef, catalogueNumber, inValues),
                                            fieldDefinition: catalogueNumber,
                                            collectionKey: 'CATALOGUENUMBER'
                                        },
                                        {
                                            sql: generateChildSelection(ownerDef, ownership, inValues),
                                            fieldDefinition: ownership,
                                            collectionKey: 'OWNERSHIP'
                                        }
                                    ];
                                    var completed = 0;
                                    var toExecute = queries.length;
                                    _.each(queries, function (query) {
                                        sqlTrace.log(Logger.DEBUG, query.sql);
                                        var _query = connection.query(query.sql);
                                        _query.on('result', function (row) {
                                            processRow(result.rows, row, query.fieldDefinition, query.collectionKey);
                                        }).on('end', function () {
                                            completed++;
                                            if (completed === toExecute) {
                                                connection.release();
                                                sqlTrace.log(Logger.INFO, "Time to query and process rows: " + (new Date().getTime() - t) + "ms");
                                                defer.resolve(result);
                                            }
                                        }).on('error', function (err) {
                                            connection.release();
                                            defer.reject(dataTranslator.getErrorMessage(err));
                                        });
                                    });
                                }
                            }
                        });
                    }
                });
            }, function (err) {
                defer.reject(dataTranslator.getErrorMessage(err));
            });
            return defer.promise;
        },
        collectionName: 'stamps',
        fieldDefinition: stamp
    };
}());

module.exports = stamps;
<|endoftext|>


<commit_before>// Scroll effects for the page

// Top bar text changes from white to black after scrolling a certain amount
function adjustTopBar(scroll) {
  const topBar = document.getElementsByClassName('top-bar')[0];

  // Scroll distance at which everything will switch from black to white
  const threshold = window.innerWidth > window.innerHeight
                        ? window.innerHeight * 1.5
                        : window.innerHeight;

  // Text color changes suddenly at threshold
  if (scroll > threshold) {
    topBar.style.color = 'black';
  } else {
    topBar.style.color = 'white';
  }
}

// Main scroll handler

function scrollHandler() {
  const scroll = window.scrollY;
  adjustTopBar(scroll);
}

window.addEventListener('scroll', scrollHandler);
document.addEventListener('DOMContentLoaded', scrollHandler);
<commit_msg>Fix portrait scrollbar color threshold<commit_after>// Scroll effects for the page

// Top bar text changes from white to black after scrolling a certain amount
function adjustTopBar(scroll) {
  const topBar = document.getElementsByClassName('top-bar')[0];

  // Scroll distance at which everything will switch from black to white
  const threshold = window.innerWidth > window.innerHeight
                        ? window.innerHeight * 1.5
                        : window.innerHeight * 0.95;

  // Text color changes suddenly at threshold
  if (scroll > threshold) {
    topBar.style.color = 'black';
  } else {
    topBar.style.color = 'white';
  }
}

// Main scroll handler

function scrollHandler() {
  const scroll = window.scrollY;
  adjustTopBar(scroll);
}

window.addEventListener('scroll', scrollHandler);
document.addEventListener('DOMContentLoaded', scrollHandler);
<|endoftext|>


<commit_before>var shell = require("shelljs/global"),
		exec = require("child_process").exec;

if (!test('-f', 'bower.json')) {
	if (!which('bower')) {
		echo('bower not installed');
		echo('run npm install -g bower && npm install');
		echo('aborting');
		exit(1);
	} else {
		echo('bower not initialiased... initialising');
		exec('bower init');
	}
} else {
	echo('bower.json is initialised');
}

if (test('-f', 'secrets-sample.coffee') && !test('-f', 'secrets.coffee')) {
	echo('creating your very own secrets');
	cp('secrets-sample.coffee', 'secrets.coffee');
	echo('secrets.coffee created');
} else {
	echo('secrets.coffee is ready');
}

if (!test('-d', 'jspm_packages')) {
	if (!which('jspm')) {
		echo('jspm not installed');
		echo('run npm install -g jspm && npm install');
		echo('aborting');
		exit(1);
	} else {
		echo('installing jspm packages');
		exec('jspm install');
	}
} else {
	echo('jspm packages installed');
}

if (!test('-L', 'styleguide/src/assets/toolkit/assets')) {
	echo('symlinking styleguide assets to site assets');
	cd('styleguide/src/assets/toolkit');
	ln('-s', '../../../../src/site/templates/assets', 'assets');
	echo('assets symlinked');
} else {
	echo('styleguide correctly symlinked to site assets');
}

<commit_msg>install bower via setup.js<commit_after>var shell = require("shelljs/global"),
		exec = require("child_process").exec;

if (!test('-f', 'bower.json')) {
	if (!which('bower')) {
		echo('bower module not installed');
		echo('run npm install -g bower && npm install');
		echo('aborting');
		exit(1);
	} else {
		echo('installing bower components');
		exec('bower installed');
	}
} else {
	echo('bower.json is initialised');
}

if (test('-f', 'secrets-sample.coffee') && !test('-f', 'secrets.coffee')) {
	echo('creating your very own secrets');
	cp('secrets-sample.coffee', 'secrets.coffee');
	echo('secrets.coffee created');
} else {
	echo('secrets.coffee is ready');
}

if (!test('-d', 'jspm_packages')) {
	if (!which('jspm')) {
		echo('jspm not installed');
		echo('run npm install -g jspm && npm install');
		echo('aborting');
		exit(1);
	} else {
		echo('installing jspm packages');
		exec('jspm install');
	}
} else {
	echo('jspm packages installed');
}

if (!test('-L', 'styleguide/src/assets/toolkit/assets')) {
	echo('symlinking styleguide assets to site assets');
	cd('styleguide/src/assets/toolkit');
	ln('-s', '../../../../src/site/templates/assets', 'assets');
	echo('assets symlinked');
} else {
	echo('styleguide correctly symlinked to site assets');
}

<|endoftext|>


<commit_before>define(["jquery", "backbone", "jasmine", "app"], function($, Backbone, jasmine, app) {

    describe("Moxie app changing views", function() {
        var el = $('

');

        afterEach(function() {
            app.currentView = undefined;
        });

        it("Should call render on any new view", function() {
            var dummyView = jasmine.createSpyObj('view', ['render']);
            app.showView(dummyView, el);
            expect(dummyView.render).toHaveBeenCalled();
        });

        it("Should fully remove a view", function() {
            var dummyView = jasmine.createSpyObj('view', ['render', 'remove', 'unbind']);
            var dummyView2 = jasmine.createSpyObj('view2', ['render']);
            app.showView(dummyView, el);
            app.showView(dummyView2, el);
            expect(dummyView.remove).toHaveBeenCalled();
            expect(dummyView.unbind).toHaveBeenCalled();
            expect(dummyView2.render).toHaveBeenCalled();
        });

        it("Should call onClose if defined", function() {
            var dummyView = jasmine.createSpyObj('view', ['render', 'remove', 'unbind', 'onClose']);
            var dummyView2 = jasmine.createSpyObj('view2', ['render']);
            app.showView(dummyView, el);
            app.showView(dummyView2, el);
            expect(dummyView.onClose).toHaveBeenCalled();
        });

        it("Should default to #content if no el supplied", function() {
            var jqHtml = spyOn($.fn, "html");
            var dummyView = jasmine.createSpyObj('view', ['render']);
            app.showView(dummyView);
            expect(dummyView.render).toHaveBeenCalled();
            expect(jqHtml.mostRecentCall.object.selector).toEqual('#content');
        });

        it("Should not select content when overriding el", function() {
            var jqHtml = spyOn($.fn, "html");
            var dummyView = jasmine.createSpyObj('view', ['render']);
            app.showView(dummyView, el);
            expect(dummyView.render).toHaveBeenCalled();
            expect(jqHtml.mostRecentCall.object.selector).toNotEqual('#content');
        });

        it("Should call html function on jquery object", function() {
            var jqHtml = spyOn($.fn, "html");
            var dummyView = jasmine.createSpyObj('view', ['render']);
            app.showView(dummyView);
            expect(dummyView.render).toHaveBeenCalled();
            expect(jqHtml).toHaveBeenCalled();
        });
    });

});
<commit_msg>Briefly explanation for the jquery mocking tests<commit_after>define(["jquery", "backbone", "jasmine", "app"], function($, Backbone, jasmine, app) {

    describe("Moxie app changing views", function() {
        var el = $('

');

        afterEach(function() {
            app.currentView = undefined;
        });

        it("Should call render on any new view", function() {
            var dummyView = jasmine.createSpyObj('view', ['render']);
            app.showView(dummyView, el);
            expect(dummyView.render).toHaveBeenCalled();
        });

        it("Should fully remove a view", function() {
            var dummyView = jasmine.createSpyObj('view', ['render', 'remove', 'unbind']);
            var dummyView2 = jasmine.createSpyObj('view2', ['render']);
            app.showView(dummyView, el);
            app.showView(dummyView2, el);
            expect(dummyView.remove).toHaveBeenCalled();
            expect(dummyView.unbind).toHaveBeenCalled();
            expect(dummyView2.render).toHaveBeenCalled();
        });

        it("Should call onClose if defined", function() {
            var dummyView = jasmine.createSpyObj('view', ['render', 'remove', 'unbind', 'onClose']);
            var dummyView2 = jasmine.createSpyObj('view2', ['render']);
            app.showView(dummyView, el);
            app.showView(dummyView2, el);
            expect(dummyView.onClose).toHaveBeenCalled();
        });

        it("Should default to #content if no el supplied", function() {
            // This is a useful way to mock the html function out of the jquery prototype
            var jqHtml = spyOn($.fn, "html");
            var dummyView = jasmine.createSpyObj('view', ['render']);
            app.showView(dummyView);
            expect(dummyView.render).toHaveBeenCalled();
            // Here we inspect the object our Spy was called upon to
            // query the content of the jquery selector
            expect(jqHtml.mostRecentCall.object.selector).toEqual('#content');
        });

        it("Should not select content when overriding el", function() {
            var jqHtml = spyOn($.fn, "html");
            var dummyView = jasmine.createSpyObj('view', ['render']);
            app.showView(dummyView, el);
            expect(dummyView.render).toHaveBeenCalled();
            expect(jqHtml.mostRecentCall.object.selector).toNotEqual('#content');
        });

        it("Should call html function on jquery object", function() {
            var jqHtml = spyOn($.fn, "html");
            var dummyView = jasmine.createSpyObj('view', ['render']);
            app.showView(dummyView);
            expect(dummyView.render).toHaveBeenCalled();
            expect(jqHtml).toHaveBeenCalled();
        });
    });

});
<|endoftext|>


<commit_before>var express = require('express'),
    passport = require('passport'),
    path = require('path'),
    nconf = require('nconf'),
    EntityService = require('../entity-service.js');

require('./auth.js')();

module.exports = function (app) {
    'use strict';

    var router = express.Router();

    EntityService.init(app.db);

    app.set('views', __dirname + '/views');
    app.set('view engine', 'ejs');

    router.use(express.static(path.join(__dirname, 'www')));

    router.use(function (req, res, next) {
        passport.authenticate('basic', {
            session: false
        })(req, res, next);
    });

    router.get('/', function (req, res) {
        res.render('index', {
            zones: nconf.get('zones')
        });
    });

    router.get('/entities/:zoneId', function(req, res) {
        EntityService.getAll(req.params.zoneId).then(res.send, function(err) {
            res.send(500, err);
        });
    });

    app.use('/', router);

};
<commit_msg>thrash<commit_after>var express = require('express'),
    passport = require('passport'),
    path = require('path'),
    nconf = require('nconf'),
    EntityService = require('../entity-service.js');

require('./auth.js')();

module.exports = function (app) {
    'use strict';

    var router = express.Router();

    EntityService.init(app.db);

    app.set('views', __dirname + '/views');
    app.set('view engine', 'ejs');

    router.use(express.static(path.join(__dirname, 'www')));

    router.use(function (req, res, next) {
        passport.authenticate('basic', {
            session: false
        })(req, res, next);
    });

    router.get('/', function (req, res) {
        res.render('index', {
            zones: nconf.get('zones')
        });
    });

    router.get('/entities/:zoneId', function(req, res) {
        EntityService.getAll(req.params.zoneId).then(res.send, function(err) {
            res.status(500).send(err);
        });
    });

    app.use('/', router);

};
<|endoftext|>