Add UI for viewing labels on a manifest in the tags view

This commit is contained in:
Joseph Schorr 2017-03-08 16:25:14 -05:00
parent 69e476b1f4
commit f17ef4adda
13 changed files with 336 additions and 112 deletions

View file

@ -0,0 +1,10 @@
<div class="label-list-element">
<div class="label-view"
ng-repeat="label in labels"
expand="{{expand}}"
label="label">
</div>
<div class="empty-list" ng-if="!labels.length">
No labels found
</div>
</div>

View file

@ -0,0 +1,8 @@
<a class="label-view-element" ng-click="viewLabelValue()">
<span class="kind">{{ getKind(label) }}</span>
<span class="label-value">
<span class="key">{{ label.key }}</span>
<span class="equals">=</span>
<span class="value">{{ label.value }}</span>
</span>
</a>

View file

@ -0,0 +1,11 @@
<div class="manifest-label-list-element">
<div class="cor-loader-inline" ng-if="repository && manifestDigest && !labels && !loadError"></div>
<div class="none" ng-if="repository && !manifestDigest && !loadError">
This tag does not have an associated manifest
</div>
<div class="none" ng-if="repository && manifestDigest && loadError">
Could not load labels for this manifest
</div>
<div class="label-list" labels="labels"
ng-if="repository && manifestDigest && labels && !loadError"></div>
</div>

View file

