diff --git a/web/app/(commonLayout)/global-mounts.tsx b/web/app/(commonLayout)/global-mounts.tsx
new file mode 100644
index 00000000000..9da151d84f8
--- /dev/null
+++ b/web/app/(commonLayout)/global-mounts.tsx
@@ -0,0 +1,21 @@
+'use client'
+
+import dynamic from '@/next/dynamic'
+
+const InSiteMessageNotification = dynamic(() => import('@/app/components/app/in-site-message/notification'), { ssr: false })
+const PartnerStack = dynamic(() => import('@/app/components/billing/partner-stack'), { ssr: false })
+const ReadmePanel = dynamic(() => import('@/app/components/plugins/readme-panel'), { ssr: false })
+const WorkflowGeneratorMount = dynamic(() => import('@/app/components/workflow/workflow-generator/mount'), { ssr: false })
+const GotoAnything = dynamic(() => import('@/app/components/goto-anything').then(mod => mod.GotoAnything), { ssr: false })
+
+export function CommonLayoutGlobalMounts() {
+ return (
+ <>
+
+
+
+
+
+ >
+ )
+}
diff --git a/web/app/(commonLayout)/layout.tsx b/web/app/(commonLayout)/layout.tsx
index 69a72bdb3ee..e2d29f85d30 100644
--- a/web/app/(commonLayout)/layout.tsx
+++ b/web/app/(commonLayout)/layout.tsx
@@ -1,20 +1,16 @@
import type { ReactNode } from 'react'
-import InSiteMessageNotification from '@/app/components/app/in-site-message/notification'
import AmplitudeProvider from '@/app/components/base/amplitude'
import { GoogleAnalyticsScripts } from '@/app/components/base/ga'
import Zendesk from '@/app/components/base/zendesk'
import { EducationVerifyActionRecorder } from '@/app/components/education-verify-action-recorder'
-import { GotoAnything } from '@/app/components/goto-anything'
import MainNavLayout from '@/app/components/main-nav/layout'
import { NextRouteStateBridge } from '@/app/components/next-route-state'
import { OAuthRegistrationAnalytics } from '@/app/components/oauth-registration-analytics'
-import ReadmePanel from '@/app/components/plugins/readme-panel'
-import WorkflowGeneratorMount from '@/app/components/workflow/workflow-generator/mount'
import { AppContextProvider } from '@/context/app-context-provider'
import { EventEmitterContextProvider } from '@/context/event-emitter-provider'
import { ModalContextProvider } from '@/context/modal-context-provider'
import { ProviderContextProvider } from '@/context/provider-context-provider'
-import PartnerStack from '../components/billing/partner-stack'
+import { CommonLayoutGlobalMounts } from './global-mounts'
import { CommonLayoutHydrationBoundary } from './hydration-boundary'
export default async function Layout({ children }: { children: ReactNode }) {
@@ -33,11 +29,7 @@ export default async function Layout({ children }: { children: ReactNode }) {
{children}
-
-
-
-
-
+
diff --git a/web/app/components/main-nav/__tests__/index.spec.tsx b/web/app/components/main-nav/__tests__/index.spec.tsx
index 8846220c21c..d1722533b9a 100644
--- a/web/app/components/main-nav/__tests__/index.spec.tsx
+++ b/web/app/components/main-nav/__tests__/index.spec.tsx
@@ -495,7 +495,7 @@ describe('MainNav', () => {
expect(screen.queryByRole('link', { name: /common.menus.deployments/ })).not.toBeInTheDocument()
})
- it('aligns the global navigation spacing with the main sidebar design', () => {
+ it('aligns the global navigation spacing with the main sidebar design', async () => {
mockInstalledApps = [createInstalledApp()]
renderMainNav()
@@ -508,7 +508,7 @@ describe('MainNav', () => {
expect(homeLink.closest('nav')).toHaveClass('isolate', 'flex', 'flex-col', 'gap-px', 'p-2')
expect(homeLink).toHaveClass('h-8', 'w-full', 'rounded-[10px]', 'px-2', 'py-1.5')
- const webAppsButton = screen.getByRole('button', { name: 'explore.sidebar.webApps' })
+ const webAppsButton = await screen.findByRole('button', { name: 'explore.sidebar.webApps' })
expect(webAppsButton.parentElement).toHaveClass('py-1', 'pr-2', 'pl-2')
const helpButton = screen.getByRole('button', { name: 'common.mainNav.help.openMenu' })
@@ -551,7 +551,7 @@ describe('MainNav', () => {
expect(container.querySelector('.relative.z-30')).not.toBeInTheDocument()
})
- it('hides the environment tag when app detail navigation is collapsed', () => {
+ it('hides the environment tag when app detail navigation is collapsed', async () => {
mockPathname = '/app/app-1/overview'
;(useAppContext as Mock).mockReturnValue({
...appContextValue,
@@ -562,7 +562,7 @@ describe('MainNav', () => {
})
const { container } = renderMainNav()
- fireEvent.click(screen.getByTestId('app-detail-toggle'))
+ fireEvent.click(await screen.findByTestId('app-detail-toggle'))
expect(screen.queryByText('common.environment.testing')).not.toBeInTheDocument()
expect(container.querySelector('.relative.z-30')).not.toBeInTheDocument()
@@ -659,7 +659,7 @@ describe('MainNav', () => {
expect(screen.getByRole('link', { name: /common.mainNav.home/ })).not.toHaveAttribute('aria-current')
})
- it('replaces global navigation with snippet detail navigation on snippet routes', () => {
+ it('replaces global navigation with snippet detail navigation on snippet routes', async () => {
mockPathname = '/snippets/snippet-1/orchestrate'
snippetDraftState.inputFields = snippetFields
snippetNavigationState.onFieldsChange = mockSnippetFieldsChange
@@ -671,8 +671,8 @@ describe('MainNav', () => {
expect(screen.getByRole('complementary')).toHaveClass('w-62')
expect(screen.getByRole('complementary')).toHaveClass('p-1')
expect(screen.getByRole('complementary')).toHaveClass('bg-background-body')
- expect(screen.getByTestId('snippet-detail-top')).toHaveAttribute('data-expand', 'true')
- expect(screen.getByTestId('snippet-sidebar-content')).toHaveAttribute('data-readonly', 'false')
+ expect(await screen.findByTestId('snippet-detail-top')).toHaveAttribute('data-expand', 'true')
+ expect(await screen.findByTestId('snippet-sidebar-content')).toHaveAttribute('data-readonly', 'false')
expect(screen.getByText(snippet.name)).toBeInTheDocument()
expect(screen.getByText('query')).toBeInTheDocument()
fireEvent.click(screen.getByRole('button', { name: 'change snippet fields' }))
@@ -686,14 +686,14 @@ describe('MainNav', () => {
expect(screen.getByRole('button', { name: 'common.mainNav.help.openMenu' })).toBeInTheDocument()
})
- it('collapses snippet detail navigation from the top-right toggle', () => {
+ it('collapses snippet detail navigation from the top-right toggle', async () => {
mockPathname = '/snippets/snippet-1/orchestrate'
snippetDraftState.inputFields = snippetFields
snippetNavigationState.onFieldsChange = mockSnippetFieldsChange
snippetNavigationState.snippet = snippet
renderMainNav()
- fireEvent.click(screen.getByTestId('snippet-detail-toggle'))
+ fireEvent.click(await screen.findByTestId('snippet-detail-toggle'))
expect(screen.getByRole('complementary')).toHaveClass('w-16')
expect(screen.getByRole('complementary')).toHaveClass('p-1')
@@ -704,13 +704,13 @@ describe('MainNav', () => {
expect(localStorage.getItem(DETAIL_SIDEBAR_STORAGE_KEY)).toBe('collapse')
})
- it('replaces global navigation with app detail navigation on app routes', () => {
+ it('replaces global navigation with app detail navigation on app routes', async () => {
mockPathname = '/app/app-1/overview'
renderMainNav()
- expect(screen.getByTestId('app-detail-top')).toBeInTheDocument()
- expect(screen.getByTestId('app-detail-section')).toBeInTheDocument()
+ expect(await screen.findByTestId('app-detail-top')).toBeInTheDocument()
+ expect(await screen.findByTestId('app-detail-section')).toBeInTheDocument()
expect(screen.getByTestId('app-detail-top')).toHaveAttribute('data-expand', 'true')
expect(screen.getByTestId('app-detail-section')).toHaveAttribute('data-expand', 'true')
expect(screen.getByRole('complementary')).toHaveClass('w-62')
@@ -742,56 +742,56 @@ describe('MainNav', () => {
})
})
- it('collapses app detail navigation from the top-right toggle', () => {
+ it('collapses app detail navigation from the top-right toggle', async () => {
mockPathname = '/app/app-1/overview'
renderMainNav()
- fireEvent.click(screen.getByTestId('app-detail-toggle'))
+ fireEvent.click(await screen.findByTestId('app-detail-toggle'))
expect(screen.getByRole('complementary')).toHaveClass('w-16')
expect(screen.getByRole('complementary')).not.toHaveClass('transition-none')
expect(screen.getByRole('complementary')).toHaveClass('p-1')
expect(screen.getByTestId('app-detail-top')).toHaveAttribute('data-expand', 'false')
- expect(screen.getByTestId('app-detail-section')).toHaveAttribute('data-expand', 'false')
+ expect(await screen.findByTestId('app-detail-section')).toHaveAttribute('data-expand', 'false')
expect(localStorage.getItem(DETAIL_SIDEBAR_STORAGE_KEY)).toBe('collapse')
})
- it('shows app detail navigation as a floating preview when hovering the collapsed top toggle', () => {
+ it('shows app detail navigation as a floating preview when hovering the collapsed top toggle', async () => {
mockPathname = '/app/app-1/overview'
renderMainNav()
- fireEvent.click(screen.getByTestId('app-detail-toggle'))
+ fireEvent.click(await screen.findByTestId('app-detail-toggle'))
fireEvent.mouseEnter(screen.getByTestId('app-detail-top').parentElement!)
expect(screen.getByRole('complementary')).toHaveClass('w-16', 'overflow-visible')
expect(localStorage.getItem(DETAIL_SIDEBAR_STORAGE_KEY)).toBe('collapse')
expect(screen.getAllByTestId('app-detail-top')).toHaveLength(1)
expect(screen.getByTestId('app-detail-top')).toHaveAttribute('data-expand', 'true')
- expect(screen.getByTestId('app-detail-section')).toHaveAttribute('data-expand', 'true')
+ expect(await screen.findByTestId('app-detail-section')).toHaveAttribute('data-expand', 'true')
})
- it('persists expanded app detail navigation without width animation when clicking the hovered toggle', () => {
+ it('persists expanded app detail navigation without width animation when clicking the hovered toggle', async () => {
mockPathname = '/app/app-1/overview'
renderMainNav()
- fireEvent.click(screen.getByTestId('app-detail-toggle'))
+ fireEvent.click(await screen.findByTestId('app-detail-toggle'))
fireEvent.mouseEnter(screen.getByTestId('app-detail-top').parentElement!)
fireEvent.click(screen.getByTestId('app-detail-toggle'))
expect(screen.getByRole('complementary')).toHaveClass('w-62', 'transition-none')
expect(screen.getByRole('complementary')).not.toHaveClass('overflow-visible')
expect(screen.getByTestId('app-detail-top')).toHaveAttribute('data-expand', 'true')
- expect(screen.getByTestId('app-detail-section')).toHaveAttribute('data-expand', 'true')
+ expect(await screen.findByTestId('app-detail-section')).toHaveAttribute('data-expand', 'true')
expect(localStorage.getItem(DETAIL_SIDEBAR_STORAGE_KEY)).toBe('expand')
})
- it('replaces global navigation with dataset detail navigation on dataset routes', () => {
+ it('replaces global navigation with dataset detail navigation on dataset routes', async () => {
mockPathname = '/datasets/dataset-1/documents'
renderMainNav()
- expect(screen.getByTestId('dataset-detail-top')).toBeInTheDocument()
- expect(screen.getByTestId('dataset-detail-section')).toBeInTheDocument()
+ expect(await screen.findByTestId('dataset-detail-top')).toBeInTheDocument()
+ expect(await screen.findByTestId('dataset-detail-section')).toBeInTheDocument()
expect(screen.getByTestId('dataset-detail-top')).toHaveAttribute('data-expand', 'true')
expect(screen.getByTestId('dataset-detail-section')).toHaveAttribute('data-expand', 'true')
expect(screen.getByRole('complementary')).toHaveClass('w-62')
@@ -802,42 +802,44 @@ describe('MainNav', () => {
expect(screen.queryByRole('link', { name: /common.menus.datasets/ })).not.toBeInTheDocument()
})
- it('collapses dataset detail navigation from the top-right toggle', () => {
+ it('collapses dataset detail navigation from the top-right toggle', async () => {
mockPathname = '/datasets/dataset-1/documents'
renderMainNav()
- fireEvent.click(screen.getByTestId('dataset-detail-toggle'))
+ fireEvent.click(await screen.findByTestId('dataset-detail-toggle'))
expect(screen.getByRole('complementary')).toHaveClass('w-16')
expect(screen.getByRole('complementary')).toHaveClass('p-1')
expect(screen.getByTestId('dataset-detail-top')).toHaveAttribute('data-expand', 'false')
- expect(screen.getByTestId('dataset-detail-section')).toHaveAttribute('data-expand', 'false')
+ expect(await screen.findByTestId('dataset-detail-section')).toHaveAttribute('data-expand', 'false')
expect(localStorage.getItem(DETAIL_SIDEBAR_STORAGE_KEY)).toBe('collapse')
})
- it('shows dataset detail navigation as a floating preview when hovering the collapsed top toggle', () => {
+ it('shows dataset detail navigation as a floating preview when hovering the collapsed top toggle', async () => {
mockPathname = '/datasets/dataset-1/documents'
renderMainNav()
- fireEvent.click(screen.getByTestId('dataset-detail-toggle'))
+ fireEvent.click(await screen.findByTestId('dataset-detail-toggle'))
fireEvent.mouseEnter(screen.getByTestId('dataset-detail-top').parentElement!)
expect(screen.getByRole('complementary')).toHaveClass('w-16', 'overflow-visible')
expect(localStorage.getItem(DETAIL_SIDEBAR_STORAGE_KEY)).toBe('collapse')
expect(screen.getAllByTestId('dataset-detail-top')).toHaveLength(1)
expect(screen.getByTestId('dataset-detail-top')).toHaveAttribute('data-expand', 'true')
- expect(screen.getByTestId('dataset-detail-section')).toHaveAttribute('data-expand', 'true')
+ expect(await screen.findByTestId('dataset-detail-section')).toHaveAttribute('data-expand', 'true')
})
- it('replaces global navigation with agent detail navigation on roster detail routes', () => {
+ it('replaces global navigation with agent detail navigation on roster detail routes', async () => {
mockPathname = '/roster/agent/agent-1/configure'
renderMainNav()
- expect(screen.getByTestId('agent-detail-top')).toBeInTheDocument()
- expect(screen.getByTestId('agent-detail-section')).toBeInTheDocument()
+ expect(await screen.findByTestId('agent-detail-top')).toBeInTheDocument()
+ const agentDetailNavigation = await screen.findByRole('navigation', { name: 'agentV2.agentDetail.navigationLabel' })
+ expect(agentDetailNavigation).toBeInTheDocument()
+ expect(screen.getByRole('link', { name: /agentV2.agentDetail.sections.configure/ })).toHaveAttribute('href', '/roster/agent/agent-1/configure')
expect(screen.getByTestId('agent-detail-top')).toHaveAttribute('data-expand', 'true')
- expect(screen.getByTestId('agent-detail-section')).toHaveAttribute('data-expand', 'true')
+ expect(agentDetailNavigation).toHaveClass('px-1')
expect(screen.getByRole('complementary')).toHaveClass('w-62')
expect(screen.getByRole('complementary')).toHaveClass('p-1')
expect(screen.getByRole('complementary')).toHaveClass('bg-background-body')
@@ -873,16 +875,16 @@ describe('MainNav', () => {
expect(screen.queryByRole('link', { name: /common.menus.deployments/ })).not.toBeInTheDocument()
})
- it('collapses agent detail navigation from the top-right toggle', () => {
+ it('collapses agent detail navigation from the top-right toggle', async () => {
mockPathname = '/roster/agent/agent-1/configure'
renderMainNav()
- fireEvent.click(screen.getByTestId('agent-detail-toggle'))
+ fireEvent.click(await screen.findByTestId('agent-detail-toggle'))
expect(screen.getByRole('complementary')).toHaveClass('w-16')
expect(screen.getByRole('complementary')).toHaveClass('p-1')
expect(screen.getByTestId('agent-detail-top')).toHaveAttribute('data-expand', 'false')
- expect(screen.getByTestId('agent-detail-section')).toHaveAttribute('data-expand', 'false')
+ expect(await screen.findByRole('navigation', { name: 'agentV2.agentDetail.navigationLabel' })).toHaveClass('px-3')
expect(localStorage.getItem(DETAIL_SIDEBAR_STORAGE_KEY)).toBe('collapse')
})
@@ -923,18 +925,18 @@ describe('MainNav', () => {
)
})
- it('shows agent detail navigation as a floating preview when hovering the collapsed top toggle', () => {
+ it('shows agent detail navigation as a floating preview when hovering the collapsed top toggle', async () => {
mockPathname = '/roster/agent/agent-1/configure'
renderMainNav()
- fireEvent.click(screen.getByTestId('agent-detail-toggle'))
+ fireEvent.click(await screen.findByTestId('agent-detail-toggle'))
fireEvent.mouseEnter(screen.getByTestId('agent-detail-top').parentElement!)
expect(screen.getByRole('complementary')).toHaveClass('w-16', 'overflow-visible')
expect(localStorage.getItem(DETAIL_SIDEBAR_STORAGE_KEY)).toBe('collapse')
expect(screen.getAllByTestId('agent-detail-top')).toHaveLength(1)
expect(screen.getByTestId('agent-detail-top')).toHaveAttribute('data-expand', 'true')
- expect(screen.getByTestId('agent-detail-section')).toHaveAttribute('data-expand', 'true')
+ expect(await screen.findByRole('navigation', { name: 'agentV2.agentDetail.navigationLabel' })).toHaveClass('px-1')
})
it.each([
@@ -1258,12 +1260,12 @@ describe('MainNav', () => {
}
})
- it('collapses and expands installed web apps from the section arrow', () => {
+ it('collapses and expands installed web apps from the section arrow', async () => {
mockInstalledApps = [createInstalledApp()]
renderMainNav()
- const webAppsButton = screen.getByRole('button', { name: 'explore.sidebar.webApps' })
+ const webAppsButton = await screen.findByRole('button', { name: 'explore.sidebar.webApps' })
expect(webAppsButton).toHaveAttribute('aria-expanded', 'true')
expect(screen.getByText('Alpha App')).toBeInTheDocument()
diff --git a/web/app/components/main-nav/components/snippet-detail-section.tsx b/web/app/components/main-nav/components/snippet-detail-section.tsx
new file mode 100644
index 00000000000..e9798a903d5
--- /dev/null
+++ b/web/app/components/main-nav/components/snippet-detail-section.tsx
@@ -0,0 +1,35 @@
+'use client'
+
+import { useShallow } from 'zustand/react/shallow'
+import { SnippetCollapsedPreview } from '@/app/components/snippets/components/snippet-collapsed-preview'
+import { SnippetSidebarContent } from '@/app/components/snippets/components/snippet-sidebar'
+import { useSnippetDraftStore } from '@/app/components/snippets/draft-store'
+import { useSnippetDetailStore } from '@/app/components/snippets/store'
+
+type SnippetDetailSectionProps = {
+ expand: boolean
+}
+
+export function SnippetDetailSection({ expand }: SnippetDetailSectionProps) {
+ const snippetNavigation = useSnippetDetailStore(useShallow(state => ({
+ onFieldsChange: state.onFieldsChange,
+ readonly: state.readonly,
+ snippet: state.snippet,
+ })))
+ const snippetInputFields = useSnippetDraftStore(state => state.inputFields)
+
+ if (!expand)
+ return
+
+ if (!snippetNavigation.snippet || !snippetNavigation.onFieldsChange)
+ return null
+
+ return (
+
+ )
+}
diff --git a/web/app/components/main-nav/index.tsx b/web/app/components/main-nav/index.tsx
index 9caa2900bb2..19e0872b7b1 100644
--- a/web/app/components/main-nav/index.tsx
+++ b/web/app/components/main-nav/index.tsx
@@ -7,31 +7,21 @@ import { useSuspenseQuery } from '@tanstack/react-query'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useShallow } from 'zustand/react/shallow'
-import AppDetailSection from '@/app/components/app-sidebar/app-detail-section'
-import AppDetailTop from '@/app/components/app-sidebar/app-detail-top'
-import DatasetDetailSection from '@/app/components/app-sidebar/dataset-detail-section'
-import DatasetDetailTop from '@/app/components/app-sidebar/dataset-detail-top'
import { useStore as useAppStore } from '@/app/components/app/store'
import Badge from '@/app/components/base/badge'
import DifyLogo from '@/app/components/base/logo/dify-logo'
import EnvNav from '@/app/components/header/env-nav'
-import { SnippetCollapsedPreview } from '@/app/components/snippets/components/snippet-collapsed-preview'
-import { SnippetSidebarContent } from '@/app/components/snippets/components/snippet-sidebar'
-import { useSnippetDraftStore } from '@/app/components/snippets/draft-store'
-import { useSnippetDetailStore } from '@/app/components/snippets/store'
import { useAppContext } from '@/context/app-context'
-import { AgentDetailSection, AgentDetailTop } from '@/features/agent-v2/agent-detail/navigation'
import { isAgentV2Enabled } from '@/features/agent-v2/feature-flag'
import { DeploymentDetailSection, DeploymentDetailTop } from '@/features/deployments/detail/deployment-sidebar'
import { systemFeaturesQueryOptions } from '@/features/system-features/client'
+import dynamic from '@/next/dynamic'
import Link from '@/next/link'
import { usePathname } from '@/next/navigation'
import AccountSection from './components/account-section'
import HelpMenu from './components/help-menu'
import MainNavLink from './components/nav-link'
import { MainNavSearchButton } from './components/search-button'
-import SnippetDetailTop from './components/snippet-detail-top'
-import WebAppsSection from './components/web-apps-section'
import { WorkspaceCard } from './components/workspace-card'
import { isMainNavRouteVisible, MAIN_NAV_ROUTES } from './routes'
import { useDetailSidebarMode } from './storage'
@@ -41,6 +31,16 @@ const DATASET_DOCUMENT_CREATION_ROUTES = new Set(['create', 'create-from-pipelin
const DEPLOYMENT_COLLECTION_ROUTES = new Set(['create'])
const secondarySidebarHelpTriggerIcon =
+const AppDetailSection = dynamic(() => import('@/app/components/app-sidebar/app-detail-section'), { ssr: false })
+const AppDetailTop = dynamic(() => import('@/app/components/app-sidebar/app-detail-top'), { ssr: false })
+const DatasetDetailSection = dynamic(() => import('@/app/components/app-sidebar/dataset-detail-section'), { ssr: false })
+const DatasetDetailTop = dynamic(() => import('@/app/components/app-sidebar/dataset-detail-top'), { ssr: false })
+const AgentDetailSection = dynamic(() => import('@/features/agent-v2/agent-detail/navigation').then(mod => mod.AgentDetailSection), { ssr: false })
+const AgentDetailTop = dynamic(() => import('@/features/agent-v2/agent-detail/navigation').then(mod => mod.AgentDetailTop), { ssr: false })
+const SnippetDetailTop = dynamic(() => import('./components/snippet-detail-top'), { ssr: false })
+const SnippetDetailSection = dynamic(() => import('./components/snippet-detail-section').then(mod => mod.SnippetDetailSection), { ssr: false })
+const WebAppsSection = dynamic(() => import('./components/web-apps-section'), { ssr: false })
+
function SecondarySidebarHelpMenu({
triggerClassName,
}: {
@@ -103,12 +103,6 @@ export function MainNav({
const showDeploymentDetailNavigation = canUseAppDeploy && !isCurrentWorkspaceDatasetOperator && isDeploymentDetailPathname(pathname)
const showSnippetDetailNavigation = isSnippetDetailPathname(pathname)
const showDetailNavigation = showAppDetailNavigation || showDatasetDetailNavigation || showAgentDetailNavigation || showDeploymentDetailNavigation || showSnippetDetailNavigation
- const snippetNavigation = useSnippetDetailStore(useShallow(state => ({
- onFieldsChange: state.onFieldsChange,
- readonly: state.readonly,
- snippet: state.snippet,
- })))
- const snippetInputFields = useSnippetDraftStore(state => state.inputFields)
const { hasAppDetail, setAppDetail } = useAppStore(useShallow(state => ({
hasAppDetail: !!state.appDetail,
setAppDetail: state.setAppDetail,
@@ -307,18 +301,7 @@ export function MainNav({
?
: showDeploymentDetailNavigation
?
- : detailNavigationVisibleExpanded
- ? snippetNavigation.snippet && snippetNavigation.onFieldsChange
- ? (
-
- )
- : null
- :
+ :
: (
<>