Browse Source

SONAR-10675 Decrease JavaScript boot-up time (#283)

tags/7.5
Stas Vilchik 6 years ago
parent
commit
95220229b1
29 changed files with 504 additions and 349 deletions
  1. 22
    29
      server/sonar-bitbucketcloud/.babelrc
  2. 1
    0
      server/sonar-bitbucketcloud/package.json
  3. 34
    1
      server/sonar-bitbucketcloud/yarn.lock
  4. 22
    29
      server/sonar-vsts/.babelrc
  5. 1
    0
      server/sonar-vsts/package.json
  6. 37
    0
      server/sonar-vsts/yarn.lock
  7. 22
    29
      server/sonar-web/.babelrc
  8. 18
    2
      server/sonar-web/config/webpack.config.js
  9. 2
    0
      server/sonar-web/package.json
  10. 19
    8
      server/sonar-web/src/main/js/app/components/AdminContainer.tsx
  11. 1
    1
      server/sonar-web/src/main/js/app/components/GlobalFooterSonarCloud.tsx
  12. 1
    3
      server/sonar-web/src/main/js/app/components/__tests__/GlobalFooterSonarCloud-test.tsx
  13. 3
    1
      server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx
  14. 54
    31
      server/sonar-web/src/main/js/app/utils/startReactApp.js
  15. 31
    26
      server/sonar-web/src/main/js/apps/organizations/routes.ts
  16. 0
    30
      server/sonar-web/src/main/js/apps/project-admin/routes.js
  17. 2
    1
      server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.tsx
  18. 134
    115
      server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/OrganizationStep-test.js.snap
  19. 1
    1
      server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx
  20. 8
    2
      server/sonar-web/src/main/js/components/controls/DateInput.tsx
  21. 9
    9
      server/sonar-web/src/main/js/components/controls/Select.tsx
  22. 10
    6
      server/sonar-web/src/main/js/components/controls/__tests__/DateInput-test.tsx
  23. 3
    1
      server/sonar-web/src/main/js/components/docs/DocInclude.tsx
  24. 11
    9
      server/sonar-web/src/main/js/components/docs/DocTooltip.tsx
  25. 8
    4
      server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap
  26. 3
    1
      server/sonar-web/src/main/js/components/ui/CoverageRating.tsx
  27. 6
    8
      server/sonar-web/src/main/js/helpers/dates.ts
  28. 40
    1
      server/sonar-web/yarn.lock
  29. 1
    1
      tests/src/test/java/org/sonarqube/tests/project/ProjectKeyUpdatePageTest.java

+ 22
- 29
server/sonar-bitbucketcloud/.babelrc View File

@@ -1,40 +1,35 @@
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": [
"last 3 Chrome versions",
"last 3 Firefox versions",
"last 3 Safari versions",
"last 3 Edge versions",
"IE 11"
]
},
"useBuiltIns": true
}],
[
"env",
{
"modules": false,
"targets": {
"browsers": [
"last 3 Chrome versions",
"last 3 Firefox versions",
"last 3 Safari versions",
"last 3 Edge versions",
"IE 11"
]
},
"useBuiltIns": true
}
],
"react"
],
"plugins": [
"transform-class-properties",
["transform-object-rest-spread", {
// use built-in `Object.assign`
"useBuiltIns": true
}]
// use built-in `Object.assign`
["transform-object-rest-spread", { "useBuiltIns": true }],
"lodash"
],
"env": {
"production": {
"plugins": [
"syntax-dynamic-import",
"transform-react-constant-elements"
]
"plugins": ["syntax-dynamic-import", "transform-react-constant-elements"]
},
"development": {
"plugins": [
"syntax-dynamic-import",
"transform-react-jsx-source",
"transform-react-jsx-self"
]
"plugins": ["syntax-dynamic-import", "transform-react-jsx-source", "transform-react-jsx-self"]
},
"test": {
"plugins": [
@@ -45,7 +40,5 @@
]
}
},
"ignore": [
"**/libs/**"
]
"ignore": ["**/libs/**"]
}

+ 1
- 0
server/sonar-bitbucketcloud/package.json View File

@@ -36,6 +36,7 @@
"babel-jest": "22.4.3",
"babel-loader": "7.1.4",
"babel-plugin-dynamic-import-node": "1.2.0",
"babel-plugin-lodash": "3.3.2",
"babel-plugin-syntax-dynamic-import": "6.18.0",
"babel-plugin-transform-class-properties": "6.24.1",
"babel-plugin-transform-object-rest-spread": "6.26.0",

+ 34
- 1
server/sonar-bitbucketcloud/yarn.lock View File

@@ -751,6 +751,13 @@ babel-helper-hoist-variables@^6.24.1:
babel-runtime "^6.22.0"
babel-types "^6.24.1"

babel-helper-module-imports@^7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-helper-module-imports/-/babel-helper-module-imports-7.0.0-beta.3.tgz#e15764e3af9c8e11810c09f78f498a2bdc71585a"
dependencies:
babel-types "7.0.0-beta.3"
lodash "^4.2.0"

babel-helper-optimise-call-expression@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257"
@@ -848,6 +855,16 @@ babel-plugin-jest-hoist@^22.4.3:
version "22.4.3"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.3.tgz#7d8bcccadc2667f96a0dcc6afe1891875ee6c14a"

babel-plugin-lodash@3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/babel-plugin-lodash/-/babel-plugin-lodash-3.3.2.tgz#da3a5b49ba27447f54463f6c4fa81396ccdd463f"
dependencies:
babel-helper-module-imports "^7.0.0-beta.3"
babel-types "^6.26.0"
glob "^7.1.1"
lodash "^4.17.4"
require-package-name "^2.0.1"

babel-plugin-syntax-async-functions@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
@@ -1263,6 +1280,14 @@ babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0:
invariant "^2.2.2"
lodash "^4.17.4"

