зеркало из https://github.com/mozilla/treeherder.git
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:
Родитель
9ce293f9b8
Коммит
a81e7a85c7
|
@ -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>
|
||||
|
||||
|
|
|
@ -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']));
|
||||
|
|
Загрузка…
Ссылка в новой задаче