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;
|
display: inline-block;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
width: 120px;
|
width: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-link a {
|
.manifest-link a {
|
||||||
font-family: Consolas, "Lucida Console", Monaco, monospace;
|
font-family: Consolas, "Lucida Console", Monaco, monospace;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-link .id-label {
|
.manifest-link .id-label {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
|
@ -24,6 +24,6 @@
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-link .id-label.cas {
|
.manifest-link .id-label.cas {
|
||||||
background-color: #e8f1f6;
|
background-color: #e8f1f6;
|
||||||
}
|
}
|
|
@ -252,7 +252,7 @@
|
||||||
background: #F6FCFF;
|
background: #F6FCFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
.repo-tag-history-element .history-entry .image-link {
|
.repo-tag-history-element .history-entry .manifest-link {
|
||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -159,17 +159,14 @@
|
||||||
</span>
|
</span>
|
||||||
<span bo-if="feature.vulnCount > 0 && feature.fixableScore > 0">
|
<span bo-if="feature.vulnCount > 0 && feature.fixableScore > 0">
|
||||||
<span class="strength-indicator" value="feature.fixableScore" maximum="featuresInfo.highestFixableScore"
|
<span class="strength-indicator" value="feature.fixableScore" maximum="featuresInfo.highestFixableScore"
|
||||||
log-base="2"></span>
|
log-base="2"></span>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="double-col image-col hidden-xs hidden-sm hidden-md">
|
<td class="double-col image-col hidden-xs hidden-sm hidden-md">
|
||||||
<span bo-if="feature.imageCommand">
|
<span bo-if="feature.imageCommand">
|
||||||
<image-command command="feature.imageCommand"></image-command>
|
<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>
|
||||||
|
<span bo-if="!feature.imageCommand">(No Command)</span>
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</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>
|
||||||
<td class="double-col image-col hidden-xs hidden-sm hidden-md">
|
<td class="double-col image-col hidden-xs hidden-sm hidden-md">
|
||||||
<span bo-if="vuln.imageCommand">
|
<span bo-if="vuln.imageCommand">
|
||||||
<image-command command="vuln.imageCommand"></image-command>
|
<image-command command="feature.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>
|
|
||||||
</span>
|
</span>
|
||||||
|
<span bo-if="!vuln.imageCommand">(No Command)</span>
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -181,8 +178,8 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Introduced in Image:</td>
|
<td>Introduced in Layer:</td>
|
||||||
<td><span class="image-link" repository="repository" image-id="vuln.imageId"></span></td>
|
<td>{{ ::vuln.imageId }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -38,38 +38,38 @@
|
||||||
<span ng-switch on="entry.action">
|
<span ng-switch on="entry.action">
|
||||||
<span ng-switch-when="recreate">
|
<span ng-switch-when="recreate">
|
||||||
was recreated pointing to
|
was recreated pointing to
|
||||||
<span class="image-link" repository="repository"
|
<manifest-link repository="repository"
|
||||||
image-id="entry.docker_image_id"
|
image-id="entry.docker_image_id"
|
||||||
manifest-digest="entry.manifest_digest"></span>
|
manifest-digest="entry.manifest_digest"></manifest-link>
|
||||||
</span>
|
</span>
|
||||||
<span ng-switch-when="create">
|
<span ng-switch-when="create">
|
||||||
was created pointing to
|
was created pointing to
|
||||||
<span class="image-link" repository="repository"
|
<manifest-link repository="repository"
|
||||||
image-id="entry.docker_image_id"
|
image-id="entry.docker_image_id"
|
||||||
manifest-digest="entry.manifest_digest"></span>
|
manifest-digest="entry.manifest_digest"></manifest-link>
|
||||||
</span>
|
</span>
|
||||||
<span ng-switch-when="delete">
|
<span ng-switch-when="delete">
|
||||||
was deleted
|
was deleted
|
||||||
</span>
|
</span>
|
||||||
<span ng-switch-when="move">
|
<span ng-switch-when="move">
|
||||||
was moved to
|
was moved to
|
||||||
<span class="image-link" repository="repository"
|
<manifest-link repository="repository"
|
||||||
image-id="entry.docker_image_id"
|
image-id="entry.docker_image_id"
|
||||||
manifest-digest="entry.manifest_digest"></span>
|
manifest-digest="entry.manifest_digest"></manifest-link>
|
||||||
from
|
from
|
||||||
<span class="image-link" repository="repository"
|
<manifest-link repository="repository"
|
||||||
image-id="entry.old_docker_image_id"
|
image-id="entry.old_docker_image_id"
|
||||||
manifest-digest="entry.old_manifest_digest"></span>
|
manifest-digest="entry.old_manifest_digest"></manifest-link>
|
||||||
</span>
|
</span>
|
||||||
<span ng-switch-when="revert">
|
<span ng-switch-when="revert">
|
||||||
was reverted to
|
was reverted to
|
||||||
<span class="image-link" repository="repository"
|
<manifest-link repository="repository"
|
||||||
image-id="entry.docker_image_id"
|
image-id="entry.docker_image_id"
|
||||||
manifest-digest="entry.manifest_digest"></span>
|
manifest-digest="entry.manifest_digest"></manifest-link>
|
||||||
from
|
from
|
||||||
<span class="image-link" repository="repository"
|
<manifest-link repository="repository"
|
||||||
image-id="entry.old_docker_image_id"
|
image-id="entry.old_docker_image_id"
|
||||||
manifest-digest="entry.old_manifest_digest"></span>
|
manifest-digest="entry.old_manifest_digest"></manifest-link>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -87,21 +87,21 @@
|
||||||
<span ng-switch on="entry.action">
|
<span ng-switch on="entry.action">
|
||||||
<a ng-switch-when="delete" ng-click="askRestoreTag(entry, true)">
|
<a ng-switch-when="delete" ng-click="askRestoreTag(entry, true)">
|
||||||
Restore <span class="tag-span"><span>{{ entry.tag_name }}</span></span> to
|
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"
|
image-id="entry.docker_image_id"
|
||||||
manifest-digest="entry.manifest_digest"></span>
|
manifest-digest="entry.manifest_digest"></manifest-link>
|
||||||
</a>
|
</a>
|
||||||
<a ng-switch-when="move" ng-click="askRestoreTag(entry, false)">
|
<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
|
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"
|
image-id="entry.old_docker_image_id"
|
||||||
manifest-digest="entry.old_manifest_digest"></span>
|
manifest-digest="entry.old_manifest_digest"></manifest-link>
|
||||||
</a>
|
</a>
|
||||||
<a ng-switch-when="revert" ng-click="askRestoreTag(entry, false)">
|
<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
|
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"
|
image-id="entry.old_docker_image_id"
|
||||||
manifest-digest="entry.old_manifest_digest"></span>
|
manifest-digest="entry.old_manifest_digest"></manifest-link>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</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>
|
<expiration-status-view expiration-date="tag.expiration_date" ng-if="repository.tag_operations_disabled || !repository.can_write"></expiration-status-view>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- Image link -->
|
<!-- Manifest link -->
|
||||||
<td class="hidden-xs hidden-sm image-id-col">
|
<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>
|
||||||
<td class="hidden-xs hidden-sm hidden-md image-track"
|
<td class="hidden-xs hidden-sm hidden-md image-track"
|
||||||
ng-if="imageTracks.length > maxTrackCount" bindonce>
|
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) }}">
|
<td class="labels-col" colspan="{{6 + (repository.trust_enabled ? 1 : 0) + (Features.SECURITY_SCANNER ? 1 : 0) }}">
|
||||||
<!-- Image ID -->
|
<!-- Image ID -->
|
||||||
<div class="image-id-row">
|
<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>
|
</div>
|
||||||
|
|
||||||
<!-- Labels -->
|
<!-- Labels -->
|
||||||
|
|
|
@ -162,9 +162,9 @@
|
||||||
|
|
||||||
Are you sure you want to restore tag
|
Are you sure you want to restore tag
|
||||||
<span class="label label-default tag">{{ restoreTagInfo.tag.name }}</span> to image
|
<span class="label label-default tag">{{ restoreTagInfo.tag.name }}</span> to image
|
||||||
<span class="image-link" repository="repository"
|
<manifest-link repository="repository"
|
||||||
image-id="restoreTagInfo.image_id"
|
image-id="restoreTagInfo.image_id"
|
||||||
manifest-digest="restoreTagInfo.manifest_digest"></span>?
|
manifest-digest="restoreTagInfo.manifest_digest"></manifest-link>?
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tag Operations Disabled Dialog -->
|
<!-- 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 { TimeAgoComponent } from './directives/ui/time-ago/time-ago.component';
|
||||||
import { TimeDisplayComponent } from './directives/ui/time-display/time-display.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 { 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 { MarkdownModule } from './directives/ui/markdown/markdown.module';
|
||||||
import * as Clipboard from 'clipboard';
|
import * as Clipboard from 'clipboard';
|
||||||
|
|
||||||
|
@ -85,6 +86,7 @@ import * as Clipboard from 'clipboard';
|
||||||
TimeAgoComponent,
|
TimeAgoComponent,
|
||||||
TimeDisplayComponent,
|
TimeDisplayComponent,
|
||||||
AppSpecificTokenManagerComponent,
|
AppSpecificTokenManagerComponent,
|
||||||
|
ManifestLinkComponent,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
ViewArrayImpl,
|
ViewArrayImpl,
|
||||||
|
|
Reference in a new issue