To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / vendor / plugins / redmine_tags / lib / redmine_tags / patches / projects_helper_patch.rb @ 1025:02ee54197879
History | View | Annotate | Download (9.32 KB)
| 1 | 739:b7ac21913927 | luis | module RedmineTags |
|---|---|---|---|
| 2 | module Patches |
||
| 3 | module ProjectsHelperPatch |
||
| 4 | |||
| 5 | def self.included(base) # :nodoc: |
||
| 6 | base.send(:include, InstanceMethods) |
||
| 7 | 1005:85123e5bc883 | chris | base.send(:include, TagsHelper) |
| 8 | 739:b7ac21913927 | luis | base.class_eval do
|
| 9 | unloadable |
||
| 10 | end
|
||
| 11 | end
|
||
| 12 | |||
| 13 | 753:7877f25a19d6 | luis | module InstanceMethods |
| 14 | # Renders a tree of projects that the current user does not belong
|
||
| 15 | # to, or of all projects if the current user is not logged in. The
|
||
| 16 | # given collection may be a subset of the whole project tree
|
||
| 17 | # (eg. some intermediate nodes are private and can not be seen). We
|
||
| 18 | # are potentially interested in various things: the project name,
|
||
| 19 | # description, manager(s), creation date, last activity date,
|
||
| 20 | # general activity level, whether there is anything actually hosted
|
||
| 21 | # here for the project, etc.
|
||
| 22 | 776:af852d82b00b | luis | def render_project_table_with_filtering(projects, question) |
| 23 | 753:7877f25a19d6 | luis | custom_fields = ""
|
| 24 | s = ""
|
||
| 25 | if projects.any?
|
||
| 26 | tokens = RedmineProjectFiltering.calculate_tokens(question, custom_fields)
|
||
| 27 | |||
| 28 | s << "<div class='autoscroll'>"
|
||
| 29 | s << "<table class='list projects'>"
|
||
| 30 | s << "<thead><tr>"
|
||
| 31 | |||
| 32 | s << sort_header_tag('name', :caption => l("field_name")) |
||
| 33 | 806:a42dcc01dfee | chris | s << "<th class='tags'>" << l("tags") << "</th>" |
| 34 | 753:7877f25a19d6 | luis | s << "<th class='managers'>" << l("label_managers") << "</th>" |
| 35 | s << sort_header_tag('created_on', :default_order => 'desc') |
||
| 36 | s << sort_header_tag('updated_on', :default_order => 'desc') |
||
| 37 | |||
| 38 | s << "</tr></thead><tbody>"
|
||
| 39 | |||
| 40 | original_project = @project
|
||
| 41 | |||
| 42 | projects.each do |project|
|
||
| 43 | s << render_project_in_table_with_filtering(project, cycle('odd', 'even'), 0, tokens) |
||
| 44 | end
|
||
| 45 | |||
| 46 | s << "</table>"
|
||
| 47 | else
|
||
| 48 | s << "\n"
|
||
| 49 | end
|
||
| 50 | @project = original_project
|
||
| 51 | |||
| 52 | s |
||
| 53 | end
|
||
| 54 | |||
| 55 | def render_project_in_table_with_filtering(project, oddeven, level, tokens) |
||
| 56 | # set the project environment to please macros.
|
||
| 57 | @project = project
|
||
| 58 | |||
| 59 | classes = (level == 0 ? 'root' : 'child') |
||
| 60 | |||
| 61 | s = ""
|
||
| 62 | |||
| 63 | s << "<tr class='#{oddeven} #{classes} level#{level}'>"
|
||
| 64 | s << "<td class='firstcol' align=top><div class='name hosted_here"
|
||
| 65 | s << " no_description" if project.description.blank? |
||
| 66 | s << "'>" << link_to( highlight_tokens(project.name, tokens), {:controller => 'projects', :action => 'show', :id => project}, :class => "project #{User.current.member_of?(project) ? 'my-project' : nil}") |
||
| 67 | s << "</div>"
|
||
| 68 | 796:6d3ad4b3a500 | luis | s << highlight_tokens(render_project_short_description(project), tokens) |
| 69 | 806:a42dcc01dfee | chris | s << "</td>"
|
| 70 | |||
| 71 | # taglist
|
||
| 72 | s << "<td class='tags' align=top>" << project.tag_counts.collect{ |t| render_project_tag_link(t) }.join(', ') << "</td>" |
||
| 73 | |||
| 74 | 753:7877f25a19d6 | luis | s << "<td class='managers' align=top>"
|
| 75 | |||
| 76 | u = project.users_by_role |
||
| 77 | if u
|
||
| 78 | u.keys.each do |r|
|
||
| 79 | if r.allowed_to?(:edit_project) |
||
| 80 | mgrs = [] |
||
| 81 | u[r].sort.each do |m|
|
||
| 82 | mgrs << link_to_user(m) |
||
| 83 | end
|
||
| 84 | if mgrs.size < 3 |
||
| 85 | s << '<nobr>' << mgrs.join(', ') << '</nobr>' |
||
| 86 | else
|
||
| 87 | s << mgrs.join(', ')
|
||
| 88 | end
|
||
| 89 | end
|
||
| 90 | end
|
||
| 91 | end
|
||
| 92 | |||
| 93 | s << "</td>"
|
||
| 94 | |||
| 95 | s << "<td class='created_on' align=top>" << format_date(project.created_on) << "</td>" |
||
| 96 | s << "<td class='updated_on' align=top>" << format_date(project.updated_on) << "</td>" |
||
| 97 | |||
| 98 | s << "</tr>"
|
||
| 99 | |||
| 100 | project.children.each do |child|
|
||
| 101 | if child.is_public? or User.current.member_of?(child) |
||
| 102 | s << render_project_in_table_with_filtering(child, oddeven, level + 1, tokens)
|
||
| 103 | end
|
||
| 104 | end
|
||
| 105 | |||
| 106 | s |
||
| 107 | end
|
||
| 108 | |||
| 109 | |||
| 110 | |||
| 111 | 739:b7ac21913927 | luis | # Renders a tree of projects as a nested set of unordered lists
|
| 112 | # The given collection may be a subset of the whole project tree
|
||
| 113 | # (eg. some intermediate nodes are private and can not be seen)
|
||
| 114 | def render_project_hierarchy_with_filtering(projects,custom_fields,question) |
||
| 115 | s = [] |
||
| 116 | if projects.any?
|
||
| 117 | tokens = RedmineProjectFiltering.calculate_tokens(question, custom_fields)
|
||
| 118 | debugger |
||
| 119 | |||
| 120 | |||
| 121 | ancestors = [] |
||
| 122 | original_project = @project
|
||
| 123 | projects.each do |project|
|
||
| 124 | # set the project environment to please macros.
|
||
| 125 | @project = project
|
||
| 126 | if (ancestors.empty? || project.is_descendant_of?(ancestors.last))
|
||
| 127 | s << "<ul class='projects #{ ancestors.empty? ? 'root' : nil}'>"
|
||
| 128 | else
|
||
| 129 | ancestors.pop |
||
| 130 | s << "</li>"
|
||
| 131 | while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
|
||
| 132 | ancestors.pop |
||
| 133 | s << "</ul></li>"
|
||
| 134 | end
|
||
| 135 | end
|
||
| 136 | classes = (ancestors.empty? ? 'root' : 'child') |
||
| 137 | s << "<li class='#{classes}'><div class='#{classes}'>" +
|
||
| 138 | link_to( highlight_tokens(project.name, tokens), |
||
| 139 | {:controller => 'projects', :action => 'show', :id => project},
|
||
| 140 | :class => "project #{User.current.member_of?(project) ? 'my-project' : nil}" |
||
| 141 | ) |
||
| 142 | s << "<ul class='filter_fields'>"
|
||
| 143 | |||
| 144 | # CustomField.usable_for_project_filtering.each do |field|
|
||
| 145 | # value_model = project.custom_value_for(field.id)
|
||
| 146 | # value = value_model.present? ? value_model.value : nil
|
||
| 147 | # s << "<li><b>#{field.name.humanize}:</b> #{highlight_tokens(value, tokens)}</li>" if value.present?
|
||
| 148 | # end
|
||
| 149 | |||
| 150 | s << "</ul>"
|
||
| 151 | s << "<div class='clear'></div>"
|
||
| 152 | unless project.description.blank?
|
||
| 153 | s << "<div class='wiki description'>"
|
||
| 154 | s << "<b>#{ t(:field_description) }:</b>"
|
||
| 155 | s << highlight_tokens(textilizable(project.short_description, :project => project), tokens)
|
||
| 156 | s << "\n</div>"
|
||
| 157 | end
|
||
| 158 | s << "</div>"
|
||
| 159 | ancestors << project |
||
| 160 | end
|
||
| 161 | ancestors.size.times{ s << "</li></ul>" }
|
||
| 162 | @project = original_project
|
||
| 163 | end
|
||
| 164 | s.join "\n"
|
||
| 165 | end
|
||
| 166 | |||
| 167 | 800:95b78e19e586 | luis | # Renders a tree of projects where the current user belongs
|
| 168 | # as a nested set of unordered lists
|
||
| 169 | # The given collection may be a subset of the whole project tree
|
||
| 170 | # (eg. some intermediate nodes are private and can not be seen)
|
||
| 171 | def render_my_project_hierarchy_with_tags(projects) |
||
| 172 | |||
| 173 | s = ''
|
||
| 174 | |||
| 175 | original_project = @project
|
||
| 176 | |||
| 177 | projects.each do |project|
|
||
| 178 | if project.root? || !projects.include?(project.parent)
|
||
| 179 | s << render_my_project_in_hierarchy_with_tags(project) |
||
| 180 | end
|
||
| 181 | end
|
||
| 182 | |||
| 183 | @project = original_project
|
||
| 184 | |||
| 185 | if s != '' |
||
| 186 | a = ''
|
||
| 187 | a << "<ul class='projects root'>\n"
|
||
| 188 | a << s |
||
| 189 | a << "</ul>\n"
|
||
| 190 | s = a |
||
| 191 | end
|
||
| 192 | |||
| 193 | s |
||
| 194 | |||
| 195 | end
|
||
| 196 | |||
| 197 | |||
| 198 | |||
| 199 | |||
| 200 | def render_my_project_in_hierarchy_with_tags(project) |
||
| 201 | |||
| 202 | s = ''
|
||
| 203 | |||
| 204 | if User.current.member_of?(project) |
||
| 205 | |||
| 206 | # set the project environment to please macros.
|
||
| 207 | @project = project
|
||
| 208 | |||
| 209 | classes = (project.root? ? 'root' : 'child') |
||
| 210 | |||
| 211 | s << "<li class='#{classes}'><div class='#{classes}'>" +
|
||
| 212 | link_to_project(project, {}, :class => "project my-project")
|
||
| 213 | if project.is_public?
|
||
| 214 | 806:a42dcc01dfee | chris | s << " <span class='public'>" << l(:field_is_public) << "</span>" |
| 215 | 800:95b78e19e586 | luis | else
|
| 216 | 806:a42dcc01dfee | chris | s << " <span class='private'>" << l(:field_is_private) << "</span>" |
| 217 | 800:95b78e19e586 | luis | end
|
| 218 | 806:a42dcc01dfee | chris | |
| 219 | tc = project.tag_counts |
||
| 220 | if tc.empty?
|
||
| 221 | s << " <span class='no-tags'>" << l(:field_no_tags) << "</span>" |
||
| 222 | else
|
||
| 223 | s << " <span class='tags'>" << tc.collect{ |t| render_project_tag_link(t) }.join(', ') << "</span>" |
||
| 224 | end
|
||
| 225 | |||
| 226 | 800:95b78e19e586 | luis | s << render_project_short_description(project) |
| 227 | |||
| 228 | s << "</div>\n"
|
||
| 229 | |||
| 230 | cs = ''
|
||
| 231 | project.children.each do |child|
|
||
| 232 | 806:a42dcc01dfee | chris | cs << render_my_project_in_hierarchy_with_tags(child) |
| 233 | 800:95b78e19e586 | luis | end
|
| 234 | |||
| 235 | if cs != '' |
||
| 236 | s << "<ul class='projects'>\n" << cs << "</ul>\n"; |
||
| 237 | end
|
||
| 238 | |||
| 239 | end
|
||
| 240 | |||
| 241 | s |
||
| 242 | |||
| 243 | end
|
||
| 244 | |||
| 245 | |||
| 246 | |||
| 247 | 739:b7ac21913927 | luis | private |
| 248 | |||
| 249 | # copied from search_helper. This one doesn't escape html or limit the text length
|
||
| 250 | def highlight_tokens(text, tokens) |
||
| 251 | return text unless text && tokens && !tokens.empty? |
||
| 252 | re_tokens = tokens.collect {|t| Regexp.escape(t)}
|
||
| 253 | regexp = Regexp.new "(#{re_tokens.join('|')})", Regexp::IGNORECASE |
||
| 254 | result = ''
|
||
| 255 | text.split(regexp).each_with_index do |words, i|
|
||
| 256 | words = words.mb_chars |
||
| 257 | if i.even?
|
||
| 258 | result << words |
||
| 259 | else
|
||
| 260 | t = (tokens.index(words.downcase) || 0) % 4 |
||
| 261 | result << content_tag('span', words, :class => "highlight token-#{t}") |
||
| 262 | end
|
||
| 263 | end
|
||
| 264 | result |
||
| 265 | end
|
||
| 266 | |||
| 267 | end
|
||
| 268 | end
|
||
| 269 | end
|
||
| 270 | end
|