Bug 1469047 - Create common React ancestor for PushList and DetailsPanel (#3673)

This will allow better interaction between the two components.  As we convert
more items (like navbars, etc) we will move them into this umbrella Treeherder
component.
This commit is contained in:
Cameron Dawson 2018-06-18 08:59:50 -07:00 коммит произвёл GitHub
Родитель 9ce293f9b8
Коммит a81e7a85c7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 111 добавлений и 67 удалений

Просмотреть файл

@ -2,7 +2,7 @@ strong {
font-weight: bold;
}
details-panel {
#details-panel {
font-size: 12px;
height: 35%;
max-height: 75%;
@ -18,7 +18,7 @@ details-panel {
100% { transform: translateY(0%); }
}
div#details-panel .navbar,
div#details-panel-content .navbar,
div#tabs-panel .tab-headers {
border-radius: 0;
height: 33px;
@ -46,45 +46,45 @@ div#details-panel-resizer {
padding-left: 5px;
}
div#details-panel .navbar-nav > ul {
div#details-panel-content .navbar-nav > ul {
height: 32px;
}
div#details-panel .navbar-nav.actionbar-nav > li > a,
div#details-panel .navbar-nav.actionbar-nav > li > button {
div#details-panel-content .navbar-nav.actionbar-nav > li > a,
div#details-panel-content .navbar-nav.actionbar-nav > li > button {
padding: 8px 15px;
line-height: 16px;
}
div#details-panel .navbar-nav.tab-headers > li > a,
div#details-panel .navbar-nav.tab-headers > li > button {
div#details-panel-content .navbar-nav.tab-headers > li > a,
div#details-panel-content .navbar-nav.tab-headers > li > button {
padding: 8px 15px;
line-height: 30px;
}
div#details-panel .navbar-nav > li > button {
div#details-panel-content .navbar-nav > li > button {
border: none;
background: transparent;
}
/* Use a loaded image, rather than an icon, so it needs to be slightly shorter */
div#details-panel .navbar-nav > li > a#logviewer-btn {
div#details-panel-content .navbar-nav > li > a#logviewer-btn {
line-height: 18px;
}
div#details-panel .navbar-nav > li > a.disabled,
div#details-panel .navbar-nav > li > button.disabled,
div#details-panel-content .navbar-nav > li > a.disabled,
div#details-panel-content .navbar-nav > li > button.disabled,
ul.actionbar-menu > li.disabled {
cursor: not-allowed;
text-decoration: none;
}
div#details-panel .navbar-nav > li.active a,
div#details-panel .navbar-nav > li.active a:hover,
div#details-panel .navbar-nav > li.active a:focus {
div#details-panel-content .navbar-nav > li.active a,
div#details-panel-content .navbar-nav > li.active a:hover,
div#details-panel-content .navbar-nav > li.active a:focus {
outline: 0;
}
div#details-panel .details-panel-navbar > ul.tab-headers > li {
div#details-panel-content .details-panel-navbar > ul.tab-headers > li {
border-right: 1px solid #42484F;
}
@ -114,7 +114,7 @@ div#details-panel .details-panel-navbar > ul.tab-headers > li {
color: #9FA3A5;
}
#details-panel ul.tab-headers {
#details-panel-content ul.tab-headers {
list-style: none;
flex-direction: row;
min-width: 550px;
@ -152,23 +152,23 @@ div#details-panel .details-panel-navbar > ul.tab-headers > li {
padding: 4px 15px;
}
div#details-panel .navbar-nav > li > a:hover,
div#details-panel .navbar-nav > li > a:focus,
div#details-panel .navbar-nav > li > button:hover,
div#details-panel .navbar-nav > li > button:focus
div#details-panel-content .navbar-nav > li > a:hover,
div#details-panel-content .navbar-nav > li > a:focus,
div#details-panel-content .navbar-nav > li > button:hover,
div#details-panel-content .navbar-nav > li > button:focus
{
background-color: #1E252B;
color: #D3D8DA;
}
div#details-panel .navbar-nav > li > a:active,
div#details-panel .navbar-nav > li > button:active
div#details-panel-content .navbar-nav > li > a:active,
div#details-panel-content .navbar-nav > li > button:active
{
background-color: #000;
}
div#details-panel .navbar-nav > li > a.disabled:active,
div#details-panel .navbar-nav > li > button.disabled:active
div#details-panel-content .navbar-nav > li > a.disabled:active,
div#details-panel-content .navbar-nav > li > button.disabled:active
{
background-color: #1E252B;
}
@ -177,12 +177,12 @@ div#details-panel .navbar-nav > li > button.disabled:active
flex: auto;
}
div#details-panel .details-panel-navbar .navbar-nav > li.active a,
div#details-panel .details-panel-navbar .navbar-nav > li.active a:hover,
div#details-panel .details-panel-navbar .navbar-nav > li.active a:focus,
div#details-panel .details-panel-navbar > li.active a,
div#details-panel .details-panel-navbar > li.active a:hover,
div#details-panel .details-panel-navbar > li.active a:focus {
div#details-panel-content .details-panel-navbar .navbar-nav > li.active a,
div#details-panel-content .details-panel-navbar .navbar-nav > li.active a:hover,
div#details-panel-content .details-panel-navbar .navbar-nav > li.active a:focus,
div#details-panel-content .details-panel-navbar > li.active a,
div#details-panel-content .details-panel-navbar > li.active a:hover,
div#details-panel-content .details-panel-navbar > li.active a:focus {
background-color: #1A4666;
color: #EEF0F2;
}
@ -207,14 +207,14 @@ div#details-panel .details-panel-navbar > li.active a:focus {
width: 100%;
}
#details-panel #job-details-list,
#details-panel .failure-summary-list,
#details-panel .similar-jobs > .similar-job-list tbody {
#details-panel-content #job-details-list,
#details-panel-content .failure-summary-list,
#details-panel-content .similar-jobs > .similar-job-list tbody {
overflow-y: auto;
height: 100%;
}
#details-panel {
#details-panel-content {
position: relative; /* So we can absolutely position the loading overlay */
height: 100%;
flex: auto;

