Skip to content

Commit 4546dc5

Browse files
authored
CONSOLE-3569: Expose labels modal through dynamic plugin SDK (openshift#13037)
* Rename labelsModal to labelsModalLauncher Factor out LabelsModal component from labelsModal and rename the original labelsModal to labelsModalLauncher to differentiate between the two. * Rename annotationsModal to annotationsModalLauncher Update annotationsModal to annotationsModalLauncher to be consistent with labelsModalLauncher. As we expose the underlying React components, we need to rename the exported launchers to eliminate the ambiguity. * Rename labels-modal.jsx to labels-modal.tsx * Add type definitions to labels-modal.tsx * Create useLabelsModal hook in console-shared package * Expose useLabelsModal hook through dyanmic plugin SDK * Use new `useLabelsModal` hook in `NodeDetailsOverview` and `ResourceSummary` components * Address tech debt in labels-modal.tsx
1 parent 18624e8 commit 4546dc5

File tree

11 files changed

+207
-86
lines changed

11 files changed

+207
-86
lines changed

frontend/packages/console-app/src/actions/creators/common-factory.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import i18next from 'i18next';
22
import { Action } from '@console/dynamic-plugin-sdk';
33
import {
4-
annotationsModal,
4+
annotationsModalLauncher,
55
deleteModal,
6-
labelsModal,
6+
labelsModalLauncher,
77
configureReplicaCountModal,
88
podSelectorModal,
99
tolerationsModal,
@@ -50,7 +50,7 @@ export const CommonActionFactory: ResourceActionFactory = {
5050
id: 'edit-labels',
5151
label: i18next.t('console-app~Edit labels'),
5252
cta: () =>
53-
labelsModal({
53+
labelsModalLauncher({
5454
kind,
5555
resource: obj,
5656
blocking: true,
@@ -61,7 +61,7 @@ export const CommonActionFactory: ResourceActionFactory = {
6161
id: 'edit-annotations',
6262
label: i18next.t('console-app~Edit annotations'),
6363
cta: () =>
64-
annotationsModal({
64+
annotationsModalLauncher({
6565
kind,
6666
resource: obj,
6767
blocking: true,

frontend/packages/console-app/src/components/nodes/NodeDetailsOverview.tsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ import {
1414
Timestamp,
1515
} from '@console/internal/components/utils';
1616
import { DetailsItem } from '@console/internal/components/utils/details-item';
17-
import { editLabelsModal } from '@console/internal/components/utils/details-page';
1817
import { NodeModel, MachineModel } from '@console/internal/models';
1918
import { NodeKind, referenceForModel } from '@console/internal/module/k8s';
20-
import { getNodeMachineNameAndNamespace, getNodeAddresses } from '@console/shared';
19+
import { useLabelsModal } from '@console/shared/src/hooks/useLabelsModal';
20+
import {
21+
getNodeMachineNameAndNamespace,
22+
getNodeAddresses,
23+
} from '@console/shared/src/selectors/node';
2124
import NodeIPList from './NodeIPList';
2225
import NodeStatus from './NodeStatus';
2326
import MarkAsSchedulablePopover from './popovers/MarkAsSchedulablePopover';
@@ -27,6 +30,7 @@ type NodeDetailsOverviewProps = {
2730
};
2831

2932
const NodeDetailsOverview: React.FC<NodeDetailsOverviewProps> = ({ node }) => {
33+
const launchLabelsModal = useLabelsModal(node);
3034
const machine = getNodeMachineNameAndNamespace(node);
3135
const canUpdate = useAccessReview({
3236
group: NodeModel.apiGroup,
@@ -64,7 +68,7 @@ const NodeDetailsOverview: React.FC<NodeDetailsOverviewProps> = ({ node }) => {
6468
obj={node}
6569
path="metadata.labels"
6670
valueClassName="details-item__value--labels"
67-
onEdit={(e) => editLabelsModal(e, { resource: node, kind: NodeModel })}
71+
onEdit={launchLabelsModal}
6872
canEdit={canUpdate}
6973
editAsGroup
7074
>

frontend/packages/console-dynamic-plugin-sdk/docs/api.md

+45-6
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,11 @@
6565
63. [QueryBrowser](#querybrowser)
6666
64. [useAnnotationsModal](#useannotationsmodal)
6767
65. [useDeleteModal](#usedeletemodal)
68-
66. [DEPRECATED] [PerspectiveContext](#perspectivecontext)
69-
67. [DEPRECATED] [useAccessReviewAllowed](#useaccessreviewallowed)
70-
68. [DEPRECATED] [useSafetyFirst](#usesafetyfirst)
71-
69. [DEPRECATED] [YAMLEditor](#yamleditor)
68+
66. [useLabelsModal](#uselabelsmodal)
69+
67. [DEPRECATED] [PerspectiveContext](#perspectivecontext)
70+
68. [DEPRECATED] [useAccessReviewAllowed](#useaccessreviewallowed)
71+
69. [DEPRECATED] [useSafetyFirst](#usesafetyfirst)
72+
70. [DEPRECATED] [YAMLEditor](#yamleditor)
7273

7374
---
7475

@@ -2248,7 +2249,7 @@ A component that renders a graph of the results from a Prometheus PromQL query a
22482249

22492250
### Summary
22502251

2251-
A hook for launching a modal for editing a Kubernetes resource's annotations.
2252+
A hook that provides a callback to launch a modal for editing Kubernetes resource annotations.
22522253

22532254

22542255

@@ -2286,7 +2287,7 @@ A function which will launch a modal for editing a resource's annotations.
22862287

22872288
### Summary
22882289

2289-
A hook for launching a modal for deleting a resource.
2290+
A hook that provides a callback to launch a modal for deleting a resource.
22902291

22912292

22922293

@@ -2320,6 +2321,44 @@ const DeletePodButton = ({ pod }) => {
23202321
A function which will launch a modal for deleting a resource.
23212322

23222323

2324+
---
2325+
2326+
## `useLabelsModal`
2327+
2328+
### Summary
2329+
2330+
A hook that provides a callback to launch a modal for editing Kubernetes resource labels.
2331+
2332+
2333+
2334+
### Example
2335+
2336+
2337+
```tsx
2338+
const PodLabelsButton = ({ pod }) => {
2339+
const { t } = useTranslation();
2340+
const launchLabelsModal = useLabelsModal<PodKind>(pod);
2341+
return <button onClick={launchLabelsModal}>{t('Edit Pod Labels')}</button>
2342+
}
2343+
```
2344+
2345+
2346+
2347+
2348+
2349+
### Parameters
2350+
2351+
| Parameter Name | Description |
2352+
| -------------- | ----------- |
2353+
| `resource` | The resource to edit labels for, an object of K8sResourceCommon type. |
2354+
2355+
2356+
2357+
### Returns
2358+
2359+
A function which will launch a modal for editing a resource's labels.
2360+
2361+
23232362
---
23242363

23252364
## `PerspectiveContext`

frontend/packages/console-dynamic-plugin-sdk/src/api/dynamic-core-api.ts

+39-22
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,37 @@
22
import * as React from 'react';
33
import { ActionServiceProviderProps } from '../extensions/actions';
44
import {
5+
CodeEditorProps,
6+
CodeEditorRef,
57
ErrorBoundaryFallbackProps,
68
HorizontalNavProps,
7-
UseResolvedExtensions,
8-
VirtualizedTableFC,
9-
TableDataProps,
10-
UseActiveColumns,
11-
ListPageHeaderProps,
12-
ListPageCreateProps,
13-
ListPageCreateLinkProps,
9+
InventoryItemBodyProps,
10+
InventoryItemStatusProps,
11+
InventoryItemTitleProps,
1412
ListPageCreateButtonProps,
1513
ListPageCreateDropdownProps,
14+
ListPageCreateLinkProps,
15+
ListPageCreateProps,
1616
ListPageFilterProps,
17-
UseListPageFilter,
18-
ResourceLinkProps,
19-
ResourceIconProps,
20-
OverviewProps,
17+
ListPageHeaderProps,
18+
NamespaceBarProps,
2119
OverviewGridProps,
22-
InventoryItemTitleProps,
23-
InventoryItemBodyProps,
24-
InventoryItemStatusProps,
25-
CodeEditorProps,
26-
ResourceYAMLEditorProps,
20+
OverviewProps,
21+
QueryBrowserProps,
2722
ResourceEventStreamProps,
28-
UsePrometheusPoll,
23+
ResourceIconProps,
24+
ResourceLinkProps,
25+
ResourceYAMLEditorProps,
26+
TableDataProps,
2927
TimestampProps,
30-
NamespaceBarProps,
31-
CodeEditorRef,
32-
QueryBrowserProps,
28+
UseActiveColumns,
3329
UseAnnotationsModal,
3430
UseDeleteModal,
31+
UseLabelsModal,
32+
UseListPageFilter,
33+
UsePrometheusPoll,
34+
UseResolvedExtensions,
35+
VirtualizedTableFC,
3536
} from '../extensions/console-types';
3637
import { StatusPopupSectionProps, StatusPopupItemProps } from '../extensions/dashboard-types';
3738

@@ -795,7 +796,7 @@ export const QueryBrowser: React.FC<QueryBrowserProps> = require('@console/share
795796
.default;
796797

797798
/**
798-
* A hook for launching a modal for editing a Kubernetes resource's annotations.
799+
* A hook that provides a callback to launch a modal for editing Kubernetes resource annotations.
799800
*
800801
* @param {object} resource - The resource to edit annotations for, an object of K8sResourceCommon type.
801802
* @returns A function which will launch a modal for editing a resource's annotations.
@@ -812,7 +813,7 @@ export const useAnnotationsModal: UseAnnotationsModal = require('@console/shared
812813
.useAnnotationsModal;
813814

814815
/**
815-
* A hook for launching a modal for deleting a resource.
816+
* A hook that provides a callback to launch a modal for deleting a resource.
816817
*
817818
* @param resource - The resource to delete.
818819
* @param redirectTo - (optional) A location to redirect to after deleting the resource.
@@ -829,3 +830,19 @@ export const useAnnotationsModal: UseAnnotationsModal = require('@console/shared
829830
*/
830831
export const useDeleteModal: UseDeleteModal = require('@console/shared/src/hooks/useDeleteModal')
831832
.useDeleteModal;
833+
834+
/**
835+
* A hook that provides a callback to launch a modal for editing Kubernetes resource labels.
836+
*
837+
* @param {object} resource - The resource to edit labels for, an object of K8sResourceCommon type.
838+
* @returns A function which will launch a modal for editing a resource's labels.
839+
* @example
840+
* ```tsx
841+
* const PodLabelsButton = ({ pod }) => {
842+
* const { t } = useTranslation();
843+
* const launchLabelsModal = useLabelsModal<PodKind>(pod);
844+
* return <button onClick={launchLabelsModal}>{t('Edit Pod Labels')}</button>
845+
* }
846+
* ```
847+
*/
848+
export const useLabelsModal: UseLabelsModal = require('@console/shared/src/hooks/useLabelsModal');

frontend/packages/console-dynamic-plugin-sdk/src/extensions/console-types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -724,3 +724,5 @@ export type UseDeleteModal = (
724724
btnText?: React.ReactNode,
725725
deleteAllResources?: () => Promise<K8sResourceKind[]>,
726726
) => () => void;
727+
728+
export type UseLabelsModal = (resource: K8sResourceCommon) => () => void;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import * as React from 'react';
2+
import { ModalComponent } from '@console/dynamic-plugin-sdk/src/app/modal-support/ModalProvider';
3+
import { useModal } from '@console/dynamic-plugin-sdk/src/app/modal-support/useModal';
4+
import { UseLabelsModal } from '@console/dynamic-plugin-sdk/src/extensions/console-types';
5+
import { useK8sModel } from '@console/dynamic-plugin-sdk/src/utils/k8s/hooks/useK8sModel';
6+
import { getGroupVersionKindForResource } from '@console/dynamic-plugin-sdk/src/utils/k8s/k8s-ref';
7+
import { ModalWrapper } from '@console/internal/components/factory/modal';
8+
import { LabelsModal, LabelsModalProps } from '@console/internal/components/modals/labels-modal';
9+
10+
const LabelsModalComponent: ModalComponent<LabelsModalProps> = ({ closeModal, kind, resource }) => {
11+
return (
12+
<ModalWrapper blocking onClose={closeModal}>
13+
<LabelsModal cancel={closeModal} close={closeModal} kind={kind} resource={resource} />
14+
</ModalWrapper>
15+
);
16+
};
17+
18+
export const useLabelsModal: UseLabelsModal = (resource) => {
19+
const launcher = useModal();
20+
const groupVersionKind = getGroupVersionKindForResource(resource);
21+
const [kind] = useK8sModel(groupVersionKind);
22+
return React.useCallback(
23+
() => resource && kind && launcher<LabelsModalProps>(LabelsModalComponent, { kind, resource }),
24+
[launcher, kind, resource],
25+
);
26+
};

frontend/public/components/modals/index.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ export const configureNamespacePullSecretModal = (props) =>
4747
'./configure-ns-pull-secret-modal' /* webpackChunkName: "configure-ns-pull-secret-modal" */
4848
).then((m) => m.configureNamespacePullSecretModal(props));
4949

50-
export const labelsModal = (props) =>
51-
import('./labels-modal' /* webpackChunkName: "labels-modal" */).then((m) => m.labelsModal(props));
50+
export const labelsModalLauncher = (props) =>
51+
import('./labels-modal' /* webpackChunkName: "labels-modal" */).then((m) =>
52+
m.labelsModalLauncher(props),
53+
);
5254

5355
export const podSelectorModal = (props) =>
5456
import('./labels-modal' /* webpackChunkName: "labels-modal" */).then((m) =>
@@ -65,8 +67,8 @@ export const configureUpdateStrategyModal = (props) =>
6567
'./configure-update-strategy-modal' /* webpackChunkName: "configure-update-strategy-modal" */
6668
).then((m) => m.configureUpdateStrategyModal(props));
6769

68-
export const annotationsModal = (props) =>
69-
import('./tags' /* webpackChunkName: "tags" */).then((m) => m.annotationsModal(props));
70+
export const annotationsModalLauncher = (props) =>
71+
import('./tags' /* webpackChunkName: "tags" */).then((m) => m.annotationsModalLauncher(props));
7072

7173
export const deleteModal = (props) =>
7274
import('./delete-modal' /* webpackChunkName: "delete-modal" */).then((m) => m.deleteModal(props));

0 commit comments

Comments
 (0)