diff --git a/CHANGELOG b/CHANGELOG index 1899a23..a09c0cd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +0.0.4 (2010-06-23): + * Sync with Redmine 0.9.4 + * Added plugin functionality to admin/projects page + * Fix problem with projects without active children + * Deleted unuseful plugin-skeleton files + * added js exapnd all button + * Fixed missing spent time link 0.0.3 (2009-08-02): * Improved documentation and licensing * Updated the core-overriding views (required compatibility-helpers, see below) diff --git a/README.rdoc b/README.rdoc index cb1dabb..0e1cbd9 100644 --- a/README.rdoc +++ b/README.rdoc @@ -3,9 +3,11 @@ Projects Tree View is a Redmine plugin which will turn the projects index view into a tree view. It also propagates the tree view to the project show page's subprojects list. -==Author +==Author(s) -* Chris Peterson +* cforce (edits) +* Steven Verbeek (edits) +* Chris Peterson (original) ==Changelog @@ -13,19 +15,19 @@ For the complete changelog see the CHANGELOG-file in the Projects Tree ==Latest stable release -The currently available, latest stable release of the plugin is version 0.0.3. +The currently available, latest stable release of the plugin is version 0.0.4. ==Compatibility -This plugin is compatible with Redmine trunk only! +This plugin is compatible with Redmine 0.9.4-1.2.1 ==Obtaining -URL of the GitHub repository: http://github.com/MischaTheEvil/projects_tree_view/tree/master +URL of the GitHub repository: http://github.com/dubcanada/projects_tree_view/master The source of this plugin can be "cloned" from the GitHub-repo using: -$ cd {RAILS_ROOT}/vendor/plugins && git clone git://github.com/MischaTheEvil/projects_tree_view.git +$ cd {RAILS_ROOT}/vendor/plugins && git://github.com/dubcanada/projects_tree_view.git ==Installation diff --git a/app/views/admin/projects.rhtml b/app/views/admin/projects.rhtml new file mode 100644 index 0000000..90b6360 --- /dev/null +++ b/app/views/admin/projects.rhtml @@ -0,0 +1,92 @@ +
+<%= link_to l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add' %> +
+ +

<%=l(:label_project_plural)%>

+ +<% form_tag({}, :method => :get) do %> +
<%= l(:label_filter_plural) %> + +<%= select_tag 'status', project_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %> + +<%= text_field_tag 'name', params[:name], :size => 30 %> +<%= submit_tag l(:button_apply), :class => "small", :name => nil %> +
+<% end %> +  + +
+ + + + + + + + + +<% ancestors = [] %> +<% for project in @projects %> + <% rowid = "" %> + <% classes = "" %> + <% spanicon = "" %> + <% openonclick = "" %> + <% showchildren = false %> + <% project.children.each do |child| %> + <% if @projects.include?(child) %> + <% showchildren = true %> + <% break %> + <% end %> + <% end %> + <% if(!project.children.empty? && showchildren) %> + <% classes += " closed parent " + cycle("odd", "even") %> + <% rowid = "id=\""+project.id.to_s+"span\"" %> + <% openonclick = "onclick=\"showHide('"+project.id.to_s+"','"+project.id.to_s+"span')\""%> + <% spanicon = "  " %> + <% else %> + <% classes += " child" %> + <% end %> + <% if(project.parent_id == nil) %> + <% ancestors.clear %> + <% ancestors << project.id %> + <% else %> + <% while (ancestors.any? && !(project.parent_id == ancestors.last)) %> + <% ancestors.pop %> + <% end %> + <% classes += " hide" %> + <% if( !(ancestors.detect {|pid| pid == project.parent_id })) %> + <% prvclasses = "closed show parent " + cycle("odd", "even") %> + <% ancestors.each do |pid| %> + <% prvclasses += " " + pid.to_s %> + <% end %> + <% openonclick = "onclick=\"showHide('"+project.parent_id.to_s+"','"+project.parent_id.to_s+"span')\"" %> + " > + + + + + <% ancestors << project.parent_id %> + <% end %> + <% ancestors.each do |pid| %> + <% classes += " " + pid.to_s %> + <% end %> + <% ancestors << project.id %> + <% end %> + > + + + + + + +<% end %> + +
<%=l(:label_project)%><%=l(:field_description)%><%=l(:field_is_public)%><%=l(:field_created_on)%>
<%= "" %><%="  " %><%= h("") %> class="empty">  >Project is private.
<%= "" %><%= spanicon %><%= project.active? ? link_to(h(project.name), {:controller => 'projects', :action => 'show', :id => project}, :class => "project") : h(project.name) %> ><%= textilizable project.short_description, :project => project %><%= image_tag 'true.png' if project.is_public? %><%= format_date(project.created_on) %> + <%= link_to(l(:button_archive), { :controller => 'projects', :action => 'archive', :id => project, :status => params[:status] }, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-lock') if project.active? %> + <%= link_to(l(:button_unarchive), { :controller => 'projects', :action => 'unarchive', :id => project, :status => params[:status] }, :method => :post, :class => 'icon icon-unlock') if !project.active? && (project.parent.nil? || project.parent.active?) %> + <%= link_to(l(:button_copy), { :controller => 'projects', :action => 'copy', :id => project }, :class => 'icon icon-copy') %> + <%= link_to(l(:button_delete), project_destroy_confirm_path(project), :class => 'icon icon-del') %> +
+
+ +<% html_title(l(:label_project_plural)) -%> diff --git a/app/views/projects/index.rhtml b/app/views/projects/index.rhtml index 03b3dd1..f40c322 100644 --- a/app/views/projects/index.rhtml +++ b/app/views/projects/index.rhtml @@ -1,79 +1,93 @@ -
- <% if authorize_global_implemented %> - <%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'add'}, :class => 'icon icon-add') + ' |' if User.current.allowed_to?(:add_project, nil, :global => true) %> - <% else %> - <%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'add'}, :class => 'icon icon-add') + ' |' if User.current.admin? %> - <% end %> - <%= link_to l(:label_issue_view_all), { :controller => 'issues' } %> | - <%= link_to l(:label_overall_activity), { :controller => 'projects', :action => 'activity' }%> -
- -

