Skip to content

Commit

Permalink
[WIP] NNS topology
Browse files Browse the repository at this point in the history
Signed-off-by: Aviv Turgeman <[email protected]>
  • Loading branch information
avivtur committed Aug 14, 2024
1 parent 266315a commit 776d386
Show file tree
Hide file tree
Showing 24 changed files with 1,559 additions and 45 deletions.
10 changes: 10 additions & 0 deletions locales/en/plugin__nmstate-console-plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"{{annotationsCount}} Annotations": "{{annotationsCount}} Annotations",
"{{matchingNodeText}} matching": "{{matchingNodeText}} matching",
"{{modelName}} details": "{{modelName}} details",
"{{qualifiedNodesCount}} matching Nodes found": "{{qualifiedNodesCount}} matching Nodes found",
"<0>List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.</0><1><0>{{kind}}</0><1>metadata</1><2>ownerReferences</2></1>": "<0>List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.</0><1><0>{{kind}}</0><1>metadata</1><2>ownerReferences</2></1>",
"Aborted": "Aborted",
"Actions": "Actions",
"Add another interface to the policy": "Add another interface to the policy",
Expand All @@ -10,6 +12,7 @@
"Add Option": "Add Option",
"Aggregation mode": "Aggregation mode",
"An error occurred": "An error occurred",
"Annotations": "Annotations",
"Apply this NodeNetworkConfigurationPolicy only to specific subsets of nodes using the node selector": "Apply this NodeNetworkConfigurationPolicy only to specific subsets of nodes using the node selector",
"Are you sure you want to remove {{interfaceType}} interface <5>{{name}}</5>?": "Are you sure you want to remove {{interfaceType}} interface <5>{{name}}</5>?",
"Auto-DNS": "Auto-DNS",
Expand All @@ -30,6 +33,7 @@
"Create": "Create",
"Create NodeNetworkConfigurationPolicy": "Create NodeNetworkConfigurationPolicy",
"Create NodeNetworkConfigurationPolicy error": "Create NodeNetworkConfigurationPolicy error",
"Created at": "Created at",
"Created interfaces cannot be removed": "Created interfaces cannot be removed",
"Delete": "Delete",
"Delete NodeNetworkConfigurationPolicy?": "Delete NodeNetworkConfigurationPolicy?",
Expand Down Expand Up @@ -73,6 +77,7 @@
"IPV4 address": "IPV4 address",
"IPv6": "IPv6",
"Key": "Key",
"Labels": "Labels",
"Learn more": "Learn more",
"List of network interfaces that should be created, modified, or removed, as a part of this policy.": "List of network interfaces that should be created, modified, or removed, as a part of this policy.",
"LLDP": "LLDP",
Expand All @@ -82,6 +87,7 @@
"MAC Address": "MAC Address",
"Matched nodes": "Matched nodes",
"Matched nodes summary": "Matched nodes summary",
"More info: ": "More info: ",
"MTU": "MTU",
"Name": "Name",
"Neighbors": "Neighbors",
Expand All @@ -92,6 +98,8 @@
"No node network configuration policies defined yet": "No node network configuration policies defined yet",
"No NodeNetworkStates found": "No NodeNetworkStates found",
"Node network is configured and managed by NM state. Create a node network configuration policy to describe the requested network configuration on your nodes in the cluster. The node network configuration enactment reports the netwrok policies enacted upon each node.": "Node network is configured and managed by NM state. Create a node netowrk configuration policy to describe the requested network configuration on your nodes in the cluster. The node network configuration enactment reports the netwrok policies enacted upon each node.",
"No owner": "No owner",
"Node network is configured and managed by NM state. Create a node netowrk configuration policy to describe the requested network configuration on your nodes in the cluster. The node network configuration enactment reports the netwrok policies enacted upon each node.": "Node network is configured and managed by NM state. Create a node netowrk configuration policy to describe the requested network configuration on your nodes in the cluster. The node network configuration enactment reports the netwrok policies enacted upon each node.",
"Node Selector": "Node Selector",
"NodeNetworkConfigurationPolicy": "NodeNetworkConfigurationPolicy",
"NodeNetworkState": "NodeNetworkState",
Expand All @@ -100,6 +108,8 @@
"Open vSwitch bridge mapping": "Open vSwitch bridge mapping",
"OVN localnet name": "OVN localnet name",
"OVS bridge name": "OVS bridge name",
"Not available": "Not available",
"Owner": "Owner",
"Pending": "Pending",
"Please <2>try again</2>.": "Please <2>try again</2>.",
"Policy details": "Policy details",
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
"@patternfly/react-icons": "^5.1.1",
"@patternfly/react-core": "5.1.1",
"@patternfly/react-table": "^5.1.1",
"@patternfly/react-icons": "5.2.1",
"@patternfly/react-topology": "5.2.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^12.0.0",
"@testing-library/react-hooks": "^8.0.1",
Expand Down
4 changes: 1 addition & 3 deletions src/console-models/NodeNetworkStateModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { K8sModel } from '@openshift-console/dynamic-plugin-sdk/lib/api/common-t

