mirror of
https://github.com/a2nt/webpack-bootstrap-ui-kit.git
synced 2024-10-22 11:05:45 +02:00
FIX: Fallback page loading
This commit is contained in:
parent
7f9a0f9d7a
commit
4ffbfa5a01
@ -2,101 +2,103 @@ import Events from '../_events';
|
|||||||
|
|
||||||
import { cache } from './_apollo.cache';
|
import { cache } from './_apollo.cache';
|
||||||
import {
|
import {
|
||||||
from,
|
from,
|
||||||
ApolloClient,
|
ApolloClient,
|
||||||
HttpLink,
|
HttpLink,
|
||||||
ApolloLink,
|
ApolloLink,
|
||||||
concat,
|
concat,
|
||||||
} from '@apollo/client';
|
} from '@apollo/client';
|
||||||
|
|
||||||
import { onError } from '@apollo/client/link/error';
|
import { onError } from '@apollo/client/link/error';
|
||||||
const NAME = '_appolo';
|
const NAME = '_appolo';
|
||||||
|
|
||||||
const API_META = document.querySelector('meta[name="api_url"]');
|
const API_META = document.querySelector('meta[name="api_url"]');
|
||||||
const API_URL = API_META
|
const API_URL = API_META ?
|
||||||
? API_META.getAttribute('content')
|
API_META.getAttribute('content') :
|
||||||
: `${window.location.protocol }//${ window.location.host }/graphql`;
|
`${window.location.protocol }//${ window.location.host }/graphql`;
|
||||||
|
|
||||||
const authMiddleware = new ApolloLink((operation, forward) => {
|
const authMiddleware = new ApolloLink((operation, forward) => {
|
||||||
// add the authorization to the headers
|
// add the authorization to the headers
|
||||||
operation.setContext({
|
operation.setContext({
|
||||||
headers: {
|
headers: {
|
||||||
apikey: `${GRAPHQL_API_KEY}`,
|
apikey: `${GRAPHQL_API_KEY}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return forward(operation);
|
return forward(operation);
|
||||||
});
|
});
|
||||||
|
|
||||||
console.info(`%cAPI: ${API_URL}`, 'color:green;font-size:10px');
|
console.info(`%cAPI: ${API_URL}`, 'color:green;font-size:10px');
|
||||||
|
|
||||||
const link = from([
|
const link = from([
|
||||||
authMiddleware,
|
authMiddleware,
|
||||||
new ApolloLink((operation, forward) => {
|
new ApolloLink((operation, forward) => {
|
||||||
operation.setContext({ start: new Date() });
|
operation.setContext({ start: new Date() });
|
||||||
return forward(operation);
|
return forward(operation);
|
||||||
}),
|
}),
|
||||||
onError(({ operation, response, graphQLErrors, networkError, forward }) => {
|
onError(({ operation, response, graphQLErrors, networkError, forward }) => {
|
||||||
if (operation.operationName === 'IgnoreErrorsQuery') {
|
if (operation.operationName === 'IgnoreErrorsQuery') {
|
||||||
response.errors = null;
|
console.error(`${NAME}: IgnoreErrorsQuery`);
|
||||||
return;
|
response.errors = null;
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (graphQLErrors)
|
if (graphQLErrors) {
|
||||||
graphQLErrors.forEach(({ message, locations, path }) =>
|
graphQLErrors.forEach(({ message, locations, path }) =>
|
||||||
console.error(
|
console.error(
|
||||||
`${NAME}: [GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
|
`${NAME}: [GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (networkError) {
|
if (networkError) {
|
||||||
/*let msg = '';
|
/*let msg = '';
|
||||||
switch (networkError.statusCode) {
|
switch (networkError.statusCode) {
|
||||||
case 404:
|
case 404:
|
||||||
msg = 'Not Found.';
|
msg = 'Not Found.';
|
||||||
break;
|
break;
|
||||||
case 500:
|
case 500:
|
||||||
msg = 'Server issue, please try again latter.';
|
msg = 'Server issue, please try again latter.';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
msg = 'Something went wrong.';
|
msg = 'Something went wrong.';
|
||||||
break;
|
break;
|
||||||
}*/
|
}*/
|
||||||
|
console.error(`${NAME}: [Network error] ${networkError.statusCode}`);
|
||||||
|
}
|
||||||
|
|
||||||
console.error(`${NAME}: [Network error] ${networkError.statusCode}`);
|
console.error(`${NAME}: [APOLLO_ERROR]`);
|
||||||
|
window.dispatchEvent(new Event(Events.APOLLO_ERROR));
|
||||||
|
}),
|
||||||
|
new ApolloLink((operation, forward) => {
|
||||||
|
return forward(operation).map((data) => {
|
||||||
|
// data from a previous link
|
||||||
|
const time = new Date() - operation.getContext().start;
|
||||||
|
console.log(
|
||||||
|
`${NAME}: operation ${operation.operationName} took ${time} ms to complete`,
|
||||||
|
);
|
||||||
|
|
||||||
window.dispatchEvent(new Event(Events.OFFLINE));
|
window.dispatchEvent(new Event(Events.ONLINE));
|
||||||
}
|
return data;
|
||||||
}),
|
});
|
||||||
new ApolloLink((operation, forward) => {
|
}),
|
||||||
return forward(operation).map((data) => {
|
new HttpLink({
|
||||||
// data from a previous link
|
uri: API_URL,
|
||||||
const time = new Date() - operation.getContext().start;
|
|
||||||
console.log(
|
|
||||||
`${NAME}: operation ${operation.operationName} took ${time} ms to complete`,
|
|
||||||
);
|
|
||||||
|
|
||||||
window.dispatchEvent(new Event(Events.ONLINE));
|
// Use explicit `window.fetch` so tha outgoing requests
|
||||||
return data;
|
// are captured and deferred until the Service Worker is ready.
|
||||||
});
|
fetch: (...args) => fetch(...args),
|
||||||
}),
|
credentials: 'same-origin', //'include',
|
||||||
new HttpLink({
|
connectToDevTools: process.env.NODE_ENV === 'development' ? true : false,
|
||||||
uri: API_URL,
|
}),
|
||||||
|
|
||||||
// Use explicit `window.fetch` so tha outgoing requests
|
|
||||||
// are captured and deferred until the Service Worker is ready.
|
|
||||||
fetch: (...args) => fetch(...args),
|
|
||||||
credentials: 'same-origin', //'include',
|
|
||||||
connectToDevTools: process.env.NODE_ENV === 'development' ? true : false,
|
|
||||||
}),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Isolate Apollo client so it could be reused
|
// Isolate Apollo client so it could be reused
|
||||||
// in both application runtime and tests.
|
// in both application runtime and tests.
|
||||||
|
|
||||||
const client = new ApolloClient({
|
const client = new ApolloClient({
|
||||||
cache,
|
cache,
|
||||||
link,
|
link,
|
||||||
});
|
});
|
||||||
|
|
||||||
export { client };
|
export { client };
|
||||||
|
@ -9,192 +9,213 @@ import { Collapse } from 'bootstrap';
|
|||||||
import SpinnerUI from './_main.loading-spinner';
|
import SpinnerUI from './_main.loading-spinner';
|
||||||
|
|
||||||
const MainUILinks = ((W) => {
|
const MainUILinks = ((W) => {
|
||||||
const NAME = '_main.links';
|
const NAME = '_main.links';
|
||||||
const D = document;
|
const D = document;
|
||||||
const BODY = D.body;
|
const BODY = D.body;
|
||||||
|
|
||||||
class MainUILinks {
|
class MainUILinks {
|
||||||
static init() {
|
window
|
||||||
const ui = this;
|
static init() {
|
||||||
ui.GraphPage = null;
|
const ui = this;
|
||||||
|
ui.GraphPage = null;
|
||||||
|
|
||||||
console.log(`${NAME}: init`);
|
console.log(`${NAME}: init`);
|
||||||
|
|
||||||
ui.loaded();
|
ui.loaded();
|
||||||
|
|
||||||
// history state switch
|
// history state switch
|
||||||
W.addEventListener('popstate', (e) => {
|
W.addEventListener('popstate', (e) => {
|
||||||
ui.popState(e);
|
ui.popState(e);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
static loaded() {
|
|
||||||
const ui = this;
|
|
||||||
|
|
||||||
D.querySelectorAll('.graphql-page').forEach((el, i) => {
|
|
||||||
const el_id = el.getAttribute('href');
|
|
||||||
el.setAttribute(`data-${ui.name}-id`, el_id);
|
|
||||||
|
|
||||||
el.addEventListener('click', ui.loadClick);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static setActiveLinks(link) {
|
|
||||||
const ui = this;
|
|
||||||
D.querySelectorAll(`[data-${ui.name}-id="${link}"]`).forEach(
|
|
||||||
(el) => {
|
|
||||||
el.classList.add('active');
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static reset() {
|
|
||||||
// reset focus
|
|
||||||
D.activeElement.blur();
|
|
||||||
|
|
||||||
// remove active and loading classes
|
|
||||||
D.querySelectorAll('.graphql-page,.nav-item').forEach((el2) => {
|
|
||||||
el2.classList.remove('active', 'loading');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static popState(e) {
|
|
||||||
const ui = this;
|
|
||||||
|
|
||||||
SpinnerUI.show();
|
|
||||||
|
|
||||||
if (e.state && e.state.page) {
|
|
||||||
console.log(`${NAME}: [popstate] load`);
|
|
||||||
const state = JSON.parse(e.state.page);
|
|
||||||
|
|
||||||
state.current = null;
|
|
||||||
state.popstate = true;
|
|
||||||
|
|
||||||
ui.reset();
|
|
||||||
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'),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.GraphPage.setState(state);
|
static loaded() {
|
||||||
SpinnerUI.hide();
|
const ui = this;
|
||||||
|
|
||||||
window.dispatchEvent(new Event(Events.AJAX));
|
D.querySelectorAll('.graphql-page').forEach((el, i) => {
|
||||||
} else if (e.state && e.state.landing) {
|
const el_id = el.getAttribute('href');
|
||||||
console.log(`${NAME}: [popstate] go to landing`);
|
el.setAttribute(`data-${ui.name}-id`, el_id);
|
||||||
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
|
el.addEventListener('click', ui.loadClick);
|
||||||
static loadClick(e) {
|
});
|
||||||
console.groupCollapsed(`${NAME}: load on click`);
|
}
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const ui = MainUILinks;
|
static setActiveLinks(link) {
|
||||||
const el = e.currentTarget;
|
const ui = this;
|
||||||
|
D.querySelectorAll(`[data-${ui.name}-id="${link}"]`).forEach(
|
||||||
SpinnerUI.show();
|
(el) => {
|
||||||
|
el.classList.add('active');
|
||||||
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');
|
|
||||||
if (dropdowns.length) {
|
|
||||||
const DropdownInst = Dropdown.getInstance(dropdowns[0]);
|
|
||||||
DropdownInst.hide();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (!ui.GraphPage) {
|
|
||||||
ui.GraphPage = ReactDOM.render(
|
|
||||||
<Page />,
|
|
||||||
document.getElementById('MainContent'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const link = el.getAttribute('href') || el.getAttribute('data-href');
|
|
||||||
|
|
||||||
ui.GraphPage.state.current = el;
|
|
||||||
|
|
||||||
ui.GraphPage.load(link)
|
|
||||||
.then((response) => {
|
|
||||||
BODY.classList.remove('ajax-loading');
|
|
||||||
el.classList.remove('loading');
|
|
||||||
el.classList.add('active');
|
|
||||||
|
|
||||||
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,
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
ui.setActiveLinks(ui.GraphPage.state.Link)
|
static reset() {
|
||||||
}
|
// reset focus
|
||||||
|
D.activeElement.blur();
|
||||||
|
|
||||||
SpinnerUI.hide();
|
// remove active and loading classes
|
||||||
|
D.querySelectorAll('.graphql-page,.nav-item').forEach((el2) => {
|
||||||
|
el2.classList.remove('active', 'loading');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
window.dispatchEvent(new Event(Events.AJAX));
|
static popState(e) {
|
||||||
console.groupEnd(`${NAME}: load on click`);
|
const ui = this;
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.log(e);
|
|
||||||
|
|
||||||
BODY.classList.remove('ajax-loading');
|
SpinnerUI.show();
|
||||||
el.classList.remove('loading');
|
|
||||||
el.classList.add('error', `response-${e.status}`);
|
if (e.state && e.state.page) {
|
||||||
/*switch (e.status) {
|
console.log(`${NAME}: [popstate] load`);
|
||||||
case 404:
|
const state = JSON.parse(e.state.page);
|
||||||
el.classList.add('not-found');
|
|
||||||
break;
|
state.current = null;
|
||||||
case 523:
|
state.popstate = true;
|
||||||
el.classList.add('unreachable');
|
|
||||||
break;
|
ui.reset();
|
||||||
|
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'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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');
|
||||||
|
if (dropdowns.length) {
|
||||||
|
const DropdownInst = Dropdown.getInstance(dropdowns[0]);
|
||||||
|
DropdownInst.hide();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (!ui.GraphPage) {
|
||||||
|
ui.GraphPage = ReactDOM.render(
|
||||||
|
<Page />,
|
||||||
|
document.getElementById('MainContent'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const link = el.getAttribute('href') || el.getAttribute('data-href');
|
||||||
|
|
||||||
|
|
||||||
|
ui.GraphPage.state.current = el;
|
||||||
|
|
||||||
|
ui.GraphPage.load(link)
|
||||||
|
.then((response) => {
|
||||||
|
BODY.classList.remove('ajax-loading');
|
||||||
|
el.classList.remove('loading');
|
||||||
|
el.classList.add('active');
|
||||||
|
|
||||||
|
D.loading_apollo_link = null;
|
||||||
|
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
|
||||||
|
ui.setActiveLinks(ui.GraphPage.state.Link)
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinnerUI.hide();
|
||||||
|
|
||||||
|
window.dispatchEvent(new Event(Events.AJAX));
|
||||||
|
console.groupEnd(`${NAME}: load on click`);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.error(`${NAME}: loading error`);
|
||||||
|
console.log(e);
|
||||||
|
|
||||||
|
BODY.classList.remove('ajax-loading');
|
||||||
|
el.classList.remove('loading');
|
||||||
|
el.classList.add('error', `response-${e.status}`);
|
||||||
|
/*switch (e.status) {
|
||||||
|
case 500:
|
||||||
|
break;
|
||||||
|
case 404:
|
||||||
|
el.classList.add('not-found');
|
||||||
|
break;
|
||||||
|
case 523:
|
||||||
|
el.classList.add('unreachable');
|
||||||
|
break;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
SpinnerUI.hide();
|
SpinnerUI.hide();
|
||||||
|
|
||||||
window.dispatchEvent(new Event(Events.AJAX));
|
window.dispatchEvent(new Event(Events.AJAX));
|
||||||
console.groupEnd(`${NAME}: load on click`);
|
console.groupEnd(`${NAME}: load on click`);
|
||||||
});
|
|
||||||
|
console.log(`${NAME}: reloading page ${link}`);
|
||||||
|
|
||||||
|
// fallback loading
|
||||||
|
W.location.href = link;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
W.addEventListener(`${Events.LOADED}`, () => {
|
W.addEventListener(`${Events.LOADED}`, () => {
|
||||||
MainUILinks.init();
|
MainUILinks.init();
|
||||||
});
|
});
|
||||||
|
|
||||||
W.addEventListener(`${Events.AJAX}`, () => {
|
W.addEventListener(`${Events.AJAX}`, () => {
|
||||||
MainUILinks.loaded();
|
MainUILinks.loaded();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// fallback
|
||||||
|
/*W.addEventListener(`${Events.APOLLO_ERROR}`, (e) => {
|
||||||
|
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);
|
})(window);
|
||||||
|
|
||||||
export default MainUILinks;
|
export default MainUILinks;
|
||||||
|
@ -11,53 +11,53 @@ const D = document;
|
|||||||
const BODY = document.body;
|
const BODY = document.body;
|
||||||
|
|
||||||
class Page extends Component {
|
class Page extends Component {
|
||||||
state = {
|
state = {
|
||||||
type: [],
|
type: [],
|
||||||
shown: false,
|
shown: false,
|
||||||
Title: 'Loading ...',
|
Title: 'Loading ...',
|
||||||
loading: true,
|
loading: true,
|
||||||
error: false,
|
error: false,
|
||||||
current: null,
|
current: null,
|
||||||
ID: null,
|
ID: null,
|
||||||
URLSegment: null,
|
URLSegment: null,
|
||||||
ClassName: 'Page',
|
ClassName: 'Page',
|
||||||
CSSClass: null,
|
CSSClass: null,
|
||||||
Summary: null,
|
Summary: null,
|
||||||
Link: null,
|
Link: null,
|
||||||
URL: null,
|
URL: null,
|
||||||
HTML: null,
|
HTML: null,
|
||||||
Elements: [],
|
Elements: [],
|
||||||
page: null,
|
page: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
const ui = this;
|
const ui = this;
|
||||||
|
|
||||||
if (ui.state.Title) {
|
if (ui.state.Title) {
|
||||||
document.title = ui.state.Title;
|
document.title = ui.state.Title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
const ui = this;
|
const ui = this;
|
||||||
|
|
||||||
ui.name = ui.constructor.name;
|
ui.name = ui.constructor.name;
|
||||||
ui.empty_state = ui.state;
|
ui.empty_state = ui.state;
|
||||||
|
|
||||||
console.log(`${ui.name}: init`);
|
console.log(`${ui.name}: init`);
|
||||||
}
|
}
|
||||||
|
|
||||||
isOnline = () => {
|
isOnline = () => {
|
||||||
return BODY.classList.contains('is-online');
|
return BODY.classList.contains('is-online');
|
||||||
};
|
};
|
||||||
|
|
||||||
load = (link) => {
|
load = (link) => {
|
||||||
const ui = this;
|
const ui = this;
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const query = gql(`query Pages {
|
const query = gql(`query Pages {
|
||||||
readPages(Link: "${link}") {
|
readPages(Link: "${link}") {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
@ -76,133 +76,135 @@ class Page extends Component {
|
|||||||
}
|
}
|
||||||
}`);
|
}`);
|
||||||
|
|
||||||
if (!ui.isOnline()) {
|
if (!ui.isOnline()) {
|
||||||
const data = client.readQuery({ query });
|
const data = client.readQuery({ query });
|
||||||
|
|
||||||
if (data && ui.processResponse(data)) {
|
if (data && ui.processResponse(data)) {
|
||||||
console.log(`${ui.name}: Offline cached response`);
|
console.log(`${ui.name}: Offline cached response`);
|
||||||
resolve(data);
|
resolve(data);
|
||||||
} else {
|
} else {
|
||||||
console.log(`${ui.name}: No offline response`);
|
console.log(`${ui.name}: No offline response`);
|
||||||
|
|
||||||
ui.setState(
|
ui.setState(
|
||||||
Object.assign(ui.empty_state, {
|
Object.assign(ui.empty_state, {
|
||||||
Title: 'Offline',
|
Title: 'Offline',
|
||||||
CSSClass: 'graphql__status-523',
|
CSSClass: 'graphql__status-523',
|
||||||
Summary:
|
Summary: "You're Offline. The page is not available now.",
|
||||||
"You're Offline. The page is not available now.",
|
loading: false,
|
||||||
loading: false,
|
}),
|
||||||
}),
|
);
|
||||||
);
|
|
||||||
|
|
||||||
reject({ status: 523 });
|
reject({ status: 523 });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!ui.state.loading) {
|
if (!ui.state.loading) {
|
||||||
ui.setState(ui.empty_state);
|
ui.setState(ui.empty_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
client
|
client
|
||||||
.query({
|
.query({
|
||||||
query: query,
|
query: query,
|
||||||
fetchPolicy: ui.isOnline() ? 'no-cache' : 'cache-first',
|
fetchPolicy: ui.isOnline() ? 'no-cache' : 'cache-first',
|
||||||
})
|
})
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
// write to cache
|
// write to cache
|
||||||
const data = resp.data;
|
const data = resp.data;
|
||||||
client.writeQuery({ query, data: data });
|
client.writeQuery({ query, data: data });
|
||||||
|
|
||||||
if (ui.processResponse(data)) {
|
if (ui.processResponse(data)) {
|
||||||
console.log(`${ui.name}: got the server response`);
|
console.log(`${ui.name}: got the server response`);
|
||||||
resolve(data);
|
resolve(data);
|
||||||
} else {
|
} else {
|
||||||
console.log(`${ui.name}: not found`);
|
console.log(`${ui.name}: not found`);
|
||||||
reject({ status: 404 });
|
reject({ status: 404 });
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
.catch((error) => {
|
||||||
});
|
reject({ status: 500, error: error });
|
||||||
};
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
processResponse = (data) => {
|
processResponse = (data) => {
|
||||||
const ui = this;
|
const ui = this;
|
||||||
|
|
||||||
if (!data.readPages.edges.length) {
|
if (!data.readPages.edges.length) {
|
||||||
console.log(`${ui.name}: not found`);
|
console.log(`${ui.name}: not found`);
|
||||||
|
|
||||||
ui.setState(
|
ui.setState(
|
||||||
Object.assign(ui.empty_state, {
|
Object.assign(ui.empty_state, {
|
||||||
Title: 'Not Found',
|
Title: 'Not Found',
|
||||||
CSSClass: 'graphql__status-404',
|
CSSClass: 'graphql__status-404',
|
||||||
Summary: 'The page is not found.',
|
Summary: 'The page is not found.',
|
||||||
loading: false,
|
loading: false,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const page = data.readPages.edges[0].node;
|
const page = data.readPages.edges[0].node;
|
||||||
ui.setState({
|
ui.setState({
|
||||||
ID: page.ID,
|
ID: page.ID,
|
||||||
Title: page.Title,
|
Title: page.Title,
|
||||||
ClassName: page.ClassName,
|
ClassName: page.ClassName,
|
||||||
URLSegment: page.URLSegment,
|
URLSegment: page.URLSegment,
|
||||||
CSSClass: page.CSSClass,
|
CSSClass: page.CSSClass,
|
||||||
Summary: page.Summary,
|
Summary: page.Summary,
|
||||||
Link: page.Link,
|
Link: page.Link,
|
||||||
HTML: page.HTML,
|
HTML: page.HTML,
|
||||||
Elements: [],//page.Elements.edges,
|
Elements: [], //page.Elements.edges,
|
||||||
loading: false,
|
loading: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
getHtml = (html) => {
|
getHtml = (html) => {
|
||||||
const decodeHtmlEntity = (input) => {
|
const decodeHtmlEntity = (input) => {
|
||||||
var doc = new DOMParser().parseFromString(input, 'text/html');
|
var doc = new DOMParser().parseFromString(input, 'text/html');
|
||||||
return doc.documentElement.textContent;
|
return doc.documentElement.textContent;
|
||||||
};
|
};
|
||||||
|
|
||||||
return { __html: decodeHtmlEntity(html) };
|
return { __html: decodeHtmlEntity(html) };
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const ui = this;
|
const ui = this;
|
||||||
const name = ui.name;
|
const name = ui.name;
|
||||||
const className = `elemental-area graphql__page page-${ui.state.CSSClass} url-${ui.state.URLSegment}`;
|
const className = `elemental-area graphql__page page-${ui.state.CSSClass} url-${ui.state.URLSegment}`;
|
||||||
|
|
||||||
const ElementItem = (props) => (
|
const ElementItem = (props) => (
|
||||||
<div dangerouslySetInnerHTML={props.html}></div>
|
<div dangerouslySetInnerHTML={props.html}></div>
|
||||||
);
|
);
|
||||||
|
|
||||||
let html = '';
|
let html = '';
|
||||||
if(ui.state.HTML) {
|
if (ui.state.HTML) {
|
||||||
console.log(`${ui.name}: HTML only`);
|
console.log(`${ui.name}: HTML only`);
|
||||||
html = ui.state.HTML;
|
html = ui.state.HTML;
|
||||||
}else if (ui.state.Elements.length) {
|
} else if (ui.state.Elements.length) {
|
||||||
console.log(`${ui.name}: render`);
|
console.log(`${ui.name}: render`);
|
||||||
ui.state.Elements.map((el) => {
|
ui.state.Elements.map((el) => {
|
||||||
html += el.node.Render;
|
html += el.node.Render;
|
||||||
});
|
});
|
||||||
} else if (ui.state.Summary && ui.state.Summary.length) {
|
} else if (ui.state.Summary && ui.state.Summary.length) {
|
||||||
console.log(`${ui.name}: summary only`);
|
console.log(`${ui.name}: summary only`);
|
||||||
html = `<div class="summary">${ui.state.Summary}</div>`;
|
html = `<div class="summary">${ui.state.Summary}</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ui.state.loading){
|
if (ui.state.loading) {
|
||||||
const spinner = D.getElementById('PageLoading');
|
const spinner = D.getElementById('PageLoading');
|
||||||
html = `<div class="loading">Loading ...</div>`;
|
html = `<div class="loading">Loading ...</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={className}
|
className={className}
|
||||||
dangerouslySetInnerHTML={ui.getHtml(html)}
|
dangerouslySetInnerHTML={ui.getHtml(html)}
|
||||||
></div>
|
></div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Page;
|
export default Page;
|
||||||
|
@ -3,41 +3,42 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
AJAX: 'ajax-load',
|
APOLLO_ERROR: 'apollo-error',
|
||||||
AJAXMAIN: 'ajax-main-load',
|
AJAX: 'ajax-load',
|
||||||
MAININIT: 'main-init',
|
AJAXMAIN: 'ajax-main-load',
|
||||||
TABHIDDEN: 'tab-hidden',
|
MAININIT: 'main-init',
|
||||||
TABFOCUSED: 'tab-focused',
|
TABHIDDEN: 'tab-hidden',
|
||||||
OFFLINE: 'offline',
|
TABFOCUSED: 'tab-focused',
|
||||||
ONLINE: 'online',
|
OFFLINE: 'offline',
|
||||||
BACKONLINE: 'back-online',
|
ONLINE: 'online',
|
||||||
TOUCHENABLE: 'touch-enabled',
|
BACKONLINE: 'back-online',
|
||||||
TOUCHDISABLED: 'touch-disabled',
|
TOUCHENABLE: 'touch-enabled',
|
||||||
LOADED: 'load',
|
TOUCHDISABLED: 'touch-disabled',
|
||||||
SWIPELEFT: 'swipeleft panleft',
|
LOADED: 'load',
|
||||||
SWIPERIGHT: 'swiperight panright',
|
SWIPELEFT: 'swipeleft panleft',
|
||||||
ALLERTAPPEARED: 'alert-appeared',
|
SWIPERIGHT: 'swiperight panright',
|
||||||
ALERTREMOVED: 'alert-removed',
|
ALLERTAPPEARED: 'alert-appeared',
|
||||||
LODEDANDREADY: 'load-ready',
|
ALERTREMOVED: 'alert-removed',
|
||||||
LAZYIMAGEREADY: 'image-lazy-bg-loaded',
|
LODEDANDREADY: 'load-ready',
|
||||||
LAZYIMAGESREADY: 'images-lazy-loaded',
|
LAZYIMAGEREADY: 'image-lazy-bg-loaded',
|
||||||
MAPLOADED: 'map-loaded',
|
LAZYIMAGESREADY: 'images-lazy-loaded',
|
||||||
MAPAPILOADED: 'map-api-loaded',
|
MAPLOADED: 'map-loaded',
|
||||||
MAPMARKERCLICK: 'map-marker-click',
|
MAPAPILOADED: 'map-api-loaded',
|
||||||
MAPPOPUPCLOSE: 'map-popup-close',
|
MAPMARKERCLICK: 'map-marker-click',
|
||||||
SCROLL: 'scroll',
|
MAPPOPUPCLOSE: 'map-popup-close',
|
||||||
RESIZE: 'resize',
|
SCROLL: 'scroll',
|
||||||
CAROUSEL_READY: 'bs.carousel.ready',
|
RESIZE: 'resize',
|
||||||
SET_TARGET_UPDATE: 'set-target-update',
|
CAROUSEL_READY: 'bs.carousel.ready',
|
||||||
RESTORE_FIELD: 'restore-field',
|
SET_TARGET_UPDATE: 'set-target-update',
|
||||||
FORM_INIT_BASICS: 'form-basics',
|
RESTORE_FIELD: 'restore-field',
|
||||||
FORM_INIT_STEPPED: 'form-init-stepped',
|
FORM_INIT_BASICS: 'form-basics',
|
||||||
FORM_INIT_VALIDATE: 'form-init-validate',
|
FORM_INIT_STEPPED: 'form-init-stepped',
|
||||||
FORM_INIT_VALIDATE_FIELD: 'form-init-validate-field',
|
FORM_INIT_VALIDATE: 'form-init-validate',
|
||||||
FORM_INIT_STORAGE: 'form-init-storage',
|
FORM_INIT_VALIDATE_FIELD: 'form-init-validate-field',
|
||||||
FORM_VALIDATION_FAILED: 'form-validation-failed',
|
FORM_INIT_STORAGE: 'form-init-storage',
|
||||||
FORM_STEPPED_NEW_STEP: 'form-new-step',
|
FORM_VALIDATION_FAILED: 'form-validation-failed',
|
||||||
FORM_STEPPED_FIRST_STEP: 'form-first-step',
|
FORM_STEPPED_NEW_STEP: 'form-new-step',
|
||||||
FORM_STEPPED_LAST_STEP: 'form-last-step',
|
FORM_STEPPED_FIRST_STEP: 'form-first-step',
|
||||||
FORM_FIELDS: 'input,textarea,select',
|
FORM_STEPPED_LAST_STEP: 'form-last-step',
|
||||||
|
FORM_FIELDS: 'input,textarea,select',
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user