webpack-bootstrap-ui-kit/src/js/_components/_main.links.js

222 lines
6.3 KiB
JavaScript
Raw Normal View History

// browser tab visibility state detection
import Events from '../_events';
import Consts from '../_consts';
import Page from './_page.jsx';
2021-02-21 08:05:58 +01:00
import { getParents } from './_main.funcs';
import { Collapse } from 'bootstrap';
import SpinnerUI from './_main.loading-spinner';
const MainUILinks = ((W) => {
2021-03-30 07:43:22 +02:00
const NAME = '_main.links';
const D = document;
const BODY = D.body;
2021-03-30 07:43:22 +02:00
class MainUILinks {
2021-03-30 07:37:02 +02:00
window
static init() {
2021-03-30 07:43:22 +02:00
const ui = this;
ui.GraphPage = null;
2021-03-30 07:43:22 +02:00
console.log(`${NAME}: init`);
2021-03-30 07:43:22 +02:00
ui.loaded();
2021-03-30 07:43:22 +02:00
// history state switch
W.addEventListener('popstate', (e) => {
ui.popState(e);
});
2021-03-30 07:37:02 +02:00
}
2021-03-30 07:37:02 +02:00
static loaded() {
2021-03-30 07:43:22 +02:00
const ui = this;
2021-03-30 07:43:22 +02:00
D.querySelectorAll('.graphql-page').forEach((el, i) => {
const el_id = el.getAttribute('href');
el.setAttribute(`data-${ui.name}-id`, el_id);
2021-03-30 07:43:22 +02:00
el.addEventListener('click', ui.loadClick);
});
2021-03-30 07:37:02 +02:00
}
2021-03-30 07:37:02 +02:00
static setActiveLinks(link) {
2021-03-30 07:43:22 +02:00
const ui = this;
D.querySelectorAll(`[data-${ui.name}-id="${link}"]`).forEach(
(el) => {
el.classList.add('active');
},
);
2021-03-30 07:37:02 +02:00
}
2021-03-30 07:37:02 +02:00
static reset() {
2021-03-30 07:43:22 +02:00
// reset focus
D.activeElement.blur();
2021-02-21 08:05:58 +01:00
2021-03-30 07:43:22 +02:00
// remove active and loading classes
D.querySelectorAll('.graphql-page,.nav-item').forEach((el2) => {
el2.classList.remove('active', 'loading');
});
2021-03-30 07:37:02 +02:00
}
2021-03-30 07:37:02 +02:00
static popState(e) {
2021-03-30 07:43:22 +02:00
const ui = this;
2021-02-24 12:50:25 +01:00
2021-03-30 07:43:22 +02:00
SpinnerUI.show();
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
if (e.state && e.state.page) {
console.log(`${NAME}: [popstate] load`);
const state = JSON.parse(e.state.page);
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
state.current = null;
state.popstate = true;
2021-03-30 07:37:02 +02:00
ui.reset();
2021-03-30 07:43:22 +02:00
ui.setActiveLinks(e.state.link);
if (!ui.GraphPage) {
console.log(
`${NAME}: [popstate] GraphPage is missing. Have to render it first`,
);
ui.GraphPage = ReactDOM.render(
<Page />,
document.getElementById('MainContent'),
);
2021-03-30 07:37:02 +02:00
}
2021-03-30 07:43:22 +02:00
ui.GraphPage.setState(state);
SpinnerUI.hide();
window.dispatchEvent(new Event(Events.AJAX));
} else if (e.state && e.state.landing) {
console.log(`${NAME}: [popstate] go to landing`);
W.location.href = e.state.landing;
} else {
console.warn(`${NAME}: [popstate] state is missing`);
console.log(e);
SpinnerUI.hide();
}
}
// link specific event {this} = current event, not MainUILinks
static loadClick(e) {
console.groupCollapsed(`${NAME}: load on click`);
e.preventDefault();
const ui = MainUILinks;
const el = e.currentTarget;
SpinnerUI.show();
ui.reset();
el.classList.add('loading');
el.classList.remove('response-404', 'response-500', 'response-523');
BODY.classList.add('ajax-loading');
// hide parent mobile nav
const navs = getParents(el, '.collapse');
if (navs.length) {
navs.forEach((nav) => {
const collapseInst = Collapse.getInstance(nav);
if (collapseInst) {
collapseInst.hide();
}
});
}
// hide parent dropdown
/*const dropdowns = getParents(el, '.dropdown-menu');
2021-03-30 07:37:02 +02:00
if (dropdowns.length) {
const DropdownInst = Dropdown.getInstance(dropdowns[0]);
DropdownInst.hide();
}*/
2021-03-30 07:43:22 +02:00
if (!ui.GraphPage) {
ui.GraphPage = ReactDOM.render(
<Page />,
document.getElementById('MainContent'),
);
}
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
const link = el.getAttribute('href') || el.getAttribute('data-href');
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
ui.GraphPage.state.current = el;
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
ui.GraphPage.load(link)
.then((response) => {
BODY.classList.remove('ajax-loading');
el.classList.remove('loading');
el.classList.add('active');
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
D.loading_apollo_link = null;
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
if (ui.GraphPage.state.Link) {
window.history.pushState({
page: JSON.stringify(ui.GraphPage.state),
link: el.getAttribute(`data-${ui.name}-id`),
},
ui.GraphPage.state.Title,
ui.GraphPage.state.Link,
);
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
ui.setActiveLinks(ui.GraphPage.state.Link)
}
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
SpinnerUI.hide();
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
window.dispatchEvent(new Event(Events.AJAX));
console.groupEnd(`${NAME}: load on click`);
})
.catch((e) => {
console.error(`${NAME}: loading error`);
console.log(e);
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
/*BODY.classList.remove('ajax-loading');
el.classList.remove('loading');*/
el.classList.add('error', `response-${e.status}`);
/*switch (e.status) {
2021-03-30 07:37:02 +02:00
case 500:
break;
case 404:
el.classList.add('not-found');
break;
case 523:
el.classList.add('unreachable');
break;
2021-02-24 12:49:40 +01:00
}*/
2021-03-30 07:43:22 +02:00
//SpinnerUI.hide();
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
//window.dispatchEvent(new Event(Events.AJAX));
console.groupEnd(`${NAME}: load on click`);
2021-02-24 12:49:40 +01:00
2021-03-30 07:43:22 +02:00
console.log(`${NAME}: reloading page ${link}`);
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
// fallback loading
W.location.href = link;
});
2021-03-30 07:37:02 +02:00
}
2021-03-30 07:43:22 +02:00
}
2021-03-30 07:43:22 +02:00
W.addEventListener(`${Events.LOADED}`, () => {
MainUILinks.init();
});
2021-03-30 07:43:22 +02:00
W.addEventListener(`${Events.AJAX}`, () => {
MainUILinks.loaded();
});
2021-03-30 07:37:02 +02:00
2021-03-30 07:43:22 +02:00
// fallback
/*W.addEventListener(`${Events.APOLLO_ERROR}`, (e) => {
2021-03-30 07:37:02 +02:00
console.error(`${NAME}: [APOLLO_ERROR] loading failure, reloading the page`);
//W.dispatchEvent(new Event(Events.OFFLINE));
if (D.loading_apollo_link) {
W.location.href = D.loading_apollo_link;
}
});*/
})(window);
export default MainUILinks;