Fixed documentation scrolling issue

This commit is contained in:
frikky
2021-02-14 18:24:14 +01:00
parent 036b349e0c
commit 225193e05f
5 changed files with 193 additions and 141 deletions
+2 -2
View File
@@ -2877,8 +2877,8 @@ func fixUserOrg(ctx context.Context, user *User) *User {
// Used for testing only. Shouldn't impact production. // Used for testing only. Shouldn't impact production.
func handleCors(resp http.ResponseWriter, request *http.Request) bool { func handleCors(resp http.ResponseWriter, request *http.Request) bool {
//allowedOrigins := "http://localhost:3000" allowedOrigins := "http://localhost:3000"
allowedOrigins := "http://localhost:3002" //allowedOrigins := "http://localhost:3002"
resp.Header().Set("Vary", "Origin") resp.Header().Set("Vary", "Origin")
resp.Header().Set("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Authorization") resp.Header().Set("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Authorization")
+3 -3
View File
@@ -4764,9 +4764,9 @@ func getWorkflowAppConfig(resp http.ResponseWriter, request *http.Request) {
//if IsValid bool `json:"is_valid" yaml:"is_valid" required:true datastore:"is_valid"` //if IsValid bool `json:"is_valid" yaml:"is_valid" required:true datastore:"is_valid"`
// Sharing bool `json:"sharing" yaml:"sharing" required:false datastore:"sharing"` // Sharing bool `json:"sharing" yaml:"sharing" required:false datastore:"sharing"`
log.Printf("Sharing: %s", app.Sharing) //log.Printf("Sharing: %s", app.Sharing)
log.Printf("Generated: %s", app.Generated) //log.Printf("Generated: %s", app.Generated)
log.Printf("Downloaded: %s", app.Downloaded) //log.Printf("Downloaded: %s", app.Downloaded)
// FIXME - Handle sharing and such PROPERLY // FIXME - Handle sharing and such PROPERLY
if app.Sharing && app.Generated { if app.Sharing && app.Generated {
+3
View File
@@ -30,6 +30,7 @@ import SettingsPage from "./views/SettingsPage";
import { createMuiTheme, MuiThemeProvider } from '@material-ui/core/styles'; import { createMuiTheme, MuiThemeProvider } from '@material-ui/core/styles';
import ScrollToTop from "./components/ScrollToTop";
import AlertTemplate from "./components/AlertTemplate"; import AlertTemplate from "./components/AlertTemplate";
import { positions, Provider } from "react-alert"; import { positions, Provider } from "react-alert";
@@ -74,6 +75,7 @@ const App = (message, props) => {
const [isLoggedIn, setIsLoggedIn] = useState(false); const [isLoggedIn, setIsLoggedIn] = useState(false);
const [dataset, setDataset] = useState(false); const [dataset, setDataset] = useState(false);
const [isLoaded, setIsLoaded] = useState(false); const [isLoaded, setIsLoaded] = useState(false);
const [curpath, setCurpath] = useState(typeof window === 'undefined' || window.location === undefined ? "" : window.location.pathname)
useEffect(() => { useEffect(() => {
if (dataset === false) { if (dataset === false) {
@@ -126,6 +128,7 @@ const App = (message, props) => {
<Route exact path="/home" render={props => <LandingPageNew isLoaded={isLoaded} {...props} />} /> <Route exact path="/home" render={props => <LandingPageNew isLoaded={isLoaded} {...props} />} />
</div> : </div> :
<div style={{ backgroundColor: "#1F2023", color: "rgba(255, 255, 255, 0.65)", minHeight: "100vh" }}> <div style={{ backgroundColor: "#1F2023", color: "rgba(255, 255, 255, 0.65)", minHeight: "100vh" }}>
<ScrollToTop setCurpath={setCurpath} />
<Header cookies={cookies} removeCookie={removeCookie} isLoaded={isLoaded} globalUrl={globalUrl} setIsLoggedIn={setIsLoggedIn} isLoggedIn={isLoggedIn} userdata={userdata} {...props} /> <Header cookies={cookies} removeCookie={removeCookie} isLoaded={isLoaded} globalUrl={globalUrl} setIsLoggedIn={setIsLoggedIn} isLoggedIn={isLoggedIn} userdata={userdata} {...props} />
<Route exact path="/oauth2" render={props => <Oauth2 isLoaded={isLoaded} globalUrl={globalUrl} {...props} />} /> <Route exact path="/oauth2" render={props => <Oauth2 isLoaded={isLoaded} globalUrl={globalUrl} {...props} />} />
<Route exact path="/contact" render={props => <Contact isLoaded={isLoaded} globalUrl={globalUrl} {...props} />} /> <Route exact path="/contact" render={props => <Contact isLoaded={isLoaded} globalUrl={globalUrl} {...props} />} />
+4 -3
View File
@@ -83,8 +83,8 @@ import cxtmenu from 'cytoscape-cxtmenu';
import { w3cwebsocket as W3CWebSocket } from "websocket"; import { w3cwebsocket as W3CWebSocket } from "websocket";
import { useAlert } from "react-alert"; import { useAlert } from "react-alert";
import { validateJson } from "./Workflows"; import { validateJson } from "./Workflows.jsx";
import { GetParsedPaths } from "./Apps"; import { GetParsedPaths } from "./Apps.jsx";
const surfaceColor = "#27292D" const surfaceColor = "#27292D"
const inputColor = "#383B40" const inputColor = "#383B40"
@@ -428,7 +428,8 @@ const AngularWorkflow = (props) => {
handleUpdateResults(responseJson) handleUpdateResults(responseJson)
}) })
.catch(error => { .catch(error => {
alert.error(error.toString()) console.log("Error: ", error)
//alert.error(error.toString())
stop() stop()
}); });
} }
+181 -133
View File
@@ -1,11 +1,16 @@
import React, {useState, useEffect} from 'react'; import React, {useState, useEffect} from 'react';
import { useTheme } from '@material-ui/core/styles';
import Divider from '@material-ui/core/Divider'; import Divider from '@material-ui/core/Divider';
import ReactMarkdown from 'react-markdown'; import ReactMarkdown from 'react-markdown';
import {BrowserView, MobileView} from "react-device-detect"; import {BrowserView, MobileView} from "react-device-detect";
import Button from '@material-ui/core/Button'; import Button from '@material-ui/core/Button';
import Menu from '@material-ui/core/Menu'; import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem'; import MenuItem from '@material-ui/core/MenuItem';
import Typography from '@material-ui/core/Typography';
import Paper from '@material-ui/core/Paper';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import {Link} from 'react-router-dom'; import {Link} from 'react-router-dom';
@@ -20,26 +25,21 @@ const Body = {
}; };
const dividerColor = "rgb(225, 228, 232)" const dividerColor = "rgb(225, 228, 232)"
const SideBar = {
maxWidth: 250,
flex: "1",
position: "fixed",
}
const hrefStyle = { const hrefStyle = {
color: "rgba(255, 255, 255, 0.40)", color: "rgba(255, 255, 255, 0.40)",
textDecoration: "none" textDecoration: "none"
} }
const Docs = (props) => { const Docs = (props) => {
const { isLoaded, globalUrl, inputColor } = props; const { isLoaded, globalUrl, inputColor, selectedDoc, serverside, isMobile, update} = props;
const theme = useTheme();
const [data, setData] = useState(""); const [data, setData] = useState("");
const [firstrequest, setFirstrequest] = useState(true); const [firstrequest, setFirstrequest] = useState(true);
const [list, setList] = useState([]); const [list, setList] = useState([]);
const [listLoaded, setListLoaded] = useState(false); const [listLoaded, setListLoaded] = useState(false);
const [anchorEl, setAnchorEl] = React.useState(null); const [anchorEl, setAnchorEl] = React.useState(null);
const [baseUrl, setBaseUrl] = React.useState(serverside === true ? "" : window.location.href)
function handleClick(event) { function handleClick(event) {
setAnchorEl(event.currentTarget); setAnchorEl(event.currentTarget);
@@ -49,77 +49,21 @@ const Docs = (props) => {
setAnchorEl(null); setAnchorEl(null);
} }
useEffect(() => { const SidebarPaperStyle = {
if (firstrequest) { backgroundColor: theme.palette.surfaceColor,
setFirstrequest(false) overflowX: "hidden",
fetchDocList() position: "relative",
fetchDocs(props.match.params.key) padding: 30,
return paddingTop: 15,
} borderRadius: 5,
}
// Continue this, and find the h2 with the data in it lol const SideBar = {
if (window.location.hash.length > 0) { maxWidth: 250,
var parent = document.getElementById("markdown_wrapper") flex: "1",
if (parent !== null) { position: "fixed",
var elements = parent.getElementsByTagName('h2') marginTop: 35,
}
const name = window.location.hash.slice(1, window.location.hash.lenth).toLowerCase().split("%20").join(" ").split("_").join(" ").split("-").join(" ")
console.log(name)
var found = false
for (var key in elements) {
const element = elements[key]
if (element.innerHTML === undefined) {
continue
}
// Fix location..
if (element.innerHTML.toLowerCase() === name) {
element.scrollIntoView({behavior: "smooth"})
found = true
//element.scrollTo({
// top: element.offsetTop-100,
// behavior: "smooth"
//})
}
}
// H#
if (!found) {
var elements = parent.getElementsByTagName('h3')
console.log(name)
var found = false
for (var key in elements) {
const element = elements[key]
if (element.innerHTML === undefined) {
continue
}
// Fix location..
if (element.innerHTML.toLowerCase() === name) {
element.scrollIntoView({behavior: "smooth"})
found = true
//element.scrollTo({
// top: element.offsetTop-100,
// behavior: "smooth"
//})
}
}
}
}
//console.log(element)
//console.log("NAME: ", name)
//console.log(document.body.innerHTML)
// parent = document.getElementById(parent);
//var descendants = parent.getElementsByTagName(tagname);
// this.scrollDiv.current.scrollIntoView({ behavior: 'smooth' });
//$(".parent").find("h2:contains('Statistics')").parent();
}
})
const fetchDocList = () => { const fetchDocList = () => {
fetch(globalUrl+"/api/v1/docs", { fetch(globalUrl+"/api/v1/docs", {
@@ -143,16 +87,17 @@ const Docs = (props) => {
const fetchDocs = (docId) => { const fetchDocs = (docId) => {
fetch(globalUrl+"/api/v1/docs/"+docId, { fetch(globalUrl+"/api/v1/docs/"+docId, {
method: 'GET', method: 'GET',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Accept': 'application/json', 'Accept': 'application/json',
}, },
}) })
.then((response) => response.json()) .then((response) => response.json())
.then((responseJson) => { .then((responseJson) => {
if (responseJson.success) { if (responseJson.success) {
setData(responseJson.reason) setData(responseJson.reason)
document.title = "Shuffle "+docId+" documentation"
} else { } else {
setData("# Error\nThis page doesn't exist.") setData("# Error\nThis page doesn't exist.")
} }
@@ -160,13 +105,99 @@ const Docs = (props) => {
.catch(error => {}); .catch(error => {});
} }
if (firstrequest) {
setFirstrequest(false)
if (selectedDoc !== undefined) {
setData(selectedDoc.reason)
setList(selectedDoc.list)
setListLoaded(true)
} else {
fetchDocList()
fetchDocs(props.match.params.key)
}
}
// Handles search-based changes that origin from outside this file
if (serverside !== true && window.location.href !== baseUrl) {
setBaseUrl(window.location.href)
fetchDocs(props.match.params.key)
}
const parseElementScroll = () => {
var parent = document.getElementById("markdown_wrapper_outer")
if (parent !== null) {
//console.log("IN PARENT")
var elements = parent.getElementsByTagName('h2')
const name = window.location.hash.slice(1, window.location.hash.lenth).toLowerCase().split("%20").join(" ").split("_").join(" ").split("-").join(" ")
//console.log(name)
var found = false
for (var key in elements) {
const element = elements[key]
if (element.innerHTML === undefined) {
continue
}
// Fix location..
if (element.innerHTML.toLowerCase() === name) {
element.scrollIntoView({behavior: "smooth"})
found = true
//element.scrollTo({
// top: element.offsetTop-100,
// behavior: "smooth"
//})
}
}
// H#
if (!found) {
var elements = parent.getElementsByTagName('h3')
console.log(name)
var found = false
for (var key in elements) {
const element = elements[key]
if (element.innerHTML === undefined) {
continue
}
// Fix location..
if (element.innerHTML.toLowerCase() === name) {
element.scrollIntoView({behavior: "smooth"})
found = true
//element.scrollTo({
// top: element.offsetTop-100,
// behavior: "smooth"
//})
}
}
}
}
//console.log(element)
//console.log("NAME: ", name)
//console.log(document.body.innerHTML)
// parent = document.getElementById(parent);
//var descendants = parent.getElementsByTagName(tagname);
// this.scrollDiv.current.scrollIntoView({ behavior: 'smooth' });
//$(".parent").find("h2:contains('Statistics')").parent();
}
if (serverside !== true && window.location.hash.length > 0) {
parseElementScroll()
}
const markdownStyle = { const markdownStyle = {
color: "rgba(255, 255, 255, 0.65)", color: "rgba(255, 255, 255, 0.65)",
flex: "1", flex: "1",
maxWidth: 750, maxWidth: isMobile ? "100%" : 750,
overflow: "hidden", overflow: "hidden",
paddingBottom: 200, paddingBottom: 200,
marginLeft: 250, marginLeft: isMobile ? 0 : 275,
} }
function OuterLink(props) { function OuterLink(props) {
@@ -182,7 +213,7 @@ const Docs = (props) => {
function CodeHandler(props) { function CodeHandler(props) {
return ( return (
<pre style={{padding: 10, minWidth: "50%", maxWidth: "100%", backgroundColor: inputColor}}> <pre style={{padding: 15, minWidth: "50%", maxWidth: "100%", backgroundColor: inputColor, overflowX: "auto", overflowY: "hidden",}}>
<code> <code>
{props.value} {props.value}
</code> </code>
@@ -190,13 +221,22 @@ const Docs = (props) => {
) )
} }
function TextWrapper(props) {
console.log(props)
return (
<Typography>
{props.value}
</Typography>
)
}
function Heading(props) { function Heading(props) {
const element = React.createElement(`h${props.level}`, {style: {marginTop: 40}}, props.children) const element = React.createElement(`h${props.level}`, {style: {marginTop: 40}}, props.children)
return ( return (
<span> <Typography>
{props.level !== 1 ? <Divider style={{width: "90%", marginTop: 40, backgroundColor: inputColor}} /> : null} {props.level !== 1 ? <Divider style={{width: "90%", marginTop: 40, backgroundColor: theme.palette.inputColor}} /> : null}
{element} {element}
</span> </Typography>
) )
} }
//React.createElement("p", {style: {color: "red", backgroundColor: "blue"}}, this.props.paragraph) //React.createElement("p", {style: {color: "red", backgroundColor: "blue"}}, this.props.paragraph)
@@ -213,26 +253,28 @@ const Docs = (props) => {
const postDataBrowser = const postDataBrowser =
<div style={Body}> <div style={Body}>
<div style={SideBar}> <div style={SideBar}>
<ul style={{listStyle: "none", paddingLeft: "0"}}> <Paper style={SidebarPaperStyle}>
{list.map((item, index) => { <List style={{listStyle: "none", paddingLeft: "0", }}>
const path = "/docs/"+item {list.map((item, index) => {
const newname = item.charAt(0).toUpperCase()+item.substring(1).split("_").join(" ").split("-").join(" ") const path = "/docs/"+item
return ( const newname = item.charAt(0).toUpperCase()+item.substring(1).split("_").join(" ").split("-").join(" ")
<li key={index} style={{marginTop: "10px"}}> return (
<Link style={hrefStyle} to={path} onClick={() => {fetchDocs(item)}}> <li key={index} style={{marginTop: 15,}}>
<h2>{newname}</h2> <Link key={index} style={hrefStyle} to={path} onClick={() => {fetchDocs(item)}}>
</Link> <Typography variant="h6"><b>{newname}</b></Typography>
</li> </Link>
) </li>
})} )
</ul> })}
</List>
</Paper>
</div> </div>
<div id="markdown_wrapper" style={markdownStyle}> <div id="markdown_wrapper_outer" style={markdownStyle}>
<ReactMarkdown <ReactMarkdown
id="markdown_wrapper" id="markdown_wrapper"
escapeHtml={false} escapeHtml={false}
source={data} source={data}
renderers={{ renderers={{
link: OuterLink, link: OuterLink,
image: Img, image: Img,
code: CodeHandler, code: CodeHandler,
@@ -244,46 +286,55 @@ const Docs = (props) => {
const mobileStyle = { const mobileStyle = {
color: "white", color: "white",
marginLeft: "15px", marginLeft: 15,
marginRight: "15px", marginRight: 15,
paddingBottom: "50px", paddingBottom: 50,
backgroundColor: "inherit", backgroundColor: "inherit",
display: "flex",
flexDirection: "column",
} }
const postDataMobile = const postDataMobile =
<div style={mobileStyle}> <div style={mobileStyle}>
<Button aria-controls="simple-menu" aria-haspopup="true" variant="outlined" color="primary" onClick={handleClick}> <div>
<div style={{color: "white"}}> <Button fullWidth aria-controls="simple-menu" aria-haspopup="true" variant="outlined" color="primary" onClick={handleClick}>
More items <div style={{color: "white"}}>
</div> More docs
</Button> </div>
<Menu </Button>
id="simple-menu" <Menu
anchorEl={anchorEl} id="simple-menu"
keepMounted anchorEl={anchorEl}
open={Boolean(anchorEl)} keepMounted
onClose={handleClose} open={Boolean(anchorEl)}
> onClose={handleClose}
{list.map(item => { >
const path = "/docs/"+item {list.map((item, index) => {
const newname = item.charAt(0).toUpperCase()+item.substring(1).split("_").join(" ").split("-").join(" ") const path = "/docs/"+item
return ( const newname = item.charAt(0).toUpperCase()+item.substring(1).split("_").join(" ").split("-").join(" ")
<MenuItem onClick={() => {window.location.pathname = path}}>{newname}</MenuItem> return (
) <MenuItem key={index} onClick={() => {window.location.pathname = path}}>{newname}</MenuItem>
})} )
</Menu> })}
<div style={markdownStyle}> </Menu>
</div>
<div id="markdown_wrapper_outer" style={markdownStyle}>
<ReactMarkdown <ReactMarkdown
id="markdown_wrapper" id="markdown_wrapper"
escapeHtml={false} escapeHtml={false}
source={data} source={data}
renderers={{link: OuterLink, image: Img}} renderers={{
link: OuterLink,
image: Img,
code: CodeHandler,
heading: Heading,
}}
/> />
</div> </div>
<Divider style={{marginTop: "10px", marginBottom: "10px", backgroundColor: dividerColor}}/> <Divider style={{marginTop: "10px", marginBottom: "10px", backgroundColor: dividerColor}}/>
<Button aria-controls="simple-menu" aria-haspopup="true" variant="outlined" color="primary" onClick={handleClick}> <Button fullWidth aria-controls="simple-menu" aria-haspopup="true" variant="outlined" color="primary" onClick={handleClick}>
<div style={{color: "white"}}> <div style={{color: "white"}}>
More items More docs
</div> </div>
</Button> </Button>
@@ -297,7 +348,7 @@ const Docs = (props) => {
// {imageModal} // {imageModal}
const loadedCheck = isLoaded && listLoaded ? const loadedCheck =
<div> <div>
<BrowserView> <BrowserView>
{postDataBrowser} {postDataBrowser}
@@ -306,9 +357,6 @@ const Docs = (props) => {
{postDataMobile} {postDataMobile}
</MobileView> </MobileView>
</div> </div>
:
<div>
</div>
return ( return (
<div> <div>