]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10489 improve navigation between locations (#57)
authorStas Vilchik <stas.vilchik@sonarsource.com>
Mon, 26 Mar 2018 14:04:10 +0000 (16:04 +0200)
committerSonarTech <sonartech@sonarsource.com>
Tue, 27 Mar 2018 18:22:34 +0000 (20:22 +0200)
server/sonar-web/src/main/js/app/types.ts
server/sonar-web/src/main/js/apps/issues/actions.ts
server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationsNavigatorLocation.tsx
server/sonar-web/src/main/js/apps/issues/conciseIssuesList/CrossFileLocationsNavigator.tsx
server/sonar-web/src/main/js/apps/issues/utils.ts
server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx
server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.tsx
server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx
server/sonar-web/src/main/js/components/SourceViewer/components/LineCode.tsx

index 8155161aca040d276cbf6e7d4bfb0e48aa765feb..6a0b0c2df61d2b5b49bed4ae87a6dd02ef863f24 100644 (file)
@@ -152,7 +152,7 @@ export interface FacetValue {
 export interface FlowLocation {
   component: string;
   componentName?: string;
-  msg: string;
+  msg?: string;
   textRange: TextRange;
 }
 
index f814bbf5b001fa95207630de236386993278670b..90a6897177f14ffb11cdff66774c479fadc489b2 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import { State } from './components/App';
+import { allLocationsEmpty } from './utils';
 
 export function enableLocationsNavigator(state: State): Partial<State> | undefined {
   const { openIssue, selectedLocationIndex } = state;
   if (openIssue && (openIssue.secondaryLocations.length > 0 || openIssue.flows.length > 0)) {
-    return {
-      locationsNavigator: true,
-      selectedFlowIndex: state.selectedFlowIndex || (openIssue.flows.length > 0 ? 0 : undefined),
-      // Also reset index = -1 to 0, we don't want to start on the issue when enabling the location navigator
-      selectedLocationIndex:
-        !selectedLocationIndex || selectedLocationIndex < 0 ? 0 : selectedLocationIndex
-    };
+    const selectedFlowIndex =
+      state.selectedFlowIndex || (openIssue.flows.length > 0 ? 0 : undefined);
+
+    if (!allLocationsEmpty(openIssue, selectedFlowIndex)) {
+      return {
+        locationsNavigator: true,
+        selectedFlowIndex,
+        // Also reset index = -1 to 0, we don't want to start on the issue when enabling the location navigator
+        selectedLocationIndex:
+          !selectedLocationIndex || selectedLocationIndex < 0 ? 0 : selectedLocationIndex
+      };
+    }
   }
   return undefined;
 }
index 1fe90aa029e08caeaf006cf4dc2f1d06131d9be7..a9f0d9e0bc1da89d18d3752412b1475829fd949f 100644 (file)
@@ -23,7 +23,7 @@ import LocationMessage from '../../../components/common/LocationMessage';
 
 interface Props {
   index: number;
-  message: string;
+  message: string | undefined;
   onClick: (index: number) => void;
   scroll: (element: Element) => void;
   selected: boolean;
index a2826a6b47b681c9cd35382c66aab102947151f4..295ffe694fad9bca0c5f08364aaec1e21cf33f6d 100644 (file)
@@ -108,7 +108,7 @@ export default class CrossFileLocationsNavigator extends React.PureComponent<Pro
     return groups;
   };
 
-  renderLocation = (index: number, message: string) => {
+  renderLocation = (index: number, message: string | undefined) => {
     return (
       <ConciseIssueLocationsNavigatorLocation
         index={index}
index f148547d9e11ca5045c4571b10888a9a55acbad8..0423bc1ee648e8c361d9525f2dd7b1067e4bf363 100644 (file)
@@ -256,3 +256,10 @@ export function getSelectedLocation(
     return undefined;
   }
 }
+
+export function allLocationsEmpty(
+  issue: Pick<Issue, 'flows' | 'secondaryLocations'>,
+  selectedFlowIndex: number | undefined
+) {
+  return getLocations(issue, selectedFlowIndex).every(location => !location.msg);
+}
index 629b4d86971163d2eb6ebbb0dbeae50c882ae0a6..35e97cf88472cdc6a1ceaef5f1b1ff4305fe2e4d 100644 (file)
@@ -66,7 +66,7 @@ interface Props {
   // `undefined` elements mean they are located in a different file,
   // but kept to maintaint the location indexes
   highlightedLocations?: (FlowLocation | undefined)[];
-  highlightedLocationMessage?: { index: number; text: string };
+  highlightedLocationMessage?: { index: number; text: string | undefined };
   loadComponent?: (
     component: string,
     branchLike: BranchLike | undefined
index ef1abb5af32e07e69860f4ed31d8cfdabe19ca23..21dad198aa1e1bf1b99ade35d068aab6a4c0861d 100644 (file)
@@ -53,7 +53,7 @@ interface Props {
   hasSourcesAfter: boolean;
   hasSourcesBefore: boolean;
   highlightedLine: number | undefined;
-  highlightedLocationMessage: { index: number; text: string } | undefined;
+  highlightedLocationMessage: { index: number; text: string | undefined } | undefined;
   // `undefined` elements mean they are located in a different file,
   // but kept to maintain the location indexes
   highlightedLocations: (FlowLocation | undefined)[] | undefined;
index c6fef8178b315a4e6bf254fb011e95993589fd59..188369030f9ad5215fe7ea63b1d8a6aa7a38282a 100644 (file)
@@ -43,7 +43,7 @@ interface Props {
   duplicationsCount: number;
   filtered: boolean | undefined;
   highlighted: boolean;
-  highlightedLocationMessage: { index: number; text: string } | undefined;
+  highlightedLocationMessage: { index: number; text: string | undefined } | undefined;
   highlightedSymbols: string[] | undefined;
   issueLocations: LinearIssueLocation[];
   issuePopup: { issue: string; name: string } | undefined;
index 9becbdeb876498db40de600e8fa47d6946a48a5a..b3ac1a77358107de782c3b249546be7f235fd893 100644 (file)
@@ -35,7 +35,7 @@ interface Props {
   displayIssueLocationsCount?: boolean;
   displayIssueLocationsLink?: boolean;
   displayLocationMarkers?: boolean;
-  highlightedLocationMessage: { index: number; text: string } | undefined;
+  highlightedLocationMessage: { index: number; text: string | undefined } | undefined;
   highlightedSymbols: string[] | undefined;
   issueLocations: LinearIssueLocation[];
   issuePopup: { issue: string; name: string } | undefined;
@@ -138,19 +138,18 @@ export default class LineCode extends React.PureComponent<Props, State> {
     }
   };
 
-  renderMarker(index: number, message: string | undefined, leading = false) {
+  renderMarker(index: number, message: string | undefined, selected: boolean, leading: boolean) {
     const { onLocationSelect } = this.props;
     const onClick = onLocationSelect ? () => onLocationSelect(index) : undefined;
-    const ref =
-      message != null ? (node: HTMLElement | null) => (this.activeMarkerNode = node) : undefined;
+    const ref = selected ? (node: HTMLElement | null) => (this.activeMarkerNode = node) : undefined;
     return (
       <LocationIndex
         key={`marker-${index}`}
         leading={leading}
         onClick={onClick}
-        selected={message != null}>
+        selected={selected}>
         <span ref={ref}>{index + 1}</span>
-        {message != null && <LocationMessage selected={true}>{message}</LocationMessage>}
+        {message && <LocationMessage selected={true}>{message}</LocationMessage>}
       </LocationIndex>
     );
   }
@@ -206,11 +205,10 @@ export default class LineCode extends React.PureComponent<Props, State> {
     tokens.forEach((token, index) => {
       if (this.props.displayLocationMarkers && token.markers.length > 0) {
         token.markers.forEach(marker => {
-          const message =
-            highlightedLocationMessage != null && highlightedLocationMessage.index === marker
-              ? highlightedLocationMessage.text
-              : undefined;
-          renderedTokens.push(this.renderMarker(marker, message, leadingMarker));
+          const selected =
+            highlightedLocationMessage !== undefined && highlightedLocationMessage.index === marker;
+          const message = selected ? highlightedLocationMessage!.text : undefined;
+          renderedTokens.push(this.renderMarker(marker, message, selected, leadingMarker));
         });
       }
       renderedTokens.push(