Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug 1450022 - Convert entire Details Panel to ReactJS #3621

Merged
merged 1 commit into from
Jun 13, 2018
Merged

Conversation

camd
Copy link
Contributor

@camd camd commented Jun 5, 2018

Moves everything in the details-panel to ReactJS.

Tested:

  • selecting a job and viewing the summary, job details, failure summary and all tabs
  • perf tab shows up when it's a non-failed job with perf data
  • autoclassify tab shows when &autoclassify is in url
  • classify and delete classification for a job
  • classify by manually entering a bug number
  • click bug pin in Failure Summary and the job is pinned with bug selected, save classification
  • Pinning and unpinning jobs, also "clear all" in the save drop-down of pinboard
  • Pinning 2 jobs and retriggering in save drop-down
  • Pinning the in-progress and cancelling all in save drop-down
  • All options in the "..." menu of ActionBar
  • retrigger and cancel in ActionBar
  • Viewing raw and logviewer
  • with jobs pinned, clicking open area does not clear detail panel
  • manually opening and closing the pinboard
  • close button of pinboard
  • bugfiler opens (didn't actually file a bug)
  • custom actions dialog opens

Note:

  • Resizing the bottom panel is broken in prod, so didn't address fixing that
  • Also there are some cases where esc doesn't close the bottom window. But it, again, seems to be the same as prod, so not addressing now.

@camd camd force-pushed the pinboard-to-react branch 3 times, most recently from 961393c to 46530dc Compare June 6, 2018 00:11
@camd camd had a problem deploying to treeherder-prototype June 6, 2018 04:47 Failure
@camd camd temporarily deployed to treeherder-prototype June 6, 2018 05:02 Inactive
@camd camd temporarily deployed to treeherder-prototype June 6, 2018 05:15 Inactive
@camd camd force-pushed the pinboard-to-react branch 2 times, most recently from aa1560b to 38d5c95 Compare June 6, 2018 19:11
@camd camd had a problem deploying to treeherder-prototype June 6, 2018 21:34 Failure
@camd camd temporarily deployed to treeherder-prototype June 6, 2018 21:43 Inactive
@camd camd requested a review from edmorley June 6, 2018 23:07
Copy link
Contributor

@edmorley edmorley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't had a chance to test this locally yet - will do so tomorrow.

@@ -1,48 +0,0 @@
import angular from 'angular';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this file removed, the ui/vendor/ entry can be removed from .eslintignore (and so that file removed too).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh cool, done.

thPinboardCountError,
thEvents,
thPinboardMaxSize
} from "../js/constants";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

single quotes

});
}

isSHAorCommit(str) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these might be good to move to helpers/?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point, yeah. I'll move as many static functions as possible them into helpers.

@@ -0,0 +1,89 @@
import React from 'react';
import PropTypes from 'prop-types';
import logviewerIcon from '../../../img/logviewerIcon.svg';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newline before this line

><span className="fa fa-times" /></span>
</span>
</TabList>
<TabPanel>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are you thoughts on moving <TabPanel> to be inside *Tab.jsx?
(Not sure what's considered best practice for this kind of pattern)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting idea, I'll give it a shot and see how that works. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In trying to do this, it ends up that react-tabs checks that there are a matching number of TabPanel to Tab components. If I move TabPanel to inside the tab, like FailureSummaryTab then it doesn't detect there are a matching number of Tab to TabPanel. If I have FailureSummaryTab extend TabPanel rather than React.Component then it DOES work. However, only for some of the tabs. It appears to break tab navigation.

I haven't looked too deeply, but I fear that extending TabPanel may cause state in our component to potentially interfere with TabPanel. It may also be that it's causing some interference with applying classes to show/hide in some rendering code in TabPanel.

I'm thinking this may not be an avenue worth exploring further at this time. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that sounds fine :-)

Btw I can't see the stylesheet being imported anywhere? (https://github.com/reactjs/react-tabs#styling) Would using that reduce the boilerplate we need in our own stylesheet? (If not, don't worry)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'd tried using one, but had to start overriding a pieces of styling we didn't want, so it started to get messy and I just went with what we had been using. :)

