UNPKG

@vega/review-tool

Version:
128 lines (117 loc) 3.84 kB
// @flow import React from 'react' import styles from './styles/ReviewProcess.css' import {withPropsStream} from 'react-props-stream' import ArticleSnapshot from './ArticleSnapshot' import {distinctUntilChanged, map, switchMap} from 'rxjs/operators' import {combineLatest} from 'rxjs' import {debounce} from 'lodash' import {observePaths} from 'part:@lyra/base/preview' import {currentUser$} from 'part:@vega/datastores/user' import {WithUserRoles} from './withUserRoles' import ManageReviewProcess from './ManageReviewProcess' import EditReviewItem from './EditReviewItem' import observableWithQuery from '../util/observableWithQuery' function getListenReviewItemQuery(currentUserId) { return `*[_type == "reviewItem" && reviewer._ref == "${currentUserId}" && !(_id in path('drafts.**'))][0] {...,reviewer->{_id,name},reviewProcess->{_id}}` } function loadProps(props$) { const reviewProcessId$ = props$.pipe( map(props => props.reviewProcessId), distinctUntilChanged() ) const reviewProcess$ = reviewProcessId$.pipe( switchMap(reviewProcessId => observePaths({_id: reviewProcessId}, [ 'completedAt', 'article._id', 'articleSnapshot.title', 'articleSnapshot.abstract', 'articleSnapshot.content' ]) ) ) const reviewItem$ = currentUser$.pipe( switchMap(currentUser => observableWithQuery(getListenReviewItemQuery(currentUser._id)) ) ) return combineLatest(currentUser$, reviewProcess$, reviewItem$, props$).pipe( map(([currentUser, reviewProcess, reviewItem, props]) => { const matchingReviewItem = reviewProcess._id === reviewItem.reviewProcess._id ? reviewItem : null return { currentUser, reviewProcess, reviewItem: matchingReviewItem, highlightedPointerKey: props.highlightedPointerKey } }) ) } class ReviewProcess extends React.Component<*> { componentDidUpdate() { const {highlightedPointerKey} = this.props if (highlightedPointerKey) { this.scrollPointerIntoView(highlightedPointerKey) } } scrollPointerIntoView = debounce(highlightedPointerKey => { const elm = document.getElementById(highlightedPointerKey) if (elm) { window.requestAnimationFrame(() => { elm.scrollIntoView({behavior: 'smooth', block: 'center'}) }) } }, 100) renderRole = roles => { const {reviewProcess, currentUser, reviewItem} = this.props if (roles.includes('admin')) { return <ManageReviewProcess reviewProcess={reviewProcess} /> } if (roles.includes('editor')) { return <ManageReviewProcess reviewProcess={reviewProcess} /> } if (roles.includes('reviewer')) { return ( <div> <EditReviewItem reviewItem={reviewItem} reviewer={currentUser} readOnly={Boolean(reviewItem.completedAt)} /> {Boolean(reviewItem.completedAt) && ( <div className={styles.thankYou}> <h2>Review completed</h2> <p>Thank you for the review.</p> </div> )} </div> ) } return `Unknown role: ${roles}` } render() { const {reviewProcess, highlightedPointerKey} = this.props return ( <div className={styles.root}> <div className={styles.leftPane}> <ArticleSnapshot snapshot={reviewProcess.articleSnapshot} highlightedPointerKey={highlightedPointerKey} /> </div> <div className={styles.rightPane}> <WithUserRoles subjectType="article" subjectId={reviewProcess.article._id} > {this.renderRole} </WithUserRoles> </div> </div> ) } } export default withPropsStream(loadProps, ReviewProcess)