Revision 823:73057b65abcb

View differences:

app/helpers/projects_helper.rb
150 150

  
151 151
    if s != ''
152 152
      a = ''
153
      a << "<h2>"
154
      a <<  l("label_my_project_plural")
155
      a << "</h2>"
156 153
      a << "<ul class='projects root'>\n"
157 154
      a << s
158 155
      a << "</ul>\n"
app/views/projects/show.rhtml
98 98
</div>
99 99

  
100 100
<% content_for :sidebar do %>
101
    <%= call_hook(:view_projects_show_sidebar_top, :project => @project) %>
101 102
    <% if @total_hours.present? %>
102 103
    <h3><%= l(:label_spent_time) %></h3>
103 104
    <p><span class="icon icon-time"><%= l_hours(@total_hours) %></span></p>
public/themes/soundsoftware/stylesheets/application.css
226 226

  
227 227
.embedded #matlabdoc th { text-align: left; }
228 228

  
229
/* autocomplete positioning fix */
230
div.autocomplete {
231
	margin-top:136px;
232
}
229 233

  
234
#my_projects_fieldset.collapsible {
235
	font-size: 1.0em;
236
	font-color: green;
237
}
230 238

  
239

  
240

  
241

  
vendor/plugins/redmine_bibliography/app/views/projects/show.rhtml
101 101
</div>
102 102

  
103 103
<% content_for :sidebar do %>
104
    <%= call_hook(:view_projects_show_sidebar_top, :project => @project) %>
104 105
    <% if @total_hours && User.current.allowed_to?(:view_time_entries, @project) %>
105 106
    <h3><%= l(:label_spent_time) %></h3>
106 107
    <p><span class="icon icon-time"><%= l_hours(@total_hours) %></span></p>
vendor/plugins/redmine_tags/app/views/auto_completes/_search_tag_list.html.erb
1
<ul>
2
	<% @tags.each do |tag| -%>
3
  		<%= content_tag 'li', h('%s (%d)' % [tag.name, tag.count]), :name => tag.name %>
4
	<% end -%>
5
</ul>
vendor/plugins/redmine_tags/app/views/auto_completes/_tag_list.html.erb
2 2
<% @tags.each do |tag| -%>
3 3
  <%= content_tag 'li', h('%s (%d)' % [tag.name, tag.count]), :name => tag.name %>
4 4
<% end -%>
5
<%= content_tag 'li', l(:auto_complete_new_tag) % @name, :name => @name %>
5
  <%= content_tag 'li', l(:auto_complete_new_tag) % @name, :name => @name %>
6 6
</ul>
vendor/plugins/redmine_tags/app/views/projects/_filter_search_tags.html.erb
1
<p class='tag'>
2
  <%- fields_for @project, :builder => TabularFormBuilder do |f| -%>
3
    <div>
4
      <p id="project_tags">
5
        <%= f.text_field :tag_list, :label => :label_tags_search, :size => 60, :class => 'hol' -%>
6
      </p>
7
      <div id="project_tag_candidates" class="autocomplete"></div>
8
      <%= javascript_include_tag 'tags_input', :plugin => 'redmine_tags' -%>
9
      <%= javascript_tag "observeProjectTagsField('#{url_for(:controller => 'auto_completes', :action => 'project_search_tags', :project_id => Project.first.id)}', true)" -%>
10
    </div>
11
  <%- end -%>
12
</p>
vendor/plugins/redmine_tags/app/views/projects/_filter_tags.rhtml
7 7
      <div id="project_tag_candidates" class="autocomplete"></div>
8 8
      <%= javascript_include_tag 'tags_input', :plugin => 'redmine_tags' %>
9 9

  
10
      <%= javascript_tag "observeProjectTagsField('#{url_for(:controller => 'auto_completes', :action => 'project_tags')}')" %>
10
      <%= javascript_tag "observeProjectTagsField('#{url_for(:controller => 'auto_completes', :action => 'project_tags', :project_id => Project.first.id)}')" %>
11 11
    </div>
12 12
  <% end -%>
