Add ability to tag images from the UI, including moving existing tags to different images
This commit is contained in:
parent
9371c70941
commit
20ad666308
11 changed files with 581 additions and 200 deletions
|
@ -111,9 +111,13 @@ sudo docker push quay.io/{{repo.namespace}}/{{repo.name}}</pre>
|
|||
<div class="panel-heading">
|
||||
<!-- Dropdown -->
|
||||
<div id="side-panel-dropdown" class="tag-dropdown dropdown" data-placement="top">
|
||||
<i class="fa fa-tag" ng-show="currentTag"></i>
|
||||
<i class="fa fa-archive" ng-show="!currentTag"></i>
|
||||
<a href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown">{{currentTag ? currentTag.name : currentImage.id.substr(0, 12)}} <b class="caret"></b></a>
|
||||
<i class="fa fa-tag current-context-icon" ng-show="currentTag"></i>
|
||||
<i class="fa fa-archive current-context-icon" ng-show="!currentTag"></i>
|
||||
<a href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="current-context">
|
||||
{{currentTag ? currentTag.name : currentImage.id.substr(0, 12)}}
|
||||
</span>
|
||||
<b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="tag in repo.tags">
|
||||
<a href="javascript:void(0)" ng-click="setTag(tag.name, true)">
|
||||
|
@ -170,72 +174,116 @@ sudo docker push quay.io/{{repo.namespace}}/{{repo.name}}</pre>
|
|||
|
||||
<!-- Current Image -->
|
||||
<div id="current-image" ng-show="currentImage && !currentTag">
|
||||
<div ng-show="currentImage.comment">
|
||||
<div class="image-comment" ng-if="currentImage.comment">
|
||||
<blockquote style="margin-top: 10px;">
|
||||
<span class="markdown-view" content="currentImage.comment"></span>
|
||||
</blockquote>
|
||||
</div>
|
||||
|
||||
<dl class="dl-normal">
|
||||
<dt>Created</dt>
|
||||
<dd am-time-ago="parseDate(currentImage.created)"></dd>
|
||||
<dt>Image ID</dt>
|
||||
<dd><a href="{{'/repository/' + repo.namespace + '/' + repo.name + '/image/' + currentImage.id}}">{{ currentImage.id }}</a></dd>
|
||||
<dt>Compressed Image Size</dt>
|
||||
<dd><span class="context-tooltip"
|
||||
title="The amount of data sent between Docker and Quay.io when pushing/pulling"
|
||||
bs-tooltip="tooltip.title" data-container="body">{{ currentImage.size | bytes }}</span>
|
||||
</dd>
|
||||
<dt ng-show="currentImage.command && currentImage.command.length">Command</dt>
|
||||
<dd ng-show="currentImage.command && currentImage.command.length" class="codetooltipcontainer">
|
||||
<pre class="formatted-command trimmed"
|
||||
bs-tooltip="getTooltipCommand(currentImage)"
|
||||
data-placement="top">{{ getFormattedCommand(currentImage) }}</pre>
|
||||
</dd>
|
||||
</dl>
|
||||
<div class="image-section">
|
||||
<i class="fa fa-code section-icon" bs-tooltip="tooltip.title" title="Full Image ID"></i>
|
||||
<span class="section-info">
|
||||
<a href="{{'/repository/' + repo.namespace + '/' + repo.name + '/image/' + currentImage.id}}">{{ currentImage.id }}</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="image-section">
|
||||
<i class="fa fa-tag section-icon" bs-tooltip="tooltip.title" title="Current Tags"></i>
|
||||
<span class="section-info section-info-with-dropdown">
|
||||
<a class="label tag label-default" ng-repeat="tag in currentImage.tags"
|
||||
href="/repository/{{ repo.namespace }}/{{ repo.name }}?tag={{ tag }}">
|
||||
{{ tag }}
|
||||
</a>
|
||||
<span style="color: #ccc;" ng-if="!currentImage.tags.length">(No Tags)</span>
|
||||
|
||||
|
||||
<div class="dropdown" data-placement="top" ng-if="repo.can_write || currentImage.tags">
|
||||
<a href="javascript:void(0)" class="dropdown-button" data-toggle="dropdown" bs-tooltip="tooltip.title" title="Manage Tags"
|
||||
data-container="body">
|
||||
<b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu pull-right">
|
||||
<li ng-repeat="tag in currentImage.tags">
|
||||
<a href="javascript:void(0)" ng-click="setTag(tag, true)">
|
||||
<i class="fa fa-tag"></i>{{tag}}
|
||||
</a>
|
||||
</li>
|
||||
<li class="divider" role="presentation" ng-if="repo.can_write && currentImage.tags"></li>
|
||||
<li>
|
||||
<a href="javascript:void(0)" ng-click="showAddTag(currentImage)" ng-if="repo.can_write">
|
||||
<i class="fa fa-plus"></i>Add New Tag
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="image-section" ng-if="currentImage.command && currentImage.command.length">
|
||||
<i class="fa fa-terminal section-icon" bs-tooltip="tooltip.title" title="Image Command"></i>
|
||||
<span class="section-info">
|
||||
<span class="formatted-command trimmed"
|
||||
bs-tooltip="getTooltipCommand(currentImage)"
|
||||
data-placement="top">{{ getFormattedCommand(currentImage) }}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="image-section">
|
||||
<i class="fa fa-calendar section-icon" bs-tooltip="tooltip.title" title="Created"></i>
|
||||
<span class="section-info">
|
||||
<dd am-time-ago="parseDate(currentImage.created)"></dd>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="image-section">
|
||||
<i class="fa fa-cloud-upload section-icon" bs-tooltip="tooltip.title"
|
||||
title="The amount of data sent between Docker and Quay.io when pushing/pulling"></i>
|
||||
<span class="section-info">{{ currentImage.size | bytes }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Image changes loading -->
|
||||
<div class="resource-view" resource="currentImageChangeResource">
|
||||
<div class="changes-container small-changes-container"
|
||||
<div class="changes-container small-changes-container section-info"
|
||||
ng-show="currentImageChanges.changed.length || currentImageChanges.added.length || currentImageChanges.removed.length">
|
||||
<div class="changes-count-container accordion-toggle" data-toggle="collapse" data-parent="#accordion" data-target="#collapseChanges">
|
||||
<span class="change-count added" ng-show="currentImageChanges.added.length > 0" title="Files Added"
|
||||
bs-tooltip="tooltip.title" data-placement="top">
|
||||
<i class="fa fa-plus-square"></i>
|
||||
<b>{{currentImageChanges.added.length}}</b>
|
||||
</span>
|
||||
<span class="change-count removed" ng-show="currentImageChanges.removed.length > 0" title="Files Removed"
|
||||
bs-tooltip="tooltip.title" data-placement="top">
|
||||
<i class="fa fa-minus-square"></i>
|
||||
<b>{{currentImageChanges.removed.length}}</b>
|
||||
</span>
|
||||
<span class="change-count changed" ng-show="currentImageChanges.changed.length > 0" title="Files Changed"
|
||||
bs-tooltip="tooltip.title" data-placement="top">
|
||||
<i class="fa fa-pencil-square"></i>
|
||||
<b>{{currentImageChanges.changed.length}}</b>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div id="collapseChanges" class="panel-collapse collapse in">
|
||||
<div class="well well-sm">
|
||||
<div class="change added" ng-repeat="file in currentImageChanges.added | limitTo:5">
|
||||
<div class="changes-count-container image-section">
|
||||
<i class="fa fa-code-fork section-icon" bs-tooltip="tooltip.title" title="File Changes"></i>
|
||||
<div style="float: right; display: inline-block">
|
||||
<span class="change-count added" ng-show="currentImageChanges.added.length > 0" title="Files Added"
|
||||
bs-tooltip="tooltip.title" data-placement="top" data-container="body">
|
||||
<i class="fa fa-plus-square"></i>
|
||||
<span title="{{file}}">{{file}}</span>
|
||||
</div>
|
||||
<div class="change removed" ng-repeat="file in currentImageChanges.removed | limitTo:5">
|
||||
<b>{{currentImageChanges.added.length}}</b>
|
||||
</span>
|
||||
<span class="change-count removed" ng-show="currentImageChanges.removed.length > 0" title="Files Removed"
|
||||
bs-tooltip="tooltip.title" data-placement="top" data-container="body">
|
||||
<i class="fa fa-minus-square"></i>
|
||||
<span title="{{file}}">{{file}}</span>
|
||||
</div>
|
||||
<div class="change changed" ng-repeat="file in currentImageChanges.changed | limitTo:5">
|
||||
<b>{{currentImageChanges.removed.length}}</b>
|
||||
</span>
|
||||
<span class="change-count changed" ng-show="currentImageChanges.changed.length > 0" title="Files Changed"
|
||||
bs-tooltip="tooltip.title" data-placement="top" data-container="body">
|
||||
<i class="fa fa-pencil-square"></i>
|
||||
<span title="{{file}}">{{file}}</span>
|
||||
<b>{{currentImageChanges.changed.length}}</b>
|
||||
</span>
|
||||
</div>
|
||||
<div id="collapseChanges" style="padding-top: 24px;">
|
||||
<div class="well well-sm">
|
||||
<div class="change added" ng-repeat="file in currentImageChanges.added | limitTo:2">
|
||||
<i class="fa fa-plus-square"></i>
|
||||
<span title="{{file}}">{{file}}</span>
|
||||
</div>
|
||||
<div class="change removed" ng-repeat="file in currentImageChanges.removed | limitTo:2">
|
||||
<i class="fa fa-minus-square"></i>
|
||||
<span title="{{file}}">{{file}}</span>
|
||||
</div>
|
||||
<div class="change changed" ng-repeat="file in currentImageChanges.changed | limitTo:2">
|
||||
<i class="fa fa-pencil-square"></i>
|
||||
<span title="{{file}}">{{file}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="more-changes" ng-show="getMoreCount(currentImageChanges) > 0">
|
||||
<a href="{{'/repository/' + repo.namespace + '/' + repo.name + '/image/' + currentImage.id}}">
|
||||
And {{getMoreCount(currentImageChanges)}} more...
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="more-changes" ng-show="getMoreCount(currentImageChanges) > 0">
|
||||
<a href="{{'/repository/' + repo.namespace + '/' + repo.name + '/image/' + currentImage.id}}">
|
||||
And {{getMoreCount(currentImageChanges)}} more...
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -253,6 +301,44 @@ sudo docker push quay.io/{{repo.namespace}}/{{repo.name}}</pre>
|
|||
build-started="handleBuildStarted(build)">
|
||||
</div>
|
||||
|
||||
<!-- Modal message dialog -->
|
||||
<div class="modal fade" id="addTagModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" ng-show="!creatingTag">×</button>
|
||||
<h4 class="modal-title">{{ isAnotherImageTag(toTagImage, tagToCreate) ? 'Move' : 'Add' }} Tag to Image {{ toTagImage.id.substr(0, 12) }}</h4>
|
||||
</div>
|
||||
<form name="addTagForm" ng-submit="createOrMoveTag(toTagImage, tagToCreate, addTagForm.$invalid); addTagForm.$setPristine(); tagToCreate=''">
|
||||
<div class="modal-body">
|
||||
<input type="text" class="form-control" id="tagName" placeholder="Enter tag name"
|
||||
ng-model="tagToCreate" ng-pattern="/^([a-z0-9_]){3,30}$/" required
|
||||
ng-disabled="creatingTag">
|
||||
<div style="margin: 10px; margin-top: 20px;" ng-show="isOwnedTag(toTagImage, tagToCreate)">
|
||||
Note: <span class="label tag label-default">{{ tagToCreate }}</span> is already applied to this image.
|
||||
</div>
|
||||
<div style="margin: 10px; margin-top: 20px;" ng-show="isAnotherImageTag(toTagImage, tagToCreate)">
|
||||
Note: <span class="label tag label-default">{{ tagToCreate }}</span> is already applied to another image. This will <b>move</b> the tag.
|
||||
</div>
|
||||
<div class="tag-specific-images-view" tag="tagToCreate" repository="repo" images="images"
|
||||
style="margin: 10px; margin-top: 20px; margin-bottom: -10px;" ng-show="isAnotherImageTag(toTagImage, tagToCreate)">
|
||||
This will also delete any unattach images and delete the following images:
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary"
|
||||
ng-disabled="!tagToCreate || addTagForm.$invalid || isOwnedTag(toTagImage, tagToCreate)"
|
||||
ng-class="isAnotherImageTag(toTagImage, tagToCreate) ? 'btn-warning' : 'btn-primary'" ng-show="!creatingTag">
|
||||
{{ isAnotherImageTag(toTagImage, tagToCreate) ? 'Move Tag' : 'Create Tag' }}
|
||||
</button>
|
||||
<button class="btn btn-default" data-dismiss="modal" ng-show="!creatingTag">Cancel</button>
|
||||
<div class="quay-spinner" ng-show="creatingTag"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
<!-- Modal message dialog -->
|
||||
<div class="modal fade" id="confirmdeleteTagModal">
|
||||
<div class="modal-dialog">
|
||||
|
@ -271,22 +357,8 @@ sudo docker push quay.io/{{repo.namespace}}/{{repo.name}}</pre>
|
|||
{{ tagToDelete }}
|
||||
</span>?
|
||||
|
||||
<div ng-show="tagSpecificImages(tagToDelete).length" style="margin-top: 20px">
|
||||
The following images and any other images not referenced by a tag will be deleted:
|
||||
<div class="image-listings">
|
||||
<div class="image-listing" ng-repeat="image in tagSpecificImages(tagToDelete) | limitTo:5"
|
||||
ng-class="getImageListingClasses(image, tagToDelete)">
|
||||
<!--<i class="fa fa-archive"></i>-->
|
||||
<span class="image-listing-circle"></span>
|
||||
<span class="image-listing-line"></span>
|
||||
<span class="context-tooltip image-listing-id" bs-tooltip="getFirstTextLine(image.comment)">
|
||||
{{ image.id.substr(0, 12) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="more-changes" ng-show="tagSpecificImages(tagToDelete).length > 5">
|
||||
And {{ tagSpecificImages(tagToDelete).length - 5 }} more...
|
||||
</div>
|
||||
<div class="tag-specific-images-view" tag="tagToDelete" repository="repo" images="images" style="margin-top: 20px">
|
||||
The following images and any other images not referenced by a tag will be deleted:
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
|
Reference in a new issue