Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Project Management #2308

Merged
merged 82 commits into from
Oct 28, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
cfee43f
Add Git + GitHub context headers
simurai Feb 12, 2019
8d867b0
add project repo change ability
wadethestealth Oct 15, 2019
73b1ff8
update project context ui for github tab
wadethestealth Oct 15, 2019
d4ce922
rename to header-view
wadethestealth Oct 15, 2019
1f3cfc6
add header view to git tab
wadethestealth Oct 15, 2019
0ceb2ff
remove avatar and refresh button for mvp
wadethestealth Oct 16, 2019
1d8cef8
fix lint
wadethestealth Oct 16, 2019
5e3414a
remove padding
wadethestealth Oct 16, 2019
691ca1d
fix 'CurrentPullRequestContainer' test warnings
wadethestealth Oct 16, 2019
0dc2505
fix 'GitTabContainer' test warnings
wadethestealth Oct 16, 2019
61a39e3
fix 'GitHubTabContainer' test warnings
wadethestealth Oct 16, 2019
c22dc33
create generic Error Boundary
wadethestealth Oct 16, 2019
59db453
fix 'Decoration' test warnings
wadethestealth Oct 16, 2019
1323ea4
fix 'Marker' test warnings
wadethestealth Oct 16, 2019
f8df70e
fix 'IssueDetailContainer' test warnings
wadethestealth Oct 16, 2019
ecac2bd
fix 'IssueishSearchContainer' test warnings
wadethestealth Oct 16, 2019
ad45fe4
fix 'ReviewsContainer' test warnings
wadethestealth Oct 16, 2019
3e7fd43
fix 'ChangedFileController' test warnings
wadethestealth Oct 16, 2019
924807c
fix 'CommentDecorationsController' test warnings
wadethestealth Oct 16, 2019
7a9d05c
fix 'CommentDecorationsContainer' test warnings
wadethestealth Oct 16, 2019
0162fc9
correctly consume Relay Query error on 'IssueishSearchContainer' test
wadethestealth Oct 16, 2019
004d5b4
fix async test error
wadethestealth Oct 17, 2019
32f0360
update test props for github tab view
wadethestealth Oct 17, 2019
52ef584
remove active pane context guessing
wadethestealth Oct 17, 2019
9cbd126
LINT MEH BABHEH :baby:
wadethestealth Oct 17, 2019
413cd2d
Merge remote-tracking branch 'upstream/master' into project-management
wadethestealth Oct 17, 2019
98adefc
update to not prefer absent context from preferred/saved state work dir
wadethestealth Oct 17, 2019
083f650
update some test for github-package
wadethestealth Oct 17, 2019
5a0fd75
remove unapplicable tests
wadethestealth Oct 17, 2019
35e0df5
remove unnecessary test case step
wadethestealth Oct 17, 2019
e7f5ec8
simplify rendering header
wadethestealth Oct 17, 2019
d64c079
clean up header render
wadethestealth Oct 17, 2019
e1e7795
undo test nesting
wadethestealth Oct 18, 2019
63cd27e
remove only
wadethestealth Oct 18, 2019
61cdf7c
Merge branch 'master' into project-management
wadethestealth Oct 22, 2019
571a095
revert globals
wadethestealth Oct 22, 2019
73de350
replace context with describe
wadethestealth Oct 22, 2019
52c70d9
update error catching
wadethestealth Oct 22, 2019
21e025b
remove only
wadethestealth Oct 22, 2019
8d6870b
remove unapplicable
wadethestealth Oct 22, 2019
558c9a0
remove active pane listener
wadethestealth Oct 23, 2019
f03e06a
update all tests
wadethestealth Oct 23, 2019
34adef2
lints
wadethestealth Oct 23, 2019
72eb56c
lints
wadethestealth Oct 23, 2019
aa2edc9
add test cases
wadethestealth Oct 23, 2019
265072c
add integration tests
wadethestealth Oct 23, 2019
40df468
lint
wadethestealth Oct 23, 2019
bfedc49
Update test/atom/marker.test.js
wadethestealth Oct 24, 2019
24aa298
update bad assert
wadethestealth Oct 24, 2019
ebfa43c
name change
wadethestealth Oct 24, 2019
cf1fd25
remove comments
wadethestealth Oct 24, 2019
3c73da4
update error boundary
wadethestealth Oct 24, 2019
5dbdd62
name change
wadethestealth Oct 24, 2019
dde9b3b
remove extras
wadethestealth Oct 24, 2019
22b6a80
remove unused pane function
wadethestealth Oct 24, 2019
8bd2612
remove unused refs
wadethestealth Oct 24, 2019
a1cb095
change render logic to use function call instead of switch statement
wadethestealth Oct 24, 2019
5bb76cb
Update lib/views/header-view.js
wadethestealth Oct 24, 2019
d5a555a
Update lib/error-boundary.js
wadethestealth Oct 25, 2019
44f6ea5
update tests to shallow instead of mount
wadethestealth Oct 25, 2019
1a9938a
Merge branch 'project-management' of https://github.com/wadethestealt…
wadethestealth Oct 25, 2019
faa00ae
name change to TabHeaderView
wadethestealth Oct 25, 2019
6f249de
simplify context removal from pool
wadethestealth Oct 25, 2019
1d00a4c
add event for when open workdirs change
wadethestealth Oct 25, 2019
23d1dc4
typo
wadethestealth Oct 25, 2019
810ad66
name change to avoid confusion
wadethestealth Oct 25, 2019
ef802dc
use workdirs instead of project paths
wadethestealth Oct 25, 2019
9ec4e75
lint
wadethestealth Oct 25, 2019
d33d7da
invalid use of property
wadethestealth Oct 25, 2019
6a34a52
use workdirs working prototype
wadethestealth Oct 25, 2019
70f8028
remove stub restores
wadethestealth Oct 25, 2019
80f8b89
fix incorrect assert
wadethestealth Oct 25, 2019
f9fc198
update test
wadethestealth Oct 25, 2019
9bfe8f9
fix tests
wadethestealth Oct 25, 2019
95dcc1b
update tests
wadethestealth Oct 25, 2019
2192a25
lints
wadethestealth Oct 25, 2019
a28ece8
test fixes
wadethestealth Oct 25, 2019
1e2a8b8
update test cases
wadethestealth Oct 26, 2019
11d39d1
lints
wadethestealth Oct 26, 2019
7a0315a
add work dir pool tests
wadethestealth Oct 26, 2019
879b702
lints
wadethestealth Oct 26, 2019
1069fc9
remove extra fixture
wadethestealth Oct 26, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/controllers/git-tab-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export default class GitTabController extends React.Component {
openFiles: PropTypes.func.isRequired,
openInitializeDialog: PropTypes.func.isRequired,
controllerRef: RefHolderPropType,
changeProjectWorkingDirectory: PropTypes.func.isRequired,
};