13 13
</p>
vendor/plugins/redmine_tags/app/views/projects/_filtered_projects.rhtml
1
<%= render_project_table_with_filtering(@filtered_projects, @question) %>
1
<% if @projects.empty? %>
2
<p><b><%= l(:project_filter_no_results) %></b></p>
3
<% else %>
4
<%= render_project_table_with_filtering(@projects, @question) %>
5
<% end %>
6

  
7
<p class="pagination"><%= pagination_links_full @project_pages, @project_count %></p>
vendor/plugins/redmine_tags/app/views/projects/_my_projects.rhtml
1
<fieldset id="filters" class="collapsible">
2
    <legend onclick="toggleFieldset(this);"><%= l(:label_my_projects) %></legend>
3
    <% if @user_projects %>  
1
<% if !@user_projects.empty? %>
2
<% if @myproj_status=="true" %>
3
<fieldset id="my_projects_fieldset" class="collapsible">
4
    <legend onclick="toggleFieldsetWithState(this);"><h2><%= l(:label_my_project_plural) %></h2></legend>
5
<% else %>
6
<fieldset id="my_projects_fieldset" class="collapsible collapsed">
7
    <legend onclick="toggleFieldsetWithState(this);"><h2><%= l(:label_my_project_plural) %></h2></legend>
8
    <div style="display: none;">    
9
<% end %>
4 10
    <div>
5
      <%= render_my_project_hierarchy(@user_projects)%>
11
      <%= render_my_project_hierarchy_with_tags(@user_projects)%>
6 12
    </div>
7
  <% end %>
8
</fieldset>
13
  <% unless @myproj_status=="true" %>
14
    </div>
15
  <%- end -%>
16
</fieldset>
17
<% end %>
vendor/plugins/redmine_tags/app/views/projects/_tags.html.erb
1 1
<% unless @project.tag_list.empty? %>
2
  <tr>
3
    <td><b><%=l(:tags)%>:</b></td>
4
    <td><%= @project.tag_counts.collect{ |t| render_project_tag_link(t) }.join(', ') %></td>
5
  </tr>
2
  <%= stylesheet_link_tag 'redmine_tags', :plugin => 'redmine_tags' %>
3
  <dl class="tags">
4
    <dt class="tags-title"><%=l(:tags)%></dt>
5
    <dd class="tags"><%= @project.tag_counts.collect{ |t| render_project_tag_link(t) }.join(', ') %></dd>
6
  </dl>
6 7
<% end %>
vendor/plugins/redmine_tags/app/views/projects/_tags_form.html.erb
3 3
  <p id="project_tags"><%= f.text_field :tag_list, :label => :tags, :size => 60, :class => 'hol' %></p>
4 4
  <div id="project_tag_candidates" class="autocomplete"></div>
5 5
  <%= javascript_include_tag 'tags_input', :plugin => 'redmine_tags' %>
6
  <%= javascript_tag "observeProjectTagsField('#{url_for(:controller => 'auto_completes', :action => 'project_tags', :project_id => project)}')" %>
6
  <%= javascript_tag "observeProjectTagsField('#{url_for(:controller => 'auto_completes', :action => 'project_tags', :project_id => project)}', false)" %>
7 7
</div>
8 8
<% end -%>
vendor/plugins/redmine_tags/app/views/projects/index.rhtml
1 1
<% content_for :header_tags do %>
2 2
    <%= auto_discovery_link_tag(:atom, {:action => 'index', :format => 'atom', :key => User.current.rss_key}) %>
3
    <%= stylesheet_link_tag 'redmine_tags', :plugin => 'redmine_tags' %>
3 4
<% end %>
5
<%= javascript_include_tag 'projects_index', :plugin => 'redmine_tags' %>
6

  
4 7

  
5 8
<div class="contextual">
6 9
    <%= link_to l(:label_overall_activity), { :controller => 'activities', :action => 'index' }%>
......
14 17
  <%= render :partial => 'my_projects' %>
15 18
<% end %>
16 19

  
17

  
18
<div style="clear:both;"></div>
19
<% form_tag('/projects', :method => :get, :id => :project_filtering) do %>
20
  <fieldset id="filters" class="collapsible">