babel-types@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-beta.3.tgz#cd927ca70e0ae8ab05f4aab83778cfb3e6eb20b4"
dependencies:
esutils "^2.0.2"
lodash "^4.2.0"
to-fast-properties "^2.0.0"

babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
@@ -4786,7 +4811,7 @@ lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"

lodash@4.17.10, lodash@^4.17.10, lodash@^4.17.5:
lodash@4.17.10, lodash@^4.17.10, lodash@^4.17.5, lodash@^4.2.0:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"

@@ -6610,6 +6635,10 @@ require-main-filename@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"

require-package-name@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9"

require-uncached@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
@@ -7390,6 +7419,10 @@ to-fast-properties@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"

to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"

to-object-path@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"

+ 22
- 29
server/sonar-vsts/.babelrc View File

@@ -1,40 +1,35 @@
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": [
"last 3 Chrome versions",
"last 3 Firefox versions",
"last 3 Safari versions",
"last 3 Edge versions",
"IE 11"
]
},
"useBuiltIns": true
}],
[
"env",
{
"modules": false,
"targets": {
"browsers": [
"last 3 Chrome versions",
"last 3 Firefox versions",
"last 3 Safari versions",
"last 3 Edge versions",
"IE 11"
]
},
"useBuiltIns": true
}
],
"react"
],
"plugins": [
"transform-class-properties",
["transform-object-rest-spread", {
// use built-in `Object.assign`
"useBuiltIns": true
}]
// use built-in `Object.assign`
["transform-object-rest-spread", { "useBuiltIns": true }],
"lodash"
],
"env": {
"production": {
"plugins": [
"syntax-dynamic-import",
"transform-react-constant-elements"
]
"plugins": ["syntax-dynamic-import", "transform-react-constant-elements"]
},
"development": {
"plugins": [
"syntax-dynamic-import",
"transform-react-jsx-source",
"transform-react-jsx-self"
]
"plugins": ["syntax-dynamic-import", "transform-react-jsx-source", "transform-react-jsx-self"]
},
"test": {
"plugins": [
@@ -45,7 +40,5 @@
]
}
},
"ignore": [
"**/libs/**"
]
"ignore": ["**/libs/**"]
}

+ 1
- 0
server/sonar-vsts/package.json View File

@@ -25,6 +25,7 @@
"babel-jest": "22.0.6",
"babel-loader": "7.1.4",
"babel-plugin-dynamic-import-node": "1.1.0",
"babel-plugin-lodash": "3.3.2",
"babel-plugin-syntax-dynamic-import": "6.18.0",
"babel-plugin-transform-class-properties": "6.22.0",
"babel-plugin-transform-object-rest-spread": "6.26.0",

+ 37
- 0
server/sonar-vsts/yarn.lock View File

@@ -536,6 +536,13 @@ babel-helper-hoist-variables@^6.24.1:
babel-runtime "^6.22.0"
babel-types "^6.24.1"

babel-helper-module-imports@^7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-helper-module-imports/-/babel-helper-module-imports-7.0.0-beta.3.tgz#e15764e3af9c8e11810c09f78f498a2bdc71585a"
dependencies:
babel-types "7.0.0-beta.3"
lodash "^4.2.0"

babel-helper-optimise-call-expression@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257"
@@ -633,6 +640,16 @@ babel-plugin-jest-hoist@^22.4.1:
version "22.4.1"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.1.tgz#d712fe5da8b6965f3191dacddbefdbdf4fb66d63"

babel-plugin-lodash@3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/babel-plugin-lodash/-/babel-plugin-lodash-3.3.2.tgz#da3a5b49ba27447f54463f6c4fa81396ccdd463f"
dependencies:
babel-helper-module-imports "^7.0.0-beta.3"
babel-types "^6.26.0"
glob "^7.1.1"
lodash "^4.17.4"
require-package-name "^2.0.1"

babel-plugin-syntax-async-functions@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
@@ -1031,6 +1048,14 @@ babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0:
invariant "^2.2.2"
lodash "^4.17.4"

babel-types@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-beta.3.tgz#cd927ca70e0ae8ab05f4aab83778cfb3e6eb20b4"
dependencies:
esutils "^2.0.2"
lodash "^4.2.0"
to-fast-properties "^2.0.0"

babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
@@ -4471,6 +4496,10 @@ 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@^4.2.0:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"

log-symbols@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
@@ -6221,6 +6250,10 @@ require-main-filename@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"

require-package-name@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9"

require-uncached@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
@@ -6969,6 +7002,10 @@ to-fast-properties@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"

to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"

to-object-path@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"

+ 22
- 29
server/sonar-web/.babelrc View File

@@ -1,40 +1,35 @@
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": [
"last 3 Chrome versions",
"last 3 Firefox versions",
"last 3 Safari versions",
"last 3 Edge versions",
"IE 11"
]
},
"useBuiltIns": true
}],
[
"env",
{
"modules": false,
"targets": {
"browsers": [
"last 3 Chrome versions",
"last 3 Firefox versions",
"last 3 Safari versions",
"last 3 Edge versions",
"IE 11"
]
},
"useBuiltIns": true
}
],
"react"
],
"plugins": [
"transform-class-properties",
["transform-object-rest-spread", {
// use built-in `Object.assign`
"useBuiltIns": true
}]
// use built-in `Object.assign`
["transform-object-rest-spread", { "useBuiltIns": true }],
"lodash"
],
"env": {
"production": {
"plugins": [
"syntax-dynamic-import",
"transform-react-constant-elements"
]
"plugins": ["syntax-dynamic-import", "transform-react-constant-elements"]
},
"development": {
"plugins": [
"syntax-dynamic-import",
"transform-react-jsx-source",
"transform-react-jsx-self"
]
"plugins": ["syntax-dynamic-import", "transform-react-jsx-source", "transform-react-jsx-self"]
},
"test": {
"plugins": [
@@ -45,7 +40,5 @@
]
}
},
"ignore": [
"**/libs/**"
]
"ignore": ["**/libs/**"]
}

