Skip to content

Commit

Permalink
Client - Implement ActionNavbar plugin (#161)
Browse files Browse the repository at this point in the history
  • Loading branch information
luorlandini authored May 12, 2021
1 parent 0568864 commit 81d8d0f
Show file tree
Hide file tree
Showing 17 changed files with 764 additions and 41 deletions.
1 change: 1 addition & 0 deletions geonode_mapstore_client/client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ The homepage configuration file is located in [localConfig.json](static/mapstore
| `menu` | {object} | configuration of the main menu | |
| `menu.items` | {array} | list of menu item objects, left placement | [menu item object entry](#menu-item-object) |
| `menu.rightItems` | {array} | list of menu item objects, right placement | [menu item object entry](#menu-item-object) |
| `menu.cfg.rightContents.style.width` | {number} | value to fix width in right side of action navbar | [menu item object entry](#menu-item-object) |
| `footer` | {object} | configuration of the footer | |
| `footer.items` | {array} | list of menu item objects, left placement | [menu item object entry](#menu-item-object) |
| `cardsMenu` | {object} | configuration of the menu of resource cards | |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*
* Copyright 2021, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

import React, { forwardRef, useRef, useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import Menu from '@js/components/Menu';
import BurgerMenu from '@js/components/Menu/BurgerMenu';
import useResizeElement from '@js/hooks/useResizeElement';


const LeftContentMenu = ({ items, formatHref, query }) => {

const navbarContentLeft = useRef();
const navbarLeft = useRef();
const { width: widthContentLeft } = useResizeElement(navbarContentLeft);
const { width: widthNavbarLeft } = useResizeElement(navbarLeft);
const [switchToBurgerMenu, setSwitchToBurgerMenu] = useState(false);
useEffect(() => {
setSwitchToBurgerMenu(widthNavbarLeft >= widthContentLeft);
}, [widthNavbarLeft, widthContentLeft]);

return (
<div
className={`gn-action-navbar-content-left`}
ref={navbarContentLeft}
>
{
(switchToBurgerMenu) && items && <BurgerMenu items={items} />
}

{ (!switchToBurgerMenu) && items &&

<Menu
ref={navbarLeft}
items={items}
containerClass={`gn-brand-navbar-left-side`}
childrenClass={`gn-user-dropdown`}
formatHref={formatHref}
query={query}
/>

}
</div>

);
};


const RightContentMenu = ({ items, formatHref, query, parentRef, cfg }) => {

const navbarContentRight = useRef();
const navbarRight = useRef();
const { width: widthNavbarRight } = useResizeElement(navbarRight);
const { width: widthParent } = useResizeElement(parentRef);
const { width: widthNavbarContentRight } = useResizeElement(navbarContentRight);
const isSpaceRight = (cfg?.style) ? widthNavbarRight >= widthNavbarContentRight : widthNavbarRight >= widthParent
const [switchToBurgerMenu, setSwitchToBurgerMenu] = useState(false);
useEffect(() => {
setSwitchToBurgerMenu(isSpaceRight);
}, [isSpaceRight]);

return (
<div
ref={navbarContentRight}
className={`gn-action-navbar-content-right`}
style={cfg?.style}
>

{
(switchToBurgerMenu) && items && <BurgerMenu items={items} />
}

{(!switchToBurgerMenu) && items &&
<Menu
ref={navbarRight}
items={items}
containerClass={`gn-brand-navbar-right-side`}
childrenClass={`gn-user-dropdown`}
formatHref={formatHref}
query={query}

/>

}

</div>


);
};


const ActionNavbar = forwardRef(({
style,
leftItems,
rightItems,
query,
formatHref,
tools,
cfg
}, ref) => {

return (
<nav
ref={ref}
className={`gn-action-navbar`}
style={style}
>
<div className={`gn-action-navbar-container`}>

<div
className={`gn-action-navbar-content`}
>

{
leftItems.length > 0 &&
<LeftContentMenu
items={leftItems}
formatHref={formatHref}
query={query}
/>
}

{

rightItems.length > 0 &&
<RightContentMenu
items={rightItems}
formatHref={formatHref}
query={query}
parentRef={ref}
cfg={cfg?.rightContents}
/>
}


<div className={`gn-action-navbar-content-tools`}>
{tools}
</div>
</div>


</div>

</nav>

);
});

ActionNavbar.propTypes = {
style: PropTypes.object,
leftItems: PropTypes.array,
rightItems: PropTypes.array,
query: PropTypes.object,
formatHref: PropTypes.func
};

ActionNavbar.defaultProps = {
leftItems: [],
rightItems: [],
query: {},
formatHref: () => '#'
};


export default ActionNavbar;
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/*
* Copyright 2021, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

import React from 'react';
import ReactDOM from 'react-dom';
import expect from 'expect';
import ActionNavbar from '../ActionNavbar';


const conf = {
leftItems: [
{
"labelId": "gnhome.data",
"type": "dropdown",
"items": [
{
"type": "link",
"href": "/layers/?limit=5",
"labelId": "gnhome.layers",
"badge": 1,
"permissions": [],
"allowedRoles": []
},
{
"type": "link",
"href": "/documents/?limit=5",
"labelId": "gnhome.documents",
"badge": 1,
"permissions": [],
"allowedRoles": []
},
{
"type": "link",
"href": "/services/?limit=5",
"labelId": "gnhome.remoteServices",
"permissions": [],
"allowedRoles": []
}
]
},
{
"labelId": "gnhome.maps",
"authenticated": false,
"type": "link",
"subType": "tag",
"href": "/maps/?limit=5",
"badge": 2
},
{
"type": "link",
"subType": "tag",
"href": "/apps/?limit=5",
"labelId": "gnhome.apps",
"badge": 5
},
{
"labelId": "gnhome.about",
"type": "dropdown",
"items": [
{
"type": "link",
"href": "/people/",
"labelId": "gnhome.people"
},
{
"type": "link",
"href": "/groups/",
"labelId": "gnhome.groups"
},
{
"type": "link",
"href": "/groups/categories/",
"labelId": "gnhome.groupsCategories"
}
]
},
{
"type": "link",
"subType": "tag",
"href": "/apps/?limit=5",
"labelId": "gnhome.apps",
"badge": 5
},
{
"labelId": "gnhome.about",
"type": "dropdown",
"items": [
{
"type": "link",
"href": "/people/",
"labelId": "gnhome.people"
},
{
"type": "link",
"href": "/groups/",
"labelId": "gnhome.groups"
},
{
"type": "link",
"href": "/groups/categories/",
"labelId": "gnhome.groupsCategories"
}
]
}
],
rightItems: [
{
"labelId": "gnhome.data",
"type": "dropdown",
"items": [
{
"type": "link",
"href": "/layers/?limit=5",
"labelId": "gnhome.layers",
"badge": 1,
"permissions": [],
"allowedRoles": []
},
{
"type": "link",
"href": "/documents/?limit=5",
"labelId": "gnhome.documents",
"badge": 1,
"permissions": [],
"allowedRoles": []
},
{
"type": "link",
"href": "/services/?limit=5",
"labelId": "gnhome.remoteServices",
"permissions": [],
"allowedRoles": []
}
]
},
{
"labelId": "gnhome.maps",
"authenticated": false,
"type": "link",
"subType": "tag",
"href": "/maps/?limit=5",
"badge": 2
},
{
"labelId": "gnhome.maps",
"authenticated": false,
"type": "link",
"subType": "tag",
"href": "/maps/?limit=5",
"badge": 2
},
{
"labelId": "gnhome.maps",
"authenticated": false,
"type": "link",
"subType": "tag",
"href": "/maps/?limit=5",
"badge": 2
},
{
"labelId": "gnhome.maps",
"authenticated": false,
"type": "link",
"subType": "tag",
"href": "/maps/?limit=5",
"badge": 2
}
]

};

describe('Test GeoNode action navbar component', () => {
beforeEach((done) => {
document.body.innerHTML = '<div id="container"></div>';
setTimeout(done);
});
afterEach((done) => {
ReactDOM.unmountComponentAtNode(document.getElementById("container"));
document.body.innerHTML = '';
setTimeout(done);
});
it('should render with default', () => {
ReactDOM.render( <ActionNavbar/>, document.getElementById("container"));
const el = document.querySelector('.gn-action-navbar');
expect(el).toExist();
});

it('should render left content right content', () => {
ReactDOM.render( <ActionNavbar
leftItems={conf.leftItems.items}
rightItems={conf.rightItems.items}
/>, document.getElementById("container"));

const el = document.querySelector('.gn-action-navbar');
expect(el).toExist();
const navBarContent = document.querySelector('.gn-action-navbar-content');
expect(navBarContent).toExist();
const navBarContentRight = document.querySelector('.gn-action-navbar-content-right');
expect(navBarContentRight).toExist();
const navBarContentLeft = document.querySelector('.gn-brand-navbar-left-side');
expect(navBarContentLeft).toExist();

});

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import ActionNavbar from './ActionNavbar';
export default ActionNavbar;
Loading

0 comments on commit 81d8d0f

Please sign in to comment.