diff --git a/static/css/quay.css b/static/css/quay.css
index 47cb4b372..ff86a9c68 100644
--- a/static/css/quay.css
+++ b/static/css/quay.css
@@ -1210,6 +1210,61 @@ p.editable:hover i {
border: 0px;
}
+#confirmdeleteTagModal .image-listings {
+ margin: 10px;
+}
+
+#confirmdeleteTagModal .image-listings .image-listing {
+ margin: 4px;
+ padding: 2px;
+ position: relative;
+}
+
+#confirmdeleteTagModal .image-listings .image-listing .image-listing-id {
+ display: inline-block;
+ margin-left: 20px;
+}
+
+#confirmdeleteTagModal .image-listings .image-listing .image-listing-line {
+ border-left: 2px solid steelblue;
+ display: inline-block;
+ position: absolute;
+ top: -2px;
+ bottom: 8px;
+ left: 6px;
+ width: 1px;
+ z-index: 1;
+}
+
+#confirmdeleteTagModal .image-listings .image-listing.tag-image .image-listing-line {
+ top: 8px;
+}
+
+#confirmdeleteTagModal .image-listings .image-listing.child .image-listing-line {
+ bottom: -2px;
+}
+
+#confirmdeleteTagModal .image-listings .image-listing .image-listing-circle {
+ position: absolute;
+ top: 8px;
+
+ border-radius: 50%;
+ border: 2px solid steelblue;
+ width: 10px;
+ height: 10px;
+ display: inline-block;
+ background: white;
+ z-index: 2;
+}
+
+#confirmdeleteTagModal .image-listings .image-listing.tag-image .image-listing-circle {
+ background: steelblue;
+}
+
+#confirmdeleteTagModal .more-changes {
+ margin-left: 16px;
+}
+
.repo .header {
margin-bottom: 10px;
position: relative;
diff --git a/static/js/controllers.js b/static/js/controllers.js
index 800d25232..b4433590f 100644
--- a/static/js/controllers.js
+++ b/static/js/controllers.js
@@ -194,6 +194,60 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
}
};
+ $scope.tagSpecificImages = function(tagName) {
+ if (!tagName) { return []; }
+
+ var tag = $scope.repo.tags[tagName];
+ if (!tag) { return []; }
+
+ if ($scope.specificImages && $scope.specificImages[tagName]) {
+ return $scope.specificImages[tagName];
+ }
+
+ 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;
+ }
+ }
+ return ids;
+ };
+
+
+ // Remove any IDs that match other tags.
+ var toDelete = getIdsForTag(tag);
+ for (var currentTagName in $scope.repo.tags) {
+ var currentTag = $scope.repo.tags[currentTagName];
+ if (currentTag != tag) {
+ for (var dbid in getIdsForTag(currentTag)) {
+ delete toDelete[dbid];
+ }
+ }
+ }
+
+ // Return the matching list of images.
+ var images = [];
+ for (var i = 0; i < $scope.images.length; ++i) {
+ var image = $scope.images[i];
+ if (toDelete[image.dbid]) {
+ images.push(image);
+ }
+ }
+
+ images.sort(function(a, b) {
+ return b.dbid - a.dbid;
+ });
+
+ $scope.specificImages[tagName] = images;
+ return images;
+ };
+
+
$scope.askDeleteTag = function(tagName) {
if (!$scope.repo.can_admin) { return; }
@@ -257,6 +311,22 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
}
};
+ $scope.getFirstTextLine = getFirstTextLine;
+
+ $scope.getImageListingClasses = function(image, tagName) {
+ var classes = '';
+ if (image.ancestors.length > 1) {
+ classes += 'child ';
+ }
+
+ var currentTag = $scope.repo.tags[tagName];
+ if (image.dbid == currentTag.image.dbid) {
+ classes += 'tag-image ';
+ }
+
+ return classes;
+ };
+
$scope.getTagCount = function(repo) {
if (!repo) { return 0; }
var count = 0;
@@ -389,6 +459,9 @@ function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $lo
var listImages = function() {
var params = {'repository': namespace + '/' + name};
$scope.imageHistory = ApiService.listRepositoryImagesAsResource(params).get(function(resp) {
+ $scope.images = resp.images;
+ $scope.specificImages = [];
+
// Dispose of any existing tree.
if ($scope.tree) {
$scope.tree.dispose();
diff --git a/static/partials/view-repo.html b/static/partials/view-repo.html
index 7166cdefc..b28e9e266 100644
--- a/static/partials/view-repo.html
+++ b/static/partials/view-repo.html
@@ -213,8 +213,23 @@ sudo docker push quay.io/{{repo.namespace}}/{{repo.name}}
{{ tagToDelete }}
?
-
- Doing so will delete any images not attached to another tag.
+