Rename image-link into manifest-link, and change to typescript, in prep for the UI changes to link to manifests

This commit is contained in:
Joseph Schorr 2018-03-28 13:56:09 -04:00
parent 58c2ddac98
commit d41dcaae23
12 changed files with 122 additions and 125 deletions

View file

@ -1,16 +1,16 @@
.image-link {
.manifest-link {
display: inline-block;
white-space: nowrap;
width: 120px;
}
.image-link a {
.manifest-link a {
font-family: Consolas, "Lucida Console", Monaco, monospace;
font-size: 12px;
text-decoration: none;
}
.image-link .id-label {
.manifest-link .id-label {
font-size: 10px;
cursor: pointer;
padding: 2px;
@ -24,6 +24,6 @@
display: inline-block;
}
.image-link .id-label.cas {
.manifest-link .id-label.cas {
background-color: #e8f1f6;
}

View file

@ -252,7 +252,7 @@
background: #F6FCFF;
}
.repo-tag-history-element .history-entry .image-link {
.repo-tag-history-element .history-entry .manifest-link {
margin-left: 6px;
}

View file

@ -159,17 +159,14 @@
</span>
<span bo-if="feature.vulnCount > 0 && feature.fixableScore > 0">
<span class="strength-indicator" value="feature.fixableScore" maximum="featuresInfo.highestFixableScore"
log-base="2"></span>
log-base="2"></span>
</span>
</td>
<td class="double-col image-col hidden-xs hidden-sm hidden-md">
<span bo-if="feature.imageCommand">
<image-command command="feature.imageCommand"></image-command>
<a href="/repository/{{ repository.namespace }}/{{ repository.name }}/image/{{ feature.imageId }}"><i class="fa fa-archive"></i></a>
</span>
<span bo-if="!feature.imageCommand">
<span class="image-link" repository="repository" image-id="feature.imageId"></span>
</span>
<span bo-if="!feature.imageCommand">(No Command)</span>
</td>
<td></td>
</tr>

View file

@ -1,37 +0,0 @@
<span>
<span class="id-label" ng-if="!hasSHA256(manifestDigest)"
data-title="The Docker V1 ID for this image. This ID is not content addressable nor is it stable across pulls."
data-container="body"
ng-click="showCopyBox()"
bs-tooltip>V1ID</span>
<span class="id-label cas" ng-if="hasSHA256(manifestDigest)"
data-title="The content-addressable SHA256 hash of this tag."
data-container="body"
ng-click="showCopyBox()"
bs-tooltip>SHA256</span>
<a bo-href-i="/repository/{{ repository.namespace }}/{{ repository.name }}/image/{{ imageId }}"
class="image-link-element" bindonce>
<span ng-if="!hasSHA256(manifestDigest)">{{ imageId.substr(0, 12) }}</span>
<span ng-if="hasSHA256(manifestDigest)">{{ getShortDigest(manifestDigest) }}</span>
</a>
<div class="modal fade co-dialog" ng-if="showingCopyBox">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-click="hideCopyBox()"
aria-hidden="true">&times;</button>
<h4 class="modal-title"><span ng-if="hasSHA256(manifestDigest)">Manifest SHA256</span><span ng-if="!hasSHA256(manifestDigest)">V1 ID</span></h4>
</div>
<div class="modal-body">
<div class="copy-box" hovering-message="true" value="hasSHA256(manifestDigest) ? manifestDigest : imageId"></div>
</div>
<div class="modal-footer" ng-show="!working">
<button type="button" class="btn btn-default" ng-click="hideCopyBox()">Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</span>

View file

@ -152,12 +152,9 @@
</td>
<td class="double-col image-col hidden-xs hidden-sm hidden-md">
<span bo-if="vuln.imageCommand">
<image-command command="vuln.imageCommand"></image-command>
<a href="/repository/{{ repository.namespace }}/{{ repository.name }}/image/{{ vuln.imageId }}"><i class="fa fa-archive"></i></a>
</span>
<span bo-if="!vuln.imageCommand">
<span class="image-link" repository="repository" image-id="vuln.imageId"></span>
<image-command command="feature.imageCommand"></image-command>
</span>
<span bo-if="!vuln.imageCommand">(No Command)</span>
</td>
<td></td>
</tr>
@ -181,8 +178,8 @@
</td>
</tr>
<tr>
<td>Introduced in Image:</td>
<td><span class="image-link" repository="repository" image-id="vuln.imageId"></span></td>
<td>Introduced in Layer:</td>
<td>{{ ::vuln.imageId }}</td>
</tr>
</table>
</div>

View file

@ -38,38 +38,38 @@
<span ng-switch on="entry.action">
<span ng-switch-when="recreate">
was recreated pointing to
<span class="image-link" repository="repository"
<manifest-link repository="repository"
image-id="entry.docker_image_id"
manifest-digest="entry.manifest_digest"></span>
manifest-digest="entry.manifest_digest"></manifest-link>
</span>
<span ng-switch-when="create">
was created pointing to
<span class="image-link" repository="repository"
<manifest-link repository="repository"
image-id="entry.docker_image_id"
manifest-digest="entry.manifest_digest"></span>
manifest-digest="entry.manifest_digest"></manifest-link>
</span>
<span ng-switch-when="delete">
was deleted
</span>
<span ng-switch-when="move">
was moved to
<span class="image-link" repository="repository"
<manifest-link repository="repository"
image-id="entry.docker_image_id"
manifest-digest="entry.manifest_digest"></span>
manifest-digest="entry.manifest_digest"></manifest-link>
from
<span class="image-link" repository="repository"
<manifest-link repository="repository"
image-id="entry.old_docker_image_id"
manifest-digest="entry.old_manifest_digest"></span>
manifest-digest="entry.old_manifest_digest"></manifest-link>
</span>
<span ng-switch-when="revert">
was reverted to
<span class="image-link" repository="repository"
<manifest-link repository="repository"
image-id="entry.docker_image_id"
manifest-digest="entry.manifest_digest"></span>
manifest-digest="entry.manifest_digest"></manifest-link>
from
<span class="image-link" repository="repository"
<manifest-link repository="repository"
image-id="entry.old_docker_image_id"
manifest-digest="entry.old_manifest_digest"></span>
manifest-digest="entry.old_manifest_digest"></manifest-link>
</span>
</span>
</div>
@ -87,21 +87,21 @@
<span ng-switch on="entry.action">
<a ng-switch-when="delete" ng-click="askRestoreTag(entry, true)">
Restore <span class="tag-span"><span>{{ entry.tag_name }}</span></span> to
<span class="image-link" repository="repository"
<manifest-link repository="repository"
image-id="entry.docker_image_id"
manifest-digest="entry.manifest_digest"></span>
manifest-digest="entry.manifest_digest"></manifest-link>
</a>
<a ng-switch-when="move" ng-click="askRestoreTag(entry, false)">
Revert <span class="tag-span" data-title="{{ entry.tag_name }}" bs-tooltip><span>{{ entry.tag_name }}</span></span> to
<span class="image-link" repository="repository"
<manifest-link repository="repository"
image-id="entry.old_docker_image_id"
manifest-digest="entry.old_manifest_digest"></span>
manifest-digest="entry.old_manifest_digest"></manifest-link>
</a>
<a ng-switch-when="revert" ng-click="askRestoreTag(entry, false)">
Restore <span class="tag-span" data-title="{{ entry.tag_name }}" bs-tooltip><span>{{ entry.tag_name }}</span></span> to
<span class="image-link" repository="repository"
<manifest-link repository="repository"
image-id="entry.old_docker_image_id"
manifest-digest="entry.old_manifest_digest"></span>
manifest-digest="entry.old_manifest_digest"></manifest-link>
</a>
</span>
</div>

View file

@ -237,9 +237,9 @@
<expiration-status-view expiration-date="tag.expiration_date" ng-if="repository.tag_operations_disabled || !repository.can_write"></expiration-status-view>
</td>
<!-- Image link -->
<!-- Manifest link -->
<td class="hidden-xs hidden-sm image-id-col">
<span class="image-link" repository="repository" image-id="tag.image_id" manifest-digest="tag.manifest_digest"></span>
<manifest-link repository="repository" image-id="tag.image_id" manifest-digest="tag.manifest_digest"></manifest-link>
</td>
<td class="hidden-xs hidden-sm hidden-md image-track"
ng-if="imageTracks.length > maxTrackCount" bindonce>
@ -293,7 +293,7 @@
<td class="labels-col" colspan="{{6 + (repository.trust_enabled ? 1 : 0) + (Features.SECURITY_SCANNER ? 1 : 0) }}">
<!-- Image ID -->
<div class="image-id-row">
<span class="image-link" repository="repository" image-id="tag.image_id" manifest-digest="tag.manifest_digest"></span>
<manifest-link repository="repository" image-id="tag.image_id" manifest-digest="tag.manifest_digest"></manifest-link>
</div>
<!-- Labels -->

View file

@ -162,9 +162,9 @@
Are you sure you want to restore tag
<span class="label label-default tag">{{ restoreTagInfo.tag.name }}</span> to image
<span class="image-link" repository="repository"
image-id="restoreTagInfo.image_id"
manifest-digest="restoreTagInfo.manifest_digest"></span>?
<manifest-link repository="repository"
image-id="restoreTagInfo.image_id"
manifest-digest="restoreTagInfo.manifest_digest"></manifest-link>?
</div>
<!-- Tag Operations Disabled Dialog -->

View file

@ -1,47 +0,0 @@
/**
* An element which displays a link to a repository image.
*/
angular.module('quay').directive('imageLink', function () {
var directiveDefinitionObject = {
priority: 0,
templateUrl: '/static/directives/image-link.html',
replace: false,
transclude: true,
restrict: 'C',
scope: {
'repository': '=repository',
'imageId': '=imageId',
'manifestDigest': '=?manifestDigest'
},
controller: function($scope, $element, $timeout) {
$scope.showingCopyBox = false;
$scope.hasSHA256 = function(digest) {
return digest && digest.indexOf('sha256:') == 0;
};
$scope.getShortDigest = function(digest) {
return digest.substr('sha256:'.length).substr(0, 12);
};
$scope.showCopyBox = function() {
$scope.showingCopyBox = true;
// Necessary to wait for digest cycle to complete.
$timeout(function() {
$element.find('.modal').modal('show');
}, 10);
};
$scope.hideCopyBox = function() {
$element.find('.modal').modal('hide');
// Wait for the modal to hide before removing from the DOM.
$timeout(function() {
$scope.showingCopyBox = false;
}, 10);
};
}
};
return directiveDefinitionObject;
});

View file

@ -0,0 +1,37 @@
<span class="manifest-link">
<span class="id-label" ng-if="!$ctrl.hasSHA256($ctrl.manifestDigest)"
data-title="The Docker V1 ID for this image. This ID is not content addressable nor is it stable across pulls."
data-container="body"
ng-click="$ctrl.showCopyBox()"
bs-tooltip>V1ID</span>
<span class="id-label cas" ng-if="$ctrl.hasSHA256($ctrl.manifestDigest)"
data-title="The content-addressable SHA256 hash of this tag."
data-container="body"
ng-click="$ctrl.showCopyBox()"
bs-tooltip>SHA256</span>
<a bo-href-i="/repository/{{ $ctrl.repository.namespace }}/{{ $ctrl.repository.name }}/image/{{ $ctrl.imageId }}"
class="image-link-element" bindonce>
<span ng-if="!$ctrl.hasSHA256($ctrl.manifestDigest)">{{ $ctrl.imageId.substr(0, 12) }}</span>
<span ng-if="$ctrl.hasSHA256($ctrl.manifestDigest)">{{ $ctrl.getShortDigest($ctrl.manifestDigest) }}</span>
</a>
<div class="modal fade co-dialog" ng-if="$ctrl.showingCopyBox">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-click="$ctrl.hideCopyBox()"
aria-hidden="true">&times;</button>
<h4 class="modal-title"><span ng-if="$ctrl.hasSHA256($ctrl.manifestDigest)">Manifest SHA256</span><span ng-if="!$ctrl.hasSHA256($ctrl.manifestDigest)">V1 ID</span></h4>
</div>
<div class="modal-body">
<div class="copy-box" hovering-message="true" value="$ctrl.hasSHA256($ctrl.manifestDigest) ? $ctrl.manifestDigest : $ctrl.imageId"></div>
</div>
<div class="modal-footer" ng-show="!working">
<button type="button" class="btn btn-default" ng-click="$ctrl.hideCopyBox()">Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</span>

View file

@ -0,0 +1,48 @@
import { Input, Component, Inject } from 'ng-metadata/core';
import { Repository } from '../../../types/common.types';
/**
* A component that links to a manifest view.
*/
@Component({
selector: 'manifest-link',
templateUrl: '/static/js/directives/ui/manifest-link/manifest-link.component.html'
})
export class ManifestLinkComponent {
@Input('<') public repository: Repository;
@Input('<') public manifestDigest: string;
@Input('<') public imageId: string;
private showingCopyBox: boolean = false;
constructor(@Inject('$timeout') private $timeout, @Inject('$element') private $element) {
}
private hasSHA256(digest: string) {
return digest && digest.indexOf('sha256:') == 0;
}
private getShortDigest(digest: string) {
return digest.substr('sha256:'.length).substr(0, 12);
}
private showCopyBox() {
this.showingCopyBox = true;
// Necessary to wait for digest cycle to complete.
this.$timeout(() => {
this.$element.find('.modal').modal('show');
}, 10);
};
private hideCopyBox() {
this.$element.find('.modal').modal('hide');
// Wait for the modal to hide before removing from the DOM.
this.$timeout(() => {
this.showingCopyBox = false;
}, 10);
};
}

View file

@ -40,6 +40,7 @@ import { TriggerDescriptionComponent } from './directives/ui/trigger-description
import { TimeAgoComponent } from './directives/ui/time-ago/time-ago.component';
import { TimeDisplayComponent } from './directives/ui/time-display/time-display.component';
import { AppSpecificTokenManagerComponent } from './directives/ui/app-specific-token-manager/app-specific-token-manager.component';
import { ManifestLinkComponent } from './directives/ui/manifest-link/manifest-link.component';
import { MarkdownModule } from './directives/ui/markdown/markdown.module';
import * as Clipboard from 'clipboard';
@ -85,6 +86,7 @@ import * as Clipboard from 'clipboard';
TimeAgoComponent,
TimeDisplayComponent,
AppSpecificTokenManagerComponent,
ManifestLinkComponent,
],
providers: [
ViewArrayImpl,