-
Notifications
You must be signed in to change notification settings - Fork 594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the component and utility for helm release grouping #3913
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ import { | |
useCombineRefs, | ||
createSvgIdUrl, | ||
} from '@console/topology'; | ||
import { getImageForIconClass } from '@console/internal/components/catalog/catalog-item-icon'; | ||
import SvgResourceIcon from '../topology/components/nodes/ResourceIcon'; | ||
import SvgDropShadowFilter from './SvgDropShadowFilter'; | ||
|
||
|
@@ -20,12 +21,16 @@ export interface SvgBoxedTextProps { | |
kind?: string; | ||
truncate?: number; | ||
dragRef?: WithDndDragProps['dndDragRef']; | ||
icon?: string; | ||
// TODO remove with 2.0 | ||
onMouseEnter?: React.MouseEventHandler<SVGGElement>; | ||
onMouseLeave?: React.MouseEventHandler<SVGGElement>; | ||
} | ||
|
||
const FILTER_ID = 'SvgBoxedTextDropShadowFilterId'; | ||
const iconFilterID = 'SVGBoxedTextRectIconFilter'; | ||
const iconSize = 36; | ||
const iconPadding = 3; | ||
|
||
const truncateEnd = (text: string = '', length: number): string => { | ||
if (text.length <= length) { | ||
|
@@ -50,21 +55,25 @@ const SvgBoxedText: React.FC<SvgBoxedTextProps> = ({ | |
onMouseLeave, | ||
truncate, | ||
dragRef, | ||
icon, | ||
...other | ||
}) => { | ||
const [labelHover, labelHoverRef] = useHover(); | ||
const [textSize, textRef] = useSize([children, className, labelHover]); | ||
const [iconSize, iconRef] = useSize([kind]); | ||
const iconSpace = kind && iconSize ? iconSize.width + paddingX : 0; | ||
const [badgeSize, badgeRef] = useSize([kind]); | ||
const [labelSize, labelRef] = useSize([children, textSize, badgeSize]); | ||
const iconSpace = kind && badgeSize ? badgeSize.width + paddingX : 0; | ||
const labelSizeWidth = icon ? paddingX * 2 + iconSpace + iconSize / 2 : paddingX * 2 + iconSpace; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove the duplicate parts to before the ternary operation. |
||
const refs = useCombineRefs(dragRef, typeof truncate === 'number' ? labelHoverRef : undefined); | ||
return ( | ||
<g className={className} ref={refs}> | ||
<SvgDropShadowFilter id={FILTER_ID} /> | ||
{textSize && ( | ||
<rect | ||
ref={labelRef} | ||
filter={createSvgIdUrl(FILTER_ID)} | ||
x={x - paddingX - textSize.width / 2 - iconSpace / 2} | ||
width={textSize.width + paddingX * 2 + iconSpace} | ||
width={textSize.width + labelSizeWidth} | ||
y={y - paddingY - textSize.height / 2} | ||
height={textSize.height + paddingY * 2} | ||
rx={cornerRadius} | ||
|
@@ -73,12 +82,13 @@ const SvgBoxedText: React.FC<SvgBoxedTextProps> = ({ | |
)} | ||
{textSize && kind && ( | ||
<SvgResourceIcon | ||
ref={iconRef} | ||
ref={badgeRef} | ||
x={x - textSize.width / 2 - paddingX / 2} | ||
y={y} | ||
kind={kind} | ||
/> | ||
)} | ||
|
||
<text | ||
{...other} | ||
ref={textRef} | ||
|
@@ -95,6 +105,28 @@ const SvgBoxedText: React.FC<SvgBoxedTextProps> = ({ | |
: truncateEnd(children, truncate) | ||
: children} | ||
</text> | ||
{icon && textSize && badgeSize && labelSize && ( | ||
<> | ||
<SvgDropShadowFilter id={iconFilterID} /> | ||
<rect | ||
x={x + labelSize.width / 2 + paddingX - iconSize / 2} | ||
y={y} | ||
width={iconSize} | ||
height={iconSize} | ||
fill="#fff" | ||
rx={cornerRadius} | ||
ry={cornerRadius} | ||
filter={createSvgIdUrl(iconFilterID)} | ||
/> | ||
<image | ||
x={x + labelSize.width / 2 + paddingX - iconSize / 2 + iconPadding} | ||
y={y + iconPadding} | ||
width={30} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Iconsize - iconpadding * 2? You seem to be doing a lot computed values but this size remains static even though it is as relative value. |
||
height={30} | ||
xlinkHref={getImageForIconClass(`icon-${icon}`)} | ||
/> | ||
</> | ||
)} | ||
</g> | ||
); | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
.odc-helm-release { | ||
fill: #e2e2e2; | ||
stroke: #bbbbbb; | ||
stroke-width: 4px; | ||
stroke-dasharray: 9; | ||
cursor: pointer; | ||
|
||
&__label { | ||
cursor: pointer; | ||
} | ||
} | ||
|
||
.odc-m-filter-active { | ||
.odc-helm-release { | ||
&__label { | ||
opacity: 0.3; | ||
&.is-filtered { | ||
opacity: 1; | ||
} | ||
} | ||
} | ||
} | ||
|
||
.odc-m-drag-active { | ||
.odc-helm-release { | ||
&__label { | ||
opacity: 0.3; | ||
&.is-dragging { | ||
opacity: 1; | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import * as React from 'react'; | ||
import * as classNames from 'classnames'; | ||
import { connect } from 'react-redux'; | ||
import { | ||
Layer, | ||
useHover, | ||
Node, | ||
createSvgIdUrl, | ||
useDragNode, | ||
observer, | ||
useCombineRefs, | ||
} from '@console/topology'; | ||
import { RootState } from '@console/internal/redux'; | ||
import NodeShadows, { NODE_SHADOW_FILTER_ID_HOVER, NODE_SHADOW_FILTER_ID } from '../NodeShadows'; | ||
import SvgBoxedText from '../../../svg/SvgBoxedText'; | ||
import './HelmRelease.scss'; | ||
import { getTopologyFilters, TopologyFilters } from '../../filters/filter-utils'; | ||
import useFilter from '../../filters/useFilter'; | ||
|
||
export type HelmReleaseProps = { | ||
element: Node; | ||
dragging?: boolean; | ||
filters: TopologyFilters; | ||
}; | ||
|
||
const HelmRelease: React.FC<HelmReleaseProps> = ({ element, dragging, filters }) => { | ||
const [hover, hoverRef] = useHover(); | ||
const { x, y, width, height } = element.getBounds(); | ||
const dragNodeRef = useDragNode()[1]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use deconstructing |
||
const dragLabelRef = useDragNode()[1]; | ||
const refs = useCombineRefs(dragNodeRef, hoverRef); | ||
const filtered = useFilter(filters, { metadata: { name: element.getLabel() } }); | ||
return ( | ||
<g> | ||
<NodeShadows /> | ||
<Layer id={dragging ? undefined : 'groups'}> | ||
<rect | ||
ref={refs} | ||
className="odc-helm-release" | ||
x={x} | ||
y={y} | ||
width={width} | ||
height={height} | ||
rx="5" | ||
ry="5" | ||
filter={createSvgIdUrl( | ||
hover || dragging ? NODE_SHADOW_FILTER_ID_HOVER : NODE_SHADOW_FILTER_ID, | ||
)} | ||
/> | ||
</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> | ||
); | ||
}; | ||
|
||
const HelmReleaseState = (state: RootState) => ({ | ||
filters: getTopologyFilters(state), | ||
}); | ||
|
||
export default connect(HelmReleaseState)(observer(HelmRelease)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a computed value of 30 + padding * 2