Commit b1cf68f2 authored by Lyza Danger Gardner's avatar Lyza Danger Gardner

Remove `onReplyCountClick` prop and use store method instead

Let `AnnotationHeader` call `store.setCollapsed` directly instead of
passing a callback down through several layers of components
parent 7032092c
import { createElement } from 'preact';
import propTypes from 'prop-types';
import useStore from '../store/use-store';
import { isHighlight, isReply } from '../util/annotation-metadata';
import { isPrivate } from '../util/permissions';
......@@ -19,12 +20,13 @@ import Timestamp from './timestamp';
export default function AnnotationHeader({
annotation,
isEditing,
onReplyCountClick,
replyCount,
showDocumentInfo,
threadIsCollapsed,
}) {
const isCollapsedReply = isReply(annotation) && threadIsCollapsed;
const setCollapsed = useStore(store => store.setCollapsed);
const annotationIsPrivate = isPrivate(
annotation.permissions,
annotation.user
......@@ -34,7 +36,7 @@ export default function AnnotationHeader({
// NB: `created` and `updated` are strings, not `Date`s
const hasBeenEdited =
annotation.updated && annotation.created !== annotation.updated;
const showTimestamp = !isEditing;
const showTimestamp = !isEditing && annotation.created;
const showEditedTimestamp = hasBeenEdited && !isCollapsedReply;
const replyPluralized = replyCount > 1 ? 'replies' : 'reply';
......@@ -42,6 +44,8 @@ export default function AnnotationHeader({
const showReplyButton = replyCount > 0 && isCollapsedReply;
const showExtendedInfo = !isReply(annotation);
const onReplyCountClick = () => setCollapsed(annotation.id, false);
return (
<header className="annotation-header">
<div className="annotation-header__row">
......@@ -112,8 +116,6 @@ AnnotationHeader.propTypes = {
annotation: propTypes.object.isRequired,
/* Whether the annotation is actively being edited */
isEditing: propTypes.bool,
/* Callback for when the toggle-replies element is clicked */
onReplyCountClick: propTypes.func.isRequired,
/* How many replies this annotation currently has */
replyCount: propTypes.number,
/**
......
......@@ -22,7 +22,6 @@ import Button from './button';
function Annotation({
annotation,
annotationsService,
onReplyCountClick,
replyCount,
showDocumentInfo,
threadIsCollapsed,
......@@ -101,7 +100,6 @@ function Annotation({
<AnnotationHeader
annotation={annotation}
isEditing={isEditing}
onReplyCountClick={onReplyCountClick}
replyCount={replyCount}
showDocumentInfo={showDocumentInfo}
threadIsCollapsed={threadIsCollapsed}
......@@ -159,8 +157,6 @@ function Annotation({
Annotation.propTypes = {
annotation: propTypes.object.isRequired,
/** Callback for reply-count clicks */
onReplyCountClick: propTypes.func.isRequired,
/** Number of replies to this annotation (thread) */
replyCount: propTypes.number.isRequired,
/** Should extended document info be rendered (e.g. in non-sidebar contexts)? */
......
......@@ -12,13 +12,13 @@ describe('AnnotationHeader', () => {
let fakeIsHighlight;
let fakeIsReply;
let fakeIsPrivate;
let fakeStore;
const createAnnotationHeader = props => {
return mount(
<AnnotationHeader
annotation={fixtures.defaultAnnotation()}
isEditing={false}
onReplyCountClick={sinon.stub()}
replyCount={0}
showDocumentInfo={false}
threadIsCollapsed={false}
......@@ -32,8 +32,13 @@ describe('AnnotationHeader', () => {
fakeIsReply = sinon.stub().returns(false);
fakeIsPrivate = sinon.stub();
fakeStore = {
setCollapsed: sinon.stub(),
};
$imports.$mock(mockImportedComponents());
$imports.$mock({
'../store/use-store': callback => callback(fakeStore),
'../util/annotation-metadata': {
isHighlight: fakeIsHighlight,
isReply: fakeIsReply,
......@@ -70,17 +75,30 @@ describe('AnnotationHeader', () => {
wrapper.find('Button').filter('.annotation-header__reply-toggle');
it('should render if annotation is a collapsed reply and there are replies to show', () => {
let fakeCallback = sinon.stub();
fakeIsReply.returns(true);
const wrapper = createAnnotationHeader({
onReplyCountClick: fakeCallback,
replyCount: 1,
threadIsCollapsed: true,
});
const btn = findReplyButton(wrapper);
assert.isTrue(btn.exists());
assert.equal(btn.props().onClick, fakeCallback);
});
it('should expand replies when clicked', () => {
fakeIsReply.returns(true);
const fakeAnnotation = fixtures.defaultAnnotation();
const wrapper = createAnnotationHeader({
annotation: fakeAnnotation,
replyCount: 1,
threadIsCollapsed: true,
});
const btn = findReplyButton(wrapper);
btn.props().onClick();
assert.calledOnce(fakeStore.setCollapsed);
assert.calledWith(fakeStore.setCollapsed, fakeAnnotation.id, false);
});
it('should not render if there are no replies to show', () => {
......
......@@ -12,8 +12,6 @@ import Annotation from '../annotation';
import { $imports } from '../annotation';
describe('Annotation', () => {
let fakeOnReplyCountClick;
// Dependency Mocks
let fakeMetadata;
let fakePermissions;
......@@ -38,7 +36,6 @@ describe('Annotation', () => {
annotation={fixtures.defaultAnnotation()}
annotationsService={fakeAnnotationsService}
toastMessenger={fakeToastMessenger}
onReplyCountClick={fakeOnReplyCountClick}
replyCount={0}
showDocumentInfo={false}
threadIsCollapsed={true}
......@@ -48,8 +45,6 @@ describe('Annotation', () => {
};
beforeEach(() => {
fakeOnReplyCountClick = sinon.stub();
fakeAnnotationsService = {
reply: sinon.stub(),
save: sinon.stub().resolves(),
......
......@@ -66,7 +66,6 @@ function Thread({ showDocumentInfo = false, thread, threadsService }) {
<Annotation
annotation={thread.annotation}
replyCount={thread.replyCount}
onReplyCountClick={onToggleReplies}
showDocumentInfo={showDocumentInfo}
threadIsCollapsed={thread.collapsed}
/>
......
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