aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-docs/src/tooltips/quality-gates/built-in-quality-gate.md1
-rw-r--r--server/sonar-docs/src/tooltips/quality-gates/default-quality-gate.md1
-rw-r--r--server/sonar-docs/src/tooltips/quality-gates/project-homepage-quality-gate.md1
-rw-r--r--server/sonar-docs/src/tooltips/quality-gates/quality-gate-conditions.md5
-rw-r--r--server/sonar-docs/src/tooltips/quality-gates/quality-gate-projects.md1
-rw-r--r--server/sonar-docs/src/tooltips/quality-gates/quality-gate.md1
-rw-r--r--server/sonar-docs/src/tooltips/quality-profiles/built-in-quality-profile.md1
-rw-r--r--server/sonar-docs/src/tooltips/quality-profiles/default-quality-profile.md1
-rw-r--r--server/sonar-docs/src/tooltips/quality-profiles/quality-profile-projects.md1
-rw-r--r--server/sonar-docs/src/tooltips/rules/custom-rule-removal.md1
-rw-r--r--server/sonar-docs/src/tooltips/rules/custom-rules.md1
-rw-r--r--server/sonar-docs/src/tooltips/rules/rule-templates.md1
-rw-r--r--server/sonar-docs/src/tooltips/rules/rules-quality-profiles.md5
-rw-r--r--server/sonar-web/config/webpack.config.js10
-rw-r--r--server/sonar-web/package.json3
-rw-r--r--server/sonar-web/src/main/js/@types/remark-react.d.ts33
-rw-r--r--server/sonar-web/src/main/js/@types/remark.d.ts22
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.css1
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBranch.tsx83
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/NoBranchSupportPopup.tsx30
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/SingleBranchHelperPopup.tsx34
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBranch-test.tsx10
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBranch-test.tsx.snap81
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/NoBranchSupportPopup-test.tsx.snap43
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/SingleBranchHelperPopup-test.tsx.snap43
-rw-r--r--server/sonar-web/src/main/js/app/styles/components/badges.css1
-rw-r--r--server/sonar-web/src/main/js/app/styles/components/search-navigator.css1
-rw-r--r--server/sonar-web/src/main/js/app/styles/components/tooltips.css168
-rw-r--r--server/sonar-web/src/main/js/app/styles/init/links.css4
-rw-r--r--server/sonar-web/src/main/js/app/styles/init/tables.css10
-rw-r--r--server/sonar-web/src/main/js/app/styles/style.css8
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/Facet.tsx14
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/ProfileFacet.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetails.tsx18
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsMeta.tsx20
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/TemplateFacet.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGate.js10
-rw-r--r--server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/__snapshots__/QualityGate-test.js.snap17
-rw-r--r--server/sonar-web/src/main/js/apps/overview/styles.css5
-rw-r--r--server/sonar-web/src/main/js/apps/projectQualityGate/Header.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/__snapshots__/Header-test.tsx.snap14
-rw-r--r--server/sonar-web/src/main/js/apps/projectQualityProfiles/Header.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/projectQualityProfiles/__tests__/__snapshots__/Header-test.tsx.snap14
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js6
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js6
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx14
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/ListHeader.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx9
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx45
-rw-r--r--server/sonar-web/src/main/js/components/common/BubblePopup.tsx4
-rw-r--r--server/sonar-web/src/main/js/components/controls/Popup.tsx73
-rw-r--r--server/sonar-web/src/main/js/components/controls/Tooltip.css126
-rw-r--r--server/sonar-web/src/main/js/components/controls/Tooltip.tsx9
-rw-r--r--server/sonar-web/src/main/js/components/docs/DocLink.tsx45
-rw-r--r--server/sonar-web/src/main/js/components/docs/DocMarkdownBlock.tsx48
-rw-r--r--server/sonar-web/src/main/js/components/docs/DocTooltip.tsx134
-rw-r--r--server/sonar-web/src/main/js/components/docs/__tests__/DocLink-test.tsx30
-rw-r--r--server/sonar-web/src/main/js/components/docs/__tests__/DocMarkdownBlock-test.tsx43
-rw-r--r--server/sonar-web/src/main/js/components/docs/__tests__/DocTooltip-test.tsx48
-rw-r--r--server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocLink-test.tsx.snap7
-rw-r--r--server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocMarkdownBlock-test.tsx.snap32
-rw-r--r--server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap61
-rw-r--r--server/sonar-web/src/main/js/components/facet/FacetHeader.tsx5
-rw-r--r--server/sonar-web/src/main/js/components/icons-components/PlusCircleIcon.tsx39
-rw-r--r--server/sonar-web/yarn.lock743
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties3
67 files changed, 1763 insertions, 517 deletions
diff --git a/server/sonar-docs/src/tooltips/quality-gates/built-in-quality-gate.md b/server/sonar-docs/src/tooltips/quality-gates/built-in-quality-gate.md
new file mode 100644
index 00000000000..7d5470bd4da
--- /dev/null
+++ b/server/sonar-docs/src/tooltips/quality-gates/built-in-quality-gate.md
@@ -0,0 +1 @@
+Built-in, immutable Quality Gate reflecting best practices.
diff --git a/server/sonar-docs/src/tooltips/quality-gates/default-quality-gate.md b/server/sonar-docs/src/tooltips/quality-gates/default-quality-gate.md
new file mode 100644
index 00000000000..2cf1296dc53
--- /dev/null
+++ b/server/sonar-docs/src/tooltips/quality-gates/default-quality-gate.md
@@ -0,0 +1 @@
+The Default gate is applied to all projects not explicitly assigned to a gate. Quality Profile and Gate administrators can assign projects to a gate from the Quality Profile page. Project administrators can also choose a non-default gate.
diff --git a/server/sonar-docs/src/tooltips/quality-gates/project-homepage-quality-gate.md b/server/sonar-docs/src/tooltips/quality-gates/project-homepage-quality-gate.md
new file mode 100644
index 00000000000..115b34f419a
--- /dev/null
+++ b/server/sonar-docs/src/tooltips/quality-gates/project-homepage-quality-gate.md
@@ -0,0 +1 @@
+A Quality Gate is a set of measure-based Boolean conditions. It helps you know immediately whether your project is production-ready. If your current status is not Passed, you'll see which values caused the problem and the value required to pass.
diff --git a/server/sonar-docs/src/tooltips/quality-gates/quality-gate-conditions.md b/server/sonar-docs/src/tooltips/quality-gates/quality-gate-conditions.md
new file mode 100644
index 00000000000..e961eeb17f6
--- /dev/null
+++ b/server/sonar-docs/src/tooltips/quality-gates/quality-gate-conditions.md
@@ -0,0 +1,5 @@
+For each Quality Gate condition you must choose the metric to be tested, the threshold at which to raise a warning or error, and whether or not to apply the condition to all code or only to Leak Period code (irrelevant for conditions "on New Code").
+
+---
+
+See also: [Fixing the Water Leak](/fixing-the-water-leak)
diff --git a/server/sonar-docs/src/tooltips/quality-gates/quality-gate-projects.md b/server/sonar-docs/src/tooltips/quality-gates/quality-gate-projects.md
new file mode 100644
index 00000000000..2cf1296dc53
--- /dev/null
+++ b/server/sonar-docs/src/tooltips/quality-gates/quality-gate-projects.md
@@ -0,0 +1 @@
+The Default gate is applied to all projects not explicitly assigned to a gate. Quality Profile and Gate administrators can assign projects to a gate from the Quality Profile page. Project administrators can also choose a non-default gate.
diff --git a/server/sonar-docs/src/tooltips/quality-gates/quality-gate.md b/server/sonar-docs/src/tooltips/quality-gates/quality-gate.md
new file mode 100644
index 00000000000..0762cbcbcaa
--- /dev/null
+++ b/server/sonar-docs/src/tooltips/quality-gates/quality-gate.md
@@ -0,0 +1 @@
+A Quality Gate is a set of measure-based, Boolean conditions. It helps you know immediately whether your projects are production-ready. Ideally, all projects will use the same quality gate. Each project's Quality Gate status is displayed prominently on its homepage.
diff --git a/server/sonar-docs/src/tooltips/quality-profiles/built-in-quality-profile.md b/server/sonar-docs/src/tooltips/quality-profiles/built-in-quality-profile.md
new file mode 100644
index 00000000000..5c0ddbf1f2c
--- /dev/null
+++ b/server/sonar-docs/src/tooltips/quality-profiles/built-in-quality-profile.md
@@ -0,0 +1 @@
+Built-in profiles are provided directly by the language analyzers and may be updated with each new analyzer version. They represent best-practice, minimum rule sets.
diff --git a/server/sonar-docs/src/tooltips/quality-profiles/default-quality-profile.md b/server/sonar-docs/src/tooltips/quality-profiles/default-quality-profile.md
new file mode 100644
index 00000000000..310164c8be5
--- /dev/null
+++ b/server/sonar-docs/src/tooltips/quality-profiles/default-quality-profile.md
@@ -0,0 +1 @@
+For each language there is a default profile. All projects not explicitly assigned to some other profile will be analyzed with the default.
diff --git a/server/sonar-docs/src/tooltips/quality-profiles/quality-profile-projects.md b/server/sonar-docs/src/tooltips/quality-profiles/quality-profile-projects.md
new file mode 100644
index 00000000000..0c96fe0fb64
--- /dev/null
+++ b/server/sonar-docs/src/tooltips/quality-profiles/quality-profile-projects.md
@@ -0,0 +1 @@
+Projects assigned to a profile will always be analyzed with it for that language, regardless of which profile is the default. Quality Profile administrators may assign projects to a profile. Project administrators may also choose a non-default profile for each language.
diff --git a/server/sonar-docs/src/tooltips/rules/custom-rule-removal.md b/server/sonar-docs/src/tooltips/rules/custom-rule-removal.md
new file mode 100644
index 00000000000..c8d9be85acd
--- /dev/null
+++ b/server/sonar-docs/src/tooltips/rules/custom-rule-removal.md
@@ -0,0 +1 @@
+Only custom rules may be deleted. When a custom rule is deleted, it is not removed from the SonarQube instance. Instead its status is set to "REMOVED", allowing relevant issues to continue to be displayed properly.
diff --git a/server/sonar-docs/src/tooltips/rules/custom-rules.md b/server/sonar-docs/src/tooltips/rules/custom-rules.md
new file mode 100644
index 00000000000..37981a7dffb
--- /dev/null
+++ b/server/sonar-docs/src/tooltips/rules/custom-rules.md
@@ -0,0 +1 @@
+Custom rules are created by administrators from templates, and are the only fully-editable rules.
diff --git a/server/sonar-docs/src/tooltips/rules/rule-templates.md b/server/sonar-docs/src/tooltips/rules/rule-templates.md
new file mode 100644
index 00000000000..582e4cf24be
--- /dev/null
+++ b/server/sonar-docs/src/tooltips/rules/rule-templates.md
@@ -0,0 +1 @@
+Rule Templates allow users to easily define their own rules. They are like cookie cutters from which you can stamp out new, "custom rules". The rules created from a template are listed on its rule detail page.
diff --git a/server/sonar-docs/src/tooltips/rules/rules-quality-profiles.md b/server/sonar-docs/src/tooltips/rules/rules-quality-profiles.md
new file mode 100644
index 00000000000..809df1df132
--- /dev/null
+++ b/server/sonar-docs/src/tooltips/rules/rules-quality-profiles.md
@@ -0,0 +1,5 @@
+Quality Profiles are collections of Rules to apply during an analysis.
+
+---
+
+See also: [Quality Profiles](/quality-profiles)
diff --git a/server/sonar-web/config/webpack.config.js b/server/sonar-web/config/webpack.config.js
index cbad122a5b5..cc2bfe7e970 100644
--- a/server/sonar-web/config/webpack.config.js
+++ b/server/sonar-web/config/webpack.config.js
@@ -33,7 +33,11 @@ module.exports = ({ production = true }) => ({
devtool: production ? 'source-map' : 'cheap-module-source-map',
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
- extensions: ['.ts', '.tsx', '.js', '.json']
+ extensions: ['.ts', '.tsx', '.js', '.json'],
+ // import from 'Docs/foo.md' is rewritten to import from 'sonar-docs/src/foo.md'
+ alias: {
+ Docs: path.resolve(__dirname, '../../sonar-docs/src/tooltips')
+ }
},
entry: [
!production && require.resolve('react-dev-utils/webpackHotDevClient'),
@@ -69,6 +73,10 @@ module.exports = ({ production = true }) => ({
utils.postcssLoader()
].filter(Boolean)
},
+ {
+ test: /\.md$/,
+ use: 'raw-loader'
+ },
{ test: require.resolve('lodash'), loader: 'expose-loader?_' },
{ test: require.resolve('react'), loader: 'expose-loader?React' },
{ test: require.resolve('react-dom'), loader: 'expose-loader?ReactDOM' }
diff --git a/server/sonar-web/package.json b/server/sonar-web/package.json
index 11e65a186d7..a8b3f522569 100644
--- a/server/sonar-web/package.json
+++ b/server/sonar-web/package.json
@@ -94,9 +94,12 @@
"postcss-custom-properties": "6.2.0",
"postcss-loader": "2.1.1",
"prettier": "1.11.1",
+ "raw-loader": "0.5.1",
"react-dev-utils": "5.0.0",
"react-error-overlay": "1.0.7",
"react-test-renderer": "16.2.0",
+ "remark": "9.0.0",
+ "remark-react": "4.0.1",
"style-loader": "0.20.3",
"ts-jest": "22.0.1",
"ts-loader": "4.1.0",
diff --git a/server/sonar-web/src/main/js/@types/remark-react.d.ts b/server/sonar-web/src/main/js/@types/remark-react.d.ts
new file mode 100644
index 00000000000..0e944118732
--- /dev/null
+++ b/server/sonar-web/src/main/js/@types/remark-react.d.ts
@@ -0,0 +1,33 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.
+ */
+declare module 'remark-react' {
+ interface Options {
+ /** `h()` */
+ createElement?: (...args: any[]) => JSX.Element;
+ /** Key prefix. */
+ prefix?: string;
+ /** Components. */
+ remarkReactComponents?: any;
+ /** Sanitation schema. */
+ sanitize?: any;
+ }
+
+ export default function remarkReact(options?: Options): JSX.Element;
+}
diff --git a/server/sonar-web/src/main/js/@types/remark.d.ts b/server/sonar-web/src/main/js/@types/remark.d.ts
new file mode 100644
index 00000000000..60cc5c56b85
--- /dev/null
+++ b/server/sonar-web/src/main/js/@types/remark.d.ts
@@ -0,0 +1,22 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.
+ */
+declare module 'remark' {
+ export default function remark(): any;
+}
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.css b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.css
index 2362ba94a4e..8be68d6447c 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.css
+++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.css
@@ -21,6 +21,7 @@
.navbar-context-branches {
display: inline-flex;
justify-content: center;
+ align-items: center;
flex-shrink: 1 !important;
min-width: 0;
line-height: calc(2 * var(--gridSize));
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBranch.tsx b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBranch.tsx
index a369fd1412a..5569d2a7844 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBranch.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBranch.tsx
@@ -34,8 +34,8 @@ import {
isPullRequest
} from '../../../../helpers/branches';
import { translate } from '../../../../helpers/l10n';
-import HelpIcon from '../../../../components/icons-components/HelpIcon';
-import BubblePopupHelper from '../../../../components/common/BubblePopupHelper';
+import PlusCircleIcon from '../../../../components/icons-components/PlusCircleIcon';
+import Popup from '../../../../components/controls/Popup';
import Tooltip from '../../../../components/controls/Tooltip';
interface Props {
@@ -47,8 +47,6 @@ interface Props {
interface State {
dropdownOpen: boolean;
- noBranchSupportPopupOpen: boolean;
- singleBranchPopupOpen: boolean;
}
export default class ComponentNavBranch extends React.PureComponent<Props, State> {
@@ -59,14 +57,9 @@ export default class ComponentNavBranch extends React.PureComponent<Props, State
onSonarCloud: PropTypes.bool
};
- constructor(props: Props) {
- super(props);
- this.state = {
- dropdownOpen: false,
- noBranchSupportPopupOpen: false,
- singleBranchPopupOpen: false
- };
- }
+ state: State = {
+ dropdownOpen: false
+ };
componentDidMount() {
this.mounted = true;
@@ -78,7 +71,7 @@ export default class ComponentNavBranch extends React.PureComponent<Props, State
!isSameBranchLike(nextProps.currentBranchLike, this.props.currentBranchLike) ||
nextProps.location !== this.props.location
) {
- this.setState({ dropdownOpen: false, singleBranchPopupOpen: false });
+ this.setState({ dropdownOpen: false });
}
}
@@ -99,34 +92,6 @@ export default class ComponentNavBranch extends React.PureComponent<Props, State
}
};
- toggleSingleBranchPopup = (show?: boolean) => {
- if (show !== undefined) {
- this.setState({ singleBranchPopupOpen: show });
- } else {
- this.setState(state => ({ singleBranchPopupOpen: !state.singleBranchPopupOpen }));
- }
- };
-
- toggleNoBranchSupportPopup = (show?: boolean) => {
- if (show !== undefined) {
- this.setState({ noBranchSupportPopupOpen: show });
- } else {
- this.setState(state => ({ noBranchSupportPopupOpen: !state.noBranchSupportPopupOpen }));
- }
- };
-
- handleSingleBranchClick = (event: React.SyntheticEvent<HTMLAnchorElement>) => {
- event.preventDefault();
- event.stopPropagation();
- this.toggleSingleBranchPopup();
- };
-
- handleNoBranchSupportClick = (event: React.SyntheticEvent<HTMLAnchorElement>) => {
- event.preventDefault();
- event.stopPropagation();
- this.toggleNoBranchSupportPopup();
- };
-
renderDropdown = () => {
const { configuration } = this.props.component;
return this.state.dropdownOpen ? (
@@ -174,31 +139,23 @@ export default class ComponentNavBranch extends React.PureComponent<Props, State
};
renderSingleBranchPopup = () => (
- <div className="display-inline-block spacer-left">
- <a className="link-no-underline" href="#" onClick={this.handleSingleBranchClick}>
- <HelpIcon fill={theme.blue} />
- </a>
- <BubblePopupHelper
- isOpen={this.state.singleBranchPopupOpen}
- popup={<SingleBranchHelperPopup />}
- position="bottomleft"
- togglePopup={this.toggleSingleBranchPopup}
- />
- </div>
+ <Popup overlay={<SingleBranchHelperPopup />}>
+ {({ onClick }) => (
+ <a className="display-flex-center spacer-left link-no-underline" href="#" onClick={onClick}>
+ <PlusCircleIcon fill={theme.blue} size={12} />
+ </a>
+ )}
+ </Popup>
);
renderNoBranchSupportPopup = () => (
- <div className="display-inline-block spacer-left">
- <a className="link-no-underline" href="#" onClick={this.handleNoBranchSupportClick}>
- <HelpIcon fill={theme.gray80} />
- </a>
- <BubblePopupHelper
- isOpen={this.state.noBranchSupportPopupOpen}
- popup={<NoBranchSupportPopup />}
- position="bottomleft"
- togglePopup={this.toggleNoBranchSupportPopup}
- />
- </div>
+ <Popup overlay={<NoBranchSupportPopup />}>
+ {({ onClick }) => (
+ <a className="display-flex-center spacer-left link-no-underline" href="#" onClick={onClick}>
+ <PlusCircleIcon fill={theme.gray80} size={12} />
+ </a>
+ )}
+ </Popup>
);
render() {
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/NoBranchSupportPopup.tsx b/server/sonar-web/src/main/js/app/components/nav/component/NoBranchSupportPopup.tsx
index d6a15f81671..5493c37d39c 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/NoBranchSupportPopup.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/component/NoBranchSupportPopup.tsx
@@ -18,25 +18,21 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import BubblePopup from '../../../../components/common/BubblePopup';
import { translate } from '../../../../helpers/l10n';
-interface Props {
- popupPosition?: any;
-}
-
-export default function NoBranchSupportPopup(props: Props) {
+export default function NoBranchSupportPopup() {
return (
- <BubblePopup position={props.popupPosition} customClass="bubble-popup-bottom">
- <div className="abs-width-400">
- <h6 className="spacer-bottom">{translate('branches.no_support.header')}</h6>
- <p className="big-spacer-bottom markdown">{translate('branches.no_support.header.text')}</p>
- <p>
- <a href="https://redirect.sonarsource.com/editions/developer.html" target="_blank">
- {translate('learn_more')}
- </a>
- </p>
- </div>
- </BubblePopup>
+ <>
+ <h6 className="spacer-bottom">{translate('branches.no_support.header')}</h6>
+ <p className="big-spacer-bottom markdown">{translate('branches.no_support.header.text')}</p>
+ <p>
+ <a
+ href="https://redirect.sonarsource.com/editions/developer.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('learn_more')}
+ </a>
+ </p>
+ </>
);
}
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/SingleBranchHelperPopup.tsx b/server/sonar-web/src/main/js/app/components/nav/component/SingleBranchHelperPopup.tsx
index 399aff45650..b569b999505 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/SingleBranchHelperPopup.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/component/SingleBranchHelperPopup.tsx
@@ -18,28 +18,22 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import BubblePopup from '../../../../components/common/BubblePopup';
import { translate } from '../../../../helpers/l10n';
-interface Props {
- popupPosition?: any;
-}
-
-export default function SingleBranchHelperPopup(props: Props) {
+export default function SingleBranchHelperPopup() {
return (
- <BubblePopup position={props.popupPosition} customClass="bubble-popup-bottom">
- <div className="abs-width-400">
- <h6 className="spacer-bottom">{translate('branches.learn_how_to_analyze')}</h6>
- <p className="big-spacer-bottom markdown">
- {translate('branches.learn_how_to_analyze.text')}
- </p>
- <a
- className="button"
- href="https://redirect.sonarsource.com/doc/branches.html"
- target="_blank">
- {translate('about_page.read_documentation')}
- </a>
- </div>
- </BubblePopup>
+ <>
+ <h6 className="spacer-bottom">{translate('branches.learn_how_to_analyze')}</h6>
+ <p className="big-spacer-bottom markdown">
+ {translate('branches.learn_how_to_analyze.text')}
+ </p>
+ <a
+ className="button"
+ href="https://redirect.sonarsource.com/doc/branches.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('about_page.read_documentation')}
+ </a>
+ </>
);
}
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBranch-test.tsx b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBranch-test.tsx
index 5258daf383f..2c2651988af 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBranch-test.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBranch-test.tsx
@@ -114,10 +114,7 @@ it('renders single branch popup', () => {
/>,
{ context: { branchesEnabled: true } }
);
- expect(wrapper).toMatchSnapshot();
- expect(wrapper.find('BubblePopupHelper').prop('isOpen')).toBe(false);
- click(wrapper.find('a'));
- expect(wrapper.find('BubblePopupHelper').prop('isOpen')).toBe(true);
+ expect(wrapper.find('Popup')).toMatchSnapshot();
});
it('renders no branch support popup', () => {
@@ -130,10 +127,7 @@ it('renders no branch support popup', () => {
/>,
{ context: { branchesEnabled: false } }
);
- expect(wrapper).toMatchSnapshot();
- expect(wrapper.find('BubblePopupHelper').prop('isOpen')).toBe(false);
- click(wrapper.find('a'));
- expect(wrapper.find('BubblePopupHelper').prop('isOpen')).toBe(true);
+ expect(wrapper.find('Popup')).toMatchSnapshot();
});
it('renders nothing on SonarCloud without branch support', () => {
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBranch-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBranch-test.tsx.snap
index 42bc367a274..c3042574729 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBranch-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBranch-test.tsx.snap
@@ -36,44 +36,9 @@ exports[`renders main branch 1`] = `
`;
exports[`renders no branch support popup 1`] = `
-<div
- className="navbar-context-branches"
->
- <BranchIcon
- branchLike={
- Object {
- "isMain": true,
- "name": "master",
- }
- }
- className="little-spacer-right"
- fill="#cdcdcd"
- />
- <span
- className="note"
- >
- master
- </span>
- <div
- className="display-inline-block spacer-left"
- >
- <a
- className="link-no-underline"
- href="#"
- onClick={[Function]}
- >
- <HelpIcon
- fill="#cdcdcd"
- />
- </a>
- <BubblePopupHelper
- isOpen={false}
- popup={<NoBranchSupportPopup />}
- position="bottomleft"
- togglePopup={[Function]}
- />
- </div>
-</div>
+<Popup
+ overlay={<NoBranchSupportPopup />}
+/>
`;
exports[`renders pull request 1`] = `
@@ -185,41 +150,7 @@ exports[`renders short-living branch 1`] = `
`;
exports[`renders single branch popup 1`] = `
-<div
- className="navbar-context-branches"
->
- <BranchIcon
- branchLike={
- Object {
- "isMain": true,
- "name": "master",
- }
- }
- className="little-spacer-right"
- />
- <span
- className="note"
- >
- master
- </span>
- <div
- className="display-inline-block spacer-left"
- >
- <a
- className="link-no-underline"
- href="#"
- onClick={[Function]}
- >
- <HelpIcon
- fill="#4b9fd5"
- />
- </a>
- <BubblePopupHelper
- isOpen={false}
- popup={<SingleBranchHelperPopup />}
- position="bottomleft"
- togglePopup={[Function]}
- />
- </div>
-</div>
+<Popup
+ overlay={<SingleBranchHelperPopup />}
+/>
`;
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/NoBranchSupportPopup-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/NoBranchSupportPopup-test.tsx.snap
index cdc9d4cb965..964fc40a823 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/NoBranchSupportPopup-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/NoBranchSupportPopup-test.tsx.snap
@@ -1,30 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders 1`] = `
-<BubblePopup
- customClass="bubble-popup-bottom"
->
- <div
- className="abs-width-400"
+<React.Fragment>
+ <h6
+ className="spacer-bottom"
>
- <h6
- className="spacer-bottom"
- >
- branches.no_support.header
- </h6>
- <p
- className="big-spacer-bottom markdown"
+ branches.no_support.header
+ </h6>
+ <p
+ className="big-spacer-bottom markdown"
+ >
+ branches.no_support.header.text
+ </p>
+ <p>
+ <a
+ href="https://redirect.sonarsource.com/editions/developer.html"
+ rel="noopener noreferrer"
+ target="_blank"
>
- branches.no_support.header.text
- </p>
- <p>
- <a
- href="https://redirect.sonarsource.com/editions/developer.html"
- target="_blank"
- >
- learn_more
- </a>
- </p>
- </div>
-</BubblePopup>
+ learn_more
+ </a>
+ </p>
+</React.Fragment>
`;
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/SingleBranchHelperPopup-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/SingleBranchHelperPopup-test.tsx.snap
index 459630aab47..a27c56302eb 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/SingleBranchHelperPopup-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/SingleBranchHelperPopup-test.tsx.snap
@@ -1,29 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders 1`] = `
-<BubblePopup
- customClass="bubble-popup-bottom"
->
- <div
- className="abs-width-400"
+<React.Fragment>
+ <h6
+ className="spacer-bottom"
>
- <h6
- className="spacer-bottom"
- >
- branches.learn_how_to_analyze
- </h6>
- <p
- className="big-spacer-bottom markdown"
- >
- branches.learn_how_to_analyze.text
- </p>
- <a
- className="button"
- href="https://redirect.sonarsource.com/doc/branches.html"
- target="_blank"
- >
- about_page.read_documentation
- </a>
- </div>
-</BubblePopup>
+ branches.learn_how_to_analyze
+ </h6>
+ <p
+ className="big-spacer-bottom markdown"
+ >
+ branches.learn_how_to_analyze.text
+ </p>
+ <a
+ className="button"
+ href="https://redirect.sonarsource.com/doc/branches.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ about_page.read_documentation
+ </a>
+</React.Fragment>
`;
diff --git a/server/sonar-web/src/main/js/app/styles/components/badges.css b/server/sonar-web/src/main/js/app/styles/components/badges.css
index c7c42cc6d59..9d0e5a5a2d9 100644
--- a/server/sonar-web/src/main/js/app/styles/components/badges.css
+++ b/server/sonar-web/src/main/js/app/styles/components/badges.css
@@ -143,6 +143,7 @@ a.badge-focus:active {
color: var(--secondFontColor);
font-size: var(--smallFontSize);
font-weight: 400;
+ white-space: nowrap;
}
.outline-badge.active {
diff --git a/server/sonar-web/src/main/js/app/styles/components/search-navigator.css b/server/sonar-web/src/main/js/app/styles/components/search-navigator.css
index 6c9d545ce78..b661a707b43 100644
--- a/server/sonar-web/src/main/js/app/styles/components/search-navigator.css
+++ b/server/sonar-web/src/main/js/app/styles/components/search-navigator.css
@@ -464,7 +464,6 @@ a.search-navigator-facet:focus .facet-stat {
.search-navigator-facet-header-value {
display: block;
- padding: 8px 0;
overflow: hidden;
}
diff --git a/server/sonar-web/src/main/js/app/styles/components/tooltips.css b/server/sonar-web/src/main/js/app/styles/components/tooltips.css
deleted file mode 100644
index ca2109a4cd4..00000000000
--- a/server/sonar-web/src/main/js/app/styles/components/tooltips.css
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-.tooltip,
-.rc-tooltip {
- position: absolute;
- z-index: var(--tooltipZIndex);
- display: block;
- height: auto;
- font-size: var(--smallFontSize);
- font-weight: 300;
- line-height: 1.5;
- animation: fadeIn 0.3s forwards;
-}
-
-.rc-tooltip-hidden {
- display: none;
-}
-
-.tooltip.top,
-.rc-tooltip-placement-top {
- padding: 5px 0;
- margin-top: -3px;
-}
-
-.tooltip.right,
-.rc-tooltip-placement-right {
- padding: 0 5px;
- margin-left: 3px;
-}
-
-.tooltip.bottom,
-.rc-tooltip-placement-bottom {
- padding: 5px 0;
- margin-top: 3px;
-}
-
-.tooltip.left,
-.rc-tooltip-placement-left {
- padding: 0 5px;
- margin-left: -3px;
-}
-
-.tooltip-inner,
-.rc-tooltip-inner {
- max-width: 300px;
- padding: 3px 8px;
- color: #fff;
- text-align: left;
- text-decoration: none;
- background-color: #475760;
- border-radius: 4px;
- letter-spacing: 0.04em;
- overflow: hidden;
- word-break: break-word;
-}
-
-.tooltip-inner .alert,
-.rc-tooltip-inner .alert {
- margin-bottom: 5px;
- border-radius: 4px;
-}
-
-.tooltip-arrow,
-.rc-tooltip-arrow {
- position: absolute;
- width: 0;
- height: 0;
- border: solid transparent;
-}
-
-.tooltip.top .tooltip-arrow,
-.rc-tooltip-placement-top .rc-tooltip-arrow {
- bottom: 0;
- left: 50%;
- margin-left: -5px;
- border-width: 5px 5px 0;
- border-top-color: #475760;
-}
-
-.tooltip.top-left .tooltip-arrow,
-.rc-tooltip-placement-topLeft .rc-tooltip-arrow {
- right: 5px;
- bottom: 0;
- margin-bottom: -5px;
- border-width: 5px 5px 0;
- border-top-color: #475760;
-}
-
-.tooltip.top-right .tooltip-arrow,
-.rc-tooltip-placement-topRight .rc-tooltip-arrow {
- bottom: 0;
- left: 5px;
- margin-bottom: -5px;
- border-width: 5px 5px 0;
- border-top-color: #475760;
-}
-
-.tooltip.right .tooltip-arrow,
-.rc-tooltip-placement-right .rc-tooltip-arrow {
- top: 50%;
- left: 0;
- margin-top: -5px;
- border-width: 5px 5px 5px 0;
- border-right-color: #475760;
-}
-
-.tooltip.left .tooltip-arrow,
-.rc-tooltip-placement-left .rc-tooltip-arrow {
- top: 50%;
- right: 0;
- margin-top: -5px;
- border-width: 5px 0 5px 5px;
- border-left-color: #475760;
-}
-
-.tooltip.bottom .tooltip-arrow,
-.rc-tooltip-placement-bottom .rc-tooltip-arrow {
- top: 0;
- left: 50%;
- margin-left: -5px;
- border-width: 0 5px 5px;
- border-bottom-color: #475760;
-}
-
-.tooltip.bottom-left .tooltip-arrow,
-.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow {
- top: 0;
- right: 5px;
- margin-top: -5px;
- border-width: 0 5px 5px;
- border-bottom-color: #475760;
-}
-
-.tooltip.bottom-right .tooltip-arrow,
-.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {
- top: 0;
- left: 5px;
- margin-top: -5px;
- border-width: 0 5px 5px;
- border-bottom-color: #475760;
-}
-
-@keyframes fadeIn {
- from {
- opacity: 0;
- }
-
- to {
- opacity: 1;
- }
-}
diff --git a/server/sonar-web/src/main/js/app/styles/init/links.css b/server/sonar-web/src/main/js/app/styles/init/links.css
index c370f7bb0e8..bcf268567d2 100644
--- a/server/sonar-web/src/main/js/app/styles/init/links.css
+++ b/server/sonar-web/src/main/js/app/styles/init/links.css
@@ -52,10 +52,6 @@ a:focus {
border-bottom-color: var(--lightBlue);
}
-.tooltip a {
- color: var(--lightBlue);
-}
-
.link-no-underline {
border-bottom: none;
}
diff --git a/server/sonar-web/src/main/js/app/styles/init/tables.css b/server/sonar-web/src/main/js/app/styles/init/tables.css
index bdc3568bf8d..2a2a29366bb 100644
--- a/server/sonar-web/src/main/js/app/styles/init/tables.css
+++ b/server/sonar-web/src/main/js/app/styles/init/tables.css
@@ -76,6 +76,7 @@ table.data > thead:after {
}
table.data > thead > tr > th {
+ position: relative;
vertical-align: top;
line-height: 18px;
padding: 8px 10px;
@@ -96,6 +97,7 @@ table.data > tfoot > tr > td {
}
table.data > tbody > tr > td {
+ position: relative;
padding: 8px 10px;
vertical-align: text-top;
line-height: 16px;
@@ -263,3 +265,11 @@ table.form td img {
table#project-history tr > td {
vertical-align: top;
}
+
+.table-cell-doc {
+ position: absolute;
+ z-index: var(--aboveNormalZIndex);
+ right: -8px;
+ top: 50%;
+ margin-top: -6px;
+}
diff --git a/server/sonar-web/src/main/js/app/styles/style.css b/server/sonar-web/src/main/js/app/styles/style.css
index f5bcff13ca5..4fc6c561948 100644
--- a/server/sonar-web/src/main/js/app/styles/style.css
+++ b/server/sonar-web/src/main/js/app/styles/style.css
@@ -65,6 +65,14 @@
line-height: 1.5;
}
+.markdown.cut-margins > *:first-child {
+ margin-top: 0 !important;
+}
+
+.markdown.cut-margins > *:last-child {
+ margin-bottom: 0 !important;
+}
+
.rule-desc p,
.markdown p,
.rule-desc ul,
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/Facet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/Facet.tsx
index dd0a053202e..7e844278970 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/Facet.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/Facet.tsx
@@ -21,6 +21,7 @@ import * as React from 'react';
import { orderBy, without, sortBy } from 'lodash';
import * as classNames from 'classnames';
import { FacetKey } from '../query';
+import Tooltip from '../../../components/controls/Tooltip';
import FacetBox from '../../../components/facet/FacetBox';
import FacetHeader from '../../../components/facet/FacetHeader';
import FacetItem from '../../../components/facet/FacetItem';
@@ -37,6 +38,7 @@ export interface BasicProps {
}
interface Props extends BasicProps {
+ children?: React.ReactNode;
disabled?: boolean;
disabledHelper?: string;
halfWidth?: boolean;
@@ -101,13 +103,17 @@ export default class Facet extends React.PureComponent<Props> {
className={classNames({ 'search-navigator-facet-box-forbidden': this.props.disabled })}
property={this.props.property}>
<FacetHeader
- helper={this.props.disabled ? this.props.disabledHelper : undefined}
- name={translate('coding_rules.facet', this.props.property)}
+ name={
+ <Tooltip overlay={this.props.disabled ? this.props.disabledHelper : undefined}>
+ <span>{translate('coding_rules.facet', this.props.property)}</span>
+ </Tooltip>
+ }
onClear={this.handleClear}
onClick={this.props.disabled ? undefined : this.handleHeaderClick}
open={this.props.open && !this.props.disabled}
- values={values}
- />
+ values={values}>
+ {this.props.children}
+ </FacetHeader>
{this.props.open &&
items !== undefined && <FacetItemsList>{items.map(this.renderItem)}</FacetItemsList>}
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/ProfileFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/ProfileFacet.tsx
index 402b971dcaa..68b6f9ae1ca 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/ProfileFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/ProfileFacet.tsx
@@ -22,6 +22,7 @@ import { sortBy } from 'lodash';
import * as classNames from 'classnames';
import { Query, FacetKey } from '../query';
import { Profile } from '../../../api/quality-profiles';
+import DocTooltip from '../../../components/docs/DocTooltip';
import FacetBox from '../../../components/facet/FacetBox';
import FacetHeader from '../../../components/facet/FacetHeader';
import FacetItem from '../../../components/facet/FacetItem';
@@ -161,8 +162,9 @@ export default class ProfileFacet extends React.PureComponent<Props> {
onClear={this.handleClear}
onClick={this.handleHeaderClick}
open={this.props.open}
- values={this.getTextValue()}
- />
+ values={this.getTextValue()}>
+ <DocTooltip className="spacer-left" doc="rules/rules-quality-profiles" />
+ </FacetHeader>
{this.props.open && <FacetItemsList>{profiles.map(this.renderItem)}</FacetItemsList>}
</FacetBox>
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetails.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetails.tsx
index e951e3b9d44..21481a1f240 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetails.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetails.tsx
@@ -31,6 +31,7 @@ import { getRuleDetails, deleteRule, updateRule } from '../../../api/rules';
import { RuleActivation, RuleDetails as IRuleDetails } from '../../../app/types';
import DeferredSpinner from '../../../components/common/DeferredSpinner';
import ConfirmButton from '../../../components/controls/ConfirmButton';
+import DocTooltip from '../../../components/docs/DocTooltip';
import { Button } from '../../../components/ui/buttons';
import { translate, translateWithParameters } from '../../../helpers/l10n';
@@ -175,7 +176,7 @@ export default class RuleDetails extends React.PureComponent<Props, State> {
{params.length > 0 && <RuleDetailsParameters params={params} />}
{isEditable && (
- <div className="coding-rules-detail-description">
+ <div className="coding-rules-detail-description display-flex-center">
{/* `templateRule` is used to get rule meta data, `customRule` is used to get parameter values */}
{/* it's expected to pass the same rule to both parameters */}
<CustomRuleButton
@@ -202,12 +203,15 @@ export default class RuleDetails extends React.PureComponent<Props, State> {
modalHeader={translate('coding_rules.delete_rule')}
onConfirm={this.handleDelete}>
{({ onClick }) => (
- <Button
- className="button-red spacer-left js-delete"
- id="coding-rules-detail-rule-delete"
- onClick={onClick}>
- {translate('delete')}
- </Button>
+ <>
+ <Button
+ className="button-red spacer-left js-delete"
+ id="coding-rules-detail-rule-delete"
+ onClick={onClick}>
+ {translate('delete')}
+ </Button>
+ <DocTooltip className="spacer-left" doc="rules/custom-rule-removal" />
+ </>
)}
</ConfirmButton>
</div>
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsMeta.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsMeta.tsx
index 5d5bc25cdae..16e9f0d6f65 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsMeta.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsMeta.tsx
@@ -27,6 +27,7 @@ import { getRuleUrl } from '../../../helpers/urls';
import LinkIcon from '../../../components/icons-components/LinkIcon';
import RuleScopeIcon from '../../../components/icons-components/RuleScopeIcon';
import Tooltip from '../../../components/controls/Tooltip';
+import DocTooltip from '../../../components/docs/DocTooltip';
import { translate } from '../../../helpers/l10n';
import IssueTypeIcon from '../../../components/ui/IssueTypeIcon';
import SeverityHelper from '../../../components/shared/SeverityHelper';
@@ -174,16 +175,15 @@ export default class RuleDetailsMeta extends React.PureComponent<Props, State> {
return null;
}
return (
- <Tooltip overlay={translate('coding_rules.custom_rule.title')}>
- <li className="coding-rules-detail-property">
- {translate('coding_rules.custom_rule')}
- {' ('}
- <Link to={getRuleUrl(ruleDetails.templateKey, this.props.organization)}>
- {translate('coding_rules.show_template')}
- </Link>
- {')'}
- </li>
- </Tooltip>
+ <li className="coding-rules-detail-property">
+ {translate('coding_rules.custom_rule')}
+ {' ('}
+ <Link to={getRuleUrl(ruleDetails.templateKey, this.props.organization)}>
+ {translate('coding_rules.show_template')}
+ </Link>
+ {')'}
+ <DocTooltip className="little-spacer-left" doc="rules/custom-rules" />
+ </li>
);
};
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/TemplateFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/TemplateFacet.tsx
index 4a5c87d4774..1f9c3f803ab 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/TemplateFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/TemplateFacet.tsx
@@ -20,6 +20,7 @@
import * as React from 'react';
import Facet, { BasicProps } from './Facet';
import { Omit } from '../../../app/types';
+import DocTooltip from '../../../components/docs/DocTooltip';
import { translate } from '../../../helpers/l10n';
interface Props extends Omit<BasicProps, 'onChange' | 'values'> {
@@ -55,8 +56,9 @@ export default class TemplateFacet extends React.PureComponent<Props> {
renderName={this.renderName}
renderTextName={this.renderName}
singleSelection={true}
- values={value !== undefined ? [String(value)] : []}
- />
+ values={value !== undefined ? [String(value)] : []}>
+ <DocTooltip className="spacer-left" doc="rules/rule-templates" />
+ </Facet>
);
}
}
diff --git a/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGate.js b/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGate.js
index 20ab7885146..8c647e71b56 100644
--- a/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGate.js
+++ b/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGate.js
@@ -25,6 +25,7 @@ import * as theme from '../../../app/theme';
import { translate } from '../../../helpers/l10n';
import Level from '../../../components/ui/Level';
import Tooltip from '../../../components/controls/Tooltip';
+import DocTooltip from '../../../components/docs/DocTooltip';
import HelpIcon from '../../../components/icons-components/HelpIcon';
/*:: import type { Component, MeasuresList } from '../types'; */
@@ -64,10 +65,11 @@ export default function QualityGate({ branchLike, component, measures } /*: Prop
return (
<div className="overview-quality-gate" id="overview-quality-gate">
- <h2 className="overview-title">
- {translate('overview.quality_gate')}
- <Level level={level} />
- </h2>
+ <div className="display-flex-center">
+ <h2 className="overview-title">{translate('overview.quality_gate')}</h2>
+ <DocTooltip className="spacer-left" doc="quality-gates/project-homepage-quality-gate" />
+ <Level className="big-spacer-left" level={level} />
+ </div>
{ignoredConditions && (
<div className="alert alert-info display-inline-block big-spacer-top">
diff --git a/server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/__snapshots__/QualityGate-test.js.snap b/server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/__snapshots__/QualityGate-test.js.snap
index 2b9f86b6062..2387806ada6 100644
--- a/server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/__snapshots__/QualityGate-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/__snapshots__/QualityGate-test.js.snap
@@ -5,14 +5,23 @@ exports[`renders message about ignored conditions 1`] = `
className="overview-quality-gate"
id="overview-quality-gate"
>
- <h2
- className="overview-title"
+ <div
+ className="display-flex-center"
>
- overview.quality_gate
+ <h2
+ className="overview-title"
+ >
+ overview.quality_gate
+ </h2>
+ <DocTooltip
+ className="spacer-left"
+ doc="quality-gates/project-homepage-quality-gate"
+ />
<Level
+ className="big-spacer-left"
level="OK"
/>
- </h2>
+ </div>
<div
className="alert alert-info display-inline-block big-spacer-top"
>
diff --git a/server/sonar-web/src/main/js/apps/overview/styles.css b/server/sonar-web/src/main/js/apps/overview/styles.css
index ac492720ff5..0d0dc6dbee9 100644
--- a/server/sonar-web/src/main/js/apps/overview/styles.css
+++ b/server/sonar-web/src/main/js/apps/overview/styles.css
@@ -45,11 +45,6 @@
font-weight: 400;
}
-.overview-title > .level {
- vertical-align: top;
- margin-left: 15px;
-}
-
/*
* Quality Gate
*/
diff --git a/server/sonar-web/src/main/js/apps/projectQualityGate/Header.tsx b/server/sonar-web/src/main/js/apps/projectQualityGate/Header.tsx
index 5adc7becf55..de42184f96d 100644
--- a/server/sonar-web/src/main/js/apps/projectQualityGate/Header.tsx
+++ b/server/sonar-web/src/main/js/apps/projectQualityGate/Header.tsx
@@ -18,12 +18,16 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import DocTooltip from '../../components/docs/DocTooltip';
import { translate } from '../../helpers/l10n';
export default function Header() {
return (
<header className="page-header">
- <h1 className="page-title">{translate('project_quality_gate.page')}</h1>
+ <div className="page-title display-flex-center">
+ <h1>{translate('project_quality_gate.page')}</h1>
+ <DocTooltip className="spacer-left" doc="quality-gates/quality-gate-projects" />
+ </div>
<div className="page-description">{translate('project_quality_gate.page.description')}</div>
</header>
);
diff --git a/server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/__snapshots__/Header-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/__snapshots__/Header-test.tsx.snap
index eaade8b5468..ccf8e090d57 100644
--- a/server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/__snapshots__/Header-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/__snapshots__/Header-test.tsx.snap
@@ -4,11 +4,17 @@ exports[`renders 1`] = `
<header
className="page-header"
>
- <h1
- className="page-title"
+ <div
+ className="page-title display-flex-center"
>
- project_quality_gate.page
- </h1>
+ <h1>
+ project_quality_gate.page
+ </h1>
+ <DocTooltip
+ className="spacer-left"
+ doc="quality-gates/quality-gate-projects"
+ />
+ </div>
<div
className="page-description"
>
diff --git a/server/sonar-web/src/main/js/apps/projectQualityProfiles/Header.tsx b/server/sonar-web/src/main/js/apps/projectQualityProfiles/Header.tsx
index b1347b6ff2e..cf31adcb621 100644
--- a/server/sonar-web/src/main/js/apps/projectQualityProfiles/Header.tsx
+++ b/server/sonar-web/src/main/js/apps/projectQualityProfiles/Header.tsx
@@ -18,12 +18,16 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import DocTooltip from '../../components/docs/DocTooltip';
import { translate } from '../../helpers/l10n';
export default function Header() {
return (
<header className="page-header">
- <h1 className="page-title">{translate('project_quality_profiles.page')}</h1>
+ <div className="page-title display-flex-center">
+ <h1>{translate('project_quality_profiles.page')}</h1>
+ <DocTooltip className="spacer-left" doc="quality-profiles/quality-profile-projects" />
+ </div>
<div className="page-description">
{translate('project_quality_profiles.page.description')}
</div>
diff --git a/server/sonar-web/src/main/js/apps/projectQualityProfiles/__tests__/__snapshots__/Header-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectQualityProfiles/__tests__/__snapshots__/Header-test.tsx.snap
index 4f0e35f4a2f..03ed0f32b01 100644
--- a/server/sonar-web/src/main/js/apps/projectQualityProfiles/__tests__/__snapshots__/Header-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projectQualityProfiles/__tests__/__snapshots__/Header-test.tsx.snap
@@ -4,11 +4,17 @@ exports[`renders 1`] = `
<header
className="page-header"
>
- <h1
- className="page-title"
+ <div
+ className="page-title display-flex-center"
>
- project_quality_profiles.page
- </h1>
+ <h1>
+ project_quality_profiles.page
+ </h1>
+ <DocTooltip
+ className="spacer-left"
+ doc="quality-profiles/quality-profile-projects"
+ />
+ </div>
<div
className="page-description"
>
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js
index f3fb35559e7..982d6d9f2ab 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js
@@ -21,6 +21,7 @@ import React from 'react';
import { sortBy, uniqBy } from 'lodash';
import AddConditionForm from './AddConditionForm';
import Condition from './Condition';
+import DocTooltip from '../../../components/docs/DocTooltip';
import { translate, getLocalizedMetricName } from '../../../helpers/l10n';
function getKey(condition, index) {
@@ -89,7 +90,10 @@ export default class Conditions extends React.PureComponent {
}));
return (
<div className="quality-gate-section" id="quality-gate-conditions">
- <h3 className="spacer-bottom">{translate('quality_gates.conditions')}</h3>
+ <header className="display-flex-center spacer-bottom">
+ <h3>{translate('quality_gates.conditions')}</h3>
+ <DocTooltip className="spacer-left" doc="quality-gates/quality-gate-conditions" />
+ </header>
<div className="big-spacer-bottom">{translate('quality_gates.introduction')}</div>
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js
index ebe73fe1e8a..35b37f12bae 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js
@@ -20,6 +20,7 @@
import React from 'react';
import Conditions from './Conditions';
import Projects from './Projects';
+import DocTooltip from '../../../components/docs/DocTooltip';
import { translate } from '../../../helpers/l10n';
export default class DetailsContent extends React.PureComponent {
@@ -47,7 +48,10 @@ export default class DetailsContent extends React.PureComponent {
/>
<div id="quality-gate-projects" className="quality-gate-section">
- <h3 className="spacer-bottom">{translate('quality_gates.projects')}</h3>
+ <header className="display-flex-center spacer-bottom">
+ <h3>{translate('quality_gates.projects')}</h3>
+ <DocTooltip className="spacer-left" doc="quality-gates/quality-gate-projects" />
+ </header>
{gate.isDefault ? (
defaultMessage
) : (
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx
index a661becfdef..8e2b1aa14ba 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx
@@ -23,6 +23,7 @@ import RenameQualityGateForm from './RenameQualityGateForm';
import CopyQualityGateForm from './CopyQualityGateForm';
import DeleteQualityGateForm from './DeleteQualityGateForm';
import { fetchQualityGate, QualityGate, setQualityGateAsDefault } from '../../../api/quality-gates';
+import DocTooltip from '../../../components/docs/DocTooltip';
import { Button } from '../../../components/ui/buttons';
import { translate } from '../../../helpers/l10n';
@@ -73,10 +74,15 @@ export default class DetailsHeader extends React.PureComponent<Props, State> {
<div className="layout-page-header-panel layout-page-main-header issues-main-header">
<div className="layout-page-header-panel-inner layout-page-main-header-inner">
<div className="layout-page-main-inner">
- <h2 className="pull-left">
- {qualityGate.name}
- {qualityGate.isBuiltIn && <BuiltInQualityGateBadge className="spacer-left" />}
- </h2>
+ <div className="pull-left display-flex-center">
+ <h2>{qualityGate.name}</h2>
+ {qualityGate.isBuiltIn && (
+ <>
+ <BuiltInQualityGateBadge className="spacer-left" />
+ <DocTooltip className="spacer-left" doc="quality-gates/built-in-quality-gate" />
+ </>
+ )}
+ </div>
<div className="pull-right">
{actions.rename && (
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/ListHeader.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/ListHeader.tsx
index 4a267e581fb..da61b1c5623 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/ListHeader.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/ListHeader.tsx
@@ -21,6 +21,7 @@ import * as React from 'react';
import CreateQualityGateForm from '../components/CreateQualityGateForm';
import { QualityGate } from '../../../api/quality-gates';
import { Organization } from '../../../app/types';
+import DocTooltip from '../../../components/docs/DocTooltip';
import { Button } from '../../../components/ui/buttons';
import { translate } from '../../../helpers/l10n';
@@ -50,7 +51,6 @@ export default class ListHeader extends React.PureComponent<Props, State> {
return (
<header className="page-header">
- <h1 className="page-title">{translate('quality_gates.page')}</h1>
{this.props.canCreate && (
<div className="page-actions">
<Button id="quality-gate-add" onClick={this.openCreateQualityGateForm}>
@@ -58,6 +58,10 @@ export default class ListHeader extends React.PureComponent<Props, State> {
</Button>
</div>
)}
+ <div className="display-flex-center">
+ <h1 className="page-title">{translate('quality_gates.page')}</h1>
+ <DocTooltip className="spacer-left" doc="quality-gates/quality-gate" />
+ </div>
{this.state.createQualityGateOpen && (
<CreateQualityGateForm
onClose={this.closeCreateQualityGateForm}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.tsx
index c30eff07980..af274592121 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.tsx
@@ -32,8 +32,8 @@ interface Props {
export default function ProfileLink({ name, language, organization, children, ...other }: Props) {
return (
<Link
- to={getProfilePath(name, language, organization)}
activeClassName="link-no-underline"
+ to={getProfilePath(name, language, organization)}
{...other}>
{children}
</Link>
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx
index 812d6110047..ae1e57854f9 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx
@@ -21,6 +21,7 @@ import * as React from 'react';
import { groupBy, pick, sortBy } from 'lodash';
import ProfilesListRow from './ProfilesListRow';
import ProfilesListHeader from './ProfilesListHeader';
+import DocTooltip from '../../../components/docs/DocTooltip';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { Profile } from '../types';
@@ -61,7 +62,13 @@ export default class ProfilesList extends React.PureComponent<Props> {
{', '}
{translateWithParameters('quality_profiles.x_profiles', profilesCount)}
</th>
- <th className="text-right nowrap">{translate('quality_profiles.list.projects')}</th>
+ <th className="text-right nowrap">
+ {translate('quality_profiles.list.projects')}
+ <DocTooltip
+ className="table-cell-doc"
+ doc="quality-profiles/quality-profile-projects"
+ />
+ </th>
<th className="text-right nowrap">{translate('quality_profiles.list.rules')}</th>
<th className="text-right nowrap">{translate('quality_profiles.list.updated')}</th>
<th className="text-right nowrap">{translate('quality_profiles.list.used')}</th>
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx
index 677ce226b99..a0b3302ff48 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx
@@ -28,6 +28,7 @@ import { getRulesUrl } from '../../../helpers/urls';
import { isStagnant } from '../utils';
import { Profile } from '../types';
import Tooltip from '../../../components/controls/Tooltip';
+import DocTooltip from '../../../components/docs/DocTooltip';
interface Props {
onRequestFail: (reason: any) => void;
@@ -41,14 +42,21 @@ export default class ProfilesListRow extends React.PureComponent<Props> {
const { profile } = this.props;
const offset = 25 * (profile.depth - 1);
return (
- <div style={{ paddingLeft: offset }}>
- <ProfileLink
- language={profile.language}
- name={profile.name}
- organization={this.props.organization}>
- {profile.name}
- </ProfileLink>
- {profile.isBuiltIn && <BuiltInQualityProfileBadge className="spacer-left" />}
+ <div className="display-flex-center" style={{ paddingLeft: offset }}>
+ <div>
+ <ProfileLink
+ language={profile.language}
+ name={profile.name}
+ organization={this.props.organization}>
+ {profile.name}
+ </ProfileLink>
+ </div>
+ {profile.isBuiltIn && (
+ <>
+ <BuiltInQualityProfileBadge className="spacer-left" />
+ <DocTooltip className="spacer-left" doc="quality-profiles/built-in-quality-profile" />
+ </>
+ )}
</div>
);
}
@@ -57,7 +65,12 @@ export default class ProfilesListRow extends React.PureComponent<Props> {
const { profile } = this.props;
if (profile.isDefault) {
- return <span className="badge">{translate('default')}</span>;
+ return (
+ <>
+ <span className="badge">{translate('default')}</span>
+ <DocTooltip className="table-cell-doc" doc="quality-profiles/default-quality-profile" />
+ </>
+ );
}
return <span>{profile.projectCount}</span>;
@@ -122,23 +135,23 @@ export default class ProfilesListRow extends React.PureComponent<Props> {
render() {
return (
<tr
- className="quality-profiles-table-row"
+ className="quality-profiles-table-row text-middle"
data-key={this.props.profile.key}
data-name={this.props.profile.name}>
- <td className="quality-profiles-table-name">{this.renderName()}</td>
- <td className="quality-profiles-table-projects thin nowrap text-right">
+ <td className="quality-profiles-table-name text-middle">{this.renderName()}</td>
+ <td className="quality-profiles-table-projects thin nowrap text-middle text-right">
{this.renderProjects()}
</td>
- <td className="quality-profiles-table-rules thin nowrap text-right">
+ <td className="quality-profiles-table-rules thin nowrap text-middle text-right">
{this.renderRules()}
</td>
- <td className="quality-profiles-table-date thin nowrap text-right">
+ <td className="quality-profiles-table-date thin nowrap text-middle text-right">
{this.renderUpdateDate()}
</td>
- <td className="quality-profiles-table-date thin nowrap text-right">
+ <td className="quality-profiles-table-date thin nowrap text-middle text-right">
{this.renderUsageDate()}
</td>
- <td className="quality-profiles-table-actions thin nowrap text-right">
+ <td className="quality-profiles-table-actions thin nowrap text-middle text-right">
<ProfileActions
fromList={true}
onRequestFail={this.props.onRequestFail}
diff --git a/server/sonar-web/src/main/js/components/common/BubblePopup.tsx b/server/sonar-web/src/main/js/components/common/BubblePopup.tsx
index 38ebd834989..7020ee57490 100644
--- a/server/sonar-web/src/main/js/components/common/BubblePopup.tsx
+++ b/server/sonar-web/src/main/js/components/common/BubblePopup.tsx
@@ -32,6 +32,10 @@ interface Props {
position: BubblePopupPosition;
}
+/**
+ * Deprecated.
+ * Use <Popup /> instead.
+ */
export default function BubblePopup(props: Props) {
const popupClass = classNames('bubble-popup', props.customClass);
const popupStyle = { ...props.position };
diff --git a/server/sonar-web/src/main/js/components/controls/Popup.tsx b/server/sonar-web/src/main/js/components/controls/Popup.tsx
new file mode 100644
index 00000000000..68f8415f4e5
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/controls/Popup.tsx
@@ -0,0 +1,73 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 OutsideClickHandler from './OutsideClickHandler';
+import Tooltip from './Tooltip';
+
+interface Props {
+ children: (props: { onClick: () => void }) => React.ReactElement<any>;
+ overlay: React.ReactNode;
+}
+
+interface State {
+ visible: boolean;
+}
+
+export default class Popup extends React.Component<Props, State> {
+ state: State = { visible: false };
+
+ componentWillReceiveProps(nextProps: Props) {
+ if (nextProps.overlay !== this.props.overlay) {
+ this.setState({ visible: false });
+ }
+ }
+
+ handleClick = (event?: React.MouseEvent<HTMLElement>) => {
+ if (event) {
+ event.preventDefault();
+ event.currentTarget.blur();
+ }
+
+ // defer opening to not trigger OutsideClickHandler.onClickOutside callback
+ setTimeout(() => {
+ this.setState({ visible: true });
+ }, 0);
+ };
+
+ handleClickOutside = () => {
+ this.setState({ visible: false });
+ };
+
+ renderOverlay() {
+ return (
+ <OutsideClickHandler onClickOutside={this.handleClickOutside}>
+ {({ ref }) => <div ref={ref}>{this.props.overlay}</div>}
+ </OutsideClickHandler>
+ );
+ }
+
+ render() {
+ return (
+ <Tooltip classNameSpace="popup" overlay={this.renderOverlay()} visible={this.state.visible}>
+ {this.props.children({ onClick: this.handleClick })}
+ </Tooltip>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/components/controls/Tooltip.css b/server/sonar-web/src/main/js/components/controls/Tooltip.css
index c2529a06b75..bbb8ae5c942 100644
--- a/server/sonar-web/src/main/js/components/controls/Tooltip.css
+++ b/server/sonar-web/src/main/js/components/controls/Tooltip.css
@@ -17,72 +17,120 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-.tooltip {
+.tooltip,
+.popup {
position: absolute;
z-index: var(--tooltipZIndex);
display: block;
height: auto;
box-sizing: border-box;
+}
+
+.tooltip {
font-size: var(--smallFontSize);
font-weight: 300;
line-height: 1.5;
animation: fadeIn 0.3s forwards;
}
-.tooltip.top {
+.popup {
+ font-size: var(--baseFontSize);
+ font-weight: normal;
+}
+
+.tooltip.top,
+.popup.top {
padding: 5px 0;
margin-top: -3px;
}
-.tooltip.right {
+.tooltip.right,
+.popup.right {
padding: 0 5px;
margin-left: 3px;
}
-.tooltip.bottom {
+.tooltip.bottom,
+.popup.bottom {
padding: 5px 0;
margin-top: 3px;
}
-.tooltip.left {
+.tooltip.left,
+.popup.left {
padding: 0 5px;
margin-left: -3px;
}
-.tooltip-inner {
+.tooltip-inner,
+.popup-inner {
max-width: 300px;
- padding: 3px 8px;
- color: #fff;
text-align: left;
text-decoration: none;
- background-color: #475760;
border-radius: 4px;
- letter-spacing: 0.04em;
overflow: hidden;
word-break: break-word;
}
+.tooltip-inner {
+ padding: 3px 8px;
+ color: #fff;
+ background-color: #475760;
+ letter-spacing: 0.04em;
+}
+
+.popup-inner {
+ padding: calc(2 * var(--gridSize));
+ border: 1px solid var(--barBorderColor);
+ color: var(--baseFontColor);
+ background-color: #fff;
+ box-shadow: var(--defaultShadow);
+}
+
.tooltip-inner .alert {
margin-bottom: 5px;
border-radius: 4px;
}
-.tooltip-arrow {
+.tooltip-inner a {
+ color: var(--lightBlue);
+}
+
+.tooltip-arrow,
+.popup-arrow,
+.popup-arrow::after {
position: absolute;
width: 0;
height: 0;
border: solid transparent;
}
-.tooltip.top .tooltip-arrow {
+.tooltip.top .tooltip-arrow,
+.popup.top .popup-arrow,
+.popup.top .popup-arrow::after {
bottom: 0;
left: 50%;
border-width: 5px 5px 0;
- border-top-color: #475760;
transform: translateX(-5px);
}
-.tooltip.right .tooltip-arrow {
+.tooltip.top .tooltip-arrow {
+ border-top-color: #475760;
+}
+
+.popup.top .popup-arrow {
+ border-top-color: var(--barBorderColor);
+}
+
+.popup.top .popup-arrow::after {
+ content: '';
+ border-top-color: #fff;
+ transform: translateX(-5px) translateY(-1px);
+}
+
+.tooltip.right .tooltip-arrow,
+.popup.right .popup-arrow,
+.popup.right .popup-arrow::after {
top: 50%;
left: 0;
transform: translateY(-5px);
@@ -90,7 +138,23 @@
border-right-color: #475760;
}
-.tooltip.left .tooltip-arrow {
+.tooltip.right .tooltip-arrow {
+ border-right-color: #475760;
+}
+
+.popup.right .popup-arrow {
+ border-right-color: var(--barBorderColor);
+}
+
+.popup.right .popup-arrow::after {
+ content: '';
+ border-right-color: #fff;
+ transform: translateY(-5px) translateX(1px);
+}
+
+.tooltip.left .tooltip-arrow,
+.popup.left .popup-arrow,
+.popup.left .popup-arrow::after {
top: 50%;
right: 0;
transform: translateY(-5px);
@@ -98,7 +162,23 @@
border-left-color: #475760;
}
-.tooltip.bottom .tooltip-arrow {
+.tooltip.left .tooltip-arrow {
+ border-left-color: #475760;
+}
+
+.popup.left .popup-arrow {
+ border-left-color: var(--barBorderColor);
+}
+
+.popup.left .popup-arrow::after {
+ content: '';
+ border-left-color: #fff;
+ transform: translateY(-5px) translateX(-1px);
+}
+
+.tooltip.bottom .tooltip-arrow,
+.popup.bottom .popup-arrow,
+.popup.bottom .popup-arrow::after {
top: 0;
left: 50%;
transform: translateX(-5px);
@@ -106,6 +186,20 @@
border-bottom-color: #475760;
}
+.tooltip.bottom .tooltip-arrow {
+ border-bottom-color: #475760;
+}
+
+.popup.bottom .popup-arrow {
+ border-bottom-color: var(--barBorderColor);
+}
+
+.popup.bottom .popup-arrow::after {
+ content: '';
+ border-bottom-color: #fff;
+ transform: translateX(-5px) translateY(1px);
+}
+
@keyframes fadeIn {
from {
opacity: 0;
diff --git a/server/sonar-web/src/main/js/components/controls/Tooltip.tsx b/server/sonar-web/src/main/js/components/controls/Tooltip.tsx
index a16c9c691db..adc29a6270e 100644
--- a/server/sonar-web/src/main/js/components/controls/Tooltip.tsx
+++ b/server/sonar-web/src/main/js/components/controls/Tooltip.tsx
@@ -25,6 +25,7 @@ import './Tooltip.css';
export type Placement = 'bottom' | 'right' | 'left' | 'top';
interface Props {
+ classNameSpace?: string;
children: React.ReactElement<{}>;
mouseEnterDelay?: number;
onShow?: () => void;
@@ -244,6 +245,8 @@ export class TooltipInner extends React.Component<Props, State> {
};
render() {
+ const { classNameSpace = 'tooltip' } = this.props;
+
return (
<>
{React.cloneElement(this.props.children, {
@@ -253,7 +256,7 @@ export class TooltipInner extends React.Component<Props, State> {
{this.isVisible() && (
<TooltipPortal>
<div
- className={`tooltip ${this.getPlacement()}`}
+ className={`${classNameSpace} ${this.getPlacement()}`}
ref={this.tooltipNodeRef}
style={
isMeasured(this.state)
@@ -265,9 +268,9 @@ export class TooltipInner extends React.Component<Props, State> {
}
: undefined
}>
- <div className="tooltip-inner">{this.props.overlay}</div>
+ <div className={`${classNameSpace}-inner`}>{this.props.overlay}</div>
<div
- className="tooltip-arrow"
+ className={`${classNameSpace}-arrow`}
style={
isMeasured(this.state)
? { marginLeft: -this.state.leftFix, marginTop: -this.state.topFix }
diff --git a/server/sonar-web/src/main/js/components/docs/DocLink.tsx b/server/sonar-web/src/main/js/components/docs/DocLink.tsx
new file mode 100644
index 00000000000..fd19f91cd94
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/docs/DocLink.tsx
@@ -0,0 +1,45 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { Link } from 'react-router';
+
+export default function DocLink(props: React.AnchorHTMLAttributes<HTMLAnchorElement>) {
+ const { children, href, ...other } = props;
+
+ if (process.env.NODE_ENV === 'development') {
+ if (href && href.startsWith('#')) {
+ return (
+ <>
+ {/* TODO implement after SONAR-10612 Create documentation space in the web app */}
+ <Link to="" {...other}>
+ {children}
+ </Link>
+ <strong className="little-spacer-left text-danger">[TODO]</strong>
+ </>
+ );
+ }
+ }
+
+ return (
+ <a href={href} {...other}>
+ {children}
+ </a>
+ );
+}
diff --git a/server/sonar-web/src/main/js/components/docs/DocMarkdownBlock.tsx b/server/sonar-web/src/main/js/components/docs/DocMarkdownBlock.tsx
new file mode 100644
index 00000000000..7a74a9f4b10
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/docs/DocMarkdownBlock.tsx
@@ -0,0 +1,48 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 * as classNames from 'classnames';
+import remark from 'remark';
+import reactRenderer from 'remark-react';
+import DocLink from './DocLink';
+
+interface Props {
+ className?: string;
+ content: string | undefined;
+}
+
+export default function DocMarkdownBlock({ className, content }: Props) {
+ return (
+ <div className={classNames('markdown', className)}>
+ {
+ remark()
+ .use(reactRenderer, {
+ remarkReactComponents: {
+ // do not render outer <div />
+ div: React.Fragment,
+ // use custom link to render documentation anchors
+ a: DocLink
+ }
+ })
+ .processSync(content).contents
+ }
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/components/docs/DocTooltip.tsx b/server/sonar-web/src/main/js/components/docs/DocTooltip.tsx
new file mode 100644
index 00000000000..0dc27dd9954
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/docs/DocTooltip.tsx
@@ -0,0 +1,134 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 * as classNames from 'classnames';
+import DocMarkdownBlock from './DocMarkdownBlock';
+import HelpIcon from '../icons-components/HelpIcon';
+import Tooltip from '../controls/Tooltip';
+import OutsideClickHandler from '../controls/OutsideClickHandler';
+import * as theme from '../../app/theme';
+
+interface Props {
+ className?: string;
+ /** Key of the documentation chunk */
+ doc: string;
+}
+
+interface State {
+ content?: string;
+ loading: boolean;
+ open: boolean;
+}
+
+export default class DocTooltip extends React.PureComponent<Props, State> {
+ mounted = false;
+ state: State = { loading: false, open: false };
+
+ componentDidMount() {
+ this.mounted = true;
+ document.addEventListener('scroll', this.close, true);
+ }
+
+ componentWillReceiveProps(nextProps: Props) {
+ if (nextProps.doc !== this.props.doc) {
+ this.setState({ content: undefined, loading: false, open: false });
+ }
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ document.removeEventListener('scroll', this.close, true);
+ }
+
+ fetchContent = () => {
+ this.setState({ loading: true });
+ import(`Docs/${this.props.doc}.md`).then(
+ ({ default: content }) => {
+ if (this.mounted) {
+ this.setState({ content, loading: false });
+ }
+ },
+ () => {
+ if (this.mounted) {
+ this.setState({ loading: false });
+ }
+ }
+ );
+ };
+
+ close = () => {
+ this.setState({ open: false });
+ };
+
+ handleHelpClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
+ event.preventDefault();
+ event.currentTarget.blur();
+ if (!this.state.open && !this.state.loading && this.state.content === undefined) {
+ this.fetchContent();
+ }
+
+ if (this.state.open) {
+ this.setState({ open: false });
+ } else {
+ // defer opening to not trigger OutsideClickHandler.onClickOutside callback
+ setTimeout(() => {
+ this.setState({ open: true });
+ }, 0);
+ }
+ };
+
+ renderOverlay() {
+ if (this.state.loading) {
+ return (
+ <div className="abs-width-300">
+ <i className="spinner" />
+ </div>
+ );
+ }
+
+ return (
+ <OutsideClickHandler onClickOutside={this.close}>
+ {({ ref }) => (
+ <div ref={ref}>
+ <DocMarkdownBlock className="cut-margins abs-width-300" content={this.state.content} />
+ </div>
+ )}
+ </OutsideClickHandler>
+ );
+ }
+
+ render() {
+ return (
+ <div className={classNames('display-flex-center', this.props.className)}>
+ <Tooltip
+ classNameSpace="popup"
+ overlay={this.renderOverlay()}
+ visible={this.state.content !== undefined && this.state.open}>
+ <a
+ className="display-flex-center link-no-underline"
+ href="#"
+ onClick={this.handleHelpClick}>
+ <HelpIcon fill={theme.gray80} size={12} />
+ </a>
+ </Tooltip>
+ </div>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/components/docs/__tests__/DocLink-test.tsx b/server/sonar-web/src/main/js/components/docs/__tests__/DocLink-test.tsx
new file mode 100644
index 00000000000..ad740c2d833
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/docs/__tests__/DocLink-test.tsx
@@ -0,0 +1,30 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+import DocLink from '../DocLink';
+
+it('should render simple link', () => {
+ expect(shallow(<DocLink href="http://sample.com" />)).toMatchSnapshot();
+});
+
+it.skip('should render documentation anchor', () => {
+ expect(shallow(<DocLink href="#quality-profiles" />)).toMatchSnapshot();
+});
diff --git a/server/sonar-web/src/main/js/components/docs/__tests__/DocMarkdownBlock-test.tsx b/server/sonar-web/src/main/js/components/docs/__tests__/DocMarkdownBlock-test.tsx
new file mode 100644
index 00000000000..587343d7c0b
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/docs/__tests__/DocMarkdownBlock-test.tsx
@@ -0,0 +1,43 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+import DocMarkdownBlock from '../DocMarkdownBlock';
+
+// mock `remark` and `remark-react` to work around the issue with cjs imports
+jest.mock('remark', () => {
+ const remark = require.requireActual('remark');
+ return { default: remark };
+});
+
+jest.mock('remark-react', () => {
+ const remarkReact = require.requireActual('remark-react');
+ return { default: remarkReact };
+});
+
+it('should render simple markdown', () => {
+ expect(shallow(<DocMarkdownBlock content="this is *bold* text" />)).toMatchSnapshot();
+});
+
+it('should render use custom component for links', () => {
+ expect(
+ shallow(<DocMarkdownBlock content="some [link](#quality-profiles)" />).find('DocLink')
+ ).toMatchSnapshot();
+});
diff --git a/server/sonar-web/src/main/js/components/docs/__tests__/DocTooltip-test.tsx b/server/sonar-web/src/main/js/components/docs/__tests__/DocTooltip-test.tsx
new file mode 100644
index 00000000000..bc5b4998cc7
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/docs/__tests__/DocTooltip-test.tsx
@@ -0,0 +1,48 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+import DocTooltip from '../DocTooltip';
+import { click } from '../../../helpers/testUtils';
+
+jest.useFakeTimers();
+
+it('should render', () => {
+ const wrapper = shallow(<DocTooltip doc="foo/bar" />);
+ wrapper.setState({ content: 'this is *bold* text', open: true, loading: true });
+ expect(wrapper).toMatchSnapshot();
+ wrapper.setState({ loading: false });
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('should reset state when receiving new doc', () => {
+ const wrapper = shallow(<DocTooltip doc="foo/bar" />);
+ wrapper.setState({ content: 'this is *bold* text', open: true });
+ wrapper.setProps({ doc: 'baz' });
+ expect(wrapper.state()).toEqual({ content: undefined, loading: false, open: false });
+});
+
+it('should toggle', () => {
+ const wrapper = shallow(<DocTooltip doc="foo/bar" />);
+ expect(wrapper.state('open')).toBe(false);
+ click(wrapper.find('a'));
+ jest.runAllTimers();
+ expect(wrapper.state('open')).toBe(true);
+});
diff --git a/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocLink-test.tsx.snap b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocLink-test.tsx.snap
new file mode 100644
index 00000000000..97a6d1d24bc
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocLink-test.tsx.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render simple link 1`] = `
+<a
+ href="http://sample.com"
+/>
+`;
diff --git a/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocMarkdownBlock-test.tsx.snap b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocMarkdownBlock-test.tsx.snap
new file mode 100644
index 00000000000..28a2441e530
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocMarkdownBlock-test.tsx.snap
@@ -0,0 +1,32 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render simple markdown 1`] = `
+<div
+ className="markdown"
+>
+ <React.Fragment
+ key="h-1"
+ >
+ <p
+ key="h-2"
+ >
+ this is
+ <em
+ key="h-3"
+ >
+ bold
+ </em>
+ text
+ </p>
+ </React.Fragment>
+</div>
+`;
+
+exports[`should render use custom component for links 1`] = `
+<DocLink
+ href="#quality-profiles"
+ key="h-3"
+>
+ link
+</DocLink>
+`;
diff --git a/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap
new file mode 100644
index 00000000000..38e7789c044
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap
@@ -0,0 +1,61 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render 1`] = `
+<div
+ className="display-flex-center"
+>
+ <Tooltip
+ classNameSpace="popup"
+ overlay={
+ <div
+ className="abs-width-300"
+ >
+ <i
+ className="spinner"
+ />
+ </div>
+ }
+ visible={true}
+ >
+ <a
+ className="display-flex-center link-no-underline"
+ href="#"
+ onClick={[Function]}
+ >
+ <HelpIcon
+ fill="#cdcdcd"
+ size={12}
+ />
+ </a>
+ </Tooltip>
+</div>
+`;
+
+exports[`should render 2`] = `
+<div
+ className="display-flex-center"
+>
+ <Tooltip
+ classNameSpace="popup"
+ overlay={
+ <OutsideClickHandler
+ onClickOutside={[Function]}
+ >
+ [Function]
+ </OutsideClickHandler>
+ }
+ visible={true}
+ >
+ <a
+ className="display-flex-center link-no-underline"
+ href="#"
+ onClick={[Function]}
+ >
+ <HelpIcon
+ fill="#cdcdcd"
+ size={12}
+ />
+ </a>
+ </Tooltip>
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/components/facet/FacetHeader.tsx b/server/sonar-web/src/main/js/components/facet/FacetHeader.tsx
index 00b6803c124..cc1ae72047a 100644
--- a/server/sonar-web/src/main/js/components/facet/FacetHeader.tsx
+++ b/server/sonar-web/src/main/js/components/facet/FacetHeader.tsx
@@ -25,8 +25,9 @@ import { Button } from '../ui/buttons';
import { translate, translateWithParameters } from '../../helpers/l10n';
interface Props {
+ children?: React.ReactNode;
helper?: string;
- name: string;
+ name: React.ReactNode;
onClear?: () => void;
onClick?: () => void;
open: boolean;
@@ -90,6 +91,8 @@ export default class FacetHeader extends React.PureComponent<Props> {
</span>
)}
+ {this.props.children}
+
<span className="search-navigator-facet-header-value spacer-left spacer-right ">
{this.renderValueIndicator()}
</span>
diff --git a/server/sonar-web/src/main/js/components/icons-components/PlusCircleIcon.tsx b/server/sonar-web/src/main/js/components/icons-components/PlusCircleIcon.tsx
new file mode 100644
index 00000000000..eb529b71d77
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/icons-components/PlusCircleIcon.tsx
@@ -0,0 +1,39 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { IconProps } from './types';
+
+export default function PlusCircleIcon({ className, fill = 'currentColor', size = 16 }: IconProps) {
+ return (
+ <svg
+ className={className}
+ height={size}
+ version="1.1"
+ viewBox="0 0 16 16"
+ width={size}
+ xmlSpace="preserve"
+ xmlnsXlink="http://www.w3.org/1999/xlink">
+ <path
+ d="M8 1c3.863 0 7 3.137 7 7s-3.137 7-7 7-7-3.137-7-7 3.137-7 7-7zm3.726 7.985A.274.274 0 0 0 12 8.711V7.289a.274.274 0 0 0-.274-.274H8.985V4.274A.274.274 0 0 0 8.711 4H7.289a.274.274 0 0 0-.274.274v2.741H4.274A.274.274 0 0 0 4 7.289v1.422c0 .152.123.274.274.274h2.741v2.741c0 .151.122.274.274.274h1.422a.274.274 0 0 0 .274-.274V8.985h2.741z"
+ style={{ fill }}
+ />;
+ </svg>
+ );
+}
diff --git a/server/sonar-web/yarn.lock b/server/sonar-web/yarn.lock
index 873367f260e..d9881ef214d 100644
--- a/server/sonar-web/yarn.lock
+++ b/server/sonar-web/yarn.lock
@@ -121,6 +121,13 @@
version "16.0.29"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.0.29.tgz#4eea6a8de9f40ca71d580ae7a9f3b4b77b368de8"
+JSONStream@^1.0.4:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea"
+ dependencies:
+ jsonparse "^1.2.0"
+ through ">=2.2.7 <3"
+
abab@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
@@ -162,6 +169,10 @@ acorn@^5.0.0, acorn@^5.1.2, acorn@^5.3.0, acorn@^5.5.0:
version "5.5.3"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9"
+add-stream@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa"
+
address@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/address/-/address-1.0.2.tgz#480081e82b587ba319459fef512f516fe03d58af"
@@ -345,6 +356,10 @@ array-flatten@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.1.tgz#426bb9da84090c1838d812c8150af20a8331e296"
+array-ify@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece"
+
array-includes@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d"
@@ -352,6 +367,10 @@ array-includes@^3.0.3:
define-properties "^1.1.2"
es-abstract "^1.7.0"
+array-iterate@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/array-iterate/-/array-iterate-1.1.2.tgz#f66a57e84426f8097f4197fbb6c051b8e5cdf7d8"
+
array-map@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
@@ -1115,6 +1134,10 @@ babylon@^6.18.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
+bail@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.3.tgz#63cfb9ddbac829b02a3128cd53224be78e6c21a3"
+
balanced-match@^0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
@@ -1437,6 +1460,14 @@ camelcase-keys@^2.0.0:
camelcase "^2.0.0"
map-obj "^1.0.0"
+camelcase-keys@^4.0.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77"
+ dependencies:
+ camelcase "^4.1.0"
+ map-obj "^2.0.0"
+ quick-lru "^1.0.0"
+
camelcase@^1.0.2:
version "1.2.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"
@@ -1470,6 +1501,10 @@ caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
+ccount@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.3.tgz#f1cec43f332e2ea5a569fd46f9f5bde4e6102aff"
+
center-align@^0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad"
@@ -1503,6 +1538,22 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
+character-entities-html4@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.2.tgz#c44fdde3ce66b52e8d321d6c1bf46101f0150610"
+
+character-entities-legacy@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.2.tgz#7c6defb81648498222c9855309953d05f4d63a9c"
+
+character-entities@^1.0.0:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.2.tgz#58c8f371c0774ef0ba9b2aca5f00d8f100e6e363"
+
+character-reference-invalid@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.2.tgz#21e421ad3d84055952dab4a43a04e73cd425d3ed"
+
check-types@^7.3.0:
version "7.3.0"
resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.3.0.tgz#468f571a4435c24248f5fd0cb0e8d87c3c341e7d"
@@ -1675,6 +1726,10 @@ code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+collapse-white-space@^1.0.0, collapse-white-space@^1.0.2:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.4.tgz#ce05cf49e54c3277ae573036a26851ba430a0091"
+
collection-visit@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
@@ -1728,6 +1783,12 @@ combined-stream@^1.0.5, combined-stream@~1.0.5:
dependencies:
delayed-stream "~1.0.0"
+comma-separated-tokens@^1.0.0:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.5.tgz#b13793131d9ea2d2431cf5b507ddec258f0ce0db"
+ dependencies:
+ trim "0.0.1"
+
commander@2.11.x, commander@~2.11.0:
version "2.11.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"
@@ -1744,6 +1805,13 @@ commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
+compare-func@^1.3.1:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648"
+ dependencies:
+ array-ify "^1.0.0"
+ dot-prop "^3.0.0"
+
component-emitter@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
@@ -1813,6 +1881,62 @@ content-type@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
+conventional-changelog-angular@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-0.1.0.tgz#ac3d4b869878de5ad57726696b21eedd798ae3c7"
+ dependencies:
+ compare-func "^1.3.1"
+ q "^1.4.1"
+
+conventional-changelog-core@^0.0.2:
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-0.0.2.tgz#795a298de84f8801398cd0fee20fb799a1f02089"
+ dependencies:
+ conventional-changelog-writer "^0.4.1"
+ conventional-commits-parser "^0.1.2"
+ dateformat "^1.0.12"
+ get-pkg-repo "^0.1.0"
+ git-raw-commits "^0.1.2"
+ git-semver-tags "^1.1.0"
+ lodash "^4.0.0"
+ q "^1.4.1"
+ read-pkg "^1.1.0"
+ read-pkg-up "^1.0.1"
+ through2 "^2.0.0"
+
+conventional-changelog-writer@^0.4.1:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-0.4.2.tgz#ccb03c5ebd17ceb94a236cb80b27f4ef6bee7731"
+ dependencies:
+ compare-func "^1.3.1"
+ conventional-commits-filter "^0.1.0"
+ dateformat "^1.0.11"
+ handlebars "^4.0.2"
+ lodash "^4.0.0"
+ meow "^3.3.0"
+ semver "^5.0.1"
+ split "^1.0.0"
+ through2 "^2.0.0"
+
+conventional-commits-filter@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-0.1.1.tgz#d9d26c7599f89de3d249cba3def7911fc51c0dab"
+ dependencies:
+ is-subset "^0.1.1"
+ modify-values "^1.0.0"
+
+conventional-commits-parser@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-0.1.2.tgz#4a624010634f02122520ecbaf19ca0ba23120437"
+ dependencies:
+ JSONStream "^1.0.4"
+ is-text-path "^1.0.0"
+ lodash "^3.3.1"
+ meow "^3.3.0"
+ split "^1.0.0"
+ through2 "^2.0.0"
+ trim-off-newlines "^1.0.0"
+
convert-source-map@^1.4.0, convert-source-map@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
@@ -2158,6 +2282,12 @@ damerau-levenshtein@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514"
+dargs@^4.0.1:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17"
+ dependencies:
+ number-is-nan "^1.0.0"
+
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
@@ -2172,6 +2302,13 @@ date-now@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
+dateformat@^1.0.11, dateformat@^1.0.12:
+ version "1.0.12"
+ resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9"
+ dependencies:
+ get-stdin "^4.0.1"
+ meow "^3.3.0"
+
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.6, debug@^2.6.8:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@@ -2184,7 +2321,14 @@ debug@^3.1.0:
dependencies:
ms "2.0.0"
-decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2:
+decamelize-keys@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9"
+ dependencies:
+ decamelize "^1.1.0"
+ map-obj "^1.0.0"
+
+decamelize@^1.0.0, decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
@@ -2214,7 +2358,7 @@ default-require-extensions@^1.0.0:
dependencies:
strip-bom "^2.0.0"
-define-properties@^1.1.2:
+define-properties@^1.1.1, define-properties@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
dependencies:
@@ -2298,6 +2442,12 @@ destroy@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
+detab@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.1.tgz#531f5e326620e2fd4f03264a905fb3bcc8af4df4"
+ dependencies:
+ repeat-string "^1.5.4"
+
detect-indent@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
@@ -2444,6 +2594,12 @@ domutils@^1.5.1:
dom-serializer "0"
domelementtype "1"
+dot-prop@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177"
+ dependencies:
+ is-obj "^1.0.0"
+
duplexer@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
@@ -2580,7 +2736,7 @@ errno@^0.1.3, errno@~0.1.7:
dependencies:
prr "~1.0.1"
-error-ex@^1.2.0:
+error-ex@^1.2.0, error-ex@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
dependencies:
@@ -2935,7 +3091,7 @@ extend-shallow@^3.0.2:
assign-symbols "^1.0.0"
is-extendable "^1.0.1"
-extend@~3.0.0, extend@~3.0.1:
+extend@^3.0.0, extend@~3.0.0, extend@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
@@ -3286,6 +3442,15 @@ get-own-enumerable-property-symbols@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz#5c4ad87f2834c4b9b4e84549dc1e0650fb38c24b"
+get-pkg-repo@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-0.1.0.tgz#7f04d968564bf9cd2e901810577f84c37f2b03bd"
+ dependencies:
+ hosted-git-info "^2.1.4"
+ meow "^3.3.0"
+ normalize-package-data "^2.3.0"
+ through2 "^2.0.0"
+
get-stdin@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
@@ -3304,6 +3469,23 @@ getpass@^0.1.1:
dependencies:
assert-plus "^1.0.0"
+git-raw-commits@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-0.1.2.tgz#2becbdcd3f96ef0b19f16863f7a2f6d9d8ab8369"
+ dependencies:
+ dargs "^4.0.1"
+ lodash.template "^3.6.1"
+ meow "^3.1.0"
+ split2 "^1.0.0"
+ through2 "^2.0.0"
+
+git-semver-tags@^1.1.0:
+ version "1.3.6"
+ resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-1.3.6.tgz#357ea01f7280794fe0927f2806bee6414d2caba5"
+ dependencies:
+ meow "^4.0.0"
+ semver "^5.5.0"
+
glob-base@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
@@ -3430,7 +3612,7 @@ handle-thing@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4"
-handlebars@^4.0.3:
+handlebars@^4.0.2, handlebars@^4.0.3:
version "4.0.11"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc"
dependencies:
@@ -3541,6 +3723,24 @@ hash.js@^1.0.0, hash.js@^1.0.3:
inherits "^2.0.3"
minimalistic-assert "^1.0.0"
+hast-to-hyperscript@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-3.1.0.tgz#58ef4af5344f4da22f0622e072a8d5fa062693d3"
+ dependencies:
+ comma-separated-tokens "^1.0.0"
+ is-nan "^1.2.1"
+ kebab-case "^1.0.0"
+ property-information "^3.0.0"
+ space-separated-tokens "^1.0.0"
+ trim "0.0.1"
+ unist-util-is "^2.0.0"
+
+hast-util-sanitize@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/hast-util-sanitize/-/hast-util-sanitize-1.1.2.tgz#d10bd6757a21e59c13abc8ae3530dd3b6d7d679e"
+ dependencies:
+ xtend "^4.0.1"
+
hawk@3.1.3, hawk@~3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
@@ -3906,6 +4106,21 @@ is-accessor-descriptor@^1.0.0:
dependencies:
kind-of "^6.0.0"
+is-alphabetical@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.2.tgz#1fa6e49213cb7885b75d15862fb3f3d96c884f41"
+
+is-alphanumeric@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz#4a9cef71daf4c001c1d81d63d140cf53fd6889f4"
+
+is-alphanumerical@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.2.tgz#1138e9ae5040158dc6ff76b820acd6b7a181fd40"
+ dependencies:
+ is-alphabetical "^1.0.0"
+ is-decimal "^1.0.0"
+
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
@@ -3920,7 +4135,7 @@ is-boolean-object@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"
-is-buffer@^1.1.5:
+is-buffer@^1.1.4, is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
@@ -3956,6 +4171,10 @@ is-date-object@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
+is-decimal@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.2.tgz#894662d6a8709d307f3a276ca4339c8fa5dff0ff"
+
is-descriptor@^0.1.0:
version "0.1.6"
resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca"
@@ -4042,6 +4261,16 @@ is-glob@^4.0.0:
dependencies:
is-extglob "^2.1.1"
+is-hexadecimal@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.2.tgz#b6e710d7d07bb66b98cb8cece5c9b4921deeb835"
+
+is-nan@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.2.1.tgz#9faf65b6fb6db24b7f5c0628475ea71f988401e2"
+ dependencies:
+ define-properties "^1.1.1"
+
is-number-object@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.3.tgz#f265ab89a9f445034ef6aff15a8f00b00f551799"
@@ -4062,7 +4291,7 @@ is-number@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff"
-is-obj@^1.0.1:
+is-obj@^1.0.0, is-obj@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
@@ -4088,7 +4317,7 @@ is-path-inside@^1.0.0:
dependencies:
path-is-inside "^1.0.1"
-is-plain-obj@^1.0.0:
+is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
@@ -4152,6 +4381,12 @@ is-symbol@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
+is-text-path@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e"
+ dependencies:
+ text-extensions "^1.0.0"
+
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
@@ -4160,10 +4395,18 @@ is-utf8@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
+is-whitespace-character@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.2.tgz#ede53b4c6f6fb3874533751ec9280d01928d03ed"
+
is-windows@^1.0.1, is-windows@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
+is-word-character@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.1.tgz#5a03fa1ea91ace8a6eb0c7cd770eb86d65c8befb"
+
is-wsl@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
@@ -4590,6 +4833,10 @@ jsesc@~0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
+json-parse-better-errors@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
+
json-schema-traverse@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
@@ -4630,6 +4877,10 @@ jsonify@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
+jsonparse@^1.2.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
+
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@@ -4645,6 +4896,10 @@ jsx-ast-utils@^2.0.0, jsx-ast-utils@^2.0.1:
dependencies:
array-includes "^3.0.3"
+kebab-case@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/kebab-case/-/kebab-case-1.0.0.tgz#3f9e4990adcad0c686c0e701f7645868f75f91eb"
+
keymaster@1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/keymaster/-/keymaster-1.6.2.tgz#e1ae54d0ea9488f9f60b66b668f02e9a1946c6eb"
@@ -4790,6 +5045,15 @@ load-json-file@^2.0.0:
pify "^2.0.0"
strip-bom "^3.0.0"
+load-json-file@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
+ dependencies:
+ graceful-fs "^4.1.2"
+ parse-json "^4.0.0"
+ pify "^3.0.0"
+ strip-bom "^3.0.0"
+
loader-runner@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2"
@@ -4822,6 +5086,34 @@ lodash-es@^4.2.0, lodash-es@^4.2.1:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7"
+lodash._basecopy@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36"
+
+lodash._basetostring@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5"
+
+lodash._basevalues@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7"
+
+lodash._getnative@^3.0.0:
+ version "3.9.1"
+ resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
+
+lodash._isiterateecall@^3.0.0:
+ version "3.0.9"
+ resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c"
+
+lodash._reinterpolate@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
+
+lodash._root@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692"
+
lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
@@ -4830,22 +5122,73 @@ lodash.clonedeep@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
+lodash.cond@^4.3.0:
+ version "4.5.2"
+ resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5"
+
+lodash.escape@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698"
+ dependencies:
+ lodash._root "^3.0.0"
+
lodash.flattendeep@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
+lodash.isarguments@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
+
+lodash.isarray@^3.0.0:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
+
lodash.isequal@4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
+lodash.keys@^3.0.0:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
+ dependencies:
+ lodash._getnative "^3.0.0"
+ lodash.isarguments "^3.0.0"
+ lodash.isarray "^3.0.0"
+
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
+lodash.restparam@^3.0.0:
+ version "3.6.1"
+ resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
+
lodash.sortby@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
+lodash.template@^3.6.1:
+ version "3.6.2"
+ resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f"
+ dependencies:
+ lodash._basecopy "^3.0.0"
+ lodash._basetostring "^3.0.0"
+ lodash._basevalues "^3.0.0"
+ lodash._isiterateecall "^3.0.0"
+ lodash._reinterpolate "^3.0.0"
+ lodash.escape "^3.0.0"
+ lodash.keys "^3.0.0"
+ lodash.restparam "^3.0.0"
+ lodash.templatesettings "^3.0.0"
+
+lodash.templatesettings@^3.0.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5"
+ dependencies:
+ lodash._reinterpolate "^3.0.0"
+ lodash.escape "^3.0.0"
+
lodash.topath@4.5.2:
version "4.5.2"
resolved "https://registry.yarnpkg.com/lodash.topath/-/lodash.topath-4.5.2.tgz#3616351f3bba61994a0931989660bd03254fd009"
@@ -4862,6 +5205,14 @@ lodash@4.17.4, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, l
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
+lodash@^3.3.1:
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
+
+lodash@^4.0.0, lodash@^4.1.0:
+ version "4.17.5"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
+
log-symbols@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
@@ -4889,6 +5240,10 @@ loglevelnext@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/loglevelnext/-/loglevelnext-1.0.3.tgz#0f69277e73bbbf2cd61b94d82313216bf87ac66e"
+longest-streak@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.2.tgz#2421b6ba939a443bb9ffebf596585a50b4c38e2e"
+
longest@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
@@ -4941,12 +5296,24 @@ map-obj@^1.0.0, map-obj@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
+map-obj@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9"
+
map-visit@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f"
dependencies:
object-visit "^1.0.0"
+markdown-escapes@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.2.tgz#e639cbde7b99c841c0bacc8a07982873b46d2122"
+
+markdown-table@^1.1.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.2.tgz#c78db948fa879903a41bce522e3b96f801c63786"
+
math-expression-evaluator@^1.2.14:
version "1.2.17"
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac"
@@ -4958,6 +5325,39 @@ md5.js@^1.3.4:
hash-base "^3.0.0"
inherits "^2.0.1"
+mdast-util-compact@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/mdast-util-compact/-/mdast-util-compact-1.0.1.tgz#cdb5f84e2b6a2d3114df33bd05d9cb32e3c4083a"
+ dependencies:
+ unist-util-modify-children "^1.0.0"
+ unist-util-visit "^1.1.0"
+
+mdast-util-definitions@^1.2.0:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-1.2.2.tgz#673f4377c3e23d3de7af7a4fe2214c0e221c5ac7"
+ dependencies:
+ unist-util-visit "^1.0.0"
+
+mdast-util-to-hast@^2.0.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-2.5.0.tgz#f087844d255c7540f36906da30ba106c0ee5ee2f"
+ dependencies:
+ collapse-white-space "^1.0.0"
+ detab "^2.0.0"
+ mdast-util-definitions "^1.2.0"
+ mdurl "^1.0.1"
+ trim "0.0.1"
+ trim-lines "^1.0.0"
+ unist-builder "^1.0.1"
+ unist-util-generated "^1.1.0"
+ unist-util-position "^3.0.0"
+ unist-util-visit "^1.1.0"
+ xtend "^4.0.1"
+
+mdurl@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
+
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@@ -4975,7 +5375,7 @@ memory-fs@^0.4.0, memory-fs@~0.4.1:
errno "^0.1.3"
readable-stream "^2.0.1"
-meow@^3.3.0:
+meow@^3.1.0, meow@^3.3.0, meow@^3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb"
dependencies:
@@ -4990,6 +5390,20 @@ meow@^3.3.0:
redent "^1.0.0"
trim-newlines "^1.0.0"
+meow@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/meow/-/meow-4.0.0.tgz#fd5855dd008db5b92c552082db1c307cba20b29d"
+ dependencies:
+ camelcase-keys "^4.0.0"
+ decamelize-keys "^1.0.0"
+ loud-rejection "^1.0.0"
+ minimist "^1.1.3"
+ minimist-options "^3.0.1"
+ normalize-package-data "^2.3.4"
+ read-pkg-up "^3.0.0"
+ redent "^2.0.0"
+ trim-newlines "^2.0.0"
+
merge-descriptors@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
@@ -5100,6 +5514,13 @@ minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
dependencies:
brace-expansion "^1.1.7"
+minimist-options@^3.0.1:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954"
+ dependencies:
+ arrify "^1.0.1"
+ is-plain-obj "^1.1.0"
+
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
@@ -5140,6 +5561,10 @@ mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
dependencies:
minimist "0.0.8"
+modify-values@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
+
move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
@@ -5304,7 +5729,7 @@ nopt@^4.0.1:
abbrev "1"
osenv "^0.1.4"
-normalize-package-data@^2.3.2, normalize-package-data@^2.3.4:
+normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4:
version "2.4.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f"
dependencies:
@@ -5618,6 +6043,17 @@ parse-asn1@^5.0.0:
evp_bytestokey "^1.0.0"
pbkdf2 "^3.0.3"
+parse-entities@^1.0.2, parse-entities@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.1.1.tgz#8112d88471319f27abae4d64964b122fe4e1b890"
+ dependencies:
+ character-entities "^1.0.0"
+ character-entities-legacy "^1.0.0"
+ character-reference-invalid "^1.0.0"
+ is-alphanumerical "^1.0.0"
+ is-decimal "^1.0.0"
+ is-hexadecimal "^1.0.0"
+
parse-glob@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
@@ -5633,6 +6069,13 @@ parse-json@^2.2.0:
dependencies:
error-ex "^1.2.0"
+parse-json@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
+ dependencies:
+ error-ex "^1.3.1"
+ json-parse-better-errors "^1.0.1"
+
parse-passwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
@@ -6150,6 +6593,10 @@ prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.8,
loose-envify "^1.3.1"
object-assign "^4.1.1"
+property-information@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/property-information/-/property-information-3.2.0.tgz#fd1483c8fbac61808f5fe359e7693a1f48a58331"
+
proxy-addr@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341"
@@ -6202,7 +6649,7 @@ punycode@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d"
-q@^1.1.2:
+q@^1.1.2, q@^1.4.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
@@ -6237,6 +6684,10 @@ querystringify@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb"
+quick-lru@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8"
+
raf@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.0.tgz#a28876881b4bc2ca9117d4138163ddb80f781575"
@@ -6280,6 +6731,10 @@ raw-body@2.3.2:
iconv-lite "0.4.19"
unpipe "1.0.0"
+raw-loader@0.5.1:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa"
+
rc@^1.1.7:
version "1.2.2"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077"
@@ -6493,7 +6948,14 @@ read-pkg-up@^2.0.0:
find-up "^2.0.0"
read-pkg "^2.0.0"
-read-pkg@^1.0.0:
+read-pkg-up@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07"
+ dependencies:
+ find-up "^2.0.0"
+ read-pkg "^3.0.0"
+
+read-pkg@^1.0.0, read-pkg@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
dependencies:
@@ -6509,6 +6971,14 @@ read-pkg@^2.0.0:
normalize-package-data "^2.3.2"
path-type "^2.0.0"
+read-pkg@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
+ dependencies:
+ load-json-file "^4.0.0"
+ normalize-package-data "^2.3.2"
+ path-type "^3.0.0"
+
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.9:
version "2.3.5"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.5.tgz#b4f85003a938cbb6ecbce2a124fb1012bd1a838d"
@@ -6558,6 +7028,13 @@ redent@^1.0.0:
indent-string "^2.1.0"
strip-indent "^1.0.1"
+redent@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa"
+ dependencies:
+ indent-string "^3.0.0"
+ strip-indent "^2.0.0"
+
reduce-css-calc@^1.2.6:
version "1.3.0"
resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716"
@@ -6664,6 +7141,63 @@ relateurl@0.2.x:
version "0.2.7"
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
+remark-parse@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-5.0.0.tgz#4c077f9e499044d1d5c13f80d7a98cf7b9285d95"
+ dependencies:
+ collapse-white-space "^1.0.2"
+ is-alphabetical "^1.0.0"
+ is-decimal "^1.0.0"
+ is-whitespace-character "^1.0.0"
+ is-word-character "^1.0.0"
+ markdown-escapes "^1.0.0"
+ parse-entities "^1.1.0"
+ repeat-string "^1.5.4"
+ state-toggle "^1.0.0"
+ trim "0.0.1"
+ trim-trailing-lines "^1.0.0"
+ unherit "^1.0.4"
+ unist-util-remove-position "^1.0.0"
+ vfile-location "^2.0.0"
+ xtend "^4.0.1"
+
+remark-react@4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/remark-react/-/remark-react-4.0.1.tgz#82926c3b445c2e3d1034b354edc292f37369f823"
+ dependencies:
+ hast-to-hyperscript "^3.0.0"
+ hast-util-sanitize "^1.0.0"
+ mdast-util-to-hast "^2.0.0"
+ standard-changelog "^0.0.1"
+ xtend "^4.0.1"
+
+remark-stringify@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-5.0.0.tgz#336d3a4d4a6a3390d933eeba62e8de4bd280afba"
+ dependencies:
+ ccount "^1.0.0"
+ is-alphanumeric "^1.0.0"
+ is-decimal "^1.0.0"
+ is-whitespace-character "^1.0.0"
+ longest-streak "^2.0.1"
+ markdown-escapes "^1.0.0"
+ markdown-table "^1.1.0"
+ mdast-util-compact "^1.0.0"
+ parse-entities "^1.0.2"
+ repeat-string "^1.5.4"
+ state-toggle "^1.0.0"
+ stringify-entities "^1.0.1"
+ unherit "^1.0.4"
+ xtend "^4.0.1"
+
+remark@9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/remark/-/remark-9.0.0.tgz#c5cfa8ec535c73a67c4b0f12bfdbd3a67d8b2f60"
+ dependencies:
+ remark-parse "^5.0.0"
+ remark-stringify "^5.0.0"
+ unified "^6.0.0"
+
remove-trailing-separator@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
@@ -6682,7 +7216,7 @@ repeat-element@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
-repeat-string@^1.5.2, repeat-string@^1.6.1:
+repeat-string@^1.5.2, repeat-string@^1.5.4, repeat-string@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
@@ -6692,6 +7226,10 @@ repeating@^2.0.0:
dependencies:
is-finite "^1.0.0"
+replace-ext@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb"
+
request-promise-core@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6"
@@ -6939,7 +7477,7 @@ selfsigned@^1.9.1:
dependencies:
node-forge "0.6.33"
-"semver@2 || 3 || 4 || 5", semver@5.5.0, semver@^5.0.1, semver@^5.3.0:
+"semver@2 || 3 || 4 || 5", semver@5.5.0, semver@^5.0.1, semver@^5.3.0, semver@^5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
@@ -7197,6 +7735,12 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+space-separated-tokens@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.2.tgz#e95ab9d19ae841e200808cd96bc7bd0adbbb3412"
+ dependencies:
+ trim "0.0.1"
+
spdx-correct@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
@@ -7240,6 +7784,18 @@ split-string@^3.0.1, split-string@^3.0.2:
dependencies:
extend-shallow "^2.0.1"
+split2@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/split2/-/split2-1.1.1.tgz#162d9b18865f02ab2f2ad9585522db9b54c481f9"
+ dependencies:
+ through2 "~2.0.0"
+
+split@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
+ dependencies:
+ through "2"
+
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
@@ -7272,6 +7828,21 @@ staged-git-files@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-0.0.4.tgz#d797e1b551ca7a639dec0237dc6eb4bb9be17d35"
+standard-changelog@^0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/standard-changelog/-/standard-changelog-0.0.1.tgz#b367266fce05ca39ef2bbc09c0d24ddbd4191891"
+ dependencies:
+ add-stream "^1.0.0"
+ conventional-changelog-angular "^0.1.0"
+ conventional-changelog-core "^0.0.2"
+ lodash "^4.1.0"
+ meow "^3.7.0"
+ tempfile "^1.1.1"
+
+state-toggle@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.1.tgz#c3cb0974f40a6a0f8e905b96789eb41afa1cde3a"
+
static-extend@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
@@ -7355,6 +7926,15 @@ string_decoder@~1.0.3:
dependencies:
safe-buffer "~5.1.0"
+stringify-entities@^1.0.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-1.3.1.tgz#b150ec2d72ac4c1b5f324b51fb6b28c9cdff058c"
+ dependencies:
+ character-entities-html4 "^1.0.0"
+ character-entities-legacy "^1.0.0"
+ is-alphanumerical "^1.0.0"
+ is-hexadecimal "^1.0.0"
+
stringify-object@^3.2.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.1.tgz#2720c2eff940854c819f6ee252aaeb581f30624d"
@@ -7399,6 +7979,10 @@ strip-indent@^1.0.1:
dependencies:
get-stdin "^4.0.1"
+strip-indent@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68"
+
strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
@@ -7494,6 +8078,13 @@ tar@^2.2.1:
fstream "^1.0.2"
inherits "2"
+tempfile@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-1.1.1.tgz#5bcc4eaecc4ab2c707d8bc11d99ccc9a2cb287f2"
+ dependencies:
+ os-tmpdir "^1.0.0"
+ uuid "^2.0.1"
+
test-exclude@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26"
@@ -7504,6 +8095,10 @@ test-exclude@^4.1.1:
read-pkg-up "^1.0.1"
require-main-filename "^1.0.1"
+text-extensions@^1.0.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.7.0.tgz#faaaba2625ed746d568a23e4d0aacd9bf08a8b39"
+
text-table@0.2.0, text-table@~0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@@ -7512,14 +8107,14 @@ throat@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a"
-through2@^2.0.0:
+through2@^2.0.0, through2@~2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
dependencies:
readable-stream "^2.1.5"
xtend "~4.0.1"
-through@^2.3.6:
+through@2, "through@>=2.2.7 <3", through@^2.3.6:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
@@ -7592,14 +8187,38 @@ tr46@^1.0.0:
dependencies:
punycode "^2.1.0"
+trim-lines@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-1.1.1.tgz#da738ff58fa74817588455e30b11b85289f2a396"
+
trim-newlines@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
+trim-newlines@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20"
+
+trim-off-newlines@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3"
+
trim-right@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
+trim-trailing-lines@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.0.tgz#7aefbb7808df9d669f6da2e438cac8c46ada7684"
+
+trim@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd"
+
+trough@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.2.tgz#7f1663ec55c480139e2de5e486c6aef6cc24a535"
+
tryer@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.0.tgz#027b69fa823225e551cace3ef03b11f6ab37c1d7"
@@ -7727,6 +8346,25 @@ underscore@~1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604"
+unherit@^1.0.4:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.0.tgz#6b9aaedfbf73df1756ad9e316dd981885840cd7d"
+ dependencies:
+ inherits "^2.0.1"
+ xtend "^4.0.1"
+
+unified@^6.0.0:
+ version "6.1.6"
+ resolved "https://registry.yarnpkg.com/unified/-/unified-6.1.6.tgz#5ea7f807a0898f1f8acdeefe5f25faa010cc42b1"
+ dependencies:
+ bail "^1.0.0"
+ extend "^3.0.0"
+ is-plain-obj "^1.1.0"
+ trough "^1.0.0"
+ vfile "^2.0.0"
+ x-is-function "^1.0.4"
+ x-is-string "^0.1.0"
+
union-value@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4"
@@ -7762,6 +8400,46 @@ unique-slug@^2.0.0:
dependencies:
imurmurhash "^0.1.4"
+unist-builder@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-1.0.2.tgz#8c3b9903ef64bcfb117dd7cf6a5d98fc1b3b27b6"
+ dependencies:
+ object-assign "^4.1.0"
+
+unist-util-generated@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.1.tgz#99f16c78959ac854dee7c615c291924c8bf4de7f"
+
+unist-util-is@^2.0.0, unist-util-is@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.1.tgz#0c312629e3f960c66e931e812d3d80e77010947b"
+
+unist-util-modify-children@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/unist-util-modify-children/-/unist-util-modify-children-1.1.1.tgz#66d7e6a449e6f67220b976ab3cb8b5ebac39e51d"
+ dependencies:
+ array-iterate "^1.0.0"
+
+unist-util-position@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.0.0.tgz#e6e1e03eeeb81c5e1afe553e8d4adfbd7c0d8f82"
+
+unist-util-remove-position@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.1.tgz#5a85c1555fc1ba0c101b86707d15e50fa4c871bb"
+ dependencies:
+ unist-util-visit "^1.1.0"
+
+unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.1.tgz#3ccbdc53679eed6ecf3777dd7f5e3229c1b6aa3c"
+
+unist-util-visit@^1.0.0, unist-util-visit@^1.1.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.3.0.tgz#41ca7c82981fd1ce6c762aac397fc24e35711444"
+ dependencies:
+ unist-util-is "^2.1.1"
+
universalify@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7"
@@ -7851,6 +8529,10 @@ utils-merge@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
+uuid@^2.0.1:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a"
+
uuid@^3.0.0, uuid@^3.0.1, uuid@^3.1.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
@@ -7878,6 +8560,25 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
+vfile-location@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.2.tgz#d3675c59c877498e492b4756ff65e4af1a752255"
+
+vfile-message@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-1.0.0.tgz#a6adb0474ea400fa25d929f1d673abea6a17e359"
+ dependencies:
+ unist-util-stringify-position "^1.1.1"
+
+vfile@^2.0.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.3.0.tgz#e62d8e72b20e83c324bc6c67278ee272488bf84a"
+ dependencies:
+ is-buffer "^1.1.4"
+ replace-ext "1.0.0"
+ unist-util-stringify-position "^1.0.0"
+ vfile-message "^1.0.0"
+
vm-browserify@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"
@@ -8126,6 +8827,14 @@ ws@^4.0.0:
async-limiter "~1.0.0"
safe-buffer "~5.1.0"
+x-is-function@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/x-is-function/-/x-is-function-1.0.4.tgz#5d294dc3d268cbdd062580e0c5df77a391d1fa1e"
+
+x-is-string@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82"
+
xml-char-classes@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/xml-char-classes/-/xml-char-classes-1.0.0.tgz#64657848a20ffc5df583a42ad8a277b4512bbc4d"
@@ -8134,7 +8843,7 @@ xml-name-validator@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635"
-xtend@^4.0.0, xtend@~4.0.1:
+xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
index c8f3db1dc4b..331c0b74f45 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -1102,7 +1102,7 @@ quality_profile.empty_comparison=The quality profiles are equal.
quality_profiles.activate_more=Activate More
quality_profiles.activate_more_rules=Activate More Rules
quality_profiles.intro1=Quality Profiles are collections of rules to apply during an analysis.
-quality_profiles.intro2=For each language there is a default profile. All projects not explicitly assigned to some other profile will be analyzed with the default.
+quality_profiles.intro2=For each language there is a default profile. All projects not explicitly assigned to some other profile will be analyzed with the default. Ideally, all projects will use the same profile for a language.
quality_profiles.list.projects=Projects
quality_profiles.list.rules=Rules
quality_profiles.list.updated=Updated
@@ -1227,7 +1227,6 @@ coding_rules.change_details=Change Details of Quality Profile
coding_rules.create=Create
coding_rules.create_custom_rule=Create Custom Rule
coding_rules.custom_rule=Custom Rule
-coding_rules.custom_rule.title=This rule has been created through customization of a rule template
coding_rules.custom_rule.activation_notice=Note: parameters of a custom rule are not customizable on rule activation, only during creation/edit.
coding_rules.custom_rules=Custom Rules
coding_rules.deactivate_in_quality_profile=Deactivate In Quality Profile