diff options
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 |