2022-07-22 02:18:04 +02:00
import parse from 'html-react-parser' ;
import { ReactElement } from 'react' ;
2019-12-18 23:54:23 +01:00
import { SilverstripeDocument } from '../types' ;
2019-11-08 03:40:20 +01:00
import sortFiles from './sortFiles' ;
2019-12-18 23:54:23 +01:00
let __nodes : SilverstripeDocument [ ] ;
2019-11-12 04:09:29 +01:00
let __currentVersion : string | null = null ;
2019-12-18 23:54:23 +01:00
let __path : string | null = null ;
2019-11-08 03:40:20 +01:00
2019-12-18 23:54:23 +01:00
const homeMap = new Map ( ) ;
2019-11-08 03:40:20 +01:00
const childrenMap = new Map ( ) ;
const navChildrenMap = new Map ( ) ;
const siblingMap = new Map ( ) ;
const parentMap = new Map ( ) ;
2019-12-18 23:54:23 +01:00
const nodeMap = new Map ( ) ;
/ * *
* Hydrate these functions with the list of all nodes
* @param nodes
* /
const initialise = ( nodes : SilverstripeDocument [ ] ) = > __nodes = nodes ;
2019-11-08 03:40:20 +01:00
2019-11-19 04:29:29 +01:00
/ * *
* Get all documents in the source
* /
2019-12-18 23:54:23 +01:00
const getNodes = ( ) : SilverstripeDocument [ ] = > __nodes ;
2019-11-08 03:40:20 +01:00
2019-11-19 04:29:29 +01:00
/ * *
* Get the children of a given node
2019-11-20 22:26:11 +01:00
*
2019-11-19 04:29:29 +01:00
* @param node
2019-11-20 22:26:11 +01:00
* @param includeFolders
2019-11-19 04:29:29 +01:00
* /
2019-11-08 03:40:20 +01:00
const getChildren = (
node : SilverstripeDocument ,
includeFolders : boolean = true
) : SilverstripeDocument [ ] = > {
const sku = ` ${ node . slug } ${ includeFolders ? '1' : '0' } ` ;
if ( childrenMap . has ( sku ) ) {
return childrenMap . get ( sku ) ;
}
const nodes = getNodes ( ) ;
let children : SilverstripeDocument [ ] = [ ] ;
if ( node . isIndex ) {
children = nodes . filter ( n = > {
return n . parentSlug === node . slug && ( includeFolders || ! n . isIndex ) ;
} ) . sort ( sortFiles ) ;
}
childrenMap . set ( sku , children ) ;
return childrenMap . get ( sku ) ;
}
2019-11-19 04:29:29 +01:00
/ * *
* Get children of a given node that should be shown in navigation
2019-11-20 22:26:11 +01:00
*
* @param node
2019-11-19 04:29:29 +01:00
* /
2019-11-08 03:40:20 +01:00
const getNavChildren = ( node : SilverstripeDocument ) : SilverstripeDocument [ ] = > {
if ( navChildrenMap . has ( node . slug ) ) {
return navChildrenMap . get ( node . slug ) ;
}
let children : SilverstripeDocument [ ] = [ ] ;
if ( ! node . hideChildren ) {
children = getChildren ( node , true ) . filter ( n = > ! n . hideSelf ) ;
}
2019-11-20 22:26:11 +01:00
getChildren ( node , true ) . filter ( n = > n . unhideSelf ) . forEach ( c = > children . push ( c ) ) ;
2019-11-08 03:40:20 +01:00
navChildrenMap . set ( node . slug , children ) ;
return navChildrenMap . get ( node . slug ) ;
} ;
2019-11-19 04:29:29 +01:00
/ * *
* Get the siblings of a given node
2019-11-20 22:26:11 +01:00
*
* @param node
2019-11-19 04:29:29 +01:00
* /
2019-11-20 22:26:11 +01:00
const getSiblings = ( node : SilverstripeDocument ) : SilverstripeDocument [ ] = > {
2019-11-08 03:40:20 +01:00
if ( siblingMap . has ( node . slug ) ) {
return siblingMap . get ( node . slug ) ;
}
const nodes = getNodes ( ) ;
const siblings = nodes . filter ( n = > n . parentSlug === node . parentSlug ) ;
siblingMap . set ( node . slug , siblings ) ;
return siblingMap . get ( node . slug ) ;
} ;
2019-11-19 04:29:29 +01:00
/ * *
* Get the parent of a given node
2019-11-20 22:26:11 +01:00
* @param node
2019-11-19 04:29:29 +01:00
* /
2019-11-08 03:40:20 +01:00
const getParent = ( node : SilverstripeDocument ) : SilverstripeDocument | null = > {
if ( parentMap . has ( node . slug ) ) {
return parentMap . get ( node . slug ) ;
}
const nodes = getNodes ( ) ;
const parent = nodes . find ( n = > n . slug === node . parentSlug ) || null ;
parentMap . set ( node . slug , parent ) ;
return parentMap . get ( node . slug ) ;
} ;
2019-11-19 04:29:29 +01:00
/ * *
* Get the current node . Must be set by setCurrentNode ( string : slug )
* /
2019-12-18 23:54:23 +01:00
const getCurrentNode = ( ) : SilverstripeDocument | null = > {
if ( ! __path ) {
return null ;
}
if ( nodeMap . has ( __path ) ) {
return nodeMap . get ( __path ) || null ;
}
const node = getNodes ( ) . find ( n = > n . slug === __path ) || null ;
nodeMap . set ( __path , node ) ;
return nodeMap . get ( __path ) ;
}
2019-11-08 03:40:20 +01:00
2019-11-19 04:29:29 +01:00
/ * *
* Get the home page
* /
2019-11-08 03:40:20 +01:00
const getHomePage = ( ) : SilverstripeDocument | null = > {
const nodes = getNodes ( ) ;
2019-11-12 04:09:29 +01:00
const version = getCurrentVersion ( ) ;
2019-12-18 23:54:23 +01:00
let slug = ` /en/ ${ version } / ` ;
if ( homeMap . has ( slug ) ) {
return homeMap . get ( slug ) || null ;
}
const homePage = nodes . find ( n = > n . slug === slug ) || null ;
homeMap . set ( slug , homePage ) ;
2019-11-08 03:40:20 +01:00
2019-12-18 23:54:23 +01:00
return homeMap . get ( slug ) ;
2019-11-08 03:40:20 +01:00
} ;
2022-07-22 02:16:07 +02:00
/ * *
* Get the default version
* /
const getDefaultVersion = ( ) : string = > '4' ;
2019-11-19 04:29:29 +01:00
/ * *
* Get the selected version
* /
2022-07-22 02:16:07 +02:00
const getCurrentVersion = ( ) : string = > __currentVersion || getDefaultVersion ( ) ;
2019-11-12 04:09:29 +01:00
2022-07-22 02:18:04 +02:00
/ * *
* Get a message to display for all pages on this version ' s docs
* /
const getVersionMessage = ( ) : ReactElement | ReactElement [ ] | string | null = > {
const EOL = [
'3' ,
] ;
const PRE_RELEASE = [
'5' ,
] ;
const version = getCurrentVersion ( ) ;
const stablePath = getVersionPath ( getCurrentNode ( ) , getDefaultVersion ( ) ) ;
// Output the appropriate message and styling
function makeMessage ( style : string , icon : string , stability : string , message : string | null ) : string {
let template = ` <div id="version-callout" class="callout-block callout-block--version callout-block- ${ style } ">
< div class = "callout-version-title" > Version $ { version } < span class = "callout-version-stability" >
< i class = "far fa-${icon}" > < / i > < span class = "callout-version-stability-text" > $ { stability } < / span > < / span >
< / div > ` ;
if ( message ) {
template += ` <div class="callout-version-content">
This version of Silverstripe CMS $ { message } .
< a href = "${stablePath}" > Go to documentation for the most recent stable version . < / a >
< / div > ` ;
}
template += '</div>' ;
return template ;
}
// Return the correct message for the current version
if ( EOL . includes ( version ) ) {
return parse ( makeMessage ( 'danger' , 'times-circle' , 'end of life' , 'will not recieve any additional bug fixes or documentation updates' ) ) ;
}
if ( PRE_RELEASE . includes ( version ) ) {
return parse ( makeMessage (
'warning' ,
'calendar' ,
'pre-stable' ,
'has not yet been given a stable release. See <a target="_blank" href="https://www.silverstripe.org/software/roadmap/">the release roadmap</a> for more information'
) ) ;
}
return parse ( makeMessage ( 'success' , 'check-circle' , 'supported' , null ) ) ;
} ;
2020-06-30 23:14:19 +02:00
/ * *
* Gets the path in another version
* @param currentNode
* @param version
* /
2022-07-22 02:18:04 +02:00
const getVersionPath = ( currentNode : SilverstripeDocument | null , version : number | string ) : string = > {
const basePath = ` /en/ ${ version } ` ;
if ( ! currentNode ) {
return basePath ;
}
const newPath = currentNode . slug . replace ( /^\/en\/[0-9]+\// , ` ${ basePath } / ` ) ;
2020-06-30 23:14:19 +02:00
const otherNode = getNodes ( ) . find ( n = > n . slug === newPath ) ;
2022-07-22 02:18:04 +02:00
return otherNode ? otherNode.slug : basePath ;
2020-06-30 23:14:19 +02:00
} ;
2019-11-19 04:29:29 +01:00
/ * *
2019-12-18 23:54:23 +01:00
* Set the current path , with some side effects for version
* @param slug
2019-11-19 04:29:29 +01:00
* /
2019-12-18 23:54:23 +01:00
const setCurrentPath = ( path : string ) = > {
__path = path || ` / ` ;
const [ _ , lang , version ] = __path . split ( '/' ) ;
__currentVersion = version ;
2019-11-12 04:09:29 +01:00
} ;
2019-11-08 03:40:20 +01:00
export {
2019-12-18 23:54:23 +01:00
initialise ,
2019-11-08 03:40:20 +01:00
getNodes ,
getChildren ,
getSiblings ,
getParent ,
getCurrentNode ,
getHomePage ,
getNavChildren ,
2019-11-12 04:09:29 +01:00
getCurrentVersion ,
2020-06-30 23:14:19 +02:00
getVersionPath ,
2022-07-22 02:16:07 +02:00
setCurrentPath ,
getDefaultVersion ,
2022-07-22 02:18:04 +02:00
getVersionMessage ,
2019-11-08 03:40:20 +01:00
} ;