aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/app
diff options
context:
space:
mode:
authorIsmail Cherri <ismail.cherri@sonarsource.com>2024-03-28 18:08:51 +0100
committersonartech <sonartech@sonarsource.com>2024-04-03 20:02:41 +0000
commit62458cc73c69ff89de412fe3fcaff19cb88dd0bb (patch)
treeb72c5e7e38bd20824f7663a9bfde869820eca0a5 /server/sonar-web/src/main/js/app
parenta5ad37c33725d0bebd76c00cfad10eb0ff985f23 (diff)
downloadsonarqube-62458cc73c69ff89de412fe3fcaff19cb88dd0bb.tar.gz
sonarqube-62458cc73c69ff89de412fe3fcaff19cb88dd0bb.zip
SONAR-21909 Add version status badge in Footer and System Information
Diffstat (limited to 'server/sonar-web/src/main/js/app')
-rw-r--r--server/sonar-web/src/main/js/app/components/GlobalFooter.tsx28
-rw-r--r--server/sonar-web/src/main/js/app/components/__tests__/GlobalFooter-test.tsx34
2 files changed, 48 insertions, 14 deletions
diff --git a/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx b/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx
index e98c67615ad..085e75a378d 100644
--- a/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx
+++ b/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx
@@ -27,21 +27,23 @@ import {
themeBorder,
themeColor,
} from 'design-system';
-import * as React from 'react';
+import React from 'react';
+import { useIntl } from 'react-intl';
import InstanceMessage from '../../components/common/InstanceMessage';
+import AppVersionStatus from '../../components/shared/AppVersionStatus';
import { useDocUrl } from '../../helpers/docs';
import { getEdition } from '../../helpers/editions';
-import { translate, translateWithParameters } from '../../helpers/l10n';
+import { useAppState } from './app-state/withAppStateContext';
import GlobalFooterBranding from './GlobalFooterBranding';
-import { AppStateContext } from './app-state/AppStateContext';
interface GlobalFooterProps {
hideLoggedInInfo?: boolean;
}
export default function GlobalFooter({ hideLoggedInInfo }: Readonly<GlobalFooterProps>) {
- const appState = React.useContext(AppStateContext);
+ const appState = useAppState();
const currentEdition = appState?.edition && getEdition(appState.edition);
+ const intl = useIntl();
const docUrl = useDocUrl();
@@ -52,12 +54,14 @@ export default function GlobalFooter({ hideLoggedInInfo }: Readonly<GlobalFooter
<FlagMessage className="sw-mb-4" id="evaluation_warning" variant="warning">
<p>
<span className="sw-body-md-highlight">
- {translate('footer.production_database_warning')}
+ {intl.formatMessage({ id: 'footer.production_database_warning' })}
</span>
<br />
- <InstanceMessage message={translate('footer.production_database_explanation')} />
+ <InstanceMessage
+ message={intl.formatMessage({ id: 'footer.production_database_explanation' })}
+ />
</p>
</FlagMessage>
)}
@@ -70,7 +74,7 @@ export default function GlobalFooter({ hideLoggedInInfo }: Readonly<GlobalFooter
{!hideLoggedInInfo && appState?.version && (
<li className="sw-code">
- {translateWithParameters('footer.version_x', appState.version)}
+ <AppVersionStatus />
</li>
)}
@@ -79,7 +83,7 @@ export default function GlobalFooter({ hideLoggedInInfo }: Readonly<GlobalFooter
highlight={LinkHighlight.CurrentColor}
to="https://www.gnu.org/licenses/lgpl-3.0.txt"
>
- {translate('footer.license')}
+ {intl.formatMessage({ id: 'footer.license' })}
</LinkStandalone>
</li>
@@ -88,13 +92,13 @@ export default function GlobalFooter({ hideLoggedInInfo }: Readonly<GlobalFooter
highlight={LinkHighlight.CurrentColor}
to="https://community.sonarsource.com/c/help/sq"
>
- {translate('footer.community')}
+ {intl.formatMessage({ id: 'footer.community' })}
</LinkStandalone>
</li>
<li>
<LinkStandalone highlight={LinkHighlight.CurrentColor} to={docUrl('/')}>
- {translate('footer.documentation')}
+ {intl.formatMessage({ id: 'footer.documentation' })}
</LinkStandalone>
</li>
@@ -103,14 +107,14 @@ export default function GlobalFooter({ hideLoggedInInfo }: Readonly<GlobalFooter
highlight={LinkHighlight.CurrentColor}
to={docUrl('/instance-administration/plugin-version-matrix/')}
>
- {translate('footer.plugins')}
+ {intl.formatMessage({ id: 'footer.plugins' })}
</LinkStandalone>
</li>
{!hideLoggedInInfo && (
<li>
<LinkStandalone highlight={LinkHighlight.CurrentColor} to="/web_api">
- {translate('footer.web_api')}
+ {intl.formatMessage({ id: 'footer.web_api' })}
</LinkStandalone>
</li>
)}
diff --git a/server/sonar-web/src/main/js/app/components/__tests__/GlobalFooter-test.tsx b/server/sonar-web/src/main/js/app/components/__tests__/GlobalFooter-test.tsx
index 1314125f386..4c0503d5c2d 100644
--- a/server/sonar-web/src/main/js/app/components/__tests__/GlobalFooter-test.tsx
+++ b/server/sonar-web/src/main/js/app/components/__tests__/GlobalFooter-test.tsx
@@ -18,6 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import SystemServiceMock from '../../../api/mocks/SystemServiceMock';
import { mockAppState } from '../../../helpers/testMocks';
import { renderComponent } from '../../../helpers/testReactTestingUtils';
import { byRole, byText } from '../../../helpers/testSelector';
@@ -26,7 +27,13 @@ import { EditionKey } from '../../../types/editions';
import { FCProps } from '../../../types/misc';
import GlobalFooter from '../GlobalFooter';
-it('should render the logged-in information', () => {
+const systemMock = new SystemServiceMock();
+
+afterEach(() => {
+ systemMock.reset();
+});
+
+it('should render the logged-in information', async () => {
renderGlobalFooter();
expect(ui.databaseWarningMessage.query()).not.toBeInTheDocument();
@@ -35,9 +42,26 @@ it('should render the logged-in information', () => {
expect(byText('Community Edition').get()).toBeInTheDocument();
expect(ui.versionLabel('4.2').get()).toBeInTheDocument();
+ expect(await ui.ltaDocumentationLinkActive.find()).toBeInTheDocument();
expect(ui.apiLink.get()).toBeInTheDocument();
});
+it('should render the inactive version and cleanup build number', async () => {
+ systemMock.setSystemUpgrades({ installedVersionActive: false });
+ renderGlobalFooter({}, { version: '4.2 (build 12345)' });
+
+ expect(ui.versionLabel('4.2.12345').get()).toBeInTheDocument();
+ expect(await ui.ltaDocumentationLinkInactive.find()).toBeInTheDocument();
+});
+
+it('should active status if undefined', () => {
+ systemMock.setSystemUpgrades({ installedVersionActive: undefined });
+ renderGlobalFooter({}, { version: '4.2 (build 12345)' });
+
+ expect(ui.ltaDocumentationLinkInactive.query()).not.toBeInTheDocument();
+ expect(ui.ltaDocumentationLinkActive.query()).not.toBeInTheDocument();
+});
+
it('should not render missing logged-in information', () => {
renderGlobalFooter({}, { edition: undefined, version: '' });
@@ -84,7 +108,7 @@ const ui = {
databaseWarningMessage: byText('footer.production_database_warning'),
versionLabel: (version?: string) =>
- version ? byText(`footer.version_x.${version}`) : byText(/footer\.version_x/),
+ version ? byText(/footer\.version\.*(\d.\d)/) : byText(/footer\.version/),
// links
websiteLink: byRole('link', { name: 'SonarQubeâ„¢' }),
@@ -94,4 +118,10 @@ const ui = {
docsLink: byRole('link', { name: 'opens_in_new_window footer.documentation' }),
pluginsLink: byRole('link', { name: 'opens_in_new_window footer.plugins' }),
apiLink: byRole('link', { name: 'footer.web_api' }),
+ ltaDocumentationLinkActive: byRole('link', {
+ name: `footer.version.status.active open_in_new_window`,
+ }),
+ ltaDocumentationLinkInactive: byRole('link', {
+ name: `footer.version.status.inactive open_in_new_window`,
+ }),
};