├── .gitignore
├── config
├── env.js
├── jest
│ ├── CSSStub.js
│ └── FileStub.js
├── paths.js
├── polyfills.js
├── storybook
│ ├── config.js
│ ├── dummy-child_process.js
│ ├── dummy-electron.js
│ └── webpack.config.js
├── webpack.config.dev.js
└── webpack.config.prod.js
├── electron.js
├── license.md
├── package.json
├── public
├── about.html
├── index.html
├── loader.css
├── logo.png
└── spinner.svg
├── readme.md
├── resources
├── icon.icns
└── icon.ico
├── scripts
├── build.js
├── start.js
└── test.js
├── src
├── About.css
├── About.js
├── App.css
├── App.js
├── Button.css
├── Button.js
├── CreateModal.css
├── CreateModal.js
├── CreateModal
│ ├── Config.js
│ ├── Type.css
│ └── Type.js
├── Form
│ ├── FixedValue.css
│ ├── FixedValue.js
│ └── Table
│ │ ├── index.css
│ │ └── index.js
├── Header.css
├── Header.js
├── Icon.js
├── Installer.css
├── Installer.js
├── Installer.scss
├── Installer
│ ├── DownloadStatus.js
│ ├── Downloader.css
│ ├── Downloader.js
│ ├── Downloads.css
│ ├── Downloads.js
│ ├── ImportBoxes.css
│ ├── ImportBoxes.js
│ ├── Ready.css
│ ├── Ready.js
│ ├── Vagrant.png
│ ├── VirtualBox.png
│ └── Welcome.js
├── ItemList.css
├── ItemList.js
├── KeyHandler.css
├── KeyHandler.js
├── LoadingIndicator.css
├── LoadingIndicator.js
├── MachineActions.css
├── MachineActions.js
├── MachineDetails.js
├── MachineDetails.scss
├── MachineItem.css
├── MachineItem.js
├── MachineList.css
├── MachineList.js
├── MachineSettings.css
├── MachineSettings.js
├── Modal.css
├── Modal.js
├── Root.js
├── Settings.css
├── Settings.js
├── Splash.js
├── Step.js
├── Steps.js
├── Steps.scss
├── Terminal.js
├── Terminal.scss
├── Toolbar.js
├── about-entry.js
├── index.js
├── lib
│ ├── actions.js
│ ├── actions
│ │ ├── cloneChassis.js
│ │ ├── install.js
│ │ ├── loadConfig.js
│ │ ├── runCommand.js
│ │ ├── updateBoxStatus.js
│ │ ├── updateConfig.js
│ │ └── updateGlobalStatus.js
│ ├── configure.js
│ ├── createStore.js
│ ├── download.js
│ ├── formatPath.js
│ ├── keys.js
│ ├── openBrowser.js
│ ├── reducers.js
│ ├── reducers
│ │ ├── boxes.js
│ │ ├── installer.js
│ │ ├── preferences.js
│ │ ├── terminal.js
│ │ ├── ui.js
│ │ └── vagrant.js
│ ├── spawn-sync.js
│ └── vagrant
│ │ ├── Machine.js
│ │ └── parser.js
└── logo.svg
└── stories
├── Button.js
├── Header.js
├── MachineActions.js
├── MachineItem.js
├── MachineSettings.js
└── Terminal.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 |
6 | # testing
7 | coverage
8 |
9 | # production
10 | build
11 | dist
12 |
13 | # misc
14 | .DS_Store
15 | .env
16 | npm-debug.log
17 |
--------------------------------------------------------------------------------
/config/env.js:
--------------------------------------------------------------------------------
1 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
2 | // injected into the application via DefinePlugin in Webpack configuration.
3 |
4 | var REACT_APP = /^REACT_APP_/i;
5 |
6 | function getClientEnvironment(publicUrl) {
7 | return Object
8 | .keys(process.env)
9 | .filter(key => REACT_APP.test(key))
10 | .reduce((env, key) => {
11 | env['process.env.' + key] = JSON.stringify(process.env[key]);
12 | return env;
13 | }, {
14 | // Useful for determining whether we’re running in production mode.
15 | // Most importantly, it switches React into the correct mode.
16 | 'process.env.NODE_ENV': JSON.stringify(
17 | process.env.NODE_ENV || 'development'
18 | ),
19 | // Useful for resolving the correct path to static assets in `public`.
20 | // For example,
.
21 | // This should only be used as an escape hatch. Normally you would put
22 | // images into the `src` and `import` them in code to get their paths.
23 | 'process.env.PUBLIC_URL': JSON.stringify(publicUrl)
24 | });
25 | }
26 |
27 | module.exports = getClientEnvironment;
28 |
--------------------------------------------------------------------------------
/config/jest/CSSStub.js:
--------------------------------------------------------------------------------
1 | module.exports = {};
2 |
--------------------------------------------------------------------------------
/config/jest/FileStub.js:
--------------------------------------------------------------------------------
1 | module.exports = "test-file-stub";
2 |
--------------------------------------------------------------------------------
/config/paths.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var fs = require('fs');
3 |
4 | // Make sure any symlinks in the project folder are resolved:
5 | // https://github.com/facebookincubator/create-react-app/issues/637
6 | var appDirectory = fs.realpathSync(process.cwd());
7 | function resolveApp(relativePath) {
8 | return path.resolve(appDirectory, relativePath);
9 | }
10 |
11 | // We support resolving modules according to `NODE_PATH`.
12 | // This lets you use absolute paths in imports inside large monorepos:
13 | // https://github.com/facebookincubator/create-react-app/issues/253.
14 |
15 | // It works similar to `NODE_PATH` in Node itself:
16 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
17 |
18 | // We will export `nodePaths` as an array of absolute paths.
19 | // It will then be used by Webpack configs.
20 | // Jest doesn’t need this because it already handles `NODE_PATH` out of the box.
21 |
22 | var nodePaths = (process.env.NODE_PATH || '')
23 | .split(process.platform === 'win32' ? ';' : ':')
24 | .filter(Boolean)
25 | .map(resolveApp);
26 |
27 | // config after eject: we're in ./config/
28 | module.exports = {
29 | appBuild: resolveApp('build'),
30 | appPublic: resolveApp('public'),
31 | appHtml: resolveApp('public/index.html'),
32 | appIndexJs: resolveApp('src/index.js'),
33 | appAboutHtml: resolveApp('public/about.html'),
34 | appAboutJs: resolveApp('src/about-entry.js'),
35 | appPackageJson: resolveApp('package.json'),
36 | appSrc: resolveApp('src'),
37 | testsSetup: resolveApp('src/setupTests.js'),
38 | appNodeModules: resolveApp('node_modules'),
39 | ownNodeModules: resolveApp('node_modules'),
40 | nodePaths: nodePaths
41 | };
42 |
--------------------------------------------------------------------------------
/config/polyfills.js:
--------------------------------------------------------------------------------
1 | if (typeof Promise === 'undefined') {
2 | // Rejection tracking prevents a common issue where React gets into an
3 | // inconsistent state due to an error, but it gets swallowed by a Promise,
4 | // and the user has no idea what causes React's erratic future behavior.
5 | require('promise/lib/rejection-tracking').enable();
6 | window.Promise = require('promise/lib/es6-extensions.js');
7 | }
8 |
9 | // fetch() polyfill for making API calls.
10 | require('whatwg-fetch');
11 |
12 | // Object.assign() is commonly used with React.
13 | // It will use the native implementation if it's present and isn't buggy.
14 | Object.assign = require('object-assign');
15 |
--------------------------------------------------------------------------------
/config/storybook/config.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Provider } from 'react-redux';
3 | import { createStore } from 'redux';
4 | import { addDecorator, configure } from '@storybook/react';
5 |
6 | // Load CSS
7 | import 'font-awesome/css/font-awesome.css';
8 | import '../../public/loader.css';
9 |
10 | const require_story = require.context( '../../stories', true, /\.js$/ )
11 |
12 | function loadStories() {
13 | require_story.keys().forEach( filename => require_story( filename ) );
14 | }
15 |
16 | // Add dummy store for KeyHandler
17 | const INITIAL_STATE = {
18 | preferences: {},
19 | };
20 | addDecorator( story => (
21 | state, INITIAL_STATE ) }>
22 | { story() }
23 |
24 | ));
25 |
26 | // Add dummy handler.
27 | window.keyHandler = {
28 | register: () => {},
29 | unregister: () => {},
30 | };
31 |
32 | configure( loadStories, module );
33 |
--------------------------------------------------------------------------------
/config/storybook/dummy-child_process.js:
--------------------------------------------------------------------------------
1 | export const spawn = () => {
2 | throw new Error( 'Not running in Electron context.' )
3 | };
4 |
--------------------------------------------------------------------------------
/config/storybook/dummy-electron.js:
--------------------------------------------------------------------------------
1 | export const shell = {
2 | openExternal: url => console.log( url ),
3 | };
4 |
--------------------------------------------------------------------------------
/config/storybook/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require( 'path' );
2 | const genDefaultConfig = require('@storybook/react/dist/server/config/defaults/webpack.config.js');
3 |
4 | module.exports = (baseConfig, env) => {
5 | const config = genDefaultConfig(baseConfig, env);
6 |
7 | // Shim in our fake electron modules.
8 | config.resolve.alias.child_process = path.resolve( __dirname, 'dummy-child_process.js' );
9 | config.resolve.alias.electron = path.resolve( __dirname, 'dummy-electron.js' );
10 |
11 | // Add SCSS processing.
12 | // console.log( config );
13 | config.module.rules.push({
14 | test: /\.scss$/,
15 | use: [
16 | {
17 | loader: "style-loader" // creates style nodes from JS strings
18 | },
19 | {
20 | loader: "css-loader" // translates CSS into CommonJS
21 | },
22 | {
23 | loader: "sass-loader" // compiles Sass to CSS
24 | },
25 | ],
26 | // loader: ExtractTextPlugin.extract('style', 'css!sass')
27 | });
28 |
29 | return config;
30 | };
31 |
--------------------------------------------------------------------------------
/config/webpack.config.dev.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var autoprefixer = require('autoprefixer');
3 | var webpack = require('webpack');
4 | var findCacheDir = require('find-cache-dir');
5 | var HtmlWebpackPlugin = require('html-webpack-plugin');
6 | var ExtractTextPlugin = require('extract-text-webpack-plugin');
7 | var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
8 | var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
9 | var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
10 | var getClientEnvironment = require('./env');
11 | var paths = require('./paths');
12 |
13 | // Webpack uses `publicPath` to determine where the app is being served from.
14 | // In development, we always serve from the root. This makes config easier.
15 | var publicPath = '/';
16 | // `publicUrl` is just like `publicPath`, but we will provide it to our app
17 | // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
18 | // Omit trailing shlash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
19 | var publicUrl = '';
20 | // Get enrivonment variables to inject into our app.
21 | var env = getClientEnvironment(publicUrl);
22 |
23 | // This is the development configuration.
24 | // It is focused on developer experience and fast rebuilds.
25 | // The production configuration is different and lives in a separate file.
26 | module.exports = {
27 | // This makes the bundle appear split into separate modules in the devtools.
28 | // We don't use source maps here because they can be confusing:
29 | // https://github.com/facebookincubator/create-react-app/issues/343#issuecomment-237241875
30 | // You may want 'cheap-module-source-map' instead if you prefer source maps.
31 | devtool: 'eval',
32 |
33 | // Add Electron as the target.
34 | target: 'electron-renderer',
35 |
36 | // These are the "entry points" to our application.
37 | // This means they will be the "root" imports that are included in JS bundle.
38 | // The first two entry points enable "hot" CSS and auto-refreshes for JS.
39 | entry: {
40 | main: [
41 | // Include an alternative client for WebpackDevServer. A client's job is to
42 | // connect to WebpackDevServer by a socket and get notified about changes.
43 | // When you save a file, the client will either apply hot updates (in case
44 | // of CSS changes), or refresh the page (in case of JS changes). When you
45 | // make a syntax error, this client will display a syntax error overlay.
46 | // Note: instead of the default WebpackDevServer client, we use a custom one
47 | // to bring better experience for Create React App users. You can replace
48 | // the line below with these two lines if you prefer the stock client:
49 | // require.resolve('webpack-dev-server/client') + '?/',
50 | // require.resolve('webpack/hot/dev-server'),
51 | require.resolve('react-dev-utils/webpackHotDevClient'),
52 | // We ship a few polyfills by default:
53 | require.resolve('./polyfills'),
54 | // Finally, this is your app's code:
55 | paths.appIndexJs
56 | // We include the app code last so that if there is a runtime error during
57 | // initialization, it doesn't blow up the WebpackDevServer client, and
58 | // changing JS code would still trigger a refresh.
59 | ],
60 | about: [
61 | require.resolve('react-dev-utils/webpackHotDevClient'),
62 | require.resolve('./polyfills'),
63 | paths.appAboutJs,
64 | ]
65 | },
66 | output: {
67 | // Next line is not used in dev but WebpackDevServer crashes without it:
68 | path: paths.appBuild,
69 | // Add /* filename */ comments to generated require()s in the output.
70 | pathinfo: true,
71 | // This does not produce a real file. It's just the virtual path that is
72 | // served by WebpackDevServer in development. This is the JS bundle
73 | // containing code from all our entry points, and the Webpack runtime.
74 | filename: 'static/js/[name].js',
75 | // This is the URL that app is served from. We use "/" in development.
76 | publicPath: publicPath
77 | },
78 | resolve: {
79 | // This allows you to set a fallback for where Webpack should look for modules.
80 | // We read `NODE_PATH` environment variable in `paths.js` and pass paths here.
81 | // We use `fallback` instead of `root` because we want `node_modules` to "win"
82 | // if there any conflicts. This matches Node resolution mechanism.
83 | // https://github.com/facebookincubator/create-react-app/issues/253
84 | fallback: paths.nodePaths,
85 | // These are the reasonable defaults supported by the Node ecosystem.
86 | // We also include JSX as a common component filename extension to support
87 | // some tools, although we do not recommend using it, see:
88 | // https://github.com/facebookincubator/create-react-app/issues/290
89 | extensions: ['.js', '.json', '.jsx', ''],
90 | alias: {
91 | // Support React Native Web
92 | // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
93 | 'react-native': 'react-native-web',
94 | 'spawn-sync': path.join( paths.appSrc, 'lib', 'spawn-sync.js' ),
95 | }
96 | },
97 |
98 | module: {
99 | // First, run the linter.
100 | // It's important to do this before Babel processes the JS.
101 | preLoaders: [
102 | {
103 | test: /\.(js|jsx)$/,
104 | loader: 'eslint',
105 | include: paths.appSrc,
106 | }
107 | ],
108 | loaders: [
109 | // Process JS with Babel.
110 | {
111 | test: /\.(js|jsx)$/,
112 | include: paths.appSrc,
113 | loader: 'babel',
114 | query: {
115 |
116 | // This is a feature of `babel-loader` for webpack (not Babel itself).
117 | // It enables caching results in ./node_modules/.cache/react-scripts/
118 | // directory for faster rebuilds. We use findCacheDir() because of:
119 | // https://github.com/facebookincubator/create-react-app/issues/483
120 | cacheDirectory: findCacheDir({
121 | name: 'react-scripts'
122 | })
123 | }
124 | },
125 | // "postcss" loader applies autoprefixer to our CSS.
126 | // "css" loader resolves paths in CSS and adds assets as dependencies.
127 | // "style" loader turns CSS into JS modules that inject