Provisioning: Fix settings error loop (#115677)

This commit is contained in:
Alex Khomenko
2025-12-23 16:16:48 +02:00
committed by GitHub
parent 359505a8aa
commit 47436a3eeb
4 changed files with 40 additions and 23 deletions
@@ -14,13 +14,12 @@ export interface Props {
}
export const FolderRepo = memo(function FolderRepo({ folder }: Props) {
// skip rendering if:
// folder is not present
// folder have parentUID
// folder is not managed
// if whole instance is provisioned
const isProvisionedInstance = useIsProvisionedInstance();
const skipRender = getShouldSkipRender(folder, isProvisionedInstance);
// Check if we can skip early without needing the useIsProvisionedInstance query
// This reduces RTK Query subscriptions and prevents re-render loops on API errors
const canSkipEarly = getCanSkipEarly(folder);
const isProvisionedInstance = useIsProvisionedInstance({ skip: canSkipEarly });
const skipRender = canSkipEarly || isProvisionedInstance;
const { isReadOnlyRepo, repoType } = useGetResourceRepositoryView({
folderName: skipRender ? undefined : folder?.uid,
@@ -51,11 +50,19 @@ export const FolderRepo = memo(function FolderRepo({ folder }: Props) {
);
});
function getShouldSkipRender(folder: FolderDTO | DashboardViewItem | undefined, isProvisionedInstance?: boolean) {
// Skip render if parentUID is present, then we should skip rendering. we only display icon for root folders
const hasParent = folder && Boolean('parentUID' in folder && folder.parentUID);
// Skip render if folder is not managed by Repo
const isNotManaged = folder && folder.managedBy !== ManagerKind.Repo;
return !folder || hasParent || isNotManaged || isProvisionedInstance;
// Check conditions that don't require the useIsProvisionedInstance hook
function getCanSkipEarly(folder: FolderDTO | DashboardViewItem | undefined): boolean {
if (!folder) {
return true;
}
// Skip render if parentUID is present - we only display icon for root folders
const hasParent = Boolean('parentUID' in folder && folder.parentUID);
if (hasParent) {
return true;
}
const isNotManaged = folder.managedBy !== ManagerKind.Repo;
if (isNotManaged) {
return true;
}
return false;
}
@@ -43,10 +43,10 @@ export function BrowseView({ folderUID, width, height, permissions, isReadOnlyRe
const selectedItems = useCheckboxSelectionState();
const childrenByParentUID = useChildrenByParentUIDState();
const canSelect = canSelectItems(permissions);
const isProvisionedInstance = useIsProvisionedInstance();
const provisioningEnabled = config.featureToggles.provisioning;
const hasNoRole = contextSrv.user.orgRole === OrgRole.None;
const { data: settingsData } = useGetFrontendSettingsQuery(!provisioningEnabled || hasNoRole ? skipToken : undefined);
const isProvisionedInstance = useIsProvisionedInstance({ settings: settingsData });
const rootItems = useSelector(rootItemsSelector);
const [, stateManager] = useSearchStateManager();
@@ -34,9 +34,10 @@ export const useGetResourceRepositoryView = ({
const hasNoRole = contextSrv.user.orgRole === OrgRole.None;
const provisioningEnabled = config.featureToggles.provisioning;
const { data: settingsData, isLoading: isSettingsLoading } = useGetFrontendSettingsQuery(
!provisioningEnabled || skipQuery || hasNoRole ? skipToken : undefined
);
const shouldSkipSettings = !provisioningEnabled || skipQuery || hasNoRole || (!name && !folderName);
const settingsQueryArg = shouldSkipSettings ? skipToken : undefined;
const { data: settingsData, isLoading: isSettingsLoading } = useGetFrontendSettingsQuery(settingsQueryArg);
const skipFolderQuery = !folderName || !provisioningEnabled || skipQuery || hasNoRole;
const { data: folder, isLoading: isFolderLoading } = useGetFolderQuery(
@@ -5,13 +5,22 @@ import { config } from '@grafana/runtime';
import { RepositoryViewList, useGetFrontendSettingsQuery } from 'app/api/clients/provisioning/v0alpha1';
import { contextSrv } from 'app/core/services/context_srv';
export function useIsProvisionedInstance(settings?: RepositoryViewList) {
interface UseIsProvisionedInstanceOptions {
settings?: RepositoryViewList;
skip?: boolean;
}
export function useIsProvisionedInstance(options: UseIsProvisionedInstanceOptions = {}) {
const { settings, skip: skipQuery } = options;
const hasNoRole = contextSrv.user.orgRole === OrgRole.None;
const skip = !config.featureToggles.provisioning || hasNoRole;
const skip = !config.featureToggles.provisioning || hasNoRole || skipQuery;
const settingsQuery = useGetFrontendSettingsQuery(settings || skip ? skipToken : undefined);
if (!settings) {
settings = settingsQuery.data;
if (settingsQuery.isError) {
return false;
}
return settings?.items?.some((item) => item.target === 'instance');
const effectiveSettings = settings ?? settingsQuery.data;
return effectiveSettings?.items?.some((item) => item.target === 'instance');
}