* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { getJSON, post, postJSON } from 'sonar-ui-common/helpers/request';
+import { getJSON } from 'sonar-ui-common/helpers/request';
import throwGlobalError from '../app/utils/throwGlobalError';
export interface MetricsResponse {
});
}
}
-
-export function getMetricDomains(): Promise<string[]> {
- return getJSON('/api/metrics/domains').then(r => r.domains, throwGlobalError);
-}
-
-export function getMetricTypes(): Promise<string[]> {
- return getJSON('/api/metrics/types').then(r => r.types, throwGlobalError);
-}
-
-export function createMetric(data: {
- description?: string;
- domain?: string;
- key: string;
- name: string;
- type: string;
-}): Promise<T.Metric> {
- return postJSON('/api/metrics/create', data).catch(throwGlobalError);
-}
-
-export function updateMetric(data: {
- description?: string;
- domain?: string;
- id: string;
- key?: string;
- name?: string;
- type?: string;
-}) {
- return post('/api/metrics/update', data).catch(throwGlobalError);
-}
-
-export function deleteMetric(data: { keys: string }) {
- return post('/api/metrics/delete', data).catch(throwGlobalError);
-}
{translate('property.category.security.encryption')}
</IndexLink>
</li>
- <li>
- <IndexLink activeClassName="active" to="/admin/custom_metrics">
- {translate('custom_metrics.page')}
- </IndexLink>
- </li>
<li>
<IndexLink activeClassName="active" to="/admin/webhooks">
{translate('webhooks.page')}
property.category.security.encryption
</IndexLink>
</li>
- <li>
- <IndexLink
- activeClassName="active"
- to="/admin/custom_metrics"
- >
- custom_metrics.page
- </IndexLink>
- </li>
<li>
<IndexLink
activeClassName="active"
property.category.security.encryption
</IndexLink>
</li>
- <li>
- <IndexLink
- activeClassName="active"
- to="/admin/custom_metrics"
- >
- custom_metrics.page
- </IndexLink>
- </li>
<li>
<IndexLink
activeClassName="active"
import codeRoutes from '../../apps/code/routes';
import codingRulesRoutes from '../../apps/coding-rules/routes';
import componentMeasuresRoutes from '../../apps/component-measures/routes';
-import customMetricsRoutes from '../../apps/custom-metrics/routes';
import documentationRoutes from '../../apps/documentation/routes';
import groupsRoutes from '../../apps/groups/routes';
import Issues from '../../apps/issues/components/AppContainer';
)}
/>
<RouteWithChildRoutes path="background_tasks" childRoutes={backgroundTasksRoutes} />
- <RouteWithChildRoutes path="custom_metrics" childRoutes={customMetricsRoutes} />
<RouteWithChildRoutes path="groups" childRoutes={groupsRoutes} />
<RouteWithChildRoutes path="permission_templates" childRoutes={permissionTemplatesRoutes} />
<RouteWithChildRoutes path="permissions" childRoutes={globalPermissionsRoutes} />
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import * as React from 'react';
-import { Helmet } from 'react-helmet-async';
-import ListFooter from 'sonar-ui-common/components/controls/ListFooter';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import {
- createMetric,
- deleteMetric,
- getMetricDomains,
- getMetrics,
- getMetricTypes,
- MetricsResponse,
- updateMetric
-} from '../../../api/metrics';
-import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
-import { MetricProps } from './Form';
-import Header from './Header';
-import List from './List';
-
-interface Props {}
-
-interface State {
- domains?: string[];
- loading: boolean;
- metrics?: T.Metric[];
- paging?: T.Paging;
- types?: string[];
-}
-
-const PAGE_SIZE = 50;
-
-export default class App extends React.PureComponent<Props, State> {
- mounted = false;
- state: State = { loading: true };
-
- componentDidMount() {
- this.mounted = true;
- this.fetchData();
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- fetchData = () => {
- Promise.all([
- getMetricDomains(),
- getMetricTypes(),
- getMetrics({ isCustom: true, ps: PAGE_SIZE })
- ]).then(([domains, types, metricsResponse]) => {
- if (this.mounted) {
- this.setState({
- domains,
- loading: false,
- metrics: metricsResponse.metrics,
- paging: this.getPaging(metricsResponse),
- types
- });
- }
- }, this.stopLoading);
- };
-
- fetchMore = () => {
- const { paging } = this.state;
- if (paging) {
- this.setState({ loading: true });
- getMetrics({ isCustom: true, p: paging.pageIndex + 1, ps: PAGE_SIZE }).then(
- metricsResponse => {
- if (this.mounted) {
- this.setState(({ metrics = [] }: State) => ({
- loading: false,
- metrics: [...metrics, ...metricsResponse.metrics],
- paging: this.getPaging(metricsResponse)
- }));
- }
- },
- this.stopLoading
- );
- }
- };
-
- stopLoading = () => {
- if (this.mounted) {
- this.setState({ loading: false });
- }
- };
-
- getPaging = (response: MetricsResponse): T.Paging => ({
- pageIndex: response.p,
- pageSize: response.ps,
- total: response.total
- });
-
- handleCreate = (data: MetricProps) => {
- return createMetric(data).then(metric => {
- if (this.mounted) {
- this.setState(({ metrics = [], paging }: State) => ({
- metrics: [...metrics, metric],
- paging: paging && { ...paging, total: paging.total + 1 }
- }));
- }
- });
- };
-
- handleEdit = (data: { id: string } & MetricProps) => {
- return updateMetric(data).then(() => {
- if (this.mounted) {
- this.setState(({ metrics = [] }: State) => ({
- metrics: metrics.map(metric => (metric.id === data.id ? { ...metric, ...data } : metric))
- }));
- }
- });
- };
-
- handleDelete = (metricKey: string) => {
- return deleteMetric({ keys: metricKey }).then(() => {
- if (this.mounted) {
- this.setState(({ metrics = [], paging }: State) => ({
- metrics: metrics.filter(metric => metric.key !== metricKey),
- paging: paging && { ...paging, total: paging.total - 1 }
- }));
- }
- });
- };
-
- render() {
- const { domains, loading, metrics, paging, types } = this.state;
-
- return (
- <>
- <Suggestions suggestions="custom_metrics" />
- <Helmet defer={false} title={translate('custom_metrics.page')} />
- <div className="page page-limited" id="custom-metrics-page">
- <Header domains={domains} loading={loading} onCreate={this.handleCreate} types={types} />
- {metrics && (
- <List
- domains={domains}
- metrics={metrics}
- onDelete={this.handleDelete}
- onEdit={this.handleEdit}
- types={types}
- />
- )}
- {metrics && paging && (
- <ListFooter
- count={metrics.length}
- loadMore={this.fetchMore}
- ready={!loading}
- total={paging.total}
- />
- )}
- </div>
- </>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import * as React from 'react';
-import { Button } from 'sonar-ui-common/components/controls/buttons';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import Form, { MetricProps } from './Form';
-
-interface Props {
- domains: string[];
- onCreate: (data: MetricProps) => Promise<void>;
- types: string[];
-}
-
-interface State {
- modal: boolean;
-}
-
-export default class CreateButton extends React.PureComponent<Props, State> {
- mounted = false;
- state: State = { modal: false };
-
- componentDidMount() {
- this.mounted = true;
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- handleClick = () => {
- this.setState({ modal: true });
- };
-
- handleClose = () => {
- if (this.mounted) {
- this.setState({ modal: false });
- }
- };
-
- render() {
- return (
- <>
- <Button id="metrics-create" onClick={this.handleClick}>
- {translate('custom_metrics.create_metric')}
- </Button>
- {this.state.modal && (
- <Form
- confirmButtonText={translate('create')}
- domains={this.props.domains}
- header={translate('custom_metrics.create_metric')}
- onClose={this.handleClose}
- onSubmit={this.props.onCreate}
- types={this.props.types}
- />
- )}
- </>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import * as React from 'react';
-import { ResetButtonLink, SubmitButton } from 'sonar-ui-common/components/controls/buttons';
-import SimpleModal from 'sonar-ui-common/components/controls/SimpleModal';
-import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
-import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n';
-
-interface Props {
- metric: T.Metric;
- onClose: () => void;
- onSubmit: () => Promise<void>;
-}
-
-export default function DeleteForm({ metric, onClose, onSubmit }: Props) {
- const header = translate('custom_metrics.delete_metric');
-
- return (
- <SimpleModal header={header} onClose={onClose} onSubmit={onSubmit}>
- {({ onCloseClick, onFormSubmit, submitting }) => (
- <form onSubmit={onFormSubmit}>
- <header className="modal-head">
- <h2>{header}</h2>
- </header>
-
- <div className="modal-body">
- {translateWithParameters('custom_metrics.delete_metric.confirmation', metric.name)}
- </div>
-
- <footer className="modal-foot">
- <DeferredSpinner className="spacer-right" loading={submitting} />
- <SubmitButton className="button-red" disabled={submitting}>
- {translate('delete')}
- </SubmitButton>
- <ResetButtonLink disabled={submitting} onClick={onCloseClick}>
- {translate('cancel')}
- </ResetButtonLink>
- </footer>
- </form>
- )}
- </SimpleModal>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import * as React from 'react';
-import { ResetButtonLink, SubmitButton } from 'sonar-ui-common/components/controls/buttons';
-import Select, { Creatable } from 'sonar-ui-common/components/controls/Select';
-import SimpleModal from 'sonar-ui-common/components/controls/SimpleModal';
-import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
-import MandatoryFieldMarker from 'sonar-ui-common/components/ui/MandatoryFieldMarker';
-import MandatoryFieldsExplanation from 'sonar-ui-common/components/ui/MandatoryFieldsExplanation';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-
-export interface MetricProps {
- description: string;
- domain?: string;
- key: string;
- name: string;
- type: string;
-}
-
-interface Props {
- confirmButtonText: string;
- domains: string[];
- metric?: T.Metric;
- header: string;
- onClose: () => void;
- onSubmit: (data: MetricProps) => Promise<void>;
- types: string[];
-}
-
-interface State extends MetricProps {}
-
-export default class Form extends React.PureComponent<Props, State> {
- constructor(props: Props) {
- super(props);
- this.state = {
- description: (props.metric && props.metric.description) || '',
- domain: props.metric && props.metric.domain,
- key: (props.metric && props.metric.key) || '',
- name: (props.metric && props.metric.name) || '',
- type: (props.metric && props.metric.type) || 'INT'
- };
- }
-
- handleSubmit = () => {
- return this.props
- .onSubmit({
- description: this.state.description,
- domain: this.state.domain,
- key: this.state.key,
- name: this.state.name,
- type: this.state.type
- })
- .then(this.props.onClose);
- };
-
- handleKeyChange = (event: React.ChangeEvent<HTMLInputElement>) => {
- this.setState({ key: event.currentTarget.value });
- };
-
- handleDescriptionChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
- this.setState({ description: event.currentTarget.value });
- };
-
- handleNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
- this.setState({ name: event.currentTarget.value });
- };
-
- handleDomainChange = (option: { value: string } | null) => {
- this.setState({ domain: option ? option.value : undefined });
- };
-
- handleTypeChange = ({ value }: { value: string }) => {
- this.setState({ type: value });
- };
-
- render() {
- const domains = [...this.props.domains];
- if (this.state.domain) {
- domains.push(this.state.domain);
- }
-
- return (
- <SimpleModal
- header={this.props.header}
- onClose={this.props.onClose}
- onSubmit={this.handleSubmit}
- size="small">
- {({ onCloseClick, onFormSubmit, submitting }) => (
- <form onSubmit={onFormSubmit}>
- <header className="modal-head">
- <h2>{this.props.header}</h2>
- </header>
-
- <div className="modal-body modal-container">
- <MandatoryFieldsExplanation className="modal-field" />
-
- <div className="modal-field">
- <label htmlFor="create-metric-key">
- {translate('key')}
- <MandatoryFieldMarker />
- </label>
- <input
- autoFocus={true}
- id="create-metric-key"
- maxLength={64}
- name="key"
- onChange={this.handleKeyChange}
- required={true}
- type="text"
- value={this.state.key}
- />
- </div>
- <div className="modal-field">
- <label htmlFor="create-metric-name">
- {translate('name')}
- <MandatoryFieldMarker />
- </label>
- <input
- id="create-metric-name"
- maxLength={64}
- name="name"
- onChange={this.handleNameChange}
- required={true}
- type="text"
- value={this.state.name}
- />
- </div>
- <div className="modal-field">
- <label htmlFor="create-metric-description">{translate('description')}</label>
- <textarea
- id="create-metric-description"
- name="description"
- onChange={this.handleDescriptionChange}
- value={this.state.description}
- />
- </div>
- <div className="modal-field">
- <label htmlFor="create-metric-domain">{translate('custom_metrics.domain')}</label>
- <Creatable
- id="create-metric-domain"
- onChange={this.handleDomainChange}
- options={domains.map(domain => ({ label: domain, value: domain }))}
- value={this.state.domain}
- />
- </div>
- <div className="modal-field">
- <label htmlFor="create-metric-type">
- {translate('type')}
- <MandatoryFieldMarker />
- </label>
- <Select
- clearable={false}
- id="create-metric-type"
- onChange={this.handleTypeChange}
- options={this.props.types.map(type => ({
- label: translate('metric.type', type),
- value: type
- }))}
- value={this.state.type}
- />
- </div>
- </div>
-
- <footer className="modal-foot">
- <DeferredSpinner className="spacer-right" loading={submitting} />
- <SubmitButton disabled={submitting} id="create-metric-submit">
- {this.props.confirmButtonText}
- </SubmitButton>
- <ResetButtonLink
- disabled={submitting}
- id="create-metric-cancel"
- onClick={onCloseClick}>
- {translate('cancel')}
- </ResetButtonLink>
- </footer>
- </form>
- )}
- </SimpleModal>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import * as React from 'react';
-import { Alert } from 'sonar-ui-common/components/ui/Alert';
-import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import CreateButton from './CreateButton';
-import { MetricProps } from './Form';
-
-interface Props {
- domains: string[] | undefined;
- loading: boolean;
- onCreate: (data: MetricProps) => Promise<void>;
- types: string[] | undefined;
-}
-
-export default function Header({ domains, loading, onCreate, types }: Props) {
- return (
- <header className="page-header" id="custom-metrics-header">
- <h1 className="page-title">{translate('custom_metrics.page')}</h1>
- <DeferredSpinner loading={loading} />
- <div className="page-actions">
- {domains && types && <CreateButton domains={domains} onCreate={onCreate} types={types} />}
- </div>
- <div className="page-description">
- <Alert display="inline" variant="error">
- {translate('custom_metrics.deprecated')}
- </Alert>
- <p>{translate('custom_metrics.page.description')}</p>
- </div>
- </header>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import * as React from 'react';
-import ActionsDropdown, {
- ActionsDropdownDivider,
- ActionsDropdownItem
-} from 'sonar-ui-common/components/controls/ActionsDropdown';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import DeleteForm from './DeleteForm';
-import Form, { MetricProps } from './Form';
-
-interface Props {
- domains?: string[];
- metric: T.Metric;
- onDelete: (metricKey: string) => Promise<void>;
- onEdit: (data: { id: string } & MetricProps) => Promise<void>;
- types?: string[];
-}
-
-interface State {
- deleteForm: boolean;
- editForm: boolean;
-}
-
-export default class Item extends React.PureComponent<Props, State> {
- mounted = false;
-
- state: State = { deleteForm: false, editForm: false };
-
- componentDidMount() {
- this.mounted = true;
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- handleEditClick = () => {
- this.setState({ editForm: true });
- };
-
- handleDeleteClick = () => {
- this.setState({ deleteForm: true });
- };
-
- closeEditForm = () => {
- if (this.mounted) {
- this.setState({ editForm: false });
- }
- };
-
- closeDeleteForm = () => {
- if (this.mounted) {
- this.setState({ deleteForm: false });
- }
- };
-
- handleEditFormSubmit = (data: MetricProps) => {
- return this.props.onEdit({ id: this.props.metric.id, ...data });
- };
-
- handleDeleteFormSubmit = () => {
- return this.props.onDelete(this.props.metric.key);
- };
-
- render() {
- const { domains, metric, types } = this.props;
-
- return (
- <tr data-metric={metric.key}>
- <td className="width-30">
- <div>
- <strong className="js-metric-name">{metric.name}</strong>
- <span className="js-metric-key note little-spacer-left">{metric.key}</span>
- </div>
- </td>
-
- <td className="width-20">
- <span className="js-metric-domain">{metric.domain}</span>
- </td>
-
- <td className="width-20">
- <span className="js-metric-type">{translate('metric.type', metric.type)}</span>
- </td>
-
- <td className="width-20" title={metric.description}>
- <span className="js-metric-description">{metric.description}</span>
- </td>
-
- <td className="thin nowrap">
- <ActionsDropdown>
- {domains && types && (
- <ActionsDropdownItem className="js-metric-update" onClick={this.handleEditClick}>
- {translate('update_details')}
- </ActionsDropdownItem>
- )}
- <ActionsDropdownDivider />
- <ActionsDropdownItem
- className="js-metric-delete"
- destructive={true}
- onClick={this.handleDeleteClick}>
- {translate('delete')}
- </ActionsDropdownItem>
- </ActionsDropdown>
- </td>
-
- {this.state.editForm && domains && types && (
- <Form
- confirmButtonText={translate('update_verb')}
- domains={domains}
- header={translate('custom_metrics.update_metric')}
- metric={metric}
- onClose={this.closeEditForm}
- onSubmit={this.handleEditFormSubmit}
- types={types}
- />
- )}
-
- {this.state.deleteForm && (
- <DeleteForm
- metric={metric}
- onClose={this.closeDeleteForm}
- onSubmit={this.handleDeleteFormSubmit}
- />
- )}
- </tr>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import { sortBy } from 'lodash';
-import * as React from 'react';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import { MetricProps } from './Form';
-import Item from './Item';
-
-interface Props {
- domains?: string[];
- metrics: T.Metric[];
- onDelete: (metricKey: string) => Promise<void>;
- onEdit: (data: { id: string } & MetricProps) => Promise<void>;
- types?: string[];
-}
-
-export default function List({ domains, metrics, onDelete, onEdit, types }: Props) {
- return (
- <div className="boxed-group boxed-group-inner" id="custom-metrics-list">
- {metrics.length > 0 ? (
- <table className="data zebra zebra-hover">
- <tbody>
- {sortBy(metrics, metric => metric.name.toLowerCase()).map(metric => (
- <Item
- domains={domains}
- key={metric.key}
- metric={metric}
- onDelete={onDelete}
- onEdit={onEdit}
- types={types}
- />
- ))}
- </tbody>
- </table>
- ) : (
- <p>{translate('no_results')}</p>
- )}
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
-import App from '../App';
-
-jest.mock('../../../../api/metrics', () => ({
- getMetricDomains: () => Promise.resolve(['Coverage', 'Issues']),
- getMetricTypes: () => Promise.resolve(['INT', 'STRING']),
- getMetrics: () =>
- Promise.resolve({
- metrics: [{ id: '3', key: 'foo', name: 'Foo', type: 'INT' }],
- p: 1,
- ps: 1,
- total: 1
- }),
- deleteMetric: () => Promise.resolve(),
- updateMetric: () => Promise.resolve(),
- createMetric: () =>
- Promise.resolve({ id: '4', domain: 'Coverage', key: 'bar', name: 'Bar', type: 'INT' })
-}));
-
-it('should work', async () => {
- const wrapper = shallow<App>(<App />);
- wrapper.instance().mounted = true;
- expect(wrapper).toMatchSnapshot();
-
- await waitAndUpdate(wrapper);
- expect(wrapper).toMatchSnapshot();
-
- // create
- wrapper.find('Header').prop<Function>('onCreate')({
- domain: 'Coverage',
- key: 'bar',
- name: 'Bar',
- type: 'INT'
- });
- await waitAndUpdate(wrapper);
- expect(wrapper.state().metrics).toMatchSnapshot();
- expect(wrapper.state().paging!.total).toBe(2);
-
- // edit
- wrapper.find('List').prop<Function>('onEdit')({
- domain: undefined,
- id: '4',
- key: 'bar',
- name: 'Bar',
- type: 'STRING'
- });
- await waitAndUpdate(wrapper);
- expect(wrapper.state().metrics).toMatchSnapshot();
- expect(wrapper.state().paging!.total).toBe(2);
-
- // delete
- wrapper.find('List').prop<Function>('onDelete')('bar');
- await waitAndUpdate(wrapper);
- expect(wrapper.state().metrics).toMatchSnapshot();
- expect(wrapper.state().paging!.total).toBe(1);
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { click } from 'sonar-ui-common/helpers/testUtils';
-import CreateButton from '../CreateButton';
-
-it('should create new group', () => {
- const onCreate = jest.fn(() => Promise.resolve());
- const wrapper = shallow(
- <CreateButton domains={['Coverage', 'Issues']} onCreate={onCreate} types={['INT', 'STRING']} />
- );
- expect(wrapper).toMatchSnapshot();
-
- click(wrapper.find('#metrics-create'));
- expect(wrapper).toMatchSnapshot();
-
- wrapper.find('Form').prop<Function>('onSubmit')({ key: 'foo', name: 'foo', type: 'INT' });
- expect(onCreate).toBeCalledWith({ key: 'foo', name: 'foo', type: 'INT' });
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import DeleteForm from '../DeleteForm';
-
-it('should render', () => {
- const metric = { id: '3', key: 'foo', name: 'Foo', type: 'INT' };
- expect(
- shallow(<DeleteForm metric={metric} onClose={jest.fn()} onSubmit={jest.fn()} />).dive()
- ).toMatchSnapshot();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { change, click, submit } from 'sonar-ui-common/helpers/testUtils';
-import Form from '../Form';
-
-it('should render form', async () => {
- const onClose = jest.fn();
- const onSubmit = jest.fn(() => Promise.resolve());
- const wrapper = shallow(
- <Form
- confirmButtonText="confirmButtonText"
- domains={['Coverage', 'Issues']}
- header="header"
- onClose={onClose}
- onSubmit={onSubmit}
- types={['INT', 'STRING']}
- />
- ).dive();
- expect(wrapper).toMatchSnapshot();
-
- change(wrapper.find('[name="key"]'), 'foo');
- change(wrapper.find('[name="name"]'), 'Foo');
- change(wrapper.find('[name="description"]'), 'bar');
- wrapper.find('Creatable').prop<Function>('onChange')({ value: 'Coverage' });
- submit(wrapper.find('form'));
- expect(onSubmit).toBeCalledWith({
- description: 'bar',
- domain: 'Coverage',
- key: 'foo',
- name: 'Foo',
- type: 'INT'
- });
-
- await new Promise(setImmediate);
- expect(onClose).toBeCalled();
-
- onClose.mockClear();
- click(wrapper.find('ResetButtonLink'));
- expect(onClose).toBeCalled();
-});
-
-it('should create new domain', () => {
- const wrapper = shallow(
- <Form
- confirmButtonText="confirmButtonText"
- domains={['Coverage', 'Issues']}
- header="header"
- onClose={jest.fn()}
- onSubmit={jest.fn()}
- types={['INT', 'STRING']}
- />
- );
-
- const optionsBefore = [
- { label: 'Coverage', value: 'Coverage' },
- { label: 'Issues', value: 'Issues' }
- ];
- expect(getSelect().prop('options')).toEqual(optionsBefore);
-
- getSelect().prop<Function>('onChange')({ value: 'Another' });
- wrapper.update();
-
- expect(getSelect().prop('options')).toEqual([
- ...optionsBefore,
- { label: 'Another', value: 'Another' }
- ]);
-
- function getSelect() {
- return wrapper.dive().find('Creatable');
- }
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import Header from '../Header';
-
-it('should create new metric', () => {
- const onCreate = jest.fn(() => Promise.resolve());
- const wrapper = shallow(
- <Header
- domains={['Coverage', 'Issues']}
- loading={false}
- onCreate={onCreate}
- types={['INT', 'STRING']}
- />
- );
- expect(wrapper).toMatchSnapshot();
-
- wrapper.find('CreateButton').prop<Function>('onCreate')({ key: 'foo', name: 'Foo', type: 'INT' });
- expect(onCreate).toBeCalledWith({ key: 'foo', name: 'Foo', type: 'INT' });
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { click } from 'sonar-ui-common/helpers/testUtils';
-import Item from '../Item';
-
-const metric = { id: '3', key: 'foo', name: 'Foo', type: 'INT' };
-
-it('should render', () => {
- expect(
- shallow(<Item metric={metric} onDelete={jest.fn()} onEdit={jest.fn()} />)
- ).toMatchSnapshot();
-});
-
-it('should edit metric', () => {
- const onEdit = jest.fn();
-
- const wrapper = shallow(
- <Item
- domains={['Coverage', 'Issues']}
- metric={metric}
- onDelete={jest.fn()}
- onEdit={onEdit}
- types={['INT', 'STRING']}
- />
- );
-
- click(wrapper.find('.js-metric-update'));
- wrapper.update();
-
- wrapper.find('Form').prop<Function>('onSubmit')({
- ...metric,
- description: 'bla bla',
- domain: 'Coverage'
- });
- expect(onEdit).toBeCalledWith({ ...metric, description: 'bla bla', domain: 'Coverage' });
-});
-
-it('should delete metric', () => {
- const onDelete = jest.fn();
- const wrapper = shallow(<Item metric={metric} onDelete={onDelete} onEdit={jest.fn()} />);
-
- click(wrapper.find('.js-metric-delete'));
- wrapper.update();
-
- wrapper.find('DeleteForm').prop<Function>('onSubmit')();
- expect(onDelete).toBeCalledWith('foo');
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import List from '../List';
-
-it('should render', () => {
- const metrics = [
- { id: '3', key: 'foo', name: 'Foo', type: 'INT' },
- { id: '4', domain: 'Coverage', key: 'bar', name: 'Bar', type: 'INT' }
- ];
- expect(
- shallow(<List metrics={metrics} onDelete={jest.fn()} onEdit={jest.fn()} />)
- ).toMatchSnapshot();
-});
-
-it('should render no results', () => {
- expect(shallow(<List metrics={[]} onDelete={jest.fn()} onEdit={jest.fn()} />)).toMatchSnapshot();
-});
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should work 1`] = `
-<Fragment>
- <Suggestions
- suggestions="custom_metrics"
- />
- <Helmet
- defer={false}
- encodeSpecialCharacters={true}
- title="custom_metrics.page"
- />
- <div
- className="page page-limited"
- id="custom-metrics-page"
- >
- <Header
- loading={true}
- onCreate={[Function]}
- />
- </div>
-</Fragment>
-`;
-
-exports[`should work 2`] = `
-<Fragment>
- <Suggestions
- suggestions="custom_metrics"
- />
- <Helmet
- defer={false}
- encodeSpecialCharacters={true}
- title="custom_metrics.page"
- />
- <div
- className="page page-limited"
- id="custom-metrics-page"
- >
- <Header
- domains={
- Array [
- "Coverage",
- "Issues",
- ]
- }
- loading={false}
- onCreate={[Function]}
- types={
- Array [
- "INT",
- "STRING",
- ]
- }
- />
- <List
- domains={
- Array [
- "Coverage",
- "Issues",
- ]
- }
- metrics={
- Array [
- Object {
- "id": "3",
- "key": "foo",
- "name": "Foo",
- "type": "INT",
- },
- ]
- }
- onDelete={[Function]}
- onEdit={[Function]}
- types={
- Array [
- "INT",
- "STRING",
- ]
- }
- />
- <ListFooter
- count={1}
- loadMore={[Function]}
- ready={true}
- total={1}
- />
- </div>
-</Fragment>
-`;
-
-exports[`should work 3`] = `
-Array [
- Object {
- "id": "3",
- "key": "foo",
- "name": "Foo",
- "type": "INT",
- },
- Object {
- "domain": "Coverage",
- "id": "4",
- "key": "bar",
- "name": "Bar",
- "type": "INT",
- },
-]
-`;
-
-exports[`should work 4`] = `
-Array [
- Object {
- "id": "3",
- "key": "foo",
- "name": "Foo",
- "type": "INT",
- },
- Object {
- "domain": undefined,
- "id": "4",
- "key": "bar",
- "name": "Bar",
- "type": "STRING",
- },
-]
-`;
-
-exports[`should work 5`] = `
-Array [
- Object {
- "id": "3",
- "key": "foo",
- "name": "Foo",
- "type": "INT",
- },
-]
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should create new group 1`] = `
-<Fragment>
- <Button
- id="metrics-create"
- onClick={[Function]}
- >
- custom_metrics.create_metric
- </Button>
-</Fragment>
-`;
-
-exports[`should create new group 2`] = `
-<Fragment>
- <Button
- id="metrics-create"
- onClick={[Function]}
- >
- custom_metrics.create_metric
- </Button>
- <Form
- confirmButtonText="create"
- domains={
- Array [
- "Coverage",
- "Issues",
- ]
- }
- header="custom_metrics.create_metric"
- onClose={[Function]}
- onSubmit={[MockFunction]}
- types={
- Array [
- "INT",
- "STRING",
- ]
- }
- />
-</Fragment>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render 1`] = `
-<Modal
- contentLabel="custom_metrics.delete_metric"
- onRequestClose={[MockFunction]}
->
- <form
- onSubmit={[Function]}
- >
- <header
- className="modal-head"
- >
- <h2>
- custom_metrics.delete_metric
- </h2>
- </header>
- <div
- className="modal-body"
- >
- custom_metrics.delete_metric.confirmation.Foo
- </div>
- <footer
- className="modal-foot"
- >
- <DeferredSpinner
- className="spacer-right"
- loading={false}
- />
- <SubmitButton
- className="button-red"
- disabled={false}
- >
- delete
- </SubmitButton>
- <ResetButtonLink
- disabled={false}
- onClick={[Function]}
- >
- cancel
- </ResetButtonLink>
- </footer>
- </form>
-</Modal>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render form 1`] = `
-<Modal
- contentLabel="header"
- onRequestClose={[MockFunction]}
- size="small"
->
- <form
- onSubmit={[Function]}
- >
- <header
- className="modal-head"
- >
- <h2>
- header
- </h2>
- </header>
- <div
- className="modal-body modal-container"
- >
- <MandatoryFieldsExplanation
- className="modal-field"
- />
- <div
- className="modal-field"
- >
- <label
- htmlFor="create-metric-key"
- >
- key
- <MandatoryFieldMarker />
- </label>
- <input
- autoFocus={true}
- id="create-metric-key"
- maxLength={64}
- name="key"
- onChange={[Function]}
- required={true}
- type="text"
- value=""
- />
- </div>
- <div
- className="modal-field"
- >
- <label
- htmlFor="create-metric-name"
- >
- name
- <MandatoryFieldMarker />
- </label>
- <input
- id="create-metric-name"
- maxLength={64}
- name="name"
- onChange={[Function]}
- required={true}
- type="text"
- value=""
- />
- </div>
- <div
- className="modal-field"
- >
- <label
- htmlFor="create-metric-description"
- >
- description
- </label>
- <textarea
- id="create-metric-description"
- name="description"
- onChange={[Function]}
- value=""
- />
- </div>
- <div
- className="modal-field"
- >
- <label
- htmlFor="create-metric-domain"
- >
- custom_metrics.domain
- </label>
- <Creatable
- id="create-metric-domain"
- onChange={[Function]}
- options={
- Array [
- Object {
- "label": "Coverage",
- "value": "Coverage",
- },
- Object {
- "label": "Issues",
- "value": "Issues",
- },
- ]
- }
- />
- </div>
- <div
- className="modal-field"
- >
- <label
- htmlFor="create-metric-type"
- >
- type
- <MandatoryFieldMarker />
- </label>
- <Select
- clearable={false}
- id="create-metric-type"
- onChange={[Function]}
- options={
- Array [
- Object {
- "label": "metric.type.INT",
- "value": "INT",
- },
- Object {
- "label": "metric.type.STRING",
- "value": "STRING",
- },
- ]
- }
- value="INT"
- />
- </div>
- </div>
- <footer
- className="modal-foot"
- >
- <DeferredSpinner
- className="spacer-right"
- loading={false}
- />
- <SubmitButton
- disabled={false}
- id="create-metric-submit"
- >
- confirmButtonText
- </SubmitButton>
- <ResetButtonLink
- disabled={false}
- id="create-metric-cancel"
- onClick={[Function]}
- >
- cancel
- </ResetButtonLink>
- </footer>
- </form>
-</Modal>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should create new metric 1`] = `
-<header
- className="page-header"
- id="custom-metrics-header"
->
- <h1
- className="page-title"
- >
- custom_metrics.page
- </h1>
- <DeferredSpinner
- loading={false}
- />
- <div
- className="page-actions"
- >
- <CreateButton
- domains={
- Array [
- "Coverage",
- "Issues",
- ]
- }
- onCreate={[MockFunction]}
- types={
- Array [
- "INT",
- "STRING",
- ]
- }
- />
- </div>
- <div
- className="page-description"
- >
- <Alert
- display="inline"
- variant="error"
- >
- custom_metrics.deprecated
- </Alert>
- <p>
- custom_metrics.page.description
- </p>
- </div>
-</header>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render 1`] = `
-<tr
- data-metric="foo"
->
- <td
- className="width-30"
- >
- <div>
- <strong
- className="js-metric-name"
- >
- Foo
- </strong>
- <span
- className="js-metric-key note little-spacer-left"
- >
- foo
- </span>
- </div>
- </td>
- <td
- className="width-20"
- >
- <span
- className="js-metric-domain"
- />
- </td>
- <td
- className="width-20"
- >
- <span
- className="js-metric-type"
- >
- metric.type.INT
- </span>
- </td>
- <td
- className="width-20"
- >
- <span
- className="js-metric-description"
- />
- </td>
- <td
- className="thin nowrap"
- >
- <ActionsDropdown>
- <ActionsDropdownDivider />
- <ActionsDropdownItem
- className="js-metric-delete"
- destructive={true}
- onClick={[Function]}
- >
- delete
- </ActionsDropdownItem>
- </ActionsDropdown>
- </td>
-</tr>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render 1`] = `
-<div
- className="boxed-group boxed-group-inner"
- id="custom-metrics-list"
->
- <table
- className="data zebra zebra-hover"
- >
- <tbody>
- <Item
- key="bar"
- metric={
- Object {
- "domain": "Coverage",
- "id": "4",
- "key": "bar",
- "name": "Bar",
- "type": "INT",
- }
- }
- onDelete={[MockFunction]}
- onEdit={[MockFunction]}
- />
- <Item
- key="foo"
- metric={
- Object {
- "id": "3",
- "key": "foo",
- "name": "Foo",
- "type": "INT",
- }
- }
- onDelete={[MockFunction]}
- onEdit={[MockFunction]}
- />
- </tbody>
- </table>
-</div>
-`;
-
-exports[`should render no results 1`] = `
-<div
- className="boxed-group boxed-group-inner"
- id="custom-metrics-list"
->
- <p>
- no_results
- </p>
-</div>
-`;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.
- */
-import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent';
-
-const routes = [
- {
- indexRoute: { component: lazyLoadComponent(() => import('./components/App')) }
- }
-];
-
-export default routes;
{
"path": "api/metrics",
"since": "2.6",
- "description": "Get information on automatic metrics, and manage custom metrics. See also api/custom_measures.",
+ "description": "Get information on automatic metrics, and manage metrics.",
"actions": [
- {
- "key": "create",
- "description": "Create custom metric.<br /> Requires 'Administer System' permission.",
- "since": "5.2",
- "internal": false,
- "post": true,
- "hasResponseExample": false,
- "changelog": [],
- "params": [
- {
- "key": "description",
- "description": "Description",
- "required": false,
- "internal": false,
- "exampleValue": "Size of the team",
- "maximumLength": 255
- },
- {
- "key": "domain",
- "description": "Domain",
- "required": false,
- "internal": false,
- "exampleValue": "Tests",
- "maximumLength": 64
- },
- {
- "key": "key",
- "description": "Key",
- "required": true,
- "internal": false,
- "exampleValue": "team_size",
- "maximumLength": 64
- },
- {
- "key": "name",
- "description": "Name",
- "required": true,
- "internal": false,
- "exampleValue": "Team Size",
- "maximumLength": 64
- },
- {
- "key": "type",
- "description": "Metric type key",
- "required": true,
- "internal": false,
- "exampleValue": "INT",
- "possibleValues": [
- "INT",
- "FLOAT",
- "PERCENT",
- "BOOL",
- "STRING",
- "MILLISEC",
- "DATA",
- "LEVEL",
- "DISTRIB",
- "RATING",
- "WORK_DUR"
- ]
- }
- ]
- },
- {
- "key": "delete",
- "description": "Delete metrics and associated measures. Delete only custom metrics.<br />Ids or keys must be provided. <br />Requires 'Administer System' permission.",
- "since": "5.2",
- "internal": false,
- "post": true,
- "hasResponseExample": false,
- "changelog": [],
- "params": [
- {
- "key": "ids",
- "description": "Metrics ids to delete.",
- "required": false,
- "internal": false,
- "exampleValue": "5, 23, 42"
- },
- {
- "key": "keys",
- "description": "Metrics keys to delete",
- "required": false,
- "internal": false,
- "exampleValue": "team_size, business_value"
- }
- ]
- },
- {
- "key": "domains",
- "description": "List all custom metric domains.",
- "since": "5.2",
- "internal": false,
- "post": false,
- "hasResponseExample": true,
- "changelog": []
- },
{
"key": "search",
"description": "Search for metrics",
"post": false,
"hasResponseExample": true,
"changelog": []
- },
- {
- "key": "update",
- "description": "Update a custom metric.<br /> Requires 'Administer System' permission.",
- "since": "5.2",
- "internal": false,
- "post": true,
- "hasResponseExample": false,
- "changelog": [],
- "params": [
- {
- "key": "description",
- "description": "Description",
- "required": false,
- "internal": false,
- "exampleValue": "Size of the team",
- "maximumLength": 255
- },
- {
- "key": "domain",
- "description": "Domain",
- "required": false,
- "internal": false,
- "exampleValue": "Tests",
- "maximumLength": 64
- },
- {
- "key": "id",
- "description": "Id of the custom metric to update",
- "required": true,
- "internal": false,
- "exampleValue": "42"
- },
- {
- "key": "key",
- "description": "Key",
- "required": false,
- "internal": false,
- "exampleValue": "team_size",
- "maximumLength": 64
- },
- {
- "key": "name",
- "description": "Name",
- "required": false,
- "internal": false,
- "maximumLength": 64
- },
- {
- "key": "type",
- "description": "Metric type key",
- "required": false,
- "internal": false,
- "exampleValue": "INT",
- "possibleValues": [
- "INT",
- "FLOAT",
- "PERCENT",
- "BOOL",
- "STRING",
- "MILLISEC",
- "DATA",
- "LEVEL",
- "DISTRIB",
- "RATING",
- "WORK_DUR"
- ]
- }
- ]
}
]
},