aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main
diff options
context:
space:
mode:
authorPhilippe Perrin <philippe.perrin@sonarsource.com>2022-01-28 17:39:50 +0100
committersonartech <sonartech@sonarsource.com>2022-03-29 20:03:37 +0000
commitb345bbc09eb8e0bd04951e1db88f56666f5f4c6a (patch)
treed61378aa709f81a1c6a9729b6c792e404700dfcf /server/sonar-web/src/main
parentc1ea1e9df27db899c07948ce50e6aa9cceab348a (diff)
downloadsonarqube-b345bbc09eb8e0bd04951e1db88f56666f5f4c6a.tar.gz
sonarqube-b345bbc09eb8e0bd04951e1db88f56666f5f4c6a.zip
SONAR-15938 Improve code sharing with the license extension
Diffstat (limited to 'server/sonar-web/src/main')
-rw-r--r--server/sonar-web/src/main/js/api/alm-integrations.ts2
-rw-r--r--server/sonar-web/src/main/js/api/alm-settings.ts2
-rw-r--r--server/sonar-web/src/main/js/api/application.ts2
-rw-r--r--server/sonar-web/src/main/js/api/branches.ts2
-rw-r--r--server/sonar-web/src/main/js/api/ce.ts2
-rw-r--r--server/sonar-web/src/main/js/api/component-report.ts2
-rw-r--r--server/sonar-web/src/main/js/api/components.ts2
-rw-r--r--server/sonar-web/src/main/js/api/editions.ts (renamed from server/sonar-web/src/main/js/api/marketplace.ts)20
-rw-r--r--server/sonar-web/src/main/js/api/issues.ts2
-rw-r--r--server/sonar-web/src/main/js/api/l10n.ts2
-rw-r--r--server/sonar-web/src/main/js/api/languages.ts2
-rw-r--r--server/sonar-web/src/main/js/api/measures.ts2
-rw-r--r--server/sonar-web/src/main/js/api/metrics.ts2
-rw-r--r--server/sonar-web/src/main/js/api/nav.ts2
-rw-r--r--server/sonar-web/src/main/js/api/newCodePeriod.ts2
-rw-r--r--server/sonar-web/src/main/js/api/notifications.ts2
-rw-r--r--server/sonar-web/src/main/js/api/permissions.ts2
-rw-r--r--server/sonar-web/src/main/js/api/plugins.ts2
-rw-r--r--server/sonar-web/src/main/js/api/project-badges.ts2
-rw-r--r--server/sonar-web/src/main/js/api/project-dump.ts2
-rw-r--r--server/sonar-web/src/main/js/api/projectActivity.ts2
-rw-r--r--server/sonar-web/src/main/js/api/projectLinks.ts2
-rw-r--r--server/sonar-web/src/main/js/api/quality-gates.ts2
-rw-r--r--server/sonar-web/src/main/js/api/quality-profiles.ts2
-rw-r--r--server/sonar-web/src/main/js/api/rules.ts2
-rw-r--r--server/sonar-web/src/main/js/api/security-hotspots.ts2
-rw-r--r--server/sonar-web/src/main/js/api/settings.ts2
-rw-r--r--server/sonar-web/src/main/js/api/system.ts2
-rw-r--r--server/sonar-web/src/main/js/api/time-machine.ts2
-rw-r--r--server/sonar-web/src/main/js/api/user-tokens.ts2
-rw-r--r--server/sonar-web/src/main/js/api/user_groups.ts2
-rw-r--r--server/sonar-web/src/main/js/api/users.ts2
-rw-r--r--server/sonar-web/src/main/js/api/web-api.ts2
-rw-r--r--server/sonar-web/src/main/js/api/webhooks.ts2
-rw-r--r--server/sonar-web/src/main/js/app/components/StartupModal.tsx2
-rw-r--r--server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/app/components/extensions/Extension.tsx3
-rw-r--r--server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts2
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/ComponentNavLicenseNotif.tsx2
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavLicenseNotif-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/app/index.ts2
-rw-r--r--server/sonar-web/src/main/js/app/utils/exportModulesAsGlobals.ts45
-rw-r--r--server/sonar-web/src/main/js/app/utils/startReactApp.tsx18
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/sidebar/__tests__/__snapshots__/DomainFacet-test.tsx.snap4
-rw-r--r--server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/permissions/__tests__/utils-test.ts36
-rw-r--r--server/sonar-web/src/main/js/apps/projectDump/ProjectDumpApp.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap16
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/DefinitionRenderer-test.tsx.snap62
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap12
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/SubCategoryDefinitionsList-test.tsx.snap30
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/PasswordForm.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/UserForm.tsx2
-rw-r--r--server/sonar-web/src/main/js/components/issue/__tests__/actions-test.ts4
-rw-r--r--server/sonar-web/src/main/js/components/issue/actions.ts2
-rw-r--r--server/sonar-web/src/main/js/helpers/__tests__/error-test.ts (renamed from server/sonar-web/src/main/js/app/utils/__tests__/throwGlobalError-test.ts)20
-rw-r--r--server/sonar-web/src/main/js/helpers/__tests__/l10n-test.ts90
-rw-r--r--server/sonar-web/src/main/js/helpers/__tests__/l10nBundle-test.ts71
-rw-r--r--server/sonar-web/src/main/js/helpers/__tests__/measures-test.ts58
-rw-r--r--server/sonar-web/src/main/js/helpers/error.ts (renamed from server/sonar-web/src/main/js/app/utils/throwGlobalError.ts)8
-rw-r--r--server/sonar-web/src/main/js/helpers/l10n.ts129
-rw-r--r--server/sonar-web/src/main/js/helpers/l10nBundle.ts93
-rw-r--r--server/sonar-web/src/main/js/helpers/measures.ts3
-rw-r--r--server/sonar-web/src/main/js/helpers/mocks/editions.ts41
-rw-r--r--server/sonar-web/src/main/js/types/browser.ts2
-rw-r--r--server/sonar-web/src/main/js/types/editions.ts17
-rw-r--r--server/sonar-web/src/main/js/types/extension.ts2
-rw-r--r--server/sonar-web/src/main/js/types/l10nBundle.ts (renamed from server/sonar-web/src/main/js/types/l10n.ts)1
-rw-r--r--server/sonar-web/src/main/js/types/settings.ts3
71 files changed, 533 insertions, 351 deletions
diff --git a/server/sonar-web/src/main/js/api/alm-integrations.ts b/server/sonar-web/src/main/js/api/alm-integrations.ts
index 32186b51d98..1cd48a9e80a 100644
--- a/server/sonar-web/src/main/js/api/alm-integrations.ts
+++ b/server/sonar-web/src/main/js/api/alm-integrations.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { get, getJSON, parseError, post, postJSON } from '../helpers/request';
import {
AzureProject,
diff --git a/server/sonar-web/src/main/js/api/alm-settings.ts b/server/sonar-web/src/main/js/api/alm-settings.ts
index 218ca9de03b..d4d4e3f4c38 100644
--- a/server/sonar-web/src/main/js/api/alm-settings.ts
+++ b/server/sonar-web/src/main/js/api/alm-settings.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { get, getJSON, HttpStatus, parseError, parseJSON, post } from '../helpers/request';
import {
AlmSettingsBindingDefinitions,
diff --git a/server/sonar-web/src/main/js/api/application.ts b/server/sonar-web/src/main/js/api/application.ts
index 5e5ca222d55..99bd71ef4a9 100644
--- a/server/sonar-web/src/main/js/api/application.ts
+++ b/server/sonar-web/src/main/js/api/application.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON } from '../helpers/request';
import { Application, ApplicationPeriod } from '../types/application';
import { Visibility } from '../types/component';
diff --git a/server/sonar-web/src/main/js/api/branches.ts b/server/sonar-web/src/main/js/api/branches.ts
index 8be0209fcad..baf8f9d9d72 100644
--- a/server/sonar-web/src/main/js/api/branches.ts
+++ b/server/sonar-web/src/main/js/api/branches.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post } from '../helpers/request';
import { Branch, PullRequest } from '../types/branch-like';
diff --git a/server/sonar-web/src/main/js/api/ce.ts b/server/sonar-web/src/main/js/api/ce.ts
index eea8235f8f6..b91be651a4d 100644
--- a/server/sonar-web/src/main/js/api/ce.ts
+++ b/server/sonar-web/src/main/js/api/ce.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, RequestData } from '../helpers/request';
import { IndexationStatus } from '../types/indexation';
import { Task, TaskWarning } from '../types/tasks';
diff --git a/server/sonar-web/src/main/js/api/component-report.ts b/server/sonar-web/src/main/js/api/component-report.ts
index 9bc734f2308..a3133b80adb 100644
--- a/server/sonar-web/src/main/js/api/component-report.ts
+++ b/server/sonar-web/src/main/js/api/component-report.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post } from '../helpers/request';
import { getBaseUrl } from '../helpers/system';
import { ComponentReportStatus } from '../types/component-report';
diff --git a/server/sonar-web/src/main/js/api/components.ts b/server/sonar-web/src/main/js/api/components.ts
index 3ebc6070a00..eebd23b059f 100644
--- a/server/sonar-web/src/main/js/api/components.ts
+++ b/server/sonar-web/src/main/js/api/components.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON, RequestData } from '../helpers/request';
import { BranchParameters } from '../types/branch-like';
import { ComponentQualifier, TreeComponent, TreeComponentWithPath } from '../types/component';
diff --git a/server/sonar-web/src/main/js/api/marketplace.ts b/server/sonar-web/src/main/js/api/editions.ts
index 6c376b36eec..7a9d871af71 100644
--- a/server/sonar-web/src/main/js/api/marketplace.ts
+++ b/server/sonar-web/src/main/js/api/editions.ts
@@ -17,25 +17,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON } from '../helpers/request';
-
-export interface License {
- contactEmail: string;
- edition: string;
- expiresAt: string;
- isExpired: boolean;
- isOfficialDistribution: boolean;
- isSupported: boolean;
- isValidEdition: boolean;
- isValidServerId: boolean;
- loc: number;
- maxLoc: number;
- plugins: string[];
- remainingLocThreshold: number;
- serverId: string;
- type: string;
-}
+import { License } from '../types/editions';
export function isValidLicense(): Promise<{ isValidLicense: boolean }> {
return getJSON('/api/editions/is_valid_license');
diff --git a/server/sonar-web/src/main/js/api/issues.ts b/server/sonar-web/src/main/js/api/issues.ts
index 60fd262dbb5..b4e6509c10c 100644
--- a/server/sonar-web/src/main/js/api/issues.ts
+++ b/server/sonar-web/src/main/js/api/issues.ts
@@ -17,8 +17,8 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
import getCoverageStatus from '../components/SourceViewer/helpers/getCoverageStatus';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON, RequestData } from '../helpers/request';
import { IssueResponse, RawIssuesResponse } from '../types/issues';
import { Dict, FacetValue, IssueChangelog, SnippetsByComponent, SourceLine } from '../types/types';
diff --git a/server/sonar-web/src/main/js/api/l10n.ts b/server/sonar-web/src/main/js/api/l10n.ts
index 4144301f796..f6c39df6559 100644
--- a/server/sonar-web/src/main/js/api/l10n.ts
+++ b/server/sonar-web/src/main/js/api/l10n.ts
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { getJSON } from '../helpers/request';
-import { L10nBundleRequestParams, L10nBundleRequestResponse } from '../types/l10n';
+import { L10nBundleRequestParams, L10nBundleRequestResponse } from '../types/l10nBundle';
export function fetchL10nBundle(
params: L10nBundleRequestParams
diff --git a/server/sonar-web/src/main/js/api/languages.ts b/server/sonar-web/src/main/js/api/languages.ts
index 941c2c4c7ba..45d891d9486 100644
--- a/server/sonar-web/src/main/js/api/languages.ts
+++ b/server/sonar-web/src/main/js/api/languages.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON } from '../helpers/request';
import { Language } from '../types/languages';
diff --git a/server/sonar-web/src/main/js/api/measures.ts b/server/sonar-web/src/main/js/api/measures.ts
index 0387baf9f37..de681a61a49 100644
--- a/server/sonar-web/src/main/js/api/measures.ts
+++ b/server/sonar-web/src/main/js/api/measures.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON } from '../helpers/request';
import { BranchParameters } from '../types/branch-like';
import {
diff --git a/server/sonar-web/src/main/js/api/metrics.ts b/server/sonar-web/src/main/js/api/metrics.ts
index d2d5996b891..c3d684d774a 100644
--- a/server/sonar-web/src/main/js/api/metrics.ts
+++ b/server/sonar-web/src/main/js/api/metrics.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON } from '../helpers/request';
import { Metric } from '../types/types';
diff --git a/server/sonar-web/src/main/js/api/nav.ts b/server/sonar-web/src/main/js/api/nav.ts
index 974fb5fc1b3..bca04cabf98 100644
--- a/server/sonar-web/src/main/js/api/nav.ts
+++ b/server/sonar-web/src/main/js/api/nav.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON } from '../helpers/request';
import { BranchParameters } from '../types/branch-like';
import { Component, Extension } from '../types/types';
diff --git a/server/sonar-web/src/main/js/api/newCodePeriod.ts b/server/sonar-web/src/main/js/api/newCodePeriod.ts
index e33b3d297a4..6e570e338aa 100644
--- a/server/sonar-web/src/main/js/api/newCodePeriod.ts
+++ b/server/sonar-web/src/main/js/api/newCodePeriod.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post } from '../helpers/request';
import { NewCodePeriod, NewCodePeriodBranch, NewCodePeriodSettingType } from '../types/types';
diff --git a/server/sonar-web/src/main/js/api/notifications.ts b/server/sonar-web/src/main/js/api/notifications.ts
index 27f0a2ad6a0..79f51757d06 100644
--- a/server/sonar-web/src/main/js/api/notifications.ts
+++ b/server/sonar-web/src/main/js/api/notifications.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post } from '../helpers/request';
import { Notification } from '../types/types';
diff --git a/server/sonar-web/src/main/js/api/permissions.ts b/server/sonar-web/src/main/js/api/permissions.ts
index cb274e2e591..295ccc7f274 100644
--- a/server/sonar-web/src/main/js/api/permissions.ts
+++ b/server/sonar-web/src/main/js/api/permissions.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON, RequestData } from '../helpers/request';
import {
Paging,
diff --git a/server/sonar-web/src/main/js/api/plugins.ts b/server/sonar-web/src/main/js/api/plugins.ts
index abffaad12b6..64510fd49e9 100644
--- a/server/sonar-web/src/main/js/api/plugins.ts
+++ b/server/sonar-web/src/main/js/api/plugins.ts
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { findLastIndex } from 'lodash';
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post } from '../helpers/request';
import { isDefined } from '../helpers/types';
import {
diff --git a/server/sonar-web/src/main/js/api/project-badges.ts b/server/sonar-web/src/main/js/api/project-badges.ts
index aa5110861b4..44c9e94f34d 100644
--- a/server/sonar-web/src/main/js/api/project-badges.ts
+++ b/server/sonar-web/src/main/js/api/project-badges.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, postJSON } from '../helpers/request';
export function getProjectBadgesToken(project: string) {
diff --git a/server/sonar-web/src/main/js/api/project-dump.ts b/server/sonar-web/src/main/js/api/project-dump.ts
index 9e027dc9c47..34e9271c7d4 100644
--- a/server/sonar-web/src/main/js/api/project-dump.ts
+++ b/server/sonar-web/src/main/js/api/project-dump.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post } from '../helpers/request';
import { DumpStatus } from '../types/project-dump';
diff --git a/server/sonar-web/src/main/js/api/projectActivity.ts b/server/sonar-web/src/main/js/api/projectActivity.ts
index cc773eea128..9fde41ead19 100644
--- a/server/sonar-web/src/main/js/api/projectActivity.ts
+++ b/server/sonar-web/src/main/js/api/projectActivity.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON, RequestData } from '../helpers/request';
import { BranchParameters } from '../types/branch-like';
import { Analysis, Paging } from '../types/types';
diff --git a/server/sonar-web/src/main/js/api/projectLinks.ts b/server/sonar-web/src/main/js/api/projectLinks.ts
index 7c7307d510b..6af46e1adc5 100644
--- a/server/sonar-web/src/main/js/api/projectLinks.ts
+++ b/server/sonar-web/src/main/js/api/projectLinks.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON } from '../helpers/request';
import { ProjectLink } from '../types/types';
diff --git a/server/sonar-web/src/main/js/api/quality-gates.ts b/server/sonar-web/src/main/js/api/quality-gates.ts
index e28492899cd..dbc478b3b60 100644
--- a/server/sonar-web/src/main/js/api/quality-gates.ts
+++ b/server/sonar-web/src/main/js/api/quality-gates.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON } from '../helpers/request';
import { BranchParameters } from '../types/branch-like';
import {
diff --git a/server/sonar-web/src/main/js/api/quality-profiles.ts b/server/sonar-web/src/main/js/api/quality-profiles.ts
index ae130bb6373..283f0c52d2a 100644
--- a/server/sonar-web/src/main/js/api/quality-profiles.ts
+++ b/server/sonar-web/src/main/js/api/quality-profiles.ts
@@ -18,9 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { map } from 'lodash';
-import throwGlobalError from '../app/utils/throwGlobalError';
import { Exporter, ProfileChangelogEvent } from '../apps/quality-profiles/types';
import { csvEscape } from '../helpers/csv';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON, RequestData } from '../helpers/request';
import { Dict, Paging, ProfileInheritanceDetails, UserSelected } from '../types/types';
diff --git a/server/sonar-web/src/main/js/api/rules.ts b/server/sonar-web/src/main/js/api/rules.ts
index 419e7ed7eef..6a39950ed35 100644
--- a/server/sonar-web/src/main/js/api/rules.ts
+++ b/server/sonar-web/src/main/js/api/rules.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON } from '../helpers/request';
import { GetRulesAppResponse, SearchRulesResponse } from '../types/coding-rules';
import { SearchRulesQuery } from '../types/rules';
diff --git a/server/sonar-web/src/main/js/api/security-hotspots.ts b/server/sonar-web/src/main/js/api/security-hotspots.ts
index 2f2608b2b3b..b4d4d01dba0 100644
--- a/server/sonar-web/src/main/js/api/security-hotspots.ts
+++ b/server/sonar-web/src/main/js/api/security-hotspots.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post } from '../helpers/request';
import { BranchParameters } from '../types/branch-like';
import {
diff --git a/server/sonar-web/src/main/js/api/settings.ts b/server/sonar-web/src/main/js/api/settings.ts
index e621314c27e..e322511bce8 100644
--- a/server/sonar-web/src/main/js/api/settings.ts
+++ b/server/sonar-web/src/main/js/api/settings.ts
@@ -18,8 +18,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { omitBy } from 'lodash';
-import throwGlobalError from '../app/utils/throwGlobalError';
import { isCategoryDefinition } from '../apps/settings/utils';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON, RequestData } from '../helpers/request';
import { BranchParameters } from '../types/branch-like';
import {
diff --git a/server/sonar-web/src/main/js/api/system.ts b/server/sonar-web/src/main/js/api/system.ts
index 40b03839a31..fa0721eb9b8 100644
--- a/server/sonar-web/src/main/js/api/system.ts
+++ b/server/sonar-web/src/main/js/api/system.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON, requestTryAndRepeatUntil } from '../helpers/request';
import { SystemUpgrade } from '../types/system';
import { SysInfoCluster, SysInfoStandalone, SysStatus } from '../types/types';
diff --git a/server/sonar-web/src/main/js/api/time-machine.ts b/server/sonar-web/src/main/js/api/time-machine.ts
index 720e562738c..f6e7ee3da68 100644
--- a/server/sonar-web/src/main/js/api/time-machine.ts
+++ b/server/sonar-web/src/main/js/api/time-machine.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON } from '../helpers/request';
import { BranchParameters } from '../types/branch-like';
import { Paging } from '../types/types';
diff --git a/server/sonar-web/src/main/js/api/user-tokens.ts b/server/sonar-web/src/main/js/api/user-tokens.ts
index adcc9215475..53daaf04b4b 100644
--- a/server/sonar-web/src/main/js/api/user-tokens.ts
+++ b/server/sonar-web/src/main/js/api/user-tokens.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON } from '../helpers/request';
import { NewUserToken, UserToken } from '../types/types';
diff --git a/server/sonar-web/src/main/js/api/user_groups.ts b/server/sonar-web/src/main/js/api/user_groups.ts
index 9b78402d12d..5949d53c70d 100644
--- a/server/sonar-web/src/main/js/api/user_groups.ts
+++ b/server/sonar-web/src/main/js/api/user_groups.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON } from '../helpers/request';
import { Group, Paging, UserSelected } from '../types/types';
diff --git a/server/sonar-web/src/main/js/api/users.ts b/server/sonar-web/src/main/js/api/users.ts
index 272c2c73295..9b94961ebc8 100644
--- a/server/sonar-web/src/main/js/api/users.ts
+++ b/server/sonar-web/src/main/js/api/users.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON } from '../helpers/request';
import { IdentityProvider, Paging } from '../types/types';
import { CurrentUser, HomePage, User } from '../types/users';
diff --git a/server/sonar-web/src/main/js/api/web-api.ts b/server/sonar-web/src/main/js/api/web-api.ts
index b9d7119dde6..31b3770d7ac 100644
--- a/server/sonar-web/src/main/js/api/web-api.ts
+++ b/server/sonar-web/src/main/js/api/web-api.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON } from '../helpers/request';
import { WebApi } from '../types/types';
diff --git a/server/sonar-web/src/main/js/api/webhooks.ts b/server/sonar-web/src/main/js/api/webhooks.ts
index e178cc4dc02..3c9fe1300ef 100644
--- a/server/sonar-web/src/main/js/api/webhooks.ts
+++ b/server/sonar-web/src/main/js/api/webhooks.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../app/utils/throwGlobalError';
+import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON } from '../helpers/request';
import { Paging, Webhook, WebhookDelivery } from '../types/types';
diff --git a/server/sonar-web/src/main/js/app/components/StartupModal.tsx b/server/sonar-web/src/main/js/app/components/StartupModal.tsx
index ebbdebed587..8bf0201d3b4 100644
--- a/server/sonar-web/src/main/js/app/components/StartupModal.tsx
+++ b/server/sonar-web/src/main/js/app/components/StartupModal.tsx
@@ -19,7 +19,7 @@
*/
import { differenceInDays } from 'date-fns';
import * as React from 'react';
-import { showLicense } from '../../api/marketplace';
+import { showLicense } from '../../api/editions';
import { Location, Router, withRouter } from '../../components/hoc/withRouter';
import { lazyLoadComponent } from '../../components/lazyLoadComponent';
import { parseDate, toShortNotSoISOString } from '../../helpers/dates';
diff --git a/server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx b/server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx
index 0813389c9ba..c6d82ab38e9 100644
--- a/server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx
+++ b/server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx
@@ -20,7 +20,7 @@
import { differenceInDays } from 'date-fns';
import { shallow, ShallowWrapper } from 'enzyme';
import * as React from 'react';
-import { showLicense } from '../../../api/marketplace';
+import { showLicense } from '../../../api/editions';
import { toShortNotSoISOString } from '../../../helpers/dates';
import { hasMessage } from '../../../helpers/l10n';
import { get, save } from '../../../helpers/storage';
@@ -30,7 +30,7 @@ import { EditionKey } from '../../../types/editions';
import { LoggedInUser } from '../../../types/users';
import { StartupModal } from '../StartupModal';
-jest.mock('../../../api/marketplace', () => ({
+jest.mock('../../../api/editions', () => ({
showLicense: jest.fn().mockResolvedValue(undefined)
}));
diff --git a/server/sonar-web/src/main/js/app/components/extensions/Extension.tsx b/server/sonar-web/src/main/js/app/components/extensions/Extension.tsx
index 695cd5f3efc..1220526fb6a 100644
--- a/server/sonar-web/src/main/js/app/components/extensions/Extension.tsx
+++ b/server/sonar-web/src/main/js/app/components/extensions/Extension.tsx
@@ -23,7 +23,8 @@ import { injectIntl, WrappedComponentProps } from 'react-intl';
import { connect } from 'react-redux';
import { Location, Router, withRouter } from '../../../components/hoc/withRouter';
import { getExtensionStart } from '../../../helpers/extensions';
-import { getCurrentL10nBundle, translate } from '../../../helpers/l10n';
+import { translate } from '../../../helpers/l10n';
+import { getCurrentL10nBundle } from '../../../helpers/l10nBundle';
import { getBaseUrl } from '../../../helpers/system';
import { addGlobalErrorMessage } from '../../../store/globalMessages';
import { AppState } from '../../../types/appstate';
diff --git a/server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts b/server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts
index 243356b07ee..ab9847c117b 100644
--- a/server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts
+++ b/server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts
@@ -87,6 +87,7 @@ import {
isPullRequest,
sortBranches
} from '../../../helpers/branch-like';
+import { throwGlobalError } from '../../../helpers/error';
import handleRequiredAuthentication from '../../../helpers/handleRequiredAuthentication';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import * as measures from '../../../helpers/measures';
@@ -119,7 +120,6 @@ import {
getRulesUrl
} from '../../../helpers/urls';
import addGlobalSuccessMessage from '../../utils/addGlobalSuccessMessage';
-import throwGlobalError from '../../utils/throwGlobalError';
import A11ySkipTarget from '../a11y/A11ySkipTarget';
import Suggestions from '../embed-docs-modal/Suggestions';
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavLicenseNotif.tsx b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavLicenseNotif.tsx
index 7c9e217e1ab..7ada2c4db56 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavLicenseNotif.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavLicenseNotif.tsx
@@ -19,7 +19,7 @@
*/
import * as React from 'react';
import { Link } from 'react-router';
-import { isValidLicense } from '../../../../api/marketplace';
+import { isValidLicense } from '../../../../api/editions';
import { Alert } from '../../../../components/ui/Alert';
import { translate, translateWithParameters } from '../../../../helpers/l10n';
import { AppState } from '../../../../types/appstate';
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavLicenseNotif-test.tsx b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavLicenseNotif-test.tsx
index 354a592c179..292790dfdce 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavLicenseNotif-test.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavLicenseNotif-test.tsx
@@ -19,7 +19,7 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { isValidLicense } from '../../../../../api/marketplace';
+import { isValidLicense } from '../../../../../api/editions';
import { mockTask } from '../../../../../helpers/mocks/tasks';
import { mockAppState } from '../../../../../helpers/testMocks';
import { waitAndUpdate } from '../../../../../helpers/testUtils';
@@ -31,7 +31,7 @@ jest.mock('../../../../../helpers/l10n', () => ({
hasMessage: jest.fn().mockReturnValue(true)
}));
-jest.mock('../../../../../api/marketplace', () => ({
+jest.mock('../../../../../api/editions', () => ({
isValidLicense: jest.fn().mockResolvedValue({ isValidLicense: false })
}));
diff --git a/server/sonar-web/src/main/js/app/index.ts b/server/sonar-web/src/main/js/app/index.ts
index f63328930f4..85532d23a70 100644
--- a/server/sonar-web/src/main/js/app/index.ts
+++ b/server/sonar-web/src/main/js/app/index.ts
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { installExtensionsHandler, installWebAnalyticsHandler } from '../helpers/extensionsHandler';
-import { loadL10nBundle } from '../helpers/l10n';
+import { loadL10nBundle } from '../helpers/l10nBundle';
import { parseJSON, request } from '../helpers/request';
import { getBaseUrl, getSystemStatus } from '../helpers/system';
import { AppState } from '../types/appstate';
diff --git a/server/sonar-web/src/main/js/app/utils/exportModulesAsGlobals.ts b/server/sonar-web/src/main/js/app/utils/exportModulesAsGlobals.ts
new file mode 100644
index 00000000000..f9351d9ef26
--- /dev/null
+++ b/server/sonar-web/src/main/js/app/utils/exportModulesAsGlobals.ts
@@ -0,0 +1,45 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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 EmotionReact from '@emotion/react';
+import EmotionStyled from '@emotion/styled';
+import * as DateFns from 'date-fns';
+import Lodash from 'lodash';
+import React from 'react';
+import * as ReactDom from 'react-dom';
+import * as ReactIntl from 'react-intl';
+import ReactModal from 'react-modal';
+import * as ReactRouter from 'react-router';
+
+/*
+ * Expose dependencies to extensions
+ */
+export default function exportModulesAsGlobals() {
+ const w = (window as unknown) as any;
+ w.EmotionReact = EmotionReact;
+ w.EmotionStyled = EmotionStyled;
+ w.DateFns = DateFns;
+ w.Lodash = Lodash;
+ w.React = React;
+ w.ReactDOM = ReactDom;
+ w.ReactIntl = ReactIntl;
+ w.ReactModal = ReactModal;
+ w.ReactRouter = ReactRouter;
+}
diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx
index 0c8dc2ab1d5..fc17431e3fa 100644
--- a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx
+++ b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx
@@ -21,7 +21,7 @@
import { Location } from 'history';
import { pick } from 'lodash';
import * as React from 'react';
-import ReactDom, { render } from 'react-dom';
+import { render } from 'react-dom';
import { HelmetProvider } from 'react-helmet-async';
import { IntlProvider } from 'react-intl';
import { Provider } from 'react-redux';
@@ -69,16 +69,9 @@ import GlobalContainer from '../components/GlobalContainer';
import { PageContext } from '../components/indexation/PageUnavailableDueToIndexation';
import MigrationContainer from '../components/MigrationContainer';
import NonAdminPagesContainer from '../components/NonAdminPagesContainer';
+import exportModulesAsGlobals from './exportModulesAsGlobals';
import getStore from './getStore';
-/*
- * Expose dependencies to extensions
- */
-function attachToGlobal() {
- window.React = React;
- window.ReactDOM = ReactDom;
-}
-
function handleUpdate(this: { state: { location: Location } }) {
const { action } = this.state.location;
@@ -202,7 +195,10 @@ function renderComponentRoutes() {
if (query.types === 'SECURITY_HOTSPOT') {
replace({
pathname: '/security_hotspots',
- query: { ...pick(query, ['id', 'branch', 'pullRequest']), assignedToMe: false }
+ query: {
+ ...pick(query, ['id', 'branch', 'pullRequest']),
+ assignedToMe: false
+ }
});
} else {
query.types = query.types
@@ -282,7 +278,7 @@ function renderAdminRoutes() {
}
export default function startReactApp(lang: string, appState: AppState, currentUser?: CurrentUser) {
- attachToGlobal();
+ exportModulesAsGlobals();
const el = document.getElementById('content');
diff --git a/server/sonar-web/src/main/js/apps/component-measures/sidebar/__tests__/__snapshots__/DomainFacet-test.tsx.snap b/server/sonar-web/src/main/js/apps/component-measures/sidebar/__tests__/__snapshots__/DomainFacet-test.tsx.snap
index 11dab834f4b..7fe3dc6a978 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/sidebar/__tests__/__snapshots__/DomainFacet-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/component-measures/sidebar/__tests__/__snapshots__/DomainFacet-test.tsx.snap
@@ -5,6 +5,7 @@ exports[`should display facet item list 1`] = `
property="Reliability"
>
<FacetHeader
+ helper="component_measures.domain_facets.Reliability.help"
name="Reliability"
onClick={[Function]}
open={true}
@@ -141,6 +142,7 @@ exports[`should display facet item list with bugs selected 1`] = `
property="Reliability"
>
<FacetHeader
+ helper="component_measures.domain_facets.Reliability.help"
name="Reliability"
onClick={[Function]}
open={true}
@@ -281,6 +283,7 @@ exports[`should not display subtitles of new measures if there is none 1`] = `
property="Reliability"
>
<FacetHeader
+ helper="component_measures.domain_facets.Reliability.help"
name="Reliability"
onClick={[Function]}
open={true}
@@ -363,6 +366,7 @@ exports[`should not display subtitles of new measures if there is none, even on
property="Reliability"
>
<FacetHeader
+ helper="component_measures.domain_facets.Reliability.help"
name="Reliability"
onClick={[Function]}
open={true}
diff --git a/server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.tsx b/server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.tsx
index fe751666118..0690a1223a9 100644
--- a/server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.tsx
@@ -21,7 +21,6 @@ import { pickBy, sortBy } from 'lodash';
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import { bulkChangeIssues, searchIssueTags } from '../../../api/issues';
-import throwGlobalError from '../../../app/utils/throwGlobalError';
import FormattingTips from '../../../components/common/FormattingTips';
import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import Checkbox from '../../../components/controls/Checkbox';
@@ -35,6 +34,7 @@ import IssueTypeIcon from '../../../components/icons/IssueTypeIcon';
import SeverityHelper from '../../../components/shared/SeverityHelper';
import { Alert } from '../../../components/ui/Alert';
import Avatar from '../../../components/ui/Avatar';
+import { throwGlobalError } from '../../../helpers/error';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { Component, Dict, Issue, IssueType, Paging } from '../../../types/types';
import { CurrentUser, isLoggedIn, isUserActive } from '../../../types/users';
diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx
index ed64d641e5f..2bd9406c410 100644
--- a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx
@@ -21,7 +21,6 @@ import { findLastIndex } from 'lodash';
import * as React from 'react';
import { getDuplications } from '../../../api/components';
import { getIssueFlowSnippets } from '../../../api/issues';
-import throwGlobalError from '../../../app/utils/throwGlobalError';
import DuplicationPopup from '../../../components/SourceViewer/components/DuplicationPopup';
import {
filterDuplicationBlocksByLine,
@@ -37,6 +36,7 @@ import { Alert } from '../../../components/ui/Alert';
import DeferredSpinner from '../../../components/ui/DeferredSpinner';
import { WorkspaceContext } from '../../../components/workspace/context';
import { getBranchLikeQuery } from '../../../helpers/branch-like';
+import { throwGlobalError } from '../../../helpers/error';
import { translate } from '../../../helpers/l10n';
import { BranchLike } from '../../../types/branch-like';
import {
diff --git a/server/sonar-web/src/main/js/apps/permissions/__tests__/utils-test.ts b/server/sonar-web/src/main/js/apps/permissions/__tests__/utils-test.ts
index a7a8493f2cd..72e28f5ac38 100644
--- a/server/sonar-web/src/main/js/apps/permissions/__tests__/utils-test.ts
+++ b/server/sonar-web/src/main/js/apps/permissions/__tests__/utils-test.ts
@@ -17,27 +17,26 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { resetMessages } from '../../../helpers/l10n';
import { isSonarCloud } from '../../../helpers/system';
import { convertToPermissionDefinitions } from '../utils';
jest.mock('../../../helpers/system', () => ({ isSonarCloud: jest.fn() }));
-afterEach(() => {
- resetMessages({});
-});
+jest.mock('../../../helpers/l10nBundle', () => ({
+ getMessages: jest.fn().mockReturnValue({})
+}));
describe('convertToPermissionDefinitions', () => {
it('should convert and translate a permission definition', () => {
(isSonarCloud as jest.Mock).mockImplementation(() => false);
- resetMessages({
- 'global_permissions.admin': 'Administer System'
- });
-
const data = convertToPermissionDefinitions(['admin'], 'global_permissions');
const expected = [
- { description: 'global_permissions.admin.desc', key: 'admin', name: 'Administer System' }
+ {
+ description: 'global_permissions.admin.desc',
+ key: 'admin',
+ name: 'global_permissions.admin'
+ }
];
expect(data).toEqual(expected);
@@ -46,17 +45,12 @@ describe('convertToPermissionDefinitions', () => {
it('should convert and translate a permission definition for SonarCloud', () => {
(isSonarCloud as jest.Mock).mockImplementation(() => true);
- resetMessages({
- 'global_permissions.admin': 'Administer System',
- 'global_permissions.admin.sonarcloud': 'Administer Organization'
- });
-
const data = convertToPermissionDefinitions(['admin'], 'global_permissions');
const expected = [
{
- description: 'global_permissions.admin.desc',
+ description: 'global_permissions.admin.desc.sonarcloud',
key: 'admin',
- name: 'Administer Organization'
+ name: 'global_permissions.admin.sonarcloud'
}
];
@@ -66,13 +60,13 @@ describe('convertToPermissionDefinitions', () => {
it('should fallback to basic message when SonarCloud version does not exist', () => {
(isSonarCloud as jest.Mock).mockImplementation(() => true);
- resetMessages({
- 'global_permissions.admin': 'Administer System'
- });
-
const data = convertToPermissionDefinitions(['admin'], 'global_permissions');
const expected = [
- { description: 'global_permissions.admin.desc', key: 'admin', name: 'Administer System' }
+ {
+ description: 'global_permissions.admin.desc.sonarcloud',
+ key: 'admin',
+ name: 'global_permissions.admin.sonarcloud'
+ }
];
expect(data).toEqual(expected);
diff --git a/server/sonar-web/src/main/js/apps/projectDump/ProjectDumpApp.tsx b/server/sonar-web/src/main/js/apps/projectDump/ProjectDumpApp.tsx
index 29043ef9a85..43c17531ec2 100644
--- a/server/sonar-web/src/main/js/apps/projectDump/ProjectDumpApp.tsx
+++ b/server/sonar-web/src/main/js/apps/projectDump/ProjectDumpApp.tsx
@@ -21,7 +21,7 @@ import * as React from 'react';
import { getActivity } from '../../api/ce';
import { getStatus } from '../../api/project-dump';
import withAppStateContext from '../../app/components/app-state/withAppStateContext';
-import throwGlobalError from '../../app/utils/throwGlobalError';
+import { throwGlobalError } from '../../helpers/error';
import { translate } from '../../helpers/l10n';
import { AppState } from '../../types/appstate';
import { DumpStatus, DumpTask } from '../../types/project-dump';
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap
index bc199c6498d..1b46b821b3f 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap
@@ -27,7 +27,7 @@ exports[`should render correctly: branches disabled 1`] = `
>
<IndexLink
className=""
- title="general"
+ title="property.category.general"
to={
Object {
"pathname": "/admin/settings",
@@ -37,7 +37,7 @@ exports[`should render correctly: branches disabled 1`] = `
}
}
>
- general
+ property.category.general
</IndexLink>
</li>
</ul>
@@ -88,7 +88,7 @@ exports[`should render correctly: global mode 1`] = `
>
<IndexLink
className=""
- title="general"
+ title="property.category.general"
to={
Object {
"pathname": "/admin/settings",
@@ -98,7 +98,7 @@ exports[`should render correctly: global mode 1`] = `
}
}
>
- general
+ property.category.general
</IndexLink>
</li>
</ul>
@@ -151,7 +151,7 @@ exports[`should render correctly: project mode 1`] = `
>
<IndexLink
className=""
- title="general"
+ title="property.category.general"
to={
Object {
"pathname": "/project/settings",
@@ -162,7 +162,7 @@ exports[`should render correctly: project mode 1`] = `
}
}
>
- general
+ property.category.general
</IndexLink>
</li>
</ul>
@@ -213,7 +213,7 @@ exports[`should render correctly: selected category 1`] = `
>
<IndexLink
className=""
- title="general"
+ title="property.category.general"
to={
Object {
"pathname": "/admin/settings",
@@ -223,7 +223,7 @@ exports[`should render correctly: selected category 1`] = `
}
}
>
- general
+ property.category.general
</IndexLink>
</li>
</ul>
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/DefinitionRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/DefinitionRenderer-test.tsx.snap
index 25ae668483f..4dd0f528a50 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/DefinitionRenderer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/DefinitionRenderer-test.tsx.snap
@@ -10,6 +10,17 @@ exports[`should render correctly: changed value 1`] = `
>
<h3
className="settings-definition-name"
+ title="property.foo.name"
+ >
+ property.foo.name
+ </h3>
+ <div
+ className="markdown small spacer-top"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "property.foo.description",
+ }
+ }
/>
<div
className="settings-definition-key note little-spacer-top"
@@ -83,6 +94,17 @@ exports[`should render correctly: in error 1`] = `
>
<h3
className="settings-definition-name"
+ title="property.foo.name"
+ >
+ property.foo.name
+ </h3>
+ <div
+ className="markdown small spacer-top"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "property.foo.description",
+ }
+ }
/>
<div
className="settings-definition-key note little-spacer-top"
@@ -165,6 +187,17 @@ exports[`should render correctly: loading 1`] = `
>
<h3
className="settings-definition-name"
+ title="property.foo.name"
+ >
+ property.foo.name
+ </h3>
+ <div
+ className="markdown small spacer-top"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "property.foo.description",
+ }
+ }
/>
<div
className="settings-definition-key note little-spacer-top"
@@ -245,6 +278,17 @@ exports[`should render correctly: original value 1`] = `
>
<h3
className="settings-definition-name"
+ title="property.foo.name"
+ >
+ property.foo.name
+ </h3>
+ <div
+ className="markdown small spacer-top"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "property.foo.description",
+ }
+ }
/>
<div
className="settings-definition-key note little-spacer-top"
@@ -319,6 +363,17 @@ exports[`should render correctly: success 1`] = `
>
<h3
className="settings-definition-name"
+ title="property.foo.name"
+ >
+ property.foo.name
+ </h3>
+ <div
+ className="markdown small spacer-top"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "property.foo.description",
+ }
+ }
/>
<div
className="settings-definition-key note little-spacer-top"
@@ -399,12 +454,15 @@ exports[`should render correctly: with description 1`] = `
>
<h3
className="settings-definition-name"
- />
+ title="property.foo.name"
+ >
+ property.foo.name
+ </h3>
<div
className="markdown small spacer-top"
dangerouslySetInnerHTML={
Object {
- "__html": "description",
+ "__html": "property.foo.description",
}
}
/>
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap
index 71ac56dcb64..0659334976a 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap
@@ -16,17 +16,17 @@ exports[`should render correctly 1`] = `
options={
Array [
Object {
- "label": "Java",
+ "label": "property.category.Java",
"originalValue": "Java",
"value": "java",
},
Object {
- "label": "JavaScript",
+ "label": "property.category.JavaScript",
"originalValue": "JavaScript",
"value": "javascript",
},
Object {
- "label": "COBOL",
+ "label": "property.category.COBOL",
"originalValue": "COBOL",
"value": "cobol",
},
@@ -63,17 +63,17 @@ exports[`should render correctly with an unknow language 1`] = `
options={
Array [
Object {
- "label": "Java",
+ "label": "property.category.Java",
"originalValue": "Java",
"value": "java",
},
Object {
- "label": "JavaScript",
+ "label": "property.category.JavaScript",
"originalValue": "JavaScript",
"value": "javascript",
},
Object {
- "label": "COBOL",
+ "label": "property.category.COBOL",
"originalValue": "COBOL",
"value": "cobol",
},
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/SubCategoryDefinitionsList-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/SubCategoryDefinitionsList-test.tsx.snap
index ff66d64f6a4..d4699f7f8e2 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/SubCategoryDefinitionsList-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/SubCategoryDefinitionsList-test.tsx.snap
@@ -11,8 +11,16 @@ exports[`should render correctly 1`] = `
className="settings-sub-category-name"
data-key="email"
>
- email
+ property.category.general.email
</h2>
+ <div
+ className="settings-sub-category-description markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "property.category.general.email.description",
+ }
+ }
+ />
<DefinitionsList
scrollToDefinition={[Function]}
settings={
@@ -45,8 +53,16 @@ exports[`should render correctly 1`] = `
className="settings-sub-category-name"
data-key="qg"
>
- qg
+ property.category.general.qg
</h2>
+ <div
+ className="settings-sub-category-description markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "property.category.general.qg.description",
+ }
+ }
+ />
<DefinitionsList
scrollToDefinition={[Function]}
settings={
@@ -83,8 +99,16 @@ exports[`should render correctly: subcategory 1`] = `
className="settings-sub-category-name"
data-key="qg"
>
- qg
+ property.category.general.qg
</h2>
+ <div
+ className="settings-sub-category-description markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "property.category.general.qg.description",
+ }
+ }
+ />
<DefinitionsList
scrollToDefinition={[Function]}
settings={
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx
index dcd43858157..5d307e589cc 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx
@@ -30,7 +30,7 @@ import {
validateProjectAlmBinding
} from '../../../../api/alm-settings';
import withCurrentUserContext from '../../../../app/components/current-user/withCurrentUserContext';
-import throwGlobalError from '../../../../app/utils/throwGlobalError';
+import { throwGlobalError } from '../../../../helpers/error';
import { HttpStatus } from '../../../../helpers/request';
import { hasGlobalPermission } from '../../../../helpers/users';
import {
diff --git a/server/sonar-web/src/main/js/apps/users/components/PasswordForm.tsx b/server/sonar-web/src/main/js/apps/users/components/PasswordForm.tsx
index b4b0d24b776..86f9416a7fe 100644
--- a/server/sonar-web/src/main/js/apps/users/components/PasswordForm.tsx
+++ b/server/sonar-web/src/main/js/apps/users/components/PasswordForm.tsx
@@ -20,12 +20,12 @@
import * as React from 'react';
import { changePassword } from '../../../api/users';
import addGlobalSuccessMessage from '../../../app/utils/addGlobalSuccessMessage';
-import throwGlobalError from '../../../app/utils/throwGlobalError';
import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import Modal from '../../../components/controls/Modal';
import { Alert } from '../../../components/ui/Alert';
import MandatoryFieldMarker from '../../../components/ui/MandatoryFieldMarker';
import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsExplanation';
+import { throwGlobalError } from '../../../helpers/error';
import { translate } from '../../../helpers/l10n';
import { parseError } from '../../../helpers/request';
import { User } from '../../../types/users';
diff --git a/server/sonar-web/src/main/js/apps/users/components/UserForm.tsx b/server/sonar-web/src/main/js/apps/users/components/UserForm.tsx
index e0d954293d6..3bd0a8cc0e9 100644
--- a/server/sonar-web/src/main/js/apps/users/components/UserForm.tsx
+++ b/server/sonar-web/src/main/js/apps/users/components/UserForm.tsx
@@ -20,12 +20,12 @@
import { uniq } from 'lodash';
import * as React from 'react';
import { createUser, updateUser } from '../../../api/users';
-import throwGlobalError from '../../../app/utils/throwGlobalError';
import { Button, ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import SimpleModal from '../../../components/controls/SimpleModal';
import { Alert } from '../../../components/ui/Alert';
import MandatoryFieldMarker from '../../../components/ui/MandatoryFieldMarker';
import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsExplanation';
+import { throwGlobalError } from '../../../helpers/error';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { parseError } from '../../../helpers/request';
import { User } from '../../../types/users';
diff --git a/server/sonar-web/src/main/js/components/issue/__tests__/actions-test.ts b/server/sonar-web/src/main/js/components/issue/__tests__/actions-test.ts
index 93d18d556ff..fb0a525465b 100644
--- a/server/sonar-web/src/main/js/components/issue/__tests__/actions-test.ts
+++ b/server/sonar-web/src/main/js/components/issue/__tests__/actions-test.ts
@@ -17,13 +17,13 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../../../app/utils/throwGlobalError';
+import { throwGlobalError } from '../../../helpers/error';
import { parseIssueFromResponse } from '../../../helpers/issues';
import { mockComponent } from '../../../helpers/mocks/component';
import { mockIssue } from '../../../helpers/testMocks';
import { updateIssue } from '../actions';
-jest.mock('../../../app/utils/throwGlobalError', () => jest.fn());
+jest.mock('../../../helpers/error', () => ({ throwGlobalError: jest.fn() }));
jest.mock('../../../helpers/issues', () => ({
parseIssueFromResponse: jest.fn()
diff --git a/server/sonar-web/src/main/js/components/issue/actions.ts b/server/sonar-web/src/main/js/components/issue/actions.ts
index c074dc0c952..e84b3a5fcd7 100644
--- a/server/sonar-web/src/main/js/components/issue/actions.ts
+++ b/server/sonar-web/src/main/js/components/issue/actions.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import throwGlobalError from '../../app/utils/throwGlobalError';
+import { throwGlobalError } from '../../helpers/error';
import { parseIssueFromResponse } from '../../helpers/issues';
import { IssueResponse } from '../../types/issues';
import { Issue } from '../../types/types';
diff --git a/server/sonar-web/src/main/js/app/utils/__tests__/throwGlobalError-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/error-test.ts
index 13c5f9f85b4..ca6f81a60e9 100644
--- a/server/sonar-web/src/main/js/app/utils/__tests__/throwGlobalError-test.ts
+++ b/server/sonar-web/src/main/js/helpers/__tests__/error-test.ts
@@ -17,8 +17,8 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import getStore from '../getStore';
-import throwGlobalError from '../throwGlobalError';
+import getStore from '../../app/utils/getStore';
+import { throwGlobalError } from '../error';
beforeAll(() => {
jest.useFakeTimers();
@@ -35,7 +35,9 @@ it('should put the error message in the store', async () => {
// We need to catch because throwGlobalError rethrows after displaying the message
await throwGlobalError(response)
- .then(() => fail('Should throw'))
+ .then(() => {
+ throw new Error('Should throw');
+ })
.catch(() => {});
expect(getStore().getState().globalMessages[0]).toMatchObject({
@@ -50,7 +52,9 @@ it('should put a default error messsage in the store', async () => {
// We need to catch because throwGlobalError rethrows after displaying the message
await throwGlobalError(response)
- .then(() => fail('Should throw'))
+ .then(() => {
+ throw new Error('Should throw');
+ })
.catch(() => {});
expect(getStore().getState().globalMessages[0]).toMatchObject({
@@ -63,7 +67,9 @@ it('should handle weird response types', () => {
const response = { weird: 'response type' };
return throwGlobalError(response)
- .then(() => fail('Should throw'))
+ .then(() => {
+ throw new Error('Should throw');
+ })
.catch(error => {
expect(error).toBe(response);
});
@@ -78,7 +84,9 @@ it('should unwrap response if necessary', async () => {
// We need to catch because throwGlobalError rethrows after displaying the message
await throwGlobalError({ response })
- .then(() => fail('Should throw'))
+ .then(() => {
+ throw new Error('Should throw');
+ })
.catch(() => {});
/* eslint-disable-next-line no-console */
diff --git a/server/sonar-web/src/main/js/helpers/__tests__/l10n-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/l10n-test.ts
index 58d2f94461d..346d097dce8 100644
--- a/server/sonar-web/src/main/js/helpers/__tests__/l10n-test.ts
+++ b/server/sonar-web/src/main/js/helpers/__tests__/l10n-test.ts
@@ -17,84 +17,51 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { fetchL10nBundle } from '../../api/l10n';
+import { Dict } from '../../types/types';
import {
getLocalizedCategoryMetricName,
getLocalizedMetricDomain,
getLocalizedMetricName,
- getMessages,
getShortMonthName,
getShortWeekDayName,
getWeekDayName,
hasMessage,
- loadL10nBundle,
- resetMessages,
translate,
translateWithParameters
} from '../l10n';
-import { get } from '../storage';
+import { getMessages } from '../l10nBundle';
-beforeEach(() => {
- jest.clearAllMocks();
- jest.spyOn(window.navigator, 'languages', 'get').mockReturnValue(['de']);
-});
+const MSG = 'my_message';
-jest.mock('../../api/l10n', () => ({
- fetchL10nBundle: jest
- .fn()
- .mockResolvedValue({ effectiveLocale: 'de', messages: { test_message: 'test' } })
-}));
+jest.unmock('../l10n');
-jest.mock('../../helpers/storage', () => ({
- get: jest.fn(),
- save: jest.fn()
+jest.mock('../l10nBundle', () => ({
+ getMessages: jest.fn().mockReturnValue({})
}));
-describe('#loadL10nBundle', () => {
- it('should fetch bundle without any timestamp', async () => {
- await loadL10nBundle();
-
- expect(fetchL10nBundle).toHaveBeenCalledWith({ locale: 'de', ts: undefined });
- });
-
- it('should ftech bundle without local storage timestamp if locales are different', async () => {
- const cachedBundle = { timestamp: 'timestamp', locale: 'fr', messages: { cache: 'cache' } };
- (get as jest.Mock).mockReturnValueOnce(JSON.stringify(cachedBundle));
-
- await loadL10nBundle();
-
- expect(fetchL10nBundle).toHaveBeenCalledWith({ locale: 'de', ts: undefined });
- });
-
- it('should fetch bundle with cached bundle timestamp and browser locale', async () => {
- const cachedBundle = { timestamp: 'timestamp', locale: 'de', messages: { cache: 'cache' } };
- (get as jest.Mock).mockReturnValueOnce(JSON.stringify(cachedBundle));
+const resetMessages = (messages: Dict<string>) =>
+ (getMessages as jest.Mock).mockReturnValue(messages);
- await loadL10nBundle();
+beforeEach(() => {
+ resetMessages({});
+});
- expect(fetchL10nBundle).toHaveBeenCalledWith({ locale: 'de', ts: cachedBundle.timestamp });
+describe('hasMessage', () => {
+ it('should return that the message exists', () => {
+ resetMessages({
+ foo: 'foo',
+ 'foo.bar': 'foobar'
+ });
+ expect(hasMessage('foo')).toBe(true);
+ expect(hasMessage('foo', 'bar')).toBe(true);
});
- it('should fallback to cached bundle if the server respond with 304', async () => {
- const cachedBundle = { timestamp: 'timestamp', locale: 'fr', messages: { cache: 'cache' } };
- (fetchL10nBundle as jest.Mock).mockRejectedValueOnce({ status: 304 });
- (get as jest.Mock).mockReturnValueOnce(JSON.stringify(cachedBundle));
-
- const bundle = await loadL10nBundle();
-
- expect(bundle).toEqual(
- expect.objectContaining({ locale: cachedBundle.locale, messages: cachedBundle.messages })
- );
+ it('should return that the message is missing', () => {
+ expect(hasMessage('foo')).toBe(false);
+ expect(hasMessage('foo', 'bar')).toBe(false);
});
});
-const originalMessages = getMessages();
-const MSG = 'my_message';
-
-afterEach(() => {
- resetMessages(originalMessages);
-});
-
describe('translate', () => {
it('should translate simple message', () => {
resetMessages({ my_key: MSG });
@@ -153,19 +120,6 @@ describe('translateWithParameters', () => {
});
});
-describe('hasMessage', () => {
- it('should return that the message exists', () => {
- resetMessages({ foo: 'Foo', 'foo.bar': 'Foo Bar' });
- expect(hasMessage('foo')).toBe(true);
- expect(hasMessage('foo', 'bar')).toBe(true);
- });
-
- it('should return that the message is missing', () => {
- expect(hasMessage('foo')).toBe(false);
- expect(hasMessage('foo', 'bar')).toBe(false);
- });
-});
-
describe('getLocalizedMetricName', () => {
const metric = { key: 'new_code', name: 'new_code_metric_name' };
diff --git a/server/sonar-web/src/main/js/helpers/__tests__/l10nBundle-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/l10nBundle-test.ts
new file mode 100644
index 00000000000..58c1e603b51
--- /dev/null
+++ b/server/sonar-web/src/main/js/helpers/__tests__/l10nBundle-test.ts
@@ -0,0 +1,71 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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 { fetchL10nBundle } from '../../api/l10n';
+import { loadL10nBundle } from '../l10nBundle';
+
+beforeEach(() => {
+ jest.clearAllMocks();
+ jest.spyOn(window.navigator, 'languages', 'get').mockReturnValue(['de']);
+});
+
+jest.mock('../../api/l10n', () => ({
+ fetchL10nBundle: jest.fn().mockResolvedValue({
+ effectiveLocale: 'de',
+ messages: { foo: 'Foo', 'foo.bar': 'Foo Bar' }
+ })
+}));
+
+describe('#loadL10nBundle', () => {
+ it('should fetch bundle without any timestamp', async () => {
+ await loadL10nBundle();
+
+ expect(fetchL10nBundle).toHaveBeenCalledWith({ locale: 'de', ts: undefined });
+ });
+
+ it('should ftech bundle without local storage timestamp if locales are different', async () => {
+ const cachedBundle = { timestamp: 'timestamp', locale: 'fr', messages: { cache: 'cache' } };
+ ((window as unknown) as any).sonarQubeL10nBundle = cachedBundle;
+
+ await loadL10nBundle();
+
+ expect(fetchL10nBundle).toHaveBeenCalledWith({ locale: 'de', ts: undefined });
+ });
+
+ it('should fetch bundle with cached bundle timestamp and browser locale', async () => {
+ const cachedBundle = { timestamp: 'timestamp', locale: 'de', messages: { cache: 'cache' } };
+ ((window as unknown) as any).sonarQubeL10nBundle = cachedBundle;
+
+ await loadL10nBundle();
+
+ expect(fetchL10nBundle).toHaveBeenCalledWith({ locale: 'de', ts: cachedBundle.timestamp });
+ });
+
+ it('should fallback to cached bundle if the server respond with 304', async () => {
+ const cachedBundle = { timestamp: 'timestamp', locale: 'fr', messages: { cache: 'cache' } };
+ (fetchL10nBundle as jest.Mock).mockRejectedValueOnce({ status: 304 });
+ ((window as unknown) as any).sonarQubeL10nBundle = cachedBundle;
+
+ const bundle = await loadL10nBundle();
+
+ expect(bundle).toEqual(
+ expect.objectContaining({ locale: cachedBundle.locale, messages: cachedBundle.messages })
+ );
+ });
+});
diff --git a/server/sonar-web/src/main/js/helpers/__tests__/measures-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/measures-test.ts
index 04a0bfa2ffa..3a301c9b9b6 100644
--- a/server/sonar-web/src/main/js/helpers/__tests__/measures-test.ts
+++ b/server/sonar-web/src/main/js/helpers/__tests__/measures-test.ts
@@ -17,7 +17,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { resetMessages } from '../l10n';
+
+import { Dict } from '../../types/types';
+import { getMessages } from '../l10nBundle';
import {
enhanceConditionWithMeasure,
formatMeasure,
@@ -27,6 +29,36 @@ import {
import { mockQualityGateStatusCondition } from '../mocks/quality-gates';
import { mockMeasureEnhanced, mockMetric } from '../testMocks';
+jest.unmock('../l10n');
+
+jest.mock('../l10nBundle', () => ({
+ getCurrentLocale: jest.fn().mockReturnValue('us'),
+ getMessages: jest.fn().mockReturnValue({})
+}));
+
+const resetMessages = (messages: Dict<string>) =>
+ (getMessages as jest.Mock).mockReturnValue(messages);
+
+beforeAll(() => {
+ resetMessages({
+ 'work_duration.x_days': '{0}d',
+ 'work_duration.x_hours': '{0}h',
+ 'work_duration.x_minutes': '{0}min',
+ 'work_duration.about': '~ {0}',
+ 'metric.level.ERROR': 'Error',
+ 'metric.level.WARN': 'Warning',
+ 'metric.level.OK': 'Ok',
+ 'short_number_suffix.g': 'G',
+ 'short_number_suffix.k': 'k',
+ 'short_number_suffix.m': 'M'
+ });
+});
+
+const HOURS_IN_DAY = 8;
+const ONE_MINUTE = 1;
+const ONE_HOUR = ONE_MINUTE * 60;
+const ONE_DAY = HOURS_IN_DAY * ONE_HOUR;
+
describe('enhanceConditionWithMeasure', () => {
it('should correctly map enhance conditions with measure data', () => {
const measures = [
@@ -71,30 +103,6 @@ describe('isPeriodBestValue', () => {
});
});
-const HOURS_IN_DAY = 8;
-const ONE_MINUTE = 1;
-const ONE_HOUR = ONE_MINUTE * 60;
-const ONE_DAY = HOURS_IN_DAY * ONE_HOUR;
-
-beforeAll(() => {
- resetMessages({
- 'work_duration.x_days': '{0}d',
- 'work_duration.x_hours': '{0}h',
- 'work_duration.x_minutes': '{0}min',
- 'work_duration.about': '~ {0}',
- 'metric.level.ERROR': 'Error',
- 'metric.level.WARN': 'Warning',
- 'metric.level.OK': 'Ok',
- 'short_number_suffix.g': 'G',
- 'short_number_suffix.k': 'k',
- 'short_number_suffix.m': 'M'
- });
-});
-
-afterAll(() => {
- resetMessages({});
-});
-
describe('#formatMeasure()', () => {
it('should format INT', () => {
expect(formatMeasure(0, 'INT')).toBe('0');
diff --git a/server/sonar-web/src/main/js/app/utils/throwGlobalError.ts b/server/sonar-web/src/main/js/helpers/error.ts
index dbb9ee45771..78f2fa12d9a 100644
--- a/server/sonar-web/src/main/js/app/utils/throwGlobalError.ts
+++ b/server/sonar-web/src/main/js/helpers/error.ts
@@ -17,11 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { parseError } from '../../helpers/request';
-import { addGlobalErrorMessage } from '../../store/globalMessages';
-import getStore from './getStore';
+import getStore from '../app/utils/getStore';
+import { addGlobalErrorMessage } from '../store/globalMessages';
+import { parseError } from './request';
-export default function throwGlobalError(param: Response | any): Promise<Response | any> {
+export function throwGlobalError(param: Response | any): Promise<Response | any> {
const store = getStore();
if (param.response instanceof Response) {
diff --git a/server/sonar-web/src/main/js/helpers/l10n.ts b/server/sonar-web/src/main/js/helpers/l10n.ts
index 9b8fafa258e..149955f2844 100644
--- a/server/sonar-web/src/main/js/helpers/l10n.ts
+++ b/server/sonar-web/src/main/js/helpers/l10n.ts
@@ -17,22 +17,13 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { fetchL10nBundle } from '../api/l10n';
-import { L10nBundle, L10nBundleRequestParams } from '../types/l10n';
-import { Dict } from '../types/types';
-import { toNotSoISOString } from './dates';
-import { get as loadFromLocalStorage, save as saveInLocalStorage } from './storage';
-export type Messages = Dict<string>;
+import { getMessages } from './l10nBundle';
-export const DEFAULT_LOCALE = 'en';
-export const DEFAULT_MESSAGES = {
- // eslint-disable-next-line camelcase
- default_error_message: 'The request cannot be processed. Try again later.'
-};
-
-let allMessages: Messages = {};
-let locale: string | undefined;
+export function hasMessage(...keys: string[]): boolean {
+ const messageKey = keys.join('.');
+ return getMessages()[messageKey] != null;
+}
export function translate(...keys: string[]): string {
const messageKey = keys.join('.');
@@ -61,23 +52,6 @@ export function translateWithParameters(
return `${messageKey}.${parameters.join('.')}`;
}
-export function hasMessage(...keys: string[]): boolean {
- const messageKey = keys.join('.');
- return getMessages()[messageKey] != null;
-}
-
-export function getMessages() {
- if (typeof allMessages === 'undefined') {
- logWarning('L10n messages are not initialized. Use default messages.');
- return DEFAULT_MESSAGES;
- }
- return allMessages;
-}
-
-export function resetMessages(newMessages: Messages) {
- allMessages = newMessages;
-}
-
export function getLocalizedMetricName(
metric: { key: string; name?: string },
short = false
@@ -101,14 +75,6 @@ export function getLocalizedMetricDomain(domainName: string) {
return hasMessage(bundleKey) ? translate(bundleKey) : domainName;
}
-export function getCurrentLocale() {
- return locale;
-}
-
-export function resetCurrentLocale(newLocale: string) {
- locale = newLocale;
-}
-
export function getShortMonthName(index: number) {
const months = [
'Jan',
@@ -136,88 +102,3 @@ export function getShortWeekDayName(index: number) {
const weekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
return weekdays[index] ? translate(weekdays[index]) : '';
}
-
-const L10N_BUNDLE_LS_KEY = 'l10n.bundle';
-
-export async function loadL10nBundle() {
- const bundle = await getLatestL10nBundle().catch(() => ({
- locale: DEFAULT_LOCALE,
- messages: {}
- }));
-
- resetCurrentLocale(bundle.locale);
- resetMessages(bundle.messages);
-
- return bundle;
-}
-
-export async function getLatestL10nBundle() {
- const browserLocale = getPreferredLanguage();
- const cachedBundle = loadL10nBundleFromLocalStorage();
-
- const params: L10nBundleRequestParams = {};
-
- if (browserLocale) {
- params.locale = browserLocale;
-
- if (
- cachedBundle.locale &&
- browserLocale.startsWith(cachedBundle.locale) &&
- cachedBundle.timestamp &&
- cachedBundle.messages
- ) {
- params.ts = cachedBundle.timestamp;
- }
- }
-
- const { effectiveLocale, messages } = await fetchL10nBundle(params).catch(response => {
- if (response && response.status === 304) {
- return {
- effectiveLocale: cachedBundle.locale || browserLocale || DEFAULT_LOCALE,
- messages: cachedBundle.messages ?? {}
- };
- }
- throw new Error(`Unexpected status code: ${response.status}`);
- });
-
- const bundle = {
- timestamp: toNotSoISOString(new Date()),
- locale: effectiveLocale,
- messages
- };
-
- saveL10nBundleToLocalStorage(bundle);
-
- return bundle;
-}
-
-export function getCurrentL10nBundle() {
- return loadL10nBundleFromLocalStorage();
-}
-
-function getPreferredLanguage() {
- return window.navigator.languages ? window.navigator.languages[0] : window.navigator.language;
-}
-
-function loadL10nBundleFromLocalStorage() {
- let bundle: L10nBundle;
-
- try {
- bundle = JSON.parse(loadFromLocalStorage(L10N_BUNDLE_LS_KEY) ?? '{}');
- } catch {
- bundle = {};
- }
-
- return bundle;
-}
-
-function saveL10nBundleToLocalStorage(bundle: L10nBundle) {
- saveInLocalStorage(L10N_BUNDLE_LS_KEY, JSON.stringify(bundle));
-}
-
-function logWarning(message: string) {
- if (process.env.NODE_ENV !== 'production') {
- // eslint-disable-next-line no-console
- console.warn(message);
- }
-}
diff --git a/server/sonar-web/src/main/js/helpers/l10nBundle.ts b/server/sonar-web/src/main/js/helpers/l10nBundle.ts
new file mode 100644
index 00000000000..fc1a4414d57
--- /dev/null
+++ b/server/sonar-web/src/main/js/helpers/l10nBundle.ts
@@ -0,0 +1,93 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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 { fetchL10nBundle } from '../api/l10n';
+import { L10nBundle, L10nBundleRequestParams } from '../types/l10nBundle';
+import { toNotSoISOString } from './dates';
+
+const DEFAULT_LOCALE = 'en';
+const DEFAULT_MESSAGES = {
+ // eslint-disable-next-line camelcase
+ default_error_message: 'The request cannot be processed. Try again later.'
+};
+
+export function getMessages() {
+ return getL10nBundleFromCache().messages ?? DEFAULT_MESSAGES;
+}
+
+export function getCurrentLocale() {
+ return getL10nBundleFromCache().locale;
+}
+
+export function getCurrentL10nBundle() {
+ return getL10nBundleFromCache();
+}
+
+export async function loadL10nBundle() {
+ const browserLocale = getPreferredLanguage();
+ const cachedBundle = getL10nBundleFromCache();
+
+ const params: L10nBundleRequestParams = {};
+
+ if (browserLocale) {
+ params.locale = browserLocale;
+
+ if (
+ cachedBundle.locale &&
+ browserLocale.startsWith(cachedBundle.locale) &&
+ cachedBundle.timestamp &&
+ cachedBundle.messages
+ ) {
+ params.ts = cachedBundle.timestamp;
+ }
+ }
+
+ const { effectiveLocale, messages } = await fetchL10nBundle(params).catch(response => {
+ if (response && response.status === 304) {
+ return {
+ effectiveLocale: cachedBundle.locale || browserLocale || DEFAULT_LOCALE,
+ messages: cachedBundle.messages ?? {}
+ };
+ }
+ throw new Error(`Unexpected status code: ${response.status}`);
+ });
+
+ const bundle = {
+ timestamp: toNotSoISOString(new Date()),
+ locale: effectiveLocale,
+ messages
+ };
+
+ persistL10nBundleInCache(bundle);
+
+ return bundle;
+}
+
+function getPreferredLanguage() {
+ return window.navigator.languages ? window.navigator.languages[0] : window.navigator.language;
+}
+
+function getL10nBundleFromCache() {
+ return ((window as unknown) as any).sonarQubeL10nBundle ?? {};
+}
+
+function persistL10nBundleInCache(bundle: L10nBundle) {
+ ((window as unknown) as any).sonarQubeL10nBundle = bundle;
+}
diff --git a/server/sonar-web/src/main/js/helpers/measures.ts b/server/sonar-web/src/main/js/helpers/measures.ts
index cedf304914a..31aca41f983 100644
--- a/server/sonar-web/src/main/js/helpers/measures.ts
+++ b/server/sonar-web/src/main/js/helpers/measures.ts
@@ -23,7 +23,8 @@ import {
QualityGateStatusConditionEnhanced
} from '../types/quality-gates';
import { Dict, Measure, MeasureEnhanced, Metric } from '../types/types';
-import { getCurrentLocale, translate, translateWithParameters } from './l10n';
+import { translate, translateWithParameters } from './l10n';
+import { getCurrentLocale } from './l10nBundle';
import { isDefined } from './types';
export function enhanceMeasuresWithMetrics(
diff --git a/server/sonar-web/src/main/js/helpers/mocks/editions.ts b/server/sonar-web/src/main/js/helpers/mocks/editions.ts
new file mode 100644
index 00000000000..58fb0b759cb
--- /dev/null
+++ b/server/sonar-web/src/main/js/helpers/mocks/editions.ts
@@ -0,0 +1,41 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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 { License } from '../../types/editions';
+
+export function mockLicense(override?: Partial<License>) {
+ return {
+ contactEmail: 'contact@sonarsource.com',
+ edition: 'Developer Edition',
+ expiresAt: '2018-05-18',
+ isExpired: false,
+ isValidEdition: true,
+ isValidServerId: true,
+ isOfficialDistribution: true,
+ isSupported: false,
+ loc: 120085,
+ maxLoc: 500000,
+ plugins: ['Branches', 'PLI language'],
+ remainingLocThreshold: 490000,
+ serverId: 'AU-TpxcA-iU5OvuD2FL0',
+ type: 'production',
+ ...override
+ };
+}
diff --git a/server/sonar-web/src/main/js/types/browser.ts b/server/sonar-web/src/main/js/types/browser.ts
index de6f688b8cc..b2adcb34d6d 100644
--- a/server/sonar-web/src/main/js/types/browser.ts
+++ b/server/sonar-web/src/main/js/types/browser.ts
@@ -27,6 +27,6 @@ export interface EnhancedWindow extends Window {
instance: InstanceType;
official: boolean;
- registerExtension: (key: string, start: ExtensionStartMethod) => void;
+ registerExtension: (key: string, start: ExtensionStartMethod, providesCSSFile?: boolean) => void;
setWebAnalyticsPageChangeHandler: (pageHandler: (pathname: string) => void) => void;
}
diff --git a/server/sonar-web/src/main/js/types/editions.ts b/server/sonar-web/src/main/js/types/editions.ts
index eb86835624c..82098ba4429 100644
--- a/server/sonar-web/src/main/js/types/editions.ts
+++ b/server/sonar-web/src/main/js/types/editions.ts
@@ -32,3 +32,20 @@ export interface Edition {
key: EditionKey;
name: string;
}
+
+export interface License {
+ contactEmail: string;
+ edition: string;
+ expiresAt: string;
+ isExpired: boolean;
+ isOfficialDistribution: boolean;
+ isSupported: boolean;
+ isValidEdition: boolean;
+ isValidServerId: boolean;
+ loc: number;
+ maxLoc: number;
+ plugins: string[];
+ remainingLocThreshold: number;
+ serverId: string;
+ type: string;
+}
diff --git a/server/sonar-web/src/main/js/types/extension.ts b/server/sonar-web/src/main/js/types/extension.ts
index 5ec01bd71f0..73324b6ce66 100644
--- a/server/sonar-web/src/main/js/types/extension.ts
+++ b/server/sonar-web/src/main/js/types/extension.ts
@@ -22,7 +22,7 @@ import { Store as ReduxStore } from 'redux';
import { Location, Router } from '../components/hoc/withRouter';
import { Store } from '../store/rootReducer';
import { AppState } from './appstate';
-import { L10nBundle } from './l10n';
+import { L10nBundle } from './l10nBundle';
import { Dict } from './types';
import { CurrentUser } from './users';
diff --git a/server/sonar-web/src/main/js/types/l10n.ts b/server/sonar-web/src/main/js/types/l10nBundle.ts
index dec56e5d81b..0fcc3cee01e 100644
--- a/server/sonar-web/src/main/js/types/l10n.ts
+++ b/server/sonar-web/src/main/js/types/l10nBundle.ts
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
import { Dict } from './types';
export interface L10nBundleRequestParams {
diff --git a/server/sonar-web/src/main/js/types/settings.ts b/server/sonar-web/src/main/js/types/settings.ts
index bf95ca0336b..a9b9b5f610a 100644
--- a/server/sonar-web/src/main/js/types/settings.ts
+++ b/server/sonar-web/src/main/js/types/settings.ts
@@ -24,7 +24,8 @@ export const enum SettingsKey {
DaysBeforeDeletingInactiveBranchesAndPRs = 'sonar.dbcleaner.daysBeforeDeletingInactiveBranchesAndPRs',
DefaultProjectVisibility = 'projects.default.visibility',
ServerBaseUrl = 'sonar.core.serverBaseURL',
- PluginRiskConsent = 'sonar.plugins.risk.consent'
+ PluginRiskConsent = 'sonar.plugins.risk.consent',
+ LicenceRemainingLocNotificationThreshold = 'sonar.license.notifications.remainingLocThreshold'
}
export enum GlobalSettingKeys {