Skip to content

Commit

Permalink
feat(heureka): switches to TopNavigationItem (#344)
Browse files Browse the repository at this point in the history
* chore(heureka): fix linting issues

* feat(heureka): uses TopNavigationItem instead of TabNavigationItem

* Create hot-dolphins-know.md

* Revert "chore(heureka): fix linting issues"

This reverts commit b4ecc09.

* feat(heureka): renames all tab names into navEntry

* Create little-onions-obey.md

* Delete .changeset/hot-dolphins-know.md
  • Loading branch information
hodanoori authored Sep 13, 2024
1 parent 732a05b commit 2078dc5
Show file tree
Hide file tree
Showing 12 changed files with 106 additions and 95 deletions.
5 changes: 5 additions & 0 deletions .changeset/little-onions-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fake-scope/fake-pkg": minor
---

feat(heureka): switches to TopNavigationItem
4 changes: 2 additions & 2 deletions apps/heureka/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { AppShell, AppShellProvider, CodeBlock } from "@cloudoperators/juno-ui-c
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { MessagesProvider } from "@cloudoperators/juno-messages-provider"
import AsyncWorker from "./components/AsyncWorker"
import TabContext from "./components/tabs/TabContext"
import NavEntryContext from "./components/navEntries/NavEntryContext"
import { ErrorBoundary } from "react-error-boundary"
import { useGlobalsActions, StoreProvider } from "./hooks/useAppStore"
import PanelManager from "./components/shared/PanelManager"
Expand Down Expand Up @@ -57,7 +57,7 @@ function App(props = {}) {
<ErrorBoundary fallbackRender={fallbackRender}>
<AsyncWorker consumerId={props.id} />
<PanelManager />
<TabContext />
<NavEntryContext />
</ErrorBoundary>
</AppShell>
</QueryClientProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
*/

import React, { useMemo } from "react"
import { useGlobalsActiveTab } from "../../hooks/useAppStore"
import { useGlobalsActiveNavEntry } from "../../hooks/useAppStore"

const TabPanel = ({ value, children }) => {
const activeTab = useGlobalsActiveTab()
const NavEntry = ({ value, children }) => {
const activeNavEntry = useGlobalsActiveNavEntry()

// ATENTION!! compare with == since tabindex is int and value is string
const displayChildren = useMemo(() => activeTab == value, [activeTab, value])
const displayChildren = useMemo(() => activeNavEntry == value, [activeNavEntry, value])

return <div style={{ display: displayChildren ? "inline" : "none" }}>{children}</div>
}

export default TabPanel
export default NavEntry
73 changes: 73 additions & 0 deletions apps/heureka/src/components/navEntries/NavEntryContext.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useMemo } from "react"
import { Container, TopNavigation, TopNavigationItem } from "@cloudoperators/juno-ui-components"
import NavEntry from "./NavEntry"
import { useGlobalsActions, useGlobalsActiveNavEntry } from "../../hooks/useAppStore"

import ServicesNav from "../services/ServicesTopNavItem"
import IssueMatchesNav from "../issueMatches/IssueMatchesTopNavItem"
import ComponentsNav from "../components/ComponentsTopNavItem"

const NAV_CONFIG = [
{
label: "Services",
value: "Services",
icon: "dns",
component: ServicesNav,
},
{
label: "IssueMatches",
value: "IssueMatches",
icon: "autoAwesomeMotion",
component: IssueMatchesNav,
},
{
label: "Components",
value: "Components",
icon: "autoAwesomeMotion",
component: ComponentsNav,
},
]

const NavEntryContext = () => {
const { setActiveNavEntry } = useGlobalsActions()
const activeNavEntry = useGlobalsActiveNavEntry()

// Memorized top navigation items
const memorizedNavItems = useMemo(
() =>
NAV_CONFIG.map((nav) => (
<TopNavigationItem
key={nav.value}
label={nav.label}
active={activeNavEntry === nav.value} // Set the active item
onClick={() => setActiveNavEntry(nav.value)} // Trigger tab change
/>
)),
[activeNavEntry, setActiveNavEntry]
)

// Memorized tab panels
const memorizedNavItemContents = useMemo(
() =>
NAV_CONFIG.map((nav) => (
<NavEntry key={nav.value} value={nav.value}>
<nav.component />
</NavEntry>
)),
[]
)

return (
<>
<TopNavigation onActiveItemChange={() => {}}>{memorizedNavItems}</TopNavigation>
<Container py>{memorizedNavItemContents}</Container>
</>
)
}

export default NavEntryContext
6 changes: 3 additions & 3 deletions apps/heureka/src/components/shared/ListController.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
useGlobalsActions,
useActiveFilters,
usePredefinedFilters,
useGlobalsActiveTab,
useGlobalsActiveNavEntry,
useSearchTerm,
} from "../../hooks/useAppStore"
import { Pagination, Container, Stack } from "@cloudoperators/juno-ui-components"
Expand All @@ -23,7 +23,7 @@ const ListController = ({ queryKey, entityName, ListComponent }) => {
const queryOptions = useGlobalsQueryOptions(queryKey)
const { setQueryOptions } = useGlobalsActions()
const { addMessage, resetMessages } = messageActions()
const activeTab = useGlobalsActiveTab()
const activeNavEntry = useGlobalsActiveNavEntry()
const activeFilters = useActiveFilters(entityName)
const predefinedFilters = usePredefinedFilters(entityName)
const searchTerm = useSearchTerm(entityName)
Expand All @@ -43,7 +43,7 @@ const ListController = ({ queryKey, entityName, ListComponent }) => {
},
},
],
enabled: !!queryClientFnReady && queryKey === activeTab,
enabled: !!queryClientFnReady && queryKey === activeNavEntry,
})

