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/deseng674: Implemented authoring tab to admin engagement view #2576

Merged
merged 5 commits into from
Aug 15, 2024

Conversation

jareth-whitney
Copy link
Contributor

…. Fixed a couple of issues with Footer and Admin SideNav as well.

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

Description of changes:

  • Implemented authoring tab in admin engagement view
  • Co-ordinated with Nat to build admin view index.tsx
    • Used original data fetch config since I don't have Nat's loader
    • Modified tab values to match hi-fi prototype
  • Fixed an invalid prop in the footer
  • Fixed a React key error in admin side nav

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

…. Fixed a couple of issues with Footer and Admin SideNav as well.
@codecov-commenter
Copy link

codecov-commenter commented Aug 15, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 76.04%. Comparing base (76fbfd4) to head (b9b2baa).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2576   +/-   ##
=======================================
  Coverage   76.04%   76.04%           
=======================================
  Files         609      609           
  Lines       22080    22080           
  Branches     1785     1785           
=======================================
  Hits        16790    16790           
  Misses       5026     5026           
  Partials      264      264           
Flag Coverage Δ
metweb 65.02% <100.00%> (ø)

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

Files Coverage Δ
met-web/src/components/layout/SideNav/SideNav.tsx 94.33% <100.00%> (ø)

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.

Could we discuss the use of generateUniqueKey if you haven't found another solution yet? Also I commented in a few places where I was trying to understand the code. Since someone else may be updating the SystemMessage to work in the future, I just wanted to make sure I understood the intended use of it.

const defaultFeedbackMethods = getAuthoringValues(defaultAuthoringValue, feedbackTitles, true);

// Set useStates. When data is imported, it will be set with setSectionValues and setFeedbackMethods.
const [sectionValues, setSectionValues] = useState(defaultSectionValues);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like you've set up some infrastructure here for the conditional display of the alert messages! I know this was a tricky ask since we don't actually have any engagement data to work with.

I'm trying to understand the code here:

  • It seems like the variables defined on lines 82-87 are just for showing the lists of sections to complete, correct?
  • Is sectionValues meant to contain actual engagement data? If so, why is it set to hold data that's meant for the rendering of the section lists? Was the idea to change it to real-live engagement data later?

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, that's down to the way Prettier is autoformatting my code! Those are actually all arguments for the function, and then I'm returning the result of the map below that.


// Listen to the sectionValues useState and update the boolean value that controls the presence of the "sections" incomplete message.
useEffect(() => {
if (true !== requiredSectionsCompleted && allRequiredItemsComplete(sectionValues)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just curious why we need both requiredSectionsCompleted and allRequiredItemsComplete here

Copy link
Contributor Author

@jareth-whitney jareth-whitney Aug 15, 2024

Choose a reason for hiding this comment

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

allRequiredItemsComplete is a comparison function that returns a boolean value. It's the check that occurs before I assign the value to the requiredSectionsCompleted useState boolean.

paddingRight: '0.4rem',
};
return (
<Link style={{ textDecoration: 'none' }} href={props.item.link}>
Copy link
Collaborator

Choose a reason for hiding this comment

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

A link is definitely the way to go for those section links! As oppose to a plain button

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes definitely better for accessibility, as you taught me.

const [requiredSectionsCompleted, setRequiredSectionsCompleted] = useState(false);
const [feedbackCompleted, setFeedbackCompleted] = useState(false);

// Define styles
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 grouping the styles together nicely!


// Listen to the feedbackMethods useState and update the boolean value that controls the presence of the "feedback" incomplete message.
useEffect(() => {
if (true !== feedbackCompleted && allRequiredItemsComplete(feedbackMethods)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just curious about the need for both conditionals here too. Also, was there a reason you couldn't do:

Suggested change
if (true !== feedbackCompleted && allRequiredItemsComplete(feedbackMethods)) {
if (!feedbackCompleted && allRequiredItemsComplete(feedbackMethods)) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To me the first way is a bit more readable and a bit more strict, but I could go either way.

// Check if all required items are completed.
const allRequiredItemsComplete = (values: AuthoringValue[]) => {
const itemChecklist = values.map((value) => {
if (undefined === value.required || undefined === value.completed) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It looks like value.required and value.completed are explicitly set as falseto begin with. How would they get set toundefined`?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, you wouldn't have an undefined value from the default data. It's when you start introducing real data that this becomes important.

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 okay with proceeding with this code but I thought I'd add a note that with Typescript, we often don't need to account for undefined popping up. We have a lot more type control which allows us to not have to worry about checking for undefined in case things break.

@@ -32,6 +42,52 @@ export const AdminEngagementView = () => {
)}
</Await>
</Suspense>
</div>
<TabContext value={currentTab}>
<TabList
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this render as a nav? If not, we can specify the component element to use, or give it an aria-role of navigation

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 renders as a div right now. I'll see if I can make it render as a nav instead.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Rendering as a nav element as of the latest commit

@@ -81,3 +81,11 @@ export const isDarkColor = (color: string, sensitivity = 0.5) => {
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
return luminance < sensitivity;
};

export const generateUniqueKey = () => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

As discussed a bit, let's review the use of this function as a "key" generator. There are other recommended methods for this

title: '',
link: '#',
required: false,
completed: false,
};
const getAuthoringValues = (defaultValues: AuthoringValue, titles: string[], required: boolean): AuthoringValue[] =>
titles.map((title) => ({ ...defaultValues, title: title, required: required }));
const getAuthoringValues = (
Copy link
Collaborator

@Baelx Baelx Aug 15, 2024

Choose a reason for hiding this comment

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

Thanks for changing the formatting! It's easier on the eyes

Copy link

sonarcloud bot commented Aug 15, 2024

@jareth-whitney jareth-whitney merged commit ee6caab into main Aug 15, 2024
8 checks passed
@jareth-whitney jareth-whitney deleted the feature/deseng674 branch August 15, 2024 23:15
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