Skip to content
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

Dark theme support #152

Merged
merged 1 commit into from
Jun 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
253 changes: 158 additions & 95 deletions web/package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
"fix-imports": "eslint --no-eslintrc --no-inline-config --parser '@typescript-eslint/parser' --plugin 'unused-imports' --plugin 'react-hooks' --rule 'unused-imports/no-unused-imports:error' --fix \"./src/**/*.{ts,tsx}\""
},
"devDependencies": {
"@openshift-console/dynamic-plugin-sdk": "0.0.6",
"@openshift-console/dynamic-plugin-sdk": "0.0.10",
"@openshift-console/dynamic-plugin-sdk-webpack": "0.0.6",
"@patternfly/react-charts": "^6.51.19",
"@patternfly/react-core": "^4.202.5",
"@patternfly/react-table": "4.44.4",
"@patternfly/react-topology": "4.49.5",
"@patternfly/react-charts": "^6.67.1",
"@patternfly/react-core": "^4.214.1",
"@patternfly/react-table": "4.83.1",
"@patternfly/react-topology": "4.61.1",
"@testing-library/react": "^12.1.2",
"@types/copy-webpack-plugin": "8.0.1",
"@types/enzyme": "3.10.x",
Expand Down
5 changes: 4 additions & 1 deletion web/setup-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ jest.mock('react-i18next', () => {
jest.mock('@openshift-console/dynamic-plugin-sdk', () => {
return {
useResolvedExtensions: jest.fn(),
useK8sModels: () => {
return [{}, false];
},
ResourceLink: () => {
return null;
}
Expand All @@ -70,7 +73,7 @@ jest.mock('@patternfly/react-core', () => ({
DatePicker: () => {
return null;
},
OverflowMenuControl: ()=> {
OverflowMenuControl: () => {
return null;
}
}));
Expand Down
14 changes: 9 additions & 5 deletions web/src/components/netflow-table/netflow-table-row.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
/* table stripping from pf-color-black-150 value */
tbody>tr:nth-child(even) {
.light-stripped:nth-child(even) {
background-color: #f5f5f5;
}

.dark-stripped:nth-child(even) {
background-color: #050505;
}

.newflow-appear {
background-color: #73bcf755;
background-color: #73bcf755;
}

.newflow-appear-done {
background-color: transparent;
transition: background-color 5s;
}
background-color: transparent;
transition: background-color 5s;
}
7 changes: 6 additions & 1 deletion web/src/components/netflow-table/netflow-table-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Size } from '../dropdowns/display-dropdown';
import { RecordField } from '../netflow-record/record-field';
import './netflow-table-row.css';
import CSSTransition from 'react-transition-group/CSSTransition';
import { isDark } from '../../utils/theme';

const NetflowTableRow: React.FC<{
flow: Record;
Expand All @@ -24,7 +25,11 @@ const NetflowTableRow: React.FC<{
const shouldHighlight = React.useRef(highlight);

return (
<Tr isRowSelected={flow.key === selectedRecord?.key} onRowClick={onRowClick}>
<Tr
isRowSelected={flow.key === selectedRecord?.key}
onRowClick={onRowClick}
className={`${isDark() ? 'dark' : 'light'}-stripped`}
>
{columns.map(c => (
<CSSTransition
key={c.id}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ describe('<NetflowTopology />', () => {
const mocks = {
error: undefined as string | undefined,
loading: false,
k8sModels: {},
range: defaultTimeRange,
metricFunction: 'sum' as MetricFunction,
metricType: 'bytes' as MetricType,
Expand Down
28 changes: 20 additions & 8 deletions web/src/components/netflow-topology/components/node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ const getStatusIcon = (status: NodeStatus) => {
};

type BaseNodeProps = {
children?: React.ReactNode;
className?: string;
element: Node;
droppable?: boolean;
hover?: boolean;
Expand All @@ -66,9 +68,10 @@ type BaseNodeProps = {
label?: string; // Defaults to element.getLabel()
secondaryLabel?: string;
showLabel?: boolean; // Defaults to true
labelPosition?: LabelPosition; // Defaults to bottom
labelPosition?: LabelPosition; // Defaults to element.getLabelPosition()
truncateLength?: number; // Defaults to 13
labelIconClass?: string; // Icon to show in label
labelIcon?: React.ReactNode;
labelIconPadding?: number;
badge?: string;
badgeColor?: string;
Expand All @@ -82,7 +85,7 @@ type BaseNodeProps = {
statusDecoratorTooltip?: React.ReactNode;
onStatusDecoratorClick?: (event: React.MouseEvent<SVGGElement, MouseEvent>, element: GraphElement) => void;
getCustomShape?: (node: Node) => React.FC<ShapeProps>;
getShapeDecoratorCenter?: (quadrant: TopologyQuadrant, node: Node, radius?: number) => { x: number; y: number };
getShapeDecoratorCenter?: (quadrant: TopologyQuadrant, node: Node) => { x: number; y: number };
} & Partial<
WithSelectionProps &
WithDragNodeProps &
Expand All @@ -96,6 +99,7 @@ type BaseNodeProps = {
// to support shadow / hover behaviors

const BaseNode: React.FC<BaseNodeProps> = ({
className,
element,
selected,
hover,
Expand All @@ -104,9 +108,11 @@ const BaseNode: React.FC<BaseNodeProps> = ({
shadowed,
highlighted,
secondaryLabel,
labelPosition = LabelPosition.bottom,
labelPosition,
truncateLength,
labelIconClass,
labelIcon,
labelIconPadding,
showStatusBackground,
showStatusDecorator = false,
statusDecoratorTooltip,
Expand Down Expand Up @@ -149,8 +155,8 @@ const BaseNode: React.FC<BaseNodeProps> = ({
}

const { x, y } = getShapeDecoratorCenter
? getShapeDecoratorCenter(StatusQuadrant, element, DEFAULT_DECORATOR_RADIUS)
: getDefaultShapeDecoratorCenter(StatusQuadrant, element, DEFAULT_DECORATOR_RADIUS);
? getShapeDecoratorCenter(StatusQuadrant, element)
: getDefaultShapeDecoratorCenter(StatusQuadrant, element);

const decorator = (
<Decorator
Expand Down Expand Up @@ -191,8 +197,10 @@ const BaseNode: React.FC<BaseNodeProps> = ({

const groupClassName = css(
styles.topologyNode,
className,
isHover && 'pf-m-hover',
(dragging || edgeDragging) && 'pf-m-dragging',
canDrop && 'pf-m-highlight',
canDrop && dropTarget && 'pf-m-drop-target',
selected && 'pf-m-selected',
StatusModifier[status],
Expand All @@ -214,6 +222,8 @@ const BaseNode: React.FC<BaseNodeProps> = ({
filter = createSvgIdUrl(NODE_SHADOW_FILTER_ID_HOVER);
}

const nodeLabelPosition = labelPosition || element.getLabelPosition();

return (
<Layer id={dragging || isHover || highlighted ? TOP_LAYER : undefined}>
<g ref={hoverRef as React.LegacyRef<SVGGElement> | undefined} className={groupClassName}>
Expand All @@ -232,9 +242,9 @@ const BaseNode: React.FC<BaseNodeProps> = ({
{showLabel && (label || element.getLabel()) && (
<NodeLabel
className={css(styles.topologyNodeLabel)}
x={labelPosition === LabelPosition.right ? width + 8 : width / 2}
y={labelPosition === LabelPosition.right ? height / 2 : height + 6}
position={labelPosition}
x={nodeLabelPosition === LabelPosition.right ? width + 8 : width / 2}
y={nodeLabelPosition === LabelPosition.right ? height / 2 : height + 6}
position={nodeLabelPosition}
paddingX={8}
paddingY={4}
secondaryLabel={secondaryLabel}
Expand All @@ -250,6 +260,8 @@ const BaseNode: React.FC<BaseNodeProps> = ({
contextMenuOpen={contextMenuOpen ? true : false}
hover={isHover}
labelIconClass={labelIconClass}
labelIcon={labelIcon}
labelIconPadding={labelIconPadding}
>
{label || element.getLabel()}
</NodeLabel>
Expand Down
8 changes: 8 additions & 0 deletions web/src/components/netflow-topology/netflow-topology.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,12 @@ g.topology.node-highlighted>g>ellipse {
g.topology.edge-highlighted>.pf-topology__edge__link,
g.topology.edge-highlighted>.pf-topology-connector-arrow {
stroke: #0066CC;
}

.topology-icon {
border: none;
}

.topology-icon > text {
fill: white;
}
10 changes: 8 additions & 2 deletions web/src/components/netflow-topology/netflow-topology.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import stylesComponentFactory from './componentFactories/stylesComponentFactory'
import layoutFactory from './layouts/layoutFactory';
import './netflow-topology.css';
import { STEP_INTO_EVENT, FILTER_EVENT } from './styles/styleNode';
import { K8sModel } from '@openshift-console/dynamic-plugin-sdk';

export const HOVER_EVENT = 'hover';

Expand All @@ -64,6 +65,7 @@ const ZOOM_OUT = 3 / 4;
const FIT_PADDING = 80;

const TopologyContent: React.FC<{
k8sModels: { [key: string]: K8sModel };
range: number | TimeRange;
metricFunction?: MetricFunction;
metricType?: MetricType;
Expand All @@ -76,6 +78,7 @@ const TopologyContent: React.FC<{
selected: GraphElement | undefined;
onSelect: (e: GraphElement | undefined) => void;
}> = ({
k8sModels,
range,
metricFunction,
metricType,
Expand Down Expand Up @@ -326,7 +329,7 @@ const TopologyContent: React.FC<{
highlightedId = selectedIds[0];
}

const updatedModel = generateDataModel(metrics, getOptions(), searchValue, highlightedId, filters, t);
const updatedModel = generateDataModel(metrics, getOptions(), searchValue, highlightedId, filters, t, k8sModels);
const allIds = [...(updatedModel.nodes || []), ...(updatedModel.edges || [])].map(item => item.id);
controller.getElements().forEach(e => {
if (e.getType() !== 'graph') {
Expand All @@ -352,7 +355,7 @@ const TopologyContent: React.FC<{
}
});
controller.fromModel(updatedModel);
}, [controller, prevMetrics, metrics, hoveredId, selectedIds, getOptions, searchValue, filters, t]);
}, [controller, prevMetrics, metrics, hoveredId, selectedIds, getOptions, searchValue, filters, t, k8sModels]);

//update model on layout / metrics / filters change
React.useEffect(() => {
Expand Down Expand Up @@ -523,6 +526,7 @@ const TopologyContent: React.FC<{

const NetflowTopology: React.FC<{
loading?: boolean;
k8sModels: { [key: string]: K8sModel };
error?: string;
range: number | TimeRange;
metricFunction?: MetricFunction;
Expand All @@ -537,6 +541,7 @@ const NetflowTopology: React.FC<{
onSelect: (e: GraphElement | undefined) => void;
}> = ({
loading,
k8sModels,
error,
range,
metricFunction,
Expand Down Expand Up @@ -582,6 +587,7 @@ const NetflowTopology: React.FC<{
return (
<VisualizationProvider controller={controller}>
<TopologyContent
k8sModels={k8sModels}
range={range}
metricFunction={metricFunction}
metricType={metricType}
Expand Down
3 changes: 3 additions & 0 deletions web/src/components/netflow-traffic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
MetricFunction,
MetricType
} from '../model/flow-query';
import { useK8sModelsWithColors } from '../utils/k8s-models-hook';
import { Stats, TopologyMetrics } from '../api/loki';
import { DefaultOptions, TopologyGroupTypes, TopologyOptions } from '../model/topology';
import { Column, getDefaultColumns } from '../utils/columns';
Expand Down Expand Up @@ -105,6 +106,7 @@ export const NetflowTraffic: React.FC<{
const { push } = useHistory();
const { t } = useTranslation('plugin__network-observability-plugin');
const [extensions] = useResolvedExtensions<ModelFeatureFlag>(isModelFeatureFlag);
const k8sModels = useK8sModelsWithColors();
const [queryParams, setQueryParams] = useLocalStorage<string>(LOCAL_STORAGE_QUERY_PARAMS_KEY);
// set url params from local storage saved items at startup if empty
if (hasEmptyParams() && queryParams) {
Expand Down Expand Up @@ -566,6 +568,7 @@ export const NetflowTraffic: React.FC<{
return (
<NetflowTopology
loading={loading}
k8sModels={k8sModels}
error={error}
range={range}
metricFunction={metricFunction}
Expand Down
19 changes: 10 additions & 9 deletions web/src/model/topology.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import { elementPerMinText, roundTwoDigits } from '../utils/count';
import { TopologyMetrics } from '../api/loki';
import { Filter, FilterDefinition } from '../model/filters';
import { bytesPerSeconds, humanFileSize } from '../utils/bytes';
import { kindToAbbr } from '../utils/label';
import { defaultTimeRange } from '../utils/router';
import { findFilter } from '../utils/filter-definitions';
import { TFunction } from 'i18next';
import { K8sModel } from '@openshift-console/dynamic-plugin-sdk';

export enum LayoutName {
Cola = 'Cola',
Expand Down Expand Up @@ -198,7 +198,8 @@ export const generateNode = (
searchValue: string,
highlightedId: string,
filters: Filter[],
t: TFunction
t: TFunction,
k8sModels: { [key: string]: K8sModel }
): NodeModel => {
const id = `${data.type}.${data.namespace}.${data.name}.${data.addr}.${data.host}`;
const label = data.name
Expand All @@ -223,6 +224,7 @@ export const generateNode = (
: undefined;
const shadowed = !_.isEmpty(searchValue) && !(label.includes(searchValue) || secondaryLabel?.includes(searchValue));
const highlighted = !shadowed && !_.isEmpty(highlightedId) && highlightedId.includes(id);
const k8sModel = options.nodeBadges && data.type ? k8sModels[data.type] : undefined;
return {
id,
type: 'node',
Expand All @@ -238,11 +240,9 @@ export const generateNode = (
highlighted,
isFiltered: isElementFiltered(data, filters, t),
labelPosition: LabelPosition.bottom,
//TODO: get badge and color using console ResourceIcon
badge: options.nodeBadges && data.type ? kindToAbbr(data.type) : undefined,
//badgeColor: options.nodeBadges && type ? getModel(type)?.color : undefined,
badgeClassName:
options.nodeBadges && data.type ? `co-m-resource-icon co-m-resource-${data.type.toLowerCase()}` : undefined,
badge: k8sModel?.abbr,
badgeColor: k8sModel?.color ? k8sModel.color : '#2b9af3',
badgeClassName: 'topology-icon',
showDecorators: true,
secondaryLabel,
truncateLength: options.truncateLength !== TopologyTruncateLength.OFF ? options.truncateLength : undefined
Expand Down Expand Up @@ -359,7 +359,8 @@ export const generateDataModel = (
searchValue: string,
highlightedId: string,
filters: Filter[],
t: TFunction
t: TFunction,
k8sModels: { [key: string]: K8sModel }
): Model => {
let nodes: NodeModel[] = [];
const edges: EdgeModel[] = [];
Expand Down Expand Up @@ -415,7 +416,7 @@ export const generateDataModel = (
n.data.host === data.host
);
if (!node) {
node = generateNode(data, opts, searchValue, highlightedId, filters, t);
node = generateNode(data, opts, searchValue, highlightedId, filters, t, k8sModels);
nodes.push(node);
}

Expand Down
Loading