From 1120313177d21e9c2beda22e57ea50f2fa39ac8d Mon Sep 17 00:00:00 2001 From: Robb Hamilton Date: Tue, 10 Feb 2026 16:37:07 -0500 Subject: [PATCH] CONSOLE-4447: Migrate core modals to PatternFly v6 --- .../src/hooks/useLabelsModal.tsx | 20 +- .../modals/add-secret-to-workload.tsx | 262 +++++++------ .../components/modals/alert-routing-modal.tsx | 71 +++- .../configure-cluster-upstream-modal.tsx | 246 ++++++------ .../modals/configure-ns-pull-secret-modal.tsx | 363 +++++++++--------- .../configure-update-strategy-modal.tsx | 94 +++-- .../components/modals/expand-pvc-modal.tsx | 90 +++-- .../public/components/modals/labels-modal.tsx | 129 ++++--- .../modals/managed-resource-save-modal.tsx | 95 +++-- .../components/modals/remove-volume-modal.tsx | 83 ++-- frontend/public/style/_common.scss | 4 - 11 files changed, 852 insertions(+), 605 deletions(-) diff --git a/frontend/packages/console-shared/src/hooks/useLabelsModal.tsx b/frontend/packages/console-shared/src/hooks/useLabelsModal.tsx index d7601e21047..3916bc3e649 100644 --- a/frontend/packages/console-shared/src/hooks/useLabelsModal.tsx +++ b/frontend/packages/console-shared/src/hooks/useLabelsModal.tsx @@ -1,27 +1,17 @@ import { useCallback } from 'react'; -import type { ModalComponent } from '@console/dynamic-plugin-sdk/src/app/modal-support/ModalProvider'; -import { useModal } from '@console/dynamic-plugin-sdk/src/app/modal-support/useModal'; +import { useOverlay } from '@console/dynamic-plugin-sdk/src/app/modal-support/useOverlay'; import type { UseLabelsModal } from '@console/dynamic-plugin-sdk/src/extensions/console-types'; import { useK8sModel } from '@console/dynamic-plugin-sdk/src/utils/k8s/hooks/useK8sModel'; import { getGroupVersionKindForResource } from '@console/dynamic-plugin-sdk/src/utils/k8s/k8s-ref'; -import { ModalWrapper } from '@console/internal/components/factory/modal'; import type { LabelsModalProps } from '@console/internal/components/modals/labels-modal'; -import { LabelsModal } from '@console/internal/components/modals/labels-modal'; - -const LabelsModalComponent: ModalComponent = ({ closeModal, kind, resource }) => { - return ( - - - - ); -}; +import { LabelsModalOverlay } from '@console/internal/components/modals/labels-modal'; export const useLabelsModal: UseLabelsModal = (resource) => { - const launcher = useModal(); + const launchModal = useOverlay(); const groupVersionKind = getGroupVersionKindForResource(resource); const [kind] = useK8sModel(groupVersionKind); return useCallback( - () => resource && kind && launcher(LabelsModalComponent, { kind, resource }), - [launcher, kind, resource], + () => resource && kind && launchModal(LabelsModalOverlay, { kind, resource }), + [launchModal, kind, resource], ); }; diff --git a/frontend/public/components/modals/add-secret-to-workload.tsx b/frontend/public/components/modals/add-secret-to-workload.tsx index 36b454e1835..04b0fb0e903 100644 --- a/frontend/public/components/modals/add-secret-to-workload.tsx +++ b/frontend/public/components/modals/add-secret-to-workload.tsx @@ -3,11 +3,22 @@ import { useState, useEffect, useCallback } from 'react'; import * as _ from 'lodash'; import * as fuzzy from 'fuzzysearch'; import { useNavigate } from 'react-router-dom-v5-compat'; -import { FormGroup, Radio } from '@patternfly/react-core'; +import { + Button, + Content, + ContentVariants, + Form, + FormGroup, + Modal, + ModalBody, + ModalHeader, + ModalVariant, + Radio, + TextInput, +} from '@patternfly/react-core'; import { K8sKind, k8sList, k8sPatch, K8sResourceKind } from '../../module/k8s'; import { DeploymentModel, DeploymentConfigModel, StatefulSetModel } from '../../models'; -import { ModalTitle, ModalBody, ModalSubmitFooter, ModalWrapper } from '../factory/modal'; import { ConsoleSelect } from '@console/internal/components/utils/console-select'; import { ResourceIcon, ResourceName } from '../utils/resource-icon'; import { resourcePathFromModel } from '../utils/resource-link'; @@ -16,6 +27,8 @@ import { Trans, useTranslation } from 'react-i18next'; import { useOverlay } from '@console/dynamic-plugin-sdk/src/app/modal-support/useOverlay'; import { OverlayComponent } from '@console/dynamic-plugin-sdk/src/app/modal-support/OverlayProvider'; import { ModalCallback } from './types'; +import type { ModalComponentProps } from '../factory'; +import { ModalFooterWithAlerts } from '@console/shared/src/components/modals/ModalFooterWithAlerts'; const workloadResourceModels = [DeploymentModel, DeploymentConfigModel, StatefulSetModel]; const getContainers = (workload: K8sResourceKind) => @@ -167,132 +180,154 @@ export const AddSecretToWorkloadModal: FC = (prop const selectWorkloadPlaceholder = t('public~Select a workload'); return ( -
- {t('public~Add secret to workload')} + <> + -

+ Add all values from {{ secretName }} to a workload as environment variables or a volume. -

-
- - -
-
- {t('public~Add secret as')} -
- - - {addAsEnvironment && ( -
-
- - - setPrefix(e.currentTarget.value)} - /> - -
-
- )} - - {addAsVolume && ( -
-
- - - setMountPath(e.currentTarget.value)} - required - /> - -
-
- )} -
-
-
+ + + + + + + + setPrefix(value)} + /> + + ) + } + /> + + setMountPath(value)} + isRequired + /> + + ) + } + /> + +
- - + + + + + ); }; -export const AddSecretToWorkloadModalProvider: OverlayComponent = ( +export const AddSecretToWorkloadModalOverlay: OverlayComponent = ( props, ) => { - return ( - - - - ); + const [isOpen, setIsOpen] = useState(true); + const handleClose = () => { + setIsOpen(false); + props.closeOverlay(); + }; + + return isOpen ? ( + + + + ) : null; }; export const useAddSecretToWorkloadModalLauncher = ( props: AddSecretToWorkloadModalProps, ): ModalCallback => { - const launcher = useOverlay(); + const launchModal = useOverlay(); - return useCallback( - () => launcher(AddSecretToWorkloadModalProvider, props), - [launcher, props], - ); + return useCallback(() => { + // Move focus away from the triggering element to prevent aria-hidden warning + if (document.activeElement instanceof HTMLElement) { + document.activeElement.blur(); + } + return launchModal(AddSecretToWorkloadModalOverlay, props); + }, [launchModal, props]); }; type WorkloadItem = { @@ -303,10 +338,7 @@ type WorkloadItem = { export type AddSecretToWorkloadModalProps = { secretName: string; namespace: string; - cancel?: () => void; - close?: () => void; - blocking?: boolean; -}; +} & ModalComponentProps; export type AddSecretToWorkloadModalState = { inProgress: boolean; diff --git a/frontend/public/components/modals/alert-routing-modal.tsx b/frontend/public/components/modals/alert-routing-modal.tsx index 331400e6d82..28381204db2 100644 --- a/frontend/public/components/modals/alert-routing-modal.tsx +++ b/frontend/public/components/modals/alert-routing-modal.tsx @@ -2,14 +2,23 @@ import type { FC } from 'react'; import { useState } from 'react'; import * as _ from 'lodash'; import { useTranslation } from 'react-i18next'; +import { + Button, + Form, + FormGroup, + Modal, + ModalBody, + ModalHeader, + ModalVariant, + TextInput, +} from '@patternfly/react-core'; import { OverlayComponent } from '@console/dynamic-plugin-sdk/src/app/modal-support/OverlayProvider'; import type { ModalComponentProps } from '../factory/modal'; -import { ModalTitle, ModalBody, ModalSubmitFooter, ModalWrapper } from '../factory/modal'; import { K8sResourceKind } from '../../module/k8s'; import { AlertmanagerConfig } from '../monitoring/alertmanager/alertmanager-config'; import { patchAlertmanagerConfig } from '../monitoring/alertmanager/alertmanager-utils'; -import { Form, FormGroup, TextInput } from '@patternfly/react-core'; +import { ModalFooterWithAlerts } from '@console/shared/src/components/modals/ModalFooterWithAlerts'; const updateAlertRoutingProperty = ( config: any, @@ -63,10 +72,13 @@ export const AlertRoutingModal: FC = ({ }; return ( -
- {t('public~Edit routing configuration')} + <> + -
+ = ({ data-test-id="input-repeat-interval" /> -
+
- - + + + + + ); }; -export const AlertRoutingModalOverlay: OverlayComponent = (props) => ( - - - -); +export const AlertRoutingModalOverlay: OverlayComponent = (props) => { + const [isOpen, setIsOpen] = useState(true); + const handleClose = () => { + setIsOpen(false); + props.closeOverlay(); + }; + + return isOpen ? ( + + + + ) : null; +}; type AlertRoutingModalProps = { config: AlertmanagerConfig; diff --git a/frontend/public/components/modals/configure-cluster-upstream-modal.tsx b/frontend/public/components/modals/configure-cluster-upstream-modal.tsx index b5f067eae53..cffc3945995 100644 --- a/frontend/public/components/modals/configure-cluster-upstream-modal.tsx +++ b/frontend/public/components/modals/configure-cluster-upstream-modal.tsx @@ -1,28 +1,28 @@ import type { FormEventHandler } from 'react'; import { useState, useRef, useCallback } from 'react'; import { + Button, + Content, + ContentVariants, Form, + FormGroup, FormHelperText, - FormSection, HelperText, HelperTextItem, + Modal, + ModalBody, + ModalHeader, + ModalVariant, Radio, - Stack, - StackItem, TextInput, } from '@patternfly/react-core'; import { ExclamationCircleIcon } from '@patternfly/react-icons'; import { ClusterVersionModel } from '../../models'; import { ClusterVersionKind, k8sPatch } from '../../module/k8s'; -import { - ModalBody, - ModalComponentProps, - ModalSubmitFooter, - ModalTitle, - ModalWrapper, -} from '../factory/modal'; +import { ModalComponentProps } from '../factory/modal'; import { OverlayComponent } from '@console/dynamic-plugin-sdk/src/app/modal-support/OverlayProvider'; +import { ModalFooterWithAlerts } from '@console/shared/src/components/modals/ModalFooterWithAlerts'; import { ExternalLink } from '@console/shared/src/components/links/ExternalLink'; import { documentationURLs, @@ -73,95 +73,120 @@ export const ConfigureClusterUpstreamModal = (props: ConfigureClusterUpstreamMod return ( <> - {t('public~Edit upstream configuration')} -
- -

- {t( - 'public~Select a configuration to receive updates. Updates can be configured to receive information from Red Hat or a custom update service.', - )} -

- {!isManaged() && !isUpstream() && ( -

- -

+ + + + {t( + 'public~Select a configuration to receive updates. Updates can be configured to receive information from Red Hat or a custom update service.', )} - - - - { - setCustomSelected(false); - setInvalidCustomURL(false); - }} - label={t('public~Default')} - isChecked={!customSelected} - /> - - - - - {t('public~Receive update information from Red Hat.')} - - - - - - { - setCustomSelected(true); - customURLInputRef.current.focus(); - }} - label={t('public~Custom update service')} - isChecked={customSelected} - /> - { - setCustomSelected(true); - setCustomURL(text); - setInvalidCustomURL(false); - }} - validated={invalidCustomURL ? 'error' : 'default'} - ref={customURLInputRef} - /> - {invalidCustomURL && ( - - - } variant="error"> - {t('public~Please enter a URL.')} - - - - )} - - - - - - + + {!isManaged() && !isUpstream() && ( + + + + )} +
+ + { + setCustomSelected(false); + setInvalidCustomURL(false); + }} + label={t('public~Default')} + isChecked={!customSelected} + body={ + !customSelected && ( + <> + + + + + {t('public~Receive update information from Red Hat.')} + + + + + ) + } + /> + { + setCustomSelected(true); + setTimeout(() => { + customURLInputRef.current?.focus(); + }, 0); + }} + label={t('public~Custom update service')} + isChecked={customSelected} + body={ + customSelected && ( + <> + { + setCustomSelected(true); + setCustomURL(text); + setInvalidCustomURL(false); + }} + validated={invalidCustomURL ? 'error' : 'default'} + ref={customURLInputRef} + /> + {invalidCustomURL && ( + + + } variant="error"> + {t('public~Please enter a URL.')} + + + + )} + + ) + } + /> + +
+
+ + + + ); }; @@ -169,15 +194,22 @@ export const ConfigureClusterUpstreamModal = (props: ConfigureClusterUpstreamMod export const ConfigureClusterUpstreamModalOverlay: OverlayComponent = ( props, ) => { - return ( - - - - ); + const [isOpen, setIsOpen] = useState(true); + const handleClose = () => { + setIsOpen(false); + props.closeOverlay(); + }; + + return isOpen ? ( + + + + ) : null; }; export type ConfigureClusterUpstreamModalProps = { diff --git a/frontend/public/components/modals/configure-ns-pull-secret-modal.tsx b/frontend/public/components/modals/configure-ns-pull-secret-modal.tsx index c9b8669dcff..5ec1a724d65 100644 --- a/frontend/public/components/modals/configure-ns-pull-secret-modal.tsx +++ b/frontend/public/components/modals/configure-ns-pull-secret-modal.tsx @@ -2,13 +2,19 @@ import * as _ from 'lodash'; import { Base64 } from 'js-base64'; import { Alert, + Button, CodeBlock, CodeBlockCode, Content, ContentVariants, + Form, FormGroup, Grid, GridItem, + Modal, + ModalBody, + ModalHeader, + ModalVariant, Radio, TextInput, } from '@patternfly/react-core'; @@ -20,14 +26,9 @@ import { OverlayComponent } from '@console/dynamic-plugin-sdk/src/app/modal-supp import { k8sPatchByName, k8sCreate, K8sResourceKind } from '../../module/k8s'; import { SecretModel, ServiceAccountModel } from '../../models'; import { useState, useCallback } from 'react'; -import { - ModalTitle, - ModalBody, - ModalSubmitFooter, - ModalWrapper, - ModalComponentProps, -} from '../factory/modal'; +import { ModalComponentProps } from '../factory/modal'; import { ResourceIcon } from '../utils/resource-icon'; +import { ModalFooterWithAlerts } from '@console/shared/src/components/modals/ModalFooterWithAlerts'; interface FormData { username: string; @@ -152,178 +153,198 @@ const ConfigureNamespacePullSecret: FC = (pro ); return ( -
- {t('public~Default pull Secret')} + <> + - - - - {t( - 'public~Specify default credentials to be used to authenticate and download containers within this namespace. These credentials will be the default unless a pod references a specific pull Secret.', - )} - - - - - - - -  {namespace.metadata.name} - - - - - - - - - - {t('public~Friendly name to help you manage this in the future')} - - - - - - - -
- - - - -
-
- - {method === 'form' && ( - <> - - - - - - - - - - - - - - {t('public~Optional, depending on registry provider')} - - - - - - - - - - - - - - - - - - )} - - {method === 'upload' && ( - <> - - - - - - - {t( - 'public~Properly configured Docker config file in JSON format. Will be base64 encoded after upload.', - )} - - - - {invalidJson && ( - - - {t('public~The uploaded file is not properly-formatted JSON.')} - + + + + + {t( + 'public~Specify default credentials to be used to authenticate and download containers within this namespace. These credentials will be the default unless a pod references a specific pull Secret.', + )} + + + + + + + +  {namespace.metadata.name} + + + + + + + + + + {t('public~Friendly name to help you manage this in the future')} + + + + + + + +
+ + + + +
+
+ + {method === 'form' && ( + <> + + + + + + + + + + + + + + {t('public~Optional, depending on registry provider')} + + + + + + + + + + + + + + + + + + )} + + {method === 'upload' && ( + <> + + - )} - {fileData && ( - - - {fileData} - + + + + {t( + 'public~Properly configured Docker config file in JSON format. Will be base64 encoded after upload.', + )} + - )} - - )} -
+ + {invalidJson && ( + + + {t('public~The uploaded file is not properly-formatted JSON.')} + + + )} + {fileData && ( + + + {fileData} + + + )} + + )} +
+
- - + + + + + ); }; export const ConfigureNamespacePullSecretModalOverlay: OverlayComponent = ( props, ) => { - return ( - - - - ); + const [isOpen, setIsOpen] = useState(true); + const handleClose = () => { + setIsOpen(false); + props.closeOverlay(); + }; + + return isOpen ? ( + + + + ) : null; }; diff --git a/frontend/public/components/modals/configure-update-strategy-modal.tsx b/frontend/public/components/modals/configure-update-strategy-modal.tsx index aa80e897c34..02ff355cebc 100644 --- a/frontend/public/components/modals/configure-update-strategy-modal.tsx +++ b/frontend/public/components/modals/configure-update-strategy-modal.tsx @@ -2,6 +2,8 @@ import * as _ from 'lodash'; import { useCallback, useState } from 'react'; import type { FC } from 'react'; import { + Button, + Form, FormGroup, FormHelperText, FormSection, @@ -10,6 +12,10 @@ import { InputGroup, InputGroupItem, InputGroupText, + Modal, + ModalBody, + ModalHeader, + ModalVariant, Radio, TextInput, Tooltip, @@ -18,14 +24,9 @@ import { useTranslation } from 'react-i18next'; import { OverlayComponent } from '@console/dynamic-plugin-sdk/src/app/modal-support/OverlayProvider'; import { k8sPatch, Patch, DeploymentUpdateStrategy, K8sResourceKind } from '../../module/k8s'; import { DeploymentModel } from '../../models'; -import { - ModalTitle, - ModalBody, - ModalSubmitFooter, - ModalWrapper, - ModalComponentProps, -} from '../factory/modal'; +import { ModalComponentProps } from '../factory/modal'; import { usePromiseHandler } from '@console/shared/src/hooks/promise-handler'; +import { ModalFooterWithAlerts } from '@console/shared/src/components/modals/ModalFooterWithAlerts'; export const getNumberOrPercent = (value) => { if (typeof value === 'undefined') { @@ -52,7 +53,7 @@ export const ConfigureUpdateStrategy: FC = ({ const { t } = useTranslation(); const strategyIsNotRollingUpdate = strategyType !== 'RollingUpdate'; return ( -
+ <> {showDescription && ( {t('public~How should the pods be replaced when a new revision is created?')} @@ -157,7 +158,7 @@ export const ConfigureUpdateStrategy: FC = ({ autoFocus={strategyType === 'Recreate'} data-test="recreate-update-strategy-radio" /> -
+ ); }; @@ -199,41 +200,62 @@ export const ConfigureUpdateStrategyModal: FC ); return ( -
- {t('public~Edit update strategy')} + <> + - + + + - - + + + + + ); }; export const ConfigureUpdateStrategyModalOverlay: OverlayComponent = ( props, ) => { - return ( - - - - ); + const [isOpen, setIsOpen] = useState(true); + const handleClose = () => { + setIsOpen(false); + props.closeOverlay(); + }; + + return isOpen ? ( + + + + ) : null; }; export type ConfigureUpdateStrategyProps = { diff --git a/frontend/public/components/modals/expand-pvc-modal.tsx b/frontend/public/components/modals/expand-pvc-modal.tsx index 21d09ee09a7..087a0b1c04c 100644 --- a/frontend/public/components/modals/expand-pvc-modal.tsx +++ b/frontend/public/components/modals/expand-pvc-modal.tsx @@ -1,20 +1,26 @@ import { useState, useCallback, FC } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom-v5-compat'; -import { OverlayComponent } from '@console/dynamic-plugin-sdk/src/app/modal-support/OverlayProvider'; import { - ModalTitle, + Button, + Content, + ContentVariants, + Form, + FormGroup, + Modal, ModalBody, - ModalSubmitFooter, - ModalWrapper, - ModalComponentProps, -} from '../factory/modal'; + ModalHeader, + ModalVariant, +} from '@patternfly/react-core'; +import { OverlayComponent } from '@console/dynamic-plugin-sdk/src/app/modal-support/OverlayProvider'; +import { ModalComponentProps } from '../factory/modal'; import { RequestSizeInput } from '../utils/request-size-input'; import { resourceObjPath } from '../utils/resource-link'; import { validate, convertToBaseValue, humanizeBinaryBytesWithoutB } from '../utils/units'; import { k8sPatch, referenceFor, K8sKind, K8sResourceKind } from '../../module/k8s/'; import { getRequestedPVCSize } from '@console/shared/src/selectors/storage'; import { usePromiseHandler } from '@console/shared/src/hooks/promise-handler'; +import { ModalFooterWithAlerts } from '@console/shared/src/components/modals/ModalFooterWithAlerts'; // Modal for expanding persistent volume claims const ExpandPVCModal: FC = ({ resource, kind, close, cancel }) => { @@ -58,36 +64,48 @@ const ExpandPVCModal: FC = ({ resource, kind, close, cancel }; return ( -
- {t('public~Expand {{kind}}', { kind: kind.label })} + <> + -

+ Increase the capacity of PVC{' '} {{ resourceName: resource.metadata.name }}.{' '} Note that capacity must be at least the current PVC size. This expansion might take some time to complete. -

- - + + + + + +
- - + + + + + ); }; @@ -97,9 +115,15 @@ export type ExpandPVCModalProps = { } & ModalComponentProps; export const ExpandPVCModalOverlay: OverlayComponent = (props) => { - return ( - - - - ); + const [isOpen, setIsOpen] = useState(true); + const handleClose = () => { + setIsOpen(false); + props.closeOverlay(); + }; + + return isOpen ? ( + + + + ) : null; }; diff --git a/frontend/public/components/modals/labels-modal.tsx b/frontend/public/components/modals/labels-modal.tsx index ab09981df54..dae4bc6c08c 100644 --- a/frontend/public/components/modals/labels-modal.tsx +++ b/frontend/public/components/modals/labels-modal.tsx @@ -2,6 +2,17 @@ import * as _ from 'lodash'; import type { FC } from 'react'; import { useState, useEffect, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; +import { + Button, + Content, + ContentVariants, + Form, + FormGroup, + Modal, + ModalBody, + ModalHeader, + ModalVariant, +} from '@patternfly/react-core'; import { getGroupVersionKindForModel } from '@console/dynamic-plugin-sdk/src/utils/k8s/k8s-ref'; import { K8sModel } from '@console/dynamic-plugin-sdk/src/api/common-types'; import { k8sPatchResource } from '@console/dynamic-plugin-sdk/src/utils/k8s/k8s-resource'; @@ -9,17 +20,11 @@ import { K8sResourceCommon } from '@console/dynamic-plugin-sdk/src/extensions/co import { OverlayComponent } from '@console/dynamic-plugin-sdk/src/app/modal-support/OverlayProvider'; import { K8sResourceKind } from '../../module/k8s'; import { usePromiseHandler } from '@console/shared/src/hooks/promise-handler'; -import { - ModalBody, - ModalComponentProps, - ModalSubmitFooter, - ModalTitle, - ModalWrapper, -} from '../factory/modal'; +import { ModalComponentProps } from '../factory/modal'; import { ResourceIcon } from '../utils/resource-icon'; import { SelectorInput } from '../utils/selector-input'; import { useK8sWatchResource } from '../utils/k8s-watch-hook'; -import { Grid, GridItem } from '@patternfly/react-core'; +import { ModalFooterWithAlerts } from '@console/shared/src/components/modals/ModalFooterWithAlerts'; const LABELS_PATH = '/metadata/labels'; const TEMPLATE_SELECTOR_PATH = '/spec/template/metadata/labels'; @@ -88,31 +93,39 @@ const BaseLabelsModal: FC = ({ ); return ( -
- - {descriptionKey - ? t('public~Edit {{description}}', { - description: t(descriptionKey), - }) - : t('public~Edit labels')} - + <> + - - - {messageKey - ? t(messageKey, messageVariables) - : t( - 'public~Labels help you organize and select resources. Adding labels below will let you query for objects that have similar, overlapping or dissimilar labels.', - )} - - - + + {messageKey + ? t(messageKey, messageVariables) + : t( + 'public~Labels help you organize and select resources. Adding labels below will let you query for objects that have similar, overlapping or dissimilar labels.', + )} + + + + {descriptionKey + ? t('{{description}} for', { description: t(descriptionKey) }) + : t('public~Labels for')}{' '} + {' '} + {resource?.metadata?.name} + + } + fieldId="tags-input" + > setLabels(l)} onValidationChange={setIsInputValid} @@ -120,34 +133,56 @@ const BaseLabelsModal: FC = ({ labelClassName={labelClassName || `co-m-${kind.id}`} autoFocus /> - - + + - - + > + + + + ); }; -export const LabelsModal: FC = (props) => ( +const LabelsModal: FC = (props) => ( ); -export const LabelsModalOverlay: OverlayComponent = (props) => ( - - - -); +export const LabelsModalOverlay: OverlayComponent = (props) => { + const [isOpen, setIsOpen] = useState(true); + const handleClose = () => { + setIsOpen(false); + props.closeOverlay(); + }; + + return isOpen ? ( + + + + ) : null; +}; type BaseLabelsModalProps = { descriptionKey?: string; diff --git a/frontend/public/components/modals/managed-resource-save-modal.tsx b/frontend/public/components/modals/managed-resource-save-modal.tsx index b4c01c8e718..f5efdf3d543 100644 --- a/frontend/public/components/modals/managed-resource-save-modal.tsx +++ b/frontend/public/components/modals/managed-resource-save-modal.tsx @@ -1,18 +1,21 @@ import type { FC } from 'react'; +import { useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; - import { - ModalTitle, + Button, + Content, + ContentVariants, + Form, + Modal, ModalBody, - ModalSubmitFooter, - ModalComponentProps, - ModalWrapper, -} from '../factory/modal'; + ModalHeader, + ModalVariant, +} from '@patternfly/react-core'; import { referenceForOwnerRef, K8sResourceCommon, OwnerReference } from '../../module/k8s/'; -import { YellowExclamationTriangleIcon } from '@console/shared/src/components/status/icons'; import { OverlayComponent } from '@console/dynamic-plugin-sdk/src/app/modal-support/OverlayProvider'; - +import { ModalComponentProps } from '../factory/modal'; import { ResourceLink } from '../utils/resource-link'; +import { ModalFooterWithAlerts } from '@console/shared/src/components/modals/ModalFooterWithAlerts'; const ManagedResourceSaveModal: FC = (props) => { const submit = (event) => { @@ -24,36 +27,66 @@ const ManagedResourceSaveModal: FC = (props) => { const { owner, resource } = props; const { t } = useTranslation(); return ( -
- - {t('public~Managed resource')} - - - - This resource is managed by{' '} - {' '} - and any modifications may be overwritten. Edit the managing resource to preserve changes. - + <> + + + + + + This resource is managed by{' '} + {' '} + and any modifications may be overwritten. Edit the managing resource to preserve + changes. + + + - - + + + + + ); }; export const ManagedResourceSaveModalOverlay: OverlayComponent = ( props, ) => { - return ( - - - - ); + const [isOpen, setIsOpen] = useState(true); + const handleClose = () => { + setIsOpen(false); + props.closeOverlay(); + }; + + return isOpen ? ( + + + + ) : null; }; type ManagedResourceSaveModalProps = { diff --git a/frontend/public/components/modals/remove-volume-modal.tsx b/frontend/public/components/modals/remove-volume-modal.tsx index b204da10107..9ae6d683609 100644 --- a/frontend/public/components/modals/remove-volume-modal.tsx +++ b/frontend/public/components/modals/remove-volume-modal.tsx @@ -2,9 +2,18 @@ import * as _ from 'lodash'; import type { FC, FormEvent } from 'react'; import { useState, useCallback } from 'react'; import { Trans, useTranslation } from 'react-i18next'; +import { + Button, + Content, + ContentVariants, + Form, + Modal, + ModalBody, + ModalHeader, + ModalVariant, +} from '@patternfly/react-core'; import { useOverlay } from '@console/dynamic-plugin-sdk/src/app/modal-support/useOverlay'; import { OverlayComponent } from '@console/dynamic-plugin-sdk/src/app/modal-support/OverlayProvider'; -import { ModalTitle, ModalBody, ModalSubmitFooter, ModalWrapper } from '../factory/modal'; import { ContainerSpec, getVolumeType, @@ -15,8 +24,8 @@ import { VolumeMount, } from '../../module/k8s/'; import { RowVolumeData } from '../volumes-table'; -import { YellowExclamationTriangleIcon } from '@console/shared/src/components/status/icons'; import { ModalCallback } from './types'; +import { ModalFooterWithAlerts } from '@console/shared/src/components/modals/ModalFooterWithAlerts'; export const RemoveVolumeModal: FC = (props) => { const [inProgress, setInProgress] = useState(false); @@ -81,43 +90,63 @@ export const RemoveVolumeModal: FC = (props) => { const label = kind.label; const resourceName = resource.metadata.name; return ( -
- - {t('public~Remove volume?')} - - -
+ <> + + + Are you sure you want to remove volume{' '} {{ volumeName }} from{' '} {{ label }}: {{ resourceName }}? -
+ {type && ( -
- -
+ + {t('public~Note: This will not remove the underlying {{type}}.', { type })} + )} +
- - + + + + + ); }; export const RemoveVolumeModalProvider: OverlayComponent = (props) => { - return ( - - - - ); + const [isOpen, setIsOpen] = useState(true); + const handleClose = () => { + setIsOpen(false); + props.closeOverlay(); + }; + + return isOpen ? ( + + + + ) : null; }; export const useRemoveModalLauncher = (props: RemoveVolumeModalProps): ModalCallback => { diff --git a/frontend/public/style/_common.scss b/frontend/public/style/_common.scss index 50433300d07..7bb83e65f9b 100644 --- a/frontend/public/style/_common.scss +++ b/frontend/public/style/_common.scss @@ -167,10 +167,6 @@ white-space: nowrap; } -.co-m-radio-desc { - margin-left: 20px; -} - .co-m-form-row { margin-bottom: var(--pf-t--global--spacer--md); }