const [currentPage, setCurrentPage] = useState(1)
Expand Down
68 changes: 0 additions & 68 deletions apps/heureka/src/components/tabs/TabContext.jsx

This file was deleted.

5 changes: 3 additions & 2 deletions apps/heureka/src/hooks/useAppStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ const useAppStore = (selector) => useStore(useContext(StoreContext), selector)
// Globals exports
export const useGlobalsEmbedded = () => useAppStore((state) => state.globals.embedded)
export const useGlobalsQueryClientFnReady = () => useAppStore((state) => state.globals.queryClientFnReady)
export const useGlobalsActiveTab = () => useAppStore((state) => state.globals.activeTab)
export const useGlobalsQueryOptions = (tab) => useAppStore((state) => state.globals.tabs[tab].queryOptions)
export const useGlobalsActiveNavEntry = () => useAppStore((state) => state.globals.activeNavEntry)
export const useGlobalsQueryOptions = (navEntry) =>
useAppStore((state) => state.globals.navEntries[navEntry].queryOptions)
export const useGlobalsApiEndpoint = () => useAppStore((state) => state.globals.apiEndpoint)
export const useGlobalsShowPanel = () => useAppStore((state) => state.globals.showPanel)
export const useGlobalsShowServiceDetail = () => useAppStore((state) => state.globals.showServiceDetail)
Expand Down
16 changes: 8 additions & 8 deletions apps/heureka/src/hooks/useUrlState.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,38 @@

import { useState, useEffect } from "react"
import { registerConsumer } from "@cloudoperators/juno-url-state-provider-v1"
import { useGlobalsActions, useGlobalsActiveTab } from "./useAppStore"
import { useGlobalsActions, useGlobalsActiveNavEntry } from "./useAppStore"

const DEFAULT_KEY = "heureka"
const ACTIVE_TAB = "t"
const ACTIVE_NAV = "t"

const useUrlState = (key) => {
const [isURLRead, setIsURLRead] = useState(false)
// it is possible to have two apps instances on the same page
// int his case the key should be different per app
const urlStateManager = registerConsumer(key || DEFAULT_KEY)

const { setActiveTab } = useGlobalsActions()
const activeTab = useGlobalsActiveTab()
const { setActiveNavEntry } = useGlobalsActions()
const activeNavEntry = useGlobalsActiveNavEntry()

// Set initial state from URL (on login)
useEffect(() => {
if (isURLRead) return

// READ the url state and set the state
const newTabIndex = urlStateManager.currentState()?.[ACTIVE_TAB]
const newNavIndex = urlStateManager.currentState()?.[ACTIVE_NAV]
// SAVE the state
if (newTabIndex) setActiveTab(newTabIndex)
if (newNavIndex) setActiveNavEntry(newNavIndex)
setIsURLRead(true)
}, [isURLRead])

// SYNC states to URL state
useEffect(() => {
if (!isURLRead) return
urlStateManager.push({
[ACTIVE_TAB]: activeTab,
[ACTIVE_NAV]: activeNavEntry,
})
}, [isURLRead, activeTab])
}, [isURLRead, activeNavEntry])
}

export default useUrlState
14 changes: 7 additions & 7 deletions apps/heureka/src/lib/slices/createGlobalsSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ const createGlobalsSlice = (set, get, options) => ({
apiEndpoint: options?.apiEndpoint, //The API endpoint to use for fetching data.
isUrlStateSetup: false, //Set to true when the URL state has been set up.
queryClientFnReady: false, //Set to true when the queryClient function is ready to be used.
activeTab: "Services", //Set to the active tab.
activeNavEntry: "Services", //Set to the active navEntry.
showPanel: constants.PANEL_NONE, //Set to the which panel should be shown (e.g service details panel, issue matches details panel and so on), if any.

showServiceDetail: null,
showIssueDetail: null,
tabs: {
navEntries: {
Services: {
queryOptions: {
first: 20,
Expand Down Expand Up @@ -45,10 +45,10 @@ const createGlobalsSlice = (set, get, options) => ({
"globals/setQueryClientFnReady"
),

setQueryOptions: (tab, options) =>
setQueryOptions: (navEntry, options) =>
set(
produce((state) => {
state.globals.tabs[tab].queryOptions = options
state.globals.navEntries[navEntry].queryOptions = options
}),
false,
"globals/setQueryOptions"
Expand All @@ -63,13 +63,13 @@ const createGlobalsSlice = (set, get, options) => ({
false,
"globals/setApiEndpoint"
),
setActiveTab: (activeTab) =>
setActiveNavEntry: (activeNavEntry) =>
set(
(state) => ({
globals: { ...state.globals, activeTab: activeTab },
globals: { ...state.globals, activeNavEntry: activeNavEntry },
}),
false,
"globals/setActiveTab"
"globals/setActiveNavEntry"
),
setShowPanel: (panel) =>
set(
Expand Down

0 comments on commit 2078dc5

Please sign in to comment.