<%=l(:label_project_plural)%>

- - - - - - - - - - <% ancestors = [] %> - <% for project in @projects %> - <% rowid = "" %> - <% classes = "" %> - <% spanicon = "" %> - <% openonclick = "" %> - <% if(!project.children.empty?) %> - <% classes += " closed parent " + cycle("odd", "even") %> - <% rowid = "id=\""+project.id.to_s+"span\"" %> - <% openonclick = "onclick=\"showHide('"+project.id.to_s+"','"+project.id.to_s+"span')\""%> - <% spanicon = "  " %> - <% else %> - <% classes += " child" %> - <% end %> - <% if(project.parent_id == nil) %> - <% ancestors.clear %> - <% ancestors << project.id %> - <% else %> - <% while (ancestors.any? && !(project.parent_id == ancestors.last)) %> - <% ancestors.pop %> - <% end %> - <% classes += " hide" %> - <% if( !(ancestors.detect {|pid| pid == project.parent_id })) %> - <% prvclasses = "closed show parent " + cycle("odd", "even") %> - <% ancestors.each do |pid| %> - <% prvclasses += " " + pid.to_s %> - <% end %> - <% openonclick = "onclick=\"showHide('"+project.parent_id.to_s+"','"+project.parent_id.to_s+"span')\"" %> - " > - - - - - <% ancestors << project.parent_id %> - <% end %> - <% ancestors.each do |pid| %> - <% classes += " " + pid.to_s %> - <% end %> - <% ancestors << project.id %> - <% end %> - > - - - - <% end %> - -
<%=l(:label_project)%><%=l(:field_description)%>
<%= "" %><%="  " %><%= h("") %> class="empty">  >Project is private.
<%= "" %><%= spanicon %><%= project.active? ? link_to(h(project.name), {:controller => 'projects', :action => 'show', :id => project}, :class => "project") : h(project.name) %> class="empty <%=User.current.member_of?(project) ? 'my-project' : nil%>">  ><%= textilizable project.short_description.gsub(/\!.+\!/,""), :project => project %>
- -<% if User.current.logged? %> -

-<%= l(:label_my_projects) %> -

-<% end %> - -<% other_formats_links do |f| %> - <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %> -<% end %> - -<% html_title(l(:label_project_plural)) -%> +<% content_for :header_tags do %> + <%= auto_discovery_link_tag(:atom, {:action => 'index', :format => 'atom', :key => User.current.rss_key}) %> +<% end %> +
+ <% if authorize_global_implemented %> + <%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add') + ' |' if User.current.allowed_to?(:add_project, nil, :global => true) %> + <% else %> + <%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add') + ' |' if User.current.admin? %> + <% end %> + <%= link_to(l(:label_issue_view_all), { :controller => 'issues' }) + ' |' if User.current.allowed_to?(:view_issues, nil, :global => true) %> + <%= link_to(l(:label_overall_spent_time), { :controller => 'time_entries' }) + ' |' if User.current.allowed_to?(:view_time_entries, nil, :global => true) %> + <%= link_to l(:label_overall_activity), { :controller => 'activities', :action => 'index' }%> +
+ +