21
    <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
22
    <div>
23
      <p class='q'>
24
        <%= label_tag 'q', l('project_filtering_q_label') %>
25
        <%= text_field_tag 'q', @question, :size => 30, :id => 'search-input' %>
26
      </p>
27

  
28
      <div id='filter_tags'>
29
        <%= render :partial => 'filter_tags' %>
30
      </div>
31

  
32
      <p class='buttons'><%= submit_tag( l('button_filter'), :id => 'filter_button') -%></p>                  
33
    </div>
34
  </fieldset>
35
<% end %>
36

  
37 20
<div style="clear:both;"></div>
38 21
<h2>
39 22
  <%= l("label_project_all") %>
40 23
</h2>
41 24

  
25
<div style="clear:both;"></div>
26
  <%- form_remote_tag(:controller => :projects, :action => :index, :method => :get, :html => {:id => :project_filtering_form}) do -%>
27

  
28
    <% if @filter_status=="true" %>
29
      <fieldset id="filters_fieldset" class="collapsible">
30
      <legend onclick="toggleFieldsetWithState(this);"><%= l(:label_filter_plural) %></legend>
31
    <%- else -%>
32
      <fieldset id="filters_fieldset" class="collapsible collapsed">
33
      <legend onclick="toggleFieldsetWithState(this);"><%= l(:label_filter_plural) %></legend>
34
      <div style="display: none;">
35
    <%- end -%>
36

  
37
  <div>
38
    <div id='filter_tags'>
39
      <%= render :partial => 'filter_search_tags' -%>
40
    </div>
41

  
42
    <p class='q'>
43
      <%= label_tag 'q', l('project_filtering_q_label') %>
44
      <%= text_field_tag 'q', @question, :size => 30, :id => 'search-input' %>
45
    </p>
46

  
47
    <p style="display: none;"><%= submit_tag( l('button_filter'), :id => 'submitButton') -%></p>
48
    <%= link_to l(:button_apply), {}, :onclick => "$('submitButton').click(); return false;", :class => 'icon icon-checked' -%>
49
    <%= link_to l(:button_clear), {}, :class => 'icon icon-reload'  %>                         
50
  </div>
51
  
52
    <% unless @filter_status=="true" %>
53
      </div>
54
    <%- end -%>
55

  
56

  
57
<%- end -%>
58
</fieldset>
59

  
42 60
<div id="projects">
43 61
  <%= render :partial => 'filtered_projects' %>
44 62
</div>
45 63

  
46
<p class="pagination"><%= pagination_links_full @project_pages, @project_count %></p>
64

  
47 65

  
48 66

  
49 67
<% other_formats_links do |f| %>
vendor/plugins/redmine_tags/assets/javascripts/projects_index.js
1
function toggleFieldsetWithState(this_field){
2
	id = Element.up(this_field, 'fieldset').id;	
3
	// is the fieldset collapsed?
4
	status = $(id).hasClassName("collapsed");
5
	change_session(id, status);
6
	
7
	toggleFieldset(this_field);
8

  
9
};
10

  
11
	function submitForm(){
12
		$('submitButton').click();		
13
	};
