mirror of
https://github.com/redmine/redmine.git
synced 2025-11-02 19:36:00 +01:00
Add a sticky issue header to issue page (#42684).
Patch by Mizuki ISHIKAWA (user:ishikawa999). git-svn-id: https://svn.redmine.org/redmine/trunk@23752 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -680,6 +680,36 @@ div.issue .attribute.string_cf .value .wiki p {margin-top: 0; margin-bottom: 0;}
|
||||
div.issue .attribute.text_cf .value .wiki p:first-of-type {margin-top: 0;}
|
||||
div.issue.overdue .due-date .value { color: #c22; }
|
||||
body.controller-issues h2.inline-flex {padding-right: 0}
|
||||
div#sticky-issue-header {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: white;
|
||||
border-bottom: 1px solid #d0d7de;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
|
||||
font-size: 0.8125rem;
|
||||
align-items: center;
|
||||
z-index: 1000;
|
||||
padding: 10px 6px;
|
||||
border-radius: 0px;
|
||||
}
|
||||
div#sticky-issue-header.is-visible {
|
||||
display: flex;
|
||||
}
|
||||
div#sticky-issue-header .issue-heading {
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
margin-right: 6px;
|
||||
}
|
||||
div#sticky-issue-header .subject {
|
||||
font-weight: bold;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#issue_tree table.issues, #relations table.issues {border: 0;}
|
||||
#issue_tree table.issues td, #relations table.issues td {border: 0;}
|
||||
|
||||
@@ -848,6 +848,12 @@
|
||||
font-size: 1.1em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Sticky issue header */
|
||||
/* When project-jump.drdn is visible in mobile layout, offset the sticky header by its height to prevent it from being hidden. */
|
||||
div#sticky-issue-header {
|
||||
top: 64px;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 599px) {
|
||||
|
||||
22
app/javascript/controllers/sticky_issue_header_controller.js
Normal file
22
app/javascript/controllers/sticky_issue_header_controller.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Controller } from "@hotwired/stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["original", "stickyHeader"];
|
||||
|
||||
connect() {
|
||||
if (!this.originalTarget || !this.stickyHeaderTarget) return;
|
||||
|
||||
this.observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
this.stickyHeaderTarget.classList.toggle("is-visible", !entry.isIntersecting);
|
||||
},
|
||||
{ threshold: 0 }
|
||||
);
|
||||
|
||||
this.observer.observe(this.originalTarget);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.observer?.disconnect();
|
||||
}
|
||||
}
|
||||
@@ -37,9 +37,16 @@
|
||||
<%= assignee_avatar(@issue.assigned_to, :size => "22", :class => "gravatar-child") if @issue.assigned_to %>
|
||||
</div>
|
||||
|
||||
<div class="subject">
|
||||
<%= render_issue_subject_with_tree(@issue) %>
|
||||
<div data-controller="sticky-issue-header">
|
||||
<div class="subject" data-sticky-issue-header-target="original">
|
||||
<%= render_issue_subject_with_tree(@issue) %>
|
||||
</div>
|
||||
<div id="sticky-issue-header" data-sticky-issue-header-target="stickyHeader" class="issue">
|
||||
<span class="issue-heading"><%= issue_heading(@issue) %>:</span>
|
||||
<span class="subject"><%= @issue.subject %></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="author">
|
||||
<%= authoring @issue.created_on, @issue.author %>.
|
||||
<% if @issue.created_on != @issue.updated_on %>
|
||||
|
||||
38
test/system/sticky_issue_header_test.rb
Normal file
38
test/system/sticky_issue_header_test.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006- Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
require_relative '../application_system_test_case'
|
||||
class StickyIssueHeaderSystemTest < ApplicationSystemTestCase
|
||||
test "sticky issue header is hidden by default" do
|
||||
issue = Issue.find(1)
|
||||
visit issue_path(issue)
|
||||
|
||||
assert_no_selector "#sticky-issue-header", text: issue.subject
|
||||
end
|
||||
|
||||
test "sticky issue header appears on scroll" do
|
||||
issue = Issue.find(2)
|
||||
visit issue_path(issue)
|
||||
|
||||
page.execute_script("window.scrollTo(0, 1000)")
|
||||
assert_selector "#sticky-issue-header.is-visible", text: issue.subject
|
||||
|
||||
page.execute_script("window.scrollTo(0, 0)")
|
||||
assert_no_selector "#sticky-issue-header", text: issue.subject
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user