Mercurial > hg > soundsoftware-site
changeset 136:bf38a7365edf live
Merge fixes for bug #51 and bug #35 from branch "cannam-pre-20110113-merge"
author | Chris Cannam |
---|---|
date | Wed, 19 Jan 2011 15:34:59 +0000 |
parents | cede720e8f53 (current diff) 6a2f8e88344e (diff) |
children | 637d05516475 |
files | public/themes/soundsoftware/stylesheets/application.css |
diffstat | 12 files changed, 141 insertions(+), 68 deletions(-) [+] |
line wrap: on
line diff
--- a/app/controllers/members_controller.rb Mon Dec 20 22:15:06 2010 +0000 +++ b/app/controllers/members_controller.rb Wed Jan 19 15:34:59 2011 +0000 @@ -94,6 +94,7 @@ def autocomplete_for_member @principals = Principal.active.like(params[:q]).find(:all, :limit => 100) - @project.principals + logger.debug "Query for #{params[:q]} returned #{@principals.size} results" render :layout => false end
--- a/app/controllers/projects_controller.rb Mon Dec 20 22:15:06 2010 +0000 +++ b/app/controllers/projects_controller.rb Wed Jan 19 15:34:59 2011 +0000 @@ -45,12 +45,22 @@ helper :repositories include RepositoriesHelper include ProjectsHelper - + # Lists visible projects def index respond_to do |format| format.html { - @projects = Project.visible.find(:all, :order => 'lft') + sort_init 'lft' + sort_update %w(lft title created_on updated_on) + @limit = per_page_option + @project_count = Project.visible.count + @project_pages = Paginator.new self, @project_count, @limit, params['page'] + @offset ||= @project_pages.current.offset + @projects = Project.visible.all(:offset => @offset, :limit => @limit, :order => sort_clause) + if User.current.logged? + @user_projects = User.current.projects.sort_by(&:lft) + end + render :template => 'projects/index.rhtml', :layout => !request.xhr? } format.xml { @projects = Project.visible.find(:all, :order => 'lft')
--- a/app/helpers/application_helper.rb Mon Dec 20 22:15:06 2010 +0000 +++ b/app/helpers/application_helper.rb Wed Jan 19 15:34:59 2011 +0000 @@ -273,7 +273,7 @@ def principals_check_box_tags(name, principals) s = '' principals.sort.each do |principal| - s << "<label>#{ check_box_tag name, principal.id, false } #{h principal}</label>\n" + s << "<label>#{ check_box_tag name, principal.id, false } #{link_to_user principal}</label>\n" end s end
--- a/app/helpers/projects_helper.rb Mon Dec 20 22:15:06 2010 +0000 +++ b/app/helpers/projects_helper.rb Wed Jan 19 15:34:59 2011 +0000 @@ -121,7 +121,12 @@ classes = (ancestors.empty? ? 'root' : 'child') s << "<li class='#{classes}'><div class='#{classes}'>" + - link_to_project(project, {}, :class => "project #{User.current.member_of?(project) ? 'my-project' : nil}") + link_to_project(project, {}, :class => "project my-project") + if project.is_public? + s << " <span class='public'>" << l("field_is_public") << "</span>" + else + s << " <span class='private'>" << l("field_is_private") << "</span>" + end s << "<div class='wiki description'>#{textilizable(project.short_description, :project => project)}</div>" unless project.description.blank? s << "</div>\n" ancestors << project @@ -143,66 +148,93 @@ a end - # Renders a tree of projects where the current DOES NOT belong - # as a nested set of unordered lists - # The given collection may be a subset of the whole project tree - # (eg. some intermediate nodes are private and can not be seen) - def render_other_project_hierarchy(projects) - a = '' - s = '' + # Renders a tree of projects that the current user does not belong + # to, or of all projects if the current user is not logged in. The + # given collection may be a subset of the whole project tree + # (eg. some intermediate nodes are private and can not be seen). We + # are potentially interested in various things: the project name, + # description, manager(s), creation date, last activity date, + # general activity level, whether there is anything actually hosted + # here for the project, etc. + def render_project_table(projects) - # True if user has any projects (affects the heading used) - t = FALSE + s = "" + s << "<div class='autoscroll'>" + s << "<table class='list projects'>" + s << "<thead><tr>" + + s << sort_header_tag('lft', :caption => l("field_name"), :default_order => 'desc') + s << "<th class='managers'>" << l("label_managers") << "</th>" + s << sort_header_tag('created_on', :default_order => 'desc') + s << sort_header_tag('updated_on', :default_order => 'desc') - if projects.any? - ancestors = [] - original_project = @project - projects.each do |project| - # set the project environment to please macros. + s << "</tr></thead><tbody>" - @project = project + ancestors = [] + original_project = @project + oddeven = 'even' + level = 0 - if not User.current.member_of?(project): + projects.each do |project| - if (ancestors.empty? || project.is_descendant_of?(ancestors.last)) - s << "<ul class='projects #{ ancestors.empty? ? 'root' : nil}'>\n" - else - ancestors.pop - s << "</li>" - while (ancestors.any? && !project.is_descendant_of?(ancestors.last)) - ancestors.pop - s << "</ul></li>\n" + # set the project environment to please macros. + + @project = project + + if (ancestors.empty? || project.is_descendant_of?(ancestors.last)) + level = level + 1 + else + level = 0 + oddeven = cycle('odd','even') + ancestors.pop + while (ancestors.any? && !project.is_descendant_of?(ancestors.last)) + ancestors.pop + end + end + + classes = (ancestors.empty? ? 'root' : 'child') + + s << "<tr class='#{oddeven} #{classes} level#{level}'>" + s << "<td class='firstcol name hosted_here'>" << link_to_project(project, {}, :class => "project #{User.current.member_of?(project) ? 'my-project' : nil}") << "</td>" + s << "<td class='managers'>" + + u = project.users_by_role + if u + u.keys.each do |r| + if r.allowed_to?(:edit_project) + mgrs = [] + u[r].sort.each do |m| + mgrs << link_to_user(m) + end + if mgrs.size < 3 + s << '<nobr>' << mgrs.join(', ') << '</nobr>' + else + s << mgrs.join(', ') end end + end + end - classes = (ancestors.empty? ? 'root' : 'child') - s << "<li class='#{classes}'><div class='#{classes}'>" + - link_to_project(project, {}, :class => "project #{User.current.member_of?(project) ? 'my-project' : nil}") - s << "<div class='wiki description'>#{textilizable(project.short_description, :project => project)}</div>" unless project.description.blank? - s << "</div>\n" - ancestors << project - else - t = TRUE - end - end + s << "</td>" + s << "<td class='created_on'>" << format_date(project.created_on) << "</td>" + s << "<td class='updated_on'>" << format_date(project.updated_on) << "</td>" - s << ("</li></ul>\n" * ancestors.size) - @project = original_project + s << "</tr>" + s << "<tr class='#{oddeven} #{classes}'>" + s << "<td class='firstcol wiki description'>" + s << textilizable(project.short_description, :project => project) unless project.description.blank? + s << "</td>" + s << "<td colspan=3> </td>" + s << "</tr>" + + ancestors << project end - if t == TRUE - a << "<h2>" - a << l("label_other_project_plural") - a << "</h2>" - a << s - else - a << "<h2>" - a << l("label_project_all") - a << "</h2>" - a << s - end + s << "</table>" - a + @project = original_project + + s end
--- a/app/models/project.rb Mon Dec 20 22:15:06 2010 +0000 +++ b/app/models/project.rb Wed Jan 19 15:34:59 2011 +0000 @@ -418,7 +418,14 @@ # Returns a short description of the projects (first lines) def short_description(length = 255) - description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description + ## Original Redmine code: this truncates to the CR that is more + ## than "length" characters from the start. + # description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description + ## That's too much for us, and also we want to omit images and the + ## like. Truncate instead to the first CR that follows _any_ + ## non-blank text, and to the next word break beyond "length" + ## characters if the result is still longer than that. + description.gsub(/![^\s]+!/, '').gsub(/^(\s*[^\n\r]*).*$/m, '\1').gsub(/^(.{#{length}}\b).*$/m, '\1 ...').strip if description end def css_classes
--- a/app/views/members/autocomplete_for_member.rhtml Mon Dec 20 22:15:06 2010 +0000 +++ b/app/views/members/autocomplete_for_member.rhtml Wed Jan 19 15:34:59 2011 +0000 @@ -1,1 +1,3 @@ -<%= principals_check_box_tags 'member[user_ids][]', @principals %> \ No newline at end of file +<% if params[:q] && params[:q].length > 1 %> +<%= principals_check_box_tags 'member[user_ids][]', @principals %> +<% end %>
--- a/app/views/projects/index.rhtml Mon Dec 20 22:15:06 2010 +0000 +++ b/app/views/projects/index.rhtml Wed Jan 19 15:34:59 2011 +0000 @@ -8,18 +8,19 @@ <%= '| ' + link_to(l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add') if User.current.allowed_to?(:add_project, nil, :global => true) %> </div> -<% if User.current.logged? %> +<% if @user_projects %> - <%= render_my_project_hierarchy(@projects)%> + <%= render_my_project_hierarchy(@user_projects)%> - <%= render_other_project_hierarchy(@projects)%> - -<% else %> - - <h2><%=l(:label_project_plural)%></h2> - <%= render_project_hierarchy(@projects)%> <% end %> +<h2> +<%= l("label_project_all") %> +</h2> + +<%= render_project_table(@projects) %> + +<p class="pagination"><%= pagination_links_full @project_pages, @project_count %></p> <% other_formats_links do |f| %>
--- a/app/views/projects/settings/_members.rhtml Mon Dec 20 22:15:06 2010 +0000 +++ b/app/views/projects/settings/_members.rhtml Wed Jan 19 15:34:59 2011 +0000 @@ -50,7 +50,7 @@ </div> -<% principals = Principal.active.find(:all, :limit => 10, :order => 'type, login, lastname ASC') - @project.principals %> +<% principals = Principal.active.find(:all, :limit => 100, :order => 'type, login, lastname ASC') - @project.principals %> <div class="splitcontentright"> <% if roles.any? && principals.any? %> @@ -66,9 +66,11 @@ :url => { :controller => 'members', :action => 'autocomplete_for_member', :id => @project }, :with => 'q') %> - + <div id="principals"> - <%= principals_check_box_tags 'member[user_ids][]', principals %> + <% if params[:q] && params[:q].length > 1 %> + <%= principals_check_box_tags 'member[user_ids][]', @principals %> + <% end %> </div> <p><%= l(:label_role_plural) %>:
--- a/app/views/projects/settings/_repository.rhtml Mon Dec 20 22:15:06 2010 +0000 +++ b/app/views/projects/settings/_repository.rhtml Wed Jan 19 15:34:59 2011 +0000 @@ -7,7 +7,7 @@ <div class="box tabular"> <% if !@repository || !@repository.url %> -<ul><li>The repository for a project will normally be set up automatically within a few minutes of the project being created.</li></ul> +<ul><li><%= l(:text_settings_repo_creation) %></li></ul> <% end %> <p><%= label_tag('repository_scm', l(:label_scm)) %><%= scm_select_tag(@repository) %></p> <%= repository_field_tags(f, @repository) if @repository %>
--- a/config/locales/en-GB.yml Mon Dec 20 22:15:06 2010 +0000 +++ b/config/locales/en-GB.yml Wed Jan 19 15:34:59 2011 +0000 @@ -237,6 +237,7 @@ field_role: Role field_homepage: Homepage field_is_public: Public + field_is_private: Private field_parent: Subproject of field_is_in_roadmap: Issues displayed in roadmap field_login: Login @@ -430,6 +431,7 @@ other: "{{count}} projects" label_project_all: All Projects label_project_latest: Latest projects + label_managers: Managed by label_issue: Issue label_issue_new: New issue label_issue_plural: Issues @@ -841,6 +843,7 @@ text_tip_issue_end_day: task ending this day text_tip_issue_begin_end_day: task beginning and ending this day text_project_identifier_info: 'Only lower case letters (a-z), numbers and dashes are allowed.<br /> This will be used in all project-related URLs, and as the repository name. Once saved, the identifier <b>can not</b> be changed.' + text_project_homepage_info: 'Link to an external project page.' text_project_name_info: "This will be the name of your project throughout this site.<br /> You can change your project's name at any time, in the project's settings." text_project_visibility_info: "If your project is not public, it will only be visible to users that you have added as project members." text_user_ssamr_description_info: 'Please describe your current research or development interests, within the fields of audio and music.<br/>This information is publicly visible in your profile and you can edit it at any time.<br/>It may also be used to establish eligibility for your initial registration.' @@ -885,6 +888,7 @@ text_wiki_page_destroy_children: "Delete child pages and all their descendants" text_wiki_page_reassign_children: "Reassign child pages to this parent page" text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?" + text_settings_repo_creation: The repository for a project should be set up automatically within a few minutes of the project being created.<br>You should not have to adjust any settings here; please check again in ten minutes. default_role_manager: Manager default_role_developer: Developer @@ -943,7 +947,7 @@ label_user_mail_option_only_my_events: Only for things I watch or I'm involved in label_user_mail_option_only_assigned: Only for things I am assigned to notice_not_authorized_archived_project: The project you're trying to access has been archived. - label_principal_search: "Search for user or group:" + label_principal_search: "Search by name:" label_user_search: "Search for user:" field_visible: Visible setting_emails_header: Emails header
--- a/config/locales/en.yml Mon Dec 20 22:15:06 2010 +0000 +++ b/config/locales/en.yml Wed Jan 19 15:34:59 2011 +0000 @@ -242,6 +242,7 @@ field_role: Role field_homepage: Homepage field_is_public: Public + field_is_private: Private field_parent: Subproject of field_is_in_roadmap: Issues displayed in roadmap field_login: Login @@ -444,6 +445,7 @@ other: "{{count}} projects" label_project_all: All Projects label_project_latest: Latest projects + label_managers: Managed by label_issue: Issue label_issue_new: New issue label_issue_plural: Issues @@ -793,7 +795,7 @@ label_profile: Profile label_subtask_plural: Subtasks label_project_copy_notifications: Send email notifications during the project copy - label_principal_search: "Search for user or group:" + label_principal_search: "Search by name:" label_user_search: "Search for user:" button_login: Login @@ -914,6 +916,7 @@ text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?" text_zoom_in: Zoom in text_zoom_out: Zoom out + text_settings_repo_creation: The repository for a project should be set up automatically within a few minutes of the project being created.<br>You should not have to adjust any settings here.<br>Please check again in ten minutes, and <a href="/projects/soundsoftware-site/wiki/Help">contact us</a> if there is any problem. default_role_manager: Manager default_role_developer: Developer
--- a/public/themes/soundsoftware/stylesheets/application.css Mon Dec 20 22:15:06 2010 +0000 +++ b/public/themes/soundsoftware/stylesheets/application.css Wed Jan 19 15:34:59 2011 +0000 @@ -67,6 +67,17 @@ tr.entry { border-left: 1px solid #a9b680; border-right: 1px solid #a9b680; } tr.entry:last-child { border-bottom: 1px solid #a9b680; } +table.projects th { text-align: left; } +table.projects th.managers { color: #3e442c; } +table.projects .hosted_here { font-weight: bold; } +table.projects .child .name { font-weight: normal; } +table.projects .child .description { font-size: 0.95em; } +table.projects .child .firstcol { padding-left: 1em } +table.projects .level2 .firstcol { padding-left: 2em; } +table.projects .level3 .firstcol { padding-left: 3em; } + +ul.projects .public, ul.projects .private { padding-left: 0.5em; color: #3e442c; font-size: 0.95em } + #top-menu { position: absolute; top: 0; z-index: 1; left: 0px; width: 100%; font-size: 90%; /* height: 2em; */ margin: 0; padding: 0; padding-top: 0.5em; background-color: #3e442c; } #top-menu ul { margin-left: 10px; } #top-menu a { font-weight: bold; }