var _ = require('underscore'); var $ = require('jquery'); var React = require('react/addons'); var Router = require('react-router'); var ContainerStore = require('./ContainerStore'); var ContainerUtil = require('./ContainerUtil'); var docker = require('./docker'); var exec = require('exec'); var boot2docker = require('./boot2docker'); var ProgressBar = require('react-bootstrap/ProgressBar'); var Route = Router.Route; var NotFoundRoute = Router.NotFoundRoute; var DefaultRoute = Router.DefaultRoute; var Link = Router.Link; var RouteHandler = Router.RouteHandler; var ContainerDetails = React.createClass({ mixins: [Router.State], _oldHeight: 0, PAGE_LOGS: 'logs', PAGE_SETTINGS: 'settings', getInitialState: function () { return { logs: [], page: this.PAGE_LOGS, env: {}, pendingEnv: {} }; }, componentWillReceiveProps: function () { if (this.state.page === this.PAGE_SETTINGS) { } console.log(this.props.container); this.init(); }, componentWillMount: function () { this.init(); }, componentDidMount: function () { ContainerStore.on(ContainerStore.SERVER_PROGRESS_EVENT, this.updateProgress); ContainerStore.on(ContainerStore.SERVER_LOGS_EVENT, this.updateLogs); }, componentWillUnmount: function () { // app close ContainerStore.removeListener(ContainerStore.SERVER_PROGRESS_EVENT, this.updateProgress); ContainerStore.removeListener(ContainerStore.SERVER_LOGS_EVENT, this.updateLogs); }, componentDidUpdate: function () { var parent = $('.details-logs'); if (!parent.length) { return; } if (parent.scrollTop() >= this._oldHeight) { parent.stop(); parent.scrollTop(parent[0].scrollHeight - parent.height()); } this._oldHeight = parent[0].scrollHeight - parent.height(); }, init: function () { this.setState({ env: ContainerUtil.env(ContainerStore.container(this.getParams().name)) }); ContainerStore.fetchLogs(this.getParams().name, function () { this.updateLogs(); }.bind(this)); }, updateLogs: function (name) { if (name && name !== this.getParams().name) { return; } this.setState({ logs: ContainerStore.logs(this.getParams().name) }); }, updateProgress: function (name) { console.log('progress', name, ContainerStore.progress(name)); if (name === this.getParams().name) { this.setState({ progress: ContainerStore.progress(name) }); } }, showLogs: function () { this.setState({ page: this.PAGE_LOGS }); }, showSettings: function () { this.setState({ page: this.PAGE_SETTINGS }); }, handleView: function () { var container = this.props.container; boot2docker.ip(function (err, ip) { var ports = _.map(container.NetworkSettings.Ports, function (value, key) { var portProtocolPair = key.split('/'); var res = { 'port': portProtocolPair[0], 'protocol': portProtocolPair[1] }; if (value && value.length) { var port = value[0].HostPort; res.host = ip; res.port = port; res.url = 'http://' + ip + ':' + port; } else { return null; } return res; }); exec(['open', ports[0].url], function (err) { if (err) { throw err; } }); }); }, handleSaveEnvVar: function () { var $rows = $('.env-vars .keyval-row'); var envVarList = []; $rows.each(function () { var key = $(this).find('.key').val(); var val = $(this).find('.val').val(); if (!key.length || !val.length) { return; } envVarList.push(key + '=' + val); }); ContainerStore.updateContainer(this.props.container.Name, { Env: envVarList }); }, handleAddPendingEnvVar: function () { var newKey = $('#new-env-key').val(); var newVal = $('#new-env-val').val(); var newEnv = {}; newEnv[newKey] = newVal; this.setState({ pendingEnv: _.extend(this.state.pendingEnv, newEnv) }); $('#new-env-key').val(''); $('#new-env-val').val(''); }, handleRemoveEnvVar: function (key) { var newEnv = _.omit(this.state.env, key); this.setState({ env: newEnv }); }, handleRemovePendingEnvVar: function (key) { var newEnv = _.omit(this.state.pendingEnv, key); this.setState({ pendingEnv: newEnv }); }, handleDeleteContainer: function () { var container = this.props.container; var name = container.Name.replace('/', ''); ContainerStore.remove(name, function (err) { console.error(err); }); }, render: function () { var self = this; if (!this.state) { return
; } var logs = this.state.logs.map(function (l, i) { return

; }); if (!this.props.container) { return false; } var state; if (this.props.container.State.Running) { state =

running

; } else if (this.props.container.State.Restarting) { state =

restarting

; } else if (this.props.container.State.Paused) { state =

paused

; } else if (this.props.container.State.Downloading) { state =

downloading

; } var button; if (this.state.progress === 1) { button = View; } else { button = View; } var envVars = _.map(this.state.env, function (val, key) { return (
); }); var pendingEnvVars = _.map(this.state.pendingEnv, function (val, key) { return (
); }); var body; if (this.props.container.State.Downloading) { body = (
); } else { if (this.state.page === this.PAGE_LOGS) { body = (
{logs}
); } else { body = (

Container Name

Environment Variables

KEY
VALUE
{envVars} {pendingEnvVars}
Save

Delete Container

Delete Container
); } } var disabledClass = ''; if (!this.props.container.State.Running) { disabledClass = 'disabled'; } var buttonClass = React.addons.classSet({ btn: true, 'btn-action': true, 'with-icon': true, disabled: !this.props.container.State.Running }); var dropdownButtonClass = React.addons.classSet({ btn: true, 'btn-action': true, 'with-icon': true, 'dropdown-toggle': true, disabled: !this.props.container.State.Running }); var textButtonClasses = React.addons.classSet({ 'btn': true, 'btn-action': true, 'only-icon': true, 'active': this.state.page === this.PAGE_LOGS, disabled: !this.props.container.State.Running }); var gearButtonClass = React.addons.classSet({ 'btn': true, 'btn-action': true, 'only-icon': true, 'active': this.state.page === this.PAGE_SETTINGS, disabled: !this.props.container.State.Running }); return (

{this.props.container.Name}

{state}

Image

{this.props.container.Config.Image}

View
Volumes
Restart
Terminal
{body}
); } }); module.exports = ContainerDetails;