From ae59fb0467d251023414071fd3fd93a38a3feedc Mon Sep 17 00:00:00 2001 From: Sharon Gratch Date: Wed, 8 Jan 2025 03:44:19 +0200 Subject: [PATCH] Migrate deprecated Dropdown component to PF5 and remove ActionServiceDropdown Reference: https://issues.redhat.com/browse/MTV-1051 - Migrate the deprecated Dropdown component to PF5 - see https://v5-archive.patternfly.org/components/menus/dropdown/react-deprecated - Remove unused common component: ActionServiceDropdown - Fix few bugs regarding the Dropdown component, e.g. changing the dropdown menu to be scrollable when needed, since otherwise part of the dropdown items are not reachable. Signed-off-by: Sharon Gratch --- .../ActionServiceDropdown.tsx | 137 ------------------ .../components/ActionServiceDropdown/index.ts | 3 - packages/common/src/components/index.ts | 1 - .../FilterableSelect/FilterableSelect.tsx | 2 +- .../components/actions/DropdownItemLink.tsx | 30 ++-- .../actions/NetworkMapActionsDropdown.tsx | 71 +++++---- .../NetworkMapActionsDropdownItems.tsx | 19 ++- .../tabs/Details/cards/WelcomeCard.tsx | 33 +++-- .../Metrics/cards/MigrationsChartCard.tsx | 68 +++++++-- .../Metrics/cards/VmMigrationsChartCard.tsx | 68 +++++++-- .../Plans/actions/PlanActionsDropdown.tsx | 61 ++++---- .../actions/PlanActionsDropdownItems.tsx | 12 +- .../create/components/SelectProvider.tsx | 2 +- .../EditPlanTransferNetwork.tsx | 65 +++++++-- .../actions/ProviderActionsDropdown.tsx | 63 +++++--- .../actions/ProviderActionsDropdownItems.tsx | 39 +++-- .../EditProviderDefaultTransferNetwork.tsx | 64 ++++++-- .../actions/StorageMapActionsDropdown.tsx | 69 +++++---- .../StorageMapActionsDropdownItems.tsx | 19 ++- 19 files changed, 471 insertions(+), 355 deletions(-) delete mode 100644 packages/common/src/components/ActionServiceDropdown/ActionServiceDropdown.tsx delete mode 100644 packages/common/src/components/ActionServiceDropdown/index.ts diff --git a/packages/common/src/components/ActionServiceDropdown/ActionServiceDropdown.tsx b/packages/common/src/components/ActionServiceDropdown/ActionServiceDropdown.tsx deleted file mode 100644 index 832cfff79..000000000 --- a/packages/common/src/components/ActionServiceDropdown/ActionServiceDropdown.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import React, { useMemo, useState } from 'react'; -import { useHistory } from 'react-router'; - -import { ActionService, ActionServiceProvider } from '@openshift-console/dynamic-plugin-sdk'; -import { - Dropdown, - DropdownItem, - DropdownToggle, - KebabToggle, -} from '@patternfly/react-core/deprecated'; - -import { ToggleEventType } from '../../utils'; - -export interface ActionServiceDropdownProps { - /** The contextId of the `console.action/provider` extension to use */ - contextId: string; - - /** The kind of toggle to use for the resourceData actions. Default: `'kebab'` */ - variant?: 'kebab' | 'dropdown'; - - /** Text to display when the variant is 'dropdown'. */ - dropdownToggleText?: string; - - /** The resource's namespace. */ - namespace?: string; - - /** Resource the actions will act upon. */ - resourceData: T; - - /** A list of actions to ignore and leave off the full set of actions for the entity. */ - ignoreList?: string[]; -} - -/** - * Use the `console.action/provider` defined extension provided to generate the set of - * actions to provide for the given resource. Use `ActionsAsDropdown` to render the - * list actions generated by the service provider. - */ -export function ActionServiceDropdown({ - contextId, - variant = 'kebab', - dropdownToggleText, - namespace, - resourceData, - ignoreList, -}: ActionServiceDropdownProps) { - const serviceProviderData = useMemo( - () => ({ [contextId]: { resourceData, namespace } }), - [contextId, resourceData, namespace], - ); - - return ( - - {(actionService: ActionService) => ( - - )} - - ); -} -ActionServiceDropdown.displayName = 'ActionServiceDropdown'; - -const ActionsAsDropdown = ({ - actions, - variant, - dropdownToggleText = '', - ignoreList = [], -}: ActionService & - Pick, 'variant' | 'dropdownToggleText' | 'ignoreList'>) => { - const history = useHistory(); - const [isActionMenuOpen, setIsActionMenuOpen] = useState(false); - const isPlain = variant === 'kebab'; - - const onToggle: (isExpanded: boolean, event: ToggleEventType) => void = (isExpanded) => { - setIsActionMenuOpen(isExpanded); - }; - - const toggle = - variant === 'kebab' ? ( - onToggle(v, e)} /> - ) : ( - onToggle(v, e)}>{dropdownToggleText} - ); - - return ( - setIsActionMenuOpen(!isActionMenuOpen)} - toggle={toggle} - isOpen={isActionMenuOpen} - isPlain={isPlain} - dropdownItems={actions - .filter(({ id }) => !ignoreList?.includes(id)) - .map(({ id, label, cta, disabled, disabledTooltip, tooltip }) => ( - cta.href && history.push(cta.href)} - isAriaDisabled={disabled} - tooltip={disabled ? disabledTooltip : tooltip} - > - {label} - - ))} - /> - ); -}; - -export function withActionServiceContext( - { - contextId, - variant, - dropdownToggleText, - }: Pick, 'contextId' | 'variant' | 'dropdownToggleText'>, - Component: typeof ActionServiceDropdown = ActionServiceDropdown, -) { - function ActionServiceDropdownProviderHoc( - props: Pick, 'namespace' | 'resourceData' | 'ignoreList'>, - ) { - return ( - - {...props} - contextId={contextId} - variant={variant} - dropdownToggleText={dropdownToggleText} - /> - ); - } - - const componentName = Component['displayName'] || Component.name || 'Component'; - ActionServiceDropdownProviderHoc.displayName = `withActionServiceContext(${componentName})`; - - return ActionServiceDropdownProviderHoc; -} diff --git a/packages/common/src/components/ActionServiceDropdown/index.ts b/packages/common/src/components/ActionServiceDropdown/index.ts deleted file mode 100644 index 35b90af15..000000000 --- a/packages/common/src/components/ActionServiceDropdown/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// @index(['./*', /__/g], f => `export * from '${f.path}';`) -export * from './ActionServiceDropdown'; -// @endindex diff --git a/packages/common/src/components/index.ts b/packages/common/src/components/index.ts index 54b33dbf8..28db5f4a5 100644 --- a/packages/common/src/components/index.ts +++ b/packages/common/src/components/index.ts @@ -1,5 +1,4 @@ // @index(['./*', /__/g], f => `export * from '${f.path}';`) -export * from './ActionServiceDropdown'; export * from './ExternalLink'; export * from './Filter'; export * from './FilterGroup'; diff --git a/packages/forklift-console-plugin/src/components/FilterableSelect/FilterableSelect.tsx b/packages/forklift-console-plugin/src/components/FilterableSelect/FilterableSelect.tsx index 46b250d57..4a7e499bf 100644 --- a/packages/forklift-console-plugin/src/components/FilterableSelect/FilterableSelect.tsx +++ b/packages/forklift-console-plugin/src/components/FilterableSelect/FilterableSelect.tsx @@ -118,7 +118,7 @@ export const FilterableSelect: React.FunctionComponent = * Toggles the open state of the select dropdown. */ const onToggleClick = () => { - setIsOpen(!isOpen); + setIsOpen((isOpen) => !isOpen); }; /** diff --git a/packages/forklift-console-plugin/src/components/actions/DropdownItemLink.tsx b/packages/forklift-console-plugin/src/components/actions/DropdownItemLink.tsx index bc4154e91..ae1a7a53a 100644 --- a/packages/forklift-console-plugin/src/components/actions/DropdownItemLink.tsx +++ b/packages/forklift-console-plugin/src/components/actions/DropdownItemLink.tsx @@ -1,7 +1,7 @@ -import React from 'react'; +import React, { ReactNode } from 'react'; import { Link } from 'react-router-dom'; -import { DropdownItem } from '@patternfly/react-core/deprecated'; +import { DropdownItem } from '@patternfly/react-core'; /** * `DropdownItemLink` is a functional component that renders a dropdown item with a link. @@ -13,23 +13,27 @@ import { DropdownItem } from '@patternfly/react-core/deprecated'; * * @returns {React.ReactElement} The rendered JSX element. */ -export const DropdownItemLink = ({ key, href, description, children }: DropdownItemLinkProps) => { +export const DropdownItemLink = ({ + key, + value, + href, + description, + children, +}: DropdownItemLinkProps) => { return ( - -
{children}
- {description &&
{description}
} - - } - /> + + +
{children}
+ {description &&
{description}
} + +
); }; export type DropdownItemLinkProps = { key: string; + value: number; href: string; description?: string; - children?: React.ReactNode; + children?: ReactNode; }; diff --git a/packages/forklift-console-plugin/src/modules/NetworkMaps/actions/NetworkMapActionsDropdown.tsx b/packages/forklift-console-plugin/src/modules/NetworkMaps/actions/NetworkMapActionsDropdown.tsx index d1c5f73d3..5a40d97aa 100644 --- a/packages/forklift-console-plugin/src/modules/NetworkMaps/actions/NetworkMapActionsDropdown.tsx +++ b/packages/forklift-console-plugin/src/modules/NetworkMaps/actions/NetworkMapActionsDropdown.tsx @@ -1,15 +1,16 @@ -import React from 'react'; -import { useToggle } from 'src/modules/Providers/hooks'; +import React, { FC, Ref, useState } from 'react'; import { ModalHOC } from 'src/modules/Providers/modals'; import { useForkliftTranslation } from 'src/utils/i18n'; -import { Flex, FlexItem } from '@patternfly/react-core'; import { Dropdown, - DropdownPosition, - DropdownToggle, - KebabToggle, -} from '@patternfly/react-core/deprecated'; + DropdownList, + Flex, + FlexItem, + MenuToggle, + MenuToggleElement, +} from '@patternfly/react-core'; +import { EllipsisVIcon } from '@patternfly/react-icons'; import { CellProps } from '../views/list/components'; @@ -17,38 +18,50 @@ import { NetworkMapActionsDropdownItems } from './NetworkMapActionsDropdownItems import './NetworkMapActionsDropdown.style.css'; -const NetworkMapActionsKebabDropdown_: React.FC = ({ - data, - isKebab, -}) => { +const NetworkMapActionsKebabDropdown_: FC = ({ data, isKebab }) => { const { t } = useForkliftTranslation(); - // Hook for managing the open/close state of the dropdown - const [isDropdownOpen, toggle] = useToggle(); + const [isOpen, setIsOpen] = useState(false); + + const onToggleClick = () => { + setIsOpen((isOpen) => !isOpen); + }; + + const onSelect = ( + _event: React.MouseEvent | undefined, + _value: string | number | undefined, + ) => { + setIsOpen(false); + }; // Returning the Dropdown component from PatternFly library return ( - ) : ( - - {t('Actions')} - - ) - } - dropdownItems={NetworkMapActionsDropdownItems({ data })} - /> + isOpen={isOpen} + onOpenChange={(isOpen: boolean) => setIsOpen(isOpen)} + onSelect={onSelect} + toggle={(toggleRef: Ref) => ( + + {isKebab ? : t('Actions')} + + )} + shouldFocusToggleOnSelect + popperProps={{ + position: 'right', + }} + > + {NetworkMapActionsDropdownItems({ data })} + ); }; -export const NetworkMapActionsDropdown: React.FC = (props) => ( +export const NetworkMapActionsDropdown: FC = (props) => ( diff --git a/packages/forklift-console-plugin/src/modules/NetworkMaps/actions/NetworkMapActionsDropdownItems.tsx b/packages/forklift-console-plugin/src/modules/NetworkMaps/actions/NetworkMapActionsDropdownItems.tsx index 3d203d136..82fa5ced7 100644 --- a/packages/forklift-console-plugin/src/modules/NetworkMaps/actions/NetworkMapActionsDropdownItems.tsx +++ b/packages/forklift-console-plugin/src/modules/NetworkMaps/actions/NetworkMapActionsDropdownItems.tsx @@ -5,7 +5,7 @@ import { getResourceUrl } from 'src/modules/Providers/utils'; import { useForkliftTranslation } from 'src/utils/i18n'; import { NetworkMapModel, NetworkMapModelRef } from '@kubev2v/types'; -import { DropdownItem } from '@patternfly/react-core/deprecated'; +import { DropdownItem } from '@patternfly/react-core'; import { NetworkMapData } from '../utils'; @@ -26,10 +26,19 @@ export const NetworkMapActionsDropdownItems = ({ data }: NetworkMapActionsDropdo }; return [ - - {t('Edit NetworkMap')} - , - + , + + {t('Delete NetworkMap')} , ]; diff --git a/packages/forklift-console-plugin/src/modules/Overview/views/overview/tabs/Details/cards/WelcomeCard.tsx b/packages/forklift-console-plugin/src/modules/Overview/views/overview/tabs/Details/cards/WelcomeCard.tsx index 941d84a9d..17277c078 100644 --- a/packages/forklift-console-plugin/src/modules/Overview/views/overview/tabs/Details/cards/WelcomeCard.tsx +++ b/packages/forklift-console-plugin/src/modules/Overview/views/overview/tabs/Details/cards/WelcomeCard.tsx @@ -1,4 +1,4 @@ -import React, { FC } from 'react'; +import React, { FC, Ref, useState } from 'react'; import { ForkliftTrans, useForkliftTranslation } from 'src/utils/i18n'; import { V1beta1ForkliftController } from '@kubev2v/types'; @@ -11,7 +11,14 @@ import { SplitItem, Text, } from '@patternfly/react-core'; -import { Dropdown, DropdownItem, KebabToggle } from '@patternfly/react-core/deprecated'; +import { + Dropdown, + DropdownItem, + DropdownList, + MenuToggle, + MenuToggleElement, +} from '@patternfly/react-core'; +import { EllipsisVIcon } from '@patternfly/react-icons'; import automationIcon from '../../../../../images/automation.svg'; @@ -27,6 +34,7 @@ const hideFromViewDropdownOption = (onHide: () => void, t) => { return hasHideAction ? ( void, t) => { export const OverviewCard: FC = ({ onHide }) => { const { t } = useForkliftTranslation(); - const [menuIsOpen, setMenuIsOpen] = React.useState(false); - + const [menuIsOpen, setMenuIsOpen] = useState(false); const actionDropdownItems = [hideFromViewDropdownOption(onHide, t)]; const onToggle = () => setMenuIsOpen((open) => !open); const headerActions = ( } - position="right" - dropdownItems={actionDropdownItems} - /> + onOpenChange={(menuIsOpen: boolean) => setMenuIsOpen(menuIsOpen)} + toggle={(toggleRef: Ref) => ( + + {} + + )} + shouldFocusFirstItemOnOpen={false} + popperProps={{ + position: 'right', + }} + > + {actionDropdownItems} + ); return ( diff --git a/packages/forklift-console-plugin/src/modules/Overview/views/overview/tabs/Metrics/cards/MigrationsChartCard.tsx b/packages/forklift-console-plugin/src/modules/Overview/views/overview/tabs/Metrics/cards/MigrationsChartCard.tsx index 819f7d469..8b5859aad 100644 --- a/packages/forklift-console-plugin/src/modules/Overview/views/overview/tabs/Metrics/cards/MigrationsChartCard.tsx +++ b/packages/forklift-console-plugin/src/modules/Overview/views/overview/tabs/Metrics/cards/MigrationsChartCard.tsx @@ -1,11 +1,22 @@ -import React, { useState } from 'react'; +import React, { FC, Ref, useState } from 'react'; import { useForkliftTranslation } from 'src/utils/i18n'; import { MigrationModelGroupVersionKind, V1beta1Migration } from '@kubev2v/types'; import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk'; import { Chart, ChartAxis, ChartBar, ChartGroup, ChartTooltip } from '@patternfly/react-charts'; -import { Card, CardBody, CardHeader, CardTitle, Flex } from '@patternfly/react-core'; -import { Dropdown, DropdownItem, KebabToggle } from '@patternfly/react-core/deprecated'; +import { + Card, + CardBody, + CardHeader, + CardTitle, + Dropdown, + DropdownItem, + DropdownList, + Flex, + MenuToggle, + MenuToggleElement, +} from '@patternfly/react-core'; +import { EllipsisVIcon } from '@patternfly/react-icons'; import chart_color_blue_200 from '@patternfly/react-tokens/dist/esm/chart_color_blue_200'; import chart_color_green_400 from '@patternfly/react-tokens/dist/esm/chart_color_green_400'; import chart_color_red_100 from '@patternfly/react-tokens/dist/esm/chart_color_red_100'; @@ -23,13 +34,24 @@ const toDataPointsForMigrations = ( selectedTimeRange: TimeRangeOptions, ): MigrationDataPoint[] => toDataPoints(allMigrations.map(toTimestamp), selectedTimeRange); -export const MigrationsChartCard: React.FC = () => { +export const MigrationsChartCard: FC = () => { const { t } = useForkliftTranslation(); + const [isDropdownOpened, setIsDropdownOpened] = useState(false); - const onToggle = () => setIsDropdownOpened(!isDropdownOpened); + const [selectedTimeRange, setSelectedTimeRange] = useState( TimeRangeOptions.Last7Days, ); + const onToggleClick = () => { + setIsDropdownOpened((isDropdownOpened) => !isDropdownOpened); + }; + const onSelect = ( + _event: React.MouseEvent | undefined, + _value: string | number | undefined, + ) => { + setIsDropdownOpened(false); + }; + const [migrations] = useK8sWatchResource({ groupVersionKind: MigrationModelGroupVersionKind, namespaced: true, @@ -64,36 +86,54 @@ export const MigrationsChartCard: React.FC = () => { ); const handleTimeRangeSelectedFactory = (timeRange: TimeRangeOptions) => () => { - onToggle(); + onToggleClick(); setSelectedTimeRange(timeRange); }; const headerActions = ( } isOpen={isDropdownOpened} - isPlain - dropdownItems={[ + onOpenChange={setIsDropdownOpened} + onSelect={onSelect} + toggle={(toggleRef: Ref) => ( + + + + )} + shouldFocusFirstItemOnOpen={false} + popperProps={{ + direction: 'down', + }} + > + {t('7 days')} - , + {t('31 days')} - , + {t('24 hours')} - , - ]} - /> +
+ +
); return ( diff --git a/packages/forklift-console-plugin/src/modules/Overview/views/overview/tabs/Metrics/cards/VmMigrationsChartCard.tsx b/packages/forklift-console-plugin/src/modules/Overview/views/overview/tabs/Metrics/cards/VmMigrationsChartCard.tsx index fdccf6ab4..d68190c73 100644 --- a/packages/forklift-console-plugin/src/modules/Overview/views/overview/tabs/Metrics/cards/VmMigrationsChartCard.tsx +++ b/packages/forklift-console-plugin/src/modules/Overview/views/overview/tabs/Metrics/cards/VmMigrationsChartCard.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { FC, Ref, useState } from 'react'; import { useForkliftTranslation } from 'src/utils/i18n'; import { @@ -8,8 +8,19 @@ import { } from '@kubev2v/types'; import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk'; import { Chart, ChartAxis, ChartBar, ChartGroup, ChartTooltip } from '@patternfly/react-charts'; -import { Card, CardBody, CardHeader, CardTitle, Flex } from '@patternfly/react-core'; -import { Dropdown, DropdownItem, KebabToggle } from '@patternfly/react-core/deprecated'; +import { + Card, + CardBody, + CardHeader, + CardTitle, + Dropdown, + DropdownItem, + DropdownList, + Flex, + MenuToggle, + MenuToggleElement, +} from '@patternfly/react-core'; +import { EllipsisVIcon } from '@patternfly/react-icons'; import chart_color_blue_200 from '@patternfly/react-tokens/dist/esm/chart_color_blue_200'; import chart_color_green_400 from '@patternfly/react-tokens/dist/esm/chart_color_green_400'; import chart_color_red_100 from '@patternfly/react-tokens/dist/esm/chart_color_red_100'; @@ -27,10 +38,21 @@ const toDataPointsForVmMigrations = ( selectedTimeRange: TimeRangeOptions, ): MigrationDataPoint[] => toDataPoints(allVmMigrations.map(toTimestamp), selectedTimeRange); -export const VmMigrationsChartCard: React.FC = () => { +export const VmMigrationsChartCard: FC = () => { const { t } = useForkliftTranslation(); const [isDropdownOpened, setIsDropdownOpened] = useState(false); - const onToggle = () => setIsDropdownOpened(!isDropdownOpened); + + const onToggleClick = () => { + setIsDropdownOpened((isDropdownOpened) => !isDropdownOpened); + }; + + const onSelect = ( + _event: React.MouseEvent | undefined, + _value: string | number | undefined, + ) => { + setIsDropdownOpened(false); + }; + const [selectedTimeRange, setSelectedTimeRange] = useState( TimeRangeOptions.Last7Days, ); @@ -86,36 +108,54 @@ export const VmMigrationsChartCard: React.FC = () => { ); const handleTimeRangeSelectedFactory = (timeRange: TimeRangeOptions) => () => { - onToggle(); + onToggleClick(); setSelectedTimeRange(timeRange); }; const headerActions = ( } isOpen={isDropdownOpened} - isPlain - dropdownItems={[ + onOpenChange={setIsDropdownOpened} + onSelect={onSelect} + toggle={(toggleRef: Ref) => ( + + + + )} + shouldFocusFirstItemOnOpen={false} + popperProps={{ + direction: 'down', + }} + > + {t('7 days')} - , + {t('31 days')} - , + {t('24 hours')} - , - ]} - /> + + + ); return ( diff --git a/packages/forklift-console-plugin/src/modules/Plans/actions/PlanActionsDropdown.tsx b/packages/forklift-console-plugin/src/modules/Plans/actions/PlanActionsDropdown.tsx index 411efdf1d..766490b43 100644 --- a/packages/forklift-console-plugin/src/modules/Plans/actions/PlanActionsDropdown.tsx +++ b/packages/forklift-console-plugin/src/modules/Plans/actions/PlanActionsDropdown.tsx @@ -1,14 +1,9 @@ -import React from 'react'; -import { useToggle } from 'src/modules/Providers/hooks'; +import React, { Ref } from 'react'; import { ModalHOC } from 'src/modules/Providers/modals'; import { useForkliftTranslation } from 'src/utils/i18n'; -import { - Dropdown, - DropdownPosition, - DropdownToggle, - KebabToggle, -} from '@patternfly/react-core/deprecated'; +import { Dropdown, DropdownList, MenuToggle, MenuToggleElement } from '@patternfly/react-core'; +import { EllipsisVIcon } from '@patternfly/react-icons'; import { CellProps } from '../views/list/components'; @@ -20,27 +15,43 @@ const PlanActionsKebabDropdown_: React.FC = ({ data, i const { t } = useForkliftTranslation(); // Hook for managing the open/close state of the dropdown - const [isDropdownOpen, toggle] = useToggle(); + const [isOpen, setIsOpen] = React.useState(false); + + const onToggleClick = () => { + setIsOpen((isOpen) => !isOpen); + }; + + const onSelect = ( + _event: React.MouseEvent | undefined, + _value: string | number | undefined, + ) => { + setIsOpen(false); + }; // Returning the Dropdown component from PatternFly library return ( - ) : ( - - {t('Actions')} - - ) - } - dropdownItems={PlanActionsDropdownItems({ data })} - /> + className={isKebab ? undefined : 'forklift-dropdown'} + isOpen={isOpen} + onOpenChange={setIsOpen} + onSelect={onSelect} + toggle={(toggleRef: Ref) => ( + + {isKebab ? : t('Actions')} + + )} + shouldFocusToggleOnSelect + popperProps={{ + position: 'right', + }} + > + {PlanActionsDropdownItems({ data })} + ); }; diff --git a/packages/forklift-console-plugin/src/modules/Plans/actions/PlanActionsDropdownItems.tsx b/packages/forklift-console-plugin/src/modules/Plans/actions/PlanActionsDropdownItems.tsx index 541d95c15..49d52aef5 100644 --- a/packages/forklift-console-plugin/src/modules/Plans/actions/PlanActionsDropdownItems.tsx +++ b/packages/forklift-console-plugin/src/modules/Plans/actions/PlanActionsDropdownItems.tsx @@ -5,7 +5,7 @@ import { getResourceUrl } from 'src/modules/Providers/utils/helpers'; import { useForkliftTranslation } from 'src/utils/i18n'; import { PlanModel, PlanModelRef } from '@kubev2v/types'; -import { DropdownItem } from '@patternfly/react-core/deprecated'; +import { DropdownItem } from '@patternfly/react-core'; import { ArchiveModal, @@ -68,15 +68,14 @@ export const PlanActionsDropdownItems = ({ data }: PlanActionsDropdownItemsProps }; return [ - - {t('Edit Plan')} - , + , - + {buttonStartLabel} , , , , = ({ const [isOpen, setIsOpen] = useState(false); const onToggle = () => { - setIsOpen(!isOpen); + setIsOpen((isOpen) => !isOpen); }; const providerTypesArray = Object.keys(providerTypes); diff --git a/packages/forklift-console-plugin/src/modules/Plans/views/details/components/SettingsSection/modals/EditPlanTransferNetwork/EditPlanTransferNetwork.tsx b/packages/forklift-console-plugin/src/modules/Plans/views/details/components/SettingsSection/modals/EditPlanTransferNetwork/EditPlanTransferNetwork.tsx index 914ce1c26..255a3992f 100644 --- a/packages/forklift-console-plugin/src/modules/Plans/views/details/components/SettingsSection/modals/EditPlanTransferNetwork/EditPlanTransferNetwork.tsx +++ b/packages/forklift-console-plugin/src/modules/Plans/views/details/components/SettingsSection/modals/EditPlanTransferNetwork/EditPlanTransferNetwork.tsx @@ -1,5 +1,5 @@ -import React from 'react'; -import { useProviderInventory, useToggle } from 'src/modules/Providers/hooks'; +import React, { FC, Ref, useState } from 'react'; +import { useProviderInventory } from 'src/modules/Providers/hooks'; import { EditModal, EditModalProps, @@ -17,7 +17,13 @@ import { V1beta1Provider, } from '@kubev2v/types'; import { K8sModel, k8sPatch } from '@openshift-console/dynamic-plugin-sdk'; -import { Dropdown, DropdownItem, DropdownToggle } from '@patternfly/react-core/deprecated'; +import { + Dropdown, + DropdownItem, + DropdownList, + MenuToggle, + MenuToggleElement, +} from '@patternfly/react-core'; const onConfirm: OnConfirmHookType = async ({ resource, model, newValue }) => { const plan = resource as V1beta1Plan; @@ -48,8 +54,20 @@ interface DropdownRendererProps { const OpenshiftNetworksInputFactory: ({ resource }) => ModalInputComponentType = ({ resource }) => { const provider = resource as V1beta1Provider; - const DropdownRenderer: React.FC = ({ value, onChange }) => { - const [isOpen, onToggle] = useToggle(false); + const DropdownRenderer: FC = ({ value, onChange }) => { + // Hook for managing the open/close state of the dropdown + const [isOpen, setIsOpen] = useState(false); + + const onToggleClick = () => { + setIsOpen((isOpen) => !isOpen); + }; + + const onSelect = ( + _event: React.MouseEvent | undefined, + _value: string | number | undefined, + ) => { + setIsOpen(false); + }; const { inventory: networks } = useProviderInventory({ provider, @@ -67,6 +85,7 @@ const OpenshiftNetworksInputFactory: ({ resource }) => ModalInputComponentType = const dropdownItems = [ onChange('')} @@ -74,7 +93,12 @@ const OpenshiftNetworksInputFactory: ({ resource }) => ModalInputComponentType = {'Providers default'} , ...(transferNetworks || []).map((n) => ( - onChange(n)}> + onChange(n)} + > {n.name} )), @@ -82,16 +106,27 @@ const OpenshiftNetworksInputFactory: ({ resource }) => ModalInputComponentType = return ( - {getNetworkName(value)} - - } isOpen={isOpen} - dropdownItems={dropdownItems} - menuAppendTo="parent" - /> + onOpenChange={setIsOpen} + onSelect={onSelect} + toggle={(toggleRef: Ref) => ( + + {getNetworkName(value)} + + )} + shouldFocusToggleOnSelect + popperProps={{ + position: 'right', + }} + isScrollable={true} + > + {dropdownItems} + ); }; diff --git a/packages/forklift-console-plugin/src/modules/Providers/actions/ProviderActionsDropdown.tsx b/packages/forklift-console-plugin/src/modules/Providers/actions/ProviderActionsDropdown.tsx index e4b10c725..76e3eff5a 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/actions/ProviderActionsDropdown.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/actions/ProviderActionsDropdown.tsx @@ -1,15 +1,16 @@ -import React from 'react'; +import React, { Ref } from 'react'; import { useForkliftTranslation } from 'src/utils/i18n'; -import { Flex, FlexItem } from '@patternfly/react-core'; import { Dropdown, - DropdownPosition, - DropdownToggle, - KebabToggle, -} from '@patternfly/react-core/deprecated'; + DropdownList, + Flex, + FlexItem, + MenuToggle, + MenuToggleElement, +} from '@patternfly/react-core'; +import { EllipsisVIcon } from '@patternfly/react-icons'; -import { useToggle } from '../hooks'; import { ModalHOC } from '../modals'; import { CellProps } from '../views'; @@ -30,27 +31,43 @@ const ProviderActionsKebabDropdown_: React.FC = ({ const { t } = useForkliftTranslation(); // Hook for managing the open/close state of the dropdown - const [isDropdownOpen, toggle] = useToggle(); + const [isOpen, setIsOpen] = React.useState(false); + + const onToggleClick = () => { + setIsOpen((isOpen) => !isOpen); + }; + + const onSelect = ( + _event: React.MouseEvent | undefined, + _value: string | number | undefined, + ) => { + setIsOpen(false); + }; // Returning the Dropdown component from PatternFly library return ( - ) : ( - - {t('Actions')} - - ) - } - dropdownItems={ProviderActionsDropdownItems({ data })} - /> + isOpen={isOpen} + onOpenChange={setIsOpen} + onSelect={onSelect} + toggle={(toggleRef: Ref) => ( + + {isKebab ? : t('Actions')} + + )} + shouldFocusToggleOnSelect + popperProps={{ + position: 'right', + }} + > + {ProviderActionsDropdownItems({ data })} + ); }; diff --git a/packages/forklift-console-plugin/src/modules/Providers/actions/ProviderActionsDropdownItems.tsx b/packages/forklift-console-plugin/src/modules/Providers/actions/ProviderActionsDropdownItems.tsx index 28aade4d8..f0d1b0822 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/actions/ProviderActionsDropdownItems.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/actions/ProviderActionsDropdownItems.tsx @@ -3,7 +3,7 @@ import { DropdownItemLink } from 'src/components/actions/DropdownItemLink'; import { useForkliftTranslation } from 'src/utils/i18n'; import { ProviderModel, ProviderModelRef } from '@kubev2v/types'; -import { DropdownItem } from '@patternfly/react-core/deprecated'; +import { DropdownItem } from '@patternfly/react-core'; import { DeleteModal, useModal } from '../modals'; import { getResourceUrl, ProviderData } from '../utils'; @@ -25,16 +25,33 @@ export const ProviderActionsDropdownItems = ({ data }: ProviderActionsDropdownIt }; const dropdownItems = [ - - {t('Edit Provider')} - , - - {t('Edit Provider Credentials')} - , - - {t('Migrate')} - , - + , + + , + + , + + {t('Delete Provider')} , ]; diff --git a/packages/forklift-console-plugin/src/modules/Providers/modals/EditProviderDefaultTransferNetwork/EditProviderDefaultTransferNetwork.tsx b/packages/forklift-console-plugin/src/modules/Providers/modals/EditProviderDefaultTransferNetwork/EditProviderDefaultTransferNetwork.tsx index a60881231..c524d14a5 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/modals/EditProviderDefaultTransferNetwork/EditProviderDefaultTransferNetwork.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/modals/EditProviderDefaultTransferNetwork/EditProviderDefaultTransferNetwork.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { FC, Ref, useState } from 'react'; import { useForkliftTranslation } from 'src/utils/i18n'; import { @@ -8,9 +8,15 @@ import { V1beta1Provider, } from '@kubev2v/types'; import { K8sModel, k8sPatch } from '@openshift-console/dynamic-plugin-sdk'; -import { Dropdown, DropdownItem, DropdownToggle } from '@patternfly/react-core/deprecated'; - -import { useProviderInventory, useToggle } from '../../hooks'; +import { + Dropdown, + DropdownItem, + DropdownList, + MenuToggle, + MenuToggleElement, +} from '@patternfly/react-core'; + +import { useProviderInventory } from '../../hooks'; import { EditModal, EditModalProps, @@ -60,8 +66,21 @@ interface DropdownRendererProps { const OpenshiftNetworksInputFactory: ({ resource }) => ModalInputComponentType = ({ resource: provider, }) => { - const DropdownRenderer: React.FC = ({ value, onChange }) => { - const [isOpen, onToggle] = useToggle(false); + const DropdownRenderer: FC = ({ value, onChange }) => { + // Hook for managing the open/close state of the dropdown + const [isOpen, setIsOpen] = useState(false); + + const onToggleClick = () => { + setIsOpen((isOpen) => !isOpen); + }; + + const onSelect = ( + _event: React.MouseEvent | undefined, + _value: string | number | undefined, + ) => { + setIsOpen(false); + }; + const { inventory: networks } = useProviderInventory({ provider, // eslint-disable-next-line @cspell/spellchecker @@ -72,7 +91,8 @@ const OpenshiftNetworksInputFactory: ({ resource }) => ModalInputComponentType = const dropdownItems = [ onChange('')} > @@ -80,6 +100,7 @@ const OpenshiftNetworksInputFactory: ({ resource }) => ModalInputComponentType = , ...(networks || []).map((n) => ( onChange(`${n.namespace}/${n.name}`)} @@ -91,16 +112,27 @@ const OpenshiftNetworksInputFactory: ({ resource }) => ModalInputComponentType = return ( - {name} - - } isOpen={isOpen} - dropdownItems={dropdownItems} - menuAppendTo="parent" - /> + onOpenChange={setIsOpen} + onSelect={onSelect} + toggle={(toggleRef: Ref) => ( + + {name} + + )} + shouldFocusToggleOnSelect + popperProps={{ + position: 'right', + }} + isScrollable={true} + > + {dropdownItems} + ); }; diff --git a/packages/forklift-console-plugin/src/modules/StorageMaps/actions/StorageMapActionsDropdown.tsx b/packages/forklift-console-plugin/src/modules/StorageMaps/actions/StorageMapActionsDropdown.tsx index 7051b67b6..647da2398 100644 --- a/packages/forklift-console-plugin/src/modules/StorageMaps/actions/StorageMapActionsDropdown.tsx +++ b/packages/forklift-console-plugin/src/modules/StorageMaps/actions/StorageMapActionsDropdown.tsx @@ -1,15 +1,16 @@ -import React from 'react'; -import { useToggle } from 'src/modules/Providers/hooks'; +import React, { FC, Ref, useState } from 'react'; import { ModalHOC } from 'src/modules/Providers/modals'; import { useForkliftTranslation } from 'src/utils/i18n'; -import { Flex, FlexItem } from '@patternfly/react-core'; import { Dropdown, - DropdownPosition, - DropdownToggle, - KebabToggle, -} from '@patternfly/react-core/deprecated'; + DropdownList, + Flex, + FlexItem, + MenuToggle, + MenuToggleElement, +} from '@patternfly/react-core'; +import { EllipsisVIcon } from '@patternfly/react-icons'; import { CellProps } from '../views/list/components'; @@ -17,34 +18,46 @@ import { StorageMapActionsDropdownItems } from './StorageMapActionsDropdownItems import './StorageMapActionsDropdown.style.css'; -const StorageMapActionsKebabDropdown_: React.FC = ({ - data, - isKebab, -}) => { +const StorageMapActionsKebabDropdown_: FC = ({ data, isKebab }) => { const { t } = useForkliftTranslation(); - // Hook for managing the open/close state of the dropdown - const [isDropdownOpen, toggle] = useToggle(); + const [isOpen, setIsOpen] = useState(false); + + const onToggleClick = () => { + setIsOpen((isOpen) => !isOpen); + }; + + const onSelect = ( + _event: React.MouseEvent | undefined, + _value: string | number | undefined, + ) => { + setIsOpen(false); + }; // Returning the Dropdown component from PatternFly library return ( - ) : ( - - {t('Actions')} - - ) - } - dropdownItems={StorageMapActionsDropdownItems({ data })} - /> + isOpen={isOpen} + onOpenChange={setIsOpen} + onSelect={onSelect} + toggle={(toggleRef: Ref) => ( + + {isKebab ? : t('Actions')} + + )} + shouldFocusToggleOnSelect + popperProps={{ + position: 'right', + }} + > + {StorageMapActionsDropdownItems({ data })} + ); }; diff --git a/packages/forklift-console-plugin/src/modules/StorageMaps/actions/StorageMapActionsDropdownItems.tsx b/packages/forklift-console-plugin/src/modules/StorageMaps/actions/StorageMapActionsDropdownItems.tsx index a34b43271..1ebbc8873 100644 --- a/packages/forklift-console-plugin/src/modules/StorageMaps/actions/StorageMapActionsDropdownItems.tsx +++ b/packages/forklift-console-plugin/src/modules/StorageMaps/actions/StorageMapActionsDropdownItems.tsx @@ -5,7 +5,7 @@ import { getResourceUrl } from 'src/modules/Providers/utils'; import { useForkliftTranslation } from 'src/utils/i18n'; import { StorageMapModel, StorageMapModelRef } from '@kubev2v/types'; -import { DropdownItem } from '@patternfly/react-core/deprecated'; +import { DropdownItem } from '@patternfly/react-core'; import { StorageMapData } from '../utils'; @@ -26,10 +26,19 @@ export const StorageMapActionsDropdownItems = ({ data }: StorageMapActionsDropdo }; return [ - - {t('Edit StorageMap')} - , - + , + + {t('Delete StorageMap')} , ];