Fixed multiple navigation issues
This commit is contained in:
@@ -860,6 +860,7 @@ const Billing = memo((props) => {
|
|||||||
"Add Card Details"
|
"Add Card Details"
|
||||||
}
|
}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{userdata.has_card_available === true ?
|
{userdata.has_card_available === true ?
|
||||||
<Button
|
<Button
|
||||||
fullWidth
|
fullWidth
|
||||||
@@ -888,7 +889,8 @@ const Billing = memo((props) => {
|
|||||||
: null}
|
: null}
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
: null}
|
: null}
|
||||||
|
|
||||||
{showSupport ?
|
{showSupport ?
|
||||||
<Button variant="outlined" color="primary" style={{ marginTop: 20, marginBottom: 10, }} onClick={() => {
|
<Button variant="outlined" color="primary" style={{ marginTop: 20, marginBottom: 10, }} onClick={() => {
|
||||||
if (window.drift !== undefined) {
|
if (window.drift !== undefined) {
|
||||||
@@ -1204,12 +1206,13 @@ const Billing = memo((props) => {
|
|||||||
ReactGA.event({
|
ReactGA.event({
|
||||||
category: "Billing",
|
category: "Billing",
|
||||||
action: "Buy_consultation_hours",
|
action: "Buy_consultation_hours",
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = userdata.licensed === true
|
const url = userdata.licensed === true
|
||||||
? "https://book.stripe.com/6oEeY23fw2T84M06oq"
|
? "https://book.stripe.com/6oEeY23fw2T84M06oq"
|
||||||
: "https://book.stripe.com/00g6rw3fw9hwguI289";
|
: "https://book.stripe.com/00g6rw3fw9hwguI289"
|
||||||
window.open(url, "_blank");
|
window.open(url, "_blank")
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Book Professional Service Hours
|
Book Professional Service Hours
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ const ExpandMoreAndLessIcon = "/icons/expandMoreIcon.svg";
|
|||||||
const LeftSideBar = ({ userdata, serverside, globalUrl, notifications, }) => {
|
const LeftSideBar = ({ userdata, serverside, globalUrl, notifications, }) => {
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const {setLeftSideBarOpenByClick, leftSideBarOpenByClick, setSearchBarModalOpen, searchBarModalOpen} = useContext(Context);
|
const {setLeftSideBarOpenByClick, leftSideBarOpenByClick, setSearchBarModalOpen, searchBarModalOpen, isDocSearchModalOpen} = useContext(Context);
|
||||||
|
|
||||||
const [expandLeftNav, setExpandLeftNav] = useState(false);
|
const [expandLeftNav, setExpandLeftNav] = useState(false);
|
||||||
const [activeOrgName, setActiveOrgName] = useState(
|
const [activeOrgName, setActiveOrgName] = useState(
|
||||||
@@ -790,7 +790,7 @@ const LeftSideBar = ({ userdata, serverside, globalUrl, notifications, }) => {
|
|||||||
height: "calc((100vh - 32px)*1.2)",
|
height: "calc((100vh - 32px)*1.2)",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{searchBarModalOpen ? <ModalView serverside={serverside} userdata={userdata} searchBarModalOpen={searchBarModalOpen} setSearchBarModalOpen={setSearchBarModalOpen} globalUrl={globalUrl} /> : null}
|
{searchBarModalOpen && !isDocSearchModalOpen ? <ModalView serverside={serverside} userdata={userdata} searchBarModalOpen={searchBarModalOpen} setSearchBarModalOpen={setSearchBarModalOpen} globalUrl={globalUrl} isDocSearchModalOpen={isDocSearchModalOpen} /> : null}
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@@ -1911,11 +1911,11 @@ const LeftSideBar = ({ userdata, serverside, globalUrl, notifications, }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default LeftSideBar;
|
export default LeftSideBar;
|
||||||
const ModalView = memo(({searchBarModalOpen, setSearchBarModalOpen, globalUrl, serverside, userdata}) => {
|
const ModalView = memo(({searchBarModalOpen, setSearchBarModalOpen, globalUrl, serverside, userdata, isDocSearchModalOpen}) => {
|
||||||
return (
|
return (
|
||||||
(
|
(
|
||||||
<Dialog
|
<Dialog
|
||||||
open={searchBarModalOpen}
|
open={searchBarModalOpen && !isDocSearchModalOpen}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setSearchBarModalOpen(false);
|
setSearchBarModalOpen(false);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
AppBar,
|
AppBar,
|
||||||
@@ -35,6 +35,7 @@ import { toast } from "react-toastify";
|
|||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
import Mousetrap from "mousetrap";
|
import Mousetrap from "mousetrap";
|
||||||
import LicencePopup from "../components/LicencePopup.jsx";
|
import LicencePopup from "../components/LicencePopup.jsx";
|
||||||
|
import { Context } from "../context/ContextApi.jsx";
|
||||||
|
|
||||||
const curpath = (typeof window !== "undefined" && window.location && typeof window.location.pathname === "string")
|
const curpath = (typeof window !== "undefined" && window.location && typeof window.location.pathname === "string")
|
||||||
? window.location.pathname
|
? window.location.pathname
|
||||||
@@ -750,7 +751,7 @@ const Navbar = (props) => {
|
|||||||
const topbar_var = "topbar_closed10"
|
const topbar_var = "topbar_closed10"
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const [searchBarModalOpen, setSearchBarModalOpen] = useState(false);
|
const {searchBarModalOpen, setSearchBarModalOpen, isDocSearchModalOpen} = useContext(Context)
|
||||||
const [pricingModalOpen, setPricingModalOpen] = useState(false);
|
const [pricingModalOpen, setPricingModalOpen] = useState(false);
|
||||||
const isTabletOrMobile = useMediaQuery(theme.breakpoints.down("lg"));
|
const isTabletOrMobile = useMediaQuery(theme.breakpoints.down("lg"));
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down("md"));
|
const isMobile = useMediaQuery(theme.breakpoints.down("md"));
|
||||||
@@ -845,7 +846,7 @@ const Navbar = (props) => {
|
|||||||
|
|
||||||
const modalView = (
|
const modalView = (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={searchBarModalOpen}
|
open={searchBarModalOpen && !isDocSearchModalOpen}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setSearchBarModalOpen(false);
|
setSearchBarModalOpen(false);
|
||||||
}}
|
}}
|
||||||
@@ -1287,10 +1288,21 @@ const Navbar = (props) => {
|
|||||||
<Button
|
<Button
|
||||||
onMouseEnter={() => handleMenuOpen(item)}
|
onMouseEnter={() => handleMenuOpen(item)}
|
||||||
onMouseLeave={(e) => {
|
onMouseLeave={(e) => {
|
||||||
// Only close if not moving to dropdown
|
|
||||||
|
const dropdown = document.querySelector('.dropdown-content'); // Adjust the selector as needed
|
||||||
const rect = e.currentTarget.getBoundingClientRect();
|
const rect = e.currentTarget.getBoundingClientRect();
|
||||||
|
const dropdownRect = dropdown ? dropdown.getBoundingClientRect() : null;
|
||||||
|
|
||||||
|
// Check if the cursor is moving down
|
||||||
const isMovingDown = e.clientY > rect.bottom;
|
const isMovingDown = e.clientY > rect.bottom;
|
||||||
if (!isMovingDown) {
|
|
||||||
|
// Check if the cursor is within the dropdown area or a buffer zone
|
||||||
|
const isOverDropdown = dropdownRect && (
|
||||||
|
(e.clientY >= dropdownRect.top - 20 && e.clientY <= dropdownRect.bottom + 20) && // Buffer zone
|
||||||
|
(e.clientX >= dropdownRect.left && e.clientX <= dropdownRect.right)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isMovingDown && !isOverDropdown) {
|
||||||
handleMenuClose();
|
handleMenuClose();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
@@ -1352,6 +1364,11 @@ const Navbar = (props) => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
if(isCloud) {
|
if(isCloud) {
|
||||||
navigate("/pricing");
|
navigate("/pricing");
|
||||||
|
ReactGA.event({
|
||||||
|
category: "navbar",
|
||||||
|
action: "pricing_click",
|
||||||
|
label: "go_to_pricing",
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
window.open("https://shuffler.io/pricing", '_blank');
|
window.open("https://shuffler.io/pricing", '_blank');
|
||||||
return;
|
return;
|
||||||
@@ -1365,6 +1382,11 @@ const Navbar = (props) => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
if(isCloud) {
|
if(isCloud) {
|
||||||
navigate("/partners");
|
navigate("/partners");
|
||||||
|
ReactGA.event({
|
||||||
|
category: "navbar",
|
||||||
|
action: "partners_click",
|
||||||
|
label: "go_to_partners",
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
window.open("https://shuffler.io/partners", '_blank');
|
window.open("https://shuffler.io/partners", '_blank');
|
||||||
return;
|
return;
|
||||||
@@ -1722,7 +1744,11 @@ const Navbar = (props) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{topbar}
|
{topbar}
|
||||||
<Container maxWidth="xl">
|
<Container maxWidth="xl" sx={{ zoom: {
|
||||||
|
md: "0.7",
|
||||||
|
lg: "0.8",
|
||||||
|
xl: "1",
|
||||||
|
} }}>
|
||||||
<Toolbar disableGutters sx={{ justifyContent: "space-between" }}>
|
<Toolbar disableGutters sx={{ justifyContent: "space-between" }}>
|
||||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||||
<Link
|
<Link
|
||||||
|
|||||||
@@ -51,12 +51,13 @@ const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e52
|
|||||||
const SearchData = props => {
|
const SearchData = props => {
|
||||||
const { serverside, globalUrl, userdata } = props
|
const { serverside, globalUrl, userdata } = props
|
||||||
let navigate = useNavigate();
|
let navigate = useNavigate();
|
||||||
const { searchBarModalOpen, setSearchBarModalOpen } = useContext(Context);
|
const { searchBarModalOpen, setSearchBarModalOpen, isDocSearchModalOpen } = useContext(Context);
|
||||||
const borderRadius = 3
|
const borderRadius = 3
|
||||||
const node = useRef()
|
const node = useRef()
|
||||||
const [searchOpen, setSearchOpen] = useState(false)
|
const [searchOpen, setSearchOpen] = useState(false)
|
||||||
const [oldPath, setOldPath] = useState("")
|
const [oldPath, setOldPath] = useState("")
|
||||||
const [value, setValue] = useState("");
|
const [value, setValue] = useState("");
|
||||||
|
const isDocSearchModal = isDocSearchModalOpen;
|
||||||
|
|
||||||
const handleLinkClick = () => {
|
const handleLinkClick = () => {
|
||||||
if (searchBarModalOpen) {
|
if (searchBarModalOpen) {
|
||||||
@@ -90,6 +91,8 @@ const SearchData = props => {
|
|||||||
const [inputValue, setInputValue] = useState(currentRefinement);
|
const [inputValue, setInputValue] = useState(currentRefinement);
|
||||||
|
|
||||||
const textFieldRef = useRef(null);
|
const textFieldRef = useRef(null);
|
||||||
|
const debounceTimeoutRef = useRef(null);
|
||||||
|
|
||||||
const keyPressHandler = (e) => {
|
const keyPressHandler = (e) => {
|
||||||
if (e.key === "Enter") {
|
if (e.key === "Enter") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -110,10 +113,25 @@ const SearchData = props => {
|
|||||||
}, [searchOpen]);
|
}, [searchOpen]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (currentRefinement !== inputValue) {
|
// Clear any existing timeout to prevent multiple executions
|
||||||
refine(inputValue);
|
if (debounceTimeoutRef.current) {
|
||||||
|
clearTimeout(debounceTimeoutRef.current);
|
||||||
}
|
}
|
||||||
}, [currentRefinement]);
|
|
||||||
|
// Set a new timeout that will execute the search after a 200ms delay
|
||||||
|
debounceTimeoutRef.current = setTimeout(() => {
|
||||||
|
refine(inputValue);
|
||||||
|
setSearchOpen(inputValue.trim() !== '');
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
// Cleanup function that runs when component unmounts or when dependencies change
|
||||||
|
// This ensures we don't have any hanging timeouts
|
||||||
|
return () => {
|
||||||
|
if (debounceTimeoutRef.current) {
|
||||||
|
clearTimeout(debounceTimeoutRef.current);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [inputValue, refine]); // Effect runs when inputValue or refine function changes
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
@@ -122,7 +140,7 @@ const SearchData = props => {
|
|||||||
>
|
>
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
style={{ zIndex: 1100, marginTop: -20, marginBottom: 200, position: "fixed", backgroundColor: theme.palette.inputColor, borderRadius: borderRadius, width: 685, }}
|
style={{ zIndex: 1100, marginTop: -20, marginBottom: 200, position: "fixed", backgroundColor: theme.palette.inputColor, borderRadius: borderRadius, width: 690, }}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
style: {
|
style: {
|
||||||
color: "white",
|
color: "white",
|
||||||
@@ -149,7 +167,7 @@ const SearchData = props => {
|
|||||||
autoComplete='off'
|
autoComplete='off'
|
||||||
type="search"
|
type="search"
|
||||||
color="primary"
|
color="primary"
|
||||||
placeholder="Find Public Apps, Workflows, Documentation..."
|
placeholder={isDocSearchModal ? "Type to search documentation..." : "Find Public Apps, Workflows, Documentation..."}
|
||||||
value={inputValue}
|
value={inputValue}
|
||||||
id="shuffle_search_field"
|
id="shuffle_search_field"
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
@@ -163,12 +181,6 @@ const SearchData = props => {
|
|||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
const newValue = event.target.value;
|
const newValue = event.target.value;
|
||||||
setInputValue(newValue);
|
setInputValue(newValue);
|
||||||
refine(newValue);
|
|
||||||
if (newValue.trim() !== '') {
|
|
||||||
setSearchOpen(true);
|
|
||||||
} else {
|
|
||||||
setSearchOpen(false);
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
onKeyDown={keyPressHandler}
|
onKeyDown={keyPressHandler}
|
||||||
inputRef={textFieldRef}
|
inputRef={textFieldRef}
|
||||||
@@ -605,7 +617,11 @@ const SearchData = props => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hits.length > 4) {
|
if (hits.length > 4) {
|
||||||
hits = hits.slice(0, 4)
|
if(!isDocSearchModal) {
|
||||||
|
hits = hits.slice(0, 4)
|
||||||
|
} else {
|
||||||
|
hits = hits.slice(0, 15)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const type = "documentation"
|
const type = "documentation"
|
||||||
@@ -614,15 +630,19 @@ const SearchData = props => {
|
|||||||
//console.log(type, hits.length, hits)
|
//console.log(type, hits.length, hits)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card elevation={0} style={{ marginRight: 10, marginTop: 50, color: "white", zIndex: 1002, backgroundColor: theme.palette.inputColor, width: "100%", left: 470, boxShadows: "none", }}>
|
<Card elevation={0} style={{ marginRight: 10, marginTop: isDocSearchModal ? 0 : 50, color: "white", zIndex: 1002, backgroundColor: theme.palette.inputColor, width: "100%", left: 470, boxShadows: "none", }}>
|
||||||
{/* <IconButton style={{ zIndex: 5000, position: "absolute", right: 14, color: "grey" }} onClick={() => {
|
{/* <IconButton style={{ zIndex: 5000, position: "absolute", right: 14, color: "grey" }} onClick={() => {
|
||||||
setSearchOpen(false)
|
setSearchOpen(false)
|
||||||
}}>
|
}}>
|
||||||
<CloseIcon />
|
<CloseIcon />
|
||||||
</IconButton> */}
|
</IconButton> */}
|
||||||
<Typography variant="h6" style={{ margin: "10px 10px 0px 20px", color: "#FF8444", borderBottom: "1px solid", width: 152 }}>
|
{
|
||||||
Documentation
|
!isDocSearchModal && (
|
||||||
</Typography>
|
<Typography variant="h6" style={{ margin: "10px 10px 0px 20px", color: "#FF8444", borderBottom: "1px solid", width: 152 }}>
|
||||||
|
Documentation
|
||||||
|
</Typography>
|
||||||
|
)
|
||||||
|
}
|
||||||
{/*
|
{/*
|
||||||
<IconButton edge="end" aria-label="delete" style={{position: "absolute", top: 5, right: 15,}} onClick={() => {
|
<IconButton edge="end" aria-label="delete" style={{position: "absolute", top: 5, right: 15,}} onClick={() => {
|
||||||
setSearchOpen(false)
|
setSearchOpen(false)
|
||||||
@@ -630,7 +650,7 @@ const SearchData = props => {
|
|||||||
<DeleteIcon />
|
<DeleteIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
*/}
|
*/}
|
||||||
<List style={{ backgroundColor: theme.palette.inputColor, }}>
|
<List style={{ backgroundColor: theme.palette.inputColor, marginTop: isDocSearchModal ? 35 : 0, }}>
|
||||||
{hits.length === 0 ?
|
{hits.length === 0 ?
|
||||||
<ListItem style={outerlistitemStyle}>
|
<ListItem style={outerlistitemStyle}>
|
||||||
<ListItemAvatar onClick={() => console.log(hits)}>
|
<ListItemAvatar onClick={() => console.log(hits)}>
|
||||||
@@ -654,8 +674,8 @@ const SearchData = props => {
|
|||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
marginLeft: 5,
|
marginLeft: 5,
|
||||||
marginRight: 5,
|
marginRight: 5,
|
||||||
maxHeight: 75,
|
maxHeight: isDocSearchModal ? 100 : 75,
|
||||||
minHeight: 75,
|
minHeight: isDocSearchModal ? 100 : 75,
|
||||||
maxWidth: 420,
|
maxWidth: 420,
|
||||||
minWidth: "100%",
|
minWidth: "100%",
|
||||||
}
|
}
|
||||||
@@ -666,9 +686,13 @@ const SearchData = props => {
|
|||||||
(hit.name.charAt(0).toUpperCase() + hit.name.slice(1)).replaceAll("_", " ")
|
(hit.name.charAt(0).toUpperCase() + hit.name.slice(1)).replaceAll("_", " ")
|
||||||
|
|
||||||
if (name.length > 30) {
|
if (name.length > 30) {
|
||||||
name = name.slice(0, 30) + "..."
|
if(isDocSearchModal) {
|
||||||
|
name = name.slice(0, 70) + "..."
|
||||||
|
} else {
|
||||||
|
name = name.slice(0, 30) + "..."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const secondaryText = hit.data !== undefined ? hit.data.slice(0, 40) + "..." : ""
|
const secondaryText = hit.data !== undefined ? hit.data.slice(0, 80) + "..." : ""
|
||||||
const avatar = hit.image_url === undefined ?
|
const avatar = hit.image_url === undefined ?
|
||||||
baseImage
|
baseImage
|
||||||
:
|
:
|
||||||
@@ -719,7 +743,7 @@ const SearchData = props => {
|
|||||||
</ListItemAvatar>
|
</ListItemAvatar>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={name}
|
primary={name}
|
||||||
secondary={secondaryText}
|
secondary={<div style={{ padding: '8px 0' }}>{secondaryText}</div>}
|
||||||
/>
|
/>
|
||||||
{/*
|
{/*
|
||||||
<ListItemSecondaryAction>
|
<ListItemSecondaryAction>
|
||||||
@@ -897,28 +921,38 @@ const SearchData = props => {
|
|||||||
|
|
||||||
const modalView = (
|
const modalView = (
|
||||||
<div>
|
<div>
|
||||||
<Grid container style={{ display: "contents", }}>
|
{
|
||||||
<Grid item xs="auto" style={{}}>
|
!isDocSearchModal ? (
|
||||||
<Index indexName="appsearch">
|
<Grid container style={{ display: "contents", }}>
|
||||||
<CustomAppHits />
|
<Grid item xs="auto" style={{}}>
|
||||||
</Index>
|
<Index indexName="appsearch">
|
||||||
|
<CustomAppHits />
|
||||||
|
</Index>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs="auto" style={{}}>
|
||||||
|
<Index indexName="workflows">
|
||||||
|
<CustomWorkflowHits />
|
||||||
|
</Index>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs="auto" style={{}}>
|
||||||
|
<Index indexName="documentation">
|
||||||
|
<CustomDocHits />
|
||||||
|
</Index>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs="auto" style={{}}>
|
||||||
|
<Index indexName="discord_chat">
|
||||||
|
<CustomDiscordHits />
|
||||||
|
</Index>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs="auto" style={{}}>
|
) : (
|
||||||
<Index indexName="workflows">
|
<Grid item xs="auto" style={{width: "100%"}}>
|
||||||
<CustomWorkflowHits />
|
<Index indexName="documentation">
|
||||||
</Index>
|
<CustomDocHits />
|
||||||
</Grid>
|
</Index>
|
||||||
<Grid item xs="auto" style={{}}>
|
</Grid>
|
||||||
<Index indexName="documentation">
|
)
|
||||||
<CustomDocHits />
|
}
|
||||||
</Index>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs="auto" style={{}}>
|
|
||||||
<Index indexName="discord_chat">
|
|
||||||
<CustomDiscordHits />
|
|
||||||
</Index>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -932,7 +966,7 @@ const SearchData = props => {
|
|||||||
<CustomSearchBox />
|
<CustomSearchBox />
|
||||||
{modalView}
|
{modalView}
|
||||||
</InstantSearch>
|
</InstantSearch>
|
||||||
{gettingStartData}
|
{!isDocSearchModal && gettingStartData}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export const AppContext = (props) => {
|
|||||||
|
|
||||||
// Left side bar global states
|
// Left side bar global states
|
||||||
const [searchBarModalOpen, setSearchBarModalOpen] = useState(false);
|
const [searchBarModalOpen, setSearchBarModalOpen] = useState(false);
|
||||||
|
const [isDocSearchModalOpen, setIsDocSearchModalOpen] = useState(false);
|
||||||
const [leftSideBarOpenByClick, setLeftSideBarOpenByClick] = useState(currentLocation?.includes('/workflows/') ? false : true)
|
const [leftSideBarOpenByClick, setLeftSideBarOpenByClick] = useState(currentLocation?.includes('/workflows/') ? false : true)
|
||||||
const [windowWidth, setWindowWidth] = useState(serverside === true ? 100 : window.innerWidth);
|
const [windowWidth, setWindowWidth] = useState(serverside === true ? 100 : window.innerWidth);
|
||||||
|
|
||||||
@@ -37,6 +38,8 @@ export const AppContext = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Context.Provider value={{
|
<Context.Provider value={{
|
||||||
|
isDocSearchModalOpen,
|
||||||
|
setIsDocSearchModalOpen,
|
||||||
searchBarModalOpen,
|
searchBarModalOpen,
|
||||||
setSearchBarModalOpen,
|
setSearchBarModalOpen,
|
||||||
leftSideBarOpenByClick,
|
leftSideBarOpenByClick,
|
||||||
|
|||||||
+126
-2
@@ -23,7 +23,12 @@ import {
|
|||||||
List,
|
List,
|
||||||
Collapse,
|
Collapse,
|
||||||
ListItemButton,
|
ListItemButton,
|
||||||
ListItemText
|
ListItemText,
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
Box,
|
||||||
|
DialogContent,
|
||||||
|
InputAdornment
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import {
|
import {
|
||||||
Link as LinkIcon,
|
Link as LinkIcon,
|
||||||
@@ -32,9 +37,12 @@ import {
|
|||||||
ExpandMore as ExpandMoreIcon,
|
ExpandMore as ExpandMoreIcon,
|
||||||
FileCopy as FileCopyIcon,
|
FileCopy as FileCopyIcon,
|
||||||
ChevronLeft,
|
ChevronLeft,
|
||||||
ChevronRight
|
ChevronRight,
|
||||||
|
Search as SearchIcon,
|
||||||
|
Close as CloseIcon
|
||||||
} from "@mui/icons-material";
|
} from "@mui/icons-material";
|
||||||
import { fontGrid } from "@mui/material/styles/cssUtils.js";
|
import { fontGrid } from "@mui/material/styles/cssUtils.js";
|
||||||
|
import SearchBox from "../components/SearchData.jsx";
|
||||||
|
|
||||||
const Body = {
|
const Body = {
|
||||||
//maxWidth: 1000,
|
//maxWidth: 1000,
|
||||||
@@ -280,6 +288,8 @@ export const CodeHandler = (props) => {
|
|||||||
const Docs = (defaultprops) => {
|
const Docs = (defaultprops) => {
|
||||||
const { globalUrl, selectedDoc, serverside, serverMobile, isLoggedIn, isLoaded, userdata } = defaultprops;
|
const { globalUrl, selectedDoc, serverside, serverMobile, isLoggedIn, isLoaded, userdata } = defaultprops;
|
||||||
|
|
||||||
|
const { searchBarModalOpen, setSearchBarModalOpen, isDocSearchModalOpen, setIsDocSearchModalOpen, leftSideBarOpenByClick } = useContext(Context);
|
||||||
|
|
||||||
let navigate = useNavigate();
|
let navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
// Quickfix for react router 5 -> 6
|
// Quickfix for react router 5 -> 6
|
||||||
@@ -316,6 +326,7 @@ const Docs = (defaultprops) => {
|
|||||||
const [activeSubItem, setActiveSubItem] = useState(false);
|
const [activeSubItem, setActiveSubItem] = useState(false);
|
||||||
const headingElementsRef = useRef({})
|
const headingElementsRef = useRef({})
|
||||||
var isArticlePage = window.location.pathname.includes("/articles/") || window.location.pathname === "/articles" ? true : false;
|
var isArticlePage = window.location.pathname.includes("/articles/") || window.location.pathname === "/articles" ? true : false;
|
||||||
|
const searchFieldRef = useRef(null);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -338,6 +349,13 @@ const Docs = (defaultprops) => {
|
|||||||
}
|
}
|
||||||
}, [location]);
|
}, [location]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
setIsDocSearchModalOpen(false);
|
||||||
|
setSearchBarModalOpen(false);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleClick = (event) => {
|
const handleClick = (event) => {
|
||||||
setAnchorEl(event.currentTarget);
|
setAnchorEl(event.currentTarget);
|
||||||
}
|
}
|
||||||
@@ -467,6 +485,71 @@ const Docs = (defaultprops) => {
|
|||||||
return headings;
|
return headings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const modalView = (
|
||||||
|
<Dialog
|
||||||
|
open={searchBarModalOpen && isDocSearchModalOpen}
|
||||||
|
onClose={() => {
|
||||||
|
setSearchBarModalOpen(false);
|
||||||
|
if (searchFieldRef.current) {
|
||||||
|
searchFieldRef.current.blur();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
PaperProps={{
|
||||||
|
style: {
|
||||||
|
color: "white",
|
||||||
|
minWidth: 750,
|
||||||
|
minHeight: "180px",
|
||||||
|
maxHeight: "85vh",
|
||||||
|
borderRadius: 16,
|
||||||
|
border: "1px solid var(--Container-Stroke, #494949)",
|
||||||
|
background: "var(--Container, #000000)",
|
||||||
|
boxShadow: "0px 16px 24px 8px rgba(0, 0, 0, 0.25)",
|
||||||
|
position: "fixed",
|
||||||
|
top: "70px",
|
||||||
|
left: "50%",
|
||||||
|
transform: "translateX(-50%)",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
zIndex: 50005,
|
||||||
|
'& .MuiBackdrop-root': {
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center", px: 2, pr: 3, pt: 2 }}>
|
||||||
|
<DialogTitle
|
||||||
|
sx={{
|
||||||
|
color: "var(--Paragraph-text, #C8C8C8)",
|
||||||
|
p: 0,
|
||||||
|
m: 0,
|
||||||
|
ml: 1.5,
|
||||||
|
fontFamily: theme.typography.fontFamily,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Search for Documentation
|
||||||
|
</DialogTitle>
|
||||||
|
<IconButton
|
||||||
|
onClick={() => setSearchBarModalOpen(false)}
|
||||||
|
sx={{
|
||||||
|
color: 'white',
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: 'rgba(255, 255, 255, 0.1)'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CloseIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
<DialogContent>
|
||||||
|
<Box sx={{ pt: 3 }}>
|
||||||
|
<SearchBox globalUrl={globalUrl} serverside={serverside} userdata={userdata} />
|
||||||
|
</Box>
|
||||||
|
</DialogContent>
|
||||||
|
<Divider sx={{ backgroundColor: 'rgba(255, 255, 255, 0.1)' }}/>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// extract TOC from actual markdown
|
// extract TOC from actual markdown
|
||||||
const tocvalue = (markdown) => {
|
const tocvalue = (markdown) => {
|
||||||
@@ -1117,9 +1200,50 @@ const Docs = (defaultprops) => {
|
|||||||
<div style={Body}>
|
<div style={Body}>
|
||||||
<div style={!isArticlePage ? SideBar : (sidebarOpen ? SideBar : collapsedSideBar)}>
|
<div style={!isArticlePage ? SideBar : (sidebarOpen ? SideBar : collapsedSideBar)}>
|
||||||
<Paper style={SidebarPaperStyle}>
|
<Paper style={SidebarPaperStyle}>
|
||||||
|
{modalView}
|
||||||
|
{
|
||||||
|
!isArticlePage && (
|
||||||
|
<TextField
|
||||||
|
variant="outlined"
|
||||||
|
placeholder="Search Docs..."
|
||||||
|
size="small"
|
||||||
|
onClick={() => {
|
||||||
|
setIsDocSearchModalOpen(true)
|
||||||
|
setSearchBarModalOpen(true)
|
||||||
|
}}
|
||||||
|
inputRef={searchFieldRef}
|
||||||
|
InputProps={{
|
||||||
|
endAdornment: (
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<SearchIcon style={{ color: "white" }} />
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
style: {
|
||||||
|
backgroundColor: "#212121",
|
||||||
|
borderRadius: 4,
|
||||||
|
color: "white",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
marginTop: 10,
|
||||||
|
marginLeft: 10,
|
||||||
|
borderRadius: 4,
|
||||||
|
width: !isLoggedIn ? "14%" : !leftSideBarOpenByClick ? "12%" : "11%",
|
||||||
|
maxWidth: "285px",
|
||||||
|
position: "fixed",
|
||||||
|
zIndex: 1100,
|
||||||
|
}}
|
||||||
|
inputProps={{
|
||||||
|
readOnly: true,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
<List style={{
|
<List style={{
|
||||||
listStyle: "none",
|
listStyle: "none",
|
||||||
paddingLeft: "0",
|
paddingLeft: "0",
|
||||||
|
paddingTop: !isArticlePage ? "60px" : undefined,
|
||||||
|
paddingBottom: !isArticlePage ? "30px" : undefined,
|
||||||
display: isArticlePage ? sidebarOpen ? "block" : "none" : undefined,
|
display: isArticlePage ? sidebarOpen ? "block" : "none" : undefined,
|
||||||
opacity: isArticlePage ? sidebarOpen ? 1 : 0 : undefined,
|
opacity: isArticlePage ? sidebarOpen ? 1 : 0 : undefined,
|
||||||
transition: isArticlePage ? "opacity 0.3s ease" : undefined,
|
transition: isArticlePage ? "opacity 0.3s ease" : undefined,
|
||||||
|
|||||||
@@ -773,25 +773,36 @@ func handleBackendImageDownload(ctx context.Context, images string) error {
|
|||||||
//time.Sleep(time.Duration(30) * time.Second)
|
//time.Sleep(time.Duration(30) * time.Second)
|
||||||
|
|
||||||
newImages := []string{}
|
newImages := []string{}
|
||||||
for _, image := range strings.Split(images, ",") {
|
for _, curimage := range strings.Split(images, ",") {
|
||||||
image = strings.TrimSpace(image)
|
curimage = strings.TrimSpace(curimage)
|
||||||
if shuffle.ArrayContains(handled, image) {
|
if shuffle.ArrayContains(handled, curimage) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
handled = append(handled, image)
|
handled = append(handled, curimage)
|
||||||
if !strings.Contains(image, "/") {
|
if !strings.Contains(curimage, "/") {
|
||||||
image = fmt.Sprintf("frikky/shuffle:%s", image)
|
curimage = fmt.Sprintf("frikky/shuffle:%s", curimage)
|
||||||
}
|
}
|
||||||
|
|
||||||
newImages = append(newImages, image)
|
newImages = append(newImages, curimage)
|
||||||
|
|
||||||
log.Printf("[DEBUG] Downloading image: %s", image)
|
// Force remove the current image to avoid cached layers
|
||||||
err := shuffle.DownloadDockerImageBackend(&http.Client{Timeout: imagedownloadTimeout}, image)
|
_, err := dockercli.ImageRemove(ctx, curimage, image.RemoveOptions{
|
||||||
|
Force: true,
|
||||||
|
PruneChildren: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERROR] Failed removing image for re-download: %s", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("[DEBUG] Removed image: %s", curimage)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = shuffle.DownloadDockerImageBackend(&http.Client{Timeout: imagedownloadTimeout}, curimage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[ERROR] Failed downloading image: %s", err)
|
log.Printf("[ERROR] Failed downloading image: %s", err)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[DEBUG] Downloaded image: %s", image)
|
log.Printf("[DEBUG] Downloaded image: %s", curimage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user