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

Feature/deseng671: New Summary page in authoring section #2587

Merged
merged 3 commits into from
Sep 13, 2024

Conversation

jareth-whitney
Copy link
Contributor

Issue #: https://citz-gdx.atlassian.net/browse/DESENG-671

Description of changes:

  • Feature New Summary page in authoring section 🎟️ DESENG-671
    • Fetches values
    • Saves values to database
    • Returns success and error messages to user after form submission
    • Resets form dirty state after submission

User Guide update ticket (if applicable):
N/A

Copy link
Collaborator

@Baelx Baelx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this Jareth! Please have a look at my comments but the only thing really required is that we update the labels for the body text. The text there seems like it's referring to Section Headings.


const AuthoringBanner = () => {
const AuthoringSummary = () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this rename! Helps make it clearer that it's the for the page summary section

// Check if the form has succeeded or failed after a submit, and issue a message to the user.
const dispatch = useAppDispatch();
useEffect(() => {
if ('success' === fetcher.data) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could potentially save some code like this:

Suggested change
if ('success' === fetcher.data) {
const responseSeverity = 'success' === fetcher.data ? 'success' : 'error';
const responseText = 'success' === fetcher.data ? 'Engagement saved successfully.' : 'Unable to save engagement.';
dispatch(
openNotification({
severity: responseSeverity,
text: responseText,
}),
);

Copy link
Contributor Author

@jareth-whitney jareth-whitney Sep 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only issue here is that fetcher.data could be returning other values that aren't 'success' or 'error'. So we could have things that are called 'errors' that are false positives. Previous technique was an if > else if statement. However, this code has inspired me to make the code less verbose, so I'll find a solution.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for considering my suggestion and no worries if you don't end up reducing code here!

Your original code only handles two cases. So you're saying that there are other responses from the fetcher in which we want the request to complete but no message be displayed to the user? I feel like at the presentation layer, a user would only care about their request being successful or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solution:
useEffect(() => {
if ('success' === fetcher.data || 'failure' === fetcher.data) {
const responseText =
'success' === fetcher.data ? 'Engagement saved successfully.' : 'Unable to save engagement.';
const responseSeverity = 'success' === fetcher.data ? 'success' : 'error';
dispatch(
openNotification({
severity: responseSeverity,
text: responseText,
}),
);
fetcher.data = undefined;
}
}, [fetcher.data]);

};

// Determines whether a string is JSON parseable.
const tryParse = (json: string) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we do JSON parsing for sending/receiving json data elsewhere in the frontend? Just curious. Maybe this is something that is handled by yup elsewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you can do something like this with yup but it's pretty much equally long-winded.

Yup.string().test("json", "Invalid JSON format", (value) => {
try {
JSON.parse(value);
return true;
} catch (error) {
return false;
}
}),

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay yeah, thanks for looking into that! With this big app, I just think it's important that we don't reinvent the wheel on common operations like handling JSON in requests/forms. But it looks like if we're using yup elsewhere then it's about the same code footprint

/>
</label>
</Grid>

<Grid sx={{ ...formItemContainerStyles, backgroundColor: colors.surface.blue[10] }} item>
<label htmlFor="body_copy">
<label htmlFor="editor_state">
<MetBigLabel style={metBigLabelStyles} role="document" tab-index="0">
Body Copy
<span style={{ fontWeight: 'normal' }}> (Required)</span>
</MetBigLabel>
<FormDescriptionText style={formDescriptionTextStyles}>
Your section heading should be descriptive, short and succinct.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagine this description needs to be updated for body text?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Funny story, the state of the RichTextArea was very hard to manage because of the Controller. However, I need the Controller because it checks if the form is dirty. So this is actually a dummy field that isn't sent to the API, but it manages the state of the RichTextArea. However, I think I should rename it to something like summary_editor_state because that would be specific to the summary page.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about this and I'll message you to learn more!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I thought we were talking about the editor_state label but you meant the FormDescriptionText text. Fixed.

render={({ field }) => {
return (
<RichTextArea
ariaLabel="Body Copy: Your section heading should be descriptive, short and succinct."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more directions that seem meant for the section header input!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will fix.

ariaLabel="Body Copy: Your section heading should be descriptive, short and succinct."
spellCheck
initialContentState={
tryParse(content[0].json_content)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would accomplish the same thing:

Suggested change
tryParse(content[0].json_content)
tryParse(content[0].json_content) || ''

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I'm taking a second look at this and it's not quite the same. The first function just checks if the JSON is valid, the second one actually parses it. I need both unfortunately.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But tryParse returns parsed JSON too, doesn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and upon third inspection, I think this actually will work, since I am returning the value if it is parseable (I thought I was just returning true).

@@ -108,7 +109,8 @@ const AuthoringTemplate = () => {
<SystemMessage status="warning">
Under construction - the settings in this section have no effect.
</SystemMessage>
{'details' === slug && (

<When condition={'details' === slug}>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks pretty minimal but I'd say no need to modify the details section any further. I've changed a lot of this in my work so far.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, this was the only modification to the Details section. I wanted to make it consistent with the rest of our code, where we use often instead of the && conditional.


<When condition={'summary' === slug}>
<Grid container sx={{ maxWidth: '700px', mt: '1rem' }} direction="column">
<WidgetPicker location={1} />
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small thing but would you consider passing the enum so it's a bit more readable?

Suggested change
<WidgetPicker location={1} />
<WidgetPicker location={WidgetLocation.specify_your_location} />

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

…est WidgetPicker component from authoring tab, due to unit tests failing.
Copy link

@codecov-commenter
Copy link

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 75.27%. Comparing base (6ba4401) to head (bdc0dc9).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2587      +/-   ##
==========================================
- Coverage   75.80%   75.27%   -0.54%     
==========================================
  Files         607      612       +5     
  Lines       21881    22145     +264     
  Branches     1810     1839      +29     
==========================================
+ Hits        16587    16669      +82     
- Misses       5032     5203     +171     
- Partials      262      273      +11     
Flag Coverage Δ
metweb 64.35% <100.00%> (-0.78%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
.../components/engagement/admin/view/AuthoringTab.tsx 27.27% <100.00%> (+1.34%) ⬆️
met-web/src/models/widget.tsx 100.00% <100.00%> (ø)

... and 12 files with indirect coverage changes

Copy link
Collaborator

@Baelx Baelx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good thanks!

@jareth-whitney jareth-whitney merged commit 5373540 into main Sep 13, 2024
7 of 8 checks passed
@jareth-whitney jareth-whitney deleted the feature/deseng671 branch September 13, 2024 22:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants