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:
parent
58c2ddac98
commit
d41dcaae23
12 changed files with 122 additions and 125 deletions
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">×</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>
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 -->
|
||||
|
|
|
@ -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 -->
|
||||
|
|
|
@ -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;
|
||||
});
|
|
@ -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">×</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>
|
|
@ -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);
|
||||
};
|
||||
}
|
|
@ -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,
|
||||
|
|
Reference in a new issue