diff --git a/src/common/Breadcrumbs/Breadcrumbs.jsx b/src/common/Breadcrumbs/Breadcrumbs.jsx
index 44e48643a8..05f65b078f 100644
--- a/src/common/Breadcrumbs/Breadcrumbs.jsx
+++ b/src/common/Breadcrumbs/Breadcrumbs.jsx
@@ -17,16 +17,17 @@ illegal under applicable law, and the grant of the foregoing license
under the Apache 2.0 license is conditioned upon your compliance with
such restriction.
*/
-import React, { useMemo, useRef, useState } from 'react'
+import React, { useEffect, useMemo, useRef, useState } from 'react'
import PropTypes from 'prop-types'
import { useLocation, useParams } from 'react-router-dom'
-import { useSelector } from 'react-redux'
+import { useDispatch, useSelector } from 'react-redux'
import BreadcrumbsStep from './BreadcrumbsStep/BreadcrumbsStep'
import { generateMlrunScreens, generateTabsList } from './breadcrumbs.util'
import { MONITORING_APP_PAGE, PROJECTS_PAGE_PATH } from '../../constants'
import { generateProjectsList } from '../../utils/projects'
+import { fetchNuclioFunctions } from '../../reducers/nuclioReducer'
import './breadcrumbs.scss'
@@ -34,16 +35,27 @@ const Breadcrumbs = ({ onClick = () => {} }) => {
const [searchValue, setSearchValue] = useState('')
const [showScreensList, setShowScreensList] = useState(false)
const [showProjectsList, setShowProjectsList] = useState(false)
+ const [showFunctionsList, setShowFunctionsList] = useState(false)
const breadcrumbsRef = useRef()
const params = useParams()
const location = useLocation()
+ const dispatch = useDispatch()
const projectStore = useSelector(state => state.projectStore)
+ const nuclioStore = useSelector(state => state.nuclioStore)
const projectsList = useMemo(() => {
return generateProjectsList(projectStore.projectsNames.data)
}, [projectStore.projectsNames.data])
+ const currentProjectFunctions = nuclioStore.currentProjectFunctions || []
+
+ useEffect(() => {
+ if (params.projectName && location.pathname.includes('real-time-functions')) {
+ dispatch(fetchNuclioFunctions({ project: params.projectName }))
+ }
+ }, [dispatch, params.projectName, location.pathname])
+
const mlrunScreens = useMemo(() => {
return generateMlrunScreens(params)
}, [params])
@@ -53,30 +65,35 @@ const Breadcrumbs = ({ onClick = () => {} }) => {
const urlParts = useMemo(() => {
if (params.projectName) {
- const [projects, projectName, screenName] = location.pathname.split('/').slice(1, 4)
+ const pathParts = location.pathname.split('/').slice(1)
+ const [projects, projectName, screenName, functionName, ...functionPath] = pathParts
+
const screen = mlrunScreens.find(screen => screen.id === screenName)
- let tab = projectTabs.find(tab =>
- location.pathname
- .split('/')
- .slice(3)
- .find(pathItem => pathItem === tab.id)
- )
-
- if (screen.id === MONITORING_APP_PAGE) {
+ let tab = projectTabs.find(tab => pathParts[2] === tab.id)
+
+ if (screen?.id === MONITORING_APP_PAGE) {
tab = {}
}
+ const pathItems = [projects, projectName, screen?.id || screenName]
+
+ if (screen?.id === 'real-time-functions' && functionName) {
+ pathItems.push(functionName)
+ }
+
return {
- pathItems: [projects, projectName, screen?.label || screenName],
+ pathItems,
screen,
- tab
+ tab,
+ functionName,
+ functionPath
}
} else {
const [page] = location.pathname.split('/').slice(3, 4)
const screen = mlrunScreens.find(screen => screen.id === page)
return {
- pathItems: [PROJECTS_PAGE_PATH, screen?.label || page],
+ pathItems: [PROJECTS_PAGE_PATH, screen?.id || page],
screen
}
}
@@ -99,8 +116,11 @@ const Breadcrumbs = ({ onClick = () => {} }) => {
setSearchValue={setSearchValue}
setShowProjectsList={setShowProjectsList}
setShowScreensList={setShowScreensList}
+ setShowFunctionsList={setShowFunctionsList}
showProjectsList={showProjectsList}
showScreensList={showScreensList}
+ showFunctionsList={showFunctionsList}
+ currentProjectFunctions={currentProjectFunctions}
urlPart={urlPart}
urlParts={urlParts}
/>
diff --git a/src/common/Breadcrumbs/BreadcrumbsStep/BreadcrumbsStep.jsx b/src/common/Breadcrumbs/BreadcrumbsStep/BreadcrumbsStep.jsx
index 33969d13bb..7e0b43a721 100644
--- a/src/common/Breadcrumbs/BreadcrumbsStep/BreadcrumbsStep.jsx
+++ b/src/common/Breadcrumbs/BreadcrumbsStep/BreadcrumbsStep.jsx
@@ -43,8 +43,11 @@ const BreadcrumbsStep = React.forwardRef(
setSearchValue,
setShowProjectsList,
setShowScreensList,
+ setShowFunctionsList,
showProjectsList,
showScreensList,
+ showFunctionsList,
+ currentProjectFunctions,
urlPart,
urlParts
},
@@ -54,10 +57,13 @@ const BreadcrumbsStep = React.forwardRef(
const separatorRef = useRef()
const isParam = useMemo(() => Object.values(params ?? {}).includes(urlPart), [urlPart, params])
- const label = useMemo(
- () => (isParam ? urlPart : urlPart.charAt(0).toUpperCase() + urlPart.slice(1)),
- [urlPart, isParam]
- )
+ const label = useMemo(() => {
+ if (isParam || urlPart === urlParts.functionName) return urlPart
+ if (urlParts.screen && urlPart === urlParts.screen.id) {
+ return urlParts.screen.label || urlPart
+ }
+ return urlPart.charAt(0).toUpperCase() + urlPart.slice(1)
+ }, [urlPart, isParam, urlParts.screen, urlParts.functionName])
const to = useMemo(
() => `/${urlParts.pathItems.slice(0, index + 1).join('/')}`,
[index, urlParts.pathItems]
@@ -70,15 +76,35 @@ const BreadcrumbsStep = React.forwardRef(
const separatorClassNames = classnames(
'breadcrumbs__separator',
((urlParts.pathItems[index + 1] === urlParts.screen?.id && !isParam) ||
- urlParts.pathItems[index + 1] === params.projectName) &&
+ urlParts.pathItems[index + 1] === params.projectName ||
+ urlParts.pathItems[index + 1] === urlParts.functionName) &&
'breadcrumbs__separator_tumbler'
)
+ const functionsListFormatted = useMemo(() => {
+ if (!Array.isArray(currentProjectFunctions)) return []
+
+ return currentProjectFunctions.map(func => {
+ const functionId = func?.metadata?.name || ''
+ const functionPath = urlParts?.functionPath?.length
+ ? `/${urlParts.functionPath.join('/')}`
+ : ''
+
+ return {
+ id: functionId,
+ label: functionId,
+ linkTo: `${to}/${functionId}${functionPath}`
+ }
+ })
+ }, [currentProjectFunctions, to, urlParts.functionPath])
+
const handleSelectDropdownItem = separatorRef => {
if (showProjectsList) setShowProjectsList(false)
if (showScreensList) setShowScreensList(false)
+ if (showFunctionsList) setShowFunctionsList(false)
+
separatorRef.current.classList.remove('breadcrumbs__separator_active')
}
@@ -94,6 +120,8 @@ const BreadcrumbsStep = React.forwardRef(
if (showScreensList) setShowScreensList(false)
if (showProjectsList) setShowProjectsList(false)
+
+ if (showFunctionsList) setShowFunctionsList(false)
}
setSearchValue('')
@@ -103,8 +131,10 @@ const BreadcrumbsStep = React.forwardRef(
setSearchValue,
setShowProjectsList,
setShowScreensList,
+ setShowFunctionsList,
showProjectsList,
- showScreensList
+ showScreensList,
+ showFunctionsList
]
)
@@ -127,9 +157,12 @@ const BreadcrumbsStep = React.forwardRef(
}, [handleCloseDropdown])
const handleSeparatorClick = (nextItem, separatorRef) => {
- const nextItemIsScreen = Boolean(mlrunScreens.find(screen => screen.label === nextItem))
+ const nextItemIsScreen = Boolean(mlrunScreens.find(screen => screen.id === nextItem))
+ const nextItemIsFunction = Boolean(
+ currentProjectFunctions.find(func => func.metadata.name === nextItem)
+ )
- if (nextItemIsScreen || nextItem === params.projectName) {
+ if (nextItemIsScreen || nextItem === params.projectName || nextItemIsFunction) {
const [activeSeparator] = document.getElementsByClassName('breadcrumbs__separator_active')
if (
@@ -142,17 +175,22 @@ const BreadcrumbsStep = React.forwardRef(
if (nextItemIsScreen) {
setShowScreensList(state => !state)
- if (showProjectsList) {
- setShowProjectsList(false)
- }
+ if (showProjectsList) setShowProjectsList(false)
+ if (showFunctionsList) setShowFunctionsList(false)
}
if (nextItem === params.projectName) {
setShowProjectsList(state => !state)
- if (showScreensList) {
- setShowScreensList(false)
- }
+ if (showScreensList) setShowScreensList(false)
+ if (showFunctionsList) setShowFunctionsList(false)
+ }
+
+ if (nextItemIsFunction) {
+ setShowFunctionsList(state => !state)
+
+ if (showScreensList) setShowScreensList(false)
+ if (showProjectsList) setShowProjectsList(false)
}
separatorRef.current.classList.toggle('breadcrumbs__separator_active')
@@ -185,7 +223,7 @@ const BreadcrumbsStep = React.forwardRef(
>
- {showScreensList && urlParts.pathItems[index + 1] === urlParts.screen?.label && (
+ {showScreensList && urlParts.pathItems[index + 1] === urlParts.screen?.id && (
)}
+ {showFunctionsList && urlParts.pathItems[index + 1] === urlParts.functionName && (
+ handleSelectDropdownItem(separatorRef)}
+ selectedItem={urlParts.functionName}
+ searchValue={searchValue}
+ setSearchValue={setSearchValue}
+ withSearch
+ />
+ )}
{showProjectsList && urlParts.pathItems[index + 1] === params.projectName && (
<>