-
Notifications
You must be signed in to change notification settings - Fork 596
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13240 from TheRealJon/CONSOLE-3695
CONSOLE-3695: Add details item extension to console dynamic plugin SDK
- Loading branch information
Showing
15 changed files
with
289 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
frontend/packages/console-dynamic-plugin-sdk/src/extensions/details-item.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { ExtensionK8sModel } from '../api/common-types'; | ||
import { Extension, ExtensionDeclaration, CodeRef } from '../types'; | ||
import { K8sResourceCommon } from './console-types'; | ||
|
||
export type DetailsItemColumn = 'right' | 'left'; | ||
|
||
export type DetailsItemComponentProps<R extends K8sResourceCommon = K8sResourceCommon, V = any> = { | ||
/** The subject resource */ | ||
obj: R; | ||
|
||
/** The path property provided by the extension */ | ||
path?: string; | ||
|
||
/** The property of obj referenced by path */ | ||
value?: V; | ||
}; | ||
|
||
/** Adds a new details item to the default resource summary on the details page. */ | ||
export type DetailsItem = ExtensionDeclaration< | ||
'console.resource/details-item', | ||
{ | ||
/** The subject resource's API group, version, and kind. */ | ||
model: ExtensionK8sModel; | ||
|
||
/** A unique identifier. */ | ||
id: string; | ||
|
||
/** | ||
* Determines if the item will appear in the 'left' or 'right' column of the resource summary on | ||
* the details page. Default: 'right' | ||
*/ | ||
column: DetailsItemColumn; | ||
|
||
/** The details item title. */ | ||
title: string; | ||
|
||
/** | ||
* An optional, fully-qualified path to a resource property to used as the details item | ||
* value. Only [primitive type](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) | ||
* values can be rendered directly. Use the component property to handle other data types. | ||
*/ | ||
path?: string; | ||
|
||
/** | ||
* An optional React component that will render the details item value. | ||
*/ | ||
component?: CodeRef<React.ComponentType<DetailsItemComponentProps>>; | ||
|
||
/** | ||
* An optional sort weight, relative to all other details items in the same column. Represented | ||
* by any valid [JavaScript | ||
* Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type). | ||
* Items in each column are sorted independently, lowest to highest. Items without sort weights | ||
* are sorted after items with sort weights. | ||
*/ | ||
sortWeight?: number; | ||
} | ||
>; | ||
|
||
export const isDetailsItem = (e: Extension): e is DetailsItem => | ||
e.type === 'console.resource/details-item'; | ||
|
||
export const isLeftDetailsItem = (e: DetailsItem): e is DetailsItem => | ||
isDetailsItem(e) && e.properties.column === 'left'; | ||
|
||
export const isRightDetailsItem = (e: DetailsItem): e is DetailsItem => | ||
isDetailsItem(e) && e.properties.column === 'right'; |
27 changes: 14 additions & 13 deletions
27
frontend/packages/console-dynamic-plugin-sdk/src/extensions/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,33 @@ | ||
export * from './actions'; | ||
export * from './add-actions'; | ||
export * from './alerts'; | ||
export * from './breadcrumbs'; | ||
export * from './catalog'; | ||
export * from './cluster-configuration'; | ||
export * from './cluster-overview'; | ||
export * from './cluster-settings'; | ||
export * from './console-types'; | ||
export * from './context-providers'; | ||
export * from './create-resource'; | ||
export * from './dashboard-types'; | ||
export * from './dashboards'; | ||
export * from './details-item'; | ||
export * from './feature-flags'; | ||
export * from './file-upload'; | ||
export * from './horizontal-nav-tabs'; | ||
export * from './import-environments'; | ||
export * from './navigation'; | ||
export * from './notification-alert'; | ||
export * from './pages'; | ||
export * from './perspectives'; | ||
export * from './project-overview'; | ||
export * from './pvc'; | ||
export * from './redux'; | ||
export * from './resource-metadata'; | ||
export * from './telemetry'; | ||
export * from './yaml-templates'; | ||
export * from './notification-alert'; | ||
export * from './console-types'; | ||
export * from './storage-class-provisioner'; | ||
export * from './storage-provider'; | ||
export * from './actions'; | ||
export * from './telemetry'; | ||
export * from './topology-details'; | ||
export * from './topology'; | ||
export * from './create-resource'; | ||
export * from './user-preferences'; | ||
export * from './horizontal-nav-tabs'; | ||
export * from './import-environments'; | ||
export * from './cluster-overview'; | ||
export * from './project-overview'; | ||
export * from './dashboard-types'; | ||
export * from './breadcrumbs'; | ||
export * from './storage-class-provisioner'; | ||
export * from './yaml-templates'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
frontend/packages/console-shared/src/components/details-page/ExtensionDetailsItem.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import * as React from 'react'; | ||
import * as _ from 'lodash'; | ||
import { K8sResourceCommon } from '@console/dynamic-plugin-sdk/src/extensions/console-types'; | ||
import { DetailsItem as DetailsItemExtension } from '@console/dynamic-plugin-sdk/src/extensions/details-item'; | ||
import { ResolvedExtension } from '@console/dynamic-plugin-sdk/src/types'; | ||
import { DetailsItem } from '@console/internal/components/utils/details-item'; | ||
|
||
export const ExtensionDetailsItem: ExtensionDetailsItemComponent = ({ extension, obj }) => { | ||
const { path, title, component: Component, id } = extension.properties; | ||
const sortWeight = extension.properties.sortWeight ?? 'none'; | ||
const value = _.get(obj, path); | ||
if (!Component && typeof value === 'object') { | ||
// eslint-disable-next-line no-console | ||
console.warn( | ||
`Invalid 'console.resource/details-item' extension: '${id}'. The value referenced at path '${path}' must be primitive if not accompanied by a custom component.`, | ||
); | ||
} | ||
const content = Component ? ( | ||
<Component obj={obj} path={path} value={value} /> | ||
) : ( | ||
(value ?? '-').toString() | ||
); | ||
|
||
return ( | ||
<DetailsItem | ||
obj={obj} | ||
path={path} | ||
label={title} | ||
labelClassName={`details-item__sort-weight-${sortWeight}`} // for visibility | ||
> | ||
{content} | ||
</DetailsItem> | ||
); | ||
}; | ||
|
||
type ExtensionDetailsItemProps = { | ||
obj: K8sResourceCommon; | ||
extension: ResolvedExtension<DetailsItemExtension>; | ||
}; | ||
type ExtensionDetailsItemComponent = (props: ExtensionDetailsItemProps) => React.ReactElement; |
54 changes: 54 additions & 0 deletions
54
frontend/packages/console-shared/src/hooks/useDetailsItemExtensionsForResource.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import * as React from 'react'; | ||
import { useResolvedExtensions } from '@console/dynamic-plugin-sdk/src/api/useResolvedExtensions'; | ||
import { K8sResourceCommon } from '@console/dynamic-plugin-sdk/src/extensions/console-types'; | ||
import { | ||
isDetailsItem, | ||
DetailsItem, | ||
DetailsItemColumn, | ||
} from '@console/dynamic-plugin-sdk/src/extensions/details-item'; | ||
import { ResolvedExtension, ExtensionTypeGuard } from '@console/dynamic-plugin-sdk/src/types'; | ||
import { referenceFor, referenceForExtensionModel } from '@console/internal/module/k8s/k8s'; | ||
|
||
/** | ||
* A hook to retrieve sorted details item extensions for a given resource and column. | ||
* | ||
* @param obj The k8s resource for which details are being rendered. | ||
* @param column The column in which the details item will be rendered. | ||
* @returns A sorted list of details item extensions for the given resource and column. Null safe. | ||
*/ | ||
export const useDetailsItemExtensionsForResource: UseDetailsItemExtensionsForResource = ( | ||
obj, | ||
column, | ||
) => { | ||
const typeGuard = React.useCallback<ExtensionTypeGuard<DetailsItem>>( | ||
(e): e is DetailsItem => { | ||
const columnMatches = e.properties.column === column; | ||
const modelMatches = referenceFor(obj) === referenceForExtensionModel(e.properties.model); | ||
return isDetailsItem(e) && modelMatches && columnMatches; | ||
}, | ||
[obj, column], | ||
); | ||
|
||
const [extensions] = useResolvedExtensions<DetailsItem>(typeGuard); | ||
|
||
return React.useMemo( | ||
() => | ||
(extensions ?? []).sort((a, b) => { | ||
const aWeight = Number(a.properties.sortWeight); | ||
const bWeight = Number(b.properties.sortWeight); | ||
if (Number.isNaN(aWeight)) { | ||
return 1; | ||
} | ||
if (Number.isNaN(bWeight)) { | ||
return -1; | ||
} | ||
return aWeight - bWeight; | ||
}), | ||
[extensions], | ||
); | ||
}; | ||
|
||
type UseDetailsItemExtensionsForResource = ( | ||
obj: K8sResourceCommon, | ||
column: DetailsItemColumn, | ||
) => ResolvedExtension<DetailsItem>[]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.