<%=l(:label_project_plural)%>

+ + + + + + + + + + <% ancestors = [] %> + <% for project in @projects %> + <% rowid = "" %> + <% classes = "" %> + <% spanicon = "" %> + <% openonclick = "" %> + <% showchildren = false %> + <% project.children.each do |child| %> + <% if @projects.include?(child) %> + <% showchildren = true %> + <% break %> + <% end %> + <% end %> + <% if(!project.children.empty? && showchildren) %> + <% classes += " closed parent " + cycle("odd", "even") %> + <% rowid = "id=\""+project.id.to_s+"span\"" %> + <% openonclick = "onclick=\"showHide('"+project.id.to_s+"','"+project.id.to_s+"span')\""%> + <% spanicon = "  " %> + <% else %> + <% classes += " child" %> + <% end %> + <% if(project.parent_id == nil) %> + <% ancestors.clear %> + <% ancestors << project.id %> + <% else %> + <% while (ancestors.any? && !(project.parent_id == ancestors.last)) %> + <% ancestors.pop %> + <% end %> + <% classes += " hide" %> + <% if( !(ancestors.detect {|pid| pid == project.parent_id })) %> + <% prvclasses = "closed show parent " + cycle("odd", "even") %> + <% ancestors.each do |pid| %> + <% prvclasses += " " + pid.to_s %> + <% end %> + <% openonclick = "onclick=\"showHide('"+project.parent_id.to_s+"','"+project.parent_id.to_s+"span')\"" %> + " > + + + + + <% ancestors << project.parent_id %> + <% end %> + <% ancestors.each do |pid| %> + <% classes += " " + pid.to_s %> + <% end %> + <% ancestors << project.id %> + <% end %> + > + + + + <% end %> + +
<%=l(:label_project)%><%=l(:field_description)%>
<%= "" %><%="  " %><%= h("") %> class="empty">  >Project is private.
<%= "" %><%= spanicon %><%= project.active? ? link_to(h(project.name), {:controller => 'projects', :action => 'show', :id => project}, :class => "project") : h(project.name) %> class="empty <%=User.current.member_of?(project) ? 'my-project' : nil%>">  ><%= textilizable project.short_description.gsub(/\!.+\!/,""), :project => project %>
+ +Expand All + + +<% if User.current.logged? %> +

+<%= l(:label_my_projects) %> +