constructor(props, context) {
Expand Down Expand Up @@ -119,6 +120,7 @@ export default class GitTabController extends React.Component {
openFiles={this.props.openFiles}
discardWorkDirChangesForPaths={this.props.discardWorkDirChangesForPaths}
undoLastDiscard={this.props.undoLastDiscard}
changeProjectWorkingDirectory={this.props.changeProjectWorkingDirectory}

attemptFileStageOperation={this.attemptFileStageOperation}
attemptStageAllOperation={this.attemptStageAllOperation}
Expand Down
5 changes: 5 additions & 0 deletions lib/controllers/github-tab-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import GitHubTabView from '../views/github-tab-view';

export default class GitHubTabController extends React.Component {
static propTypes = {
project: PropTypes.object.isRequired,
workspace: PropTypes.object.isRequired,
repository: PropTypes.object.isRequired,
remoteOperationObserver: OperationStateObserverPropType.isRequired,
Expand All @@ -21,6 +22,8 @@ export default class GitHubTabController extends React.Component {
aheadCount: PropTypes.number,
pushInProgress: PropTypes.bool.isRequired,
isLoading: PropTypes.bool.isRequired,

changeProjectWorkingDirectory: PropTypes.func.isRequired,
}

render() {
Expand All @@ -37,6 +40,7 @@ export default class GitHubTabController extends React.Component {

return (
<GitHubTabView
project={this.props.project}
workspace={this.props.workspace}
remoteOperationObserver={this.props.remoteOperationObserver}
loginModel={this.props.loginModel}
Expand All @@ -54,6 +58,7 @@ export default class GitHubTabController extends React.Component {

handlePushBranch={this.handlePushBranch}
handleRemoteSelect={this.handleRemoteSelect}
changeProjectWorkingDirectory={this.props.changeProjectWorkingDirectory}
/>
);
}
Expand Down
4 changes: 4 additions & 0 deletions lib/controllers/root-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export default class RootController extends React.Component {
clone: PropTypes.func.isRequired,

// Control
changeProjectWorkingDirectory: PropTypes.func.isRequired,
startOpen: PropTypes.bool,
startRevealed: PropTypes.bool,
}
Expand Down Expand Up @@ -284,6 +285,7 @@ export default class RootController extends React.Component {
discardWorkDirChangesForPaths={this.discardWorkDirChangesForPaths}
undoLastDiscard={this.undoLastDiscard}
refreshResolutionProgress={this.refreshResolutionProgress}
changeProjectWorkingDirectory={this.props.changeProjectWorkingDirectory}
/>
)}
</PaneItem>
Expand All @@ -296,7 +298,9 @@ export default class RootController extends React.Component {
ref={itemHolder.setter}
repository={this.props.repository}
loginModel={this.props.loginModel}
project={this.props.project}
workspace={this.props.workspace}
changeProjectWorkingDirectory={this.props.changeProjectWorkingDirectory}
/>
)}
</PaneItem>
Expand Down
71 changes: 47 additions & 24 deletions lib/github-package.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,21 @@ export default class GithubPackage {
return !!event.target.closest('.github-FilePatchListView').querySelector('.is-selected');
};

const handleActivePaneChange = item => {
const activeRepository = this.getActiveRepository();
const activeRepositoryPath = activeRepository ? activeRepository.getWorkingDirectoryPath() : null;
this.scheduleActiveContextUpdate({activeRepositoryPath}, {item});
};

const handleProjectPathsChange = projectPaths => {
const activeRepository = this.getActiveRepository();
const activeRepositoryPath = activeRepository ? activeRepository.getWorkingDirectoryPath() : null;
this.scheduleActiveContextUpdate({activeRepositoryPath}, {projectPaths});
};

this.subscriptions.add(
this.project.onDidChangePaths(this.scheduleActiveContextUpdate),
this.workspace.getCenter().onDidChangeActivePaneItem(this.scheduleActiveContextUpdate),
this.project.onDidChangePaths(handleProjectPathsChange),
this.workspace.getCenter().onDidStopChangingActivePaneItem(handleActivePaneChange),
this.styleCalculator.startWatching(
'github-package-styles',
['editor.fontSize', 'editor.fontFamily', 'editor.lineHeight', 'editor.tabLength'],
Expand Down Expand Up @@ -269,6 +281,10 @@ export default class GithubPackage {
}));
}

const changeProjectWorkingDirectory = projectWorkingDirectory => {
this.scheduleActiveContextUpdate({activeRepositoryPath: projectWorkingDirectory});
};

this.renderFn(
<RootController
ref={c => { this.controller = c; }}
Expand All @@ -294,6 +310,7 @@ export default class GithubPackage {
startOpen={this.startOpen}
startRevealed={this.startRevealed}
removeFilePatchItem={this.removeFilePatchItem}
changeProjectWorkingDirectory={changeProjectWorkingDirectory}
/>, this.element, callback,
);
}
Expand Down Expand Up @@ -486,25 +503,30 @@ export default class GithubPackage {
return this.switchboard;
}

async scheduleActiveContextUpdate(savedState = {}) {
/**
* Extras can be responses from subscribing to events
* For example, in `handleProjectPathsChange` extras contains the projectPaths changes,
* and in `handleActivePaneChange` extras contains the item changes.
*/
async scheduleActiveContextUpdate(savedState = {}, extras = null) {
this.switchboard.didScheduleActiveContextUpdate();
await this.activeContextQueue.push(this.updateActiveContext.bind(this, savedState), {parallel: false});
await this.activeContextQueue.push(this.updateActiveContext.bind(this, savedState, extras), {parallel: false});
}

/**
* Derive the git working directory context that should be used for the package's git operations based on the current
* state of the Atom workspace. In priority, this prefers:
*
* - The preferred git working directory set by the user (This is also the working directory that was active when the
* package was last serialized).
* - A git working directory that contains the active pane item in the workspace's center.
* - A git working directory corresponding to a single Project.
* - When initially activating the package, the working directory that was active when the package was last
* serialized.
* - The current context, unchanged, which may be a `NullWorkdirContext`.
*
* First updates the pool of resident contexts to match all git working directories that correspond to open
* projects and pane items.
*/
async getNextContext(savedState) {
async getNextContext(savedState, extras) {
const workdirs = new Set(
await Promise.all(
this.project.getPaths().map(async projectPath => {
Expand All @@ -530,39 +552,40 @@ export default class GithubPackage {
return {itemPath, itemWorkdir};
};

const active = await fromPaneItem(this.workspace.getCenter().getActivePaneItem());

this.contextPool.set(workdirs, savedState);

if (savedState.activeRepositoryPath) {
// Preferred git directory (the preferred directory or the last serialized directory).
return this.contextPool.getContext(savedState.activeRepositoryPath);
}

const active = await fromPaneItem(this.workspace.getCenter().getActivePaneItem());

if (active.itemPath) {
// Prefer an active item
return this.contextPool.getContext(active.itemWorkdir || active.itemPath);
}

if (this.project.getPaths().length === 1) {
const projectPaths = this.project.getPaths();

if (projectPaths.length === 1) {
// Single project
const projectPath = this.project.getPaths()[0];
const projectPath = projectPaths[0];
const activeWorkingDir = await this.workdirCache.find(projectPath);
return this.contextPool.getContext(activeWorkingDir || projectPath);
}

if (this.project.getPaths().length === 0 && !this.activeContext.getRepository().isUndetermined()) {
if (projectPaths.length === 0 && !this.activeContext.getRepository().isUndetermined()) {
// No projects. Revert to the absent context unless we've guessed that more projects are on the way.
return WorkdirContext.absent({pipelineManager: this.pipelineManager});
}

// Restore models from saved state. Will return a NullWorkdirContext if this path is not presently
// resident in the pool.
const savedWorkingDir = savedState.activeRepositoryPath;
if (savedWorkingDir) {
return this.contextPool.getContext(savedWorkingDir);
}

return this.activeContext;
}

setActiveContext(nextActiveContext) {
if (nextActiveContext !== this.activeContext) {
setActiveContext(nextActiveContext, extras) {
// Always update rendering when paths change.
if (nextActiveContext !== this.activeContext || (extras && extras.projectPaths)) {
if (this.activeContext === this.guessedContext) {
this.guessedContext.destroy();
this.guessedContext = null;
Expand All @@ -577,15 +600,15 @@ export default class GithubPackage {
}
}

async updateActiveContext(savedState = {}) {
async updateActiveContext(savedState = {}, extras = null) {
if (this.workspace.isDestroyed()) {
return;
}

this.switchboard.didBeginActiveContextUpdate();

const nextActiveContext = await this.getNextContext(savedState);
this.setActiveContext(nextActiveContext);
const nextActiveContext = await this.getNextContext(savedState, extras);
this.setActiveContext(nextActiveContext, extras);
}

async refreshAtomGitRepository(workdir) {
Expand Down
7 changes: 7 additions & 0 deletions lib/views/git-tab-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import cx from 'classnames';
import {CompositeDisposable} from 'atom';

import StagingView from './staging-view';
import HeaderView from './header-view';
import CommitController from '../controllers/commit-controller';
import RecentCommitsController from '../controllers/recent-commits-controller';
import RefHolder from '../models/ref-holder';
Expand Down Expand Up @@ -60,6 +61,7 @@ export default class GitTabView extends React.Component {
attemptFileStageOperation: PropTypes.func.isRequired,
discardWorkDirChangesForPaths: PropTypes.func.isRequired,
openFiles: PropTypes.func.isRequired,
changeProjectWorkingDirectory: PropTypes.func.isRequired,
};

constructor(props, context) {
Expand Down Expand Up @@ -141,6 +143,11 @@ export default class GitTabView extends React.Component {
className={cx('github-Git', {'is-loading': isLoading})}
tabIndex="-1"
ref={this.props.refRoot.setter}>
<HeaderView
handleProjectSelect={e => this.props.changeProjectWorkingDirectory(e.target.value)}
currentProject={this.props.workingDirectoryPath}
projectPaths={this.props.project.getPaths()}
/>
<StagingView
ref={this.props.refStagingView.setter}
commands={this.props.commands}
Expand Down
8 changes: 8 additions & 0 deletions lib/views/github-tab-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import {
} from '../prop-types';
import LoadingView from './loading-view';
import RemoteSelectorView from './remote-selector-view';
import HeaderView from './header-view';
import RemoteContainer from '../containers/remote-container';

export default class GitHubTabView extends React.Component {
static propTypes = {
project: PropTypes.object.isRequired,
workspace: PropTypes.object.isRequired,
remoteOperationObserver: OperationStateObserverPropType.isRequired,
loginModel: GithubLoginModelPropType.isRequired,
Expand All @@ -28,11 +30,17 @@ export default class GitHubTabView extends React.Component {

handlePushBranch: PropTypes.func.isRequired,
handleRemoteSelect: PropTypes.func.isRequired,
changeProjectWorkingDirectory: PropTypes.func.isRequired,
}

render() {
return (
<div className="github-GitHub" ref={this.props.rootHolder.setter}>
<HeaderView
handleProjectSelect={e => this.props.changeProjectWorkingDirectory(e.target.value)}
currentProject={this.props.workingDirectory}
projectPaths={this.props.project.getPaths()}
/>
<div className="github-GitHub-content">
{this.renderRemote()}
</div>
Expand Down
32 changes: 32 additions & 0 deletions lib/views/header-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import PropTypes from 'prop-types';
import path from 'path';

export default class HeaderView extends React.Component {
static propTypes = {
currentProject: PropTypes.string,
projectPaths: PropTypes.arrayOf(PropTypes.string),

handleProjectSelect: PropTypes.func.isRequired,
}

render() {
return (
<header className="github-Project">
<select className="github-Project-path input-select"
value={this.props.currentProject}
onChange={this.props.handleProjectSelect}>
{this.renderProjects()}
</select>
</header>
);
}

renderProjects = () => {
const projects = [];
for (const projectPath of this.props.projectPaths) {
projects.push(<option key={projectPath} value={projectPath}>{path.basename(projectPath)}</option>);
}
return projects;
};
}
13 changes: 13 additions & 0 deletions styles/project.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@import "variables";

.github-Project {
display: flex;
align-items: center;
padding: @component-padding/2 @component-padding;
border-bottom: 1px solid @base-border-color;

&-path {
flex: 1;
}

}