diff --git a/web/src/components/ai-proposals/useProposalCheck.ts b/web/src/components/ai-proposals/useProposalCheck.ts index cfe0e1a69..fc421c3da 100644 --- a/web/src/components/ai-proposals/useProposalCheck.ts +++ b/web/src/components/ai-proposals/useProposalCheck.ts @@ -3,7 +3,7 @@ import { k8sListResourceItems } from '@openshift-console/dynamic-plugin-sdk/lib/ import { useQuery } from '@tanstack/react-query'; import { useCallback, useMemo, useState } from 'react'; import { ProposalModel } from '../console/models'; -import { getAlertFingerprintPrefix, matchesProposal } from './alert-identifier'; +import { getAlertFingerprintPrefix } from './alert-identifier'; import { PROPOSAL_LABEL_FINGERPRINT, PROPOSAL_LABEL_SOURCE, @@ -12,11 +12,11 @@ import { PROPOSAL_STALE_TIME, } from './constants'; -const buildQueryFn = (alertFingerprint: string) => () => +const buildQueryFn = (namespace: string, alertFingerprint: string) => () => k8sListResourceItems({ model: ProposalModel, queryParams: { - ns: PROPOSAL_NAMESPACE, + ns: namespace, labelSelector: { matchLabels: { [PROPOSAL_LABEL_FINGERPRINT]: alertFingerprint, @@ -28,27 +28,51 @@ const buildQueryFn = (alertFingerprint: string) => () => export const useProposalCheck = (alert: Alert) => { const alertFingerprint = useMemo(() => getAlertFingerprintPrefix(alert.labels), [alert.labels]); + const alertNamespace = alert.labels?.namespace; + const hasDistinctAlertNamespace = !!alertNamespace && alertNamespace !== PROPOSAL_NAMESPACE; const [shouldFetch, setShouldFetch] = useState(false); - const { data, isFetching } = useQuery({ - queryKey: ['proposal-check', alertFingerprint], - queryFn: buildQueryFn(alertFingerprint), + const { + data: defaultNsData, + isFetching: defaultNsFetching, + isError: defaultNsError, + } = useQuery({ + queryKey: ['proposal-check', PROPOSAL_NAMESPACE, alertFingerprint], + queryFn: buildQueryFn(PROPOSAL_NAMESPACE, alertFingerprint), enabled: shouldFetch, staleTime: PROPOSAL_STALE_TIME, retry: false, }); + const { + data: alertNsData, + isFetching: alertNsFetching, + isError: alertNsError, + } = useQuery({ + queryKey: ['proposal-check', alertNamespace, alertFingerprint], + queryFn: buildQueryFn(alertNamespace!, alertFingerprint), + enabled: shouldFetch && hasDistinctAlertNamespace, + staleTime: PROPOSAL_STALE_TIME, + retry: false, + }); + const prefetch = useCallback(() => setShouldFetch(true), []); - const proposals = useMemo( - () => (data ?? []).filter((p) => matchesProposal(alert, p)), - [data, alert], - ); + const proposals = useMemo(() => { + const matchesFp = (p: K8sResourceCommon) => + p.metadata?.labels?.[PROPOSAL_LABEL_FINGERPRINT] === alertFingerprint; + + return [...(defaultNsData ?? []).filter(matchesFp), ...(alertNsData ?? []).filter(matchesFp)]; + }, [defaultNsData, alertNsData, alertFingerprint]); + + const isFetching = defaultNsFetching || alertNsFetching; + const isError = defaultNsError && (hasDistinctAlertNamespace ? alertNsError : true); return { proposals, hasProposal: proposals.length > 0, isFetching, + isError, prefetch, alertFingerprint, }; diff --git a/web/src/components/alerting/AlertList/AlertTableRow.tsx b/web/src/components/alerting/AlertList/AlertTableRow.tsx index ea92548cc..87295aa94 100644 --- a/web/src/components/alerting/AlertList/AlertTableRow.tsx +++ b/web/src/components/alerting/AlertList/AlertTableRow.tsx @@ -26,7 +26,6 @@ import { AlertResource, alertState } from '../../../components/utils'; import { getAlertUrl, getNewSilenceAlertUrl, - getProposalsUrl, usePerspective, } from '../../../components/hooks/usePerspective'; import { useMonitoringNamespace } from '../../hooks/useMonitoringNamespace'; @@ -34,6 +33,10 @@ import { DataTestIDs } from '../../data-test'; import { useProposalCheck } from '../../ai-proposals/useProposalCheck'; import CustomIcon from '../../CustomIcon'; +const getProposalUrl = (namespace: string, name: string): string => { + return `/lightspeed/proposals/${namespace}/${name}`; +}; + const AlertTableRow: FC<{ alert: Alert }> = ({ alert }) => { const { t } = useTranslation(process.env.I18N_NAMESPACE); const { perspective } = usePerspective(); @@ -41,8 +44,7 @@ const AlertTableRow: FC<{ alert: Alert }> = ({ alert }) => { const { namespace } = useMonitoringNamespace(); const state = alertState(alert); - const { proposals, hasProposal, prefetch, alertFingerprint, isFetching } = - useProposalCheck(alert); + const { proposals, hasProposal, prefetch, isFetching } = useProposalCheck(alert); const title: string = alert.annotations?.description || alert.annotations?.message; @@ -61,23 +63,21 @@ const AlertTableRow: FC<{ alert: Alert }> = ({ alert }) => { } if (hasProposal) { - const proposalName = proposals.length === 1 ? proposals[0].metadata?.name : undefined; - const proposalUrl = getProposalsUrl( - perspective, - new URLSearchParams( - proposalName ? { name: proposalName } : { fingerprint: alertFingerprint }, - ), - ); - dropdownItems.push( - } - onClick={() => navigate(proposalUrl)} - data-test={DataTestIDs.ViewAIInvestigationDropdownItem} - > - {t('View AI Investigation')} - , - ); + const proposal = proposals[0]; + const proposalName = proposal.metadata?.name; + if (proposalName) { + const proposalUrl = getProposalUrl(proposal.metadata.namespace, proposalName); + dropdownItems.push( + } + onClick={() => navigate(proposalUrl)} + data-test={DataTestIDs.ViewAIInvestigationDropdownItem} + > + {t('View AI Investigation')} + , + ); + } } else if (isFetching) { dropdownItems.push( { return ''; } }; - -export const getProposalsUrl = (perspective: Perspective, params?: URLSearchParams): string => { - const qs = params ? params.toString() : ''; - const queryParams = qs ? `?${qs}` : ''; - - switch (perspective) { - case 'admin': - return `/monitoring/v2/ai/proposals${queryParams}`; - default: - return ''; - } -};