Skip to content
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
63 changes: 30 additions & 33 deletions packages/react-integration/demo-app-ts/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ import {
PageHeader,
PageHeaderTools,
PageHeaderToolsItem,
SelectOption,
Select,
SelectVariant
PageHeaderToolsGroup,
Radio
} from '@patternfly/react-core';
import imgBrand from './assets/images/imgBrand.svg';
import imgAvatar from './assets/images/imgAvatar.svg';
Expand All @@ -25,43 +24,32 @@ import './App.css';
interface AppState {
activeItem: number | string;
isNavOpen: boolean;
isThemesOpen: boolean;
theme: string;
isDarkTheme: boolean;
}

class App extends React.Component<{}, AppState> {
state: AppState = {
activeItem: '',
isNavOpen: true,
isThemesOpen: false,
theme: 'Light theme'
isDarkTheme: false
};

private onNavSelect = (selectedItem: { itemId: number | string }) => {
this.setState({ activeItem: selectedItem.itemId });
};

private onThemeSelect = (event: React.MouseEvent<Element, MouseEvent>, selectedItem: string) => {
this.setState({ theme: selectedItem, isThemesOpen: false });
private onThemeSelect = (isDarkTheme: boolean) => {
this.setState({ isDarkTheme });
const htmlElement = document.getElementsByTagName('html')[0];
if (htmlElement) {
if (selectedItem === 'Dark theme') {
if (isDarkTheme) {
htmlElement.classList.add('pf-theme-dark');
} else {
htmlElement.classList.remove('pf-theme-dark');
}
}
};

private onThemeToggle = () => {
this.setState({ isThemesOpen: !this.state.isThemesOpen });
};

private themeSelectItems = [
<SelectOption key="light" value="Light theme" />,
<SelectOption key="dark" value="Dark theme" />
];

private getPages = () => (
<React.Fragment>
{Demos.map(demo => (
Expand All @@ -82,23 +70,32 @@ class App extends React.Component<{}, AppState> {
private getSkipToContentLink = () => <SkipToContent href={`#${this.pageId}`}>Skip to Content</SkipToContent>;

render() {
const { isNavOpen, activeItem, isThemesOpen, theme } = this.state;
const { isNavOpen, activeItem, isDarkTheme } = this.state;

const AppToolbar = (
<PageHeaderTools>
<PageHeaderToolsItem>
<Select
toggleId="select-theme-toggle"
variant={SelectVariant.single}
position="right"
onToggle={this.onThemeToggle}
onSelect={this.onThemeSelect}
selections={theme}
isOpen={isThemesOpen}
>
{this.themeSelectItems}
</Select>
</PageHeaderToolsItem>
<PageHeaderToolsGroup>
<PageHeaderToolsItem style={{ marginRight: '10px' }}>
<Radio
id="light-theme"
aria-label="Light theme"
label={`Light theme`}
name="light-theme"
isChecked={!isDarkTheme}
onChange={checked => checked && this.onThemeSelect(false)}
/>
</PageHeaderToolsItem>
<PageHeaderToolsItem>
<Radio
id="dark-theme"
label="Dark theme"
aria-label="Dark theme"
name="dark-theme"
isChecked={isDarkTheme}
onChange={checked => checked && this.onThemeSelect(true)}
/>
</PageHeaderToolsItem>
</PageHeaderToolsGroup>
<Avatar src={imgAvatar} alt="Avatar image" />
</PageHeaderTools>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ const TopologyViewComponent: React.FunctionComponent<TopologyViewComponentProps>
);
};

export const Topology = () => {
export const Topology = React.memo(() => {
const controller = new Visualization();
controller.registerLayoutFactory(defaultLayoutFactory);
controller.registerComponentFactory(defaultComponentFactory);
Expand All @@ -600,9 +600,9 @@ export const Topology = () => {
<TopologyViewComponent useSidebar={false} />
</VisualizationProvider>
);
};
});

export const WithSideBar = () => {
export const WithSideBar = React.memo(() => {
const controller = new Visualization();
controller.registerLayoutFactory(defaultLayoutFactory);
controller.registerComponentFactory(defaultComponentFactory);
Expand All @@ -613,9 +613,9 @@ export const WithSideBar = () => {
<TopologyViewComponent useSidebar />
</VisualizationProvider>
);
};
});

export const WithResizableSideBar = () => {
export const WithResizableSideBar = React.memo(() => {
const controller = new Visualization();
controller.registerLayoutFactory(defaultLayoutFactory);
controller.registerComponentFactory(defaultComponentFactory);
Expand All @@ -625,4 +625,4 @@ export const WithResizableSideBar = () => {
<TopologyViewComponent useSidebar sideBarResizable />
</VisualizationProvider>
);
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import BlueprintIcon from '@patternfly/react-icons/dist/esm/icons/blueprint-icon
import PauseCircle from '@patternfly/react-icons/dist/esm/icons/pause-circle-icon';
import Thumbtack from '@patternfly/react-icons/dist/esm/icons/thumbtack-icon';
import useDetailsLevel from '@patternfly/react-topology/dist/esm/hooks/useDetailsLevel';
import { SVGIconProps } from '@patternfly/react-icons/dist/esm/createIcon';

export enum DataTypes {
Default,
Expand All @@ -34,6 +35,7 @@ type StyleNodeProps = {
getCustomShape?: (node: Node) => React.FunctionComponent<ShapeProps>;
getShapeDecoratorCenter?: (quadrant: TopologyQuadrant, node: Node) => { x: number; y: number };
showLabel?: boolean; // Defaults to true
labelIcon?: React.ComponentClass<SVGIconProps>;
showStatusDecorator?: boolean; // Defaults to false
regrouping?: boolean;
dragging?: boolean;
Expand Down Expand Up @@ -134,6 +136,7 @@ const StyleNode: React.FunctionComponent<StyleNodeProps> = ({
return newData;
}, [data]);

const LabelIcon = passedData.labelIcon;
return (
<DefaultNode
element={element}
Expand All @@ -146,6 +149,7 @@ const StyleNode: React.FunctionComponent<StyleNodeProps> = ({
showStatusDecorator={detailsLevel === ScaleDetailsLevel.high && passedData.showStatusDecorator}
onContextMenu={data.showContextMenu ? onContextMenu : undefined}
contextMenuOpen={contextMenuOpen}
labelIcon={LabelIcon && <LabelIcon noVerticalAlign />}
attachments={
detailsLevel === ScaleDetailsLevel.high && renderDecorators(element, passedData, rest.getShapeDecoratorCenter)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import React from 'react';
import {
EdgeAnimationSpeed,
EdgeModel,
Expand All @@ -8,8 +9,10 @@ import {
NodeShape,
NodeStatus
} from '@patternfly/react-topology';
import SignOutAltIcon from '@patternfly/react-icons/dist/esm/icons/skull-icon';
import { createEdge, createNode } from '../utils/styleUtils';
import { logos } from '../utils/logos';
import { SVGIconProps } from '@patternfly/react-icons/dist/esm/createIcon';

const getRandomNode = (numNodes: number, notNode = -1): number => {
let node = Math.floor(Math.random() * numNodes);
Expand Down Expand Up @@ -74,8 +77,11 @@ export const getNodeOptions = (
showDecorators?: boolean;
showContextMenu?: boolean;
labelIconClass?: string;
labelIcon?: React.ComponentClass<SVGIconProps>;
} => {
const shapeEnumIndex = Math.round(Math.random() * (nodeCreationOptions.shapes.length - 1));
const labelIconClass = index % 2 === 0 && nodeCreationOptions.nodeIcons ? logos.get('icon-java') : undefined;
const labelIcon = index % 2 === 1 && nodeCreationOptions.nodeIcons ? SignOutAltIcon : undefined;
return {
status: nodeCreationOptions.statuses[index % nodeCreationOptions.statuses.length],
shape: nodeCreationOptions.shapes[shapeEnumIndex],
Expand All @@ -85,7 +91,8 @@ export const getNodeOptions = (
showStatusDecorator: nodeCreationOptions.statusDecorators,
showDecorators: nodeCreationOptions.showDecorators,
showContextMenu: nodeCreationOptions.contextMenus,
labelIconClass: nodeCreationOptions.nodeIcons ? logos.get('icon-java') : undefined
labelIconClass,
labelIcon
};
};

Expand Down
Loading