From 25db46c34122a78f790815bd6b672dd821039fc1 Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Fri, 3 Mar 2017 18:41:26 -0500 Subject: [PATCH] Redo UI of the tag history timeline and add restoration --- static/css/directives/ui/image-link.css | 2 +- static/css/directives/ui/repo-tag-history.css | 125 +++++++++++--- static/directives/repo-tag-history.html | 155 ++++++++++++------ static/directives/tag-operations-dialog.html | 18 +- static/js/directives/ui/logs-view.js | 10 +- static/js/directives/ui/repo-tag-history.js | 16 +- .../js/directives/ui/tag-operations-dialog.js | 19 ++- static/partials/repo-view.html | 1 + 8 files changed, 256 insertions(+), 90 deletions(-) diff --git a/static/css/directives/ui/image-link.css b/static/css/directives/ui/image-link.css index 3b08a1a86..9e9b38913 100644 --- a/static/css/directives/ui/image-link.css +++ b/static/css/directives/ui/image-link.css @@ -1,7 +1,7 @@ .image-link { display: inline-block; white-space: nowrap; - width: 130px; + width: 120px; } .image-link a { diff --git a/static/css/directives/ui/repo-tag-history.css b/static/css/directives/ui/repo-tag-history.css index 5312c46f4..3388a4e3a 100644 --- a/static/css/directives/ui/repo-tag-history.css +++ b/static/css/directives/ui/repo-tag-history.css @@ -1,7 +1,73 @@ .repo-tag-history-element .history-list { margin: 10px; - border-left: 2px solid #eee; - margin-right: 150px; +} + +.repo-tag-history-element .co-table thead { + margin-bottom: 20px; +} + +.repo-tag-history-element .co-table tbody td { + border-bottom: 0px; +} + +.repo-tag-history-element .co-table td.revert-col { + font-size: 12px; +} + +.repo-tag-history-element .co-table td.revert-col .tag-span { + padding-left: 4px; + padding-right: 4px; +} + +.repo-tag-history-element .co-table td.icon-col { + border-bottom: 0px; + width: 32px; + height: 32px; + text-align: center; + line-height: 32px; + vertical-align: middle; + padding: 0px; + position: relative; +} + +.repo-tag-history-element .co-table td.history-col { + width: 520px; +} + +.repo-tag-history-element .co-table td.datetime-col { + width: 250px; +} + +.repo-tag-history-element .co-table td.icon-col:after { + content: " "; + display: inline-block; + position: absolute; + top: 0px; + bottom: 0px; + left: 15px; + width: 2px; + background-color: #ddd; + z-index: 1; +} + +.repo-tag-history-element .co-table td.icon-col .history-icon { + position: absolute; + top: 7px; + left: 0px; + z-index: 2; +} + +.repo-tag-history-element .co-table td.icon-col .datetime-icon { + position: absolute; + top: 13px; + left: 9px; + z-index: 2; + background-color: white; +} + +.repo-tag-history-element .history-row { + font-size: 13px; + color: #aaa; } .repo-tag-history-element .history-entry { @@ -12,10 +78,12 @@ transition: all 350ms ease-in-out; } -.repo-tag-history-element .history-entry .history-text { - transition: transform 350ms ease-in-out, opacity 350ms ease-in-out; +.repo-tag-history-element .history-entry .history-description, +.repo-tag-history-element .history-entry .history-datetime, +.repo-tag-history-element .history-entry .history-revert { + transition: height 350ms ease-in-out, opacity 350ms ease-in-out; overflow: hidden; - height: 40px; + height: 24px; } .repo-tag-history-element .co-filter-box { @@ -42,7 +110,17 @@ margin-top: 10px; } -.repo-tag-history-element .history-entry.filtered-mismatch .history-text { +.repo-tag-history-element .history-entry.filtered-mismatch .history-datetime { + height: 18px; + opacity: 0; +} + +.repo-tag-history-element .history-entry.filtered-mismatch .history-revert { + height: 18px; + opacity: 0; +} + +.repo-tag-history-element .history-entry.filtered-mismatch .history-description { height: 18px; opacity: 0; } @@ -64,19 +142,12 @@ content: "\f073"; font-family: FontAwesome; - position: absolute; width: 12px; height: 12px; - top: 1px; - left: -9px; background: white; } .repo-tag-history-element .history-entry .history-icon { - position: absolute; - left: -17px; - top: -4px; - border-radius: 50%; width: 32px; height: 32px; @@ -100,6 +171,11 @@ font-family: FontAwesome; } +.repo-tag-history-element .history-entry.recreate .history-icon:before { + content: "\f10d"; + font-family: core-icons; +} + .repo-tag-history-element .history-entry.revert .history-icon:before { content: "\f0e2"; font-family: FontAwesome; @@ -122,6 +198,10 @@ background-color: #98df8a; } +.repo-tag-history-element .history-entry.current.recreate .history-icon { + background-color: #ba8adf; +} + .repo-tag-history-element .history-entry.current.delete .history-icon { background-color: #ff9896; } @@ -135,21 +215,23 @@ border-radius: 4px; padding: 2px; background: #eee; + padding-left: 6px; padding-right: 6px; color: black; + cursor: default; +} + + +.repo-tag-history-element .history-entry .tag-span span { + max-width: 150px; + overflow: hidden; + text-overflow: ellipsis; } .repo-tag-history-element .history-entry .tag-span.checked { background: #F6FCFF; } -.repo-tag-history-element .history-entry .tag-span:before { - content: "\f02b"; - font-family: FontAwesome; - margin-left: 4px; - margin-right: 4px; -} - .repo-tag-history-element .history-entry .image-link { margin-left: 6px; } @@ -159,6 +241,5 @@ } .repo-tag-history-element .history-entry .history-datetime { - font-size: 12px; - color: #ccc; + font-size: 14px; } \ No newline at end of file diff --git a/static/directives/repo-tag-history.html b/static/directives/repo-tag-history.html index 5c03cfc4a..5a00b55f4 100644 --- a/static/directives/repo-tag-history.html +++ b/static/directives/repo-tag-history.html @@ -11,54 +11,115 @@
There has not been any recent tag activity on this repository.
-
-
- {{ entry.date | amDateFormat:'dddd, MMMM Do YYYY' }} -
-
-
-
-
-
-
- {{ entry.tag_name }} - - - was created pointing to - + + + + + + + + + + + + + + + + + + + + +
Tag ChangeDate/TimeRestore
+ + + {{ entry.date | amDateFormat:'dddd, MMMM Do YYYY' }} + +
+
+
+ {{ entry.tag_name }} + + + was recreated pointing to + + + + was created pointing to + + + + was deleted + + + was moved to + + from + + + + was reverted to + + from + + - - was deleted +
+
+
{{ entry.time | amDateFormat:'dddd, MMMM Do YYYY, h:mm:ss a' }}
+
+ -
{{ entry.time | amDateFormat:'dddd, MMMM Do YYYY, h:mm:ss a' }}
- - - + +
+ +
+
diff --git a/static/directives/tag-operations-dialog.html b/static/directives/tag-operations-dialog.html index f71f92c6e..103bb23d4 100644 --- a/static/directives/tag-operations-dialog.html +++ b/static/directives/tag-operations-dialog.html @@ -106,19 +106,21 @@
- +
+ dialog-context="restoreTagInfo" + dialog-action="restoreTag(info.tag, info.image_id, info.manifest_digest, callback)" + dialog-title="Restore Tag" + dialog-action-title="Restore Tag">
This will change the image to which the tag points.
- Are you sure you want to revert tag - {{ revertTagInfo.tag.name }} to image - {{ revertTagInfo.image_id.substr(0, 12) }}? + Are you sure you want to restore tag + {{ restoreTagInfo.tag.name }} to image + ?
diff --git a/static/js/directives/ui/logs-view.js b/static/js/directives/ui/logs-view.js index c9bbb713e..7bdf43b97 100644 --- a/static/js/directives/ui/logs-view.js +++ b/static/js/directives/ui/logs-view.js @@ -125,7 +125,13 @@ angular.module('quay').directive('logsView', function () { return 'Remove permission for token {token} from repository {namespace}/{repo}'; } }, - 'revert_tag': 'Tag {tag} reverted to image {image} from image {original_image}', + 'revert_tag': function(metadata) { + if (metadata.original_image) { + return 'Tag {tag} restored to image {image} from image {original_image}'; + } else { + return 'Tag {tag} recreated pointing to image {image}'; + } + }, 'delete_tag': 'Tag {tag} deleted in repository {namespace}/{repo} by user {username}', 'create_tag': 'Tag {tag} created in repository {namespace}/{repo} on image {image} by user {username}', 'move_tag': 'Tag {tag} moved from image {original_image} to image {image} in repository {namespace}/{repo} by user {username}', @@ -266,7 +272,7 @@ angular.module('quay').directive('logsView', function () { 'delete_tag': 'Delete Tag', 'create_tag': 'Create Tag', 'move_tag': 'Move Tag', - 'revert_tag':' Revert Tag', + 'revert_tag':'Restore Tag', 'org_create_team': 'Create team', 'org_delete_team': 'Delete team', 'org_add_team_member': 'Add team member', diff --git a/static/js/directives/ui/repo-tag-history.js b/static/js/directives/ui/repo-tag-history.js index 295b6d265..e5bfc8895 100644 --- a/static/js/directives/ui/repo-tag-history.js +++ b/static/js/directives/ui/repo-tag-history.js @@ -11,7 +11,8 @@ angular.module('quay').directive('repoTagHistory', function () { scope: { 'repository': '=repository', 'filter': '=filter', - 'isEnabled': '=isEnabled' + 'isEnabled': '=isEnabled', + 'imageLoader': '=imageLoader' }, controller: function($scope, $element, ApiService) { $scope.tagHistoryData = null; @@ -57,6 +58,7 @@ angular.module('quay').directive('repoTagHistory', function () { var addEntry = function(action, time, opt_docker_id, opt_old_docker_id, opt_manifest_digest, opt_old_manifest_digest) { var entry = { + 'tag': tag, 'tag_name': tagName, 'action': action, 'start_ts': tag.start_ts, @@ -66,7 +68,7 @@ angular.module('quay').directive('repoTagHistory', function () { 'docker_image_id': opt_docker_id || dockerImageId, 'old_docker_image_id': opt_old_docker_id || '', 'manifest_digest': opt_manifest_digest || manifestDigest, - 'old_manifest_digest': opt_old_manifest_digest || '' + 'old_manifest_digest': opt_old_manifest_digest || null }; tagEntries[tagName].push(entry); @@ -92,7 +94,7 @@ angular.module('quay').directive('repoTagHistory', function () { // If the tag has a start time, it was created. if (tag.start_ts) { - addEntry('create', tag.start_ts); + addEntry(tag.reversion ? 'recreate' : 'create', tag.start_ts); } }); @@ -139,6 +141,14 @@ angular.module('quay').directive('repoTagHistory', function () { return $scope.historyEntryMap[entry.tag_name][0] == entry; }; + $scope.askRestoreTag = function(entity, use_current_id) { + if ($scope.repository.can_write) { + var docker_id = use_current_id ? entity.docker_image_id : entity.old_docker_image_id; + var digest = use_current_id ? entity.manifest_digest : entity.old_manifest_digest; + $scope.tagActionHandler.askRestoreTag(entity.tag, docker_id, digest); + } + }; + $scope.getEntryClasses = function(entry, historyFilter) { if (!entry.action) { return ''; } diff --git a/static/js/directives/ui/tag-operations-dialog.js b/static/js/directives/ui/tag-operations-dialog.js index d2081c3e6..648ee0f10 100644 --- a/static/js/directives/ui/tag-operations-dialog.js +++ b/static/js/directives/ui/tag-operations-dialog.js @@ -115,7 +115,7 @@ angular.module('quay').directive('tagOperationsDialog', function () { }, errorHandler); }; - $scope.revertTag = function(tag, image_id, callback) { + $scope.restoreTag = function(tag, image_id, opt_manifest_digest, callback) { if (!$scope.repository.can_write) { return; } var params = { @@ -127,8 +127,12 @@ angular.module('quay').directive('tagOperationsDialog', function () { 'image': image_id }; - var errorHandler = ApiService.errorDisplay('Cannot revert tag', callback); - ApiService.revertTag(data, params).then(function() { + if (opt_manifest_digest) { + data['manifest_digest'] = opt_manifest_digest; + } + + var errorHandler = ApiService.errorDisplay('Cannot restore tag', callback); + ApiService.restoreTag(data, params).then(function() { callback(true); markChanged([], [tag]); }, errorHandler); @@ -155,18 +159,19 @@ angular.module('quay').directive('tagOperationsDialog', function () { $element.find('#createOrMoveTagModal').modal('show'); }, - 'askRevertTag': function(tag, image_id) { + 'askRestoreTag': function(tag, image_id, opt_manifest_digest) { if (tag.image_id == image_id) { bootbox.alert('This is the current image for the tag'); return; } - $scope.revertTagInfo = { + $scope.restoreTagInfo = { 'tag': tag, - 'image_id': image_id + 'image_id': image_id, + 'manifest_digest': opt_manifest_digest }; - $element.find('#revertTagModal').modal('show'); + $element.find('#restoreTagModal').modal('show'); } }; } diff --git a/static/partials/repo-view.html b/static/partials/repo-view.html index 1d889cad3..f2e58e783 100644 --- a/static/partials/repo-view.html +++ b/static/partials/repo-view.html @@ -95,6 +95,7 @@