diff options
author | Jeremy Davis <jeremy.davis@sonarsource.com> | 2024-02-05 16:26:24 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2024-02-06 16:38:17 +0000 |
commit | c744505c7165e2fae69bcff7617a16d9d66944c1 (patch) | |
tree | 1e4c3e68004a4494794297dea7ed465749aeedae | |
parent | 06065657445f4e4511cc3f58d269716584f58e18 (diff) | |
download | sonarqube-c744505c7165e2fae69bcff7617a16d9d66944c1.tar.gz sonarqube-c744505c7165e2fae69bcff7617a16d9d66944c1.zip |
SONAR-21565 Migrate Global Footer to the new UI
7 files changed, 85 insertions, 117 deletions
diff --git a/server/sonar-web/design-system/src/helpers/constants.ts b/server/sonar-web/design-system/src/helpers/constants.ts index b7dbb637131..0b18515f3e5 100644 --- a/server/sonar-web/design-system/src/helpers/constants.ts +++ b/server/sonar-web/design-system/src/helpers/constants.ts @@ -63,7 +63,7 @@ export const LAYOUT_PROJECT_NAV_HEIGHT = 108; export const LAYOUT_LOGO_MARGIN_RIGHT = 45; export const LAYOUT_LOGO_MAX_HEIGHT = 40; export const LAYOUT_LOGO_MAX_WIDTH = 150; -export const LAYOUT_FOOTER_HEIGHT = 60; +export const LAYOUT_FOOTER_HEIGHT = 69; export const LAYOUT_NOTIFICATIONSBAR_WIDTH = 350; export const CORE_CONCEPTS_WIDTH = 350; 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 2a613a95828..adee7ea7bcf 100644 --- a/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx +++ b/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx @@ -17,12 +17,18 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { LargeCenteredLayout } from 'design-system'; +import styled from '@emotion/styled'; +import { + DiscreetLink, + FlagMessage, + LAYOUT_VIEWPORT_MIN_WIDTH, + PageContentFontWrapper, + themeBorder, + themeColor, +} from 'design-system'; import * as React from 'react'; -import DocLink from '../../components/common/DocLink'; import InstanceMessage from '../../components/common/InstanceMessage'; -import Link from '../../components/common/Link'; -import { Alert } from '../../components/ui/Alert'; +import { useDocUrl } from '../../helpers/docs'; import { getEdition } from '../../helpers/editions'; import { translate, translateWithParameters } from '../../helpers/l10n'; import GlobalFooterBranding from './GlobalFooterBranding'; @@ -36,62 +42,66 @@ export default function GlobalFooter({ hideLoggedInInfo }: GlobalFooterProps) { const appState = React.useContext(AppStateContext); const currentEdition = appState?.edition && getEdition(appState.edition); + const docUrl = useDocUrl(); + return ( - <div className="page-footer page-container" id="footer"> - <LargeCenteredLayout className=" sw-flex sw-flex-col sw-items-center"> + <StyledFooter className="sw-p-6" id="footer"> + <PageContentFontWrapper className="sw-body-sm sw-h-full sw-flex sw-flex-col sw-items-stretch"> {appState?.productionDatabase === false && ( - <Alert display="inline" id="evaluation_warning" variant="warning"> - <p className="big">{translate('footer.production_database_warning')}</p> + <FlagMessage className="sw-mb-4" id="evaluation_warning" variant="warning"> <p> + <span className="sw-body-md-highlight"> + {translate('footer.production_database_warning')} + </span> + <br /> <InstanceMessage message={translate('footer.production_database_explanation')} /> </p> - </Alert> + </FlagMessage> )} - <GlobalFooterBranding /> + <div className="sw-flex sw-justify-between sw-items-center"> + <GlobalFooterBranding /> - <ul className="page-footer-menu"> - {!hideLoggedInInfo && currentEdition && ( - <li className="page-footer-menu-item">{currentEdition.name}</li> - )} - {!hideLoggedInInfo && appState?.version && ( - <li className="page-footer-menu-item"> - {translateWithParameters('footer.version_x', appState.version)} + <ul className="sw-flex sw-items-center sw-gap-3 sw-ml-4"> + {!hideLoggedInInfo && currentEdition && <li>{currentEdition.name}</li>} + {!hideLoggedInInfo && appState?.version && ( + <li className="sw-code"> + {translateWithParameters('footer.version_x', appState.version)} + </li> + )} + <li> + <DiscreetLink to="https://www.gnu.org/licenses/lgpl-3.0.txt"> + {translate('footer.license')} + </DiscreetLink> + </li> + <li> + <DiscreetLink to="https://community.sonarsource.com/c/help/sq"> + {translate('footer.community')} + </DiscreetLink> </li> - )} - <li className="page-footer-menu-item"> - <a - href="https://www.gnu.org/licenses/lgpl-3.0.txt" - rel="noopener noreferrer" - target="_blank" - > - {translate('footer.license')} - </a> - </li> - <li className="page-footer-menu-item"> - <a - href="https://community.sonarsource.com/c/help/sq" - rel="noopener noreferrer" - target="_blank" - > - {translate('footer.community')} - </a> - </li> - <li className="page-footer-menu-item"> - <DocLink to="/">{translate('footer.documentation')}</DocLink> - </li> - <li className="page-footer-menu-item"> - <DocLink to="/instance-administration/plugin-version-matrix/"> - {translate('footer.plugins')} - </DocLink> - </li> - {!hideLoggedInInfo && ( - <li className="page-footer-menu-item"> - <Link to="/web_api">{translate('footer.web_api')}</Link> + <li> + <DiscreetLink to={docUrl('/')}>{translate('footer.documentation')}</DiscreetLink> </li> - )} - </ul> - </LargeCenteredLayout> - </div> + <li> + <DiscreetLink to={docUrl('/instance-administration/plugin-version-matrix/')}> + {translate('footer.plugins')} + </DiscreetLink> + </li> + {!hideLoggedInInfo && ( + <li> + <DiscreetLink to="/web_api">{translate('footer.web_api')}</DiscreetLink> + </li> + )} + </ul> + </div> + </PageContentFontWrapper> + </StyledFooter> ); } + +const StyledFooter = styled.div` + box-sizing: border-box; + min-width: ${LAYOUT_VIEWPORT_MIN_WIDTH}px; + border-top: ${themeBorder('default')}; + background-color: ${themeColor('backgroundSecondary')}; +`; diff --git a/server/sonar-web/src/main/js/app/components/GlobalFooterBranding.tsx b/server/sonar-web/src/main/js/app/components/GlobalFooterBranding.tsx index 6b360908496..b9a5ddbf252 100644 --- a/server/sonar-web/src/main/js/app/components/GlobalFooterBranding.tsx +++ b/server/sonar-web/src/main/js/app/components/GlobalFooterBranding.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { DiscreetLink } from 'design-system'; import * as React from 'react'; import { isOfficial } from '../../helpers/system'; @@ -26,30 +27,21 @@ export default function GlobalFooterBranding() { return official ? ( <div> SonarQube™ technology is powered by{' '} - <a href="https://www.sonarsource.com" rel="noopener noreferrer" target="_blank"> - SonarSource SA - </a> + <DiscreetLink to="https://www.sonarsource.com">SonarSource SA</DiscreetLink> </div> ) : ( <div> This application is based on{' '} - <a - href="https://www.sonarsource.com/products/sonarqube/?referrer=sonarqube" - rel="noopener noreferrer" - target="_blank" + <DiscreetLink + to="https://www.sonarsource.com/products/sonarqube/?referrer=sonarqube" title="SonarQube™" > SonarQube™ - </a>{' '} + </DiscreetLink>{' '} but is <strong>not</strong> an official version provided by{' '} - <a - href="https://www.sonarsource.com" - rel="noopener noreferrer" - target="_blank" - title="SonarSource SA" - > + <DiscreetLink to="https://www.sonarsource.com" title="SonarSource SA"> SonarSource SA - </a> + </DiscreetLink> . </div> ); diff --git a/server/sonar-web/src/main/js/app/styles/components/page.css b/server/sonar-web/src/main/js/app/styles/components/page.css index 61910dc6b45..812f7cf6cc9 100644 --- a/server/sonar-web/src/main/js/app/styles/components/page.css +++ b/server/sonar-web/src/main/js/app/styles/components/page.css @@ -127,37 +127,6 @@ margin-top: 6px; } -.page-footer { - min-height: 60px; - padding: 10px; - line-height: 1.5; - border-top: 1px solid var(--barBorderColor); - box-sizing: border-box; - background-color: var(--barBackgroundColor); - color: #595959; - font-size: var(--smallFontSize); - text-align: center; -} - -.sidebar-page #footer > div { - padding-left: 410px; -} - -.sidebar-page #footer > div div, -.sidebar-page #footer > div .page-footer-menu { - max-width: 980px; -} - -.page-footer-menu-item { - display: inline-block; -} - -.page-footer-menu-item + .page-footer-menu-item::before { - content: '-'; - padding: 0 calc(0.5 * var(--gridSize)); - user-select: none; -} - .page-with-sidebar { display: flex; } @@ -304,12 +273,6 @@ padding-right: 20px; } -@media (min-width: 1920px) { - .sidebar-page #footer > div { - padding-left: 500px; - } -} - @media (max-width: 1320px) { .layout-page-side-outer { width: 300px; diff --git a/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx b/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx index 1b1573006e6..f712711fcd7 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx @@ -1093,7 +1093,7 @@ export class App extends React.PureComponent<Props, State> { aria-label={openIssue ? translate('list_of_issues') : translate('filters')} data-testid="issues-nav-bar" className="issues-nav-bar sw-overflow-y-auto issue-filters-list" - style={{ height: `calc((100vh - ${top}px) - 60px)` }} // 60px (footer) + style={{ height: `calc((100vh - ${top}px) - ${LAYOUT_FOOTER_HEIGHT}px)` }} > <div className="sw-w-[300px] lg:sw-w-[390px] sw-h-full"> <A11ySkipTarget diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx index cb994ed1c52..1a464436c81 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx @@ -382,17 +382,19 @@ export class SidebarClass extends React.PureComponent<Props> { <BasicSeparator className="sw-my-4" /> - <AuthorFacet - author={query.author} - component={component} - fetching={this.props.loadingFacets.author === true} - loadSearchResultCount={this.props.loadSearchResultCount} - onChange={this.props.onFilterChange} - onToggle={this.props.onFacetToggle} - open={!!openFacets.author} - query={query} - stats={facets.author} - /> + <div className="sw-mb-4"> + <AuthorFacet + author={query.author} + component={component} + fetching={this.props.loadingFacets.author === true} + loadSearchResultCount={this.props.loadSearchResultCount} + onChange={this.props.onFilterChange} + onToggle={this.props.onFacetToggle} + open={!!openFacets.author} + query={query} + stats={facets.author} + /> + </div> </> )} </> diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx index 53e91fabb82..e57a7822858 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx @@ -19,6 +19,7 @@ */ import styled from '@emotion/styled'; import { + LAYOUT_FOOTER_HEIGHT, LargeCenteredLayout, PageContentFontWrapper, Spinner, @@ -235,7 +236,7 @@ export class AllProjects extends React.PureComponent<Props, State> { <section aria-label={translate('filters')} className="sw-overflow-y-auto project-filters-list" - style={{ height: `calc((100vh - ${top}px) - 60px)` }} // 60 for the footer + style={{ height: `calc((100vh - ${top}px) - ${LAYOUT_FOOTER_HEIGHT}px)` }} > <div className="sw-w-[300px] lg:sw-w-[390px]"> <A11ySkipTarget |