Patch #42966 » 0002-Replace-autocomplete-input-loading-icon-with-SVG.patch
| app/assets/javascripts/application-legacy.js | ||
|---|---|---|
| 748 | 748 |
source: url, |
| 749 | 749 |
minLength: 2, |
| 750 | 750 |
position: {collision: "flipfit"},
|
| 751 |
search: function(){$('#'+fieldId).addClass('ajax-loading');},
|
|
| 752 |
response: function(){$('#'+fieldId).removeClass('ajax-loading');}
|
|
| 751 |
search: function(){showAutocompleteLoadingIcon(fieldId)},
|
|
| 752 |
response: function(){restoreAutocompleteSearchIcon(fieldId)}
|
|
| 753 | 753 |
}, options)); |
| 754 | 754 |
$('#'+fieldId).addClass('autocomplete');
|
| 755 | 755 |
}); |
| 756 | 756 |
} |
| 757 | 757 | |
| 758 |
function showAutocompleteLoadingIcon(fieldId) {
|
|
| 759 |
const input = document.getElementById(fieldId); |
|
| 760 |
if (!input) return; |
|
| 761 | ||
| 762 |
const container = input.closest('p');
|
|
| 763 |
if (!container) return; |
|
| 764 | ||
| 765 |
const svg = container.querySelector('svg.svg-search');
|
|
| 766 |
if (!svg) return; |
|
| 767 | ||
| 768 |
updateSVGIcon(svg, 'loader'); |
|
| 769 |
svg.classList.remove('svg-search');
|
|
| 770 |
svg.classList.add('svg-loader');
|
|
| 771 |
input.classList.add('ajax-loading');
|
|
| 772 |
} |
|
| 773 | ||
| 774 |
function restoreAutocompleteSearchIcon(fieldId) {
|
|
| 775 |
const input = document.getElementById(fieldId); |
|
| 776 |
if (!input) return; |
|
| 777 | ||
| 778 |
const container = input.closest('p');
|
|
| 779 |
if (!container) return; |
|
| 780 | ||
| 781 |
const svg = container.querySelector('svg.svg-loader');
|
|
| 782 |
if (!svg) return; |
|
| 783 | ||
| 784 |
updateSVGIcon(svg, 'search'); |
|
| 785 |
svg.classList.remove('svg-loader');
|
|
| 786 |
svg.classList.add('svg-search');
|
|
| 787 |
input.classList.remove('ajax-loading');
|
|
| 788 |
} |
|
| 789 | ||
| 758 | 790 |
function multipleAutocompleteField(fieldId, url, options) {
|
| 759 | 791 |
function split(val) {
|
| 760 | 792 |
return val.split(/,\s*/); |
| ... | ... | |
| 774 | 806 |
minLength: 2, |
| 775 | 807 |
position: {collision: "flipfit"},
|
| 776 | 808 |
search: function () {
|
| 777 |
$('#' + fieldId).addClass('ajax-loading');
|
|
| 809 |
showAutocompleteLoadingIcon(fieldId);
|
|
| 778 | 810 |
}, |
| 779 | 811 |
response: function () {
|
| 780 |
$('#' + fieldId).removeClass('ajax-loading');
|
|
| 812 |
restoreAutocompleteSearchIcon(fieldId);
|
|
| 781 | 813 |
}, |
| 782 | 814 |
select: function (event, ui) {
|
| 783 | 815 |
var terms = split(this.value); |
| ... | ... | |
| 809 | 841 |
type: 'get', |
| 810 | 842 |
data: {q: $this.val()},
|
| 811 | 843 |
success: function(data){ if(targetId) $('#'+targetId).html(data); },
|
| 812 |
beforeSend: function(){ $this.addClass('ajax-loading'); },
|
|
| 813 |
complete: function(){ $this.removeClass('ajax-loading'); }
|
|
| 844 |
beforeSend: function(){ showAutocompleteLoadingIcon(fieldId); },
|
|
| 845 |
complete: function(){ restoreAutocompleteSearchIcon(fieldId); }
|
|
| 814 | 846 |
}); |
| 815 | 847 |
} |
| 816 | 848 |
}; |
| app/assets/stylesheets/application.css | ||
|---|---|---|
| 965 | 965 |
.total-hours span.hours-int { font-size: 120%; }
|
| 966 | 966 | |
| 967 | 967 |
.autoscroll {overflow-x: auto; padding:1px; margin-bottom: 1.2em; position: relative;}
|
| 968 |
#user_login, #user_firstname, #user_lastname, #user_mail, #my_account_form select, #user_form select { width: 90%; }
|
|
| 968 |
#user_firstname, #user_lastname, #user_mail, #my_account_form select, #user_form select { width: 90%; }
|
|
| 969 |
#user_login { width: calc(90% - 18px); }
|
|
| 969 | 970 | |
| 970 | 971 |
#workflow_copy_form select { width: 200px; }
|
| 971 | 972 |
table.transitions td.enabled {background: #bfb;}
|
| ... | ... | |
| 1199 | 1200 |
input#principal_search, input#user_search {width:90%}
|
| 1200 | 1201 |
.roles-selection label {display:inline-block; width:210px;}
|
| 1201 | 1202 | |
| 1202 |
input.autocomplete {
|
|
| 1203 |
background: #fff url(/search.svg) no-repeat 2px 50%; padding-left:20px !important; |
|
| 1204 |
} |
|
| 1205 |
input.autocomplete.ajax-loading {
|
|
| 1206 |
background-image: url(/loading.gif); |
|
| 1207 |
} |
|
| 1208 | ||
| 1209 | 1203 |
.role-visibility {padding-left:2em;}
|
| 1210 | 1204 | |
| 1211 | 1205 |
.objects-selection {
|
| app/assets/stylesheets/rtl.css | ||
|---|---|---|
| 230 | 230 |
.attachments_fields input.description {margin-left:0px; margin-right:4px;}
|
| 231 | 231 | |
| 232 | 232 |
.attachments_fields input.filename {background:url(/attachment.png) no-repeat right 1px top 50%; padding-left:0px; padding-right:18px;}
|
| 233 |
.attachments_fields .ajax-waiting input.filename {background:url(/hourglass-empty.svg) no-repeat right top 50%;}
|
|
| 234 |
.attachments_fields .ajax-loading input.filename {background:url(/loading.gif) no-repeat right top 50%;}
|
|
| 235 | 233 |
.attachments_fields div.ui-progressbar {margin: 2px 8px -5px 0;}
|
| 236 | 234 | |
| 237 | 235 |
a.remove-upload {background: url(/delete.png) no-repeat right 1px top 50%; padding-left:0px; padding-right:16px;}
|
| ... | ... | |
| 247 | 245 |
table.members td.name {padding-right: 20px; padding-left:0; }
|
| 248 | 246 |
table.members td.group, table.members td.groupnonmember, table.members td.groupanonymous {background: url(/group.png) no-repeat right 50%;}
|
| 249 | 247 | |
| 250 |
input.autocomplete {
|
|
| 251 |
background: #fff url(/search.svg) no-repeat right 2px top 50%; padding-left:0px !important; padding-right:20px !important; |
|
| 252 |
} |
|
| 253 | ||
| 254 | 248 |
.role-visibility {padding-right:2em; padding-left:0;}
|
| 255 | 249 | |
| 256 | 250 |
/***** Flash & error messages ****/ |
| app/views/groups/_new_users_form.html.erb | ||
|---|---|---|
| 1 | 1 |
<fieldset class="box"> |
| 2 | 2 |
<legend><%= label_tag "user_search", l(:label_user_search) %></legend> |
| 3 |
<p><%= text_field_tag 'user_search', nil %></p> |
|
| 3 |
<p> |
|
| 4 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
| 5 |
<%= text_field_tag 'user_search', nil %> |
|
| 6 |
</p> |
|
| 4 | 7 |
<%= javascript_tag "observeSearchfield('user_search', null, '#{ escape_javascript autocomplete_for_user_group_path(@group) }')" %>
|
| 5 | 8 | |
| 6 | 9 |
<div id="users"> |
| app/views/issue_relations/_form.html.erb | ||
|---|---|---|
| 11 | 11 |
</div> |
| 12 | 12 |
<% end %> |
| 13 | 13 |
<p><%= f.select :relation_type, collection_for_relation_type_select, {}, :onchange => "setPredecessorFieldsVisibility();" %>
|
| 14 |
<%= l(:label_issue) %> #<%= f.text_field :issue_to_id, :value => unsaved_relations_ids, :size => 10 %> |
|
| 14 |
<span> |
|
| 15 |
<%= l(:label_issue) %> #<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %><%= f.text_field :issue_to_id, :value => unsaved_relations_ids, :size => 10 %> |
|
| 16 |
</span> |
|
| 15 | 17 |
<span id="predecessor_fields" style="display:none;"> |
| 16 | 18 |
<%= l(:field_delay) %>: <%= f.text_field :delay, :size => 3 %> <%= l(:label_day_plural) %> |
| 17 | 19 |
</span> |
| app/views/issues/_attributes.html.erb | ||
|---|---|---|
| 63 | 63 | |
| 64 | 64 |
<div class="splitcontentright"> |
| 65 | 65 |
<% if @issue.safe_attribute? 'parent_issue_id' %> |
| 66 |
<p id="parent_issue"><%= f.text_field :parent_issue_id, :size => 10, |
|
| 66 |
<p id="parent_issue"> |
|
| 67 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
| 68 |
<%= f.text_field :parent_issue_id, :size => 9, |
|
| 67 | 69 |
:required => @issue.required_attribute?('parent_issue_id'),
|
| 68 |
:onchange => "updateIssueFrom('#{escape_javascript update_issue_form_path(@project, @issue)}', this)" %></p>
|
|
| 70 |
:onchange => "updateIssueFrom('#{escape_javascript update_issue_form_path(@project, @issue)}', this)" %>
|
|
| 71 |
</p> |
|
| 69 | 72 |
<%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript(auto_complete_issues_path(:project_id => @issue.project, :scope => Setting.cross_project_subtasks, :status => @issue.closed? ? 'c' : 'o', :issue_id => @issue.id))}')" %>
|
| 70 | 73 |
<% end %> |
| 71 | 74 | |
| app/views/issues/bulk_edit.html.erb | ||
|---|---|---|
| 146 | 146 |
<% if @safe_attributes.include?('parent_issue_id') && @project %>
|
| 147 | 147 |
<p> |
| 148 | 148 |
<label for='issue_parent_issue_id'><%= l(:field_parent_issue) %></label> |
| 149 |
<%= text_field_tag 'issue[parent_issue_id]', '', :size => 10, :value => @issue_params[:parent_issue_id] %> |
|
| 149 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
| 150 |
<%= text_field_tag 'issue[parent_issue_id]', '', :size => 9, :value => @issue_params[:parent_issue_id] %> |
|
| 150 | 151 |
<label class="inline"><%= check_box_tag 'issue[parent_issue_id]', 'none', (@issue_params[:parent_issue_id] == 'none'), :id => nil, :data => {:disables => '#issue_parent_issue_id'} %><%= l(:button_clear) %></label>
|
| 151 | 152 |
</p> |
| 152 | 153 |
<%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project, :scope => Setting.cross_project_subtasks)}')" %>
|
| app/views/issues/destroy.html.erb | ||
|---|---|---|
| 10 | 10 |
<label><%= radio_button_tag 'todo', 'nullify', false %> <%= l(:text_assign_time_entries_to_project) %></label><br /> |
| 11 | 11 |
<% end %> |
| 12 | 12 |
<% if @project %> |
| 13 |
<span> |
|
| 13 | 14 |
<label><%= radio_button_tag 'todo', 'reassign', false, :onchange => 'if (this.checked) { $("#reassign_to_id").focus(); }' %> <%= l(:text_reassign_time_entries) %></label>
|
| 15 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
| 14 | 16 |
<%= text_field_tag 'reassign_to_id', params[:reassign_to_id], :size => 6, :onfocus => '$("#todo_reassign").attr("checked", true);' %>
|
| 17 |
</span> |
|
| 15 | 18 |
<%= javascript_tag "observeAutocompleteField('reassign_to_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project)}')" %>
|
| 16 | 19 |
<% end %> |
| 17 | 20 |
</p> |
| app/views/members/_new_form.html.erb | ||
|---|---|---|
| 1 | 1 |
<fieldset class="box"> |
| 2 | 2 |
<legend><%= label_tag("principal_search", l(:label_principal_search)) %></legend>
|
| 3 |
<p><%= text_field_tag('principal_search', nil) %></p>
|
|
| 3 |
<p> |
|
| 4 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
| 5 |
<%= text_field_tag('principal_search', nil) %>
|
|
| 6 |
</p> |
|
| 4 | 7 |
<%= javascript_tag "observeSearchfield('principal_search', null, '#{ escape_javascript autocomplete_project_memberships_path(@project, :format => 'js') }')" %>
|
| 5 | 8 |
<div id="principals_for_new_member"> |
| 6 | 9 |
<%= render_principals_for_new_members(@project) %> |
| app/views/repositories/_related_issues.html.erb | ||
|---|---|---|
| 32 | 32 |
:remote => true, |
| 33 | 33 |
:method => :post, |
| 34 | 34 |
:id => 'new-relation-form', :style => (@issue ? '' : 'display: none;')) do |f| %> |
| 35 |
<%= l(:label_issue) %> #<%= text_field_tag 'issue_id', '', :size => 10 %> |
|
| 35 |
<p> |
|
| 36 |
<%= l(:label_issue) %> # |
|
| 37 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
| 38 |
<%= text_field_tag 'issue_id', '', :size => 10 %> |
|
| 39 |
</p> |
|
| 36 | 40 |
<%= submit_tag l(:button_add) %> |
| 37 | 41 |
<%= toggle_link l(:button_cancel), 'new-relation-form'%> |
| 38 | 42 |
<% end %> |
| app/views/timelog/_form.html.erb | ||
|---|---|---|
| 11 | 11 |
<% end %> |
| 12 | 12 | |
| 13 | 13 |
<p> |
| 14 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
| 14 | 15 |
<%= f.text_field :issue_id, :size => 6, :required => Setting.timelog_required_fields.include?('issue_id') %>
|
| 15 | 16 |
<span id="time_entry_issue"> |
| 16 | 17 |
<%= link_to_issue(@time_entry.issue) if @time_entry.issue.try(:visible?) %> |
| app/views/timelog/bulk_edit.html.erb | ||
|---|---|---|
| 40 | 40 |
:onchange => "updateBulkEditFrom('#{escape_javascript url_for(:action => 'bulk_edit', :format => 'js')}')" ) %>
|
| 41 | 41 |
</p> |
| 42 | 42 |
<p> |
| 43 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
| 43 | 44 |
<label for="time_entry_issue_id"><%= l(:field_issue) %></label> |
| 44 | 45 |
<%= text_field :time_entry, :issue_id, :size => 6 %> |
| 45 | 46 |
<label class="inline"><%= check_box_tag 'time_entry[issue_id]', 'none', (@time_entry_params[:issue_id] == 'none'), :id => nil, :data => {:disables => '#time_entry_issue_id'} %><%= l(:button_clear) %></label>
|
| app/views/users/_form.html.erb | ||
|---|---|---|
| 6 | 6 |
<div class="splitcontentleft"> |
| 7 | 7 |
<fieldset class="box tabular"> |
| 8 | 8 |
<legend><%=l(:label_information_plural)%></legend> |
| 9 |
<p><%= f.text_field :login, :required => true, :size => 25 %></p> |
|
| 9 |
<p><%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %><%= f.text_field :login, :required => true, :size => 25 %></p>
|
|
| 10 | 10 |
<p><%= f.text_field :firstname, :required => true %></p> |
| 11 | 11 |
<p><%= f.text_field :lastname, :required => true %></p> |
| 12 | 12 |
<p><%= f.text_field :mail, :required => true %></p> |
| app/views/watchers/_new.html.erb | ||
|---|---|---|
| 21 | 21 |
<% end %> |
| 22 | 22 |
<%= hidden_field_tag 'project_id', @project.id if @project %> |
| 23 | 23 | |
| 24 |
<p><%= label_tag 'user_search', l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p> |
|
| 24 |
<p> |
|
| 25 |
<%= label_tag 'user_search', l(:label_user_search) %><br> |
|
| 26 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %><%= text_field_tag 'user_search', nil %> |
|
| 27 |
</p> |
|
| 25 | 28 |
<%= javascript_tag( |
| 26 | 29 |
"observeSearchfield( |
| 27 | 30 |
'user_search', |