[issue #195] Added AJAX to /projects list.
This commit is contained in:
parent
a3aaf4f7ce
commit
9bb1d80172
2
Gemfile
2
Gemfile
|
@ -19,6 +19,8 @@ gem 'russian', '~> 0.6.0'
|
|||
gem 'highline', '~> 1.6.11'
|
||||
gem 'rails-xmlrpc', '~> 0.3.6' # :git => 'git://github.com/chipiga/rails-xmlrpc.git'
|
||||
|
||||
gem 'jbuilder'
|
||||
|
||||
# gem 'rugged', '~> 0.16.0'
|
||||
gem 'grack', :git => 'git://github.com/rdblue/grack.git', :require => 'git_http'
|
||||
gem "grit", :git => 'git://github.com/chipiga/grit.git'
|
||||
|
|
|
@ -63,6 +63,7 @@ GEM
|
|||
arel (3.0.2)
|
||||
bcrypt-ruby (3.0.1)
|
||||
bcrypt-ruby (3.0.1-java)
|
||||
blankslate (2.1.2.4)
|
||||
bluepill (0.0.60)
|
||||
activesupport (>= 3.0.0)
|
||||
daemons (~> 1.1.4, <= 1.1.6)
|
||||
|
@ -141,6 +142,9 @@ GEM
|
|||
hike (1.2.1)
|
||||
hirb (0.6.2)
|
||||
i18n (0.6.0)
|
||||
jbuilder (0.4.0)
|
||||
activesupport (>= 3.0.0)
|
||||
blankslate (>= 2.1.2.4)
|
||||
journey (1.0.3)
|
||||
jquery-rails (2.0.1)
|
||||
railties (>= 3.2.0, < 5.0)
|
||||
|
@ -336,6 +340,7 @@ DEPENDENCIES
|
|||
haml-rails (~> 0.3.4)
|
||||
highline (~> 1.6.11)
|
||||
hirb
|
||||
jbuilder
|
||||
jquery-rails (~> 2.0.1)
|
||||
mailcatcher
|
||||
meta-tags (~> 1.2.5)
|
||||
|
|
|
@ -636,6 +636,10 @@ ul.ui-autocomplete {
|
|||
z-index: 999 !important;
|
||||
}
|
||||
|
||||
table.dataTable {
|
||||
margin: 10px 0 15px;
|
||||
}
|
||||
|
||||
table.tablesorter tr.search th {
|
||||
background: none repeat scroll 0 0 #DCECFA;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,13 @@ class ProjectsController < ApplicationController
|
|||
load_and_authorize_resource
|
||||
|
||||
def index
|
||||
@projects = Project.accessible_by(current_ability, :members).recent.paginate(:page => params[:page])
|
||||
@projects = Project.accessible_by(current_ability, :members)
|
||||
|
||||
#puts prepare_list(@projects).inspect
|
||||
respond_to do |format|
|
||||
format.html { @projects = @projects.recent.paginate(:page => params[:page], :per_page => 25) }
|
||||
format.json { @projects = prepare_list(@projects) }
|
||||
end
|
||||
# @projects = @projects.search(params[:query]).search_order if params[:query]
|
||||
end
|
||||
|
||||
|
@ -78,6 +84,32 @@ class ProjectsController < ApplicationController
|
|||
|
||||
protected
|
||||
|
||||
def prepare_list(projects)
|
||||
res = {}
|
||||
|
||||
colName = ['name']
|
||||
sort_col = params[:iSortCol_0] || 0
|
||||
sort_dir = params[:sSortDir_0] == "desc" ? 'desc' : 'asc'
|
||||
order = "#{colName[sort_col.to_i]} #{sort_dir}"
|
||||
|
||||
res[:total_count] = projects.count
|
||||
projects = projects.where(['projects.name ILIKE ?', "%#{ params[:sSearch] }%"]) if params[:sSearch] and !params[:sSearch].empty?
|
||||
res[:filtered_count] = projects.count
|
||||
|
||||
projects = projects.order(order)
|
||||
res[:projects] = if params[:iDisplayLength].present?
|
||||
start = params[:iDisplayStart].present? ? params[:iDisplayStart].to_i : 0
|
||||
length = params[:iDisplayLength].to_i
|
||||
page = start/length + 1
|
||||
|
||||
projects.paginate(:page => page, :per_page => length)
|
||||
else
|
||||
projects
|
||||
end
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
def choose_owner
|
||||
if params[:who_owns] == 'group'
|
||||
Group.find(params[:owner_id])
|
||||
|
|
|
@ -2,7 +2,13 @@
|
|||
%td
|
||||
= link_to project do
|
||||
.table-sort-left= image_tag visibility_icon(project.visibility)
|
||||
.table-sort-right #{project.owner.uname} / #{project.name}
|
||||
.table-sort-right
|
||||
= link_to project.owner.uname, project.owner.class == User ? user_path(project.owner) : group_path(project.owner) #{project.owner.uname} / #{project.name}
|
||||
#{ ' / ' }
|
||||
= link_to project.name, project_path(project)
|
||||
%td.td2= project.description
|
||||
%td= t("layout.collaborators.role_names.#{project.relations.by_user_through_groups(current_user).first.role}")
|
||||
%td.td5= link_to image_tag('x.png'), remove_user_project_path(project), :method => :delete, :confirm => t("layout.confirm") unless project.owner == current_user
|
||||
%td.td5
|
||||
- unless project.owner == current_user
|
||||
= link_to remove_user_project_path(project), :method => :delete, :confirm => t("layout.confirm") do
|
||||
%span.delete
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
json.project do |proj|
|
||||
proj.visibility project.visibility.to_s
|
||||
|
||||
proj.name project.name
|
||||
proj.description project.description
|
||||
proj.link project_path(project)
|
||||
|
||||
proj.role t("layout.collaborators.role_names.#{project.relations.by_user_through_groups(current_user).first.role}").force_encoding(Encoding::UTF_8)
|
||||
|
||||
proj.leave_link remove_user_project_path(project) unless project.owner == current_user
|
||||
|
||||
proj.owner do |owner|
|
||||
owner.name project.owner.uname
|
||||
owner.type project.owner.class.to_s.underscore
|
||||
owner.link project.owner.class == User ? user_path(project.owner) : group_path(project.owner)
|
||||
end
|
||||
end
|
|
@ -30,6 +30,46 @@
|
|||
:javascript
|
||||
$(document).ready(function() {
|
||||
|
||||
var JsonParser = function (json) {
|
||||
|
||||
var firstColumn = function(row) {
|
||||
var project = row.project
|
||||
|
||||
var image = '<img alt="' + project.visibility + '" src="' + icons.visibilities[project.visibility] + '" />';
|
||||
|
||||
var owner = '<a href="' + project.owner.link + '">' + project.owner.name + '</a>';
|
||||
var project = '<a href="' + project.link + '">' + project.name + '</a>';
|
||||
|
||||
return '<div class="table-sort-left">' + image + "</div>\n" +
|
||||
'<div class="table-sort-right">' + owner + ' / ' + project + '<div>';
|
||||
}
|
||||
|
||||
var lastColumn = function(row) {
|
||||
var project = row.project
|
||||
var res = '';
|
||||
if (project.leave_link !== undefined) {
|
||||
res = '<a href="' + project.leave_link + '" data-method="delete" rel="nofollow" data-confirm="' + messages.remove_confirm + '">' +
|
||||
'<span class="delete"> </span></a>';
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
var icons = json.icons;
|
||||
var messages = json.messages;
|
||||
|
||||
var res = [];
|
||||
for ( var i=0, iLen=json.aaData.length ; i<iLen ; i++ ) {
|
||||
var data = json.aaData[i];
|
||||
var inner = [];
|
||||
inner.push( firstColumn(data) );
|
||||
inner.push( data.project.description );
|
||||
inner.push( data.project.role );
|
||||
inner.push( lastColumn(data) );
|
||||
res.push( inner );
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
var oTable = $('#datatable').dataTable({
|
||||
"oLanguage": {
|
||||
#{t("datatables.full")}
|
||||
|
@ -39,9 +79,19 @@
|
|||
"bLengthChange": false,
|
||||
"aaSorting": [[ 0, 'asc' ]],
|
||||
"sDom": 'rtip',
|
||||
"bServerSide": true,
|
||||
"sAjaxSource": "#{ projects_path :format => :json }",
|
||||
"iDeferLoading": #{ @projects.count },
|
||||
"aoColumns": [
|
||||
#{ format_columns_for_datatable(columns) }
|
||||
]
|
||||
],
|
||||
"fnServerData": function ( sSource, aoData, fnCallback ) {
|
||||
$.getJSON( sSource, aoData, function (json) {
|
||||
json.aaData = JsonParser(json);
|
||||
fnCallback(json);
|
||||
} );
|
||||
}
|
||||
|
||||
});
|
||||
$('#datatable_wrapper').append("<div class='both'></div>");
|
||||
|
||||
|
@ -63,7 +113,9 @@
|
|||
return true;
|
||||
});
|
||||
$search.live('keyup', function() {
|
||||
oTable.fnFilter(this.value);
|
||||
if (this.value.length > 1) {
|
||||
oTable.fnFilter(this.value);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
json.sEcho h(params[:sEcho].to_i || -1)
|
||||
json.iTotalRecords @projects[:total_count]
|
||||
json.iTotalDisplayRecords @projects[:filtered_count]
|
||||
|
||||
json.messages do |msg|
|
||||
msg.remove_confirm t("layout.confirm")
|
||||
end
|
||||
|
||||
json.icons do |icons|
|
||||
icons.visibilities do |vis|
|
||||
Project::VISIBILITIES.each do |visibility|
|
||||
vis.set!(visibility, image_path(visibility_icon(visibility)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
json.aaData do |aadata|
|
||||
aadata.array!(@projects[:projects]) do |json, proj|
|
||||
json.partial! 'project', :project => proj
|
||||
end
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
en:
|
||||
datatables:
|
||||
full: |
|
||||
"sProcessing": "Wait...",
|
||||
"sZeroRecords": "No data accessible",
|
||||
"sInfo": "Records displayed from _START_ to _END_ total _TOTAL_",
|
||||
"sInfoEmpty": "Records displayed from 0 to 0 total 0",
|
||||
"sInfoFiltered": "(filtered from _MAX_)",
|
||||
"sInfoPostFix": "",
|
||||
"sUrl": "",
|
||||
"oPaginate": {
|
||||
"sFirst": "« First",
|
||||
"sPrevious": "‹ Previous",
|
||||
"sNext": "Next ›",
|
||||
"sLast": "Last »"
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
ru:
|
||||
datatables:
|
||||
full: |
|
||||
"sProcessing": "Подождите...",
|
||||
"sZeroRecords": "Нет доступных данных",
|
||||
"sInfo": "Показаны записи с _START_ по _END_ из _TOTAL_",
|
||||
"sInfoEmpty": "Показаны записи с 0 до 0 из 0",
|
||||
"sInfoFiltered": "(отфильтровано из _MAX_)",
|
||||
"sInfoPostFix": "",
|
||||
"sUrl": "",
|
||||
"oPaginate": {
|
||||
"sFirst": "« Первая",
|
||||
"sPrevious": "‹ Предыдущая",
|
||||
"sNext": "Следующая ›",
|
||||
"sLast": "Последняя »"
|
||||
}
|
Loading…
Reference in New Issue