diff --git a/app/ContainerDetails.react.js b/app/ContainerDetails.react.js index ed0b7e56ef..7b14765f3b 100644 --- a/app/ContainerDetails.react.js +++ b/app/ContainerDetails.react.js @@ -11,6 +11,8 @@ var ContainerUtil = require('./ContainerUtil'); var docker = require('./docker'); var boot2docker = require('./boot2docker'); var ProgressBar = require('react-bootstrap/ProgressBar'); +var Popover = require('react-bootstrap/Popover'); +var OverlayTrigger = require('react-bootstrap/OverlayTrigger'); var Route = Router.Route; var NotFoundRoute = Router.NotFoundRoute; @@ -28,7 +30,9 @@ var ContainerDetails = React.createClass({ logs: [], page: this.PAGE_LOGS, env: {}, - pendingEnv: {} + pendingEnv: {}, + ports: {}, + volumes: {} }; }, componentWillReceiveProps: function () { @@ -59,8 +63,14 @@ var ContainerDetails = React.createClass({ }, init: function () { this.setState({ - env: ContainerUtil.env(ContainerStore.container(this.getParams().name)) + env: ContainerUtil.env(ContainerStore.container(this.getParams().name)), + volumes: ContainerUtil.volumes(ContainerStore.container(this.getParams().name)) }); + ContainerUtil.ports(ContainerStore.container(this.getParams().name), function (err, ports) { + this.setState({ + ports: ports + }); + }.bind(this)); ContainerStore.fetchLogs(this.getParams().name, function () { this.updateLogs(); }.bind(this)); @@ -115,6 +125,11 @@ var ContainerDetails = React.createClass({ }); }); }, + handleViewLink: function (url) { + exec(['open', url], function (err) { + if (err) { throw err; } + }); + }, handleTerminal: function () { var container = this.props.container; var terminal = path.join(process.cwd(), 'resources', 'terminal').replace(/ /g, '\\\\ '); @@ -125,6 +140,18 @@ var ContainerDetails = React.createClass({ } }); }, + handleSaveContainerName: function () { + var newName = $('#input-container-name').val(); + var self = this; + console.log(newName); + ContainerStore.updateContainer(self.props.container.Name, { + name: newName + }, function (err) { + if (err) { + console.error(err); + } + }); + }, handleSaveEnvVar: function () { var $rows = $('.env-vars .keyval-row'); var envVarList = []; @@ -259,7 +286,10 @@ var ContainerDetails = React.createClass({

Container Name

- +
+ +
+ Save

Environment Variables

KEY
@@ -317,6 +347,29 @@ var ContainerDetails = React.createClass({ disabled: this.props.container.State.Downloading }); + var viewPopoverClasses = React.addons.classSet({ + popover: true, + hidden: false + }); + + var ports = _.map(self.state.ports, function (val, key) { + return ( +
+ {key} + {val.display} +
+ ); + }); + + var volumes = _.map(self.state.volumes, function (val, key) { + return ( +
+ {key} + {val} +
+ ); + }); + return (
@@ -325,10 +378,35 @@ var ContainerDetails = React.createClass({
- View + View + +
+
DOCKER PORT
+
LOCAL PORT
+
+
+ {ports} +
+ + }> + +
- Volumes + +
+
DOCKER FOLDER
+
LOCAL FOLDER
+
+
+ {volumes} +
+ + }> + Volumes +
Restart diff --git a/app/ContainerModal.react.js b/app/ContainerModal.react.js index a8f45c03b9..74098a8320 100644 --- a/app/ContainerModal.react.js +++ b/app/ContainerModal.react.js @@ -227,6 +227,7 @@ var ContainerModal = React.createClass({
+ {question}
{title}
{results} diff --git a/app/ContainerStore.js b/app/ContainerStore.js index 072390ea84..f3896c7894 100644 --- a/app/ContainerStore.js +++ b/app/ContainerStore.js @@ -397,7 +397,10 @@ var ContainerStore = assign(EventEmitter.prototype, { }, updateContainer: function (name, data, callback) { _muted[name] = true; + console.log(data); + console.log(_containers[name]); var fullData = assign(_containers[name], data); + console.log(fullData); this._createContainer(name, fullData, function (err) { this.emit(this.CLIENT_CONTAINER_EVENT, name); _muted[name] = false; diff --git a/app/ContainerUtil.js b/app/ContainerUtil.js index 41b9a7cca3..4fe9bcd823 100644 --- a/app/ContainerUtil.js +++ b/app/ContainerUtil.js @@ -10,7 +10,39 @@ var ContainerUtil = { var splits = [env.slice(0, i), env.slice(i + 1)]; return splits; })); - } + }, + ports: function (container, callback) { + var res = {}; + boot2docker.ip(function (err, ip) { + _.each(container.NetworkSettings.Ports, function (value, key) { + var dockerPort = key.split('/')[0]; + var localUrl = null; + var localUrlDisplay = null; + if (value && value.length) { + var port = value[0].HostPort; + localUrl = 'http://' + ip + ':' + port; + localUrlDisplay = ip + ':' + port; + } + res[dockerPort] = { + url: localUrl, + display: localUrlDisplay + }; + }); + callback(err, res); + }); + }, + volumes: function (container) { + var res = {}; + if (container.Volumes) { + res = container.Volumes; + _.each(res, function (value, key) { + if (value && value.indexOf("/mnt/sda1/var/lib/docker/vfs/dir/") > -1) { + res[key] = null; + } + }); + } + return res; + }, }; module.exports = ContainerUtil; diff --git a/app/styles/containers.less b/app/styles/containers.less index 6882fb166a..842fbf355c 100644 --- a/app/styles/containers.less +++ b/app/styles/containers.less @@ -1,3 +1,28 @@ +.port-labels { + width: 100%; + font-size: 12px; + color: @gray-lightest; + margin-left: 5px; + margin-bottom: 5px; + .label-docker { + display: inline-block; + margin-right: 30px; + width: 20%; + } + .label-local { + display: inline-block; + width: 40%; + } +} + +.popover-view { + min-width: 500px; +} + +.popover-volume { + min-width: 500px; +} + .containers { height: 100%; display: flex; @@ -349,6 +374,13 @@ } } + .container-name { + margin-bottom: 20px; + input { + width: 20%; + } + } + .env-vars-labels { width: 100%; font-size: 12px;