Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import * as _ from 'lodash';
import { K8sVerb } from '../../../api/common-types';
import {
Expand All @@ -10,7 +10,6 @@ import { k8sCreate } from '../../../utils/k8s/k8s-resource';
import { getImpersonate } from '../../core/reducers/coreSelectors';
import { ImpersonateKind } from '../../redux-types';
import storeHandler from '../../storeHandler';
import { useSafetyFirst } from '../safety-first';

/**
* It provides impersonation key based on data from the redux store.
Expand Down Expand Up @@ -109,8 +108,8 @@ export const useAccessReview = (
impersonate?: ImpersonateKind,
noCheckForEmptyGroupAndResource?: boolean,
): [boolean, boolean] => {
const [loading, setLoading] = useSafetyFirst(true);
const [isAllowed, setAllowed] = useSafetyFirst(false);
const [loading, setLoading] = useState(true);
const [isAllowed, setAllowed] = useState(false);
// Destructure the attributes to pass them as dependencies to `useEffect`,
// which doesn't do deep comparison of object dependencies.
const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useState, useRef, useCallback, useEffect } from 'react';
import { Menu, MenuContent, MenuList, Popper } from '@patternfly/react-core';
import * as _ from 'lodash';
import { Action, MenuOption } from '@console/dynamic-plugin-sdk';
import { useSafetyFirst } from '@console/dynamic-plugin-sdk/src/app/components/safety-first';
import { checkAccess } from '@console/internal/components/utils/rbac';
import { ActionMenuVariant } from '../types';
import ActionMenuContent from './ActionMenuContent';
Expand All @@ -29,7 +28,7 @@ const ActionMenu: FC<ActionMenuProps> = ({
appendTo,
}) => {
const isKebabVariant = variant === ActionMenuVariant.KEBAB;
const [isVisible, setVisible] = useSafetyFirst(isKebabVariant);
const [isVisible, setVisible] = useState(isKebabVariant);
const [isOpen, setIsOpen] = useState<boolean>(false);
const menuRef = useRef<HTMLDivElement>(null);
const toggleRef = useRef<HTMLButtonElement>(null);
Expand Down
9 changes: 4 additions & 5 deletions frontend/packages/console-shared/src/hooks/usePodsWatcher.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useMemo, useCallback, useEffect } from 'react';
import { useSafetyFirst } from '@console/dynamic-plugin-sdk/src/app/components/safety-first';
import { useMemo, useCallback, useEffect, useState } from 'react';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find PodRCData type definition
echo "=== Searching for PodRCData definition ==="
rg -n "type PodRCData|interface PodRCData" --type ts --type tsx

echo ""
echo "=== Checking tsconfig.json for strictNullChecks ==="
find . -name "tsconfig.json" -type f | head -10 | while read f; do
  echo "File: $f"
  rg "strictNullChecks" "$f"
done

echo ""
echo "=== Examining usePodsWatcher.ts file ==="
cat -n frontend/packages/console-shared/src/hooks/usePodsWatcher.ts | head -30

Repository: openshift/console

Length of output: 2452


🏁 Script executed:

#!/bin/bash
# Find types file in console-shared
echo "=== Looking for types file in console-shared ==="
find frontend/packages/console-shared/src -name "types*" -type f

echo ""
echo "=== Checking console-shared tsconfig ==="
find frontend/packages/console-shared -name "tsconfig.json" -type f | while read f; do
  echo "File: $f"
  cat "$f" | grep -A2 -B2 "strictNullChecks"
done

echo ""
echo "=== Searching for PodRCData with better pattern ==="
rg "PodRCData" frontend/packages/console-shared/src --type ts -A 2 -B 2

echo ""
echo "=== Check return type mismatch on line 18 ==="
sed -n '14,25p' frontend/packages/console-shared/src/hooks/usePodsWatcher.ts

Repository: openshift/console

Length of output: 10441


🏁 Script executed:

#!/bin/bash
echo "=== Reading PodRCData definition ==="
cat -n frontend/packages/console-shared/src/types/pod.ts

echo ""
echo "=== Looking for tsconfig.json in console-shared parent dirs ==="
find frontend/packages/console-shared -name "tsconfig.json"

echo ""
echo "=== Check frontend root tsconfig ==="
ls -la frontend/tsconfig.json 2>/dev/null && cat frontend/tsconfig.json | grep -A 2 -B 2 "strictNullChecks"

Repository: openshift/console

Length of output: 1669


🏁 Script executed:

#!/bin/bash
echo "=== Check tsconfig strictNullChecks ==="
cat frontend/tsconfig.json | grep -A 2 -B 2 "strictNullChecks"

echo ""
echo "=== Find PodRCData actual definition ==="
find . -path ./node_modules -prune -o -name "console-types*" -type f -print

echo ""
echo "=== Search for PodRCData type definition ==="
rg "type PodRCData|interface PodRCData" --type ts -A 5 -B 2

Repository: openshift/console

Length of output: 1650


🏁 Script executed:

#!/bin/bash
echo "=== Full usePodsWatcher implementation ==="
cat -n frontend/packages/console-shared/src/hooks/usePodsWatcher.ts

echo ""
echo "=== Check frontend tsconfig for compilerOptions ==="
cat frontend/tsconfig.json

Repository: openshift/console

Length of output: 5043


Widen podData state type to match runtime behavior.

Line 21 initializes podData with undefined, but the return type (line 18) declares podData: PodRCData without allowing undefined. This creates a type mismatch: consumers expect a fully-formed PodRCData object, but receive undefined on initial render before loaded becomes true. Align the type annotation with the actual state lifecycle.

🔧 Suggested fix
-  const [podData, setPodData] = useState<PodRCData>(undefined);
+  const [podData, setPodData] = useState<PodRCData | undefined>(undefined);

Also update the return type:

-): { loaded: boolean; loadError: string; podData: PodRCData } => {
+): { loaded: boolean; loadError: string; podData: PodRCData | undefined } => {
🤖 Prompt for AI Agents
In `@frontend/packages/console-shared/src/hooks/usePodsWatcher.ts` at line 1, The
state podData in usePodsWatcher is initialized as undefined but the hook's
return type declares podData: PodRCData, causing a mismatch; update the podData
state/type to allow undefined (e.g., PodRCData | undefined) and adjust the
hook's return signature so podData can be undefined until loaded is true,
referencing the podData state declaration and the PodRCData type and the
usePodsWatcher return type to locate the changes.

import { useK8sWatchResources } from '@console/internal/components/utils/k8s-watch-hook';
import { K8sResourceKind } from '@console/internal/module/k8s';
import { PodRCData } from '../types';
Expand All @@ -17,9 +16,9 @@ export const usePodsWatcher = (
kind?: string,
namespace?: string,
): { loaded: boolean; loadError: string; podData: PodRCData } => {
const [loaded, setLoaded] = useSafetyFirst<boolean>(false);
const [loadError, setLoadError] = useSafetyFirst<string>('');
const [podData, setPodData] = useSafetyFirst<PodRCData>(undefined);
const [loaded, setLoaded] = useState<boolean>(false);
const [loadError, setLoadError] = useState<string>('');
const [podData, setPodData] = useState<PodRCData>(undefined);
const watchKind = kind || resource?.kind;
const watchNS = namespace || resource?.metadata.namespace;
const watchedResources = useMemo(
Expand Down
5 changes: 2 additions & 3 deletions frontend/packages/console-shared/src/utils/pod-ring-utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import type { ReactElement } from 'react';
import { createElement, useMemo, useEffect } from 'react';
import { createElement, useMemo, useEffect, useState } from 'react';
import { ChartLabel } from '@patternfly/react-charts/victory';
import { css } from '@patternfly/react-styles';
import i18next, { TFunction } from 'i18next';
import * as _ from 'lodash';
import type { ImpersonateKind } from '@console/dynamic-plugin-sdk';
import { useSafetyFirst } from '@console/dynamic-plugin-sdk/src/app/components/safety-first';
import { DaemonSetModel, PodModel, JobModel, CronJobModel } from '@console/internal/models';
import {
K8sResourceKind,
Expand Down Expand Up @@ -241,7 +240,7 @@ export const usePodScalingAccessStatus = (
const isKnativeRevision = obj.kind === 'Revision';
const isPod = obj.kind === 'Pod';
const isScalingAllowed = !isKnativeRevision && !isPod && enableScaling;
const [editable, setEditable] = useSafetyFirst(false);
const [editable, setEditable] = useState(false);

useEffect(() => {
if (isScalingAllowed) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { safeLoad } from 'js-yaml';
import * as _ from 'lodash';
import {
getCommonAnnotations,
getAppLabels,
} from '@console/dev-console/src/utils/resource-label-utils';
import { useSafetyFirst } from '@console/dynamic-plugin-sdk/src/app/components/safety-first';
import { checkAccess } from '@console/internal/components/utils';
import { useK8sGet } from '@console/internal/components/utils/k8s-get-hook';
import { ConfigMapModel } from '@console/internal/models';
Expand Down Expand Up @@ -40,7 +39,7 @@ export const getChannelKind = (ref: string): string => {
};

export const useChannelList = (namespace: string): ChannelListProps => {
const [accessData, setAccessData] = useSafetyFirst({ loaded: false, channelList: [] });
const [accessData, setAccessData] = useState({ loaded: false, channelList: [] });
const { channels, loaded: channelsLoaded } = useChannelResourcesList();
useEffect(() => {
const accessList = [];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { chart_color_red_orange_300 as knativeEventingColor } from '@patternfly/react-tokens/dist/js/chart_color_red_orange_300';
import * as _ from 'lodash';
import { useSafetyFirst } from '@console/dynamic-plugin-sdk/src/app/components/safety-first';
import { coFetch } from '@console/internal/co-fetch';
import {
K8sKind,
Expand Down Expand Up @@ -85,7 +84,7 @@ export const fetchEventSourcesCrd = async () => {
};

export const useEventSourceModels = (): EventSourcetData => {
const [modelsData, setModelsData] = useSafetyFirst({ loaded: false, eventSourceModels: [] });
const [modelsData, setModelsData] = useState({ loaded: false, eventSourceModels: [] });
useEffect(() => {
if (eventSourceData.eventSourceModels.length === 0) {
fetchEventSourcesCrd()
Expand Down Expand Up @@ -201,7 +200,7 @@ export const fetchChannelsCrd = async () => {
};

export const useChannelModels = () => {
const [modelsData, setModelsData] = useSafetyFirst({ loaded: false, eventSourceChannels: [] });
const [modelsData, setModelsData] = useState({ loaded: false, eventSourceChannels: [] });
useEffect(() => {
if (eventSourceData.eventSourceChannels.length === 0) {
fetchChannelsCrd()
Expand Down Expand Up @@ -246,7 +245,7 @@ export const getDynamicEventingChannelWatchers = (namespace: string) => {
}, {});
};
export const useChannelResourcesList = (): EventChannelData => {
const [modelRefs, setModelRefs] = useSafetyFirst<EventChannelData>({
const [modelRefs, setModelRefs] = useState<EventChannelData>({
channels: [],
loaded: false,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { useEffect } from 'react';
import { useSafetyFirst } from '@console/dynamic-plugin-sdk/src/app/components/safety-first';
import { useEffect, useState } from 'react';
import { getTerminalInstalledNamespace } from './cloud-shell-utils';

const useCloudShellNamespace = (): [string, string] => {
const [terminalNamespace, setTerminalNamespace] = useSafetyFirst<string>(undefined);
const [fetchError, setFetchError] = useSafetyFirst<string>(undefined);
const [terminalNamespace, setTerminalNamespace] = useState<string>(undefined);
const [fetchError, setFetchError] = useState<string>(undefined);
useEffect(() => {
const fetchNamespace = async () => {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useEffect, useMemo } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { WatchK8sResource, WatchK8sResult } from '@console/dynamic-plugin-sdk';
import { useSafetyFirst } from '@console/dynamic-plugin-sdk/src/app/components/safety-first';
import { useAccessReview2 } from '@console/internal/components/utils';
import { useK8sWatchResource } from '@console/internal/components/utils/k8s-watch-hook';
import { ProjectModel } from '@console/internal/models';
Expand Down Expand Up @@ -30,9 +29,9 @@ const useCloudShellWorkspace = (
workspaceModel: K8sKind,
defaultNamespace: string = null,
): WatchK8sResult<CloudShellResource> => {
const [namespace, setNamespace] = useSafetyFirst(defaultNamespace);
const [searching, setSearching] = useSafetyFirst<boolean>(false);
const [noNamespaceFound, setNoNamespaceFound] = useSafetyFirst<boolean>(false);
const [namespace, setNamespace] = useState(defaultNamespace);
const [searching, setSearching] = useState<boolean>(false);
const [noNamespaceFound, setNoNamespaceFound] = useState<boolean>(false);

// sync defaultNamespace to namespace
useEffect(() => {
Expand Down
122 changes: 0 additions & 122 deletions frontend/public/components/__tests__/safety-first.spec.tsx

This file was deleted.

3 changes: 1 addition & 2 deletions frontend/public/components/utils/actions-menu.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { FC } from 'react';
import { ImpersonateKind, impersonateStateToProps } from '@console/dynamic-plugin-sdk';
import { useSafetyFirst } from '@console/dynamic-plugin-sdk/src/app/components/safety-first';
import { Button, Dropdown, MenuToggle, MenuToggleElement } from '@patternfly/react-core';
import { some } from 'lodash';
import { useTranslation } from 'react-i18next';
Expand Down Expand Up @@ -81,7 +80,7 @@ export const ActionsMenu = connect(impersonateStateToProps)(
impersonate,
title = undefined,
}: ActionsMenuProps & { impersonate?: ImpersonateKind }) => {
const [isVisible, setVisible] = useSafetyFirst(false);
const [isVisible, setVisible] = useState(false);

// Check if any actions are visible when actions have access reviews.
useEffect(() => {
Expand Down
5 changes: 2 additions & 3 deletions frontend/public/components/utils/managed-by.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FC } from 'react';
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { css } from '@patternfly/react-styles';
import { Link } from 'react-router-dom-v5-compat';
import { useTranslation } from 'react-i18next';
Expand All @@ -13,7 +13,6 @@ import {
modelFor,
k8sList,
} from '../../module/k8s';
import { useSafetyFirst } from '@console/dynamic-plugin-sdk/src/app/components/safety-first';
import { findOwner, matchOwnerAndCSV } from '../../module/k8s/managed-by';
import { ClusterServiceVersionModel } from '@console/operator-lifecycle-manager/src/models';
import { ClusterServiceVersionKind } from '@console/operator-lifecycle-manager';
Expand Down Expand Up @@ -52,7 +51,7 @@ export const ManagedByOperatorResourceLink: FC<ManagerLinkProps> = ({

export const ManagedByOperatorLink: FC<ManagedByLinkProps> = ({ obj, className }) => {
const { t } = useTranslation();
const [data, setData] = useSafetyFirst<ClusterServiceVersionKind[] | undefined>(undefined);
const [data, setData] = useState<ClusterServiceVersionKind[] | undefined>(undefined);
const namespace = obj.metadata.namespace;
useEffect(() => {
if (!namespace) {
Expand Down