diff options
author | Wouter Admiraal <wouter.admiraal@sonarsource.com> | 2019-01-17 08:50:30 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2019-02-11 09:11:24 +0100 |
commit | b6aeddaea44525337d14ed3566fcd5f08d1e671f (patch) | |
tree | c282b7f8b88b6c945e507465aa321e52fb4c37b9 /server/sonar-web/src/main/js/components/ui | |
parent | 8b7cd93d7a751fd49e8df3faef1cf03e320f470a (diff) | |
download | sonarqube-b6aeddaea44525337d14ed3566fcd5f08d1e671f.tar.gz sonarqube-b6aeddaea44525337d14ed3566fcd5f08d1e671f.zip |
SONAR-8697 Enable keyboard file navigation in Code page
Diffstat (limited to 'server/sonar-web/src/main/js/components/ui')
6 files changed, 391 insertions, 0 deletions
diff --git a/server/sonar-web/src/main/js/components/ui/FilesCounter.tsx b/server/sonar-web/src/main/js/components/ui/FilesCounter.tsx new file mode 100644 index 00000000000..09ef95d5005 --- /dev/null +++ b/server/sonar-web/src/main/js/components/ui/FilesCounter.tsx @@ -0,0 +1,45 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import { translate } from '../../helpers/l10n'; +import { formatMeasure } from '../../helpers/measures'; + +interface Props { + className?: string; + current?: number; + total: number; +} + +export default function FilesCounter({ className, current, total }: Props) { + return ( + <span className={className}> + <strong> + {current !== undefined && ( + <span> + {formatMeasure(current, 'INT')} + {' / '} + </span> + )} + {formatMeasure(total, 'INT')} + </strong>{' '} + {translate('component_measures.files')} + </span> + ); +} diff --git a/server/sonar-web/src/main/js/components/ui/PageActions.tsx b/server/sonar-web/src/main/js/components/ui/PageActions.tsx new file mode 100644 index 00000000000..4e6d6386c2a --- /dev/null +++ b/server/sonar-web/src/main/js/components/ui/PageActions.tsx @@ -0,0 +1,84 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import FilesCounter from './FilesCounter'; +import { translate } from '../../helpers/l10n'; + +interface Props { + current?: number; + isFile?: boolean; + paging?: T.Paging; + showPaging?: boolean; + showShortcuts?: boolean; + totalLoadedComponents?: number; +} + +export default function PageActions(props: Props) { + const { isFile, paging, showPaging, showShortcuts, totalLoadedComponents } = props; + let total = 0; + + if (showPaging && totalLoadedComponents) { + total = totalLoadedComponents; + } else if (paging !== undefined) { + total = isFile && totalLoadedComponents ? totalLoadedComponents : paging.total; + } + + return ( + <div className="page-actions display-flex-center"> + {!isFile && showShortcuts && renderShortcuts()} + {isFile && (paging || showPaging) && renderFileShortcuts()} + {total > 0 && ( + <div className="measure-details-page-actions nowrap"> + <FilesCounter className="big-spacer-left" current={props.current} total={total} /> + </div> + )} + </div> + ); +} + +function renderShortcuts() { + return ( + <span className="note nowrap"> + <span className="big-spacer-right"> + <span className="shortcut-button little-spacer-right">↑</span> + <span className="shortcut-button little-spacer-right">↓</span> + {translate('component_measures.to_select_files')} + </span> + + <span> + <span className="shortcut-button little-spacer-right">←</span> + <span className="shortcut-button little-spacer-right">→</span> + {translate('component_measures.to_navigate')} + </span> + </span> + ); +} + +function renderFileShortcuts() { + return ( + <span className="note nowrap"> + <span> + <span className="shortcut-button little-spacer-right">j</span> + <span className="shortcut-button little-spacer-right">k</span> + {translate('component_measures.to_navigate_files')} + </span> + </span> + ); +} diff --git a/server/sonar-web/src/main/js/components/ui/__tests__/FilesCounter-test.tsx b/server/sonar-web/src/main/js/components/ui/__tests__/FilesCounter-test.tsx new file mode 100644 index 00000000000..374631e3762 --- /dev/null +++ b/server/sonar-web/src/main/js/components/ui/__tests__/FilesCounter-test.tsx @@ -0,0 +1,30 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import FilesCounter from '../FilesCounter'; + +it('should display x files on y total', () => { + expect(shallow(<FilesCounter current={12} total={123455} />)).toMatchSnapshot(); +}); + +it('should display only total of files', () => { + expect(shallow(<FilesCounter current={undefined} total={123455} />)).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/components/ui/__tests__/PageActions-test.tsx b/server/sonar-web/src/main/js/components/ui/__tests__/PageActions-test.tsx new file mode 100644 index 00000000000..edefa9311ee --- /dev/null +++ b/server/sonar-web/src/main/js/components/ui/__tests__/PageActions-test.tsx @@ -0,0 +1,74 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import PageActions from '../PageActions'; + +const PAGING = { + pageIndex: 1, + pageSize: 100, + total: 120 +}; + +it('should display correctly for a project', () => { + expect( + shallow(<PageActions isFile={false} showShortcuts={true} totalLoadedComponents={20} />) + ).toMatchSnapshot(); +}); + +it('should display correctly for a file', () => { + const wrapper = shallow( + <PageActions isFile={true} showShortcuts={true} totalLoadedComponents={10} /> + ); + expect(wrapper).toMatchSnapshot(); + wrapper.setProps({ paging: { total: 100 } }); + expect(wrapper).toMatchSnapshot(); +}); + +it('should not display shortcuts for treemap', () => { + expect( + shallow(<PageActions isFile={false} showShortcuts={false} totalLoadedComponents={20} />) + ).toMatchSnapshot(); +}); + +it('should display the total of files', () => { + expect( + shallow( + <PageActions + current={12} + isFile={false} + paging={PAGING} + showShortcuts={false} + totalLoadedComponents={20} + /> + ) + ).toMatchSnapshot(); + expect( + shallow( + <PageActions + current={12} + isFile={true} + paging={PAGING} + showShortcuts={true} + totalLoadedComponents={20} + /> + ) + ).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/components/ui/__tests__/__snapshots__/FilesCounter-test.tsx.snap b/server/sonar-web/src/main/js/components/ui/__tests__/__snapshots__/FilesCounter-test.tsx.snap new file mode 100644 index 00000000000..bb01a6121da --- /dev/null +++ b/server/sonar-web/src/main/js/components/ui/__tests__/__snapshots__/FilesCounter-test.tsx.snap @@ -0,0 +1,25 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should display only total of files 1`] = ` +<span> + <strong> + 123,455 + </strong> + + component_measures.files +</span> +`; + +exports[`should display x files on y total 1`] = ` +<span> + <strong> + <span> + 12 + / + </span> + 123,455 + </strong> + + component_measures.files +</span> +`; diff --git a/server/sonar-web/src/main/js/components/ui/__tests__/__snapshots__/PageActions-test.tsx.snap b/server/sonar-web/src/main/js/components/ui/__tests__/__snapshots__/PageActions-test.tsx.snap new file mode 100644 index 00000000000..d76eabe318c --- /dev/null +++ b/server/sonar-web/src/main/js/components/ui/__tests__/__snapshots__/PageActions-test.tsx.snap @@ -0,0 +1,133 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should display correctly for a file 1`] = ` +<div + className="page-actions display-flex-center" +/> +`; + +exports[`should display correctly for a file 2`] = ` +<div + className="page-actions display-flex-center" +> + <span + className="note nowrap" + > + <span> + <span + className="shortcut-button little-spacer-right" + > + j + </span> + <span + className="shortcut-button little-spacer-right" + > + k + </span> + component_measures.to_navigate_files + </span> + </span> + <div + className="measure-details-page-actions nowrap" + > + <FilesCounter + className="big-spacer-left" + total={10} + /> + </div> +</div> +`; + +exports[`should display correctly for a project 1`] = ` +<div + className="page-actions display-flex-center" +> + <span + className="note nowrap" + > + <span + className="big-spacer-right" + > + <span + className="shortcut-button little-spacer-right" + > + ↑ + </span> + <span + className="shortcut-button little-spacer-right" + > + ↓ + </span> + component_measures.to_select_files + </span> + <span> + <span + className="shortcut-button little-spacer-right" + > + ← + </span> + <span + className="shortcut-button little-spacer-right" + > + → + </span> + component_measures.to_navigate + </span> + </span> +</div> +`; + +exports[`should display the total of files 1`] = ` +<div + className="page-actions display-flex-center" +> + <div + className="measure-details-page-actions nowrap" + > + <FilesCounter + className="big-spacer-left" + current={12} + total={120} + /> + </div> +</div> +`; + +exports[`should display the total of files 2`] = ` +<div + className="page-actions display-flex-center" +> + <span + className="note nowrap" + > + <span> + <span + className="shortcut-button little-spacer-right" + > + j + </span> + <span + className="shortcut-button little-spacer-right" + > + k + </span> + component_measures.to_navigate_files + </span> + </span> + <div + className="measure-details-page-actions nowrap" + > + <FilesCounter + className="big-spacer-left" + current={12} + total={20} + /> + </div> +</div> +`; + +exports[`should not display shortcuts for treemap 1`] = ` +<div + className="page-actions display-flex-center" +/> +`; |