/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2019 SonarSource SA | |||||
* mailto:info AT sonarsource DOT com | |||||
* | |||||
* This program is free software; you can redistribute it and/or | |||||
* modify it under the terms of the GNU Lesser General Public | |||||
* License as published by the Free Software Foundation; either | |||||
* version 3 of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||||
* Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program; if not, write to the Free Software Foundation, | |||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||||
*/ | |||||
/* TODO remove this file */ | |||||
.line-chart-legend { | |||||
color: var(--blue); | |||||
} | |||||
.line-chart-legend.line-chart-legend-1 { | |||||
color: var(--darkBlue); | |||||
} | |||||
.line-chart-legend.line-chart-legend-2 { | |||||
color: #24c6e0; | |||||
} |
@import './components/menu.css'; | @import './components/menu.css'; | ||||
@import './components/page.css'; | @import './components/page.css'; | ||||
@import './components/component-name.css'; | @import './components/component-name.css'; | ||||
@import './components/graphics.css'; | |||||
@import './components/list-groups.css'; | @import './components/list-groups.css'; | ||||
@import './components/panels.css'; | @import './components/panels.css'; | ||||
@import './components/badges.css'; | @import './components/badges.css'; |
const hasData = hasDataValues(serie); | const hasData = hasDataValues(serie); | ||||
const legendItem = ( | const legendItem = ( | ||||
<GraphsLegendItem | <GraphsLegendItem | ||||
index={idx} | |||||
metric={serie.name} | metric={serie.name} | ||||
name={serie.translatedName} | name={serie.translatedName} | ||||
removeMetric={removeMetric} | removeMetric={removeMetric} | ||||
showWarning={!hasData} | showWarning={!hasData} | ||||
style={idx.toString()} | |||||
/> | /> | ||||
); | ); | ||||
if (!hasData) { | if (!hasData) { |
interface Props { | interface Props { | ||||
className?: string; | className?: string; | ||||
index: number; | |||||
metric: string; | metric: string; | ||||
name: string; | name: string; | ||||
showWarning?: boolean; | showWarning?: boolean; | ||||
style: string; | |||||
removeMetric?: (metric: string) => void; | removeMetric?: (metric: string) => void; | ||||
} | } | ||||
{this.props.showWarning ? ( | {this.props.showWarning ? ( | ||||
<AlertWarnIcon className="spacer-right" /> | <AlertWarnIcon className="spacer-right" /> | ||||
) : ( | ) : ( | ||||
<ChartLegendIcon | |||||
className={classNames( | |||||
'text-middle spacer-right line-chart-legend', | |||||
'line-chart-legend-' + this.props.style | |||||
)} | |||||
/> | |||||
<ChartLegendIcon className="text-middle spacer-right" index={this.props.index} /> | |||||
)} | )} | ||||
<span className="text-middle">{this.props.name}</span> | <span className="text-middle">{this.props.name}</span> | ||||
{isActionable && ( | {isActionable && ( |
{series.map((serie, idx) => ( | {series.map((serie, idx) => ( | ||||
<GraphsLegendItem | <GraphsLegendItem | ||||
className="big-spacer-left big-spacer-right" | className="big-spacer-left big-spacer-right" | ||||
index={idx} | |||||
key={serie.name} | key={serie.name} | ||||
metric={serie.name} | metric={serie.name} | ||||
name={serie.translatedName} | name={serie.translatedName} | ||||
style={idx.toString()} | |||||
/> | /> | ||||
))} | ))} | ||||
</div> | </div> |
if (this.props.graph === DEFAULT_GRAPH) { | if (this.props.graph === DEFAULT_GRAPH) { | ||||
return ( | return ( | ||||
<GraphsTooltipsContentIssues | <GraphsTooltipsContentIssues | ||||
index={idx} | |||||
key={serie.name} | key={serie.name} | ||||
measuresHistory={this.props.measuresHistory} | measuresHistory={this.props.measuresHistory} | ||||
name={serie.name} | name={serie.name} | ||||
style={idx.toString()} | |||||
tooltipIdx={tooltipIdx} | tooltipIdx={tooltipIdx} | ||||
translatedName={serie.translatedName} | translatedName={serie.translatedName} | ||||
value={this.props.formatValue(point.y)} | value={this.props.formatValue(point.y)} | ||||
} else { | } else { | ||||
return ( | return ( | ||||
<GraphsTooltipsContent | <GraphsTooltipsContent | ||||
index={idx} | |||||
key={serie.name} | key={serie.name} | ||||
name={serie.name} | name={serie.name} | ||||
style={idx.toString()} | |||||
translatedName={serie.translatedName} | translatedName={serie.translatedName} | ||||
value={this.props.formatValue(point.y)} | value={this.props.formatValue(point.y)} | ||||
/> | /> |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import * as classNames from 'classnames'; | |||||
import ChartLegendIcon from '../../../components/icons-components/ChartLegendIcon'; | import ChartLegendIcon from '../../../components/icons-components/ChartLegendIcon'; | ||||
interface Props { | interface Props { | ||||
name: string; | name: string; | ||||
style: string; | |||||
index: number; | |||||
translatedName: string; | translatedName: string; | ||||
value: string; | value: string; | ||||
} | } | ||||
export default function GraphsTooltipsContent({ name, style, translatedName, value }: Props) { | |||||
export default function GraphsTooltipsContent({ name, index, translatedName, value }: Props) { | |||||
return ( | return ( | ||||
<tr className="project-activity-graph-tooltip-line" key={name}> | <tr className="project-activity-graph-tooltip-line" key={name}> | ||||
<td className="thin"> | <td className="thin"> | ||||
<ChartLegendIcon | |||||
className={classNames('spacer-right line-chart-legend', 'line-chart-legend-' + style)} | |||||
/> | |||||
<ChartLegendIcon className="spacer-right" index={index} /> | |||||
</td> | </td> | ||||
<td className="project-activity-graph-tooltip-value text-right spacer-right thin">{value}</td> | <td className="project-activity-graph-tooltip-value text-right spacer-right thin">{value}</td> | ||||
<td>{translatedName}</td> | <td>{translatedName}</td> |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import * as classNames from 'classnames'; | |||||
import ChartLegendIcon from '../../../components/icons-components/ChartLegendIcon'; | import ChartLegendIcon from '../../../components/icons-components/ChartLegendIcon'; | ||||
import Rating from '../../../components/ui/Rating'; | import Rating from '../../../components/ui/Rating'; | ||||
import { MeasureHistory } from '../utils'; | import { MeasureHistory } from '../utils'; | ||||
interface Props { | interface Props { | ||||
index: number; | |||||
measuresHistory: MeasureHistory[]; | measuresHistory: MeasureHistory[]; | ||||
name: string; | name: string; | ||||
style: string; | |||||
tooltipIdx: number; | tooltipIdx: number; | ||||
translatedName: string; | translatedName: string; | ||||
value: string; | value: string; | ||||
return ( | return ( | ||||
<tr className="project-activity-graph-tooltip-issues-line" key={props.name}> | <tr className="project-activity-graph-tooltip-issues-line" key={props.name}> | ||||
<td className="thin"> | <td className="thin"> | ||||
<ChartLegendIcon | |||||
className={classNames( | |||||
'spacer-right line-chart-legend', | |||||
'line-chart-legend-' + props.style | |||||
)} | |||||
/> | |||||
<ChartLegendIcon className="spacer-right" index={props.index} /> | |||||
</td> | </td> | ||||
<td className="text-right spacer-right"> | <td className="text-right spacer-right"> | ||||
<span className="project-activity-graph-tooltip-value">{props.value}</span> | <span className="project-activity-graph-tooltip-value">{props.value}</span> |
import GraphsLegendItem from '../GraphsLegendItem'; | import GraphsLegendItem from '../GraphsLegendItem'; | ||||
it('should render correctly a legend', () => { | it('should render correctly a legend', () => { | ||||
expect(shallow(<GraphsLegendItem metric="bugs" name="Bugs" style="2" />)).toMatchSnapshot(); | |||||
expect(shallow(<GraphsLegendItem index={2} metric="bugs" name="Bugs" />)).toMatchSnapshot(); | |||||
}); | }); | ||||
it('should render correctly an actionable legend', () => { | it('should render correctly an actionable legend', () => { | ||||
shallow( | shallow( | ||||
<GraphsLegendItem | <GraphsLegendItem | ||||
className="myclass" | className="myclass" | ||||
index={1} | |||||
metric="foo" | metric="foo" | ||||
name="Foo" | name="Foo" | ||||
removeMetric={() => {}} | removeMetric={() => {}} | ||||
style="1" | |||||
/> | /> | ||||
) | ) | ||||
).toMatchSnapshot(); | ).toMatchSnapshot(); | ||||
it('should render correctly legends with warning', () => { | it('should render correctly legends with warning', () => { | ||||
expect( | expect( | ||||
shallow( | shallow( | ||||
<GraphsLegendItem className="myclass" metric="foo" name="Foo" showWarning={true} style="1" /> | |||||
<GraphsLegendItem className="myclass" index={1} metric="foo" name="Foo" showWarning={true} /> | |||||
) | ) | ||||
).toMatchSnapshot(); | ).toMatchSnapshot(); | ||||
}); | }); |
import GraphsTooltipsContent from '../GraphsTooltipsContent'; | import GraphsTooltipsContent from '../GraphsTooltipsContent'; | ||||
const DEFAULT_PROPS = { | const DEFAULT_PROPS = { | ||||
index: 1, | |||||
name: 'code_smells', | name: 'code_smells', | ||||
style: '1', | |||||
translatedName: 'Code Smells', | translatedName: 'Code Smells', | ||||
value: '1.2k' | value: '1.2k' | ||||
}; | }; |
]; | ]; | ||||
const DEFAULT_PROPS = { | const DEFAULT_PROPS = { | ||||
index: 2, | |||||
measuresHistory: MEASURES_ISSUES, | measuresHistory: MEASURES_ISSUES, | ||||
name: 'bugs', | name: 'bugs', | ||||
style: '2', | |||||
tooltipIdx: 1, | tooltipIdx: 1, | ||||
translatedName: 'Bugs', | translatedName: 'Bugs', | ||||
value: '1.2k' | value: '1.2k' |
key="bugs" | key="bugs" | ||||
> | > | ||||
<GraphsLegendItem | <GraphsLegendItem | ||||
index={0} | |||||
metric="bugs" | metric="bugs" | ||||
name="Bugs" | name="Bugs" | ||||
removeMetric={[Function]} | removeMetric={[Function]} | ||||
showWarning={false} | showWarning={false} | ||||
style="0" | |||||
/> | /> | ||||
</span> | </span> | ||||
<span | <span | ||||
key="my_metric" | key="my_metric" | ||||
> | > | ||||
<GraphsLegendItem | <GraphsLegendItem | ||||
index={1} | |||||
metric="my_metric" | metric="my_metric" | ||||
name="My Metric" | name="My Metric" | ||||
removeMetric={[Function]} | removeMetric={[Function]} | ||||
showWarning={false} | showWarning={false} | ||||
style="1" | |||||
/> | /> | ||||
</span> | </span> | ||||
<Tooltip | <Tooltip | ||||
className="spacer-left spacer-right" | className="spacer-left spacer-right" | ||||
> | > | ||||
<GraphsLegendItem | <GraphsLegendItem | ||||
index={2} | |||||
metric="foo" | metric="foo" | ||||
name="Foo" | name="Foo" | ||||
removeMetric={[Function]} | removeMetric={[Function]} | ||||
showWarning={true} | showWarning={true} | ||||
style="2" | |||||
/> | /> | ||||
</span> | </span> | ||||
</Tooltip> | </Tooltip> |
className="" | className="" | ||||
> | > | ||||
<ChartLegendIcon | <ChartLegendIcon | ||||
className="text-middle spacer-right line-chart-legend line-chart-legend-2" | |||||
className="text-middle spacer-right" | |||||
index={2} | |||||
/> | /> | ||||
<span | <span | ||||
className="text-middle" | className="text-middle" | ||||
className="project-activity-graph-legend-actionable myclass" | className="project-activity-graph-legend-actionable myclass" | ||||
> | > | ||||
<ChartLegendIcon | <ChartLegendIcon | ||||
className="text-middle spacer-right line-chart-legend line-chart-legend-1" | |||||
className="text-middle spacer-right" | |||||
index={1} | |||||
/> | /> | ||||
<span | <span | ||||
className="text-middle" | className="text-middle" |
> | > | ||||
<GraphsLegendItem | <GraphsLegendItem | ||||
className="big-spacer-left big-spacer-right" | className="big-spacer-left big-spacer-right" | ||||
index={0} | |||||
key="bugs" | key="bugs" | ||||
metric="bugs" | metric="bugs" | ||||
name="Bugs" | name="Bugs" | ||||
style="0" | |||||
/> | /> | ||||
<GraphsLegendItem | <GraphsLegendItem | ||||
className="big-spacer-left big-spacer-right" | className="big-spacer-left big-spacer-right" | ||||
index={1} | |||||
key="code_smells" | key="code_smells" | ||||
metric="code_smells" | metric="code_smells" | ||||
name="Code Smells" | name="Code Smells" | ||||
style="1" | |||||
/> | /> | ||||
</div> | </div> | ||||
`; | `; |
> | > | ||||
<tbody> | <tbody> | ||||
<GraphsTooltipsContentIssues | <GraphsTooltipsContentIssues | ||||
index={0} | |||||
key="bugs" | key="bugs" | ||||
measuresHistory={Array []} | measuresHistory={Array []} | ||||
name="bugs" | name="bugs" | ||||
style="0" | |||||
tooltipIdx={0} | tooltipIdx={0} | ||||
translatedName="Bugs" | translatedName="Bugs" | ||||
value="Formated.3" | value="Formated.3" | ||||
/> | /> | ||||
<GraphsTooltipsContentIssues | <GraphsTooltipsContentIssues | ||||
index={1} | |||||
key="code_smells" | key="code_smells" | ||||
measuresHistory={Array []} | measuresHistory={Array []} | ||||
name="code_smells" | name="code_smells" | ||||
style="1" | |||||
tooltipIdx={0} | tooltipIdx={0} | ||||
translatedName="Code Smells" | translatedName="Code Smells" | ||||
value="Formated.18" | value="Formated.18" | ||||
/> | /> | ||||
<GraphsTooltipsContentIssues | <GraphsTooltipsContentIssues | ||||
index={2} | |||||
key="vulnerabilities" | key="vulnerabilities" | ||||
measuresHistory={Array []} | measuresHistory={Array []} | ||||
name="vulnerabilities" | name="vulnerabilities" | ||||
style="2" | |||||
tooltipIdx={0} | tooltipIdx={0} | ||||
translatedName="Vulnerabilities" | translatedName="Vulnerabilities" | ||||
value="Formated.0" | value="Formated.0" | ||||
> | > | ||||
<tbody> | <tbody> | ||||
<GraphsTooltipsContent | <GraphsTooltipsContent | ||||
index={0} | |||||
key="bugs" | key="bugs" | ||||
name="bugs" | name="bugs" | ||||
style="0" | |||||
translatedName="Bugs" | translatedName="Bugs" | ||||
value="Formated.0" | value="Formated.0" | ||||
/> | /> | ||||
<GraphsTooltipsContent | <GraphsTooltipsContent | ||||
index={1} | |||||
key="code_smells" | key="code_smells" | ||||
name="code_smells" | name="code_smells" | ||||
style="1" | |||||
translatedName="Code Smells" | translatedName="Code Smells" | ||||
value="Formated.15" | value="Formated.15" | ||||
/> | /> | ||||
<GraphsTooltipsContent | <GraphsTooltipsContent | ||||
index={2} | |||||
key="vulnerabilities" | key="vulnerabilities" | ||||
name="vulnerabilities" | name="vulnerabilities" | ||||
style="2" | |||||
translatedName="Vulnerabilities" | translatedName="Vulnerabilities" | ||||
value="Formated.1" | value="Formated.1" | ||||
/> | /> |
className="thin" | className="thin" | ||||
> | > | ||||
<ChartLegendIcon | <ChartLegendIcon | ||||
className="spacer-right line-chart-legend line-chart-legend-1" | |||||
className="spacer-right" | |||||
index={1} | |||||
/> | /> | ||||
</td> | </td> | ||||
<td | <td |
className="thin" | className="thin" | ||||
> | > | ||||
<ChartLegendIcon | <ChartLegendIcon | ||||
className="spacer-right line-chart-legend line-chart-legend-2" | |||||
className="spacer-right" | |||||
index={2} | |||||
/> | /> | ||||
</td> | </td> | ||||
<td | <td | ||||
className="thin" | className="thin" | ||||
> | > | ||||
<ChartLegendIcon | <ChartLegendIcon | ||||
className="spacer-right line-chart-legend line-chart-legend-2" | |||||
className="spacer-right" | |||||
index={2} | |||||
/> | /> | ||||
</td> | </td> | ||||
<td | <td |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import Icon, { IconProps } from './Icon'; | |||||
import Icon from './Icon'; | |||||
import * as theme from '../../app/theme'; | |||||
export default function ChartLegendIcon({ className, fill = 'currentColor', size }: IconProps) { | |||||
interface Props { | |||||
className?: string; | |||||
index: number; | |||||
size?: number; | |||||
} | |||||
const COLORS = [theme.blue, theme.darkBlue, '#24c6e0']; | |||||
export default function ChartLegendIcon({ className, index, size }: Props) { | |||||
const fill = COLORS[index] || COLORS[0]; | |||||
return ( | return ( | ||||
<Icon className={className} size={size}> | <Icon className={className} size={size}> | ||||
<path | <path |
} | } | ||||
return ( | return ( | ||||
<PreviewGraphTooltipsContent | <PreviewGraphTooltipsContent | ||||
index={idx} | |||||
key={serie.name} | key={serie.name} | ||||
style={idx.toString()} | |||||
translatedName={serie.translatedName} | translatedName={serie.translatedName} | ||||
value={this.props.formatValue(point.y)} | value={this.props.formatValue(point.y)} | ||||
/> | /> |
import ChartLegendIcon from '../icons-components/ChartLegendIcon'; | import ChartLegendIcon from '../icons-components/ChartLegendIcon'; | ||||
interface Props { | interface Props { | ||||
style: string; | |||||
index: number; | |||||
translatedName: string; | translatedName: string; | ||||
value: string; | value: string; | ||||
} | } | ||||
export default function PreviewGraphTooltipsContent({ style, translatedName, value }: Props) { | |||||
export default function PreviewGraphTooltipsContent({ index, translatedName, value }: Props) { | |||||
return ( | return ( | ||||
<tr className="overview-analysis-graph-tooltip-line"> | <tr className="overview-analysis-graph-tooltip-line"> | ||||
<td className="thin"> | <td className="thin"> | ||||
<ChartLegendIcon | |||||
className={'little-spacer-right line-chart-legend line-chart-legend-' + style} | |||||
/> | |||||
<ChartLegendIcon className="little-spacer-right" index={index} /> | |||||
</td> | </td> | ||||
<td className="overview-analysis-graph-tooltip-value text-right little-spacer-right thin"> | <td className="overview-analysis-graph-tooltip-value text-right little-spacer-right thin"> | ||||
{value} | {value} |
import PreviewGraphTooltipsContent from '../PreviewGraphTooltipsContent'; | import PreviewGraphTooltipsContent from '../PreviewGraphTooltipsContent'; | ||||
const DEFAULT_PROPS = { | const DEFAULT_PROPS = { | ||||
style: '1', | |||||
index: 1, | |||||
translatedName: 'Code Smells', | translatedName: 'Code Smells', | ||||
value: '1.2k' | value: '1.2k' | ||||
}; | }; |
> | > | ||||
<tbody> | <tbody> | ||||
<PreviewGraphTooltipsContent | <PreviewGraphTooltipsContent | ||||
index={0} | |||||
key="code_smells" | key="code_smells" | ||||
style="0" | |||||
translatedName="Code Smells" | translatedName="Code Smells" | ||||
value="Formated.15" | value="Formated.15" | ||||
/> | /> | ||||
<PreviewGraphTooltipsContent | <PreviewGraphTooltipsContent | ||||
index={1} | |||||
key="bugs" | key="bugs" | ||||
style="1" | |||||
translatedName="Bugs" | translatedName="Bugs" | ||||
value="Formated.0" | value="Formated.0" | ||||
/> | /> | ||||
<PreviewGraphTooltipsContent | <PreviewGraphTooltipsContent | ||||
index={2} | |||||
key="vulnerabilities" | key="vulnerabilities" | ||||
style="2" | |||||
translatedName="Vulnerabilities" | translatedName="Vulnerabilities" | ||||
value="Formated.1" | value="Formated.1" | ||||
/> | /> |
className="thin" | className="thin" | ||||
> | > | ||||
<ChartLegendIcon | <ChartLegendIcon | ||||
className="little-spacer-right line-chart-legend line-chart-legend-1" | |||||
className="little-spacer-right" | |||||
index={1} | |||||
/> | /> | ||||
</td> | </td> | ||||
<td | <td |