Replaces various icons with SVG icons (#23980).

git-svn-id: https://svn.redmine.org/redmine/trunk@23039 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Marius Balteanu
2024-09-08 17:23:06 +00:00
parent 00cc5f7440
commit dfc5b2a13b
18 changed files with 68 additions and 31 deletions

View File

@@ -167,6 +167,9 @@
<symbol viewBox="0 0 512 512" id="icon--issue-edit">
<path d="M471.6 21.7c-21.9-21.9-57.3-21.9-79.2 0l-30.1 30l97.9 97.9l30.1-30.1c21.9-21.9 21.9-57.3 0-79.2zm-299.2 220c-6.1 6.1-10.8 13.6-13.5 21.9l-29.6 88.8c-2.9 8.6-.6 18.1 5.8 24.6s15.9 8.7 24.6 5.8l88.8-29.6c8.2-2.7 15.7-7.4 21.9-13.5l167.3-167.4l-98-98zM96 64c-53 0-96 43-96 96v256c0 53 43 96 96 96h256c53 0 96-43 96-96v-96c0-17.7-14.3-32-32-32s-32 14.3-32 32v96c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32z"/>
</symbol>
<symbol viewBox="0 0 640 512" id="icon--link">
<path d="M579.8 267.7c56.5-56.5 56.5-148 0-204.5c-50-50-128.8-56.5-186.3-15.4l-1.6 1.1c-14.4 10.3-17.7 30.3-7.4 44.6s30.3 17.7 44.6 7.4l1.6-1.1c32.1-22.9 76-19.3 103.8 8.6c31.5 31.5 31.5 82.5 0 114L422.3 334.8c-31.5 31.5-82.5 31.5-114 0c-27.9-27.9-31.5-71.8-8.6-103.8l1.1-1.6c10.3-14.4 6.9-34.4-7.4-44.6s-34.4-6.9-44.6 7.4l-1.1 1.6C206.5 251.2 213 330 263 380c56.5 56.5 148 56.5 204.5 0zM60.2 244.3c-56.5 56.5-56.5 148 0 204.5c50 50 128.8 56.5 186.3 15.4l1.6-1.1c14.4-10.3 17.7-30.3 7.4-44.6s-30.3-17.7-44.6-7.4l-1.6 1.1c-32.1 22.9-76 19.3-103.8-8.6C74 372 74 321 105.5 289.5l112.2-112.3c31.5-31.5 82.5-31.5 114 0c27.9 27.9 31.5 71.8 8.6 103.9l-1.1 1.6c-10.3 14.4-6.9 34.4 7.4 44.6s34.4 6.9 44.6-7.4l1.1-1.6C433.5 260.8 427 182 377 132c-56.5-56.5-148-56.5-204.5 0z"/>
</symbol>
<symbol viewBox="0 0 640 512" id="icon--link-break">
<path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2s-6.3 25.5 4.1 33.7l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L489.3 358.2l90.5-90.5c56.5-56.5 56.5-148 0-204.5c-50-50-128.8-56.5-186.3-15.4l-1.6 1.1c-14.4 10.3-17.7 30.3-7.4 44.6s30.3 17.7 44.6 7.4l1.6-1.1c32.1-22.9 76-19.3 103.8 8.6c31.5 31.5 31.5 82.5 0 114l-96 96l-31.9-25c24.3-53.8 13.5-118.3-29.6-161.4c-52.2-52.3-134.5-56.2-191.3-11.7zM239 162c30.1-14.9 67.7-9.9 92.8 15.3c20 20 27.5 48.3 21.7 74.5zm167.6 254.4L220.9 270c-2.1 39.8 12.2 80.1 42.2 110c38.9 38.9 94.4 51 143.6 36.3zm-290-228.5l-56.4 56.4c-56.5 56.5-56.5 148 0 204.5c50 50 128.8 56.5 186.3 15.4l1.6-1.1c14.4-10.3 17.7-30.3 7.4-44.6s-30.3-17.7-44.6-7.4l-1.6 1.1c-32.1 22.9-76 19.3-103.8-8.6C74 372 74 321 105.5 289.5l61.8-61.8l-50.6-39.9z"/>
</symbol>

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -171,7 +171,7 @@ a.user.user-mention {
#sidebar a.selected:hover {text-decoration:none;}
#sidebar .query.default {font-weight: bold;}
#admin-menu a {line-height:1.7em;}
#admin-menu a.selected {padding-left: 20px !important; background-position: 2px 40%;}
#admin-menu a.selected:not(:has(svg)) {padding-left: 20px !important; background-position: 2px 40%;}
a.collapsible {padding-left: 12px; }
@@ -354,10 +354,11 @@ body.avatars-on #replies .message.reply {padding-left: 32px;}
#replies h4 img.gravatar {margin-left:-32px;}
tr.version.closed, tr.version.closed a { color: #999; }
tr.version td.name { padding-left: 20px; }
tr.version td.name:not(.icon-shared) { padding-left: 20px; }
tr.version td.date, tr.version td.status, tr.version td.sharing { text-align: center; white-space:nowrap; }
tr.member td.icon-user, #principals_for_new_member .icon-user {background:transparent;}
#principals_for_new_member svg {margin-right: 4px;}
tr.user td {width:13%;white-space: nowrap;}
td.username, td.firstname, td.lastname, td.email {text-align:left !important;}
@@ -1000,6 +1001,8 @@ span.required {color: #bb0000;}
.attachments_fields input.description, #existing-attachments input.description {margin-left:4px; width:340px;}
.attachments_fields>span, #existing-attachments>span {display:block; white-space:nowrap;}
/* ToDo: delete this line when legacy icons are deleted */
.attachments_fields , #existing-attachments .icon-attachment {background-image: none; padding-left: 0}
.attachments_fields input.filename, #existing-attachments .filename {border:0; width:250px; color:#555; background-color:inherit; }
.tabular input.filename {max-width:75% !important;}
.attachments_fields input.filename {height:1.8em;}
@@ -1634,6 +1637,18 @@ a.icon:hover svg, a.icon-only:hover svg {
fill: #c61a1a;
}
svg.icon-error {
fill: #f37c60;
}
svg.icon-ok {
fill: #5db651;
}
.icon-warning svg {
fill: #e4bc4b;
}
.icon-only span {
display: none;
}
@@ -1646,6 +1661,11 @@ svg {
width: 14px;
height: 14px;
}
&.s12 {
width: 12px;
height: 12px;
}
}
span.icon-label {
@@ -1655,6 +1675,7 @@ span.icon-label {
.icon-bookmarked-project svg {
fill: #169;
}
.icon-user svg {
fill: #169;
}
@@ -1703,8 +1724,8 @@ span.icon-label {
.icon-time-entry:not(:has(svg)), .icon-time:not(:has(svg)) { background-image: url(/time.png); }
.icon-time-add:not(:has(svg)) { background-image: url(/time_add.png); }
.icon-stats:not(:has(svg)) { background-image: url(/stats.png); }
.icon-warning { background-image: url(/warning.png); }
.icon-error { background-image: url(/exclamation.png); }
.icon-warning:not(:has(svg)) { background-image: url(/warning.png); }
.icon-error:not(svg) { background-image: url(/exclamation.png); }
.icon-fav:not(:has(svg)) { background-image: url(/fav.png); }
.icon-fav-off:not(:has(svg)) { background-image: url(/fav_off.png); }
.icon-reload:not(:has(svg)) { background-image: url(/reload.png); }
@@ -1724,14 +1745,14 @@ span.icon-label {
.icon-email:not(:has(svg)) { background-image: url(/email.png); }
.icon-email-disabled:not(:has(svg)) { background-image: url(/email_disabled.png); }
.icon-email-add:not(:has(svg)) { background-image: url(/email_add.png); }
.icon-ok { background-image: url(/true.png); }
.icon-ok:not(svg) { background-image: url(/true.png); }
.icon-not-ok { background-image: url(/false.png); }
.icon-link-break:not(:has(svg)) { background-image: url(/link_break.png); }
.icon-list:not(:has(svg)) { background-image: url(/text_list_bullets.png); }
.icon-close:not(:has(svg)) { background-image: url(/close.png); }
.icon-close:hover:not(:has(svg)) { background-image: url(/close_hl.png); }
.icon-settings:not(:has(svg)) { background-image: url(/changeset.png); }
.icon-group:not(:has(svg)),.icon-groupnonmember, .icon-groupanonymous { background-image: url(/group.png); }
.icon-group:not(:has(svg)),.icon-groupnonmember:not(:has(svg)), .icon-groupanonymous:not(:has(svg)) { background-image: url(/group.png); }
.icon-roles:not(:has(svg)) { background-image: url(/database_key.png); }
.icon-issue-edit:not(:has(svg)) { background-image: url(/ticket_edit.png); }
.icon-workflows:not(:has(svg)) { background-image: url(/ticket_go.png); }
@@ -1745,8 +1766,8 @@ span.icon-label {
.icon-reply:not(:has(svg)) { background-image: url(/comments.png); }
.icon-wiki-page:not(:has(svg)) { background-image: url(/wiki_edit.png); }
.icon-document:not(:has(svg)) { background-image: url(/document.png); }
.icon-add-bullet { background-image: url(/bullet_add.png); }
.icon-shared { background-image: url(/link.png); }
.icon-add-bullet:not(:has(svg)) { background-image: url(/bullet_add.png); }
.icon-shared:not(:has(svg)) { background-image: url(/link.png); }
.icon-actions:not(:has(svg)) { background-image: url(/3_bullets.png); }
.icon-sort-handle:not(:has(svg)) { background-image: url(/reorder.png); }
.icon-expanded { background-image: url(/arrow_down.png); }

View File

@@ -657,7 +657,7 @@ module ApplicationHelper
check_box_tag(name, principal.id, false, :id => nil) +
(avatar(principal, :size => 16).presence ||
content_tag(
'span', nil,
'span', icon_for_principal(principal.class.name.downcase),
:class => "name icon icon-#{principal.class.name.downcase}"
)
) + principal.to_s

View File

@@ -21,22 +21,26 @@ module IconsHelper
DEFAULT_ICON_SIZE = "14"
DEFAULT_SPRITE = "icons"
def icon_with_label(icon_name, label_text, icon_only: false)
def icon_with_label(icon_name, label_text, icon_only: false, size: DEFAULT_ICON_SIZE, css_class: nil)
label_classes = ["icon-label"]
label_classes << "hidden" if icon_only
sprite_icon(icon_name) + content_tag(:span, label_text, class: label_classes.join(' '))
sprite_icon(icon_name, size: size, css_class: css_class) + content_tag(:span, label_text, class: label_classes.join(' '))
end
def icon_for_file(entry, name)
def icon_for_file(entry, name, size: DEFAULT_ICON_SIZE, css_class: nil)
if entry.is_dir?
icon_with_label("folder", name)
icon_with_label("folder", name, size: size, css_class: css_class)
else
icon = icon_for_mime_type(Redmine::MimeType.css_class_of(name))
icon_with_label(icon, name)
icon_with_label(icon, name, size: size, css_class: css_class)
end
end
def icon_for_event_type(event_type)
def icon_for_principal(principal_class, size: DEFAULT_ICON_SIZE, css_class: nil)
sprite_icon('group', size: size, css_class:css_class) if ['groupanonymous', 'groupnonmember', 'group'].include?(principal_class)
end
def icon_for_event_type(event_type, size: DEFAULT_ICON_SIZE, css_class: nil)
icon = case event_type
when 'reply', 'issue-note'
'comments'
@@ -48,10 +52,10 @@ module IconsHelper
event_type
end
sprite_icon icon
sprite_icon(icon, size: size, css_class: css_class)
end
def sprite_icon(icon_name, size: DEFAULT_ICON_SIZE, sprite: DEFAULT_SPRITE)
def sprite_icon(icon_name, size: DEFAULT_ICON_SIZE, sprite: DEFAULT_SPRITE, css_class: nil)
sprite_path = "#{sprite}.svg"
content_tag(

View File

@@ -69,11 +69,11 @@ module UsersHelper
url = {:controller => 'users', :action => 'update', :id => user, :page => params[:page], :status => params[:status], :tab => nil}
if user.locked?
link_to l(:button_unlock), url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :put, :class => 'icon icon-unlock'
link_to icon_with_label('unlock', l(:button_unlock)), url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :put, :class => 'icon icon-unlock'
elsif user.registered?
link_to l(:button_activate), url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :put, :class => 'icon icon-unlock'
link_to icon_with_label('unlock', l(:button_activate)), url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :put, :class => 'icon icon-unlock'
elsif user != User.current
link_to l(:button_lock), url.merge(:user => {:status => User::STATUS_LOCKED}), :method => :put, :class => 'icon icon-lock'
link_to icon_with_label('lock', l(:button_lock)), url.merge(:user => {:status => User::STATUS_LOCKED}), :method => :put, :class => 'icon icon-lock'
end
end

View File

@@ -6,7 +6,7 @@
<% @checklist.each do |label, result| %>
<tr>
<td class="name"><%= label.is_a?(Symbol) ? l(label) : label %></td>
<td class="tick"><span class="icon-only <%= (result ? 'icon-ok' : 'icon-error') %>"></span></td>
<td class="tick"><%= result ? sprite_icon('checked', css_class: "icon-ok") : sprite_icon('error', css_class: "icon-error") %></td>
</tr>
<% end %>
</table>

View File

@@ -5,7 +5,7 @@
<% end %>
<% if @archived_project && User.current.admin? %>
<p><%= link_to l(:button_unarchive), unarchive_project_path(@archived_project), :method => :post, :class => 'icon icon-unlock' %></p>
<p><%= link_to icon_with_label('unlock', l(:button_unarchive)), unarchive_project_path(@archived_project), :method => :post, :class => 'icon icon-unlock' %></p>
<% end %>
<p><a href="javascript:history.back()"><%= l(:button_back) %></a></p>

View File

@@ -54,6 +54,7 @@
<div id="existing-attachments" style="<%= @issue.deleted_attachment_ids.blank? ? 'display:none;' : '' %>">
<% @issue.attachments.each do |attachment| %>
<span class="existing-attachment">
<%= sprite_icon('attachment', size: 12) %>
<%= text_field_tag '', attachment.filename, :class => "icon icon-attachment filename", :disabled => true %>
<label>
<%= check_box_tag 'issue[deleted_attachment_ids][]',

View File

@@ -5,7 +5,7 @@
<%= watchers_checkboxes(@issue, users_for_new_issue_watchers(@issue)) %>
</span>
<span class="search_for_watchers">
<%= link_to l(:label_search_for_watchers),
<%= link_to icon_with_label('add', l(:label_search_for_watchers), size: 12),
{:controller => 'watchers', :action => 'new', :project_id => @issue.project},
:class => 'icon icon-add-bullet',
:remote => true,

View File

@@ -63,7 +63,7 @@
<%= export_csv_separator_select_tag %>
<% if @issue_count > Setting.issues_export_limit.to_i %>
<p class="icon icon-warning">
<%= l(:setting_issues_export_limit) %>: <%= Setting.issues_export_limit.to_i %>
<%= icon_with_label('warning', l(:setting_issues_export_limit)) %>: <%= Setting.issues_export_limit.to_i %>
</p>
<% end %>
<p class="buttons">

View File

@@ -19,7 +19,10 @@
<% members.each do |member| %>
<% next if member.new_record? %>
<tr id="member-<%= member.id %>" class="member">
<td class="name icon icon-<%= member.principal.class.name.downcase %>"><%= link_to_user member.principal %></td>
<td class="name icon icon-<%= member.principal.class.name.downcase %>">
<%= icon_for_principal(member.principal.class.name.downcase) %>
<%= link_to_user member.principal %>
</td>
<td class="roles">
<span id="member-<%= member.id %>-roles"><%= member.roles.sort.collect(&:to_s).join(', ') %></span>
<div id="member-<%= member.id %>-form"></div>

View File

@@ -34,7 +34,11 @@
<tbody>
<% @versions.each do |version| %>
<tr class="version <%=h version.status %> <%= 'shared' if version.project != @project %>">
<td class="name <%= 'icon icon-shared' if version.project != @project %>"><%= link_to_version version %></td>
<% is_shared = version.project != @project %>
<td class="name <%= 'icon icon-shared' if is_shared %>">
<%= sprite_icon('link') if is_shared %>
<%= link_to_version version %>
</td>
<td class="tick"><%= checked_image(version.id == @project.default_version_id) %></td>
<td class="date"><%= format_date(version.effective_date) %></td>
<td class="description"><%= version.description %></td>

View File

@@ -18,7 +18,7 @@
<td>
<% unless role.builtin? || role.workflow_rules.exists? %>
<span class="icon icon-warning">
<%= l(:text_role_no_workflow) %> (<%= link_to l(:button_edit), edit_workflows_path(:role_id => role) %>)
<%= icon_with_label('warning', l(:text_role_no_workflow)) %> (<%= link_to l(:button_edit), edit_workflows_path(:role_id => role) %>)
</span>
<% end %>
</td>

View File

@@ -1,5 +1,5 @@
<div class="contextual">
<%= link_to l(:label_profile), user_path(@user), :class => 'icon icon-user' %>
<%= link_to icon_with_label('user', l(:label_profile)), user_path(@user), :class => 'icon icon-user' %>
<%= additional_emails_link(@user) %>
<%= change_status_link(@user) %>
<%= delete_link user_path(@user) if User.current != @user %>

View File

@@ -4,7 +4,7 @@
<% end %>
<%= watcher_link(@wiki, User.current) %>
<% if User.current.allowed_to?(:manage_wiki, @project) %>
<%= link_to l(:button_delete), {:controller => 'wikis', :action => 'destroy', :id => @project}, :class => 'icon icon-del' %>
<%= link_to icon_with_label('del', l(:button_delete)), {:controller => 'wikis', :action => 'destroy', :id => @project}, :class => 'icon icon-del' %>
<% end %>
</div>

View File

@@ -1,5 +1,5 @@
<div class="contextual">
<%= link_to(l(:label_history), {:action => 'history', :id => @page.title},
<%= link_to(icon_with_label('history', l(:label_history)), {:action => 'history', :id => @page.title},
:class => 'icon icon-history') %>
</div>

View File

@@ -41,6 +41,7 @@
<div id="existing-attachments" style="<%= @page.deleted_attachment_ids.blank? ? 'display:none;' : '' %>">
<% @page.attachments.each do |attachment| %>
<span class="existing-attachment">
<%= sprite_icon('attachment', size: 12) %>
<%= text_field_tag '', attachment.filename, :class => "icon icon-attachment filename", :disabled => true %>
<label class='inline'>
<%= check_box_tag 'wiki_page[deleted_attachment_ids][]',

View File

@@ -2027,7 +2027,7 @@ class ApplicationHelperTest < Redmine::HelperTest
tags = principals_check_box_tags(name, principals)
principals.each_with_index do |principal, i|
assert_not_include avatar_tags[i], tags
assert_include content_tag('span', nil, :class => "name icon icon-#{principal.class.name.downcase}"), tags
assert_include content_tag('span', icon_for_principal(principal.class.name.downcase), :class => "name icon icon-#{principal.class.name.downcase}"), tags
end
end
end