This is an automated email from the ASF dual-hosted git repository. eallen pushed a commit to branch eallen-DISPATCH-1385 in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git
The following commit(s) were added to refs/heads/eallen-DISPATCH-1385 by this push: new aea3637 More tests aea3637 is described below commit aea3637c2b6f8fb342dcb6f7687ed92e37e3bbae Author: Ernest Allen <eal...@redhat.com> AuthorDate: Sat Nov 23 12:47:50 2019 -0500 More tests --- console/react/src/App.css | 1 + console/react/src/common/updated.js | 4 +- console/react/src/details/createEntity.js | 6 +- .../{updateEntity.js => createEntity.test.js} | 28 +++--- .../react/src/details/dataSources/routerData.js | 101 --------------------- console/react/src/details/deleteEntity.js | 35 +++---- .../{createEntity.js => deleteEntity.test.js} | 27 +++--- console/react/src/details/detailsTablePage.test.js | 30 ++++-- console/react/src/details/entityList.test.js | 4 + console/react/src/details/routerSelect.js | 26 +++--- console/react/src/details/updateEntity.js | 6 +- .../{updateEntity.js => updateEntity.test.js} | 28 +++--- console/react/src/overview/dashboard/layout.js | 4 +- console/react/src/topology/clientInfoComponent.js | 7 ++ console/react/src/topology/nodes.js | 2 +- console/react/src/topology/routerInfoComponent.js | 3 + console/react/src/topology/svgUtils.js | 2 +- console/react/src/topology/topologyViewer.js | 78 ++++++---------- 18 files changed, 145 insertions(+), 247 deletions(-) diff --git a/console/react/src/App.css b/console/react/src/App.css index 2f0581f..e4a51a6 100644 --- a/console/react/src/App.css +++ b/console/react/src/App.css @@ -753,6 +753,7 @@ path.empty { opacity: 1; padding: 12px; font-size: 14px; + display: none; } #popover-div { diff --git a/console/react/src/common/updated.js b/console/react/src/common/updated.js index e762d8e..1813edd 100644 --- a/console/react/src/common/updated.js +++ b/console/react/src/common/updated.js @@ -28,9 +28,7 @@ class Updated extends Component { render() { return ( <pre aria-label="last-updated" data-pf-content="true" className="overview-loading"> - {`Updated ${this.props.service.utilities.strDate( - this.props.lastUpdated - )}`} + {`Updated ${this.props.service.utilities.strDate(this.props.lastUpdated)}`} </pre> ); } diff --git a/console/react/src/details/createEntity.js b/console/react/src/details/createEntity.js index 3f5dfe2..205b37b 100644 --- a/console/react/src/details/createEntity.js +++ b/console/react/src/details/createEntity.js @@ -31,7 +31,11 @@ class CreateEntity extends React.Component { }; render() { - return <Button onClick={this.handleClick}>Create</Button>; + return ( + <Button aria-label="create-entity-button" onClick={this.handleClick}> + Create + </Button> + ); } } diff --git a/console/react/src/details/updateEntity.js b/console/react/src/details/createEntity.test.js similarity index 62% copy from console/react/src/details/updateEntity.js copy to console/react/src/details/createEntity.test.js index 4d1fac9..d31f50d 100644 --- a/console/react/src/details/updateEntity.js +++ b/console/react/src/details/createEntity.test.js @@ -18,21 +18,21 @@ under the License. */ import React from "react"; -import { Button } from "@patternfly/react-core"; +import { render, fireEvent } from "@testing-library/react"; +import CreateEntity from "./createEntity"; -class UpdateEntity extends React.Component { - constructor(props) { - super(props); - this.state = {}; - } - - handleClick = () => { - this.props.handleEntityAction("update", this.props.record); +it("renders UpdateEntity", () => { + let buttonClicked = false; + const props = { + handleEntityAction: () => { + buttonClicked = true; + } }; - render() { - return <Button onClick={this.handleClick}>Update</Button>; - } -} + const { getByLabelText } = render(<CreateEntity {...props} />); + const button = getByLabelText("create-entity-button"); + expect(button).toBeInTheDocument(); -export default UpdateEntity; + fireEvent.click(button); + expect(buttonClicked).toBe(true); +}); diff --git a/console/react/src/details/dataSources/routerData.js b/console/react/src/details/dataSources/routerData.js deleted file mode 100644 index 67c015e..0000000 --- a/console/react/src/details/dataSources/routerData.js +++ /dev/null @@ -1,101 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -class RouterData { - constructor(service) { - this.service = service; - this.fields = [ - { title: "Router", field: "name" }, - { title: "Area", field: "area" }, - { title: "Mode", field: "mode" }, - { - title: "Addresses", - field: "addrCount", - numeric: true - }, - { - title: "Links", - field: "linkCount", - numeric: true - }, - { - title: "External connections", - field: "connections", - numeric: true - } - ]; - this.detailEntity = "router"; - this.detailName = "Router"; - } - - fetchRecord = (currentRecord, schema) => { - return new Promise(resolve => { - this.service.management.topology.fetchEntities( - currentRecord.nodeId, - [{ entity: "router" }], - results => { - const record = results[currentRecord.nodeId].router; - let router = this.service.utilities.flatten( - record.attributeNames, - record.results[0] - ); - router = this.service.utilities.formatAttributes( - router, - schema.entityTypes.router - ); - resolve(router); - } - ); - }); - }; - - doFetch = (page, perPage) => { - return new Promise(resolve => { - this.service.management.topology.fetchAllEntities( - [{ entity: "connection", attrs: ["role"] }, { entity: "router" }], - nodes => { - // we have all the data now in the nodes object - let allRouterFields = []; - for (let node in nodes) { - let connections = 0; - for (let i = 0; i < nodes[node]["connection"].results.length; ++i) { - // we only requested "role" so it will be at results[0] - if (nodes[node]["connection"].results[i][0] !== "inter-router") - ++connections; - } - let routerRow = { - connections, - nodeId: node, - id: this.service.utilities.nameFromId(node) - }; - nodes[node]["router"].attributeNames.forEach((routerAttr, i) => { - if (routerAttr !== "id") { - routerRow[routerAttr] = nodes[node]["router"].results[0][i]; - } - }); - allRouterFields.push(routerRow); - } - resolve({ data: allRouterFields, page, perPage }); - } - ); - }); - }; -} - -export default RouterData; diff --git a/console/react/src/details/deleteEntity.js b/console/react/src/details/deleteEntity.js index 8313fbf..8a40979 100644 --- a/console/react/src/details/deleteEntity.js +++ b/console/react/src/details/deleteEntity.js @@ -43,9 +43,7 @@ class DeleteEntity extends React.Component { }; getName = record => { - return record.name !== null - ? record.name - : `${this.props.entity}/${record.identity}`; + return record.name !== null ? record.name : `${this.props.entity}/${record.identity}`; }; delete = () => { @@ -60,35 +58,21 @@ class DeleteEntity extends React.Component { "DELETE" ) .then(results => { - let statusCode = - results.context.message.application_properties.statusCode; + let statusCode = results.context.message.application_properties.statusCode; if (statusCode < 200 || statusCode >= 300) { const msg = `Deleted ${name} failed with message: ${results.context.message.application_properties.statusDescription}`; console.log(`error ${msg}`); - this.props.handleAddNotification( - "action", - msg, - new Date(), - "danger" - ); + this.props.handleAddNotification("action", msg, new Date(), "danger"); } else { const msg = `Deleted ${this.props.entity} ${name}`; console.log(`success ${msg}`); - this.props.handleAddNotification( - "action", - msg, - new Date(), - "success" - ); + this.props.handleAddNotification("action", msg, new Date(), "success"); } - this.setState( - { isModalOpen: false, closing: false, closed: true }, - () => { - if (this.props.notifyClick) { - this.props.notifyClick("Done"); - } + this.setState({ isModalOpen: false, closing: false, closed: true }, () => { + if (this.props.notifyClick) { + this.props.notifyClick("Done"); } - ); + }); }); }); }; @@ -101,6 +85,7 @@ class DeleteEntity extends React.Component { <React.Fragment> {!this.props.showNow && ( <Button + aria-label="delete-entity-button" className={`${this.props.asButton ? "" : "link-button"}`} onClick={this.handleModalShow} > @@ -114,6 +99,7 @@ class DeleteEntity extends React.Component { onClose={this.handleModalHide} actions={[ <Button + aria-label="confirm-delete" key="confirm" variant="primary" onClick={this.delete} @@ -122,6 +108,7 @@ class DeleteEntity extends React.Component { Delete </Button>, <Button + aria-label="cancel-delete" key="cancel" variant="link" onClick={this.handleModalHide} diff --git a/console/react/src/details/createEntity.js b/console/react/src/details/deleteEntity.test.js similarity index 61% copy from console/react/src/details/createEntity.js copy to console/react/src/details/deleteEntity.test.js index 3f5dfe2..ac30005 100644 --- a/console/react/src/details/createEntity.js +++ b/console/react/src/details/deleteEntity.test.js @@ -18,21 +18,20 @@ under the License. */ import React from "react"; -import { Button } from "@patternfly/react-core"; +import { render, fireEvent } from "@testing-library/react"; +import DeleteEntity from "./deleteEntity"; -class CreateEntity extends React.Component { - constructor(props) { - super(props); - this.state = {}; - } - - handleClick = () => { - this.props.handleEntityAction("create"); +it("renders DeleteEntity", () => { + const entity = "listener"; + const props = { + entity, + record: { name: "testListener" } }; - render() { - return <Button onClick={this.handleClick}>Create</Button>; - } -} + const { getByLabelText } = render(<DeleteEntity {...props} />); + const button = getByLabelText("delete-entity-button"); + expect(button).toBeInTheDocument(); -export default CreateEntity; + fireEvent.click(button); + expect(getByLabelText("confirm-delete")).toBeInTheDocument(); +}); diff --git a/console/react/src/details/detailsTablePage.test.js b/console/react/src/details/detailsTablePage.test.js index 9f49d38..53b927b 100644 --- a/console/react/src/details/detailsTablePage.test.js +++ b/console/react/src/details/detailsTablePage.test.js @@ -19,18 +19,30 @@ under the License. import React from "react"; import { render } from "@testing-library/react"; -import DetailsTablePage from "./detailsTablePage"; +import { service, login } from "../serviceTest"; +import DetailTablesPage from "./detailsTablePage"; + +it("renders the DetailTablesPage", async () => { + const entity = "router"; + const routerName = "A"; + + await login(); + expect(service.management.connection.is_connected()).toBe(true); -it("renders the detailsTablePage", () => { - const entity = "testEntity"; const props = { entity, - locationState: { currentRecord: { name: "test" } }, + locationState: { + currentRecord: { + name: routerName, + routerId: service.utilities.idFromName(routerName, "_topo") + } + }, details: true, - schema: { entityTypes: { testEntity: { attributes: [], operations: [] } } }, - service: { management: { topology: { fetchEntities: () => Promise.resolve([]) } } } + service, + schema: service.schema }; - const { getByLabelText } = render(<DetailsTablePage {...props} />); - const table = getByLabelText(entity); - expect(table).toBeInTheDocument(); + + const { getByTestId } = render(<DetailTablesPage {...props} />); + const header = getByTestId(`detail-for-${routerName}`); + expect(header).toBeInTheDocument(); }); diff --git a/console/react/src/details/entityList.test.js b/console/react/src/details/entityList.test.js index 40b43f7..d86d4c7 100644 --- a/console/react/src/details/entityList.test.js +++ b/console/react/src/details/entityList.test.js @@ -42,4 +42,8 @@ it("renders a EntityList", async () => { // clicking on the log entity should not crash fireEvent.click(logEntity); + + fireEvent.click(getByTestId("router")); + fireEvent.click(getByTestId("autoLink")); + fireEvent.click(getByTestId("connection")); }); diff --git a/console/react/src/details/routerSelect.js b/console/react/src/details/routerSelect.js index 0d3bec0..f6af128 100644 --- a/console/react/src/details/routerSelect.js +++ b/console/react/src/details/routerSelect.js @@ -33,19 +33,6 @@ class RouterSelect extends React.Component { selectedOption: "", routers: [] }; - - this.onToggle = () => { - this.setState({ - isOpen: !this.state.isOpen - }); - }; - - this.onSelect = event => { - const routerName = event.target.id; - this.setState({ selectedOption: routerName, isOpen: false }, () => { - this.props.handleRouterSelected(this.nameToId[routerName]); - }); - }; } componentDidMount = () => { @@ -62,6 +49,19 @@ class RouterSelect extends React.Component { }); }; + onToggle = () => { + this.setState({ + isOpen: !this.state.isOpen + }); + }; + + onSelect = event => { + const routerName = event.target.textContent; + this.setState({ selectedOption: routerName, isOpen: false }, () => { + this.props.handleRouterSelected(this.nameToId[routerName]); + }); + }; + render() { const { routers, selectedOption, isOpen } = this.state; const menuItems = routers.map(r => ( diff --git a/console/react/src/details/updateEntity.js b/console/react/src/details/updateEntity.js index 4d1fac9..3abeba8 100644 --- a/console/react/src/details/updateEntity.js +++ b/console/react/src/details/updateEntity.js @@ -31,7 +31,11 @@ class UpdateEntity extends React.Component { }; render() { - return <Button onClick={this.handleClick}>Update</Button>; + return ( + <Button aria-label="update-entity-button" onClick={this.handleClick}> + Update + </Button> + ); } } diff --git a/console/react/src/details/updateEntity.js b/console/react/src/details/updateEntity.test.js similarity index 62% copy from console/react/src/details/updateEntity.js copy to console/react/src/details/updateEntity.test.js index 4d1fac9..43206d2 100644 --- a/console/react/src/details/updateEntity.js +++ b/console/react/src/details/updateEntity.test.js @@ -18,21 +18,21 @@ under the License. */ import React from "react"; -import { Button } from "@patternfly/react-core"; +import { render, fireEvent } from "@testing-library/react"; +import UpdateEntity from "./updateEntity"; -class UpdateEntity extends React.Component { - constructor(props) { - super(props); - this.state = {}; - } - - handleClick = () => { - this.props.handleEntityAction("update", this.props.record); +it("renders UpdateEntity", () => { + let buttonClicked = false; + const props = { + handleEntityAction: () => { + buttonClicked = true; + } }; - render() { - return <Button onClick={this.handleClick}>Update</Button>; - } -} + const { getByLabelText } = render(<UpdateEntity {...props} />); + const button = getByLabelText("update-entity-button"); + expect(button).toBeInTheDocument(); -export default UpdateEntity; + fireEvent.click(button); + expect(buttonClicked).toBe(true); +}); diff --git a/console/react/src/overview/dashboard/layout.js b/console/react/src/overview/dashboard/layout.js index 46fe58c..fc6e6b6 100644 --- a/console/react/src/overview/dashboard/layout.js +++ b/console/react/src/overview/dashboard/layout.js @@ -88,8 +88,8 @@ class PageLayout extends React.Component { visualizations: [{ name: "topology" }, { name: "flow", title: "Message flow" }], details: [{ name: "entities" }, { name: "schema" }] }; - this.state.connecting = true; - this.tryInitialConnect(); + //this.state.connecting = true; + //this.tryInitialConnect(); } componentDidMount = () => { diff --git a/console/react/src/topology/clientInfoComponent.js b/console/react/src/topology/clientInfoComponent.js index feb6e5f..e782c38 100644 --- a/console/react/src/topology/clientInfoComponent.js +++ b/console/react/src/topology/clientInfoComponent.js @@ -162,6 +162,8 @@ class ClientInfoComponent extends Component { }; componentWillUnmount = () => { + this.unmounted = true; + if (this.timer) { clearInterval(this.timer); this.timer = null; @@ -173,6 +175,7 @@ class ClientInfoComponent extends Component { }; getTooltip = () => { this.props.d.toolTip(this.props.topology, true).then(toolTip => { + if (this.unmounted) return; this.setState({ toolTip }); }); }; @@ -248,6 +251,7 @@ class ClientInfoComponent extends Component { } // await until all sent requests have completed q.await(() => { + if (this.unmounted) return; this.setState({ detail: { template: "edgeRouters", title: "edge router" } }); @@ -265,6 +269,7 @@ class ClientInfoComponent extends Component { this.d.key, [{ entity: "router.link", attrs: attrs }], results => { + if (this.unmounted) return; let links = results[this.d.key]["router.link"]; for (let i = 0; i < this.d.normals.length; i++) { let n = this.d.normals[i]; @@ -319,6 +324,7 @@ class ClientInfoComponent extends Component { }; updateDetail = () => { this.groupDetail().then(det => { + if (this.unmounted) return; Object.keys(det.infoPerId).forEach(id => { this.cachedInfo.push(det.infoPerId[id]); }); @@ -406,6 +412,7 @@ class ClientInfoComponent extends Component { onExpand = (event, rowIndex, colIndex, isOpen, rowData, extraData) => { const { rows } = this.state; + if (this.unmounted) return; if (!isOpen) { //set all other expanded cells false in this row if we are expanding rows[rowIndex].cells.forEach(cell => { diff --git a/console/react/src/topology/nodes.js b/console/react/src/topology/nodes.js index 1ae1337..d25b93f 100644 --- a/console/react/src/topology/nodes.js +++ b/console/react/src/topology/nodes.js @@ -185,7 +185,7 @@ const nodeProperties = { charge: [-1800, -900] }, edge: { - radius: 20, + radius: 24, refX: { end: 24, start: -12 diff --git a/console/react/src/topology/routerInfoComponent.js b/console/react/src/topology/routerInfoComponent.js index 6ac557c..c5b14d6 100644 --- a/console/react/src/topology/routerInfoComponent.js +++ b/console/react/src/topology/routerInfoComponent.js @@ -35,13 +35,16 @@ class RouterInfoComponent extends Component { }; componentWillUnmount = () => { + this.unmounted = true; if (this.timer) { clearInterval(this.timer); this.timer = null; } }; + getTooltip = () => { this.props.d.toolTip(this.props.topology, true).then(toolTip => { + if (this.unmounted) return; this.setState({ toolTip }); }); }; diff --git a/console/react/src/topology/svgUtils.js b/console/react/src/topology/svgUtils.js index c9d9477..9243f7f 100644 --- a/console/react/src/topology/svgUtils.js +++ b/console/react/src/topology/svgUtils.js @@ -111,7 +111,7 @@ export function appendContent(g) { else if (d.nodeType === "edge" || d.nodeType === "_edge") y = 4; return y; }) - .attr("class", "id") + .attr("class", d => (d.nodeType === "_topo" ? "label" : "id")) .classed("console", function(d) { return utils.isConsole(d); }) diff --git a/console/react/src/topology/topologyViewer.js b/console/react/src/topology/topologyViewer.js index 5871970..610efb0 100644 --- a/console/react/src/topology/topologyViewer.js +++ b/console/react/src/topology/topologyViewer.js @@ -26,7 +26,6 @@ import { TopologySideBar } from "@patternfly/react-topology"; -import QDRPopup from "../common/qdrPopup"; import { Traffic } from "./traffic.js"; import { separateAddresses } from "../chord/filters.js"; import { Nodes } from "./nodes.js"; @@ -83,8 +82,6 @@ class TopologyPage extends Component { savedOptions.map.show = false; } this.state = { - popupContent: "", - showPopup: false, legendOptions: savedOptions, showRouterInfo: false, showClientInfo: false, @@ -149,6 +146,7 @@ class TopologyPage extends Component { this.props.service.management.topology.setUpdateEntities([]); this.props.service.management.topology.stopUpdating(); this.props.service.management.topology.delChangedAction("topology"); + this.props.service.management.topology.delUpdatedAction("connectionPopupHTML"); this.traffic.remove(); this.forceData.nodes.savePositions(); window.removeEventListener("resize", this.resize); @@ -391,7 +389,7 @@ class TopologyPage extends Component { // mouse out of a path this.popupCancelled = true; this.props.service.management.topology.delUpdatedAction("connectionPopupHTML"); - this.setState({ showPopup: false }); + this.hideTooltip(); d.selected = false; connectionPopupHTML(); }; @@ -429,14 +427,13 @@ class TopologyPage extends Component { d.selected = true; this.popupCancelled = false; let updateTooltip = () => { + if (this.popupCancelled) return; if (d.selected) { - this.setState({ - popupContent: connectionPopupHTML( - d, - this.props.service.management.topology._nodeInfo - ) - }); - this.displayTooltip(event); + const popupContent = connectionPopupHTML( + d, + this.props.service.management.topology._nodeInfo + ); + this.displayTooltip(popupContent, { x: event.pageX, y: event.pageY }); } else { this.handleMouseOutPath(d); } @@ -534,7 +531,8 @@ class TopologyPage extends Component { let e = d3.event; self.popupCancelled = false; d.toolTip(self.props.service.management.topology).then(function(toolTip) { - self.showToolTip(toolTip, e); + if (self.popupCancelled) return; + self.displayTooltip(toolTip, { x: e.pageX, y: e.pageY }); }); if (d === self.mousedown_node) return; // enlarge target node @@ -564,8 +562,8 @@ class TopologyPage extends Component { self.current_node = null; // unenlarge target node d3.select(this).attr("transform", ""); - self.setState({ showPopup: false }); self.popupCancelled = true; + self.hideTooltip(); self.clearAllHighlights(); self.mouseover_node = null; self.restart(); @@ -610,9 +608,9 @@ class TopologyPage extends Component { self.clearAllHighlights(); self.mousedown_node = null; // handle clicking on nodes that represent multiple sub-nodes - if (d.normals && !d.isArtemis && !d.isQpid) { + if (d.normals && !d.isArtemis && !d.isQpid && d.nodeType !== "edge") { self.doDialog(d, "client"); - } else if (d.nodeType === "_topo") { + } else if (d.nodeType === "_topo" || d.nodeType === "edge") { self.doDialog(d, "router"); } // apply any data changes to the interface @@ -670,7 +668,7 @@ class TopologyPage extends Component { this.svg.selectAll(".subtext").remove(); let multiples = this.svg.selectAll(".multiple"); multiples.each(function(d) { - let g = d3.select(this); + let g = d3.select(this.parentNode); let r = Nodes.radius(d.nodeType); g.append("svg:text") .attr("x", r + 4) @@ -764,37 +762,29 @@ class TopologyPage extends Component { this.setState({ showClientInfo: true }); } }; + handleCloseRouterInfo = type => { this.setState({ showRouterInfo: false }); }; + handleCloseClientInfo = () => { this.setState({ showClientInfo: false }); }; - showToolTip = (title, event) => { - // show the tooltip - this.setState({ popupContent: title }); - this.displayTooltip(event); - }; - - displayTooltip = event => { + displayTooltip = (content, xy) => { if (this.popupCancelled) { - this.setState({ showPopup: false }); - return; + return this.hideTooltip(); } // position the popup d3.select("#popover-div") - .style("left", event.pageX + 5 + "px") - .style("top", `${event.pageY}px`); - // show popup - this.setState({ showPopup: true }, () => - d3 - .select("#popover-div") - //.style("left", Math.min(width - pwidth, event.pageX + 5) + "px") - .on("mouseout", () => { - this.setState({ showPopup: false }); - }) - ); + .style("left", `${xy.x + 5}px`) + .style("top", `${xy.y}px`) + .style("display", "block") + .html(content); + }; + + hideTooltip = () => { + d3.select("#popover-div").style("display", "none"); }; clearAllHighlights = () => { @@ -1020,31 +1010,21 @@ class TopologyPage extends Component { /> )} - <div - id="popover-div" - className={this.state.showPopup ? "qdrPopup" : "qdrPopup hidden"} - ref={el => (this.popupRef = el)} - > - <QDRPopup content={this.state.popupContent}></QDRPopup> - </div> + <div id="popover-div" className="qdrPopup"></div> - {this.state.showRouterInfo ? ( + {this.state.showRouterInfo && ( <RouterInfoComponent d={this.d} topology={this.props.service.management.topology} handleCloseRouterInfo={this.handleCloseRouterInfo} /> - ) : ( - <div /> )} - {this.state.showClientInfo ? ( + {this.state.showClientInfo && ( <ClientInfoComponent d={this.d} topology={this.props.service.management.topology} handleCloseClientInfo={this.handleCloseClientInfo} /> - ) : ( - <div /> )} </TopologyView> ); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org