@@ -379,37 +376,31 @@ var ContainerDetails = React.createClass({
View
-
-
-
DOCKER PORT
-
LOCAL PORT
-
-
- {ports}
-
-
- }>
-
-
+
+
+
DOCKER PORT
+
LOCAL PORT
+
+
+ {ports}
+
+
+
-
-
-
DOCKER FOLDER
-
LOCAL FOLDER
-
-
- {volumes}
-
-
- }>
- Volumes
-
+
+
+
DOCKER FOLDER
+
LOCAL FOLDER
+
+
+ {volumes}
+
+
+
Volumes
Terminal
diff --git a/app/ContainerModal.react.js b/app/ContainerModal.react.js
index 74098a8320..629e3c699b 100644
--- a/app/ContainerModal.react.js
+++ b/app/ContainerModal.react.js
@@ -26,7 +26,7 @@ var ContainerModal = React.createClass({
},
componentDidMount: function () {
this.refs.searchInput.getDOMNode().focus();
- ContainerStore.on(ContainerStore.SERVER_RECOMMENDED_EVENT, this.update);
+ ContainerStore.on(ContainerStore.CLIENT_RECOMMENDED_EVENT, this.update);
},
update: function () {
if (!this.state.query.length) {
diff --git a/app/ContainerStore.js b/app/ContainerStore.js
index f3896c7894..95966bd70f 100644
--- a/app/ContainerStore.js
+++ b/app/ContainerStore.js
@@ -19,9 +19,9 @@ var _muted = {};
var ContainerStore = assign(EventEmitter.prototype, {
CLIENT_CONTAINER_EVENT: 'client_container',
+ CLIENT_RECOMMENDED_EVENT: 'client_recommended_event',
SERVER_CONTAINER_EVENT: 'server_container',
SERVER_PROGRESS_EVENT: 'server_progress',
- SERVER_RECOMMENDED_EVENT: 'server_recommended_event',
SERVER_LOGS_EVENT: 'server_logs',
_pullScratchImage: function (callback) {
var image = docker.client().getImage('scratch:latest');
@@ -110,7 +110,7 @@ var ContainerStore = assign(EventEmitter.prototype, {
_createContainer: function (name, containerData, callback) {
var existing = docker.client().getContainer(name);
var self = this;
- containerData.name = name;
+ if (!containerData.name) containerData.name = containerData.Name;
if (containerData.Config && containerData.Config.Image) {
containerData.Image = containerData.Config.Image;
}
@@ -232,12 +232,12 @@ var ContainerStore = assign(EventEmitter.prototype, {
this.fetchAllContainers(function (err) {
callback();
this.emit(this.CLIENT_CONTAINER_EVENT);
- this.fetchRecommended(function (err) {
- this.emit(this.SERVER_RECOMMENDED_EVENT);
- }.bind(this));
this._resumePulling();
this._startListeningToEvents();
}.bind(this));
+ this.fetchRecommended(function (err) {
+ this.emit(this.CLIENT_RECOMMENDED_EVENT);
+ }.bind(this));
},
fetchContainer: function (id, callback) {
docker.client().getContainer(id).inspect(function (err, container) {
@@ -407,21 +407,27 @@ var ContainerStore = assign(EventEmitter.prototype, {
callback(err);
}.bind(this));
},
+ restart: function (name, callback) {
+ var container = docker.client().getContainer(name);
+ container.restart(function (err) {
+ callback(err);
+ });
+ },
remove: function (name, callback) {
var self = this;
- var existing = docker.client().getContainer(name);
+ var container = docker.client().getContainer(name);
if (_containers[name].State.Paused) {
- existing.unpause(function (err) {
+ container.unpause(function (err) {
if (err) {
callback(err);
return;
} else {
- existing.kill(function (err) {
+ container.kill(function (err) {
if (err) {
callback(err);
return;
} else {
- existing.remove(function (err) {
+ container.remove(function (err) {
if (err) {
callback(err);
return;
@@ -432,12 +438,12 @@ var ContainerStore = assign(EventEmitter.prototype, {
}
});
} else {
- existing.kill(function (err) {
+ container.kill(function (err) {
if (err) {
callback(err);
return;
} else {
- existing.remove(function (err) {
+ container.remove(function (err) {
if (err) {
callback(err);
return;
diff --git a/app/Containers.react.js b/app/Containers.react.js
index 45789f8db0..0372475515 100644
--- a/app/Containers.react.js
+++ b/app/Containers.react.js
@@ -72,6 +72,7 @@ var Containers = React.createClass({
sidebarHeaderClass += ' sep';
}
+ var container = this.getParams().name ? this.state.containers[this.getParams().name] : {};
return (
@@ -89,7 +90,7 @@ var Containers = React.createClass({
-
+
);
diff --git a/app/Menu.js b/app/Menu.js
new file mode 100644
index 0000000000..68bcd9cf2a
--- /dev/null
+++ b/app/Menu.js
@@ -0,0 +1,142 @@
+var remote = require('remote');
+var app = remote.require('app');
+var Menu = remote.require('menu');
+var MenuItem = remote.require('menu-item');
+var BrowserWindow = remote.require('browser-window');
+var router = require('./router');
+
+// main.js
+var template = [
+{
+ label: 'Kitematic',
+ submenu: [
+ {
+ label: 'About Kitematic',
+ selector: 'orderFrontStandardAboutPanel:'
+ },
+ {
+ type: 'separator'
+ },
+ {
+ label: 'Preferences',
+ accelerator: 'Command+,',
+ click: function () {
+ router.transitionTo('preferences');
+ }
+ },
+ {
+ type: 'separator'
+ },
+ {
+ label: 'Services',
+ submenu: []
+ },
+ {
+ type: 'separator'
+ },
+ {
+ label: 'Hide Kitematic',
+ accelerator: 'Command+H',
+ selector: 'hide:'
+ },
+ {
+ label: 'Hide Others',
+ accelerator: 'Command+Shift+H',
+ selector: 'hideOtherApplications:'
+ },
+ {
+ label: 'Show All',
+ selector: 'unhideAllApplications:'
+ },
+ {
+ type: 'separator'
+ },
+ {
+ label: 'Quit',
+ accelerator: 'Command+Q',
+ click: function() {
+ app.quit();
+ }
+ },
+ ]
+},
+{
+ label: 'Edit',
+ submenu: [
+ {
+ label: 'Undo',
+ accelerator: 'Command+Z',
+ selector: 'undo:'
+ },
+ {
+ label: 'Redo',
+ accelerator: 'Shift+Command+Z',
+ selector: 'redo:'
+ },
+ {
+ type: 'separator'
+ },
+ {
+ label: 'Cut',
+ accelerator: 'Command+X',
+ selector: 'cut:'
+ },
+ {
+ label: 'Copy',
+ accelerator: 'Command+C',
+ selector: 'copy:'
+ },
+ {
+ label: 'Paste',
+ accelerator: 'Command+V',
+ selector: 'paste:'
+ },
+ {
+ label: 'Select All',
+ accelerator: 'Command+A',
+ selector: 'selectAll:'
+ },
+ ]
+},
+{
+ label: 'View',
+ submenu: [
+ {
+ label: 'Toggle DevTools',
+ accelerator: 'Alt+Command+I',
+ click: function() { BrowserWindow.getFocusedWindow().toggleDevTools(); }
+ },
+ ]
+},
+{
+ label: 'Window',
+ submenu: [
+ {
+ label: 'Minimize',
+ accelerator: 'Command+M',
+ selector: 'performMiniaturize:'
+ },
+ {
+ label: 'Close',
+ accelerator: 'Command+W',
+ selector: 'performClose:'
+ },
+ {
+ type: 'separator'
+ },
+ {
+ label: 'Bring All to Front',
+ selector: 'arrangeInFront:'
+ },
+ ]
+},
+{
+ label: 'Help',
+ submenu: []
+},
+];
+
+menu = Menu.buildFromTemplate(template);
+Menu.setApplicationMenu(menu);
+
+module.exports = menu;
diff --git a/app/Preferences.react.js b/app/Preferences.react.js
new file mode 100644
index 0000000000..c18ddc782c
--- /dev/null
+++ b/app/Preferences.react.js
@@ -0,0 +1,64 @@
+var React = require('react/addons');
+var assign = require('object-assign');
+var ipc = require('ipc');
+
+// TODO: move this somewhere else
+if (localStorage.getItem('options')) {
+ ipc.send('vm', JSON.parse(localStorage.getItem('options')).save_vm_on_quit);
+}
+
+var Preferences = React.createClass({
+ getInitialState: function () {
+ var data = JSON.parse(localStorage.getItem('options'));
+ return assign({
+ save_vm_on_quit: true,
+ report_analytics: true
+ }, data || {});
+ },
+ handleChange: function (key, e) {
+ var change = {};
+ change[key] = !this.state[key];
+ console.log(change);
+ this.setState(change);
+ },
+ saveState: function () {
+ ipc.send('vm', this.state.save_vm_on_quit);
+ localStorage.setItem('options', JSON.stringify(this.state));
+ },
+ componentDidMount: function () {
+ this.saveState();
+ },
+ componentDidUpdate: function () {
+ this.saveState();
+ },
+ render: function () {
+ console.log('render');
+ return (
+
+
+
VM Settings
+
+
+ Save Linux VM state on closing Kitematic
+
+
+
+
+
+
App Settings
+
+
+ Report anonymous usage analytics
+
+
+
+
+
+
+
+
+ );
+ }
+});
+
+module.exports = Preferences;
diff --git a/app/Setup.react.js b/app/Setup.react.js
index 16f8928b31..08561310e5 100644
--- a/app/Setup.react.js
+++ b/app/Setup.react.js
@@ -173,7 +173,9 @@ var Setup = React.createClass({
if (!err) {
boot2docker.ip(function (err, ip) {
docker.setHost(ip);
- self.transitionTo('containers');
+ ContainerStore.init(function () {
+ self.transitionTo('containers');
+ });
});
}
});
diff --git a/app/index.html b/app/index.html
index a97ba8b788..699c7186f0 100644
--- a/app/index.html
+++ b/app/index.html
@@ -7,6 +7,5 @@
-