]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16346 Replace React legacy lifecycle methods in the issue app
authorPhilippe Perrin <philippe.perrin@sonarsource.com>
Fri, 29 Apr 2022 14:29:10 +0000 (16:29 +0200)
committersonartech <sonartech@sonarsource.com>
Mon, 2 May 2022 20:02:50 +0000 (20:02 +0000)
server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx
server/sonar-web/src/main/js/apps/issues/components/__tests__/IssuesApp-test.tsx
server/sonar-web/src/main/js/apps/issues/utils.ts

index b00454f3fcae838bef7ddd4a7cf1d69b3726e109..05089203608cf59bb945f6a5ac613c3f9c368d71 100644 (file)
@@ -75,6 +75,7 @@ import {
   areMyIssuesSelected,
   areQueriesEqual,
   getOpen,
+  getOpenIssue,
   parseFacets,
   parseQuery,
   Query,
@@ -175,6 +176,18 @@ export default class App extends React.PureComponent<Props, State> {
     this.refreshBranchStatus = debounce(this.refreshBranchStatus, BRANCH_STATUS_REFRESH_INTERVAL);
   }
 
+  static getDerivedStateFromProps(props: Props, state: State) {
+    const {
+      location: { query }
+    } = props;
+
+    return {
+      myIssues: areMyIssuesSelected(query),
+      query: parseQuery(query),
+      openIssue: getOpenIssue(props, state.issues)
+    };
+  }
+
   componentDidMount() {
     this.mounted = true;
 
@@ -189,33 +202,11 @@ export default class App extends React.PureComponent<Props, State> {
     this.fetchFirstIssues();
   }
 
-  componentWillReceiveProps(nextProps: Props) {
-    const { issues, selected } = this.state;
-    const openIssue = this.getOpenIssue(nextProps, issues);
-
-    if (openIssue && openIssue.key !== selected) {
-      this.setState({
-        locationsNavigator: false,
-        selected: openIssue.key,
-        selectedFlowIndex: undefined,
-        selectedLocationIndex: undefined
-      });
-    }
-
-    if (!openIssue) {
-      this.setState({ selectedFlowIndex: undefined, selectedLocationIndex: undefined });
-    }
-
-    this.setState({
-      myIssues: areMyIssuesSelected(nextProps.location.query),
-      openIssue,
-      query: parseQuery(nextProps.location.query)
-    });
-  }
-
   componentDidUpdate(prevProps: Props, prevState: State) {
     const { query } = this.props.location;
     const { query: prevQuery } = prevProps.location;
+    const { openIssue } = this.state;
+
     if (
       prevProps.component !== this.props.component ||
       !isSameBranchLike(prevProps.branchLike, this.props.branchLike) ||
@@ -231,6 +222,13 @@ export default class App extends React.PureComponent<Props, State> {
       // if user simply selected another issue
       // or if user went from the source code back to the list of issues
       this.scrollToSelectedIssue();
+    } else if (openIssue && openIssue.key !== this.state.selected) {
+      this.setState({
+        locationsNavigator: false,
+        selected: openIssue.key,
+        selectedFlowIndex: undefined,
+        selectedLocationIndex: undefined
+      });
     }
   }
 
@@ -308,11 +306,6 @@ export default class App extends React.PureComponent<Props, State> {
     return index !== -1 ? index : undefined;
   }
 
-  getOpenIssue = (props: Props, issues: Issue[]) => {
-    const open = getOpen(props.location.query);
-    return open ? issues.find(issue => issue.key === open) : undefined;
-  };
-
   selectNextIssue = () => {
     const { issues } = this.state;
     const selectedIndex = this.getSelectedIndex();
@@ -477,7 +470,7 @@ export default class App extends React.PureComponent<Props, State> {
     return fetchPromise.then(
       ({ effortTotal, facets, issues, paging, ...other }) => {
         if (this.mounted && areQueriesEqual(prevQuery, this.props.location.query)) {
-          const openIssue = this.getOpenIssue(this.props, issues);
+          const openIssue = getOpenIssue(this.props, issues);
           let selected: string | undefined = undefined;
           if (issues.length > 0) {
             selected = openIssue ? openIssue.key : issues[0].key;
@@ -791,8 +784,7 @@ export default class App extends React.PureComponent<Props, State> {
   handleIssueChange = (issue: Issue) => {
     this.refreshBranchStatus();
     this.setState(state => ({
-      issues: state.issues.map(candidate => (candidate.key === issue.key ? issue : candidate)),
-      openIssue: state.openIssue && state.openIssue.key === issue.key ? issue : state.openIssue
+      issues: state.issues.map(candidate => (candidate.key === issue.key ? issue : candidate))
     }));
   };
 
index 7b9c514592f573fe37df1f903bc0f573bd92ecd3..1727414d5171f08870ede5ebf80551fb003f39e4 100644 (file)
@@ -546,15 +546,22 @@ it('should refresh branch status if issues are updated', async () => {
 });
 
 it('should update the open issue when it is changed', async () => {
+  (searchIssues as jest.Mock).mockImplementation(mockSearchIssuesResponse());
+
   const wrapper = shallowRender();
   await waitAndUpdate(wrapper);
 
-  wrapper.setState({ openIssue: ISSUES[0] });
+  const issue = wrapper.state().issues[0];
+  wrapper.setProps({ location: mockLocation({ query: { open: issue.key } }) });
+  await waitAndUpdate(wrapper);
+
+  expect(wrapper.state().openIssue).toEqual(issue);
 
-  const updatedIssue: Issue = { ...ISSUES[0], type: 'SECURITY_HOTSPOT' };
+  const updatedIssue: Issue = { ...issue, type: 'SECURITY_HOTSPOT' };
   wrapper.instance().handleIssueChange(updatedIssue);
 
-  expect(wrapper.state().openIssue).toBe(updatedIssue);
+  await waitAndUpdate(wrapper);
+  expect(wrapper.state().openIssue).toEqual(updatedIssue);
 });
 
 it('should handle createAfter query param with time', async () => {
index 0805f292f4e3f06b1c831df70eec7a4abe99228a..590e1a4af58f6ceeb738e9e184d72d56de6a62d7 100644 (file)
@@ -117,6 +117,11 @@ export function getOpen(query: RawQuery): string | undefined {
   return query.open;
 }
 
+export function getOpenIssue(props: { location: { query: RawQuery } }, issues: Issue[]) {
+  const open = getOpen(props.location.query);
+  return open ? issues.find(issue => issue.key === open) : undefined;
+}
+
 export const areMyIssuesSelected = (query: RawQuery) => query.myIssues === 'true';
 
 export function serializeQuery(query: Query): RawQuery {