mirror of https://github.com/docker/docs.git
227 lines
6.5 KiB
JavaScript
227 lines
6.5 KiB
JavaScript
var _ = require('underscore');
|
|
var React = require('react/addons');
|
|
var remote = require('remote');
|
|
var metrics = require('../utils/MetricsUtil');
|
|
var dialog = remote.require('dialog');
|
|
var ContainerUtil = require('../utils/ContainerUtil');
|
|
var containerActions = require('../actions/ContainerActions');
|
|
|
|
var ContainerSettingsGeneral = React.createClass({
|
|
mixins: [React.addons.LinkedStateMixin],
|
|
|
|
contextTypes: {
|
|
router: React.PropTypes.func
|
|
},
|
|
|
|
getInitialState: function () {
|
|
let env = ContainerUtil.env(this.props.container) || [];
|
|
env.push(['', '']);
|
|
return {
|
|
slugName: null,
|
|
nameError: null,
|
|
env: env
|
|
};
|
|
},
|
|
|
|
shouldComponentUpdate: function (nextProps, nextState) {
|
|
if (nextState.slugName !== this.state.slugName || nextState.nameError !== this.state.nameError) {
|
|
return true;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
|
|
handleNameChange: function (e) {
|
|
let name = e.target.value;
|
|
if (name === this.state.slugName) {
|
|
return;
|
|
}
|
|
|
|
name = name.replace(/^\s+|\s+$/g, ''); // Trim
|
|
name = name.toLowerCase();
|
|
// Remove Accents
|
|
let from = "àáäâèéëêìíïîòóöôùúüûñç·/,:;";
|
|
let to = "aaaaeeeeiiiioooouuuunc-----";
|
|
for (var i=0, l=from.length ; i<l ; i++) {
|
|
name = name.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
|
|
}
|
|
name = name.replace(/[^a-z0-9-_.\s]/g, '') // Remove invalid chars
|
|
.replace(/\s+/g, '-') // Collapse whitespace and replace by -
|
|
.replace(/-+/g, '-') // Collapse dashes
|
|
.replace(/_+/g, '_'); // Collapse underscores
|
|
|
|
this.setState({
|
|
slugName: name
|
|
});
|
|
},
|
|
|
|
handleNameOnKeyUp: function (e) {
|
|
if (e.keyCode === 13 && this.state.slugName) {
|
|
this.handleSaveContainerName();
|
|
}
|
|
},
|
|
|
|
handleSaveContainerName: function () {
|
|
var newName = this.state.slugName;
|
|
if (newName === this.props.container.Name) {
|
|
return;
|
|
}
|
|
|
|
this.setState({
|
|
slugName: null
|
|
});
|
|
|
|
if (this.props.containers[newName]) {
|
|
this.setState({
|
|
nameError: 'A container already exists with this name.'
|
|
});
|
|
return;
|
|
}
|
|
|
|
containerActions.rename(this.props.container.Name, newName);
|
|
this.context.router.transitionTo('containerSettingsGeneral', {name: newName});
|
|
metrics.track('Changed Container Name');
|
|
},
|
|
|
|
handleSaveEnvVars: function () {
|
|
metrics.track('Saved Environment Variables');
|
|
let list = [];
|
|
_.each(this.state.env, kvp => {
|
|
let [key, value] = kvp;
|
|
if ((key && key.length) || (value && value.length)) {
|
|
list.push(key + '=' + value);
|
|
}
|
|
});
|
|
containerActions.update(this.props.container.Name, {Env: list});
|
|
},
|
|
|
|
handleChangeEnvKey: function (index, event) {
|
|
let env = _.map(this.state.env, _.clone);
|
|
env[index][0] = event.target.value;
|
|
this.setState({
|
|
env: env
|
|
});
|
|
},
|
|
|
|
handleChangeEnvVal: function (index, event) {
|
|
let env = _.map(this.state.env, _.clone);
|
|
env[index][1] = event.target.value;
|
|
this.setState({
|
|
env: env
|
|
});
|
|
},
|
|
|
|
handleAddEnvVar: function () {
|
|
let env = _.map(this.state.env, _.clone);
|
|
env.push(['', '']);
|
|
this.setState({
|
|
env: env
|
|
});
|
|
metrics.track('Added Pending Environment Variable');
|
|
},
|
|
|
|
handleRemoveEnvVar: function (index) {
|
|
let env = _.map(this.state.env, _.clone);
|
|
env.splice(index, 1);
|
|
if (env.length === 0) {
|
|
env.push(['', '']);
|
|
}
|
|
|
|
this.setState({
|
|
env: env
|
|
});
|
|
|
|
metrics.track('Removed Environment Variable');
|
|
},
|
|
|
|
handleDeleteContainer: function () {
|
|
dialog.showMessageBox({
|
|
message: 'Are you sure you want to delete this container?',
|
|
buttons: ['Delete', 'Cancel']
|
|
}, index => {
|
|
if (index === 0) {
|
|
metrics.track('Deleted Container', {
|
|
from: 'settings',
|
|
type: 'existing'
|
|
});
|
|
containerActions.destroy(this.props.container.Name);
|
|
}
|
|
});
|
|
},
|
|
|
|
render: function () {
|
|
if (!this.props.container) {
|
|
return false;
|
|
}
|
|
|
|
var willBeRenamedAs;
|
|
var btnSaveName = (
|
|
<a className="btn btn-action" onClick={this.handleSaveContainerName} disabled="disabled">Save</a>
|
|
);
|
|
if (this.state.slugName) {
|
|
willBeRenamedAs = (
|
|
<p>Will be renamed as: <strong>{this.state.slugName}</strong></p>
|
|
);
|
|
btnSaveName = (
|
|
<a className="btn btn-action" onClick={this.handleSaveContainerName}>Save</a>
|
|
);
|
|
} else if (this.state.nameError) {
|
|
willBeRenamedAs = (
|
|
<p><strong>{this.state.nameError}</strong></p>
|
|
);
|
|
}
|
|
|
|
let rename = (
|
|
<div className="settings-section">
|
|
<h3>Container Name</h3>
|
|
<div className="container-name">
|
|
<input id="input-container-name" type="text" className="line" placeholder="Container Name" defaultValue={this.props.container.Name} onChange={this.handleNameChange} onKeyUp={this.handleNameOnKeyUp}></input>
|
|
{willBeRenamedAs}
|
|
</div>
|
|
{btnSaveName}
|
|
</div>
|
|
);
|
|
|
|
let vars = _.map(this.state.env, (kvp, index) => {
|
|
let [key, val] = kvp;
|
|
let icon;
|
|
if (index === this.state.env.length - 1) {
|
|
icon = <a onClick={this.handleAddEnvVar} className="only-icon btn btn-positive small"><span className="icon icon-add-1"></span></a>;
|
|
} else {
|
|
icon = <a onClick={this.handleRemoveEnvVar.bind(this, index)} className="only-icon btn btn-action small"><span className="icon icon-cross"></span></a>;
|
|
}
|
|
|
|
return (
|
|
<div className="keyval-row">
|
|
<input type="text" className="key line" defaultValue={key} onChange={this.handleChangeEnvKey.bind(this, index)}></input>
|
|
<input type="text" className="val line" defaultValue={val} onChange={this.handleChangeEnvVal.bind(this, index)}></input>
|
|
{icon}
|
|
</div>
|
|
);
|
|
});
|
|
|
|
return (
|
|
<div className="settings-panel">
|
|
{rename}
|
|
<div className="settings-section">
|
|
<h3>Environment Variables</h3>
|
|
<div className="env-vars-labels">
|
|
<div className="label-key">KEY</div>
|
|
<div className="label-val">VALUE</div>
|
|
</div>
|
|
<div className="env-vars">
|
|
{vars}
|
|
</div>
|
|
<a className="btn btn-action" disabled={this.props.container.State.Updating} onClick={this.handleSaveEnvVars}>Save</a>
|
|
</div>
|
|
<div className="settings-section">
|
|
<h3>Delete Container</h3>
|
|
<a className="btn btn-action" onClick={this.handleDeleteContainer}>Delete Container</a>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
});
|
|
|
|
module.exports = ContainerSettingsGeneral;
|