From 782b311983a81e0fa48853029d4d4af13ffb5561 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Thu, 29 Dec 2011 22:16:39 +0400 Subject: [PATCH 1/7] [issue #76] Changed project list in repositories. --- app/views/repositories/_proj_list.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/repositories/_proj_list.html.haml b/app/views/repositories/_proj_list.html.haml index cb3745999..087de3c70 100644 --- a/app/views/repositories/_proj_list.html.haml +++ b/app/views/repositories/_proj_list.html.haml @@ -5,7 +5,7 @@ - @projects.each do |project| %tr{:class => cycle("odd", "even")} %td - = link_to project.owner.name + '/' + project.name, project_path(project) + = link_to project.owner.uname + '/' + project.name, project_path(project) %td.last #{link_to t("layout.show"), project_path(project)} | #{link_to t("layout.add"), url_for(:controller => :repositories, :action => :add_project, :project_id => project.id)} From 7c50b2c3f583b12a24935f5167cd6218c1b2f0b5 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Sat, 31 Dec 2011 02:42:58 +0400 Subject: [PATCH 2/7] [issue #76] Added jQuery DataTable. But it doesn't work yet --- app/controllers/repositories_controller.rb | 27 +++- app/views/repositories/_proj_ajax.js.erb | 12 ++ app/views/repositories/_proj_list.html.haml | 12 +- .../repositories/projects_list.html.haml | 2 +- config/routes.rb | 1 + public/javascripts/jquery.dataTables.min.js | 151 ++++++++++++++++++ vendor/plugins/rails_datatables/MIT-LICENSE | 20 +++ vendor/plugins/rails_datatables/README.md | 138 ++++++++++++++++ vendor/plugins/rails_datatables/Rakefile | 23 +++ vendor/plugins/rails_datatables/init.rb | 1 + vendor/plugins/rails_datatables/install.rb | 1 + .../rails_datatables/lib/rails_datatables.rb | 81 ++++++++++ .../test/rails_datatables_test.rb | 8 + .../rails_datatables/test/test_helper.rb | 3 + vendor/plugins/rails_datatables/uninstall.rb | 1 + 15 files changed, 472 insertions(+), 9 deletions(-) create mode 100644 app/views/repositories/_proj_ajax.js.erb create mode 100644 public/javascripts/jquery.dataTables.min.js create mode 100644 vendor/plugins/rails_datatables/MIT-LICENSE create mode 100644 vendor/plugins/rails_datatables/README.md create mode 100644 vendor/plugins/rails_datatables/Rakefile create mode 100644 vendor/plugins/rails_datatables/init.rb create mode 100644 vendor/plugins/rails_datatables/install.rb create mode 100644 vendor/plugins/rails_datatables/lib/rails_datatables.rb create mode 100644 vendor/plugins/rails_datatables/test/rails_datatables_test.rb create mode 100644 vendor/plugins/rails_datatables/test/test_helper.rb create mode 100644 vendor/plugins/rails_datatables/uninstall.rb diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 8bbca916e..bb6dbdbe5 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -63,15 +63,32 @@ class RepositoriesController < ApplicationController end redirect_to repository_path(@repository) else - if @repository.platform.platform_type == 'main' - @projects = Project.addable_to_repository(@repository.id).by_visibilities(['open']).paginate(:page => params[:project_page]) - else - @projects = Project.addable_to_repository(@repository.id).paginate(:page => params[:project_page]) - end +# if @repository.platform.platform_type == 'main' +# @projects = Project.addable_to_repository(@repository.id).by_visibilities(['open']).paginate(:page => params[:project_page]) +# else +# @projects = Project.addable_to_repository(@repository.id).paginate(:page => params[:project_page]) +# end render 'projects_list' end end + def projects_list + colName = ['owner.uname', 'projects.name'] + sort_col = params[:iSortCol_0] || 0 + sort_dir = params[:sSortDir_0]=="asc" ? 'asc' : 'desc' + order = "#{colName[sort_col.to_i]} #{sort_dir}" + + @projects = Project.addable_to_repository(@repository.id) + @projects = @projects.by_visibilities(['open']) if @repository.platform.platform_type == 'main' + + @total_projects = @projects.count + @projects = @projects.where(['projects.name LIKE ?', "#{params[:sSearch]}%"]) if params[:sSearch] and !params[:sSearch].empty? + @total_project = @projects.count + @projects = @projects.order(order)#.includes(:owner) #WTF???? + + render :partial => 'proj_ajax', :layout => false + end + def remove_project @project = Project.find(params[:project_id]) ProjectToRepository.where(:project_id => @project.id, :repository_id => @repository.id).destroy_all diff --git a/app/views/repositories/_proj_ajax.js.erb b/app/views/repositories/_proj_ajax.js.erb new file mode 100644 index 000000000..b70fc996f --- /dev/null +++ b/app/views/repositories/_proj_ajax.js.erb @@ -0,0 +1,12 @@ +{"sEcho": <%= params[:sEcho] || -1 %>, + "iTotalRecords": <%= @total_projects %>, + "iTotalDisplayRecords": <%= @total_project %>, + "aaData":[ +<% @projects.each do |project| %> + ['<%= link_to(project.owner.uname, project.owner) %>', + '<%= link_to(project.name, project) %>', + '<%= link_to t("layout.add"), url_for(:controller => :repositories, :action => :add_project, :project_id => project.id) %>' + ], +<% end %> +]} + diff --git a/app/views/repositories/_proj_list.html.haml b/app/views/repositories/_proj_list.html.haml index 087de3c70..67bdd09f1 100644 --- a/app/views/repositories/_proj_list.html.haml +++ b/app/views/repositories/_proj_list.html.haml @@ -1,11 +1,17 @@ -%table.table +- columns = [{:type => 'html', :sortable => false, :searchable => false}, {:type => 'html'}, {:type => nil}] += raw datatable(columns, {:sort_by => "[1, 'asc']", :ajax_source => "#{url_for :controller => :repositories, :action => :projects_list, :id => @repository.id}" }) + +%table.table.datatable %tr - %th.first= t("activerecord.attributes.project.name") + %th.first= t("activerecord.attributes.user.uname") + %th= t("activerecord.attributes.project.name") %th.last   - - @projects.each do |project| + -# @projects.each do |project| %tr{:class => cycle("odd", "even")} %td = link_to project.owner.uname + '/' + project.name, project_path(project) %td.last #{link_to t("layout.show"), project_path(project)} | #{link_to t("layout.add"), url_for(:controller => :repositories, :action => :add_project, :project_id => project.id)} += content_for :javascripts do + = javascript_include_tag 'jquery.dataTables.min.js' diff --git a/app/views/repositories/projects_list.html.haml b/app/views/repositories/projects_list.html.haml index de40de54c..56f66de84 100644 --- a/app/views/repositories/projects_list.html.haml +++ b/app/views/repositories/projects_list.html.haml @@ -41,7 +41,7 @@ .inner = render :partial => 'shared/search_form' = render :partial => 'proj_list', :object => @projects - .actions-bar.wat-cf + -#.actions-bar.wat-cf .actions = will_paginate @projects, :param_name => :project_page diff --git a/config/routes.rb b/config/routes.rb index dcea79076..ca9648c86 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -110,6 +110,7 @@ Rosa::Application.routes.draw do member do get :add_project get :remove_project + get :projects_list end end diff --git a/public/javascripts/jquery.dataTables.min.js b/public/javascripts/jquery.dataTables.min.js new file mode 100644 index 000000000..4280c6d63 --- /dev/null +++ b/public/javascripts/jquery.dataTables.min.js @@ -0,0 +1,151 @@ +/* + * File: jquery.dataTables.min.js + * Version: 1.8.2 + * Author: Allan Jardine (www.sprymedia.co.uk) + * Info: www.datatables.net + * + * Copyright 2008-2011 Allan Jardine, all rights reserved. + * + * This source file is free software, under either the GPL v2 license or a + * BSD style license, as supplied with this software. + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + */ +(function(i,za,p){i.fn.dataTableSettings=[];var D=i.fn.dataTableSettings;i.fn.dataTableExt={};var n=i.fn.dataTableExt;n.sVersion="1.8.2";n.sErrMode="alert";n.iApiIndex=0;n.oApi={};n.afnFiltering=[];n.aoFeatures=[];n.ofnSearch={};n.afnSortData=[];n.oStdClasses={sPagePrevEnabled:"paginate_enabled_previous",sPagePrevDisabled:"paginate_disabled_previous",sPageNextEnabled:"paginate_enabled_next",sPageNextDisabled:"paginate_disabled_next",sPageJUINext:"",sPageJUIPrev:"",sPageButton:"paginate_button",sPageButtonActive:"paginate_active", +sPageButtonStaticDisabled:"paginate_button paginate_button_disabled",sPageFirst:"first",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled", +sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:""};n.oJUIClasses={sPagePrevEnabled:"fg-button ui-button ui-state-default ui-corner-left", +sPagePrevDisabled:"fg-button ui-button ui-state-default ui-corner-left ui-state-disabled",sPageNextEnabled:"fg-button ui-button ui-state-default ui-corner-right",sPageNextDisabled:"fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",sPageJUINext:"ui-icon ui-icon-circle-arrow-e",sPageJUIPrev:"ui-icon ui-icon-circle-arrow-w",sPageButton:"fg-button ui-button ui-state-default",sPageButtonActive:"fg-button ui-button ui-state-default ui-state-disabled",sPageButtonStaticDisabled:"fg-button ui-button ui-state-default ui-state-disabled", +sPageFirst:"first ui-corner-tl ui-corner-bl",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last ui-corner-tr ui-corner-br",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"ui-state-default",sSortDesc:"ui-state-default",sSortable:"ui-state-default", +sSortableAsc:"ui-state-default",sSortableDesc:"ui-state-default",sSortableNone:"ui-state-default",sSortColumn:"sorting_",sSortJUIAsc:"css_right ui-icon ui-icon-triangle-1-n",sSortJUIDesc:"css_right ui-icon ui-icon-triangle-1-s",sSortJUI:"css_right ui-icon ui-icon-carat-2-n-s",sSortJUIAscAllowed:"css_right ui-icon ui-icon-carat-1-n",sSortJUIDescAllowed:"css_right ui-icon ui-icon-carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sSortIcon:"DataTables_sort_icon",sScrollWrapper:"dataTables_scroll", +sScrollHead:"dataTables_scrollHead ui-state-default",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot ui-state-default",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:"ui-state-default"};n.oPagination={two_button:{fnInit:function(g,l,s){var t,w,y;if(g.bJUI){t=p.createElement("a");w=p.createElement("a");y=p.createElement("span");y.className=g.oClasses.sPageJUINext;w.appendChild(y);y=p.createElement("span");y.className=g.oClasses.sPageJUIPrev; +t.appendChild(y)}else{t=p.createElement("div");w=p.createElement("div")}t.className=g.oClasses.sPagePrevDisabled;w.className=g.oClasses.sPageNextDisabled;t.title=g.oLanguage.oPaginate.sPrevious;w.title=g.oLanguage.oPaginate.sNext;l.appendChild(t);l.appendChild(w);i(t).bind("click.DT",function(){g.oApi._fnPageChange(g,"previous")&&s(g)});i(w).bind("click.DT",function(){g.oApi._fnPageChange(g,"next")&&s(g)});i(t).bind("selectstart.DT",function(){return false});i(w).bind("selectstart.DT",function(){return false}); +if(g.sTableId!==""&&typeof g.aanFeatures.p=="undefined"){l.setAttribute("id",g.sTableId+"_paginate");t.setAttribute("id",g.sTableId+"_previous");w.setAttribute("id",g.sTableId+"_next")}},fnUpdate:function(g){if(g.aanFeatures.p)for(var l=g.aanFeatures.p,s=0,t=l.length;s=w-t){t=w-s+1;x=w}else{t=y-Math.ceil(s/2)+1;x=t+s-1}for(s=t;s<=x;s++)F+=y!=s?''+s+"":''+s+"";x=g.aanFeatures.p;var z,$=function(M){g._iDisplayStart=(this.innerHTML*1-1)*g._iDisplayLength;l(g);M.preventDefault()},X=function(){return false};s=0;for(t=x.length;sl?1:0},"string-desc":function(g,l){if(typeof g!="string")g="";if(typeof l!="string")l="";g=g.toLowerCase();l=l.toLowerCase();return gl?-1:0},"html-asc":function(g,l){g=g.replace(/<.*?>/g,"").toLowerCase();l=l.replace(/<.*?>/g,"").toLowerCase();return g< +l?-1:g>l?1:0},"html-desc":function(g,l){g=g.replace(/<.*?>/g,"").toLowerCase();l=l.replace(/<.*?>/g,"").toLowerCase();return gl?-1:0},"date-asc":function(g,l){g=Date.parse(g);l=Date.parse(l);if(isNaN(g)||g==="")g=Date.parse("01/01/1970 00:00:00");if(isNaN(l)||l==="")l=Date.parse("01/01/1970 00:00:00");return g-l},"date-desc":function(g,l){g=Date.parse(g);l=Date.parse(l);if(isNaN(g)||g==="")g=Date.parse("01/01/1970 00:00:00");if(isNaN(l)||l==="")l=Date.parse("01/01/1970 00:00:00");return l- +g},"numeric-asc":function(g,l){return(g=="-"||g===""?0:g*1)-(l=="-"||l===""?0:l*1)},"numeric-desc":function(g,l){return(l=="-"||l===""?0:l*1)-(g=="-"||g===""?0:g*1)}};n.aTypes=[function(g){if(typeof g=="number")return"numeric";else if(typeof g!="string")return null;var l,s=false;l=g.charAt(0);if("0123456789-".indexOf(l)==-1)return null;for(var t=1;t")!=-1)return"html";return null}];n.fnVersionCheck=function(g){var l=function(x,v){for(;x.length=parseInt(w,10)};n._oExternConfig={iNextUnique:0};i.fn.dataTable=function(g){function l(){this.fnRecordsTotal= +function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsTotal,10):this.aiDisplayMaster.length};this.fnRecordsDisplay=function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsDisplay,10):this.aiDisplay.length};this.fnDisplayEnd=function(){return this.oFeatures.bServerSide?this.oFeatures.bPaginate===false||this._iDisplayLength==-1?this._iDisplayStart+this.aiDisplay.length:Math.min(this._iDisplayStart+this._iDisplayLength,this._iRecordsDisplay):this._iDisplayEnd};this.sInstance= +this.oInstance=null;this.oFeatures={bPaginate:true,bLengthChange:true,bFilter:true,bSort:true,bInfo:true,bAutoWidth:true,bProcessing:false,bSortClasses:true,bStateSave:false,bServerSide:false,bDeferRender:false};this.oScroll={sX:"",sXInner:"",sY:"",bCollapse:false,bInfinite:false,iLoadGap:100,iBarWidth:0,bAutoCss:true};this.aanFeatures=[];this.oLanguage={sProcessing:"Processing...",sLengthMenu:"Show _MENU_ entries",sZeroRecords:"No matching records found",sEmptyTable:"No data available in table", +sLoadingRecords:"Loading...",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sInfoThousands:",",sSearch:"Search:",sUrl:"",oPaginate:{sFirst:"First",sPrevious:"Previous",sNext:"Next",sLast:"Last"},fnInfoCallback:null};this.aoData=[];this.aiDisplay=[];this.aiDisplayMaster=[];this.aoColumns=[];this.aoHeader=[];this.aoFooter=[];this.iNextId=0;this.asDataSearch=[];this.oPreviousSearch={sSearch:"", +bRegex:false,bSmart:true};this.aoPreSearchCols=[];this.aaSorting=[[0,"asc",0]];this.aaSortingFixed=null;this.asStripeClasses=[];this.asDestroyStripes=[];this.sDestroyWidth=0;this.fnFooterCallback=this.fnHeaderCallback=this.fnRowCallback=null;this.aoDrawCallback=[];this.fnInitComplete=this.fnPreDrawCallback=null;this.sTableId="";this.nTableWrapper=this.nTBody=this.nTFoot=this.nTHead=this.nTable=null;this.bInitialised=this.bDeferLoading=false;this.aoOpenRows=[];this.sDom="lfrtip";this.sPaginationType= +"two_button";this.iCookieDuration=7200;this.sCookiePrefix="SpryMedia_DataTables_";this.fnCookieCallback=null;this.aoStateSave=[];this.aoStateLoad=[];this.sAjaxSource=this.oLoadedState=null;this.sAjaxDataProp="aaData";this.bAjaxDataGet=true;this.jqXHR=null;this.fnServerData=function(a,b,c,d){d.jqXHR=i.ajax({url:a,data:b,success:function(f){i(d.oInstance).trigger("xhr",d);c(f)},dataType:"json",cache:false,error:function(f,e){e=="parsererror"&&alert("DataTables warning: JSON data from server could not be parsed. This is caused by a JSON formatting error.")}})}; +this.aoServerParams=[];this.fnFormatNumber=function(a){if(a<1E3)return a;else{var b=a+"";a=b.split("");var c="";b=b.length;for(var d=0;d=0;e--)!a.aoColumns[e].bVisible&&!c&&h[d].splice(e,1);j.push([])}d=0;for(f=h.length;d=a.fnRecordsDisplay()?0:a.iInitDisplayStart;a.iInitDisplayStart=-1;E(a)}if(a.bDeferLoading){a.bDeferLoading=false;a.iDraw++}else if(a.oFeatures.bServerSide){if(!a.bDestroying&&!Ca(a))return}else a.iDraw++;if(a.aiDisplay.length!==0){var h=a._iDisplayStart,j=a._iDisplayEnd;if(a.oFeatures.bServerSide){h=0;j=a.aoData.length}for(h= +h;h=0;b--)c[b].parentNode.removeChild(c[b])}b=0;for(c=d.length;b=0;b--)a.aoDrawCallback[b].fn.call(a.oInstance,a);i(a.oInstance).trigger("draw",a);a.bSorted=false;a.bFiltered=false;a.bDrawing=false;if(a.oFeatures.bServerSide){K(a,false);typeof a._bInitComplete=="undefined"&&w(a)}}}function da(a){if(a.oFeatures.bSort)R(a,a.oPreviousSearch);else if(a.oFeatures.bFilter)N(a, +a.oPreviousSearch);else{E(a);C(a)}}function Ca(a){if(a.bAjaxDataGet){a.iDraw++;K(a,true);var b=Da(a);ha(a,b);a.fnServerData.call(a.oInstance,a.sAjaxSource,b,function(c){Ea(a,c)},a);return false}else return true}function Da(a){var b=a.aoColumns.length,c=[],d,f;c.push({name:"sEcho",value:a.iDraw});c.push({name:"iColumns",value:b});c.push({name:"sColumns",value:ka(a)});c.push({name:"iDisplayStart",value:a._iDisplayStart});c.push({name:"iDisplayLength",value:a.oFeatures.bPaginate!==false?a._iDisplayLength: +-1});for(f=0;f")c=c.parentNode;else if(h=="l"&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange){f=Ga(a);e=1}else if(h=="f"&&a.oFeatures.bFilter){f=Ha(a);e=1}else if(h=="r"&&a.oFeatures.bProcessing){f=Ia(a);e=1}else if(h=="t"){f=Ja(a);e=1}else if(h=="i"&&a.oFeatures.bInfo){f=Ka(a);e=1}else if(h=="p"&&a.oFeatures.bPaginate){f=La(a);e=1}else if(n.aoFeatures.length!==0){j=n.aoFeatures;u=0;for(k=j.length;ui(a.nTable).height()-a.oScroll.iLoadGap)if(a.fnDisplayEnd()0&&a.nTable.removeChild(h[0]);if(a.nTFoot!==null){k=a.nTable.getElementsByTagName("tfoot");k.length>0&&a.nTable.removeChild(k[0])}h=a.nTHead.cloneNode(true);a.nTable.insertBefore(h,a.nTable.childNodes[0]);if(a.nTFoot!==null){k=a.nTFoot.cloneNode(true); +a.nTable.insertBefore(k,a.nTable.childNodes[1])}if(a.oScroll.sX===""){d.style.width="100%";b.parentNode.style.width="100%"}var U=S(a,h);f=0;for(e=U.length;fd.offsetHeight||i(d).css("overflow-y")=="scroll"))a.nTable.style.width=q(i(a.nTable).outerWidth()-a.oScroll.iBarWidth)}else if(a.oScroll.sXInner!== +"")a.nTable.style.width=q(a.oScroll.sXInner);else if(f==i(d).width()&&i(d).height()f-a.oScroll.iBarWidth)a.nTable.style.width=q(f)}else a.nTable.style.width=q(f);f=i(a.nTable).outerWidth();e=a.nTHead.getElementsByTagName("tr");h=h.getElementsByTagName("tr");P(function(I,na){m=I.style;m.paddingTop="0";m.paddingBottom="0";m.borderTopWidth="0";m.borderBottomWidth="0";m.height=0;r=i(I).width();na.style.width= +q(r);H.push(r)},h,e);i(h).height(0);if(a.nTFoot!==null){j=k.getElementsByTagName("tr");k=a.nTFoot.getElementsByTagName("tr");P(function(I,na){m=I.style;m.paddingTop="0";m.paddingBottom="0";m.borderTopWidth="0";m.borderBottomWidth="0";m.height=0;r=i(I).width();na.style.width=q(r);H.push(r)},j,k);i(j).height(0)}P(function(I){I.innerHTML="";I.style.width=q(H.shift())},h);a.nTFoot!==null&&P(function(I){I.innerHTML="";I.style.width=q(H.shift())},j);if(i(a.nTable).outerWidth()d.offsetHeight|| +i(d).css("overflow-y")=="scroll"?f+a.oScroll.iBarWidth:f;if(B&&(d.scrollHeight>d.offsetHeight||i(d).css("overflow-y")=="scroll"))a.nTable.style.width=q(j-a.oScroll.iBarWidth);d.style.width=q(j);b.parentNode.style.width=q(j);if(a.nTFoot!==null)L.parentNode.style.width=q(j);if(a.oScroll.sX==="")J(a,1,"The table cannot fit into the current element which will cause column misalignment. The table has been drawn at its minimum possible width.");else a.oScroll.sXInner!==""&&J(a,1,"The table cannot fit into the current element which will cause column misalignment. Increase the sScrollXInner value or remove it to allow automatic calculation")}else{d.style.width= +q("100%");b.parentNode.style.width=q("100%");if(a.nTFoot!==null)L.parentNode.style.width=q("100%")}if(a.oScroll.sY==="")if(B)d.style.height=q(a.nTable.offsetHeight+a.oScroll.iBarWidth);if(a.oScroll.sY!==""&&a.oScroll.bCollapse){d.style.height=q(a.oScroll.sY);B=a.oScroll.sX!==""&&a.nTable.offsetWidth>d.offsetWidth?a.oScroll.iBarWidth:0;if(a.nTable.offsetHeight'):b===""?'':b+' ';var c=p.createElement("div"); +c.className=a.oClasses.sFilter;c.innerHTML="";a.sTableId!==""&&typeof a.aanFeatures.f=="undefined"&&c.setAttribute("id",a.sTableId+"_filter");b=i("input",c);b.val(a.oPreviousSearch.sSearch.replace('"',"""));b.bind("keyup.DT",function(){for(var d=a.aanFeatures.f,f=0,e=d.length;f=0;d--){f=qa(G(a,a.aiDisplay[d],c,"filter"),a.aoColumns[c].sType);if(!b.test(f)){a.aiDisplay.splice(d,1);e++}}}}function Oa(a,b,c,d,f){var e=pa(b,d,f);if(typeof c=="undefined"||c===null)c=0;if(n.afnFiltering.length!==0)c=1;if(b.length<=0){a.aiDisplay.splice(0,a.aiDisplay.length);a.aiDisplay=a.aiDisplayMaster.slice()}else if(a.aiDisplay.length==a.aiDisplayMaster.length|| +a.oPreviousSearch.sSearch.length>b.length||c==1||b.indexOf(a.oPreviousSearch.sSearch)!==0){a.aiDisplay.splice(0,a.aiDisplay.length);oa(a,1);for(c=0;c/g,"");else if(typeof a=="string")return a.replace(/\n/g," ");else if(a===null)return"";return a}function R(a,b){var c,d,f,e,h=[],j=[],k=n.oSort;d=a.aoData;var m=a.aoColumns;if(!a.oFeatures.bServerSide&& +(a.aaSorting.length!==0||a.aaSortingFixed!==null)){h=a.aaSortingFixed!==null?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(c=0;c=h)for(b=0;b=0?a._iDisplayStart-a._iDisplayLength:0;if(a._iDisplayStart<0)a._iDisplayStart=0}else if(b=="next")if(a._iDisplayLength>=0){if(a._iDisplayStart+a._iDisplayLength=0){b=parseInt((a.fnRecordsDisplay()- +1)/a._iDisplayLength,10)+1;a._iDisplayStart=(b-1)*a._iDisplayLength}else a._iDisplayStart=0;else J(a,0,"Unknown paging action: "+b);i(a.oInstance).trigger("page",a);return c!=a._iDisplayStart}function Ka(a){var b=p.createElement("div");b.className=a.oClasses.sInfo;if(typeof a.aanFeatures.i=="undefined"){a.aoDrawCallback.push({fn:Ra,sName:"information"});a.sTableId!==""&&b.setAttribute("id",a.sTableId+"_info")}return b}function Ra(a){if(!(!a.oFeatures.bInfo||a.aanFeatures.i.length===0)){var b=a._iDisplayStart+ +1,c=a.fnDisplayEnd(),d=a.fnRecordsTotal(),f=a.fnRecordsDisplay(),e=a.fnFormatNumber(b),h=a.fnFormatNumber(c),j=a.fnFormatNumber(d),k=a.fnFormatNumber(f);if(a.oScroll.bInfinite)e=a.fnFormatNumber(1);e=a.fnRecordsDisplay()===0&&a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfoEmpty+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()===0?a.oLanguage.sInfoEmpty+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",j)+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfo.replace("_START_", +e).replace("_END_",h).replace("_TOTAL_",k)+a.oLanguage.sInfoPostFix:a.oLanguage.sInfo.replace("_START_",e).replace("_END_",h).replace("_TOTAL_",k)+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",a.fnFormatNumber(a.fnRecordsTotal()))+a.oLanguage.sInfoPostFix;if(a.oLanguage.fnInfoCallback!==null)e=a.oLanguage.fnInfoCallback(a,b,c,d,f,e);a=a.aanFeatures.i;b=0;for(c=a.length;b",c,d;if(a.aLengthMenu.length==2&&typeof a.aLengthMenu[0]=="object"&&typeof a.aLengthMenu[1]=="object"){c=0;for(d=a.aLengthMenu[0].length;c'+a.aLengthMenu[1][c]+""}else{c=0;for(d=a.aLengthMenu.length;c'+a.aLengthMenu[c]+""}b+="";var f=p.createElement("div");a.sTableId!==""&&typeof a.aanFeatures.l=="undefined"&&f.setAttribute("id",a.sTableId+"_length"); +f.className=a.oClasses.sLength;f.innerHTML="";i('select option[value="'+a._iDisplayLength+'"]',f).attr("selected",true);i("select",f).bind("change.DT",function(){var e=i(this).val(),h=a.aanFeatures.l;c=0;for(d=h.length;ca.aiDisplay.length||a._iDisplayLength==-1?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function Sa(a,b){if(!a||a===null||a==="")return 0;if(typeof b=="undefined")b=p.getElementsByTagName("body")[0];var c=p.createElement("div");c.style.width=q(a);b.appendChild(c);a=c.offsetWidth;b.removeChild(c);return a}function ga(a){var b=0,c,d=0,f=a.aoColumns.length,e,h=i("th", +a.nTHead);for(e=0;etd",b);h=S(a,e);for(e=d=0;e0)a.aoColumns[e].sWidth=q(c);d++}a.nTable.style.width=q(i(b).outerWidth());b.parentNode.removeChild(b)}}function Ua(a,b){if(a.oScroll.sX===""&&a.oScroll.sY!==""){i(b).width();b.style.width=q(i(b).outerWidth()-a.oScroll.iBarWidth)}else if(a.oScroll.sX!== +"")b.style.width=q(i(b).outerWidth())}function Ta(a,b){var c=Va(a,b);if(c<0)return null;if(a.aoData[c].nTr===null){var d=p.createElement("td");d.innerHTML=G(a,c,b,"");return d}return Q(a,c)[b]}function Va(a,b){for(var c=-1,d=-1,f=0;f/g,"");if(e.length>c){c=e.length;d=f}}return d}function q(a){if(a===null)return"0px";if(typeof a=="number"){if(a<0)return"0px";return a+"px"}var b=a.charCodeAt(a.length-1);if(b<48||b>57)return a;return a+ +"px"}function Za(a,b){if(a.length!=b.length)return 1;for(var c=0;cb&&a[d]--;c!=-1&&a.splice(c,1)}function Fa(a,b){b=b.split(",");for(var c=[],d=0,f=a.aoColumns.length;d4096){a=p.cookie.split(";");for(var j=0,k=a.length;j=d.aiDisplay.length){d._iDisplayStart-=d._iDisplayLength;if(d._iDisplayStart<0)d._iDisplayStart=0}if(typeof c=="undefined"||c){E(d);C(d)}return f};this.fnClearTable=function(a){var b=A(this[n.iApiIndex]);la(b);if(typeof a=="undefined"||a)C(b)};this.fnOpen=function(a,b,c){var d=A(this[n.iApiIndex]);this.fnClose(a);var f=p.createElement("tr"),e=p.createElement("td");f.appendChild(e);e.className=c; +e.colSpan=Z(d);if(typeof b.jquery!="undefined"||typeof b=="object")e.appendChild(b);else e.innerHTML=b;b=i("tr",d.nTBody);i.inArray(a,b)!=-1&&i(f).insertAfter(a);d.aoOpenRows.push({nTr:f,nParent:a});return f};this.fnClose=function(a){for(var b=A(this[n.iApiIndex]),c=0;c=Z(d);if(!j)for(f=a;ftr>td."+a.oClasses.sRowEmpty,a.nTable).parent().remove(); +if(a.nTable!=a.nTHead.parentNode){i(a.nTable).children("thead").remove();a.nTable.appendChild(a.nTHead)}if(a.nTFoot&&a.nTable!=a.nTFoot.parentNode){i(a.nTable).children("tfoot").remove();a.nTable.appendChild(a.nTFoot)}a.nTable.parentNode.removeChild(a.nTable);i(a.nTableWrapper).remove();a.aaSorting=[];a.aaSortingFixed=[];V(a);i(ba(a)).removeClass(a.asStripeClasses.join(" "));if(a.bJUI){i("th",a.nTHead).removeClass([n.oStdClasses.sSortable,n.oJUIClasses.sSortableAsc,n.oJUIClasses.sSortableDesc,n.oJUIClasses.sSortableNone].join(" ")); +i("th span."+n.oJUIClasses.sSortIcon,a.nTHead).remove();i("th",a.nTHead).each(function(){var e=i("div."+n.oJUIClasses.sSortJUIWrapper,this),h=e.contents();i(this).append(h);e.remove()})}else i("th",a.nTHead).removeClass([n.oStdClasses.sSortable,n.oStdClasses.sSortableAsc,n.oStdClasses.sSortableDesc,n.oStdClasses.sSortableNone].join(" "));a.nTableReinsertBefore?b.insertBefore(a.nTable,a.nTableReinsertBefore):b.appendChild(a.nTable);d=0;for(f=a.aoData.length;dt<"F"ip>'}if(e.oScroll.sX!==""||e.oScroll.sY!== +"")e.oScroll.iBarWidth=Ya();if(typeof g.iDisplayStart!="undefined"&&typeof e.iInitDisplayStart=="undefined"){e.iInitDisplayStart=g.iDisplayStart;e._iDisplayStart=g.iDisplayStart}if(typeof g.bStateSave!="undefined"){e.oFeatures.bStateSave=g.bStateSave;Xa(e,g);e.aoDrawCallback.push({fn:va,sName:"state_save"})}if(typeof g.iDeferLoading!="undefined"){e.bDeferLoading=true;e._iRecordsTotal=g.iDeferLoading;e._iRecordsDisplay=g.iDeferLoading}if(typeof g.aaData!="undefined")j=true;if(typeof g!="undefined"&& +typeof g.aoData!="undefined")g.aoColumns=g.aoData;if(typeof g.oLanguage!="undefined")if(typeof g.oLanguage.sUrl!="undefined"&&g.oLanguage.sUrl!==""){e.oLanguage.sUrl=g.oLanguage.sUrl;i.getJSON(e.oLanguage.sUrl,null,function(u){y(e,u,true)});h=true}else y(e,g.oLanguage,false)}else g={};if(typeof g.asStripClasses=="undefined"&&typeof g.asStripeClasses=="undefined"){e.asStripeClasses.push(e.oClasses.sStripeOdd);e.asStripeClasses.push(e.oClasses.sStripeEven)}c=false;d=i(this).children("tbody").children("tr"); +a=0;for(b=e.asStripeClasses.length;a=0;a--){var m= +g.aoColumnDefs[a].aTargets;i.isArray(m)||J(e,1,"aTargets must be an array of targets, not a "+typeof m);c=0;for(d=m.length;c=0){for(;e.aoColumns.length<=m[c];)F(e);x(e,m[c],g.aoColumnDefs[a])}else if(typeof m[c]=="number"&&m[c]<0)x(e,e.aoColumns.length+m[c],g.aoColumnDefs[a]);else if(typeof m[c]=="string"){b=0;for(f=e.aoColumns.length;b=e.aoColumns.length)e.aaSorting[a][0]=0;k=e.aoColumns[e.aaSorting[a][0]];if(typeof e.aaSorting[a][2]=="undefined")e.aaSorting[a][2]=0;if(typeof g.aaSorting=="undefined"&&typeof e.saved_aaSorting=="undefined")e.aaSorting[a][1]=k.asSorting[0];c=0;for(d=k.asSorting.length;c0){e.nTFoot=a[0];Y(e.aoFooter,e.nTFoot)}if(j)for(a=0;a, passing in the columns, how to filter them (sorting type), and any other settings (ajax source, search?, label for search, processing image) + + <% columns = [{:type => 'html', :class => "first"}, {:type => 'html'}, {:type => 'html'}, {:type => nil, :class => "last"}] %> + <%= datatable(columns, {:sort_by => "[0, 'desc']", :processing => image_tag("spinner.gif") }) %> + + + + + + + + + + + + <%- @users.each do |user| -%> + + + + + + + <%- end -%> + +
NameAccount LevelEmailActions
<%= user.name %><%= user.account.account_level.name %><%= user.email %><%= link_to "Edit", edit_system_user_path(user) %>
+ +### Options + +#### Table Options + + :sort_by - array, default column number (0 - n-1) and sort order. e.g. "[2, 'desc']". Defaults to initial order. + :search - boolean, display the search field. Defaults to true. + :search_label - string, the label for the search field. Defaults to "Search". + :processing - string, the text or image to display while processing data. Defaults to "Processing". + :persist_state - boolean, remember the sorting and page of the tables for the user. Defaults to true. + :additional_data - hash, pass along additional data, such as filter values. Default is none. + :table_dom_id - string, the ID of the table to alter. If nothing is passed, it will look for a class of 'datatable'. Necessary if you want to have multiple DataTables on a single page. + :per_page - the number of rows to show per page (renamed from display_length) + :append - functions to all at the end of the dataTable() call. Useful for [Datatables plugins](http://www.datatables.net/plug-ins/api) + :no_records_message - Message to display if no records are found, whether on load or after searching + :auto_width - Automatically adjust the width of the columns. Defaults to true. + :row_callback - a function to run on each row in the table. Inserted in to "'fnRowCallback': function( nRow, aData, iDisplayIndex ) { }". See [documentation for fnRowCallback](http://www.datatables.net/usage/callbacks) for more information. + +#### Column Options + + :class - string, the class to assign to the table cell. Default is none. + :type - string, the type of content in the column, for non-Ajax tables. 'html' will strip all HTML and sort on the inner value, as a string. Default is string. + :sortable - boolean, allow this column to be sorted on. Default is true. + :searchable - boolean, allow this column to be searched, for non-Ajax tables. Default is true. + +#### AJAX Options + + When you're working with large datasets it's not reasonable to load everything on page load. Use an :ajax_source to load just the records that are being displayed, do custom searching (DB, Solr, etc). + + :ajax_source - string, for large datasets, use an ajax source to load each page on its own. For smaller datasets, just load the whole set and let datatable do the sorting + +Add a datatable method on your controller to return JSON +* Return the objects to be displayed +* Return the total number of objects +* Add a method to handle sorting - DataTables returns the column that is being sorted (0 - n), so you need to know which column is which and sort on it. + +### AJAX Example + +#### Datatable view example - datatable.html.erb + + {"sEcho": <%= params[:sEcho] || -1 %>, + "iTotalRecords": <%= @total_objects %>, + "iTotalDisplayRecords": <%= @total_object %>, + "aaData":[ + <% @objects.each do |object| %> + ['<%= link_to(object.user.name, user) %>', + '<%= object.description || "-" %>', + '<%= object.created_at %>' + ], + <% end %> + ]} + +#### Controller example - using will_paginate + + def datatable + @objects = current_objects(params) + @total_objectss = total_objects(params) + render :layout => false + end + + private + + def current_objects(params={}) + current_page = (params[:iDisplayStart].to_i/params[:iDisplayLength].to_i rescue 0)+1 + @current_objects = Object.paginate :page => current_page, + :include => [:user], + :order => "#{datatable_columns(params[:iSortCol_0])} #{params[:sSortDir_0] || "DESC"}", + :conditions => conditions, + :per_page => params[:iDisplayLength] + end + + def total_objects(params={}) + @total_objects = Object.count :include => [:user], :conditions => conditions + end + + def datatable_columns(column_id) + case column_id.to_i + when 1 + return "objects.description" + when 2 + return "objects.created_at" + else + return "users.name" + end + end + + def conditions + conditions = [] + conditions << "(objects.description ILIKE '%#{params[:sSearch]}%' OR users.name ILIKE '%#{params[:sSearch]}%')" if(params[:sSearch]) + return conditions.join(" AND ") + end + +### Note +There is a more functionality offered by DataTables than this plugin currently provides. We add to it as we find need for other features. If there's a feature of DataTables that you'd like to see, fork this repo and add it so we can all benefit. + +### Credits + +Copyright (c) 2009 [Phronos](http://phronos.com), released under the MIT license diff --git a/vendor/plugins/rails_datatables/Rakefile b/vendor/plugins/rails_datatables/Rakefile new file mode 100644 index 000000000..6be4ee971 --- /dev/null +++ b/vendor/plugins/rails_datatables/Rakefile @@ -0,0 +1,23 @@ +require 'rake' +require 'rake/testtask' +require 'rake/rdoctask' + +desc 'Default: run unit tests.' +task :default => :test + +desc 'Test the rails_datatables plugin.' +Rake::TestTask.new(:test) do |t| + t.libs << 'lib' + t.libs << 'test' + t.pattern = 'test/**/*_test.rb' + t.verbose = true +end + +desc 'Generate documentation for the rails_datatables plugin.' +Rake::RDocTask.new(:rdoc) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = 'RailsDatatables' + rdoc.options << '--line-numbers' << '--inline-source' + rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('lib/**/*.rb') +end diff --git a/vendor/plugins/rails_datatables/init.rb b/vendor/plugins/rails_datatables/init.rb new file mode 100644 index 000000000..538f33510 --- /dev/null +++ b/vendor/plugins/rails_datatables/init.rb @@ -0,0 +1 @@ +ActionView::Base.send :include, RailsDatatables \ No newline at end of file diff --git a/vendor/plugins/rails_datatables/install.rb b/vendor/plugins/rails_datatables/install.rb new file mode 100644 index 000000000..f7732d379 --- /dev/null +++ b/vendor/plugins/rails_datatables/install.rb @@ -0,0 +1 @@ +# Install hook code here diff --git a/vendor/plugins/rails_datatables/lib/rails_datatables.rb b/vendor/plugins/rails_datatables/lib/rails_datatables.rb new file mode 100644 index 000000000..68bc52d9b --- /dev/null +++ b/vendor/plugins/rails_datatables/lib/rails_datatables.rb @@ -0,0 +1,81 @@ +module RailsDatatables + def datatable(columns, opts={}) + sort_by = opts[:sort_by] || nil + additional_data = opts[:additional_data] || {} + search = opts[:search].present? ? opts[:search].to_s : "true" + search_label = opts[:search_label] || "Search" + processing = opts[:processing] || "Processing" + persist_state = opts[:persist_state].present? ? opts[:persist_state].to_s : "true" + table_dom_id = opts[:table_dom_id] ? "##{opts[:table_dom_id]}" : ".datatable" + per_page = opts[:per_page] || opts[:display_length]|| 25 + no_records_message = opts[:no_records_message] || nil + auto_width = opts[:auto_width].present? ? opts[:auto_width].to_s : "true" + row_callback = opts[:row_callback] || nil + + append = opts[:append] || nil + + ajax_source = opts[:ajax_source] || nil + server_side = opts[:ajax_source].present? + + additional_data_string = "" + additional_data.each_pair do |name,value| + additional_data_string = additional_data_string + ", " if !additional_data_string.blank? && value + additional_data_string = additional_data_string + "{'name': '#{name}', 'value':'#{value}'}" if value + end + + %Q{ + + } + end + + private + def formatted_columns(columns) + i = 0 + columns.map {|c| + i += 1 + if c.nil? or c.empty? + "null" + else + searchable = c[:searchable].to_s.present? ? c[:searchable].to_s : "true" + sortable = c[:sortable].to_s.present? ? c[:sortable].to_s : "true" + + "{ + 'sType': '#{c[:type] || "string"}', + 'bSortable':#{sortable}, + 'bSearchable':#{searchable} + #{",'sClass':'#{c[:class]}'" if c[:class]} + }" + end + }.join(",") + end +end \ No newline at end of file diff --git a/vendor/plugins/rails_datatables/test/rails_datatables_test.rb b/vendor/plugins/rails_datatables/test/rails_datatables_test.rb new file mode 100644 index 000000000..e96dcb002 --- /dev/null +++ b/vendor/plugins/rails_datatables/test/rails_datatables_test.rb @@ -0,0 +1,8 @@ +require 'test_helper' + +class RailsDatatablesTest < ActiveSupport::TestCase + # Replace this with your real tests. + test "the truth" do + assert true + end +end diff --git a/vendor/plugins/rails_datatables/test/test_helper.rb b/vendor/plugins/rails_datatables/test/test_helper.rb new file mode 100644 index 000000000..cf148b8b4 --- /dev/null +++ b/vendor/plugins/rails_datatables/test/test_helper.rb @@ -0,0 +1,3 @@ +require 'rubygems' +require 'active_support' +require 'active_support/test_case' \ No newline at end of file diff --git a/vendor/plugins/rails_datatables/uninstall.rb b/vendor/plugins/rails_datatables/uninstall.rb new file mode 100644 index 000000000..973833346 --- /dev/null +++ b/vendor/plugins/rails_datatables/uninstall.rb @@ -0,0 +1 @@ +# Uninstall hook code here From c23312ad5160ff6f2aef0d7fce03c7271fed1606 Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Wed, 11 Jan 2012 21:43:33 +0200 Subject: [PATCH 3/7] Research and fix problem with build_lists#auto_publish feature. Fix specs. Refs #97 --- app/controllers/build_lists_controller.rb | 2 +- db/schema.rb | 11 +++++------ spec/spec_helper.rb | 4 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/app/controllers/build_lists_controller.rb b/app/controllers/build_lists_controller.rb index 143ddc880..fc650a4b3 100644 --- a/app/controllers/build_lists_controller.rb +++ b/app/controllers/build_lists_controller.rb @@ -113,7 +113,7 @@ class BuildListsController < ApplicationController @build_list.notified_at = Time.current @build_list.save - @build_list.publish if @build_list.auto_publish # && @build_list.can_publish? + @build_list.delay.publish if @build_list.auto_publish # && @build_list.can_publish? render :nothing => true, :status => 200 end diff --git a/db/schema.rb b/db/schema.rb index c4eb51827..e80b0c134 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -246,7 +246,6 @@ ActiveRecord::Schema.define(:version => 20111228182425) do t.string "object_type" t.integer "target_id" t.string "target_type" - t.integer "role_id" t.datetime "created_at" t.datetime "updated_at" t.string "role" @@ -283,16 +282,16 @@ ActiveRecord::Schema.define(:version => 20111228182425) do create_table "users", :force => true do |t| t.string "name" - t.string "email", :default => "", :null => false - t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "email", :default => "", :null => false + t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "password_salt", :default => "", :null => false t.string "reset_password_token" - t.datetime "reset_password_sent_at" + t.string "remember_token" t.datetime "remember_created_at" t.datetime "created_at" t.datetime "updated_at" - t.string "uname" t.text "ssh_key" - t.integer "role_id" + t.string "uname" t.string "role" end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e15db9c3b..a79b3ce74 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -37,9 +37,9 @@ def stub_rsync_methods any_instance_of(Platform, :umount_directory_for_rsync => true) end +Delayed::Worker.delay_jobs = false # Execute all jobs realtime + # Add testing root_path %x(rm -Rf #{Rails.root}/tmp/test_root) %x(mkdir -p #{Rails.root}/tmp/test_root) APP_CONFIG['root_path'] = "#{Rails.root}/tmp/test_root" - - From 49082c2a8da1beb335b7d4d6f99460212c7e8e6e Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Thu, 12 Jan 2012 01:12:56 +0400 Subject: [PATCH 4/7] [issue #76] Fixed bug with JSON generation. --- app/controllers/repositories_controller.rb | 2 +- app/views/repositories/_proj_ajax.js.erb | 25 +++++++++++-------- app/views/repositories/_proj_list.html.haml | 16 +++++------- .../repositories/projects_list.html.haml | 2 +- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index bb6dbdbe5..c1c24c242 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -68,7 +68,7 @@ class RepositoriesController < ApplicationController # else # @projects = Project.addable_to_repository(@repository.id).paginate(:page => params[:project_page]) # end - render 'projects_list' + render :projects_list end end diff --git a/app/views/repositories/_proj_ajax.js.erb b/app/views/repositories/_proj_ajax.js.erb index b70fc996f..942b4b1e2 100644 --- a/app/views/repositories/_proj_ajax.js.erb +++ b/app/views/repositories/_proj_ajax.js.erb @@ -1,12 +1,15 @@ -{"sEcho": <%= params[:sEcho] || -1 %>, - "iTotalRecords": <%= @total_projects %>, - "iTotalDisplayRecords": <%= @total_project %>, - "aaData":[ -<% @projects.each do |project| %> - ['<%= link_to(project.owner.uname, project.owner) %>', - '<%= link_to(project.name, project) %>', - '<%= link_to t("layout.add"), url_for(:controller => :repositories, :action => :add_project, :project_id => project.id) %>' - ], -<% end %> -]} +{ + "sEcho": <%=h params[:sEcho].to_i || -1 %>, + "iTotalRecords": <%= @total_projects %>, + "iTotalDisplayRecords": <%= @total_project %>, + "aaData": [ + <% @projects.each do |project| %> + [ + "<%=j link_to project.owner.uname, project.owner %>", + "<%=j link_to project.name, project %>", + "<%=j link_to t("layout.add"), url_for(:controller => :repositories, :action => :add_project, :project_id => project.id) %>" + ]<%= project == @projects.last ? '' : ',' %> + <% end %> + ] +} diff --git a/app/views/repositories/_proj_list.html.haml b/app/views/repositories/_proj_list.html.haml index 67bdd09f1..a326b40ed 100644 --- a/app/views/repositories/_proj_list.html.haml +++ b/app/views/repositories/_proj_list.html.haml @@ -2,16 +2,12 @@ = raw datatable(columns, {:sort_by => "[1, 'asc']", :ajax_source => "#{url_for :controller => :repositories, :action => :projects_list, :id => @repository.id}" }) %table.table.datatable - %tr - %th.first= t("activerecord.attributes.user.uname") - %th= t("activerecord.attributes.project.name") - %th.last   - -# @projects.each do |project| - %tr{:class => cycle("odd", "even")} - %td - = link_to project.owner.uname + '/' + project.name, project_path(project) - %td.last - #{link_to t("layout.show"), project_path(project)} | #{link_to t("layout.add"), url_for(:controller => :repositories, :action => :add_project, :project_id => project.id)} + %thead + %tr + %th.first= t("activerecord.attributes.user.uname") + %th= t("activerecord.attributes.project.name") + %th.last   + %tbody = content_for :javascripts do = javascript_include_tag 'jquery.dataTables.min.js' diff --git a/app/views/repositories/projects_list.html.haml b/app/views/repositories/projects_list.html.haml index 56f66de84..af5a9a1a9 100644 --- a/app/views/repositories/projects_list.html.haml +++ b/app/views/repositories/projects_list.html.haml @@ -39,7 +39,7 @@ %h2.title = t("layout.projects.list_header") .inner - = render :partial => 'shared/search_form' + -#= render :partial => 'shared/search_form' = render :partial => 'proj_list', :object => @projects -#.actions-bar.wat-cf .actions From 73b710ae4ea784690616b6b0ffba2df2552a3306 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Thu, 12 Jan 2012 20:37:50 +0400 Subject: [PATCH 5/7] [close #76] Changed styles. Fixed bug with pagination. --- app/controllers/repositories_controller.rb | 18 +++++++----- app/views/layouts/_stylesheets.html.haml | 2 +- app/views/repositories/_proj_list.html.haml | 14 +++++++-- config/locales/ru.yml | 11 +++++++ .../rails_datatables/lib/rails_datatables.rb | 29 ++++++++++++++++++- 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index c1c24c242..85d0175cc 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -54,7 +54,6 @@ class RepositoriesController < ApplicationController def add_project if params[:project_id] @project = Project.find(params[:project_id]) - # params[:project_id] = nil unless @repository.projects.find_by_name(@project.name) @repository.projects << @project flash[:notice] = t('flash.repository.project_added') @@ -63,22 +62,27 @@ class RepositoriesController < ApplicationController end redirect_to repository_path(@repository) else -# if @repository.platform.platform_type == 'main' -# @projects = Project.addable_to_repository(@repository.id).by_visibilities(['open']).paginate(:page => params[:project_page]) -# else -# @projects = Project.addable_to_repository(@repository.id).paginate(:page => params[:project_page]) -# end render :projects_list end end def projects_list + owner_subquery = " + INNER JOIN ( + SELECT id, 'User' AS type, uname + FROM users + UNION + SELECT id, 'Group' AS type, uname + FROM groups + ) AS owner + ON projects.owner_id = owner.id AND projects.owner_type = owner.type" colName = ['owner.uname', 'projects.name'] sort_col = params[:iSortCol_0] || 0 sort_dir = params[:sSortDir_0]=="asc" ? 'asc' : 'desc' order = "#{colName[sort_col.to_i]} #{sort_dir}" - @projects = Project.addable_to_repository(@repository.id) + @projects = Project.joins(owner_subquery).addable_to_repository(@repository.id) + @projects = @projects.paginate(:page => (params[:iDisplayStart].to_i/params[:iDisplayLength].to_i).to_i + 1, :per_page => params[:iDisplayLength]) @projects = @projects.by_visibilities(['open']) if @repository.platform.platform_type == 'main' @total_projects = @projects.count diff --git a/app/views/layouts/_stylesheets.html.haml b/app/views/layouts/_stylesheets.html.haml index b2e58f3b8..b74e60ab4 100644 --- a/app/views/layouts/_stylesheets.html.haml +++ b/app/views/layouts/_stylesheets.html.haml @@ -1,6 +1,6 @@ -#= include_stylesheets :application = stylesheet_link_tag "web-app-theme/base.css", "web-app-theme/themes/default/style.css", "web-app-theme/override.css", "git/style.css" -= stylesheet_link_tag "jquery-ui-1.8.16.custom.css" += stylesheet_link_tag "jquery-ui-1.8.16.custom.css", "datatable.css" = yield :stylesheets diff --git a/app/views/repositories/_proj_list.html.haml b/app/views/repositories/_proj_list.html.haml index a326b40ed..64d8a5da8 100644 --- a/app/views/repositories/_proj_list.html.haml +++ b/app/views/repositories/_proj_list.html.haml @@ -1,13 +1,21 @@ -- columns = [{:type => 'html', :sortable => false, :searchable => false}, {:type => 'html'}, {:type => nil}] -= raw datatable(columns, {:sort_by => "[1, 'asc']", :ajax_source => "#{url_for :controller => :repositories, :action => :projects_list, :id => @repository.id}" }) +- columns = [{:type => 'html', :searchable => false}, {:type => 'html'}, {:type => nil, :sortable => false, :searchable => false}] += raw datatable(columns, {:sort_by => "[1, 'asc']", :search_label => t("layout.search_by_name"), :processing => t("layout.processing"), + :pagination_labels => {:first => t("datatables.first_label"), :previous => t("datatables.previous_label"), + :next => t("datatables.next_label"), :last => t("datatables.last_label")}, + :empty_label => t("datatables.empty_label"), + :info_label => t("datatables.info_label"), + :info_empty_label => t("datatables.info_empty_label"), + :filtered_label => t("datatables.filtered_label"), + :ajax_source => "#{url_for :controller => :repositories, :action => :projects_list, :id => @repository.id}" }) %table.table.datatable %thead %tr - %th.first= t("activerecord.attributes.user.uname") + %th.first{:style => 'width: 80px'}= t("activerecord.attributes.user.uname") %th= t("activerecord.attributes.project.name") %th.last   %tbody +%br = content_for :javascripts do = javascript_include_tag 'jquery.dataTables.min.js' diff --git a/config/locales/ru.yml b/config/locales/ru.yml index dbc4294dc..7fcd2b6c0 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -3,6 +3,16 @@ ru: previous_label: ‹ Предыдущая next_label: Следующая › page_gap: ... + + datatables: + previous_label: ‹ Пред. + next_label: След. › + first_label: « Первая + last_label: Последняя » + empty_label: Нет доступных данных + info_label: Показаны записи с _START_ по _END_ из _TOTAL_ + info_empty_label: Показаны записи с 0 по 0 из 0 + filtered_label: (отфильтровано из _MAX_) layout: logged_in_as: Вы вошли как @@ -30,6 +40,7 @@ ru: not_access: Нет доступа! owner: Владелец confirm: Уверенны? + processing: Обрабатывается... downloads: title: Статистика закачек пакетов diff --git a/vendor/plugins/rails_datatables/lib/rails_datatables.rb b/vendor/plugins/rails_datatables/lib/rails_datatables.rb index 68bc52d9b..1088cb9fe 100644 --- a/vendor/plugins/rails_datatables/lib/rails_datatables.rb +++ b/vendor/plugins/rails_datatables/lib/rails_datatables.rb @@ -12,6 +12,22 @@ module RailsDatatables auto_width = opts[:auto_width].present? ? opts[:auto_width].to_s : "true" row_callback = opts[:row_callback] || nil + empty_label = opts[:empty_label] if opts[:empty_label].present? + info_label = opts[:info_label] if opts[:info_label].present? + info_empty_label = opts[:info_empty_label] if opts[:info_empty_label].present? + filtered_label = opts[:filtered_label] if opts[:filtered_label].present? + + if opts[:pagination_labels].present? + pagination_labels = [] + pagination_labels << "'sFirst': '#{opts[:pagination_labels][:first]}'" if opts[:pagination_labels][:first].present? + pagination_labels << "'sLast': '#{opts[:pagination_labels][:last]}'" if opts[:pagination_labels][:last].present? + pagination_labels << "'sPrevious': '#{opts[:pagination_labels][:previous]}'" if opts[:pagination_labels][:previous].present? + pagination_labels << "'sNext': '#{opts[:pagination_labels][:next]}'" if opts[:pagination_labels][:next].present? + pagination_labels = pagination_labels.join(",\n") + else + pagination_labels = false + end + append = opts[:append] || nil ajax_source = opts[:ajax_source] || nil @@ -30,6 +46,17 @@ module RailsDatatables "oLanguage": { "sSearch": "#{search_label}", #{"'sZeroRecords': '#{no_records_message}'," if no_records_message} + #{" + 'oPaginate': { + #{pagination_labels} + }, + " if pagination_labels} + + #{"'sEmptyTable': '#{empty_label}'," if empty_label} + #{"'sInfo': '#{info_label}'," if info_label} + #{"'sInfoEmpty': '#{info_empty_label}'," if info_empty_label} + #{"'sInfoFiltered': '#{filtered_label}'," if filtered_label} + "sProcessing": '#{processing}' }, "sPaginationType": "full_numbers", @@ -78,4 +105,4 @@ module RailsDatatables end }.join(",") end -end \ No newline at end of file +end From f8177f88ad56e2f6a64e06d69e8317acf7c3275e Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Thu, 12 Jan 2012 22:46:56 +0400 Subject: [PATCH 6/7] [update #76] Removed unnecessary files. --- .../rails_datatables/test/rails_datatables_test.rb | 8 -------- vendor/plugins/rails_datatables/test/test_helper.rb | 3 --- 2 files changed, 11 deletions(-) delete mode 100644 vendor/plugins/rails_datatables/test/rails_datatables_test.rb delete mode 100644 vendor/plugins/rails_datatables/test/test_helper.rb diff --git a/vendor/plugins/rails_datatables/test/rails_datatables_test.rb b/vendor/plugins/rails_datatables/test/rails_datatables_test.rb deleted file mode 100644 index e96dcb002..000000000 --- a/vendor/plugins/rails_datatables/test/rails_datatables_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require 'test_helper' - -class RailsDatatablesTest < ActiveSupport::TestCase - # Replace this with your real tests. - test "the truth" do - assert true - end -end diff --git a/vendor/plugins/rails_datatables/test/test_helper.rb b/vendor/plugins/rails_datatables/test/test_helper.rb deleted file mode 100644 index cf148b8b4..000000000 --- a/vendor/plugins/rails_datatables/test/test_helper.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'rubygems' -require 'active_support' -require 'active_support/test_case' \ No newline at end of file From 8d35c14fc11536d4a58fbed6d4bc851e6a99684a Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Fri, 13 Jan 2012 17:48:48 +0400 Subject: [PATCH 7/7] [update #76] Added forgotten files. --- public/images/datatables/Sorting icons.psd | Bin 0 -> 27490 bytes public/images/datatables/back_disabled.jpg | Bin 0 -> 612 bytes public/images/datatables/back_enabled.jpg | Bin 0 -> 807 bytes public/images/datatables/favicon.ico | Bin 0 -> 894 bytes public/images/datatables/forward_disabled.jpg | Bin 0 -> 635 bytes public/images/datatables/forward_enabled.jpg | Bin 0 -> 852 bytes public/images/datatables/sort_asc.png | Bin 0 -> 263 bytes .../images/datatables/sort_asc_disabled.png | Bin 0 -> 252 bytes public/images/datatables/sort_both.png | Bin 0 -> 282 bytes public/images/datatables/sort_desc.png | Bin 0 -> 260 bytes .../images/datatables/sort_desc_disabled.png | Bin 0 -> 251 bytes public/javascripts/jquery.dataTables.js | 11349 ++++++++++++++++ public/stylesheets/datatable.css | 550 + 13 files changed, 11899 insertions(+) create mode 100644 public/images/datatables/Sorting icons.psd create mode 100644 public/images/datatables/back_disabled.jpg create mode 100644 public/images/datatables/back_enabled.jpg create mode 100644 public/images/datatables/favicon.ico create mode 100644 public/images/datatables/forward_disabled.jpg create mode 100644 public/images/datatables/forward_enabled.jpg create mode 100644 public/images/datatables/sort_asc.png create mode 100644 public/images/datatables/sort_asc_disabled.png create mode 100644 public/images/datatables/sort_both.png create mode 100644 public/images/datatables/sort_desc.png create mode 100644 public/images/datatables/sort_desc_disabled.png create mode 100644 public/javascripts/jquery.dataTables.js create mode 100644 public/stylesheets/datatable.css diff --git a/public/images/datatables/Sorting icons.psd b/public/images/datatables/Sorting icons.psd new file mode 100644 index 0000000000000000000000000000000000000000..53b2e06850767cb57c52b316f0b845b1a8e0ca0e GIT binary patch literal 27490 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 Y16@Zf7?Q8!JB-NJ(KYBs*Ff|C0Zg4MIsgCw literal 0 HcmV?d00001 diff --git a/public/images/datatables/back_disabled.jpg b/public/images/datatables/back_disabled.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1e73a546e3609636f9cf4c543c2a4fe4050866c3 GIT binary patch literal 612 zcmex=C5UDGKfoZ!!63{a%*-grz$D1XEXer(2tyUn z+02YUSHb}sD?0}l&^EXLguy7lz`(-H!phDIlVN0HVHIR%V-ON%S2Pq6HFFG{Xryc+ zmRQ($@S#&sld*HEn>dFcBLmQ_$YwDLDjGT#PW*q1fd^^;oX+iLI)z|@;wX;U8Xr> zT8Qgxn;R!Cottl}#(8Ri${a3d=J*$R5qBRbK9bRJe*4BYwq9(uIM4mLS9%TSY?*y6 zE==owYH)vf>dq6(Uzum+IyVJqc3N&dRPD57vW(=l(=(DZ-K_!LSx zwPk@>bN@4B-OI9gCf>Wc_;CDAS%c@BJZ}kBlbDz~@y-*&Y^_U+@};q`xNUthN} On^Cj9W}Eu@|2F})$f79# literal 0 HcmV?d00001 diff --git a/public/images/datatables/back_enabled.jpg b/public/images/datatables/back_enabled.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a6d764c79c7a2047b6bf65bf9d96fcafd5161e38 GIT binary patch literal 807 zcmex=C5UDGKfoZ!!63{a%*-grz$D1XEXer(2*U&h z1}0{pBN2d|gO!bok%5r~RhW^Pm5qg+Lx6#Sm5Gs^od+h%$i&RTD#*spplB#0EW!~u z(MZ`u)XXulu<_tSr=TWdXR%Z_aiE1jZ7eM8Fl&IpCkWK1$Y$s$#2&a&N#sM~M5iWU z<^Q)Bc$gW1&SMs2uxGfw`}E06etb^r9k|jMc@Dlk(IlSD-Wwx*G{%4ThHhR%HnTsw zbu3z!=BtbC=-In5f5nt;je{+vrKZdWckk$U`c^FEYC6}Jn=lG)17QB>6z3khm7PHhg<-pEGSO0F>VA}N6`w53!8pr$>MbUW| zMEsFn=(%w+^5v0yp7Lmb+~3PpI4(#G~bQ$y_;t)oo+U5`bnSHZcn){CH~m7Ys2rz z2!R@xgGrCtcPz?eOPOzKr2P26p~(mTGjR1-c3?psA>uUGsyt|R2Ts3~!B zN71DGSrW%W*`w8#2{O$LX)%%8*<4Ycyr;tN(Hm8|M=_HtvR>P P+Rcr(b5Xx$|NkZcT0jT? literal 0 HcmV?d00001 diff --git a/public/images/datatables/favicon.ico b/public/images/datatables/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..6eeaa2a0d393190ce748107222d9a026f992e4a7 GIT binary patch literal 894 zcmZQzU<5(|0R|u`!H~hsz#zuJz@P!dKp_SNAO?xUfG{@$0|>*weY}F;x;`B~@Mg`jC-vo5%k$%{OoKy1zkdA+(K2o3 zEDKGQQ~gcX+N!TtEj1|9e2tL(rheJva*5dKY#gZsIRxM zB;!h75Wi?9l5?>z>S-`t`=OAFp5C?(007k>qM(bnVuyja#;c*qL9N z(Q%=@`f7d2?T&^wySIHjy#MKh?rZrO7i!Bt-@f(!@WDrwB`uD&)%Eqcd3o(gVV7ri zp6ji@(BF7(+uE0x&)(R!?s#YIg_7JW1=-KHZv1@s(DSxD9<^am-%+f#!uU}z9=j>5*%b{WE2`20#tutPWS1# zz4s39d~xOMwaqJzOl{rMU%#oo=xj&xyY1WF&71o?Hs-LOkAD^4SRbV?yXz(e#efNwKXpT1J^s+yE;1`KXoe5&f?1A$tYso}un=1c3AzCL>B&D=RpqN3i1hL&lnclP!D`u*G0#bsJv!oAH) z-rc|T`^Wdkrw?7(xb)_p%`Y#WdAn`Pvz+W#0Rbo6-Ha3zp1gPgjDkZ)k6Gz!@9D0( zG^hL4?)Be4zWep#`{$>RUhUoaq@wgyfd9*oU{6tz+SXQhl3284sj;T&{L=I*bGxt4 z@4vfX%A<*$FN^a&MMa!C5UDGKfoZ!!63{a%*-grz$D1XEXer(2tySE z1JEp>E8&2Nm4%I+g9~UMTnNHo6kuRrVP;|B;)Y2uGBL9Vva&GlzGLeh=CM*_u2I6%$1L~6;-1yGa|?*FvavCW+Av>{Flt>+*?d?iZ`9)^O?_H|D3t8;Og6lD<#WHQvW(mo1ETsD>A@mr8@sqg(?1R z%d@qrmWLWmIn1#pQuo}{brVW*C8t%EDXbOt_DabwXgGW3;wDX1;~7hWrYL+ZX=qre z&-y^2q0zm?-FJb#(AWJTHOJ-3`S`D|JEhzC{KvY_h0kZinXP-?w!g_L@p#JQO^!z$ mYCgVwS7#SryXs@?>&L&t^Z(SozHVt~@Z#>58}s)6zX<@qORf(9 literal 0 HcmV?d00001 diff --git a/public/images/datatables/forward_enabled.jpg b/public/images/datatables/forward_enabled.jpg new file mode 100644 index 0000000000000000000000000000000000000000..598c075f13ab0e4bbe05a4eeea7cf777ba73cf03 GIT binary patch literal 852 zcmex=C5UDGKfoZ!!63{a%*-grz$D1XEXer(2tywO z0~0eN(3Nn&%Fe>Z!NthH$ciG&$iU3P%Em6hz`z1zu=B#yGcqx=2(q#<2(fb*3M-3< zDh5t8G7&R#Oe}1C=oHjs?40T*F37+LbR`oj+(bq}CT0c}Rz*W0Hg?Cv#)(EB0yioN zi~PUEzyov)lOVGogFVA5dn3uE%Z<*rn&ugY^FIG9<<=87L*?mOy^~u`Rq(Eg+UDw^ z@^Uh}zJ$t~P2YpRT#sm2p`oEt8zJ-EBRfY;>b?DxZo!24Z)Q(O&}!Mbt}27`dKa(x zr)AHkZg5MjKa&4$syaupXWNXgp32dQs_rj-?|M=Q9pN^hZg^mV7=UWs>}D5 z$40(ME7Q1T4h8p}ZJ8O!G-Xk84;P~#ci!&o`A5I3kG@gLm*VlJbn%kvSqIh?3Y?HQ zAX0NL>XIkpf=MN83*!%}9-aN5)p7^py2Am>F9gW&pFSp#V0dxX#ZPW;UoD(gaI@8E z(rNQz1DBIiM13!LtZ|85lHB@$wW~n0fhRz-$?R&m{@z;uI}N|35As;}zdXB<I#+N1k=r*G-&mI78vJ_Ezs!yIV%J}l7d*c9>7Bn;xyLT84V&`$ z@9WMTAJ6DZyR)~=FS6P2e3MDv7lHB>{C&1H^7EJ9PIf=EdUwUYtGE9%$X9(m*ZWLf M_rC2^{;K~s0TRp{r2qf` literal 0 HcmV?d00001 diff --git a/public/images/datatables/sort_asc.png b/public/images/datatables/sort_asc.png new file mode 100644 index 0000000000000000000000000000000000000000..a56d0e21902ce620cd57f87fa58a6d3e804135cf GIT binary patch literal 263 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5tEa{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i>l2Ka=y{`vF&J9*~+_wWBdfBFCW_y37A{>@tOZ^^2EJ(K_a|Nno&o$%d2jr=7+e!)O45@5J; zXU0OHl&hzUV@SoVE9Xw~GAQscA1s)^?0*rXqM}DeLv7?|BU8z@QCOGupVzP9Hek5&L+Gnl%BD>~0~tJB{an^LB{Ts5b0m7= literal 0 HcmV?d00001 diff --git a/public/images/datatables/sort_asc_disabled.png b/public/images/datatables/sort_asc_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..b7e621ef1c68da839ce077cec6e201a55c1ba168 GIT binary patch literal 252 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5tEa{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i=)2l#}z{`>du$&)AV-@pIyd9;k)4B*-rq$b|z2+ZRf0KnW*L z7srr_TUXBQ7GeV6G?@}f$7k6Jhw{qGm$-QDzD`qrDaZ3s$b2XF;fBBPU nqjNDy&Nw~puHFA+-v&m8`?>-yUFVHK{$ucT^>bP0l+XkKhw^g= literal 0 HcmV?d00001 diff --git a/public/images/datatables/sort_both.png b/public/images/datatables/sort_both.png new file mode 100644 index 0000000000000000000000000000000000000000..839ac4bb5b0b414834c950de9deafff6dd94ed2d GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5tEa{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i=)2l#}z{`>du$&)AV-@pIyd9;k)4B*-rq$b|z2+ZRf0K#2rT z7srr_TRjsz`4|*ASOSl%eg6Ob+(JtRwX|O@S}a^IESQCgTe~DWM4fR9b+X literal 0 HcmV?d00001 diff --git a/public/images/datatables/sort_desc.png b/public/images/datatables/sort_desc.png new file mode 100644 index 0000000000000000000000000000000000000000..90b295159df995329b3a84340d32761f3d1dbade GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5tEa{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i>l2Ka=y{`vF&J9*~+_wWBdfBFCW_y37A{>@tOZ^^2EJ(K_a|Nno&o$%d2jr=7+e!)O45@5J; zXU0OHl#{26V@SoVqz8vtc$~v}dc~O{CLEF2anNavMpdMP)0v(X&o(k0opIq!LdvtJ wj~up7@0`wiSoe($&y07EkGxK6U|?nlJSz0{?wJWUfu=Edy85}Sb4q9e0C9MGu>b%7 literal 0 HcmV?d00001 diff --git a/public/images/datatables/sort_desc_disabled.png b/public/images/datatables/sort_desc_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..2409653dc94cd21a281a31c0e3819323b84704b7 GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5tEa{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i=)2l#}z{`>du$&)AV-@pIyd9;k)4B*-rq$b|z2+ZRf0KnX`r z7srr_TS*TNvhX;E^>j)zMNBv%VR68zN24n8K+>5N&kUJbBQCy4c=qgBiu3mAQ)hD? n)_oJhGvi(If!Apb49pB3GXz|UGFKJ=4P)?h^>bP0l+XkK*57ji literal 0 HcmV?d00001 diff --git a/public/javascripts/jquery.dataTables.js b/public/javascripts/jquery.dataTables.js new file mode 100644 index 000000000..1d84033a8 --- /dev/null +++ b/public/javascripts/jquery.dataTables.js @@ -0,0 +1,11349 @@ +/** + * @summary DataTables + * @description Paginate, search and sort HTML tables + * @version 1.9.0.dev.2 + * @file jquery.dataTables.js + * @author Allan Jardine (www.sprymedia.co.uk) + * @contact www.sprymedia.co.uk/contact + * + * @copyright Copyright 2008-2012 Allan Jardine, all rights reserved. + * + * This source file is free software, under either the GPL v2 license or a + * BSD style license, available at: + * http://datatables.net/license_gpl2 + * http://datatables.net/license_bsd + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * For details please refer to: http://www.datatables.net + */ + +/*jslint evil: true, undef: true, browser: true */ +/*globals $, jQuery,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString*/ + +(/** @lends */function($, window, document, undefined) { + /** + * DataTables is a plug-in for the jQuery Javascript library. It is a + * highly flexible tool, based upon the foundations of progressive + * enhancement, which will add advanced interaction controls to any + * HTML table. For a full list of features please refer to + * DataTables.net. + * + * Note that the DataTable object is not a global variable but is + * aliased to jQuery.fn.DataTable and jQuery.fn.dataTable through which + * it may be accessed. + * + * @class + * @param {object} [oInit={}] Configuration object for DataTables. Options + * are defined by {@link DataTable.defaults} + * @requires jQuery 1.3+ + * + * @example + * // Basic initialisation + * $(document).ready( function { + * $('#example').dataTable(); + * } ); + * + * @example + * // Initialisation with configuration options - in this case, disable + * // pagination and sorting. + * $(document).ready( function { + * $('#example').dataTable( { + * "bPaginate": false, + * "bSort": false + * } ); + * } ); + */ + var DataTable = function( oInit ) + { + + + /** + * Add a column to the list used for the table with default values + * @param {object} oSettings dataTables settings object + * @param {node} nTh The th element for this column + * @memberof DataTable#oApi + */ + function _fnAddColumn( oSettings, nTh ) + { + var oDefaults = DataTable.defaults.columns; + var iCol = oSettings.aoColumns.length; + var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { + "sSortingClass": oSettings.oClasses.sSortable, + "sSortingClassJUI": oSettings.oClasses.sSortJUI, + "nTh": nTh ? nTh : document.createElement('th'), + "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', + "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], + "mDataProp": oDefaults.mDataProp ? oDefaults.oDefaults : iCol + } ); + oSettings.aoColumns.push( oCol ); + + /* Add a column specific filter */ + if ( !oSettings.aoPreSearchCols[ iCol ] ) + { + oSettings.aoPreSearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch ); + } + else + { + var oPre = oSettings.aoPreSearchCols[ iCol ]; + + /* Don't require that the user must specify bRegex, bSmart or bCaseInsensitive */ + if ( oPre.bRegex === undefined ) + { + oPre.bRegex = true; + } + + if ( oPre.bSmart === undefined ) + { + oPre.bSmart = true; + } + + if ( oPre.bCaseInsensitive === undefined ) + { + oPre.bCaseInsensitive = true; + } + } + + /* Use the column options function to initialise classes etc */ + _fnColumnOptions( oSettings, iCol, null ); + } + + + /** + * Apply options for a column + * @param {object} oSettings dataTables settings object + * @param {int} iCol column index to consider + * @param {object} oOptions object with sType, bVisible and bSearchable + * @memberof DataTable#oApi + */ + function _fnColumnOptions( oSettings, iCol, oOptions ) + { + var oCol = oSettings.aoColumns[ iCol ]; + + /* User specified column options */ + if ( oOptions !== undefined && oOptions !== null ) + { + if ( oOptions.sType !== undefined ) + { + oCol.sType = oOptions.sType; + oCol._bAutoType = false; + } + + $.extend( oCol, oOptions ); + _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); + + /* iDataSort to be applied (backwards compatibility), but aDataSort will take + * priority if defined + */ + if ( oOptions.iDataSort !== undefined ) + { + oCol.aDataSort = [ oOptions.iDataSort ]; + } + _fnMap( oCol, oOptions, "aDataSort" ); + } + + /* Cache the data get and set functions for speed */ + oCol.fnGetData = _fnGetObjectDataFn( oCol.mDataProp ); + oCol.fnSetData = _fnSetObjectDataFn( oCol.mDataProp ); + + /* Feature sorting overrides column specific when off */ + if ( !oSettings.oFeatures.bSort ) + { + oCol.bSortable = false; + } + + /* Check that the class assignment is correct for sorting */ + if ( !oCol.bSortable || + ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) + { + oCol.sSortingClass = oSettings.oClasses.sSortableNone; + oCol.sSortingClassJUI = ""; + } + else if ( oCol.bSortable || + ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) + { + oCol.sSortingClass = oSettings.oClasses.sSortable; + oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI; + } + else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 ) + { + oCol.sSortingClass = oSettings.oClasses.sSortableAsc; + oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed; + } + else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 ) + { + oCol.sSortingClass = oSettings.oClasses.sSortableDesc; + oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed; + } + } + + + /** + * Adjust the table column widths for new data. Note: you would probably want to + * do a redraw after calling this function! + * @param {object} oSettings dataTables settings object + * @memberof DataTable#oApi + */ + function _fnAdjustColumnSizing ( oSettings ) + { + /* Not interested in doing column width calculation if autowidth is disabled */ + if ( oSettings.oFeatures.bAutoWidth === false ) + { + return false; + } + + _fnCalculateColumnWidths( oSettings ); + for ( var i=0 , iLen=oSettings.aoColumns.length ; i