diff --git a/static/css/directives/ui/image-changes-view.css b/static/css/directives/ui/image-changes-view.css
deleted file mode 100644
index 9e7b8940e..000000000
--- a/static/css/directives/ui/image-changes-view.css
+++ /dev/null
@@ -1,47 +0,0 @@
-.image-changes-view .change-count {
- font-size: 16px;
- display: inline-block;
- margin-right: 10px;
-}
-
-.image-changes-view .change-count b {
- font-weight: normal;
- margin-left: 6px;
- vertical-align: middle;
-}
-
-.image-changes-view .changes-container .well {
- border: 0px;
-}
-
-.image-changes-view .changes-container i.fa-plus-square {
- color: rgb(73, 209, 73);
-}
-
-.image-changes-view .changes-container i.fa-minus-square {
- color: rgb(209, 73, 73);
-}
-
-.image-changes-view .changes-container i.fa-pencil-square {
- color: rgb(73, 100, 209);
-}
-
-.image-changes-view .change-count:last-child {
- margin-right: 0px;
-}
-
-.image-changes-view .change-count i {
- font-size: 16px;
- vertical-align: middle;
-}
-
-.image-changes-view .change i {
- float: right;
- vertical-align: middle;
- margin-left: 4px;
-}
-
-.image-changes-view .more-changes {
- padding: 6px;
- text-align: right;
-}
diff --git a/static/directives/image-changes-view.html b/static/directives/image-changes-view.html
deleted file mode 100644
index 78b9581ce..000000000
--- a/static/directives/image-changes-view.html
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
- {{ changeData.added.length }}
-
-
-
- {{ changeData.removed.length }}
-
-
-
- {{ changeData.changed.length }}
-
-
-
-
diff --git a/static/directives/image-info-sidebar.html b/static/directives/image-info-sidebar.html
index a126c88ca..7a69f578d 100644
--- a/static/directives/image-info-sidebar.html
+++ b/static/directives/image-info-sidebar.html
@@ -91,15 +91,4 @@
ng-repeat="location in imageData.locations">
-
-
-
diff --git a/static/js/directives/ui/image-changes-view.js b/static/js/directives/ui/image-changes-view.js
deleted file mode 100644
index 997473c2c..000000000
--- a/static/js/directives/ui/image-changes-view.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * An element which loads and displays UI representing the changes made in an image.
- */
-angular.module('quay').directive('imageChangesView', function () {
- var directiveDefinitionObject = {
- priority: 0,
- templateUrl: '/static/directives/image-changes-view.html',
- replace: false,
- transclude: false,
- restrict: 'C',
- scope: {
- 'repository': '=repository',
- 'image': '=image',
- 'hasChanges': '=hasChanges'
- },
- controller: function($scope, $element, ApiService) {
- $scope.$watch('image', function() {
- if (!$scope.image || !$scope.repository) { return; }
-
- var params = {
- 'repository': $scope.repository.namespace + '/' + $scope.repository.name,
- 'image_id': $scope.image
- };
-
- $scope.hasChanges = true;
- $scope.imageChangesResource = ApiService.getImageChangesAsResource(params).get(function(resp) {
- $scope.changeData = resp;
- $scope.hasChanges = resp.added.length || resp.removed.length || resp.changed.length;
- });
- });
- }
- };
- return directiveDefinitionObject;
-});
diff --git a/static/js/graphing.js b/static/js/graphing.js
index 67b5aa346..0d4f308cd 100644
--- a/static/js/graphing.js
+++ b/static/js/graphing.js
@@ -989,519 +989,6 @@ ImageHistoryTree.prototype.dispose = function() {
$('#' + container).html('');
};
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Based off of http://bl.ocks.org/mbostock/1093025 by Mike Bostock (@mbostock)
- */
-function FileTreeBase() {
- /**
- * Counter for creating unique IDs.
- */
- this.idCounter_ = 0;
-
- /**
- * Map from file path to associated tree node.
- */
- this.nodeMap_ = {};
-}
-
-
-/**
- * Calculates the dimensions of the tree.
- */
-FileTreeBase.prototype.calculateDimensions_ = function(container) {
- var containerElm = document.getElementById(container);
- if (!containerElm) {
- return null;
- }
-
- var cw = containerElm ? containerElm.clientWidth : 1200;
- var barHeight = 20;
- var ch = (this.getNodesHeight() * barHeight) + 40;
-
- var margin = { top: 40, right: 00, bottom: 20, left: 20 };
- var m = [margin.top, margin.right, margin.bottom, margin.left];
- var w = Math.max(0, cw - m[1] - m[3]);
- var h = Math.max(0, ch - m[0] - m[2]);
-
- var barWidth = Math.max(0, cw * 0.8 - m[1] - m[3]);
-
- return {
- 'w': w,
- 'h': h,
- 'm': m,
- 'cw': cw,
- 'ch': ch,
- 'bw': barWidth,
- 'bh': barHeight
- };
-};
-
-
-/**
- * Updates the dimensions of the tree.
- */
-FileTreeBase.prototype.updateDimensions_ = function() {
- if (!this.rootSvg_) { return; }
-
- var container = this.container_;
- var dimensions = this.calculateDimensions_(container);
- if (!dimensions) { return; }
-
- var w = dimensions.w;
- var h = dimensions.h;
- var m = dimensions.m;
-
- // Update the tree.
- var rootSvg = this.rootSvg_;
- var tree = this.tree_;
- var vis = this.vis_;
-
- rootSvg
- .attr("width", w + m[1] + m[3])
- .attr("height", h + m[0] + m[2]);
-
- tree.size([h, 100]);
- vis.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
-
- this.barWidth_ = dimensions.bw;
- this.barHeight_ = dimensions.bh;
-
- return dimensions;
-};
-
-
-/**
- * Redraws the image change tree to fit the new size.
- */
-FileTreeBase.prototype.notifyResized = function() {
- this.updateDimensions_();
- this.update_(this.root_);
-};
-
-
-/**
- * Disposes of the tree.
- */
-FileTreeBase.prototype.dispose = function() {
- var container = this.container_ ;
- document.getElementById(container).innerHTML = '';
-};
-
-
-/**
- * Draws the tree.
- */
-FileTreeBase.prototype.draw = function(container) {
- this.container_ = container;
-
- var dimensions = this.calculateDimensions_(container);
- if (!dimensions) { return; }
-
- var w = dimensions.w;
- var h = dimensions.h;
- var m = dimensions.m;
-
- this.barWidth_ = dimensions.bw;
- this.barHeight_ = dimensions.bh;
-
- var tree = d3.layout.tree()
- .size([h, 100]);
-
- var diagonal = d3.svg.diagonal()
- .projection(function(d) { return [d.y, d.x]; });
-
- var rootSvg = d3.select("#" + container).append("svg:svg")
- .attr('class', 'file-tree-base')
- .attr("width", w)
- .attr("height", h);
-
- var vis = rootSvg
- .append("svg:g")
- .attr("transform", "translate(" + m[3] + "," + m[0] + ")");
-
- this.rootSvg_ = rootSvg;
- this.tree_ = tree;
- this.diagonal_ = diagonal;
- this.vis_ = vis;
-
- this.populateAndDraw_();
-};
-
-
-/**
- * Populates the tree and then draws it.
- */
-FileTreeBase.prototype.populateAndDraw_ = function() {
- // Build all the nodes for the file tree.
- this.buildAllNodes();
-
- // Sort the children of each node so that folders are on top.
- var sortByName = function (a, b) {
- if (a.name > b.name) {
- return 1;
- }
- if (a.name < b.name) {
- return -1;
- }
- return 0;
- };
-
- var sortFunction = function(a, b) {
- var hasA = a._children.length > 0;
- var hasB = b._children.length > 0;
- if (hasA == hasB) {
- // Sort alphabetically.
- return sortByName(a, b);
- }
- if (hasA) { return -1; }
- return 1;
- };
-
- for (var path in this.nodeMap_) {
- if (!this.nodeMap_.hasOwnProperty(path) || !this.nodeMap_[path]._children) {
- continue;
- }
-
- this.nodeMap_[path]._children.sort(sortFunction);
- }
-
- this.root_ = this.nodeMap_[''];
- if (this.root_) {
- this.root_.x0 = 0;
- this.root_.y0 = 0;
- }
-
- this.toggle_(this.root_);
- this.update_(this.root_);
-};
-
-
-/**
- * Builds all the nodes in the tree.
- */
-FileTreeBase.prototype.buildNodes_ = function(path) {
- var parts = path.split('/');
- for (var i = 0; i < parts.length; ++i) {
- var currentPath = parts.slice(0, i + 1).join('/');
- if (!this.nodeMap_[currentPath]) {
- this.nodeMap_[currentPath] = { 'name': parts[i] || '/', 'path': currentPath, '_children': [] };
-
- if (currentPath.length > 0) {
- var parentPath = parts.slice(0, i).join('/');
- var parent = this.buildNodes_(parentPath);
- parent._children.push(this.nodeMap_[currentPath]);
- }
- }
- }
- return this.nodeMap_[path];
-};
-
-
-/**
- * Calculates the count of visible nodes.
- */
-FileTreeBase.prototype.getVisibleCount_ = function(node) {
- if (node.children) {
- var count = 1;
- for (var i = 0; i < node.children.length; ++i) {
- count += this.getVisibleCount_(node.children[i]);
- }
- return count;
- }
- return 1;
-};
-
-
-/**
- * Calculates the height for the container.
- */
-FileTreeBase.prototype.getContainerHeight_ = function() {
- var dimensions = this.calculateDimensions_(this.container_);
- if (!dimensions) { return; }
-
- var barHeight = this.barHeight_;
- var height = (this.getVisibleCount_(this.root_) * (barHeight + 2));
- return height + dimensions.m[0] + dimensions.m[2];
-};
-
-
-/**
- * Updates the tree starting at the given source node.
- */
-FileTreeBase.prototype.update_ = function(source) {
- var that = this;
- var tree = this.tree_;
- var vis = this.vis_;
- var svg = this.rootSvg_;
- var diagonal = this.diagonal_;
- var barWidth = this.barWidth_;
- var barHeight = this.barHeight_;
-
- var duration = 400;
-
- var color = function(d) {
- if (d.kind) {
- return '';
- }
- return d._children ? "#E9E9E9" : "#c6dbef";
- };
-
- // Update the height of the container and the SVG.
- var containerElm = document.getElementById(this.container_);
- if (!containerElm) {
- return;
- }
-
- containerElm.style.height = this.getContainerHeight_() + 'px';
- svg.attr('height', this.getContainerHeight_());
-
- // Compute the flattened node list.
- var nodes = tree.nodes(this.root_);
-
- // Compute the "layout".
- nodes.forEach(function(n, i) {
- n.x = i * barHeight;
- });
-
- // Update the nodes...
- var node = vis.selectAll("g.node")
- .data(nodes, function(d) { return d.id || (d.id = that.idCounter_++); });
-
- var nodeEnter = node.enter().append("svg:g")
- .attr("class", function(d) {
- return "node " + (d.kind ? d.kind : 'folder');
- })
- .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
- .style("opacity", 1e-6);
-
- // Enter any new nodes at the parent's previous position.
- nodeEnter.append("svg:rect")
- .attr("class", "main-rect")
- .attr("y", -barHeight / 2)
- .attr("height", barHeight)
- .attr("width", barWidth)
- .style("fill", color)
- .on("click", function(d) {
- if (d.kind) {
- $(that).trigger({
- 'type': 'fileClicked',
- 'path': d.path
- });
- return;
- }
- that.toggle_(d);
- that.update_(source);
- });
-
- nodeEnter.append("svg:text")
- .attr("dy", 3.5)
- .attr("dx", 5.5 + 18)
- .text(function(d) { return d.name; });
-
- var body = nodeEnter.append('svg:foreignObject')
- .attr("class", "fo")
- .attr("width", 18)
- .attr("height", barHeight)
- .append('xhtml:body');
-
- body.append('div')
- .attr('class', 'node-icon');
-
- // Transition nodes to their new position.
- nodeEnter.transition()
- .duration(duration)
- .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
- .style("opacity", 1);
-
- node.transition()
- .duration(duration)
- // TODO: reenable for full animation
- //.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
- .style("opacity", 1)
- .select("rect")
- .style("fill", color);
-
- // TODO: remove if full animation.
- node.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
-
- node.select('.main-rect')
- .attr("y", -barHeight / 2)
- .attr("height", barHeight)
- .attr("width", barWidth);
-
- node.select('.fo')
- .attr("x", function(d) { return d.kind ? barWidth - 18 : 0; })
- .attr("y", -10)
-
- node.select('.node-icon')
- .html(function(d) {
- if (!d.kind) {
- var folder = d._children ? 'fa fa-folder' : 'fa fa-folder-open';
- return '';
- }
-
- return that.determineIcon(d);
- });
-
- // Transition exiting nodes to the parent's new position.
- node.exit().transition()
- .duration(duration)
- // TODO: reenable for full animation
- // .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
- .style("opacity", 1e-6)
- .remove();
-
- // Update the links...
- var link = vis.selectAll("path.link")
- .data(tree.links(nodes), function(d) { return d.target.id; });
-
- // Enter any new links at the parent's previous position.
- link.enter().insert("svg:path", "g")
- .attr("class", "link")
- .attr("d", function(d) {
- var o = {x: source.x0, y: source.y0};
- return diagonal({source: o, target: o});
- })
- .transition()
- .duration(duration)
- .attr("d", diagonal);
-
- // Transition links to their new position.
- link.transition()
- .duration(duration)
- .attr("d", function(d) {
- var s = {x: d.source.x + 14, y: d.source.y + 9};
- var t = d.target;
- return diagonal({source: s, target: t});
- });
-
- // Transition exiting nodes to the parent's new position.
- link.exit().transition()
- .duration(duration)
- .attr("d", function(d) {
- var o = {x: source.x, y: source.y};
- return diagonal({source: o, target: o});
- })
- .remove();
-
- // Stash the old positions for transition.
- nodes.forEach(function(d) {
- d.x0 = d.x;
- d.y0 = d.y;
- });
-};
-
-/**
- * Toggles children of a node.
- */
-FileTreeBase.prototype.toggle_ = function(d) {
- if (d.children) {
- d._children = d.children;
- d.children = null;
- } else {
- d.children = d._children;
- d._children = null;
- }
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-function ImageFileChangeTree(image, changes) {
- FileTreeBase.apply(this);
-
- /**
- * The parent image.
- */
- this.image_ = image;
-
- /**
- * The changes being drawn.
- */
- this.changes_ = changes;
-}
-
-$.extend(ImageFileChangeTree.prototype, FileTreeBase.prototype);
-
-/**
- * Builds all the file nodes from the changes.
- */
-ImageFileChangeTree.prototype.buildAllNodes = function() {
- for (var i = 0; i < this.changes_.length; ++i) {
- var filepath = this.changes_[i].file;
- var node = this.buildNodes_(filepath);
- node.kind = this.changes_[i].kind;
- }
-};
-
-
-/**
- * Determines the icon for a node.
- */
-ImageFileChangeTree.prototype.determineIcon = function(d) {
- var icon = {
- 'added': 'plus-square',
- 'removed': 'minus-square',
- 'changed': 'pencil-square'
- };
-
- return '';
-};
-
-
-/**
- * Returns the max height of the tree.
- */
-ImageFileChangeTree.prototype.getNodesHeight = function() {
- return this.changes_.length;
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-function FileTree(files) {
- FileTreeBase.apply(this);
-
- /**
- * The set of file paths found in the tree.
- */
- this.files_ = files;
-}
-
-$.extend(FileTree.prototype, FileTreeBase.prototype);
-
-
-/**
- * Builds all the file nodes from the paths.
- */
-FileTree.prototype.buildAllNodes = function() {
- for (var i = 0; i < this.files_.length; ++i) {
- var filepath = this.files_[i];
- if (filepath[filepath.length - 1] == '/') { continue; }
- var node = this.buildNodes_(filepath);
- node.kind = 'file';
- }
-};
-
-
-/**
- * Determines the icon for a node.
- */
-FileTree.prototype.determineIcon = function(d) {
- return '';
-};
-
-
-/**
- * Returns the max height of the tree.
- */
-FileTree.prototype.getNodesHeight = function() {
- return this.files_.length;
-};
-
-
////////////////////////////////////////////////////////////////////////////////
/**