Compare commits
4 Commits
inf-392
...
saad/hacka
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa236f96d8 | ||
|
|
ac117c75de | ||
|
|
37ee085253 | ||
|
|
f13b34c6c7 |
@@ -55,6 +55,8 @@ export const ContentActions = {
|
|||||||
CHANGE_TOPIC: 'topic_id',
|
CHANGE_TOPIC: 'topic_id',
|
||||||
CHANGE_TYPE: 'type',
|
CHANGE_TYPE: 'type',
|
||||||
VOTE: 'voted',
|
VOTE: 'voted',
|
||||||
|
ACCEPT_REVIEW: 'accept_review',
|
||||||
|
REJECT_REVIEW: 'reject_review',
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ function ActionsDropdown({
|
|||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="bg-white p-1 shadow d-flex flex-column"
|
className="bg-white shadow d-flex flex-column"
|
||||||
data-testid="actions-dropdown-modal-popup"
|
data-testid="actions-dropdown-modal-popup"
|
||||||
>
|
>
|
||||||
{actions.map(action => (
|
{actions.map(action => (
|
||||||
@@ -91,9 +91,15 @@ function ActionsDropdown({
|
|||||||
close();
|
close();
|
||||||
handleActions(action.action);
|
handleActions(action.action);
|
||||||
}}
|
}}
|
||||||
className="d-flex justify-content-start py-1.5 mr-4"
|
className="d-flex justify-content-start actions-dropdown-item"
|
||||||
>
|
>
|
||||||
<Icon src={action.icon} className="mr-1" /> {intl.formatMessage(action.label)}
|
<Icon
|
||||||
|
src={action.icon}
|
||||||
|
className="icon-size-24"
|
||||||
|
/>
|
||||||
|
<span className="font-weight-normal font-xl ml-2">
|
||||||
|
{intl.formatMessage(action.label)}
|
||||||
|
</span>
|
||||||
</Dropdown.Item>
|
</Dropdown.Item>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -26,6 +26,16 @@ const messages = defineMessages({
|
|||||||
defaultMessage: 'Unpin',
|
defaultMessage: 'Unpin',
|
||||||
description: 'Action to unpin a post',
|
description: 'Action to unpin a post',
|
||||||
},
|
},
|
||||||
|
acceptReview: {
|
||||||
|
id: 'discussions.actions.reviewAccept',
|
||||||
|
defaultMessage: 'Accept',
|
||||||
|
description: 'Action to accept content flagged for review',
|
||||||
|
},
|
||||||
|
rejectReview: {
|
||||||
|
id: 'discussions.actions.reviewReject',
|
||||||
|
defaultMessage: 'Decline',
|
||||||
|
description: 'Action to reject content flagged for review',
|
||||||
|
},
|
||||||
deleteAction: {
|
deleteAction: {
|
||||||
id: 'discussions.actions.delete',
|
id: 'discussions.actions.delete',
|
||||||
defaultMessage: 'Delete',
|
defaultMessage: 'Delete',
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ export async function updateThread(threadId, {
|
|||||||
pinned,
|
pinned,
|
||||||
editReasonCode,
|
editReasonCode,
|
||||||
closeReasonCode,
|
closeReasonCode,
|
||||||
|
reviewStatus,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
const url = `${getThreadsApiUrl()}${threadId}/`;
|
const url = `${getThreadsApiUrl()}${threadId}/`;
|
||||||
const patchData = snakeCaseObject({
|
const patchData = snakeCaseObject({
|
||||||
@@ -166,6 +167,7 @@ export async function updateThread(threadId, {
|
|||||||
pinned,
|
pinned,
|
||||||
editReasonCode,
|
editReasonCode,
|
||||||
closeReasonCode,
|
closeReasonCode,
|
||||||
|
reviewStatus,
|
||||||
});
|
});
|
||||||
const { data } = await getAuthenticatedHttpClient()
|
const { data } = await getAuthenticatedHttpClient()
|
||||||
.patch(url, patchData, { headers: { 'Content-Type': 'application/merge-patch+json' } });
|
.patch(url, patchData, { headers: { 'Content-Type': 'application/merge-patch+json' } });
|
||||||
|
|||||||
@@ -239,6 +239,7 @@ export function createNewThread({
|
|||||||
|
|
||||||
export function updateExistingThread(threadId, {
|
export function updateExistingThread(threadId, {
|
||||||
flagged, voted, read, topicId, type, title, content, following, closed, pinned, closeReasonCode, editReasonCode,
|
flagged, voted, read, topicId, type, title, content, following, closed, pinned, closeReasonCode, editReasonCode,
|
||||||
|
reviewStatus,
|
||||||
}) {
|
}) {
|
||||||
return async (dispatch) => {
|
return async (dispatch) => {
|
||||||
try {
|
try {
|
||||||
@@ -256,6 +257,7 @@ export function updateExistingThread(threadId, {
|
|||||||
pinned,
|
pinned,
|
||||||
editReasonCode,
|
editReasonCode,
|
||||||
closeReasonCode,
|
closeReasonCode,
|
||||||
|
reviewStatus,
|
||||||
}));
|
}));
|
||||||
const data = await updateThread(threadId, {
|
const data = await updateThread(threadId, {
|
||||||
flagged,
|
flagged,
|
||||||
@@ -270,6 +272,7 @@ export function updateExistingThread(threadId, {
|
|||||||
pinned,
|
pinned,
|
||||||
editReasonCode,
|
editReasonCode,
|
||||||
closeReasonCode,
|
closeReasonCode,
|
||||||
|
reviewStatus,
|
||||||
});
|
});
|
||||||
dispatch(updateThreadSuccess(camelCaseObject(data)));
|
dispatch(updateThreadSuccess(camelCaseObject(data)));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ function Post({
|
|||||||
const userHasModerationPrivileges = useSelector(selectUserHasModerationPrivileges);
|
const userHasModerationPrivileges = useSelector(selectUserHasModerationPrivileges);
|
||||||
const displayPostFooter = post.following || post.voteCount || post.closed
|
const displayPostFooter = post.following || post.voteCount || post.closed
|
||||||
|| (post.groupId && userHasModerationPrivileges);
|
|| (post.groupId && userHasModerationPrivileges);
|
||||||
|
const displayReviewContentLabel = post.reviewStatus === "PENDING";
|
||||||
|
|
||||||
const handleAbusedFlag = useCallback(() => {
|
const handleAbusedFlag = useCallback(() => {
|
||||||
if (post.abuseFlagged) {
|
if (post.abuseFlagged) {
|
||||||
@@ -85,6 +86,8 @@ function Post({
|
|||||||
[ContentActions.COPY_LINK]: () => { navigator.clipboard.writeText(`${window.location.origin}/${courseId}/posts/${post.id}`); },
|
[ContentActions.COPY_LINK]: () => { navigator.clipboard.writeText(`${window.location.origin}/${courseId}/posts/${post.id}`); },
|
||||||
[ContentActions.PIN]: () => dispatch(updateExistingThread(post.id, { pinned: !post.pinned })),
|
[ContentActions.PIN]: () => dispatch(updateExistingThread(post.id, { pinned: !post.pinned })),
|
||||||
[ContentActions.REPORT]: () => handleAbusedFlag(),
|
[ContentActions.REPORT]: () => handleAbusedFlag(),
|
||||||
|
[ContentActions.ACCEPT_REVIEW]: () => dispatch(updateExistingThread(post.id, { reviewStatus: "ACCEPTED" })),
|
||||||
|
[ContentActions.REJECT_REVIEW]: () => dispatch(updateExistingThread(post.id, { reviewStatus: "REJECTED" })),
|
||||||
}), [
|
}), [
|
||||||
showDeleteConfirmation,
|
showDeleteConfirmation,
|
||||||
history,
|
history,
|
||||||
@@ -144,6 +147,8 @@ function Post({
|
|||||||
/>
|
/>
|
||||||
<AlertBanner content={post} />
|
<AlertBanner content={post} />
|
||||||
<PostHeader post={post} />
|
<PostHeader post={post} />
|
||||||
|
{displayReviewContentLabel && <p style= {{ background: "yellow" }}> This content is under review </p>}
|
||||||
|
|
||||||
<div className="d-flex mt-14px text-break font-style text-primary-500">
|
<div className="d-flex mt-14px text-break font-style text-primary-500">
|
||||||
<HTMLLoader htmlNode={post.renderedBody} componentId="post" cssClassName="html-loader" testId={post.id} />
|
<HTMLLoader htmlNode={post.renderedBody} componentId="post" cssClassName="html-loader" testId={post.id} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import { generatePath, useRouteMatch } from 'react-router';
|
|||||||
|
|
||||||
import { getConfig } from '@edx/frontend-platform';
|
import { getConfig } from '@edx/frontend-platform';
|
||||||
import {
|
import {
|
||||||
CheckCircle, CheckCircleOutline, Delete, Edit, Lock, LockOpen, Pin, Report, Verified, VerifiedOutline,
|
CheckCircle, CheckCircleOutline, Close, Delete, Done,
|
||||||
|
Edit, Lock, LockOpen, Pin, Report, Verified, VerifiedOutline,
|
||||||
} from '@edx/paragon/icons';
|
} from '@edx/paragon/icons';
|
||||||
|
|
||||||
import { InsertLink } from '../components/icons';
|
import { InsertLink } from '../components/icons';
|
||||||
@@ -173,6 +174,20 @@ export const ACTIONS_LIST = [
|
|||||||
label: messages.deleteAction,
|
label: messages.deleteAction,
|
||||||
conditions: { canDelete: true },
|
conditions: { canDelete: true },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'accept-review',
|
||||||
|
action: ContentActions.ACCEPT_REVIEW,
|
||||||
|
icon: Done,
|
||||||
|
label: messages.acceptReview,
|
||||||
|
conditions: { reviewStatus: 'PENDING' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'reject-review',
|
||||||
|
action: ContentActions.REJECT_REVIEW,
|
||||||
|
icon: Close,
|
||||||
|
label: messages.rejectReview,
|
||||||
|
conditions: { reviewStatus: 'PENDING' },
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export function useActions(content) {
|
export function useActions(content) {
|
||||||
|
|||||||
@@ -502,3 +502,19 @@ header {
|
|||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-size-24 {
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions-dropdown-item {
|
||||||
|
padding: 12px 16px;
|
||||||
|
height: 48px;
|
||||||
|
width: 304px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-xl {
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user