Skip to content

Commit

Permalink
Nse 7726 (#37)
Browse files Browse the repository at this point in the history
* Added prototype application menu.

* Updates to application menu.

* Updates for handling real data.

* Added CSS arrow to application menu.

* Comments and cleanup.

* Updated comments.

* Minor reformatting.

* Incremented version.

* Generated lib outputs.
  • Loading branch information
rmarkel-neon authored May 5, 2021
1 parent cb47b81 commit 3b9bb87
Show file tree
Hide file tree
Showing 12 changed files with 28,735 additions and 81 deletions.
2 changes: 2 additions & 0 deletions lib/components/NeonHeader/ApplicationMenu.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// <reference types="react" />
export default function ApplicationMenu(): JSX.Element | null;
265 changes: 265 additions & 0 deletions lib/components/NeonHeader/ApplicationMenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = ApplicationMenu;

var _react = _interopRequireDefault(require("react"));

var _styles = require("@material-ui/core/styles");

var _IconButton = _interopRequireDefault(require("@material-ui/core/IconButton"));

var _ClickAwayListener = _interopRequireDefault(require("@material-ui/core/ClickAwayListener"));

var _Paper = _interopRequireDefault(require("@material-ui/core/Paper"));

var _Popper = _interopRequireDefault(require("@material-ui/core/Popper"));

var _Tooltip = _interopRequireDefault(require("@material-ui/core/Tooltip"));

var _Apps = _interopRequireDefault(require("@material-ui/icons/Apps"));

var _Fade = _interopRequireDefault(require("@material-ui/core/Fade"));

var _Launch = _interopRequireDefault(require("@material-ui/icons/Launch"));

var _Card = _interopRequireDefault(require("@material-ui/core/Card"));

var _CardContent = _interopRequireDefault(require("@material-ui/core/CardContent"));

var _Typography = _interopRequireDefault(require("@material-ui/core/Typography"));

var _Grid = _interopRequireDefault(require("@material-ui/core/Grid"));

var _NeonContext = _interopRequireDefault(require("../NeonContext/NeonContext"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

// declare styles
var useStyles = (0, _styles.makeStyles)(function (theme) {
return (0, _styles.createStyles)({
menuContainer: {
zIndex: 1000 // be sure to display the menu over other elements

},
toolbarContainer: {
display: 'flex',
justifyContent: 'space-between',
boxShadow: '0px 1px 3px rgba(0, 0, 0, 0.45)',
// match shadow of site header
position: 'relative'
},
toolbarButtons: {
display: 'flex',
marginLeft: 'auto',
// align content right
marginRight: theme.spacing(2.5),
marginTop: theme.spacing(0.5),
marginBottom: theme.spacing(0.5)
},
paper: {
padding: theme.spacing(4),
maxWidth: '500px',
// limit width of menu
marginTop: theme.spacing(1),
// line top of menu up with divider
overflowX: 'unset',
overflowY: 'unset',
'&::before': {
// add tooltip like arrow to top of menu
content: '""',
position: 'absolute',
marginRight: theme.spacing(4),
// center arrow point beneath menu button
top: 0,
right: 0,
width: theme.spacing(2),
// width of arrow
height: theme.spacing(2),
// height of arrow
backgroundColor: theme.palette.background.paper,
// match paper background
boxShadow: theme.shadows[2],
// add arrow shadow
transform: 'rotate(315deg)',
// point arrow up toward menu button
clipPath: 'polygon(-5px -5px, calc(100% + 5px) -5px, calc(100% + 5px) calc(100% + 5px))'
}
},
card: {
transition: '0.4s',
'&:hover': {
// raised hover effect for Cards
transform: 'translateY(-2px)',
// raise Card
boxShadow: theme.shadows[2] // add shadow

},
cursor: 'pointer',
// visually indicate Cards are links
width: '100%',
// ensure Cards are equal width
border: 0 // remove default Card border

},
cardContent: {
textAlign: 'center'
},
gridItem: {
display: 'flex' // so grid items stretch to equal height

}
});
});

var getApps = function getApps() {
var _authData$userData, _authData$userData$da;

var _NeonContext$useNeonC = _NeonContext.default.useNeonContextState(),
_NeonContext$useNeonC2 = _slicedToArray(_NeonContext$useNeonC, 1),
authData = _NeonContext$useNeonC2[0].auth;

return authData === null || authData === void 0 ? void 0 : (_authData$userData = authData.userData) === null || _authData$userData === void 0 ? void 0 : (_authData$userData$da = _authData$userData.data) === null || _authData$userData$da === void 0 ? void 0 : _authData$userData$da.apps;
}; // define the menu component


var Menu = function Menu(props) {
var apps = props.apps;
var classes = useStyles();

var _React$useState = _react.default.useState(false),
_React$useState2 = _slicedToArray(_React$useState, 2),
open = _React$useState2[0],
setOpen = _React$useState2[1];

var anchorRef = _react.default.useRef(null); // handle menu toggle


var handleToggle = function handleToggle() {
setOpen(function (prevOpen) {
return !prevOpen;
});
}; // close the menu


var handleClose = function handleClose(event) {
if (anchorRef.current && anchorRef.current.contains(event.target)) {
return;
}

setOpen(false);
}; // open menu by tab key


function handleMenuKeyDown(event) {
if (event.key === 'Tab') {
event.preventDefault();
setOpen(false);
}
} // handle a menu selection


var handleMenuItemClick = function handleMenuItemClick(event, url) {
window.location.href = url;
};

return /*#__PURE__*/_react.default.createElement("div", {
className: classes.toolbarContainer
}, /*#__PURE__*/_react.default.createElement("div", {
className: classes.toolbarButtons
}, /*#__PURE__*/_react.default.createElement(_Tooltip.default, {
title: "Neon Applications",
"aria-label": "Neon Applications",
placement: "left",
TransitionComponent: _Fade.default,
TransitionProps: {
timeout: 200
},
arrow: true
}, /*#__PURE__*/_react.default.createElement(_IconButton.default, {
ref: anchorRef,
style: {
color: 'black'
},
"aria-label": "more",
"aria-controls": open ? 'neon-application-menu' : undefined,
"aria-haspopup": "true",
onClick: handleToggle,
onKeyDown: handleMenuKeyDown
}, /*#__PURE__*/_react.default.createElement(_Apps.default, null))), /*#__PURE__*/_react.default.createElement(_Popper.default, {
className: classes.menuContainer,
open: open,
anchorEl: anchorRef.current,
role: "presentation",
transition: true
}, function (_ref) {
var TransitionProps = _ref.TransitionProps,
placement = _ref.placement;
return /*#__PURE__*/_react.default.createElement(_Fade.default, _extends({}, TransitionProps, {
style: {
transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom'
},
timeout: 200
}), /*#__PURE__*/_react.default.createElement(_Paper.default, {
elevation: 3,
className: classes.paper
}, /*#__PURE__*/_react.default.createElement(_ClickAwayListener.default, {
onClickAway: handleClose
}, /*#__PURE__*/_react.default.createElement(_Grid.default, {
container: true,
spacing: 4,
alignItems: "stretch"
}, apps.map(function (app) {
return /*#__PURE__*/_react.default.createElement(_Grid.default, {
item: true,
xs: apps.length === 1 ? 12 : 6,
className: classes.gridItem,
key: app.name
}, /*#__PURE__*/_react.default.createElement(_Card.default, {
onClick: function onClick(event) {
return handleMenuItemClick(event, app.url);
},
key: app.url,
className: classes.card
}, /*#__PURE__*/_react.default.createElement(_CardContent.default, {
className: classes.cardContent
}, /*#__PURE__*/_react.default.createElement(_Launch.default, {
fontSize: "large"
}), /*#__PURE__*/_react.default.createElement(_Typography.default, {
variant: "subtitle1",
gutterBottom: true,
style: {
lineHeight: 1
}
}, app.name), app.description)));
})))));
})));
};

function ApplicationMenu() {
var apps = getApps();

if ((apps === null || apps === void 0 ? void 0 : apps.length) > 0) {
return /*#__PURE__*/_react.default.createElement(Menu, {
apps: apps
});
}

return null;
}
25 changes: 19 additions & 6 deletions lib/components/NeonHeader/NeonHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ var _NeonEnvironment = _interopRequireDefault(require("../NeonEnvironment/NeonEn

var _NeonContext = _interopRequireWildcard(require("../NeonContext/NeonContext"));

var _ApplicationMenu = _interopRequireDefault(require("./ApplicationMenu"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
Expand Down Expand Up @@ -64,6 +66,7 @@ var useStyles = (0, _styles.makeStyles)(function (theme) {
skeletonHeader: {
boxShadow: '0px 1px 3px rgba(0, 0, 0, 0.25), 0px 1px 1px rgba(0, 0, 0, 0.25)'
},
// positioning of sign-in and sign-out buttons
coreAuthContainer: (_coreAuthContainer = {
// common styles
textAlign: 'right',
Expand Down Expand Up @@ -111,13 +114,20 @@ var useStyles = (0, _styles.makeStyles)(function (theme) {
// Injecting these styles as a means of fixing up the search display
// Ideally, this CSS comes from Drupal and is removed from here...
headerContainer: (_headerContainer = {
// Added menu__link to more closely mimic Drupal site links.
'& .menu__link': {
fontSize: '1.1rem !important',
fontWeight: '700 !important'
},
'& .header__search': {
background: '#f5f6f7',
position: 'relative',
zIndex: 1,
transition: 'all 0.2s ease-in-out',
opacity: 1,
visibility: 'visible'
visibility: 'visible',
fontSize: '1.1rem' // Added, font sizes look bigger on Drupal site.

},
'& .header__search.visually-hidden': {
visibility: 'hidden',
Expand All @@ -141,13 +151,16 @@ var useStyles = (0, _styles.makeStyles)(function (theme) {
alignItems: 'center'
},
'& .header__search--inner > .header__search--title': {
fontWeight: '600 !important',
fontSize: '0.9rem !important',
fontWeight: '700 !important',
// Changed from 600 to match Drupal site.
fontSize: '1.2rem !important',
// Changed from 0.9 to match Drupal site.
margin: '0 2.6rem 0 0 !important'
}
}, _defineProperty(_headerContainer, theme.breakpoints.up('lg'), {
'& .header__search--inner > .header__search--title': {
fontSize: '1rem !important'
fontSize: '1.2rem !important' // Changed from 1.0 to match Drupal site.

}
}), _defineProperty(_headerContainer, '& .header__search--inner > .form-item', {
width: '100%',
Expand Down Expand Up @@ -416,11 +429,11 @@ var NeonHeader = /*#__PURE__*/(0, _react.forwardRef)(function (props, headerRef)
}
};
var html = renderMode === 'drupal' ? headerHTML : _drupalHeader.default;
return /*#__PURE__*/_react.default.createElement("header", {
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("header", {
ref: headerRef,
id: "header",
className: unstickyDrupalHeader ? "".concat(classes.unstickyHeader, " ").concat(classes.headerContainer) : classes.headerContainer
}, (0, _htmlReactParser.default)(html, injectAuth));
}, (0, _htmlReactParser.default)(html, injectAuth)), /*#__PURE__*/_react.default.createElement(_ApplicationMenu.default, null));
});
NeonHeader.propTypes = {
drupalCssLoaded: _propTypes.default.bool,
Expand Down
2 changes: 1 addition & 1 deletion lib/components/NeonPage/NeonPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ var isAtMaxScroll = function isAtMaxScroll() {
return scrollTop / trackLength >= 0.99;
}; // Google Tag Manager Data Layer
// Define if not already defined. This must be set in the public/index.html for any apps/pages that
// would seek top use it. More info: https://developers.google.com/tag-manager/devguide
// would seek to use it. More info: https://developers.google.com/tag-manager/devguide


if (!window.gtmDataLayer) {
Expand Down
2 changes: 1 addition & 1 deletion lib/remoteAssets/drupal-header.html.d.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/remoteAssets/drupal-header.html.js

Large diffs are not rendered by default.

Loading

0 comments on commit 3b9bb87

Please sign in to comment.