-
Notifications
You must be signed in to change notification settings - Fork 64
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
perf(RHIF-167): get rid of activeApps in redux #1754
perf(RHIF-167): get rid of activeApps in redux #1754
Conversation
Putting this in the draft state to merge Karel's PR and this together as a unified refactoring approach. |
b1b7fa7
to
e1e5046
Compare
Codecov ReportBase: 73.29% // Head: 73.02% // Decreases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## master #1754 +/- ##
==========================================
- Coverage 73.29% 73.02% -0.27%
==========================================
Files 97 98 +1
Lines 2127 2143 +16
Branches 823 829 +6
==========================================
+ Hits 1559 1565 +6
- Misses 568 578 +10
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While testing this PR I was unable to find any change/errors other than the intended changes like layout/performance.
I'd prefer another person take a look as well, but I was unable to find any issues. Great Job!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! Just a few minor questions and adjustments. I'll test it locally later on.
@@ -60,7 +60,7 @@ class GeneralInformation extends Component { | |||
}; | |||
|
|||
componentDidMount() { | |||
this.props.loadSystemDetail && this.props.loadSystemDetail(this.props.entity.id); | |||
this.props.loadSystemDetail && this.props.loadSystemDetail(this.props.inventoryId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd change this so we don't make the inventoryId
required yet (edge for instance doesn't pass it yet)
this.props.loadSystemDetail && this.props.loadSystemDetail(this.props.inventoryId); | |
this.props.loadSystemDetail?.(this.props.inventoryId || this.props.entity.id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha, I will do so
const DetailHeader = ({ | ||
entity, | ||
hideInvLink, | ||
loaded, | ||
addNotification, | ||
deleteEntity, | ||
onBackToListClick, | ||
actions, | ||
UUIDWrapper, | ||
LastSeenWrapper, | ||
children, | ||
showInventoryDrawer, | ||
shouldWrapAsPage, | ||
BreadcrumbWrapper, | ||
additionalClasses, | ||
showDelete, | ||
showTags, | ||
TitleWrapper, | ||
TagsWrapper, | ||
DeleteWrapper, | ||
ActionsWrapper | ||
}) => { | ||
const HeaderInfo = (<Fragment> | ||
<TopBar | ||
entity={entity} | ||
loaded={loaded} | ||
onBackToListClick={onBackToListClick} | ||
actions={actions} | ||
deleteEntity={deleteEntity} | ||
addNotification={addNotification} | ||
hideInvLink={hideInvLink} | ||
showInventoryDrawer={showInventoryDrawer} | ||
showDelete={showDelete} | ||
showTags={showTags} | ||
TitleWrapper={TitleWrapper} | ||
TagsWrapper={TagsWrapper} | ||
DeleteWrapper={DeleteWrapper} | ||
ActionsWrapper={ActionsWrapper} | ||
/> | ||
<FactsInfo | ||
loaded={loaded} | ||
entity={entity} | ||
UUIDWrapper={UUIDWrapper} | ||
LastSeenWrapper={LastSeenWrapper} | ||
/> | ||
{(loaded && verifyCulledInsightsClient(entity?.per_reporter_staleness)) && <InsightsPrompt />} | ||
{children} | ||
</Fragment>); | ||
|
||
return (shouldWrapAsPage ? | ||
(<PageHeader className={classnames('pf-m-light ins-inventory-detail', additionalClasses)} > | ||
{BreadcrumbWrapper} | ||
{HeaderInfo} | ||
</PageHeader>) : HeaderInfo); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a good idea to create new component on each render (especially with so many props). How about we'd split it into two components?
const DetailHeader = ({ | |
entity, | |
hideInvLink, | |
loaded, | |
addNotification, | |
deleteEntity, | |
onBackToListClick, | |
actions, | |
UUIDWrapper, | |
LastSeenWrapper, | |
children, | |
showInventoryDrawer, | |
shouldWrapAsPage, | |
BreadcrumbWrapper, | |
additionalClasses, | |
showDelete, | |
showTags, | |
TitleWrapper, | |
TagsWrapper, | |
DeleteWrapper, | |
ActionsWrapper | |
}) => { | |
const HeaderInfo = (<Fragment> | |
<TopBar | |
entity={entity} | |
loaded={loaded} | |
onBackToListClick={onBackToListClick} | |
actions={actions} | |
deleteEntity={deleteEntity} | |
addNotification={addNotification} | |
hideInvLink={hideInvLink} | |
showInventoryDrawer={showInventoryDrawer} | |
showDelete={showDelete} | |
showTags={showTags} | |
TitleWrapper={TitleWrapper} | |
TagsWrapper={TagsWrapper} | |
DeleteWrapper={DeleteWrapper} | |
ActionsWrapper={ActionsWrapper} | |
/> | |
<FactsInfo | |
loaded={loaded} | |
entity={entity} | |
UUIDWrapper={UUIDWrapper} | |
LastSeenWrapper={LastSeenWrapper} | |
/> | |
{(loaded && verifyCulledInsightsClient(entity?.per_reporter_staleness)) && <InsightsPrompt />} | |
{children} | |
</Fragment>); | |
return (shouldWrapAsPage ? | |
(<PageHeader className={classnames('pf-m-light ins-inventory-detail', additionalClasses)} > | |
{BreadcrumbWrapper} | |
{HeaderInfo} | |
</PageHeader>) : HeaderInfo); | |
}; | |
const HeaderInfo = ({ entity, loaded, UUIDWrapper, LastSeenWrapper, children, ...props }) => (<Fragment> | |
<TopBar | |
entity={entity} | |
loaded={loaded} | |
{...props} | |
/> | |
<FactsInfo | |
loaded={loaded} | |
entity={entity} | |
UUIDWrapper={UUIDWrapper} | |
LastSeenWrapper={LastSeenWrapper} | |
/> | |
{(loaded && verifyCulledInsightsClient(entity?.per_reporter_staleness)) && <InsightsPrompt />} | |
{children} | |
</Fragment>); | |
const DetailHeader = ({ shouldWrapAsPage, ...props }) => { | |
return (shouldWrapAsPage ? | |
(<PageHeader className={classnames('pf-m-light ins-inventory-detail', additionalClasses)} > | |
{BreadcrumbWrapper} | |
<HeaderInfo {...props} /> | |
</PageHeader>) : <HeaderInfo {...props} />); | |
}; | |
HeaderInfo.propTypes = DetailHeader.propTypes; |
I am not sure if I didn't missaligned anything, better to try this locally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course. I missed this caveat. I will adopt the suggestion
useEffect(() => { | ||
if (!entity || !(entity?.id === inventoryId) || !loaded) { | ||
dispatch(loadEntity(inventoryId, { hasItems: true }, { showTags })); | ||
} | ||
}, []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if app doesn't send inventoryId
? Wouldn't this cause constant re-renders? Also, if entity
is changed via selector no new re-calculation is not triggered
useEffect(() => { | |
if (!entity || !(entity?.id === inventoryId) || !loaded) { | |
dispatch(loadEntity(inventoryId, { hasItems: true }, { showTags })); | |
} | |
}, []); | |
useEffect(() => { | |
if (!entity || !(entity?.id === inventoryId) || !loaded) { | |
dispatch(loadEntity(inventoryId, { hasItems: true }, { showTags })); | |
} | |
}, [entity, inventoryId, loaded]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am just thinking about why the entity would change on this page. But, maybe there is something that I am not aware of.
useEffect(() => { | ||
chrome?.hideGlobalFilter?.(true); | ||
chrome.appAction('system-detail'); | ||
clearNotifications(); | ||
const appName = searchParams.get('appName'); | ||
if (appName) { | ||
dispatch(detailSelect(appName)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember removing this action caused incorrect tab activation. I guess the new refs deal with this, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, this is resolved by refs
src/routes/InventoryDetail.js
Outdated
history.push({ | ||
search | ||
}); | ||
}, []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should add at least to list of dependencies searchParams
.
@karelhala I have adopted all the necessary adjustments. Please have a look one more time |
@karelhala Hopefully, everything is as expected now. Here is the edge PR to align the app with this refactoring. Please run these apps to verify. The important thing is that with this PR, inventoryId prop will be used as a main factor to fetch host detail. Thus this prop is marked as required. This enables apps to independently render the header and the main section. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! Tested it locally and everything seems to be working!
🎉 This PR is included in version 1.3.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This is the second step of improving the Inventory details page by getting rid of using the redux store to render active apps in the Main section tab. Now, an active application that needs to be displayed will be decided by the
appName
in the URL. If it is not set, the first application inappsList
prop will get displayed. Also, this PR introduces wrapping general information sections withCard
component as a result of this UX ask. This PR is backward compatible. There are a few extra components that needs to be removed once all apps migrate to new approach safely.Benefits of this refactor:
Regarding consumer applications dealing with InventoryDetailHead and AppInfo components in the fed-mod, I have been working to remove AppInfo component and passing inventoryId into DetailsWrapper component to directly use DetailHeader as presentational component. This gives those apps more freedom, and reduces the complexity of how we deal with federated modules. In the following commit/PR I will target consuming InventoryDetailHeader and DetailWrapper in fed-modules.
General information tab before:
General information tab after: