Skip to content
This repository has been archived by the owner on Apr 29, 2022. It is now read-only.

Commit

Permalink
rewire UI to latest proposal #11
Browse files Browse the repository at this point in the history
  • Loading branch information
sballesteros committed Nov 18, 2019
1 parent 6f60bae commit 3d0cec3
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 75 deletions.
2 changes: 1 addition & 1 deletion src/components/moderation-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function ModerationModal({
ref={ref}
id="moderation-reason"
name="moderationReason"
rows="2"
rows="4"
/>

<Controls error={moderationProgress.error}>
Expand Down
1 change: 1 addition & 0 deletions src/components/preprint-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ export default function PreprintCard({
<Collapse isOpened={isOpened} className="preprint-card__collapse">
<div className="preprint-card-expansion">
<ReviewReader
user={user}
identifier={preprint.doi || preprint.arXivId}
actions={reviews}
preview={true}
Expand Down
13 changes: 8 additions & 5 deletions src/components/review-reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@ import { MdInfoOutline } from 'react-icons/md';
import classNames from 'classnames';
import Barplot from './barplot';
import { getId } from '../utils/jsonld';
import { getYesNoStats, getTextAnswers } from '../utils/stats';
import { getYesNoStats } from '../utils/stats';
import TextAnswers from './text-answers';
import { PotentialRoles, HighlightedRoles } from './role-list';
import ShareMenu from './share-menu';

const ReviewReader = React.memo(function ReviewReader({
user,
role,
preview,
identifier,
actions,
nRequests,
defaultHighlightedRoleIds,
onHighlighedRoleIdsChange = noop,
isModerationInProgress,
canModerate,
onModerate
}) {
const [highlightedRoleIds, setHighlightedRoleIds] = useState(
Expand Down Expand Up @@ -118,9 +119,10 @@ const ReviewReader = React.memo(function ReviewReader({

{!preview && (
<TextAnswers
answers={getTextAnswers(highlightedActions)}
user={user}
role={role}
actions={highlightedActions}
isModerationInProgress={isModerationInProgress}
canModerate={canModerate}
onModerate={onModerate}
/>
)}
Expand All @@ -131,6 +133,8 @@ const ReviewReader = React.memo(function ReviewReader({
});

ReviewReader.propTypes = {
user: PropTypes.object,
role: PropTypes.object,
preview: PropTypes.bool,
identifier: PropTypes.string.isRequired, // DOI or arXivID
onHighlighedRoleIdsChange: PropTypes.func,
Expand All @@ -152,7 +156,6 @@ ReviewReader.propTypes = {
).isRequired,
nRequests: PropTypes.number,
defaultHighlightedRoleIds: PropTypes.arrayOf(PropTypes.string),
canModerate: PropTypes.bool,
isModerationInProgress: PropTypes.bool,
onModerate: PropTypes.func
};
Expand Down
26 changes: 12 additions & 14 deletions src/components/shell-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ function ShellContentRead({ user, preprint, actions, fetchActionsProgress }) {

const location = useLocation();
const history = useHistory();
const [moderation, setModeration] = useState(null);
const [moderatedReviewId, setModeratedReviewId] = useState(null);
const [post, postProgress, resetPostState] = usePostAction();
const [role, fetchRoleProgress] = useRole(user && user.defaultRole);

Expand Down Expand Up @@ -273,11 +273,12 @@ function ShellContentRead({ user, preprint, actions, fetchActionsProgress }) {

{!fetchActionsProgress.isActive && (
<ReviewReader
user={user}
role={role}
isModerationInProgress={postProgress.isActive}
canModerate={role && role.isModerator}
onModerate={(type, object) => {
onModerate={reportedActionId => {
resetPostState();
setModeration({ type, object });
setModeratedReviewId(reportedActionId);
}}
onHighlighedRoleIdsChange={roleIds => {
if (process.env.IS_EXTENSION) {
Expand Down Expand Up @@ -310,29 +311,26 @@ function ShellContentRead({ user, preprint, actions, fetchActionsProgress }) {
/>
)}

{!!moderation && (
{!!moderatedReviewId && (
<ModerationModal
title={`Moderate ${moderation.type}`}
title={`Report review as violating the Code of Conduct`}
moderationProgress={postProgress}
onSubmit={moderationReason => {
post(
cleanup({
'@type':
moderation.type === 'role'
? 'ModerateRoleAction'
: 'ModerateRapidPREReviewAction',
'@type': 'ReportRapidPREreviewAction',
agent: user.defaultRole,
actionStatus: 'CompletedActionStatus',
object: moderation.object,
object: moderatedReviewId,
moderationReason
}),
() => {
setModeration(null);
body => {
setModeratedReviewId(null);
}
);
}}
onCancel={() => {
setModeration(null);
setModeratedReviewId(null);
}}
/>
)}
Expand Down
91 changes: 54 additions & 37 deletions src/components/text-answers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,22 @@ import PropTypes from 'prop-types';
import { MenuItem } from '@reach/menu-button';
import Value from './value';
import RoleBadge from './role-badge';
import { getId, arrayify } from '../utils/jsonld';
import { getTextAnswers } from '../utils/stats';

export default function TextAnswers({
answers,
canModerate,
user,
role,
actions,
isModerationInProgress,
onModerate
}) {
const answers = getTextAnswers(actions);

const isLoggedIn = !!user;

console.log(actions);

return (
<div className="text-answers">
<dl>
Expand All @@ -18,36 +27,37 @@ export default function TextAnswers({
<dt className="text-answers__question">
<Value tagName="span">{question}</Value>
</dt>
{answers.map(({ actionId, roleId, text }) => (
<dd className="text-answers__response-row" key={roleId}>
<div className="text-answers__user-badge-container">
<RoleBadge roleId={roleId}>
{!!canModerate && (
<MenuItem
disabled={isModerationInProgress}
onSelect={() => {
onModerate('role', roleId);
}}
>
Report Author
</MenuItem>
)}
{!!canModerate && (
<MenuItem
disabled={isModerationInProgress}
onSelect={() => {
onModerate('review', actionId);
}}
>
Report Author’s Review
</MenuItem>
)}
</RoleBadge>
</div>
{answers.map(({ actionId, roleId, text }) => {
const action = actions.find(action => getId(action) === actionId);
return (
<dd className="text-answers__response-row" key={roleId}>
<div className="text-answers__user-badge-container">
<RoleBadge roleId={roleId}>
{isLoggedIn && (
<MenuItem
disabled={
isModerationInProgress ||
arrayify(action.moderationAction).some(
action =>
action['@type'] ===
'ReportRapidPREreviewAction' &&
getId(action.agent) === getId(role)
)
}
onSelect={() => {
onModerate(actionId);
}}
>
Report Author’s Review
</MenuItem>
)}
</RoleBadge>
</div>

<Value className="text-answers__response">{text}</Value>
</dd>
))}
<Value className="text-answers__response">{text}</Value>
</dd>
);
})}
</div>
))}
</dl>
Expand All @@ -56,18 +66,25 @@ export default function TextAnswers({
}

TextAnswers.propTypes = {
answers: PropTypes.arrayOf(
user: PropTypes.object,
role: PropTypes.object,
actions: PropTypes.arrayOf(
PropTypes.shape({
questionId: PropTypes.string.isRequired,
question: PropTypes.string.isRequired,
answers: PropTypes.arrayOf(
'@type': PropTypes.oneOf(['RapidPREreviewAction']).isRequired,
actionStatus: PropTypes.oneOf(['CompletedActionStatus']).isRequired,
agent: PropTypes.string.isRequired,
moderationAction: PropTypes.arrayOf(
PropTypes.shape({
roleId: PropTypes.string.isRequired,
text: PropTypes.string.isRequired
'@type': PropTypes.oneOf([
// !! `ModerateRapidPREreviewAction` cannot be present reviews with it must be excluded upstream
'ReportRapidPREreviewAction',
'IgnoreReportRapidPREreviewAction'
]).isRequired
})
)
})
).isRequired,
canBan: PropTypes.bool,
canModerate: PropTypes.bool,
isModerationInProgress: PropTypes.bool,
onModerate: PropTypes.func
Expand Down
57 changes: 43 additions & 14 deletions src/components/text-answers.stories.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,53 @@
import React from 'react';
import faker from 'faker';
import sample from 'lodash/sample';
import { BrowserRouter as Router } from 'react-router-dom';
import TextAnswers from './text-answers';
import { QUESTIONS } from '../constants';
import { StoresProvider } from '../contexts/store-context';
import { RoleStore } from '../stores/user-stores';

export default { title: 'TextAnswers' };

export function Random() {
const roleIds = ['role:role1', 'role:role2'];
const roleStore = new RoleStore();

const answers = QUESTIONS.filter(({ type }) => {
return type === 'Question';
}).map(({ question, identifier }) => {
return {
questionId: `question:${identifier}`,
question,
answers: roleIds.map(roleId => {
return { roleId, text: faker.lorem.paragraph() };
})
};
});
export function Random() {
const actions = ['role:roleId1', 'role:roleId2', 'role:roleId3'].map(
roleId => {
return {
'@type': 'RapidPREreviewAction',
agent: roleId,
actionStatus: 'CompletedActionStatus',
object: 'doi:doi',
resultReview: {
'@type': 'RapidPREreview',
about: [
{
'@type': 'OutbreakScienceEntity',
name: sample(['Influenza', 'Dengue', 'Zika'])
}
],
reviewAnswer: QUESTIONS.map(question => {
return {
'@type':
question.type === 'YesNoQuestion' ? 'YesNoAnswer' : 'Answer',
parentItem: `question:${question.identifier}`,
text:
question.type === 'YesNoQuestion'
? sample(['yes', 'no', 'n.a.', 'unsure'])
: faker.lorem.paragraph()
};
})
}
};
}
);

return <TextAnswers answers={answers} />;
return (
<Router>
<StoresProvider roleStore={roleStore}>
<TextAnswers actions={actions} />
</StoresProvider>
</Router>
);
}
2 changes: 2 additions & 0 deletions src/db/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ export default class DB {
}

// potential action: we merge all distincts
// TODO handle `moderationAction`
merged.potentialAction = uniqBy(
arrayify(merged.potentialAction).concat(
arrayify(doc.potentialAction)
Expand All @@ -486,6 +487,7 @@ export default class DB {
});
}

// TODO handle `moderationAction`
if (
!merged.potentialAction.some(
_action => getId(_action) === getId(action)
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/api-hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export function usePostAction() {

if (body['@type'] === 'UpdateUserAction') {
setUser(body.result);
} else if (body['@type'] === 'ModerateRapidPREReviewAction') {
} else if (body['@type'] === 'ModerateRapidPREreviewAction') {
preprintsSearchResultsStore.reset();
}

Expand Down
6 changes: 4 additions & 2 deletions src/middlewares/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,12 @@ export function invalidate() {
break;
}

case 'ModerateRapidPREReviewAction':
case 'ReportRapidPREreviewAction':
case 'IgnoreReportRapidPREreviewAction':
case 'ModerateRapidPREreviewAction':
case 'RequestForRapidPREreviewAction':
case 'RapidPREreviewAction': {
if (action['@type'] === 'ModerateRapidPREReviewAction') {
if (action['@type'] === 'ModerateRapidPREreviewAction') {
action = action.result;
}

Expand Down
6 changes: 5 additions & 1 deletion src/stores/preprint-stores.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ export class PreprintsWithActionsStore extends EventEmitter {
}

upsertAction(action) {
if (action['@type'] === 'ModerateRapidPREReviewAction') {
if (
action['@type'] === 'ModerateRapidPREreviewAction' ||
action['@type'] === 'ReportRapidPREreviewAction' ||
action['@type'] === 'IgnoreReportRapidPREreviewAction'
) {
action = action.result;
}

Expand Down
5 changes: 5 additions & 0 deletions src/utils/preprints.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ export function dehydrateAction(action) {
);
break;

case 'moderationAction':
// TODO
// only keep ModerateRapidPREreviewAction ?
break;

default:
compacted[key] = action[key];
break;
Expand Down

0 comments on commit 3d0cec3

Please sign in to comment.