import { modelToGroupVersionKind, modelToRef } from './modelUtils';

const NodeNetworkStateModel: K8sModel = {
export const NodeNetworkStateModel: K8sModel = {
label: 'NodeNetworkState',
labelPlural: 'NodeNetworkStates',
apiVersion: 'v1beta1',
Expand All @@ -17,5 +17,3 @@ const NodeNetworkStateModel: K8sModel = {

export const NodeNetworkStateModelGroupVersionKind = modelToGroupVersionKind(NodeNetworkStateModel);
export const NodeNetworkStateModelRef = modelToRef(NodeNetworkStateModel);

export default NodeNetworkStateModel;
17 changes: 17 additions & 0 deletions src/utils/components/DetailItem/DetailItem.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.description-item__title {
justify-content: space-between;
flex: 1;
}

.margin-top {
margin-top: var(--pf-v5-global--spacer--md);
}

.DescriptionItemHeader {
&--list-term {
.pf-c-description-list__text {
align-items: center;
display: inline-flex;
}
}
}
116 changes: 116 additions & 0 deletions src/utils/components/DetailItem/DetailItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import React, { FC, ReactNode } from 'react';

import {
Button,
DescriptionListDescription,
DescriptionListGroup,
DescriptionListTermHelpText,
Flex,
FlexItem,
} from '@patternfly/react-core';
import { PencilAltIcon } from '@patternfly/react-icons';
import { useNMStateTranslation } from '@utils/hooks/useNMStateTranslation';

import { DetailItemHeader } from './DetailItemHeader';
import EditButtonWithTooltip from './EditButtonWithTooltip';

import './DetailItem.scss';

type DetailItemProps = {
bodyContent?: ReactNode;
breadcrumb?: string;
className?: string;
'data-test-id'?: string;
descriptionData: any;

Check warning on line 24 in src/utils/components/DetailItem/DetailItem.tsx

View workflow job for this annotation

GitHub Actions / Run linter and tests

Unexpected any. Specify a different type
descriptionHeader?: ReactNode;
editOnTitleJustify?: boolean;
isDisabled?: boolean;
isEdit?: boolean;
isPopover?: boolean;
label?: ReactNode;
messageOnDisabled?: string;
moreInfoURL?: string;
onEditClick?: () => void;
showEditOnTitle?: boolean;
};

const DetailItem: FC<DetailItemProps> = ({
bodyContent,
breadcrumb,
className,
'data-test-id': testId,
descriptionData,
descriptionHeader,
editOnTitleJustify = false,
isDisabled,
isEdit,
isPopover,
label,
messageOnDisabled,
moreInfoURL,
onEditClick,
showEditOnTitle,
}) => {
const { t } = useNMStateTranslation();
const NotAvailable = <span className="text-muted">{t('Not available')}</span>;

const description = (
<EditButtonWithTooltip
isEditable={!isDisabled}
onEditClick={onEditClick}
testId={testId}
tooltipContent={messageOnDisabled}
>
{descriptionData ?? NotAvailable}
</EditButtonWithTooltip>
);

return (
<DescriptionListGroup className={`pf-c-description-list__group ${className && className}`}>
<DescriptionListTermHelpText className="pf-c-description-list__term">
<Flex
justifyContent={{
default: editOnTitleJustify ? 'justifyContentSpaceBetween' : 'justifyContentFlexStart',
}}
>
{(bodyContent || breadcrumb || descriptionHeader || label || moreInfoURL) && (
<FlexItem>
<DetailItemHeader
bodyContent={bodyContent}
breadcrumb={breadcrumb}
descriptionHeader={descriptionHeader}
isPopover={isPopover}
label={label}
moreInfoURL={moreInfoURL}
/>
</FlexItem>
)}
{isEdit && showEditOnTitle && (
<FlexItem>
<Button
data-test-id={`${testId}-edit`}
isDisabled={isDisabled}
isInline
onClick={onEditClick}
type="button"
variant="link"
>
{t('Edit')}
<PencilAltIcon className="co-icon-space-l pf-v5-c-button-icon--plain" />
</Button>
</FlexItem>
)}
</Flex>
</DescriptionListTermHelpText>

<DescriptionListDescription
className="pf-c-description-list__description"
data-test-id={testId}
>
{isEdit && !showEditOnTitle ? description : descriptionData}
</DescriptionListDescription>
</DescriptionListGroup>
);
};

export default DetailItem;
74 changes: 74 additions & 0 deletions src/utils/components/DetailItem/DetailItemHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { FC, ReactNode } from 'react';

import {
Breadcrumb,
BreadcrumbItem,
DescriptionListTerm,
DescriptionListTermHelpTextButton,
Popover,
} from '@patternfly/react-core';
import { useNMStateTranslation } from '@utils/hooks/useNMStateTranslation';

import './DetailItem.scss';

type DetailItemHeaderProps = {
bodyContent: ReactNode;
breadcrumb?: string;
descriptionHeader: ReactNode;
isPopover: boolean;
label?: ReactNode;
maxWidth?: string;
moreInfoURL?: string;
};

export const DetailItemHeader: FC<DetailItemHeaderProps> = ({
bodyContent,
breadcrumb,
descriptionHeader,
isPopover,
label,
maxWidth,
moreInfoURL,
}) => {
const { t } = useNMStateTranslation();

if (isPopover && bodyContent) {
return (
<Popover
bodyContent={
<>
{bodyContent}
{moreInfoURL && (
<>
{t('More info: ')}
<a href={moreInfoURL}>{moreInfoURL}</a>
</>
)}
{breadcrumb && (
<div className="margin-top">
<Breadcrumb>
{breadcrumb.split('.').map((item) => (
<BreadcrumbItem key={item}>{item}</BreadcrumbItem>
))}
</Breadcrumb>
</div>
)}
</>
}
hasAutoWidth
headerContent={descriptionHeader}
maxWidth={maxWidth || '30rem'}
>
<DescriptionListTermHelpTextButton className="pf-c-description-list__text">
{descriptionHeader}
</DescriptionListTermHelpTextButton>
</Popover>
);
}

return (
<DescriptionListTerm className="DescriptionItemHeader--list-term">
{descriptionHeader} {label}
</DescriptionListTerm>
);
};
51 changes: 51 additions & 0 deletions src/utils/components/DetailItem/EditButtonWithTooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React, { FC, PropsWithChildren, ReactNode, SyntheticEvent } from 'react';

import { Button, Flex, Tooltip } from '@patternfly/react-core';
import { PencilAltIcon } from '@patternfly/react-icons';

type EditButtonWithTooltipProps = PropsWithChildren<{
isEditable: boolean;
onEditClick: () => void;
testId: string;
tooltipContent?: ReactNode;
}>;

const EditButtonWithTooltip: FC<EditButtonWithTooltipProps> = ({
children,
isEditable,
onEditClick,
testId,
tooltipContent,
}) => {
const EditButton = () => (
<Button
onClick={(e: SyntheticEvent<HTMLButtonElement>) => {
e.stopPropagation();
onEditClick?.();
}}
data-test-id={testId}
isDisabled={!isEditable}
isInline
variant="link"
>
<Flex>
{children}
<PencilAltIcon className="co-icon-space-l" />
</Flex>
</Button>
);

if (!isEditable && tooltipContent) {
return (
<Tooltip content={tooltipContent}>
<span>
<EditButton />
</span>
</Tooltip>
);
}

return <EditButton />;
};

export default EditButtonWithTooltip;
Loading

0 comments on commit 776d386

Please sign in to comment.