*/
import { getJSON, post, postJSON, requestTryAndRepeatUntil } from 'sonar-ui-common/helpers/request';
import throwGlobalError from '../app/utils/throwGlobalError';
+import { SystemUpgrade } from '../types/system';
export function setLogLevel(level: string): Promise<void | Response> {
return post('/api/system/change_log_level', { level }).catch(throwGlobalError);
}
export function getSystemUpgrades(): Promise<{
- upgrades: T.SystemUpgrade[];
+ upgrades: SystemUpgrade[];
updateCenterRefresh: string;
}> {
return getJSON('/api/system/upgrades');
import { Link } from 'react-router';
import { Alert } from 'sonar-ui-common/components/ui/Alert';
import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n';
-import { EDITIONS } from '../../apps/marketplace/utils';
import InstanceMessage from '../../components/common/InstanceMessage';
+import { getEdition } from '../../helpers/editions';
import { isSonarCloud } from '../../helpers/system';
+import { EditionKey } from '../../types/editions';
import GlobalFooterBranding from './GlobalFooterBranding';
import GlobalFooterSonarCloud from './GlobalFooterSonarCloud';
interface Props {
hideLoggedInInfo?: boolean;
productionDatabase: boolean;
- sonarqubeEdition?: T.EditionKey;
+ sonarqubeEdition?: EditionKey;
sonarqubeVersion?: string;
}
return <GlobalFooterSonarCloud />;
}
- const currentEdition = EDITIONS.find(edition => edition.key === sonarqubeEdition);
+ const currentEdition = sonarqubeEdition && getEdition(sonarqubeEdition);
return (
<div className="page-footer page-container" id="footer">
*/
import { connect } from 'react-redux';
import { getAppState, Store } from '../../store/rootReducer';
+import { EditionKey } from '../../types/editions';
import GlobalFooter from './GlobalFooter';
interface StateProps {
productionDatabase: boolean;
- sonarqubeEdition?: T.EditionKey;
+ sonarqubeEdition?: EditionKey;
sonarqubeVersion?: string;
}
const mapStateToProps = (state: Store): StateProps => ({
productionDatabase: getAppState(state).productionDatabase,
- sonarqubeEdition: getAppState(state).edition,
+ sonarqubeEdition: getAppState(state).edition as EditionKey, // TODO: Fix once AppState is no longer ambiant.
sonarqubeVersion: getAppState(state).version
});
import { isLoggedIn } from '../../helpers/users';
import { getAppState, getCurrentUser, Store } from '../../store/rootReducer';
import { skipOnboarding } from '../../store/users';
+import { EditionKey } from '../../types/editions';
import { OnboardingContext } from './OnboardingContext';
const OnboardingModal = lazyLoad(() => import('../../apps/tutorials/onboarding/OnboardingModal'));
interface StateProps {
canAdmin?: boolean;
- currentEdition?: T.EditionKey;
+ currentEdition?: EditionKey;
currentUser: T.CurrentUser;
}
const mapStateToProps = (state: Store): StateProps => ({
canAdmin: getAppState(state).canAdmin,
- currentEdition: getAppState(state).edition,
+ currentEdition: getAppState(state).edition as EditionKey, // TODO: Fix once AppState is no longer ambiant.
currentUser: getCurrentUser(state)
});
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { EditionKey } from '../../../apps/marketplace/utils';
import { isSonarCloud } from '../../../helpers/system';
+import { EditionKey } from '../../../types/editions';
import GlobalFooter from '../GlobalFooter';
jest.mock('../../../helpers/system', () => ({ isSonarCloud: jest.fn() }));
import { get, save } from 'sonar-ui-common/helpers/storage';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
import { showLicense } from '../../../api/marketplace';
-import { EditionKey } from '../../../apps/marketplace/utils';
import { mockOrganization, mockRouter } from '../../../helpers/testMocks';
+import { EditionKey } from '../../../types/editions';
import { ModalKey, StartupModal } from '../StartupModal';
jest.mock('../../../api/marketplace', () => ({
branchesEnabled?: boolean;
canAdmin?: boolean;
defaultOrganization: string;
- edition: EditionKey | undefined;
+ edition: 'community' | 'developer' | 'enterprise' | 'datacenter' | undefined;
globalPages?: Extension[];
organizationsEnabled?: boolean;
productionDatabase: boolean;
subProjectName?: string;
}
- export type EditionKey = 'community' | 'developer' | 'enterprise' | 'datacenter';
-
export type ExpandDirection = 'up' | 'down';
export interface Extension {
| 'DB_MIGRATION_NEEDED'
| 'DB_MIGRATION_RUNNING';
- export interface SystemUpgrade {
- version: string;
- description: string;
- releaseDate: string;
- changeLogUrl: string;
- downloadUrl: string;
- }
-
export interface Task {
analysisId?: string;
branch?: string;
} from '../../api/plugins';
import Suggestions from '../../app/components/embed-docs-modal/Suggestions';
import { Location, Router, withRouter } from '../../components/hoc/withRouter';
+import { EditionKey } from '../../types/editions';
import EditionBoxes from './EditionBoxes';
import Footer from './Footer';
import Header from './Header';
import { filterPlugins, parseQuery, Query, serializeQuery } from './utils';
export interface Props {
- currentEdition?: T.EditionKey;
+ currentEdition?: EditionKey;
fetchPendingPlugins: () => void;
pendingPlugins: PluginPendingResult;
location: Location;
import { connect } from 'react-redux';
import AdminContext from '../../app/components/AdminContext';
import { getAppState, getGlobalSettingValue, Store } from '../../store/rootReducer';
+import { EditionKey } from '../../types/editions';
import App from './App';
interface OwnProps {
}
interface StateToProps {
- currentEdition?: T.EditionKey;
+ currentEdition?: EditionKey;
standaloneMode?: boolean;
updateCenterActive: boolean;
}
const mapStateToProps = (state: Store) => {
const updateCenterActive = getGlobalSettingValue(state, 'sonar.updatecenter.activate');
return {
- currentEdition: getAppState(state).edition,
+ currentEdition: getAppState(state).edition as EditionKey, // TODO: Fix once AppState is no longer ambiant.
standaloneMode: getAppState(state).standalone,
updateCenterActive: Boolean(updateCenterActive && updateCenterActive.value === 'true')
};
*/
import * as React from 'react';
import { getMarketplaceNavigation } from '../../api/nav';
+import { getAllEditionsAbove } from '../../helpers/editions';
+import { EditionKey } from '../../types/editions';
import EditionBox from './components/EditionBox';
-import { EDITIONS } from './utils';
export interface Props {
- currentEdition?: T.EditionKey;
+ currentEdition?: EditionKey;
}
interface State {
render() {
const { currentEdition } = this.props;
const { serverId, ncloc } = this.state;
- const currentEditionIdx = EDITIONS.findIndex(edition => edition.key === currentEdition);
- const visibleEditions = EDITIONS.slice(currentEditionIdx + 1);
+ const visibleEditions = getAllEditionsAbove(currentEdition);
if (visibleEditions.length <= 0) {
return null;
*/
import * as React from 'react';
import { translate } from 'sonar-ui-common/helpers/l10n';
+import { EditionKey } from '../../types/editions';
interface Props {
- currentEdition?: T.EditionKey;
+ currentEdition?: EditionKey;
}
export default function Header({ currentEdition }: Props) {
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { EditionKey } from '../../../types/editions';
import EditionBoxes from '../EditionBoxes';
-import { EditionKey } from '../utils';
it('should display the available edition boxes correctly', () => {
expect(getWrapper()).toMatchSnapshot();
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { EditionKey } from '../../../types/editions';
import Header from '../Header';
-import { EditionKey } from '../utils';
it('should render with installed editions', () => {
expect(shallow(<Header currentEdition={EditionKey.community} />)).toMatchSnapshot();
currentEdition="community"
edition={
Object {
- "downloadUrl": "https://binaries.sonarsource.com/CommercialDistribution/editions/developer-edition-7.0.0.717.zip",
+ "downloadProperty": "downloadDeveloperUrl",
"homeUrl": "https://redirect.sonarsource.com/editions/developer.html",
"key": "developer",
"name": "Developer Edition",
currentEdition="community"
edition={
Object {
- "downloadUrl": "https://binaries.sonarsource.com/CommercialDistribution/editions/enterprise-edition-7.0.0.717.zip",
+ "downloadProperty": "downloadEnterpriseUrl",
"homeUrl": "https://redirect.sonarsource.com/editions/enterprise.html",
"key": "enterprise",
"name": "Enterprise Edition",
currentEdition="community"
edition={
Object {
- "downloadUrl": "https://binaries.sonarsource.com/CommercialDistribution/editions/datacenter-edition-7.0.0.717.zip",
+ "downloadProperty": "downloadDatacenterUrl",
"homeUrl": "https://redirect.sonarsource.com/editions/datacenter.html",
"key": "datacenter",
"name": "Data Center Edition",
currentEdition="enterprise"
edition={
Object {
- "downloadUrl": "https://binaries.sonarsource.com/CommercialDistribution/editions/datacenter-edition-7.0.0.717.zip",
+ "downloadProperty": "downloadDatacenterUrl",
"homeUrl": "https://redirect.sonarsource.com/editions/datacenter.html",
"key": "datacenter",
"name": "Data Center Edition",
currentEdition="developer"
edition={
Object {
- "downloadUrl": "https://binaries.sonarsource.com/CommercialDistribution/editions/enterprise-edition-7.0.0.717.zip",
+ "downloadProperty": "downloadEnterpriseUrl",
"homeUrl": "https://redirect.sonarsource.com/editions/enterprise.html",
"key": "enterprise",
"name": "Enterprise Edition",
currentEdition="developer"
edition={
Object {
- "downloadUrl": "https://binaries.sonarsource.com/CommercialDistribution/editions/datacenter-edition-7.0.0.717.zip",
+ "downloadProperty": "downloadDatacenterUrl",
"homeUrl": "https://redirect.sonarsource.com/editions/datacenter.html",
"key": "datacenter",
"name": "Data Center Edition",
import * as React from 'react';
import { lazyLoad } from 'sonar-ui-common/components/lazyLoad';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { Edition, getEditionUrl } from '../utils';
+import { getEditionUrl } from '../../../helpers/editions';
+import { Edition, EditionKey } from '../../../types/editions';
const DocMarkdownBlock = lazyLoad(() => import('../../../components/docs/DocMarkdownBlock'));
interface Props {
- currentEdition?: T.EditionKey;
+ currentEdition?: EditionKey;
edition: Edition;
ncloc?: number;
serverId?: string;
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { EditionKey } from '../../utils';
+import { getEdition } from '../../../../helpers/editions';
+import { EditionKey } from '../../../../types/editions';
import EditionBox from '../EditionBox';
-const DEFAULT_EDITION = {
- key: EditionKey.developer,
- name: 'Developer',
- downloadUrl: 'download_url',
- homeUrl: 'more_url'
-};
-
it('should display the edition', () => {
expect(
shallow(
<EditionBox
currentEdition={EditionKey.community}
- edition={DEFAULT_EDITION}
+ edition={getEdition(EditionKey.developer)}
ncloc={1000}
serverId="serverId"
/>
className="marketplace-edition-action spacer-top"
>
<a
- href="more_url?ncloc=1000&serverId=serverId&sourceEdition=community"
+ href="https://redirect.sonarsource.com/editions/developer.html?ncloc=1000&serverId=serverId&sourceEdition=community"
rel="noopener noreferrer"
target="_blank"
>
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { memoize } from 'lodash';
-import { stringify } from 'querystring';
import { cleanQuery, parseAsString, serializeString } from 'sonar-ui-common/helpers/query';
-import { omitNil } from 'sonar-ui-common/helpers/request';
import { Plugin, PluginAvailable, PluginInstalled, PluginPending } from '../../api/plugins';
-export enum EditionKey {
- community = 'community',
- developer = 'developer',
- enterprise = 'enterprise',
- datacenter = 'datacenter'
-}
-
-export interface Edition {
- downloadUrl?: string;
- homeUrl: string;
- key: EditionKey;
- name: string;
-}
-
export interface Query {
filter: string;
search?: string;
}
-export const EDITIONS: Edition[] = [
- {
- key: EditionKey.community,
- name: 'Community Edition',
- homeUrl: 'https://redirect.sonarsource.com/editions/community.html'
- },
- {
- key: EditionKey.developer,
- name: 'Developer Edition',
- homeUrl: 'https://redirect.sonarsource.com/editions/developer.html',
- downloadUrl:
- 'https://binaries.sonarsource.com/CommercialDistribution/editions/developer-edition-7.0.0.717.zip'
- },
- {
- key: EditionKey.enterprise,
- name: 'Enterprise Edition',
- homeUrl: 'https://redirect.sonarsource.com/editions/enterprise.html',
- downloadUrl:
- 'https://binaries.sonarsource.com/CommercialDistribution/editions/enterprise-edition-7.0.0.717.zip'
- },
- {
- key: EditionKey.datacenter,
- name: 'Data Center Edition',
- homeUrl: 'https://redirect.sonarsource.com/editions/datacenter.html',
- downloadUrl:
- 'https://binaries.sonarsource.com/CommercialDistribution/editions/datacenter-edition-7.0.0.717.zip'
- }
-];
-
-export function getEditionUrl(
- edition: Edition,
- data: { serverId?: string; ncloc?: number; sourceEdition?: T.EditionKey }
-) {
- let url = edition.homeUrl;
- const query = stringify(omitNil(data));
- if (query) {
- url += '?' + query;
- }
- return url;
-}
-
const EXCLUDED_PLUGINS = ['license'];
export function filterPlugins(plugins: Plugin[], search?: string): Plugin[] {
if (!search) {
*/
/* eslint-disable sonarjs/no-duplicate-string */
import { mockClusterSysInfo, mockStandaloneSysInfo } from '../../../helpers/testMocks';
+import { SystemUpgrade } from '../../../types/system';
import * as u from '../utils';
describe('parseQuery', () => {
{ version: '5.10' },
{ version: '5.1' },
{ version: '5.4' }
- ] as T.SystemUpgrade[])
+ ] as SystemUpgrade[])
).toEqual([{ version: '5.10' }, { version: '5.4.2' }, { version: '5.4' }, { version: '5.1' }]);
expect(
u.sortUpgrades([
{ version: '5.1.2' },
{ version: '6.0' },
{ version: '6.9' }
- ] as T.SystemUpgrade[])
+ ] as SystemUpgrade[])
).toEqual([{ version: '6.9' }, { version: '6.0' }, { version: '5.10' }, { version: '5.1.2' }]);
});
});
{ version: '5.4.2' },
{ version: '5.4' },
{ version: '5.1' }
- ] as T.SystemUpgrade[])
+ ] as SystemUpgrade[])
).toEqual([
[{ version: '5.10' }, { version: '5.4.2' }, { version: '5.4' }, { version: '5.1' }]
]);
{ version: '6.0' },
{ version: '5.10' },
{ version: '5.4.2' }
- ] as T.SystemUpgrade[])
+ ] as SystemUpgrade[])
).toEqual([
[{ version: '6.9' }, { version: '6.7' }, { version: '6.0' }],
[{ version: '5.10' }, { version: '5.4.2' }]
parseAsString,
serializeStringArray
} from 'sonar-ui-common/helpers/query';
+import { SystemUpgrade } from '../../types/system';
export interface Query {
expandedCards: string[];
})
);
-export function sortUpgrades(upgrades: T.SystemUpgrade[]): T.SystemUpgrade[] {
+export function sortUpgrades(upgrades: SystemUpgrade[]): SystemUpgrade[] {
return sortBy(upgrades, [
- (upgrade: T.SystemUpgrade) => -Number(upgrade.version.split('.')[0]),
- (upgrade: T.SystemUpgrade) => -Number(upgrade.version.split('.')[1] || 0),
- (upgrade: T.SystemUpgrade) => -Number(upgrade.version.split('.')[2] || 0)
+ (upgrade: SystemUpgrade) => -Number(upgrade.version.split('.')[0]),
+ (upgrade: SystemUpgrade) => -Number(upgrade.version.split('.')[1] || 0),
+ (upgrade: SystemUpgrade) => -Number(upgrade.version.split('.')[2] || 0)
]);
}
-export function groupUpgrades(upgrades: T.SystemUpgrade[]): T.SystemUpgrade[][] {
+export function groupUpgrades(upgrades: SystemUpgrade[]): SystemUpgrade[][] {
const groupedVersions = groupBy(upgrades, upgrade => upgrade.version.split('.')[0]);
const sortedMajor = sortBy(Object.keys(groupedVersions), key => -Number(key));
return sortedMajor.map(key => groupedVersions[key]);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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 { stringify } from 'querystring';
+import { omitNil } from 'sonar-ui-common/helpers/request';
+import { Edition, EditionKey } from '../types/editions';
+import { SystemUpgrade } from '../types/system';
+
+const EDITIONS: { [x in EditionKey]: Edition } = {
+ community: {
+ key: EditionKey.community,
+ name: 'Community Edition',
+ homeUrl: 'https://redirect.sonarsource.com/editions/community.html',
+ downloadProperty: 'downloadUrl'
+ },
+ developer: {
+ key: EditionKey.developer,
+ name: 'Developer Edition',
+ homeUrl: 'https://redirect.sonarsource.com/editions/developer.html',
+ downloadProperty: 'downloadDeveloperUrl'
+ },
+ enterprise: {
+ key: EditionKey.enterprise,
+ name: 'Enterprise Edition',
+ homeUrl: 'https://redirect.sonarsource.com/editions/enterprise.html',
+ downloadProperty: 'downloadEnterpriseUrl'
+ },
+ datacenter: {
+ key: EditionKey.datacenter,
+ name: 'Data Center Edition',
+ homeUrl: 'https://redirect.sonarsource.com/editions/datacenter.html',
+ downloadProperty: 'downloadDatacenterUrl'
+ }
+};
+
+export function getEdition(editionKey: EditionKey) {
+ return EDITIONS[editionKey];
+}
+
+export function getAllEditionsAbove(currentEdition?: EditionKey) {
+ const editions = Object.values(EDITIONS);
+ const currentEditionIdx = editions.findIndex(edition => edition.key === currentEdition);
+ return editions.slice(currentEditionIdx + 1);
+}
+
+export function getEditionUrl(
+ edition: Edition,
+ data: { serverId?: string; ncloc?: number; sourceEdition?: EditionKey }
+) {
+ let url = edition.homeUrl;
+ const query = stringify(omitNil(data));
+ if (query) {
+ url += '?' + query;
+ }
+ return url;
+}
+
+export function getEditionDownloadUrl(edition: Edition, lastUpgrade: SystemUpgrade) {
+ return lastUpgrade[edition.downloadProperty] || lastUpgrade.downloadUrl;
+}
+
+export function getEditionDownloadFilename(url: string) {
+ return url.replace(/^.+\/(sonarqube-[\w\-.]+\.zip)$/, '$1');
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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 { SystemUpgradeDownloadUrls } from './system';
+
+export enum EditionKey {
+ community = 'community',
+ developer = 'developer',
+ enterprise = 'enterprise',
+ datacenter = 'datacenter'
+}
+
+export interface Edition {
+ downloadProperty: keyof SystemUpgradeDownloadUrls;
+ homeUrl: string;
+ key: EditionKey;
+ name: string;
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.
+ */
+export interface SystemUpgradeDownloadUrls {
+ downloadDatacenterUrl?: string;
+ downloadDeveloperUrl?: string;
+ downloadEnterpriseUrl?: string;
+ downloadUrl: string;
+}
+
+export interface SystemUpgrade extends SystemUpgradeDownloadUrls {
+ changeLogUrl?: string;
+ description?: string;
+ releaseDate?: string;
+ version: string;
+}