Skip to content

Commit

Permalink
Topology: Add Helm Release selection and details side panel
Browse files Browse the repository at this point in the history
  • Loading branch information
jeff-phillips-18 committed Jan 24, 2020
1 parent 3e08b3b commit ff6fbcf
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 21 deletions.
Expand Up @@ -26,8 +26,9 @@ import TopologyApplicationPanel from './application-panel/TopologyApplicationPan
import { topologyModelFromDataModel } from './topology-utils';
import { layoutFactory, COLA_LAYOUT, COLA_FORCE_LAYOUT } from './layouts/layoutFactory';
import ComponentFactory from './componentFactory';
import { TYPE_APPLICATION_GROUP } from './const';
import { TYPE_APPLICATION_GROUP, TYPE_HELM_RELEASE } from './const';
import TopologyFilterBar from './filters/TopologyFilterBar';
import TopologyHelmReleasePanel from './TopologyHelmReleasePanel';

export interface TopologyProps {
data: TopologyDataModel;
Expand Down Expand Up @@ -188,6 +189,9 @@ const Topology: React.FC<TopologyProps> = ({ data, serviceBinding }) => {
/>
);
}
if (selectedEntity.getType() === TYPE_HELM_RELEASE) {
return <TopologyHelmReleasePanel helmRelease={selectedEntity} />;
}
return <TopologyResourcePanel item={selectedEntity.getData() as TopologyDataObject} />;
}

Expand Down
@@ -0,0 +1,129 @@
import * as React from 'react';
import { Link } from 'react-router-dom';
import * as _ from 'lodash';
import {
Firehose,
FirehoseResult,
LoadingBox,
StatusBox,
navFactory,
ResourceIcon,
SimpleTabNav,
FirehoseResource,
} from '@console/internal/components/utils';
import { SecretModel } from '@console/internal/models';
import { K8sResourceCommon } from '@console/internal/module/k8s';
import { Node } from '@console/topology';
import HelmReleaseOverview from '../helm/HelmReleaseOverview';

export type TopologyHelmReleasePanelObjProps = {
obj?: FirehoseResult<K8sResourceCommon>;
};

export type TopologyHelmReleasePanelSecretsProps = {
secrets?: FirehoseResult<K8sResourceCommon[]>;
helmReleaseName: string;
};

export type TopologyHelmReleasePanelProps = {
helmRelease: Node;
};

const TopologyHelmReleasePanelObj: React.FC<TopologyHelmReleasePanelObjProps> = ({ obj }) => {
if (!obj || (!obj.loaded && _.isEmpty(obj.loadError))) {
return <LoadingBox />;
}

if (obj.loadError) {
return <StatusBox loaded={obj.loaded} loadError={obj.loadError} />;
}

const name = obj.data?.metadata.labels?.name;
const namespace = obj.data?.metadata.namespace;

return (
<div className="overview__sidebar-pane resource-overview">
<div className="overview__sidebar-pane-head resource-overview__heading">
<h1 className="co-m-pane__heading">
<div className="co-m-pane__name co-resource-item">
<ResourceIcon className="co-m-resource-icon--lg" kind="HelmRelease" />
<Link
to={`/helm-releases/ns/${namespace}/release/${name}`}
className="co-resource-item__resource-name"
>
{name}
</Link>
</div>
</h1>
</div>
<SimpleTabNav
selectedTab={'Details'}
tabs={[{ name: 'Details', component: navFactory.details(HelmReleaseOverview).component }]}
tabProps={{ obj: obj.data }}
additionalClassNames="co-m-horizontal-nav__menu--within-sidebar co-m-horizontal-nav__menu--within-overview-sidebar"
/>
</div>
);
};

const TopologyHelmReleasePanelSecrets: React.FC<TopologyHelmReleasePanelSecretsProps> = ({
secrets,
helmReleaseName,
}) => {
if (!secrets || (!secrets.loaded && _.isEmpty(secrets.loadError))) {
return <LoadingBox />;
}

if (secrets.loadError) {
return <StatusBox loaded={secrets.loaded} loadError={secrets.loadError} />;
}

const secretResource = secrets.data[0];
if (!secretResource) {
return (
<StatusBox
loaded={secrets.loaded}
loadError={{ message: `Unable to find resource for ${helmReleaseName}` }}
/>
);
}

return (
<Firehose
resources={[
{
kind: SecretModel.kind,
kindObj: SecretModel,
name: secretResource.metadata.name,
namespace: secretResource.metadata.namespace,
isList: false,
prop: 'obj',
} as FirehoseResource,
]}
>
<TopologyHelmReleasePanelObj />
</Firehose>
);
};

