diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2018-04-06 17:22:28 +0200 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2018-04-09 20:20:45 +0200 |
commit | 3136ecae882db65db856b5f6f9e0a19a9781763f (patch) | |
tree | 3ce431cc3477a636b59fa66aedbb7a90564085ad /server/sonar-web/src/main | |
parent | 18f6091bb9b381012013bf0fdf261a2300da8926 (diff) | |
download | sonarqube-3136ecae882db65db856b5f6f9e0a19a9781763f.tar.gz sonarqube-3136ecae882db65db856b5f6f9e0a19a9781763f.zip |
Fix QA
Diffstat (limited to 'server/sonar-web/src/main')
11 files changed, 96 insertions, 61 deletions
diff --git a/server/sonar-web/src/main/js/apps/explore/ExploreProjects.tsx b/server/sonar-web/src/main/js/apps/explore/ExploreProjects.tsx index 67f09dc545e..ff1789ee68c 100644 --- a/server/sonar-web/src/main/js/apps/explore/ExploreProjects.tsx +++ b/server/sonar-web/src/main/js/apps/explore/ExploreProjects.tsx @@ -26,5 +26,5 @@ interface Props { } export default function ExploreProjects(props: Props) { - return <AllProjectsContainer isFavorite={false} {...props} />; + return <AllProjectsContainer isFavorite={false} storageOptionsSuffix="explore" {...props} />; } 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 b0f995c2846..dc9836331d8 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 @@ -44,6 +44,7 @@ export interface Props { onSonarCloud: boolean; organization?: { key: string }; organizationsEnabled: boolean; + storageOptionsSuffix?: string; } interface State { @@ -151,25 +152,27 @@ export default class AllProjects extends React.PureComponent<Props, State> { } }; - getSavedOptions = () => { + getStorageOptions = () => { + const { storageOptionsSuffix } = this.props; const options: { sort?: string; view?: string; visualization?: string; } = {}; - if (storage.getSort()) { - options.sort = storage.getSort() || undefined; + if (storage.getSort(storageOptionsSuffix)) { + options.sort = storage.getSort(storageOptionsSuffix) || undefined; } - if (storage.getView()) { - options.view = storage.getView() || undefined; + if (storage.getView(storageOptionsSuffix)) { + options.view = storage.getView(storageOptionsSuffix) || undefined; } - if (storage.getVisualization()) { - options.visualization = storage.getVisualization() || undefined; + if (storage.getVisualization(storageOptionsSuffix)) { + options.visualization = storage.getVisualization(storageOptionsSuffix) || undefined; } return options; }; handlePerspectiveChange = ({ view, visualization }: { view: string; visualization?: string }) => { + const { storageOptionsSuffix } = this.props; const query: { view: string | undefined; visualization: string | undefined; @@ -191,20 +194,20 @@ export default class AllProjects extends React.PureComponent<Props, State> { this.updateLocationQuery(query); } - storage.saveSort(query.sort); - storage.saveView(query.view); - storage.saveVisualization(visualization); + storage.saveSort(query.sort, storageOptionsSuffix); + storage.saveView(query.view, storageOptionsSuffix); + storage.saveVisualization(visualization, storageOptionsSuffix); }; handleSortChange = (sort: string, desc: boolean) => { const asString = (desc ? '-' : '') + sort; this.updateLocationQuery({ sort: asString }); - storage.saveSort(asString); + storage.saveSort(asString, this.props.storageOptionsSuffix); }; handleQueryChange(initialMount: boolean) { const query = parseUrlQuery(this.props.location.query); - const savedOptions = this.getSavedOptions(); + const savedOptions = this.getStorageOptions(); const savedOptionsSet = savedOptions.sort || savedOptions.view || savedOptions.visualization; // if there is no filter, but there are saved preferences in the localStorage diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx index 6d236c388a2..cd24cb1cb1e 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx @@ -37,6 +37,7 @@ interface OwnProps { isFavorite: boolean; location: { pathname: string; query: RawQuery }; organization?: { key: string }; + storageOptionsSuffix?: string; } const stateToProps = (state: any) => { diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx index 14ea18c6c7c..cc642e972f4 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx @@ -117,7 +117,7 @@ it('changes sort', () => { const wrapper = shallowRender({}, push); wrapper.find('PageHeader').prop<Function>('onSortChange')('size', false); expect(push).lastCalledWith({ pathname: '/projects', query: { sort: 'size' } }); - expect(saveSort).lastCalledWith('size'); + expect(saveSort).lastCalledWith('size', undefined); }); it('changes perspective to leak', () => { @@ -128,9 +128,9 @@ it('changes perspective to leak', () => { pathname: '/projects', query: { view: 'leak', visualization: undefined } }); - expect(saveSort).lastCalledWith(undefined); - expect(saveView).lastCalledWith('leak'); - expect(saveVisualization).lastCalledWith(undefined); + expect(saveSort).lastCalledWith(undefined, undefined); + expect(saveView).lastCalledWith('leak', undefined); + expect(saveVisualization).lastCalledWith(undefined, undefined); }); it('updates sorting when changing perspective from leak', () => { @@ -144,9 +144,9 @@ it('updates sorting when changing perspective from leak', () => { pathname: '/projects', query: { sort: 'coverage', view: undefined, visualization: undefined } }); - expect(saveSort).lastCalledWith('coverage'); - expect(saveView).lastCalledWith(undefined); - expect(saveVisualization).lastCalledWith(undefined); + expect(saveSort).lastCalledWith('coverage', undefined); + expect(saveView).lastCalledWith(undefined, undefined); + expect(saveVisualization).lastCalledWith(undefined, undefined); }); it('changes perspective to risk visualization', () => { @@ -160,9 +160,9 @@ it('changes perspective to risk visualization', () => { pathname: '/projects', query: { view: 'visualizations', visualization: 'risk' } }); - expect(saveSort).lastCalledWith(undefined); - expect(saveView).lastCalledWith('visualizations'); - expect(saveVisualization).lastCalledWith('risk'); + expect(saveSort).lastCalledWith(undefined, undefined); + expect(saveView).lastCalledWith('visualizations', undefined); + expect(saveVisualization).lastCalledWith('risk', undefined); }); function mountRender(props: any = {}, push: Function = jest.fn(), replace: Function = jest.fn()) { diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx index 1c615cc6bd4..c0e9326f5e8 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx @@ -100,7 +100,6 @@ interface State { duplications?: Duplication[]; duplicationsByLine: { [line: number]: number[] }; hasSourcesAfter: boolean; - highlightedLine?: number; highlightedSymbols: string[]; issueLocationsByLine: { [line: number]: LinearIssueLocation[] }; issuePopup?: { issue: string; name: string }; @@ -134,11 +133,11 @@ export default class SourceViewerBase extends React.PureComponent<Props, State> constructor(props: Props) { super(props); + this.state = { displayDuplications: false, duplicationsByLine: {}, hasSourcesAfter: false, - highlightedLine: props.highlightedLine, highlightedSymbols: [], issuesByLine: {}, issueLocationsByLine: {}, @@ -242,6 +241,7 @@ export default class SourceViewerBase extends React.PureComponent<Props, State> issues => { if (this.mounted) { const finalSources = sources.slice(0, LINES); + this.setState( { component, @@ -250,7 +250,6 @@ export default class SourceViewerBase extends React.PureComponent<Props, State> duplications: undefined, duplicationsByLine: {}, hasSourcesAfter: sources.length > LINES, - highlightedLine: undefined, highlightedSymbols: [], issueLocationsByLine: locationsByLine(issues), issues, @@ -669,7 +668,7 @@ export default class SourceViewerBase extends React.PureComponent<Props, State> filterLine={this.handleFilterLine} hasSourcesAfter={this.state.hasSourcesAfter} hasSourcesBefore={hasSourcesBefore} - highlightedLine={this.state.highlightedLine} + highlightedLine={this.props.highlightedLine} highlightedLocationMessage={this.props.highlightedLocationMessage} highlightedLocations={this.props.highlightedLocations} highlightedSymbols={this.state.highlightedSymbols} diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.tsx index 6d1f4940141..9297036d88d 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.tsx @@ -56,6 +56,7 @@ export default class LineNumber extends React.PureComponent<Props> { tabIndex={0}> <BubblePopupHelper isOpen={popupOpen} + offset={{ vertical: -18, horizontal: 0 }} popup={ <LineOptionsPopup branchLike={branchLike} componentKey={componentKey} line={line} /> } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineSCM.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/LineSCM.tsx index c1de61e6ee2..e692a3c46f1 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineSCM.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineSCM.tsx @@ -58,6 +58,7 @@ export default class LineSCM extends React.PureComponent<Props> { {cell} <BubblePopupHelper isOpen={popupOpen} + offset={{ vertical: -18, horizontal: 0 }} popup={<SCMPopup line={line} />} position="bottomright" togglePopup={this.handleTogglePopup} diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineNumber-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineNumber-test.tsx.snap index 2633afb6d2c..3841048e4ae 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineNumber-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineNumber-test.tsx.snap @@ -16,6 +16,12 @@ exports[`render line 3 1`] = ` > <BubblePopupHelper isOpen={false} + offset={ + Object { + "horizontal": 0, + "vertical": -18, + } + } popup={ <LineOptionsPopup branchLike={undefined} diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineSCM-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineSCM-test.tsx.snap index dcbaf7e2c9c..c320b6a9b36 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineSCM-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineSCM-test.tsx.snap @@ -10,6 +10,12 @@ exports[`does not render scm details 1`] = ` > <BubblePopupHelper isOpen={false} + offset={ + Object { + "horizontal": 0, + "vertical": -18, + } + } popup={ <SCMPopup line={ @@ -41,6 +47,12 @@ exports[`render scm details 1`] = ` /> <BubblePopupHelper isOpen={false} + offset={ + Object { + "horizontal": 0, + "vertical": -18, + } + } popup={ <SCMPopup line={ @@ -72,6 +84,12 @@ exports[`render scm details for the first line 1`] = ` /> <BubblePopupHelper isOpen={false} + offset={ + Object { + "horizontal": 0, + "vertical": -18, + } + } popup={ <SCMPopup line={ diff --git a/server/sonar-web/src/main/js/components/common/MultiSelect.tsx b/server/sonar-web/src/main/js/components/common/MultiSelect.tsx index 892cab66813..3da8a520ebe 100644 --- a/server/sonar-web/src/main/js/components/common/MultiSelect.tsx +++ b/server/sonar-web/src/main/js/components/common/MultiSelect.tsx @@ -257,6 +257,7 @@ export default class MultiSelect extends React.PureComponent<Props, State> { const { renderLabel } = this.props as PropsWithDefault; const { query, activeIdx, selectedElements, unselectedElements } = this.state; const activeElement = this.getAllElements(this.props, this.state)[activeIdx]; + const showNewElement = allowNewElements && this.isNewElement(query, this.props); const infiniteList = this.props.listSize === 0; const listClasses = classNames('menu', { 'menu-vertically-limited': infiniteList, @@ -278,10 +279,6 @@ export default class MultiSelect extends React.PureComponent<Props, State> { /> </div> <ul className={listClasses}> - {selectedElements.length < 1 && - unselectedElements.length < 1 && ( - <li className="spacer-left">{translateWithParameters('no_results_for_x', query)}</li> - )} {selectedElements.length > 0 && selectedElements.map(element => ( <MultiSelectOption @@ -306,17 +303,21 @@ export default class MultiSelect extends React.PureComponent<Props, State> { renderLabel={renderLabel} /> ))} - {allowNewElements && - this.isNewElement(query, this.props) && ( - <MultiSelectOption - active={activeElement === query} - custom={true} - element={query} - key={query} - onHover={this.handleElementHover} - onSelectChange={this.handleSelectChange} - renderLabel={renderLabel} - /> + {showNewElement && ( + <MultiSelectOption + active={activeElement === query} + custom={true} + element={query} + key={query} + onHover={this.handleElementHover} + onSelectChange={this.handleSelectChange} + renderLabel={renderLabel} + /> + )} + {!showNewElement && + selectedElements.length < 1 && + unselectedElements.length < 1 && ( + <li className="spacer-left">{translateWithParameters('no_results_for_x', query)}</li> )} </ul> {footerNode} diff --git a/server/sonar-web/src/main/js/helpers/storage.ts b/server/sonar-web/src/main/js/helpers/storage.ts index fc54899c8b4..b533d353735 100644 --- a/server/sonar-web/src/main/js/helpers/storage.ts +++ b/server/sonar-web/src/main/js/helpers/storage.ts @@ -28,12 +28,13 @@ const PROJECTS_SORT = 'sonarqube.projects.sort'; const PROJECT_ACTIVITY_GRAPH = 'sonarqube.project_activity.graph'; const PROJECT_ACTIVITY_GRAPH_CUSTOM = 'sonarqube.project_activity.graph.custom'; -function save(key: string, value?: string): void { +function save(key: string, value?: string, suffix?: string): void { try { + const finalKey = suffix ? `${key}.${suffix}` : key; if (value) { - window.localStorage.setItem(key, value); + window.localStorage.setItem(finalKey, value); } else { - window.localStorage.removeItem(key); + window.localStorage.removeItem(finalKey); } } catch (e) { // usually that means the storage is full @@ -41,12 +42,16 @@ function save(key: string, value?: string): void { } } +function get(key: string, suffix?: string): string | null { + return window.localStorage.getItem(suffix ? `${key}.${suffix}` : key); +} + export function saveFavorite(): void { save(PROJECTS_DEFAULT_FILTER, PROJECTS_FAVORITE); } export function isFavoriteSet(): boolean { - const setting = window.localStorage.getItem(PROJECTS_DEFAULT_FILTER); + const setting = get(PROJECTS_DEFAULT_FILTER); return setting === PROJECTS_FAVORITE; } @@ -55,32 +60,32 @@ export function saveAll(): void { } export function isAllSet(): boolean { - const setting = window.localStorage.getItem(PROJECTS_DEFAULT_FILTER); + const setting = get(PROJECTS_DEFAULT_FILTER); return setting === PROJECTS_ALL; } -export function saveView(view?: string): void { - save(PROJECTS_VIEW, view); +export function saveView(view?: string, suffix?: string): void { + save(PROJECTS_VIEW, view, suffix); } -export function getView(): string | null { - return window.localStorage.getItem(PROJECTS_VIEW); +export function getView(suffix?: string): string | null { + return get(PROJECTS_VIEW, suffix); } -export function saveVisualization(visualization?: string): void { - save(PROJECTS_VISUALIZATION, visualization); +export function saveVisualization(visualization?: string, suffix?: string): void { + save(PROJECTS_VISUALIZATION, visualization, suffix); } -export function getVisualization(): string | null { - return window.localStorage.getItem(PROJECTS_VISUALIZATION); +export function getVisualization(suffix?: string): string | null { + return get(PROJECTS_VISUALIZATION, suffix); } -export function saveSort(sort?: string): void { - save(PROJECTS_SORT, sort); +export function saveSort(sort?: string, suffix?: string): void { + save(PROJECTS_SORT, sort, suffix); } -export function getSort(): string | null { - return window.localStorage.getItem(PROJECTS_SORT); +export function getSort(suffix?: string): string | null { + return get(PROJECTS_SORT, suffix); } export function saveCustomGraph(metrics?: string[]): void { @@ -88,7 +93,7 @@ export function saveCustomGraph(metrics?: string[]): void { } export function getCustomGraph(): string[] { - const customGraphs = window.localStorage.getItem(PROJECT_ACTIVITY_GRAPH_CUSTOM); + const customGraphs = get(PROJECT_ACTIVITY_GRAPH_CUSTOM); return customGraphs ? customGraphs.split(',') : []; } @@ -97,5 +102,5 @@ export function saveGraph(graph?: string): void { } export function getGraph(): string { - return window.localStorage.getItem(PROJECT_ACTIVITY_GRAPH) || 'issues'; + return get(PROJECT_ACTIVITY_GRAPH) || 'issues'; } |