diff --git a/src/features/auth/store/authStore.ts b/src/features/auth/store/authStore.ts index 7f69e0cfd..f8631e44c 100644 --- a/src/features/auth/store/authStore.ts +++ b/src/features/auth/store/authStore.ts @@ -190,7 +190,7 @@ class AuthStore { return value ? JSON.parse(atob(value)) : undefined; } - public checkForFabricConnect(id: EntityIds): boolean { + public checkForFabricConnect(id: EntityIds | undefined): boolean { return localStorage.getItem(this.fabricConnectKeyPrefix + id) === 'true'; } diff --git a/src/features/instance/InstanceNavBar.tsx b/src/features/instance/InstanceNavBar.tsx index 2822f1067..8dd95bde9 100644 --- a/src/features/instance/InstanceNavBar.tsx +++ b/src/features/instance/InstanceNavBar.tsx @@ -34,7 +34,7 @@ export function InstanceNavBar() { const params = useParams({ strict: false }); const { version }: RegistrationInfoResponse = useLoaderData({ strict: false }); - const statusAvailable = wasAReleasedBeforeB('4.6.0', version); + const statusAvailable = wasAReleasedBeforeB('4.6.0', version) && canManage; const apisAvailable = wasAReleasedBeforeB('4.7.0-beta.7', version); const instanceParams = useInstanceClientIdParams(); @@ -43,7 +43,7 @@ export function InstanceNavBar() { const links = useMemo(() => [ - { + canManage && { to: buildAbsoluteLinkToPage(params), activeOptions: { exact: true }, name: 'Applications', diff --git a/src/features/instance/applications/context/EditorViewProvider.tsx b/src/features/instance/applications/context/EditorViewProvider.tsx index 7db39d649..0e9718be8 100644 --- a/src/features/instance/applications/context/EditorViewProvider.tsx +++ b/src/features/instance/applications/context/EditorViewProvider.tsx @@ -21,7 +21,7 @@ import { } from '@/integrations/api/instance/applications/setComponentFile'; import { useListener } from '@/lib/events/listener'; import { setWatchedValue } from '@/lib/events/watcher'; -import { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useNavigate, useSearch } from '@tanstack/react-router'; import { PropsWithChildren, useCallback, useEffect, useMemo, useState } from 'react'; import { TreeItemIndex } from 'react-complex-tree/src/types'; @@ -43,8 +43,17 @@ export function EditorViewProvider({ children }: PropsWithChildren) { /* Create our structured view from the relational API data. */ - const { data: apiComponents } = useSuspenseQuery(getComponentsQueryOptions(instanceParams)); - const mappedData = useMemo(() => calculateRootEntries(apiComponents.entries), [apiComponents]); + const { data: apiComponents } = useQuery(getComponentsQueryOptions(instanceParams)); + const mappedData = useMemo(() => { + if (!apiComponents) { + return { + rootEntries: [], + pathsRegistry: new Map(), + allEntries: new Map(), + }; + } + return calculateRootEntries(apiComponents.entries); + }, [apiComponents]); const reloadRootEntries = useCallback(async () => queryClient.fetchQuery({ @@ -63,7 +72,7 @@ export function EditorViewProvider({ children }: PropsWithChildren) { ).map(rootEntry => rootEntry.name); let defaultFocusedItem = defaultFolderExpansions[0]; let defaultSelectedItem = defaultFolderExpansions.slice(0, 1); - if (!defaultFocusedItem) { + if (!defaultFocusedItem && apiComponents) { defaultFocusedItem = newApplication; defaultSelectedItem = [newApplication]; } diff --git a/src/features/instance/applications/index.tsx b/src/features/instance/applications/index.tsx index 1df4de53f..a4721e06a 100644 --- a/src/features/instance/applications/index.tsx +++ b/src/features/instance/applications/index.tsx @@ -1,4 +1,7 @@ +import { useInstanceManagePermission } from '@/hooks/usePermissions'; import { useSessionToggler } from '@/hooks/useSessionToggler'; +import { buildAbsoluteLinkToPage } from '@/lib/urls/buildAbsoluteLinkToPage'; +import { Navigate, useParams } from '@tanstack/react-router'; import { cx } from 'class-variance-authority'; import { ApplicationsSidebar } from './components/ApplicationsSidebar'; import { ContentActions } from './components/ContentActions'; @@ -12,8 +15,14 @@ import { RedeployApplicationModal } from './modals/RedeployApplicationModal'; import { RenameFileModal } from './modals/RenameFileModal'; export function ApplicationsEditor() { + const canManage = useInstanceManagePermission(); + const params = useParams({ strict: false }); const { toggle, toggled } = useSessionToggler('ApplicationsSidebarOpened', true); + if (!canManage) { + return ; + } + return (