From 52b9657118a346a2b8b8d03840453d9a35541865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alfonso=20Mart=C3=ADnez?= Date: Thu, 7 Nov 2024 17:07:38 +0100 Subject: [PATCH] TSLint: enable rule 'react/no-unstable-nested-components' --- .eslintrc.js | 1 - locales/en/plugin__odf-console.json | 14 +++--- .../create-dr-policy/utils/k8s-utils.ts | 4 +- .../namespace-step/namespace-step.tsx | 2 +- ...amesapce-table.tsx => namespace-table.tsx} | 47 +++++++++++++++---- .../replication-step/replication-step.tsx | 2 +- .../status-card/status-card.spec.tsx | 2 +- .../data-policies-status-popover.tsx | 14 ++++-- .../helper/pvc-details-wizard-content.tsx | 2 +- ...search-quries.ts => acm-search-queries.ts} | 2 +- packages/mco/utils/index.ts | 2 +- .../buckets-card/buckets-card-item.tsx | 2 +- .../buckets-card/buckets-card.tsx | 34 +++++--------- .../object-details/ObjectDetailsSidebar.tsx | 23 +++++---- .../upload-status/UploadStatusList.tsx | 35 +++++++------- packages/shared/src/kebab/kebab.tsx | 31 ++++++------ 16 files changed, 121 insertions(+), 96 deletions(-) rename packages/mco/components/discovered-application-wizard/wizard-steps/namespace-step/{namesapce-table.tsx => namespace-table.tsx} (88%) rename packages/mco/utils/{acm-search-quries.ts => acm-search-queries.ts} (99%) diff --git a/.eslintrc.js b/.eslintrc.js index 324538ef2..9f16e69da 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -67,7 +67,6 @@ module.exports = { 'react/jsx-indent': 'off', 'react/jsx-no-constructed-context-values': 'off', 'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }], - 'react/no-unstable-nested-components': 'off', 'react/no-unused-prop-types': 'off', 'consistent-return': 'off', 'default-case': 'off', diff --git a/locales/en/plugin__odf-console.json b/locales/en/plugin__odf-console.json index 4214fb14f..7e492cf5e 100644 --- a/locales/en/plugin__odf-console.json +++ b/locales/en/plugin__odf-console.json @@ -105,13 +105,6 @@ "PVC label selectors": "PVC label selectors", "Protect all your volumes that match the selected PVC labels": "Protect all your volumes that match the selected PVC labels", "Add PVC label selector": "Add PVC label selector", - "{{count}} results found for {{clusterName}}_one": "{{count}} results found for {{clusterName}}", - "{{count}} results found for {{clusterName}}_other": "{{count}} results found for {{clusterName}}", - "0 results found": "0 results found", - "Select a namespace": "Select a namespace", - "There are no namespaces to display. Select a cluster first to view namespaces.": "There are no namespaces to display. Select a cluster first to view namespaces.", - "There are no namespaces to display.": "There are no namespaces to display.", - "This list does not include namespaces where applications are enrolled separately under disaster recovery protection.": "This list does not include namespaces where applications are enrolled separately under disaster recovery protection.", "Name requirements": "Name requirements", "Example": "Example", "Enter a unique name": "Enter a unique name", @@ -126,6 +119,13 @@ "Namespace": "Namespace", "Select namespaces that belongs to your ACM discovered applications.": "Select namespaces that belongs to your ACM discovered applications.", "Once you select namespaces, applications regardless of their type, within those namespaces cannot be subsequently enrolled separately under disaster recovery protection.": "Once you select namespaces, applications regardless of their type, within those namespaces cannot be subsequently enrolled separately under disaster recovery protection.", + "There are no namespaces to display.": "There are no namespaces to display.", + "There are no namespaces to display. Select a cluster first to view namespaces.": "There are no namespaces to display. Select a cluster first to view namespaces.", + "{{count}} results found for {{clusterName}}_one": "{{count}} results found for {{clusterName}}", + "{{count}} results found for {{clusterName}}_other": "{{count}} results found for {{clusterName}}", + "0 results found": "0 results found", + "Select a namespace": "Select a namespace", + "This list does not include namespaces where applications are enrolled separately under disaster recovery protection.": "This list does not include namespaces where applications are enrolled separately under disaster recovery protection.", "Replication type: {{type}}, Interval: {{interval}}, Clusters: {{clusters}}": "Replication type: {{type}}, Interval: {{interval}}, Clusters: {{clusters}}", "Replication type: {{type}}, Clusters: {{clusters}}": "Replication type: {{type}}, Clusters: {{clusters}}", "Status: {{status}}": "Status: {{status}}", diff --git a/packages/mco/components/create-dr-policy/utils/k8s-utils.ts b/packages/mco/components/create-dr-policy/utils/k8s-utils.ts index 70e1c732b..c26e90f63 100644 --- a/packages/mco/components/create-dr-policy/utils/k8s-utils.ts +++ b/packages/mco/components/create-dr-policy/utils/k8s-utils.ts @@ -20,12 +20,12 @@ const getODFPeers = (cluster: ManagedClusterInfoType) => { const getPeerClustersRef = (clusters: ManagedClusterInfoType[]) => clusters.map((cluster) => { - const [storageClusterName, storageClusterNamesapce] = getODFPeers(cluster); + const [storageClusterName, storageClusterNamespace] = getODFPeers(cluster); return { clusterName: getName(cluster), storageClusterRef: { name: storageClusterName, - namespace: storageClusterNamesapce, + namespace: storageClusterNamespace, }, }; }); diff --git a/packages/mco/components/discovered-application-wizard/wizard-steps/namespace-step/namespace-step.tsx b/packages/mco/components/discovered-application-wizard/wizard-steps/namespace-step/namespace-step.tsx index db82a8eac..0613b7bf9 100644 --- a/packages/mco/components/discovered-application-wizard/wizard-steps/namespace-step/namespace-step.tsx +++ b/packages/mco/components/discovered-application-wizard/wizard-steps/namespace-step/namespace-step.tsx @@ -38,7 +38,7 @@ import { EnrollDiscoveredApplicationState, EnrollDiscoveredApplicationStateType, } from '../../utils/reducer'; -import { NamespaceSelectionTable } from './namesapce-table'; +import { NamespaceSelectionTable } from './namespace-table'; import './namespace-step.scss'; const getDRClusterFromPolicies = (drPolicies: DRPolicyKind[]): string[] => { diff --git a/packages/mco/components/discovered-application-wizard/wizard-steps/namespace-step/namesapce-table.tsx b/packages/mco/components/discovered-application-wizard/wizard-steps/namespace-step/namespace-table.tsx similarity index 88% rename from packages/mco/components/discovered-application-wizard/wizard-steps/namespace-step/namesapce-table.tsx rename to packages/mco/components/discovered-application-wizard/wizard-steps/namespace-step/namespace-table.tsx index c6f83e8cb..f61094de5 100644 --- a/packages/mco/components/discovered-application-wizard/wizard-steps/namespace-step/namesapce-table.tsx +++ b/packages/mco/components/discovered-application-wizard/wizard-steps/namespace-step/namespace-table.tsx @@ -91,6 +91,36 @@ const TableRow: React.FC> = ({ ); }; +const EmptyRowMessageWrapper: React.FC = ({ children }) => { + return ( + + {children} + + ); +}; + +const EmptyRowMessage: React.FC = () => { + const { t } = useCustomTranslation(); + + return ( + + {t('There are no namespaces to display.')} + + ); +}; + +const NoClusterEmptyRowMessage: React.FC = () => { + const { t } = useCustomTranslation(); + + return ( + + {t( + 'There are no namespaces to display. Select a cluster first to view namespaces.' + )} + + ); +}; + export const NamespaceSelectionTable: React.FC = ({ namespaces, @@ -178,16 +208,13 @@ export const NamespaceSelectionTable: React.FC = setSelectedRows={setSelectedNamespaces} loaded={searchLoaded} borders={false} - emptyRowMessage={() => ( - - {!!searchError || - (!clusterName - ? t( - 'There are no namespaces to display. Select a cluster first to view namespaces.' - ) - : t('There are no namespaces to display.'))} - - )} + emptyRowMessage={ + searchError + ? searchError + : clusterName + ? EmptyRowMessage + : NoClusterEmptyRowMessage + } /> {t( diff --git a/packages/mco/components/discovered-application-wizard/wizard-steps/replication-step/replication-step.tsx b/packages/mco/components/discovered-application-wizard/wizard-steps/replication-step/replication-step.tsx index c41dc9207..945f52717 100644 --- a/packages/mco/components/discovered-application-wizard/wizard-steps/replication-step/replication-step.tsx +++ b/packages/mco/components/discovered-application-wizard/wizard-steps/replication-step/replication-step.tsx @@ -39,7 +39,7 @@ import { EnrollDiscoveredApplicationState, EnrollDiscoveredApplicationStateType, } from '../../utils/reducer'; -import { findAllEligiblePolicies } from '../namespace-step/namesapce-table'; +import { findAllEligiblePolicies } from '../namespace-step/namespace-table'; import '../../enroll-discovered-application.scss'; const getPolicyOptions = (dataPolicies: DRPolicyKind[], t: TFunction) => diff --git a/packages/mco/components/mco-dashboard/storage-system/status-card/status-card.spec.tsx b/packages/mco/components/mco-dashboard/storage-system/status-card/status-card.spec.tsx index 30a3f766c..28841054f 100644 --- a/packages/mco/components/mco-dashboard/storage-system/status-card/status-card.spec.tsx +++ b/packages/mco/components/mco-dashboard/storage-system/status-card/status-card.spec.tsx @@ -228,7 +228,7 @@ jest.mock('@openshift-console/dynamic-plugin-sdk-internal', () => ({ HealthBody: (props) => , })); -describe('Test ODF cluster status from different clusters and namesapces', () => { +describe('Test ODF cluster status from different clusters and namespaces', () => { test('All healthy case testing', async () => { testCaseId = 1; render(); diff --git a/packages/mco/components/modals/app-data-policies-status/subscriptions/data-policies-status-popover.tsx b/packages/mco/components/modals/app-data-policies-status/subscriptions/data-policies-status-popover.tsx index 56a90cb47..280d97704 100644 --- a/packages/mco/components/modals/app-data-policies-status/subscriptions/data-policies-status-popover.tsx +++ b/packages/mco/components/modals/app-data-policies-status/subscriptions/data-policies-status-popover.tsx @@ -74,6 +74,7 @@ const DataPoliciesStatusModal = React.lazy( export const DataPoliciesStatusPopover: React.FC = ({ application }) => { const { t } = useCustomTranslation(); + const [isVisible, setIsVisible] = React.useState(false); const launcher = useModal(); const response = useK8sWatchResources( drResources(getNamespace(application)) @@ -187,9 +188,9 @@ export const DataPoliciesStatusPopover: React.FC [launcher, dataPoliciesStatus] ); - const onClick = (hide: any) => { + const onClick = () => { launchModal(); - hide(); + setIsVisible(false); }; const headerText = pluralize( @@ -220,19 +221,22 @@ export const DataPoliciesStatusPopover: React.FC } - footerContent={(hide) => ( + isVisible={isVisible} + shouldClose={() => setIsVisible(false)} + shouldOpen={() => setIsVisible(true)} + footerContent={ - )} + } > {!!count && {linkText}} diff --git a/packages/mco/components/modals/app-manage-policies/helper/pvc-details-wizard-content.tsx b/packages/mco/components/modals/app-manage-policies/helper/pvc-details-wizard-content.tsx index f99eb190b..74c806a8a 100644 --- a/packages/mco/components/modals/app-manage-policies/helper/pvc-details-wizard-content.tsx +++ b/packages/mco/components/modals/app-manage-policies/helper/pvc-details-wizard-content.tsx @@ -34,7 +34,7 @@ import { ButtonVariant, } from '@patternfly/react-core'; import { MinusCircleIcon } from '@patternfly/react-icons'; -import { queryAppWorkloadPVCs } from '../../../../utils/acm-search-quries'; +import { queryAppWorkloadPVCs } from '../../../../utils/acm-search-queries'; import { getClusterNamesFromPlacements } from '../utils/parser-utils'; import { ManagePolicyStateAction, diff --git a/packages/mco/utils/acm-search-quries.ts b/packages/mco/utils/acm-search-queries.ts similarity index 99% rename from packages/mco/utils/acm-search-quries.ts rename to packages/mco/utils/acm-search-queries.ts index 9d633e50e..267c243d7 100644 --- a/packages/mco/utils/acm-search-quries.ts +++ b/packages/mco/utils/acm-search-queries.ts @@ -130,7 +130,7 @@ export const queryRecipesFromCluster = ( query: searchFilterQuery, }); -// ACM seach query to fetch all releated resources of this namesapces from the managed cluster. +// ACM seach query to fetch all releated resources of this namespaces from the managed cluster. export const queryK8sResourceFromCluster = ( clusterName: string, namespaces: string[] diff --git a/packages/mco/utils/index.ts b/packages/mco/utils/index.ts index f611dcf8d..a5dfc6634 100644 --- a/packages/mco/utils/index.ts +++ b/packages/mco/utils/index.ts @@ -1,3 +1,3 @@ export * from './disaster-recovery'; export * from './common'; -export * from './acm-search-quries'; +export * from './acm-search-queries'; diff --git a/packages/ocs/dashboards/object-service/buckets-card/buckets-card-item.tsx b/packages/ocs/dashboards/object-service/buckets-card/buckets-card-item.tsx index fa311a062..6c09b1975 100644 --- a/packages/ocs/dashboards/object-service/buckets-card/buckets-card-item.tsx +++ b/packages/ocs/dashboards/object-service/buckets-card/buckets-card-item.tsx @@ -43,6 +43,6 @@ export const BucketsTitle: React.FC = ({ export type BucketsTitleProps = { objects: PrometheusResponse; - link: string; + link?: string; error: boolean; }; diff --git a/packages/ocs/dashboards/object-service/buckets-card/buckets-card.tsx b/packages/ocs/dashboards/object-service/buckets-card/buckets-card.tsx index 9ebc2fa1e..3dbe6d8ee 100644 --- a/packages/ocs/dashboards/object-service/buckets-card/buckets-card.tsx +++ b/packages/ocs/dashboards/object-service/buckets-card/buckets-card.tsx @@ -20,6 +20,7 @@ import { InventoryItem, InventoryItemLoading, InventoryItemBody, + PrometheusResponse, } from '@openshift-console/dynamic-plugin-sdk'; import { ResourceInventoryItem } from '@openshift-console/dynamic-plugin-sdk-internal'; import { useParams } from 'react-router-dom-v5-compat'; @@ -54,8 +55,8 @@ type ObjectInventoryItemProps = { count: number; children?: React.ReactNode; error?: boolean; - TitleComponent?: React.ComponentType<{}>; - dataTest?: string; + objectCount?: PrometheusResponse; + objectCountError?: boolean; }; const ObjectInventoryItem: React.FC = ({ @@ -65,8 +66,8 @@ const ObjectInventoryItem: React.FC = ({ count, children, error = false, - TitleComponent, - dataTest, + objectCount, + objectCountError, }) => { const titleMessage = pluralize( count, @@ -76,16 +77,11 @@ const ObjectInventoryItem: React.FC = ({ ); return ( -
+
{isLoading && !error && } - {TitleComponent ? ( - {titleMessage} - ) : ( - titleMessage - )} + + {titleMessage} +
{children} @@ -124,16 +120,8 @@ const ObjectInventoryItem_: React.FC = () => { error={!!(noobaaCountError || unhealthyNoobaaBucketsError)} title={t('NooBaa Bucket')} count={Number(getGaugeValue(noobaaCount))} - TitleComponent={React.useCallback( - (props) => ( - - ), - [noobaaObjectsCount, noobaaObjectsCountError] - )} + objectCount={noobaaObjectsCount} + objectCountError={!!noobaaObjectsCountError} > {unhealthyNoobaaBucketsCount > 0 && ( <> diff --git a/packages/odf/components/s3-browser/object-details/ObjectDetailsSidebar.tsx b/packages/odf/components/s3-browser/object-details/ObjectDetailsSidebar.tsx index 30ef26d98..41ee6c169 100644 --- a/packages/odf/components/s3-browser/object-details/ObjectDetailsSidebar.tsx +++ b/packages/odf/components/s3-browser/object-details/ObjectDetailsSidebar.tsx @@ -37,7 +37,6 @@ import { Level, LevelItem, MenuToggle, - MenuToggleElement, Title, } from '@patternfly/react-core'; import { TagIcon } from '@patternfly/react-icons'; @@ -54,6 +53,7 @@ const ObjectDetailsSidebarContent: React.FC = ({ closeSidebar, object, objectActions }) => { const { t } = useCustomTranslation(); const [isOpen, setIsOpen] = React.useState(false); + const dropdownToggleRef = React.useRef(); const onToggleClick = () => { setIsOpen(!isOpen); }; @@ -127,15 +127,18 @@ const ObjectDetailsSidebarContent: React.FC = ) => ( - - {t('Actions')} - - )} + toggle={{ + toggleNode: ( + + {t('Actions')} + + ), + toggleRef: dropdownToggleRef, + }} > {dropdownItems} diff --git a/packages/odf/components/s3-browser/upload-objects/upload-status/UploadStatusList.tsx b/packages/odf/components/s3-browser/upload-objects/upload-status/UploadStatusList.tsx index ce8149ee0..e1d483bfc 100644 --- a/packages/odf/components/s3-browser/upload-objects/upload-status/UploadStatusList.tsx +++ b/packages/odf/components/s3-browser/upload-objects/upload-status/UploadStatusList.tsx @@ -24,35 +24,36 @@ const getProgressVariant = ( } }; +const UploadStatusListRow = ({ data, index, style }) => { + const item = data[index]; + return ( +
+ +
+ ); +}; + export const UploadStatusList: React.FC = ({ progress, }) => { - const Row = ({ index, style }) => { - const item = progress[index]; - return ( -
- -
- ); - }; - return ( {({ height, width }) => ( - {Row} + {UploadStatusListRow} )} diff --git a/packages/shared/src/kebab/kebab.tsx b/packages/shared/src/kebab/kebab.tsx index 6daca7625..d0adac0d6 100644 --- a/packages/shared/src/kebab/kebab.tsx +++ b/packages/shared/src/kebab/kebab.tsx @@ -13,7 +13,6 @@ import { DropdownItem, DropdownPopperProps, MenuToggle, - MenuToggleElement, Tooltip, } from '@patternfly/react-core'; import { EllipsisVIcon } from '@patternfly/react-icons'; @@ -106,6 +105,7 @@ export const Kebab: React.FC & KebabStaticProperties = ({ const launchModal = useModal(); const eventRef = React.useRef(undefined); + const dropdownToggleRef = React.useRef(); const [toggleDirection, setToggleDirection] = React.useState('down'); const [isOpen, setOpen] = React.useState(false); @@ -253,19 +253,22 @@ export const Kebab: React.FC & KebabStaticProperties = ({ ) => ( - setOpen((o) => !o)} - isExpanded={isOpen} - data-test="kebab-button" - isDisabled={isDisabled} - > - {toggleType === 'Kebab' ? : t('Actions')} - - )} + toggle={{ + toggleNode: ( + setOpen((o) => !o)} + isExpanded={isOpen} + data-test="kebab-button" + isDisabled={isDisabled} + > + {toggleType === 'Kebab' ? : t('Actions')} + + ), + toggleRef: dropdownToggleRef, + }} isOpen={isOpen} data-test-id="kebab-button" popperProps={{