Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix preview changes when mock status changes #1858

Merged
merged 2 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { useEffect } from 'react';
import { EditorState, ContentState, convertFromHTML, convertFromRaw, convertToRaw } from 'draft-js';
import { EditorState, convertToRaw } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import { FormControl, FormHelperText } from '@mui/material';
import { MetPaper } from '../../common';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
import './RichEditorStyles.css';
import { getEditorStateFromHtml, getEditorStateFromRaw } from './utils';
import { MetPaper } from '..';

const RichTextEditor = ({
setRawText = (_rawText: string) => {
Expand All @@ -20,30 +21,17 @@ const RichTextEditor = ({
}) => {
const getStateFromInitialValue = () => {
if (initialRawEditorState) {
setEditorState(getEditorState(initialRawEditorState));
setEditorState(getEditorStateFromRaw(initialRawEditorState));
return;
}

if (initialHTMLText) {
const blocksFromHTML = convertFromHTML(initialHTMLText);
const contentState = ContentState.createFromBlockArray(
blocksFromHTML.contentBlocks,
blocksFromHTML.entityMap,
);
setEditorState(EditorState.createWithContent(contentState));
return;
}
};

const getEditorState = (rawTextToConvert: string) => {
if (!rawTextToConvert) {
return EditorState.createEmpty();
const contentState = getEditorStateFromHtml(initialHTMLText);
setEditorState(contentState);
}
const rawContentFromStore = convertFromRaw(JSON.parse(rawTextToConvert));
return EditorState.createWithContent(rawContentFromStore);
};

const [editorState, setEditorState] = React.useState(getEditorState(initialRawEditorState));
const [editorState, setEditorState] = React.useState(getEditorStateFromRaw(initialRawEditorState));

const handleChange = (newEditorState: EditorState) => {
const plainText = newEditorState.getCurrentContent().getPlainText();
Expand Down
17 changes: 17 additions & 0 deletions met-web/src/components/common/RichTextEditor/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ContentState, EditorState, convertFromHTML, convertFromRaw } from 'draft-js';

// For draft-js to convert raw text to editor state
export const getEditorStateFromRaw = (rawTextToConvert: string) => {
if (!rawTextToConvert) {
return EditorState.createEmpty();
}
const rawContentFromStore = convertFromRaw(JSON.parse(rawTextToConvert));
return EditorState.createWithContent(rawContentFromStore);
};

// For draft-js to convert html to editor state
export const getEditorStateFromHtml = (htmlToConvert: string) => {
const blocksFromHTML = convertFromHTML(htmlToConvert);
const contentState = ContentState.createFromBlockArray(blocksFromHTML.contentBlocks, blocksFromHTML.entityMap);
return EditorState.createWithContent(contentState);
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useContext, useEffect, useState } from 'react';
import { Typography, Grid, TextField, Stack, Box } from '@mui/material';
import { MetPaper, MetLabel, PrimaryButton, SecondaryButton, MetDescription } from '../../../common';
import RichTextEditor from '../RichTextEditor';
import { ActionContext } from '../ActionContext';
import ImageUpload from 'components/imageUpload';
import { useNavigate } from 'react-router-dom';
Expand All @@ -11,6 +10,7 @@ import { EngagementTabsContext } from './EngagementTabsContext';
import { SUBMISSION_STATUS } from 'constants/engagementStatus';
import DayCalculatorModal from '../DayCalculator';
import { ENGAGEMENT_CROPPER_ASPECT_RATIO, ENGAGMENET_UPLOADER_HEIGHT } from './constants';
import RichTextEditor from 'components/common/RichTextEditor';

const CREATE = 'create';
const EngagementForm = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useContext, useState } from 'react';
import { defaultClosedText } from 'constants/submissionStatusText';
import RichTextEditor from '../../RichTextEditor';
import RichTextEditor from 'components/common/RichTextEditor';
import { EngagementTabsContext } from '../EngagementTabsContext';

export const SurveyClosedTextInput = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useContext, useState } from 'react';
import { defaultOpenText } from 'constants/submissionStatusText';
import RichTextEditor from '../../RichTextEditor';
import RichTextEditor from 'components/common/RichTextEditor';
import { EngagementTabsContext } from '../EngagementTabsContext';

export const SurveyOpenTextInput = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useContext, useState } from 'react';
import { defaultUpcomingText } from 'constants/submissionStatusText';
import RichTextEditor from '../../RichTextEditor';
import RichTextEditor from 'components/common/RichTextEditor';
import { EngagementTabsContext } from '../EngagementTabsContext';

export const SurveyUpcomingTextInput = () => {
Expand Down
44 changes: 33 additions & 11 deletions met-web/src/components/engagement/status/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,62 @@ import { Chip } from '@mui/material';
import { SubmissionStatus } from 'constants/engagementStatus';
const Chip_Font_Weight = { fontWeight: 'bold' };

const Open = ({ preview }: { preview?: boolean }) => {
return <Chip label="Open" color={preview ? 'default' : 'success'} sx={{ ...Chip_Font_Weight }} />;
interface ChipParams {
active: boolean;
clickable: boolean;
}
const Open = ({ active, clickable }: ChipParams) => {
return (
<Chip
label="Open"
color={active ? 'success' : 'default'}
sx={[{ ...Chip_Font_Weight }, clickable && { cursor: 'pointer' }]}
/>
);
};

const Closed = ({ preview }: { preview?: boolean }) => {
return <Chip label="Closed" color={preview ? 'default' : 'error'} sx={{ ...Chip_Font_Weight }} />;
const Closed = ({ active, clickable }: ChipParams) => {
return (
<Chip
label="Closed"
color={active ? 'error' : 'default'}
sx={[{ ...Chip_Font_Weight }, clickable && { cursor: 'pointer' }]}
/>
);
};

const Upcoming = ({ preview }: { preview?: boolean }) => {
const Upcoming = ({ active, clickable }: ChipParams) => {
return (
<Chip
label="Upcoming"
sx={preview ? { ...Chip_Font_Weight } : { ...Chip_Font_Weight, backgroundColor: '#FFC107', color: 'black' }}
sx={[
{ ...Chip_Font_Weight },
active && { backgroundColor: '#FFC107', color: 'black' },
clickable && { cursor: 'pointer' },
]}
/>
);
};

export const EngagementStatusChip = ({
submissionStatus,
preview,
active = true,
clickable = false,
}: {
submissionStatus: SubmissionStatus;
preview?: boolean;
active?: boolean;
clickable?: boolean;
}) => {
switch (submissionStatus) {
case SubmissionStatus.Upcoming:
// Engagement is published but submission start date is not due yet.
return <Upcoming preview={preview} />;
return <Upcoming active={active} clickable={clickable} />;
case SubmissionStatus.Open:
// Engagement is published and open for submission.
return <Open preview={preview} />;
return <Open active={active} clickable={clickable} />;
case SubmissionStatus.Closed:
// Engagement is published but it's past the submission date.
return <Closed preview={preview} />;
return <Closed active={active} clickable={clickable} />;
default:
return null;
}
Expand Down
7 changes: 4 additions & 3 deletions met-web/src/components/engagement/view/EngagementBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import { When } from 'react-if';
import EngagementInfoSection from './EngagementInfoSection';

export const EngagementBanner = ({ startSurvey }: EngagementBannerProps) => {
const { isEngagementLoading, savedEngagement } = useContext(ActionContext);
const { isEngagementLoading, savedEngagement, mockStatus } = useContext(ActionContext);
const surveyId = savedEngagement.surveys[0]?.id || '';
const isOpen = savedEngagement.submission_status === SubmissionStatus.Open;
const isLoggedIn = useAppSelector((state) => state.user.authentication.authenticated);
const isPreview = isLoggedIn;
const currentStatus = isPreview ? mockStatus : savedEngagement.submission_status;
const isOpen = currentStatus === SubmissionStatus.Open;

if (isEngagementLoading) {
return <Skeleton variant="rectangular" width="100%" height="35em" />;
Expand All @@ -23,7 +24,7 @@ export const EngagementBanner = ({ startSurvey }: EngagementBannerProps) => {
return (
<Banner imageUrl={savedEngagement.banner_url}>
<EngagementInfoSection savedEngagement={savedEngagement}>
<When condition={!!surveyId && (isOpen || isPreview)}>
<When condition={surveyId && isOpen}>
<Grid item container direction={{ xs: 'column', sm: 'row' }} xs={12} justifyContent="flex-end">
<PrimaryButton data-testid="EngagementBanner/share-your-thoughts-button" onClick={startSurvey}>
Share your thoughts
Expand Down
4 changes: 2 additions & 2 deletions met-web/src/components/engagement/view/EngagementContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { MetPaper } from '../../common';
import { Editor } from 'react-draft-wysiwyg';
import { ActionContext } from './ActionContext';
import { Skeleton } from '@mui/material';
import { getEditorState } from 'utils';
import { getEditorStateFromRaw } from 'components/common/RichTextEditor/utils';

export const EngagementContent = () => {
const { savedEngagement, isEngagementLoading } = useContext(ActionContext);
Expand All @@ -16,7 +16,7 @@ export const EngagementContent = () => {

return (
<MetPaper elevation={1} sx={{ padding: '2em', pt: '0px', minHeight: '30em' }}>
<Editor editorState={getEditorState(rich_content)} readOnly={true} toolbarHidden />
<Editor editorState={getEditorStateFromRaw(rich_content)} readOnly={true} toolbarHidden />
</MetPaper>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { Grid, Typography, Stack } from '@mui/material';
import { MetHeader1 } from 'components/common';
import { EngagementStatusChip } from '../status';
import { Editor } from 'react-draft-wysiwyg';
import { getEditorState } from 'utils';
import dayjs from 'dayjs';
import { ActionContext } from './ActionContext';
import { Engagement } from 'models/engagement';
import { useAppSelector } from 'hooks';
import { getEditorStateFromRaw } from 'components/common/RichTextEditor/utils';

interface EngagementInfoSectionProps {
savedEngagement: Engagement;
Expand Down Expand Up @@ -58,7 +58,7 @@ const EngagementInfoSection = ({ savedEngagement, children }: EngagementInfoSect
<Grid item xs={12} sx={{ maxHeight: '20em', overflowY: 'auto', overflowX: 'auto' }}>
<MetHeader1>{name}</MetHeader1>
<Grid item xs={12} sx={{ mb: 1 }}>
<Editor editorState={getEditorState(rich_description)} readOnly={true} toolbarHidden />
<Editor editorState={getEditorStateFromRaw(rich_description)} readOnly={true} toolbarHidden />
</Grid>
</Grid>
<Grid item xs={12}>
Expand Down
9 changes: 6 additions & 3 deletions met-web/src/components/engagement/view/PreviewBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,20 +154,23 @@ export const PreviewBanner = () => {
<Stack spacing={1} direction={{ md: 'row' }} alignItems="center" justifyContent="center">
<IconButton onClick={() => updateMockStatus(SubmissionStatus.Upcoming)}>
<EngagementStatusChip
preview={mockStatus !== SubmissionStatus.Upcoming}
submissionStatus={SubmissionStatus.Upcoming}
active={mockStatus === SubmissionStatus.Upcoming}
clickable
/>
</IconButton>
<IconButton onClick={() => updateMockStatus(SubmissionStatus.Open)}>
<EngagementStatusChip
preview={mockStatus !== SubmissionStatus.Open}
submissionStatus={SubmissionStatus.Open}
active={mockStatus === SubmissionStatus.Open}
clickable
/>
</IconButton>
<IconButton onClick={() => updateMockStatus(SubmissionStatus.Closed)}>
<EngagementStatusChip
preview={mockStatus !== SubmissionStatus.Closed}
submissionStatus={SubmissionStatus.Closed}
active={mockStatus === SubmissionStatus.Closed}
clickable
/>
</IconButton>
</Stack>
Expand Down
48 changes: 17 additions & 31 deletions met-web/src/components/engagement/view/SurveyBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,21 @@ import { ActionContext } from './ActionContext';
import { SubmissionStatus } from 'constants/engagementStatus';
import { SurveyBlockProps } from './types';
import { useAppSelector } from 'hooks';
import { If, Then, Else } from 'react-if';
import { submissionStatusArray } from 'constants/submissionStatusText';
import { Editor } from 'react-draft-wysiwyg';
import { getEditorState } from 'utils';

const statusMap = {
1: 'Upcoming',
2: 'Open',
3: 'Closed',
};
import { getEditorStateFromHtml, getEditorStateFromRaw } from 'components/common/RichTextEditor/utils';

const SurveyBlock = ({ startSurvey }: SurveyBlockProps) => {
const { savedEngagement, isEngagementLoading, mockStatus } = useContext(ActionContext);
const isOpen = savedEngagement.submission_status === SubmissionStatus.Open;
const surveyId = savedEngagement.surveys[0]?.id || '';
const isLoggedIn = useAppSelector((state) => state.user.authentication.authenticated);
const isPreview = isLoggedIn;
const currentStatus = isPreview ? mockStatus : savedEngagement.submission_status;
const isOpen = currentStatus === SubmissionStatus.Open;
const surveyId = savedEngagement.surveys[0]?.id || '';
const status_block = savedEngagement.status_block;
const status_text = status_block.find((status) => status.survey_status === statusMap[mockStatus])?.block_text;
const isMockStatusClosed = SubmissionStatus.Closed === mockStatus;
const status_text = status_block.find(
(status) => status.survey_status === SubmissionStatus[currentStatus],
)?.block_text;
if (isEngagementLoading) {
return <Skeleton variant="rectangular" height={'15em'} />;
}
Expand All @@ -33,29 +28,20 @@ const SurveyBlock = ({ startSurvey }: SurveyBlockProps) => {
<MetPaper elevation={1} sx={{ padding: '2em', pt: '0px' }}>
<Grid container direction="row" alignItems="flex-end" justifyContent="flex-end" spacing={2}>
<Grid item xs={12}>
<>
<If condition={!!status_text}>
<Then>
<Editor
editorState={getEditorState(status_text ? status_text : '')}
readOnly={true}
toolbarHidden
/>
</Then>
<Else>
<div
dangerouslySetInnerHTML={{
__html: submissionStatusArray[mockStatus - 1],
}}
/>
</Else>
</If>
</>
<Editor
editorState={
status_text
? getEditorStateFromRaw(status_text)
: getEditorStateFromHtml(submissionStatusArray[currentStatus - 1])
}
readOnly={true}
toolbarHidden
/>
</Grid>
<Grid item container direction={{ xs: 'column', sm: 'row' }} xs={12} justifyContent="flex-end">
<PrimaryButton
data-testid="SurveyBlock/take-me-to-survey-button"
disabled={!surveyId || (!isOpen && !isPreview) || (isPreview && isMockStatusClosed)}
disabled={!surveyId || !isOpen}
onClick={startSurvey}
>
Take me to the survey
Expand Down
10 changes: 0 additions & 10 deletions met-web/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { AxiosResponse } from 'axios';
import { EditorState, convertFromRaw } from 'draft-js';

export function hasKey<O>(obj: O, key: PropertyKey): key is keyof O {
return key in obj;
Expand All @@ -15,15 +14,6 @@ export function checkEmail(email: string) {
return filter.test(email);
}

// For draft-js to convert raw text to editor state
export const getEditorState = (rawTextToConvert: string) => {
if (!rawTextToConvert) {
return EditorState.createEmpty();
}
const rawContentFromStore = convertFromRaw(JSON.parse(rawTextToConvert));
return EditorState.createWithContent(rawContentFromStore);
};

export const downloadFile = (response: AxiosResponse<Blob, unknown>, filename: string) => {
if (!filename) {
throw new Error('Filename must be specified');
Expand Down
Loading