Commit fcfde74a authored by Eduardo Sanz García's avatar Eduardo Sanz García Committed by Eduardo

Display the annotation header on the top-level annotation

This PR ensures that the annotation header is always shown, even if the
top-level annotation is hidden by a filter. The annotation header
contains the document target. This information is specially important in
the context of the notebook, where annotations from different documents
are displayed together.

I created a wrapper around the `AnnotationHeader` component. I couldn't
use it directly because I needed a couple of methods from the store to
mimic 100% the same behaviour as when `AnnotationHeader` is called
through `Annotation` component.
parent cf22b700
......@@ -7,6 +7,7 @@ import { withServices } from '../service-context';
import { countHidden, countVisible } from '../helpers/thread';
import Annotation from './Annotation';
import AnnotationHeader from './Annotation/AnnotationHeader';
import ModerationBanner from './ModerationBanner';
/** @typedef {import('../helpers/build-thread').Thread} Thread */
......@@ -108,11 +109,22 @@ function Thread({ thread, threadsService }) {
{annotationContent}
{showHiddenToggle && (
<div className="Thread__hidden-toggle-button-container">
<LabeledButton onClick={() => threadsService.forceVisible(thread)}>
Show {countHidden(thread)} more in conversation
</LabeledButton>
</div>
<>
{!thread.parent && (
<ThreadHeader
annotation={thread.annotation}
replyCount={thread.replyCount}
threadIsCollapsed={thread.collapsed}
/>
)}
<div className="Thread__hidden-toggle-button-container">
<LabeledButton
onClick={() => threadsService.forceVisible(thread)}
>
Show {countHidden(thread)} more in conversation
</LabeledButton>
</div>
</>
)}
{showChildren && (
......@@ -129,4 +141,36 @@ function Thread({ thread, threadsService }) {
);
}
/**
* This wrapper around AnnotationHeader is to show the document target on the
* top-level annotation (if such exists).
*
* @param {object} props
* @param {Thread['annotation']} props.annotation
* @param {number} props.replyCount
* @param {boolean} props.threadIsCollapsed
*/
function ThreadHeader({ annotation, ...restProps }) {
const store = useStoreProxy();
// These two lines are copied from the AnnotationHeader component to mimic the
// exact same behaviour.
const isSaving = annotation && store.isSavingAnnotation(annotation);
const isEditing = annotation && !!store.getDraft(annotation) && !isSaving;
if (!annotation) {
return null;
}
return (
<div className="Thread__top-annotation-header">
<AnnotationHeader
annotation={annotation}
isEditing={isEditing}
{...restProps}
/>
</div>
);
}
export default withServices(Thread, ['threadsService']);
......@@ -81,6 +81,8 @@ describe('Thread', () => {
fakeStore = {
hasAppliedFilter: sinon.stub().returns(false),
setExpanded: sinon.stub(),
isSavingAnnotation: sinon.stub().returns(false),
getDraft: sinon.stub().returns(false),
};
fakeThreadsService = {
......@@ -239,6 +241,29 @@ describe('Thread', () => {
assert.calledOnce(fakeThreadsService.forceVisible);
assert.calledWith(fakeThreadsService.forceVisible, thread);
});
it('shows the annotation header on a hidden top-level thread', () => {
const thread = createThread();
const wrapper = createComponent({ thread });
assert.isTrue(wrapper.find('ThreadHeader').exists());
});
it("doesn't show the annotation header if top-level annotation is missing", () => {
const thread = createThread();
thread.annotation = null;
const wrapper = createComponent({ thread });
assert.isTrue(wrapper.find('ThreadHeader').isEmptyRender());
});
it("doesn't show the annotation header if thread is a child", () => {
const thread = createThread();
thread.parent = {}; // child threads have a parent
const wrapper = createComponent({ thread });
assert.isFalse(wrapper.find('ThreadHeader').exists());
});
});
context('thread with child threads', () => {
......
......@@ -56,6 +56,12 @@
margin-top: -0.25em;
}
&__top-annotation-header {
// This disables the vertical alignment for the parent thread which contain
// an annotation header.
margin-bottom: 0.5em;
}
&__content {
flex-grow: 1;
// Prevent annotation content from overflowing the container
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment