Skip to content

Commit

Permalink
Merge pull request #1135 from sgratch/add-provider-ui-details-item
Browse files Browse the repository at this point in the history
🐾 Support a new details item field for the remote provider's web ui
  • Loading branch information
yaacov authored May 13, 2024
2 parents e00a3dd + e52fed5 commit 359204b
Show file tree
Hide file tree
Showing 16 changed files with 238 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"Category": "Category",
"Certificate change detected": "Certificate change detected",
"Clear all filters": "Clear all filters",
"Click the pencil for setting provider web UI link": "Click the pencil for setting provider web UI link",
"Click the update credentials button to save your changes, button is disabled until a change is detected.": "Click the update credentials button to save your changes, button is disabled until a change is detected.",
"Click the update hooks button to save your changes, button is disabled until a change is detected.": "Click the update hooks button to save your changes, button is disabled until a change is detected.",
"Click the update mappings button to save your changes, button is disabled until a change is detected.": "Click the update mappings button to save your changes, button is disabled until a change is detected.",
Expand Down Expand Up @@ -271,6 +272,7 @@
"No secret.": "No secret.",
"No StorageMaps found.": "No StorageMaps found.",
"No storages in this category": "No storages in this category",
"No value for provider web UI link": "No value for provider web UI link",
"Not Ready": "Not Ready",
"NUMA": "NUMA",
"Number of cluster in provider": "Number of cluster in provider",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';

import { Modify, V1beta1Provider } from '@kubev2v/types';
import { K8sModel } from '@openshift-console/dynamic-plugin-sdk/lib/api/core-api';

import { EditModalProps } from '../EditModal';

export type EditProviderUIModalProps = Modify<
EditModalProps,
{
resource: V1beta1Provider;
title?: string;
label?: string;
model?: K8sModel;
jsonPath?: string | string[];
content?: string;
}
>;

export const EditProviderUIModal: React.FC<EditProviderUIModalProps> = (props) => {
switch (props.resource?.spec?.type) {
case 'ovirt':
case 'openshift':
case 'openstack':
case 'vsphere':
default:
return <></>;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @index('./*.tsx', f => `export * from '${f.path}';`)
export * from './EditProviderUIModal';
// @endindex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export * from './components';
export * from './DeleteModal';
export * from './EditModal';
export * from './EditProviderDefaultTransferNetwork';
export * from './EditProviderUI';
export * from './EditProviderURL';
export * from './EditProviderVDDKImage';
export * from './ModalHOC';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon';
import Pencil from '@patternfly/react-icons/dist/esm/icons/pencil-alt-icon';

import { ensureArray } from '../../helpers';

/**
* Component for displaying a details item.
* It can optionally include a help text popover, breadcrumbs, and an edit button.
Expand All @@ -27,37 +29,66 @@ import Pencil from '@patternfly/react-icons/dist/esm/icons/pencil-alt-icon';
*/
export const DetailsItem: React.FC<DetailsItemProps> = ({
title,
content,
helpContent,
showHelpIconNextToTitle,
moreInfoLabel,
moreInfoLink,
crumbs,
content,
onEdit,
}) => {
const contents = ensureArray(content);
const onEdits = ensureArray(onEdit);

return (
<DescriptionListGroup>
{helpContent ? (
<DescriptionTitleWithHelp
title={title}
helpContent={helpContent}
showHelpIconNextToTitle={showHelpIconNextToTitle}
moreInfoLabel={moreInfoLabel}
moreInfoLink={moreInfoLink}
crumbs={crumbs}
/>
) : (
<DescriptionTitle title={title} />
)}
{onEdit ? (
<EditableContentButton content={content} onEdit={onEdit} />
) : (
<NonEditableContent content={content} />
)}
<DisplayTitle
title={title}
helpContent={helpContent}
showHelpIconNextToTitle={showHelpIconNextToTitle}
moreInfoLabel={moreInfoLabel}
moreInfoLink={moreInfoLink}
crumbs={crumbs}
/>
<DescriptionListDescription>
{contents?.map((value, index) => (
<ContentField
key={'content-field-' + index}
content={value}
onEdit={onEdits ? (onEdits[index] as () => void) : null}
/>
))}
</DescriptionListDescription>
</DescriptionListGroup>
);
};

/**
* Component for displaying an item's title
*
* @component
*/
export const DisplayTitle: React.FC<{
title: string;
helpContent: ReactNode;
showHelpIconNextToTitle: boolean;
moreInfoLabel?: string;
moreInfoLink?: string;
crumbs?: string[];
}> = ({ title, helpContent, showHelpIconNextToTitle, moreInfoLabel, moreInfoLink, crumbs }) =>
helpContent ? (
<DescriptionTitleWithHelp
title={title}
helpContent={helpContent}
showHelpIconNextToTitle={showHelpIconNextToTitle}
moreInfoLabel={moreInfoLabel}
moreInfoLink={moreInfoLink}
crumbs={crumbs}
/>
) : (
<DescriptionTitle title={title} />
);

/**
* Component for displaying title with help text in a popover.
*
Expand Down Expand Up @@ -123,7 +154,7 @@ export const DescriptionTitleWithHelp: React.FC<{
);

/**
* Component for displaying title.
* Component for displaying title without a popover.
*
* @component
*/
Expand All @@ -132,55 +163,49 @@ export const DescriptionTitle: React.FC<{ title: string }> = ({ title }) => (
);

/**
* Component for displaying an editable content in the following format:
* The content field's element and next to that appears a press-able inline
* Component for displaying an editable or non editable content field with the following format:
* The content field's element and if editable, next to that appears a press-able inline
* link edit button with the pencil icon, for triggering the onEdit callback.
*
* @component
* @param {ReactNode} content - The field's content element.
* @param {Function} onEdit - Function to be called when the button is clicked.
*/
export const EditableContentButton: React.FC<{

export const ContentField: React.FC<{
content: ReactNode;
onEdit: () => void;
}> = ({ content, onEdit }) => (
<DescriptionListDescription>
{content}
<Button variant="link" isInline onClick={onEdit}>
<Pencil className="forklift-page-details-edit-pencil" />
</Button>
</DescriptionListDescription>
);

/**
* Component for displaying a non-editable content.
*
* @component
* @param {ReactNode} content - The content of the description.
*/
export const NonEditableContent: React.FC<{ content: ReactNode }> = ({ content }) => (
<DescriptionListDescription>{content}</DescriptionListDescription>
);
}> = ({ content, onEdit }) =>
onEdit ? (
<DescriptionListDescription>
{content}
<Button variant="link" isInline onClick={onEdit}>
<Pencil className="forklift-page-details-edit-pencil" />
</Button>
</DescriptionListDescription>
) : (
<DescriptionListDescription>{content}</DescriptionListDescription>
);

/**
* Type for the props of the DetailsItem component.
*
* @typedef {Object} DetailsItemProps
* @property {string} title - The title of the details item.
* @property {ReactNode} content - The content of the details item.
* @property {ReactNode} [helpContent] - The content to display in the help popover.
* @property {ReactNode} [showHelpIconNextToTitle] - if true, adding a help icon next to the title for displaying the help popover.
* If false, show the default Patternfly dashed line under the title.
* @property {string[]} [crumbs] - Breadcrumbs for the details item.
* @property {Function} [onEdit] - Function to be called when the edit button is clicked.
* @property {ReactNode | ReactNode[]} content - Array of content fields to be displayed for the details item.
* @property {Function | Function[]} onEdit - Array of functions per content field to be called when the edit button is clicked or null if the field is non editable.
*/
export type DetailsItemProps = {
title: string;
content: ReactNode;
helpContent?: ReactNode;
showHelpIconNextToTitle?: boolean;
moreInfoLabel?: string;
moreInfoLink?: string;
crumbs?: string[];
onEdit?: () => void;
content: ReactNode | ReactNode[];
onEdit?: (() => void) | (() => void)[];
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Function to ensure that the input node is always an array.
*/
export const ensureArray = (node: unknown | unknown[]): unknown[] => {
if (Array.isArray(node)) {
return node;
} else {
return [node]; // Wrap the single ReactNode in an array
}
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// @index(['./*.tsx', './*.ts', /__/g], f => `export * from '${f.path}';`)
export * from './ensureArray';
export * from './findInventoryByID';
export * from './getApiUrl';
export * from './getCachedData';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { DetailsItem } from '../../../../utils';

import {
CreatedAtDetailsItem,
NameDetailsItem,
NameAndUiLinkDetailsItem,
NamespaceDetailsItem,
OwnerDetailsItem,
TypeDetailsItem,
Expand All @@ -30,7 +30,7 @@ export const OVADetailsSection: React.FC<DetailsSectionProps> = ({ data }) => {

<DetailsItem title={''} content={''} />

<NameDetailsItem resource={provider} />
<NameAndUiLinkDetailsItem resource={provider} />

<NamespaceDetailsItem resource={provider} />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { DetailsItem } from '../../../../utils';
import {
CreatedAtDetailsItem,
CredentialsDetailsItem,
NameDetailsItem,
NameAndUiLinkDetailsItem,
NamespaceDetailsItem,
OwnerDetailsItem,
TransferNetworkDetailsItem,
Expand All @@ -32,7 +32,7 @@ export const OpenshiftDetailsSection: React.FC<DetailsSectionProps> = ({ data })

<DetailsItem title={''} content={''} />

<NameDetailsItem resource={provider} />
<NameAndUiLinkDetailsItem resource={provider} />

<NamespaceDetailsItem resource={provider} />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { DetailsItem } from '../../../../utils';
import {
CreatedAtDetailsItem,
CredentialsDetailsItem,
NameDetailsItem,
NameAndUiLinkDetailsItem,
NamespaceDetailsItem,
OwnerDetailsItem,
TypeDetailsItem,
Expand All @@ -29,7 +29,7 @@ export const OpenstackDetailsSection: React.FC<DetailsSectionProps> = ({ data })

<DetailsItem title={''} content={''} />

<NameDetailsItem resource={provider} />
<NameAndUiLinkDetailsItem resource={provider} />

<NamespaceDetailsItem resource={provider} />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { DetailsItem } from '../../../../utils';
import {
CreatedAtDetailsItem,
CredentialsDetailsItem,
NameDetailsItem,
NameAndUiLinkDetailsItem,
NamespaceDetailsItem,
OwnerDetailsItem,
TypeDetailsItem,
Expand All @@ -31,7 +31,7 @@ export const OvirtDetailsSection: React.FC<DetailsSectionProps> = ({ data }) =>

<DetailsItem title={''} content={''} />

<NameDetailsItem resource={provider} />
<NameAndUiLinkDetailsItem resource={provider} />

<NamespaceDetailsItem resource={provider} />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { DetailsItem } from '../../../../utils';
import {
CreatedAtDetailsItem,
CredentialsDetailsItem,
NameDetailsItem,
NameAndUiLinkDetailsItem,
NamespaceDetailsItem,
OwnerDetailsItem,
TypeDetailsItem,
Expand Down Expand Up @@ -37,7 +37,7 @@ export const VSphereDetailsSection: React.FC<DetailsSectionProps> = ({ data }) =
crumbs={['Inventory', 'providers', `${provider.spec.type}`, '[UID]']}
/>

<NameDetailsItem resource={provider} />
<NameAndUiLinkDetailsItem resource={provider} />

<NamespaceDetailsItem resource={provider} />

Expand Down
Loading

0 comments on commit 359204b

Please sign in to comment.