diff --git a/CHANGELOG b/CHANGELOG index ef98fc8..c058237 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +0.0.6 (2012-05-30): + * patched to work with redmine 2.0 + * UI updated to enforce breakline properly utilised 0.0.5 (2011-01-23): * added js exapnd all button * Fixed missing spent time link diff --git a/README.rdoc b/README.rdoc index 23f893f..6b206ce 100644 --- a/README.rdoc +++ b/README.rdoc @@ -11,13 +11,14 @@ propagates the tree view to the project show page's subprojects list. * Anton-zaytsev * Shadowbq * cforce +* danmunn ==Changelog For the complete changelog see the CHANGELOG-file in the Projects Tree View plugin directory. ==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.6. ==Compatibility diff --git a/app/views/admin/projects.rhtml b/app/views/admin/projects.rhtml deleted file mode 100644 index 38a9f3b..0000000 --- a/app/views/admin/projects.rhtml +++ /dev/null @@ -1,97 +0,0 @@ -
| <%=l(:label_project)%> | -<%=l(:field_description)%> | -<%=l(:field_is_public)%> | -<%=l(:field_created_on)%> | -- |
|---|---|---|---|---|
| <%= "" %><%="" %><%= h(" |
- >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') %> - | -
+<%= link_to(l(:expand_all), "#", :onclick => 'expandAll()')%> / <%= link_to l(:collapse_all), "#", :onclick => 'collapseAll()' %> +
+ +| <%= l(:label_project)%> | +<%= l(:field_description)%> | +<%= l(:field_go_to)%> | + <% if show_project_progress %> +<%= l(:field_versions)%> | + <% end %> +<%= l(:field_created_on)%> | +
|---|---|---|---|---|
| + <% if has_children %> + + <% end %> + <%= project.active? ? link_to_project(project, {:action => 'show'}) : h(project.name) %> + "> | +<%= textilizable project.short_description.gsub(/\!.+\!/,""), :project => project %> | +<%= favorite_project_modules_links(project) %> | + <% if show_project_progress %> +<%= render_project_progress(project) %> | + <% end %> +<%= format_date(project.created_on) %> | +
+<%= link_to(l(:expand_all), "#", :onclick => 'expandAll()')%> / <%= link_to l(:collapse_all), "#", :onclick => 'collapseAll()' %> +
+ +<% 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/app/views/projects/index.rhtml b/app/views/projects/index.rhtml deleted file mode 100644 index b3ebaea..0000000 --- a/app/views/projects/index.rhtml +++ /dev/null @@ -1,101 +0,0 @@ -<% content_for :header_tags do %> - <%= auto_discovery_link_tag(:atom, {:action => 'index', :format => 'atom', :key => User.current.rss_key}) %> -<% end %> -| <%=l(:label_project)%> | -<%=l(:field_description)%> | -<%=l(:field_go_to)%> | -<%=l(:field_versions)%> | -<%=l(:field_created_on)%> | -
|---|---|---|---|---|
| <%= "" %><%="" %><%= h(" |
- >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 %> | -<%= favorite_project_modules_links(project) %> | -- | <%= format_date(project.created_on) %> | -
-<%= 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/app/views/settings/_project_tree_settings.html.erb b/app/views/settings/_project_tree_settings.html.erb new file mode 100644 index 0000000..fb7087e --- /dev/null +++ b/app/views/settings/_project_tree_settings.html.erb @@ -0,0 +1,4 @@ ++ <%= content_tag(:label, l(:show_progress)) %> + <%= check_box_tag('settings[show_project_progress]', true, @settings['show_project_progress'])%> +
diff --git a/assets/javascripts/projects_tree_view.js b/assets/javascripts/projects_tree_view.js index 5f11259..3ff6fbc 100644 --- a/assets/javascripts/projects_tree_view.js +++ b/assets/javascripts/projects_tree_view.js @@ -1,104 +1,69 @@ /* 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 toggleOddEven() { + var isEven = false; + $('table.list tr.project:not(.hide)').each(function() { + var e = $(this); + e.removeClass('odd'); + e.removeClass('even'); + e.addClass(isEven ? 'even' : 'odd'); + isEven = !isEven; + }) +} + +function expandProjectTree(id) { + $('table.list tr.child.' + id).each(function() { + var e = $(this); + e.removeClass('hide'); + if (e.hasClass('open')) { + expandProjectTree(e.context.id); + } + }) +} + +function collapseProjectTree(id) { + $('table.list tr.child.' + id).each(function() { + var e = $(this); + e.addClass('hide'); + collapseProjectTree(e.context.id); + }) +} + +function toggleShowHide(id) { + var e = $('#' + id); -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) ) { + if (e.hasClass('open')) { + collapseProjectTree(id); + e.removeClass('open'); + } else { + expandProjectTree(id); + e.addClass('open'); + } - var cnames = els[i].className; - - cnames = cnames.replace(/hide/g,''); - - if (expand.test(document.getElementById(PM).className)) - { - cnames += ' hide'; - } - else - { - /* classid test function is buggy and matches incorrect ids 5 matches 50. */ - 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; - } + toggleOddEven(); } +function expandAll() { + $('table.list tr.project').each(function() { + var e = $(this); + e.removeClass('hide'); + if (!e.hasClass('leaf')) { + e.addClass('open'); + } + }); + + toggleOddEven(); +} + +function collapseAll() { + $('table.list tr.project').each(function() { + var e = $(this); + e.removeClass('open'); + if (!e.hasClass('root')) { + e.addClass('hide'); + } + }); + + toggleOddEven(); +} diff --git a/assets/stylesheets/projects_tree_view.css b/assets/stylesheets/projects_tree_view.css index 6bf1e9a..44ade45 100644 --- a/assets/stylesheets/projects_tree_view.css +++ b/assets/stylesheets/projects_tree_view.css @@ -1,11 +1,9 @@ tr.parent { border: 1px solid #f8f8f8; } tr.parent td.name { white-space: nowrap; width: 300px; } -tr.child { border: 1px solid #f8f8f8; } -tr.child td.name { white-space: nowrap; width: 300px; } -tr.parent span.expander {background-image: url(../images/bullet_toggle_plus.png); padding-left: 8px; margin-left: 0; cursor: pointer;} -span.empty { text-align:right; width: 100%; cursor: pointer;} -tr.parent.open span.expander {background-image: url(../images/bullet_toggle_minus.png); cursor: pointer;} -tr.parent.open {background-color:#ffffbb;} -tr.hide { - display:none; - } +tr.child { border: 1px solid #f8f8f8; } +tr.child td.name { white-space: nowrap; width: 300px; } +tr.leaf td.name a { margin-left: 16px; } +tr.parent span.expander { background-image: url(../images/bullet_toggle_plus.png); padding-left: 8px; margin-left: 0; cursor: pointer; } +span.empty { text-align:right; width: 100%; cursor: pointer; } +tr.parent.open span.expander { background-image: url(../images/bullet_toggle_minus.png); cursor: pointer; } +tr.hide { display:none; } diff --git a/config/locales/en.yml b/config/locales/en.yml index 04710ce..a9d3ada 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -5,3 +5,5 @@ en: field_go_to: Go to module subprojects: sub projects expand_all: "Expand All" + collapse_all: "Collapse All" + show_progress: "Show project progress" diff --git a/config/locales/ja.yml b/config/locales/ja.yml new file mode 100644 index 0000000..a2f9ffa --- /dev/null +++ b/config/locales/ja.yml @@ -0,0 +1,8 @@ +ja: + + field_versions: "バージョン" + field_go_to: "モジュール" + subprojects: "サブプロジェクト" + expand_all: "すべて表示する" + collapse_all: "サブプロジェクトを隠す" + show_progress: "プロジェクトの進捗を表示する" diff --git a/init.rb b/init.rb index eee09a0..a917d14 100644 --- a/init.rb +++ b/init.rb @@ -1,22 +1,22 @@ require 'redmine' +require 'projects_tree_view_projects_helper_patch' + # Patches to the Redmine core. -require 'dispatcher' -require 'projectstreeview_projects_helper_patch' +Rails.configuration.to_prepare do + require_dependency 'projects_helper' + ProjectsHelper.send(:include, ProjectsTreeView::ProjectsHelperPatch) +end Redmine::Plugin.register :projects_tree_view do name 'Projects Tree View plugin' - author 'Chris Peterson' + author 'Chris Peterson and Github community' description 'This is a Redmine plugin which will turn the projects page into a tree view' - version '0.0.4' -end - -class ProjectsTreeViewListener < Redmine::Hook::ViewListener + url 'https://github.com/cforce/projects_tree_view' + version '0.0.8' + requires_redmine :version_or_higher => '2.1.0' - # Adds javascript and stylesheet tags - def view_layouts_base_html_head(context) - javascript_include_tag('projects_tree_view', :plugin => :projects_tree_view) + - stylesheet_link_tag('projects_tree_view', :plugin => :projects_tree_view) - end - + settings :default => { + 'show_project_progress' => true + }, :partial => 'settings/project_tree_settings' end diff --git a/lib/projects_tree_view_projects_helper_patch.rb b/lib/projects_tree_view_projects_helper_patch.rb new file mode 100644 index 0000000..b154e54 --- /dev/null +++ b/lib/projects_tree_view_projects_helper_patch.rb @@ -0,0 +1,65 @@ +module ProjectsTreeView + module ProjectsHelperPatch + extend ActiveSupport::Concern + + module ClassMethods + end + + def render_project_progress(project) + s = '' + cond = project.project_condition(false) + + open_issues = Issue.visible.count(:include => [:project, :status, :tracker], :conditions => ["(#{cond}) AND #{IssueStatus.table_name}.is_closed=?", false]) + + if open_issues > 0 + issues_closed_pourcent = (1 - open_issues.to_f/project.issues.count) * 100 + s << "