@ -1,4 +1,17 @@
<div class="repo-panel-tags-element">
<div class="tab-header-controls">
<div class="btn-group btn-group-sm">
<button class="btn" ng-class="!expandedView ? 'btn-primary active' : 'btn-default'"
ng-click="setExpanded(false)">
Compact
</button>
<button class="btn" ng-class="expandedView ? 'btn-info active' : 'btn-default'"
ng-click="setExpanded(true)">
Expanded
</button>
</div>
</div>
<h3 class="tab-header"><span class="hidden-xs">Repository </span>Tags</h3>
<div class="co-alert co-alert-danger" ng-if="hasDefcon1">
One or more of your tags has an <strong>extremely critical</strong> vulnerability which should be addressed immediately:
@ -103,129 +116,147 @@
<td class="hidden-xs hidden-sm" style="width: 4px"></td>
</thead>
<tr class="co-checkable-row"
<tbody class="co-checkable-row"
ng-repeat="tag in tags | slice:(tagsPerPage * options.page):(tagsPerPage * (options.page + 1))"
ng-class="checkedTags.isChecked(tag, checkedTags.checked) ? 'checked' : ''"
bindonce>
<td><span class="cor-checkable-item" controller="checkedTags" item="tag"></span></td>
<td class="co-flowing-col"><span class="tag-span"><span bo-text="tag.name"></span></span></td>
<td class="hidden-xs">
<span bo-if="tag.last_modified" data-title="{{ tag.last_modified | amDateFormat:'dddd, MMMM Do YYYY, h:mm:ss a' }}" bs-tooltip>
<span am-time-ago="tag.last_modified"></span>
</span>
<span bo-if="!tag.last_modified">Unknown</span>
</td>
<td quay-require="['SECURITY_SCANNER']" class="security-scan-col hidden-xs">
<span class="cor-loader-inline" ng-if="getTagVulnerabilities(tag).loading"></span>
<span class="vuln-load-error" ng-if="getTagVulnerabilities(tag).hasError"
data-title="The vulnerabilities for this tag could not be retrieved at the present time, try again later"
bs-tooltip>
<i class="fa fa-times-circle"></i>
Could not load security information
</span>
<span ng-if="!getTagVulnerabilities(tag).loading">
<!-- Queued -->
<span class="scanning" ng-if="getTagVulnerabilities(tag).status == 'queued'"
data-title="The image for this tag is queued to be scanned for vulnerabilities"
bs-tooltip>
<i class="fa fa-ellipsis-h"></i>
Queued
<tr ng-class="expandedView ? 'expanded-view': ''">
<td><span class="cor-checkable-item" controller="checkedTags" item="tag"></span></td>
<td class="co-flowing-col"><span class="tag-span"><span bo-text="tag.name"></span></span></td>
<td class="hidden-xs">
<span bo-if="tag.last_modified" data-title="{{ tag.last_modified | amDateFormat:'dddd, MMMM Do YYYY, h:mm:ss a' }}" bs-tooltip>
<span am-time-ago="tag.last_modified"></span>
</span>
<!-- Scan Failed -->
<span class="failed-scan" ng-if="getTagVulnerabilities(tag).status == 'failed'"
data-title="The image for this tag could not be scanned for vulnerabilities"
<span bo-if="!tag.last_modified">Unknown</span>
</td>
<td quay-require="['SECURITY_SCANNER']" class="security-scan-col hidden-xs">
<span class="cor-loader-inline" ng-if="getTagVulnerabilities(tag).loading"></span>
<span class="vuln-load-error" ng-if="getTagVulnerabilities(tag).hasError"
data-title="The vulnerabilities for this tag could not be retrieved at the present time, try again later"
bs-tooltip>
<i class="fa fa-question-circle"></i>
Unable to scan
</span>
<!-- No Features -->
<span class="failed-scan"
ng-if="getTagVulnerabilities(tag).status == 'scanned' && !getTagVulnerabilities(tag).hasFeatures"
data-title="The image for this tag has an operating system or package manager unsupported by Quay Security Scanner"
bs-tooltip
bindonce>
<i class="fa fa-times-circle"></i>
Unsupported
Could not load security information
</span>
<!-- Features and No Vulns -->
<span class="no-vulns"
ng-if="getTagVulnerabilities(tag).status == 'scanned' && getTagVulnerabilities(tag).hasFeatures && !getTagVulnerabilities(tag).hasVulnerabilities"
data-title="The image for this tag has no vulnerabilities as found in our database"
bs-tooltip
bindonce>
<a bo-href-i="/repository/{{ repository.namespace }}/{{ repository.name }}/image/{{ tag.image_id }}?tab=vulnerabilities">
<i class="fa fa-check-circle"></i>
Passed
</a>
</span>
<span ng-if="!getTagVulnerabilities(tag).loading">
<!-- Queued -->
<span class="scanning" ng-if="getTagVulnerabilities(tag).status == 'queued'"
data-title="The image for this tag is queued to be scanned for vulnerabilities"
bs-tooltip>
<i class="fa fa-ellipsis-h"></i>
Queued
</span>
<!-- Vulns -->
<span ng-if="getTagVulnerabilities(tag).status == 'scanned' && getTagVulnerabilities(tag).hasFeatures && getTagVulnerabilities(tag).hasVulnerabilities"
ng-class="getTagVulnerabilities(tag).highestVulnerability.Priority"
class="has-vulns" bindonce>
<!-- Scan Failed -->
<span class="failed-scan" ng-if="getTagVulnerabilities(tag).status == 'failed'"
data-title="The image for this tag could not be scanned for vulnerabilities"
bs-tooltip>
<i class="fa fa-question-circle"></i>
Unable to scan
</span>
<a class="vuln-link" bo-href-i="/repository/{{ repository.namespace }}/{{ repository.name }}/image/{{ tag.image_id }}?tab=vulnerabilities"
data-title="This tag has {{ getTagVulnerabilities(tag).vulnerabilities.length }} vulnerabilities across {{ getTagVulnerabilities(tag).featuresInfo.brokenFeaturesCount }} packages"
bs-tooltip>
<!-- Donut -->
<span class="donut-chart" width="24" data="getTagVulnerabilities(tag).featuresInfo.severityBreakdown"></span>
<!-- No Features -->
<span class="failed-scan"
ng-if="getTagVulnerabilities(tag).status == 'scanned' && !getTagVulnerabilities(tag).hasFeatures"
data-title="The image for this tag has an operating system or package manager unsupported by Quay Security Scanner"
bs-tooltip
bindonce>
<i class="fa fa-times-circle"></i>
Unsupported
</span>
<!-- Messaging -->
<span ng-if="getTagVulnerabilities(tag).featuresInfo.fixableFeatureCount == 0">
{{ getTagVulnerabilities(tag).featuresInfo.brokenFeaturesCount }} vulnerable package<span ng-if="getTagVulnerabilities(tag).featuresInfo.brokenFeaturesCount != 1">s</span>
</span>
<span ng-if="getTagVulnerabilities(tag).featuresInfo.fixableFeatureCount > 0">
{{ getTagVulnerabilities(tag).featuresInfo.fixableFeatureCount }} fixable package<span ng-if="getTagVulnerabilities(tag).featuresInfo.fixableFeatureCount != 1">s</span>
</span>
</a>
</span>
</span>
</td>
<td class="hidden-sm hidden-xs" bo-text="tag.size | bytes"></td>
<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>
</td>
<td class="hidden-xs hidden-sm image-track"
ng-if="imageTracks.length > maxTrackCount" bindonce>
<span ng-repeat="it in imageTracks">
<span ng-repeat="entry in it.entries">
<span class="image-track-dot" bo-if="entry.image_id == tag.image_id"
bo-style="{'borderColor': entry.color}" ng-click="selectTrack(entry)"></span>
<!-- Features and No Vulns -->
<span class="no-vulns"
ng-if="getTagVulnerabilities(tag).status == 'scanned' && getTagVulnerabilities(tag).hasFeatures && !getTagVulnerabilities(tag).hasVulnerabilities"
data-title="The image for this tag has no vulnerabilities as found in our database"
bs-tooltip
bindonce>
<a bo-href-i="/repository/{{ repository.namespace }}/{{ repository.name }}/image/{{ tag.image_id }}?tab=vulnerabilities">
<i class="fa fa-check-circle"></i>
Passed
</a>
</span>
<!-- Vulns -->
<span ng-if="getTagVulnerabilities(tag).status == 'scanned' && getTagVulnerabilities(tag).hasFeatures && getTagVulnerabilities(tag).hasVulnerabilities"
ng-class="getTagVulnerabilities(tag).highestVulnerability.Priority"
class="has-vulns" bindonce>
<a class="vuln-link" bo-href-i="/repository/{{ repository.namespace }}/{{ repository.name }}/image/{{ tag.image_id }}?tab=vulnerabilities"
data-title="This tag has {{ getTagVulnerabilities(tag).vulnerabilities.length }} vulnerabilities across {{ getTagVulnerabilities(tag).featuresInfo.brokenFeaturesCount }} packages"
bs-tooltip>
<!-- Donut -->
<span class="donut-chart" width="24" data="getTagVulnerabilities(tag).featuresInfo.severityBreakdown"></span>
<!-- Messaging -->
<span ng-if="getTagVulnerabilities(tag).featuresInfo.fixableFeatureCount == 0">
{{ getTagVulnerabilities(tag).featuresInfo.brokenFeaturesCount }} vulnerable package<span ng-if="getTagVulnerabilities(tag).featuresInfo.brokenFeaturesCount != 1">s</span>
</span>
<span ng-if="getTagVulnerabilities(tag).featuresInfo.fixableFeatureCount > 0">
{{ getTagVulnerabilities(tag).featuresInfo.fixableFeatureCount }} fixable package<span ng-if="getTagVulnerabilities(tag).featuresInfo.fixableFeatureCount != 1">s</span>
</span>
</a>
</span>
</span>
</td>
<td class="hidden-xs hidden-sm image-track" ng-repeat="it in imageTracks"
ng-if="imageTracks.length <= maxTrackCount" bindonce>
<span ng-repeat="entry in it.entries">
<span class="image-track-dot" bo-if="entry.image_id == tag.image_id"
bo-style="{'borderColor': entry.color}" ng-click="selectTrack(entry)"></span>
<span class="image-track-line" bo-class="trackLineClass($parent.$parent.$parent.$index, entry)"
bo-style="{'borderColor': entry.color}"></span>
</span>
</td>
<td class="options-col">
<i class="fa fa-download" data-title="Fetch Tag" bs-tooltip
ng-click="fetchTagActionHandler.askFetchTag(tag)">
</i>
</td>
<td class="options-col">
<span bo-if="repository.can_write">
<span class="cor-options-menu">
<span class="cor-option" option-click="askAddTag(tag)">
<i class="fa fa-plus"></i> Add New Tag
</td>
<td class="hidden-sm hidden-xs" bo-text="tag.size | bytes"></td>
<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>
</td>
<td class="hidden-xs hidden-sm image-track"
ng-if="imageTracks.length > maxTrackCount" bindonce>
<span ng-repeat="it in imageTracks">
<span ng-repeat="entry in it.entries">
<span class="image-track-dot" bo-if="entry.image_id == tag.image_id"
bo-style="{'borderColor': entry.color}" ng-click="selectTrack(entry)"></span>
</span>
</span>
<span class="cor-option" option-click="askDeleteTag(tag.name)">
<i class="fa fa-times"></i> Delete Tag
</td>
<td class="hidden-xs hidden-sm image-track" ng-repeat="it in imageTracks"
ng-if="imageTracks.length <= maxTrackCount" bindonce>
<span ng-repeat="entry in it.entries">
<span class="image-track-dot" bo-if="entry.image_id == tag.image_id"
bo-style="{'borderColor': entry.color}" ng-click="selectTrack(entry)"></span>
<span class="image-track-line" bo-class="trackLineClass($parent.$parent.$parent.$index, entry)"
bo-style="{'borderColor': entry.color}"></span>
</span>
</td>
<td class="options-col">
<i class="fa fa-download" data-title="Fetch Tag" bs-tooltip
ng-click="fetchTagActionHandler.askFetchTag(tag)">
</i>
</td>
<td class="options-col">
<span bo-if="repository.can_write">
<span class="cor-options-menu">
<span class="cor-option" option-click="askAddTag(tag)">
<i class="fa fa-plus"></i> Add New Tag
</span>
<span class="cor-option" option-click="askDeleteTag(tag.name)">
<i class="fa fa-times"></i> Delete Tag
</span>
</span>
</span>
</span>
</td>
<td class="options-col hidden-xs hidden-sm"><!-- Whitespace col --></td>
</tr>
</td>
<td class="options-col hidden-xs hidden-sm"><!-- Whitespace col --></td>
</tr>
<tr ng-if="expandedView">
<td class="checkbox-col"></td>
<td class="labels-col" colspan="{{5 + (Features.SECURITY_SCANNER ? 1 : 0)}}">
<div class="manifest-label-list" repository="repository"
manifest-digest="tag.manifest_digest"></div>
</td>
<td class="hidden-xs hidden-sm image-track" ng-repeat="it in imageTracks"
ng-if="imageTracks.length <= maxTrackCount" bindonce>
<span ng-repeat="entry in it.entries">
<span class="image-track-line"
bo-class="trackLineExpandedClass($parent.$parent.$parent.$index, entry)"
bo-style="{'borderColor': entry.color}"></span>
</span>
</td>
<td colspan="2"></td>
</tr>
</tbody>
</table>
<div class="empty" ng-if="allTags.length && !tags.length">