export function getSystemUpgrades(): Promise<{
upgrades: SystemUpgrade[];
+ latestLTS: string;
updateCenterRefresh: string;
}> {
return getJSON('/api/system/upgrades');
import IndexationNotification from './indexation/IndexationNotification';
import GlobalNav from './nav/global/GlobalNav';
import StartupModal from './StartupModal';
+import UpdateNotification from './update-notification/UpdateNotification';
export interface Props {
children: React.ReactNode;
<GlobalNav location={props.location} />
<GlobalMessagesContainer />
<IndexationNotification />
+ <UpdateNotification />
{props.children}
</IndexationContextProvider>
</Workspace>
/>
<Connect(GlobalMessages) />
<Connect(withCurrentUser(withIndexationContext(IndexationNotification))) />
+ <Connect(withCurrentUser(Connect(withAppState(UpdateNotification)))) />
<ChildComponent />
</Connect(withAppState(IndexationContextProvider))>
</Workspace>
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.
+ */
+.promote-update-notification.dismissable-alert-wrapper {
+ height: 42px;
+}
+
+.promote-update-notification .dismissable-alert-banner {
+ margin-bottom: 0 !important;
+ position: fixed;
+ width: 100%;
+ z-index: var(--globalBannerZIndex);
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 { groupBy, isEmpty, mapValues } from 'lodash';
+import * as React from 'react';
+import { getSystemUpgrades } from '../../../api/system';
+import { withAppState } from '../../../components/hoc/withAppState';
+import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
+import { AlertVariant } from '../../../components/ui/Alert';
+import DismissableAlert from '../../../components/ui/DismissableAlert';
+import SystemUpgradeButton from '../../../components/upgrade/SystemUpgradeButton';
+import { sortUpgrades } from '../../../components/upgrade/utils';
+import { translate } from '../../../helpers/l10n';
+import { hasGlobalPermission, isLoggedIn } from '../../../helpers/users';
+import { Permissions } from '../../../types/permissions';
+import { SystemUpgrade } from '../../../types/system';
+import './UpdateNotification.css';
+
+const MONTH_BEFOR_PREVIOUS_LTS_NOTIFICATION = 6;
+
+type GroupedSystemUpdate = {
+ [x: string]: T.Dict<SystemUpgrade[]>;
+};
+
+enum UseCase {
+ NewMinorVersion = 'new_minor_version',
+ NewPatch = 'new_patch',
+ PreLTS = 'pre_lts',
+ PreviousLTS = 'previous_lts'
+}
+
+const MAP_VARIANT: T.Dict<AlertVariant> = {
+ [UseCase.NewMinorVersion]: 'info',
+ [UseCase.NewPatch]: 'warning',
+ [UseCase.PreLTS]: 'warning',
+ [UseCase.PreviousLTS]: 'error'
+};
+
+interface Props {
+ appState: Pick<T.AppState, 'version'>;
+ currentUser: T.CurrentUser;
+}
+
+interface State {
+ dismissKey: string;
+ useCase: UseCase;
+ systemUpgrades: SystemUpgrade[];
+ canSeeNotification: boolean;
+}
+
+export class UpdateNotification extends React.PureComponent<Props, State> {
+ mounted = false;
+ versionParser = /^(\d+)\.(\d+)(\.(\d+))?/;
+
+ constructor(props: Props) {
+ super(props);
+ this.state = {
+ dismissKey: '',
+ systemUpgrades: [],
+ canSeeNotification: false,
+ useCase: UseCase.NewMinorVersion
+ };
+ this.fetchSystemUpgradeInformation();
+ }
+
+ componentDidMount() {
+ this.mounted = true;
+ }
+
+ componentDidUpdate(prevProps: Props) {
+ if (
+ prevProps.currentUser !== this.props.currentUser ||
+ this.props.appState.version !== prevProps.appState.version
+ ) {
+ this.fetchSystemUpgradeInformation();
+ }
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ isPreLTSUpdate(parsedVersion: number[], latestLTS: string) {
+ const [currentMajor, currentMinor] = parsedVersion;
+ const [ltsMajor, ltsMinor] = latestLTS.split('.').map(Number);
+ return currentMajor < ltsMajor || (currentMajor === ltsMajor && currentMinor < ltsMinor);
+ }
+
+ isPreviousLTSUpdate(
+ parsedVersion: number[],
+ latestLTS: string,
+ systemUpgrades: GroupedSystemUpdate
+ ) {
+ const [ltsMajor, ltsMinor] = latestLTS.split('.').map(Number);
+ let ltsOlderThan6Month = false;
+ const beforeLts = this.isPreLTSUpdate(parsedVersion, latestLTS);
+ if (beforeLts) {
+ const allLTS = sortUpgrades(systemUpgrades[ltsMajor][ltsMinor]);
+ const ltsReleaseDate = new Date(allLTS[allLTS.length - 1]?.releaseDate || '');
+ if (isNaN(ltsReleaseDate.getTime())) {
+ // We can not parse the LTS date.
+ // It is unlikly that this could happen but consider LTS to be old.
+ return true;
+ }
+ ltsOlderThan6Month =
+ ltsReleaseDate.setMonth(ltsReleaseDate.getMonth() + MONTH_BEFOR_PREVIOUS_LTS_NOTIFICATION) -
+ Date.now() <
+ 0;
+ }
+ return ltsOlderThan6Month && beforeLts;
+ }
+
+ isMinorUpdate(parsedVersion: number[], systemUpgrades: GroupedSystemUpdate) {
+ const [currentMajor, currentMinor] = parsedVersion;
+ const allMinor = systemUpgrades[currentMajor];
+ return Object.keys(allMinor)
+ .map(Number)
+ .some(minor => minor > currentMinor);
+ }
+
+ isPatchUpdate(parsedVersion: number[], systemUpgrades: GroupedSystemUpdate) {
+ const [currentMajor, currentMinor, currentPatch] = parsedVersion;
+ const allMinor = systemUpgrades[currentMajor];
+ const allPatch = sortUpgrades(allMinor[currentMinor] || []);
+
+ if (!isEmpty(allPatch)) {
+ const [, , latestPatch] = allPatch[0].version.split('.').map(Number);
+ const effectiveCurrentPatch = isNaN(currentPatch) ? 0 : currentPatch;
+ const effectiveLatestPatch = isNaN(latestPatch) ? 0 : latestPatch;
+ return effectiveCurrentPatch < effectiveLatestPatch;
+ }
+ return false;
+ }
+
+ async fetchSystemUpgradeInformation() {
+ if (
+ !isLoggedIn(this.props.currentUser) ||
+ !hasGlobalPermission(this.props.currentUser, Permissions.Admin)
+ ) {
+ this.noPromptToShow();
+ return;
+ }
+
+ const regExpParsedVersion = this.versionParser.exec(this.props.appState.version);
+ if (regExpParsedVersion === null) {
+ this.noPromptToShow();
+ return;
+ }
+ regExpParsedVersion.shift();
+ const parsedVersion = regExpParsedVersion.map(Number).map(n => (isNaN(n) ? 0 : n));
+
+ const { upgrades, latestLTS } = await getSystemUpgrades();
+
+ if (isEmpty(upgrades)) {
+ // No new upgrades
+ this.noPromptToShow();
+ return;
+ }
+ const systemUpgrades = mapValues(
+ groupBy(upgrades, upgrade => {
+ const [major] = upgrade.version.split('.');
+ return major;
+ }),
+ upgrades =>
+ groupBy(upgrades, upgrade => {
+ const [, minor] = upgrade.version.split('.');
+ return minor;
+ })
+ );
+
+ let useCase = UseCase.NewMinorVersion;
+
+ if (this.isPreviousLTSUpdate(parsedVersion, latestLTS, systemUpgrades)) {
+ useCase = UseCase.PreviousLTS;
+ } else if (this.isPreLTSUpdate(parsedVersion, latestLTS)) {
+ useCase = UseCase.PreLTS;
+ } else if (this.isPatchUpdate(parsedVersion, systemUpgrades)) {
+ useCase = UseCase.NewPatch;
+ } else if (this.isMinorUpdate(parsedVersion, systemUpgrades)) {
+ useCase = UseCase.NewMinorVersion;
+ }
+
+ const latest = [...upgrades].sort(
+ (upgrade1, upgrade2) =>
+ new Date(upgrade2.releaseDate || '').getTime() -
+ new Date(upgrade1.releaseDate || '').getTime()
+ )[0];
+
+ const dismissKey = useCase + latest.version;
+
+ if (this.mounted) {
+ this.setState({
+ useCase,
+ dismissKey,
+ systemUpgrades: upgrades,
+ canSeeNotification: true
+ });
+ }
+ }
+
+ noPromptToShow() {
+ if (this.mounted) {
+ this.setState({ canSeeNotification: false });
+ }
+ }
+
+ render() {
+ const { systemUpgrades, canSeeNotification, useCase, dismissKey } = this.state;
+ if (!canSeeNotification) {
+ return null;
+ }
+ return (
+ <DismissableAlert
+ alertKey={dismissKey}
+ variant={MAP_VARIANT[useCase]}
+ className="promote-update-notification">
+ {translate('admin_notification.update', useCase)}
+ <SystemUpgradeButton systemUpgrades={systemUpgrades} />
+ </DismissableAlert>
+ );
+ }
+}
+
+export default withCurrentUser(withAppState(UpdateNotification));
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
+import * as React from 'react';
+import { getSystemUpgrades } from '../../../../api/system';
+import DismissableAlert from '../../../../components/ui/DismissableAlert';
+import { mockUpgrades } from '../../../../helpers/mocks/system-upgrades';
+import { mockAppState, mockCurrentUser, mockLoggedInUser } from '../../../../helpers/testMocks';
+import { waitAndUpdate } from '../../../../helpers/testUtils';
+import { Permissions } from '../../../../types/permissions';
+import { UpdateNotification } from '../UpdateNotification';
+
+jest.mock('../../../../api/system', () => {
+ const { mockUpgrades } = jest.requireActual('../../../../helpers/mocks/system-upgrades');
+ return {
+ getSystemUpgrades: jest.fn().mockResolvedValue({ upgrades: [mockUpgrades()], latestLTS: '8.9' })
+ };
+});
+
+function formatDate(date: Date): string {
+ return `${date.getFullYear()}-${date.getMonth()}-${date.getDay()}`;
+}
+
+it('should not show prompt when not admin', async () => {
+ //As anonymous
+ const wrapper = shallowRender();
+ await waitAndUpdate(wrapper);
+ expect(wrapper.type()).toBeNull();
+
+ // As non admin user
+ wrapper.setProps({ currentUser: mockLoggedInUser() });
+ await waitAndUpdate(wrapper);
+ expect(wrapper.type()).toBeNull();
+});
+
+it('should not show prompt when no current version', async () => {
+ const wrapper = shallowRender({ appState: mockAppState({ version: 'NOVERSION' }) });
+ await waitAndUpdate(wrapper);
+ expect(wrapper.type()).toBeNull();
+});
+
+it('should not show prompt when no upgrade', async () => {
+ (getSystemUpgrades as jest.Mock).mockResolvedValueOnce({ upgrades: [], latestLTS: '8.9' });
+ const wrapper = shallowRender({
+ appState: mockAppState({ version: '9.1' }),
+ currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } })
+ });
+ await waitAndUpdate(wrapper);
+ expect(wrapper.type()).toBeNull();
+});
+
+it('should show prompt when no lts date', async () => {
+ (getSystemUpgrades as jest.Mock).mockResolvedValueOnce({
+ upgrades: [mockUpgrades({ version: '8.9', releaseDate: 'INVALID' })],
+ latestLTS: '8.9'
+ });
+ const wrapper = shallowRender({
+ appState: mockAppState({ version: '8.1' }),
+ currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } })
+ });
+ await waitAndUpdate(wrapper);
+ expect(wrapper.find(DismissableAlert).props().alertKey).toBe('previous_lts8.9');
+ expect(wrapper.contains('admin_notification.update.previous_lts')).toBe(true);
+});
+
+it('should show prompt when minor upgrade', async () => {
+ (getSystemUpgrades as jest.Mock).mockResolvedValueOnce({
+ upgrades: [mockUpgrades({ version: '9.2' }), mockUpgrades({ version: '9.1' })],
+ latestLTS: '8.9'
+ });
+ const wrapper = shallowRender({
+ appState: mockAppState({ version: '9.1' }),
+ currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } })
+ });
+ await waitAndUpdate(wrapper);
+ expect(wrapper.find(DismissableAlert).props().alertKey).toBe('new_minor_version9.2');
+ expect(wrapper.contains('admin_notification.update.new_minor_version')).toBe(true);
+});
+
+it('should show prompt when patch upgrade', async () => {
+ (getSystemUpgrades as jest.Mock).mockResolvedValueOnce({
+ upgrades: [mockUpgrades({ version: '9.2' }), mockUpgrades({ version: '9.1.1' })],
+ latestLTS: '8.9'
+ });
+ const wrapper = shallowRender({
+ appState: mockAppState({ version: '9.1' }),
+ currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } })
+ });
+ await waitAndUpdate(wrapper);
+ expect(wrapper.find(DismissableAlert).props().alertKey).toBe('new_patch9.2');
+ expect(wrapper.contains('admin_notification.update.new_patch')).toBe(true);
+});
+
+it('should show prompt when lts upgrade', async () => {
+ (getSystemUpgrades as jest.Mock).mockResolvedValueOnce({
+ upgrades: [
+ mockUpgrades({ version: '8.9', releaseDate: formatDate(new Date(Date.now())) }),
+ mockUpgrades({ version: '9.2' }),
+ mockUpgrades({ version: '9.1.1' })
+ ],
+ latestLTS: '8.9'
+ });
+ const wrapper = shallowRender({
+ appState: mockAppState({ version: '8.8' }),
+ currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } })
+ });
+ await waitAndUpdate(wrapper);
+ expect(wrapper.find(DismissableAlert).props().alertKey).toBe('pre_lts8.9');
+ expect(wrapper.contains('admin_notification.update.pre_lts')).toBe(true);
+});
+
+it('should show prompt when lts upgrade is more than 6 month', async () => {
+ const ltsDate = new Date(Date.now());
+ ltsDate.setMonth(ltsDate.getMonth() - 7);
+ (getSystemUpgrades as jest.Mock).mockResolvedValueOnce({
+ upgrades: [
+ mockUpgrades({ version: '8.9', releaseDate: formatDate(ltsDate) }),
+ mockUpgrades({ version: '9.2' }),
+ mockUpgrades({ version: '9.1.1' })
+ ],
+ latestLTS: '8.9'
+ });
+ const wrapper = shallowRender({
+ appState: mockAppState({ version: '8.8' }),
+ currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } })
+ });
+ await waitAndUpdate(wrapper);
+ expect(wrapper.find(DismissableAlert).props().alertKey).toBe('previous_lts8.9');
+ expect(wrapper.contains('admin_notification.update.previous_lts')).toBe(true);
+});
+
+function shallowRender(props: Partial<UpdateNotification['props']> = {}) {
+ return shallow(
+ <UpdateNotification appState={mockAppState()} currentUser={mockCurrentUser()} {...props} />
+ );
+}
*/
import { mockClusterSysInfo, mockStandaloneSysInfo } from '../../../helpers/testMocks';
-import { SystemUpgrade } from '../../../types/system';
import * as u from '../utils';
describe('parseQuery', () => {
});
});
-describe('sortUpgrades', () => {
- it('should sort correctly versions', () => {
- expect(
- u.sortUpgrades([
- { version: '5.4.2' },
- { version: '5.10' },
- { version: '5.1' },
- { version: '5.4' }
- ] as SystemUpgrade[])
- ).toEqual([{ version: '5.10' }, { version: '5.4.2' }, { version: '5.4' }, { version: '5.1' }]);
- expect(
- u.sortUpgrades([
- { version: '5.10' },
- { version: '5.1.2' },
- { version: '6.0' },
- { version: '6.9' }
- ] as SystemUpgrade[])
- ).toEqual([{ version: '6.9' }, { version: '6.0' }, { version: '5.10' }, { version: '5.1.2' }]);
- });
-});
-
-describe('groupUpgrades', () => {
- it('should group correctly', () => {
- expect(
- u.groupUpgrades([
- { version: '5.10' },
- { version: '5.4.2' },
- { version: '5.4' },
- { version: '5.1' }
- ] as SystemUpgrade[])
- ).toEqual([
- [{ version: '5.10' }, { version: '5.4.2' }, { version: '5.4' }, { version: '5.1' }]
- ]);
- expect(
- u.groupUpgrades([
- { version: '6.9' },
- { version: '6.7' },
- { version: '6.0' },
- { version: '5.10' },
- { version: '5.4.2' }
- ] as SystemUpgrade[])
- ).toEqual([
- [{ version: '6.9' }, { version: '6.7' }, { version: '6.0' }],
- [{ version: '5.10' }, { version: '5.4.2' }]
- ]);
- });
-});
-
describe('isCluster', () => {
it('should return the correct information', () => {
expect(u.isCluster(mockClusterSysInfo())).toBe(true);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import { ResetButtonLink } from '../../../../components/controls/buttons';
-import Modal from '../../../../components/controls/Modal';
-import { withAppState } from '../../../../components/hoc/withAppState';
-import { translate } from '../../../../helpers/l10n';
-import { EditionKey } from '../../../../types/editions';
-import { SystemUpgrade } from '../../../../types/system';
-import SystemUpgradeItem from './SystemUpgradeItem';
-
-interface Props {
- appState: Pick<T.AppState, 'edition'>;
- onClose: () => void;
- systemUpgrades: SystemUpgrade[][];
-}
-
-interface State {
- upgrading: boolean;
-}
-
-export class SystemUpgradeForm extends React.PureComponent<Props, State> {
- state: State = { upgrading: false };
-
- render() {
- const { upgrading } = this.state;
- const { appState, systemUpgrades } = this.props;
- const header = translate('system.system_upgrade');
- return (
- <Modal contentLabel={header} onRequestClose={this.props.onClose}>
- <div className="modal-head">
- <h2>{header}</h2>
- </div>
- <div className="modal-body">
- {systemUpgrades.map((upgrades, idx) => (
- <SystemUpgradeItem
- edition={
- appState.edition as EditionKey /* TODO: Fix once AppState is no longer ambiant. */
- }
- key={upgrades[upgrades.length - 1].version}
- systemUpgrades={upgrades}
- isLatestVersion={idx === 0}
- />
- ))}
- </div>
- <div className="modal-foot">
- {upgrading && <i className="spinner spacer-right" />}
- <a
- className="pull-left"
- href="https://www.sonarqube.org/downloads/?referrer=sonarqube"
- rel="noopener noreferrer"
- target="_blank">
- {translate('system.see_sonarqube_downloads')}
- </a>
- <ResetButtonLink onClick={this.props.onClose}>{translate('cancel')}</ResetButtonLink>
- </div>
- </Modal>
- );
- }
-}
-
-export default withAppState(SystemUpgradeForm);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import { ButtonLink } from '../../../../components/controls/buttons';
-import DropdownIcon from '../../../../components/icons/DropdownIcon';
-import DateFormatter from '../../../../components/intl/DateFormatter';
-import { translate } from '../../../../helpers/l10n';
-import { SystemUpgrade } from '../../../../types/system';
-
-interface Props {
- className?: string;
- upgrades: SystemUpgrade[];
-}
-
-interface State {
- showMore: boolean;
-}
-
-export default class SystemUpgradeIntermediate extends React.PureComponent<Props, State> {
- state: State = { showMore: false };
-
- toggleIntermediatVersions = () => {
- this.setState(state => ({ showMore: !state.showMore }));
- };
-
- render() {
- const { showMore } = this.state;
- const { upgrades } = this.props;
- if (upgrades.length <= 0) {
- return null;
- }
-
- return (
- <div className={this.props.className}>
- <ButtonLink className="little-spacer-bottom" onClick={this.toggleIntermediatVersions}>
- {showMore
- ? translate('system.hide_intermediate_versions')
- : translate('system.show_intermediate_versions')}
- <DropdownIcon className="little-spacer-left" turned={showMore} />
- </ButtonLink>
- {showMore &&
- upgrades.map(upgrade => (
- <div className="note system-upgrade-intermediate" key={upgrade.version}>
- {upgrade.releaseDate && (
- <DateFormatter date={upgrade.releaseDate} long={true}>
- {formattedDate => (
- <p>
- <b className="little-spacer-right">SonarQube {upgrade.version}</b>
- {formattedDate}
- {upgrade.changeLogUrl && (
- <a
- className="spacer-left"
- href={upgrade.changeLogUrl}
- rel="noopener noreferrer"
- target="_blank">
- {translate('system.release_notes')}
- </a>
- )}
- </p>
- )}
- </DateFormatter>
- )}
- {upgrade.description && <p className="little-spacer-top">{upgrade.description}</p>}
- </div>
- ))}
- </div>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import { FormattedMessage } from 'react-intl';
-import DateFormatter from '../../../../components/intl/DateFormatter';
-import {
- getEdition,
- getEditionDownloadFilename,
- getEditionDownloadUrl
-} from '../../../../helpers/editions';
-import { translate, translateWithParameters } from '../../../../helpers/l10n';
-import { EditionKey } from '../../../../types/editions';
-import { SystemUpgrade } from '../../../../types/system';
-import SystemUpgradeIntermediate from './SystemUpgradeIntermediate';
-
-export interface SystemUpgradeItemProps {
- edition: EditionKey | undefined;
- isLatestVersion: boolean;
- systemUpgrades: SystemUpgrade[];
-}
-
-export default function SystemUpgradeItem(props: SystemUpgradeItemProps) {
- const { edition, isLatestVersion, systemUpgrades } = props;
- const lastUpgrade = systemUpgrades[0];
- const downloadUrl = getEditionDownloadUrl(
- getEdition(edition || EditionKey.community),
- lastUpgrade
- );
-
- return (
- <div className="system-upgrade-version">
- <h3 className="h1 spacer-bottom">
- <strong>
- {isLatestVersion ? translate('system.latest_version') : translate('system.lts_version')}
- </strong>
- {isLatestVersion && (
- <a
- className="spacer-left medium"
- href="https://www.sonarqube.org/whats-new/?referrer=sonarqube"
- rel="noopener noreferrer"
- target="_blank">
- {translate('system.see_whats_new')}
- </a>
- )}
- </h3>
- <p>
- <FormattedMessage
- defaultMessage={translate('system.version_is_availble')}
- id="system.version_is_availble"
- values={{ version: <b>SonarQube {lastUpgrade.version}</b> }}
- />
- </p>
- <p className="spacer-top">{lastUpgrade.description}</p>
- <div className="big-spacer-top">
- {lastUpgrade.releaseDate && (
- <DateFormatter date={lastUpgrade.releaseDate} long={true}>
- {formattedDate => (
- <span>{translateWithParameters('system.released_x', formattedDate)}</span>
- )}
- </DateFormatter>
- )}
- {lastUpgrade.changeLogUrl && (
- <a
- className="spacer-left"
- href={lastUpgrade.changeLogUrl}
- rel="noopener noreferrer"
- target="_blank">
- {translate('system.release_notes')}
- </a>
- )}
- </div>
- <SystemUpgradeIntermediate className="spacer-top" upgrades={systemUpgrades.slice(1)} />
- <div className="big-spacer-top">
- <a
- className="button"
- download={getEditionDownloadFilename(downloadUrl)}
- href={downloadUrl}
- rel="noopener noreferrer"
- target="_blank">
- {translateWithParameters('system.download_x', lastUpgrade.version)}
- </a>
- <a
- className="spacer-left"
- href="https://redirect.sonarsource.com/doc/upgrading.html"
- rel="noopener noreferrer"
- target="_blank">
- {translate('system.how_to_upgrade')}
- </a>
- </div>
- </div>
- );
-}
*/
import * as React from 'react';
import { getSystemUpgrades } from '../../../../api/system';
-import { Button } from '../../../../components/controls/buttons';
import { Alert } from '../../../../components/ui/Alert';
+import SystemUpgradeButton from '../../../../components/upgrade/SystemUpgradeButton';
import { translate } from '../../../../helpers/l10n';
import { SystemUpgrade } from '../../../../types/system';
-import { groupUpgrades, sortUpgrades } from '../../utils';
-import SystemUpgradeForm from './SystemUpgradeForm';
interface State {
- systemUpgrades: SystemUpgrade[][];
- openSystemUpgradeForm: boolean;
+ systemUpgrades: SystemUpgrade[];
}
export default class SystemUpgradeNotif extends React.PureComponent<{}, State> {
mounted = false;
- state: State = { openSystemUpgradeForm: false, systemUpgrades: [] };
+ state: State = { systemUpgrades: [] };
componentDidMount() {
this.mounted = true;
getSystemUpgrades().then(
({ upgrades }) => {
if (this.mounted) {
- this.setState({ systemUpgrades: groupUpgrades(sortUpgrades(upgrades)) });
+ this.setState({ systemUpgrades: upgrades });
}
},
() => {}
);
- handleOpenSystemUpgradeForm = () => {
- this.setState({ openSystemUpgradeForm: true });
- };
-
- handleCloseSystemUpgradeForm = () => {
- this.setState({ openSystemUpgradeForm: false });
- };
-
render() {
const { systemUpgrades } = this.state;
<div className="page-notifs">
<Alert variant="info">
{translate('system.new_version_available')}
- <Button className="spacer-left" onClick={this.handleOpenSystemUpgradeForm}>
- {translate('learn_more')}
- </Button>
+ <SystemUpgradeButton systemUpgrades={systemUpgrades} />
</Alert>
- {this.state.openSystemUpgradeForm && (
- <SystemUpgradeForm
- onClose={this.handleCloseSystemUpgradeForm}
- systemUpgrades={systemUpgrades}
- />
- )}
</div>
);
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { EditionKey } from '../../../../../types/editions';
-import { SystemUpgradeForm } from '../SystemUpgradeForm';
-
-const UPGRADES = [
- [
- {
- version: '6.4',
- description: 'Version 6.4 description',
- releaseDate: '2017-06-02',
- changeLogUrl: 'changelogurl',
- downloadUrl: 'downloadurl',
- plugins: {}
- },
- {
- version: '6.3',
- description: 'Version 6.3 description',
- releaseDate: '2017-05-02',
- changeLogUrl: 'changelogurl',
- downloadUrl: 'downloadurl',
- plugins: {}
- }
- ],
- [
- {
- version: '5.6.7',
- description: 'Version 5.6.7 description',
- releaseDate: '2017-03-01',
- changeLogUrl: 'changelogurl',
- downloadUrl: 'downloadurl',
- plugins: {}
- },
- {
- version: '5.6.6',
- description: 'Version 5.6.6 description',
- releaseDate: '2017-04-02',
- changeLogUrl: 'changelogurl',
- downloadUrl: 'downloadurl',
- plugins: {}
- },
- {
- version: '5.6.5',
- description: 'Version 5.6.5 description',
- releaseDate: '2017-03-01',
- changeLogUrl: 'changelogurl',
- downloadUrl: 'downloadurl',
- plugins: {}
- }
- ]
-];
-
-it('should display correctly', () => {
- expect(
- shallow(
- <SystemUpgradeForm
- appState={{ edition: EditionKey.community }}
- onClose={jest.fn()}
- systemUpgrades={UPGRADES}
- />
- )
- ).toMatchSnapshot();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { click } from '../../../../../helpers/testUtils';
-import SystemUpgradeIntermediate from '../SystemUpgradeIntermediate';
-
-const UPGRADES = [
- {
- version: '5.6.6',
- description: 'Version 5.6.6 description',
- releaseDate: '2017-04-02',
- changeLogUrl: 'changelogurl',
- downloadUrl: 'downloadurl',
- plugins: {}
- },
- {
- version: '5.6.5',
- description: 'Version 5.6.5 description',
- releaseDate: '2017-03-01',
- changeLogUrl: 'changelogurl',
- downloadUrl: 'downloadurl',
- plugins: {}
- }
-];
-
-it('should display correctly', () => {
- const wrapper = shallow(<SystemUpgradeIntermediate upgrades={UPGRADES} />);
- expect(wrapper).toMatchSnapshot();
- wrapper.setState({ showMore: true });
- expect(wrapper).toMatchSnapshot();
-});
-
-it('should allow to show and hide intermediates', () => {
- const wrapper = shallow(<SystemUpgradeIntermediate upgrades={UPGRADES} />);
- expect(wrapper.find('.system-upgrade-intermediate').exists()).toBe(false);
- click(wrapper.find('ButtonLink'));
- expect(wrapper.find('.system-upgrade-intermediate').exists()).toBe(true);
- click(wrapper.find('ButtonLink'));
- expect(wrapper.find('.system-upgrade-intermediate').exists()).toBe(false);
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { EditionKey } from '../../../../../types/editions';
-import SystemUpgradeItem, { SystemUpgradeItemProps } from '../SystemUpgradeItem';
-
-it('should display correctly', () => {
- expect(shallowRender()).toMatchSnapshot();
- expect(shallowRender({ isLatestVersion: false })).toMatchSnapshot();
- expect(shallowRender({ edition: EditionKey.developer })).toMatchSnapshot();
- expect(shallowRender({ edition: EditionKey.enterprise })).toMatchSnapshot();
- expect(shallowRender({ edition: EditionKey.datacenter })).toMatchSnapshot();
- // Fallback to Community.
- expect(
- shallowRender({
- systemUpgrades: [
- {
- version: '5.6.7',
- description: 'Version 5.6.7 description',
- releaseDate: '2017-03-01',
- changeLogUrl: 'http://changelog.url/',
- downloadUrl: 'http://download.url/community'
- }
- ]
- })
- ).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<SystemUpgradeItemProps> = {}) {
- return shallow<SystemUpgradeItemProps>(
- <SystemUpgradeItem
- edition={EditionKey.community}
- systemUpgrades={[
- {
- version: '5.6.7',
- description: 'Version 5.6.7 description',
- releaseDate: '2017-03-01',
- changeLogUrl: 'http://changelog.url/',
- downloadUrl: 'http://download.url/community',
- downloadDeveloperUrl: 'http://download.url/developer',
- downloadEnterpriseUrl: 'http://download.url/enterprise',
- downloadDatacenterUrl: 'http://download.url/datacenter'
- },
- {
- version: '5.6.6',
- description: 'Version 5.6.6 description',
- releaseDate: '2017-04-02',
- changeLogUrl: 'http://changelog.url/',
- downloadUrl: 'http://download.url/community',
- downloadDeveloperUrl: 'http://download.url/developer'
- },
- {
- version: '5.6.5',
- description: 'Version 5.6.5 description',
- releaseDate: '2017-03-01',
- changeLogUrl: 'http://changelog.url/',
- downloadUrl: 'http://download.url/community',
- downloadDeveloperUrl: 'http://download.url/developer'
- }
- ]}
- isLatestVersion={true}
- {...props}
- />
- );
-}
import { shallow } from 'enzyme';
import * as React from 'react';
import { getSystemUpgrades } from '../../../../../api/system';
-import { click, waitAndUpdate } from '../../../../../helpers/testUtils';
+import { waitAndUpdate } from '../../../../../helpers/testUtils';
import SystemUpgradeNotif from '../SystemUpgradeNotif';
jest.mock('../../../../../api/system', () => ({
expect(getSystemUpgrades).toHaveBeenCalled();
expect(wrapper).toMatchSnapshot();
-
- click(wrapper.find('Button'));
- expect(wrapper).toMatchSnapshot();
});
it('should display nothing', async () => {
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should display correctly 1`] = `
-<Modal
- contentLabel="system.system_upgrade"
- onRequestClose={[MockFunction]}
->
- <div
- className="modal-head"
- >
- <h2>
- system.system_upgrade
- </h2>
- </div>
- <div
- className="modal-body"
- >
- <SystemUpgradeItem
- edition="community"
- isLatestVersion={true}
- key="6.3"
- systemUpgrades={
- Array [
- Object {
- "changeLogUrl": "changelogurl",
- "description": "Version 6.4 description",
- "downloadUrl": "downloadurl",
- "plugins": Object {},
- "releaseDate": "2017-06-02",
- "version": "6.4",
- },
- Object {
- "changeLogUrl": "changelogurl",
- "description": "Version 6.3 description",
- "downloadUrl": "downloadurl",
- "plugins": Object {},
- "releaseDate": "2017-05-02",
- "version": "6.3",
- },
- ]
- }
- />
- <SystemUpgradeItem
- edition="community"
- isLatestVersion={false}
- key="5.6.5"
- systemUpgrades={
- Array [
- Object {
- "changeLogUrl": "changelogurl",
- "description": "Version 5.6.7 description",
- "downloadUrl": "downloadurl",
- "plugins": Object {},
- "releaseDate": "2017-03-01",
- "version": "5.6.7",
- },
- Object {
- "changeLogUrl": "changelogurl",
- "description": "Version 5.6.6 description",
- "downloadUrl": "downloadurl",
- "plugins": Object {},
- "releaseDate": "2017-04-02",
- "version": "5.6.6",
- },
- Object {
- "changeLogUrl": "changelogurl",
- "description": "Version 5.6.5 description",
- "downloadUrl": "downloadurl",
- "plugins": Object {},
- "releaseDate": "2017-03-01",
- "version": "5.6.5",
- },
- ]
- }
- />
- </div>
- <div
- className="modal-foot"
- >
- <a
- className="pull-left"
- href="https://www.sonarqube.org/downloads/?referrer=sonarqube"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.see_sonarqube_downloads
- </a>
- <ResetButtonLink
- onClick={[MockFunction]}
- >
- cancel
- </ResetButtonLink>
- </div>
-</Modal>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should display correctly 1`] = `
-<div>
- <ButtonLink
- className="little-spacer-bottom"
- onClick={[Function]}
- >
- system.show_intermediate_versions
- <DropdownIcon
- className="little-spacer-left"
- turned={false}
- />
- </ButtonLink>
-</div>
-`;
-
-exports[`should display correctly 2`] = `
-<div>
- <ButtonLink
- className="little-spacer-bottom"
- onClick={[Function]}
- >
- system.hide_intermediate_versions
- <DropdownIcon
- className="little-spacer-left"
- turned={true}
- />
- </ButtonLink>
- <div
- className="note system-upgrade-intermediate"
- key="5.6.6"
- >
- <DateFormatter
- date="2017-04-02"
- long={true}
- >
- <Component />
- </DateFormatter>
- <p
- className="little-spacer-top"
- >
- Version 5.6.6 description
- </p>
- </div>
- <div
- className="note system-upgrade-intermediate"
- key="5.6.5"
- >
- <DateFormatter
- date="2017-03-01"
- long={true}
- >
- <Component />
- </DateFormatter>
- <p
- className="little-spacer-top"
- >
- Version 5.6.5 description
- </p>
- </div>
-</div>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should display correctly 1`] = `
-<div
- className="system-upgrade-version"
->
- <h3
- className="h1 spacer-bottom"
- >
- <strong>
- system.latest_version
- </strong>
- <a
- className="spacer-left medium"
- href="https://www.sonarqube.org/whats-new/?referrer=sonarqube"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.see_whats_new
- </a>
- </h3>
- <p>
- <FormattedMessage
- defaultMessage="system.version_is_availble"
- id="system.version_is_availble"
- values={
- Object {
- "version": <b>
- SonarQube
- 5.6.7
- </b>,
- }
- }
- />
- </p>
- <p
- className="spacer-top"
- >
- Version 5.6.7 description
- </p>
- <div
- className="big-spacer-top"
- >
- <DateFormatter
- date="2017-03-01"
- long={true}
- >
- <Component />
- </DateFormatter>
- <a
- className="spacer-left"
- href="http://changelog.url/"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.release_notes
- </a>
- </div>
- <SystemUpgradeIntermediate
- className="spacer-top"
- upgrades={
- Array [
- Object {
- "changeLogUrl": "http://changelog.url/",
- "description": "Version 5.6.6 description",
- "downloadDeveloperUrl": "http://download.url/developer",
- "downloadUrl": "http://download.url/community",
- "releaseDate": "2017-04-02",
- "version": "5.6.6",
- },
- Object {
- "changeLogUrl": "http://changelog.url/",
- "description": "Version 5.6.5 description",
- "downloadDeveloperUrl": "http://download.url/developer",
- "downloadUrl": "http://download.url/community",
- "releaseDate": "2017-03-01",
- "version": "5.6.5",
- },
- ]
- }
- />
- <div
- className="big-spacer-top"
- >
- <a
- className="button"
- download="http://download.url/community"
- href="http://download.url/community"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.download_x.5.6.7
- </a>
- <a
- className="spacer-left"
- href="https://redirect.sonarsource.com/doc/upgrading.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.how_to_upgrade
- </a>
- </div>
-</div>
-`;
-
-exports[`should display correctly 2`] = `
-<div
- className="system-upgrade-version"
->
- <h3
- className="h1 spacer-bottom"
- >
- <strong>
- system.lts_version
- </strong>
- </h3>
- <p>
- <FormattedMessage
- defaultMessage="system.version_is_availble"
- id="system.version_is_availble"
- values={
- Object {
- "version": <b>
- SonarQube
- 5.6.7
- </b>,
- }
- }
- />
- </p>
- <p
- className="spacer-top"
- >
- Version 5.6.7 description
- </p>
- <div
- className="big-spacer-top"
- >
- <DateFormatter
- date="2017-03-01"
- long={true}
- >
- <Component />
- </DateFormatter>
- <a
- className="spacer-left"
- href="http://changelog.url/"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.release_notes
- </a>
- </div>
- <SystemUpgradeIntermediate
- className="spacer-top"
- upgrades={
- Array [
- Object {
- "changeLogUrl": "http://changelog.url/",
- "description": "Version 5.6.6 description",
- "downloadDeveloperUrl": "http://download.url/developer",
- "downloadUrl": "http://download.url/community",
- "releaseDate": "2017-04-02",
- "version": "5.6.6",
- },
- Object {
- "changeLogUrl": "http://changelog.url/",
- "description": "Version 5.6.5 description",
- "downloadDeveloperUrl": "http://download.url/developer",
- "downloadUrl": "http://download.url/community",
- "releaseDate": "2017-03-01",
- "version": "5.6.5",
- },
- ]
- }
- />
- <div
- className="big-spacer-top"
- >
- <a
- className="button"
- download="http://download.url/community"
- href="http://download.url/community"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.download_x.5.6.7
- </a>
- <a
- className="spacer-left"
- href="https://redirect.sonarsource.com/doc/upgrading.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.how_to_upgrade
- </a>
- </div>
-</div>
-`;
-
-exports[`should display correctly 3`] = `
-<div
- className="system-upgrade-version"
->
- <h3
- className="h1 spacer-bottom"
- >
- <strong>
- system.latest_version
- </strong>
- <a
- className="spacer-left medium"
- href="https://www.sonarqube.org/whats-new/?referrer=sonarqube"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.see_whats_new
- </a>
- </h3>
- <p>
- <FormattedMessage
- defaultMessage="system.version_is_availble"
- id="system.version_is_availble"
- values={
- Object {
- "version": <b>
- SonarQube
- 5.6.7
- </b>,
- }
- }
- />
- </p>
- <p
- className="spacer-top"
- >
- Version 5.6.7 description
- </p>
- <div
- className="big-spacer-top"
- >
- <DateFormatter
- date="2017-03-01"
- long={true}
- >
- <Component />
- </DateFormatter>
- <a
- className="spacer-left"
- href="http://changelog.url/"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.release_notes
- </a>
- </div>
- <SystemUpgradeIntermediate
- className="spacer-top"
- upgrades={
- Array [
- Object {
- "changeLogUrl": "http://changelog.url/",
- "description": "Version 5.6.6 description",
- "downloadDeveloperUrl": "http://download.url/developer",
- "downloadUrl": "http://download.url/community",
- "releaseDate": "2017-04-02",
- "version": "5.6.6",
- },
- Object {
- "changeLogUrl": "http://changelog.url/",
- "description": "Version 5.6.5 description",
- "downloadDeveloperUrl": "http://download.url/developer",
- "downloadUrl": "http://download.url/community",
- "releaseDate": "2017-03-01",
- "version": "5.6.5",
- },
- ]
- }
- />
- <div
- className="big-spacer-top"
- >
- <a
- className="button"
- download="http://download.url/developer"
- href="http://download.url/developer"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.download_x.5.6.7
- </a>
- <a
- className="spacer-left"
- href="https://redirect.sonarsource.com/doc/upgrading.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.how_to_upgrade
- </a>
- </div>
-</div>
-`;
-
-exports[`should display correctly 4`] = `
-<div
- className="system-upgrade-version"
->
- <h3
- className="h1 spacer-bottom"
- >
- <strong>
- system.latest_version
- </strong>
- <a
- className="spacer-left medium"
- href="https://www.sonarqube.org/whats-new/?referrer=sonarqube"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.see_whats_new
- </a>
- </h3>
- <p>
- <FormattedMessage
- defaultMessage="system.version_is_availble"
- id="system.version_is_availble"
- values={
- Object {
- "version": <b>
- SonarQube
- 5.6.7
- </b>,
- }
- }
- />
- </p>
- <p
- className="spacer-top"
- >
- Version 5.6.7 description
- </p>
- <div
- className="big-spacer-top"
- >
- <DateFormatter
- date="2017-03-01"
- long={true}
- >
- <Component />
- </DateFormatter>
- <a
- className="spacer-left"
- href="http://changelog.url/"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.release_notes
- </a>
- </div>
- <SystemUpgradeIntermediate
- className="spacer-top"
- upgrades={
- Array [
- Object {
- "changeLogUrl": "http://changelog.url/",
- "description": "Version 5.6.6 description",
- "downloadDeveloperUrl": "http://download.url/developer",
- "downloadUrl": "http://download.url/community",
- "releaseDate": "2017-04-02",
- "version": "5.6.6",
- },
- Object {
- "changeLogUrl": "http://changelog.url/",
- "description": "Version 5.6.5 description",
- "downloadDeveloperUrl": "http://download.url/developer",
- "downloadUrl": "http://download.url/community",
- "releaseDate": "2017-03-01",
- "version": "5.6.5",
- },
- ]
- }
- />
- <div
- className="big-spacer-top"
- >
- <a
- className="button"
- download="http://download.url/enterprise"
- href="http://download.url/enterprise"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.download_x.5.6.7
- </a>
- <a
- className="spacer-left"
- href="https://redirect.sonarsource.com/doc/upgrading.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.how_to_upgrade
- </a>
- </div>
-</div>
-`;
-
-exports[`should display correctly 5`] = `
-<div
- className="system-upgrade-version"
->
- <h3
- className="h1 spacer-bottom"
- >
- <strong>
- system.latest_version
- </strong>
- <a
- className="spacer-left medium"
- href="https://www.sonarqube.org/whats-new/?referrer=sonarqube"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.see_whats_new
- </a>
- </h3>
- <p>
- <FormattedMessage
- defaultMessage="system.version_is_availble"
- id="system.version_is_availble"
- values={
- Object {
- "version": <b>
- SonarQube
- 5.6.7
- </b>,
- }
- }
- />
- </p>
- <p
- className="spacer-top"
- >
- Version 5.6.7 description
- </p>
- <div
- className="big-spacer-top"
- >
- <DateFormatter
- date="2017-03-01"
- long={true}
- >
- <Component />
- </DateFormatter>
- <a
- className="spacer-left"
- href="http://changelog.url/"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.release_notes
- </a>
- </div>
- <SystemUpgradeIntermediate
- className="spacer-top"
- upgrades={
- Array [
- Object {
- "changeLogUrl": "http://changelog.url/",
- "description": "Version 5.6.6 description",
- "downloadDeveloperUrl": "http://download.url/developer",
- "downloadUrl": "http://download.url/community",
- "releaseDate": "2017-04-02",
- "version": "5.6.6",
- },
- Object {
- "changeLogUrl": "http://changelog.url/",
- "description": "Version 5.6.5 description",
- "downloadDeveloperUrl": "http://download.url/developer",
- "downloadUrl": "http://download.url/community",
- "releaseDate": "2017-03-01",
- "version": "5.6.5",
- },
- ]
- }
- />
- <div
- className="big-spacer-top"
- >
- <a
- className="button"
- download="http://download.url/datacenter"
- href="http://download.url/datacenter"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.download_x.5.6.7
- </a>
- <a
- className="spacer-left"
- href="https://redirect.sonarsource.com/doc/upgrading.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.how_to_upgrade
- </a>
- </div>
-</div>
-`;
-
-exports[`should display correctly 6`] = `
-<div
- className="system-upgrade-version"
->
- <h3
- className="h1 spacer-bottom"
- >
- <strong>
- system.latest_version
- </strong>
- <a
- className="spacer-left medium"
- href="https://www.sonarqube.org/whats-new/?referrer=sonarqube"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.see_whats_new
- </a>
- </h3>
- <p>
- <FormattedMessage
- defaultMessage="system.version_is_availble"
- id="system.version_is_availble"
- values={
- Object {
- "version": <b>
- SonarQube
- 5.6.7
- </b>,
- }
- }
- />
- </p>
- <p
- className="spacer-top"
- >
- Version 5.6.7 description
- </p>
- <div
- className="big-spacer-top"
- >
- <DateFormatter
- date="2017-03-01"
- long={true}
- >
- <Component />
- </DateFormatter>
- <a
- className="spacer-left"
- href="http://changelog.url/"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.release_notes
- </a>
- </div>
- <SystemUpgradeIntermediate
- className="spacer-top"
- upgrades={Array []}
- />
- <div
- className="big-spacer-top"
- >
- <a
- className="button"
- download="http://download.url/community"
- href="http://download.url/community"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.download_x.5.6.7
- </a>
- <a
- className="spacer-left"
- href="https://redirect.sonarsource.com/doc/upgrading.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- system.how_to_upgrade
- </a>
- </div>
-</div>
-`;
variant="info"
>
system.new_version_available
- <Button
- className="spacer-left"
- onClick={[Function]}
- >
- learn_more
- </Button>
- </Alert>
-</div>
-`;
-
-exports[`should render correctly 2`] = `
-<div
- className="page-notifs"
->
- <Alert
- variant="info"
- >
- system.new_version_available
- <Button
- className="spacer-left"
- onClick={[Function]}
- >
- learn_more
- </Button>
- </Alert>
- <Connect(withAppState(SystemUpgradeForm))
- onClose={[Function]}
- systemUpgrades={
- Array [
+ <SystemUpgradeButton
+ systemUpgrades={
Array [
Object {
"changeLogUrl": "changelogurl",
- "description": "Version 6.4 description",
+ "description": "Version 5.6.7 description",
"downloadUrl": "downloadurl",
"plugins": Object {},
- "releaseDate": "2017-06-02",
- "version": "6.4",
+ "releaseDate": "2017-03-01",
+ "version": "5.6.7",
},
Object {
"changeLogUrl": "changelogurl",
- "description": "Version 6.3 description",
+ "description": "Version 5.6.5 description",
"downloadUrl": "downloadurl",
"plugins": Object {},
- "releaseDate": "2017-05-02",
- "version": "6.3",
+ "releaseDate": "2017-03-01",
+ "version": "5.6.5",
},
- ],
- Array [
Object {
"changeLogUrl": "changelogurl",
- "description": "Version 5.6.7 description",
+ "description": "Version 6.3 description",
"downloadUrl": "downloadurl",
"plugins": Object {},
- "releaseDate": "2017-03-01",
- "version": "5.6.7",
+ "releaseDate": "2017-05-02",
+ "version": "6.3",
},
Object {
"changeLogUrl": "changelogurl",
},
Object {
"changeLogUrl": "changelogurl",
- "description": "Version 5.6.5 description",
+ "description": "Version 6.4 description",
"downloadUrl": "downloadurl",
"plugins": Object {},
- "releaseDate": "2017-03-01",
- "version": "5.6.5",
+ "releaseDate": "2017-06-02",
+ "version": "6.4",
},
- ],
- ]
- }
- />
+ ]
+ }
+ />
+ </Alert>
</div>
`;
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { each, groupBy, memoize, omit, omitBy, pickBy, sortBy } from 'lodash';
+import { each, memoize, omit, omitBy, pickBy, sortBy } from 'lodash';
import { formatMeasure } from '../../helpers/measures';
import { cleanQuery, parseAsArray, parseAsString, serializeStringArray } from '../../helpers/query';
-import { SystemUpgrade } from '../../types/system';
export interface Query {
expandedCards: string[];
expand: serializeStringArray(query.expandedCards)
})
);
-
-export function sortUpgrades(upgrades: SystemUpgrade[]): SystemUpgrade[] {
- return sortBy(upgrades, [
- (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: 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]);
-}
import DeferredSpinner from './DeferredSpinner';
type AlertDisplay = 'banner' | 'inline' | 'block';
-type AlertVariant = 'error' | 'warning' | 'success' | 'info' | 'loading';
+export type AlertVariant = 'error' | 'warning' | 'success' | 'info' | 'loading';
export interface AlertProps {
display?: AlertDisplay;
}, [alertKey]);
const hideAlert = () => {
+ window.dispatchEvent(new Event('resize'));
save(DISMISSED_ALERT_STORAGE_KEY, 'true', alertKey);
};
return !show ? null : (
- <Alert
- className={classNames(`dismissable-alert-${display}`, className)}
- display={display}
- variant={variant}>
- <div className="display-flex-center dismissable-alert-content">
- <div className="flex-1">{children}</div>
- <ButtonIcon
- aria-label={translate('alert.dismiss')}
- onClick={() => {
- hideAlert();
- setShow(false);
- }}>
- <ClearIcon size={12} thin={true} />
- </ButtonIcon>
- </div>
- </Alert>
+ <div className={classNames('dismissable-alert-wrapper', className)}>
+ <Alert className={`dismissable-alert-${display}`} display={display} variant={variant}>
+ <div className="display-flex-center dismissable-alert-content">
+ <div className="flex-1">{children}</div>
+ <ButtonIcon
+ aria-label={translate('alert.dismiss')}
+ onClick={() => {
+ hideAlert();
+ setShow(false);
+ }}>
+ <ClearIcon size={12} thin={true} />
+ </ButtonIcon>
+ </div>
+ </Alert>
+ </div>
);
}
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly 1`] = `
-<Alert
- className="dismissable-alert-banner"
- display="banner"
- variant="info"
+<div
+ className="dismissable-alert-wrapper"
>
- <div
- className="display-flex-center dismissable-alert-content"
+ <Alert
+ className="dismissable-alert-banner"
+ display="banner"
+ variant="info"
>
<div
- className="flex-1"
+ className="display-flex-center dismissable-alert-content"
>
- <div>
- My content
+ <div
+ className="flex-1"
+ >
+ <div>
+ My content
+ </div>
</div>
+ <ButtonIcon
+ aria-label="alert.dismiss"
+ onClick={[Function]}
+ >
+ <ClearIcon
+ size={12}
+ thin={true}
+ />
+ </ButtonIcon>
</div>
- <ButtonIcon
- aria-label="alert.dismiss"
- onClick={[Function]}
- >
- <ClearIcon
- size={12}
- thin={true}
- />
- </ButtonIcon>
- </div>
-</Alert>
+ </Alert>
+</div>
`;
exports[`should render correctly with a non-default display 1`] = `
-<Alert
- className="dismissable-alert-block"
- display="block"
- variant="info"
+<div
+ className="dismissable-alert-wrapper"
>
- <div
- className="display-flex-center dismissable-alert-content"
+ <Alert
+ className="dismissable-alert-block"
+ display="block"
+ variant="info"
>
<div
- className="flex-1"
+ className="display-flex-center dismissable-alert-content"
>
- <div>
- My content
+ <div
+ className="flex-1"
+ >
+ <div>
+ My content
+ </div>
</div>
+ <ButtonIcon
+ aria-label="alert.dismiss"
+ onClick={[Function]}
+ >
+ <ClearIcon
+ size={12}
+ thin={true}
+ />
+ </ButtonIcon>
</div>
- <ButtonIcon
- aria-label="alert.dismiss"
- onClick={[Function]}
- >
- <ClearIcon
- size={12}
- thin={true}
- />
- </ButtonIcon>
- </div>
-</Alert>
+ </Alert>
+</div>
`;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { translate } from '../../helpers/l10n';
+import { SystemUpgrade } from '../../types/system';
+import { Button } from '../controls/buttons';
+import SystemUpgradeForm from './SystemUpgradeForm';
+import { groupUpgrades, sortUpgrades } from './utils';
+
+interface Props {
+ systemUpgrades: SystemUpgrade[];
+}
+
+interface State {
+ openSystemUpgradeForm: boolean;
+}
+
+export default class SystemUpgradeButton extends React.PureComponent<Props, State> {
+ state: State = { openSystemUpgradeForm: false };
+
+ handleOpenSystemUpgradeForm = () => {
+ this.setState({ openSystemUpgradeForm: true });
+ };
+
+ handleCloseSystemUpgradeForm = () => {
+ this.setState({ openSystemUpgradeForm: false });
+ };
+
+ render() {
+ const { systemUpgrades } = this.props;
+ const { openSystemUpgradeForm } = this.state;
+ return (
+ <>
+ <Button className="spacer-left" onClick={this.handleOpenSystemUpgradeForm}>
+ {translate('learn_more')}
+ </Button>
+ {openSystemUpgradeForm && (
+ <SystemUpgradeForm
+ onClose={this.handleCloseSystemUpgradeForm}
+ systemUpgrades={groupUpgrades(sortUpgrades(systemUpgrades))}
+ />
+ )}
+ </>
+ );
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { translate } from '../../helpers/l10n';
+import { EditionKey } from '../../types/editions';
+import { SystemUpgrade } from '../../types/system';
+import { ResetButtonLink } from '../controls/buttons';
+import Modal from '../controls/Modal';
+import { withAppState } from '../hoc/withAppState';
+import SystemUpgradeItem from './SystemUpgradeItem';
+
+interface Props {
+ appState: Pick<T.AppState, 'edition'>;
+ onClose: () => void;
+ systemUpgrades: SystemUpgrade[][];
+}
+
+interface State {
+ upgrading: boolean;
+}
+
+export class SystemUpgradeForm extends React.PureComponent<Props, State> {
+ state: State = { upgrading: false };
+
+ render() {
+ const { upgrading } = this.state;
+ const { appState, systemUpgrades } = this.props;
+ const header = translate('system.system_upgrade');
+ return (
+ <Modal contentLabel={header} onRequestClose={this.props.onClose}>
+ <div className="modal-head">
+ <h2>{header}</h2>
+ </div>
+ <div className="modal-body">
+ {systemUpgrades.map((upgrades, idx) => (
+ <SystemUpgradeItem
+ edition={
+ appState.edition as EditionKey /* TODO: Fix once AppState is no longer ambiant. */
+ }
+ key={upgrades[upgrades.length - 1].version}
+ systemUpgrades={upgrades}
+ isLatestVersion={idx === 0}
+ />
+ ))}
+ </div>
+ <div className="modal-foot">
+ {upgrading && <i className="spinner spacer-right" />}
+ <a
+ className="pull-left"
+ href="https://www.sonarqube.org/downloads/?referrer=sonarqube"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('system.see_sonarqube_downloads')}
+ </a>
+ <ResetButtonLink onClick={this.props.onClose}>{translate('cancel')}</ResetButtonLink>
+ </div>
+ </Modal>
+ );
+ }
+}
+
+export default withAppState(SystemUpgradeForm);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { translate } from '../../helpers/l10n';
+import { SystemUpgrade } from '../../types/system';
+import { ButtonLink } from '../controls/buttons';
+import DropdownIcon from '../icons/DropdownIcon';
+import DateFormatter from '../intl/DateFormatter';
+
+interface Props {
+ className?: string;
+ upgrades: SystemUpgrade[];
+}
+
+interface State {
+ showMore: boolean;
+}
+
+export default class SystemUpgradeIntermediate extends React.PureComponent<Props, State> {
+ state: State = { showMore: false };
+
+ toggleIntermediatVersions = () => {
+ this.setState(state => ({ showMore: !state.showMore }));
+ };
+
+ render() {
+ const { showMore } = this.state;
+ const { upgrades } = this.props;
+ if (upgrades.length <= 0) {
+ return null;
+ }
+
+ return (
+ <div className={this.props.className}>
+ <ButtonLink className="little-spacer-bottom" onClick={this.toggleIntermediatVersions}>
+ {showMore
+ ? translate('system.hide_intermediate_versions')
+ : translate('system.show_intermediate_versions')}
+ <DropdownIcon className="little-spacer-left" turned={showMore} />
+ </ButtonLink>
+ {showMore &&
+ upgrades.map(upgrade => (
+ <div className="note system-upgrade-intermediate" key={upgrade.version}>
+ {upgrade.releaseDate && (
+ <DateFormatter date={upgrade.releaseDate} long={true}>
+ {formattedDate => (
+ <p>
+ <b className="little-spacer-right">SonarQube {upgrade.version}</b>
+ {formattedDate}
+ {upgrade.changeLogUrl && (
+ <a
+ className="spacer-left"
+ href={upgrade.changeLogUrl}
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('system.release_notes')}
+ </a>
+ )}
+ </p>
+ )}
+ </DateFormatter>
+ )}
+ {upgrade.description && <p className="little-spacer-top">{upgrade.description}</p>}
+ </div>
+ ))}
+ </div>
+ );
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import {
+ getEdition,
+ getEditionDownloadFilename,
+ getEditionDownloadUrl
+} from '../../helpers/editions';
+import { translate, translateWithParameters } from '../../helpers/l10n';
+import { EditionKey } from '../../types/editions';
+import { SystemUpgrade } from '../../types/system';
+import DateFormatter from '../intl/DateFormatter';
+import SystemUpgradeIntermediate from './SystemUpgradeIntermediate';
+
+export interface SystemUpgradeItemProps {
+ edition: EditionKey | undefined;
+ isLatestVersion: boolean;
+ systemUpgrades: SystemUpgrade[];
+}
+
+export default function SystemUpgradeItem(props: SystemUpgradeItemProps) {
+ const { edition, isLatestVersion, systemUpgrades } = props;
+ const lastUpgrade = systemUpgrades[0];
+ const downloadUrl = getEditionDownloadUrl(
+ getEdition(edition || EditionKey.community),
+ lastUpgrade
+ );
+
+ return (
+ <div className="system-upgrade-version">
+ <h3 className="h1 spacer-bottom">
+ <strong>
+ {isLatestVersion ? translate('system.latest_version') : translate('system.lts_version')}
+ </strong>
+ {isLatestVersion && (
+ <a
+ className="spacer-left medium"
+ href="https://www.sonarqube.org/whats-new/?referrer=sonarqube"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('system.see_whats_new')}
+ </a>
+ )}
+ </h3>
+ <p>
+ <FormattedMessage
+ defaultMessage={translate('system.version_is_availble')}
+ id="system.version_is_availble"
+ values={{ version: <b>SonarQube {lastUpgrade.version}</b> }}
+ />
+ </p>
+ <p className="spacer-top">{lastUpgrade.description}</p>
+ <div className="big-spacer-top">
+ {lastUpgrade.releaseDate && (
+ <DateFormatter date={lastUpgrade.releaseDate} long={true}>
+ {formattedDate => (
+ <span>{translateWithParameters('system.released_x', formattedDate)}</span>
+ )}
+ </DateFormatter>
+ )}
+ {lastUpgrade.changeLogUrl && (
+ <a
+ className="spacer-left"
+ href={lastUpgrade.changeLogUrl}
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('system.release_notes')}
+ </a>
+ )}
+ </div>
+ <SystemUpgradeIntermediate className="spacer-top" upgrades={systemUpgrades.slice(1)} />
+ <div className="big-spacer-top">
+ <a
+ className="button"
+ download={getEditionDownloadFilename(downloadUrl)}
+ href={downloadUrl}
+ rel="noopener noreferrer"
+ target="_blank">
+ {translateWithParameters('system.download_x', lastUpgrade.version)}
+ </a>
+ <a
+ className="spacer-left"
+ href="https://redirect.sonarsource.com/doc/upgrading.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('system.how_to_upgrade')}
+ </a>
+ </div>
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
+import * as React from 'react';
+import { click } from '../../../helpers/testUtils';
+import { Button } from '../../controls/buttons';
+import SystemUpgradeButton from '../SystemUpgradeButton';
+import SystemUpgradeForm from '../SystemUpgradeForm';
+
+it('should open modal correctly', () => {
+ const wrapper = shallowRender();
+ expect(wrapper).toMatchSnapshot();
+ click(wrapper.find(Button));
+ expect(wrapper.find(SystemUpgradeForm)).toBeDefined();
+});
+
+function shallowRender(props: Partial<SystemUpgradeButton['props']> = {}) {
+ return shallow<SystemUpgradeButton['props']>(
+ <SystemUpgradeButton systemUpgrades={[]} {...props} />
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
+import * as React from 'react';
+import { EditionKey } from '../../../types/editions';
+import { SystemUpgradeForm } from '../SystemUpgradeForm';
+
+const UPGRADES = [
+ [
+ {
+ version: '6.4',
+ description: 'Version 6.4 description',
+ releaseDate: '2017-06-02',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '6.3',
+ description: 'Version 6.3 description',
+ releaseDate: '2017-05-02',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ }
+ ],
+ [
+ {
+ version: '5.6.7',
+ description: 'Version 5.6.7 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '5.6.6',
+ description: 'Version 5.6.6 description',
+ releaseDate: '2017-04-02',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '5.6.5',
+ description: 'Version 5.6.5 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ }
+ ]
+];
+
+it('should display correctly', () => {
+ expect(
+ shallow(
+ <SystemUpgradeForm
+ appState={{ edition: EditionKey.community }}
+ onClose={jest.fn()}
+ systemUpgrades={UPGRADES}
+ />
+ )
+ ).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
+import * as React from 'react';
+import { click } from '../../../helpers/testUtils';
+import SystemUpgradeIntermediate from '../SystemUpgradeIntermediate';
+
+const UPGRADES = [
+ {
+ version: '5.6.6',
+ description: 'Version 5.6.6 description',
+ releaseDate: '2017-04-02',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '5.6.5',
+ description: 'Version 5.6.5 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ }
+];
+
+it('should display correctly', () => {
+ const wrapper = shallow(<SystemUpgradeIntermediate upgrades={UPGRADES} />);
+ expect(wrapper).toMatchSnapshot();
+ wrapper.setState({ showMore: true });
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('should allow to show and hide intermediates', () => {
+ const wrapper = shallow(<SystemUpgradeIntermediate upgrades={UPGRADES} />);
+ expect(wrapper.find('.system-upgrade-intermediate').exists()).toBe(false);
+ click(wrapper.find('ButtonLink'));
+ expect(wrapper.find('.system-upgrade-intermediate').exists()).toBe(true);
+ click(wrapper.find('ButtonLink'));
+ expect(wrapper.find('.system-upgrade-intermediate').exists()).toBe(false);
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 { shallow } from 'enzyme';
+import * as React from 'react';
+import { EditionKey } from '../../../types/editions';
+import SystemUpgradeItem, { SystemUpgradeItemProps } from '../SystemUpgradeItem';
+
+it('should display correctly', () => {
+ expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender({ isLatestVersion: false })).toMatchSnapshot();
+ expect(shallowRender({ edition: EditionKey.developer })).toMatchSnapshot();
+ expect(shallowRender({ edition: EditionKey.enterprise })).toMatchSnapshot();
+ expect(shallowRender({ edition: EditionKey.datacenter })).toMatchSnapshot();
+ // Fallback to Community.
+ expect(
+ shallowRender({
+ systemUpgrades: [
+ {
+ version: '5.6.7',
+ description: 'Version 5.6.7 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'http://changelog.url/',
+ downloadUrl: 'http://download.url/community'
+ }
+ ]
+ })
+ ).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<SystemUpgradeItemProps> = {}) {
+ return shallow<SystemUpgradeItemProps>(
+ <SystemUpgradeItem
+ edition={EditionKey.community}
+ systemUpgrades={[
+ {
+ version: '5.6.7',
+ description: 'Version 5.6.7 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'http://changelog.url/',
+ downloadUrl: 'http://download.url/community',
+ downloadDeveloperUrl: 'http://download.url/developer',
+ downloadEnterpriseUrl: 'http://download.url/enterprise',
+ downloadDatacenterUrl: 'http://download.url/datacenter'
+ },
+ {
+ version: '5.6.6',
+ description: 'Version 5.6.6 description',
+ releaseDate: '2017-04-02',
+ changeLogUrl: 'http://changelog.url/',
+ downloadUrl: 'http://download.url/community',
+ downloadDeveloperUrl: 'http://download.url/developer'
+ },
+ {
+ version: '5.6.5',
+ description: 'Version 5.6.5 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'http://changelog.url/',
+ downloadUrl: 'http://download.url/community',
+ downloadDeveloperUrl: 'http://download.url/developer'
+ }
+ ]}
+ isLatestVersion={true}
+ {...props}
+ />
+ );
+}
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should open modal correctly 1`] = `
+<Fragment>
+ <Button
+ className="spacer-left"
+ onClick={[Function]}
+ >
+ learn_more
+ </Button>
+</Fragment>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should display correctly 1`] = `
+<Modal
+ contentLabel="system.system_upgrade"
+ onRequestClose={[MockFunction]}
+>
+ <div
+ className="modal-head"
+ >
+ <h2>
+ system.system_upgrade
+ </h2>
+ </div>
+ <div
+ className="modal-body"
+ >
+ <SystemUpgradeItem
+ edition="community"
+ isLatestVersion={true}
+ key="6.3"
+ systemUpgrades={
+ Array [
+ Object {
+ "changeLogUrl": "changelogurl",
+ "description": "Version 6.4 description",
+ "downloadUrl": "downloadurl",
+ "plugins": Object {},
+ "releaseDate": "2017-06-02",
+ "version": "6.4",
+ },
+ Object {
+ "changeLogUrl": "changelogurl",
+ "description": "Version 6.3 description",
+ "downloadUrl": "downloadurl",
+ "plugins": Object {},
+ "releaseDate": "2017-05-02",
+ "version": "6.3",
+ },
+ ]
+ }
+ />
+ <SystemUpgradeItem
+ edition="community"
+ isLatestVersion={false}
+ key="5.6.5"
+ systemUpgrades={
+ Array [
+ Object {
+ "changeLogUrl": "changelogurl",
+ "description": "Version 5.6.7 description",
+ "downloadUrl": "downloadurl",
+ "plugins": Object {},
+ "releaseDate": "2017-03-01",
+ "version": "5.6.7",
+ },
+ Object {
+ "changeLogUrl": "changelogurl",
+ "description": "Version 5.6.6 description",
+ "downloadUrl": "downloadurl",
+ "plugins": Object {},
+ "releaseDate": "2017-04-02",
+ "version": "5.6.6",
+ },
+ Object {
+ "changeLogUrl": "changelogurl",
+ "description": "Version 5.6.5 description",
+ "downloadUrl": "downloadurl",
+ "plugins": Object {},
+ "releaseDate": "2017-03-01",
+ "version": "5.6.5",
+ },
+ ]
+ }
+ />
+ </div>
+ <div
+ className="modal-foot"
+ >
+ <a
+ className="pull-left"
+ href="https://www.sonarqube.org/downloads/?referrer=sonarqube"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.see_sonarqube_downloads
+ </a>
+ <ResetButtonLink
+ onClick={[MockFunction]}
+ >
+ cancel
+ </ResetButtonLink>
+ </div>
+</Modal>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should display correctly 1`] = `
+<div>
+ <ButtonLink
+ className="little-spacer-bottom"
+ onClick={[Function]}
+ >
+ system.show_intermediate_versions
+ <DropdownIcon
+ className="little-spacer-left"
+ turned={false}
+ />
+ </ButtonLink>
+</div>
+`;
+
+exports[`should display correctly 2`] = `
+<div>
+ <ButtonLink
+ className="little-spacer-bottom"
+ onClick={[Function]}
+ >
+ system.hide_intermediate_versions
+ <DropdownIcon
+ className="little-spacer-left"
+ turned={true}
+ />
+ </ButtonLink>
+ <div
+ className="note system-upgrade-intermediate"
+ key="5.6.6"
+ >
+ <DateFormatter
+ date="2017-04-02"
+ long={true}
+ >
+ <Component />
+ </DateFormatter>
+ <p
+ className="little-spacer-top"
+ >
+ Version 5.6.6 description
+ </p>
+ </div>
+ <div
+ className="note system-upgrade-intermediate"
+ key="5.6.5"
+ >
+ <DateFormatter
+ date="2017-03-01"
+ long={true}
+ >
+ <Component />
+ </DateFormatter>
+ <p
+ className="little-spacer-top"
+ >
+ Version 5.6.5 description
+ </p>
+ </div>
+</div>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should display correctly 1`] = `
+<div
+ className="system-upgrade-version"
+>
+ <h3
+ className="h1 spacer-bottom"
+ >
+ <strong>
+ system.latest_version
+ </strong>
+ <a
+ className="spacer-left medium"
+ href="https://www.sonarqube.org/whats-new/?referrer=sonarqube"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.see_whats_new
+ </a>
+ </h3>
+ <p>
+ <FormattedMessage
+ defaultMessage="system.version_is_availble"
+ id="system.version_is_availble"
+ values={
+ Object {
+ "version": <b>
+ SonarQube
+ 5.6.7
+ </b>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="spacer-top"
+ >
+ Version 5.6.7 description
+ </p>
+ <div
+ className="big-spacer-top"
+ >
+ <DateFormatter
+ date="2017-03-01"
+ long={true}
+ >
+ <Component />
+ </DateFormatter>
+ <a
+ className="spacer-left"
+ href="http://changelog.url/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.release_notes
+ </a>
+ </div>
+ <SystemUpgradeIntermediate
+ className="spacer-top"
+ upgrades={
+ Array [
+ Object {
+ "changeLogUrl": "http://changelog.url/",
+ "description": "Version 5.6.6 description",
+ "downloadDeveloperUrl": "http://download.url/developer",
+ "downloadUrl": "http://download.url/community",
+ "releaseDate": "2017-04-02",
+ "version": "5.6.6",
+ },
+ Object {
+ "changeLogUrl": "http://changelog.url/",
+ "description": "Version 5.6.5 description",
+ "downloadDeveloperUrl": "http://download.url/developer",
+ "downloadUrl": "http://download.url/community",
+ "releaseDate": "2017-03-01",
+ "version": "5.6.5",
+ },
+ ]
+ }
+ />
+ <div
+ className="big-spacer-top"
+ >
+ <a
+ className="button"
+ download="http://download.url/community"
+ href="http://download.url/community"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.download_x.5.6.7
+ </a>
+ <a
+ className="spacer-left"
+ href="https://redirect.sonarsource.com/doc/upgrading.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.how_to_upgrade
+ </a>
+ </div>
+</div>
+`;
+
+exports[`should display correctly 2`] = `
+<div
+ className="system-upgrade-version"
+>
+ <h3
+ className="h1 spacer-bottom"
+ >
+ <strong>
+ system.lts_version
+ </strong>
+ </h3>
+ <p>
+ <FormattedMessage
+ defaultMessage="system.version_is_availble"
+ id="system.version_is_availble"
+ values={
+ Object {
+ "version": <b>
+ SonarQube
+ 5.6.7
+ </b>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="spacer-top"
+ >
+ Version 5.6.7 description
+ </p>
+ <div
+ className="big-spacer-top"
+ >
+ <DateFormatter
+ date="2017-03-01"
+ long={true}
+ >
+ <Component />
+ </DateFormatter>
+ <a
+ className="spacer-left"
+ href="http://changelog.url/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.release_notes
+ </a>
+ </div>
+ <SystemUpgradeIntermediate
+ className="spacer-top"
+ upgrades={
+ Array [
+ Object {
+ "changeLogUrl": "http://changelog.url/",
+ "description": "Version 5.6.6 description",
+ "downloadDeveloperUrl": "http://download.url/developer",
+ "downloadUrl": "http://download.url/community",
+ "releaseDate": "2017-04-02",
+ "version": "5.6.6",
+ },
+ Object {
+ "changeLogUrl": "http://changelog.url/",
+ "description": "Version 5.6.5 description",
+ "downloadDeveloperUrl": "http://download.url/developer",
+ "downloadUrl": "http://download.url/community",
+ "releaseDate": "2017-03-01",
+ "version": "5.6.5",
+ },
+ ]
+ }
+ />
+ <div
+ className="big-spacer-top"
+ >
+ <a
+ className="button"
+ download="http://download.url/community"
+ href="http://download.url/community"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.download_x.5.6.7
+ </a>
+ <a
+ className="spacer-left"
+ href="https://redirect.sonarsource.com/doc/upgrading.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.how_to_upgrade
+ </a>
+ </div>
+</div>
+`;
+
+exports[`should display correctly 3`] = `
+<div
+ className="system-upgrade-version"
+>
+ <h3
+ className="h1 spacer-bottom"
+ >
+ <strong>
+ system.latest_version
+ </strong>
+ <a
+ className="spacer-left medium"
+ href="https://www.sonarqube.org/whats-new/?referrer=sonarqube"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.see_whats_new
+ </a>
+ </h3>
+ <p>
+ <FormattedMessage
+ defaultMessage="system.version_is_availble"
+ id="system.version_is_availble"
+ values={
+ Object {
+ "version": <b>
+ SonarQube
+ 5.6.7
+ </b>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="spacer-top"
+ >
+ Version 5.6.7 description
+ </p>
+ <div
+ className="big-spacer-top"
+ >
+ <DateFormatter
+ date="2017-03-01"
+ long={true}
+ >
+ <Component />
+ </DateFormatter>
+ <a
+ className="spacer-left"
+ href="http://changelog.url/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.release_notes
+ </a>
+ </div>
+ <SystemUpgradeIntermediate
+ className="spacer-top"
+ upgrades={
+ Array [
+ Object {
+ "changeLogUrl": "http://changelog.url/",
+ "description": "Version 5.6.6 description",
+ "downloadDeveloperUrl": "http://download.url/developer",
+ "downloadUrl": "http://download.url/community",
+ "releaseDate": "2017-04-02",
+ "version": "5.6.6",
+ },
+ Object {
+ "changeLogUrl": "http://changelog.url/",
+ "description": "Version 5.6.5 description",
+ "downloadDeveloperUrl": "http://download.url/developer",
+ "downloadUrl": "http://download.url/community",
+ "releaseDate": "2017-03-01",
+ "version": "5.6.5",
+ },
+ ]
+ }
+ />
+ <div
+ className="big-spacer-top"
+ >
+ <a
+ className="button"
+ download="http://download.url/developer"
+ href="http://download.url/developer"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.download_x.5.6.7
+ </a>
+ <a
+ className="spacer-left"
+ href="https://redirect.sonarsource.com/doc/upgrading.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.how_to_upgrade
+ </a>
+ </div>
+</div>
+`;
+
+exports[`should display correctly 4`] = `
+<div
+ className="system-upgrade-version"
+>
+ <h3
+ className="h1 spacer-bottom"
+ >
+ <strong>
+ system.latest_version
+ </strong>
+ <a
+ className="spacer-left medium"
+ href="https://www.sonarqube.org/whats-new/?referrer=sonarqube"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.see_whats_new
+ </a>
+ </h3>
+ <p>
+ <FormattedMessage
+ defaultMessage="system.version_is_availble"
+ id="system.version_is_availble"
+ values={
+ Object {
+ "version": <b>
+ SonarQube
+ 5.6.7
+ </b>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="spacer-top"
+ >
+ Version 5.6.7 description
+ </p>
+ <div
+ className="big-spacer-top"
+ >
+ <DateFormatter
+ date="2017-03-01"
+ long={true}
+ >
+ <Component />
+ </DateFormatter>
+ <a
+ className="spacer-left"
+ href="http://changelog.url/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.release_notes
+ </a>
+ </div>
+ <SystemUpgradeIntermediate
+ className="spacer-top"
+ upgrades={
+ Array [
+ Object {
+ "changeLogUrl": "http://changelog.url/",
+ "description": "Version 5.6.6 description",
+ "downloadDeveloperUrl": "http://download.url/developer",
+ "downloadUrl": "http://download.url/community",
+ "releaseDate": "2017-04-02",
+ "version": "5.6.6",
+ },
+ Object {
+ "changeLogUrl": "http://changelog.url/",
+ "description": "Version 5.6.5 description",
+ "downloadDeveloperUrl": "http://download.url/developer",
+ "downloadUrl": "http://download.url/community",
+ "releaseDate": "2017-03-01",
+ "version": "5.6.5",
+ },
+ ]
+ }
+ />
+ <div
+ className="big-spacer-top"
+ >
+ <a
+ className="button"
+ download="http://download.url/enterprise"
+ href="http://download.url/enterprise"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.download_x.5.6.7
+ </a>
+ <a
+ className="spacer-left"
+ href="https://redirect.sonarsource.com/doc/upgrading.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.how_to_upgrade
+ </a>
+ </div>
+</div>
+`;
+
+exports[`should display correctly 5`] = `
+<div
+ className="system-upgrade-version"
+>
+ <h3
+ className="h1 spacer-bottom"
+ >
+ <strong>
+ system.latest_version
+ </strong>
+ <a
+ className="spacer-left medium"
+ href="https://www.sonarqube.org/whats-new/?referrer=sonarqube"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.see_whats_new
+ </a>
+ </h3>
+ <p>
+ <FormattedMessage
+ defaultMessage="system.version_is_availble"
+ id="system.version_is_availble"
+ values={
+ Object {
+ "version": <b>
+ SonarQube
+ 5.6.7
+ </b>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="spacer-top"
+ >
+ Version 5.6.7 description
+ </p>
+ <div
+ className="big-spacer-top"
+ >
+ <DateFormatter
+ date="2017-03-01"
+ long={true}
+ >
+ <Component />
+ </DateFormatter>
+ <a
+ className="spacer-left"
+ href="http://changelog.url/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.release_notes
+ </a>
+ </div>
+ <SystemUpgradeIntermediate
+ className="spacer-top"
+ upgrades={
+ Array [
+ Object {
+ "changeLogUrl": "http://changelog.url/",
+ "description": "Version 5.6.6 description",
+ "downloadDeveloperUrl": "http://download.url/developer",
+ "downloadUrl": "http://download.url/community",
+ "releaseDate": "2017-04-02",
+ "version": "5.6.6",
+ },
+ Object {
+ "changeLogUrl": "http://changelog.url/",
+ "description": "Version 5.6.5 description",
+ "downloadDeveloperUrl": "http://download.url/developer",
+ "downloadUrl": "http://download.url/community",
+ "releaseDate": "2017-03-01",
+ "version": "5.6.5",
+ },
+ ]
+ }
+ />
+ <div
+ className="big-spacer-top"
+ >
+ <a
+ className="button"
+ download="http://download.url/datacenter"
+ href="http://download.url/datacenter"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.download_x.5.6.7
+ </a>
+ <a
+ className="spacer-left"
+ href="https://redirect.sonarsource.com/doc/upgrading.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.how_to_upgrade
+ </a>
+ </div>
+</div>
+`;
+
+exports[`should display correctly 6`] = `
+<div
+ className="system-upgrade-version"
+>
+ <h3
+ className="h1 spacer-bottom"
+ >
+ <strong>
+ system.latest_version
+ </strong>
+ <a
+ className="spacer-left medium"
+ href="https://www.sonarqube.org/whats-new/?referrer=sonarqube"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.see_whats_new
+ </a>
+ </h3>
+ <p>
+ <FormattedMessage
+ defaultMessage="system.version_is_availble"
+ id="system.version_is_availble"
+ values={
+ Object {
+ "version": <b>
+ SonarQube
+ 5.6.7
+ </b>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="spacer-top"
+ >
+ Version 5.6.7 description
+ </p>
+ <div
+ className="big-spacer-top"
+ >
+ <DateFormatter
+ date="2017-03-01"
+ long={true}
+ >
+ <Component />
+ </DateFormatter>
+ <a
+ className="spacer-left"
+ href="http://changelog.url/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.release_notes
+ </a>
+ </div>
+ <SystemUpgradeIntermediate
+ className="spacer-top"
+ upgrades={Array []}
+ />
+ <div
+ className="big-spacer-top"
+ >
+ <a
+ className="button"
+ download="http://download.url/community"
+ href="http://download.url/community"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.download_x.5.6.7
+ </a>
+ <a
+ className="spacer-left"
+ href="https://redirect.sonarsource.com/doc/upgrading.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ system.how_to_upgrade
+ </a>
+ </div>
+</div>
+`;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 { SystemUpgrade } from '../../../types/system';
+import * as u from '../utils';
+
+describe('sortUpgrades', () => {
+ it('should sort correctly versions', () => {
+ expect(
+ u.sortUpgrades([
+ { version: '5.4.2' },
+ { version: '5.10' },
+ { version: '5.1' },
+ { version: '5.4' }
+ ] as SystemUpgrade[])
+ ).toEqual([{ version: '5.10' }, { version: '5.4.2' }, { version: '5.4' }, { version: '5.1' }]);
+ expect(
+ u.sortUpgrades([
+ { version: '5.10' },
+ { version: '5.1.2' },
+ { version: '6.0' },
+ { version: '6.9' }
+ ] as SystemUpgrade[])
+ ).toEqual([{ version: '6.9' }, { version: '6.0' }, { version: '5.10' }, { version: '5.1.2' }]);
+ });
+});
+
+describe('groupUpgrades', () => {
+ it('should group correctly', () => {
+ expect(
+ u.groupUpgrades([
+ { version: '5.10' },
+ { version: '5.4.2' },
+ { version: '5.4' },
+ { version: '5.1' }
+ ] as SystemUpgrade[])
+ ).toEqual([
+ [{ version: '5.10' }, { version: '5.4.2' }, { version: '5.4' }, { version: '5.1' }]
+ ]);
+ expect(
+ u.groupUpgrades([
+ { version: '6.9' },
+ { version: '6.7' },
+ { version: '6.0' },
+ { version: '5.10' },
+ { version: '5.4.2' }
+ ] as SystemUpgrade[])
+ ).toEqual([
+ [{ version: '6.9' }, { version: '6.7' }, { version: '6.0' }],
+ [{ version: '5.10' }, { version: '5.4.2' }]
+ ]);
+ });
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 { groupBy, sortBy } from 'lodash';
+import { SystemUpgrade } from '../../types/system';
+
+export function sortUpgrades(upgrades: SystemUpgrade[]): SystemUpgrade[] {
+ return sortBy(upgrades, [
+ (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: 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-2021 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 { SystemUpgrade } from '../../types/system';
+
+export function mockUpgrades(override: Partial<SystemUpgrade>): SystemUpgrade {
+ return {
+ version: '5.6.7',
+ description: 'Version 5.6.7 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ ...override
+ };
+}
qualifier.description.SVW=Potentially multi-level, management-oriented overview aggregation.
qualifier.description.APP=Single-level aggregation with a technical focus and a project-like homepage.
+
+#------------------------------------------------------------------------------
+#
+# Admin notification
+#
+#------------------------------------------------------------------------------
+admin_notification.update.new_minor_version=There’s a new version of SonarQube available. Update to enjoy the latest updates and features.
+admin_notification.update.new_patch=There’s an update available for your SonarQube instance. Please update to make sure you benefit from the latest security and bug fixes.
+admin_notification.update.pre_lts=You’re running a version of SonarQube that has reached end of life. Please upgrade to a supported version at your earliest convenience.
+admin_notification.update.previous_lts=You’re running a version of SonarQube that is past end of life. Please upgrade to a supported version immediately.
+
#------------------------------------------------------------------------------
#
# PROJECT LINKS