feat: same-domain consoles

This commit is contained in:
Sérgio Ramos 2018-03-06 01:14:33 +00:00 committed by Sérgio Ramos
parent b64dbb289d
commit da59d5e808
49 changed files with 457 additions and 449 deletions

View File

@ -22,10 +22,12 @@ const {
BASE_URL = `http://0.0.0.0:${PORT}`,
ROLLBAR_SERVER_TOKEN,
NODE_ENV = 'development',
CONSOLE = 'my-joy-instances'
// CONSOLE = 'my-joy-instances'
} = process.env;
const Ui = require(CONSOLE);
const Ui = require('my-joy-instances');
// const Instances = require('my-joy-instances');
// const Images = require('my-joy-images');
const server = Hapi.server({
compression: {

View File

@ -1,6 +1,7 @@
{
"name": "joyent-icons",
"version": "5.0.0",
"private": true,
"license": "MPL-2.0",
"repository": "github:yldio/joyent-portal",
"main": "dist/umd/index.js",

View File

@ -1,6 +1,7 @@
{
"name": "joyent-logo-assets",
"version": "1.0.0",
"private": true,
"license": "MPL-2.0",
"repository": "github:yldio/joyent-portal",
"main": "dist/umd/index.js",

View File

@ -24,3 +24,4 @@ yarn-error.log*
!lib/app
!dist
!build

View File

@ -1,8 +1,8 @@
{
"name": "my-joy-images",
"version": "1.0.0",
"license": "MPL-2.0",
"version": "1.1.6",
"private": true,
"license": "MPL-2.0",
"repository": "github:yldio/joyent-portal",
"main": "lib/index.js",
"scripts": {
@ -29,8 +29,8 @@
"declarative-redux-form": "^2.0.8",
"force-array": "^3.1.0",
"fuse.js": "^3.2.0",
"hapi-render-react": "^2.1.0",
"hapi-render-react-joyent-document": "^4.2.3",
"hapi-render-react": "^2.2.0",
"hapi-render-react-joyent-document": "^4.4.0",
"joyent-logo-assets": "^1.0.0",
"joyent-react-styled-flexboxgrid": "^2.2.3",
"joyent-ui-toolkit": "^5.0.0",

View File

@ -8,6 +8,7 @@ const { default: createClient } = require('./state/apollo-client');
const { default: createStore } = require('./state/redux-store');
const indexFile = path.join(__dirname, '../../build/index.html');
const assets = require('../../build/asset-manifest.json');
const getState = request => {
const { req } = request.raw;
@ -31,4 +32,9 @@ const getState = request => {
};
};
module.exports = Document({ indexFile, getState });
module.exports = Document({
namespace: 'images/',
assets,
indexFile,
getState
});

View File

@ -23,6 +23,7 @@ import {
StatusLoader
} from 'joyent-ui-toolkit';
import GLOBAL from '@state/global';
import { ImageType, OS } from '@root/constants';
const A = styled(Anchor)`
@ -78,7 +79,7 @@ export const Image = ({
onCreateInstance
}) => (
<Margin bottom={3}>
<CardAnchor to={`/${name}`} component={Link}>
<CardAnchor to={`/images/${name}`} component={Link}>
<Card radius>
{removing ? (
<Padding all={2}>
@ -95,7 +96,7 @@ export const Image = ({
height: '24'
})}
</Margin>
<A to={`/${name}/summary`} component={Link}>
<A to={`/images/${name}/summary`} component={Link}>
{name}
</A>
</Flex>
@ -124,7 +125,7 @@ export const Image = ({
<Popover placement="bottom">
<PopoverItem disabled={false} onClick={onCreateInstance}>
<ItemAnchor
href={`http://localhost:3069/~create/?image=${name}`}
href={`${GLOBAL.origin}/instances/~create/?image=${name}`}
target="__blank"
rel="noopener noreferrer"
>

View File

@ -24,6 +24,7 @@ import {
Input
} from 'joyent-ui-toolkit';
import GLOBAL from '@state/global';
import { ImageType, OS } from '@root/constants';
const { SmallOnly, Medium } = QueryBreakpoints;
@ -115,7 +116,7 @@ export default withTheme(({ theme = {}, onRemove, removing, ...image }) => (
<Medium>
<Button
type="button"
href={`http://localhost:3069/~create/?image=${image.name}`}
href={`${GLOBAL.origin}/instances/~create/?image=${image.name}`}
target="__blank"
rel="noopener noreferrer"
bold

View File

@ -12,19 +12,23 @@ export default ({ match }) => {
const links = [
{
name: 'Images',
name: 'Compute',
pathname: '/'
},
{
name: 'Images',
pathname: '/images'
}
]
.concat(
create && [
{
name: 'Create Image',
pathname: `/~create`
pathname: `/images/~create`
},
{
name: instance,
pathname: `/~create/${instance}`
pathname: `/images/~create/${instance}`
}
]
)
@ -32,7 +36,7 @@ export default ({ match }) => {
image && [
{
name: paramCase(image),
pathname: `/${image}`
pathname: `/images/${image}`
}
]
)

View File

@ -143,11 +143,11 @@ export default compose(
(dispatch, { history, match }) => ({
handleNext: () => {
dispatch(set({ name: `${Forms.FORM_DETAILS}-proceeded`, value: true }));
return history.push(`/~create/${match.params.instance}/tag`);
return history.push(`/images/~create/${match.params.instance}/tag`);
},
handleEdit: () => {
dispatch(set({ name: `${Forms.FORM_DETAILS}-proceeded`, value: true }));
return history.push(`/~create/${match.params.instance}/name`);
return history.push(`/images/~create/${match.params.instance}/name`);
},
shouldAsyncValidate: ({ trigger }) => {
return trigger === 'change';

View File

@ -141,10 +141,10 @@ export default compose(
handleNext: () => {
dispatch(set({ name: `${Forms.CREATE_TAGS}-proceeded`, value: true }));
return history.push(`/~create/${match.params.instance}/create`);
return history.push(`/images/~create/${match.params.instance}/create`);
},
handleEdit: () => {
return history.push(`/~create/${match.params.instance}/tag`);
return history.push(`/images/~create/${match.params.instance}/tag`);
},
shouldAsyncValidate: ({ trigger }) => {
return trigger === 'submit';

View File

@ -102,7 +102,11 @@ export default compose(
}),
props: ({ data: { loading, error, variables, ...rest } }) => {
const notFoundMsg = `Instance "${variables.name}" not found!`;
const inst = find(get(rest, 'machines.results', []), ['name', variables.name]);
const inst = find(get(rest, 'machines.results', []), [
'name',
variables.name
]);
const notFound = !loading && !inst ? notFoundMsg : false;
return {
@ -186,7 +190,7 @@ export default compose(
const { data } = res;
const { createImageFromMachine } = data;
history.push(`/${createImageFromMachine.name}`);
history.push(`/images/${createImageFromMachine.name}`);
}
};
})

View File

@ -19,6 +19,7 @@ import {
MessageDescription
} from 'joyent-ui-toolkit';
import GLOBAL from '@state/global';
import ToolbarForm from '@components/toolbar';
import Empty from '@components/empty';
import { ImageType, Forms } from '@root/constants';
@ -157,10 +158,11 @@ export default compose(
};
},
(dispatch, { removeImage, history }) => ({
handleCreateInstance: image =>
window
.open(`http://localhost:3069/~create/?image=${image.name}`, '_blank')
.focus(),
handleCreateInstance: image => {
return window
.open(`${GLOBAL.origin}/instances/~create/?image=${image.name}`, '_blank')
.focus();
},
handleRemove: async id => {
dispatch([set({ name: `remove-mutation-${id}-loading`, value: true })]);
@ -184,7 +186,7 @@ export default compose(
set({ name: `remove-mutation-${id}-loading`, value: false })
);
history.push(`/`);
history.push('/images');
}
}
})

View File

@ -14,7 +14,7 @@ export default ({ match }) => {
const links = sections.map(({ name, pathname }) => ({
name,
pathname: `/${imageSlug}/${pathname}`
pathname: `/images/${imageSlug}/${pathname}`
}));
return <Menu links={links} />;

View File

@ -112,7 +112,7 @@ export default compose(
if (res) {
dispatch(set({ name: 'remove-mutation-loading', value: false }));
history.push(`/`);
history.push('/images');
}
}
})

View File

@ -1,6 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { ThemeProvider, consolidateStreamedStyles } from 'styled-components';
import { ThemeProvider } from 'styled-components';
import { Provider as ReduxProvider } from 'react-redux';
import { ApolloProvider } from 'react-apollo';
import { BrowserRouter } from 'react-router-dom';
@ -11,15 +11,12 @@ import { theme } from 'joyent-ui-toolkit';
import createStore from '@state/redux-store';
import createClient from '@state/apollo-client';
import { register } from './sw';
import App from './app';
if (!isFunction(Number.isFinite)) {
Number.isFinite = isFinite;
}
consolidateStreamedStyles();
ReactDOM.hydrate(
<ApolloProvider client={createClient()}>
<ThemeProvider theme={theme}>
@ -32,5 +29,3 @@ ReactDOM.hydrate(
</ApolloProvider>,
document.getElementById('root')
);
register();

View File

@ -21,48 +21,52 @@ import { Route as ServerError } from '@root/server-error';
export default () => (
<PageContainer>
{/* Breadcrumb */}
{/* Breadcrumb */}
<Switch>
<Route path="/~server-error" component={Breadcrumb} />
<Route path="/~create/:instance/:step?" exact component={Breadcrumb} />
<Route path="/:image?" component={Breadcrumb} />
</Switch>
{/* Menu */}
<Switch>
<Route path="/~server-error" component={() => null} />
<Route path="/:image/:section?" component={Menu} />
<Route path="/~create/:instance/:step?" component={() => {}} />
</Switch>
{/* Images */}
<Switch>
<Route path="/~server-error" component={() => null} />
<Route path="/" exact component={List} />
<Route path="/:image/summary" exact component={Summary} />
<Route path="/:image/tags" exact component={Tags} />
<Route path="/images/~server-error" component={Breadcrumb} />
<Route
path="/:image"
path="/images/~create/:instance/:step?"
exact
component={Breadcrumb}
/>
<Route path="/images/:image?" component={Breadcrumb} />
</Switch>
{/* Menu */}
<Switch>
<Route path="/images/~server-error" component={() => null} />
<Route path="/images/:image/:section?" component={Menu} />
<Route path="/images/~create/:instance/:step?" component={() => {}} />
</Switch>
{/* Images */}
<Switch>
{/* <Route path="/images/~server-error" component={() => null} /> */}
<Route path="/images/" exact component={List} />
<Route path="/images/:image/summary" exact component={Summary} />
<Route path="/images/:image/tags" exact component={Tags} />
<Route
path="/images/:image"
exact
component={({ match }) => (
<Redirect to={`/${get(match, 'params.image')}/summary`} />
<Redirect to={`/images/${get(match, 'params.image')}/summary`} />
)}
/>
</Switch>
{/* Create Image */}
{/* Create Image */}
<Switch>
<Route
path="/~create/:instance?"
path="/images/~create/:instance?"
exact
component={({ match }) => (
<Redirect to={`/~create/${match.params.instance}/name`} />
<Redirect to={`/images/~create/${match.params.instance}/name`} />
)}
/>
<Route path="/~create/:instance/:step" component={Create} />
<Route path="/images/~create/:instance/:step" component={Create} />
</Switch>
<Route path="/~server-error" component={ServerError} />
<Route path="/images/~server-error" component={ServerError} />
<noscript>
<ViewContainer main>

View File

@ -9,6 +9,7 @@ export default (() => {
port: window.location.port,
protocol: window.location.protocol.replace(/:$/, ''),
hostname: window.location.hostname,
origin: window.location.origin,
__REDUX_DEVTOOLS_EXTENSION__: window.__REDUX_DEVTOOLS_EXTENSION__,
__APOLLO_STATE__: window.__APOLLO_STATE__,
__REDUX_STATE__: window.__REDUX_STATE__

View File

@ -1,108 +0,0 @@
// In production, we register a service worker to serve assets from local cache.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export function register() {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (!isLocalhost) {
// Is not local host. Just register service worker
registerValidSW(swUrl);
} else {
// This is running on localhost. Lets check if a service worker still exists or not.
checkValidServiceWorker(swUrl);
}
});
}
}
function registerValidSW(swUrl) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in your web app.
console.log('New content is available; please refresh.');
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
if (
response.status === 404 ||
response.headers.get('content-type').indexOf('javascript') === -1
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}

View File

@ -21,5 +21,7 @@ yarn-error.log*
**/__diff_output__
!lib/app
!dist
!build
!lib

View File

@ -1,26 +1,31 @@
const Inert = require('inert');
const resolvePkg = require('resolve-pkg');
const Path = require('path');
const RenderReact = require('hapi-render-react');
const Wreck = require('wreck');
const Url = require('url');
const ImagesRoot = resolvePkg('my-joy-images', {
cwd: __dirname
});
exports.register = async server => {
const InstancesRelativeTo = Path.join(__dirname, 'app');
const ImagesRelativeTo = Path.join(ImagesRoot, 'lib/app');
await server.register([
{
plugin: Inert
},
{
plugin: RenderReact,
options: {
relativeTo: Path.join(__dirname, 'app')
}
plugin: RenderReact
}
]);
server.route([
{
method: 'GET',
path: '/service-worker.js',
path: '/instances/service-worker.js',
config: {
auth: false,
handler: {
@ -32,7 +37,19 @@ exports.register = async server => {
},
{
method: 'GET',
path: '/favicon.ico',
path: '/images/service-worker.js',
config: {
auth: false,
handler: {
file: {
path: Path.join(ImagesRoot, 'build/service-worker.js')
}
}
}
},
{
method: 'GET',
path: '/instances/favicon.ico',
config: {
auth: false,
handler: {
@ -42,6 +59,18 @@ exports.register = async server => {
}
}
},
{
method: 'GET',
path: '/images/favicon.ico',
config: {
auth: false,
handler: {
file: {
path: Path.join(ImagesRoot, 'build/favicon.ico')
}
}
}
},
{
method: 'GET',
path: '/font/{pathname*}',
@ -103,7 +132,7 @@ exports.register = async server => {
},
{
method: 'GET',
path: '/static/{path*}',
path: '/instances/static/{path*}',
config: {
auth: false,
handler: {
@ -115,12 +144,47 @@ exports.register = async server => {
}
}
},
{
method: 'GET',
path: '/images/static/{path*}',
config: {
auth: false,
handler: {
directory: {
path: Path.join(ImagesRoot, 'build/static/'),
redirectToSlash: true,
index: false
}
}
}
},
{
method: '*',
path: '/~server-error',
path: '/instances/~server-error',
handler: {
view: {
name: 'server-error'
name: 'server-error',
relativeTo: InstancesRelativeTo
}
}
},
{
method: '*',
path: '/images/~server-error',
handler: {
view: {
name: 'server-error',
relativeTo: ImagesRelativeTo
}
}
},
{
method: '*',
path: '/images/{path*}',
handler: {
view: {
name: 'app',
relativeTo: ImagesRelativeTo
}
}
},
@ -129,7 +193,8 @@ exports.register = async server => {
path: '/{path*}',
handler: {
view: {
name: 'app'
name: 'app',
relativeTo: InstancesRelativeTo
}
}
}

View File

@ -1,8 +1,8 @@
{
"name": "my-joy-instances",
"version": "2.0.0",
"license": "MPL-2.0",
"version": "2.1.7",
"private": true,
"license": "MPL-2.0",
"repository": "github:yldio/joyent-portal",
"main": "lib/index.js",
"scripts": {
@ -31,8 +31,8 @@
"declarative-redux-form": "^2.0.8",
"exenv": "^1.2.2",
"fuse.js": "^3.2.0",
"hapi-render-react": "^2.1.0",
"hapi-render-react-joyent-document": "^4.2.3",
"hapi-render-react": "^2.2.0",
"hapi-render-react-joyent-document": "^4.4.0",
"inert": "^5.1.0",
"joyent-logo-assets": "^1.0.0",
"joyent-manifest-editor": "^1.4.0",
@ -54,6 +54,7 @@
"lodash.sortby": "^4.7.0",
"lodash.uniqby": "^4.7.0",
"lodash.values": "^4.3.0",
"my-joy-images": "1.1.5",
"param-case": "^2.1.1",
"query-string": "^5.1.0",
"react": "^16.2.0",
@ -66,6 +67,7 @@
"redux": "^3.7.2",
"redux-form": "^7.2.3",
"remcalc": "^1.0.10",
"resolve-pkg": "^1.0.0",
"styled-components": "^3.1.6",
"styled-components-spacing": "^2.1.3",
"styled-flex-component": "^2.2.1",

View File

@ -8,6 +8,7 @@ const { default: createClient } = require('./state/apollo-client');
const { default: createStore } = require('./state/redux-store');
const indexFile = path.join(__dirname, '../../build/index.html');
const assets = require('../../build/asset-manifest.json');
const getState = request => {
const { req } = request.raw;
@ -31,4 +32,9 @@ const getState = request => {
};
};
module.exports = Document({ indexFile, getState });
module.exports = Document({
namespace: 'instances/',
assets,
indexFile,
getState
});

View File

@ -27,6 +27,8 @@ import {
ActionsIcon
} from 'joyent-ui-toolkit';
import GLOBAL from '@state/global';
const stateColor = {
PROVISIONING: 'primary',
RUNNING: 'green',
@ -75,7 +77,7 @@ export const Item = ({
</FormGroup>
</TableTd>
<TableTd middle left>
<A to={`/${name}`} component={Link}>
<A to={`/instances/${name}`} component={Link}>
{name}
</A>
</TableTd>
@ -116,7 +118,7 @@ export const Item = ({
<PopoverDivider />
<PopoverItem disabled={false} onClick={onCreateImage}>
<ItemAnchor
href={`http://localhost:3070/~create/${name}`}
href={`${GLOBAL.origin}/images/~create/${name}`}
target="__blank"
rel="noopener noreferrer"
>

View File

@ -24,6 +24,8 @@ import {
InstanceTypeIcon
} from 'joyent-ui-toolkit';
import GLOBAL from '@state/global';
const { SmallOnly, Medium } = QueryBreakpoints;
const stateColor = {
@ -140,7 +142,7 @@ export default withTheme(
<Row between="xs">
<Col xs={9}>
<Button
href={`http://localhost:3070/~create/${instance.name}`}
href={`${GLOBAL.origin}/images/~create/${instance.name}`}
target="__blank"
rel="noopener noreferrer"
secondary

View File

@ -189,7 +189,9 @@ export default compose(
: validateRule({ ...aff, type });
},
handleEdit: () => {
return history.push(`/~create/affinity${history.location.search}`);
return history.push(
`/instances/~create/affinity${history.location.search}`
);
},
handleCreateAffinityRules: value => {
return dispatch([

View File

@ -168,11 +168,13 @@ export default compose(
connect(null, (dispatch, { history, cnsEnabled, serviceNames = [] }) => ({
handleNext: () => {
dispatch(set({ name: IC_CNS_V_PROCEEDED, value: true }));
return history.push(`/~create/affinity${history.location.search}`);
return history.push(
`/instances/~create/affinity${history.location.search}`
);
},
handleEdit: () => {
dispatch(set({ name: IC_CNS_V_PROCEEDED, value: true }));
history.push(`/~create/cns${history.location.search}`);
history.push(`/instances/~create/cns${history.location.search}`);
},
shouldAsyncValidate: ({ trigger }) => {
return trigger === 'submit';

View File

@ -164,11 +164,13 @@ export default compose(
(dispatch, { history }) => ({
handleNext: () => {
dispatch(set({ name: IC_FW_V_PROCEEDED, value: true }));
return history.push(`/~create/cns${history.location.search}`);
return history.push(`/instances/~create/cns${history.location.search}`);
},
handleEdit: () => {
dispatch(set({ name: IC_FW_V_PROCEEDED, value: true }));
return history.push(`/~create/firewall${history.location.search}`);
return history.push(
`/instances/~create/firewall${history.location.search}`
);
}
})
),

View File

@ -26,7 +26,7 @@ const { IC_IMG_V_PROCEEDED, IC_IMG_V_VMS } = Values;
const HarcodedImage = (image = {}) => (
<Fragment>
<Title icon={<InstanceTypeIcon />} collapsed={false}>
<Title icon={<InstanceTypeIcon />} collapsed={true}>
Instance type and image
</Title>
{image.id ? (
@ -148,10 +148,14 @@ export default compose(
(dispatch, { history }) => ({
handleNext: () => {
dispatch(set({ name: IC_IMG_V_PROCEEDED, value: true }));
return history.push(`/~create/package${history.location.search}`);
return history.push(
`/instances/~create/package${history.location.search}`
);
},
handleEdit: () => {
return history.push(`/~create/image${history.location.search}`);
return history.push(
`/instances/~create/image${history.location.search}`
);
},
handleSelectLatest: ({ versions }) => {
return dispatch(change(IC_IMG_F, 'image', versions[0].id));

View File

@ -370,7 +370,7 @@ export default compose(
}
dispatch([destroyAll(), forms.map(name => destroy(name))]);
history.push(`/${res.data.createMachine.name}`);
history.push(`/instances/${res.data.createMachine.name}`);
}
};
})

View File

@ -166,11 +166,15 @@ export default compose(
connect(null, (dispatch, { metadata = [], history }) => ({
handleNext: () => {
dispatch(set({ name: IC_MD_V_PROCEEDED, value: true }));
return history.push(`/~create/user-script${history.location.search}`);
return history.push(
`/instances/~create/user-script${history.location.search}`
);
},
handleEdit: () => {
dispatch(set({ name: IC_MD_V_PROCEEDED, value: true }));
return history.push(`/~create/metadata${history.location.search}`);
return history.push(
`/instances/~create/metadata${history.location.search}`
);
},
shouldAsyncValidate: ({ trigger }) => {
return trigger === 'submit';

View File

@ -116,13 +116,13 @@ export default compose(
handleNext: () => {
dispatch(set({ name: IC_NAME_V_PROCEEDED, value: true }));
return history.push(
`/~create/${query.image ? 'package' : 'image'}${
`/instances/~create/${query.image ? 'package' : 'image'}${
history.location.search
}`
);
},
handleEdit: () => {
history.push(`/~create/name${history.location.search}`);
history.push(`/instances/~create/name${history.location.search}`);
},
shouldAsyncValidate: ({ trigger }) => {
return trigger === 'change';

View File

@ -173,11 +173,15 @@ export default compose(
(dispatch, { history }) => ({
handleNext: () => {
dispatch(set({ name: IC_NW_V_PROCEEDED, value: true }));
return history.push(`/~create/firewall${history.location.search}`);
return history.push(
`/instances/~create/firewall${history.location.search}`
);
},
handleEdit: () => {
dispatch(set({ name: IC_NW_V_PROCEEDED, value: true }));
return history.push(`/~create/networks${history.location.search}`);
return history.push(
`/instances/~create/networks${history.location.search}`
);
},
setInfoExpanded: (id, expanded) => {
return dispatch(

View File

@ -236,10 +236,14 @@ export default compose(
(dispatch, { history }) => ({
handleNext: () => {
dispatch(set({ name: IC_PKG_V_PROCEEDED, value: true }));
return history.push(`/~create/tags${history.location.search}`);
return history.push(
`/instances/~create/tags${history.location.search}`
);
},
handleEdit: () => {
return history.push(`/~create/package${history.location.search}`);
return history.push(
`/instances/~create/package${history.location.search}`
);
},
handleResetFilters: () => {
dispatch(destroy(IC_PKG_F_FILTER));

View File

@ -146,11 +146,13 @@ export default compose(
connect(null, (dispatch, { tags = [], history }) => ({
handleNext: () => {
dispatch(set({ name: IC_TAG_V_PROCEEDED, value: true }));
return history.push(`/~create/metadata${history.location.search}`);
return history.push(
`/instances/~create/metadata${history.location.search}`
);
},
handleEdit: () => {
dispatch(set({ name: IC_TAG_V_PROCEEDED, value: true }));
return history.push(`/~create/tags${history.location.search}`);
return history.push(`/instances/~create/tags${history.location.search}`);
},
shouldAsyncValidate: ({ trigger }) => {
return trigger === 'submit';

View File

@ -120,7 +120,9 @@ export default compose(
set({ name: IC_US_V_OPEN, value: true })
]);
return history.push(`/~create/user-script${history.location.search}`);
return history.push(
`/instances/~create/user-script${history.location.search}`
);
},
handleChangeOpenForm: value => {
return dispatch([set({ name: IC_US_V_OPEN, value })]);
@ -131,7 +133,9 @@ export default compose(
set({ name: IC_US_V_PROCEEDED, value: true })
]);
return history.push(`/~create/networks${history.location.search}`);
return history.push(
`/instances/~create/networks${history.location.search}`
);
}
})
)

View File

@ -23,6 +23,7 @@ import {
Divider
} from 'joyent-ui-toolkit';
import GLOBAL from '@state/global';
import ListInstances from '@graphql/list-instances.gql';
import StopInstance from '@graphql/stop-instance.gql';
import StartInstance from '@graphql/start-instance.gql';
@ -160,7 +161,7 @@ export const List = ({
searchLabel="Filter instances"
searchable={!_loading}
actionLabel="Create Instance"
onActionClick={() => history.push(`/~create`)}
onActionClick={() => history.push('/instances/~create')}
/>
)}
</ReduxForm>
@ -272,8 +273,11 @@ export default compose(
};
},
(dispatch, { refetch, ...ownProps }) => ({
handleCreateImage: ({ name }) =>
window.open(`http://localhost:3070/~create/${name}`, '_blank').focus(),
handleCreateImage: ({ name }) => {
return window
.open(`${GLOBAL.origin}/images/~create/${name}`, '_blank')
.focus();
},
handleSortBy: ({ sortBy: currentSortBy, sortOrder }) => newSortBy => {
// sort prop is the same, toggle
if (currentSortBy === newSortBy) {

View File

@ -221,7 +221,7 @@ export default compose(
if (!err && action === 'remove') {
const { history } = ownProps;
return history.push(`/`);
return history.push('/instances');
}
// after mutation, sets loading back to false

View File

@ -15,14 +15,14 @@ export default ({ match }) => {
},
{
name: 'Instances',
pathname: '/'
pathname: '/instances'
}
]
.concat(
instance && [
{
name: paramCase(instance),
pathname: `/${instance}`
pathname: `/instances/${instance}`
}
]
)

View File

@ -10,7 +10,7 @@ export default connect((state, { match }) => {
const links = sections.map(({ name, pathname }) => ({
name,
pathname: `/${instanceSlug}/${pathname}`
pathname: `/instances/${instanceSlug}/${pathname}`
}));
return {

View File

@ -1,6 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { ThemeProvider, consolidateStreamedStyles } from 'styled-components';
import { ThemeProvider } from 'styled-components';
import { Provider as ReduxProvider } from 'react-redux';
import { ApolloProvider } from 'react-apollo';
import { BrowserRouter } from 'react-router-dom';
@ -11,15 +11,12 @@ import { theme } from 'joyent-ui-toolkit';
import createStore from '@state/redux-store';
import createClient from '@state/apollo-client';
import { register } from './sw';
import App from './app';
if (!isFunction(Number.isFinite)) {
Number.isFinite = isFinite;
}
consolidateStreamedStyles();
ReactDOM.hydrate(
<ApolloProvider client={createClient()}>
<ThemeProvider theme={theme}>
@ -32,5 +29,3 @@ ReactDOM.hydrate(
</ApolloProvider>,
document.getElementById('root')
);
register();

View File

@ -31,43 +31,69 @@ export default () => (
<PageContainer>
{/* Breadcrumb */}
<Switch>
<Route path="/~create/:section?" exact component={Breadcrumb} />
<Route path="/~:action/:instance?" exact component={Breadcrumb} />
<Route path="/:instance?" component={Breadcrumb} />
<Route path="/instances/~create/:section?" exact component={Breadcrumb} />
<Route
path="/instances/~:action/:instance?"
exact
component={Breadcrumb}
/>
<Route path="/instances/:instance?" component={Breadcrumb} />
</Switch>
{/* Menu */}
<Switch>
<Route path="/~server-error" component={() => null} />
<Route path="/~:action/:id?" exact component={Menu} />
<Route path="/:instance?/:section?" component={Menu} />
<Route path="/instances/~:action/:id?" exact component={Menu} />
<Route path="/instances/:instance?/:section?" component={Menu} />
</Switch>
{/* Instances List */}
<Switch>
<Route path="/" exact component={Instances} />
<Route path="/instances" exact component={Instances} />
</Switch>
{/* Instance Sections */}
<Switch>
<Route path="/~:action" component={() => null} />
<Route path="/:instance/summary" exact component={InstanceSummary} />
<Route path="/:instance/tags" exact component={InstanceTags} />
<Route path="/:instance/metadata" exact component={InstanceMetadata} />
<Route path="/:instance/networks" exact component={InstanceNetworks} />
<Route path="/:instance/firewall" exact component={InstanceFirewall} />
<Route path="/:instance/snapshots" exact component={InstanceSnapshots} />
<Route path="/:instance/cns" exact component={InstanceCns} />
<Route path="/instances/~:action" component={() => null} />
<Route
path="/:instance/user-script"
path="/instances/:instance/summary"
exact
component={InstanceSummary}
/>
<Route path="/instances/:instance/tags" exact component={InstanceTags} />
<Route
path="/instances/:instance/metadata"
exact
component={InstanceMetadata}
/>
<Route
path="/instances/:instance/networks"
exact
component={InstanceNetworks}
/>
<Route
path="/instances/:instance/firewall"
exact
component={InstanceFirewall}
/>
<Route
path="/instances/:instance/snapshots"
exact
component={InstanceSnapshots}
/>
<Route path="/instances/:instance/cns" exact component={InstanceCns} />
<Route
path="/instances/:instance/user-script"
exact
component={InstanceUserScript}
/>
<Route
path="/:instance"
path="/instances/:instance"
exact
component={({ match }) => (
<Redirect to={`/${get(match, 'params.instance')}/summary`} />
<Redirect
to={`/instances/${get(match, 'params.instance')}/summary`}
/>
)}
/>
</Switch>
@ -76,17 +102,17 @@ export default () => (
<Switch>
{/* Create Instance */}
<Route
path="/~create/"
path="/instances/~create/"
exact
component={({ match, location }) => (
<Redirect to={`/~create/name${location.search}`} />
)}
component={({ match, location }) => (<Redirect to={`/instances/~create/name${location.search}`} />)}
/>
<Route path="/~create/:step" component={CreateInstance} />
<Route path="/instances/~create/:step" component={CreateInstance} />
</Switch>
<Route path="/~server-error" exact component={ServerError} />
<Route path="/" exact component={() => <Redirect to="/instances" />} />
<noscript>
<ViewContainer main>
<Message warning>

View File

@ -9,6 +9,7 @@ export default (() => {
port: window.location.port,
protocol: window.location.protocol.replace(/:$/, ''),
hostname: window.location.hostname,
origin: window.location.origin,
__REDUX_DEVTOOLS_EXTENSION__: window.__REDUX_DEVTOOLS_EXTENSION__,
__APOLLO_STATE__: window.__APOLLO_STATE__,
__REDUX_STATE__: window.__REDUX_STATE__

View File

@ -30,14 +30,14 @@ const validateSchema = async (schema, value) => {
const matches = {
nameStart: /^[a-zA-Z]|\d/,
nameBody: /^([a-zA-Z]|\d|\.|_|-)+$/
nameBody: /^([a-zA-Z]|\d|_|-)+$/
};
const msgs = {
required: prefix => `${prefix} must be defined.`,
nameStart: prefix => `${prefix} can only start with letters and numbers.`,
nameBody: prefix =>
`${prefix} cannot contain spaces and can only contain letters, numbers, periods (.), underscores (_), and hyphens (-).`
`${prefix} cannot contain spaces and can only contain letters, numbers, underscores (_), and hyphens (-).`
};
const Schemas = {

View File

@ -1,108 +0,0 @@
// In production, we register a service worker to serve assets from local cache.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export function register() {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (!isLocalhost) {
// Is not local host. Just register service worker
registerValidSW(swUrl);
} else {
// This is running on localhost. Lets check if a service worker still exists or not.
checkValidServiceWorker(swUrl);
}
});
}
}
function registerValidSW(swUrl) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in your web app.
console.log('New content is available; please refresh.');
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
if (
response.status === 404 ||
response.headers.get('content-type').indexOf('javascript') === -1
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}

View File

@ -1,6 +1,7 @@
{
"name": "my-joy-navigation",
"version": "2.0.0",
"version": "2.1.0",
"private": true,
"license": "MPL-2.0",
"main": "lib/index.js",
"scripts": {

View File

@ -85,7 +85,7 @@ const Navigation = ({
</HeaderItemIcon>
</HeaderItem>
) : null}
{datacenter ? (<HeaderDividerItem />) : null}
{datacenter ? <HeaderDividerItem /> : null}
{login ? (
<HeaderItem>
<HeaderItemContent>

View File

@ -1,6 +1,7 @@
{
"name": "joyent-ui-toolkit",
"version": "5.0.0",
"private": true,
"license": "MPL-2.0",
"repository": "github:yldio/joyent-portal",
"main": "dist/umd/index.js",

252
yarn.lock
View File

@ -290,7 +290,7 @@ acorn@^4.0.3, acorn@^4.0.4:
version "4.0.13"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787"
acorn@^5.0.0, acorn@^5.0.3, acorn@^5.1.1, acorn@^5.4.0, acorn@^5.4.1:
acorn@^5.0.0, acorn@^5.0.3, acorn@^5.1.1, acorn@^5.4.1, acorn@^5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.0.tgz#1abb587fbf051f94e3de20e6b26ef910b1828298"
@ -308,7 +308,7 @@ agent-base@^4.1.0:
dependencies:
es6-promisify "^5.0.0"
ajv-keywords@^2.0.0:
ajv-keywords@^2.0.0, ajv-keywords@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
@ -323,7 +323,7 @@ ajv@^4.9.1:
co "^4.6.0"
json-stable-stringify "^1.0.1"
ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5, ajv@^5.2.0, ajv@^5.3.0:
ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5, ajv@^5.2.0, ajv@^5.2.3, ajv@^5.3.0:
version "5.5.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
dependencies:
@ -333,8 +333,8 @@ ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5, ajv@^5.2.0, ajv@^5.3.0:
json-schema-traverse "^0.3.0"
ajv@^6.0.1, ajv@^6.1.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.2.0.tgz#afac295bbaa0152449e522742e4547c1ae9328d2"
version "6.2.1"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.2.1.tgz#28a6abc493a2abe0fb4c8507acaedb43fa550671"
dependencies:
fast-deep-equal "^1.0.0"
fast-json-stable-stringify "^2.0.0"
@ -405,9 +405,9 @@ ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
ansi-styles@^3.0.0, ansi-styles@^3.1.0, ansi-styles@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
ansi-styles@^3.0.0, ansi-styles@^3.1.0, ansi-styles@^3.2.0, ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
dependencies:
color-convert "^1.9.0"
@ -467,18 +467,18 @@ apollo-link-dedup@^1.0.0:
dependencies:
apollo-link "^1.2.1"
apollo-link-http-common@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.2.tgz#ac8a1810eca6a7ed37a34baeeb0a55752e6a0e30"
apollo-link-http-common@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.3.tgz#82ae0d4ff0cdd7c5c8826411d9dd7f7d8049ca46"
dependencies:
apollo-link "^1.2.1"
apollo-link-http@^1.5.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.2.tgz#cac4202b7f802869f892397f989d002c4ebb3b56"
version "1.5.3"
resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.3.tgz#3aa0d3ecfe5666ef0c360f359c425ff6ea1d285b"
dependencies:
apollo-link "^1.2.1"
apollo-link-http-common "^0.2.2"
apollo-link-http-common "^0.2.3"
apollo-link-state@^0.4.0:
version "0.4.0"
@ -1269,8 +1269,8 @@ babel-plugin-module-resolver@^3.1.0:
resolve "^1.4.0"
babel-plugin-styled-components@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.5.0.tgz#4549f28a19fb05170aa9ee429b4de0eac2d2401d"
version "1.5.1"
resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.5.1.tgz#31dbeb696d1354d1585e60d66c7905f5e474afcd"
dependencies:
"@babel/helper-annotate-as-pure" "^7.0.0-beta.37"
babel-types "^6.26.0"
@ -2304,12 +2304,12 @@ caniuse-api@^1.5.2:
lodash.uniq "^4.5.0"
caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
version "1.0.30000810"
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000810.tgz#bd25830c41efab64339a2e381f49677343c84509"
version "1.0.30000812"
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000812.tgz#29c28dd6927ee43e8c2ab648e5236ac916c97d69"
caniuse-lite@^1.0.30000748, caniuse-lite@^1.0.30000792:
version "1.0.30000810"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000810.tgz#47585fffce0e9f3593a6feea4673b945424351d9"
version "1.0.30000812"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000812.tgz#d173b686b49bc941fa18ff2e7e533048e20ed92c"
capture-stack-trace@^1.0.0:
version "1.0.0"
@ -2374,12 +2374,12 @@ chalk@2.1.0:
supports-color "^4.0.0"
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796"
version "2.3.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65"
dependencies:
ansi-styles "^3.2.0"
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.2.0"
supports-color "^5.3.0"
chalk@~0.5.1:
version "0.5.1"
@ -2497,8 +2497,8 @@ classnames@^2.2.5:
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
clean-css@4.1.x:
version "4.1.9"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.1.9.tgz#35cee8ae7687a49b98034f70de00c4edd3826301"
version "4.1.10"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.1.10.tgz#3dfc2c2569d5f03c14b41d875ad9bccae09cb89e"
dependencies:
source-map "0.5.x"
@ -2843,11 +2843,11 @@ conventional-changelog-atom@^0.2.4:
q "^1.5.1"
conventional-changelog-cli@^1.3.13:
version "1.3.15"
resolved "https://registry.yarnpkg.com/conventional-changelog-cli/-/conventional-changelog-cli-1.3.15.tgz#cd7f0e64473f1cecee902ee5ee00548ea91bcc9e"
version "1.3.16"
resolved "https://registry.yarnpkg.com/conventional-changelog-cli/-/conventional-changelog-cli-1.3.16.tgz#69acdcc4b68b4d123c5945868dffe394960cea9d"
dependencies:
add-stream "^1.0.0"
conventional-changelog "^1.1.17"
conventional-changelog "^1.1.18"
lodash "^4.2.1"
meow "^4.0.0"
tempfile "^1.1.1"
@ -2882,9 +2882,9 @@ conventional-changelog-ember@^0.3.6:
dependencies:
q "^1.5.1"
conventional-changelog-eslint@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/conventional-changelog-eslint/-/conventional-changelog-eslint-1.0.4.tgz#333456d1884d96f3a49cc0984a745095e9d56288"
conventional-changelog-eslint@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/conventional-changelog-eslint/-/conventional-changelog-eslint-1.0.5.tgz#8bae05ebbf574e6506caf7b37dc51ca21b74d220"
dependencies:
q "^1.5.1"
@ -2932,16 +2932,16 @@ conventional-changelog-writer@^3.0.4:
split "^1.0.0"
through2 "^2.0.0"
conventional-changelog@^1.1.17:
version "1.1.17"
resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-1.1.17.tgz#9019503d51328d8b33b0be6d425ab7f065918332"
conventional-changelog@^1.1.18:
version "1.1.18"
resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-1.1.18.tgz#ffe28798e4ddef5f6e2f74398e8248bcb233360b"
dependencies:
conventional-changelog-angular "^1.6.6"
conventional-changelog-atom "^0.2.4"
conventional-changelog-codemirror "^0.3.4"
conventional-changelog-core "^2.0.5"
conventional-changelog-ember "^0.3.6"
conventional-changelog-eslint "^1.0.4"
conventional-changelog-eslint "^1.0.5"
conventional-changelog-express "^0.3.4"
conventional-changelog-jquery "^0.1.0"
conventional-changelog-jscs "^0.1.0"
@ -3007,8 +3007,8 @@ copy-descriptor@^0.1.0:
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
copy-webpack-plugin@^4.3.0:
version "4.4.3"
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.4.3.tgz#65d56fb9e1936b39e129f9aa2aec097ce1fd44be"
version "4.5.0"
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.5.0.tgz#9cb012163317666ea47479d2a8c57daca3557da5"
dependencies:
cacache "^10.0.1"
find-cache-dir "^1.0.0"
@ -3559,8 +3559,8 @@ dictionary-en-us@^1.0.2:
resolved "https://registry.yarnpkg.com/dictionary-en-us/-/dictionary-en-us-1.2.1.tgz#d21009edaccab49fae8eefdc483da83438526b5f"
diff@^3.2.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c"
version "3.5.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
diffie-hellman@^5.0.0:
version "5.0.2"
@ -3709,8 +3709,8 @@ duplexer@^0.1.1:
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
duplexify@^3.4.2, duplexify@^3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.3.tgz#8b5818800df92fd0125b27ab896491912858243e"
version "3.5.4"
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.4.tgz#4bb46c1796eabebeec4ca9a2e66b808cb7a3d8b4"
dependencies:
end-of-stream "^1.0.0"
inherits "^2.0.1"
@ -3737,8 +3737,8 @@ ee-first@1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.30:
version "1.3.34"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.34.tgz#d93498f40391bb0c16a603d8241b9951404157ed"
version "1.3.35"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.35.tgz#693c17cfb93841d38cb59b8df019d17e356985f0"
elliptic@^6.0.0:
version "6.4.0"
@ -4154,8 +4154,8 @@ eslint@4.10.0:
text-table "~0.2.0"
eslint@^4.18.1:
version "4.18.1"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.18.1.tgz#b9138440cb1e98b2f44a0d578c6ecf8eae6150b0"
version "4.18.2"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.18.2.tgz#0f81267ad1012e7d2051e186a9004cc2267b8d45"
dependencies:
ajv "^5.3.0"
babel-code-frame "^6.22.0"
@ -4192,14 +4192,14 @@ eslint@^4.18.1:
semver "^5.3.0"
strip-ansi "^4.0.0"
strip-json-comments "~2.0.1"
table "^4.0.1"
table "4.0.2"
text-table "~0.2.0"
espree@^3.5.1, espree@^3.5.2:
version "3.5.3"
resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.3.tgz#931e0af64e7fbbed26b050a29daad1fc64799fa6"
version "3.5.4"
resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7"
dependencies:
acorn "^5.4.0"
acorn "^5.5.0"
acorn-jsx "^3.0.0"
esprima@^2.1.0, esprima@^2.6.0:
@ -5184,15 +5184,15 @@ handlebars@^4.0.2, handlebars@^4.0.3:
optionalDependencies:
uglify-js "^2.6"
hapi-render-react-joyent-document@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/hapi-render-react-joyent-document/-/hapi-render-react-joyent-document-4.2.3.tgz#c7d7e5614cf31697b39d3f0f276056b5d36be340"
hapi-render-react-joyent-document@^4.3.0, hapi-render-react-joyent-document@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/hapi-render-react-joyent-document/-/hapi-render-react-joyent-document-4.4.0.tgz#af0b75f4b646908bc4f2ad41221ca1ecf219ff07"
dependencies:
through2 "^2.0.3"
hapi-render-react@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/hapi-render-react/-/hapi-render-react-2.1.0.tgz#b9374d96783240fc3aafa38e26704ab48849afc2"
hapi-render-react@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/hapi-render-react/-/hapi-render-react-2.2.0.tgz#4f95f5e24256ffa26fa618f5d41379a15970d0f6"
dependencies:
mz "^2.7.0"
@ -5450,8 +5450,8 @@ html-entities@^1.2.0:
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f"
html-minifier@^3.2.3:
version "3.5.9"
resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.9.tgz#74424014b872598d4bb0e20ac420926ec61024b6"
version "3.5.10"
resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.10.tgz#8522c772c388db81aa5c26f62033302d906ea1c7"
dependencies:
camel-case "3.0.x"
clean-css "4.1.x"
@ -5567,8 +5567,8 @@ https-browserify@^1.0.0:
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
https-proxy-agent@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.1.1.tgz#a7ce4382a1ba8266ee848578778122d491260fd9"
version "2.2.0"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.0.tgz#7fbba856be8cd677986f42ebd3664f6317257887"
dependencies:
agent-base "^4.1.0"
debug "^3.1.0"
@ -5621,8 +5621,8 @@ iltorb@1.3.x:
prebuild-install "^2.3.0"
immutability-helper@^2.1.2:
version "2.6.5"
resolved "https://registry.yarnpkg.com/immutability-helper/-/immutability-helper-2.6.5.tgz#94a10f18f1196244b2dea92d46522d2b4dce7b73"
version "2.6.6"
resolved "https://registry.yarnpkg.com/immutability-helper/-/immutability-helper-2.6.6.tgz#9b384c240d65257133c155086e16f678ca563b05"
dependencies:
invariant "^2.2.0"
@ -5764,7 +5764,7 @@ interpret@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2:
invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.3:
version "2.2.3"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.3.tgz#1a827dfde7dcbd7c323f0ca826be8fa7c5e9d688"
dependencies:
@ -6547,8 +6547,8 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
js-yaml@^3.4.3, js-yaml@^3.7.0, js-yaml@^3.9.0, js-yaml@^3.9.1:
version "3.10.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
version "3.11.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef"
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
@ -6928,7 +6928,7 @@ locate-path@^2.0.0:
p-locate "^2.0.0"
path-exists "^3.0.0"
lodash-es@^4.17.3, lodash-es@^4.17.4, lodash-es@^4.17.5, lodash-es@^4.2.1:
lodash-es@^4.17.4, lodash-es@^4.17.5, lodash-es@^4.2.1:
version "4.17.5"
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.5.tgz#9fc6e737b1c4d151d8f9cae2247305d552ce748f"
@ -7224,7 +7224,7 @@ markdown-table@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.1.tgz#4b3dd3a133d1518b8ef0dbc709bf2a1b4824bc8c"
markdown-to-jsx@^6.3.1:
markdown-to-jsx@^6.4.1:
version "6.4.1"
resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-6.4.1.tgz#95fe617b5790fec6f4e0399a296e3a2f10fffaad"
dependencies:
@ -7505,8 +7505,8 @@ modify-values@^1.0.0:
resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.0.tgz#e2b6cdeb9ce19f99317a53722f3dbf5df5eaaab2"
moment@^2.6.0:
version "2.20.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd"
version "2.21.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.21.0.tgz#2a114b51d2a6ec9e6d83cf803f838a878d8a023a"
move-concurrently@^1.0.1:
version "1.0.1"
@ -7546,6 +7546,50 @@ mute-stream@0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
my-joy-images@1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/my-joy-images/-/my-joy-images-1.1.5.tgz#f25af4e454aa95135c35e8795a7c6a2a125c8777"
dependencies:
"@manaflair/redux-batch" "^0.1.0"
apollo "^0.2.2"
apollo-cache-inmemory "^1.1.9"
apollo-client "^2.2.5"
apollo-link-http "^1.5.2"
apr-intercept "^3.0.3"
date-fns "^1.29.0"
declarative-redux-form "^2.0.8"
force-array "^3.1.0"
fuse.js "^3.2.0"
hapi-render-react "^2.2.0"
hapi-render-react-joyent-document "^4.3.0"
joyent-logo-assets "^1.0.0"
joyent-react-styled-flexboxgrid "^2.2.3"
joyent-ui-toolkit "^5.0.0"
lodash.find "^4.6.0"
lodash.get "^4.4.2"
lodash.isfinite "^3.3.2"
lodash.isfunction "^3.0.9"
lodash.omit "^4.5.0"
lodash.uniqby "^4.7.0"
lunr "^2.1.6"
param-case "^2.1.1"
react "^16.2.0"
react-apollo "^2.0.4"
react-dom "^16.2.0"
react-redux "^5.0.7"
react-redux-values "^1.1.2"
react-router "^4.2.0"
react-router-dom "^4.2.2"
redux "^3.7.2"
redux-form "^7.2.3"
remcalc "^1.0.10"
styled-components "^3.1.6"
styled-components-spacing "^2.1.3"
styled-flex-component "^2.2.1"
styled-is "^1.1.2"
title-case "^2.1.1"
yup "^0.24.1"
mz@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
@ -8766,7 +8810,7 @@ promise@^7.1.1:
dependencies:
asap "~2.0.3"
prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.5.9, prop-types@^15.6.0, prop-types@^15.6.1:
prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1:
version "15.6.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
dependencies:
@ -9264,8 +9308,8 @@ react-scripts@^1.1.0:
fsevents "^1.1.3"
react-styleguidist@^6.2.5:
version "6.2.5"
resolved "https://registry.yarnpkg.com/react-styleguidist/-/react-styleguidist-6.2.5.tgz#fe4da35d999220425012c8b0350f06608d734d6d"
version "6.2.6"
resolved "https://registry.yarnpkg.com/react-styleguidist/-/react-styleguidist-6.2.6.tgz#412da04ac361a882593ba3a5a6ecc81b9f4a1d39"
dependencies:
ast-types "^0.10.1"
buble "^0.19.2"
@ -9302,7 +9346,7 @@ react-styleguidist@^6.2.5:
loader-utils "^1.1.0"
lodash "^4.17.4"
lowercase-keys "^1.0.0"
markdown-to-jsx "^6.3.1"
markdown-to-jsx "^6.4.1"
minimist "^1.2.0"
ora "^1.3.0"
prop-types "^15.6.0"
@ -9417,8 +9461,8 @@ read-pkg@^3.0.0:
path-type "^3.0.0"
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3:
version "2.3.4"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.4.tgz#c946c3f47fa7d8eabc0b6150f4a12f69a4574071"
version "2.3.5"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.5.tgz#b4f85003a938cbb6ecbce2a124fb1012bd1a838d"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
@ -9554,17 +9598,17 @@ redux-actions@^2.2.1:
reduce-reducers "^0.1.0"
redux-form@^7.2.3:
version "7.2.3"
resolved "https://registry.yarnpkg.com/redux-form/-/redux-form-7.2.3.tgz#a01111116f386f3d88451b5528dfbb180561a8b4"
version "7.3.0"
resolved "https://registry.yarnpkg.com/redux-form/-/redux-form-7.3.0.tgz#b92ef1639c86a6009b0821aacfc80ad8b5ac8c05"
dependencies:
deep-equal "^1.0.1"
es6-error "^4.1.1"
hoist-non-react-statics "^2.3.1"
invariant "^2.2.2"
hoist-non-react-statics "^2.5.0"
invariant "^2.2.3"
is-promise "^2.1.0"
lodash "^4.17.3"
lodash-es "^4.17.3"
prop-types "^15.5.9"
lodash "^4.17.5"
lodash-es "^4.17.5"
prop-types "^15.6.1"
redux@^3.7.2:
version "3.7.2"
@ -9913,6 +9957,10 @@ resolve-from@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
resolve-from@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57"
resolve-from@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
@ -9921,6 +9969,12 @@ resolve-pathname@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879"
resolve-pkg@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/resolve-pkg/-/resolve-pkg-1.0.0.tgz#e19a15e78aca2e124461dc92b2e3943ef93494d9"
dependencies:
resolve-from "^2.0.0"
resolve-url@^0.2.1, resolve-url@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
@ -10819,17 +10873,18 @@ styled-components-spacing@^2.1.3:
styled-components-breakpoint "^1.0.0-preview.3"
styled-components@^3.1.6:
version "3.1.6"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-3.1.6.tgz#9c443146fa82c6659a9f64dd493bf2202480342e"
version "3.2.0"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-3.2.0.tgz#5e063656783a66f6bf411153fcfe994572f3e848"
dependencies:
buffer "^5.0.3"
css-to-react-native "^2.0.3"
fbjs "^0.8.9"
hoist-non-react-statics "^1.2.0"
is-plain-object "^2.0.1"
opencollective "^1.0.3"
prop-types "^15.5.4"
stylis "^3.4.0"
stylis-rule-sheet "^0.0.7"
stylis "^3.4.10"
stylis-rule-sheet "^0.0.8"
supports-color "^3.2.3"
styled-flex-component@^2.2.1:
@ -10842,11 +10897,11 @@ styled-is@1.1.2, styled-is@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/styled-is/-/styled-is-1.1.2.tgz#f23a43249ba52ac9136c166aac1da30a5711593e"
stylis-rule-sheet@0.0.7, stylis-rule-sheet@^0.0.5, stylis-rule-sheet@^0.0.7:
stylis-rule-sheet@0.0.7, stylis-rule-sheet@^0.0.5, stylis-rule-sheet@^0.0.8:
version "0.0.7"
resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.7.tgz#5c51dc879141a61821c2094ba91d2cbcf2469c6c"
stylis@^3.0.0, stylis@^3.3.2, stylis@^3.4.0:
stylis@^3.0.0, stylis@^3.3.2, stylis@^3.4.10:
version "3.4.10"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.4.10.tgz#a135cab4b9ff208e327fbb5a6fde3fa991c638ee"
@ -10880,9 +10935,9 @@ supports-color@^4.0.0, supports-color@^4.1.0, supports-color@^4.2.1:
dependencies:
has-flag "^2.0.0"
supports-color@^5.1.0, supports-color@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.2.0.tgz#b0d5333b1184dd3666cbe5aa0b45c5ac7ac17a4a"
supports-color@^5.1.0, supports-color@^5.2.0, supports-color@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0"
dependencies:
has-flag "^3.0.0"
@ -10952,6 +11007,17 @@ synchronous-promise@^1.0.18:
version "1.0.18"
resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-1.0.18.tgz#936e8763e6554088cdcf78dc64f7473b972fcefc"
table@4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36"
dependencies:
ajv "^5.2.3"
ajv-keywords "^2.1.0"
chalk "^2.1.0"
lodash "^4.17.4"
slice-ansi "1.0.0"
string-width "^2.1.1"
table@^4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc"
@ -11332,8 +11398,8 @@ uglify-es@^3.3.4:
source-map "~0.6.1"
uglify-js@3.3.x, uglify-js@^3.0.13:
version "3.3.12"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.12.tgz#efd87c16a1f4c674a8a5ede571001ef634dcc883"
version "3.3.13"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.13.tgz#8a1a89eeb16e2d6a66b0db2b04cb871af3c669cf"
dependencies:
commander "~2.14.1"
source-map "~0.6.1"