225 lines
5.0 KiB
JavaScript
225 lines
5.0 KiB
JavaScript
/*
|
|
* page #MainContent area
|
|
*/
|
|
import { Component } from "react";
|
|
|
|
import { useQuery, gql } from "@apollo/client";
|
|
import { client } from "../apollo/init";
|
|
import { cache } from "../apollo/cache";
|
|
|
|
const D = document;
|
|
const BODY = document.body;
|
|
|
|
class Page extends Component {
|
|
state = {
|
|
type: [],
|
|
shown: false,
|
|
Title: "Loading ...",
|
|
loading: true,
|
|
error: false,
|
|
current: null,
|
|
ID: null,
|
|
URLSegment: null,
|
|
ClassName: "Page",
|
|
CSSClass: null,
|
|
Summary: null,
|
|
Link: null,
|
|
URL: null,
|
|
HTML: null,
|
|
Elements: [],
|
|
page: null,
|
|
};
|
|
|
|
componentDidUpdate() {
|
|
const ui = this;
|
|
|
|
if (ui.state.Title) {
|
|
document.title = ui.state.Title;
|
|
}
|
|
}
|
|
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
const ui = this;
|
|
|
|
ui.name = ui.constructor.name;
|
|
ui.empty_state = ui.state;
|
|
|
|
console.log(`${ui.name}: init`);
|
|
}
|
|
|
|
isOnline = () => {
|
|
return BODY.classList.contains("is-online");
|
|
};
|
|
|
|
load = (link) => {
|
|
const ui = this;
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const query = gql(`query Pages {
|
|
readPages(Link: "${link}") {
|
|
edges {
|
|
node {
|
|
__typename
|
|
_id
|
|
ID
|
|
Title
|
|
ClassName
|
|
CSSClass
|
|
Summary
|
|
Link
|
|
URLSegment
|
|
HTML
|
|
}
|
|
}
|
|
}
|
|
}`);
|
|
|
|
if (!ui.isOnline()) {
|
|
const data = client.readQuery({
|
|
query,
|
|
});
|
|
|
|
if (data && ui.processResponse(data)) {
|
|
console.log(`${ui.name}: Offline cached response`);
|
|
resolve(data);
|
|
} else {
|
|
console.log(`${ui.name}: No offline response`);
|
|
|
|
ui.setState(
|
|
Object.assign(ui.empty_state, {
|
|
Title: "Offline",
|
|
CSSClass: "graphql__status-523",
|
|
Summary: "You're Offline. The page is not available now.",
|
|
loading: false,
|
|
})
|
|
);
|
|
|
|
reject({
|
|
status: 523,
|
|
});
|
|
}
|
|
} else {
|
|
if (!ui.state.loading) {
|
|
ui.setState(ui.empty_state);
|
|
}
|
|
|
|
client
|
|
.query({
|
|
query: query,
|
|
fetchPolicy: ui.isOnline() ? "no-cache" : "cache-first",
|
|
})
|
|
.then((resp) => {
|
|
// write to cache
|
|
const data = resp.data;
|
|
client.writeQuery({
|
|
query,
|
|
data: data,
|
|
});
|
|
|
|
if (ui.processResponse(data)) {
|
|
console.log(`${ui.name}: got the server response`);
|
|
resolve(data);
|
|
} else {
|
|
console.log(`${ui.name}: not found`);
|
|
reject({
|
|
status: 404,
|
|
});
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
reject({
|
|
status: 500,
|
|
error: error,
|
|
});
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
processResponse = (data) => {
|
|
const ui = this;
|
|
|
|
if (!data.readPages.edges.length) {
|
|
console.log(`${ui.name}: not found`);
|
|
|
|
ui.setState(
|
|
Object.assign(ui.empty_state, {
|
|
Title: "Not Found",
|
|
CSSClass: "graphql__status-404",
|
|
Summary: "The page is not found.",
|
|
loading: false,
|
|
})
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
const page = data.readPages.edges[0].node;
|
|
ui.setState({
|
|
ID: page.ID,
|
|
Title: page.Title,
|
|
ClassName: page.ClassName,
|
|
URLSegment: page.URLSegment,
|
|
CSSClass: page.CSSClass,
|
|
Summary: page.Summary,
|
|
Link: page.Link,
|
|
HTML: page.HTML,
|
|
Elements: [], //page.Elements.edges,
|
|
loading: false,
|
|
});
|
|
|
|
return true;
|
|
};
|
|
|
|
getHtml = (html) => {
|
|
const decodeHtmlEntity = (input) => {
|
|
var doc = new DOMParser().parseFromString(input, "text/html");
|
|
return doc.documentElement.textContent;
|
|
};
|
|
|
|
return {
|
|
__html: decodeHtmlEntity(html),
|
|
};
|
|
};
|
|
|
|
render() {
|
|
const ui = this;
|
|
const name = ui.name;
|
|
const className = `elemental-area graphql__page page-${ui.state.CSSClass} url-${ui.state.URLSegment}`;
|
|
|
|
const ElementItem = (props) => (
|
|
<div dangerouslySetInnerHTML={props.html}></div>
|
|
);
|
|
|
|
let html = "";
|
|
if (ui.state.HTML) {
|
|
console.log(`${ui.name}: HTML only`);
|
|
html = ui.state.HTML;
|
|
} else if (ui.state.Elements.length) {
|
|
console.log(`${ui.name}: render`);
|
|
ui.state.Elements.map((el) => {
|
|
html += el.node.Render;
|
|
});
|
|
} else if (ui.state.Summary && ui.state.Summary.length) {
|
|
console.log(`${ui.name}: summary only`);
|
|
html = `<div class="summary">${ui.state.Summary}</div>`;
|
|
}
|
|
|
|
if (ui.state.loading) {
|
|
const spinner = D.getElementById("PageLoading");
|
|
html = `<div class="loading">Loading ...</div>`;
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className={className}
|
|
dangerouslySetInnerHTML={ui.getHtml(html)}
|
|
></div>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default Page;
|