const TopologyHelmReleasePanel: React.FC<TopologyHelmReleasePanelProps> = ({ helmRelease }) => {
const { namespace } = helmRelease.getChildren()[0].getData().resources.obj.metadata;
const helmReleaseName = helmRelease.getLabel();
return (
<Firehose
resources={[
{
kind: SecretModel.kind,
namespace,
isList: true,
selector: { name: `${helmReleaseName}` },
prop: 'secrets',
},
]}
>
<TopologyHelmReleasePanelSecrets helmReleaseName={helmReleaseName} />
</Firehose>
);
};

export default TopologyHelmReleasePanel;
Expand Up @@ -78,7 +78,7 @@ class ComponentFactory {
return (kind, type): ComponentType<{ element: GraphElement }> | undefined => {
switch (type) {
case TYPE_HELM_RELEASE:
return HelmRelease;
return withSelection(false, true)(HelmRelease);
case TYPE_HELM_WORKLOAD:
return withCreateConnector(createConnectorCallback(this.hasServiceBinding))(
withDndDrop<
Expand Down
Expand Up @@ -8,6 +8,10 @@
&__label {
cursor: pointer;
}
&.is-selected {
stroke: var(--pf-global--active-color--100);
fill: var(--pf-global--active-color--200);
}
}

.odc-m-filter-active {
Expand Down
Expand Up @@ -9,6 +9,7 @@ import {
useDragNode,
observer,
useCombineRefs,
WithSelectionProps,
} from '@console/topology';
import { RootState } from '@console/internal/redux';
import NodeShadows, { NODE_SHADOW_FILTER_ID_HOVER, NODE_SHADOW_FILTER_ID } from '../NodeShadows';
Expand All @@ -21,22 +22,35 @@ export type HelmReleaseProps = {
element: Node;
dragging?: boolean;
filters: TopologyFilters;
};
} & WithSelectionProps;

const HelmRelease: React.FC<HelmReleaseProps> = ({ element, dragging, filters }) => {
const HelmRelease: React.FC<HelmReleaseProps> = ({
element,
dragging,
filters,
onSelect,
selected,
}) => {
const [hover, hoverRef] = useHover();
const { x, y, width, height } = element.getBounds();
const dragNodeRef = useDragNode()[1];
const dragLabelRef = useDragNode()[1];
const refs = useCombineRefs(dragNodeRef, hoverRef);
const filtered = useFilter(filters, { metadata: { name: element.getLabel() } });

const rectClasses = classNames('odc-helm-release', {
'is-selected': selected,
'is-hover': hover,
'is-filtered': filtered,
});
return (
<g>
<NodeShadows />
<Layer id={dragging ? undefined : 'groups'}>
<rect
ref={refs}
className="odc-helm-release"
className={rectClasses}
onClick={onSelect}
x={x}
y={y}
width={width}
Expand All @@ -49,22 +63,24 @@ const HelmRelease: React.FC<HelmReleaseProps> = ({ element, dragging, filters })
/>
</Layer>
{element.getLabel() && (
<SvgBoxedText
className={classNames('odc-base-node__label', 'odc-helm-release__label', {
'is-filtered': filtered,
'is-dragging': dragging,
})}
x={x + width / 2}
y={y + height + 20}
paddingX={8}
paddingY={4}
kind="HelmRelease"
truncate={16}
dragRef={dragLabelRef}
icon="helm"
>
{element.getLabel()}
</SvgBoxedText>
<g onClick={onSelect}>
<SvgBoxedText
className={classNames('odc-base-node__label', 'odc-helm-release__label', {
'is-filtered': filtered,
'is-dragging': dragging,
})}
x={x + width / 2}
y={y + height + 20}
paddingX={8}
paddingY={4}
kind="HelmRelease"
truncate={16}
dragRef={dragLabelRef}
icon="helm"
>
{element.getLabel()}
</SvgBoxedText>
</g>
)}
</g>
);
Expand Down

0 comments on commit ff6fbcf

Please sign in to comment.