Switch to a new single-selected-context layout and system in the view repository screen. Now selecting tags or images changes the context

This commit is contained in:
Joseph Schorr 2014-01-09 18:54:59 -05:00
parent b584d74bf0
commit 7337adf498
4 changed files with 193 additions and 68 deletions

View file

@ -151,7 +151,13 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
// Watch for changes to the tag parameter.
$scope.$on('$routeUpdate', function(){
$scope.setTag($location.search().tag, false);
if ($location.search().tag) {
$scope.setTag($location.search().tag, false);
} else if ($location.search().image) {
$scope.setImage($location.search().image, false);
} else {
$scope.setTag($location.search().tag, false);
}
});
// Start scope methods //////////////////////////////////////////
@ -186,11 +192,28 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
addedDisplayed - removedDisplayed - changedDisplayed;
};
$scope.setImage = function(image) {
$scope.setImage = function(imageId, opt_updateURL) {
var image = null;
for (var i = 0; i < $scope.images.length; ++i) {
var currentImage = $scope.images[i];
if (currentImage.id == imageId || currentImage.id.substr(0, 12) == imageId) {
image = currentImage;
break;
}
}
if (!image) { return; }
$scope.currentTag = null;
$scope.currentImage = image;
$scope.loadImageChanges(image);
if ($scope.tree) {
$scope.tree.setImage($scope.currentImage.id);
$scope.tree.setImage(image.id);
}
if (opt_updateURL) {
$location.search('tag', null);
$location.search('image', imageId.substr(0, 12));
}
};
@ -205,20 +228,13 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
}
var getIdsForTag = function(currentTag) {
var ancestors = currentTag.image.ancestors.split('/');
var dbid = currentTag.image.dbid;
var ids = {};
ids[dbid] = true;
for (var i = 0; i < ancestors.length; ++i) {
if (ancestors[i]) {
ids[ancestors[i]] = true;
}
}
forAllTagImages(currentTag, function(image) {
ids[image.dbid] = true;
});
return ids;
};
// Remove any IDs that match other tags.
var toDelete = getIdsForTag(tag);
for (var currentTagName in $scope.repo.tags) {
@ -252,7 +268,6 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
return images;
};
$scope.askDeleteTag = function(tagName) {
if (!$scope.repo.can_admin) { return; }
@ -285,6 +300,27 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
});
};
$scope.getImagesForTagBySize = function(tag) {
var images = [];
forAllTagImages(tag, function(image) {
images.push(image);
});
images.sort(function(a, b) {
return b.size - a.size;
});
return images;
};
$scope.getTotalSize = function(tag) {
var size = 0;
forAllTagImages(tag, function(image) {
size += image.size;
});
return size;
};
$scope.setTag = function(tagName, opt_updateURL) {
var repo = $scope.repo;
var proposedTag = repo.tags[tagName];
@ -306,6 +342,7 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
}
if (opt_updateURL) {
$location.search('image', null);
$location.search('tag', $scope.currentTag.name);
}
}
@ -387,6 +424,20 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
}
};
var forAllTagImages = function(tag, callback) {
if (!tag || !$scope.imageByDBID) { return; }
callback(tag.image);
var ancestors = tag.image.ancestors.split('/');
for (var i = 0; i < ancestors.length; ++i) {
var image = $scope.imageByDBID[ancestors[i]];
if (image) {
callback(image);
}
}
};
var fetchRepository = function() {
var params = {'repository': namespace + '/' + name};
$rootScope.title = 'Loading Repository...';
@ -467,6 +518,13 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
$scope.images = resp.images;
$scope.specificImages = [];
// Build various images for quick lookup of images.
$scope.imageByDBID = {};
for (var i = 0; i < $scope.images.length; ++i) {
var currentImage = $scope.images[i];
$scope.imageByDBID[currentImage.dbid] = currentImage;
}
// Dispose of any existing tree.
if ($scope.tree) {
$scope.tree.dispose();
@ -489,7 +547,7 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
});
$($scope.tree).bind('imageChanged', function(e) {
$scope.$apply(function() { $scope.setImage(e.image); });
$scope.$apply(function() { $scope.setImage(e.image.id, true); });
});
$($scope.tree).bind('showTagMenu', function(e) {
@ -500,6 +558,10 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
$scope.$apply(function() { $scope.hideTagMenu(); });
});
if ($routeParams.image) {
$scope.setImage($routeParams.image);
}
return resp.images;
});
};
@ -936,7 +998,7 @@ function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService) {
}, 10);
};
var fetchImage = function() {
var fetchImages = function() {
var params = {
'repository': namespace + '/' + name,
'image_id': imageid

View file

@ -40,6 +40,11 @@ function ImageHistoryTree(namespace, name, images, formatComment, formatTime) {
*/
this.currentImage_ = null;
/**
* The currently highlighted node (if any).
*/
this.currentNode_ = null;
/**
* Counter for creating unique IDs.
*/
@ -231,6 +236,23 @@ ImageHistoryTree.prototype.setImage = function(imageId) {
};
/**
* Updates the highlighted path in the tree.
*/
ImageHistoryTree.prototype.setHighlightedPath_ = function(image) {
if (this.currentNode_) {
this.markPath_(this.currentNode_, false);
}
var imageByDBID = this.imageByDBID_;
var currentNode = imageByDBID[image.dbid];
if (currentNode) {
this.markPath_(currentNode, true);
this.currentNode_ = currentNode;
}
};
/**
* Returns the ancestors of the given image.
*/
@ -468,26 +490,15 @@ ImageHistoryTree.prototype.setTag_ = function(tagName) {
// Save the current tag.
var previousTagName = this.currentTag_;
this.currentTag_ = tagName;
this.currentImage_ = null;
// Update the state of each existing node to no longer be highlighted.
var previousImage = this.findImage_(function(image) {
return image.tags.indexOf(previousTagName || '(no tag specified)') >= 0;
});
if (previousImage) {
var currentNode = imageByDBID[previousImage.dbid];
this.markPath_(currentNode, false);
}
// Find the new current image (if any).
this.currentImage_ = this.findImage_(function(image) {
// Update the path.
var tagImage = this.findImage_(function(image) {
return image.tags.indexOf(tagName || '(no tag specified)') >= 0;
});
// Update the state of the new node path.
if (this.currentImage_) {
var currentNode = imageByDBID[this.currentImage_.dbid];
this.markPath_(currentNode, true);
if (tagImage) {
this.setHighlightedPath_(tagImage);
}
// Ensure that the children are in the correct order.
@ -531,7 +542,9 @@ ImageHistoryTree.prototype.setImage_ = function(imageId) {
return;
}
this.setHighlightedPath_(newImage);
this.currentImage_ = newImage;
this.currentTag_ = null;
this.update_(this.root_);
};