Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions core/src/client/ProductNavigation/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
* Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
*/
import React from 'react';
import { createRoot } from 'react-dom/client';
import { createRoot, Root } from 'react-dom/client';
import { App } from '@labkey/api';

import { AppContext, ProductNavigation } from './ProductNavigation';

let root: Root;

App.registerApp<AppContext>('productNavigation', (target, ctx) => {
createRoot(document.getElementById(target)).render(<ProductNavigation context={ctx} />);
if (!root) root = createRoot(document.getElementById(target));
root.render(<ProductNavigation context={ctx} />);
});
4 changes: 3 additions & 1 deletion core/src/org/labkey/core/view/template/bootstrap/header.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,9 @@
<i class="fa fa-th-large" style="font-size: 18px; padding-top: 2px;"></i>
</a>
<ul class="dropdown-menu dropdown-menu-right">
<div id="headerProductDropdown-content"></div>
<li id="headerProductDropdown-content">
<div role="status" style="padding: 10px;"><i aria-hidden="true" class="fa fa-spinner fa-pulse"></i> Loading...</div>
</li>
</ul>
</li>
<%
Expand Down
56 changes: 31 additions & 25 deletions core/webapp/core/ProductNavigationHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,44 @@
*/
(function ($)
{
var HEADER_ID_PREFIX = 'headerProductDropdown';
var HEADER_CONTENT_ID = HEADER_ID_PREFIX + '-content';
const HEADER_ID_PREFIX = 'headerProductDropdown';
const HEADER_CONTENT_ID = HEADER_ID_PREFIX + '-content';
let scriptRequested = false;
let scriptLoaded = false;
let menuOpen = false;

// wait to load the product navigation dependencies until the hover over the header icon
var productNavLoaded = false;
$(document).on('mouseenter', '#' + HEADER_ID_PREFIX + ' .dropdown-toggle', function(e) {
if (!productNavLoaded) {
$("#" + HEADER_CONTENT_ID).html("<div style=\"padding: 10px;\"><i class=\"fa fa-spinner fa-pulse\"></i> Loading...</div>");
function showProductMenu(show) {
LABKEY.App.loadApp('productNavigation', HEADER_CONTENT_ID, { show });
}

LABKEY.requiresScript('gen/productNavigation', loadProductNav);
// LABKEY.requiresScript('http://localhost:3001/productNavigation.js', loadProductNav);
} else {
loadProductNav();
}
function onLoad() {
scriptLoaded = true;
if (menuOpen) showProductMenu(true);
}

function requireProductNav() {
if (scriptRequested) return;
scriptRequested = true;
LABKEY.requiresScript('gen/productNavigation', onLoad);
// LABKEY.requiresScript('http://localhost:3001/productNavigation.js', onLoad);
}

// preload on hover/focus so the menu is usually ready by the time it opens
$(document).on('mouseenter focusin', '#' + HEADER_ID_PREFIX + ' .dropdown-toggle', requireProductNav);

$(document).on('show.bs.dropdown', '#' + HEADER_ID_PREFIX, function () {
menuOpen = true;
requireProductNav();
if (scriptLoaded) showProductMenu(true);
});

var loadProductNav = function() {
LABKEY.App.loadApp('productNavigation', HEADER_CONTENT_ID, { show: true });
$(document).on('click', addProductNavClickHandler);
productNavLoaded = true;
};
$(document).on('hidden.bs.dropdown', '#' + HEADER_ID_PREFIX, function () {
menuOpen = false;
if (scriptLoaded) showProductMenu(false);
});

// stop the product navigation menu from closing when click within the menu div
$(document).on('click', '#' + HEADER_CONTENT_ID, function (e) {
e.stopPropagation();
});

// on click outside of the open menu, remove click handler and hide menu (which will force it to reset on next open)
var addProductNavClickHandler = function (e) {
if ($(e.target).closest(HEADER_CONTENT_ID).length === 0) {
LABKEY.App.loadApp('productNavigation', HEADER_CONTENT_ID, { show: false });
$(document).off('click', addProductNavClickHandler);
}
};
})(jQuery);
Loading