Commit b897f578 authored by Kyle Keating's avatar Kyle Keating Committed by Kyle Keating

Improve typechecking

- add props for annotation-action-bar
- add props for annotation-document-info
- dependency fixes:
  - add selector types for groups stores
  - fixup errors discovered in annotation-share-control
  - fixup errors in util/permissions
parent 8493d07d
...@@ -10,9 +10,24 @@ import { withServices } from '../util/service-context'; ...@@ -10,9 +10,24 @@ import { withServices } from '../util/service-context';
import AnnotationShareControl from './annotation-share-control'; import AnnotationShareControl from './annotation-share-control';
import Button from './button'; import Button from './button';
/** @typedef {import("../../types/api").Annotation} Annotation */
/** @typedef {import('../../types/config').HostConfig} HostConfig */
/**
* @typedef AnnotationActionBarProps
* @prop {Annotation} annotation - The annotation in question
* @prop {() => any} onReply - Callbacks for when action buttons are clicked/tapped
* @prop {Object} annotationsService
* @prop {HostConfig} settings
* @prop {Object} toastMessenger
*/
/** /**
* A collection of `Button`s in the footer area of an annotation that take * A collection of `Button`s in the footer area of an annotation that take
* actions on the annotation. * actions on the annotation.
*
* @param {AnnotationActionBarProps} props
*/ */
function AnnotationActionBar({ function AnnotationActionBar({
annotation, annotation,
...@@ -67,12 +82,12 @@ function AnnotationActionBar({ ...@@ -67,12 +82,12 @@ function AnnotationActionBar({
.catch(() => toastMessenger.error('Flagging annotation failed')); .catch(() => toastMessenger.error('Flagging annotation failed'));
}; };
const onReplyClick = event => { const onReplyClick = () => {
if (!isLoggedIn) { if (!isLoggedIn) {
openSidebarPanel(uiConstants.PANEL_LOGIN_PROMPT); openSidebarPanel(uiConstants.PANEL_LOGIN_PROMPT);
return; return;
} }
onReply(event); onReply();
}; };
return ( return (
...@@ -109,10 +124,7 @@ function AnnotationActionBar({ ...@@ -109,10 +124,7 @@ function AnnotationActionBar({
AnnotationActionBar.propTypes = { AnnotationActionBar.propTypes = {
annotation: propTypes.object.isRequired, annotation: propTypes.object.isRequired,
/** Callbacks for when action buttons are clicked/tapped */
onReply: propTypes.func.isRequired, onReply: propTypes.func.isRequired,
// Injected services
annotationsService: propTypes.object.isRequired, annotationsService: propTypes.object.isRequired,
settings: propTypes.object.isRequired, settings: propTypes.object.isRequired,
toastMessenger: propTypes.object.isRequired, toastMessenger: propTypes.object.isRequired,
......
...@@ -3,9 +3,18 @@ import propTypes from 'prop-types'; ...@@ -3,9 +3,18 @@ import propTypes from 'prop-types';
import * as annotationMetadata from '../util/annotation-metadata'; import * as annotationMetadata from '../util/annotation-metadata';
/** @typedef {import("../../types/api").Annotation} Annotation */
/**
* @typedef AnnotationDocumentInfoProps
* @prop {Annotation} annotation - Annotation for which the document metadata will be rendered
*/
/** /**
* Render some metadata about an annotation's document and link to it * Render some metadata about an annotation's document and link to it
* if a link is available. * if a link is available.
*
* @param {AnnotationDocumentInfoProps} props
*/ */
export default function AnnotationDocumentInfo({ annotation }) { export default function AnnotationDocumentInfo({ annotation }) {
const documentInfo = annotationMetadata.domainAndTitle(annotation); const documentInfo = annotationMetadata.domainAndTitle(annotation);
...@@ -35,6 +44,5 @@ export default function AnnotationDocumentInfo({ annotation }) { ...@@ -35,6 +44,5 @@ export default function AnnotationDocumentInfo({ annotation }) {
} }
AnnotationDocumentInfo.propTypes = { AnnotationDocumentInfo.propTypes = {
/* Annotation for which the document metadata will be rendered */
annotation: propTypes.object.isRequired, annotation: propTypes.object.isRequired,
}; };
...@@ -21,12 +21,9 @@ function AnnotationShareControl({ ...@@ -21,12 +21,9 @@ function AnnotationShareControl({
group, group,
shareUri, shareUri,
}) { }) {
const annotationIsPrivate = isPrivate( const annotationIsPrivate = isPrivate(annotation.permissions);
annotation.permissions, const shareRef = useRef(/** @type {HTMLDivElement|null} */ (null));
annotation.user const inputRef = useRef(/** @type {HTMLInputElement|null} */ (null));
);
const shareRef = useRef();
const inputRef = useRef();
const [isOpen, setOpen] = useState(false); const [isOpen, setOpen] = useState(false);
const wasOpen = useRef(isOpen); const wasOpen = useRef(isOpen);
......
...@@ -206,7 +206,6 @@ const getCurrentlyViewingGroups = createSelector( ...@@ -206,7 +206,6 @@ const getCurrentlyViewingGroups = createSelector(
* *
* // Selectors * // Selectors
* @prop {() => Group[]} allGroups * @prop {() => Group[]} allGroups
* @prop {() => Group[]} allGroups
* @prop {() => Group|undefined|null} focusedGroup * @prop {() => Group|undefined|null} focusedGroup
* @prop {() => string|null} focusedGroupId * @prop {() => string|null} focusedGroupId
* @prop {() => Group[]} getFeaturedGroups * @prop {() => Group[]} getFeaturedGroups
......
...@@ -98,9 +98,9 @@ export function isPrivate(perms) { ...@@ -98,9 +98,9 @@ export function isPrivate(perms) {
* *
* @param {Permissions} perms * @param {Permissions} perms
* @param {'update'|'delete'} action * @param {'update'|'delete'} action
* @param {string} userid * @param {string|null} userid
* @return {boolean} * @return {boolean}
*/ */
export function permits(perms, action, userid) { export function permits(perms, action, userid) {
return perms[action].indexOf(userid) !== -1; return perms[action].indexOf(userid || '') !== -1;
} }
...@@ -93,5 +93,10 @@ describe('sidebar/util/permissions', () => { ...@@ -93,5 +93,10 @@ describe('sidebar/util/permissions', () => {
assert.isFalse(permissions.permits(perms, 'update', userid)); assert.isFalse(permissions.permits(perms, 'update', userid));
assert.isFalse(permissions.permits(perms, 'delete', userid)); assert.isFalse(permissions.permits(perms, 'delete', userid));
}); });
it('returns false if the userid is null', () => {
const perms = permissions.privatePermissions(userid);
assert.isFalse(permissions.permits(perms, 'update', null));
});
}); });
}); });
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
// Files in `src/sidebar/components` that may still have errors. // Files in `src/sidebar/components` that may still have errors.
// Remove them from this list as they are resolved. // Remove them from this list as they are resolved.
"sidebar/components/hooks/use-root-thread.js", "sidebar/components/hooks/use-root-thread.js",
"sidebar/components/annotation-action-bar.js",
"sidebar/components/annotation-header.js", "sidebar/components/annotation-header.js",
"sidebar/components/annotation-publish-control.js", "sidebar/components/annotation-publish-control.js",
"sidebar/components/annotation-quote.js", "sidebar/components/annotation-quote.js",
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
* that have not been saved to the service yet (and thus do not have an id) * that have not been saved to the service yet (and thus do not have an id)
* @prop {string[]} [references] * @prop {string[]} [references]
* @prop {string} created * @prop {string} created
* @prop {boolean} [flagged]
* @prop {string} group * @prop {string} group
* @prop {string} updated * @prop {string} updated
* @prop {string[]} tags * @prop {string[]} tags
......
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