#214: updated #branches page, integrated AngularJS
This commit is contained in:
parent
6c6b73ada9
commit
d747ffd070
5
Gemfile
5
Gemfile
|
@ -58,6 +58,11 @@ gem 'rest-client', '~> 1.6.6'
|
|||
gem 'attr_encrypted', '1.2.1'
|
||||
gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
|
||||
|
||||
# AngularJS related stuff
|
||||
gem 'angularjs-rails'
|
||||
gem 'ng-rails-csrf'
|
||||
# gem 'angularjs-rails-resource'
|
||||
|
||||
group :assets do
|
||||
gem 'sass-rails', '~> 3.2.5'
|
||||
gem 'coffee-rails', '~> 3.2.2'
|
||||
|
|
|
@ -58,6 +58,8 @@ GEM
|
|||
json
|
||||
ancestry (1.3.0)
|
||||
activerecord (>= 2.3.14)
|
||||
angularjs-rails (1.0.7)
|
||||
angularjs-rails-resource (0.2.0)
|
||||
arel (3.0.2)
|
||||
attr_encrypted (1.2.1)
|
||||
encryptor (>= 1.1.1)
|
||||
|
@ -209,6 +211,7 @@ GEM
|
|||
net-ssh-gateway (1.2.0)
|
||||
net-ssh (>= 2.6.5)
|
||||
newrelic_rpm (3.5.5.38)
|
||||
ng-rails-csrf (0.1.0)
|
||||
nokogiri (1.5.9)
|
||||
oauth2 (0.8.1)
|
||||
faraday (~> 0.8)
|
||||
|
@ -407,6 +410,8 @@ DEPENDENCIES
|
|||
RedCloth
|
||||
airbrake (~> 3.1.2)
|
||||
ancestry (~> 1.3.0)
|
||||
angularjs-rails
|
||||
angularjs-rails-resource
|
||||
attr_encrypted (= 1.2.1)
|
||||
better_errors
|
||||
binding_of_caller
|
||||
|
@ -437,6 +442,7 @@ DEPENDENCIES
|
|||
meta_request
|
||||
mock_redis (= 0.6.2)
|
||||
newrelic_rpm (~> 3.5.5.38)
|
||||
ng-rails-csrf
|
||||
omniauth
|
||||
omniauth-facebook
|
||||
omniauth-github
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
var RosaABF = angular.module('RosaABF', ['ngResource', 'ng-rails-csrf']);
|
|
@ -0,0 +1,44 @@
|
|||
RosaABF.controller('ProjectRefsController', function($scope, $http, $location, ApiProject) {
|
||||
|
||||
$scope.branches = [];
|
||||
$scope.tags = [];
|
||||
$scope.project_id = null;
|
||||
$scope.current_ref = null;
|
||||
|
||||
$scope.init = function(project_id, ref) {
|
||||
$scope.project_id = project_id;
|
||||
$scope.current_ref = ref;
|
||||
ApiProject.project($scope.project_id, function(result){
|
||||
$scope.project = result;
|
||||
});
|
||||
$scope.getRefs();
|
||||
}
|
||||
|
||||
$scope.getRefs = function() {
|
||||
//returns [ProjectRef, ProjectRef, ...]
|
||||
ApiProject.refs($scope.project_id, function(results){
|
||||
_.each(results, function(result){
|
||||
if (result.isTag) {
|
||||
if (result.ref == $scope.current_ref) {
|
||||
$scope.tags.unshift(result);
|
||||
} else {
|
||||
$scope.tags.push(result);
|
||||
}
|
||||
} else {
|
||||
if (result.ref == $scope.current_ref) {
|
||||
$scope.branches.unshift(result);
|
||||
} else {
|
||||
$scope.branches.push(result);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.destroy = function(branch) {
|
||||
var path = $location.$$absUrl.replace(/\/[\w\-]+$/, '') + '/' + branch.name;
|
||||
$http.delete(path).success(function(data) {
|
||||
$scope.getRefs();
|
||||
});
|
||||
}
|
||||
});
|
|
@ -0,0 +1,14 @@
|
|||
var Project = function(atts){
|
||||
var self = this;
|
||||
var initialSettings = atts || {};
|
||||
//initial settings if passed in
|
||||
for(var setting in initialSettings){
|
||||
if(initialSettings.hasOwnProperty(setting))
|
||||
self[setting] = initialSettings[setting];
|
||||
};
|
||||
|
||||
//with some logic...
|
||||
|
||||
//return the scope-safe instance
|
||||
return self;
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
var ProjectRef = function(atts) {
|
||||
var self = this;
|
||||
var initialSettings = atts || {};
|
||||
//initial settings if passed in
|
||||
for(var setting in initialSettings){
|
||||
if(initialSettings.hasOwnProperty(setting))
|
||||
self[setting] = initialSettings[setting];
|
||||
};
|
||||
|
||||
|
||||
|
||||
//with some logic...
|
||||
self.isTag = self.object.type == 'tag';
|
||||
|
||||
self.path = function(project) {
|
||||
return '/' + project.fullname + '/tree/' + self.ref;
|
||||
}
|
||||
|
||||
self.diff_path = function(project, current_ref) {
|
||||
return '/' + project.fullname + '/diff/' + current_ref + '...' + self.ref;
|
||||
}
|
||||
|
||||
//return the scope-safe instance
|
||||
return self;
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
var ApiProject = function($resource) {
|
||||
|
||||
var projectResource = $resource('/api/v1/projects/:project_id.json');
|
||||
var queryProject = function(project_id, next) {
|
||||
projectResource.get({project_id: project_id}, function(results){
|
||||
next(new Project(results.project));
|
||||
});
|
||||
};
|
||||
|
||||
var refsResource = $resource('/api/v1/projects/:project_id/refs_list.json');
|
||||
var queryRefs = function(project_id, next) {
|
||||
//use a callback instead of a promise
|
||||
refsResource.get({project_id: project_id}, function(results) {
|
||||
var out = [];
|
||||
//Underscore's "each" method
|
||||
_.each(results.refs_list, function(ref){
|
||||
//using our ProjectRef(ref) prototype above
|
||||
out.push(new ProjectRef(ref));
|
||||
});
|
||||
next(out);
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
refs : queryRefs,
|
||||
project : queryProject
|
||||
}
|
||||
}
|
||||
|
||||
RosaABF.factory("ApiProject", ApiProject);
|
|
@ -13,6 +13,11 @@
|
|||
//= require backbone_rails_sync
|
||||
//= require backbone_datalink
|
||||
//= require backbone/rosa
|
||||
//= require angular
|
||||
//= require angular-resource
|
||||
// require angularjs/rails/resource
|
||||
//= require ng-rails-csrf
|
||||
//= require_tree ./angularjs
|
||||
//= require_self
|
||||
|
||||
function disableNotifierCbx(global_cbx) {
|
||||
|
|
|
@ -2,7 +2,11 @@
|
|||
class Projects::Git::BaseController < Projects::BaseController
|
||||
before_filter :authenticate_user!
|
||||
skip_before_filter :authenticate_user!, :only => [:show, :index, :blame, :raw, :archive, :diff, :tags, :branches] if APP_CONFIG['anonymous_access']
|
||||
load_and_authorize_resource :project
|
||||
|
||||
load_and_authorize_resource :project, :except => :destroy
|
||||
load_resource :project, :only => :destroy
|
||||
before_filter lambda { authorize!(:write, @project) }, :only => :destroy
|
||||
|
||||
|
||||
before_filter :set_treeish_and_path
|
||||
before_filter :set_branch_and_tree
|
||||
|
|
|
@ -32,10 +32,26 @@ class Projects::Git::TreesController < Projects::Git::BaseController
|
|||
render 'refs'
|
||||
end
|
||||
|
||||
def destroy
|
||||
render :nothing => true
|
||||
end
|
||||
|
||||
def branches
|
||||
raise Grit::NoSuchPathError if params[:treeish] != @branch.try(:name) # get wrong branch name to nonempty project
|
||||
if request.xhr?
|
||||
@branches = @project.repo.branches.sort_by(&:name).select{ |b| b.name != @branch.name }.unshift(@branch).compact if @branch
|
||||
@branches = @branches.map do |branch|
|
||||
{
|
||||
:name => branch.name,
|
||||
:path => tree_path(@project, branch.name),
|
||||
:current => (branch.name == @branch.try(:name)),
|
||||
:diff_path => diff_path(@project, "#{@branch.name}...#{branch.name}")
|
||||
}
|
||||
end
|
||||
render :json => @branches
|
||||
else
|
||||
render 'refs'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
- if user_signed_in?
|
||||
= auto_discovery_link_tag :atom, atom_activity_feeds_path(:format => 'atom', :token => current_user.authentication_token), :title => t("layout.atom_link_tag_title", :nickname => current_user.uname, :app_name => APP_CONFIG['project_name'])
|
||||
|
||||
%body
|
||||
%body{'ng-app' => 'RosaABF'}
|
||||
.wrap{:class => content_for?(:sidebar) ? 'columns' : ''}
|
||||
%header
|
||||
.left
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
- if subject.blank?
|
||||
%p= t("layout.projects.no_#{subjects_name}")
|
||||
- elsif subject.count == 1
|
||||
%p= t("layout.projects.showing_#{subjects_name.singularize}")
|
||||
%p= t("layout.projects.total_#{subjects_name.singularize}")
|
||||
- else
|
||||
%p= t("layout.projects.showing_#{subjects_name}", :count => subject.count)
|
||||
%p= t("layout.projects.total_#{subjects_name}", :count => subject.count)
|
||||
.both
|
|
@ -4,11 +4,35 @@
|
|||
= render 'repo_block', :project => @project
|
||||
= render 'header', :subject => (@branches || @tags)
|
||||
|
||||
|
||||
%div{'ng-controller' => 'ProjectRefsController',
|
||||
'ng-init' => "init('#{@project.id}','#{@branch.try(:name)}')"}
|
||||
|
||||
.both
|
||||
Search:
|
||||
%input{'ng-model' => 'query.ref'}
|
||||
.both
|
||||
|
||||
%table#project-branches
|
||||
%tbody
|
||||
%tr{'ng-repeat' => 'branch in branches | filter:query', 'ng-class' => '{base: branch.ref == current_ref}'}
|
||||
%td.name
|
||||
%a{'ng-href' => '{{branch.path(project)}}' } {{branch.ref}}
|
||||
%td.actions
|
||||
%ul.actions
|
||||
%li.text{'ng-show' => 'branch.ref == current_ref'}
|
||||
= t('layout.projects.base_branch')
|
||||
%li{'ng-hide' => 'branch.ref == current_ref'}
|
||||
%a{:href => '#', 'ng-click' => 'destroy(branch)'}= t('layout.projects.delete_branch')
|
||||
%li{'ng-hide' => 'branch.ref == current_ref'}
|
||||
%a{'ng-href' => '{{branch.diff_path(project, current_ref)}}' }= t('layout.projects.compare')
|
||||
|
||||
|
||||
- if @tags.present?
|
||||
%div#project-tags
|
||||
%ol.release-list
|
||||
= render :partial => 'tag', :collection => @tags
|
||||
- elsif @branches.present?
|
||||
- elsif false # @branches.present?
|
||||
%table#project-branches
|
||||
%tbody
|
||||
= render :partial => 'branch', :collection => @branches
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
.flash
|
||||
%div{:class => @pull.ready? ? 'notice' : 'alert'}
|
||||
=pull_status @pull
|
||||
wwwww
|
||||
-if can? :update, @pull
|
||||
-if action = @pull.can_close? ? 'close' : ('reopen' if @pull.can_reopen?)
|
||||
%br
|
||||
|
|
|
@ -2,16 +2,17 @@ en:
|
|||
layout:
|
||||
projects:
|
||||
branches: Branches
|
||||
showing_branches: Showing %{count} branches
|
||||
showing_branch: Showing 1 branch
|
||||
delete_branch: Delete branch
|
||||
total_branches: Total %{count} branches
|
||||
total_branch: Total 1 branch
|
||||
no_branches: No branches
|
||||
base_branch: Base branch
|
||||
compare: Compare
|
||||
browse_code: Browse code
|
||||
source_code: Source code (%{type})
|
||||
tags: Tags
|
||||
showing_tags: Showing %{count} tags
|
||||
showing_tag: Showing 1 tag
|
||||
total_tags: Total %{count} tags
|
||||
total_tag: Total 1 tag
|
||||
no_tags: No tags
|
||||
add: Add
|
||||
public_projects_list: Public projects list
|
||||
|
|
|
@ -2,16 +2,17 @@ ru:
|
|||
layout:
|
||||
projects:
|
||||
branches: Ветки
|
||||
showing_branches: Показано %{count} веток
|
||||
showing_branch: Показана 1 ветка
|
||||
delete_branch: Удалить ветку
|
||||
total_branches: Всего %{count} веток
|
||||
total_branch: Всего 1 ветка
|
||||
no_branch: Нет веток
|
||||
base_branch: Текущая ветка
|
||||
compare: Сравнить
|
||||
browse_code: Просмотреть код
|
||||
source_code: Исходный код (%{type})
|
||||
tags: Теги
|
||||
showing_tags: Показано %{count} тегов
|
||||
showing_tag: Показан 1 тег
|
||||
total_tags: Всего %{count} тегов
|
||||
total_tag: Всего 1 тег
|
||||
no_tags: Нет тегов
|
||||
add: Добавить
|
||||
public_projects_list: Список публичных проектов
|
||||
|
|
|
@ -331,8 +331,10 @@ Rosa::Application.routes.draw do
|
|||
get '/tree/:treeish(/*path)' => "git/trees#show", :as => :tree, :format => false
|
||||
# Tags
|
||||
get '/tags' => "git/trees#tags", :as => :tags
|
||||
# delete '/tags/:treeish' => "git/trees#destroy", :as => :tags
|
||||
# Branches
|
||||
get '/branches/:treeish' => "git/trees#branches", :as => :branches
|
||||
# delete '/branches/:treeish' => "git/trees#destroy", :as => :branches
|
||||
# Commits
|
||||
get '/commits/:treeish(/*path)' => "git/commits#index", :as => :commits, :format => false
|
||||
get '/commit/:id(.:format)' => "git/commits#show", :as => :commit
|
||||
|
|
Loading…
Reference in New Issue