diff options
author | Wouter Admiraal <wouter.admiraal@sonarsource.com> | 2020-01-02 15:20:29 +0100 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2020-01-08 20:46:11 +0100 |
commit | 7e7b3471c9aef526a64325bb60755e9a45b42ade (patch) | |
tree | 821e7057bb94337135d22dcdfae08b83f7ea10ff /server/sonar-docs | |
parent | 8cdfa2d78c714a11a7f23608d45dd1976bc13ea3 (diff) | |
download | sonarqube-7e7b3471c9aef526a64325bb60755e9a45b42ade.tar.gz sonarqube-7e7b3471c9aef526a64325bb60755e9a45b42ade.zip |
SONAR-12886 Update LTS handling in static documentation
Diffstat (limited to 'server/sonar-docs')
9 files changed, 764 insertions, 20 deletions
diff --git a/server/sonar-docs/src/@types/types.d.ts b/server/sonar-docs/src/@types/types.d.ts index a4a11275bbb..b27e9f9f029 100644 --- a/server/sonar-docs/src/@types/types.d.ts +++ b/server/sonar-docs/src/@types/types.d.ts @@ -21,6 +21,7 @@ export type Dict<T> = { [key: string]: T }; export interface DocVersion { current: boolean; + lts?: boolean; value: string; } diff --git a/server/sonar-docs/src/components/Sidebar.tsx b/server/sonar-docs/src/components/Sidebar.tsx index 309206dfd3a..c27bd513186 100644 --- a/server/sonar-docs/src/components/Sidebar.tsx +++ b/server/sonar-docs/src/components/Sidebar.tsx @@ -165,10 +165,16 @@ export default class Sidebar extends React.PureComponent<Props, State> { render() { const { versions } = this.state; + const { version } = this.props; + const currentVersion = versions.find(v => v.current); + const ltsVersion = versions.find(v => v.lts); + const selectedVersionValue = - currentVersion && this.props.version === 'latest' ? currentVersion.value : this.props.version; + currentVersion && version === 'latest' ? currentVersion.value : version; const isOnCurrentVersion = !currentVersion || selectedVersionValue === currentVersion.value; + const isOnLTSVersion = ltsVersion && version === ltsVersion.value; + return ( <div className="page-sidebar"> <div className="sidebar-header"> @@ -176,7 +182,7 @@ export default class Sidebar extends React.PureComponent<Props, State> { <img alt="Continuous Code Quality" className="sidebar-logo" - src={`/${this.props.version}/images/SonarQubeIcon.svg`} + src={`/${version}/images/SonarQubeIcon.svg`} title="Continuous Code Quality" width="160" /> @@ -186,11 +192,10 @@ export default class Sidebar extends React.PureComponent<Props, State> { selectedVersionValue={selectedVersionValue} versions={versions} /> - {this.state.loaded && !isOnCurrentVersion && ( + {this.state.loaded && !isOnCurrentVersion && !isOnLTSVersion && ( <div className="alert alert-warning"> - This is an archived version of the doc for{' '} - <b>SonarQube version {this.props.version}</b>. <a href="/">See Documentation</a> for - current functionnality. + This is an archived version of the doc for <b>SonarQube version {version}</b>.{' '} + <a href="/">See Documentation</a> for current functionnality. </div> )} </div> @@ -207,21 +212,21 @@ export default class Sidebar extends React.PureComponent<Props, State> { <DownloadIcon /> SonarQube </a> <a href="https://community.sonarsource.com/" rel="noopener noreferrer" target="_blank"> - <img alt="Community" src={`/${this.props.version}/images/community.svg`} /> Community + <img alt="Community" src={`/${version}/images/community.svg`} /> Community </a> <a className="icon-only" href="https://twitter.com/SonarQube" rel="noopener noreferrer" target="_blank"> - <img alt="Twitter" src={`/${this.props.version}/images/twitter.svg`} /> + <img alt="Twitter" src={`/${version}/images/twitter.svg`} /> </a> <a className="icon-only" href="https://www.sonarqube.org/whats-new/" rel="noopener noreferrer" target="_blank"> - <img alt="Product News" src={`/${this.props.version}/images/newspaper.svg`} /> + <img alt="Product News" src={`/${version}/images/newspaper.svg`} /> <span className="tooltip">Product News</span> </a> </div> diff --git a/server/sonar-docs/src/components/VersionSelect.tsx b/server/sonar-docs/src/components/VersionSelect.tsx index 15ec735b8ad..3f9f61ccfca 100644 --- a/server/sonar-docs/src/components/VersionSelect.tsx +++ b/server/sonar-docs/src/components/VersionSelect.tsx @@ -62,7 +62,9 @@ export default class VersionSelect extends React.PureComponent<Props, State> { return ( <li key={version.value}> <a href={version.current ? '/' : '/' + version.value}> - <span className={version.current ? 'current' : ''}>{version.value}</span> + <span className={version.current || version.lts ? 'current' : ''}> + {version.value + (version.lts ? ' LTS' : '')} + </span> </a> </li> ); diff --git a/server/sonar-docs/src/components/__tests__/Sidebar-test.tsx b/server/sonar-docs/src/components/__tests__/Sidebar-test.tsx index 4ea1e61dcb2..0bc43821e0d 100644 --- a/server/sonar-docs/src/components/__tests__/Sidebar-test.tsx +++ b/server/sonar-docs/src/components/__tests__/Sidebar-test.tsx @@ -59,18 +59,23 @@ jest.mock('../navTreeUtils', () => { beforeEach(() => { (fetch as FetchMock).resetMocks(); (fetch as FetchMock).mockResponse(`[ - { "value": "2.0", "current": true }, + { "value": "3.0", "current": true }, + { "value": "2.0", "current": false, "lts": true }, { "value": "1.0", "current": false } ]`); }); -it('should render correctly', () => { +it('should render correctly', async () => { const wrapper = shallowRender(); - expect(wrapper).toMatchSnapshot(); + await new Promise(setImmediate); + + expect(wrapper).toMatchSnapshot('default'); + expect(wrapper.setProps({ version: '1.0' })).toMatchSnapshot('show warning'); + expect(wrapper.setProps({ version: '2.0' })).toMatchSnapshot('lts'); }); function shallowRender(props: Partial<Sidebar['props']> = {}) { - return shallow( + return shallow<Sidebar>( <Sidebar location={{ pathname: '/2.0/foo/baz/foo/bar' } as Location} pages={[ @@ -99,7 +104,7 @@ function shallowRender(props: Partial<Sidebar['props']> = {}) { } } as MarkdownRemark ]} - version="2.0" + version="3.0" {...props} /> ); diff --git a/server/sonar-docs/src/components/__tests__/VersionSelect-test.tsx b/server/sonar-docs/src/components/__tests__/VersionSelect-test.tsx new file mode 100644 index 00000000000..a0fef76725d --- /dev/null +++ b/server/sonar-docs/src/components/__tests__/VersionSelect-test.tsx @@ -0,0 +1,62 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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 'sonar-ui-common/helpers/testUtils'; +import OutsideClickHandler from '../OutsideClickHandler'; +import VersionSelect from '../VersionSelect'; + +it('should render correctly', () => { + expect(shallowRender()).toMatchSnapshot('default'); + + const wrapper = shallowRender(); + wrapper.setState({ open: true }); + expect(wrapper).toMatchSnapshot('open'); + + expect(shallowRender({ isOnCurrentVersion: true })).toMatchSnapshot('on current version'); +}); + +it('should handle open/closing the list', () => { + const wrapper = shallowRender(); + + click(wrapper.find('button')); + expect(wrapper.state().open).toBe(true); + click(wrapper.find('button')); + expect(wrapper.state().open).toBe(false); + + wrapper.setState({ open: true }); + wrapper.find(OutsideClickHandler).prop('onClickOutside')(); + expect(wrapper.state().open).toBe(false); +}); + +function shallowRender(props: Partial<VersionSelect['props']> = {}) { + return shallow<VersionSelect>( + <VersionSelect + isOnCurrentVersion={false} + selectedVersionValue="1.0" + versions={[ + { value: '3.0', current: true }, + { value: '2.0', current: false, lts: true }, + { value: '1.0', current: false } + ]} + {...props} + /> + ); +} diff --git a/server/sonar-docs/src/components/__tests__/__snapshots__/Sidebar-test.tsx.snap b/server/sonar-docs/src/components/__tests__/__snapshots__/Sidebar-test.tsx.snap index 5a05f9b2671..0fec9f778a0 100644 --- a/server/sonar-docs/src/components/__tests__/__snapshots__/Sidebar-test.tsx.snap +++ b/server/sonar-docs/src/components/__tests__/__snapshots__/Sidebar-test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should render correctly 1`] = ` +exports[`should render correctly: default 1`] = ` <div className="page-sidebar" > @@ -13,15 +13,294 @@ exports[`should render correctly 1`] = ` <img alt="Continuous Code Quality" className="sidebar-logo" - src="/2.0/images/SonarQubeIcon.svg" + src="/3.0/images/SonarQubeIcon.svg" title="Continuous Code Quality" width="160" /> </ForwardRef> <VersionSelect isOnCurrentVersion={true} + selectedVersionValue="3.0" + versions={ + Array [ + Object { + "current": true, + "value": "3.0", + }, + Object { + "current": false, + "lts": true, + "value": "2.0", + }, + Object { + "current": false, + "value": "1.0", + }, + ] + } + /> + </div> + <div + className="page-indexes" + > + <Search + navigation={ + Array [ + "/foo/", + Object { + "children": Array [ + "/foo/bar/", + "/foo/baz/", + Object { + "children": Array [ + "/foo/baz/bar/", + "/foo/baz/foo/", + Object { + "children": Array [ + "/foo/baz/foo/bar/", + "/foo/baz/foo/baz", + ], + "title": "Foo Baz Foo subs", + }, + ], + "title": "Foo Baz subs", + }, + ], + "title": "Foo subs", + }, + "/bar/", + Object { + "children": Array [ + Object { + "title": "External link 1", + "url": "http://example.com/1", + }, + "/bar/foo/", + ], + "title": "Bar subs", + }, + Object { + "title": "External link 2", + "url": "http://example.com/2", + }, + ] + } + onResultsChange={[Function]} + pages={ + Array [ + Object { + "fields": Object { + "slug": "/foo/", + }, + "frontmatter": Object { + "title": "Foo", + }, + }, + Object { + "fields": Object { + "slug": "/foo/baz/bar", + }, + "frontmatter": Object { + "title": "Foo Baz Bar", + }, + }, + Object { + "fields": Object { + "slug": "/bar/", + }, + "frontmatter": Object { + "title": "Bar", + }, + }, + ] + } + /> + <nav> + <PageLink + className="page-indexes-link" + key="/foo/" + location={ + Object { + "pathname": "/2.0/foo/baz/foo/bar", + } + } + node={ + Object { + "fields": Object { + "slug": "/foo/", + }, + "frontmatter": Object { + "title": "Foo", + }, + } + } + /> + <CategoryLink + key="Foo subs" + location={ + Object { + "pathname": "/2.0/foo/baz/foo/bar", + } + } + openByDefault={true} + title="Foo subs" + > + <CategoryLink + key="Foo Baz subs" + location={ + Object { + "pathname": "/2.0/foo/baz/foo/bar", + } + } + openByDefault={true} + title="Foo Baz subs" + > + <Component /> + <CategoryLink + key="Foo Baz Foo subs" + location={ + Object { + "pathname": "/2.0/foo/baz/foo/bar", + } + } + openByDefault={true} + title="Foo Baz Foo subs" + /> + </CategoryLink> + </CategoryLink> + <PageLink + className="page-indexes-link" + key="/bar/" + location={ + Object { + "pathname": "/2.0/foo/baz/foo/bar", + } + } + node={ + Object { + "fields": Object { + "slug": "/bar/", + }, + "frontmatter": Object { + "title": "Bar", + }, + } + } + /> + <CategoryLink + key="Bar subs" + location={ + Object { + "pathname": "/2.0/foo/baz/foo/bar", + } + } + openByDefault={false} + title="Bar subs" + > + <ExternalLink + external="http://example.com/1" + key="External link 1" + title="External link 1" + /> + </CategoryLink> + <ExternalLink + external="http://example.com/2" + key="External link 2" + title="External link 2" + /> + </nav> + </div> + <div + className="sidebar-footer" + > + <a + href="https://www.sonarqube.org/" + rel="noopener noreferrer" + target="_blank" + > + <DownloadIcon /> + SonarQube + </a> + <a + href="https://community.sonarsource.com/" + rel="noopener noreferrer" + target="_blank" + > + <img + alt="Community" + src="/3.0/images/community.svg" + /> + Community + </a> + <a + className="icon-only" + href="https://twitter.com/SonarQube" + rel="noopener noreferrer" + target="_blank" + > + <img + alt="Twitter" + src="/3.0/images/twitter.svg" + /> + </a> + <a + className="icon-only" + href="https://www.sonarqube.org/whats-new/" + rel="noopener noreferrer" + target="_blank" + > + <img + alt="Product News" + src="/3.0/images/newspaper.svg" + /> + <span + className="tooltip" + > + Product News + </span> + </a> + </div> +</div> +`; + +exports[`should render correctly: lts 1`] = ` +<div + className="page-sidebar" +> + <div + className="sidebar-header" + > + <ForwardRef + to="/" + > + <img + alt="Continuous Code Quality" + className="sidebar-logo" + src="/2.0/images/SonarQubeIcon.svg" + title="Continuous Code Quality" + width="160" + /> + </ForwardRef> + <VersionSelect + isOnCurrentVersion={false} selectedVersionValue="2.0" - versions={Array []} + versions={ + Array [ + Object { + "current": true, + "value": "3.0", + }, + Object { + "current": false, + "lts": true, + "value": "2.0", + }, + Object { + "current": false, + "value": "1.0", + }, + ] + } /> </div> <div @@ -246,3 +525,283 @@ exports[`should render correctly 1`] = ` </div> </div> `; + +exports[`should render correctly: show warning 1`] = ` +<div + className="page-sidebar" +> + <div + className="sidebar-header" + > + <ForwardRef + to="/" + > + <img + alt="Continuous Code Quality" + className="sidebar-logo" + src="/1.0/images/SonarQubeIcon.svg" + title="Continuous Code Quality" + width="160" + /> + </ForwardRef> + <VersionSelect + isOnCurrentVersion={false} + selectedVersionValue="1.0" + versions={ + Array [ + Object { + "current": true, + "value": "3.0", + }, + Object { + "current": false, + "lts": true, + "value": "2.0", + }, + Object { + "current": false, + "value": "1.0", + }, + ] + } + /> + <div + className="alert alert-warning" + > + This is an archived version of the doc for + <b> + SonarQube version + 1.0 + </b> + . + + <a + href="/" + > + See Documentation + </a> + for current functionnality. + </div> + </div> + <div + className="page-indexes" + > + <Search + navigation={ + Array [ + "/foo/", + Object { + "children": Array [ + "/foo/bar/", + "/foo/baz/", + Object { + "children": Array [ + "/foo/baz/bar/", + "/foo/baz/foo/", + Object { + "children": Array [ + "/foo/baz/foo/bar/", + "/foo/baz/foo/baz", + ], + "title": "Foo Baz Foo subs", + }, + ], + "title": "Foo Baz subs", + }, + ], + "title": "Foo subs", + }, + "/bar/", + Object { + "children": Array [ + Object { + "title": "External link 1", + "url": "http://example.com/1", + }, + "/bar/foo/", + ], + "title": "Bar subs", + }, + Object { + "title": "External link 2", + "url": "http://example.com/2", + }, + ] + } + onResultsChange={[Function]} + pages={ + Array [ + Object { + "fields": Object { + "slug": "/foo/", + }, + "frontmatter": Object { + "title": "Foo", + }, + }, + Object { + "fields": Object { + "slug": "/foo/baz/bar", + }, + "frontmatter": Object { + "title": "Foo Baz Bar", + }, + }, + Object { + "fields": Object { + "slug": "/bar/", + }, + "frontmatter": Object { + "title": "Bar", + }, + }, + ] + } + /> + <nav> + <PageLink + className="page-indexes-link" + key="/foo/" + location={ + Object { + "pathname": "/2.0/foo/baz/foo/bar", + } + } + node={ + Object { + "fields": Object { + "slug": "/foo/", + }, + "frontmatter": Object { + "title": "Foo", + }, + } + } + /> + <CategoryLink + key="Foo subs" + location={ + Object { + "pathname": "/2.0/foo/baz/foo/bar", + } + } + openByDefault={true} + title="Foo subs" + > + <CategoryLink + key="Foo Baz subs" + location={ + Object { + "pathname": "/2.0/foo/baz/foo/bar", + } + } + openByDefault={true} + title="Foo Baz subs" + > + <Component /> + <CategoryLink + key="Foo Baz Foo subs" + location={ + Object { + "pathname": "/2.0/foo/baz/foo/bar", + } + } + openByDefault={true} + title="Foo Baz Foo subs" + /> + </CategoryLink> + </CategoryLink> + <PageLink + className="page-indexes-link" + key="/bar/" + location={ + Object { + "pathname": "/2.0/foo/baz/foo/bar", + } + } + node={ + Object { + "fields": Object { + "slug": "/bar/", + }, + "frontmatter": Object { + "title": "Bar", + }, + } + } + /> + <CategoryLink + key="Bar subs" + location={ + Object { + "pathname": "/2.0/foo/baz/foo/bar", + } + } + openByDefault={false} + title="Bar subs" + > + <ExternalLink + external="http://example.com/1" + key="External link 1" + title="External link 1" + /> + </CategoryLink> + <ExternalLink + external="http://example.com/2" + key="External link 2" + title="External link 2" + /> + </nav> + </div> + <div + className="sidebar-footer" + > + <a + href="https://www.sonarqube.org/" + rel="noopener noreferrer" + target="_blank" + > + <DownloadIcon /> + SonarQube + </a> + <a + href="https://community.sonarsource.com/" + rel="noopener noreferrer" + target="_blank" + > + <img + alt="Community" + src="/1.0/images/community.svg" + /> + Community + </a> + <a + className="icon-only" + href="https://twitter.com/SonarQube" + rel="noopener noreferrer" + target="_blank" + > + <img + alt="Twitter" + src="/1.0/images/twitter.svg" + /> + </a> + <a + className="icon-only" + href="https://www.sonarqube.org/whats-new/" + rel="noopener noreferrer" + target="_blank" + > + <img + alt="Product News" + src="/1.0/images/newspaper.svg" + /> + <span + className="tooltip" + > + Product News + </span> + </a> + </div> +</div> +`; diff --git a/server/sonar-docs/src/components/__tests__/__snapshots__/VersionSelect-test.tsx.snap b/server/sonar-docs/src/components/__tests__/__snapshots__/VersionSelect-test.tsx.snap new file mode 100644 index 00000000000..b91c29e7a44 --- /dev/null +++ b/server/sonar-docs/src/components/__tests__/__snapshots__/VersionSelect-test.tsx.snap @@ -0,0 +1,109 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly: default 1`] = ` +<div + className="version-select" +> + <button + onClick={[Function]} + type="button" + > + Docs + <span + className="" + > + 1.0 + </span> + <ChevronDownIcon + size={10} + /> + </button> +</div> +`; + +exports[`should render correctly: on current version 1`] = ` +<div + className="version-select" +> + <button + onClick={[Function]} + type="button" + > + Docs + <span + className="current" + > + 1.0 + </span> + <ChevronDownIcon + size={10} + /> + </button> +</div> +`; + +exports[`should render correctly: open 1`] = ` +<div + className="version-select" +> + <button + onClick={[Function]} + type="button" + > + Docs + <span + className="" + > + 1.0 + </span> + <ChevronUpIcon + size={10} + /> + </button> + <OutsideClickHandler + onClickOutside={[Function]} + > + <ul> + <li + key="3.0" + > + <a + href="/" + > + <span + className="current" + > + 3.0 + </span> + </a> + </li> + <li + key="2.0" + > + <a + href="/2.0" + > + <span + className="current" + > + 2.0 LTS + </span> + </a> + </li> + <li + key="1.0" + > + <a + href="/1.0" + > + <span + className="" + > + 1.0 + </span> + </a> + </li> + </ul> + </OutsideClickHandler> +</div> +`; diff --git a/server/sonar-docs/src/layouts/layout.css b/server/sonar-docs/src/layouts/layout.css index 25d06883f9f..6696f42a55d 100644 --- a/server/sonar-docs/src/layouts/layout.css +++ b/server/sonar-docs/src/layouts/layout.css @@ -493,8 +493,9 @@ a.search-result .note { font-size: 15px; margin: 0; padding: 4px 16px; - text-align: center; + text-align: left; transition: all 0.2s ease; + white-space: nowrap; } .version-select ul li:hover { diff --git a/server/sonar-docs/static/DocsVersions.json b/server/sonar-docs/static/DocsVersions.json index 19772b03b16..501eab58d1e 100644 --- a/server/sonar-docs/static/DocsVersions.json +++ b/server/sonar-docs/static/DocsVersions.json @@ -1,6 +1,6 @@ [ { "value": "7.3", "current": true }, { "value": "7.2", "current": false }, - { "value": "7.1", "current": false }, + { "value": "7.1", "current": false, "lts": true }, { "value": "7.0", "current": false } ] |