@@ -226,25 +181,25 @@ var ContainerSettingsGeneral = React.createClass({
{btnSaveName}
);
- var self = this;
- var envVars = _.map(this.state.env, function (val, key) {
+
+ let vars = _.map(this.state.env, (kvp, index) => {
+ let [key, val] = kvp;
+ let icon;
+ if (index === this.state.env.length - 1) {
+ icon =
- );
- });
- var pendingEnvVars = _.map(this.state.pendingEnv, function (val, key) {
- return (
-
Delete Container
diff --git a/src/components/ContainerSettingsPorts.react.js b/src/components/ContainerSettingsPorts.react.js
index 1992763a4f..c266384d94 100644
--- a/src/components/ContainerSettingsPorts.react.js
+++ b/src/components/ContainerSettingsPorts.react.js
@@ -1,7 +1,6 @@
var _ = require('underscore');
var React = require('react/addons');
var shell = require('shell');
-var ContainerStore = require('../stores/ContainerStore');
var ContainerUtil = require('../utils/ContainerUtil');
var metrics = require('../utils/MetricsUtil');
var webPorts = require('../utils/Util').webPorts;
@@ -16,18 +15,11 @@ var ContainerSettingsPorts = React.createClass({
defaultPort: null
};
},
- componentWillReceiveProps: function () {
- this.init();
- },
componentDidMount: function() {
- this.init();
- },
- init: function () {
- var container = ContainerStore.container(this.context.router.getCurrentParams().name);
- if (!container) {
+ if (!this.props.container) {
return;
}
- var ports = ContainerUtil.ports(container);
+ var ports = ContainerUtil.ports(this.props.container);
this.setState({
ports: ports,
defaultPort: _.find(_.keys(ports), function (port) {
diff --git a/src/components/ContainerSettingsVolumes.react.js b/src/components/ContainerSettingsVolumes.react.js
index 73c8ef95c0..5ccd5e4f32 100644
--- a/src/components/ContainerSettingsVolumes.react.js
+++ b/src/components/ContainerSettingsVolumes.react.js
@@ -4,12 +4,12 @@ var remote = require('remote');
var dialog = remote.require('dialog');
var shell = require('shell');
var metrics = require('../utils/MetricsUtil');
-var ContainerStore = require('../stores/ContainerStore');
+var containerActions = require('../actions/ContainerActions');
var ContainerSettingsVolumes = React.createClass({
handleChooseVolumeClick: function (dockerVol) {
var self = this;
- dialog.showOpenDialog({properties: ['openDirectory', 'createDirectory']}, function (filenames) {
+ dialog.showOpenDialog({properties: ['openDirectory', 'createDirectory']}, (filenames) => {
if (!filenames) {
return;
}
@@ -21,11 +21,8 @@ var ContainerSettingsVolumes = React.createClass({
var binds = _.pairs(volumes).map(function (pair) {
return pair[1] + ':' + pair[0];
});
- ContainerStore.updateContainer(self.props.container.Name, {
- Binds: binds
- }, function (err) {
- if (err) { console.log(err); }
- });
+
+ containerActions.update(this.props.container.Name, {Binds: binds, Volumes: volumes});
}
});
},
@@ -38,11 +35,7 @@ var ContainerSettingsVolumes = React.createClass({
var binds = _.pairs(volumes).map(function (pair) {
return pair[1] + ':' + pair[0];
});
- ContainerStore.updateContainer(this.props.container.Name, {
- Binds: binds
- }, function (err) {
- if (err) { console.log(err); }
- });
+ containerActions.update(this.props.container.Name, {Binds: binds, Volumes: volumes});
},
handleOpenVolumeClick: function (path) {
metrics.track('Opened Volume Directory', {
@@ -52,24 +45,24 @@ var ContainerSettingsVolumes = React.createClass({
},
render: function () {
if (!this.props.container) {
- return (
);
+ return false;
}
- var self = this;
- var volumes = _.map(self.props.container.Volumes, function (val, key) {
+
+ var volumes = _.map(this.props.container.Volumes, (val, key) => {
if (!val || val.indexOf(process.env.HOME) === -1) {
val = (
No Folder
- Change
- Remove
+ Change
+ Remove
);
} else {
val = (
- {val.replace(process.env.HOME, '~')}
- Change
- Remove
+ {val.replace(process.env.HOME, '~')}
+ Change
+ Remove
);
}
diff --git a/src/components/Containers.react.js b/src/components/Containers.react.js
index 97a48806e5..03319d7d20 100644
--- a/src/components/Containers.react.js
+++ b/src/components/Containers.react.js
@@ -1,7 +1,8 @@
var $ = require('jquery');
-var React = require('react/addons');
+var _ = require('underscore');
+var React = require('react');
var Router = require('react-router');
-var ContainerStore = require('../stores/ContainerStore');
+var containerStore = require('../stores/ContainerStore');
var ContainerList = require('./ContainerList.react');
var Header = require('./Header.react');
var ipc = require('ipc');
@@ -16,22 +17,19 @@ var Containers = React.createClass({
contextTypes: {
router: React.PropTypes.func
},
+
getInitialState: function () {
return {
sidebarOffset: 0,
- containers: ContainerStore.containers(),
- sorted: ContainerStore.sorted(),
+ containers: {},
+ sorted: [],
updateAvailable: false,
- currentButtonLabel: '',
- error: ContainerStore.error(),
- downloading: ContainerStore.downloading()
+ currentButtonLabel: ''
};
},
+
componentDidMount: function () {
- this.update();
- ContainerStore.on(ContainerStore.SERVER_ERROR_EVENT, this.updateError);
- ContainerStore.on(ContainerStore.SERVER_CONTAINER_EVENT, this.update);
- ContainerStore.on(ContainerStore.CLIENT_CONTAINER_EVENT, this.updateFromClient);
+ containerStore.listen(this.update);
ipc.on('application:update-available', () => {
this.setState({
@@ -40,39 +38,47 @@ var Containers = React.createClass({
});
autoUpdater.checkForUpdates();
},
+
componentDidUnmount: function () {
- ContainerStore.removeListener(ContainerStore.SERVER_CONTAINER_EVENT, this.update);
- ContainerStore.removeListener(ContainerStore.CLIENT_CONTAINER_EVENT, this.updateFromClient);
+ containerStore.unlisten(this.update);
},
- updateError: function (err) {
- this.setState({
- error: err
+
+ update: function () {
+ let containers = containerStore.getState().containers;
+ let sorted = _.values(containers).sort(function (a, b) {
+ if (a.State.Downloading && !b.State.Downloading) {
+ return -1;
+ } else if (!a.State.Downloading && b.State.Downloading) {
+ return 1;
+ } else {
+ if (a.State.Running && !b.State.Running) {
+ return -1;
+ } else if (!a.State.Running && b.State.Running) {
+ return 1;
+ } else {
+ return a.Name.localeCompare(b.Name);
+ }
+ }
});
- },
- update: function (name, status) {
- var sorted = ContainerStore.sorted();
- this.setState({
- containers: ContainerStore.containers(),
- sorted: sorted,
- pending: ContainerStore.pending(),
- downloading: ContainerStore.downloading()
- });
- if (status === 'destroy') {
+
+ let name = this.context.router.getCurrentParams().name;
+ if (containerStore.getState().pending) {
+ this.context.router.transitionTo('pull');
+ } else if (name && !containers[name]) {
if (sorted.length) {
this.context.router.transitionTo('containerHome', {name: sorted[0].Name});
} else {
- this.context.router.transitionTo('containers');
+ this.context.router.transitionTo('search');
}
}
+
+ this.setState({
+ containers: containers,
+ sorted: sorted,
+ pending: containerStore.getState().pending
+ });
},
- updateFromClient: function (name, status) {
- this.update(name, status);
- if (status === 'create') {
- this.context.router.transitionTo('containerHome', {name: name});
- } else if (status === 'pending' && ContainerStore.pending()) {
- this.context.router.transitionTo('pull');
- }
- },
+
handleScroll: function (e) {
if (e.target.scrollTop > 0 && !this.state.sidebarOffset) {
this.setState({
@@ -84,63 +90,75 @@ var Containers = React.createClass({
});
}
},
+
handleNewContainer: function () {
$(this.getDOMNode()).find('.new-container-item').parent().fadeIn();
this.context.router.transitionTo('new');
metrics.track('Pressed New Container');
},
+
handleAutoUpdateClick: function () {
metrics.track('Restarted to Update');
ipc.send('application:quit-install');
},
+
handleClickPreferences: function () {
metrics.track('Opened Preferences', {
from: 'app'
});
this.context.router.transitionTo('preferences');
},
+
handleClickDockerTerminal: function () {
metrics.track('Opened Docker Terminal', {
from: 'app'
});
machine.dockerTerminal();
},
+
handleClickReportIssue: function () {
metrics.track('Opened Issue Reporter', {
from: 'app'
});
shell.openExternal('https://github.com/kitematic/kitematic/issues/new');
},
+
handleMouseEnterDockerTerminal: function () {
this.setState({
currentButtonLabel: 'Open terminal to use Docker command line.'
});
},
+
handleMouseLeaveDockerTerminal: function () {
this.setState({
currentButtonLabel: ''
});
},
+
handleMouseEnterReportIssue: function () {
this.setState({
currentButtonLabel: 'Report an issue or suggest feedback.'
});
},
+
handleMouseLeaveReportIssue: function () {
this.setState({
currentButtonLabel: ''
});
},
+
handleMouseEnterPreferences: function () {
this.setState({
currentButtonLabel: 'Change app preferences.'
});
},
+
handleMouseLeavePreferences: function () {
this.setState({
currentButtonLabel: ''
});
},
+
render: function () {
var sidebarHeaderClass = 'sidebar-header';
if (this.state.sidebarOffset) {
@@ -166,7 +184,7 @@ var Containers = React.createClass({