14

  
15
function change_session(id, nstatus) {
16
	var url = "projects/set_fieldset_status";
17
 	var request = new Ajax.Request(url, {
18
		method: 'post',
19
	 	parameters: {field_id: id, status: nstatus},
20
    	asynchronous: true
21
  	});
22
}
23

  
24
function keypressHandler (event){
25
  var key = event.which || event.keyCode;
26
  switch (key) {
27
      default:
28
      break;
29
      case Event.KEY_RETURN:
30
          $('submitButton').click(); return false;
31
      break;   
32
  };
33
};
34

  
35
document.observe("dom:loaded", function() {
36
	$('search-input').observe('keypress', keypressHandler);	
37
});
vendor/plugins/redmine_tags/assets/javascripts/tags_input.js
21 21
var Redmine = Redmine || {};
22 22

  
23 23
Redmine.TagsInput = Class.create({
24
  initialize: function(element) {
24
  initialize: function(element, update) {
25 25
    this.element  = $(element);
26 26
    this.input    = new Element('input', { 'type': 'text', 'autocomplete': 'off', 'size': 10 });
27 27
    this.button   = new Element('span', { 'class': 'tag-add icon icon-add' });
28 28
    this.tags     = new Hash();
29 29
    
30
		this.update = update;
31
		
32
		var uri_params = window.location.href.toQueryParams();
33
		if (uri_params["project[tag_list]"] != undefined){
34
			this.addTag(uri_params["project[tag_list]"].stripTags(), true);			
35
		};
36
		
30 37
    Event.observe(this.button, 'click', this.readTags.bind(this));
31 38
    Event.observe(this.input, 'keypress', this.onKeyPress.bindAsEventListener(this));
32 39

  
......
35 42
    this.addTagsList(this.element.value);
36 43
  },
37 44

  
38
  readTags: function() {
45
  readTags: function() {		
39 46
    this.addTagsList(this.input.value);
40 47
    this.input.value = '';
48
		if(this.update){
49
			submitForm();
50
		};
41 51
  },
42 52

  
43 53
  onKeyPress: function(event) {
44 54
    if (Event.KEY_RETURN == event.keyCode) {
45 55
      this.readTags(event);
46
      Event.stop(event);
56
      Event.stop(event);			
47 57
    }
48 58
  },
49 59

  
50
  addTag: function(tag) {
60
  addTag: function(tag, noSubmit) {
51 61
    if (tag.blank() || this.tags.get(tag)) return;
52 62

  
63
		if(noSubmit==undefined){noSubmit=false;}
64

  
53 65
    var button = new Element('span', { 'class': 'tag-delete icon icon-del' });
54 66
    var label  = new Element('span', { 'class': 'tag-label' }).insert(tag).insert(button);
55 67

  
......
57 69
    this.element.value = this.getTagsList();
58 70
    this.element.insert({ 'before': label });
59 71

  
72
		if(noSubmit==false){
73
			if(this.update){
74
				submitForm();
75
			};
76
		};
77

  
60 78
    Event.observe(button, 'click', function(){
61 79
      this.tags.unset(tag);
62 80
      this.element.value = this.getTagsList();
63 81
      label.remove();
82
		  if(this.update){submitForm();};
64 83
    }.bind(this));
65 84
  },
66 85

  
......
90 109

  
91 110

  
92 111
function observeIssueTagsField(url) {
93
  new Redmine.TagsInput('issue_tag_list').autocomplete('issue_tag_candidates', url);
112
  new Redmine.TagsInput('issue_tag_list', false).autocomplete('issue_tag_candidates', url);
94 113
}
95 114

  
96

  
97
function observeProjectTagsField(url) {
98
  new Redmine.TagsInput('project_tag_list').autocomplete('project_tag_candidates', url);
115
function observeProjectTagsField(url, update) {
116
	if(!update) { 
117
			var update = false;
118
		};
119
	
120
	new Redmine.TagsInput('project_tag_list', update).autocomplete('project_tag_candidates', url);
99 121
}
vendor/plugins/redmine_tags/assets/stylesheets/redmine_tags.css
33 33
div.tags .tag-nube-8 { font-size: 1.5em; }
34 34

  
35 35
.tag-count { font-size: .75em; margin-left: .5em; }
36

  
37
ul.projects .tags, ul.projects .no-tags { padding-left: 0.5em; color: #3e442c; font-size: 0.95em }
38
table.projects th.tags { color: #3e442c; }
39

  
40
dl.tags { margin-top: 1.5em; margin-left: 0; padding-bottom: 1em; overflow: hidden; margin-bottom: 1em; border-bottom: 1px dotted #bbbbbb; }
41
dt.tags-title { float: left; font-weight: bold; color: #3e442c; } 
42
dd.tags { margin-left: .5em; float: left; color: #3e442c; }
43
 
vendor/plugins/redmine_tags/config/locales/en.yml
23 23
  tags: Tags
24 24
  field_tags: Tags
25 25
  field_tag_list: Tags
26
  field_no_tags: "No tags"
27
  label_tags_search: "Tags: "
26 28
  setting_issue_tags: Issues Tags
27 29
  issues_sidebar: Display tags on sidebar as
28 30
  issues_show_count: Display amount of issues
......
34 36

  
35 37
  auto_complete_new_tag: Add new...
36 38
  
37
  project_filtering_q_label: "Textual search"
39
  project_filtering_q_label: "Search for text:"
40
  project_filter_no_results: "No matching projects found"
38 41
  button_filter: "Filter"
vendor/plugins/redmine_tags/config/routes.rb
1
ActionController::Routing::Routes.draw do |map|
2
  map.connect 'projects/set_fieldset_status', :controller => 'projects', :action => 'set_fieldset_status', :conditions => {:method => :post}
3
end
vendor/plugins/redmine_tags/lib/redmine_tags/hooks/views_projects_hook.rb
2 2
  module Hooks
3 3
    class ViewsProjectsHook < Redmine::Hook::ViewListener
4 4
      render_on :view_projects_form, :partial => 'projects/tags_form'
5
      render_on :view_projects_show_left, :partial => 'projects/tags'
5
      render_on :view_projects_show_sidebar_top, :partial => 'projects/tags'
6 6
#      render_on :view_issues_sidebar_planning_bottom, :partial => 'issues/tags_sidebar'
7 7
    end
8 8
  end
vendor/plugins/redmine_tags/lib/redmine_tags/patches/auto_completes_controller_patch.rb
38 38
          @tags = Project.available_tags :name_like => @name
39 39
          render :layout => false, :partial => 'tag_list'
40 40
        end
41
        
42
        def project_search_tags
43
          @name = params[:q].to_s
44
          @tags = Project.available_tags :name_like => @name
45
          render :layout => false, :partial => 'search_tag_list'
46
        end
41 47
      end
42 48
    end
43 49
  end
vendor/plugins/redmine_tags/lib/redmine_tags/patches/projects_controller_patch.rb
2 2

  
3 3
module RedmineTags
4 4
  module Patches
5
    module ProjectsControllerPatch
5
    module ProjectsControllerPatch      
6 6
      def self.included(base)
7 7
        base.send(:include, InstanceMethods)
8 8
        base.class_eval do          
9 9
          unloadable 
10
          skip_before_filter :authorize, :only => [:set_fieldset_status]
11
          skip_before_filter :find_project, :only => [:set_fieldset_status]
10 12
          before_filter :add_tags_to_project, :only => [:save, :update]
11
          before_filter :filter_projects, :only => :index                
13
#          before_filter :filter_projects, :only => :index
14

  
15
          alias :index filtered_index
12 16
        end
13 17
      end
14 18

  
15 19
      module InstanceMethods
20
        
21
        
22
        
16 23
        def add_tags_to_project
17 24

  
18 25
          if params && params[:project] && !params[:project][:tag_list].nil?
......
25 32
          end
26 33
        end
27 34

  
28
        # # luisf - TO BE REMOVED?
29
        # def calculate_project_filtering_settings
30
        #   @project_filtering_settings = Setting[:plugin_redmine_project_filtering]
31
        # end
35
        def paginate_projects
36
          sort_init 'name'
37
          sort_update %w(name lft created_on updated_on)
38
          @limit = per_page_option
39
          @project_count = Project.visible_roots.find(@projects).count
40
          @project_pages = ActionController::Pagination::Paginator.new self, @project_count, @limit, params['page']
41
          @offset ||= @project_pages.current.offset
42
        end
32 43

  
33
        def filter_projects
44
        def set_fieldset_status
45

  
46
          # luisf. test for missing parameters………
47
          field = params[:field_id]
48
          status = params[:status]
49

  
50
          session[(field + "_status").to_sym] = status
51
          render :nothing => true
52
        end
53

  
54
        # gets the status of the collabsible fieldsets
55
        def get_fieldset_statuses
56
          if session[:my_projects_fieldset_status].nil?
57
            @myproj_status = "true"
58
          else
59
            @myproj_status = session[:my_projects_fieldset_status]
60
          end
61
                    
62
          if session[:filters_fieldset_status].nil?
63
            @filter_status = "false"
64
          else
65
            @filter_status = session[:filters_fieldset_status]
66
          end
67
          
68
          if params && params[:project] && !params[:project][:tag_list].nil?
69
            @filter_status = "true"
70
          end
71
                                      
72
        end
73

  
74
        # Lists visible projects. Paginator is for top-level projects only
75
        # (subprojects belong to them)
76
        def filtered_index
34 77
          @project = Project.new
78
          filter_projects
79
          get_fieldset_statuses
35 80

  
36 81
          respond_to do |format|
37
            format.any(:html, :xml) {
38
              calculate_filtered_projects
82
            format.html { 
83
              paginate_projects
84
              
85
              @projects = Project.visible_roots.find(@projects, :offset => @offset, :limit => @limit, :order => sort_clause) 
86

  
87
              if User.current.logged?
88
                # seems sort_by gives us case-sensitive ordering, which we don't want
89
                #          @user_projects = User.current.projects.sort_by(&:name)
90
                @user_projects = User.current.projects.all(:order => :name)
91
              end
92
              
93
              render :template => 'projects/index.rhtml', :layout => !request.xhr?
94
            }
95
            format.api {
96
              @offset, @limit = api_offset_and_limit
97
              @project_count = Project.visible.count
98
              @projects = Project.visible.find(@projects, :offset => @offset, :limit => @limit, :order => 'lft')
99
            }
100
            format.atom {
101
              projects = Project.visible.find(:all, :order => 'created_on DESC', :limit => Setting.feeds_limit.to_i)
102
              render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}")
39 103
            }
40 104
            format.js {
41
              calculate_filtered_projects
105
              paginate_projects
106
              @projects = Project.visible_roots.find(@projects, :offset => @offset, :limit => @limit, :order => sort_clause)
42 107
              render :update do |page|
43 108
                page.replace_html 'projects', :partial => 'filtered_projects'
44 109
              end
45 110
            }
46
            format.atom {
47
              projects = Project.visible.find(:all, :order => 'created_on DESC',
48
              :limit => Setting.feeds_limit.to_i)
49
              render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}")
50
            }
51 111
          end
52 112
        end
53 113

  
54 114
        private
55 115

  
56
        def calculate_filtered_projects                  
116
        def filter_projects                  
57 117
          @question = (params[:q] || "").strip     
58 118

  
59 119
          if params.has_key?(:project)
......
62 122
            @tag_list = []
63 123
          end
64 124

  
65
          @projects = Project.visible
125
          if  @question == ""
126
            @projects = Project.visible
127
          else
128
            @projects = Project.visible.search_by_question(@question)
129
          end
130
  
131
          unless @tag_list.empty?
132
            @tagged_projects_ids = Project.visible.tagged_with(@tag_list).collect{ |project| Project.find(project.id) }
133
            @projects = @projects & @tagged_projects_ids
134
          end
135
          
136
          @projects = @projects.collect{ |project| project.root }
137
          @projects = @projects.uniq
66 138

  
67
          @featured_projects = @projects.featured if Project.respond_to? :featured
68

  
69
          # luisf 
70
          @projects = @projects.search_by_question(@question) unless @question == ""
71
          @tagged_projects_ids = Project.tagged_with(@tag_list).collect{ |project| Project.find(project.id) } unless @tag_list.empty?
72

  
73
          debugger
74

  
75
          # intersection of both prject groups            
76
          @projects = @projects && @tagged_projects_ids unless @tag_list.empty?
77
          
78
          @filtered_projects = @projects
79 139
        end
80 140
      end
81 141
    end
vendor/plugins/redmine_tags/lib/redmine_tags/patches/projects_helper_patch.rb
18 18
        # description, manager(s), creation date, last activity date,
19 19
        # general activity level, whether there is anything actually hosted
20 20
        # here for the project, etc.
21
        def render_project_table_with_filtering(projects, question)
22
          debugger
23
          
21
        def render_project_table_with_filtering(projects, question)          
24 22
          custom_fields = ""
25 23
          s = ""
26 24
          if projects.any?
......
31 29
            s << "<thead><tr>"
32 30
        
33 31
            s << sort_header_tag('name', :caption => l("field_name"))
32
            s << "<th class='tags'>" << l("tags") << "</th>"
34 33
            s << "<th class='managers'>" << l("label_managers") << "</th>"
35
            s << "<th class='tags'>" << l("tags") << "</th>"
36 34
            s << sort_header_tag('created_on', :default_order => 'desc')
37 35
            s << sort_header_tag('updated_on', :default_order => 'desc')
38 36
        
......
66 64
          s << " no_description" if project.description.blank?
67 65
          s << "'>" << link_to( highlight_tokens(project.name, tokens), {:controller => 'projects', :action => 'show', :id => project}, :class => "project #{User.current.member_of?(project) ? 'my-project' : nil}")
68 66
          s << "</div>"
69
          s << render_project_short_description(project)
67
          s << highlight_tokens(render_project_short_description(project), tokens)
68
          s << "</td>"
69

  
70
          # taglist
71
          s << "<td class='tags' align=top>" << project.tag_counts.collect{ |t| render_project_tag_link(t) }.join(', ') << "</td>"
72

  
70 73
          s << "<td class='managers' align=top>"
71 74
           
72 75
          u = project.users_by_role
......
88 91

  
89 92
          s << "</td>"
90 93
          
91
          # taglist
92
          s << "<td class='tags' align=top>" << project.tag_counts.collect{ |t| render_project_tag_link(t) }.join(', ') << "</td>"
93 94
          s << "<td class='created_on' align=top>" << format_date(project.created_on) << "</td>"
94 95
          s << "<td class='updated_on' align=top>" << format_date(project.updated_on) << "</td>"
95 96

  
......
162 163
          s.join "\n"
163 164
        end
164 165
        
166
        # Renders a tree of projects where the current user belongs
167
        # as a nested set of unordered lists
168
        # The given collection may be a subset of the whole project tree
169
        # (eg. some intermediate nodes are private and can not be seen)
170
        def render_my_project_hierarchy_with_tags(projects)
171

  
172
          s = ''
173

  
174
          original_project = @project
175

  
176
          projects.each do |project|
177
            if project.root? || !projects.include?(project.parent)
178
              s << render_my_project_in_hierarchy_with_tags(project)
179
            end
180
          end
181

  
182
          @project = original_project
183

  
184
          if s != ''
185
            a = ''
186
            a << "<ul class='projects root'>\n"
187
            a << s
188
            a << "</ul>\n"
189
            s = a
190
          end
191

  
192
          s
193

  
194
        end
195
        
196
        
197
        
198

  
199
        def render_my_project_in_hierarchy_with_tags(project)
200

  
201
          s = ''
202

  
203
          if User.current.member_of?(project)
204

  
205
            # set the project environment to please macros.
206
            @project = project
207

  
208
            classes = (project.root? ? 'root' : 'child')
209

  
210
            s << "<li class='#{classes}'><div class='#{classes}'>" +
211
              link_to_project(project, {}, :class => "project my-project")
212
            if project.is_public?
213
              s << " <span class='public'>" << l(:field_is_public) << "</span>"
214
            else
215
              s << " <span class='private'>" << l(:field_is_private) << "</span>"
216
            end
217
           
218
            tc = project.tag_counts
219
            if tc.empty?
220
              s << " <span class='no-tags'>" << l(:field_no_tags) << "</span>"
221
            else
222
              s << " <span class='tags'>" << tc.collect{ |t| render_project_tag_link(t) }.join(', ') << "</span>"
223
            end
224

  
225
            s << render_project_short_description(project)
226

  
227
            s << "</div>\n"
228

  
229
            cs = ''
230
            project.children.each do |child|
231
              cs << render_my_project_in_hierarchy_with_tags(child)
232
            end
233

  
234
            if cs != ''
235
              s << "<ul class='projects'>\n" << cs << "</ul>\n";
236
            end
237

  
238
          end
239

  
240
          s
241

  
242
        end
243

  
244
        
245
        
165 246
        private
166 247
        
167 248
        # copied from search_helper. This one doesn't escape html or limit the text length

Also available in: Unified diff