Patch #42972 » 0001-Unify-the-look-and-feel-of-issue-notes-news-replies-.patch
| app/assets/javascripts/application-legacy.js | ||
|---|---|---|
| 426 | 426 |
tab_content.find('.journal').show();
|
| 427 | 427 |
tab_content.find('.journal:not(.has-notes)').hide();
|
| 428 | 428 |
tab_content.find('.journal .wiki').show();
|
| 429 |
tab_content.find('.journal .contextual .journal-actions > *').show();
|
|
| 429 |
tab_content.find('.journal .journal-actions > *').show();
|
|
| 430 | 430 | |
| 431 | 431 |
// always show thumbnails in notes tab |
| 432 | 432 |
var thumbnails = tab_content.find('.journal .thumbnails');
|
| ... | ... | |
| 439 | 439 |
tab_content.find('.journal:not(.has-details)').hide();
|
| 440 | 440 |
tab_content.find('.journal .wiki').hide();
|
| 441 | 441 |
tab_content.find('.journal .thumbnails').hide();
|
| 442 |
tab_content.find('.journal .contextual .journal-actions > *').hide();
|
|
| 442 |
tab_content.find('.journal .journal-actions > *').hide();
|
|
| 443 | 443 |
// Show reaction button in properties tab |
| 444 |
tab_content.find('.journal .contextual .journal-actions .reaction-button-wrapper').show();
|
|
| 444 |
tab_content.find('.journal .journal-actions .reaction-button-wrapper').show();
|
|
| 445 | 445 |
break; |
| 446 | 446 |
default: |
| 447 | 447 |
tab_content.find('.journal').show();
|
| 448 | 448 |
tab_content.find('.journal .wiki').show();
|
| 449 | 449 |
tab_content.find('.journal .thumbnails').show();
|
| 450 |
tab_content.find('.journal .contextual .journal-actions > *').show();
|
|
| 450 |
tab_content.find('.journal .journal-actions > *').show();
|
|
| 451 | 451 |
} |
| 452 | 452 | |
| 453 | 453 |
return false; |
| app/assets/stylesheets/application.css | ||
|---|---|---|
| 306 | 306 |
} |
| 307 | 307 |
.drdn-items>span {color:#999;}
|
| 308 | 308 | |
| 309 |
.contextual .drdn-content {top:18px;}
|
|
| 310 |
.contextual .drdn-items {padding:2px; min-width: 160px;}
|
|
| 311 |
.contextual .drdn-items>a {display: flex; padding: 5px 8px;}
|
|
| 312 |
.contextual .drdn-items>a.icon:not(:has(svg)) {padding-left: 24px; background-position-x: 4px;}
|
|
| 313 |
.contextual .drdn-items>a:hover {color:#2A5685; border:1px solid #628db6; background-color:#eef5fd; border-radius:3px;}
|
|
| 309 |
.contextual .drdn-content, .journal-actions .drdn-content {
|
|
| 310 |
top: 18px; |
|
| 311 |
} |
|
| 312 | ||
| 313 |
.contextual .drdn-items, .journal-actions .drdn-items {
|
|
| 314 |
padding: 2px; |
|
| 315 |
min-width: 160px; |
|
| 316 |
} |
|
| 317 | ||
| 318 |
.contextual .drdn-items > a, .journal-actions .drdn-items > a {
|
|
| 319 |
display: flex; |
|
| 320 |
padding: 5px 8px; |
|
| 321 |
} |
|
| 322 | ||
| 323 |
.contextual .drdn-items > a.icon:not(:has(svg)), .journal-actions .drdn-items > a.icon:not(:has(svg)) {
|
|
| 324 |
padding-left: 24px; |
|
| 325 |
background-position-x: 4px; |
|
| 326 |
} |
|
| 327 | ||
| 328 |
.contextual .drdn-items > a:hover, .journal-actions .drdn-items > a:hover {
|
|
| 329 |
color: #2A5685; |
|
| 330 |
border: 1px solid #628db6; |
|
| 331 |
background-color: #eef5fd; |
|
| 332 |
border-radius: 3px; |
|
| 333 |
} |
|
| 314 | 334 | |
| 315 | 335 |
#project-jump.drdn {width:200px;display:inline-block;}
|
| 316 | 336 |
#project-jump .drdn-trigger {
|
| ... | ... | |
| 436 | 456 |
tr.message.sticky td.subject { font-weight: bold; }
|
| 437 | 457 |
tr.message td.subject:not(:has(.icon)) { padding-left: 20px; }
|
| 438 | 458 | |
| 439 |
body.avatars-on #replies .message.reply {padding-left: 32px;}
|
|
| 440 |
#replies .reply:target h4.reply-header {background-color:#DDEEFF;}
|
|
| 441 |
#replies h4 img.gravatar {margin-left:-32px;}
|
|
| 442 | ||
| 443 | 459 |
tr.version.closed, tr.version.closed a { color: #999; }
|
| 444 | 460 |
tr.version:not(.shared) td.name { padding-left: 20px; }
|
| 445 | 461 |
tr.version td.date, tr.version td.status, tr.version td.sharing { text-align: center; white-space:nowrap; }
|
| ... | ... | |
| 593 | 609 |
} |
| 594 | 610 |
.contextual {float:right; white-space: nowrap; line-height:1.4em;margin:5px 0px; padding-left: 10px; font-size:0.9em;}
|
| 595 | 611 |
.contextual input, .contextual select {font-size:0.9em;}
|
| 596 |
.message .contextual, #comments .contextual { margin-top: 0; }
|
|
| 597 | 612 | |
| 598 | 613 |
.splitcontent {overflow: auto; display: flex; flex-wrap: wrap;}
|
| 599 | 614 |
.splitcontentleft {flex: 1; margin-right: 5px;}
|
| ... | ... | |
| 775 | 790 |
div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
|
| 776 | 791 |
.changeset-comments {margin-bottom:1em;}
|
| 777 | 792 | |
| 778 |
div.journal .contextual {margin-top: 0;}
|
|
| 779 |
div.journal.private-notes .wiki {border-left:2px solid #d22; padding-left:4px; margin-left:-6px;}
|
|
| 780 |
div.journal ul.details, ul.revision-info {color:#959595; margin-bottom: 1.5em;}
|
|
| 781 |
div.journal ul.details a, ul.revision-info a {color:#70A7CD;}
|
|
| 782 |
div.journal ul.details a:hover, ul.revision-info a:hover {color:#D14848;}
|
|
| 783 |
body.avatars-on div.journal {padding-left:32px;}
|
|
| 784 |
div.journal h4 img.gravatar {margin-left:-32px;}
|
|
| 785 |
div.journal span.update-info {color: #666; font-size: 0.9em;}
|
|
| 786 | ||
| 787 | 793 |
#update {margin-bottom: 1.4em;}
|
| 788 | 794 | |
| 789 |
#history .tab-content {
|
|
| 790 |
padding: 0 8px; |
|
| 791 |
margin-bottom: 10px; |
|
| 792 |
border-right: 1px solid #d0d7de; |
|
| 793 |
border-bottom: 1px solid #d0d7de; |
|
| 794 |
border-left: 1px solid #d0d7de; |
|
| 795 |
border-radius: 0 0 3px 3px / 0 0 3px 3px; |
|
| 796 |
box-shadow: 0 1px 2px rgba(0,0,0,0.05); |
|
| 797 |
} |
|
| 798 | ||
| 799 |
#history div:target h4.note-header {background-color:#DDEEFF;}
|
|
| 800 | 795 |
#history p.nodata {display: none;}
|
| 801 | 796 |
/* Prevent content from being hidden behind a #sticky-issue-header when scrolling via anchor links. */ |
| 802 | 797 |
.controller-issues.action-show div.wiki a[name], |
| ... | ... | |
| 1193 | 1188 |
div.thumbnails {margin:0.6em;}
|
| 1194 | 1189 |
div.thumbnail {background:#fff;border:2px solid #ddd;display:inline-block;margin-right:2px;}
|
| 1195 | 1190 |
div.thumbnail img {margin: 3px; vertical-align: middle;}
|
| 1196 |
#history div.thumbnails {margin-left: 2em;}
|
|
| 1197 | 1191 | |
| 1198 | 1192 |
p.other-formats { text-align: right; font-size:0.9em; color: #666; }
|
| 1199 | 1193 |
.other-formats span + span:before { content: "| "; }
|
| ... | ... | |
| 1745 | 1739 |
.handle {cursor: move;}
|
| 1746 | 1740 | |
| 1747 | 1741 |
#my-page .list th.checkbox, #my-page .list td.checkbox {display:none;}
|
| 1742 | ||
| 1748 | 1743 |
/***** Gantt chart *****/ |
| 1749 | 1744 |
table.gantt-table {
|
| 1750 | 1745 |
width: 100%; |
| ... | ... | |
| 1858 | 1853 |
.version-behind-schedule a, .issue-behind-schedule a {color: #f66914;}
|
| 1859 | 1854 |
.version-overdue a, .issue-overdue a, .project-overdue a {color: #f00;}
|
| 1860 | 1855 | |
| 1856 |
/***** User events (ex: journal, notes, replies, comments) *****/ |
|
| 1857 |
.journals h4.journal-header {
|
|
| 1858 |
background-color: #f6f7f8; |
|
| 1859 |
border-bottom: 0; |
|
| 1860 |
padding: 8px; |
|
| 1861 |
align-items: center; |
|
| 1862 |
display: flex; |
|
| 1863 |
justify-content: space-between; |
|
| 1864 |
} |
|
| 1865 | ||
| 1866 |
.journals h4.journal-header .update-info {
|
|
| 1867 |
color: #666; |
|
| 1868 |
font-size: 0.9em; |
|
| 1869 |
} |
|
| 1870 | ||
| 1871 |
.journals h4.journal-header .badge {
|
|
| 1872 |
position: static; |
|
| 1873 |
} |
|
| 1874 | ||
| 1875 |
.journals div:target h4.journal-header {
|
|
| 1876 |
background-color:#DDEEFF; |
|
| 1877 |
} |
|
| 1878 | ||
| 1879 |
.journals .journal-content {
|
|
| 1880 |
padding-left: 8px; |
|
| 1881 |
margin-bottom: 1.2em; |
|
| 1882 |
} |
|
| 1883 | ||
| 1884 |
.journals .journal .journal-content .wiki {
|
|
| 1885 |
margin-left: 0.6em; |
|
| 1886 |
} |
|
| 1887 | ||
| 1888 |
.journals .private-notes {
|
|
| 1889 |
border-left: 2px solid #d22; |
|
| 1890 |
} |
|
| 1891 | ||
| 1892 |
.journals .journal-meta, .journals .journal-actions {
|
|
| 1893 |
display: inline-flex; |
|
| 1894 |
gap: 10px; |
|
| 1895 |
} |
|
| 1896 | ||
| 1897 |
.journals .journal-meta .journal-link {
|
|
| 1898 |
color: #555; |
|
| 1899 |
} |
|
| 1900 | ||
| 1901 |
.journals .journal-actions .reaction-button-wrapper {
|
|
| 1902 |
display: inline-flex; |
|
| 1903 |
} |
|
| 1904 | ||
| 1905 |
.journals .journal-details, ul.revision-info {
|
|
| 1906 |
color: #959595; |
|
| 1907 |
margin-bottom: 1.5em; |
|
| 1908 |
} |
|
| 1909 | ||
| 1910 |
.journals .journal-details a, ul.revision-info a {
|
|
| 1911 |
color: #70A7CD; |
|
| 1912 |
} |
|
| 1913 | ||
| 1914 |
.journals .journal-details a:hover, ul.revision-info a:hover {
|
|
| 1915 |
color: #D14848; |
|
| 1916 |
} |
|
| 1917 | ||
| 1861 | 1918 |
/***** Badges *****/ |
| 1862 | 1919 |
.badge {
|
| 1863 | 1920 |
position:relative; |
| ... | ... | |
| 2135 | 2192 |
} |
| 2136 | 2193 | |
| 2137 | 2194 |
h2 img.gravatar, h3 img.gravatar {margin-right: 4px;}
|
| 2138 |
h4 img.gravatar {margin: -2px 4px -4px 0;}
|
|
| 2139 | 2195 |
td.username img.gravatar {margin: 0 0.5em 0 0; vertical-align: top;}
|
| 2140 | 2196 |
#activity dt img.gravatar {margin: 0 1em 0 0;}
|
| 2141 | 2197 |
/* Used on 12px Gravatar img tags without the icon background */ |
| app/helpers/journals_helper.rb | ||
|---|---|---|
| 70 | 70 | |
| 71 | 71 |
def render_notes(issue, journal, options={})
|
| 72 | 72 |
content_tag('div', textilizable(journal, :notes),
|
| 73 |
id: "journal-#{journal.id}-notes", class: "wiki", data: { quote_reply_target: 'content' })
|
|
| 73 |
id: "journal-#{journal.id}-notes", class: "wiki journal-note", data: { quote_reply_target: 'content' })
|
|
| 74 | 74 |
end |
| 75 | 75 | |
| 76 | 76 |
def render_private_notes_indicator(journal) |
| app/views/issues/show.html.erb | ||
|---|---|---|
| 131 | 131 | |
| 132 | 132 |
<%= render partial: 'action_menu_edit' if User.current.wants_comments_in_reverse_order? %> |
| 133 | 133 | |
| 134 |
<div id="history"> |
|
| 134 |
<div id="history" class="journals">
|
|
| 135 | 135 |
<%= render_tabs issue_history_tabs, issue_history_default_tab %> |
| 136 | 136 |
</div> |
| 137 | 137 | |
| app/views/issues/tabs/_changesets.html.erb | ||
|---|---|---|
| 1 | 1 |
<% @changesets.each do |changeset| %> |
| 2 | 2 |
<div id="changeset-<%= changeset.id %>" class="changeset journal"> |
| 3 |
<div class="note"> |
|
| 4 |
<h4 class='note-header'> |
|
| 5 |
<%= avatar(changeset.user, :size => "24") %> |
|
| 6 |
<%= authoring changeset.committed_on, changeset.author, :label => :label_added_time_by %> |
|
| 3 |
<h4 class='journal-header'> |
|
| 4 |
<span class="journal-info"> |
|
| 5 |
<%= avatar(changeset.user, :size => "24") %> |
|
| 6 |
<%= authoring changeset.committed_on, changeset.author, :label => :label_added_time_by %> |
|
| 7 |
</span> |
|
| 7 | 8 |
</h4> |
| 8 |
<p> |
|
| 9 |
<%= "#{changeset.project.name} - " unless changeset.project == project %>
|
|
| 10 |
<%= link_to_revision(changeset, changeset.repository, |
|
| 11 |
:text => "#{l(:label_revision)} #{changeset.format_identifier}") %>
|
|
| 12 |
<% if changeset.filechanges.any? && User.current.allowed_to?(:browse_repository, changeset.project) %> |
|
| 13 |
(<%= link_to(l(:label_diff), |
|
| 14 |
:controller => 'repositories', |
|
| 15 |
:action => 'diff', |
|
| 16 |
:id => changeset.project, |
|
| 17 |
:repository_id => changeset.repository.identifier_param, |
|
| 18 |
:path => "", |
|
| 19 |
:rev => changeset.identifier) %>) |
|
| 20 |
<% end %></p> |
|
| 21 | ||
| 22 |
<div class="wiki changeset-comments"> |
|
| 23 |
<%= format_changeset_comments changeset %> |
|
| 24 |
</div> |
|
| 9 |
<div class="journal-content"> |
|
| 10 |
<p> |
|
| 11 |
<%= "#{changeset.project.name} - " unless changeset.project == project %>
|
|
| 12 |
<%= link_to_revision(changeset, changeset.repository, |
|
| 13 |
:text => "#{l(:label_revision)} #{changeset.format_identifier}") %>
|
|
| 14 |
<% if changeset.filechanges.any? && User.current.allowed_to?(:browse_repository, changeset.project) %> |
|
| 15 |
(<%= link_to(l(:label_diff), |
|
| 16 |
:controller => 'repositories', |
|
| 17 |
:action => 'diff', |
|
| 18 |
:id => changeset.project, |
|
| 19 |
:repository_id => changeset.repository.identifier_param, |
|
| 20 |
:path => "", |
|
| 21 |
:rev => changeset.identifier) %>) |
|
| 22 |
<% end %> |
|
| 23 |
</p> |
|
| 24 |
<div class="wiki changeset-comments"> |
|
| 25 |
<%= format_changeset_comments changeset %> |
|
| 26 |
</div> |
|
| 25 | 27 |
</div> |
| 26 | 28 |
</div> |
| 27 | 29 |
<%= call_hook(:view_issues_history_changeset_bottom, { :changeset => changeset }) %>
|
| app/views/issues/tabs/_history.html.erb | ||
|---|---|---|
| 7 | 7 |
<% for journal in journals %> |
| 8 | 8 |
<div id="change-<%= journal.id %>" class="<%= journal.css_classes %>" data-controller="quote-reply"> |
| 9 | 9 |
<div id="note-<%= journal.indice %>" class="note"> |
| 10 |
<div class="contextual"> |
|
| 11 |
<span class="journal-actions"><%= render_journal_actions(issue, journal, :reply_links => reply_links) %></span> |
|
| 12 |
<a href="#note-<%= journal.indice %>" class="journal-link">#<%= journal.indice %></a> |
|
| 13 |
</div> |
|
| 14 |
<h4 class='note-header'> |
|
| 15 |
<%= avatar(journal.user) %> |
|
| 16 |
<%= authoring journal.created_on, journal.user, :label => :label_updated_time_by %> |
|
| 17 |
<%= render_private_notes_indicator(journal) %> |
|
| 18 |
<%= render_journal_update_info(journal) %> |
|
| 19 |
</h4> |
|
| 20 | ||
| 21 |
<% if journal.details.any? %> |
|
| 22 |
<ul class="details"> |
|
| 23 |
<% details_to_strings(journal.visible_details).each do |string| %> |
|
| 24 |
<li><%= string %></li> |
|
| 25 |
<% end %> |
|
| 26 |
</ul> |
|
| 27 |
<% if Setting.thumbnails_enabled? && (thumbnail_attachments = journal_thumbnail_attachments(journal)).any? %> |
|
| 28 |
<div class="thumbnails"> |
|
| 29 |
<% thumbnail_attachments.each do |attachment| %> |
|
| 30 |
<%= thumbnail_tag(attachment) %> |
|
| 10 |
<h4 class='journal-header'> |
|
| 11 |
<span class="journal-info"> |
|
| 12 |
<%= avatar(journal.user) %> |
|
| 13 |
<%= authoring journal.created_on, journal.user, :label => :label_updated_time_by %> |
|
| 14 |
<%= render_private_notes_indicator(journal) %> |
|
| 15 |
<%= render_journal_update_info(journal) %> |
|
| 16 |
</span> |
|
| 17 |
<span class="journal-meta"> |
|
| 18 |
<span class="journal-actions"> |
|
| 19 |
<%= render_journal_actions(issue, journal, :reply_links => reply_links) %> |
|
| 20 |
</span> |
|
| 21 |
<a href="#note-<%= journal.indice %>" class="journal-link">#<%= journal.indice %></a> |
|
| 22 |
</span> |
|
| 23 |
</h4> |
|
| 24 |
<div class="journal-content"> |
|
| 25 |
<% if journal.details.any? %> |
|
| 26 |
<ul class="journal-details"> |
|
| 27 |
<% details_to_strings(journal.visible_details).each do |string| %> |
|
| 28 |
<li><%= string %></li> |
|
| 29 |
<% end %> |
|
| 30 |
</ul> |
|
| 31 |
<% if Setting.thumbnails_enabled? && (thumbnail_attachments = journal_thumbnail_attachments(journal)).any? %> |
|
| 32 |
<div class="thumbnails"> |
|
| 33 |
<% thumbnail_attachments.each do |attachment| %> |
|
| 34 |
<%= thumbnail_tag(attachment) %> |
|
| 35 |
<% end %> |
|
| 36 |
</div> |
|
| 37 |
<% end %> |
|
| 31 | 38 |
<% end %> |
| 39 |
<%= render_notes(issue, journal, :reply_links => reply_links) unless journal.notes.blank? %> |
|
| 32 | 40 |
</div> |
| 33 |
<% end %> |
|
| 34 |
<% end %> |
|
| 35 |
<%= render_notes(issue, journal, :reply_links => reply_links) unless journal.notes.blank? %> |
|
| 36 | 41 |
</div> |
| 37 | 42 |
</div> |
| 38 | 43 |
<%= call_hook(:view_issues_history_journal_bottom, { :journal => journal }) %>
|
| app/views/issues/tabs/_time_entries.html.erb | ||
|---|---|---|
| 1 |
<% for time_entry in time_entries%> |
|
| 1 |
<% for time_entry in time_entries %>
|
|
| 2 | 2 |
<div id="time-entry-<%= time_entry.id %>" class="time_entry journal"> |
| 3 |
<div class="note"> |
|
| 4 |
<% if time_entry.editable_by?(User.current) -%> |
|
| 5 |
<div class="contextual"> |
|
| 6 |
<span class="journal-actions"> |
|
| 7 |
<%= link_to sprite_icon('edit', l(:button_edit)), edit_time_entry_path(time_entry),
|
|
| 8 |
:title => l(:button_edit), |
|
| 9 |
:class => 'icon-only icon-edit ' %> |
|
| 10 |
<%= link_to sprite_icon('del', l(:button_delete)), time_entry_path(time_entry),
|
|
| 11 |
:data => {:confirm => l(:text_are_you_sure)},
|
|
| 12 |
:method => :delete, |
|
| 13 |
:title => l(:button_delete), |
|
| 14 |
:class => 'icon-only icon-del ' %> |
|
| 3 |
<h4 class='journal-header'> |
|
| 4 |
<span class="journal-info"> |
|
| 5 |
<%= avatar(time_entry.user, :size => "24") %> |
|
| 6 |
<%= authoring time_entry.created_on, time_entry.user, :label => :label_added_time_by %> |
|
| 15 | 7 |
</span> |
| 16 |
</div> |
|
| 17 |
<% end -%> |
|
| 18 |
<h4 class='note-header'> |
|
| 19 |
<%= avatar(time_entry.user, :size => "24") %> |
|
| 20 |
<%= authoring time_entry.created_on, time_entry.user, :label => :label_added_time_by %> |
|
| 8 |
<% if time_entry.editable_by?(User.current) -%> |
|
| 9 |
<span class="journal-meta"> |
|
| 10 |
<%= link_to sprite_icon('edit', l(:button_edit)), edit_time_entry_path(time_entry),
|
|
| 11 |
:title => l(:button_edit), |
|
| 12 |
:class => 'icon-only icon-edit' %> |
|
| 13 |
<%= link_to sprite_icon('del', l(:button_delete)), time_entry_path(time_entry),
|
|
| 14 |
:data => { :confirm => l(:text_are_you_sure) },
|
|
| 15 |
:method => :delete, |
|
| 16 |
:title => l(:button_delete), |
|
| 17 |
:class => 'icon-only icon-del' %> |
|
| 18 |
</span> |
|
| 19 |
<% end -%> |
|
| 21 | 20 |
</h4> |
| 22 |
<ul class="details"> |
|
| 23 |
<li> |
|
| 24 |
<strong><%= l(:label_time_entry_plural) %></strong>: |
|
| 25 |
<%= l_hours_short time_entry.hours %> |
|
| 26 |
</li> |
|
| 27 |
</ul> |
|
| 28 |
<p><%= time_entry.comments %></p> |
|
| 21 |
<div class="journal-content"> |
|
| 22 |
<ul class="journal-details"> |
|
| 23 |
<li> |
|
| 24 |
<strong><%= l(:label_time_entry_plural) %></strong>: |
|
| 25 |
<%= l_hours_short time_entry.hours %> |
|
| 26 |
</li> |
|
| 27 |
</ul> |
|
| 28 |
<div class="journal-note"> |
|
| 29 |
<%= time_entry.comments %> |
|
| 30 |
</div> |
|
| 29 | 31 |
</div> |
| 30 | 32 |
</div> |
| 31 | 33 |
<%= call_hook(:view_issues_history_time_entry_bottom, { :time_entry => time_entry }) %>
|
| app/views/journals/update.js.erb | ||
|---|---|---|
| 7 | 7 |
$("#journal-<%= @journal.id %>-notes").replaceWith('<%= escape_javascript(render_notes(@journal.issue, @journal, :reply_links => authorize_for('issues', 'edit'))) %>');
|
| 8 | 8 |
$("#journal-<%= @journal.id %>-notes").show();
|
| 9 | 9 |
$("#journal-<%= @journal.id %>-form").remove();
|
| 10 |
var journal_header = $("#change-<%= @journal.id %>>div.note>h4.note-header");
|
|
| 10 |
var journal_header = $("#change-<%= @journal.id %>>div.note>h4.journal-header>.journal-info");
|
|
| 11 | 11 |
var journal_updated_info = journal_header.find("span.update-info");
|
| 12 | 12 |
if (journal_updated_info.length > 0) {
|
| 13 | 13 |
journal_updated_info.replaceWith('<%= escape_javascript(render_journal_update_info(@journal)) %>');
|
| app/views/messages/show.html.erb | ||
|---|---|---|
| 8 | 8 |
) if !@topic.locked? && authorize_for('messages', 'reply') %>
|
| 9 | 9 |
<%= link_to( |
| 10 | 10 |
sprite_icon('edit', l(:button_edit)),
|
| 11 |
{:action => 'edit', :id => @topic},
|
|
| 11 |
{ :action => 'edit', :id => @topic },
|
|
| 12 | 12 |
:class => 'icon icon-edit' |
| 13 | 13 |
) if @message.editable_by?(User.current) %> |
| 14 | 14 |
<%= link_to( |
| 15 | 15 |
sprite_icon('del', l(:button_delete)),
|
| 16 |
{:action => 'destroy', :id => @topic},
|
|
| 16 |
{ :action => 'destroy', :id => @topic },
|
|
| 17 | 17 |
:method => :post, |
| 18 |
:data => {:confirm => l(:text_are_you_sure)},
|
|
| 18 |
:data => { :confirm => l(:text_are_you_sure) },
|
|
| 19 | 19 |
:class => 'icon icon-del' |
| 20 | 20 |
) if @message.destroyable_by?(User.current) %> |
| 21 | 21 |
</div> |
| ... | ... | |
| 33 | 33 |
<%= link_to_attachments @topic, :author => false, :thumbnails => true %> |
| 34 | 34 |
</div> |
| 35 | 35 |
</div> |
| 36 |
<br />
|
|
| 36 |
<br/> |
|
| 37 | 37 | |
| 38 | 38 |
<% unless @replies.empty? %> |
| 39 |
<div id="replies"> |
|
| 40 |
<h3 class="comments icon icon-comments"><%= sprite_icon('comments', l(:label_reply_plural)) %> (<%= @reply_count %>)</h3>
|
|
| 41 |
<% if !@topic.locked? && authorize_for('messages', 'reply') && @replies.size >= 3 %>
|
|
| 42 |
<p><%= toggle_link l(:button_reply), "reply", :focus => 'message_content', :scroll => "message_content" %></p> |
|
| 43 |
<% end %> |
|
| 44 |
<% @replies.each do |message| %> |
|
| 45 |
<div class="message reply" id="<%= "message-#{message.id}" %>" data-controller="quote-reply">
|
|
| 46 |
<div class="contextual"> |
|
| 47 |
<%= reaction_button message %> |
|
| 48 |
<%= quote_reply_button( |
|
| 49 |
url: url_for(action: 'quote', id: message, format: 'js'), |
|
| 50 |
icon_only: true |
|
| 51 |
) if !@topic.locked? && authorize_for('messages', 'reply') %>
|
|
| 52 |
<%= link_to( |
|
| 53 |
sprite_icon('edit', l(:button_edit), icon_only: true),
|
|
| 54 |
{:action => 'edit', :id => message},
|
|
| 55 |
:title => l(:button_edit), |
|
| 56 |
:class => 'icon icon-edit' |
|
| 57 |
) if message.editable_by?(User.current) %> |
|
| 58 |
<%= link_to( |
|
| 59 |
sprite_icon('del', l(:button_delete), icon_only: true),
|
|
| 60 |
{:action => 'destroy', :id => message},
|
|
| 61 |
:method => :post, |
|
| 62 |
:data => {:confirm => l(:text_are_you_sure)},
|
|
| 63 |
:title => l(:button_delete), |
|
| 64 |
:class => 'icon icon-del' |
|
| 65 |
) if message.destroyable_by?(User.current) %> |
|
| 66 |
</div> |
|
| 67 |
<h4 class='reply-header'> |
|
| 68 |
<%= avatar(message.author) %> |
|
| 69 |
<%= link_to message.subject, { :controller => 'messages', :action => 'show', :board_id => @board, :id => @topic, :r => message, :anchor => "message-#{message.id}" } %>
|
|
| 70 |
- |
|
| 71 |
<%= authoring message.created_on, message.author %> |
|
| 72 |
</h4> |
|
| 73 |
<div class="wiki" data-quote-reply-target="content"> |
|
| 74 |
<%= textilizable message, :content, :attachments => message.attachments %> |
|
| 39 |
<div id="replies" class="journals"> |
|
| 40 |
<h3 class="comments icon icon-comments"><%= sprite_icon('comments', l(:label_reply_plural)) %>
|
|
| 41 |
(<%= @reply_count %>)</h3> |
|
| 42 |
<% if !@topic.locked? && authorize_for('messages', 'reply') && @replies.size >= 3 %>
|
|
| 43 |
<p><%= toggle_link l(:button_reply), "reply", :focus => 'message_content', :scroll => "message_content" %></p> |
|
| 44 |
<% end %> |
|
| 45 |
<% @replies.each do |message| %> |
|
| 46 |
<div class="message reply journal" id="<%= "message-#{message.id}" %>" data-controller="quote-reply">
|
|
| 47 |
<h4 class='reply-header journal-header'> |
|
| 48 |
<span class="journal-info"> |
|
| 49 |
<%= avatar(message.author) %> |
|
| 50 |
<%= link_to message.subject, { :controller => 'messages', :action => 'show', :board_id => @board, :id => @topic, :r => message, :anchor => "message-#{message.id}" } %>
|
|
| 51 |
- |
|
| 52 |
<%= authoring message.created_on, message.author %> |
|
| 53 |
</span> |
|
| 54 |
<span class="journal-meta"> |
|
| 55 |
<%= reaction_button message %> |
|
| 56 |
<%= quote_reply_button( |
|
| 57 |
url: url_for(action: 'quote', id: message, format: 'js'), |
|
| 58 |
icon_only: true |
|
| 59 |
) if !@topic.locked? && authorize_for('messages', 'reply') %>
|
|
| 60 |
<%= link_to( |
|
| 61 |
sprite_icon('edit', l(:button_edit), icon_only: true),
|
|
| 62 |
{ :action => 'edit', :id => message },
|
|
| 63 |
:title => l(:button_edit), |
|
| 64 |
:class => 'icon icon-edit' |
|
| 65 |
) if message.editable_by?(User.current) %> |
|
| 66 |
<%= link_to( |
|
| 67 |
sprite_icon('del', l(:button_delete), icon_only: true),
|
|
| 68 |
{ :action => 'destroy', :id => message },
|
|
| 69 |
:method => :post, |
|
| 70 |
:data => { :confirm => l(:text_are_you_sure) },
|
|
| 71 |
:title => l(:button_delete), |
|
| 72 |
:class => 'icon icon-del' |
|
| 73 |
) if message.destroyable_by?(User.current) %> |
|
| 74 |
</span> |
|
| 75 |
</h4> |
|
| 76 |
<div class="wiki journal-content" data-quote-reply-target="content"> |
|
| 77 |
<%= textilizable message, :content, :attachments => message.attachments %> |
|
| 78 |
</div> |
|
| 79 |
<%= link_to_attachments message, :author => false, :thumbnails => true %> |
|
| 80 |
</div> |
|
| 81 |
<% end %> |
|
| 75 | 82 |
</div> |
| 76 |
<%= link_to_attachments message, :author => false, :thumbnails => true %> |
|
| 77 |
</div> |
|
| 78 |
<% end %> |
|
| 79 |
</div> |
|
| 80 |
<span class="pagination"><%= pagination_links_full @reply_pages, @reply_count, :per_page_links => false %></span> |
|
| 83 |
<span class="pagination"><%= pagination_links_full @reply_pages, @reply_count, :per_page_links => false %></span> |
|
| 81 | 84 |
<% end %> |
| 82 | 85 | |
| 83 | 86 |
<% if !@topic.locked? && authorize_for('messages', 'reply') %>
|
| 84 |
<p><%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %></p> |
|
| 85 |
<div id="reply" style="display:none;"> |
|
| 86 |
<%= form_for @reply, :as => :reply, :url => {:action => 'reply', :id => @topic}, :html => {:multipart => true, :id => 'message-form'} do |f| %>
|
|
| 87 |
<%= render :partial => 'form', :locals => {:f => f, :replying => true} %>
|
|
| 88 |
<%= submit_tag l(:button_submit) %> |
|
| 89 |
<% end %> |
|
| 90 |
</div> |
|
| 87 |
<p><%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %></p>
|
|
| 88 |
<div id="reply" style="display:none;">
|
|
| 89 |
<%= form_for @reply, :as => :reply, :url => { :action => 'reply', :id => @topic }, :html => { :multipart => true, :id => 'message-form' } do |f| %>
|
|
| 90 |
<%= render :partial => 'form', :locals => { :f => f, :replying => true } %>
|
|
| 91 |
<%= submit_tag l(:button_submit) %>
|
|
| 92 |
<% end %>
|
|
| 93 |
</div>
|
|
| 91 | 94 |
<% end %> |
| 92 | 95 | |
| 93 | 96 |
<% html_title @topic.subject %> |
| 94 | 97 |
<% content_for :sidebar do %> |
| 95 | 98 |
<% if User.current.allowed_to?(:add_message_watchers, @project) || |
| 96 |
(@topic.watchers.present? && User.current.allowed_to?(:view_message_watchers, @project)) %> |
|
| 99 |
(@topic.watchers.present? && User.current.allowed_to?(:view_message_watchers, @project)) %>
|
|
| 97 | 100 |
<div id="watchers"> |
| 98 |
<%= render :partial => 'watchers/watchers', :locals => {:watched => @topic} %>
|
|
| 101 |
<%= render :partial => 'watchers/watchers', :locals => { :watched => @topic } %>
|
|
| 99 | 102 |
</div> |
| 100 | 103 |
<% end %> |
| 101 | 104 |
<% end %> |
| app/views/news/show.html.erb | ||
|---|---|---|
| 35 | 35 |
</div> |
| 36 | 36 |
<br /> |
| 37 | 37 | |
| 38 |
<div id="comments" style="margin-bottom:16px;">
|
|
| 39 |
<h3 class="comments"><%= l(:label_comment_plural) %></h3> |
|
| 38 |
<div id="comments" class="journals">
|
|
| 39 |
<h3 class="comments journal-header"><%= l(:label_comment_plural) %></h3>
|
|
| 40 | 40 |
<% if @news.commentable? && @comments.size >= 3 %> |
| 41 | 41 |
<p><%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments", :scroll => "comment_comments" %></p> |
| 42 | 42 |
<% end %> |
| 43 | 43 |
<% @comments.each do |comment| %> |
| 44 |
<% next if comment.new_record? %> |
|
| 45 |
<div class="contextual"> |
|
| 46 |
<%= reaction_button comment %> |
|
| 47 |
<%= link_to_if_authorized sprite_icon('del', l(:button_delete)), { :controller => 'comments', :action => 'destroy', :id => @news, :comment_id => comment},
|
|
| 48 |
:data => {:confirm => l(:text_are_you_sure)}, :method => :delete,
|
|
| 49 |
:title => l(:button_delete), |
|
| 50 |
:class => 'icon-only icon-del' %> |
|
| 51 |
</div> |
|
| 52 |
<h4><%= avatar(comment.author) %><%= authoring comment.created_on, comment.author %></h4> |
|
| 53 |
<div class="wiki"> |
|
| 54 |
<%= textilizable(comment.comments) %> |
|
| 44 |
<div class="message reply journal-entry" id="<%= "message-#{comment.id}" %>">
|
|
| 45 |
<% next if comment.new_record? %> |
|
| 46 |
<h4 class="reply-header journal-header"> |
|
| 47 |
<span class="journal-info"> |
|
| 48 |
<%= avatar(comment.author) %> |
|
| 49 |
<%= authoring comment.created_on, comment.author %> |
|
| 50 |
</span> |
|
| 51 |
<span class="journal-meta"> |
|
| 52 |
<%= reaction_button comment %> |
|
| 53 |
<%= link_to_if_authorized sprite_icon('del', l(:button_delete)), { :controller => 'comments', :action => 'destroy', :id => @news, :comment_id => comment},
|
|
| 54 |
:data => {:confirm => l(:text_are_you_sure)}, :method => :delete,
|
|
| 55 |
:title => l(:button_delete), |
|
| 56 |
:class => 'icon-only icon-del' %> |
|
| 57 |
</span> |
|
| 58 |
</h4> |
|
| 59 |
<div class="wiki journal-content"> |
|
| 60 |
<%= textilizable(comment.comments) %> |
|
| 61 |
</div> |
|
| 55 | 62 |
</div> |
| 56 | 63 |
<% end if @comments.any? %> |
| 57 | 64 |
</div> |
| test/functional/issues_controller_test.rb | ||
|---|---|---|
| 2485 | 2485 |
end |
| 2486 | 2486 |
assert_select 'div#tab-content-history' do |
| 2487 | 2487 |
assert_select 'div[id=?]', "change-#{Issue.find(1).journals.last.id}" do
|
| 2488 |
assert_select 'ul.details', :text => "Subtask ##{issue.id} added"
|
|
| 2488 |
assert_select 'ul.journal-details', :text => "Subtask ##{issue.id} added"
|
|
| 2489 | 2489 |
end |
| 2490 | 2490 |
end |
| 2491 | 2491 |
end |
| ... | ... | |
| 3305 | 3305 |
assert_select 'a[title=?][href=?]', 'Edit', '/time_entries/3/edit' |
| 3306 | 3306 |
assert_select 'a[title=?][href=?]', 'Delete', '/time_entries/3' |
| 3307 | 3307 | |
| 3308 |
assert_select 'ul[class=?]', 'details', :text => /1.00 h/ |
|
| 3308 |
assert_select 'ul[class=?]', 'journal-details', :text => /1.00 h/
|
|
| 3309 | 3309 |
end |
| 3310 | 3310 |
end |
| 3311 | 3311 | |
| ... | ... | |
| 8697 | 8697 | |
| 8698 | 8698 |
assert_select 'div#tab-content-history' do |
| 8699 | 8699 |
assert_select 'div[id=?]', "change-#{parent.journals.last.id}" do
|
| 8700 |
assert_select 'ul.details', :text => "Subtask deleted (##{child.id})"
|
|
| 8700 |
assert_select 'ul.journal-details', :text => "Subtask deleted (##{child.id})"
|
|
| 8701 | 8701 |
end |
| 8702 | 8702 |
end |
| 8703 | 8703 |
end |
| test/functional/issues_custom_fields_visibility_test.rb | ||
|---|---|---|
| 101 | 101 |
get(:show, :params => {:id => @issue.id})
|
| 102 | 102 |
@fields.each_with_index do |field, i| |
| 103 | 103 |
if fields.include?(field) |
| 104 |
assert_select 'ul.details i', {:text => "Value#{i}", :count => 1}, "User #{user.id} was not able to view #{field.name} change"
|
|
| 104 |
assert_select 'ul.journal-details i', {:text => "Value#{i}", :count => 1}, "User #{user.id} was not able to view #{field.name} change"
|
|
| 105 | 105 |
else |
| 106 |
assert_select 'ul.details i', {:text => "Value#{i}", :count => 0}, "User #{user.id} was able to view #{field.name} change"
|
|
| 106 |
assert_select 'ul.journal-details i', {:text => "Value#{i}", :count => 0}, "User #{user.id} was able to view #{field.name} change"
|
|
| 107 | 107 |
end |
| 108 | 108 |
end |
| 109 | 109 |
end |
| test/integration/issues_test.rb | ||
|---|---|---|
| 355 | 355 |
end |
| 356 | 356 |
# Issue view |
| 357 | 357 |
follow_redirect! |
| 358 |
assert_select 'ul.details li', :text => "Tester changed from #{tester} to #{new_tester}"
|
|
| 358 |
assert_select 'ul.journal-details li', :text => "Tester changed from #{tester} to #{new_tester}"
|
|
| 359 | 359 |
end |
| 360 | 360 |
end |
| 361 | 361 | |
| test/system/issues_reply_test.rb | ||
|---|---|---|
| 93 | 93 |
# Select the entire details of the note#1 and the part of the note#1's text. |
| 94 | 94 |
page.execute_script <<-JS |
| 95 | 95 |
const range = document.createRange(); |
| 96 |
range.setStartBefore(document.querySelector('#change-1 .details'));
|
|
| 96 |
range.setStartBefore(document.querySelector('#change-1 .journal-details'));
|
|
| 97 | 97 |
// Select only the text "Journal" from the text "Journal notes" in the note-1. |
| 98 | 98 |
range.setEnd(document.querySelector('#change-1 .wiki > p').childNodes[0], 7);
|
| 99 | 99 | |