Added table of contents to left-side documentation view
This commit is contained in:
@@ -5896,6 +5896,10 @@ func initHandlers() {
|
||||
r.HandleFunc("/api/v1/files/{fileId}", shuffle.HandleDeleteFile).Methods("DELETE", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/files", shuffle.HandleGetFiles).Methods("GET", "OPTIONS")
|
||||
|
||||
r.HandleFunc("/api/v1/notifications", shuffle.HandleGetNotifications).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/notifications/{notificationId}/markasread", shuffle.HandleMarkAsRead).Methods("GET", "OPTIONS")
|
||||
//r.HandleFunc("/api/v1/notifications/{notificationId}/markasread", shuffle.HandleMarkAsRead).Methods("GET", "OPTIONS")
|
||||
|
||||
http.Handle("/", r)
|
||||
}
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@ const App = (message, props) => {
|
||||
<div style={{ backgroundColor: "#1F2023", color: "rgba(255, 255, 255, 0.65)", minHeight: "100vh" }}>
|
||||
<ScrollToTop setCurpath={setCurpath} />
|
||||
<Header checkLogin={checkLogin} cookies={cookies} removeCookie={removeCookie} isLoaded={isLoaded} globalUrl={globalUrl} setIsLoggedIn={setIsLoggedIn} isLoggedIn={isLoggedIn} userdata={userdata} {...props} />
|
||||
<div style={{marginTop: 60}}/>
|
||||
<Route exact path="/login" render={props => <LoginPage isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} checkLogin={checkLogin} {...props} />} />
|
||||
<Route exact path="/admin" render={props => <Admin userdata={userdata} isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} {...props} />} />
|
||||
<Route exact path="/admin/:key" render={props => <Admin isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} {...props} />} />
|
||||
|
||||
@@ -5,8 +5,8 @@ import {Link} from 'react-router-dom';
|
||||
|
||||
import { useTheme } from '@material-ui/core/styles';
|
||||
|
||||
import { Tooltip, List, Avatar, Menu, ListItem, MenuItem, Select, Button, IconButton, Grid } from '@material-ui/core';
|
||||
import { Home as HomeIcon, Polymer as PolymerIcon, Apps as AppsIcon, Description as DescriptionIcon} from '@material-ui/icons';
|
||||
import { Badge, Typography, Paper, Tooltip, List, Avatar, Menu, ListItem, MenuItem, Select, Button, IconButton, Grid } from '@material-ui/core';
|
||||
import { Notifications as NotificationsIcon, Home as HomeIcon, Polymer as PolymerIcon, Apps as AppsIcon, Description as DescriptionIcon} from '@material-ui/icons';
|
||||
import { useAlert } from "react-alert";
|
||||
|
||||
const hoverColor = "#f85a3e"
|
||||
@@ -148,12 +148,60 @@ const Header = props => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
const notifications = [{
|
||||
"image": "https://dytvr9ot2sszz.cloudfront.net/whats-new-announcements/billboard_metricsdashbd_sept2021.png",
|
||||
"date": "1519211809934",
|
||||
"title": "some title",
|
||||
"description": "This is a escription",
|
||||
"dismissable": true,
|
||||
"personal": false,
|
||||
"org_id": "",
|
||||
}]
|
||||
|
||||
const notificationMenu =
|
||||
<span style={{zIndex: 10001}}>
|
||||
<IconButton color="primary" style={{zIndex: 10001, marginRight: 15, }} aria-controls="simple-menu" aria-haspopup="true" onClick={(event) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
}}>
|
||||
<Badge badgeContent={notifications.length} color="primary">
|
||||
<NotificationsIcon color="secondary" style={{height: 35, width: 35,}} alt="Your username here" src="" />
|
||||
</Badge>
|
||||
</IconButton>
|
||||
<Menu
|
||||
id="simple-menu"
|
||||
anchorEl={anchorEl}
|
||||
keepMounted
|
||||
open={Boolean(anchorEl)}
|
||||
style={{zIndex: 10002}}
|
||||
onClose={() => {
|
||||
handleClose()
|
||||
}}
|
||||
>
|
||||
{notifications.map((data, index) => {
|
||||
return (
|
||||
<MenuItem onClick={(event) => {}}>
|
||||
<Paper style={{width: 300, height: 150, }}>
|
||||
<Grid container direction="row" alignItems="center">
|
||||
<Grid item>
|
||||
<Typography variant="h6">
|
||||
{new Date(data.date).toISOString()}
|
||||
</Typography >
|
||||
<Typography variant="h6">
|
||||
{data.title}
|
||||
</Typography >
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Paper>
|
||||
</MenuItem>
|
||||
)
|
||||
})}
|
||||
</Menu>
|
||||
</span>
|
||||
|
||||
// Should be based on some path
|
||||
const avatarMenu =
|
||||
<span>
|
||||
<IconButton color="primary" style={{marginRight: 15, }} aria-controls="simple-menu" aria-haspopup="true" onClick={(event) => {
|
||||
<span style={{zIndex: 10001}}>
|
||||
<IconButton color="primary" style={{zIndex: 10001, marginRight: 15, }} aria-controls="simple-menu" aria-haspopup="true" onClick={(event) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
}}>
|
||||
<Avatar style={{height: 35, width: 35,}} alt="Your username here" src="" />
|
||||
@@ -163,6 +211,7 @@ const Header = props => {
|
||||
anchorEl={anchorEl}
|
||||
keepMounted
|
||||
open={Boolean(anchorEl)}
|
||||
style={{zIndex: 10002}}
|
||||
onClose={() => {
|
||||
handleClose()
|
||||
}}
|
||||
@@ -188,8 +237,9 @@ const Header = props => {
|
||||
|
||||
// Handle top bar or something
|
||||
const logoCheck = !homePage ? null : null
|
||||
//<div style={{position: "fixed", top: 0, left: 0, display: "flex"}}>
|
||||
const loginTextBrowser = !isLoggedIn ?
|
||||
<div style={{display: "flex"}}>
|
||||
<div style={{display: "flex"}}>
|
||||
<List style={{display: "flex", flexDirect: "row"}} component="nav">
|
||||
<ListItem style={{textAlign: "center", marginLeft: "0px"}}>
|
||||
<Link to ="/docs/about" style={hrefStyle}>
|
||||
@@ -265,6 +315,7 @@ const Header = props => {
|
||||
</div>
|
||||
<div style={{flex: "10", display: "flex", flexDirection: "row-reverse"}}>
|
||||
{avatarMenu}
|
||||
{notificationMenu}
|
||||
{userdata === undefined || userdata.admin === undefined || userdata.admin === null || !userdata.admin ? null :
|
||||
<Link to="/admin" style={hrefStyle}>
|
||||
<Button color="primary" variant="contained" style={{marginRight: 15, marginTop: 12}}>
|
||||
@@ -376,7 +427,7 @@ const Header = props => {
|
||||
|
||||
// <Divider style={{height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
|
||||
const loadedCheck =
|
||||
<div style={{minHeight: 60}}>
|
||||
<div style={{minHeight: 60, }}>
|
||||
<BrowserView>
|
||||
{loginTextBrowser}
|
||||
</BrowserView>
|
||||
@@ -386,10 +437,10 @@ const Header = props => {
|
||||
</div>
|
||||
// <div style={{backgroundImage: "linear-gradient(-90deg,#342f78 0,#29255e 50%,#1b1947 100%"}}>
|
||||
return (
|
||||
<div>
|
||||
{loadedCheck}
|
||||
<div style={{width: "100%", position: "fixed", minHeight: 60, top: 0, zIndex: 10000, backgroundColor: "inherit",}}>
|
||||
{loadedCheck}
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export default Header;
|
||||
|
||||
@@ -2936,7 +2936,7 @@ const Admin = (props) => {
|
||||
|
||||
const iconStyle = {marginRight: 10}
|
||||
const data =
|
||||
<div style={{width: 1366, margin: "auto", overflowX: "hidden", marginTop: 25,}}>
|
||||
<div style={{width: 1300, margin: "auto", overflowX: "hidden", marginTop: 25,}}>
|
||||
<Paper style={paperStyle}>
|
||||
<Tabs
|
||||
value={curTab}
|
||||
|
||||
@@ -8671,7 +8671,7 @@ const AngularWorkflow = (props) => {
|
||||
minZoom={0.35}
|
||||
maxZoom={2.00}
|
||||
wheelSensitivity={0.25}
|
||||
style={{width: bodyWidth-leftBarSize-5, height: bodyHeight-appBarSize-5, backgroundColor: surfaceColor}}
|
||||
style={{width: bodyWidth-leftBarSize-15, height: bodyHeight-appBarSize-5, backgroundColor: surfaceColor}}
|
||||
stylesheet={cystyle}
|
||||
boxSelectionEnabled={true}
|
||||
autounselectify={false}
|
||||
|
||||
@@ -129,6 +129,7 @@ const Apps = (props) => {
|
||||
const upload = React.useRef(null);
|
||||
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" ? true : false
|
||||
const borderRadius = 3
|
||||
const viewWidth = 590
|
||||
|
||||
const { start, stop } = useInterval({
|
||||
duration: 5000,
|
||||
@@ -177,6 +178,7 @@ const Apps = (props) => {
|
||||
color: "#ffffff",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
margin: "auto",
|
||||
}
|
||||
|
||||
const paperAppStyle = {
|
||||
@@ -473,13 +475,14 @@ const Apps = (props) => {
|
||||
|
||||
const dividerColor = "rgb(225, 228, 232)"
|
||||
const uploadViewPaperStyle = {
|
||||
minWidth: 662.5,
|
||||
maxWidth: 662.5,
|
||||
minWidth: viewWidth,
|
||||
maxWidth: viewWidth,
|
||||
color: "white",
|
||||
borderRadius: 5,
|
||||
backgroundColor: surfaceColor,
|
||||
display: "flex",
|
||||
marginBottom: 10,
|
||||
overflow: "hidden",
|
||||
}
|
||||
|
||||
const UploadView = () => {
|
||||
@@ -761,7 +764,7 @@ const Apps = (props) => {
|
||||
{/*<p><b>Owner:</b> {selectedApp.owner}</p>*/}
|
||||
{selectedApp.privateId !== undefined && selectedApp.privateId.length > 0 ? <p><b>PrivateID:</b> {selectedApp.privateId}</p> : null}
|
||||
<Divider style={{marginBottom: 10, marginTop: 10, backgroundColor: dividerColor}}/>
|
||||
<div style={{padding: 20}}>
|
||||
<div style={{paddingTop: 20, paddingBottom: 20, }}>
|
||||
{selectedApp.link.length > 0 ? <p><b>URL:</b> {selectedApp.link}</p> : null}
|
||||
<div style={{marginTop: 15, marginBottom: 15}}>
|
||||
<b>Actions</b>
|
||||
@@ -944,9 +947,9 @@ const Apps = (props) => {
|
||||
}, [appValidation, isDropzone]);
|
||||
|
||||
const appView = isLoggedIn ?
|
||||
<Dropzone style={{maxWidth: window.innerWidth > 1366 ? 1366 : 1200, margin: "auto", padding: 20 }} onDrop={uploadFile}>
|
||||
<Dropzone style={{width: viewWidth*2+20, margin: "auto", padding: 20 }} onDrop={uploadFile}>
|
||||
<div style={appViewStyle}>
|
||||
<div style={{flex: 1, }}>
|
||||
<div style={{flex: 1, maxWidth: viewWidth, marginRight: 10,}}>
|
||||
<Breadcrumbs aria-label="breadcrumb" separator="›" style={{color: "white",}}>
|
||||
<Link to="/apps" style={{textDecoration: "none", color: "inherit",}}>
|
||||
<Typography variant="h6" style={{color: "rgba(255,255,255,0.5)"}}>
|
||||
@@ -963,9 +966,9 @@ const Apps = (props) => {
|
||||
: null}
|
||||
</Breadcrumbs>
|
||||
<div style={{marginTop: 15}} />
|
||||
<UploadView/>
|
||||
<UploadView />
|
||||
</div>
|
||||
<div style={{flex: 1, marginLeft: 10, marginRight: 10, }}>
|
||||
<div style={{flex: 1, marginLeft: 10, maxWidth: viewWidth, }}>
|
||||
<div style={{display: "flex",}}>
|
||||
<div style={{flex: 1, marginBottom: 15, }}>
|
||||
<Typography variant="h6">
|
||||
|
||||
@@ -13,7 +13,7 @@ const Body = {
|
||||
minWidth: '768px',
|
||||
margin: 'auto',
|
||||
display: "flex",
|
||||
heigth: "100%",
|
||||
height: "100%",
|
||||
color: "white",
|
||||
//textAlign: "center",
|
||||
};
|
||||
@@ -24,6 +24,11 @@ const hrefStyle = {
|
||||
textDecoration: "none"
|
||||
}
|
||||
|
||||
const innerHrefStyle = {
|
||||
color: "rgba(255, 255, 255, 0.75)",
|
||||
textDecoration: "none"
|
||||
}
|
||||
|
||||
const Docs = (props) => {
|
||||
const { globalUrl, selectedDoc, serverside, isMobile, } = props;
|
||||
|
||||
@@ -36,6 +41,7 @@ const Docs = (props) => {
|
||||
const [anchorEl, setAnchorEl] = React.useState(null);
|
||||
const [headingSet, setHeadingSet] = React.useState(false);
|
||||
const [selectedMeta, setSelectedMeta] = React.useState({link: "hello", read_time: 2, });
|
||||
const [tocLines, setTocLines] = React.useState([]);
|
||||
const [baseUrl, setBaseUrl] = React.useState(serverside === true ? "" : window.location.href)
|
||||
|
||||
function handleClick(event) {
|
||||
@@ -52,14 +58,14 @@ const Docs = (props) => {
|
||||
position: "relative",
|
||||
padding: 30,
|
||||
paddingTop: 15,
|
||||
borderRadius: 5,
|
||||
height: "80vh",
|
||||
marginTop: 15,
|
||||
}
|
||||
|
||||
const SideBar = {
|
||||
maxWidth: 250,
|
||||
flex: "1",
|
||||
position: "fixed",
|
||||
marginTop: 35,
|
||||
}
|
||||
|
||||
const fetchDocList = () => {
|
||||
@@ -99,6 +105,54 @@ const Docs = (props) => {
|
||||
if (responseJson.meta !== undefined) {
|
||||
setSelectedMeta(responseJson.meta)
|
||||
}
|
||||
|
||||
//console.log("TOC list: ", responseJson.reason)
|
||||
if (responseJson.reason !== undefined && responseJson.reason !== null) {
|
||||
const splitkey = responseJson.reason.split("\n")
|
||||
var innerTocLines = []
|
||||
var record = false
|
||||
for (var key in splitkey) {
|
||||
const line = splitkey[key]
|
||||
//console.log("Line: ", line)
|
||||
if (line.toLowerCase().includes("table of contents")) {
|
||||
record = true
|
||||
continue
|
||||
}
|
||||
|
||||
if (record && line.length < 3) {
|
||||
record = false
|
||||
}
|
||||
|
||||
if (record) {
|
||||
const parsedline = line.split("](")
|
||||
if (parsedline.length > 1) {
|
||||
parsedline[0] = parsedline[0].replaceAll("*", "")
|
||||
parsedline[0] = parsedline[0].replaceAll("[", "")
|
||||
parsedline[0] = parsedline[0].replaceAll("]", "")
|
||||
parsedline[0] = parsedline[0].replaceAll("(", "")
|
||||
parsedline[0] = parsedline[0].replaceAll(")", "")
|
||||
parsedline[0] = parsedline[0].trim()
|
||||
|
||||
parsedline[1] = parsedline[1].replaceAll("*", "")
|
||||
parsedline[1] = parsedline[1].replaceAll("[", "")
|
||||
parsedline[1] = parsedline[1].replaceAll("]", "")
|
||||
parsedline[1] = parsedline[1].replaceAll(")", "")
|
||||
parsedline[1] = parsedline[1].replaceAll("(", "")
|
||||
parsedline[1] = parsedline[1].trim()
|
||||
console.log(parsedline[0], parsedline[1])
|
||||
|
||||
innerTocLines.push({
|
||||
"text": parsedline[0],
|
||||
"link": parsedline[1]
|
||||
})
|
||||
} else {
|
||||
console.log("Bad line for parsing: ", line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setTocLines(innerTocLines)
|
||||
}
|
||||
} else {
|
||||
setData("# Error\nThis page doesn't exist.")
|
||||
}
|
||||
@@ -230,7 +284,7 @@ const Docs = (props) => {
|
||||
}
|
||||
|
||||
const Heading = (props) => {
|
||||
const element = React.createElement(`h${props.level}`, {style: {marginTop: 50}}, props.children)
|
||||
const element = React.createElement(`h${props.level}`, {style: {marginTop: props.level === 1 ? 20 : 50}}, props.children)
|
||||
const [hover, setHover] = useState(false)
|
||||
|
||||
var extraInfo = ""
|
||||
@@ -315,11 +369,31 @@ const Docs = (props) => {
|
||||
|
||||
const path = "/docs/"+item
|
||||
const newname = item.charAt(0).toUpperCase()+item.substring(1).split("_").join(" ").split("-").join(" ")
|
||||
const itemMatching = props.match.params.key.toLowerCase() === item.toLowerCase()
|
||||
//const [tocLines, setTocLines] = React.useState([]);
|
||||
return (
|
||||
<li key={index} style={{marginTop: 10,}}>
|
||||
<Link key={index} style={hrefStyle} to={path} onClick={() => {fetchDocs(item)}}>
|
||||
<Typography style={{color: props.match.params.key.toLowerCase() === item.toLowerCase() ? "#f86a3e" : "inherit"}} variant="body1"><b>> {newname}</b></Typography>
|
||||
<Link key={index} style={hrefStyle} to={path} onClick={() => {
|
||||
setTocLines([])
|
||||
fetchDocs(item)
|
||||
}}>
|
||||
<Typography style={{color: itemMatching ? "#f86a3e" : "inherit"}} variant="body1"><b>> {newname}</b></Typography>
|
||||
</Link>
|
||||
{itemMatching && tocLines !== null && tocLines !== undefined && tocLines.length > 0 ?
|
||||
<div style={{marginLeft: 13}}>
|
||||
{tocLines.map((data, index) => {
|
||||
console.log(data)
|
||||
|
||||
return (
|
||||
<Link key={index} style={innerHrefStyle} to={data.link} onClick={() => {}}>
|
||||
<Typography variant="body2" style={{cursor: "pointer"}}>
|
||||
{data.text}
|
||||
</Typography>
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
: null}
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
@@ -422,7 +496,7 @@ const Docs = (props) => {
|
||||
</div>
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{}}>
|
||||
{loadedCheck}
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user