Skip to content

Commit c9649dd

Browse files
CONSOLE-4954: Add Workload tab to Node view
1 parent bc24385 commit c9649dd

File tree

8 files changed

+84
-10
lines changed

8 files changed

+84
-10
lines changed

frontend/packages/console-app/locales/en/console-app.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@
526526
"Kubelet version": "Kubelet version",
527527
"Kube-Proxy version": "Kube-Proxy version",
528528
"Configuration": "Configuration",
529+
"Workload": "Workload",
529530
"Machine set": "Machine set",
530531
"This count is based on your access permissions and might not include all virtual machines.": "This count is based on your access permissions and might not include all virtual machines.",
531532
"{{formattedCores}} cores / {{totalCores}} cores": "{{formattedCores}} cores / {{totalCores}} cores",

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import NodeDashboard from './node-dashboard/NodeDashboard';
2121
import NodeDetails from './NodeDetails';
2222
import NodeLogs from './NodeLogs';
2323
import NodeTerminal from './NodeTerminal';
24+
import { NodeWorkload } from './NodeWorkload';
2425

2526
const NodePodsPage: FC<PageComponentProps<NodeKind>> = ({ obj }) => (
2627
<PodsPage
@@ -55,10 +56,15 @@ export const NodeDetailsPage: FC<ComponentProps<typeof DetailsPage>> = (props) =
5556
nameKey: 'console-app~Configuration',
5657
component: NodeConfiguration,
5758
},
59+
{
60+
href: 'workload',
61+
// t('console-app~Workload')
62+
nameKey: 'console-app~Workload',
63+
component: NodeWorkload,
64+
},
65+
navFactory.editYaml(),
5866
]
59-
: []),
60-
navFactory.editYaml(),
61-
navFactory.pods(NodePodsPage),
67+
: [navFactory.editYaml(), navFactory.pods(NodePodsPage)]),
6268
navFactory.logs(NodeLogs),
6369
navFactory.events(ResourceEventStream),
6470
...(!isWindowsNode(node) ? [navFactory.terminal(NodeTerminal)] : []),

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { useQueryParams } from '@console/shared/src/hooks/useQueryParams';
1111
import { useQueryParamsMutator } from '@console/shared/src/hooks/useQueryParamsMutator';
1212

1313
export const CONFIG_PAGE_ID = 'configuration';
14+
export const WORKLOADS_PAGE_ID = 'workloads';
1415

