feat(image-details): simple image history (#425)

pull/1007/head
Gábor Kovács 7 years ago committed by Anthony Lapenna
parent 6d6f4f092d
commit b6b579d55d

@ -167,3 +167,42 @@
</rd-widget>
</div>
</div>
<div class="row" ng-if="history.length > 0">
<div class="col-lg-12 col-md-12 col-xs-12">
<rd-widget>
<rd-widget-header icon="fa-clone" title="Image layers"></rd-widget-header>
<rd-widget-body classes="no-padding">
<table id="image-layers" class="table">
<thead>
<tr>
<td>Size</td>
<td>Layer</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="layer in history">
<td style="white-space:nowrap;">{{layer.Size|humansize}}</td>
<td class="expand">
<div ng-if="layer.CreatedBy.length > 100">
<span id="layer-command-{{$index}}-full" style="display: none">
{{layer.CreatedBy|createdby}}
</span>
<span id="layer-command-{{$index}}-short">
{{layer.CreatedBy|createdby|limitTo:100}}{{layer.CreatedBy.length > 100 ? '...' : ''}}
</span>
</div>
<div ng-if="layer.CreatedBy.length <= 100">
<span id="layer-command-{{$index}}-full">
{{layer.CreatedBy|createdby}}
</span>
</div>
<div ng-if="layer.CreatedBy.length > 100"><a id="layer-command-expander{{$index}}" class="btn" ng-click='toggleLayerCommand($index)'><span class="glyphicon glyphicon-plus-sign"></span></a></div>
</td>
</tr>
</tbody>
</table>
</rd-widget-body>
</rd-widget>
</div>
</div>

@ -6,6 +6,12 @@ function ($scope, $stateParams, $state, $timeout, ImageService, RegistryService,
Registry: ''
};
$scope.toggleLayerCommand = function(layerId) {
$('#layer-command-expander'+layerId+' span').toggleClass('glyphicon-plus-sign glyphicon-minus-sign');
$('#layer-command-'+layerId+'-short').toggle();
$('#layer-command-'+layerId+'-full').toggle();
};
$scope.tagImage = function() {
$('#loadingViewSpinner').show();
var image = $scope.formValues.Image;
@ -108,6 +114,18 @@ function ($scope, $stateParams, $state, $timeout, ImageService, RegistryService,
.finally(function final() {
$('#loadingViewSpinner').hide();
});
$('#loadingViewSpinner').show();
ImageService.history($stateParams.id)
.then(function success(data) {
$scope.history = data;
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve image history');
})
.finally(function final() {
$('#loadingViewSpinner').hide();
});
}
retrieveImageDetails();

@ -271,4 +271,10 @@ angular.module('portainer.filters', [])
}
return '';
};
})
.filter('createdby', function () {
'use strict';
return function (createdBy) {
return createdBy.replace('/bin/sh -c #(nop) ','').replace('/bin/sh -c ', 'RUN ');
};
});

@ -0,0 +1,8 @@
function ImageLayerViewModel(data) {
this.Id = data.Id;
this.Created = data.Created;
this.CreatedBy = data.CreatedBy;
this.Size = data.Size;
this.Comment = data.Comment;
this.Tags = data.Tags;
}

@ -35,6 +35,26 @@ angular.module('portainer.services')
return deferred.promise;
};
service.history = function(imageId) {
var deferred = $q.defer();
Image.history({id: imageId}).$promise
.then(function success(data) {
if (data.message) {
deferred.reject({ msg: data.message });
} else {
var layers = [];
angular.forEach(data, function(imageLayer) {
layers.push(new ImageLayerViewModel(imageLayer));
});
deferred.resolve(layers);
}
})
.catch(function error(err) {
deferred.reject({ msg: 'Unable to retrieve image details', err: err });
});
return deferred.promise;
};
service.pushImage = function(tag, registry) {
var deferred = $q.defer();

@ -281,14 +281,6 @@ a[ng-click]{
margin: 0 auto;
}
ul.sidebar {
bottom: 40px;
}
ul.sidebar .sidebar-title {
height: auto;
}
ul.sidebar .sidebar-list a.active {
color: #fff;
text-indent: 22px;
@ -296,6 +288,14 @@ ul.sidebar .sidebar-list a.active {
background: #2d3e63;
}
#image-layers .btn{
padding: 0;
}
#image-layers .expand{
padding-right: 0;
}
ul.sidebar .sidebar-list .sidebar-sublist a {
text-indent: 35px;
font-size: 12px;

Loading…
Cancel
Save