+<% end %> + +<% other_formats_links do |f| %> + <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %> +<% end %> + +<% html_title(l(:label_project_plural)) -%> diff --git a/assets/javascripts/projects_tree_view.js b/assets/javascripts/projects_tree_view.js index 7cd26af..02c2e79 100644 --- a/assets/javascripts/projects_tree_view.js +++ b/assets/javascripts/projects_tree_view.js @@ -1,94 +1,103 @@ -/* Function to allow the projects to show up as a tree */ - -function showHide(EL,PM) -{ - var els = document.getElementsByTagName('tr'); - var elsLen = els.length; - var pattern = new RegExp("(^|\\s)"+EL+"(\\s|$)"); - var cpattern = new RegExp("span"); - var expand = new RegExp("open"); - var collapse = new RegExp("closed"); - var hide = new RegExp("hide"); - var spanid = PM; - var classid = new RegExp("junk"); - var oddeventoggle = 0; - for (i = 0; i < elsLen; i++) - { - - if(cpattern.test(els[i].id)) - { - var tmpspanid = spanid; - var tmpclassid = classid; - spanid = els[i].id; - classid = spanid; - classid = classid.match(/(\w+)span/)[1]; - classid = new RegExp(classid); - if(tmpclassid.test(els[i].className) && (tmpspanid.toString() != PM.toString())) - { - if(collapse.test(document.getElementById(tmpspanid).className)) - { - spanid = tmpspanid; - classid = tmpclassid; - } - } - } - - if ( pattern.test(els[i].className) ) { - - var cnames = els[i].className; - - cnames = cnames.replace(/hide/g,''); - - if (expand.test(document.getElementById(PM).className)) - { - cnames += ' hide'; - } - else - { - if((spanid.toString() != PM.toString()) && - (classid.test(els[i].className))) - { - if(collapse.test(document.getElementById(spanid).className)) - { - cnames += ' hide'; - } - } - } - - els[i].className = cnames; - - } - - if(!(hide.test(els[i].className))) - { - var cnames = els[i].className; - cnames = cnames.replace(/odd/g,''); - cnames = cnames.replace(/even/g,''); - - if(oddeventoggle == 0) - { - cnames += ' odd'; - } - else - { - cnames += ' even'; - } - - oddeventoggle ^= 1; - els[i].className = cnames; - } - } - if (collapse.test(document.getElementById(PM).className)) - { - var cnames = document.getElementById(PM).className; - cnames = cnames.replace(/closed/,'open'); - document.getElementById(PM).className = cnames; - } - else - { - var cnames = document.getElementById(PM).className; - cnames = cnames.replace(/open/,'closed'); - document.getElementById(PM).className = cnames; - } -} - +/* Function to allow the projects to show up as a tree */ + + Event.observe(window, 'load', function() { + if ($('expand_all')) { + $('expand_all').observe('click', function() { + $$('table.list tr').each(function(e) { e.addClassName('open'); e.removeClassName('hide'); }); + }); + } + }); + + +function showHide(EL,PM) +{ + var els = document.getElementsByTagName('tr'); + var elsLen = els.length; + var pattern = new RegExp("(^|\\s)"+EL+"(\\s|$)"); + var cpattern = new RegExp("span"); + var expand = new RegExp("open"); + var collapse = new RegExp("closed"); + var hide = new RegExp("hide"); + var spanid = PM; + var classid = new RegExp("junk"); + var oddeventoggle = 0; + for (i = 0; i < elsLen; i++) + { + + if(cpattern.test(els[i].id)) + { + var tmpspanid = spanid; + var tmpclassid = classid; + spanid = els[i].id; + classid = spanid; + classid = classid.match(/(\w+)span/)[1]; + classid = new RegExp(classid); + if(tmpclassid.test(els[i].className) && (tmpspanid.toString() != PM.toString())) + { + if(collapse.test(document.getElementById(tmpspanid).className)) + { + spanid = tmpspanid; + classid = tmpclassid; + } + } + } + + if ( pattern.test(els[i].className) ) { + + var cnames = els[i].className; + + cnames = cnames.replace(/hide/g,''); + + if (expand.test(document.getElementById(PM).className)) + { + cnames += ' hide'; + } + else + { + if((spanid.toString() != PM.toString()) && + (classid.test(els[i].className))) + { + if(collapse.test(document.getElementById(spanid).className)) + { + cnames += ' hide'; + } + } + } + + els[i].className = cnames; + + } + + if(!(hide.test(els[i].className))) + { + var cnames = els[i].className; + cnames = cnames.replace(/odd/g,''); + cnames = cnames.replace(/even/g,''); + + if(oddeventoggle == 0) + { + cnames += ' odd'; + } + else + { + cnames += ' even'; + } + + oddeventoggle ^= 1; + els[i].className = cnames; + } + } + if (collapse.test(document.getElementById(PM).className)) + { + var cnames = document.getElementById(PM).className; + cnames = cnames.replace(/closed/,'open'); + document.getElementById(PM).className = cnames; + } + else + { + var cnames = document.getElementById(PM).className; + cnames = cnames.replace(/open/,'closed'); + document.getElementById(PM).className = cnames; + } +} + diff --git a/init.rb b/init.rb index a1add96..eee09a0 100644 --- a/init.rb +++ b/init.rb @@ -3,15 +3,12 @@ # Patches to the Redmine core. require 'dispatcher' require 'projectstreeview_projects_helper_patch' -Dispatcher.to_prepare do - ProjectsHelper.send(:include, ProjectstreeviewProjectsHelperPatch) -end Redmine::Plugin.register :projects_tree_view do name 'Projects Tree View plugin' author 'Chris Peterson' description 'This is a Redmine plugin which will turn the projects page into a tree view' - version '0.0.3' + version '0.0.4' end class ProjectsTreeViewListener < Redmine::Hook::ViewListener diff --git a/lib/projectstreeview_projects_helper_patch.rb b/lib/projectstreeview_projects_helper_patch.rb index bb372ad..0dd3b00 100644 --- a/lib/projectstreeview_projects_helper_patch.rb +++ b/lib/projectstreeview_projects_helper_patch.rb @@ -30,3 +30,4 @@ def authorize_global_implemented end # Close the module ProjectstreeviewProjectsHelperPatch::InstanceMethods end # Close the module ProjectstreeviewProjectsHelperPatch +ProjectsHelper.send(:include, ProjectstreeviewProjectsHelperPatch)