Start on new tag view

This commit is contained in:
Joseph Schorr 2015-03-09 22:03:39 -07:00
parent 581a284744
commit afc8e95e19
103 changed files with 148505 additions and 458 deletions

View file

@ -0,0 +1,23 @@
/**
* An element which displays the information panel for a repository view.
*/
angular.module('quay').directive('repoPanelInfo', function () {
var directiveDefinitionObject = {
priority: 0,
templateUrl: '/static/directives/repo-view/repo-panel-info.html',
replace: false,
transclude: false,
restrict: 'C',
scope: {
'repository': '=repository'
},
controller: function($scope, $element, ApiService) {
$scope.updateDescription = function(content) {
$scope.repository.description = content;
$scope.repository.put();
};
}
};
return directiveDefinitionObject;
});

View file

@ -0,0 +1,222 @@
/**
* An element which displays the tags panel for a repository view.
*/
angular.module('quay').directive('repoPanelTags', function () {
var directiveDefinitionObject = {
priority: 0,
templateUrl: '/static/directives/repo-view/repo-panel-tags.html',
replace: false,
transclude: false,
restrict: 'C',
scope: {
'repository': '=repository',
'repositoryUpdated': '&repositoryUpdated'
},
controller: function($scope, $element, $filter, ApiService, UIService) {
var orderBy = $filter('orderBy');
$scope.checkedTags = UIService.createCheckStateController([]);
$scope.options = {
'predicate': 'last_modified_datetime',
'reverse': false
};
$scope.iterationState = {};
var loadImages = function() {
var params = {
'repository': $scope.repository.namespace + '/' + $scope.repository.name
};
$scope.imagesResource = ApiService.listRepositoryImagesAsResource(params).get(function(resp) {
$scope.images = resp.images;
});
};
var setTagState = function() {
if (!$scope.repository) { return; }
var tags = [];
var allTags = [];
var imageMap = {};
var imageTracks = [];
// Build a list of tags and filtered tags.
for (var tag in $scope.repository.tags) {
if (!$scope.repository.tags.hasOwnProperty(tag)) { continue; }
var tagInfo = $.extend($scope.repository.tags[tag], {
'name': tag,
'last_modified_datetime': new Date($scope.repository.tags[tag].last_modified)
});
allTags.push(tagInfo);
if (!$scope.options.tagFilter || tag.indexOf($scope.options.tagFilter) >= 0 ||
tagInfo.image_id.indexOf($scope.options.tagFilter) >= 0) {
tags.push(tagInfo);
}
}
// Sort the tags by the predicate and the reverse, and map the information.
var ordered = orderBy(tags, $scope.options.predicate, $scope.options.reverse);
for (var i = 0; i < ordered.length; ++i) {
var tagInfo = ordered[i];
if (!imageMap[tagInfo.image_id]) {
imageMap[tagInfo.image_id] = [];
}
imageMap[tagInfo.image_id].push(tagInfo);
};
// Calculate the image tracks.
var colors = d3.scale.category10();
var index = 0;
for (var image_id in imageMap) {
if (imageMap[image_id].length >= 2){
imageTracks.push({
'image_id': image_id,
'color': colors(index),
'count': imageMap[image_id].length,
'tags': imageMap[image_id]
});
++index;
}
}
$scope.imageMap = imageMap;
$scope.imageTracks = imageTracks;
$scope.tags = ordered;
$scope.checkedTags = UIService.createCheckStateController(ordered);
$scope.allTags = allTags;
$scope.iterationState = {};
}
$scope.$watch('options.predicate', setTagState);
$scope.$watch('options.reverse', setTagState);
$scope.$watch('options.tagFilter', setTagState);
$scope.$watch('repository', function(repository) {
if (!repository) { return; }
// Load the repository's images.
loadImages();
// Process each of the tags.
setTagState();
});
$scope.trackLineClass = function(index, track_info) {
var startIndex = $.inArray(track_info.tags[0], $scope.tags);
var endIndex = $.inArray(track_info.tags[track_info.tags.length - 1], $scope.tags);
if (index == startIndex) {
return 'start';
}
if (index == endIndex) {
return 'end';
}
if (index > startIndex && index < endIndex) {
return 'middle';
}
if (index < startIndex) {
return 'before';
}
if (index > endIndex) {
return 'after';
}
};
$scope.tablePredicateClass = function(name, predicate, reverse) {
if (name != predicate) {
return '';
}
return 'current ' + (reverse ? 'reversed' : '');
};
$scope.askDeleteTag = function(tag) {
$scope.deleteTagInfo = {
'tag': tag
};
};
$scope.askDeleteMultipleTags = function(tags) {
$scope.deleteMultipleTagsInfo = {
'tags': tags
};
};
$scope.deleteMultipleTags = function(tags, callback) {
var count = tags.length;
var perform = function(index) {
if (index >= count) {
callback(true);
return;
}
var tag_info = tags[index];
$scope.deleteTag(tag_info.name, function(result) {
if (!result) {
callback(false);
return;
}
perform(index + 1);
});
};
perform(0);
};
$scope.deleteTag = function(tag, callback) {
if (!$scope.repository.can_admin) { return; }
var params = {
'repository': $scope.repository.namespace + '/' + $scope.repository.name,
'tag': tag
};
var errorHandler = ApiService.errorDisplay('Cannot delete tag', callback);
ApiService.deleteFullTag(null, params).then(function() {
callback(true);
$scope.tags = $.grep($scope.tags, function(tagInfo) {
return tagInfo.name != tag;
});
$scope.checkedTags = UIService.createCheckStateController($scope.tags);
$scope.repositoryUpdated({});
}, errorHandler);
};
$scope.orderBy = function(predicate) {
if (predicate == $scope.options.predicate) {
$scope.options.reverse = !$scope.options.reverse;
return;
}
$scope.options.reverse = false;
$scope.options.predicate = predicate;
};
$scope.commitTagFilter = function(tag) {
var r = new RegExp('^[0-9a-f]{7}$');
return tag.name.match(r);
};
$scope.allTagFilter = function(tag) {
return true;
};
$scope.noTagFilter = function(tag) {
return false;
};
}
};
return directiveDefinitionObject;
});