diff --git a/frontend/packages/console-app/src/components/file-upload/__tests__/file-upload-utils.spec.ts b/frontend/packages/console-app/src/components/file-upload/__tests__/file-upload-utils.spec.ts index 41bd6563507..c6dc23d29af 100644 --- a/frontend/packages/console-app/src/components/file-upload/__tests__/file-upload-utils.spec.ts +++ b/frontend/packages/console-app/src/components/file-upload/__tests__/file-upload-utils.spec.ts @@ -102,7 +102,7 @@ describe('file-upload-utils', () => { it('should return the file upload handler for supported file type', () => { const fileEx = getRequiredFileUploadExtension(fileUploadExtensions, 'string-boot.jar'); - expect(fileEx.properties.handler).toEqual(handler1); + expect(fileEx?.properties.handler).toEqual(handler1); }); it('should return null if there is no handler for a file type', () => { diff --git a/frontend/packages/console-app/src/components/file-upload/file-upload-context.ts b/frontend/packages/console-app/src/components/file-upload/file-upload-context.ts index e79462b941b..7b1dfd9c232 100644 --- a/frontend/packages/console-app/src/components/file-upload/file-upload-context.ts +++ b/frontend/packages/console-app/src/components/file-upload/file-upload-context.ts @@ -9,7 +9,7 @@ import { getRequiredFileUploadExtension } from './file-upload-utils'; export type FileUploadContextType = { extensions: string[]; - fileUpload: File; + fileUpload: File | undefined; setFileUpload: (file: File) => void; }; @@ -26,7 +26,7 @@ export const useValuesFileUploadContext = (): FileUploadContextType => { const [fileUploadExtensions, resolved] = useResolvedExtensions(isFileUpload); const toastContext = useToast(); const [namespace] = useActiveNamespace(); - const [file, setFile] = useState(undefined); + const [file, setFile] = useState(undefined); const fileExtensions = useMemo( () => resolved diff --git a/frontend/packages/console-app/src/components/modals/clone/clone-pvc-modal.tsx b/frontend/packages/console-app/src/components/modals/clone/clone-pvc-modal.tsx index fbd62b55777..b74e13b8846 100644 --- a/frontend/packages/console-app/src/components/modals/clone/clone-pvc-modal.tsx +++ b/frontend/packages/console-app/src/components/modals/clone/clone-pvc-modal.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { useState } from 'react'; import { FormGroup, FormHelperText, @@ -55,20 +56,20 @@ const ClonePVCModal = (props: ClonePVCModalProps) => { const { close, cancel, resource } = props; const [handlePromise, inProgress, errorMessage] = usePromiseHandler(); const { name: pvcName, namespace } = resource?.metadata; - const baseValue = convertToBaseValue(getRequestedPVCSize(resource)); + const baseValue = convertToBaseValue(resource ? getRequestedPVCSize(resource) : '0'); const defaultSize: string[] = validate.split(humanizeBinaryBytesWithoutB(baseValue).string); const pvcRequestedSize = humanizeBinaryBytes(baseValue).string; - const [clonePVCName, setClonePVCName] = React.useState(`${pvcName}-clone`); - const [requestedSize, setRequestedSize] = React.useState(defaultSize[0] || ''); - const [cloneAccessMode, setCloneAccessMode] = React.useState(resource?.spec?.accessModes?.[0]); - const [requestedUnit, setRequestedUnit] = React.useState(defaultSize[1] || 'Ti'); - const [validSize, setValidSize] = React.useState(true); - const pvcAccessMode = getPVCAccessModes(resource, 'title'); - const [pvcSC, setPVCStorageClass] = React.useState(''); - const [updatedProvisioner, setUpdatedProvisioner] = React.useState(''); + const [clonePVCName, setClonePVCName] = useState(`${pvcName}-clone`); + const [requestedSize, setRequestedSize] = useState(defaultSize[0] ?? ''); + const [cloneAccessMode, setCloneAccessMode] = useState(resource?.spec?.accessModes?.[0]); + const [requestedUnit, setRequestedUnit] = useState(defaultSize[1] || 'Ti'); + const [validSize, setValidSize] = useState(true); + const pvcAccessMode = resource ? getPVCAccessModes(resource, 'title') : []; + const [pvcSC, setPVCStorageClass] = useState(''); + const [updatedProvisioner, setUpdatedProvisioner] = useState(''); const handleStorageClass = (updatedStorageClass: StorageClassResourceKind) => { - setPVCStorageClass(getName(updatedStorageClass) || ''); + setPVCStorageClass(getName(updatedStorageClass) ?? ''); setUpdatedProvisioner(updatedStorageClass?.provisioner); }; @@ -85,7 +86,7 @@ const ClonePVCModal = (props: ClonePVCModalProps) => { }); const pvcUsedCapacityQueryResult: DataPoint[] = getInstantVectorStats( response, - null, + undefined, humanizeBinaryBytes, ); const pvcUsedCapacity = pvcUsedCapacityQueryResult?.[0]?.label || '-'; @@ -93,7 +94,7 @@ const ClonePVCModal = (props: ClonePVCModalProps) => { setRequestedSize(value); setRequestedUnit(unit); const cloneSizeInBytes = convertToBaseValue(value + unit); - const pvcSizeInBytes = convertToBaseValue(getRequestedPVCSize(resource)); + const pvcSizeInBytes = convertToBaseValue(resource ? getRequestedPVCSize(resource) : '0'); const isValid = cloneSizeInBytes >= pvcSizeInBytes; setValidSize(isValid); }; @@ -106,12 +107,12 @@ const ClonePVCModal = (props: ClonePVCModalProps) => { kind: PersistentVolumeClaimModel.kind, metadata: { name: clonePVCName, - namespace: resource.metadata.namespace, + namespace: resource?.metadata.namespace, }, spec: { storageClassName: pvcSC, dataSource: { - name: pvcName, + name: pvcName ?? '', kind: PersistentVolumeClaimModel.kind, apiGroup: '', }, @@ -120,17 +121,20 @@ const ClonePVCModal = (props: ClonePVCModalProps) => { storage: `${requestedSize}${requestedUnit}`, }, }, - volumeMode: resource.spec.volumeMode, - accessModes: [cloneAccessMode], + volumeMode: resource?.spec?.volumeMode, + accessModes: [cloneAccessMode ?? ''], }, }; - handlePromise(k8sCreate(PersistentVolumeClaimModel, pvcCloneObj)) - .then((cloneResource) => { - close(); - history.push(resourceObjPath(cloneResource, referenceFor(cloneResource))); - }) - .catch(() => {}); + return handlePromise(k8sCreate(PersistentVolumeClaimModel, pvcCloneObj)).then( + (cloneResource) => { + close?.(); + const resourcePath = resourceObjPath(cloneResource, referenceFor(cloneResource)); + if (resourcePath) { + history.push(resourcePath); + } + }, + ); }; return ( @@ -219,7 +223,7 @@ const ClonePVCModal = (props: ClonePVCModalProps) => {

{t('console-app~Namespace')}

- {resource.metadata.namespace} + {resource?.metadata.namespace}

@@ -253,7 +257,7 @@ const ClonePVCModal = (props: ClonePVCModalProps) => {

{t('console-app~Volume mode')}

-

{resource.spec.volumeMode}

+

{resource?.spec?.volumeMode}

diff --git a/frontend/packages/console-app/src/components/modals/resource-limits/ResourceLimitsModalLauncher.tsx b/frontend/packages/console-app/src/components/modals/resource-limits/ResourceLimitsModalLauncher.tsx index aedc1142d1a..b38f1642148 100644 --- a/frontend/packages/console-app/src/components/modals/resource-limits/ResourceLimitsModalLauncher.tsx +++ b/frontend/packages/console-app/src/components/modals/resource-limits/ResourceLimitsModalLauncher.tsx @@ -37,7 +37,7 @@ const ResourceLimitsModalLauncher: React.FC = }, ]) .then(() => { - props.close(); + props.close?.(); }) .catch((error) => { actions.setStatus({ submitError: error }); @@ -46,7 +46,7 @@ const ResourceLimitsModalLauncher: React.FC = const currentValues = { limits: getLimitsDataFromResource(props.resource), - container: props.resource.spec.template.spec.containers[0].name, + container: props.resource?.spec?.template?.spec?.containers?.[0]?.name ?? '', }; return ( diff --git a/frontend/packages/console-app/src/components/modals/restore-pvc/restore-pvc-modal.tsx b/frontend/packages/console-app/src/components/modals/restore-pvc/restore-pvc-modal.tsx index e6309cf306b..c8e57680ad3 100644 --- a/frontend/packages/console-app/src/components/modals/restore-pvc/restore-pvc-modal.tsx +++ b/frontend/packages/console-app/src/components/modals/restore-pvc/restore-pvc-modal.tsx @@ -6,6 +6,7 @@ import { GridItem, HelperText, HelperTextItem, + Skeleton, TextInput, } from '@patternfly/react-core'; import { Trans, useTranslation } from 'react-i18next'; @@ -63,7 +64,7 @@ import './restore-pvc-modal.scss'; const RestorePVCModal = ({ close, cancel, resource }: RestorePVCModalProps) => { const [handlePromise, inProgress, errorMessage] = usePromiseHandler(); const { t } = useTranslation(); - const [restorePVCName, setPVCName] = React.useState(`${getName(resource) || 'pvc'}-restore`); + const [restorePVCName, setPVCName] = React.useState(`${getName(resource) ?? 'pvc'}-restore`); const volumeSnapshotAnnotations = getAnnotations(resource); const snapshotBaseSize = convertToBaseValue(resource?.status?.restoreSize ?? '0'); const snapshotHumanizedSize = humanizeBinaryBytesWithoutB(snapshotBaseSize); @@ -94,7 +95,7 @@ const RestorePVCModal = ({ close, cancel, resource }: RestorePVCModalProps) => { }; const handleStorageClass = (updatedStorageClass: StorageClassResourceKind) => { - setPVCStorageClass(updatedStorageClass?.metadata.name || ''); + setPVCStorageClass(updatedStorageClass?.metadata.name); setUpdatedProvisioner(updatedStorageClass?.provisioner); }; @@ -112,7 +113,7 @@ const RestorePVCModal = ({ close, cancel, resource }: RestorePVCModalProps) => { dataSource: { name: snapshotName, kind: VolumeSnapshotModel.kind, - apiGroup: VolumeSnapshotModel.apiGroup, + apiGroup: VolumeSnapshotModel.apiGroup ?? '', }, accessModes: [restoreAccessMode], volumeMode, @@ -124,14 +125,14 @@ const RestorePVCModal = ({ close, cancel, resource }: RestorePVCModalProps) => { }, }; - handlePromise(k8sCreate(PersistentVolumeClaimModel, restorePVCTemplate, { ns: namespace })) - .then((newPVC) => { - close(); - history.push( - resourcePathFromModel(PersistentVolumeClaimModel, newPVC.metadata.name, namespace), - ); - }) - .catch(() => {}); + return handlePromise( + k8sCreate(PersistentVolumeClaimModel, restorePVCTemplate, { ns: namespace }), + ).then((newPVC) => { + close?.(); + history.push( + resourcePathFromModel(PersistentVolumeClaimModel, newPVC.metadata.name, namespace), + ); + }); }; return (
@@ -161,7 +162,7 @@ const RestorePVCModal = ({ close, cancel, resource }: RestorePVCModalProps) => { {!pvcStorageClassName || !scResourceLoaded ? ( -
+ ) : ( { required /> ) : ( -
+ )} {!validSize && ( @@ -238,7 +239,7 @@ const RestorePVCModal = ({ close, cancel, resource }: RestorePVCModalProps) => {
{t('console-app~Created at')} - +
diff --git a/frontend/packages/console-app/src/components/nav/NavHeader.tsx b/frontend/packages/console-app/src/components/nav/NavHeader.tsx index 9a6cb9c6364..3f4f8d915da 100644 --- a/frontend/packages/console-app/src/components/nav/NavHeader.tsx +++ b/frontend/packages/console-app/src/components/nav/NavHeader.tsx @@ -111,7 +111,7 @@ const NavHeader: React.FC = ({ onPerspectiveSelected }) => { )} popperProps={{ - appendTo: () => document.querySelector("[data-test-id='perspective-switcher-toggle']"), + appendTo: 'inline', }} > {perspectiveDropdownItems} diff --git a/frontend/packages/console-app/src/components/nav/PinnedResource.tsx b/frontend/packages/console-app/src/components/nav/PinnedResource.tsx index 8f512a62ee2..4e24b2c5429 100644 --- a/frontend/packages/console-app/src/components/nav/PinnedResource.tsx +++ b/frontend/packages/console-app/src/components/nav/PinnedResource.tsx @@ -4,7 +4,7 @@ import { GripVerticalIcon } from '@patternfly/react-icons/dist/esm/icons/grip-ve import { MinusCircleIcon } from '@patternfly/react-icons/dist/esm/icons/minus-circle-icon'; import { css } from '@patternfly/react-styles'; import { debounce } from 'lodash'; -import { useDrag, useDrop } from 'react-dnd'; +import { useDrag, useDrop, ConnectDragSource } from 'react-dnd'; import { useTranslation } from 'react-i18next'; import { K8sModel, modelFor } from '@console/internal/module/k8s'; import { useK8sModel } from '@console/shared/src/hooks/useK8sModel'; @@ -23,7 +23,7 @@ type PinnedResourceProps = { }; type DraggableButtonProps = { - dragRef?: (node) => void | null; + dragRef?: ConnectDragSource; }; type RemoveButtonProps = { @@ -58,7 +58,7 @@ const RemoveButton: React.FC = ({ resourceRef, navResources, const unPin = (e: React.MouseEvent, navItem: string) => { e.preventDefault(); e.stopPropagation(); - confirmNavUnpinModal(navItem); + confirmNavUnpinModal(navItem, navResources ?? [], onChange); }; return (