+ 18
- 2
server/sonar-web/config/webpack.config.js View File

@@ -23,6 +23,7 @@ const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const LodashPlugin = require('lodash-webpack-plugin');
const webpack = require('webpack');
const InterpolateHtmlPlugin = require('./InterpolateHtmlPlugin');
const paths = require('./paths');
@@ -77,7 +78,6 @@ module.exports = ({ production = true }) => ({
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' },
{
@@ -113,6 +113,15 @@ module.exports = ({ production = true }) => ({
chunkFilename: 'css/[name].[chunkhash:8].chunk.css'
}),

new LodashPlugin({
// keep these features
// https://github.com/lodash/lodash-webpack-plugin#feature-sets
shorthands: true,
collections: true,
memoizing: true,
flattening: true
}),

new HtmlWebpackPlugin({
inject: false,
template: paths.appHtml,
@@ -126,5 +135,12 @@ module.exports = ({ production = true }) => ({
].filter(Boolean),
optimization: {
splitChunks: { chunks: 'all' }
}
},
performance: production
? {
hints: 'error',
maxEntrypointSize: 700000, // ~700kb, recommended: 250kb
maxAssetSize: 400000 // ~400kb, recommended: 250kb
}
: undefined
});

+ 2
- 0
server/sonar-web/package.json View File

@@ -63,6 +63,7 @@
"babel-jest": "22.4.3",
"babel-loader": "7.1.4",
"babel-plugin-dynamic-import-node": "1.2.0",
"babel-plugin-lodash": "3.3.2",
"babel-plugin-syntax-dynamic-import": "6.18.0",
"babel-plugin-transform-class-properties": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "6.26.0",
@@ -93,6 +94,7 @@
"html-webpack-plugin": "3.2.0",
"jest": "22.4.3",
"lint-staged": "4.3.0",
"lodash-webpack-plugin": "0.11.5",
"mini-css-extract-plugin": "0.4.0",
"postcss-calc": "6.0.1",
"postcss-custom-properties": "6.2.0",

+ 19
- 8
server/sonar-web/src/main/js/app/components/AdminContainer.tsx View File

@@ -41,23 +41,29 @@ import { Extension } from '../types';
import { PluginPendingResult } from '../../api/plugins';
import handleRequiredAuthorization from '../utils/handleRequiredAuthorization';

interface Props {
interface StateProps {
appState: {
adminPages: Extension[];
organizationsEnabled: boolean;
version: string;
};
editionsUrl: string;
editionStatus?: EditionStatus;
editionsUrl: string;
pendingPlugins: PluginPendingResult;
}

interface DispatchProps {
fetchEditions: (url: string, version: string) => void;
fetchPendingPlugins: () => void;
location: {};
pendingPlugins: PluginPendingResult;
setAdminPages: (adminPages: Extension[]) => void;
setEditionStatus: (editionStatus: EditionStatus) => void;
}

class AdminContainer extends React.PureComponent<Props> {
interface OwnProps {
location: {};
}

class AdminContainer extends React.PureComponent<StateProps & DispatchProps & OwnProps> {
static contextTypes = {
canAdmin: PropTypes.bool.isRequired
};
@@ -105,13 +111,18 @@ class AdminContainer extends React.PureComponent<Props> {
}
}

const mapStateToProps = (state: any) => ({
const mapStateToProps = (state: any): StateProps => ({
appState: getAppState(state),
editionStatus: getMarketplaceEditionStatus(state),
editionsUrl: (getGlobalSettingValue(state, 'sonar.editions.jsonUrl') || {}).value,
pendingPlugins: getMarketplacePendingPlugins(state)
});

const mapDispatchToProps = { setAdminPages, setEditionStatus, fetchEditions, fetchPendingPlugins };
const mapDispatchToProps: DispatchProps = {
setAdminPages,
setEditionStatus,
fetchEditions,
fetchPendingPlugins
};

export default connect(mapStateToProps, mapDispatchToProps)(AdminContainer as any);
export default connect(mapStateToProps, mapDispatchToProps)(AdminContainer);

+ 1
- 1
server/sonar-web/src/main/js/app/components/GlobalFooterSonarCloud.tsx View File

@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import { getYear } from 'date-fns';
import * as getYear from 'date-fns/get_year';
import { translate } from '../../helpers/l10n';

export default function GlobalFooterSonarCloud() {

+ 1
- 3
server/sonar-web/src/main/js/app/components/__tests__/GlobalFooterSonarCloud-test.tsx View File

@@ -21,9 +21,7 @@ import * as React from 'react';
import { shallow } from 'enzyme';
import GlobalFooterSonarCloud from '../GlobalFooterSonarCloud';

jest.mock('date-fns', () => ({
getYear: jest.fn(() => 2018)
}));
jest.mock('date-fns/get_year', () => jest.fn(() => 2018));

it('should render correctly', () => {
expect(shallow(<GlobalFooterSonarCloud />)).toMatchSnapshot();

+ 3
- 1
server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx View File

@@ -23,7 +23,6 @@ import GlobalNavBranding from './GlobalNavBranding';
import GlobalNavMenu from './GlobalNavMenu';
import GlobalNavExplore from './GlobalNavExplore';
import GlobalNavUserContainer from './GlobalNavUserContainer';
import GlobalNavPlus from './GlobalNavPlus';
import Search from '../../search/Search';
import EmbedDocsPopupHelper from '../../embed-docs-modal/EmbedDocsPopupHelper';
import * as theme from '../../../theme';
@@ -31,12 +30,15 @@ import { isLoggedIn, CurrentUser, AppState } from '../../../types';
import OnboardingModal from '../../../../apps/tutorials/onboarding/OnboardingModal';
import NavBar from '../../../../components/nav/NavBar';
import Tooltip from '../../../../components/controls/Tooltip';
import { lazyLoad } from '../../../../components/lazyLoad';
import { translate } from '../../../../helpers/l10n';
import { getCurrentUser, getAppState, getGlobalSettingValue } from '../../../../store/rootReducer';
import { skipOnboarding } from '../../../../store/users/actions';
import { SuggestionLink } from '../../embed-docs-modal/SuggestionsProvider';
import './GlobalNav.css';

const GlobalNavPlus = lazyLoad(() => import('./GlobalNavPlus'));

interface StateProps {
appState: AppState;
currentUser: CurrentUser;

+ 54
- 31
server/sonar-web/src/main/js/app/utils/startReactApp.js View File

@@ -24,24 +24,10 @@ import { Router, Route, IndexRoute, Redirect } from 'react-router';
import { Provider } from 'react-redux';
import getStore from './getStore';
import getHistory from './getHistory';
import AppContextContainer from '../components/AppContextContainer';
import LocalizationContainer from '../components/LocalizationContainer';
import MigrationContainer from '../components/MigrationContainer';
import App from '../components/App';
import GlobalContainer from '../components/GlobalContainer';
import SimpleContainer from '../components/SimpleContainer';
import SimpleSessionsContainer from '../components/SimpleSessionsContainer';
import Landing from '../components/Landing';
import ProjectAdminContainer from '../components/ProjectAdminContainer';
import ProjectPageExtension from '../components/extensions/ProjectPageExtension';
import ProjectAdminPageExtension from '../components/extensions/ProjectAdminPageExtension';
import PortfoliosPage from '../components/extensions/PortfoliosPage';
import AdminContainer from '../components/AdminContainer';
import GlobalPageExtension from '../components/extensions/GlobalPageExtension';
import GlobalAdminPageExtension from '../components/extensions/GlobalAdminPageExtension';
import MarkdownHelp from '../components/MarkdownHelp';
import NotFound from '../components/NotFound';
import OnboardingPage from '../../apps/tutorials/onboarding/OnboardingPage';
import aboutRoutes from '../../apps/about/routes';
import accountRoutes from '../../apps/account/routes';
import backgroundTasksRoutes from '../../apps/background-tasks/routes';
@@ -63,7 +49,6 @@ import organizationsRoutes from '../../apps/organizations/routes';
import permissionTemplatesRoutes from '../../apps/permission-templates/routes';
import portfolioRoutes from '../../apps/portfolio/routes';
import projectActivityRoutes from '../../apps/projectActivity/routes';
import projectAdminRoutes from '../../apps/project-admin/routes';
import projectBranchesRoutes from '../../apps/projectBranches/routes';
import projectQualityGateRoutes from '../../apps/projectQualityGate/routes';
import projectQualityProfilesRoutes from '../../apps/projectQualityProfiles/routes';
@@ -150,23 +135,26 @@ const startReactApp = () => {
<Redirect from="/view" to="/portfolio" />
<Redirect from="/users" to="/admin/users" />

<Route path="markdown/help" component={MarkdownHelp} />
<Route
path="markdown/help"
component={lazyLoad(() => import('../components/MarkdownHelp'))}
/>

<Route component={LocalizationContainer}>
<Route component={SimpleContainer}>
<Route component={lazyLoad(() => import('../components/SimpleContainer'))}>
<Route path="maintenance">{maintenanceRoutes}</Route>
<Route path="setup">{setupRoutes}</Route>
</Route>

<Route component={MigrationContainer}>
<Route component={AppContextContainer}>
<Route component={SimpleSessionsContainer}>
<Route component={lazyLoad(() => import('../components/AppContextContainer'))}>
<Route component={lazyLoad(() => import('../components/SimpleSessionsContainer'))}>
<Route path="/sessions" childRoutes={sessionsRoutes} />
</Route>
</Route>

<Route path="/" component={App}>
<IndexRoute component={Landing} />
<IndexRoute component={lazyLoad(() => import('../components/Landing'))} />

<Route component={GlobalContainer}>
<Route path="about" childRoutes={aboutRoutes} />
@@ -178,13 +166,24 @@ const startReactApp = () => {
<Route path="issues" component={ExploreIssues} />
<Route path="projects" component={ExploreProjects} />
</Route>
<Route path="extension/:pluginKey/:extensionKey" component={GlobalPageExtension} />
<Route
path="extension/:pluginKey/:extensionKey"
component={lazyLoad(() => import('../components/extensions/GlobalPageExtension'))}
/>
<Route path="issues" component={IssuesPageSelector} />
<Route path="onboarding" component={OnboardingPage} />
<Route
path="onboarding"
component={lazyLoad(() =>
import('../../apps/tutorials/onboarding/OnboardingPage')
)}
/>
<Route path="organizations" childRoutes={organizationsRoutes} />
<Route path="projects" childRoutes={projectsRoutes} />
<Route path="quality_gates" childRoutes={qualityGatesRoutes} />
<Route path="portfolios" component={PortfoliosPage} />
<Route
path="portfolios"
component={lazyLoad(() => import('../components/extensions/PortfoliosPage'))}
/>
<Route path="profiles" childRoutes={qualityProfilesRoutes} />
<Route path="web_api" childRoutes={webAPIRoutes} />

@@ -196,7 +195,9 @@ const startReactApp = () => {
<Route path="project/activity" childRoutes={projectActivityRoutes} />
<Route
path="project/extension/:pluginKey/:extensionKey"
component={ProjectPageExtension}
component={lazyLoad(() =>
import('../components/extensions/ProjectPageExtension')
)}
/>
<Route path="project/issues" component={Issues} />
<Route path="project/quality_gate" childRoutes={projectQualityGateRoutes} />
@@ -204,25 +205,44 @@ const startReactApp = () => {
path="project/quality_profiles"
childRoutes={projectQualityProfilesRoutes}
/>
<Route component={ProjectAdminContainer}>
<Route component={lazyLoad(() => import('../components/ProjectAdminContainer'))}>
<Route path="custom_measures" childRoutes={customMeasuresRoutes} />
<Route
path="project/admin/extension/:pluginKey/:extensionKey"
component={ProjectAdminPageExtension}
component={lazyLoad(() =>
import('../components/extensions/ProjectAdminPageExtension')
)}
/>
<Route path="project/background_tasks" childRoutes={backgroundTasksRoutes} />
<Route path="project/branches" childRoutes={projectBranchesRoutes} />
<Route path="project/settings" childRoutes={settingsRoutes} />
<Route path="project_roles" childRoutes={projectPermissionsRoutes} />
<Route path="project/webhooks" childRoutes={webhooksRoutes} />
<Route
path="project/deletion"
component={lazyLoad(() =>
import('../../apps/project-admin/deletion/Deletion')
)}
/>
<Route
path="project/links"
component={lazyLoad(() => import('../../apps/project-admin/links/Links'))}
/>
<Route
path="project/key"
component={lazyLoad(() => import('../../apps/project-admin/key/Key'))}
/>
</Route>
{projectAdminRoutes}
</Route>

<Route component={AdminContainer} path="admin">
<Route
component={lazyLoad(() => import('../components/AdminContainer'))}
path="admin">
<Route
path="extension/:pluginKey/:extensionKey"
component={GlobalAdminPageExtension}
component={lazyLoad(() =>
import('../components/extensions/GlobalAdminPageExtension')
)}
/>
<Route path="background_tasks" childRoutes={backgroundTasksRoutes} />
<Route path="custom_metrics" childRoutes={customMetricsRoutes} />
@@ -238,8 +258,11 @@ const startReactApp = () => {
<Route path="webhooks" childRoutes={webhooksRoutes} />
</Route>
</Route>
<Route path="not_found" component={NotFound} />
<Route path="*" component={NotFound} />
<Route
path="not_found"
component={lazyLoad(() => import('../components/NotFound'))}
/>
<Route path="*" component={lazyLoad(() => import('../components/NotFound'))} />
</Route>
</Route>
</Route>

+ 31
- 26
server/sonar-web/src/main/js/apps/organizations/routes.ts View File

@@ -18,28 +18,18 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { RouterState, RedirectFunction } from 'react-router';
import OrganizationPageContainer from './components/OrganizationPage';
import OrganizationContainer from './components/OrganizationContainer';
import OrganizationProjects from './components/OrganizationProjects';
import OrganizationAdminContainer from './components/OrganizationAdminContainer';
import OrganizationEdit from './components/OrganizationEdit';
import OrganizationMembersContainer from './components/OrganizationMembersContainer';
import OrganizationDelete from './components/OrganizationDelete';
import GlobalPermissionsApp from '../permissions/global/components/App';
import PermissionTemplateApp from '../permission-templates/components/AppContainer';
import ProjectManagementApp from '../projectsManagement/AppContainer';
import codingRulesRoutes from '../coding-rules/routes';
import qualityGatesRoutes from '../quality-gates/routes';
import qualityProfilesRoutes from '../quality-profiles/routes';
import webhooksRoutes from '../webhooks/routes';
import Issues from '../issues/components/AppContainer';
import GroupsApp from '../groups/components/App';
import OrganizationPageExtension from '../../app/components/extensions/OrganizationPageExtension';
import { lazyLoad } from '../../components/lazyLoad';

const OrganizationContainer = lazyLoad(() => import('./components/OrganizationContainer'));

const routes = [
{
path: ':organizationKey',
component: OrganizationPageContainer,
component: lazyLoad(() => import('./components/OrganizationPage')),
childRoutes: [
{
indexRoute: {
@@ -52,19 +42,23 @@ const routes = [
{
path: 'projects',
component: OrganizationContainer,
childRoutes: [{ indexRoute: { component: OrganizationProjects } }]
childRoutes: [
{ indexRoute: { component: lazyLoad(() => import('./components/OrganizationProjects')) } }
]
},
{
path: 'issues',
component: OrganizationContainer,
childRoutes: [{ indexRoute: { component: Issues } }]
childRoutes: [
{ indexRoute: { component: lazyLoad(() => import('../issues/components/AppContainer')) } }
]
},
{
path: 'members',
component: OrganizationMembersContainer
component: lazyLoad(() => import('./components/OrganizationMembersContainer'))
},
{
path: 'rules',
path: 'rules',
component: OrganizationContainer,
childRoutes: codingRulesRoutes
},
@@ -78,18 +72,29 @@ const routes = [
childRoutes: qualityGatesRoutes
},
{
component: OrganizationAdminContainer,
component: lazyLoad(() => import('./components/OrganizationAdminContainer')),
childRoutes: [
{ path: 'delete', component: OrganizationDelete },
{ path: 'edit', component: OrganizationEdit },
{ path: 'groups', component: GroupsApp },
{ path: 'permissions', component: GlobalPermissionsApp },
{ path: 'permission_templates', component: PermissionTemplateApp },
{ path: 'projects_management', component: ProjectManagementApp },
{ path: 'delete', component: lazyLoad(() => import('./components/OrganizationDelete')) },
{ path: 'edit', component: lazyLoad(() => import('./components/OrganizationEdit')) },
{ path: 'groups', component: lazyLoad(() => import('../groups/components/App')) },
{
path: 'permissions',
component: lazyLoad(() => import('../permissions/global/components/App'))
},
{
path: 'permission_templates',
component: lazyLoad(() => import('../permission-templates/components/AppContainer'))
},
{
path: 'projects_management',
component: lazyLoad(() => import('../projectsManagement/AppContainer'))
},
{ path: 'webhooks', childRoutes: webhooksRoutes },
{
path: 'extension/:pluginKey/:extensionKey',
component: OrganizationPageExtension
component: lazyLoad(() =>
import('../../app/components/extensions/OrganizationPageExtension')
)
}
]
}

+ 0
- 30
server/sonar-web/src/main/js/apps/project-admin/routes.js View File

@@ -1,30 +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.
*/
import React from 'react';
import { Route } from 'react-router';
import Deletion from './deletion/Deletion';
import Links from './links/Links';
import Key from './key/Key';

export default [
<Route key="deletion" path="project/deletion" component={Deletion} />,
<Route key="links" path="project/links" component={Links} />,
<Route key="key" path="project/key" component={Key} />
];

+ 2
- 1
server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.tsx View File

@@ -20,7 +20,8 @@
import * as React from 'react';
import { Link } from 'react-router';
import { sortBy } from 'lodash';
import { isSameMinute, startOfMinute } from 'date-fns';
import * as isSameMinute from 'date-fns/is_same_minute';
import * as startOfMinute from 'date-fns/start_of_minute';
import ChangesList from './ChangesList';
import DateTimeFormatter from '../../../components/intl/DateTimeFormatter';
import { translate } from '../../../helpers/l10n';

+ 134
- 115
server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/OrganizationStep-test.js.snap View File

@@ -80,40 +80,11 @@ exports[`works with existing organization 1`] = `
]
}
>
<Select
arrowRenderer={[Function]}
autosize={true}
backspaceRemoves={true}
backspaceToRemoveMessage="Press backspace to remove {label}"
<LazyLoader
className="input-super-large"
clearAllText="Clear all"
clearRenderer={[Function]}
clearValueText="Clear value"
clearable={false}
closeOnSelect={true}
deleteRemoves={true}
delimiter=","
disabled={false}
escapeClearsValue={true}
filterOptions={[Function]}
ignoreAccents={true}
ignoreCase={true}
inputProps={Object {}}
isLoading={false}
joinValues={false}
labelKey="label"
matchPos="any"
matchProp="any"
menuBuffer={0}
menuRenderer={[Function]}
multi={false}
noResultsText="No results found"
onBlurResetsInput={true}
onChange={[Function]}
onCloseResetsInput={true}
onSelectResetsInput={true}
openOnClick={true}
optionComponent={[Function]}
options={
Array [
Object {
@@ -126,108 +97,156 @@ exports[`works with existing organization 1`] = `
},
]
}
pageSize={5}
placeholder="Select..."
removeSelected={true}
required={false}
rtl={false}
scrollMenuIntoView={true}
searchable={true}
simpleValue={false}
tabSelectsValue={true}
trimFilter={true}
valueComponent={[Function]}
valueKey="value"
>
<div
className="Select input-super-large is-searchable Select--single"
<Select
arrowRenderer={[Function]}
autosize={true}
backspaceRemoves={true}
backspaceToRemoveMessage="Press backspace to remove {label}"
className="input-super-large"
clearAllText="Clear all"
clearRenderer={[Function]}
clearValueText="Clear value"
clearable={false}
closeOnSelect={true}
deleteRemoves={true}
delimiter=","
disabled={false}
escapeClearsValue={true}
filterOptions={[Function]}
ignoreAccents={true}
ignoreCase={true}
inputProps={Object {}}
isLoading={false}
joinValues={false}
labelKey="label"
matchPos="any"
matchProp="any"
menuBuffer={0}
menuRenderer={[Function]}
multi={false}
noResultsText="No results found"
onBlurResetsInput={true}
onChange={[Function]}
onCloseResetsInput={true}
onSelectResetsInput={true}
openOnClick={true}
optionComponent={[Function]}
options={
Array [
Object {
"label": "another",
"value": "another",
},
Object {
"label": "user",
"value": "user",
},
]
}
pageSize={5}
placeholder="Select..."
removeSelected={true}
required={false}
rtl={false}
scrollMenuIntoView={true}
searchable={true}
simpleValue={false}
tabSelectsValue={true}
trimFilter={true}
valueComponent={[Function]}
valueKey="value"
>
<div
className="Select-control"
onKeyDown={[Function]}
onMouseDown={[Function]}
onTouchEnd={[Function]}
onTouchMove={[Function]}
onTouchStart={[Function]}
className="Select input-super-large is-searchable Select--single"
>
<span
className="Select-multi-value-wrapper"
id="react-select-2--value"
<div
className="Select-control"
onKeyDown={[Function]}
onMouseDown={[Function]}
onTouchEnd={[Function]}
onTouchMove={[Function]}
onTouchStart={[Function]}
>
<div
className="Select-placeholder"
>
Select...
</div>
<AutosizeInput
aria-activedescendant="react-select-2--value"
aria-expanded="false"
aria-haspopup="false"
aria-owns=""
className="Select-input"
injectStyles={true}
minWidth="5"
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
required={false}
role="combobox"
value=""
<span
className="Select-multi-value-wrapper"
id="react-select-2--value"
>
<div
className="Select-placeholder"
>
Select...
</div>
<AutosizeInput
aria-activedescendant="react-select-2--value"
aria-expanded="false"
aria-haspopup="false"
aria-owns=""
className="Select-input"
style={
Object {
"display": "inline-block",
}
}
injectStyles={true}
minWidth="5"
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
required={false}
role="combobox"
value=""
>
<input
aria-activedescendant="react-select-2--value"
aria-expanded="false"
aria-haspopup="false"
aria-owns=""
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
required={false}
role="combobox"
style={
Object {
"boxSizing": "content-box",
"width": "5px",
}
}
value=""
/>
<div
className="Select-input"
style={
Object {
"height": 0,
"left": 0,
"overflow": "scroll",
"position": "absolute",
"top": 0,
"visibility": "hidden",
"whiteSpace": "pre",
"display": "inline-block",
}
}
/>
</div>
</AutosizeInput>
</span>
<span
className="Select-arrow-zone"
onMouseDown={[Function]}
>
>
<input
aria-activedescendant="react-select-2--value"
aria-expanded="false"
aria-haspopup="false"
aria-owns=""
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
required={false}
role="combobox"
style={
Object {
"boxSizing": "content-box",
"width": "5px",
}
}
value=""
/>
<div
style={
Object {
"height": 0,
"left": 0,
"overflow": "scroll",
"position": "absolute",
"top": 0,
"visibility": "hidden",
"whiteSpace": "pre",
}
}
/>
</div>
</AutosizeInput>
</span>
<span
className="Select-arrow"
className="Select-arrow-zone"
onMouseDown={[Function]}
/>
</span>
>
<span
className="Select-arrow"
onMouseDown={[Function]}
/>
</span>
</div>
</div>
</div>
</Select>
</Select>
</LazyLoader>
</Select>
</div>
</div>

+ 1
- 1
server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx View File

@@ -149,7 +149,7 @@ export default class Line extends React.PureComponent<Props> {
<LineDuplications line={line} onClick={this.props.loadDuplications} />
)}

{times(duplicationsCount).map(index => (
{times(duplicationsCount, index => (
<LineDuplicationBlock
duplicated={duplications.includes(index)}
index={index}

+ 8
- 2
server/sonar-web/src/main/js/components/controls/DateInput.tsx View File

@@ -19,12 +19,16 @@
*/
import * as React from 'react';
import * as classNames from 'classnames';
import DayPicker, { DayModifiers, Modifier, Modifiers } from 'react-day-picker';
import { DayModifiers, Modifier, Modifiers } from 'react-day-picker';
import { intlShape, InjectedIntlProps } from 'react-intl';
import { range } from 'lodash';
import { addMonths, subMonths, setYear, setMonth } from 'date-fns';
import * as addMonths from 'date-fns/add_months';
import * as setMonth from 'date-fns/set_month';
import * as setYear from 'date-fns/set_year';
import * as subMonths from 'date-fns/sub_months';
import OutsideClickHandler from './OutsideClickHandler';
import Select from './Select';
import { lazyLoad } from '../lazyLoad';
import * as theme from '../../app/theme';
import CalendarIcon from '../icons-components/CalendarIcon';
import ChevronLeftIcon from '../icons-components/ChevronLeftIcon';
@@ -35,6 +39,8 @@ import { getShortMonthName, getWeekDayName, getShortWeekDayName } from '../../he
import './DayPicker.css';
import './styles.css';

const DayPicker = lazyLoad(() => import('react-day-picker'));

export interface Props {
className?: string;
currentMonth?: Date;

+ 9
- 9
server/sonar-web/src/main/js/components/controls/Select.tsx View File

@@ -18,18 +18,18 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import ReactSelect, {
Creatable as ReactCreatable,
Async,
ReactSelectProps,
ReactCreatableSelectProps,
ReactAsyncSelectProps
} from 'react-select';
import { ReactSelectProps, ReactCreatableSelectProps, ReactAsyncSelectProps } from 'react-select';
import * as theme from '../../app/theme';
import ClearIcon from '../icons-components/ClearIcon';
import { ButtonIcon } from '../ui/buttons';
import { lazyLoad } from '../lazyLoad';
import './react-select.css';

const ReactSelectLib = import('react-select');
const ReactSelect = lazyLoad(() => ReactSelectLib);
const ReactCreatable = lazyLoad(() => ReactSelectLib.then(lib => ({ default: lib.Creatable })));
const ReactAsync = lazyLoad(() => ReactSelectLib.then(lib => ({ default: lib.Async })));

function renderInput() {
return (
<ButtonIcon className="button-tiny spacer-left text-middle" color={theme.gray60}>
@@ -39,7 +39,7 @@ function renderInput() {
}

interface WithInnerRef {
innerRef?: (element: ReactSelect) => void;
innerRef?: (element: React.Component) => void;
}

export default function Select({ innerRef, ...props }: WithInnerRef & ReactSelectProps) {
@@ -61,5 +61,5 @@ export function Creatable(props: ReactCreatableSelectProps) {

// TODO figure out why `ref` prop is incompatible
export function AsyncSelect(props: ReactAsyncSelectProps & { ref?: any }) {
return <Async {...props} />;
return <ReactAsync {...props} />;
}

+ 10
- 6
server/sonar-web/src/main/js/components/controls/__tests__/DateInput-test.tsx View File

@@ -18,16 +18,20 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import { subMonths, setMonth, setYear, addDays, subDays } from 'date-fns';
import * as addDays from 'date-fns/add_days';
import * as setMonth from 'date-fns/set_month';
import * as setYear from 'date-fns/set_year';
import * as subDays from 'date-fns/sub_days';
import * as subMonths from 'date-fns/sub_months';
import DateInput, { Props } from '../DateInput';
import { shallowWithIntl } from '../../../helpers/testUtils';
import { parseDate } from '../../../helpers/dates';

// need to mock, because react-day-picker uses `new Date()` as a default prop for `initialMonth`
jest.mock('react-day-picker', () => ({
// eslint-disable-next-line func-name-matching
default: function DayPicker() {
return null;
jest.mock('../../lazyLoad', () => ({
lazyLoad: () => {
return function DayPicker() {
return null;
};
}
}));


+ 3
- 1
server/sonar-web/src/main/js/components/docs/DocInclude.tsx View File

@@ -18,7 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import DocMarkdownBlock from './DocMarkdownBlock';
import { lazyLoad } from '../lazyLoad';

const DocMarkdownBlock = lazyLoad(() => import('./DocMarkdownBlock'));

interface Props {
className?: string;

+ 11
- 9
server/sonar-web/src/main/js/components/docs/DocTooltip.tsx View File

@@ -18,8 +18,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import DocMarkdownBlock from './DocMarkdownBlock';
import HelpTooltip from '../controls/HelpTooltip';
import { lazyLoad } from '../lazyLoad';

const DocMarkdownBlock = lazyLoad(() => import('./DocMarkdownBlock'));

interface Props {
className?: string;
@@ -75,15 +77,15 @@ export default class DocTooltip extends React.PureComponent<Props, State> {
};

renderOverlay() {
if (this.state.loading) {
return (
<div className="abs-width-300">
return (
<div className="abs-width-300">
{this.state.loading ? (
<i className="spinner" />
</div>
);
}
return <DocMarkdownBlock className="cut-margins abs-width-300" content={this.state.content} />;
) : (
<DocMarkdownBlock className="cut-margins" content={this.state.content} />
)}
</div>
);
}

render() {

+ 8
- 4
server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap View File

@@ -19,10 +19,14 @@ exports[`should render 2`] = `
<HelpTooltip
onShow={[Function]}
overlay={
<DocMarkdownBlock
className="cut-margins abs-width-300"
content="this is *bold* text"
/>
<div
className="abs-width-300"
>
<LazyLoader
className="cut-margins"
content="this is *bold* text"
/>
</div>
}
/>
`;

+ 3
- 1
server/sonar-web/src/main/js/components/ui/CoverageRating.tsx View File

@@ -18,9 +18,11 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import DonutChart from '../charts/DonutChart';
import { lazyLoad } from '../lazyLoad';
import * as theme from '../../app/theme';

const DonutChart = lazyLoad(() => import('../charts/DonutChart'));

const SIZE_TO_WIDTH_MAPPING = { small: 16, normal: 24, big: 40, huge: 60 };

const SIZE_TO_THICKNESS_MAPPING = { small: 2, normal: 3, big: 3, huge: 4 };

+ 6
- 8
server/sonar-web/src/main/js/helpers/dates.ts View File

@@ -17,14 +17,12 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import {
differenceInDays as _differenceInDays,
differenceInSeconds as _differenceInSeconds,
differenceInYears as _differenceInYears,
isSameDay as _isSameDay,
parse,
startOfDay as _startOfDay
} from 'date-fns';
import * as _differenceInDays from 'date-fns/difference_in_days';
import * as _differenceInSeconds from 'date-fns/difference_in_seconds';
import * as _differenceInYears from 'date-fns/difference_in_years';
import * as _isSameDay from 'date-fns/is_same_day';
import * as _startOfDay from 'date-fns/start_of_day';
import * as parse from 'date-fns/parse';

function pad(number: number) {
if (number < 10) {

+ 40
- 1
server/sonar-web/yarn.lock View File

@@ -760,6 +760,13 @@ babel-helper-hoist-variables@^6.24.1:
babel-runtime "^6.22.0"
babel-types "^6.24.1"

babel-helper-module-imports@^7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-helper-module-imports/-/babel-helper-module-imports-7.0.0-beta.3.tgz#e15764e3af9c8e11810c09f78f498a2bdc71585a"
dependencies:
babel-types "7.0.0-beta.3"
lodash "^4.2.0"

babel-helper-optimise-call-expression@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257"
@@ -849,6 +856,16 @@ babel-plugin-jest-hoist@^22.4.3:
version "22.4.3"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.3.tgz#7d8bcccadc2667f96a0dcc6afe1891875ee6c14a"

babel-plugin-lodash@3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/babel-plugin-lodash/-/babel-plugin-lodash-3.3.2.tgz#da3a5b49ba27447f54463f6c4fa81396ccdd463f"
dependencies:
babel-helper-module-imports "^7.0.0-beta.3"
babel-types "^6.26.0"
glob "^7.1.1"
lodash "^4.17.4"
require-package-name "^2.0.1"

babel-plugin-syntax-async-functions@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
@@ -1252,6 +1269,14 @@ babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0:
invariant "^2.2.2"
lodash "^4.17.4"

babel-types@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-beta.3.tgz#cd927ca70e0ae8ab05f4aab83778cfb3e6eb20b4"
dependencies:
esutils "^2.0.2"
lodash "^4.2.0"
to-fast-properties "^2.0.0"

babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
@@ -5093,6 +5118,12 @@ lodash-es@^4.17.5, lodash-es@^4.2.1:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.10.tgz#62cd7104cdf5dd87f235a837f0ede0e8e5117e05"

lodash-webpack-plugin@0.11.5:
version "0.11.5"
resolved "https://registry.yarnpkg.com/lodash-webpack-plugin/-/lodash-webpack-plugin-0.11.5.tgz#c4bd064b4f561c3f823fa5982bdeb12c475390b9"
dependencies:
lodash "^4.17.4"

lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
@@ -5129,7 +5160,7 @@ lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"

lodash@4.17.10, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.3.0:
lodash@4.17.10, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"

@@ -7169,6 +7200,10 @@ require-main-filename@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"

require-package-name@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9"

require-uncached@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
@@ -7965,6 +8000,10 @@ to-fast-properties@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"

to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"

to-object-path@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"

+ 1
- 1
tests/src/test/java/org/sonarqube/tests/project/ProjectKeyUpdatePageTest.java View File

@@ -102,7 +102,7 @@ public class ProjectKeyUpdatePageTest {

$(".modal").shouldNotBe(visible);

tester.openBrowser().openProjectKey("another");
openPage("another");
assertThat(url()).endsWith("/project/key?id=another");
}


Loading…
Cancel
Save