-
Notifications
You must be signed in to change notification settings - Fork 356
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
Move $().setupVerticalNavigation(...) logic to React #6463
Conversation
@miq-bot assign @martinpovolny |
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.
'menu-list-group-item', | ||
{ | ||
'tertiary-nav-item-pf': hasSubitems, | ||
'is-hover': useContext(HoverContext).secondLevelId === 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.
This is usage of hooks is dangerous. 1st rule of rule of react hooks is that they have to defined at the top of the function to avoid potential state inconsistencies.
const Foo = () => {
const { bar } = useSomething() // same as const bar = useSomething().bar but it is preferred syntax.
return (
<div> ...
)
}
Granted this is not the case for useContext
but still, we should follow the rules not to confuse anyone who might use this as a inspiration in the future.
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.
@fhlavac : can you move the useContext
into a separate statement after/before line 20?
@Hyperkid123 : that is what you are asking for, 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.
moved :)
@@ -10,7 +11,10 @@ const ThirdLevel = ({ | |||
visible, | |||
type, | |||
}) => (!visible ? null : ( | |||
<li className={`menu-list-group-item ${active ? 'active' : ''}`} id={`menu_item_${id}`}> | |||
<li | |||
className={`menu-list-group-item ${active ? 'active' : ''}`} |
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.
imported clsx
but its not used for composite className
'menu-list-group-item', | ||
'secondary-nav-item-pf', | ||
{ | ||
'is-hover': useContext(HoverContext).topLevelId === 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.
again hooks rules
dispatch(toggleVerticalMenuCollapsed()); | ||
const content = window.document.getElementsByClassName('container-pf-nav-pf-vertical-with-sub-menus')[0]; | ||
if (isVerticalMenuCollapsed) { | ||
content.classList.remove('collapsed-nav'); |
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 think it would be nice to check if the content exists. I don't know if its possible for the content no to be present in the DOM but its a good practice to first check if the element really exists before trying to call any functions on it.
|
||
const MainMenu = ({ menu }) => { | ||
const [activeIds, setActiveIds] = useState({}); | ||
const isVerticalMenuCollapsed = useSelector(store => store.menuReducer.isVerticalMenuCollapsed); |
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 would refer if you use object destructing for the property:
const isVerticalMenuCollapsed = useSelector(({ menuReducer: { isVerticalMenuCollapsed }}) => isVerticalMenuCollapsed);
package.json
Outdated
@@ -43,6 +43,7 @@ | |||
"bootstrap-filestyle": "~1.2.1", | |||
"bootstrap-switch": "3.3.4", | |||
"classnames": "~2.2.6", | |||
"clsx": "^1.0.4", |
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.
Just one line above, we pull in the classnames
package which does the same thing as clsx
.
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.
in ui-classic, we only have one use of classnames
, which should be trivial to change.
app/javascript/forms/miq-button.jsx
3:import ClassNames from 'classnames';
14: const klass = ClassNames({
But, in v2v, there's 28 more uses of classnames
.
So, I'd suggest just going with classnames
, unless you want to update https://github.com/ManageIQ/manageiq-v2v too.
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.
@fhlavac ok classnames
it is. Can you please change it? The package has almost the same syntax as clsx. You can find it in the docs.
My point is to use one, doesn't matter which 😆 |
@fhlavac Nope, it looks fine. |
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.
Tested. Looks fine. I do see a couple of issues with the menu in the mobile layout that are unrelated to this PR. We can address seperately.
@fhlavac : there's just a few minor comments. We are almost there. Thanks for the great work everyone! |
8db0b3d
to
b7c24ba
Compare
f72ca0b
to
5144ba2
Compare
Disable setupVerticalNavigation() and convert expanding logic to React.
@@ -65,6 +66,7 @@ ManageIQ.component.addReact('ImportDatastoreViaGit', ImportDatastoreViaGit); | |||
ManageIQ.component.addReact('MainMenu', MainMenu); | |||
ManageIQ.component.addReact('MiqAboutModal', MiqAboutModal); | |||
ManageIQ.component.addReact('MiqToolbar', MiqToolbar); | |||
ManageIQ.component.addReact('NavbarHeader', NavbarHeader); |
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.
@fhlavac Can you use the navbar.
convention here too? :)
@@ -0,0 +1 @@ | |||
= react('NavbarHeader', { :customBrand => ::Settings.server.custom_brand, :imagePath => image_path("layout/brand.svg") }) |
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.
(and here)
in component-definitions-common.js
5144ba2
to
4afbcfb
Compare
The menu currently doesn't remember the collapsed state...
It should remember and load in the collapsed state. The original implementation is using |
Yeah redux state is not persisted on full page refresh. So we will have to use local storage. We might want to think about persisting redux state to local storage further(somewhere else). But i don't know how i feel about that. |
I don't think it makes sense to persist the whole redux state, that sounds like it would always be caching more than it should. IMO we should have explicit interfaces for specific things that should remain set after reload, this may be one of them. |
agreed |
Checked commits fhlavac/manageiq-ui-classic@d794a15~...11c062d with ruby 2.5.5, rubocop 0.69.0, haml-lint 0.20.0, and yamllint 1.10.0 |
const content = window.document.getElementsByClassName('container-pf-nav-pf-vertical-with-sub-menus')[0]; | ||
if (content) { | ||
if (isVerticalMenuCollapsed) { | ||
content.classList.add('collapsed-nav'); |
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 a bit unfortunate we have to manipulate these classes manually, since this is a react component and the data is in state. Any way to use react here? :)
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.
Oh, never mind, that particular element is in app/views/layouts/_content.html.haml
and app/views/layouts/_center_div_*.html.haml
, and is still outside of the react navbar.
So, this makes sense for now, no issues :)
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.
yeah you would have to have the whole layout as a react component. No way around it for now i am afraid
$().setupVerticalNavigation(...)
method frommiq_application.js
@epwinchell Do you see anything about removing the pinning what should be changed or fixed?
@martinpovolny @himdel @Hyperkid123