Skip to content

Commit

Permalink
Merge pull request #10504 from karthikjeeyar/topology-namelabel-filter
Browse files Browse the repository at this point in the history
Add filter by label in topology
  • Loading branch information
openshift-merge-robot authored Dec 1, 2021
2 parents 48697f9 + 2ef6d41 commit 5a3922f
Show file tree
Hide file tree
Showing 19 changed files with 259 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
useSearchFilter,
SHOW_LABELS_FILTER_ID,
} from '@console/topology/src/filters';
import { getResource } from '@console/topology/src/utils';

type HelmReleaseGroupProps = {
element: Node;
Expand All @@ -47,7 +48,7 @@ const HelmReleaseGroup: React.FC<HelmReleaseGroupProps> = ({
const [{ dragging }, dragNodeRef] = useDragNode(noRegroupDragSourceSpec);
const [{ dragging: labelDragging }, dragLabelRef] = useDragNode(noRegroupDragSourceSpec);
const nodeRefs = useCombineRefs(innerHoverRef, dragNodeRef);
const [filtered] = useSearchFilter(element.getLabel());
const [filtered] = useSearchFilter(element.getLabel(), getResource(element)?.metadata?.labels);
const displayFilters = useDisplayFilters();
const showLabelsFilter = getFilterById(SHOW_LABELS_FILTER_ID, displayFilters);
const showLabels = showLabelsFilter?.value || hover || innerHover;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
noRegroupDragSourceSpec,
} from '@console/topology/src/components/graph-view';
import { useSearchFilter } from '@console/topology/src/filters/useSearchFilter';
import { getResource } from '@console/topology/src/utils';

type HelmReleaseNodeProps = {
element: Node;
Expand All @@ -42,7 +43,7 @@ const HelmReleaseNode: React.FC<HelmReleaseNodeProps> = ({
const [hover, hoverRef] = useHover();
const [{ dragging }, dragNodeRef] = useDragNode(noRegroupDragSourceSpec);
const refs = useCombineRefs<SVGRectElement>(dragNodeRef, dndDropRef, hoverRef);
const [filtered] = useSearchFilter(element.getLabel());
const [filtered] = useSearchFilter(element.getLabel(), getResource(element)?.metadata?.labels);
const { groupResources } = element.getData();
const [groupSize, groupRef] = useSize([groupResources]);
const width = groupSize ? groupSize.width : 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const KnativeServiceGroup: React.FC<KnativeServiceGroupProps> = ({
);
useAnchor(React.useCallback((node: Node) => new RectAnchor(node, 1.5 + EVENT_MARKER_RADIUS), []));

const [filtered] = useSearchFilter(element.getLabel());
const [filtered] = useSearchFilter(element.getLabel(), getResource(element)?.metadata?.labels);
const displayFilters = useDisplayFilters();
const allowEdgeCreation = useAllowEdgeCreation();
const showLabelsFilter = getFilterById(SHOW_LABELS_FILTER_ID, displayFilters);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
GroupNodeAnchor,
} from '@console/topology/src/components/graph-view';
import { useSearchFilter, useAllowEdgeCreation } from '@console/topology/src/filters';
import { getResource } from '@console/topology/src/utils';
import { TYPE_KNATIVE_SERVICE, EVENT_MARKER_RADIUS } from '../../const';

type KnativeServiceNodeProps = {
Expand Down Expand Up @@ -60,7 +61,7 @@ const KnativeServiceNode: React.FC<KnativeServiceNodeProps> = ({
const dragProps = React.useMemo(() => ({ element }), [element]);
const [{ dragging }, dragNodeRef] = useDragNode(dragSpec, dragProps);
const refs = useCombineRefs<SVGRectElement>(hoverRef, dragNodeRef);
const [filtered] = useSearchFilter(element.getLabel());
const [filtered] = useSearchFilter(element.getLabel(), getResource(element)?.metadata?.labels);
const allowEdgeCreation = useAllowEdgeCreation();
const { kind } = element.getData().data;
const { groupResources } = element.getData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ const EventSource: React.FC<EventSourceProps> = ({
const svgAnchorRef = useSvgAnchor();
const [hover, hoverRef] = useHover();
const groupRefs = useCombineRefs(dragNodeRef, dndDropRef, hoverRef);
const [filtered] = useSearchFilter(element.getLabel());
const { data, resources, resource } = element.getData();
const [filtered] = useSearchFilter(element.getLabel(), resource?.metadata?.labels);
const displayFilters = useDisplayFilters();
const showLabelsFilter = getFilterById(SHOW_LABELS_FILTER_ID, displayFilters);
const showLabels = showLabelsFilter?.value || hover;
const { width, height } = element.getBounds();
const size = Math.min(width, height);
const { data, resources } = element.getData();
const allowEdgeCreation = useAllowEdgeCreation();
const isKafkaConnectionLinkPresent =
element.getSourceEdges()?.filter((edge: Edge) => edge.getType() === TYPE_KAFKA_CONNECTION_LINK)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@ const EventingPubSubNode: React.FC<EventingPubSubNodeProps> = ({

const { t } = useTranslation();
const groupRefs = useCombineRefs(dragNodeRef, dndDropRef, hoverRef);
const [filtered] = useSearchFilter(element.getLabel());
const { data, resource } = element.getData();
const [filtered] = useSearchFilter(element.getLabel(), resource?.metadata?.labels);
const displayFilters = useDisplayFilters();
const allowEdgeCreation = useAllowEdgeCreation();
const showLabelsFilter = getFilterById(SHOW_LABELS_FILTER_ID, displayFilters);
const showLabels = showLabelsFilter?.value || hover;
const { width, height } = element.getBounds();
const { data } = element.getData();

const resourceObj = getTopologyResourceObject(element.getData());
const resourceModel =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ const ObservedVmNode: React.FC<VmNodeProps> = ({
const { kind, osImage, vmStatusBundle } = vmData;
const displayFilters = useDisplayFilters();
const allowEdgeCreation = useAllowEdgeCreation();
const [filtered] = useSearchFilter(element.getLabel());
const iconRadius = Math.min(width, height) * 0.25;
const showLabelsFilter = getFilterById(SHOW_LABELS_FILTER_ID, displayFilters);
const showLabels = showLabelsFilter?.value || hover;
const tipContent = `Create a visual connector`;
const resourceObj = getResource(element);
const resourceModel = modelFor(referenceFor(resourceObj));
const [filtered] = useSearchFilter(element.getLabel(), resourceObj?.metadata?.labels);
const editAccess = useAccessReview({
group: resourceModel.apiGroup,
verb: 'patch',
Expand Down
3 changes: 3 additions & 0 deletions frontend/packages/topology/locales/en/topology.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@
"Pod count": "Pod count",
"Labels": "Labels",
"Application groupings": "Application groupings",
"Name": "Name",
"Label": "Label",
"Mode": "Mode",
"Connectivity": "Connectivity",
"Consumption": "Consumption",
Expand All @@ -139,6 +141,7 @@
"Display options": "Display options",
"Clear all filters": "Clear all filters",
"Filter by resource": "Filter by resource",
"Find by label...": "Find by label...",
"Find by name...": "Find by name...",
"Find by name": "Find by name",
"Search results may appear outside of the visible area. <2>Click here</2> to fit to the screen.": "Search results may appear outside of the visible area. <2>Click here</2> to fit to the screen.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const BaseNode: React.FC<BaseNodeProps> = ({
name: resourceObj.metadata.name,
namespace: resourceObj.metadata.namespace,
});
const [filtered] = useSearchFilter(element.getLabel());
const [filtered] = useSearchFilter(element.getLabel(), resourceObj?.metadata?.labels);
const displayFilters = useDisplayFilters();
const showLabelsFilter = getFilterById(SHOW_LABELS_FILTER_ID, displayFilters);
const showLabels = showLabelsFilter?.value || hover;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const TrapezoidBaseNode: React.FC<TrapezoidBaseNodeProps> = ({
name: resourceObj.metadata.name,
namespace: resourceObj.metadata.namespace,
});
const [filtered] = useSearchFilter(element.getLabel());
const [filtered] = useSearchFilter(element.getLabel(), resourceObj?.metadata?.labels);
const displayFilters = useDisplayFilters();
const showLabelsFilter = getFilterById(SHOW_LABELS_FILTER_ID, displayFilters);
const showLabels = showLabelsFilter?.value || hover;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
shouldHideMonitoringAlertDecorator,
} from '@console/shared';
import { useSearchFilter } from '../../filters';
import { getResourceKind } from '../../utils/topology-utils';
import { getResource, getResourceKind } from '../../utils/topology-utils';
import {
AlertsCell,
GroupResourcesCell,
Expand Down Expand Up @@ -68,7 +68,7 @@ const TopologyListViewNode: React.FC<TopologyListViewNodeProps & DispatchProps>
children,
}) => {
const { t } = useTranslation();
const [filtered] = useSearchFilter(item.getLabel());
const [filtered] = useSearchFilter(item.getLabel(), getResource(item)?.metadata?.labels);
if (!item.isVisible) {
return null;
}
Expand Down
13 changes: 10 additions & 3 deletions frontend/packages/topology/src/components/page/TopologyView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ import {
TopologyDecoratorProvider,
TopologyDisplayFilters,
} from '../../extensions/topology';
import { getTopologySearchQuery, useAppliedDisplayFilters, useDisplayFilters } from '../../filters';
import {
getTopologySearchQuery,
TOPOLOGY_LABELS_FILTER_KEY,
TOPOLOGY_SEARCH_FILTER_KEY,
useAppliedDisplayFilters,
useDisplayFilters,
} from '../../filters';
import { FilterContext } from '../../filters/FilterProvider';
import TopologyFilterBar from '../../filters/TopologyFilterBar';
import { setSupportedTopologyFilters, setSupportedTopologyKinds } from '../../redux/action';
Expand Down Expand Up @@ -157,7 +163,8 @@ export const ConnectedTopologyView: React.FC<ComponentProps> = ({
FileUploadContext,
);

const searchParams = queryParams.get('searchQuery');
const searchParams = queryParams.get(TOPOLOGY_SEARCH_FILTER_KEY);
const labelParams = queryParams.get(TOPOLOGY_LABELS_FILTER_KEY);
const fileTypes = supportedFileExtensions.map((ex) => `.${ex}`).toString();

const onSelect = React.useCallback((entity?: GraphElement) => {
Expand Down Expand Up @@ -302,7 +309,7 @@ export const ConnectedTopologyView: React.FC<ComponentProps> = ({
} else {
document.body.classList.remove(FILTER_ACTIVE_CLASS);
}
}, [searchParams]);
}, [searchParams, labelParams]);

const viewContent = React.useMemo(
() =>
Expand Down
90 changes: 90 additions & 0 deletions frontend/packages/topology/src/filters/NameLabelFilterDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import * as React from 'react';
import { Dropdown, DropdownToggle, DropdownItem } from '@patternfly/react-core';
import { CaretDownIcon, FilterIcon } from '@patternfly/react-icons';
import { useTranslation } from 'react-i18next';
import AutocompleteInput from '@console/internal/components/autocomplete';
import { TextFilter } from '@console/internal/components/factory';
import { K8sResourceKind } from '@console/internal/module/k8s';
import { NameLabelFilterValues } from './filter-utils';

type NameLabelFilterDropdownProps = {
isDisabled: boolean;
data: K8sResourceKind[];
onChange: (type: string, value: string, endOfString: boolean) => void;
nameFilterInput: string;
labelFilterInput: string;
};

const NameLabelFilterDropdown: React.FC<NameLabelFilterDropdownProps> = (props) => {
const { data, onChange, nameFilterInput, labelFilterInput, isDisabled } = props;

const [isOpen, setOpen] = React.useState(false);
const [selected, setSelected] = React.useState(NameLabelFilterValues.Name);

const { t } = useTranslation();

const onToggle = (open: boolean) => setOpen(open);
const onSelect = (event: React.SyntheticEvent) => {
setSelected((event.target as HTMLInputElement).name as NameLabelFilterValues);
setOpen(!isOpen);
};
const dropdownItems = [
<DropdownItem key="name-action" name={NameLabelFilterValues.Name} component="button">
{t(NameLabelFilterValues.Name)}
</DropdownItem>,
<DropdownItem key="label-action" name={NameLabelFilterValues.Label} component="button">
{t(NameLabelFilterValues.Label)}
</DropdownItem>,
];

const handleInputValue = (value: string) => {
onChange(selected, value, false);
};

return (
<div className="pf-c-input-group">
<Dropdown
onSelect={onSelect}
toggle={
<DropdownToggle
isDisabled={isDisabled}
id="toggle-id"
onToggle={onToggle}
toggleIndicator={CaretDownIcon}
>
<>
<FilterIcon className="span--icon__right-margin" /> {t(selected)}
</>
</DropdownToggle>
}
isOpen={isOpen}
dropdownItems={dropdownItems}
/>
{selected === NameLabelFilterValues.Label ? (
<AutocompleteInput
onSuggestionSelect={(label) => {
onChange(NameLabelFilterValues.Label, label, true);
}}
showSuggestions
textValue={labelFilterInput}
setTextValue={handleInputValue}
placeholder={t('topology~Find by label...')}
data={data}
className="co-text-node"
labelPath={'metadata.labels'}
/>
) : (
<TextFilter
onChange={handleInputValue}
placeholder={t('topology~Find by name...')}
value={nameFilterInput}
aria-labelledby="toggle-id"
isDisabled={isDisabled}
autoFocus
/>
)}
</div>
);
};

export default NameLabelFilterDropdown;
Loading

0 comments on commit 5a3922f

Please sign in to comment.