You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BadgeParams.tsx 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. import * as React from 'react';
  21. import * as classNames from 'classnames';
  22. import { getLocalizedMetricName, translate } from 'sonar-ui-common/helpers/l10n';
  23. import Select from 'sonar-ui-common/components/controls/Select';
  24. import { BadgeColors, BadgeType, BadgeOptions, BadgeFormats } from './utils';
  25. import { fetchWebApi } from '../../../api/web-api';
  26. interface Props {
  27. className?: string;
  28. metrics: T.Dict<T.Metric>;
  29. options: BadgeOptions;
  30. type: BadgeType;
  31. updateOptions: (options: Partial<BadgeOptions>) => void;
  32. }
  33. interface State {
  34. badgeMetrics: string[];
  35. }
  36. export default class BadgeParams extends React.PureComponent<Props> {
  37. mounted = false;
  38. state: State = { badgeMetrics: [] };
  39. componentDidMount() {
  40. this.mounted = true;
  41. this.fetchBadgeMetrics();
  42. }
  43. componentWillUnmount() {
  44. this.mounted = false;
  45. }
  46. fetchBadgeMetrics() {
  47. fetchWebApi(false).then(
  48. webservices => {
  49. if (this.mounted) {
  50. const domain = webservices.find(domain => domain.path === 'api/project_badges');
  51. const ws = domain && domain.actions.find(ws => ws.key === 'measure');
  52. const param = ws && ws.params && ws.params.find(param => param.key === 'metric');
  53. if (param && param.possibleValues) {
  54. this.setState({ badgeMetrics: param.possibleValues });
  55. }
  56. }
  57. },
  58. () => {}
  59. );
  60. }
  61. getColorOptions = () => {
  62. return ['white', 'black', 'orange'].map(color => ({
  63. label: translate('overview.badges.options.colors', color),
  64. value: color
  65. }));
  66. };
  67. getFormatOptions = () => {
  68. return ['md', 'url'].map(format => ({
  69. label: translate('overview.badges.options.formats', format),
  70. value: format
  71. }));
  72. };
  73. getMetricOptions = () => {
  74. return this.state.badgeMetrics.map(key => {
  75. const metric = this.props.metrics[key];
  76. return {
  77. value: key,
  78. label: metric ? getLocalizedMetricName(metric) : key
  79. };
  80. });
  81. };
  82. handleColorChange = ({ value }: { value: BadgeColors }) => {
  83. this.props.updateOptions({ color: value });
  84. };
  85. handleFormatChange = ({ value }: { value: BadgeFormats }) => {
  86. this.props.updateOptions({ format: value });
  87. };
  88. handleMetricChange = ({ value }: { value: string }) => {
  89. this.props.updateOptions({ metric: value });
  90. };
  91. renderBadgeType = (type: BadgeType, options: BadgeOptions) => {
  92. if (type === BadgeType.marketing) {
  93. return (
  94. <>
  95. <label className="spacer-right" htmlFor="badge-color">
  96. {translate('color')}:
  97. </label>
  98. <Select
  99. className="input-medium"
  100. clearable={false}
  101. name="badge-color"
  102. onChange={this.handleColorChange}
  103. options={this.getColorOptions()}
  104. searchable={false}
  105. value={options.color}
  106. />
  107. </>
  108. );
  109. } else if (type === BadgeType.measure) {
  110. return (
  111. <>
  112. <label className="spacer-right" htmlFor="badge-metric">
  113. {translate('overview.badges.metric')}:
  114. </label>
  115. <Select
  116. className="input-medium"
  117. clearable={false}
  118. name="badge-metric"
  119. onChange={this.handleMetricChange}
  120. options={this.getMetricOptions()}
  121. searchable={false}
  122. value={options.metric}
  123. />
  124. </>
  125. );
  126. } else {
  127. return null;
  128. }
  129. };
  130. render() {
  131. const { className, options, type } = this.props;
  132. return (
  133. <div className={className}>
  134. {this.renderBadgeType(type, options)}
  135. <label
  136. className={classNames('spacer-right', {
  137. 'big-spacer-left': type !== BadgeType.qualityGate
  138. })}
  139. htmlFor="badge-format">
  140. {translate('format')}:
  141. </label>
  142. <Select
  143. className="input-medium"
  144. clearable={false}
  145. name="badge-format"
  146. onChange={this.handleFormatChange}
  147. options={this.getFormatOptions()}
  148. searchable={false}
  149. value={this.props.options.format || 'md'}
  150. />
  151. </div>
  152. );
  153. }
  154. }