mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-03 02:00:43 +00:00
Fix DOM closing tag location.
This commit is contained in:
@@ -40,7 +40,6 @@
|
||||
"jsx-a11y/click-events-have-key-events": 0,
|
||||
"jsx-a11y/mouse-events-have-key-events": 0,
|
||||
|
||||
"react/jsx-closing-tag-location": 0,
|
||||
"react/jsx-max-props-per-line": 0,
|
||||
"react/jsx-wrap-multilines": 0,
|
||||
}
|
||||
|
||||
@@ -19,9 +19,11 @@ describe('NodeDetails', () => {
|
||||
});
|
||||
|
||||
it('shows n/a when node was not found', () => {
|
||||
const c = TestUtils.renderIntoDocument(<Provider store={configureStore()}>
|
||||
<NodeDetails notFound />
|
||||
</Provider>);
|
||||
const c = TestUtils.renderIntoDocument((
|
||||
<Provider store={configureStore()}>
|
||||
<NodeDetails notFound />
|
||||
</Provider>
|
||||
));
|
||||
const notFound = TestUtils.findRenderedDOMComponentWithClass(
|
||||
c,
|
||||
'node-details-header-notavailable'
|
||||
@@ -32,13 +34,15 @@ describe('NodeDetails', () => {
|
||||
it('show label of node with title', () => {
|
||||
nodes = nodes.set(nodeId, Immutable.fromJS({id: nodeId}));
|
||||
details = {label: 'Node 1'};
|
||||
const c = TestUtils.renderIntoDocument(<Provider store={configureStore()}>
|
||||
<NodeDetails
|
||||
nodes={nodes}
|
||||
topologyId="containers"
|
||||
nodeId={nodeId} details={details}
|
||||
/>
|
||||
</Provider>);
|
||||
const c = TestUtils.renderIntoDocument((
|
||||
<Provider store={configureStore()}>
|
||||
<NodeDetails
|
||||
nodes={nodes}
|
||||
topologyId="containers"
|
||||
nodeId={nodeId} details={details}
|
||||
/>
|
||||
</Provider>
|
||||
));
|
||||
|
||||
const title = TestUtils.findRenderedDOMComponentWithClass(c, 'node-details-header-label');
|
||||
expect(title.title).toBe('Node 1');
|
||||
|
||||
@@ -194,9 +194,11 @@ class App extends React.Component {
|
||||
<TimeTravel />
|
||||
<div className="selectors">
|
||||
<div className="logo">
|
||||
{!isIframe && <svg width="100%" height="100%" viewBox="0 0 1089 217">
|
||||
<Logo />
|
||||
</svg>}
|
||||
{!isIframe &&
|
||||
<svg width="100%" height="100%" viewBox="0 0 1089 217">
|
||||
<Logo />
|
||||
</svg>
|
||||
}
|
||||
</div>
|
||||
<Search />
|
||||
<Topologies />
|
||||
|
||||
@@ -3,9 +3,11 @@ import { createDevTools } from 'redux-devtools';
|
||||
import LogMonitor from 'redux-devtools-log-monitor';
|
||||
import DockMonitor from 'redux-devtools-dock-monitor';
|
||||
|
||||
export default createDevTools(<DockMonitor
|
||||
defaultIsVisible={false}
|
||||
toggleVisibilityKey="ctrl-h"
|
||||
changePositionKey="ctrl-w">
|
||||
<LogMonitor />
|
||||
</DockMonitor>);
|
||||
export default createDevTools((
|
||||
<DockMonitor
|
||||
defaultIsVisible={false}
|
||||
toggleVisibilityKey="ctrl-h"
|
||||
changePositionKey="ctrl-w">
|
||||
<LogMonitor />
|
||||
</DockMonitor>
|
||||
));
|
||||
|
||||
@@ -49,13 +49,15 @@ class Footer extends React.Component {
|
||||
return (
|
||||
<div className="footer">
|
||||
<div className="footer-status">
|
||||
{versionUpdate && <a
|
||||
className="footer-versionupdate"
|
||||
title={versionUpdateTitle}
|
||||
href={versionUpdate.get('downloadUrl')}
|
||||
target="_blank" rel="noopener noreferrer">
|
||||
Update available: {versionUpdate.get('version')}
|
||||
</a>}
|
||||
{versionUpdate &&
|
||||
<a
|
||||
className="footer-versionupdate"
|
||||
title={versionUpdateTitle}
|
||||
href={versionUpdate.get('downloadUrl')}
|
||||
target="_blank" rel="noopener noreferrer">
|
||||
Update available: {versionUpdate.get('version')}
|
||||
</a>
|
||||
}
|
||||
<span className="footer-label">Version</span>
|
||||
{version}
|
||||
<span className="footer-label">on</span>
|
||||
|
||||
@@ -116,14 +116,21 @@ function renderSearchPanel() {
|
||||
|
||||
|
||||
function renderFieldsPanel(currentTopologyName, searchableFields) {
|
||||
const none = <span style={{fontStyle: 'italic'}}>None</span>;
|
||||
const none = (
|
||||
<span style={{fontStyle: 'italic'}}>None</span>
|
||||
);
|
||||
const currentTopology = (
|
||||
<span className="help-panel-fields-current-topology">
|
||||
{currentTopologyName}
|
||||
</span>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="help-panel-fields">
|
||||
<h2>Fields and Metrics</h2>
|
||||
<p>
|
||||
Searchable fields and metrics in the <br />
|
||||
currently selected <span className="help-panel-fields-current-topology">
|
||||
{currentTopologyName}</span> topology:
|
||||
currently selected {currentTopology} topology:
|
||||
</p>
|
||||
<div className="help-panel-fields-fields">
|
||||
<div className="help-panel-fields-fields-column">
|
||||
|
||||
@@ -41,9 +41,11 @@ export default class MatchedResults extends React.PureComponent {
|
||||
return (
|
||||
<div className="matched-results" style={style}>
|
||||
{matches.keySeq().take(SHOW_ROW_COUNT).map(fieldId => Match(matches.get(fieldId)))}
|
||||
{moreFieldMatches && <div className="matched-results-more" title={moreFieldMatchesTitle}>
|
||||
{`${moreFieldMatches.size} more matches`}
|
||||
</div>}
|
||||
{moreFieldMatches &&
|
||||
<div className="matched-results-more" title={moreFieldMatchesTitle}>
|
||||
{`${moreFieldMatches.size} more matches`}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -22,14 +22,16 @@ class MetricSelector extends React.Component {
|
||||
|
||||
return (
|
||||
<div className="metric-selector">
|
||||
{hasMetrics && <div className="metric-selector-wrapper" onMouseLeave={this.onMouseOut}>
|
||||
{availableMetrics.map(metric => (
|
||||
<MetricSelectorItem
|
||||
key={metric.get('id')}
|
||||
metric={metric}
|
||||
/>
|
||||
))}
|
||||
</div>}
|
||||
{hasMetrics &&
|
||||
<div className="metric-selector-wrapper" onMouseLeave={this.onMouseOut}>
|
||||
{availableMetrics.map(metric => (
|
||||
<MetricSelectorItem
|
||||
key={metric.get('id')}
|
||||
metric={metric}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -63,12 +63,14 @@ class NodeDetails extends React.Component {
|
||||
return (
|
||||
<div className="node-details-tools-wrapper">
|
||||
<div className="node-details-tools">
|
||||
{showSwitchTopology && <span
|
||||
title={topologyTitle}
|
||||
className="fa fa-long-arrow-left"
|
||||
onClick={this.handleShowTopologyForNode}>
|
||||
<span>Show in <span>{this.props.topologyId.replace(/-/g, ' ')}</span></span>
|
||||
</span>}
|
||||
{showSwitchTopology &&
|
||||
<span
|
||||
title={topologyTitle}
|
||||
className="fa fa-long-arrow-left"
|
||||
onClick={this.handleShowTopologyForNode}>
|
||||
<span>Show in <span>{this.props.topologyId.replace(/-/g, ' ')}</span></span>
|
||||
</span>
|
||||
}
|
||||
<span
|
||||
title="Close details"
|
||||
className="fa fa-close close-details"
|
||||
@@ -190,35 +192,42 @@ class NodeDetails extends React.Component {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{showControls && <div className="node-details-controls-wrapper" style={styles.controls}>
|
||||
<NodeDetailsControls
|
||||
nodeId={this.props.nodeId}
|
||||
controls={details.controls}
|
||||
pending={pending}
|
||||
error={error} />
|
||||
</div>}
|
||||
{showControls &&
|
||||
<div className="node-details-controls-wrapper" style={styles.controls}>
|
||||
<NodeDetailsControls
|
||||
nodeId={this.props.nodeId}
|
||||
controls={details.controls}
|
||||
pending={pending}
|
||||
error={error} />
|
||||
</div>
|
||||
}
|
||||
|
||||
<div className="node-details-content">
|
||||
{details.metrics && <div className="node-details-content-section">
|
||||
<div className="node-details-content-section-header">Status</div>
|
||||
<NodeDetailsHealth
|
||||
metrics={details.metrics}
|
||||
topologyId={topologyId}
|
||||
/>
|
||||
</div>}
|
||||
{details.metadata && <div className="node-details-content-section">
|
||||
<div className="node-details-content-section-header">Info</div>
|
||||
<NodeDetailsInfo rows={details.metadata} matches={nodeMatches.get('metadata')} />
|
||||
</div>}
|
||||
{details.metrics &&
|
||||
<div className="node-details-content-section">
|
||||
<div className="node-details-content-section-header">Status</div>
|
||||
<NodeDetailsHealth
|
||||
metrics={details.metrics}
|
||||
topologyId={topologyId}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
{details.metadata &&
|
||||
<div className="node-details-content-section">
|
||||
<div className="node-details-content-section-header">Info</div>
|
||||
<NodeDetailsInfo rows={details.metadata} matches={nodeMatches.get('metadata')} />
|
||||
</div>
|
||||
}
|
||||
|
||||
{details.connections && details.connections.filter(cs => cs.connections.length > 0)
|
||||
.map(connections => (<div className="node-details-content-section" key={connections.id}>
|
||||
<NodeDetailsTable
|
||||
{...connections}
|
||||
nodes={connections.connections}
|
||||
nodeIdKey="nodeId"
|
||||
/>
|
||||
</div>
|
||||
.map(connections => (
|
||||
<div className="node-details-content-section" key={connections.id}>
|
||||
<NodeDetailsTable
|
||||
{...connections}
|
||||
nodes={connections.connections}
|
||||
nodeIdKey="nodeId"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{details.children && details.children.map(children => (
|
||||
@@ -233,10 +242,12 @@ class NodeDetails extends React.Component {
|
||||
<div className="node-details-content-section" key={table.id}>
|
||||
<div className="node-details-content-section-header">
|
||||
{table.label && table.label.length > 0 && table.label}
|
||||
{table.truncationCount > 0 && <span
|
||||
className="node-details-content-section-header-warning">
|
||||
<Warning text={getTruncationText(table.truncationCount)} />
|
||||
</span>}
|
||||
{table.truncationCount > 0 &&
|
||||
<span
|
||||
className="node-details-content-section-header-warning">
|
||||
<Warning text={getTruncationText(table.truncationCount)} />
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
{this.renderTable(table)}
|
||||
</div>
|
||||
|
||||
@@ -71,14 +71,16 @@ describe('NodeDetailsTable', () => {
|
||||
|
||||
describe('kubernetes_ip', () => {
|
||||
it('sorts by column', () => {
|
||||
component = TestUtils.renderIntoDocument(<Provider store={configureStore()}>
|
||||
<NodeDetailsTable
|
||||
columns={columns}
|
||||
sortedBy="kubernetes_ip"
|
||||
nodeIdKey="id"
|
||||
nodes={nodes}
|
||||
/>
|
||||
</Provider>);
|
||||
component = TestUtils.renderIntoDocument((
|
||||
<Provider store={configureStore()}>
|
||||
<NodeDetailsTable
|
||||
columns={columns}
|
||||
sortedBy="kubernetes_ip"
|
||||
nodeIdKey="id"
|
||||
nodes={nodes}
|
||||
/>
|
||||
</Provider>
|
||||
));
|
||||
|
||||
matchColumnValues('kubernetes_ip', [
|
||||
'10.44.253.255',
|
||||
@@ -105,14 +107,16 @@ describe('NodeDetailsTable', () => {
|
||||
|
||||
describe('kubernetes_namespace', () => {
|
||||
it('sorts by column', () => {
|
||||
component = TestUtils.renderIntoDocument(<Provider store={configureStore()}>
|
||||
<NodeDetailsTable
|
||||
columns={columns}
|
||||
sortedBy="kubernetes_namespace"
|
||||
nodeIdKey="id"
|
||||
nodes={nodes}
|
||||
/>
|
||||
</Provider>);
|
||||
component = TestUtils.renderIntoDocument((
|
||||
<Provider store={configureStore()}>
|
||||
<NodeDetailsTable
|
||||
columns={columns}
|
||||
sortedBy="kubernetes_namespace"
|
||||
nodeIdKey="id"
|
||||
nodes={nodes}
|
||||
/>
|
||||
</Provider>
|
||||
));
|
||||
|
||||
matchColumnValues('kubernetes_namespace', ['00000', '1111', '12', '5']);
|
||||
clickColumn('Namespace');
|
||||
|
||||
@@ -15,10 +15,12 @@ export default function NodeDetailsControls({
|
||||
|
||||
return (
|
||||
<div className="node-details-controls">
|
||||
{error && <div className="node-details-controls-error" title={error}>
|
||||
<span className="node-details-controls-error-icon fa fa-warning" />
|
||||
<span className="node-details-controls-error-messages">{error}</span>
|
||||
</div>}
|
||||
{error &&
|
||||
<div className="node-details-controls-error" title={error}>
|
||||
<span className="node-details-controls-error-icon fa fa-warning" />
|
||||
<span className="node-details-controls-error-messages">{error}</span>
|
||||
</div>
|
||||
}
|
||||
<span className="node-details-controls-buttons">
|
||||
{sortBy(controls, 'rank').map(control => <NodeDetailsControlButton
|
||||
nodeId={nodeId} control={control} pending={pending} key={control.id} />)}
|
||||
|
||||
@@ -38,11 +38,13 @@ export default class NodeDetailsRelatives extends React.Component {
|
||||
key={relative.id}
|
||||
match={matches.get(relative.id)}
|
||||
{...relative} />))}
|
||||
{showLimitAction && <span
|
||||
className="node-details-relatives-more"
|
||||
onClick={this.handleLimitClick}>
|
||||
{limitActionText}
|
||||
</span>}
|
||||
{showLimitAction &&
|
||||
<span
|
||||
className="node-details-relatives-more"
|
||||
onClick={this.handleLimitClick}>
|
||||
{limitActionText}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,9 +14,11 @@ export default class NodeResourcesMetricBoxInfo extends React.Component {
|
||||
<strong>
|
||||
{showExtendedInfo ? humanizedRelativeConsumption : humanizedAbsoluteConsumption}
|
||||
</strong> used
|
||||
{showExtendedInfo && <i>{' - '}
|
||||
({humanizedAbsoluteConsumption} / <strong>{humanizedTotalCapacity}</strong>)
|
||||
</i>}
|
||||
{showExtendedInfo &&
|
||||
<i>
|
||||
{' - '}({humanizedAbsoluteConsumption} / <strong>{humanizedTotalCapacity}</strong>)
|
||||
</i>
|
||||
}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -163,11 +163,13 @@ class Search extends React.Component {
|
||||
Search
|
||||
</span>
|
||||
</div>
|
||||
{!showPinnedSearches && <div className="search-hint">
|
||||
{getHint(nodes)} <span
|
||||
className="search-help-link fa fa-question-circle"
|
||||
onMouseDown={this.props.toggleHelp} />
|
||||
</div>}
|
||||
{!showPinnedSearches &&
|
||||
<div className="search-hint">
|
||||
{getHint(nodes)} <span
|
||||
className="search-help-link fa fa-question-circle"
|
||||
onMouseDown={this.props.toggleHelp} />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -94,24 +94,27 @@ class TimeControl extends React.Component {
|
||||
{isPausedNow && <span className="fa fa-pause" />}
|
||||
<span className="label">{isPausedNow ? 'Paused' : 'Pause'}</span>
|
||||
</span>
|
||||
{hasHistoricReports && <span
|
||||
className={className(isTimeTravelling)}
|
||||
onClick={this.handleTravelClick}
|
||||
title="Travel back in time">
|
||||
{isTimeTravelling && <span className="fa fa-clock-o" />}
|
||||
<span className="label">Time Travel</span>
|
||||
</span>}
|
||||
{hasHistoricReports &&
|
||||
<span
|
||||
className={className(isTimeTravelling)}
|
||||
onClick={this.handleTravelClick}
|
||||
title="Travel back in time">
|
||||
{isTimeTravelling && <span className="fa fa-clock-o" />}
|
||||
<span className="label">Time Travel</span>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
{(isPausedNow || isTimeTravelling) && <span
|
||||
className="time-control-info"
|
||||
title={moment(pausedAt).toISOString()}>
|
||||
Showing state from {moment(pausedAt).fromNow()}
|
||||
</span>}
|
||||
{isRunningNow && timeTravelTransitioning && <span
|
||||
className="time-control-info">
|
||||
Resuming the live state
|
||||
</span>}
|
||||
{(isPausedNow || isTimeTravelling) &&
|
||||
<span
|
||||
className="time-control-info"
|
||||
title={moment(pausedAt).toISOString()}>
|
||||
Showing state from {moment(pausedAt).fromNow()}
|
||||
</span>
|
||||
}
|
||||
{isRunningNow && timeTravelTransitioning &&
|
||||
<span className="time-control-info">Resuming the live state</span>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user