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;
});

View file

@ -13,7 +13,7 @@ angular.module('quay').directive('repoListGrid', function () {
starred: '=starred',
user: "=user",
namespace: '=namespace',
toggleStar: '&toggleStar'
starToggled: '&starToggled'
},
controller: function($scope, $element, UserService) {
$scope.isOrganization = function(namespace) {

View file

@ -0,0 +1,53 @@
/**
* An element that displays the star status of a repository and allows it to be toggled.
*/
angular.module('quay').directive('repoStar', function () {
var directiveDefinitionObject = {
priority: 0,
templateUrl: '/static/directives/repo-star.html',
replace: false,
transclude: true,
restrict: 'C',
scope: {
repository: '=repository',
starToggled: '&starToggled'
},
controller: function($scope, $element, UserService, ApiService) {
// Star a repository or unstar a repository.
$scope.toggleStar = function() {
if ($scope.repository.is_starred) {
unstarRepo();
} else {
starRepo();
}
};
// Star a repository and update the UI.
var starRepo = function() {
var data = {
'namespace': $scope.repository.namespace,
'repository': $scope.repository.name
};
ApiService.createStar(data).then(function(result) {
$scope.repository.is_starred = true;
$scope.starToggled({'repository': $scope.repository});
}, ApiService.errorDisplay('Could not star repository'));
};
// Unstar a repository and update the UI.
var unstarRepo = function(repo) {
var data = {
'repository': $scope.repository.namespace + '/' + $scope.repository.name
};
ApiService.deleteStar(null, data).then(function(result) {
$scope.repository.is_starred = false;
$scope.starToggled({'repository': $scope.repository});
}, ApiService.errorDisplay('Could not unstar repository'));
};
}
};
return directiveDefinitionObject;
});

View file

@ -27,7 +27,7 @@ angular.module('quay').directive('resourceView', function () {
return 'loading';
}
if (current.error) {
if (current.hasError) {
return 'error';
}
}