webpack-bootstrap-ui-kit/src/js/ajax/models/page.jsx

225 lines
4.9 KiB
React
Raw Normal View History

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