Просмотреть файл

@ -43,9 +43,14 @@ a {
height: 100%;
}
job-view {
height: 100%;
display: flex;
flex-direction: column;
height: calc(100% - 63px);
}
.th-global-content {
flex: 1;
position: relative; /* Required to position inner content */
overflow-y: auto;
overflow-x: hidden;
}

Просмотреть файл

@ -24,8 +24,7 @@ import './css/treeherder-loading-overlay.css';
import './js/treeherder_app';
// Treeherder React UI
import './job-view/PushList';
import './job-view/details/DetailsPanel';
import './job-view/JobView';
// Treeherder JS
import './js/components/auth';

Просмотреть файл

@ -25,21 +25,12 @@
</div>
<ng-include src="'partials/main/thTreeherderUpdateBar.html'"></ng-include>
<ng-include src="'partials/main/thActiveFiltersBar.html'"></ng-include>
<div id="th-global-content" class="th-global-content">
<span class="th-view-content" ng-cloak>
<push-list
user="user"
repo-name="repoName"
revision="revision"
current-repo="currentRepo"
/>
</span>
</div>
<details-panel
<job-view
revision="revision"
current-repo="currentRepo"
repo-name="repoName"
selected-job="selectedJob"
user="user"
ng-show="selectedJob"
/>
</div>

54
ui/job-view/JobView.jsx Normal file
Просмотреть файл

@ -0,0 +1,54 @@
import React from 'react';
import PropTypes from 'prop-types';
import { react2angular } from 'react2angular/index.es2015';
import treeherder from '../js/treeherder';
import DetailsPanel from './details/DetailsPanel';
import PushList from './PushList';
const JobView = (props) => {
const { user, repoName, revision, currentRepo, selectedJob, $injector } = props;
return (
<React.Fragment>
<div id="th-global-content" className="th-global-content">
<span className="th-view-content">
<PushList
user={user}
repoName={repoName}
revision={revision}
currentRepo={currentRepo}
$injector={$injector}
/>
</span>
</div>
<DetailsPanel
className={selectedJob ? '' : 'hidden'}
repoName={repoName}
selectedJob={selectedJob}
user={user}
$injector={$injector}
/>
</React.Fragment>
);
};
JobView.propTypes = {
$injector: PropTypes.object.isRequired,
user: PropTypes.object.isRequired,
repoName: PropTypes.string.isRequired,
revision: PropTypes.string,
currentRepo: PropTypes.object,
selectedJob: PropTypes.object,
};
JobView.defaultProps = {
revision: null,
currentRepo: {},
selectedJob: null,
};
treeherder.component('jobView', react2angular(
JobView,
['repoName', 'user', 'revision', 'currentRepo', 'selectedJob'],
['$injector']));

Просмотреть файл

@ -1,9 +1,7 @@
import $ from 'jquery';
import React from 'react';
import PropTypes from 'prop-types';
import { react2angular } from 'react2angular/index.es2015';
import treeherder from '../js/treeherder';
import Push from './Push';
import {
findInstance,
@ -334,8 +332,3 @@ PushList.defaultProps = {
revision: null,
currentRepo: {},
};
treeherder.component('pushList', react2angular(
PushList,
['repoName', 'user', 'revision', 'currentRepo'],
['$injector']));

Просмотреть файл

@ -1,10 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import { react2angular } from 'react2angular/index.es2015';
import { chunk } from 'lodash';
import $ from 'jquery';
import treeherder from '../../js/treeherder';
import {
thEvents,
thBugSuggestionLimit,
@ -24,7 +22,15 @@ import PinBoard from './PinBoard';
import SummaryPanel from './summary/SummaryPanel';
import TabsPanel from './tabs/TabsPanel';
class DetailsPanel extends React.Component {
export default class DetailsPanel extends React.Component {
static getDerivedStateFromProps(props) {
if (!props.selectedJob) {
return { job: null };
}
return {};
}
constructor(props) {
super(props);
@ -42,6 +48,7 @@ class DetailsPanel extends React.Component {
this.selectJobController = null;
this.state = {
job: null,
isPinBoardVisible: false,
jobDetails: [],
jobLogUrls: [],
@ -424,7 +431,7 @@ class DetailsPanel extends React.Component {
} = this.state;
return (
<div className={job ? 'details-panel-slide' : 'hidden'}>
<div id="details-panel" className={job ? 'details-panel-slide' : 'hidden'}>
<div
id="details-panel-resizer"
resizer="horizontal"
@ -446,7 +453,7 @@ class DetailsPanel extends React.Component {
unPinAll={this.unPinAll}
$injector={$injector}
/>
{!!job && <div id="details-panel">
{!!job && <div id="details-panel-content">
<SummaryPanel
repoName={repoName}
selectedJob={job}
@ -507,8 +514,3 @@ DetailsPanel.defaultProps = {
user: { isLoggedIn: false, isStaff: false, email: null },
currentRepo: { isTryRepo: true },
};
treeherder.component('detailsPanel', react2angular(
DetailsPanel,
['repoName', 'selectedJob', 'user'],
['$injector']));