Skip to content

Commit

Permalink
Merge pull request #196 from juliancheal/physical_infra_pages
Browse files Browse the repository at this point in the history
Physical infra pages
  • Loading branch information
Dan Clarizio authored Mar 6, 2017
2 parents 0c866cf + 3d7e8df commit d304589
Show file tree
Hide file tree
Showing 30 changed files with 1,372 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ ManageIQ.angular.app.controller('emsCommonFormController', ['$http', '$scope', '
$scope.emsCommonModel.metrics_verify != '' && $scope.angularForm.metrics_verify.$valid)) {
return true;
} else if($scope.currentTab == "default" &&
["ems_container", "ems_middleware", "ems_datawarehouse" ].indexOf($scope.emsCommonModel.ems_controller) >= 0 &&
["ems_container", "ems_middleware", "ems_datawarehouse", "ems_physical_infra"].indexOf($scope.emsCommonModel.ems_controller) >= 0 &&
($scope.emsCommonModel.emstype) &&
($scope.emsCommonModel.default_hostname != '' && $scope.emsCommonModel.default_api_port) &&
($scope.emsCommonModel.default_password != '' && $scope.angularForm.default_password.$valid) &&
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
/* global miqHttpInject */

miqHttpInject(angular.module('physicalInfraTopologyApp', ['kubernetesUI', 'ui.bootstrap', 'ManageIQ']))
.controller('physicalInfraTopologyController', physicalInfraTopologyCtrl);

physicalInfraTopologyCtrl.$inject = ['$scope', '$http', '$interval', '$location', 'topologyService', 'miqService'];

function physicalInfraTopologyCtrl($scope, $http, $interval, $location, topologyService, miqService) {
var self = this;
$scope.vs = null;
var icons = null;

var d3 = window.d3;
$scope.refresh = function() {
var id;
if ($location.absUrl().match("show/$") || $location.absUrl().match("show$")) {
id = '';
} else {
id = '/' + (/physical_infra_topology\/show\/(\d+)/.exec($location.absUrl())[1]);
}

var url = '/physical_infra_topology/data' + id;

$http.get(url)
.then(getPhysicalInfraTopologyData)
.catch(miqService.handleFailure);
};

$scope.checkboxModel = {
value: false
};

$scope.legendTooltip = __("Click here to show/hide entities of this type");

$scope.show_hide_names = function() {
var vertices = $scope.vs;

if ($scope.checkboxModel.value) {
vertices.selectAll("text.attached-label")
.classed("visible", true);
} else {
vertices.selectAll("text.attached-label")
.classed("visible", false);
}
};

$scope.refresh();
var promise = $interval($scope.refresh, 1000 * 60 * 3);

$scope.$on('$destroy', function() {
$interval.cancel(promise);
});

var contextMenuShowing = false;

d3.select("body").on('click', function() {
if(contextMenuShowing) {
removeContextMenu();
}
});

var removeContextMenu = function() {
d3.event.preventDefault();
d3.select(".popup").remove();
contextMenuShowing = false;
};

self.contextMenu = function contextMenu(_that, data) {
if(contextMenuShowing) {
removeContextMenu();
} else {
d3.event.preventDefault();

var canvas = d3.select("kubernetes-topology-graph");
var mousePosition = d3.mouse(canvas.node());

var popup = canvas.append("div")
.attr("class", "popup")
.style("left", mousePosition[0] + "px")
.style("top", mousePosition[1] + "px");
popup.append("h5").text("Actions on " + data.item.display_kind);

buildContextMenuOptions(popup, data);

var canvasSize = [
canvas.node().offsetWidth,
canvas.node().offsetHeight
];

var popupSize = [
popup.node().offsetWidth,
popup.node().offsetHeight
];

if (popupSize[0] + mousePosition[0] > canvasSize[0]) {
popup.style("left", "auto");
popup.style("right", 0);
}

if (popupSize[1] + mousePosition[1] > canvasSize[1]) {
popup.style("top", "auto");
popup.style("bottom", 0);
}
contextMenuShowing = !contextMenuShowing;
}
};

var buildContextMenuOptions = function(popup, data) {
if (data.item.kind == "Tag") {
return false;
}

topologyService.addContextMenuOption(popup, __("Go to summary page"), data, self.dblclick);
};

$scope.$on("render", function(ev, vertices, added) {
/*
* We are passed two selections of <g> elements:
* vertices: All the elements
* added: Just the ones that were added
*/

added.attr("class", function(d) {
return d.item.kind;
});

added.append("circle")
.attr("r", function(d) {
return self.getDimensions(d).r;
})
.attr('class', function(d) {
return topologyService.getItemStatusClass(d);
})
.on("contextmenu", function(d) {
self.contextMenu(this, d);
});

added.append("title");

added.on("dblclick", function(d) {
return self.dblclick(d);
});

added.append("image")
.attr("xlink:href", function (d) {
var iconInfo = self.getIcon(d);
switch(iconInfo.type) {
case 'image':
return iconInfo.icon;
case "glyph":
return null;
}
})
.attr("height", function(d) {
var iconInfo = self.getIcon(d);
if (iconInfo.type != 'image') {
return 0;
}
return 40;
})
.attr("width", function(d) {
var iconInfo = self.getIcon(d);
if (iconInfo.type != 'image') {
return 0;
}
return 40;
})
.attr("y", function(d) {
return self.getDimensions(d).y;
})
.attr("x", function(d) {
return self.getDimensions(d).x;
})
.on("contextmenu", function(d) {
self.contextMenu(this, d);
});

added.append("text")
.each(function(d) {
var iconInfo = self.getIcon(d);
if (iconInfo.type != 'glyph')
return;

$(this).text(iconInfo.icon)
.attr("class", "glyph")
.attr('font-family', iconInfo.fontfamily);
})

.attr("y", function(d) {
return self.getDimensions(d).y;
})
.attr("x", function(d) {
return self.getDimensions(d).x;
})
.on("contextmenu", function(d) {
self.contextMenu(this, d);
});

added.append("text")
.attr("x", 26)
.attr("y", 24)
.text(function(d) {
return d.item.name;
})
.attr('class', function() {
var class_name = "attached-label";
if ($scope.checkboxModel.value) {
return class_name + ' visible';
} else {
return class_name;
}
});

added.selectAll("title").text(function(d) {
return topologyService.tooltip(d).join("\n");
});

$scope.vs = vertices;

/* Don't do default rendering */
ev.preventDefault();
});

this.dblclick = function dblclick(d) {
if (d.item.kind == "Tag") {
return false;
}
window.location.assign(topologyService.geturl(d));
};

this.getIcon = function getIcon(d) {
switch(d.item.kind) {
case 'PhysicalInfraManager':
return icons[d.item.display_kind];
default:
return icons[d.item.kind];
}
};

this.getDimensions = function getDimensions(d) {
var defaultDimensions = topologyService.defaultElementDimensions();
switch (d.item.kind) {
case "PhysicalInfraManager":
return { x: -20, y: -20, r: 28 };
case "EmsCluster":
return { x: defaultDimensions.x, y: defaultDimensions.y, r: defaultDimensions.r };
case "Host":
return { x: defaultDimensions.x, y: defaultDimensions.y, r: defaultDimensions.r };
case "Tag":
return { x: defaultDimensions.x, y: defaultDimensions.y, r: 13 };
default:
return defaultDimensions;
}
};

$scope.searchNode = function() {
var svg = topologyService.getSVG(d3);
var query = $scope.search.query;

topologyService.searchNode(svg, query);
};

$scope.resetSearch = function() {
topologyService.resetSearch(d3);

// Reset the search term in search input
$scope.search.query = "";
};

function getPhysicalInfraTopologyData(response) {
var data = response.data;

var currentSelectedKinds = $scope.kinds;

$scope.items = data.data.items;
$scope.relations = data.data.relations;
$scope.kinds = data.data.kinds;
icons = data.data.icons;

if (currentSelectedKinds && (Object.keys(currentSelectedKinds).length !== Object.keys($scope.kinds).length)) {
$scope.kinds = currentSelectedKinds;
}
}
}
2 changes: 2 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1683,6 +1683,8 @@ def render_or_redirect_partial(pfx)
javascript_redirect edit_ems_datawarehouse_path(params[:id])
elsif params[:pressed] == "ems_network_edit" && params[:id]
javascript_redirect edit_ems_network_path(params[:id])
elsif params[:pressed] == "ems_physical_infra_edit" && params[:id]
javascript_redirect edit_ems_physical_infra_path(params[:id])
else
javascript_redirect :action => @refresh_partial, :id => @redirect_id
end
Expand Down
7 changes: 4 additions & 3 deletions app/controllers/ems_common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -451,9 +451,10 @@ def button
javascript_redirect :back
return
end
if params[:pressed] == "ems_cloud_recheck_auth_status" ||
params[:pressed] == "ems_infra_recheck_auth_status" ||
params[:pressed] == "ems_middleware_recheck_auth_status" ||
if params[:pressed] == "ems_cloud_recheck_auth_status" ||
params[:pressed] == "ems_infra_recheck_auth_status" ||
params[:pressed] == "ems_physical_infra_recheck_auth_status" ||
params[:pressed] == "ems_middleware_recheck_auth_status" ||
params[:pressed] == "ems_container_recheck_auth_status"
if params[:id]
table_key = :table
Expand Down
67 changes: 67 additions & 0 deletions app/controllers/ems_physical_infra_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
class EmsPhysicalInfraController < ApplicationController
include Mixins::GenericListMixin
include Mixins::GenericShowMixin
include EmsCommon # common methods for EmsInfra/Cloud controllers
include Mixins::EmsCommonAngular

before_action :check_privileges
before_action :get_session_data
after_action :cleanup_action
after_action :set_session_data

def self.model
ManageIQ::Providers::PhysicalInfraManager
end

def self.table_name
@table_name ||= "ems_physical_infra"
end

def ems_path(*args)
ems_physical_infra_path(*args)
end

def new_ems_path
new_ems_physical_infra_path
end

def ems_physical_infra_form_fields
assert_privileges("#{permission_prefix}_edit")
@ems = model.new if params[:id] == 'new'
@ems = find_by_id_filtered(model, params[:id]) if params[:id] != 'new'

render :json => {
:name => @ems.name,
:emstype => @ems.emstype,
:zone => zone,
:provider_id => @ems.provider_id ? @ems.provider_id : "",
:hostname => @ems.hostname,
:default_hostname => @ems.connection_configurations.default.endpoint.hostname,
:default_api_port => @ems.connection_configurations.default.endpoint.port,
:provider_region => @ems.provider_region,
:default_userid => @ems.authentication_userid ? @ems.authentication_userid : "",
:ems_controller => controller_name,
:default_auth_status => default_auth_status,
}
end

private

############################
# Special EmsCloud link builder for restful routes
def show_link(ems, options = {})
ems_path(ems.id, options)
end

def log_and_flash_message(message)
add_flash(message, :error)
$log.error(message)
end

def restful?
true
end
public :restful?

menu_section :phy
end
Loading

0 comments on commit d304589

Please sign in to comment.