1516
export type SubPageType = {
1617
component: ComponentType<PageComponentProps<K8sResourceCommon>>;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type { FC } from 'react';
2+
import type { NodeKind } from '@console/dynamic-plugin-sdk/src';
3+
import { PodsPage } from '@console/internal/components/pod-list';
4+
import type { PageComponentProps } from '@console/internal/components/utils';
5+
import { NodeSubNavPage, WORKLOADS_PAGE_ID } from './NodeSubNavPage';
6+
7+
const NodePodsPage: FC<PageComponentProps<NodeKind>> = ({ obj }) => (
8+
<PodsPage
9+
fieldSelector={`spec.nodeName=${obj.metadata.name}`}
10+
showNamespaceOverride
11+
hideFavoriteButton
12+
/>
13+
);
14+
15+
type NodeWorkloadProps = {
16+
obj: NodeKind;
17+
};
18+
19+
const standardPages = [
20+
{
21+
tabId: 'pods',
22+
// t('console-app~Pods')
23+
nameKey: 'console-app~Pods',
24+
component: NodePodsPage,
25+
priority: 30,
26+
},
27+
];
28+
29+
export const NodeWorkload: FC<NodeWorkloadProps> = ({ obj }) => (
30+
<NodeSubNavPage obj={obj} pageId={WORKLOADS_PAGE_ID} standardPages={standardPages} />
31+
);

frontend/packages/console-app/src/components/nodes/node-dashboard/InventoryCard.tsx

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { FC } from 'react';
22
import { useMemo, useContext } from 'react';
3+
import { useResolvedExtensions } from '@openshift/dynamic-plugin-sdk';
34
import {
45
Card,
56
CardBody,
@@ -13,12 +14,16 @@ import {
1314
import { useTranslation } from 'react-i18next';
1415
import { Link } from 'react-router';
1516
import BareMetalInventoryItems from '@console/app/src/components/nodes/node-dashboard/BareMetalInventoryItems';
17+
import { WORKLOADS_PAGE_ID } from '@console/app/src/components/nodes/NodeSubNavPage';
1618
import { useIsKubevirtPluginActive } from '@console/app/src/utils/kubevirt';
19+
import type { NodeSubNavTab } from '@console/dynamic-plugin-sdk/src';
20+
import { isNodeSubNavTab } from '@console/dynamic-plugin-sdk/src';
1721
import { useK8sWatchResource } from '@console/internal/components/utils/k8s-watch-hook';
1822
import { resourcePathFromModel } from '@console/internal/components/utils/resource-link';
1923
import { PodModel, NodeModel } from '@console/internal/models';
2024
import type { K8sResourceCommon, K8sKind } from '@console/internal/module/k8s';
2125
import { referenceForModel } from '@console/internal/module/k8s';
26+
import { useTranslatedExtensions } from '@console/plugin-sdk/src/utils/useTranslatedExtensions';
2227
import type { StatusGroupMapper } from '@console/shared/src/components/dashboard/inventory-card/InventoryItem';
2328
import {
2429
InventoryItem,
@@ -29,6 +34,8 @@ import { DescriptionListTermHelp } from '@console/shared/src/components/descript
2934
import { useWatchVirtualMachineInstances, VirtualMachineModel } from '../utils/NodeVmUtils';
3035
import { NodeDashboardContext } from './NodeDashboardContext';
3136

37+
const NODE_VIRTUAL_MACHINES_PAGE_ID = 'virtualmachines';
38+
3239
export const NodeInventoryItem: FC<NodeInventoryItemProps> = ({ nodeName, model, mapper }) => {
3340
const resource = useMemo(
3441
() => ({
@@ -60,6 +67,31 @@ const InventoryCard: FC = () => {
6067
const showVms = useIsKubevirtPluginActive();
6168
const [vms, vmsLoaded, vmsLoadError] = useWatchVirtualMachineInstances(obj.metadata.name);
6269

70+
const [subTabExtensions, extensionsResolved] = useResolvedExtensions<NodeSubNavTab>(
71+
isNodeSubNavTab,
72+
);
73+
const nodeSubTabExtensions = useTranslatedExtensions(subTabExtensions ?? []);
74+
75+
const vmsLink = useMemo(() => {
76+
if (extensionsResolved) {
77+
const workloadExtensions = nodeSubTabExtensions.filter(
78+
(ext) => ext.properties.parentTab === WORKLOADS_PAGE_ID,
79+
);
80+
if (
81+
workloadExtensions.find(
82+
(ext) => ext.properties.page.tabId === NODE_VIRTUAL_MACHINES_PAGE_ID,
83+
)
84+
) {
85+
return `${resourcePathFromModel(NodeModel)}/${
86+
obj.metadata.name
87+
}/${WORKLOADS_PAGE_ID}?activeTab${NODE_VIRTUAL_MACHINES_PAGE_ID}`;
88+
}
89+
}
90+
return `${resourcePathFromModel(VirtualMachineModel)}/search?rowFilter-node=${
91+
obj.metadata.name
92+
}`;
93+
}, [extensionsResolved, nodeSubTabExtensions, obj.metadata.name]);
94+
6395
return (
6496
<Card data-test-id="inventory-card">
6597
<CardHeader>
@@ -99,11 +131,7 @@ const InventoryCard: FC = () => {
99131
)}
100132
/>
101133
<DescriptionListDescription>
102-
<Link
103-
to={`${resourcePathFromModel(VirtualMachineModel)}/search?rowFilter-node=${
104-
obj.metadata.name
105-
}`}
106-
>
134+
<Link to={vmsLink}>
107135
<InventoryItem
108136
isLoading={!vmsLoaded}
109137
title={t('console-app~Virtual machine')}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,7 @@ This extension can be used to add a tab on the sub-tabs for a Nodes details tab.
10721072
| Name | Value Type | Optional | Description |
10731073
| ---- | ---------- | -------- | ----------- |
10741074
| `parentTab` | `'configuration' \| 'health' \| 'workloads'` | no | Which detail tab to add the sub-tab to. |
1075-
| `page` | `{ tabId: string; name: string; priority: number; }` | no | The page to be show in node sub tabs. It takes tab name as name and priority of the tab.<br/>Note: Tabs are shown in priority order from highest to lowest. Current node tab priorities are:<br/>configuration:<br/> Storage: 70<br/> Operating system: 50<br/> Machine: 40<br/> High availability: 30 |
1075+
| `page` | `{ tabId: string; name: string; priority: number; }` | no | The page to be show in node sub tabs. It takes tab name as name and priority of the tab.<br/>Note: Tabs are shown in priority order from highest to lowest. Current node tab priorities are:<br/>configuration:<br/> Storage: 70<br/> Operating system: 50<br/> Machine: 40<br/> High availability: 30<br/> workloads:<br/> Pods: 30 |
10761076
| `component` | `CodeRef<ComponentType<SubPageComponentProps<K8sResourceCommon>>>` | no | The component to be rendered when the route matches. |
10771077

10781078
---

frontend/packages/console-dynamic-plugin-sdk/src/extensions/node-subnav-tabs.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ export type NodeSubNavTab = Extension<
1919
* Operating system: 50
2020
* Machine: 40
2121
* High availability: 30
22+
* workloads:
23+
* Pods: 30
2224
*/
2325
page: {
2426
tabId: string;

frontend/public/components/pod-list.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ export const PodsPage: FC<PodPageProps> = ({
588588
hideLabelFilter,
589589
hideColumnManagement,
590590
showNamespaceOverride,
591+
hideFavoriteButton,
591592
}) => {
592593
const { t } = useTranslation();
593594
const dispatch = useConsoleDispatch();
@@ -638,7 +639,10 @@ export const PodsPage: FC<PodPageProps> = ({
638639

639640
return (
640641
<>
641-
<ListPageHeader title={showTitle ? t('public~Pods') : ''}>
642+
<ListPageHeader
643+
title={showTitle ? t('public~Pods') : ''}
644+
hideFavoriteButton={hideFavoriteButton}
645+
>
642646
{canCreate && (
643647
<ListPageCreate groupVersionKind={resourceKind} createAccessReview={accessReview}>
644648
{t('public~Create Pod')}
@@ -711,4 +715,5 @@ type PodPageProps = {
711715
hideNameLabelFilters?: boolean;
712716
hideColumnManagement?: boolean;
713717
showNamespaceOverride?: boolean;
718+
hideFavoriteButton?: boolean;
714719
};

0 commit comments

Comments
 (0)