@camd camd changed the title Bug 1450022 - Convert Pinboard to ReactJS Bug 1450022 - Convert entire Details Panel to ReactJS Jun 7, 2018
@camd
Copy link
Contributor Author

camd commented Jun 7, 2018

It had also occurred to me in this PR that we have a lot of imports.. :) Maybe agreeing on some general order of them would help. My thoughts were:

  1. Components
  2. Models
  3. Helpers
  4. Constants
  5. Other

What do you think?

@edmorley
Copy link
Contributor

edmorley commented Jun 7, 2018

In the future we might want to enable this import order eslint rule:
https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md

It doesn't yet sort within the groups (import-js/eslint-plugin-import#389) though.

For now, perhaps just roughly follow the order in that rule's documentation?

@camd
Copy link
Contributor Author

camd commented Jun 7, 2018

Cool, ok. I think I've modified it to follow that.

I went ahead and started using the order of

  1. Other
  2. Constants
  3. Helpers
  4. Models
  5. Siblings, etc

With a space where there are different directory depths. I hope that's about right. :)

@camd camd force-pushed the pinboard-to-react branch 2 times, most recently from 520426e to e60264a Compare June 7, 2018 21:28
const reftestUrl = jobLogUrls.length ?
`${getReftestUrl(jobLogUrls[0].url)}&only_show_unexpected=1` :
'';
const performanceData = flatten(Object.values(results[3]));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After rebasing on master to resolve the conflict in ui/plugins/controller.js (from #3627), could you convert this and the other flatten() usage to ES6? :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely, yeah. Done.

jobLogUrls: [],
jobDetailLoading: false,
jobLogsAllParsed: false,
lvUrl: null,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think it'd be clearer if you spelled out logViewerUrl and logViewerFullUrl rather than abbreviating with 'lv' especially since it's passed down to multiple components.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, yeah.

this.closeJob = this.closeJob.bind(this);
this.countPinnedJobs = this.countPinnedJobs.bind(this);
// give access to this count to components that don't have a common ancestor in React
// TODO: remove this once we're fully on ReactJS.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this TODO filed in bugzilla or mentioned as part of other React conversion bugs? Wondering how we are keeping track of these.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. This is in Bug 1450042. But added that bug number to the TODO to help keep track. In this case, it'll be pretty obvious once all uses of $injector and $rootScope no longer exist.

this.setState({ tabIndex: nextIndex < tabCount ? nextIndex : 0 });
});

this.setTabIndex = this.setTabIndex.bind(this);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why this method is bound here rather than in the constructor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears (as far as I can tell) to be a quirk of mixing angular with react. In some cases, the function gets bound to a state of the app where you get an error on the console like this:

Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the TabsPanel component. warning.js:33 

So putting it in componentDidMount hits it at a point where it obviously WAS mounted already. I'm hoping to move these all into the constructors when we no longer need react2angular.

I actually referenced this in one of my TODOs here a while back:

// TODO: Once we're not using ng-react any longer and

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. Thanks for explaining :)

@camd
Copy link
Contributor Author

camd commented Jun 10, 2018

The selenium tests are failing for non-timeout reasons this time. :) I changed a few of the CSS classes and ids, which broke the tests. I'll address that this coming week.

@camd
Copy link
Contributor Author

camd commented Jun 13, 2018

OK, selenium tests are fixed now.

@camd camd force-pushed the pinboard-to-react branch 3 times, most recently from 3f97704 to e032f3e Compare June 13, 2018 21:47
@camd camd merged commit 15721f0 into master Jun 13, 2018
@camd camd deleted the pinboard-to-react branch June 13, 2018 22:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants