Merge pull request #439 from kitematic/polish-stop-button

Polished stop container button and added toggling start/stop button
This commit is contained in:
Sean Li 2015-04-27 12:14:00 -07:00
commit 5ee059ccb6
7 changed files with 62 additions and 11 deletions

BIN
images/button-start.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
images/button-start@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -54,12 +54,18 @@ var ContainerDetailsSubheader = React.createClass({
} }
return (this.props.container.State.Downloading || this.props.container.State.Restarting); return (this.props.container.State.Downloading || this.props.container.State.Restarting);
}, },
stopDisabled: function () { disableStop: function () {
if (!this.props.container) { if (!this.props.container) {
return false; return false;
} }
return (this.props.container.State.Downloading || this.props.container.State.ExitCode); return (this.props.container.State.Downloading || this.props.container.State.ExitCode);
}, },
disableStart: function () {
if (!this.props.container) {
return false;
}
return (this.props.container.State.Downloading || this.props.container.State.Running);
},
disableTerminal: function () { disableTerminal: function () {
if (!this.props.container) { if (!this.props.container) {
return false; return false;
@ -110,12 +116,19 @@ var ContainerDetailsSubheader = React.createClass({
} }
}, },
handleStop: function () { handleStop: function () {
if (!this.stopDisabled()) { if (!this.disableStop()) {
metrics.track('Stopped Container'); metrics.track('Stopped Container');
ContainerStore.stop(this.props.container.Name, function () { ContainerStore.stop(this.props.container.Name, function () {
}); });
} }
}, },
handleStart: function () {
if (!this.disableStart()) {
metrics.track('Started Container');
ContainerStore.start(this.props.container.Name, function () {
});
}
},
handleTerminal: function () { handleTerminal: function () {
if (!this.disableTerminal()) { if (!this.disableTerminal()) {
metrics.track('Terminaled Into Container'); metrics.track('Terminaled Into Container');
@ -155,6 +168,14 @@ var ContainerDetailsSubheader = React.createClass({
var $action = $(this.getDOMNode()).find('.action .stop'); var $action = $(this.getDOMNode()).find('.action .stop');
$action.css("visibility", "hidden"); $action.css("visibility", "hidden");
}, },
handleItemMouseEnterStart: function () {
var $action = $(this.getDOMNode()).find('.action .start');
$action.css("visibility", "visible");
},
handleItemMouseLeaveStart: function () {
var $action = $(this.getDOMNode()).find('.action .start');
$action.css("visibility", "hidden");
},
handleItemMouseEnterTerminal: function () { handleItemMouseEnterTerminal: function () {
var $action = $(this.getDOMNode()).find('.action .terminal'); var $action = $(this.getDOMNode()).find('.action .terminal');
$action.css("visibility", "visible"); $action.css("visibility", "visible");
@ -174,7 +195,11 @@ var ContainerDetailsSubheader = React.createClass({
}); });
var stopActionClass = classNames({ var stopActionClass = classNames({
action: true, action: true,
disabled: this.stopDisabled() disabled: this.disableStop()
});
var startActionClass = classNames({
action: true,
disabled: this.disableStart()
}); });
var terminalActionClass = classNames({ var terminalActionClass = classNames({
action: true, action: true,
@ -195,6 +220,22 @@ var ContainerDetailsSubheader = React.createClass({
'active': this.state.currentRoute && (this.state.currentRoute.indexOf('containerSettings') >= 0), 'active': this.state.currentRoute && (this.state.currentRoute.indexOf('containerSettings') >= 0),
disabled: this.disableTab() disabled: this.disableTab()
}); });
var startStopToggle;
if (this.disableStop()) {
startStopToggle = (
<div className={startActionClass} onMouseEnter={this.handleItemMouseEnterStart} onMouseLeave={this.handleItemMouseLeaveStart}>
<div className="action-icon" onClick={this.handleStart}><RetinaImage src="button-start.png" /></div>
<span className="btn-label start">Start</span>
</div>
);
} else {
startStopToggle = (
<div className={stopActionClass} onMouseEnter={this.handleItemMouseEnterStop} onMouseLeave={this.handleItemMouseLeaveStop}>
<div className="action-icon" onClick={this.handleStop}><RetinaImage src="button-stop.png" /></div>
<span className="btn-label stop">Stop</span>
</div>
);
}
return ( return (
<div className="details-subheader"> <div className="details-subheader">
<div className="details-header-actions"> <div className="details-header-actions">
@ -206,10 +247,7 @@ var ContainerDetailsSubheader = React.createClass({
<div className="action-icon" onClick={this.handleRestart}><RetinaImage src="button-restart.png"/></div> <div className="action-icon" onClick={this.handleRestart}><RetinaImage src="button-restart.png"/></div>
<span className="btn-label restart">Restart</span> <span className="btn-label restart">Restart</span>
</div> </div>
<div className={stopActionClass} onMouseEnter={this.handleItemMouseEnterStop} onMouseLeave={this.handleItemMouseLeaveStop}> {{startStopToggle}}
<div className="action-icon" onClick={this.handleStop}><RetinaImage src="button-stop.png"/></div>
<span className="btn-label stop">Stop</span>
</div>
<div className={terminalActionClass} onMouseEnter={this.handleItemMouseEnterTerminal} onMouseLeave={this.handleItemMouseLeaveTerminal}> <div className={terminalActionClass} onMouseEnter={this.handleItemMouseEnterTerminal} onMouseLeave={this.handleItemMouseLeaveTerminal}>
<div className="action-icon" onClick={this.handleTerminal}><RetinaImage src="button-terminal.png"/></div> <div className="action-icon" onClick={this.handleTerminal}><RetinaImage src="button-terminal.png"/></div>
<span className="btn-label terminal">Terminal</span> <span className="btn-label terminal">Terminal</span>

View File

@ -411,6 +411,16 @@ var ContainerStore = assign(Object.create(EventEmitter.prototype), {
} }
}); });
}, },
start: function (name, callback) {
var container = docker.client().getContainer(name);
container.start(err => {
if (err && err.statusCode !== 304) {
callback(err);
} else {
this.fetchContainer(name, callback);
}
});
},
remove: function (name, callback) { remove: function (name, callback) {
if (_placeholders[name]) { if (_placeholders[name]) {
delete _placeholders[name]; delete _placeholders[name];

View File

@ -25,6 +25,10 @@
.action { .action {
display: inline-block; display: inline-block;
position: relative; position: relative;
img {
width: 42px;
height: 42px;
}
&.disabled { &.disabled {
opacity: 0.3; opacity: 0.3;
} }
@ -40,19 +44,18 @@
top: 45px; top: 45px;
&.view { &.view {
left: 7px; left: 7px;
//left: 0px;
} }
&.restart { &.restart {
left: 2px; left: 2px;
//left: -18px;
} }
&.stop { &.stop {
left: 7px; left: 7px;
//left: -18px; }
&.start {
left: 7px;
} }
&.terminal { &.terminal {
left: -1px; left: -1px;
//left: -30px;
} }
visibility: hidden; visibility: hidden;
} }